From ba8f85b49c38af7bc2a9acdef5dcde2de008d25e Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 12 Jul 2008 05:00:28 +0000 Subject: Flatten bind9 vendor work area --- CHANGES | 7120 ++++ COPYRIGHT | 30 + FAQ | 781 + FAQ.xml | 1347 + Makefile.in | 68 + README | 601 + README.idnkit | 112 + acconfig.h | 151 + bin/Makefile.in | 25 + bin/check/Makefile.in | 98 + bin/check/check-tool.c | 543 + bin/check/check-tool.h | 54 + bin/check/named-checkconf.8 | 89 + bin/check/named-checkconf.c | 488 + bin/check/named-checkconf.docbook | 161 + bin/check/named-checkconf.html | 92 + bin/check/named-checkzone.8 | 269 + bin/check/named-checkzone.c | 429 + bin/check/named-checkzone.docbook | 443 + bin/check/named-checkzone.html | 256 + bin/dig/Makefile.in | 101 + bin/dig/dig.1 | 557 + bin/dig/dig.c | 1797 + bin/dig/dig.docbook | 936 + bin/dig/dig.html | 629 + bin/dig/dighost.c | 5399 +++ bin/dig/host.1 | 219 + bin/dig/host.c | 861 + bin/dig/host.docbook | 277 + bin/dig/host.html | 212 + bin/dig/include/dig/dig.h | 405 + bin/dig/nslookup.1 | 252 + bin/dig/nslookup.c | 891 + bin/dig/nslookup.docbook | 496 + bin/dig/nslookup.html | 307 + bin/dnssec/Makefile.in | 83 + bin/dnssec/dnssec-keygen.8 | 200 + bin/dnssec/dnssec-keygen.c | 512 + bin/dnssec/dnssec-keygen.docbook | 359 + bin/dnssec/dnssec-keygen.html | 232 + bin/dnssec/dnssec-signzone.8 | 272 + bin/dnssec/dnssec-signzone.c | 2333 ++ bin/dnssec/dnssec-signzone.docbook | 476 + bin/dnssec/dnssec-signzone.html | 285 + bin/dnssec/dnssectool.c | 313 + bin/dnssec/dnssectool.h | 76 + bin/named/Makefile.in | 145 + bin/named/builtin.c | 307 + bin/named/client.c | 2643 ++ bin/named/config.c | 796 + bin/named/control.c | 186 + bin/named/controlconf.c | 1461 + bin/named/include/named/builtin.h | 31 + bin/named/include/named/client.h | 361 + bin/named/include/named/config.h | 79 + bin/named/include/named/control.h | 93 + bin/named/include/named/globals.h | 120 + bin/named/include/named/interfacemgr.h | 176 + bin/named/include/named/listenlist.h | 105 + bin/named/include/named/log.h | 98 + bin/named/include/named/logconf.h | 34 + bin/named/include/named/lwaddr.h | 36 + bin/named/include/named/lwdclient.h | 234 + bin/named/include/named/lwresd.h | 121 + bin/named/include/named/lwsearch.h | 112 + bin/named/include/named/main.h | 34 + bin/named/include/named/notify.h | 55 + bin/named/include/named/ns_smf_globals.h | 44 + bin/named/include/named/query.h | 87 + bin/named/include/named/server.h | 230 + bin/named/include/named/sortlist.h | 87 + bin/named/include/named/tkeyconf.h | 53 + bin/named/include/named/tsigconf.h | 49 + bin/named/include/named/types.h | 43 + bin/named/include/named/update.h | 50 + bin/named/include/named/xfrout.h | 39 + bin/named/include/named/zoneconf.h | 63 + bin/named/interfacemgr.c | 978 + bin/named/listenlist.c | 138 + bin/named/log.c | 235 + bin/named/logconf.c | 299 + bin/named/lwaddr.c | 94 + bin/named/lwdclient.c | 467 + bin/named/lwderror.c | 80 + bin/named/lwdgabn.c | 657 + bin/named/lwdgnba.c | 272 + bin/named/lwdgrbn.c | 513 + bin/named/lwdnoop.c | 88 + bin/named/lwresd.8 | 223 + bin/named/lwresd.c | 869 + bin/named/lwresd.docbook | 372 + bin/named/lwresd.html | 225 + bin/named/lwsearch.c | 206 + bin/named/main.c | 926 + bin/named/named.8 | 236 + bin/named/named.conf.5 | 520 + bin/named/named.conf.docbook | 597 + bin/named/named.conf.html | 554 + bin/named/named.docbook | 406 + bin/named/named.html | 255 + bin/named/notify.c | 163 + bin/named/query.c | 4603 +++ bin/named/server.c | 4835 +++ bin/named/sortlist.c | 166 + bin/named/tkeyconf.c | 120 + bin/named/tsigconf.c | 181 + bin/named/unix/Makefile.in | 36 + bin/named/unix/include/named/os.h | 69 + bin/named/unix/os.c | 691 + bin/named/update.c | 3026 ++ bin/named/xfrout.c | 1810 + bin/named/zoneconf.c | 913 + bin/nsupdate/Makefile.in | 83 + bin/nsupdate/nsupdate.8 | 348 + bin/nsupdate/nsupdate.c | 2176 ++ bin/nsupdate/nsupdate.docbook | 657 + bin/nsupdate/nsupdate.html | 500 + bin/rndc/Makefile.in | 104 + bin/rndc/include/rndc/os.h | 46 + bin/rndc/rndc-confgen.8 | 211 + bin/rndc/rndc-confgen.c | 335 + bin/rndc/rndc-confgen.docbook | 286 + bin/rndc/rndc-confgen.html | 188 + bin/rndc/rndc.8 | 147 + bin/rndc/rndc.c | 852 + bin/rndc/rndc.conf | 47 + bin/rndc/rndc.conf.5 | 214 + bin/rndc/rndc.conf.docbook | 252 + bin/rndc/rndc.conf.html | 217 + bin/rndc/rndc.docbook | 250 + bin/rndc/rndc.html | 164 + bin/rndc/unix/Makefile.in | 36 + bin/rndc/unix/os.c | 70 + bin/rndc/util.c | 57 + bin/rndc/util.h | 51 + config.guess | 1447 + config.sub | 1555 + config.threads.in | 177 + configure.in | 2546 ++ contrib/bind9/CHANGES | 7120 ---- contrib/bind9/COPYRIGHT | 30 - contrib/bind9/FAQ | 781 - contrib/bind9/FAQ.xml | 1347 - contrib/bind9/Makefile.in | 68 - contrib/bind9/README | 601 - contrib/bind9/README.idnkit | 112 - contrib/bind9/acconfig.h | 151 - contrib/bind9/bin/Makefile.in | 25 - contrib/bind9/bin/check/Makefile.in | 98 - contrib/bind9/bin/check/check-tool.c | 543 - contrib/bind9/bin/check/check-tool.h | 54 - contrib/bind9/bin/check/named-checkconf.8 | 89 - contrib/bind9/bin/check/named-checkconf.c | 488 - contrib/bind9/bin/check/named-checkconf.docbook | 161 - contrib/bind9/bin/check/named-checkconf.html | 92 - contrib/bind9/bin/check/named-checkzone.8 | 269 - contrib/bind9/bin/check/named-checkzone.c | 429 - contrib/bind9/bin/check/named-checkzone.docbook | 443 - contrib/bind9/bin/check/named-checkzone.html | 256 - contrib/bind9/bin/dig/Makefile.in | 101 - contrib/bind9/bin/dig/dig.1 | 557 - contrib/bind9/bin/dig/dig.c | 1797 - contrib/bind9/bin/dig/dig.docbook | 936 - contrib/bind9/bin/dig/dig.html | 629 - contrib/bind9/bin/dig/dighost.c | 5399 --- contrib/bind9/bin/dig/host.1 | 219 - contrib/bind9/bin/dig/host.c | 861 - contrib/bind9/bin/dig/host.docbook | 277 - contrib/bind9/bin/dig/host.html | 212 - contrib/bind9/bin/dig/include/dig/dig.h | 405 - contrib/bind9/bin/dig/nslookup.1 | 252 - contrib/bind9/bin/dig/nslookup.c | 891 - contrib/bind9/bin/dig/nslookup.docbook | 496 - contrib/bind9/bin/dig/nslookup.html | 307 - contrib/bind9/bin/dnssec/Makefile.in | 83 - contrib/bind9/bin/dnssec/dnssec-keygen.8 | 200 - contrib/bind9/bin/dnssec/dnssec-keygen.c | 512 - contrib/bind9/bin/dnssec/dnssec-keygen.docbook | 359 - contrib/bind9/bin/dnssec/dnssec-keygen.html | 232 - contrib/bind9/bin/dnssec/dnssec-signzone.8 | 272 - contrib/bind9/bin/dnssec/dnssec-signzone.c | 2333 -- contrib/bind9/bin/dnssec/dnssec-signzone.docbook | 476 - contrib/bind9/bin/dnssec/dnssec-signzone.html | 285 - contrib/bind9/bin/dnssec/dnssectool.c | 313 - contrib/bind9/bin/dnssec/dnssectool.h | 76 - contrib/bind9/bin/named/Makefile.in | 145 - contrib/bind9/bin/named/builtin.c | 307 - contrib/bind9/bin/named/client.c | 2643 -- contrib/bind9/bin/named/config.c | 796 - contrib/bind9/bin/named/control.c | 186 - contrib/bind9/bin/named/controlconf.c | 1461 - contrib/bind9/bin/named/include/named/builtin.h | 31 - contrib/bind9/bin/named/include/named/client.h | 361 - contrib/bind9/bin/named/include/named/config.h | 79 - contrib/bind9/bin/named/include/named/control.h | 93 - contrib/bind9/bin/named/include/named/globals.h | 120 - .../bind9/bin/named/include/named/interfacemgr.h | 176 - contrib/bind9/bin/named/include/named/listenlist.h | 105 - contrib/bind9/bin/named/include/named/log.h | 98 - contrib/bind9/bin/named/include/named/logconf.h | 34 - contrib/bind9/bin/named/include/named/lwaddr.h | 36 - contrib/bind9/bin/named/include/named/lwdclient.h | 234 - contrib/bind9/bin/named/include/named/lwresd.h | 121 - contrib/bind9/bin/named/include/named/lwsearch.h | 112 - contrib/bind9/bin/named/include/named/main.h | 34 - contrib/bind9/bin/named/include/named/notify.h | 55 - .../bind9/bin/named/include/named/ns_smf_globals.h | 44 - contrib/bind9/bin/named/include/named/query.h | 87 - contrib/bind9/bin/named/include/named/server.h | 230 - contrib/bind9/bin/named/include/named/sortlist.h | 87 - contrib/bind9/bin/named/include/named/tkeyconf.h | 53 - contrib/bind9/bin/named/include/named/tsigconf.h | 49 - contrib/bind9/bin/named/include/named/types.h | 43 - contrib/bind9/bin/named/include/named/update.h | 50 - contrib/bind9/bin/named/include/named/xfrout.h | 39 - contrib/bind9/bin/named/include/named/zoneconf.h | 63 - contrib/bind9/bin/named/interfacemgr.c | 978 - contrib/bind9/bin/named/listenlist.c | 138 - contrib/bind9/bin/named/log.c | 235 - contrib/bind9/bin/named/logconf.c | 299 - contrib/bind9/bin/named/lwaddr.c | 94 - contrib/bind9/bin/named/lwdclient.c | 467 - contrib/bind9/bin/named/lwderror.c | 80 - contrib/bind9/bin/named/lwdgabn.c | 657 - contrib/bind9/bin/named/lwdgnba.c | 272 - contrib/bind9/bin/named/lwdgrbn.c | 513 - contrib/bind9/bin/named/lwdnoop.c | 88 - contrib/bind9/bin/named/lwresd.8 | 223 - contrib/bind9/bin/named/lwresd.c | 869 - contrib/bind9/bin/named/lwresd.docbook | 372 - contrib/bind9/bin/named/lwresd.html | 225 - contrib/bind9/bin/named/lwsearch.c | 206 - contrib/bind9/bin/named/main.c | 926 - contrib/bind9/bin/named/named.8 | 236 - contrib/bind9/bin/named/named.conf.5 | 520 - contrib/bind9/bin/named/named.conf.docbook | 597 - contrib/bind9/bin/named/named.conf.html | 554 - contrib/bind9/bin/named/named.docbook | 406 - contrib/bind9/bin/named/named.html | 255 - contrib/bind9/bin/named/notify.c | 163 - contrib/bind9/bin/named/query.c | 4603 --- contrib/bind9/bin/named/server.c | 4835 --- contrib/bind9/bin/named/sortlist.c | 166 - contrib/bind9/bin/named/tkeyconf.c | 120 - contrib/bind9/bin/named/tsigconf.c | 181 - contrib/bind9/bin/named/unix/Makefile.in | 36 - contrib/bind9/bin/named/unix/include/named/os.h | 69 - contrib/bind9/bin/named/unix/os.c | 691 - contrib/bind9/bin/named/update.c | 3026 -- contrib/bind9/bin/named/xfrout.c | 1810 - contrib/bind9/bin/named/zoneconf.c | 913 - contrib/bind9/bin/nsupdate/Makefile.in | 83 - contrib/bind9/bin/nsupdate/nsupdate.8 | 348 - contrib/bind9/bin/nsupdate/nsupdate.c | 2176 -- contrib/bind9/bin/nsupdate/nsupdate.docbook | 657 - contrib/bind9/bin/nsupdate/nsupdate.html | 500 - contrib/bind9/bin/rndc/Makefile.in | 104 - contrib/bind9/bin/rndc/include/rndc/os.h | 46 - contrib/bind9/bin/rndc/rndc-confgen.8 | 211 - contrib/bind9/bin/rndc/rndc-confgen.c | 335 - contrib/bind9/bin/rndc/rndc-confgen.docbook | 286 - contrib/bind9/bin/rndc/rndc-confgen.html | 188 - contrib/bind9/bin/rndc/rndc.8 | 147 - contrib/bind9/bin/rndc/rndc.c | 852 - contrib/bind9/bin/rndc/rndc.conf | 47 - contrib/bind9/bin/rndc/rndc.conf.5 | 214 - contrib/bind9/bin/rndc/rndc.conf.docbook | 252 - contrib/bind9/bin/rndc/rndc.conf.html | 217 - contrib/bind9/bin/rndc/rndc.docbook | 250 - contrib/bind9/bin/rndc/rndc.html | 164 - contrib/bind9/bin/rndc/unix/Makefile.in | 36 - contrib/bind9/bin/rndc/unix/os.c | 70 - contrib/bind9/bin/rndc/util.c | 57 - contrib/bind9/bin/rndc/util.h | 51 - contrib/bind9/config.guess | 1447 - contrib/bind9/config.sub | 1555 - contrib/bind9/config.threads.in | 177 - contrib/bind9/configure.in | 2546 -- contrib/bind9/doc/Makefile.in | 29 - contrib/bind9/doc/arm/Bv9ARM-book.xml | 12326 ------- contrib/bind9/doc/arm/Bv9ARM.ch01.html | 560 - contrib/bind9/doc/arm/Bv9ARM.ch02.html | 158 - contrib/bind9/doc/arm/Bv9ARM.ch03.html | 808 - contrib/bind9/doc/arm/Bv9ARM.ch04.html | 1028 - contrib/bind9/doc/arm/Bv9ARM.ch05.html | 143 - contrib/bind9/doc/arm/Bv9ARM.ch06.html | 7114 ---- contrib/bind9/doc/arm/Bv9ARM.ch07.html | 253 - contrib/bind9/doc/arm/Bv9ARM.ch08.html | 139 - contrib/bind9/doc/arm/Bv9ARM.ch09.html | 630 - contrib/bind9/doc/arm/Bv9ARM.ch10.html | 102 - contrib/bind9/doc/arm/Bv9ARM.html | 262 - contrib/bind9/doc/arm/Bv9ARM.pdf | 12885 ------- contrib/bind9/doc/arm/Makefile.in | 67 - contrib/bind9/doc/arm/README-SGML | 329 - contrib/bind9/doc/arm/isc-logo.eps | 12253 ------- contrib/bind9/doc/arm/isc-logo.pdf | Bin 21981 -> 0 bytes contrib/bind9/doc/arm/man.dig.html | 665 - contrib/bind9/doc/arm/man.dnssec-keygen.html | 269 - contrib/bind9/doc/arm/man.dnssec-signzone.html | 323 - contrib/bind9/doc/arm/man.host.html | 249 - contrib/bind9/doc/arm/man.named-checkconf.html | 130 - contrib/bind9/doc/arm/man.named-checkzone.html | 294 - contrib/bind9/doc/arm/man.named.html | 293 - contrib/bind9/doc/arm/man.rndc-confgen.html | 222 - contrib/bind9/doc/arm/man.rndc.conf.html | 255 - contrib/bind9/doc/arm/man.rndc.html | 202 - .../doc/draft/draft-baba-dnsext-acl-reqts-01.txt | 336 - contrib/bind9/doc/draft/draft-daigle-napstr-04.txt | 1232 - .../doc/draft/draft-danisch-dns-rr-smtp-03.txt | 1960 -- .../doc/draft/draft-dnsext-opcode-discover-02.txt | 241 - .../doc/draft/draft-durand-dnsop-dynreverse-00.txt | 240 - .../doc/draft/draft-ietf-dnsext-2929bis-01.txt | 928 - .../draft/draft-ietf-dnsext-axfr-clarify-05.txt | 393 - .../doc/draft/draft-ietf-dnsext-dhcid-rr-12.txt | 674 - .../draft/draft-ietf-dnsext-dns-name-p-s-00.txt | 1397 - ...t-ietf-dnsext-dnssec-2535typecode-change-06.txt | 442 - .../draft-ietf-dnsext-dnssec-bis-updates-01.txt | 616 - .../draft-ietf-dnsext-dnssec-experiments-01.txt | 784 - .../draft-ietf-dnsext-dnssec-online-signing-02.txt | 616 - .../draft/draft-ietf-dnsext-dnssec-opt-in-07.txt | 896 - .../draft-ietf-dnsext-dnssec-rsasha256-00.txt | 392 - .../draft/draft-ietf-dnsext-dnssec-trans-02.txt | 839 - .../doc/draft/draft-ietf-dnsext-ds-sha256-05.txt | 504 - .../doc/draft/draft-ietf-dnsext-ecc-key-07.txt | 928 - .../doc/draft/draft-ietf-dnsext-interop3597-02.txt | 334 - ...draft-ietf-dnsext-keyrr-key-signing-flag-12.txt | 560 - .../bind9/doc/draft/draft-ietf-dnsext-mdns-43.txt | 1740 - .../bind9/doc/draft/draft-ietf-dnsext-nsec3-04.txt | 2352 -- .../bind9/doc/draft/draft-ietf-dnsext-nsid-01.txt | 840 - .../draft/draft-ietf-dnsext-rfc2536bis-dsa-06.txt | 464 - .../doc/draft/draft-ietf-dnsext-rfc2538bis-04.txt | 840 - .../draft/draft-ietf-dnsext-rfc2539bis-dhk-06.txt | 580 - ...-dnsext-signed-nonexistence-requirements-01.txt | 755 - .../draft-ietf-dnsext-tkey-renewal-mode-05.txt | 1292 - .../draft-ietf-dnsext-trustupdate-threshold-00.txt | 1501 - .../draft-ietf-dnsext-trustupdate-timers-02.txt | 730 - .../doc/draft/draft-ietf-dnsext-tsig-sha-06.txt | 522 - .../draft/draft-ietf-dnsext-wcard-clarify-10.txt | 1063 - .../doc/draft/draft-ietf-dnsop-bad-dns-res-05.txt | 1232 - ...-ietf-dnsop-dnssec-operational-practices-08.txt | 2016 -- .../draft/draft-ietf-dnsop-inaddr-required-07.txt | 396 - .../draft-ietf-dnsop-ipv6-dns-configuration-06.txt | 1848 - .../draft/draft-ietf-dnsop-ipv6-dns-issues-11.txt | 1682 - ...aft-ietf-dnsop-ipv6-transport-guidelines-01.txt | 300 - ...aft-ietf-dnsop-key-rollover-requirements-02.txt | 389 - .../doc/draft/draft-ietf-dnsop-respsize-02.txt | 480 - .../doc/draft/draft-ietf-dnsop-serverid-06.txt | 618 - .../doc/draft/draft-ietf-enum-e164-gstn-np-05.txt | 1588 - .../draft/draft-ietf-ipv6-node-requirements-08.txt | 1200 - .../bind9/doc/draft/draft-ietf-secsh-dns-05.txt | 614 - .../draft-ihren-dnsext-threshold-validation-00.txt | 519 - .../doc/draft/draft-kato-dnsop-local-zones-00.txt | 295 - .../draft-park-ipv6-extensions-dns-pnp-00.txt | 1830 - contrib/bind9/doc/draft/update | 46 - contrib/bind9/doc/misc/Makefile.in | 47 - contrib/bind9/doc/misc/dnssec | 84 - contrib/bind9/doc/misc/format-options.pl | 36 - contrib/bind9/doc/misc/ipv6 | 113 - contrib/bind9/doc/misc/migration | 257 - contrib/bind9/doc/misc/migration-4to9 | 57 - contrib/bind9/doc/misc/options | 481 - contrib/bind9/doc/misc/rfc-compliance | 62 - contrib/bind9/doc/misc/roadmap | 47 - contrib/bind9/doc/misc/sdb | 169 - contrib/bind9/doc/rfc/index | 114 - contrib/bind9/doc/rfc/rfc1032.txt | 781 - contrib/bind9/doc/rfc/rfc1033.txt | 1229 - contrib/bind9/doc/rfc/rfc1034.txt | 3077 -- contrib/bind9/doc/rfc/rfc1035.txt | 3077 -- contrib/bind9/doc/rfc/rfc1101.txt | 787 - contrib/bind9/doc/rfc/rfc1122.txt | 6844 ---- contrib/bind9/doc/rfc/rfc1123.txt | 5782 ---- contrib/bind9/doc/rfc/rfc1183.txt | 619 - contrib/bind9/doc/rfc/rfc1348.txt | 227 - contrib/bind9/doc/rfc/rfc1535.txt | 283 - contrib/bind9/doc/rfc/rfc1536.txt | 675 - contrib/bind9/doc/rfc/rfc1537.txt | 507 - contrib/bind9/doc/rfc/rfc1591.txt | 395 - contrib/bind9/doc/rfc/rfc1611.txt | 1683 - contrib/bind9/doc/rfc/rfc1612.txt | 1795 - contrib/bind9/doc/rfc/rfc1706.txt | 563 - contrib/bind9/doc/rfc/rfc1712.txt | 395 - contrib/bind9/doc/rfc/rfc1750.txt | 1683 - contrib/bind9/doc/rfc/rfc1876.txt | 1011 - contrib/bind9/doc/rfc/rfc1886.txt | 268 - contrib/bind9/doc/rfc/rfc1982.txt | 394 - contrib/bind9/doc/rfc/rfc1995.txt | 451 - contrib/bind9/doc/rfc/rfc1996.txt | 395 - contrib/bind9/doc/rfc/rfc2052.txt | 563 - contrib/bind9/doc/rfc/rfc2104.txt | 620 - contrib/bind9/doc/rfc/rfc2119.txt | 171 - contrib/bind9/doc/rfc/rfc2133.txt | 1795 - contrib/bind9/doc/rfc/rfc2136.txt | 1460 - contrib/bind9/doc/rfc/rfc2137.txt | 619 - contrib/bind9/doc/rfc/rfc2163.txt | 1459 - contrib/bind9/doc/rfc/rfc2168.txt | 1123 - contrib/bind9/doc/rfc/rfc2181.txt | 842 - contrib/bind9/doc/rfc/rfc2230.txt | 619 - contrib/bind9/doc/rfc/rfc2308.txt | 1067 - contrib/bind9/doc/rfc/rfc2317.txt | 563 - contrib/bind9/doc/rfc/rfc2373.txt | 1459 - contrib/bind9/doc/rfc/rfc2374.txt | 675 - contrib/bind9/doc/rfc/rfc2375.txt | 451 - contrib/bind9/doc/rfc/rfc2418.txt | 1459 - contrib/bind9/doc/rfc/rfc2535.txt | 2635 -- contrib/bind9/doc/rfc/rfc2536.txt | 339 - contrib/bind9/doc/rfc/rfc2537.txt | 339 - contrib/bind9/doc/rfc/rfc2538.txt | 563 - contrib/bind9/doc/rfc/rfc2539.txt | 395 - contrib/bind9/doc/rfc/rfc2540.txt | 339 - contrib/bind9/doc/rfc/rfc2541.txt | 395 - contrib/bind9/doc/rfc/rfc2553.txt | 2299 -- contrib/bind9/doc/rfc/rfc2671.txt | 395 - contrib/bind9/doc/rfc/rfc2672.txt | 507 - contrib/bind9/doc/rfc/rfc2673.txt | 395 - contrib/bind9/doc/rfc/rfc2782.txt | 675 - contrib/bind9/doc/rfc/rfc2825.txt | 395 - contrib/bind9/doc/rfc/rfc2826.txt | 339 - contrib/bind9/doc/rfc/rfc2845.txt | 843 - contrib/bind9/doc/rfc/rfc2874.txt | 1123 - contrib/bind9/doc/rfc/rfc2915.txt | 1011 - contrib/bind9/doc/rfc/rfc2929.txt | 675 - contrib/bind9/doc/rfc/rfc2930.txt | 899 - contrib/bind9/doc/rfc/rfc2931.txt | 563 - contrib/bind9/doc/rfc/rfc3007.txt | 507 - contrib/bind9/doc/rfc/rfc3008.txt | 395 - contrib/bind9/doc/rfc/rfc3071.txt | 563 - contrib/bind9/doc/rfc/rfc3090.txt | 619 - contrib/bind9/doc/rfc/rfc3110.txt | 395 - contrib/bind9/doc/rfc/rfc3123.txt | 451 - contrib/bind9/doc/rfc/rfc3152.txt | 227 - contrib/bind9/doc/rfc/rfc3197.txt | 283 - contrib/bind9/doc/rfc/rfc3225.txt | 339 - contrib/bind9/doc/rfc/rfc3226.txt | 339 - contrib/bind9/doc/rfc/rfc3258.txt | 619 - contrib/bind9/doc/rfc/rfc3363.txt | 339 - contrib/bind9/doc/rfc/rfc3364.txt | 619 - contrib/bind9/doc/rfc/rfc3425.txt | 283 - contrib/bind9/doc/rfc/rfc3445.txt | 563 - contrib/bind9/doc/rfc/rfc3467.txt | 1739 - contrib/bind9/doc/rfc/rfc3490.txt | 1235 - contrib/bind9/doc/rfc/rfc3491.txt | 395 - contrib/bind9/doc/rfc/rfc3492.txt | 1963 -- contrib/bind9/doc/rfc/rfc3493.txt | 2187 -- contrib/bind9/doc/rfc/rfc3513.txt | 1459 - contrib/bind9/doc/rfc/rfc3596.txt | 451 - contrib/bind9/doc/rfc/rfc3597.txt | 451 - contrib/bind9/doc/rfc/rfc3645.txt | 1459 - contrib/bind9/doc/rfc/rfc3655.txt | 451 - contrib/bind9/doc/rfc/rfc3658.txt | 1067 - contrib/bind9/doc/rfc/rfc3757.txt | 451 - contrib/bind9/doc/rfc/rfc3833.txt | 899 - contrib/bind9/doc/rfc/rfc3845.txt | 395 - contrib/bind9/doc/rfc/rfc3901.txt | 283 - contrib/bind9/doc/rfc/rfc4025.txt | 675 - contrib/bind9/doc/rfc/rfc4033.txt | 1179 - contrib/bind9/doc/rfc/rfc4034.txt | 1627 - contrib/bind9/doc/rfc/rfc4035.txt | 2971 -- contrib/bind9/doc/rfc/rfc4074.txt | 339 - contrib/bind9/doc/rfc/rfc4159.txt | 171 - contrib/bind9/doc/rfc/rfc4193.txt | 899 - contrib/bind9/doc/rfc/rfc4255.txt | 507 - contrib/bind9/doc/rfc/rfc4343.txt | 563 - contrib/bind9/doc/rfc/rfc4367.txt | 955 - contrib/bind9/doc/rfc/rfc4398.txt | 955 - contrib/bind9/doc/rfc/rfc4408.txt | 2691 -- contrib/bind9/doc/rfc/rfc4431.txt | 227 - contrib/bind9/doc/rfc/rfc4470.txt | 451 - contrib/bind9/doc/rfc/rfc4634.txt | 6051 ---- contrib/bind9/doc/rfc/rfc4641.txt | 1963 -- contrib/bind9/doc/rfc/rfc952.txt | 340 - contrib/bind9/install-sh | 250 - contrib/bind9/isc-config.sh.in | 149 - contrib/bind9/lib/Makefile.in | 29 - contrib/bind9/lib/bind/Makefile.in | 133 - contrib/bind9/lib/bind/README | 4 - contrib/bind9/lib/bind/aclocal.m4 | 2 - contrib/bind9/lib/bind/api | 3 - contrib/bind9/lib/bind/bsd/Makefile.in | 39 - contrib/bind9/lib/bind/bsd/daemon.c | 81 - contrib/bind9/lib/bind/bsd/ftruncate.c | 64 - contrib/bind9/lib/bind/bsd/gettimeofday.c | 64 - contrib/bind9/lib/bind/bsd/mktemp.c | 156 - contrib/bind9/lib/bind/bsd/putenv.c | 27 - contrib/bind9/lib/bind/bsd/readv.c | 39 - contrib/bind9/lib/bind/bsd/setenv.c | 151 - contrib/bind9/lib/bind/bsd/setitimer.c | 29 - contrib/bind9/lib/bind/bsd/strcasecmp.c | 124 - contrib/bind9/lib/bind/bsd/strdup.c | 20 - contrib/bind9/lib/bind/bsd/strerror.c | 92 - contrib/bind9/lib/bind/bsd/strpbrk.c | 70 - contrib/bind9/lib/bind/bsd/strsep.c | 88 - contrib/bind9/lib/bind/bsd/strtoul.c | 119 - contrib/bind9/lib/bind/bsd/utimes.c | 40 - contrib/bind9/lib/bind/bsd/writev.c | 89 - contrib/bind9/lib/bind/config.h.in | 61 - contrib/bind9/lib/bind/configure | 33825 ------------------- contrib/bind9/lib/bind/configure.in | 2683 -- contrib/bind9/lib/bind/dst/Makefile.in | 32 - contrib/bind9/lib/bind/dst/dst_api.c | 1048 - contrib/bind9/lib/bind/dst/dst_internal.h | 155 - contrib/bind9/lib/bind/dst/hmac_link.c | 489 - contrib/bind9/lib/bind/dst/md5.h | 108 - contrib/bind9/lib/bind/dst/md5_dgst.c | 374 - contrib/bind9/lib/bind/dst/md5_locl.h | 193 - contrib/bind9/lib/bind/dst/support.c | 342 - contrib/bind9/lib/bind/include/Makefile.in | 47 - contrib/bind9/lib/bind/include/arpa/inet.h | 126 - contrib/bind9/lib/bind/include/arpa/nameser.h | 574 - .../bind9/lib/bind/include/arpa/nameser_compat.h | 232 - contrib/bind9/lib/bind/include/fd_setsize.h | 10 - contrib/bind9/lib/bind/include/hesiod.h | 39 - contrib/bind9/lib/bind/include/irp.h | 107 - contrib/bind9/lib/bind/include/irs.h | 348 - contrib/bind9/lib/bind/include/isc/assertions.h | 122 - contrib/bind9/lib/bind/include/isc/ctl.h | 112 - contrib/bind9/lib/bind/include/isc/dst.h | 168 - contrib/bind9/lib/bind/include/isc/eventlib.h | 204 - contrib/bind9/lib/bind/include/isc/heap.h | 49 - contrib/bind9/lib/bind/include/isc/irpmarshall.h | 112 - contrib/bind9/lib/bind/include/isc/list.h | 117 - contrib/bind9/lib/bind/include/isc/logging.h | 113 - contrib/bind9/lib/bind/include/isc/memcluster.h | 50 - contrib/bind9/lib/bind/include/isc/misc.h | 43 - contrib/bind9/lib/bind/include/isc/tree.h | 59 - contrib/bind9/lib/bind/include/netdb.h | 582 - contrib/bind9/lib/bind/include/netgroup.h | 26 - contrib/bind9/lib/bind/include/res_update.h | 69 - contrib/bind9/lib/bind/include/resolv.h | 505 - contrib/bind9/lib/bind/include/resolv_mt.h | 47 - contrib/bind9/lib/bind/inet/Makefile.in | 35 - contrib/bind9/lib/bind/inet/inet_addr.c | 208 - contrib/bind9/lib/bind/inet/inet_cidr_ntop.c | 263 - contrib/bind9/lib/bind/inet/inet_cidr_pton.c | 277 - contrib/bind9/lib/bind/inet/inet_data.c | 46 - contrib/bind9/lib/bind/inet/inet_lnaof.c | 65 - contrib/bind9/lib/bind/inet/inet_makeaddr.c | 68 - contrib/bind9/lib/bind/inet/inet_net_ntop.c | 279 - contrib/bind9/lib/bind/inet/inet_net_pton.c | 407 - contrib/bind9/lib/bind/inet/inet_neta.c | 89 - contrib/bind9/lib/bind/inet/inet_netof.c | 64 - contrib/bind9/lib/bind/inet/inet_network.c | 106 - contrib/bind9/lib/bind/inet/inet_ntoa.c | 64 - contrib/bind9/lib/bind/inet/inet_ntop.c | 207 - contrib/bind9/lib/bind/inet/inet_pton.c | 223 - contrib/bind9/lib/bind/inet/nsap_addr.c | 111 - contrib/bind9/lib/bind/irs/Makefile.in | 70 - contrib/bind9/lib/bind/irs/dns.c | 154 - contrib/bind9/lib/bind/irs/dns_gr.c | 294 - contrib/bind9/lib/bind/irs/dns_ho.c | 1142 - contrib/bind9/lib/bind/irs/dns_nw.c | 591 - contrib/bind9/lib/bind/irs/dns_p.h | 52 - contrib/bind9/lib/bind/irs/dns_pr.c | 268 - contrib/bind9/lib/bind/irs/dns_pw.c | 232 - contrib/bind9/lib/bind/irs/dns_sv.c | 300 - contrib/bind9/lib/bind/irs/gai_strerror.c | 105 - contrib/bind9/lib/bind/irs/gen.c | 433 - contrib/bind9/lib/bind/irs/gen_gr.c | 493 - contrib/bind9/lib/bind/irs/gen_ho.c | 391 - contrib/bind9/lib/bind/irs/gen_ng.c | 174 - contrib/bind9/lib/bind/irs/gen_nw.c | 264 - contrib/bind9/lib/bind/irs/gen_p.h | 113 - contrib/bind9/lib/bind/irs/gen_pr.c | 228 - contrib/bind9/lib/bind/irs/gen_pw.c | 234 - contrib/bind9/lib/bind/irs/gen_sv.c | 229 - contrib/bind9/lib/bind/irs/getaddrinfo.c | 1253 - contrib/bind9/lib/bind/irs/getgrent.c | 224 - contrib/bind9/lib/bind/irs/getgrent_r.c | 230 - contrib/bind9/lib/bind/irs/gethostent.c | 1070 - contrib/bind9/lib/bind/irs/gethostent_r.c | 275 - contrib/bind9/lib/bind/irs/getnameinfo.c | 334 - contrib/bind9/lib/bind/irs/getnetent.c | 345 - contrib/bind9/lib/bind/irs/getnetent_r.c | 234 - contrib/bind9/lib/bind/irs/getnetgrent.c | 158 - contrib/bind9/lib/bind/irs/getnetgrent_r.c | 178 - contrib/bind9/lib/bind/irs/getprotoent.c | 176 - contrib/bind9/lib/bind/irs/getprotoent_r.c | 223 - contrib/bind9/lib/bind/irs/getpwent.c | 201 - contrib/bind9/lib/bind/irs/getpwent_r.c | 276 - contrib/bind9/lib/bind/irs/getservent.c | 179 - contrib/bind9/lib/bind/irs/getservent_r.c | 242 - contrib/bind9/lib/bind/irs/hesiod.c | 505 - contrib/bind9/lib/bind/irs/hesiod_p.h | 48 - contrib/bind9/lib/bind/irs/irp.c | 582 - contrib/bind9/lib/bind/irs/irp_gr.c | 357 - contrib/bind9/lib/bind/irs/irp_ho.c | 405 - contrib/bind9/lib/bind/irs/irp_ng.c | 253 - contrib/bind9/lib/bind/irs/irp_nw.c | 348 - contrib/bind9/lib/bind/irs/irp_p.h | 60 - contrib/bind9/lib/bind/irs/irp_pr.c | 327 - contrib/bind9/lib/bind/irs/irp_pw.c | 340 - contrib/bind9/lib/bind/irs/irp_sv.c | 346 - contrib/bind9/lib/bind/irs/irpmarshall.c | 2301 -- contrib/bind9/lib/bind/irs/irs_data.c | 246 - contrib/bind9/lib/bind/irs/irs_data.h | 63 - contrib/bind9/lib/bind/irs/irs_p.h | 51 - contrib/bind9/lib/bind/irs/lcl.c | 142 - contrib/bind9/lib/bind/irs/lcl_gr.c | 354 - contrib/bind9/lib/bind/irs/lcl_ho.c | 578 - contrib/bind9/lib/bind/irs/lcl_ng.c | 446 - contrib/bind9/lib/bind/irs/lcl_nw.c | 373 - contrib/bind9/lib/bind/irs/lcl_p.h | 51 - contrib/bind9/lib/bind/irs/lcl_pr.c | 294 - contrib/bind9/lib/bind/irs/lcl_pw.c | 309 - contrib/bind9/lib/bind/irs/lcl_sv.c | 432 - contrib/bind9/lib/bind/irs/nis.c | 156 - contrib/bind9/lib/bind/irs/nis_gr.c | 354 - contrib/bind9/lib/bind/irs/nis_ho.c | 535 - contrib/bind9/lib/bind/irs/nis_ng.c | 304 - contrib/bind9/lib/bind/irs/nis_nw.c | 385 - contrib/bind9/lib/bind/irs/nis_p.h | 47 - contrib/bind9/lib/bind/irs/nis_pr.c | 302 - contrib/bind9/lib/bind/irs/nis_pw.c | 288 - contrib/bind9/lib/bind/irs/nis_sv.c | 310 - contrib/bind9/lib/bind/irs/nul_ng.c | 127 - contrib/bind9/lib/bind/irs/pathnames.h | 52 - contrib/bind9/lib/bind/irs/util.c | 109 - contrib/bind9/lib/bind/isc/Makefile.in | 35 - contrib/bind9/lib/bind/isc/assertions.c | 93 - contrib/bind9/lib/bind/isc/assertions.mdoc | 138 - contrib/bind9/lib/bind/isc/base64.c | 322 - contrib/bind9/lib/bind/isc/bitncmp.c | 68 - contrib/bind9/lib/bind/isc/bitncmp.mdoc | 82 - contrib/bind9/lib/bind/isc/ctl_clnt.c | 617 - contrib/bind9/lib/bind/isc/ctl_p.c | 188 - contrib/bind9/lib/bind/isc/ctl_p.h | 28 - contrib/bind9/lib/bind/isc/ctl_srvr.c | 784 - contrib/bind9/lib/bind/isc/ev_connects.c | 369 - contrib/bind9/lib/bind/isc/ev_files.c | 277 - contrib/bind9/lib/bind/isc/ev_streams.c | 308 - contrib/bind9/lib/bind/isc/ev_timers.c | 499 - contrib/bind9/lib/bind/isc/ev_waits.c | 247 - contrib/bind9/lib/bind/isc/eventlib.c | 933 - contrib/bind9/lib/bind/isc/eventlib.mdoc | 918 - contrib/bind9/lib/bind/isc/eventlib_p.h | 281 - contrib/bind9/lib/bind/isc/heap.c | 236 - contrib/bind9/lib/bind/isc/heap.mdoc | 378 - contrib/bind9/lib/bind/isc/hex.c | 119 - contrib/bind9/lib/bind/isc/logging.c | 722 - contrib/bind9/lib/bind/isc/logging.mdoc | 1056 - contrib/bind9/lib/bind/isc/logging_p.h | 61 - contrib/bind9/lib/bind/isc/memcluster.c | 588 - contrib/bind9/lib/bind/isc/memcluster.mdoc | 376 - contrib/bind9/lib/bind/isc/movefile.c | 37 - contrib/bind9/lib/bind/isc/tree.c | 534 - contrib/bind9/lib/bind/isc/tree.mdoc | 154 - contrib/bind9/lib/bind/make/includes.in | 44 - contrib/bind9/lib/bind/make/mkdep.in | 147 - contrib/bind9/lib/bind/make/rules.in | 177 - contrib/bind9/lib/bind/mkinstalldirs | 40 - contrib/bind9/lib/bind/nameser/Makefile.in | 31 - contrib/bind9/lib/bind/nameser/ns_date.c | 129 - contrib/bind9/lib/bind/nameser/ns_name.c | 973 - contrib/bind9/lib/bind/nameser/ns_netint.c | 58 - contrib/bind9/lib/bind/nameser/ns_parse.c | 211 - contrib/bind9/lib/bind/nameser/ns_print.c | 897 - contrib/bind9/lib/bind/nameser/ns_samedomain.c | 207 - contrib/bind9/lib/bind/nameser/ns_sign.c | 387 - contrib/bind9/lib/bind/nameser/ns_ttl.c | 162 - contrib/bind9/lib/bind/nameser/ns_verify.c | 484 - contrib/bind9/lib/bind/port/Makefile.in | 14 - contrib/bind9/lib/bind/port/freebsd/Makefile.in | 14 - .../lib/bind/port/freebsd/include/Makefile.in | 34 - .../lib/bind/port/freebsd/include/sys/bitypes.h | 37 - contrib/bind9/lib/bind/port_after.h.in | 415 - contrib/bind9/lib/bind/port_before.h.in | 162 - contrib/bind9/lib/bind/resolv/Makefile.in | 34 - contrib/bind9/lib/bind/resolv/herror.c | 129 - contrib/bind9/lib/bind/resolv/mtctxres.c | 129 - contrib/bind9/lib/bind/resolv/res_comp.c | 265 - contrib/bind9/lib/bind/resolv/res_data.c | 297 - contrib/bind9/lib/bind/resolv/res_debug.c | 1165 - contrib/bind9/lib/bind/resolv/res_debug.h | 35 - contrib/bind9/lib/bind/resolv/res_findzonecut.c | 722 - contrib/bind9/lib/bind/resolv/res_init.c | 801 - contrib/bind9/lib/bind/resolv/res_mkquery.c | 257 - contrib/bind9/lib/bind/resolv/res_mkupdate.c | 1162 - contrib/bind9/lib/bind/resolv/res_mkupdate.h | 25 - contrib/bind9/lib/bind/resolv/res_private.h | 22 - contrib/bind9/lib/bind/resolv/res_query.c | 432 - contrib/bind9/lib/bind/resolv/res_send.c | 1094 - contrib/bind9/lib/bind/resolv/res_sendsigned.c | 170 - contrib/bind9/lib/bind/resolv/res_update.c | 213 - contrib/bind9/lib/bind9/Makefile.in | 84 - contrib/bind9/lib/bind9/api | 3 - contrib/bind9/lib/bind9/check.c | 2043 -- contrib/bind9/lib/bind9/getaddresses.c | 231 - contrib/bind9/lib/bind9/include/Makefile.in | 25 - contrib/bind9/lib/bind9/include/bind9/Makefile.in | 42 - contrib/bind9/lib/bind9/include/bind9/check.h | 57 - .../bind9/lib/bind9/include/bind9/getaddresses.h | 61 - contrib/bind9/lib/bind9/include/bind9/version.h | 28 - contrib/bind9/lib/bind9/version.c | 28 - contrib/bind9/lib/dns/Makefile.in | 171 - contrib/bind9/lib/dns/acache.c | 1778 - contrib/bind9/lib/dns/acl.c | 452 - contrib/bind9/lib/dns/adb.c | 3610 -- contrib/bind9/lib/dns/api | 3 - contrib/bind9/lib/dns/byaddr.c | 316 - contrib/bind9/lib/dns/cache.c | 1154 - contrib/bind9/lib/dns/callbacks.c | 113 - contrib/bind9/lib/dns/compress.c | 341 - contrib/bind9/lib/dns/db.c | 821 - contrib/bind9/lib/dns/dbiterator.c | 143 - contrib/bind9/lib/dns/dbtable.c | 291 - contrib/bind9/lib/dns/diff.c | 554 - contrib/bind9/lib/dns/dispatch.c | 2674 -- contrib/bind9/lib/dns/dlz.c | 510 - contrib/bind9/lib/dns/dnssec.c | 865 - contrib/bind9/lib/dns/ds.c | 104 - contrib/bind9/lib/dns/dst_api.c | 1221 - contrib/bind9/lib/dns/dst_internal.h | 142 - contrib/bind9/lib/dns/dst_lib.c | 67 - contrib/bind9/lib/dns/dst_openssl.h | 34 - contrib/bind9/lib/dns/dst_parse.c | 493 - contrib/bind9/lib/dns/dst_parse.h | 118 - contrib/bind9/lib/dns/dst_result.c | 88 - contrib/bind9/lib/dns/forward.c | 199 - contrib/bind9/lib/dns/gen-unix.h | 97 - contrib/bind9/lib/dns/gen.c | 884 - contrib/bind9/lib/dns/gssapi_link.c | 222 - contrib/bind9/lib/dns/gssapictx.c | 264 - contrib/bind9/lib/dns/hmac_link.c | 1668 - contrib/bind9/lib/dns/include/Makefile.in | 25 - contrib/bind9/lib/dns/include/dns/Makefile.in | 54 - contrib/bind9/lib/dns/include/dns/acache.h | 445 - contrib/bind9/lib/dns/include/dns/acl.h | 222 - contrib/bind9/lib/dns/include/dns/adb.h | 635 - contrib/bind9/lib/dns/include/dns/bit.h | 39 - contrib/bind9/lib/dns/include/dns/byaddr.h | 171 - contrib/bind9/lib/dns/include/dns/cache.h | 253 - contrib/bind9/lib/dns/include/dns/callbacks.h | 87 - contrib/bind9/lib/dns/include/dns/cert.h | 69 - contrib/bind9/lib/dns/include/dns/compress.h | 269 - contrib/bind9/lib/dns/include/dns/db.h | 1299 - contrib/bind9/lib/dns/include/dns/dbiterator.h | 297 - contrib/bind9/lib/dns/include/dns/dbtable.h | 165 - contrib/bind9/lib/dns/include/dns/diff.h | 280 - contrib/bind9/lib/dns/include/dns/dispatch.h | 453 - contrib/bind9/lib/dns/include/dns/dlz.h | 290 - contrib/bind9/lib/dns/include/dns/dnssec.h | 183 - contrib/bind9/lib/dns/include/dns/ds.h | 63 - contrib/bind9/lib/dns/include/dns/events.h | 75 - contrib/bind9/lib/dns/include/dns/fixedname.h | 86 - contrib/bind9/lib/dns/include/dns/forward.h | 118 - contrib/bind9/lib/dns/include/dns/journal.h | 276 - contrib/bind9/lib/dns/include/dns/keyflags.h | 54 - contrib/bind9/lib/dns/include/dns/keytable.h | 255 - contrib/bind9/lib/dns/include/dns/keyvalues.h | 98 - contrib/bind9/lib/dns/include/dns/lib.h | 45 - contrib/bind9/lib/dns/include/dns/log.h | 106 - contrib/bind9/lib/dns/include/dns/lookup.h | 137 - contrib/bind9/lib/dns/include/dns/master.h | 277 - contrib/bind9/lib/dns/include/dns/masterdump.h | 334 - contrib/bind9/lib/dns/include/dns/message.h | 1339 - contrib/bind9/lib/dns/include/dns/name.h | 1296 - contrib/bind9/lib/dns/include/dns/ncache.h | 159 - contrib/bind9/lib/dns/include/dns/nsec.h | 69 - contrib/bind9/lib/dns/include/dns/opcode.h | 51 - contrib/bind9/lib/dns/include/dns/order.h | 99 - contrib/bind9/lib/dns/include/dns/peer.h | 212 - contrib/bind9/lib/dns/include/dns/portlist.h | 101 - contrib/bind9/lib/dns/include/dns/rbt.h | 916 - contrib/bind9/lib/dns/include/dns/rcode.h | 98 - contrib/bind9/lib/dns/include/dns/rdata.h | 701 - contrib/bind9/lib/dns/include/dns/rdataclass.h | 81 - contrib/bind9/lib/dns/include/dns/rdatalist.h | 103 - contrib/bind9/lib/dns/include/dns/rdataset.h | 597 - contrib/bind9/lib/dns/include/dns/rdatasetiter.h | 170 - contrib/bind9/lib/dns/include/dns/rdataslab.h | 163 - contrib/bind9/lib/dns/include/dns/rdatatype.h | 83 - contrib/bind9/lib/dns/include/dns/request.h | 374 - contrib/bind9/lib/dns/include/dns/resolver.h | 479 - contrib/bind9/lib/dns/include/dns/result.h | 190 - contrib/bind9/lib/dns/include/dns/rootns.h | 45 - contrib/bind9/lib/dns/include/dns/sdb.h | 209 - contrib/bind9/lib/dns/include/dns/sdlz.h | 266 - contrib/bind9/lib/dns/include/dns/secalg.h | 71 - contrib/bind9/lib/dns/include/dns/secproto.h | 71 - contrib/bind9/lib/dns/include/dns/soa.h | 81 - contrib/bind9/lib/dns/include/dns/ssu.h | 165 - contrib/bind9/lib/dns/include/dns/stats.h | 61 - contrib/bind9/lib/dns/include/dns/tcpmsg.h | 147 - contrib/bind9/lib/dns/include/dns/time.h | 72 - contrib/bind9/lib/dns/include/dns/timer.h | 52 - contrib/bind9/lib/dns/include/dns/tkey.h | 198 - contrib/bind9/lib/dns/include/dns/tsig.h | 254 - contrib/bind9/lib/dns/include/dns/ttl.h | 78 - contrib/bind9/lib/dns/include/dns/types.h | 328 - contrib/bind9/lib/dns/include/dns/validator.h | 247 - contrib/bind9/lib/dns/include/dns/version.h | 28 - contrib/bind9/lib/dns/include/dns/view.h | 804 - contrib/bind9/lib/dns/include/dns/xfrin.h | 111 - contrib/bind9/lib/dns/include/dns/zone.h | 1586 - contrib/bind9/lib/dns/include/dns/zonekey.h | 42 - contrib/bind9/lib/dns/include/dns/zt.h | 183 - contrib/bind9/lib/dns/include/dst/Makefile.in | 37 - contrib/bind9/lib/dns/include/dst/dst.h | 620 - contrib/bind9/lib/dns/include/dst/gssapi.h | 58 - contrib/bind9/lib/dns/include/dst/lib.h | 41 - contrib/bind9/lib/dns/include/dst/result.h | 70 - contrib/bind9/lib/dns/journal.c | 2182 -- contrib/bind9/lib/dns/key.c | 147 - contrib/bind9/lib/dns/keytable.c | 395 - contrib/bind9/lib/dns/lib.c | 65 - contrib/bind9/lib/dns/log.c | 97 - contrib/bind9/lib/dns/lookup.c | 497 - contrib/bind9/lib/dns/master.c | 2833 -- contrib/bind9/lib/dns/masterdump.c | 1738 - contrib/bind9/lib/dns/message.c | 3265 -- contrib/bind9/lib/dns/name.c | 2406 -- contrib/bind9/lib/dns/ncache.c | 559 - contrib/bind9/lib/dns/nsec.c | 220 - contrib/bind9/lib/dns/openssl_link.c | 261 - contrib/bind9/lib/dns/openssldh_link.c | 626 - contrib/bind9/lib/dns/openssldsa_link.c | 462 - contrib/bind9/lib/dns/opensslrsa_link.c | 629 - contrib/bind9/lib/dns/order.c | 167 - contrib/bind9/lib/dns/peer.c | 685 - contrib/bind9/lib/dns/portlist.c | 266 - contrib/bind9/lib/dns/rbt.c | 2544 -- contrib/bind9/lib/dns/rbtdb.c | 6760 ---- contrib/bind9/lib/dns/rbtdb.h | 44 - contrib/bind9/lib/dns/rbtdb64.c | 23 - contrib/bind9/lib/dns/rbtdb64.h | 45 - contrib/bind9/lib/dns/rcode.c | 474 - contrib/bind9/lib/dns/rdata.c | 1746 - contrib/bind9/lib/dns/rdata/any_255/tsig_250.c | 597 - contrib/bind9/lib/dns/rdata/any_255/tsig_250.h | 38 - contrib/bind9/lib/dns/rdata/ch_3/a_1.c | 316 - contrib/bind9/lib/dns/rdata/ch_3/a_1.h | 34 - contrib/bind9/lib/dns/rdata/generic/afsdb_18.c | 309 - contrib/bind9/lib/dns/rdata/generic/afsdb_18.h | 34 - contrib/bind9/lib/dns/rdata/generic/cert_37.c | 280 - contrib/bind9/lib/dns/rdata/generic/cert_37.h | 34 - contrib/bind9/lib/dns/rdata/generic/cname_5.c | 232 - contrib/bind9/lib/dns/rdata/generic/cname_5.h | 29 - contrib/bind9/lib/dns/rdata/generic/dlv_32769.c | 321 - contrib/bind9/lib/dns/rdata/generic/dlv_32769.h | 33 - contrib/bind9/lib/dns/rdata/generic/dname_39.c | 233 - contrib/bind9/lib/dns/rdata/generic/dname_39.h | 32 - contrib/bind9/lib/dns/rdata/generic/dnskey_48.c | 312 - contrib/bind9/lib/dns/rdata/generic/dnskey_48.h | 37 - contrib/bind9/lib/dns/rdata/generic/ds_43.c | 321 - contrib/bind9/lib/dns/rdata/generic/ds_43.h | 35 - contrib/bind9/lib/dns/rdata/generic/gpos_27.c | 252 - contrib/bind9/lib/dns/rdata/generic/gpos_27.h | 37 - contrib/bind9/lib/dns/rdata/generic/hinfo_13.c | 224 - contrib/bind9/lib/dns/rdata/generic/hinfo_13.h | 32 - contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c | 462 - contrib/bind9/lib/dns/rdata/generic/ipseckey_45.h | 35 - contrib/bind9/lib/dns/rdata/generic/isdn_20.c | 234 - contrib/bind9/lib/dns/rdata/generic/isdn_20.h | 35 - contrib/bind9/lib/dns/rdata/generic/key_25.c | 312 - contrib/bind9/lib/dns/rdata/generic/key_25.h | 37 - contrib/bind9/lib/dns/rdata/generic/loc_29.c | 794 - contrib/bind9/lib/dns/rdata/generic/loc_29.h | 43 - contrib/bind9/lib/dns/rdata/generic/mb_7.c | 234 - contrib/bind9/lib/dns/rdata/generic/mb_7.h | 30 - contrib/bind9/lib/dns/rdata/generic/md_3.c | 236 - contrib/bind9/lib/dns/rdata/generic/md_3.h | 31 - contrib/bind9/lib/dns/rdata/generic/mf_4.c | 235 - contrib/bind9/lib/dns/rdata/generic/mf_4.h | 30 - contrib/bind9/lib/dns/rdata/generic/mg_8.c | 230 - contrib/bind9/lib/dns/rdata/generic/mg_8.h | 30 - contrib/bind9/lib/dns/rdata/generic/minfo_14.c | 324 - contrib/bind9/lib/dns/rdata/generic/minfo_14.h | 31 - contrib/bind9/lib/dns/rdata/generic/mr_9.c | 231 - contrib/bind9/lib/dns/rdata/generic/mr_9.h | 30 - contrib/bind9/lib/dns/rdata/generic/mx_15.c | 319 - contrib/bind9/lib/dns/rdata/generic/mx_15.h | 31 - contrib/bind9/lib/dns/rdata/generic/ns_2.c | 251 - contrib/bind9/lib/dns/rdata/generic/ns_2.h | 31 - contrib/bind9/lib/dns/rdata/generic/nsec_47.c | 366 - contrib/bind9/lib/dns/rdata/generic/nsec_47.h | 34 - contrib/bind9/lib/dns/rdata/generic/null_10.c | 192 - contrib/bind9/lib/dns/rdata/generic/null_10.h | 32 - contrib/bind9/lib/dns/rdata/generic/nxt_30.c | 329 - contrib/bind9/lib/dns/rdata/generic/nxt_30.h | 34 - contrib/bind9/lib/dns/rdata/generic/opt_41.c | 280 - contrib/bind9/lib/dns/rdata/generic/opt_41.h | 55 - contrib/bind9/lib/dns/rdata/generic/proforma.c | 173 - contrib/bind9/lib/dns/rdata/generic/proforma.h | 30 - contrib/bind9/lib/dns/rdata/generic/ptr_12.c | 291 - contrib/bind9/lib/dns/rdata/generic/ptr_12.h | 30 - contrib/bind9/lib/dns/rdata/generic/rp_17.c | 314 - contrib/bind9/lib/dns/rdata/generic/rp_17.h | 34 - contrib/bind9/lib/dns/rdata/generic/rrsig_46.c | 551 - contrib/bind9/lib/dns/rdata/generic/rrsig_46.h | 41 - contrib/bind9/lib/dns/rdata/generic/rt_21.c | 311 - contrib/bind9/lib/dns/rdata/generic/rt_21.h | 33 - contrib/bind9/lib/dns/rdata/generic/sig_24.c | 578 - contrib/bind9/lib/dns/rdata/generic/sig_24.h | 42 - contrib/bind9/lib/dns/rdata/generic/soa_6.c | 443 - contrib/bind9/lib/dns/rdata/generic/soa_6.h | 37 - contrib/bind9/lib/dns/rdata/generic/spf_99.c | 238 - contrib/bind9/lib/dns/rdata/generic/spf_99.h | 51 - contrib/bind9/lib/dns/rdata/generic/sshfp_44.c | 262 - contrib/bind9/lib/dns/rdata/generic/sshfp_44.h | 35 - contrib/bind9/lib/dns/rdata/generic/tkey_249.c | 555 - contrib/bind9/lib/dns/rdata/generic/tkey_249.h | 41 - contrib/bind9/lib/dns/rdata/generic/txt_16.c | 238 - contrib/bind9/lib/dns/rdata/generic/txt_16.h | 52 - contrib/bind9/lib/dns/rdata/generic/unspec_103.c | 189 - contrib/bind9/lib/dns/rdata/generic/unspec_103.h | 31 - contrib/bind9/lib/dns/rdata/generic/x25_19.c | 219 - contrib/bind9/lib/dns/rdata/generic/x25_19.h | 33 - contrib/bind9/lib/dns/rdata/hs_4/a_1.c | 232 - contrib/bind9/lib/dns/rdata/hs_4/a_1.h | 29 - contrib/bind9/lib/dns/rdata/in_1/a6_38.c | 461 - contrib/bind9/lib/dns/rdata/in_1/a6_38.h | 34 - contrib/bind9/lib/dns/rdata/in_1/a_1.c | 236 - contrib/bind9/lib/dns/rdata/in_1/a_1.h | 29 - contrib/bind9/lib/dns/rdata/in_1/aaaa_28.c | 233 - contrib/bind9/lib/dns/rdata/in_1/aaaa_28.h | 31 - contrib/bind9/lib/dns/rdata/in_1/apl_42.c | 402 - contrib/bind9/lib/dns/rdata/in_1/apl_42.h | 56 - contrib/bind9/lib/dns/rdata/in_1/kx_36.c | 288 - contrib/bind9/lib/dns/rdata/in_1/kx_36.h | 33 - contrib/bind9/lib/dns/rdata/in_1/naptr_35.c | 578 - contrib/bind9/lib/dns/rdata/in_1/naptr_35.h | 40 - contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.c | 245 - contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.h | 32 - contrib/bind9/lib/dns/rdata/in_1/nsap_22.c | 255 - contrib/bind9/lib/dns/rdata/in_1/nsap_22.h | 33 - contrib/bind9/lib/dns/rdata/in_1/px_26.c | 374 - contrib/bind9/lib/dns/rdata/in_1/px_26.h | 34 - contrib/bind9/lib/dns/rdata/in_1/srv_33.c | 373 - contrib/bind9/lib/dns/rdata/in_1/srv_33.h | 37 - contrib/bind9/lib/dns/rdata/in_1/wks_11.c | 349 - contrib/bind9/lib/dns/rdata/in_1/wks_11.h | 32 - contrib/bind9/lib/dns/rdata/rdatastructpre.h | 42 - contrib/bind9/lib/dns/rdata/rdatastructsuf.h | 22 - contrib/bind9/lib/dns/rdatalist.c | 229 - contrib/bind9/lib/dns/rdatalist_p.h | 57 - contrib/bind9/lib/dns/rdataset.c | 709 - contrib/bind9/lib/dns/rdatasetiter.c | 80 - contrib/bind9/lib/dns/rdataslab.c | 1045 - contrib/bind9/lib/dns/request.c | 1461 - contrib/bind9/lib/dns/resolver.c | 7181 ---- contrib/bind9/lib/dns/result.c | 276 - contrib/bind9/lib/dns/rootns.c | 514 - contrib/bind9/lib/dns/sdb.c | 1538 - contrib/bind9/lib/dns/sdlz.c | 1786 - contrib/bind9/lib/dns/soa.c | 111 - contrib/bind9/lib/dns/ssu.c | 366 - contrib/bind9/lib/dns/stats.c | 57 - contrib/bind9/lib/dns/tcpmsg.c | 243 - contrib/bind9/lib/dns/time.c | 174 - contrib/bind9/lib/dns/timer.c | 60 - contrib/bind9/lib/dns/tkey.c | 1242 - contrib/bind9/lib/dns/tsig.c | 1464 - contrib/bind9/lib/dns/ttl.c | 216 - contrib/bind9/lib/dns/validator.c | 3078 -- contrib/bind9/lib/dns/version.c | 28 - contrib/bind9/lib/dns/view.c | 1367 - contrib/bind9/lib/dns/xfrin.c | 1470 - contrib/bind9/lib/dns/zone.c | 8043 ----- contrib/bind9/lib/dns/zonekey.c | 55 - contrib/bind9/lib/dns/zt.c | 410 - contrib/bind9/lib/isc/Makefile.in | 112 - contrib/bind9/lib/isc/alpha/Makefile.in | 24 - contrib/bind9/lib/isc/alpha/include/Makefile.in | 24 - .../bind9/lib/isc/alpha/include/isc/Makefile.in | 36 - contrib/bind9/lib/isc/alpha/include/isc/atomic.h | 170 - contrib/bind9/lib/isc/api | 3 - contrib/bind9/lib/isc/arm/include/isc/atomic.h | 81 - contrib/bind9/lib/isc/assertions.c | 96 - contrib/bind9/lib/isc/base64.c | 250 - contrib/bind9/lib/isc/bitstring.c | 127 - contrib/bind9/lib/isc/buffer.c | 413 - contrib/bind9/lib/isc/bufferlist.c | 64 - contrib/bind9/lib/isc/commandline.c | 222 - contrib/bind9/lib/isc/entropy.c | 1263 - contrib/bind9/lib/isc/error.c | 106 - contrib/bind9/lib/isc/event.c | 88 - contrib/bind9/lib/isc/fsaccess.c | 102 - contrib/bind9/lib/isc/hash.c | 390 - contrib/bind9/lib/isc/heap.c | 256 - contrib/bind9/lib/isc/hex.c | 201 - contrib/bind9/lib/isc/hmacmd5.c | 118 - contrib/bind9/lib/isc/hmacsha.c | 438 - contrib/bind9/lib/isc/ia64/Makefile.in | 24 - contrib/bind9/lib/isc/ia64/include/Makefile.in | 24 - contrib/bind9/lib/isc/ia64/include/isc/Makefile.in | 36 - contrib/bind9/lib/isc/ia64/include/isc/atomic.h | 88 - contrib/bind9/lib/isc/include/Makefile.in | 25 - contrib/bind9/lib/isc/include/isc/Makefile.in | 57 - contrib/bind9/lib/isc/include/isc/app.h | 212 - contrib/bind9/lib/isc/include/isc/assertions.h | 123 - contrib/bind9/lib/isc/include/isc/base64.h | 99 - contrib/bind9/lib/isc/include/isc/bitstring.h | 157 - contrib/bind9/lib/isc/include/isc/boolean.h | 31 - contrib/bind9/lib/isc/include/isc/buffer.h | 811 - contrib/bind9/lib/isc/include/isc/bufferlist.h | 86 - contrib/bind9/lib/isc/include/isc/commandline.h | 50 - contrib/bind9/lib/isc/include/isc/entropy.h | 307 - contrib/bind9/lib/isc/include/isc/error.h | 62 - contrib/bind9/lib/isc/include/isc/event.h | 121 - contrib/bind9/lib/isc/include/isc/eventclass.h | 53 - contrib/bind9/lib/isc/include/isc/file.h | 256 - contrib/bind9/lib/isc/include/isc/formatcheck.h | 40 - contrib/bind9/lib/isc/include/isc/fsaccess.h | 177 - contrib/bind9/lib/isc/include/isc/hash.h | 185 - contrib/bind9/lib/isc/include/isc/heap.h | 170 - contrib/bind9/lib/isc/include/isc/hex.h | 98 - contrib/bind9/lib/isc/include/isc/hmacmd5.h | 63 - contrib/bind9/lib/isc/include/isc/hmacsha.h | 156 - contrib/bind9/lib/isc/include/isc/interfaceiter.h | 133 - contrib/bind9/lib/isc/include/isc/ipv6.h | 148 - contrib/bind9/lib/isc/include/isc/lang.h | 33 - contrib/bind9/lib/isc/include/isc/lex.h | 431 - contrib/bind9/lib/isc/include/isc/lfsr.h | 130 - contrib/bind9/lib/isc/include/isc/lib.h | 41 - contrib/bind9/lib/isc/include/isc/list.h | 184 - contrib/bind9/lib/isc/include/isc/log.h | 913 - contrib/bind9/lib/isc/include/isc/magic.h | 41 - contrib/bind9/lib/isc/include/isc/md5.h | 73 - contrib/bind9/lib/isc/include/isc/mem.h | 543 - contrib/bind9/lib/isc/include/isc/msgcat.h | 131 - contrib/bind9/lib/isc/include/isc/msgs.h | 191 - contrib/bind9/lib/isc/include/isc/mutexblock.h | 71 - contrib/bind9/lib/isc/include/isc/netaddr.h | 175 - contrib/bind9/lib/isc/include/isc/netscope.h | 43 - contrib/bind9/lib/isc/include/isc/ondestroy.h | 116 - contrib/bind9/lib/isc/include/isc/os.h | 38 - contrib/bind9/lib/isc/include/isc/parseint.h | 64 - contrib/bind9/lib/isc/include/isc/platform.h.in | 306 - contrib/bind9/lib/isc/include/isc/print.h | 87 - contrib/bind9/lib/isc/include/isc/quota.h | 119 - contrib/bind9/lib/isc/include/isc/random.h | 62 - contrib/bind9/lib/isc/include/isc/ratelimiter.h | 134 - contrib/bind9/lib/isc/include/isc/refcount.h | 233 - contrib/bind9/lib/isc/include/isc/region.h | 99 - contrib/bind9/lib/isc/include/isc/resource.h | 87 - contrib/bind9/lib/isc/include/isc/result.h | 104 - contrib/bind9/lib/isc/include/isc/resultclass.h | 50 - contrib/bind9/lib/isc/include/isc/rwlock.h | 135 - contrib/bind9/lib/isc/include/isc/serial.h | 75 - contrib/bind9/lib/isc/include/isc/sha1.h | 59 - contrib/bind9/lib/isc/include/isc/sha2.h | 132 - contrib/bind9/lib/isc/include/isc/sockaddr.h | 240 - contrib/bind9/lib/isc/include/isc/socket.h | 752 - contrib/bind9/lib/isc/include/isc/stdio.h | 77 - contrib/bind9/lib/isc/include/isc/stdlib.h | 40 - contrib/bind9/lib/isc/include/isc/string.h | 231 - contrib/bind9/lib/isc/include/isc/symtab.h | 131 - contrib/bind9/lib/isc/include/isc/task.h | 616 - contrib/bind9/lib/isc/include/isc/taskpool.h | 105 - contrib/bind9/lib/isc/include/isc/timer.h | 342 - contrib/bind9/lib/isc/include/isc/types.h | 103 - contrib/bind9/lib/isc/include/isc/util.h | 233 - contrib/bind9/lib/isc/include/isc/version.h | 28 - contrib/bind9/lib/isc/inet_aton.c | 196 - contrib/bind9/lib/isc/inet_ntop.c | 198 - contrib/bind9/lib/isc/inet_pton.c | 214 - contrib/bind9/lib/isc/lex.c | 963 - contrib/bind9/lib/isc/lfsr.c | 161 - contrib/bind9/lib/isc/lib.c | 79 - contrib/bind9/lib/isc/log.c | 1761 - contrib/bind9/lib/isc/md5.c | 251 - contrib/bind9/lib/isc/mem.c | 1955 -- contrib/bind9/lib/isc/mips/Makefile.in | 24 - contrib/bind9/lib/isc/mips/include/Makefile.in | 24 - contrib/bind9/lib/isc/mips/include/isc/Makefile.in | 36 - contrib/bind9/lib/isc/mips/include/isc/atomic.h | 98 - contrib/bind9/lib/isc/mutexblock.c | 59 - contrib/bind9/lib/isc/netaddr.c | 436 - contrib/bind9/lib/isc/netscope.c | 76 - contrib/bind9/lib/isc/nls/Makefile.in | 37 - contrib/bind9/lib/isc/nls/msgcat.c | 131 - contrib/bind9/lib/isc/noatomic/Makefile.in | 24 - contrib/bind9/lib/isc/noatomic/include/Makefile.in | 24 - .../bind9/lib/isc/noatomic/include/isc/Makefile.in | 36 - .../bind9/lib/isc/noatomic/include/isc/atomic.h | 24 - contrib/bind9/lib/isc/nothreads/Makefile.in | 38 - contrib/bind9/lib/isc/nothreads/condition.c | 24 - .../bind9/lib/isc/nothreads/include/Makefile.in | 25 - .../lib/isc/nothreads/include/isc/Makefile.in | 37 - .../lib/isc/nothreads/include/isc/condition.h | 59 - .../bind9/lib/isc/nothreads/include/isc/mutex.h | 39 - contrib/bind9/lib/isc/nothreads/include/isc/once.h | 32 - .../bind9/lib/isc/nothreads/include/isc/thread.h | 35 - contrib/bind9/lib/isc/nothreads/mutex.c | 25 - contrib/bind9/lib/isc/nothreads/thread.c | 28 - contrib/bind9/lib/isc/ondestroy.c | 85 - contrib/bind9/lib/isc/parseint.c | 72 - contrib/bind9/lib/isc/powerpc/Makefile.in | 24 - contrib/bind9/lib/isc/powerpc/include/Makefile.in | 24 - .../bind9/lib/isc/powerpc/include/isc/Makefile.in | 36 - contrib/bind9/lib/isc/powerpc/include/isc/atomic.h | 160 - contrib/bind9/lib/isc/print.c | 559 - contrib/bind9/lib/isc/pthreads/Makefile.in | 38 - contrib/bind9/lib/isc/pthreads/condition.c | 74 - contrib/bind9/lib/isc/pthreads/include/Makefile.in | 25 - .../bind9/lib/isc/pthreads/include/isc/Makefile.in | 37 - .../bind9/lib/isc/pthreads/include/isc/condition.h | 65 - contrib/bind9/lib/isc/pthreads/include/isc/mutex.h | 145 - contrib/bind9/lib/isc/pthreads/include/isc/once.h | 50 - .../bind9/lib/isc/pthreads/include/isc/thread.h | 60 - contrib/bind9/lib/isc/pthreads/mutex.c | 270 - contrib/bind9/lib/isc/pthreads/thread.c | 76 - contrib/bind9/lib/isc/quota.c | 101 - contrib/bind9/lib/isc/random.c | 104 - contrib/bind9/lib/isc/ratelimiter.c | 328 - contrib/bind9/lib/isc/refcount.c | 37 - contrib/bind9/lib/isc/region.c | 45 - contrib/bind9/lib/isc/result.c | 212 - contrib/bind9/lib/isc/rwlock.c | 808 - contrib/bind9/lib/isc/serial.c | 59 - contrib/bind9/lib/isc/sha1.c | 315 - contrib/bind9/lib/isc/sha2.c | 1234 - contrib/bind9/lib/isc/sockaddr.c | 503 - contrib/bind9/lib/isc/sparc64/Makefile.in | 24 - contrib/bind9/lib/isc/sparc64/include/Makefile.in | 24 - .../bind9/lib/isc/sparc64/include/isc/Makefile.in | 36 - contrib/bind9/lib/isc/sparc64/include/isc/atomic.h | 127 - contrib/bind9/lib/isc/string.c | 270 - contrib/bind9/lib/isc/strtoul.c | 129 - contrib/bind9/lib/isc/symtab.c | 252 - contrib/bind9/lib/isc/task.c | 1298 - contrib/bind9/lib/isc/task_p.h | 31 - contrib/bind9/lib/isc/taskpool.c | 95 - contrib/bind9/lib/isc/timer.c | 930 - contrib/bind9/lib/isc/timer_p.h | 31 - contrib/bind9/lib/isc/unix/Makefile.in | 51 - contrib/bind9/lib/isc/unix/app.c | 683 - contrib/bind9/lib/isc/unix/dir.c | 247 - contrib/bind9/lib/isc/unix/entropy.c | 594 - contrib/bind9/lib/isc/unix/errno2result.c | 123 - contrib/bind9/lib/isc/unix/errno2result.h | 39 - contrib/bind9/lib/isc/unix/file.c | 437 - contrib/bind9/lib/isc/unix/fsaccess.c | 93 - contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c | 185 - contrib/bind9/lib/isc/unix/ifiter_ioctl.c | 1029 - contrib/bind9/lib/isc/unix/ifiter_sysctl.c | 302 - contrib/bind9/lib/isc/unix/include/Makefile.in | 25 - contrib/bind9/lib/isc/unix/include/isc/Makefile.in | 38 - contrib/bind9/lib/isc/unix/include/isc/dir.h | 94 - contrib/bind9/lib/isc/unix/include/isc/int.h | 55 - contrib/bind9/lib/isc/unix/include/isc/keyboard.h | 52 - contrib/bind9/lib/isc/unix/include/isc/net.h | 348 - contrib/bind9/lib/isc/unix/include/isc/netdb.h | 57 - contrib/bind9/lib/isc/unix/include/isc/offset.h | 45 - contrib/bind9/lib/isc/unix/include/isc/stat.h | 52 - contrib/bind9/lib/isc/unix/include/isc/stdtime.h | 60 - contrib/bind9/lib/isc/unix/include/isc/strerror.h | 45 - contrib/bind9/lib/isc/unix/include/isc/syslog.h | 47 - contrib/bind9/lib/isc/unix/include/isc/time.h | 304 - contrib/bind9/lib/isc/unix/interfaceiter.c | 222 - contrib/bind9/lib/isc/unix/ipv6.c | 27 - contrib/bind9/lib/isc/unix/keyboard.c | 126 - contrib/bind9/lib/isc/unix/net.c | 367 - contrib/bind9/lib/isc/unix/os.c | 94 - contrib/bind9/lib/isc/unix/resource.c | 204 - contrib/bind9/lib/isc/unix/socket.c | 3836 --- contrib/bind9/lib/isc/unix/socket_p.h | 35 - contrib/bind9/lib/isc/unix/stdio.c | 117 - contrib/bind9/lib/isc/unix/stdtime.c | 86 - contrib/bind9/lib/isc/unix/strerror.c | 74 - contrib/bind9/lib/isc/unix/syslog.c | 84 - contrib/bind9/lib/isc/unix/time.c | 414 - contrib/bind9/lib/isc/version.c | 28 - contrib/bind9/lib/isc/x86_32/Makefile.in | 24 - contrib/bind9/lib/isc/x86_32/include/Makefile.in | 24 - .../bind9/lib/isc/x86_32/include/isc/Makefile.in | 36 - contrib/bind9/lib/isc/x86_32/include/isc/atomic.h | 158 - contrib/bind9/lib/isc/x86_64/Makefile.in | 24 - contrib/bind9/lib/isc/x86_64/include/Makefile.in | 24 - .../bind9/lib/isc/x86_64/include/isc/Makefile.in | 36 - contrib/bind9/lib/isc/x86_64/include/isc/atomic.h | 103 - contrib/bind9/lib/isccc/Makefile.in | 86 - contrib/bind9/lib/isccc/alist.c | 299 - contrib/bind9/lib/isccc/api | 3 - contrib/bind9/lib/isccc/base64.c | 65 - contrib/bind9/lib/isccc/cc.c | 818 - contrib/bind9/lib/isccc/ccmsg.c | 222 - contrib/bind9/lib/isccc/include/Makefile.in | 25 - contrib/bind9/lib/isccc/include/isccc/Makefile.in | 42 - contrib/bind9/lib/isccc/include/isccc/alist.h | 74 - contrib/bind9/lib/isccc/include/isccc/base64.h | 72 - contrib/bind9/lib/isccc/include/isccc/cc.h | 109 - contrib/bind9/lib/isccc/include/isccc/ccmsg.h | 135 - contrib/bind9/lib/isccc/include/isccc/events.h | 37 - contrib/bind9/lib/isccc/include/isccc/lib.h | 42 - contrib/bind9/lib/isccc/include/isccc/result.h | 60 - contrib/bind9/lib/isccc/include/isccc/sexpr.h | 111 - contrib/bind9/lib/isccc/include/isccc/symtab.h | 122 - contrib/bind9/lib/isccc/include/isccc/symtype.h | 31 - contrib/bind9/lib/isccc/include/isccc/types.h | 46 - contrib/bind9/lib/isccc/include/isccc/util.h | 212 - contrib/bind9/lib/isccc/include/isccc/version.h | 28 - contrib/bind9/lib/isccc/lib.c | 65 - contrib/bind9/lib/isccc/result.c | 72 - contrib/bind9/lib/isccc/sexpr.c | 312 - contrib/bind9/lib/isccc/symtab.c | 280 - contrib/bind9/lib/isccc/version.c | 28 - contrib/bind9/lib/isccfg/Makefile.in | 83 - contrib/bind9/lib/isccfg/aclconf.c | 256 - contrib/bind9/lib/isccfg/api | 3 - contrib/bind9/lib/isccfg/include/Makefile.in | 25 - .../bind9/lib/isccfg/include/isccfg/Makefile.in | 42 - contrib/bind9/lib/isccfg/include/isccfg/aclconf.h | 73 - contrib/bind9/lib/isccfg/include/isccfg/cfg.h | 417 - contrib/bind9/lib/isccfg/include/isccfg/grammar.h | 452 - contrib/bind9/lib/isccfg/include/isccfg/log.h | 55 - .../bind9/lib/isccfg/include/isccfg/namedconf.h | 45 - contrib/bind9/lib/isccfg/include/isccfg/version.h | 28 - contrib/bind9/lib/isccfg/log.c | 52 - contrib/bind9/lib/isccfg/namedconf.c | 2049 -- contrib/bind9/lib/isccfg/parser.c | 2382 -- contrib/bind9/lib/isccfg/version.c | 29 - contrib/bind9/lib/lwres/Makefile.in | 84 - contrib/bind9/lib/lwres/api | 3 - contrib/bind9/lib/lwres/assert_p.h | 35 - contrib/bind9/lib/lwres/context.c | 482 - contrib/bind9/lib/lwres/context_p.h | 65 - contrib/bind9/lib/lwres/gai_strerror.c | 83 - contrib/bind9/lib/lwres/getaddrinfo.c | 808 - contrib/bind9/lib/lwres/gethost.c | 362 - contrib/bind9/lib/lwres/getipnode.c | 1148 - contrib/bind9/lib/lwres/getnameinfo.c | 346 - contrib/bind9/lib/lwres/getrrset.c | 288 - contrib/bind9/lib/lwres/herror.c | 122 - contrib/bind9/lib/lwres/include/Makefile.in | 25 - contrib/bind9/lib/lwres/include/lwres/Makefile.in | 46 - contrib/bind9/lib/lwres/include/lwres/context.h | 129 - contrib/bind9/lib/lwres/include/lwres/int.h | 34 - contrib/bind9/lib/lwres/include/lwres/ipv6.h | 124 - contrib/bind9/lib/lwres/include/lwres/lang.h | 33 - contrib/bind9/lib/lwres/include/lwres/list.h | 121 - contrib/bind9/lib/lwres/include/lwres/lwbuffer.h | 406 - contrib/bind9/lib/lwres/include/lwres/lwpacket.h | 159 - contrib/bind9/lib/lwres/include/lwres/lwres.h | 579 - contrib/bind9/lib/lwres/include/lwres/netdb.h.in | 520 - .../bind9/lib/lwres/include/lwres/platform.h.in | 120 - contrib/bind9/lib/lwres/include/lwres/result.h | 42 - contrib/bind9/lib/lwres/include/lwres/stdlib.h | 40 - contrib/bind9/lib/lwres/include/lwres/version.h | 28 - contrib/bind9/lib/lwres/lwbuffer.c | 361 - contrib/bind9/lib/lwres/lwconfig.c | 725 - contrib/bind9/lib/lwres/lwinetaton.c | 205 - contrib/bind9/lib/lwres/lwinetntop.c | 197 - contrib/bind9/lib/lwres/lwinetpton.c | 209 - contrib/bind9/lib/lwres/lwpacket.c | 129 - contrib/bind9/lib/lwres/lwres_gabn.c | 505 - contrib/bind9/lib/lwres/lwres_gnba.c | 415 - contrib/bind9/lib/lwres/lwres_grbn.c | 426 - contrib/bind9/lib/lwres/lwres_noop.c | 342 - contrib/bind9/lib/lwres/lwresutil.c | 576 - contrib/bind9/lib/lwres/man/Makefile.in | 232 - contrib/bind9/lib/lwres/man/lwres.3 | 165 - contrib/bind9/lib/lwres/man/lwres.docbook | 266 - contrib/bind9/lib/lwres/man/lwres.html | 218 - contrib/bind9/lib/lwres/man/lwres_buffer.3 | 233 - contrib/bind9/lib/lwres/man/lwres_buffer.docbook | 394 - contrib/bind9/lib/lwres/man/lwres_buffer.html | 455 - contrib/bind9/lib/lwres/man/lwres_config.3 | 106 - contrib/bind9/lib/lwres/man/lwres_config.docbook | 173 - contrib/bind9/lib/lwres/man/lwres_config.html | 156 - contrib/bind9/lib/lwres/man/lwres_context.3 | 170 - contrib/bind9/lib/lwres/man/lwres_context.docbook | 262 - contrib/bind9/lib/lwres/man/lwres_context.html | 295 - contrib/bind9/lib/lwres/man/lwres_gabn.3 | 195 - contrib/bind9/lib/lwres/man/lwres_gabn.docbook | 260 - contrib/bind9/lib/lwres/man/lwres_gabn.html | 324 - contrib/bind9/lib/lwres/man/lwres_gai_strerror.3 | 129 - .../bind9/lib/lwres/man/lwres_gai_strerror.docbook | 200 - .../bind9/lib/lwres/man/lwres_gai_strerror.html | 124 - contrib/bind9/lib/lwres/man/lwres_getaddrinfo.3 | 246 - .../bind9/lib/lwres/man/lwres_getaddrinfo.docbook | 387 - contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html | 322 - contrib/bind9/lib/lwres/man/lwres_gethostent.3 | 315 - .../bind9/lib/lwres/man/lwres_gethostent.docbook | 439 - contrib/bind9/lib/lwres/man/lwres_gethostent.html | 466 - contrib/bind9/lib/lwres/man/lwres_getipnode.3 | 206 - .../bind9/lib/lwres/man/lwres_getipnode.docbook | 331 - contrib/bind9/lib/lwres/man/lwres_getipnode.html | 279 - contrib/bind9/lib/lwres/man/lwres_getnameinfo.3 | 117 - .../bind9/lib/lwres/man/lwres_getnameinfo.docbook | 205 - contrib/bind9/lib/lwres/man/lwres_getnameinfo.html | 176 - contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.3 | 164 - .../lib/lwres/man/lwres_getrrsetbyname.docbook | 223 - .../bind9/lib/lwres/man/lwres_getrrsetbyname.html | 192 - contrib/bind9/lib/lwres/man/lwres_gnba.3 | 183 - contrib/bind9/lib/lwres/man/lwres_gnba.docbook | 261 - contrib/bind9/lib/lwres/man/lwres_gnba.html | 316 - contrib/bind9/lib/lwres/man/lwres_hstrerror.3 | 99 - .../bind9/lib/lwres/man/lwres_hstrerror.docbook | 152 - contrib/bind9/lib/lwres/man/lwres_hstrerror.html | 104 - contrib/bind9/lib/lwres/man/lwres_inetntop.3 | 77 - contrib/bind9/lib/lwres/man/lwres_inetntop.docbook | 120 - contrib/bind9/lib/lwres/man/lwres_inetntop.html | 103 - contrib/bind9/lib/lwres/man/lwres_noop.3 | 183 - contrib/bind9/lib/lwres/man/lwres_noop.docbook | 255 - contrib/bind9/lib/lwres/man/lwres_noop.html | 317 - contrib/bind9/lib/lwres/man/lwres_packet.3 | 170 - contrib/bind9/lib/lwres/man/lwres_packet.docbook | 291 - contrib/bind9/lib/lwres/man/lwres_packet.html | 235 - contrib/bind9/lib/lwres/man/lwres_resutil.3 | 170 - contrib/bind9/lib/lwres/man/lwres_resutil.docbook | 238 - contrib/bind9/lib/lwres/man/lwres_resutil.html | 258 - contrib/bind9/lib/lwres/print.c | 560 - contrib/bind9/lib/lwres/print_p.h | 86 - contrib/bind9/lib/lwres/strtoul.c | 135 - contrib/bind9/lib/lwres/unix/Makefile.in | 25 - contrib/bind9/lib/lwres/unix/include/Makefile.in | 25 - .../bind9/lib/lwres/unix/include/lwres/Makefile.in | 34 - contrib/bind9/lib/lwres/unix/include/lwres/net.h | 135 - contrib/bind9/lib/lwres/version.c | 28 - contrib/bind9/libtool.m4 | 6000 ---- contrib/bind9/ltmain.sh | 6416 ---- contrib/bind9/make/Makefile.in | 28 - contrib/bind9/make/includes.in | 48 - contrib/bind9/make/mkdep.in | 148 - contrib/bind9/make/rules.in | 232 - contrib/bind9/mkinstalldirs | 40 - contrib/bind9/version | 10 - doc/Makefile.in | 29 + doc/arm/Bv9ARM-book.xml | 12326 +++++++ doc/arm/Bv9ARM.ch01.html | 560 + doc/arm/Bv9ARM.ch02.html | 158 + doc/arm/Bv9ARM.ch03.html | 808 + doc/arm/Bv9ARM.ch04.html | 1028 + doc/arm/Bv9ARM.ch05.html | 143 + doc/arm/Bv9ARM.ch06.html | 7114 ++++ doc/arm/Bv9ARM.ch07.html | 253 + doc/arm/Bv9ARM.ch08.html | 139 + doc/arm/Bv9ARM.ch09.html | 630 + doc/arm/Bv9ARM.ch10.html | 102 + doc/arm/Bv9ARM.html | 262 + doc/arm/Bv9ARM.pdf | 12885 +++++++ doc/arm/Makefile.in | 67 + doc/arm/README-SGML | 329 + doc/arm/isc-logo.eps | 12253 +++++++ doc/arm/isc-logo.pdf | Bin 0 -> 21981 bytes doc/arm/man.dig.html | 665 + doc/arm/man.dnssec-keygen.html | 269 + doc/arm/man.dnssec-signzone.html | 323 + doc/arm/man.host.html | 249 + doc/arm/man.named-checkconf.html | 130 + doc/arm/man.named-checkzone.html | 294 + doc/arm/man.named.html | 293 + doc/arm/man.rndc-confgen.html | 222 + doc/arm/man.rndc.conf.html | 255 + doc/arm/man.rndc.html | 202 + doc/draft/draft-baba-dnsext-acl-reqts-01.txt | 336 + doc/draft/draft-daigle-napstr-04.txt | 1232 + doc/draft/draft-danisch-dns-rr-smtp-03.txt | 1960 ++ doc/draft/draft-dnsext-opcode-discover-02.txt | 241 + doc/draft/draft-durand-dnsop-dynreverse-00.txt | 240 + doc/draft/draft-ietf-dnsext-2929bis-01.txt | 928 + doc/draft/draft-ietf-dnsext-axfr-clarify-05.txt | 393 + doc/draft/draft-ietf-dnsext-dhcid-rr-12.txt | 674 + doc/draft/draft-ietf-dnsext-dns-name-p-s-00.txt | 1397 + ...t-ietf-dnsext-dnssec-2535typecode-change-06.txt | 442 + .../draft-ietf-dnsext-dnssec-bis-updates-01.txt | 616 + .../draft-ietf-dnsext-dnssec-experiments-01.txt | 784 + .../draft-ietf-dnsext-dnssec-online-signing-02.txt | 616 + doc/draft/draft-ietf-dnsext-dnssec-opt-in-07.txt | 896 + .../draft-ietf-dnsext-dnssec-rsasha256-00.txt | 392 + doc/draft/draft-ietf-dnsext-dnssec-trans-02.txt | 839 + doc/draft/draft-ietf-dnsext-ds-sha256-05.txt | 504 + doc/draft/draft-ietf-dnsext-ecc-key-07.txt | 928 + doc/draft/draft-ietf-dnsext-interop3597-02.txt | 334 + ...draft-ietf-dnsext-keyrr-key-signing-flag-12.txt | 560 + doc/draft/draft-ietf-dnsext-mdns-43.txt | 1740 + doc/draft/draft-ietf-dnsext-nsec3-04.txt | 2352 ++ doc/draft/draft-ietf-dnsext-nsid-01.txt | 840 + doc/draft/draft-ietf-dnsext-rfc2536bis-dsa-06.txt | 464 + doc/draft/draft-ietf-dnsext-rfc2538bis-04.txt | 840 + doc/draft/draft-ietf-dnsext-rfc2539bis-dhk-06.txt | 580 + ...-dnsext-signed-nonexistence-requirements-01.txt | 755 + .../draft-ietf-dnsext-tkey-renewal-mode-05.txt | 1292 + .../draft-ietf-dnsext-trustupdate-threshold-00.txt | 1501 + .../draft-ietf-dnsext-trustupdate-timers-02.txt | 730 + doc/draft/draft-ietf-dnsext-tsig-sha-06.txt | 522 + doc/draft/draft-ietf-dnsext-wcard-clarify-10.txt | 1063 + doc/draft/draft-ietf-dnsop-bad-dns-res-05.txt | 1232 + ...-ietf-dnsop-dnssec-operational-practices-08.txt | 2016 ++ doc/draft/draft-ietf-dnsop-inaddr-required-07.txt | 396 + .../draft-ietf-dnsop-ipv6-dns-configuration-06.txt | 1848 + doc/draft/draft-ietf-dnsop-ipv6-dns-issues-11.txt | 1682 + ...aft-ietf-dnsop-ipv6-transport-guidelines-01.txt | 300 + ...aft-ietf-dnsop-key-rollover-requirements-02.txt | 389 + doc/draft/draft-ietf-dnsop-respsize-02.txt | 480 + doc/draft/draft-ietf-dnsop-serverid-06.txt | 618 + doc/draft/draft-ietf-enum-e164-gstn-np-05.txt | 1588 + doc/draft/draft-ietf-ipv6-node-requirements-08.txt | 1200 + doc/draft/draft-ietf-secsh-dns-05.txt | 614 + .../draft-ihren-dnsext-threshold-validation-00.txt | 519 + doc/draft/draft-kato-dnsop-local-zones-00.txt | 295 + .../draft-park-ipv6-extensions-dns-pnp-00.txt | 1830 + doc/draft/update | 46 + doc/misc/Makefile.in | 47 + doc/misc/dnssec | 84 + doc/misc/format-options.pl | 36 + doc/misc/ipv6 | 113 + doc/misc/migration | 257 + doc/misc/migration-4to9 | 57 + doc/misc/options | 481 + doc/misc/rfc-compliance | 62 + doc/misc/roadmap | 47 + doc/misc/sdb | 169 + doc/rfc/index | 114 + doc/rfc/rfc1032.txt | 781 + doc/rfc/rfc1033.txt | 1229 + doc/rfc/rfc1034.txt | 3077 ++ doc/rfc/rfc1035.txt | 3077 ++ doc/rfc/rfc1101.txt | 787 + doc/rfc/rfc1122.txt | 6844 ++++ doc/rfc/rfc1123.txt | 5782 ++++ doc/rfc/rfc1183.txt | 619 + doc/rfc/rfc1348.txt | 227 + doc/rfc/rfc1535.txt | 283 + doc/rfc/rfc1536.txt | 675 + doc/rfc/rfc1537.txt | 507 + doc/rfc/rfc1591.txt | 395 + doc/rfc/rfc1611.txt | 1683 + doc/rfc/rfc1612.txt | 1795 + doc/rfc/rfc1706.txt | 563 + doc/rfc/rfc1712.txt | 395 + doc/rfc/rfc1750.txt | 1683 + doc/rfc/rfc1876.txt | 1011 + doc/rfc/rfc1886.txt | 268 + doc/rfc/rfc1982.txt | 394 + doc/rfc/rfc1995.txt | 451 + doc/rfc/rfc1996.txt | 395 + doc/rfc/rfc2052.txt | 563 + doc/rfc/rfc2104.txt | 620 + doc/rfc/rfc2119.txt | 171 + doc/rfc/rfc2133.txt | 1795 + doc/rfc/rfc2136.txt | 1460 + doc/rfc/rfc2137.txt | 619 + doc/rfc/rfc2163.txt | 1459 + doc/rfc/rfc2168.txt | 1123 + doc/rfc/rfc2181.txt | 842 + doc/rfc/rfc2230.txt | 619 + doc/rfc/rfc2308.txt | 1067 + doc/rfc/rfc2317.txt | 563 + doc/rfc/rfc2373.txt | 1459 + doc/rfc/rfc2374.txt | 675 + doc/rfc/rfc2375.txt | 451 + doc/rfc/rfc2418.txt | 1459 + doc/rfc/rfc2535.txt | 2635 ++ doc/rfc/rfc2536.txt | 339 + doc/rfc/rfc2537.txt | 339 + doc/rfc/rfc2538.txt | 563 + doc/rfc/rfc2539.txt | 395 + doc/rfc/rfc2540.txt | 339 + doc/rfc/rfc2541.txt | 395 + doc/rfc/rfc2553.txt | 2299 ++ doc/rfc/rfc2671.txt | 395 + doc/rfc/rfc2672.txt | 507 + doc/rfc/rfc2673.txt | 395 + doc/rfc/rfc2782.txt | 675 + doc/rfc/rfc2825.txt | 395 + doc/rfc/rfc2826.txt | 339 + doc/rfc/rfc2845.txt | 843 + doc/rfc/rfc2874.txt | 1123 + doc/rfc/rfc2915.txt | 1011 + doc/rfc/rfc2929.txt | 675 + doc/rfc/rfc2930.txt | 899 + doc/rfc/rfc2931.txt | 563 + doc/rfc/rfc3007.txt | 507 + doc/rfc/rfc3008.txt | 395 + doc/rfc/rfc3071.txt | 563 + doc/rfc/rfc3090.txt | 619 + doc/rfc/rfc3110.txt | 395 + doc/rfc/rfc3123.txt | 451 + doc/rfc/rfc3152.txt | 227 + doc/rfc/rfc3197.txt | 283 + doc/rfc/rfc3225.txt | 339 + doc/rfc/rfc3226.txt | 339 + doc/rfc/rfc3258.txt | 619 + doc/rfc/rfc3363.txt | 339 + doc/rfc/rfc3364.txt | 619 + doc/rfc/rfc3425.txt | 283 + doc/rfc/rfc3445.txt | 563 + doc/rfc/rfc3467.txt | 1739 + doc/rfc/rfc3490.txt | 1235 + doc/rfc/rfc3491.txt | 395 + doc/rfc/rfc3492.txt | 1963 ++ doc/rfc/rfc3493.txt | 2187 ++ doc/rfc/rfc3513.txt | 1459 + doc/rfc/rfc3596.txt | 451 + doc/rfc/rfc3597.txt | 451 + doc/rfc/rfc3645.txt | 1459 + doc/rfc/rfc3655.txt | 451 + doc/rfc/rfc3658.txt | 1067 + doc/rfc/rfc3757.txt | 451 + doc/rfc/rfc3833.txt | 899 + doc/rfc/rfc3845.txt | 395 + doc/rfc/rfc3901.txt | 283 + doc/rfc/rfc4025.txt | 675 + doc/rfc/rfc4033.txt | 1179 + doc/rfc/rfc4034.txt | 1627 + doc/rfc/rfc4035.txt | 2971 ++ doc/rfc/rfc4074.txt | 339 + doc/rfc/rfc4159.txt | 171 + doc/rfc/rfc4193.txt | 899 + doc/rfc/rfc4255.txt | 507 + doc/rfc/rfc4343.txt | 563 + doc/rfc/rfc4367.txt | 955 + doc/rfc/rfc4398.txt | 955 + doc/rfc/rfc4408.txt | 2691 ++ doc/rfc/rfc4431.txt | 227 + doc/rfc/rfc4470.txt | 451 + doc/rfc/rfc4634.txt | 6051 ++++ doc/rfc/rfc4641.txt | 1963 ++ doc/rfc/rfc952.txt | 340 + install-sh | 250 + isc-config.sh.in | 149 + lib/Makefile.in | 29 + lib/bind/Makefile.in | 133 + lib/bind/README | 4 + lib/bind/aclocal.m4 | 2 + lib/bind/api | 3 + lib/bind/bsd/Makefile.in | 39 + lib/bind/bsd/daemon.c | 81 + lib/bind/bsd/ftruncate.c | 64 + lib/bind/bsd/gettimeofday.c | 64 + lib/bind/bsd/mktemp.c | 156 + lib/bind/bsd/putenv.c | 27 + lib/bind/bsd/readv.c | 39 + lib/bind/bsd/setenv.c | 151 + lib/bind/bsd/setitimer.c | 29 + lib/bind/bsd/strcasecmp.c | 124 + lib/bind/bsd/strdup.c | 20 + lib/bind/bsd/strerror.c | 92 + lib/bind/bsd/strpbrk.c | 70 + lib/bind/bsd/strsep.c | 88 + lib/bind/bsd/strtoul.c | 119 + lib/bind/bsd/utimes.c | 40 + lib/bind/bsd/writev.c | 89 + lib/bind/config.h.in | 61 + lib/bind/configure | 33825 +++++++++++++++++++ lib/bind/configure.in | 2683 ++ lib/bind/dst/Makefile.in | 32 + lib/bind/dst/dst_api.c | 1048 + lib/bind/dst/dst_internal.h | 155 + lib/bind/dst/hmac_link.c | 489 + lib/bind/dst/md5.h | 108 + lib/bind/dst/md5_dgst.c | 374 + lib/bind/dst/md5_locl.h | 193 + lib/bind/dst/support.c | 342 + lib/bind/include/Makefile.in | 47 + lib/bind/include/arpa/inet.h | 126 + lib/bind/include/arpa/nameser.h | 574 + lib/bind/include/arpa/nameser_compat.h | 232 + lib/bind/include/fd_setsize.h | 10 + lib/bind/include/hesiod.h | 39 + lib/bind/include/irp.h | 107 + lib/bind/include/irs.h | 348 + lib/bind/include/isc/assertions.h | 122 + lib/bind/include/isc/ctl.h | 112 + lib/bind/include/isc/dst.h | 168 + lib/bind/include/isc/eventlib.h | 204 + lib/bind/include/isc/heap.h | 49 + lib/bind/include/isc/irpmarshall.h | 112 + lib/bind/include/isc/list.h | 117 + lib/bind/include/isc/logging.h | 113 + lib/bind/include/isc/memcluster.h | 50 + lib/bind/include/isc/misc.h | 43 + lib/bind/include/isc/tree.h | 59 + lib/bind/include/netdb.h | 582 + lib/bind/include/netgroup.h | 26 + lib/bind/include/res_update.h | 69 + lib/bind/include/resolv.h | 505 + lib/bind/include/resolv_mt.h | 47 + lib/bind/inet/Makefile.in | 35 + lib/bind/inet/inet_addr.c | 208 + lib/bind/inet/inet_cidr_ntop.c | 263 + lib/bind/inet/inet_cidr_pton.c | 277 + lib/bind/inet/inet_data.c | 46 + lib/bind/inet/inet_lnaof.c | 65 + lib/bind/inet/inet_makeaddr.c | 68 + lib/bind/inet/inet_net_ntop.c | 279 + lib/bind/inet/inet_net_pton.c | 407 + lib/bind/inet/inet_neta.c | 89 + lib/bind/inet/inet_netof.c | 64 + lib/bind/inet/inet_network.c | 106 + lib/bind/inet/inet_ntoa.c | 64 + lib/bind/inet/inet_ntop.c | 207 + lib/bind/inet/inet_pton.c | 223 + lib/bind/inet/nsap_addr.c | 111 + lib/bind/irs/Makefile.in | 70 + lib/bind/irs/dns.c | 154 + lib/bind/irs/dns_gr.c | 294 + lib/bind/irs/dns_ho.c | 1142 + lib/bind/irs/dns_nw.c | 591 + lib/bind/irs/dns_p.h | 52 + lib/bind/irs/dns_pr.c | 268 + lib/bind/irs/dns_pw.c | 232 + lib/bind/irs/dns_sv.c | 300 + lib/bind/irs/gai_strerror.c | 105 + lib/bind/irs/gen.c | 433 + lib/bind/irs/gen_gr.c | 493 + lib/bind/irs/gen_ho.c | 391 + lib/bind/irs/gen_ng.c | 174 + lib/bind/irs/gen_nw.c | 264 + lib/bind/irs/gen_p.h | 113 + lib/bind/irs/gen_pr.c | 228 + lib/bind/irs/gen_pw.c | 234 + lib/bind/irs/gen_sv.c | 229 + lib/bind/irs/getaddrinfo.c | 1253 + lib/bind/irs/getgrent.c | 224 + lib/bind/irs/getgrent_r.c | 230 + lib/bind/irs/gethostent.c | 1070 + lib/bind/irs/gethostent_r.c | 275 + lib/bind/irs/getnameinfo.c | 334 + lib/bind/irs/getnetent.c | 345 + lib/bind/irs/getnetent_r.c | 234 + lib/bind/irs/getnetgrent.c | 158 + lib/bind/irs/getnetgrent_r.c | 178 + lib/bind/irs/getprotoent.c | 176 + lib/bind/irs/getprotoent_r.c | 223 + lib/bind/irs/getpwent.c | 201 + lib/bind/irs/getpwent_r.c | 276 + lib/bind/irs/getservent.c | 179 + lib/bind/irs/getservent_r.c | 242 + lib/bind/irs/hesiod.c | 505 + lib/bind/irs/hesiod_p.h | 48 + lib/bind/irs/irp.c | 582 + lib/bind/irs/irp_gr.c | 357 + lib/bind/irs/irp_ho.c | 405 + lib/bind/irs/irp_ng.c | 253 + lib/bind/irs/irp_nw.c | 348 + lib/bind/irs/irp_p.h | 60 + lib/bind/irs/irp_pr.c | 327 + lib/bind/irs/irp_pw.c | 340 + lib/bind/irs/irp_sv.c | 346 + lib/bind/irs/irpmarshall.c | 2301 ++ lib/bind/irs/irs_data.c | 246 + lib/bind/irs/irs_data.h | 63 + lib/bind/irs/irs_p.h | 51 + lib/bind/irs/lcl.c | 142 + lib/bind/irs/lcl_gr.c | 354 + lib/bind/irs/lcl_ho.c | 578 + lib/bind/irs/lcl_ng.c | 446 + lib/bind/irs/lcl_nw.c | 373 + lib/bind/irs/lcl_p.h | 51 + lib/bind/irs/lcl_pr.c | 294 + lib/bind/irs/lcl_pw.c | 309 + lib/bind/irs/lcl_sv.c | 432 + lib/bind/irs/nis.c | 156 + lib/bind/irs/nis_gr.c | 354 + lib/bind/irs/nis_ho.c | 535 + lib/bind/irs/nis_ng.c | 304 + lib/bind/irs/nis_nw.c | 385 + lib/bind/irs/nis_p.h | 47 + lib/bind/irs/nis_pr.c | 302 + lib/bind/irs/nis_pw.c | 288 + lib/bind/irs/nis_sv.c | 310 + lib/bind/irs/nul_ng.c | 127 + lib/bind/irs/pathnames.h | 52 + lib/bind/irs/util.c | 109 + lib/bind/isc/Makefile.in | 35 + lib/bind/isc/assertions.c | 93 + lib/bind/isc/assertions.mdoc | 138 + lib/bind/isc/base64.c | 322 + lib/bind/isc/bitncmp.c | 68 + lib/bind/isc/bitncmp.mdoc | 82 + lib/bind/isc/ctl_clnt.c | 617 + lib/bind/isc/ctl_p.c | 188 + lib/bind/isc/ctl_p.h | 28 + lib/bind/isc/ctl_srvr.c | 784 + lib/bind/isc/ev_connects.c | 369 + lib/bind/isc/ev_files.c | 277 + lib/bind/isc/ev_streams.c | 308 + lib/bind/isc/ev_timers.c | 499 + lib/bind/isc/ev_waits.c | 247 + lib/bind/isc/eventlib.c | 933 + lib/bind/isc/eventlib.mdoc | 918 + lib/bind/isc/eventlib_p.h | 281 + lib/bind/isc/heap.c | 236 + lib/bind/isc/heap.mdoc | 378 + lib/bind/isc/hex.c | 119 + lib/bind/isc/logging.c | 722 + lib/bind/isc/logging.mdoc | 1056 + lib/bind/isc/logging_p.h | 61 + lib/bind/isc/memcluster.c | 588 + lib/bind/isc/memcluster.mdoc | 376 + lib/bind/isc/movefile.c | 37 + lib/bind/isc/tree.c | 534 + lib/bind/isc/tree.mdoc | 154 + lib/bind/make/includes.in | 44 + lib/bind/make/mkdep.in | 147 + lib/bind/make/rules.in | 177 + lib/bind/mkinstalldirs | 40 + lib/bind/nameser/Makefile.in | 31 + lib/bind/nameser/ns_date.c | 129 + lib/bind/nameser/ns_name.c | 973 + lib/bind/nameser/ns_netint.c | 58 + lib/bind/nameser/ns_parse.c | 211 + lib/bind/nameser/ns_print.c | 897 + lib/bind/nameser/ns_samedomain.c | 207 + lib/bind/nameser/ns_sign.c | 387 + lib/bind/nameser/ns_ttl.c | 162 + lib/bind/nameser/ns_verify.c | 484 + lib/bind/port/Makefile.in | 14 + lib/bind/port/freebsd/Makefile.in | 14 + lib/bind/port/freebsd/include/Makefile.in | 34 + lib/bind/port/freebsd/include/sys/bitypes.h | 37 + lib/bind/port_after.h.in | 415 + lib/bind/port_before.h.in | 162 + lib/bind/resolv/Makefile.in | 34 + lib/bind/resolv/herror.c | 129 + lib/bind/resolv/mtctxres.c | 129 + lib/bind/resolv/res_comp.c | 265 + lib/bind/resolv/res_data.c | 297 + lib/bind/resolv/res_debug.c | 1165 + lib/bind/resolv/res_debug.h | 35 + lib/bind/resolv/res_findzonecut.c | 722 + lib/bind/resolv/res_init.c | 801 + lib/bind/resolv/res_mkquery.c | 257 + lib/bind/resolv/res_mkupdate.c | 1162 + lib/bind/resolv/res_mkupdate.h | 25 + lib/bind/resolv/res_private.h | 22 + lib/bind/resolv/res_query.c | 432 + lib/bind/resolv/res_send.c | 1094 + lib/bind/resolv/res_sendsigned.c | 170 + lib/bind/resolv/res_update.c | 213 + lib/bind9/Makefile.in | 84 + lib/bind9/api | 3 + lib/bind9/check.c | 2043 ++ lib/bind9/getaddresses.c | 231 + lib/bind9/include/Makefile.in | 25 + lib/bind9/include/bind9/Makefile.in | 42 + lib/bind9/include/bind9/check.h | 57 + lib/bind9/include/bind9/getaddresses.h | 61 + lib/bind9/include/bind9/version.h | 28 + lib/bind9/version.c | 28 + lib/dns/Makefile.in | 171 + lib/dns/acache.c | 1778 + lib/dns/acl.c | 452 + lib/dns/adb.c | 3610 ++ lib/dns/api | 3 + lib/dns/byaddr.c | 316 + lib/dns/cache.c | 1154 + lib/dns/callbacks.c | 113 + lib/dns/compress.c | 341 + lib/dns/db.c | 821 + lib/dns/dbiterator.c | 143 + lib/dns/dbtable.c | 291 + lib/dns/diff.c | 554 + lib/dns/dispatch.c | 2674 ++ lib/dns/dlz.c | 510 + lib/dns/dnssec.c | 865 + lib/dns/ds.c | 104 + lib/dns/dst_api.c | 1221 + lib/dns/dst_internal.h | 142 + lib/dns/dst_lib.c | 67 + lib/dns/dst_openssl.h | 34 + lib/dns/dst_parse.c | 493 + lib/dns/dst_parse.h | 118 + lib/dns/dst_result.c | 88 + lib/dns/forward.c | 199 + lib/dns/gen-unix.h | 97 + lib/dns/gen.c | 884 + lib/dns/gssapi_link.c | 222 + lib/dns/gssapictx.c | 264 + lib/dns/hmac_link.c | 1668 + lib/dns/include/Makefile.in | 25 + lib/dns/include/dns/Makefile.in | 54 + lib/dns/include/dns/acache.h | 445 + lib/dns/include/dns/acl.h | 222 + lib/dns/include/dns/adb.h | 635 + lib/dns/include/dns/bit.h | 39 + lib/dns/include/dns/byaddr.h | 171 + lib/dns/include/dns/cache.h | 253 + lib/dns/include/dns/callbacks.h | 87 + lib/dns/include/dns/cert.h | 69 + lib/dns/include/dns/compress.h | 269 + lib/dns/include/dns/db.h | 1299 + lib/dns/include/dns/dbiterator.h | 297 + lib/dns/include/dns/dbtable.h | 165 + lib/dns/include/dns/diff.h | 280 + lib/dns/include/dns/dispatch.h | 453 + lib/dns/include/dns/dlz.h | 290 + lib/dns/include/dns/dnssec.h | 183 + lib/dns/include/dns/ds.h | 63 + lib/dns/include/dns/events.h | 75 + lib/dns/include/dns/fixedname.h | 86 + lib/dns/include/dns/forward.h | 118 + lib/dns/include/dns/journal.h | 276 + lib/dns/include/dns/keyflags.h | 54 + lib/dns/include/dns/keytable.h | 255 + lib/dns/include/dns/keyvalues.h | 98 + lib/dns/include/dns/lib.h | 45 + lib/dns/include/dns/log.h | 106 + lib/dns/include/dns/lookup.h | 137 + lib/dns/include/dns/master.h | 277 + lib/dns/include/dns/masterdump.h | 334 + lib/dns/include/dns/message.h | 1339 + lib/dns/include/dns/name.h | 1296 + lib/dns/include/dns/ncache.h | 159 + lib/dns/include/dns/nsec.h | 69 + lib/dns/include/dns/opcode.h | 51 + lib/dns/include/dns/order.h | 99 + lib/dns/include/dns/peer.h | 212 + lib/dns/include/dns/portlist.h | 101 + lib/dns/include/dns/rbt.h | 916 + lib/dns/include/dns/rcode.h | 98 + lib/dns/include/dns/rdata.h | 701 + lib/dns/include/dns/rdataclass.h | 81 + lib/dns/include/dns/rdatalist.h | 103 + lib/dns/include/dns/rdataset.h | 597 + lib/dns/include/dns/rdatasetiter.h | 170 + lib/dns/include/dns/rdataslab.h | 163 + lib/dns/include/dns/rdatatype.h | 83 + lib/dns/include/dns/request.h | 374 + lib/dns/include/dns/resolver.h | 479 + lib/dns/include/dns/result.h | 190 + lib/dns/include/dns/rootns.h | 45 + lib/dns/include/dns/sdb.h | 209 + lib/dns/include/dns/sdlz.h | 266 + lib/dns/include/dns/secalg.h | 71 + lib/dns/include/dns/secproto.h | 71 + lib/dns/include/dns/soa.h | 81 + lib/dns/include/dns/ssu.h | 165 + lib/dns/include/dns/stats.h | 61 + lib/dns/include/dns/tcpmsg.h | 147 + lib/dns/include/dns/time.h | 72 + lib/dns/include/dns/timer.h | 52 + lib/dns/include/dns/tkey.h | 198 + lib/dns/include/dns/tsig.h | 254 + lib/dns/include/dns/ttl.h | 78 + lib/dns/include/dns/types.h | 328 + lib/dns/include/dns/validator.h | 247 + lib/dns/include/dns/version.h | 28 + lib/dns/include/dns/view.h | 804 + lib/dns/include/dns/xfrin.h | 111 + lib/dns/include/dns/zone.h | 1586 + lib/dns/include/dns/zonekey.h | 42 + lib/dns/include/dns/zt.h | 183 + lib/dns/include/dst/Makefile.in | 37 + lib/dns/include/dst/dst.h | 620 + lib/dns/include/dst/gssapi.h | 58 + lib/dns/include/dst/lib.h | 41 + lib/dns/include/dst/result.h | 70 + lib/dns/journal.c | 2182 ++ lib/dns/key.c | 147 + lib/dns/keytable.c | 395 + lib/dns/lib.c | 65 + lib/dns/log.c | 97 + lib/dns/lookup.c | 497 + lib/dns/master.c | 2833 ++ lib/dns/masterdump.c | 1738 + lib/dns/message.c | 3265 ++ lib/dns/name.c | 2406 ++ lib/dns/ncache.c | 559 + lib/dns/nsec.c | 220 + lib/dns/openssl_link.c | 261 + lib/dns/openssldh_link.c | 626 + lib/dns/openssldsa_link.c | 462 + lib/dns/opensslrsa_link.c | 629 + lib/dns/order.c | 167 + lib/dns/peer.c | 685 + lib/dns/portlist.c | 266 + lib/dns/rbt.c | 2544 ++ lib/dns/rbtdb.c | 6760 ++++ lib/dns/rbtdb.h | 44 + lib/dns/rbtdb64.c | 23 + lib/dns/rbtdb64.h | 45 + lib/dns/rcode.c | 474 + lib/dns/rdata.c | 1746 + lib/dns/rdata/any_255/tsig_250.c | 597 + lib/dns/rdata/any_255/tsig_250.h | 38 + lib/dns/rdata/ch_3/a_1.c | 316 + lib/dns/rdata/ch_3/a_1.h | 34 + lib/dns/rdata/generic/afsdb_18.c | 309 + lib/dns/rdata/generic/afsdb_18.h | 34 + lib/dns/rdata/generic/cert_37.c | 280 + lib/dns/rdata/generic/cert_37.h | 34 + lib/dns/rdata/generic/cname_5.c | 232 + lib/dns/rdata/generic/cname_5.h | 29 + lib/dns/rdata/generic/dlv_32769.c | 321 + lib/dns/rdata/generic/dlv_32769.h | 33 + lib/dns/rdata/generic/dname_39.c | 233 + lib/dns/rdata/generic/dname_39.h | 32 + lib/dns/rdata/generic/dnskey_48.c | 312 + lib/dns/rdata/generic/dnskey_48.h | 37 + lib/dns/rdata/generic/ds_43.c | 321 + lib/dns/rdata/generic/ds_43.h | 35 + lib/dns/rdata/generic/gpos_27.c | 252 + lib/dns/rdata/generic/gpos_27.h | 37 + lib/dns/rdata/generic/hinfo_13.c | 224 + lib/dns/rdata/generic/hinfo_13.h | 32 + lib/dns/rdata/generic/ipseckey_45.c | 462 + lib/dns/rdata/generic/ipseckey_45.h | 35 + lib/dns/rdata/generic/isdn_20.c | 234 + lib/dns/rdata/generic/isdn_20.h | 35 + lib/dns/rdata/generic/key_25.c | 312 + lib/dns/rdata/generic/key_25.h | 37 + lib/dns/rdata/generic/loc_29.c | 794 + lib/dns/rdata/generic/loc_29.h | 43 + lib/dns/rdata/generic/mb_7.c | 234 + lib/dns/rdata/generic/mb_7.h | 30 + lib/dns/rdata/generic/md_3.c | 236 + lib/dns/rdata/generic/md_3.h | 31 + lib/dns/rdata/generic/mf_4.c | 235 + lib/dns/rdata/generic/mf_4.h | 30 + lib/dns/rdata/generic/mg_8.c | 230 + lib/dns/rdata/generic/mg_8.h | 30 + lib/dns/rdata/generic/minfo_14.c | 324 + lib/dns/rdata/generic/minfo_14.h | 31 + lib/dns/rdata/generic/mr_9.c | 231 + lib/dns/rdata/generic/mr_9.h | 30 + lib/dns/rdata/generic/mx_15.c | 319 + lib/dns/rdata/generic/mx_15.h | 31 + lib/dns/rdata/generic/ns_2.c | 251 + lib/dns/rdata/generic/ns_2.h | 31 + lib/dns/rdata/generic/nsec_47.c | 366 + lib/dns/rdata/generic/nsec_47.h | 34 + lib/dns/rdata/generic/null_10.c | 192 + lib/dns/rdata/generic/null_10.h | 32 + lib/dns/rdata/generic/nxt_30.c | 329 + lib/dns/rdata/generic/nxt_30.h | 34 + lib/dns/rdata/generic/opt_41.c | 280 + lib/dns/rdata/generic/opt_41.h | 55 + lib/dns/rdata/generic/proforma.c | 173 + lib/dns/rdata/generic/proforma.h | 30 + lib/dns/rdata/generic/ptr_12.c | 291 + lib/dns/rdata/generic/ptr_12.h | 30 + lib/dns/rdata/generic/rp_17.c | 314 + lib/dns/rdata/generic/rp_17.h | 34 + lib/dns/rdata/generic/rrsig_46.c | 551 + lib/dns/rdata/generic/rrsig_46.h | 41 + lib/dns/rdata/generic/rt_21.c | 311 + lib/dns/rdata/generic/rt_21.h | 33 + lib/dns/rdata/generic/sig_24.c | 578 + lib/dns/rdata/generic/sig_24.h | 42 + lib/dns/rdata/generic/soa_6.c | 443 + lib/dns/rdata/generic/soa_6.h | 37 + lib/dns/rdata/generic/spf_99.c | 238 + lib/dns/rdata/generic/spf_99.h | 51 + lib/dns/rdata/generic/sshfp_44.c | 262 + lib/dns/rdata/generic/sshfp_44.h | 35 + lib/dns/rdata/generic/tkey_249.c | 555 + lib/dns/rdata/generic/tkey_249.h | 41 + lib/dns/rdata/generic/txt_16.c | 238 + lib/dns/rdata/generic/txt_16.h | 52 + lib/dns/rdata/generic/unspec_103.c | 189 + lib/dns/rdata/generic/unspec_103.h | 31 + lib/dns/rdata/generic/x25_19.c | 219 + lib/dns/rdata/generic/x25_19.h | 33 + lib/dns/rdata/hs_4/a_1.c | 232 + lib/dns/rdata/hs_4/a_1.h | 29 + lib/dns/rdata/in_1/a6_38.c | 461 + lib/dns/rdata/in_1/a6_38.h | 34 + lib/dns/rdata/in_1/a_1.c | 236 + lib/dns/rdata/in_1/a_1.h | 29 + lib/dns/rdata/in_1/aaaa_28.c | 233 + lib/dns/rdata/in_1/aaaa_28.h | 31 + lib/dns/rdata/in_1/apl_42.c | 402 + lib/dns/rdata/in_1/apl_42.h | 56 + lib/dns/rdata/in_1/kx_36.c | 288 + lib/dns/rdata/in_1/kx_36.h | 33 + lib/dns/rdata/in_1/naptr_35.c | 578 + lib/dns/rdata/in_1/naptr_35.h | 40 + lib/dns/rdata/in_1/nsap-ptr_23.c | 245 + lib/dns/rdata/in_1/nsap-ptr_23.h | 32 + lib/dns/rdata/in_1/nsap_22.c | 255 + lib/dns/rdata/in_1/nsap_22.h | 33 + lib/dns/rdata/in_1/px_26.c | 374 + lib/dns/rdata/in_1/px_26.h | 34 + lib/dns/rdata/in_1/srv_33.c | 373 + lib/dns/rdata/in_1/srv_33.h | 37 + lib/dns/rdata/in_1/wks_11.c | 349 + lib/dns/rdata/in_1/wks_11.h | 32 + lib/dns/rdata/rdatastructpre.h | 42 + lib/dns/rdata/rdatastructsuf.h | 22 + lib/dns/rdatalist.c | 229 + lib/dns/rdatalist_p.h | 57 + lib/dns/rdataset.c | 709 + lib/dns/rdatasetiter.c | 80 + lib/dns/rdataslab.c | 1045 + lib/dns/request.c | 1461 + lib/dns/resolver.c | 7181 ++++ lib/dns/result.c | 276 + lib/dns/rootns.c | 514 + lib/dns/sdb.c | 1538 + lib/dns/sdlz.c | 1786 + lib/dns/soa.c | 111 + lib/dns/ssu.c | 366 + lib/dns/stats.c | 57 + lib/dns/tcpmsg.c | 243 + lib/dns/time.c | 174 + lib/dns/timer.c | 60 + lib/dns/tkey.c | 1242 + lib/dns/tsig.c | 1464 + lib/dns/ttl.c | 216 + lib/dns/validator.c | 3078 ++ lib/dns/version.c | 28 + lib/dns/view.c | 1367 + lib/dns/xfrin.c | 1470 + lib/dns/zone.c | 8043 +++++ lib/dns/zonekey.c | 55 + lib/dns/zt.c | 410 + lib/isc/Makefile.in | 112 + lib/isc/alpha/Makefile.in | 24 + lib/isc/alpha/include/Makefile.in | 24 + lib/isc/alpha/include/isc/Makefile.in | 36 + lib/isc/alpha/include/isc/atomic.h | 170 + lib/isc/api | 3 + lib/isc/arm/include/isc/atomic.h | 81 + lib/isc/assertions.c | 96 + lib/isc/base64.c | 250 + lib/isc/bitstring.c | 127 + lib/isc/buffer.c | 413 + lib/isc/bufferlist.c | 64 + lib/isc/commandline.c | 222 + lib/isc/entropy.c | 1263 + lib/isc/error.c | 106 + lib/isc/event.c | 88 + lib/isc/fsaccess.c | 102 + lib/isc/hash.c | 390 + lib/isc/heap.c | 256 + lib/isc/hex.c | 201 + lib/isc/hmacmd5.c | 118 + lib/isc/hmacsha.c | 438 + lib/isc/ia64/Makefile.in | 24 + lib/isc/ia64/include/Makefile.in | 24 + lib/isc/ia64/include/isc/Makefile.in | 36 + lib/isc/ia64/include/isc/atomic.h | 88 + lib/isc/include/Makefile.in | 25 + lib/isc/include/isc/Makefile.in | 57 + lib/isc/include/isc/app.h | 212 + lib/isc/include/isc/assertions.h | 123 + lib/isc/include/isc/base64.h | 99 + lib/isc/include/isc/bitstring.h | 157 + lib/isc/include/isc/boolean.h | 31 + lib/isc/include/isc/buffer.h | 811 + lib/isc/include/isc/bufferlist.h | 86 + lib/isc/include/isc/commandline.h | 50 + lib/isc/include/isc/entropy.h | 307 + lib/isc/include/isc/error.h | 62 + lib/isc/include/isc/event.h | 121 + lib/isc/include/isc/eventclass.h | 53 + lib/isc/include/isc/file.h | 256 + lib/isc/include/isc/formatcheck.h | 40 + lib/isc/include/isc/fsaccess.h | 177 + lib/isc/include/isc/hash.h | 185 + lib/isc/include/isc/heap.h | 170 + lib/isc/include/isc/hex.h | 98 + lib/isc/include/isc/hmacmd5.h | 63 + lib/isc/include/isc/hmacsha.h | 156 + lib/isc/include/isc/interfaceiter.h | 133 + lib/isc/include/isc/ipv6.h | 148 + lib/isc/include/isc/lang.h | 33 + lib/isc/include/isc/lex.h | 431 + lib/isc/include/isc/lfsr.h | 130 + lib/isc/include/isc/lib.h | 41 + lib/isc/include/isc/list.h | 184 + lib/isc/include/isc/log.h | 913 + lib/isc/include/isc/magic.h | 41 + lib/isc/include/isc/md5.h | 73 + lib/isc/include/isc/mem.h | 543 + lib/isc/include/isc/msgcat.h | 131 + lib/isc/include/isc/msgs.h | 191 + lib/isc/include/isc/mutexblock.h | 71 + lib/isc/include/isc/netaddr.h | 175 + lib/isc/include/isc/netscope.h | 43 + lib/isc/include/isc/ondestroy.h | 116 + lib/isc/include/isc/os.h | 38 + lib/isc/include/isc/parseint.h | 64 + lib/isc/include/isc/platform.h.in | 306 + lib/isc/include/isc/print.h | 87 + lib/isc/include/isc/quota.h | 119 + lib/isc/include/isc/random.h | 62 + lib/isc/include/isc/ratelimiter.h | 134 + lib/isc/include/isc/refcount.h | 233 + lib/isc/include/isc/region.h | 99 + lib/isc/include/isc/resource.h | 87 + lib/isc/include/isc/result.h | 104 + lib/isc/include/isc/resultclass.h | 50 + lib/isc/include/isc/rwlock.h | 135 + lib/isc/include/isc/serial.h | 75 + lib/isc/include/isc/sha1.h | 59 + lib/isc/include/isc/sha2.h | 132 + lib/isc/include/isc/sockaddr.h | 240 + lib/isc/include/isc/socket.h | 752 + lib/isc/include/isc/stdio.h | 77 + lib/isc/include/isc/stdlib.h | 40 + lib/isc/include/isc/string.h | 231 + lib/isc/include/isc/symtab.h | 131 + lib/isc/include/isc/task.h | 616 + lib/isc/include/isc/taskpool.h | 105 + lib/isc/include/isc/timer.h | 342 + lib/isc/include/isc/types.h | 103 + lib/isc/include/isc/util.h | 233 + lib/isc/include/isc/version.h | 28 + lib/isc/inet_aton.c | 196 + lib/isc/inet_ntop.c | 198 + lib/isc/inet_pton.c | 214 + lib/isc/lex.c | 963 + lib/isc/lfsr.c | 161 + lib/isc/lib.c | 79 + lib/isc/log.c | 1761 + lib/isc/md5.c | 251 + lib/isc/mem.c | 1955 ++ lib/isc/mips/Makefile.in | 24 + lib/isc/mips/include/Makefile.in | 24 + lib/isc/mips/include/isc/Makefile.in | 36 + lib/isc/mips/include/isc/atomic.h | 98 + lib/isc/mutexblock.c | 59 + lib/isc/netaddr.c | 436 + lib/isc/netscope.c | 76 + lib/isc/nls/Makefile.in | 37 + lib/isc/nls/msgcat.c | 131 + lib/isc/noatomic/Makefile.in | 24 + lib/isc/noatomic/include/Makefile.in | 24 + lib/isc/noatomic/include/isc/Makefile.in | 36 + lib/isc/noatomic/include/isc/atomic.h | 24 + lib/isc/nothreads/Makefile.in | 38 + lib/isc/nothreads/condition.c | 24 + lib/isc/nothreads/include/Makefile.in | 25 + lib/isc/nothreads/include/isc/Makefile.in | 37 + lib/isc/nothreads/include/isc/condition.h | 59 + lib/isc/nothreads/include/isc/mutex.h | 39 + lib/isc/nothreads/include/isc/once.h | 32 + lib/isc/nothreads/include/isc/thread.h | 35 + lib/isc/nothreads/mutex.c | 25 + lib/isc/nothreads/thread.c | 28 + lib/isc/ondestroy.c | 85 + lib/isc/parseint.c | 72 + lib/isc/powerpc/Makefile.in | 24 + lib/isc/powerpc/include/Makefile.in | 24 + lib/isc/powerpc/include/isc/Makefile.in | 36 + lib/isc/powerpc/include/isc/atomic.h | 160 + lib/isc/print.c | 559 + lib/isc/pthreads/Makefile.in | 38 + lib/isc/pthreads/condition.c | 74 + lib/isc/pthreads/include/Makefile.in | 25 + lib/isc/pthreads/include/isc/Makefile.in | 37 + lib/isc/pthreads/include/isc/condition.h | 65 + lib/isc/pthreads/include/isc/mutex.h | 145 + lib/isc/pthreads/include/isc/once.h | 50 + lib/isc/pthreads/include/isc/thread.h | 60 + lib/isc/pthreads/mutex.c | 270 + lib/isc/pthreads/thread.c | 76 + lib/isc/quota.c | 101 + lib/isc/random.c | 104 + lib/isc/ratelimiter.c | 328 + lib/isc/refcount.c | 37 + lib/isc/region.c | 45 + lib/isc/result.c | 212 + lib/isc/rwlock.c | 808 + lib/isc/serial.c | 59 + lib/isc/sha1.c | 315 + lib/isc/sha2.c | 1234 + lib/isc/sockaddr.c | 503 + lib/isc/sparc64/Makefile.in | 24 + lib/isc/sparc64/include/Makefile.in | 24 + lib/isc/sparc64/include/isc/Makefile.in | 36 + lib/isc/sparc64/include/isc/atomic.h | 127 + lib/isc/string.c | 270 + lib/isc/strtoul.c | 129 + lib/isc/symtab.c | 252 + lib/isc/task.c | 1298 + lib/isc/task_p.h | 31 + lib/isc/taskpool.c | 95 + lib/isc/timer.c | 930 + lib/isc/timer_p.h | 31 + lib/isc/unix/Makefile.in | 51 + lib/isc/unix/app.c | 683 + lib/isc/unix/dir.c | 247 + lib/isc/unix/entropy.c | 594 + lib/isc/unix/errno2result.c | 123 + lib/isc/unix/errno2result.h | 39 + lib/isc/unix/file.c | 437 + lib/isc/unix/fsaccess.c | 93 + lib/isc/unix/ifiter_getifaddrs.c | 185 + lib/isc/unix/ifiter_ioctl.c | 1029 + lib/isc/unix/ifiter_sysctl.c | 302 + lib/isc/unix/include/Makefile.in | 25 + lib/isc/unix/include/isc/Makefile.in | 38 + lib/isc/unix/include/isc/dir.h | 94 + lib/isc/unix/include/isc/int.h | 55 + lib/isc/unix/include/isc/keyboard.h | 52 + lib/isc/unix/include/isc/net.h | 348 + lib/isc/unix/include/isc/netdb.h | 57 + lib/isc/unix/include/isc/offset.h | 45 + lib/isc/unix/include/isc/stat.h | 52 + lib/isc/unix/include/isc/stdtime.h | 60 + lib/isc/unix/include/isc/strerror.h | 45 + lib/isc/unix/include/isc/syslog.h | 47 + lib/isc/unix/include/isc/time.h | 304 + lib/isc/unix/interfaceiter.c | 222 + lib/isc/unix/ipv6.c | 27 + lib/isc/unix/keyboard.c | 126 + lib/isc/unix/net.c | 367 + lib/isc/unix/os.c | 94 + lib/isc/unix/resource.c | 204 + lib/isc/unix/socket.c | 3836 +++ lib/isc/unix/socket_p.h | 35 + lib/isc/unix/stdio.c | 117 + lib/isc/unix/stdtime.c | 86 + lib/isc/unix/strerror.c | 74 + lib/isc/unix/syslog.c | 84 + lib/isc/unix/time.c | 414 + lib/isc/version.c | 28 + lib/isc/x86_32/Makefile.in | 24 + lib/isc/x86_32/include/Makefile.in | 24 + lib/isc/x86_32/include/isc/Makefile.in | 36 + lib/isc/x86_32/include/isc/atomic.h | 158 + lib/isc/x86_64/Makefile.in | 24 + lib/isc/x86_64/include/Makefile.in | 24 + lib/isc/x86_64/include/isc/Makefile.in | 36 + lib/isc/x86_64/include/isc/atomic.h | 103 + lib/isccc/Makefile.in | 86 + lib/isccc/alist.c | 299 + lib/isccc/api | 3 + lib/isccc/base64.c | 65 + lib/isccc/cc.c | 818 + lib/isccc/ccmsg.c | 222 + lib/isccc/include/Makefile.in | 25 + lib/isccc/include/isccc/Makefile.in | 42 + lib/isccc/include/isccc/alist.h | 74 + lib/isccc/include/isccc/base64.h | 72 + lib/isccc/include/isccc/cc.h | 109 + lib/isccc/include/isccc/ccmsg.h | 135 + lib/isccc/include/isccc/events.h | 37 + lib/isccc/include/isccc/lib.h | 42 + lib/isccc/include/isccc/result.h | 60 + lib/isccc/include/isccc/sexpr.h | 111 + lib/isccc/include/isccc/symtab.h | 122 + lib/isccc/include/isccc/symtype.h | 31 + lib/isccc/include/isccc/types.h | 46 + lib/isccc/include/isccc/util.h | 212 + lib/isccc/include/isccc/version.h | 28 + lib/isccc/lib.c | 65 + lib/isccc/result.c | 72 + lib/isccc/sexpr.c | 312 + lib/isccc/symtab.c | 280 + lib/isccc/version.c | 28 + lib/isccfg/Makefile.in | 83 + lib/isccfg/aclconf.c | 256 + lib/isccfg/api | 3 + lib/isccfg/include/Makefile.in | 25 + lib/isccfg/include/isccfg/Makefile.in | 42 + lib/isccfg/include/isccfg/aclconf.h | 73 + lib/isccfg/include/isccfg/cfg.h | 417 + lib/isccfg/include/isccfg/grammar.h | 452 + lib/isccfg/include/isccfg/log.h | 55 + lib/isccfg/include/isccfg/namedconf.h | 45 + lib/isccfg/include/isccfg/version.h | 28 + lib/isccfg/log.c | 52 + lib/isccfg/namedconf.c | 2049 ++ lib/isccfg/parser.c | 2382 ++ lib/isccfg/version.c | 29 + lib/lwres/Makefile.in | 84 + lib/lwres/api | 3 + lib/lwres/assert_p.h | 35 + lib/lwres/context.c | 482 + lib/lwres/context_p.h | 65 + lib/lwres/gai_strerror.c | 83 + lib/lwres/getaddrinfo.c | 808 + lib/lwres/gethost.c | 362 + lib/lwres/getipnode.c | 1148 + lib/lwres/getnameinfo.c | 346 + lib/lwres/getrrset.c | 288 + lib/lwres/herror.c | 122 + lib/lwres/include/Makefile.in | 25 + lib/lwres/include/lwres/Makefile.in | 46 + lib/lwres/include/lwres/context.h | 129 + lib/lwres/include/lwres/int.h | 34 + lib/lwres/include/lwres/ipv6.h | 124 + lib/lwres/include/lwres/lang.h | 33 + lib/lwres/include/lwres/list.h | 121 + lib/lwres/include/lwres/lwbuffer.h | 406 + lib/lwres/include/lwres/lwpacket.h | 159 + lib/lwres/include/lwres/lwres.h | 579 + lib/lwres/include/lwres/netdb.h.in | 520 + lib/lwres/include/lwres/platform.h.in | 120 + lib/lwres/include/lwres/result.h | 42 + lib/lwres/include/lwres/stdlib.h | 40 + lib/lwres/include/lwres/version.h | 28 + lib/lwres/lwbuffer.c | 361 + lib/lwres/lwconfig.c | 725 + lib/lwres/lwinetaton.c | 205 + lib/lwres/lwinetntop.c | 197 + lib/lwres/lwinetpton.c | 209 + lib/lwres/lwpacket.c | 129 + lib/lwres/lwres_gabn.c | 505 + lib/lwres/lwres_gnba.c | 415 + lib/lwres/lwres_grbn.c | 426 + lib/lwres/lwres_noop.c | 342 + lib/lwres/lwresutil.c | 576 + lib/lwres/man/Makefile.in | 232 + lib/lwres/man/lwres.3 | 165 + lib/lwres/man/lwres.docbook | 266 + lib/lwres/man/lwres.html | 218 + lib/lwres/man/lwres_buffer.3 | 233 + lib/lwres/man/lwres_buffer.docbook | 394 + lib/lwres/man/lwres_buffer.html | 455 + lib/lwres/man/lwres_config.3 | 106 + lib/lwres/man/lwres_config.docbook | 173 + lib/lwres/man/lwres_config.html | 156 + lib/lwres/man/lwres_context.3 | 170 + lib/lwres/man/lwres_context.docbook | 262 + lib/lwres/man/lwres_context.html | 295 + lib/lwres/man/lwres_gabn.3 | 195 + lib/lwres/man/lwres_gabn.docbook | 260 + lib/lwres/man/lwres_gabn.html | 324 + lib/lwres/man/lwres_gai_strerror.3 | 129 + lib/lwres/man/lwres_gai_strerror.docbook | 200 + lib/lwres/man/lwres_gai_strerror.html | 124 + lib/lwres/man/lwres_getaddrinfo.3 | 246 + lib/lwres/man/lwres_getaddrinfo.docbook | 387 + lib/lwres/man/lwres_getaddrinfo.html | 322 + lib/lwres/man/lwres_gethostent.3 | 315 + lib/lwres/man/lwres_gethostent.docbook | 439 + lib/lwres/man/lwres_gethostent.html | 466 + lib/lwres/man/lwres_getipnode.3 | 206 + lib/lwres/man/lwres_getipnode.docbook | 331 + lib/lwres/man/lwres_getipnode.html | 279 + lib/lwres/man/lwres_getnameinfo.3 | 117 + lib/lwres/man/lwres_getnameinfo.docbook | 205 + lib/lwres/man/lwres_getnameinfo.html | 176 + lib/lwres/man/lwres_getrrsetbyname.3 | 164 + lib/lwres/man/lwres_getrrsetbyname.docbook | 223 + lib/lwres/man/lwres_getrrsetbyname.html | 192 + lib/lwres/man/lwres_gnba.3 | 183 + lib/lwres/man/lwres_gnba.docbook | 261 + lib/lwres/man/lwres_gnba.html | 316 + lib/lwres/man/lwres_hstrerror.3 | 99 + lib/lwres/man/lwres_hstrerror.docbook | 152 + lib/lwres/man/lwres_hstrerror.html | 104 + lib/lwres/man/lwres_inetntop.3 | 77 + lib/lwres/man/lwres_inetntop.docbook | 120 + lib/lwres/man/lwres_inetntop.html | 103 + lib/lwres/man/lwres_noop.3 | 183 + lib/lwres/man/lwres_noop.docbook | 255 + lib/lwres/man/lwres_noop.html | 317 + lib/lwres/man/lwres_packet.3 | 170 + lib/lwres/man/lwres_packet.docbook | 291 + lib/lwres/man/lwres_packet.html | 235 + lib/lwres/man/lwres_resutil.3 | 170 + lib/lwres/man/lwres_resutil.docbook | 238 + lib/lwres/man/lwres_resutil.html | 258 + lib/lwres/print.c | 560 + lib/lwres/print_p.h | 86 + lib/lwres/strtoul.c | 135 + lib/lwres/unix/Makefile.in | 25 + lib/lwres/unix/include/Makefile.in | 25 + lib/lwres/unix/include/lwres/Makefile.in | 34 + lib/lwres/unix/include/lwres/net.h | 135 + lib/lwres/version.c | 28 + libtool.m4 | 6000 ++++ ltmain.sh | 6416 ++++ make/Makefile.in | 28 + make/includes.in | 48 + make/mkdep.in | 148 + make/rules.in | 232 + mkinstalldirs | 40 + version | 10 + 2358 files changed, 586393 insertions(+), 586393 deletions(-) create mode 100644 CHANGES create mode 100644 COPYRIGHT create mode 100644 FAQ create mode 100644 FAQ.xml create mode 100644 Makefile.in create mode 100644 README create mode 100644 README.idnkit create mode 100644 acconfig.h create mode 100644 bin/Makefile.in create mode 100644 bin/check/Makefile.in create mode 100644 bin/check/check-tool.c create mode 100644 bin/check/check-tool.h create mode 100644 bin/check/named-checkconf.8 create mode 100644 bin/check/named-checkconf.c create mode 100644 bin/check/named-checkconf.docbook create mode 100644 bin/check/named-checkconf.html create mode 100644 bin/check/named-checkzone.8 create mode 100644 bin/check/named-checkzone.c create mode 100644 bin/check/named-checkzone.docbook create mode 100644 bin/check/named-checkzone.html create mode 100644 bin/dig/Makefile.in create mode 100644 bin/dig/dig.1 create mode 100644 bin/dig/dig.c create mode 100644 bin/dig/dig.docbook create mode 100644 bin/dig/dig.html create mode 100644 bin/dig/dighost.c create mode 100644 bin/dig/host.1 create mode 100644 bin/dig/host.c create mode 100644 bin/dig/host.docbook create mode 100644 bin/dig/host.html create mode 100644 bin/dig/include/dig/dig.h create mode 100644 bin/dig/nslookup.1 create mode 100644 bin/dig/nslookup.c create mode 100644 bin/dig/nslookup.docbook create mode 100644 bin/dig/nslookup.html create mode 100644 bin/dnssec/Makefile.in create mode 100644 bin/dnssec/dnssec-keygen.8 create mode 100644 bin/dnssec/dnssec-keygen.c create mode 100644 bin/dnssec/dnssec-keygen.docbook create mode 100644 bin/dnssec/dnssec-keygen.html create mode 100644 bin/dnssec/dnssec-signzone.8 create mode 100644 bin/dnssec/dnssec-signzone.c create mode 100644 bin/dnssec/dnssec-signzone.docbook create mode 100644 bin/dnssec/dnssec-signzone.html create mode 100644 bin/dnssec/dnssectool.c create mode 100644 bin/dnssec/dnssectool.h create mode 100644 bin/named/Makefile.in create mode 100644 bin/named/builtin.c create mode 100644 bin/named/client.c create mode 100644 bin/named/config.c create mode 100644 bin/named/control.c create mode 100644 bin/named/controlconf.c create mode 100644 bin/named/include/named/builtin.h create mode 100644 bin/named/include/named/client.h create mode 100644 bin/named/include/named/config.h create mode 100644 bin/named/include/named/control.h create mode 100644 bin/named/include/named/globals.h create mode 100644 bin/named/include/named/interfacemgr.h create mode 100644 bin/named/include/named/listenlist.h create mode 100644 bin/named/include/named/log.h create mode 100644 bin/named/include/named/logconf.h create mode 100644 bin/named/include/named/lwaddr.h create mode 100644 bin/named/include/named/lwdclient.h create mode 100644 bin/named/include/named/lwresd.h create mode 100644 bin/named/include/named/lwsearch.h create mode 100644 bin/named/include/named/main.h create mode 100644 bin/named/include/named/notify.h create mode 100644 bin/named/include/named/ns_smf_globals.h create mode 100644 bin/named/include/named/query.h create mode 100644 bin/named/include/named/server.h create mode 100644 bin/named/include/named/sortlist.h create mode 100644 bin/named/include/named/tkeyconf.h create mode 100644 bin/named/include/named/tsigconf.h create mode 100644 bin/named/include/named/types.h create mode 100644 bin/named/include/named/update.h create mode 100644 bin/named/include/named/xfrout.h create mode 100644 bin/named/include/named/zoneconf.h create mode 100644 bin/named/interfacemgr.c create mode 100644 bin/named/listenlist.c create mode 100644 bin/named/log.c create mode 100644 bin/named/logconf.c create mode 100644 bin/named/lwaddr.c create mode 100644 bin/named/lwdclient.c create mode 100644 bin/named/lwderror.c create mode 100644 bin/named/lwdgabn.c create mode 100644 bin/named/lwdgnba.c create mode 100644 bin/named/lwdgrbn.c create mode 100644 bin/named/lwdnoop.c create mode 100644 bin/named/lwresd.8 create mode 100644 bin/named/lwresd.c create mode 100644 bin/named/lwresd.docbook create mode 100644 bin/named/lwresd.html create mode 100644 bin/named/lwsearch.c create mode 100644 bin/named/main.c create mode 100644 bin/named/named.8 create mode 100644 bin/named/named.conf.5 create mode 100644 bin/named/named.conf.docbook create mode 100644 bin/named/named.conf.html create mode 100644 bin/named/named.docbook create mode 100644 bin/named/named.html create mode 100644 bin/named/notify.c create mode 100644 bin/named/query.c create mode 100644 bin/named/server.c create mode 100644 bin/named/sortlist.c create mode 100644 bin/named/tkeyconf.c create mode 100644 bin/named/tsigconf.c create mode 100644 bin/named/unix/Makefile.in create mode 100644 bin/named/unix/include/named/os.h create mode 100644 bin/named/unix/os.c create mode 100644 bin/named/update.c create mode 100644 bin/named/xfrout.c create mode 100644 bin/named/zoneconf.c create mode 100644 bin/nsupdate/Makefile.in create mode 100644 bin/nsupdate/nsupdate.8 create mode 100644 bin/nsupdate/nsupdate.c create mode 100644 bin/nsupdate/nsupdate.docbook create mode 100644 bin/nsupdate/nsupdate.html create mode 100644 bin/rndc/Makefile.in create mode 100644 bin/rndc/include/rndc/os.h create mode 100644 bin/rndc/rndc-confgen.8 create mode 100644 bin/rndc/rndc-confgen.c create mode 100644 bin/rndc/rndc-confgen.docbook create mode 100644 bin/rndc/rndc-confgen.html create mode 100644 bin/rndc/rndc.8 create mode 100644 bin/rndc/rndc.c create mode 100644 bin/rndc/rndc.conf create mode 100644 bin/rndc/rndc.conf.5 create mode 100644 bin/rndc/rndc.conf.docbook create mode 100644 bin/rndc/rndc.conf.html create mode 100644 bin/rndc/rndc.docbook create mode 100644 bin/rndc/rndc.html create mode 100644 bin/rndc/unix/Makefile.in create mode 100644 bin/rndc/unix/os.c create mode 100644 bin/rndc/util.c create mode 100644 bin/rndc/util.h create mode 100644 config.guess create mode 100644 config.sub create mode 100644 config.threads.in create mode 100644 configure.in delete mode 100644 contrib/bind9/CHANGES delete mode 100644 contrib/bind9/COPYRIGHT delete mode 100644 contrib/bind9/FAQ delete mode 100644 contrib/bind9/FAQ.xml delete mode 100644 contrib/bind9/Makefile.in delete mode 100644 contrib/bind9/README delete mode 100644 contrib/bind9/README.idnkit delete mode 100644 contrib/bind9/acconfig.h delete mode 100644 contrib/bind9/bin/Makefile.in delete mode 100644 contrib/bind9/bin/check/Makefile.in delete mode 100644 contrib/bind9/bin/check/check-tool.c delete mode 100644 contrib/bind9/bin/check/check-tool.h delete mode 100644 contrib/bind9/bin/check/named-checkconf.8 delete mode 100644 contrib/bind9/bin/check/named-checkconf.c delete mode 100644 contrib/bind9/bin/check/named-checkconf.docbook delete mode 100644 contrib/bind9/bin/check/named-checkconf.html delete mode 100644 contrib/bind9/bin/check/named-checkzone.8 delete mode 100644 contrib/bind9/bin/check/named-checkzone.c delete mode 100644 contrib/bind9/bin/check/named-checkzone.docbook delete mode 100644 contrib/bind9/bin/check/named-checkzone.html delete mode 100644 contrib/bind9/bin/dig/Makefile.in delete mode 100644 contrib/bind9/bin/dig/dig.1 delete mode 100644 contrib/bind9/bin/dig/dig.c delete mode 100644 contrib/bind9/bin/dig/dig.docbook delete mode 100644 contrib/bind9/bin/dig/dig.html delete mode 100644 contrib/bind9/bin/dig/dighost.c delete mode 100644 contrib/bind9/bin/dig/host.1 delete mode 100644 contrib/bind9/bin/dig/host.c delete mode 100644 contrib/bind9/bin/dig/host.docbook delete mode 100644 contrib/bind9/bin/dig/host.html delete mode 100644 contrib/bind9/bin/dig/include/dig/dig.h delete mode 100644 contrib/bind9/bin/dig/nslookup.1 delete mode 100644 contrib/bind9/bin/dig/nslookup.c delete mode 100644 contrib/bind9/bin/dig/nslookup.docbook delete mode 100644 contrib/bind9/bin/dig/nslookup.html delete mode 100644 contrib/bind9/bin/dnssec/Makefile.in delete mode 100644 contrib/bind9/bin/dnssec/dnssec-keygen.8 delete mode 100644 contrib/bind9/bin/dnssec/dnssec-keygen.c delete mode 100644 contrib/bind9/bin/dnssec/dnssec-keygen.docbook delete mode 100644 contrib/bind9/bin/dnssec/dnssec-keygen.html delete mode 100644 contrib/bind9/bin/dnssec/dnssec-signzone.8 delete mode 100644 contrib/bind9/bin/dnssec/dnssec-signzone.c delete mode 100644 contrib/bind9/bin/dnssec/dnssec-signzone.docbook delete mode 100644 contrib/bind9/bin/dnssec/dnssec-signzone.html delete mode 100644 contrib/bind9/bin/dnssec/dnssectool.c delete mode 100644 contrib/bind9/bin/dnssec/dnssectool.h delete mode 100644 contrib/bind9/bin/named/Makefile.in delete mode 100644 contrib/bind9/bin/named/builtin.c delete mode 100644 contrib/bind9/bin/named/client.c delete mode 100644 contrib/bind9/bin/named/config.c delete mode 100644 contrib/bind9/bin/named/control.c delete mode 100644 contrib/bind9/bin/named/controlconf.c delete mode 100644 contrib/bind9/bin/named/include/named/builtin.h delete mode 100644 contrib/bind9/bin/named/include/named/client.h delete mode 100644 contrib/bind9/bin/named/include/named/config.h delete mode 100644 contrib/bind9/bin/named/include/named/control.h delete mode 100644 contrib/bind9/bin/named/include/named/globals.h delete mode 100644 contrib/bind9/bin/named/include/named/interfacemgr.h delete mode 100644 contrib/bind9/bin/named/include/named/listenlist.h delete mode 100644 contrib/bind9/bin/named/include/named/log.h delete mode 100644 contrib/bind9/bin/named/include/named/logconf.h delete mode 100644 contrib/bind9/bin/named/include/named/lwaddr.h delete mode 100644 contrib/bind9/bin/named/include/named/lwdclient.h delete mode 100644 contrib/bind9/bin/named/include/named/lwresd.h delete mode 100644 contrib/bind9/bin/named/include/named/lwsearch.h delete mode 100644 contrib/bind9/bin/named/include/named/main.h delete mode 100644 contrib/bind9/bin/named/include/named/notify.h delete mode 100644 contrib/bind9/bin/named/include/named/ns_smf_globals.h delete mode 100644 contrib/bind9/bin/named/include/named/query.h delete mode 100644 contrib/bind9/bin/named/include/named/server.h delete mode 100644 contrib/bind9/bin/named/include/named/sortlist.h delete mode 100644 contrib/bind9/bin/named/include/named/tkeyconf.h delete mode 100644 contrib/bind9/bin/named/include/named/tsigconf.h delete mode 100644 contrib/bind9/bin/named/include/named/types.h delete mode 100644 contrib/bind9/bin/named/include/named/update.h delete mode 100644 contrib/bind9/bin/named/include/named/xfrout.h delete mode 100644 contrib/bind9/bin/named/include/named/zoneconf.h delete mode 100644 contrib/bind9/bin/named/interfacemgr.c delete mode 100644 contrib/bind9/bin/named/listenlist.c delete mode 100644 contrib/bind9/bin/named/log.c delete mode 100644 contrib/bind9/bin/named/logconf.c delete mode 100644 contrib/bind9/bin/named/lwaddr.c delete mode 100644 contrib/bind9/bin/named/lwdclient.c delete mode 100644 contrib/bind9/bin/named/lwderror.c delete mode 100644 contrib/bind9/bin/named/lwdgabn.c delete mode 100644 contrib/bind9/bin/named/lwdgnba.c delete mode 100644 contrib/bind9/bin/named/lwdgrbn.c delete mode 100644 contrib/bind9/bin/named/lwdnoop.c delete mode 100644 contrib/bind9/bin/named/lwresd.8 delete mode 100644 contrib/bind9/bin/named/lwresd.c delete mode 100644 contrib/bind9/bin/named/lwresd.docbook delete mode 100644 contrib/bind9/bin/named/lwresd.html delete mode 100644 contrib/bind9/bin/named/lwsearch.c delete mode 100644 contrib/bind9/bin/named/main.c delete mode 100644 contrib/bind9/bin/named/named.8 delete mode 100644 contrib/bind9/bin/named/named.conf.5 delete mode 100644 contrib/bind9/bin/named/named.conf.docbook delete mode 100644 contrib/bind9/bin/named/named.conf.html delete mode 100644 contrib/bind9/bin/named/named.docbook delete mode 100644 contrib/bind9/bin/named/named.html delete mode 100644 contrib/bind9/bin/named/notify.c delete mode 100644 contrib/bind9/bin/named/query.c delete mode 100644 contrib/bind9/bin/named/server.c delete mode 100644 contrib/bind9/bin/named/sortlist.c delete mode 100644 contrib/bind9/bin/named/tkeyconf.c delete mode 100644 contrib/bind9/bin/named/tsigconf.c delete mode 100644 contrib/bind9/bin/named/unix/Makefile.in delete mode 100644 contrib/bind9/bin/named/unix/include/named/os.h delete mode 100644 contrib/bind9/bin/named/unix/os.c delete mode 100644 contrib/bind9/bin/named/update.c delete mode 100644 contrib/bind9/bin/named/xfrout.c delete mode 100644 contrib/bind9/bin/named/zoneconf.c delete mode 100644 contrib/bind9/bin/nsupdate/Makefile.in delete mode 100644 contrib/bind9/bin/nsupdate/nsupdate.8 delete mode 100644 contrib/bind9/bin/nsupdate/nsupdate.c delete mode 100644 contrib/bind9/bin/nsupdate/nsupdate.docbook delete mode 100644 contrib/bind9/bin/nsupdate/nsupdate.html delete mode 100644 contrib/bind9/bin/rndc/Makefile.in delete mode 100644 contrib/bind9/bin/rndc/include/rndc/os.h delete mode 100644 contrib/bind9/bin/rndc/rndc-confgen.8 delete mode 100644 contrib/bind9/bin/rndc/rndc-confgen.c delete mode 100644 contrib/bind9/bin/rndc/rndc-confgen.docbook delete mode 100644 contrib/bind9/bin/rndc/rndc-confgen.html delete mode 100644 contrib/bind9/bin/rndc/rndc.8 delete mode 100644 contrib/bind9/bin/rndc/rndc.c delete mode 100644 contrib/bind9/bin/rndc/rndc.conf delete mode 100644 contrib/bind9/bin/rndc/rndc.conf.5 delete mode 100644 contrib/bind9/bin/rndc/rndc.conf.docbook delete mode 100644 contrib/bind9/bin/rndc/rndc.conf.html delete mode 100644 contrib/bind9/bin/rndc/rndc.docbook delete mode 100644 contrib/bind9/bin/rndc/rndc.html delete mode 100644 contrib/bind9/bin/rndc/unix/Makefile.in delete mode 100644 contrib/bind9/bin/rndc/unix/os.c delete mode 100644 contrib/bind9/bin/rndc/util.c delete mode 100644 contrib/bind9/bin/rndc/util.h delete mode 100644 contrib/bind9/config.guess delete mode 100644 contrib/bind9/config.sub delete mode 100644 contrib/bind9/config.threads.in delete mode 100644 contrib/bind9/configure.in delete mode 100644 contrib/bind9/doc/Makefile.in delete mode 100644 contrib/bind9/doc/arm/Bv9ARM-book.xml delete mode 100644 contrib/bind9/doc/arm/Bv9ARM.ch01.html delete mode 100644 contrib/bind9/doc/arm/Bv9ARM.ch02.html delete mode 100644 contrib/bind9/doc/arm/Bv9ARM.ch03.html delete mode 100644 contrib/bind9/doc/arm/Bv9ARM.ch04.html delete mode 100644 contrib/bind9/doc/arm/Bv9ARM.ch05.html delete mode 100644 contrib/bind9/doc/arm/Bv9ARM.ch06.html delete mode 100644 contrib/bind9/doc/arm/Bv9ARM.ch07.html delete mode 100644 contrib/bind9/doc/arm/Bv9ARM.ch08.html delete mode 100644 contrib/bind9/doc/arm/Bv9ARM.ch09.html delete mode 100644 contrib/bind9/doc/arm/Bv9ARM.ch10.html delete mode 100644 contrib/bind9/doc/arm/Bv9ARM.html delete mode 100755 contrib/bind9/doc/arm/Bv9ARM.pdf delete mode 100644 contrib/bind9/doc/arm/Makefile.in delete mode 100644 contrib/bind9/doc/arm/README-SGML delete mode 100644 contrib/bind9/doc/arm/isc-logo.eps delete mode 100644 contrib/bind9/doc/arm/isc-logo.pdf delete mode 100644 contrib/bind9/doc/arm/man.dig.html delete mode 100644 contrib/bind9/doc/arm/man.dnssec-keygen.html delete mode 100644 contrib/bind9/doc/arm/man.dnssec-signzone.html delete mode 100644 contrib/bind9/doc/arm/man.host.html delete mode 100644 contrib/bind9/doc/arm/man.named-checkconf.html delete mode 100644 contrib/bind9/doc/arm/man.named-checkzone.html delete mode 100644 contrib/bind9/doc/arm/man.named.html delete mode 100644 contrib/bind9/doc/arm/man.rndc-confgen.html delete mode 100644 contrib/bind9/doc/arm/man.rndc.conf.html delete mode 100644 contrib/bind9/doc/arm/man.rndc.html delete mode 100644 contrib/bind9/doc/draft/draft-baba-dnsext-acl-reqts-01.txt delete mode 100644 contrib/bind9/doc/draft/draft-daigle-napstr-04.txt delete mode 100644 contrib/bind9/doc/draft/draft-danisch-dns-rr-smtp-03.txt delete mode 100644 contrib/bind9/doc/draft/draft-dnsext-opcode-discover-02.txt delete mode 100644 contrib/bind9/doc/draft/draft-durand-dnsop-dynreverse-00.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-2929bis-01.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-axfr-clarify-05.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-dhcid-rr-12.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-dns-name-p-s-00.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-2535typecode-change-06.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-bis-updates-01.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-experiments-01.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-online-signing-02.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-opt-in-07.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-rsasha256-00.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-trans-02.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-ds-sha256-05.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-ecc-key-07.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-interop3597-02.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-keyrr-key-signing-flag-12.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-mdns-43.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-nsec3-04.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-nsid-01.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-rfc2536bis-dsa-06.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-rfc2538bis-04.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-rfc2539bis-dhk-06.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-signed-nonexistence-requirements-01.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-tkey-renewal-mode-05.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-trustupdate-threshold-00.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-trustupdate-timers-02.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-tsig-sha-06.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsext-wcard-clarify-10.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsop-bad-dns-res-05.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsop-dnssec-operational-practices-08.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsop-inaddr-required-07.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsop-ipv6-dns-configuration-06.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsop-ipv6-dns-issues-11.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsop-ipv6-transport-guidelines-01.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsop-key-rollover-requirements-02.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsop-respsize-02.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-dnsop-serverid-06.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-enum-e164-gstn-np-05.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-ipv6-node-requirements-08.txt delete mode 100644 contrib/bind9/doc/draft/draft-ietf-secsh-dns-05.txt delete mode 100644 contrib/bind9/doc/draft/draft-ihren-dnsext-threshold-validation-00.txt delete mode 100644 contrib/bind9/doc/draft/draft-kato-dnsop-local-zones-00.txt delete mode 100644 contrib/bind9/doc/draft/draft-park-ipv6-extensions-dns-pnp-00.txt delete mode 100644 contrib/bind9/doc/draft/update delete mode 100644 contrib/bind9/doc/misc/Makefile.in delete mode 100644 contrib/bind9/doc/misc/dnssec delete mode 100644 contrib/bind9/doc/misc/format-options.pl delete mode 100644 contrib/bind9/doc/misc/ipv6 delete mode 100644 contrib/bind9/doc/misc/migration delete mode 100644 contrib/bind9/doc/misc/migration-4to9 delete mode 100644 contrib/bind9/doc/misc/options delete mode 100644 contrib/bind9/doc/misc/rfc-compliance delete mode 100644 contrib/bind9/doc/misc/roadmap delete mode 100644 contrib/bind9/doc/misc/sdb delete mode 100644 contrib/bind9/doc/rfc/index delete mode 100644 contrib/bind9/doc/rfc/rfc1032.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1033.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1034.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1035.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1101.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1122.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1123.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1183.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1348.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1535.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1536.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1537.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1591.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1611.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1612.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1706.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1712.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1750.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1876.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1886.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1982.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1995.txt delete mode 100644 contrib/bind9/doc/rfc/rfc1996.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2052.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2104.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2119.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2133.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2136.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2137.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2163.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2168.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2181.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2230.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2308.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2317.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2373.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2374.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2375.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2418.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2535.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2536.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2537.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2538.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2539.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2540.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2541.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2553.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2671.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2672.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2673.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2782.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2825.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2826.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2845.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2874.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2915.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2929.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2930.txt delete mode 100644 contrib/bind9/doc/rfc/rfc2931.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3007.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3008.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3071.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3090.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3110.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3123.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3152.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3197.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3225.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3226.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3258.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3363.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3364.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3425.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3445.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3467.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3490.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3491.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3492.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3493.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3513.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3596.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3597.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3645.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3655.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3658.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3757.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3833.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3845.txt delete mode 100644 contrib/bind9/doc/rfc/rfc3901.txt delete mode 100644 contrib/bind9/doc/rfc/rfc4025.txt delete mode 100644 contrib/bind9/doc/rfc/rfc4033.txt delete mode 100644 contrib/bind9/doc/rfc/rfc4034.txt delete mode 100644 contrib/bind9/doc/rfc/rfc4035.txt delete mode 100644 contrib/bind9/doc/rfc/rfc4074.txt delete mode 100644 contrib/bind9/doc/rfc/rfc4159.txt delete mode 100644 contrib/bind9/doc/rfc/rfc4193.txt delete mode 100644 contrib/bind9/doc/rfc/rfc4255.txt delete mode 100644 contrib/bind9/doc/rfc/rfc4343.txt delete mode 100644 contrib/bind9/doc/rfc/rfc4367.txt delete mode 100644 contrib/bind9/doc/rfc/rfc4398.txt delete mode 100644 contrib/bind9/doc/rfc/rfc4408.txt delete mode 100644 contrib/bind9/doc/rfc/rfc4431.txt delete mode 100644 contrib/bind9/doc/rfc/rfc4470.txt delete mode 100644 contrib/bind9/doc/rfc/rfc4634.txt delete mode 100644 contrib/bind9/doc/rfc/rfc4641.txt delete mode 100644 contrib/bind9/doc/rfc/rfc952.txt delete mode 100755 contrib/bind9/install-sh delete mode 100644 contrib/bind9/isc-config.sh.in delete mode 100644 contrib/bind9/lib/Makefile.in delete mode 100644 contrib/bind9/lib/bind/Makefile.in delete mode 100644 contrib/bind9/lib/bind/README delete mode 100644 contrib/bind9/lib/bind/aclocal.m4 delete mode 100644 contrib/bind9/lib/bind/api delete mode 100644 contrib/bind9/lib/bind/bsd/Makefile.in delete mode 100644 contrib/bind9/lib/bind/bsd/daemon.c delete mode 100644 contrib/bind9/lib/bind/bsd/ftruncate.c delete mode 100644 contrib/bind9/lib/bind/bsd/gettimeofday.c delete mode 100644 contrib/bind9/lib/bind/bsd/mktemp.c delete mode 100644 contrib/bind9/lib/bind/bsd/putenv.c delete mode 100644 contrib/bind9/lib/bind/bsd/readv.c delete mode 100644 contrib/bind9/lib/bind/bsd/setenv.c delete mode 100644 contrib/bind9/lib/bind/bsd/setitimer.c delete mode 100644 contrib/bind9/lib/bind/bsd/strcasecmp.c delete mode 100644 contrib/bind9/lib/bind/bsd/strdup.c delete mode 100644 contrib/bind9/lib/bind/bsd/strerror.c delete mode 100644 contrib/bind9/lib/bind/bsd/strpbrk.c delete mode 100644 contrib/bind9/lib/bind/bsd/strsep.c delete mode 100644 contrib/bind9/lib/bind/bsd/strtoul.c delete mode 100644 contrib/bind9/lib/bind/bsd/utimes.c delete mode 100644 contrib/bind9/lib/bind/bsd/writev.c delete mode 100644 contrib/bind9/lib/bind/config.h.in delete mode 100755 contrib/bind9/lib/bind/configure delete mode 100644 contrib/bind9/lib/bind/configure.in delete mode 100644 contrib/bind9/lib/bind/dst/Makefile.in delete mode 100644 contrib/bind9/lib/bind/dst/dst_api.c delete mode 100644 contrib/bind9/lib/bind/dst/dst_internal.h delete mode 100644 contrib/bind9/lib/bind/dst/hmac_link.c delete mode 100644 contrib/bind9/lib/bind/dst/md5.h delete mode 100644 contrib/bind9/lib/bind/dst/md5_dgst.c delete mode 100644 contrib/bind9/lib/bind/dst/md5_locl.h delete mode 100644 contrib/bind9/lib/bind/dst/support.c delete mode 100644 contrib/bind9/lib/bind/include/Makefile.in delete mode 100644 contrib/bind9/lib/bind/include/arpa/inet.h delete mode 100644 contrib/bind9/lib/bind/include/arpa/nameser.h delete mode 100644 contrib/bind9/lib/bind/include/arpa/nameser_compat.h delete mode 100644 contrib/bind9/lib/bind/include/fd_setsize.h delete mode 100644 contrib/bind9/lib/bind/include/hesiod.h delete mode 100644 contrib/bind9/lib/bind/include/irp.h delete mode 100644 contrib/bind9/lib/bind/include/irs.h delete mode 100644 contrib/bind9/lib/bind/include/isc/assertions.h delete mode 100644 contrib/bind9/lib/bind/include/isc/ctl.h delete mode 100644 contrib/bind9/lib/bind/include/isc/dst.h delete mode 100644 contrib/bind9/lib/bind/include/isc/eventlib.h delete mode 100644 contrib/bind9/lib/bind/include/isc/heap.h delete mode 100644 contrib/bind9/lib/bind/include/isc/irpmarshall.h delete mode 100644 contrib/bind9/lib/bind/include/isc/list.h delete mode 100644 contrib/bind9/lib/bind/include/isc/logging.h delete mode 100644 contrib/bind9/lib/bind/include/isc/memcluster.h delete mode 100644 contrib/bind9/lib/bind/include/isc/misc.h delete mode 100644 contrib/bind9/lib/bind/include/isc/tree.h delete mode 100644 contrib/bind9/lib/bind/include/netdb.h delete mode 100644 contrib/bind9/lib/bind/include/netgroup.h delete mode 100644 contrib/bind9/lib/bind/include/res_update.h delete mode 100644 contrib/bind9/lib/bind/include/resolv.h delete mode 100644 contrib/bind9/lib/bind/include/resolv_mt.h delete mode 100644 contrib/bind9/lib/bind/inet/Makefile.in delete mode 100644 contrib/bind9/lib/bind/inet/inet_addr.c delete mode 100644 contrib/bind9/lib/bind/inet/inet_cidr_ntop.c delete mode 100644 contrib/bind9/lib/bind/inet/inet_cidr_pton.c delete mode 100644 contrib/bind9/lib/bind/inet/inet_data.c delete mode 100644 contrib/bind9/lib/bind/inet/inet_lnaof.c delete mode 100644 contrib/bind9/lib/bind/inet/inet_makeaddr.c delete mode 100644 contrib/bind9/lib/bind/inet/inet_net_ntop.c delete mode 100644 contrib/bind9/lib/bind/inet/inet_net_pton.c delete mode 100644 contrib/bind9/lib/bind/inet/inet_neta.c delete mode 100644 contrib/bind9/lib/bind/inet/inet_netof.c delete mode 100644 contrib/bind9/lib/bind/inet/inet_network.c delete mode 100644 contrib/bind9/lib/bind/inet/inet_ntoa.c delete mode 100644 contrib/bind9/lib/bind/inet/inet_ntop.c delete mode 100644 contrib/bind9/lib/bind/inet/inet_pton.c delete mode 100644 contrib/bind9/lib/bind/inet/nsap_addr.c delete mode 100644 contrib/bind9/lib/bind/irs/Makefile.in delete mode 100644 contrib/bind9/lib/bind/irs/dns.c delete mode 100644 contrib/bind9/lib/bind/irs/dns_gr.c delete mode 100644 contrib/bind9/lib/bind/irs/dns_ho.c delete mode 100644 contrib/bind9/lib/bind/irs/dns_nw.c delete mode 100644 contrib/bind9/lib/bind/irs/dns_p.h delete mode 100644 contrib/bind9/lib/bind/irs/dns_pr.c delete mode 100644 contrib/bind9/lib/bind/irs/dns_pw.c delete mode 100644 contrib/bind9/lib/bind/irs/dns_sv.c delete mode 100644 contrib/bind9/lib/bind/irs/gai_strerror.c delete mode 100644 contrib/bind9/lib/bind/irs/gen.c delete mode 100644 contrib/bind9/lib/bind/irs/gen_gr.c delete mode 100644 contrib/bind9/lib/bind/irs/gen_ho.c delete mode 100644 contrib/bind9/lib/bind/irs/gen_ng.c delete mode 100644 contrib/bind9/lib/bind/irs/gen_nw.c delete mode 100644 contrib/bind9/lib/bind/irs/gen_p.h delete mode 100644 contrib/bind9/lib/bind/irs/gen_pr.c delete mode 100644 contrib/bind9/lib/bind/irs/gen_pw.c delete mode 100644 contrib/bind9/lib/bind/irs/gen_sv.c delete mode 100644 contrib/bind9/lib/bind/irs/getaddrinfo.c delete mode 100644 contrib/bind9/lib/bind/irs/getgrent.c delete mode 100644 contrib/bind9/lib/bind/irs/getgrent_r.c delete mode 100644 contrib/bind9/lib/bind/irs/gethostent.c delete mode 100644 contrib/bind9/lib/bind/irs/gethostent_r.c delete mode 100644 contrib/bind9/lib/bind/irs/getnameinfo.c delete mode 100644 contrib/bind9/lib/bind/irs/getnetent.c delete mode 100644 contrib/bind9/lib/bind/irs/getnetent_r.c delete mode 100644 contrib/bind9/lib/bind/irs/getnetgrent.c delete mode 100644 contrib/bind9/lib/bind/irs/getnetgrent_r.c delete mode 100644 contrib/bind9/lib/bind/irs/getprotoent.c delete mode 100644 contrib/bind9/lib/bind/irs/getprotoent_r.c delete mode 100644 contrib/bind9/lib/bind/irs/getpwent.c delete mode 100644 contrib/bind9/lib/bind/irs/getpwent_r.c delete mode 100644 contrib/bind9/lib/bind/irs/getservent.c delete mode 100644 contrib/bind9/lib/bind/irs/getservent_r.c delete mode 100644 contrib/bind9/lib/bind/irs/hesiod.c delete mode 100644 contrib/bind9/lib/bind/irs/hesiod_p.h delete mode 100644 contrib/bind9/lib/bind/irs/irp.c delete mode 100644 contrib/bind9/lib/bind/irs/irp_gr.c delete mode 100644 contrib/bind9/lib/bind/irs/irp_ho.c delete mode 100644 contrib/bind9/lib/bind/irs/irp_ng.c delete mode 100644 contrib/bind9/lib/bind/irs/irp_nw.c delete mode 100644 contrib/bind9/lib/bind/irs/irp_p.h delete mode 100644 contrib/bind9/lib/bind/irs/irp_pr.c delete mode 100644 contrib/bind9/lib/bind/irs/irp_pw.c delete mode 100644 contrib/bind9/lib/bind/irs/irp_sv.c delete mode 100644 contrib/bind9/lib/bind/irs/irpmarshall.c delete mode 100644 contrib/bind9/lib/bind/irs/irs_data.c delete mode 100644 contrib/bind9/lib/bind/irs/irs_data.h delete mode 100644 contrib/bind9/lib/bind/irs/irs_p.h delete mode 100644 contrib/bind9/lib/bind/irs/lcl.c delete mode 100644 contrib/bind9/lib/bind/irs/lcl_gr.c delete mode 100644 contrib/bind9/lib/bind/irs/lcl_ho.c delete mode 100644 contrib/bind9/lib/bind/irs/lcl_ng.c delete mode 100644 contrib/bind9/lib/bind/irs/lcl_nw.c delete mode 100644 contrib/bind9/lib/bind/irs/lcl_p.h delete mode 100644 contrib/bind9/lib/bind/irs/lcl_pr.c delete mode 100644 contrib/bind9/lib/bind/irs/lcl_pw.c delete mode 100644 contrib/bind9/lib/bind/irs/lcl_sv.c delete mode 100644 contrib/bind9/lib/bind/irs/nis.c delete mode 100644 contrib/bind9/lib/bind/irs/nis_gr.c delete mode 100644 contrib/bind9/lib/bind/irs/nis_ho.c delete mode 100644 contrib/bind9/lib/bind/irs/nis_ng.c delete mode 100644 contrib/bind9/lib/bind/irs/nis_nw.c delete mode 100644 contrib/bind9/lib/bind/irs/nis_p.h delete mode 100644 contrib/bind9/lib/bind/irs/nis_pr.c delete mode 100644 contrib/bind9/lib/bind/irs/nis_pw.c delete mode 100644 contrib/bind9/lib/bind/irs/nis_sv.c delete mode 100644 contrib/bind9/lib/bind/irs/nul_ng.c delete mode 100644 contrib/bind9/lib/bind/irs/pathnames.h delete mode 100644 contrib/bind9/lib/bind/irs/util.c delete mode 100644 contrib/bind9/lib/bind/isc/Makefile.in delete mode 100644 contrib/bind9/lib/bind/isc/assertions.c delete mode 100644 contrib/bind9/lib/bind/isc/assertions.mdoc delete mode 100644 contrib/bind9/lib/bind/isc/base64.c delete mode 100644 contrib/bind9/lib/bind/isc/bitncmp.c delete mode 100644 contrib/bind9/lib/bind/isc/bitncmp.mdoc delete mode 100644 contrib/bind9/lib/bind/isc/ctl_clnt.c delete mode 100644 contrib/bind9/lib/bind/isc/ctl_p.c delete mode 100644 contrib/bind9/lib/bind/isc/ctl_p.h delete mode 100644 contrib/bind9/lib/bind/isc/ctl_srvr.c delete mode 100644 contrib/bind9/lib/bind/isc/ev_connects.c delete mode 100644 contrib/bind9/lib/bind/isc/ev_files.c delete mode 100644 contrib/bind9/lib/bind/isc/ev_streams.c delete mode 100644 contrib/bind9/lib/bind/isc/ev_timers.c delete mode 100644 contrib/bind9/lib/bind/isc/ev_waits.c delete mode 100644 contrib/bind9/lib/bind/isc/eventlib.c delete mode 100644 contrib/bind9/lib/bind/isc/eventlib.mdoc delete mode 100644 contrib/bind9/lib/bind/isc/eventlib_p.h delete mode 100644 contrib/bind9/lib/bind/isc/heap.c delete mode 100644 contrib/bind9/lib/bind/isc/heap.mdoc delete mode 100644 contrib/bind9/lib/bind/isc/hex.c delete mode 100644 contrib/bind9/lib/bind/isc/logging.c delete mode 100644 contrib/bind9/lib/bind/isc/logging.mdoc delete mode 100644 contrib/bind9/lib/bind/isc/logging_p.h delete mode 100644 contrib/bind9/lib/bind/isc/memcluster.c delete mode 100644 contrib/bind9/lib/bind/isc/memcluster.mdoc delete mode 100644 contrib/bind9/lib/bind/isc/movefile.c delete mode 100644 contrib/bind9/lib/bind/isc/tree.c delete mode 100644 contrib/bind9/lib/bind/isc/tree.mdoc delete mode 100644 contrib/bind9/lib/bind/make/includes.in delete mode 100644 contrib/bind9/lib/bind/make/mkdep.in delete mode 100644 contrib/bind9/lib/bind/make/rules.in delete mode 100755 contrib/bind9/lib/bind/mkinstalldirs delete mode 100644 contrib/bind9/lib/bind/nameser/Makefile.in delete mode 100644 contrib/bind9/lib/bind/nameser/ns_date.c delete mode 100644 contrib/bind9/lib/bind/nameser/ns_name.c delete mode 100644 contrib/bind9/lib/bind/nameser/ns_netint.c delete mode 100644 contrib/bind9/lib/bind/nameser/ns_parse.c delete mode 100644 contrib/bind9/lib/bind/nameser/ns_print.c delete mode 100644 contrib/bind9/lib/bind/nameser/ns_samedomain.c delete mode 100644 contrib/bind9/lib/bind/nameser/ns_sign.c delete mode 100644 contrib/bind9/lib/bind/nameser/ns_ttl.c delete mode 100644 contrib/bind9/lib/bind/nameser/ns_verify.c delete mode 100644 contrib/bind9/lib/bind/port/Makefile.in delete mode 100644 contrib/bind9/lib/bind/port/freebsd/Makefile.in delete mode 100644 contrib/bind9/lib/bind/port/freebsd/include/Makefile.in delete mode 100644 contrib/bind9/lib/bind/port/freebsd/include/sys/bitypes.h delete mode 100644 contrib/bind9/lib/bind/port_after.h.in delete mode 100644 contrib/bind9/lib/bind/port_before.h.in delete mode 100644 contrib/bind9/lib/bind/resolv/Makefile.in delete mode 100644 contrib/bind9/lib/bind/resolv/herror.c delete mode 100644 contrib/bind9/lib/bind/resolv/mtctxres.c delete mode 100644 contrib/bind9/lib/bind/resolv/res_comp.c delete mode 100644 contrib/bind9/lib/bind/resolv/res_data.c delete mode 100644 contrib/bind9/lib/bind/resolv/res_debug.c delete mode 100644 contrib/bind9/lib/bind/resolv/res_debug.h delete mode 100644 contrib/bind9/lib/bind/resolv/res_findzonecut.c delete mode 100644 contrib/bind9/lib/bind/resolv/res_init.c delete mode 100644 contrib/bind9/lib/bind/resolv/res_mkquery.c delete mode 100644 contrib/bind9/lib/bind/resolv/res_mkupdate.c delete mode 100644 contrib/bind9/lib/bind/resolv/res_mkupdate.h delete mode 100644 contrib/bind9/lib/bind/resolv/res_private.h delete mode 100644 contrib/bind9/lib/bind/resolv/res_query.c delete mode 100644 contrib/bind9/lib/bind/resolv/res_send.c delete mode 100644 contrib/bind9/lib/bind/resolv/res_sendsigned.c delete mode 100644 contrib/bind9/lib/bind/resolv/res_update.c delete mode 100644 contrib/bind9/lib/bind9/Makefile.in delete mode 100644 contrib/bind9/lib/bind9/api delete mode 100644 contrib/bind9/lib/bind9/check.c delete mode 100644 contrib/bind9/lib/bind9/getaddresses.c delete mode 100644 contrib/bind9/lib/bind9/include/Makefile.in delete mode 100644 contrib/bind9/lib/bind9/include/bind9/Makefile.in delete mode 100644 contrib/bind9/lib/bind9/include/bind9/check.h delete mode 100644 contrib/bind9/lib/bind9/include/bind9/getaddresses.h delete mode 100644 contrib/bind9/lib/bind9/include/bind9/version.h delete mode 100644 contrib/bind9/lib/bind9/version.c delete mode 100644 contrib/bind9/lib/dns/Makefile.in delete mode 100644 contrib/bind9/lib/dns/acache.c delete mode 100644 contrib/bind9/lib/dns/acl.c delete mode 100644 contrib/bind9/lib/dns/adb.c delete mode 100644 contrib/bind9/lib/dns/api delete mode 100644 contrib/bind9/lib/dns/byaddr.c delete mode 100644 contrib/bind9/lib/dns/cache.c delete mode 100644 contrib/bind9/lib/dns/callbacks.c delete mode 100644 contrib/bind9/lib/dns/compress.c delete mode 100644 contrib/bind9/lib/dns/db.c delete mode 100644 contrib/bind9/lib/dns/dbiterator.c delete mode 100644 contrib/bind9/lib/dns/dbtable.c delete mode 100644 contrib/bind9/lib/dns/diff.c delete mode 100644 contrib/bind9/lib/dns/dispatch.c delete mode 100644 contrib/bind9/lib/dns/dlz.c delete mode 100644 contrib/bind9/lib/dns/dnssec.c delete mode 100644 contrib/bind9/lib/dns/ds.c delete mode 100644 contrib/bind9/lib/dns/dst_api.c delete mode 100644 contrib/bind9/lib/dns/dst_internal.h delete mode 100644 contrib/bind9/lib/dns/dst_lib.c delete mode 100644 contrib/bind9/lib/dns/dst_openssl.h delete mode 100644 contrib/bind9/lib/dns/dst_parse.c delete mode 100644 contrib/bind9/lib/dns/dst_parse.h delete mode 100644 contrib/bind9/lib/dns/dst_result.c delete mode 100644 contrib/bind9/lib/dns/forward.c delete mode 100644 contrib/bind9/lib/dns/gen-unix.h delete mode 100644 contrib/bind9/lib/dns/gen.c delete mode 100644 contrib/bind9/lib/dns/gssapi_link.c delete mode 100644 contrib/bind9/lib/dns/gssapictx.c delete mode 100644 contrib/bind9/lib/dns/hmac_link.c delete mode 100644 contrib/bind9/lib/dns/include/Makefile.in delete mode 100644 contrib/bind9/lib/dns/include/dns/Makefile.in delete mode 100644 contrib/bind9/lib/dns/include/dns/acache.h delete mode 100644 contrib/bind9/lib/dns/include/dns/acl.h delete mode 100644 contrib/bind9/lib/dns/include/dns/adb.h delete mode 100644 contrib/bind9/lib/dns/include/dns/bit.h delete mode 100644 contrib/bind9/lib/dns/include/dns/byaddr.h delete mode 100644 contrib/bind9/lib/dns/include/dns/cache.h delete mode 100644 contrib/bind9/lib/dns/include/dns/callbacks.h delete mode 100644 contrib/bind9/lib/dns/include/dns/cert.h delete mode 100644 contrib/bind9/lib/dns/include/dns/compress.h delete mode 100644 contrib/bind9/lib/dns/include/dns/db.h delete mode 100644 contrib/bind9/lib/dns/include/dns/dbiterator.h delete mode 100644 contrib/bind9/lib/dns/include/dns/dbtable.h delete mode 100644 contrib/bind9/lib/dns/include/dns/diff.h delete mode 100644 contrib/bind9/lib/dns/include/dns/dispatch.h delete mode 100644 contrib/bind9/lib/dns/include/dns/dlz.h delete mode 100644 contrib/bind9/lib/dns/include/dns/dnssec.h delete mode 100644 contrib/bind9/lib/dns/include/dns/ds.h delete mode 100644 contrib/bind9/lib/dns/include/dns/events.h delete mode 100644 contrib/bind9/lib/dns/include/dns/fixedname.h delete mode 100644 contrib/bind9/lib/dns/include/dns/forward.h delete mode 100644 contrib/bind9/lib/dns/include/dns/journal.h delete mode 100644 contrib/bind9/lib/dns/include/dns/keyflags.h delete mode 100644 contrib/bind9/lib/dns/include/dns/keytable.h delete mode 100644 contrib/bind9/lib/dns/include/dns/keyvalues.h delete mode 100644 contrib/bind9/lib/dns/include/dns/lib.h delete mode 100644 contrib/bind9/lib/dns/include/dns/log.h delete mode 100644 contrib/bind9/lib/dns/include/dns/lookup.h delete mode 100644 contrib/bind9/lib/dns/include/dns/master.h delete mode 100644 contrib/bind9/lib/dns/include/dns/masterdump.h delete mode 100644 contrib/bind9/lib/dns/include/dns/message.h delete mode 100644 contrib/bind9/lib/dns/include/dns/name.h delete mode 100644 contrib/bind9/lib/dns/include/dns/ncache.h delete mode 100644 contrib/bind9/lib/dns/include/dns/nsec.h delete mode 100644 contrib/bind9/lib/dns/include/dns/opcode.h delete mode 100644 contrib/bind9/lib/dns/include/dns/order.h delete mode 100644 contrib/bind9/lib/dns/include/dns/peer.h delete mode 100644 contrib/bind9/lib/dns/include/dns/portlist.h delete mode 100644 contrib/bind9/lib/dns/include/dns/rbt.h delete mode 100644 contrib/bind9/lib/dns/include/dns/rcode.h delete mode 100644 contrib/bind9/lib/dns/include/dns/rdata.h delete mode 100644 contrib/bind9/lib/dns/include/dns/rdataclass.h delete mode 100644 contrib/bind9/lib/dns/include/dns/rdatalist.h delete mode 100644 contrib/bind9/lib/dns/include/dns/rdataset.h delete mode 100644 contrib/bind9/lib/dns/include/dns/rdatasetiter.h delete mode 100644 contrib/bind9/lib/dns/include/dns/rdataslab.h delete mode 100644 contrib/bind9/lib/dns/include/dns/rdatatype.h delete mode 100644 contrib/bind9/lib/dns/include/dns/request.h delete mode 100644 contrib/bind9/lib/dns/include/dns/resolver.h delete mode 100644 contrib/bind9/lib/dns/include/dns/result.h delete mode 100644 contrib/bind9/lib/dns/include/dns/rootns.h delete mode 100644 contrib/bind9/lib/dns/include/dns/sdb.h delete mode 100644 contrib/bind9/lib/dns/include/dns/sdlz.h delete mode 100644 contrib/bind9/lib/dns/include/dns/secalg.h delete mode 100644 contrib/bind9/lib/dns/include/dns/secproto.h delete mode 100644 contrib/bind9/lib/dns/include/dns/soa.h delete mode 100644 contrib/bind9/lib/dns/include/dns/ssu.h delete mode 100644 contrib/bind9/lib/dns/include/dns/stats.h delete mode 100644 contrib/bind9/lib/dns/include/dns/tcpmsg.h delete mode 100644 contrib/bind9/lib/dns/include/dns/time.h delete mode 100644 contrib/bind9/lib/dns/include/dns/timer.h delete mode 100644 contrib/bind9/lib/dns/include/dns/tkey.h delete mode 100644 contrib/bind9/lib/dns/include/dns/tsig.h delete mode 100644 contrib/bind9/lib/dns/include/dns/ttl.h delete mode 100644 contrib/bind9/lib/dns/include/dns/types.h delete mode 100644 contrib/bind9/lib/dns/include/dns/validator.h delete mode 100644 contrib/bind9/lib/dns/include/dns/version.h delete mode 100644 contrib/bind9/lib/dns/include/dns/view.h delete mode 100644 contrib/bind9/lib/dns/include/dns/xfrin.h delete mode 100644 contrib/bind9/lib/dns/include/dns/zone.h delete mode 100644 contrib/bind9/lib/dns/include/dns/zonekey.h delete mode 100644 contrib/bind9/lib/dns/include/dns/zt.h delete mode 100644 contrib/bind9/lib/dns/include/dst/Makefile.in delete mode 100644 contrib/bind9/lib/dns/include/dst/dst.h delete mode 100644 contrib/bind9/lib/dns/include/dst/gssapi.h delete mode 100644 contrib/bind9/lib/dns/include/dst/lib.h delete mode 100644 contrib/bind9/lib/dns/include/dst/result.h delete mode 100644 contrib/bind9/lib/dns/journal.c delete mode 100644 contrib/bind9/lib/dns/key.c delete mode 100644 contrib/bind9/lib/dns/keytable.c delete mode 100644 contrib/bind9/lib/dns/lib.c delete mode 100644 contrib/bind9/lib/dns/log.c delete mode 100644 contrib/bind9/lib/dns/lookup.c delete mode 100644 contrib/bind9/lib/dns/master.c delete mode 100644 contrib/bind9/lib/dns/masterdump.c delete mode 100644 contrib/bind9/lib/dns/message.c delete mode 100644 contrib/bind9/lib/dns/name.c delete mode 100644 contrib/bind9/lib/dns/ncache.c delete mode 100644 contrib/bind9/lib/dns/nsec.c delete mode 100644 contrib/bind9/lib/dns/openssl_link.c delete mode 100644 contrib/bind9/lib/dns/openssldh_link.c delete mode 100644 contrib/bind9/lib/dns/openssldsa_link.c delete mode 100644 contrib/bind9/lib/dns/opensslrsa_link.c delete mode 100644 contrib/bind9/lib/dns/order.c delete mode 100644 contrib/bind9/lib/dns/peer.c delete mode 100644 contrib/bind9/lib/dns/portlist.c delete mode 100644 contrib/bind9/lib/dns/rbt.c delete mode 100644 contrib/bind9/lib/dns/rbtdb.c delete mode 100644 contrib/bind9/lib/dns/rbtdb.h delete mode 100644 contrib/bind9/lib/dns/rbtdb64.c delete mode 100644 contrib/bind9/lib/dns/rbtdb64.h delete mode 100644 contrib/bind9/lib/dns/rcode.c delete mode 100644 contrib/bind9/lib/dns/rdata.c delete mode 100644 contrib/bind9/lib/dns/rdata/any_255/tsig_250.c delete mode 100644 contrib/bind9/lib/dns/rdata/any_255/tsig_250.h delete mode 100644 contrib/bind9/lib/dns/rdata/ch_3/a_1.c delete mode 100644 contrib/bind9/lib/dns/rdata/ch_3/a_1.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/afsdb_18.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/afsdb_18.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/cert_37.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/cert_37.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/cname_5.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/cname_5.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/dlv_32769.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/dlv_32769.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/dname_39.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/dname_39.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/dnskey_48.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/dnskey_48.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/ds_43.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/ds_43.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/gpos_27.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/gpos_27.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/hinfo_13.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/hinfo_13.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/ipseckey_45.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/isdn_20.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/isdn_20.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/key_25.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/key_25.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/loc_29.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/loc_29.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/mb_7.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/mb_7.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/md_3.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/md_3.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/mf_4.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/mf_4.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/mg_8.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/mg_8.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/minfo_14.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/minfo_14.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/mr_9.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/mr_9.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/mx_15.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/mx_15.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/ns_2.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/ns_2.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/nsec_47.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/nsec_47.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/null_10.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/null_10.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/nxt_30.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/nxt_30.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/opt_41.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/opt_41.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/proforma.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/proforma.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/ptr_12.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/ptr_12.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/rp_17.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/rp_17.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/rrsig_46.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/rrsig_46.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/rt_21.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/rt_21.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/sig_24.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/sig_24.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/soa_6.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/soa_6.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/spf_99.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/spf_99.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/sshfp_44.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/sshfp_44.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/tkey_249.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/tkey_249.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/txt_16.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/txt_16.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/unspec_103.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/unspec_103.h delete mode 100644 contrib/bind9/lib/dns/rdata/generic/x25_19.c delete mode 100644 contrib/bind9/lib/dns/rdata/generic/x25_19.h delete mode 100644 contrib/bind9/lib/dns/rdata/hs_4/a_1.c delete mode 100644 contrib/bind9/lib/dns/rdata/hs_4/a_1.h delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/a6_38.c delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/a6_38.h delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/a_1.c delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/a_1.h delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/aaaa_28.c delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/aaaa_28.h delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/apl_42.c delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/apl_42.h delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/kx_36.c delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/kx_36.h delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/naptr_35.c delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/naptr_35.h delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.c delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.h delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/nsap_22.c delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/nsap_22.h delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/px_26.c delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/px_26.h delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/srv_33.c delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/srv_33.h delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/wks_11.c delete mode 100644 contrib/bind9/lib/dns/rdata/in_1/wks_11.h delete mode 100644 contrib/bind9/lib/dns/rdata/rdatastructpre.h delete mode 100644 contrib/bind9/lib/dns/rdata/rdatastructsuf.h delete mode 100644 contrib/bind9/lib/dns/rdatalist.c delete mode 100644 contrib/bind9/lib/dns/rdatalist_p.h delete mode 100644 contrib/bind9/lib/dns/rdataset.c delete mode 100644 contrib/bind9/lib/dns/rdatasetiter.c delete mode 100644 contrib/bind9/lib/dns/rdataslab.c delete mode 100644 contrib/bind9/lib/dns/request.c delete mode 100644 contrib/bind9/lib/dns/resolver.c delete mode 100644 contrib/bind9/lib/dns/result.c delete mode 100644 contrib/bind9/lib/dns/rootns.c delete mode 100644 contrib/bind9/lib/dns/sdb.c delete mode 100644 contrib/bind9/lib/dns/sdlz.c delete mode 100644 contrib/bind9/lib/dns/soa.c delete mode 100644 contrib/bind9/lib/dns/ssu.c delete mode 100644 contrib/bind9/lib/dns/stats.c delete mode 100644 contrib/bind9/lib/dns/tcpmsg.c delete mode 100644 contrib/bind9/lib/dns/time.c delete mode 100644 contrib/bind9/lib/dns/timer.c delete mode 100644 contrib/bind9/lib/dns/tkey.c delete mode 100644 contrib/bind9/lib/dns/tsig.c delete mode 100644 contrib/bind9/lib/dns/ttl.c delete mode 100644 contrib/bind9/lib/dns/validator.c delete mode 100644 contrib/bind9/lib/dns/version.c delete mode 100644 contrib/bind9/lib/dns/view.c delete mode 100644 contrib/bind9/lib/dns/xfrin.c delete mode 100644 contrib/bind9/lib/dns/zone.c delete mode 100644 contrib/bind9/lib/dns/zonekey.c delete mode 100644 contrib/bind9/lib/dns/zt.c delete mode 100644 contrib/bind9/lib/isc/Makefile.in delete mode 100644 contrib/bind9/lib/isc/alpha/Makefile.in delete mode 100644 contrib/bind9/lib/isc/alpha/include/Makefile.in delete mode 100644 contrib/bind9/lib/isc/alpha/include/isc/Makefile.in delete mode 100644 contrib/bind9/lib/isc/alpha/include/isc/atomic.h delete mode 100644 contrib/bind9/lib/isc/api delete mode 100644 contrib/bind9/lib/isc/arm/include/isc/atomic.h delete mode 100644 contrib/bind9/lib/isc/assertions.c delete mode 100644 contrib/bind9/lib/isc/base64.c delete mode 100644 contrib/bind9/lib/isc/bitstring.c delete mode 100644 contrib/bind9/lib/isc/buffer.c delete mode 100644 contrib/bind9/lib/isc/bufferlist.c delete mode 100644 contrib/bind9/lib/isc/commandline.c delete mode 100644 contrib/bind9/lib/isc/entropy.c delete mode 100644 contrib/bind9/lib/isc/error.c delete mode 100644 contrib/bind9/lib/isc/event.c delete mode 100644 contrib/bind9/lib/isc/fsaccess.c delete mode 100644 contrib/bind9/lib/isc/hash.c delete mode 100644 contrib/bind9/lib/isc/heap.c delete mode 100644 contrib/bind9/lib/isc/hex.c delete mode 100644 contrib/bind9/lib/isc/hmacmd5.c delete mode 100644 contrib/bind9/lib/isc/hmacsha.c delete mode 100644 contrib/bind9/lib/isc/ia64/Makefile.in delete mode 100644 contrib/bind9/lib/isc/ia64/include/Makefile.in delete mode 100644 contrib/bind9/lib/isc/ia64/include/isc/Makefile.in delete mode 100644 contrib/bind9/lib/isc/ia64/include/isc/atomic.h delete mode 100644 contrib/bind9/lib/isc/include/Makefile.in delete mode 100644 contrib/bind9/lib/isc/include/isc/Makefile.in delete mode 100644 contrib/bind9/lib/isc/include/isc/app.h delete mode 100644 contrib/bind9/lib/isc/include/isc/assertions.h delete mode 100644 contrib/bind9/lib/isc/include/isc/base64.h delete mode 100644 contrib/bind9/lib/isc/include/isc/bitstring.h delete mode 100644 contrib/bind9/lib/isc/include/isc/boolean.h delete mode 100644 contrib/bind9/lib/isc/include/isc/buffer.h delete mode 100644 contrib/bind9/lib/isc/include/isc/bufferlist.h delete mode 100644 contrib/bind9/lib/isc/include/isc/commandline.h delete mode 100644 contrib/bind9/lib/isc/include/isc/entropy.h delete mode 100644 contrib/bind9/lib/isc/include/isc/error.h delete mode 100644 contrib/bind9/lib/isc/include/isc/event.h delete mode 100644 contrib/bind9/lib/isc/include/isc/eventclass.h delete mode 100644 contrib/bind9/lib/isc/include/isc/file.h delete mode 100644 contrib/bind9/lib/isc/include/isc/formatcheck.h delete mode 100644 contrib/bind9/lib/isc/include/isc/fsaccess.h delete mode 100644 contrib/bind9/lib/isc/include/isc/hash.h delete mode 100644 contrib/bind9/lib/isc/include/isc/heap.h delete mode 100644 contrib/bind9/lib/isc/include/isc/hex.h delete mode 100644 contrib/bind9/lib/isc/include/isc/hmacmd5.h delete mode 100644 contrib/bind9/lib/isc/include/isc/hmacsha.h delete mode 100644 contrib/bind9/lib/isc/include/isc/interfaceiter.h delete mode 100644 contrib/bind9/lib/isc/include/isc/ipv6.h delete mode 100644 contrib/bind9/lib/isc/include/isc/lang.h delete mode 100644 contrib/bind9/lib/isc/include/isc/lex.h delete mode 100644 contrib/bind9/lib/isc/include/isc/lfsr.h delete mode 100644 contrib/bind9/lib/isc/include/isc/lib.h delete mode 100644 contrib/bind9/lib/isc/include/isc/list.h delete mode 100644 contrib/bind9/lib/isc/include/isc/log.h delete mode 100644 contrib/bind9/lib/isc/include/isc/magic.h delete mode 100644 contrib/bind9/lib/isc/include/isc/md5.h delete mode 100644 contrib/bind9/lib/isc/include/isc/mem.h delete mode 100644 contrib/bind9/lib/isc/include/isc/msgcat.h delete mode 100644 contrib/bind9/lib/isc/include/isc/msgs.h delete mode 100644 contrib/bind9/lib/isc/include/isc/mutexblock.h delete mode 100644 contrib/bind9/lib/isc/include/isc/netaddr.h delete mode 100644 contrib/bind9/lib/isc/include/isc/netscope.h delete mode 100644 contrib/bind9/lib/isc/include/isc/ondestroy.h delete mode 100644 contrib/bind9/lib/isc/include/isc/os.h delete mode 100644 contrib/bind9/lib/isc/include/isc/parseint.h delete mode 100644 contrib/bind9/lib/isc/include/isc/platform.h.in delete mode 100644 contrib/bind9/lib/isc/include/isc/print.h delete mode 100644 contrib/bind9/lib/isc/include/isc/quota.h delete mode 100644 contrib/bind9/lib/isc/include/isc/random.h delete mode 100644 contrib/bind9/lib/isc/include/isc/ratelimiter.h delete mode 100644 contrib/bind9/lib/isc/include/isc/refcount.h delete mode 100644 contrib/bind9/lib/isc/include/isc/region.h delete mode 100644 contrib/bind9/lib/isc/include/isc/resource.h delete mode 100644 contrib/bind9/lib/isc/include/isc/result.h delete mode 100644 contrib/bind9/lib/isc/include/isc/resultclass.h delete mode 100644 contrib/bind9/lib/isc/include/isc/rwlock.h delete mode 100644 contrib/bind9/lib/isc/include/isc/serial.h delete mode 100644 contrib/bind9/lib/isc/include/isc/sha1.h delete mode 100644 contrib/bind9/lib/isc/include/isc/sha2.h delete mode 100644 contrib/bind9/lib/isc/include/isc/sockaddr.h delete mode 100644 contrib/bind9/lib/isc/include/isc/socket.h delete mode 100644 contrib/bind9/lib/isc/include/isc/stdio.h delete mode 100644 contrib/bind9/lib/isc/include/isc/stdlib.h delete mode 100644 contrib/bind9/lib/isc/include/isc/string.h delete mode 100644 contrib/bind9/lib/isc/include/isc/symtab.h delete mode 100644 contrib/bind9/lib/isc/include/isc/task.h delete mode 100644 contrib/bind9/lib/isc/include/isc/taskpool.h delete mode 100644 contrib/bind9/lib/isc/include/isc/timer.h delete mode 100644 contrib/bind9/lib/isc/include/isc/types.h delete mode 100644 contrib/bind9/lib/isc/include/isc/util.h delete mode 100644 contrib/bind9/lib/isc/include/isc/version.h delete mode 100644 contrib/bind9/lib/isc/inet_aton.c delete mode 100644 contrib/bind9/lib/isc/inet_ntop.c delete mode 100644 contrib/bind9/lib/isc/inet_pton.c delete mode 100644 contrib/bind9/lib/isc/lex.c delete mode 100644 contrib/bind9/lib/isc/lfsr.c delete mode 100644 contrib/bind9/lib/isc/lib.c delete mode 100644 contrib/bind9/lib/isc/log.c delete mode 100644 contrib/bind9/lib/isc/md5.c delete mode 100644 contrib/bind9/lib/isc/mem.c delete mode 100644 contrib/bind9/lib/isc/mips/Makefile.in delete mode 100644 contrib/bind9/lib/isc/mips/include/Makefile.in delete mode 100644 contrib/bind9/lib/isc/mips/include/isc/Makefile.in delete mode 100644 contrib/bind9/lib/isc/mips/include/isc/atomic.h delete mode 100644 contrib/bind9/lib/isc/mutexblock.c delete mode 100644 contrib/bind9/lib/isc/netaddr.c delete mode 100644 contrib/bind9/lib/isc/netscope.c delete mode 100644 contrib/bind9/lib/isc/nls/Makefile.in delete mode 100644 contrib/bind9/lib/isc/nls/msgcat.c delete mode 100644 contrib/bind9/lib/isc/noatomic/Makefile.in delete mode 100644 contrib/bind9/lib/isc/noatomic/include/Makefile.in delete mode 100644 contrib/bind9/lib/isc/noatomic/include/isc/Makefile.in delete mode 100644 contrib/bind9/lib/isc/noatomic/include/isc/atomic.h delete mode 100644 contrib/bind9/lib/isc/nothreads/Makefile.in delete mode 100644 contrib/bind9/lib/isc/nothreads/condition.c delete mode 100644 contrib/bind9/lib/isc/nothreads/include/Makefile.in delete mode 100644 contrib/bind9/lib/isc/nothreads/include/isc/Makefile.in delete mode 100644 contrib/bind9/lib/isc/nothreads/include/isc/condition.h delete mode 100644 contrib/bind9/lib/isc/nothreads/include/isc/mutex.h delete mode 100644 contrib/bind9/lib/isc/nothreads/include/isc/once.h delete mode 100644 contrib/bind9/lib/isc/nothreads/include/isc/thread.h delete mode 100644 contrib/bind9/lib/isc/nothreads/mutex.c delete mode 100644 contrib/bind9/lib/isc/nothreads/thread.c delete mode 100644 contrib/bind9/lib/isc/ondestroy.c delete mode 100644 contrib/bind9/lib/isc/parseint.c delete mode 100644 contrib/bind9/lib/isc/powerpc/Makefile.in delete mode 100644 contrib/bind9/lib/isc/powerpc/include/Makefile.in delete mode 100644 contrib/bind9/lib/isc/powerpc/include/isc/Makefile.in delete mode 100644 contrib/bind9/lib/isc/powerpc/include/isc/atomic.h delete mode 100644 contrib/bind9/lib/isc/print.c delete mode 100644 contrib/bind9/lib/isc/pthreads/Makefile.in delete mode 100644 contrib/bind9/lib/isc/pthreads/condition.c delete mode 100644 contrib/bind9/lib/isc/pthreads/include/Makefile.in delete mode 100644 contrib/bind9/lib/isc/pthreads/include/isc/Makefile.in delete mode 100644 contrib/bind9/lib/isc/pthreads/include/isc/condition.h delete mode 100644 contrib/bind9/lib/isc/pthreads/include/isc/mutex.h delete mode 100644 contrib/bind9/lib/isc/pthreads/include/isc/once.h delete mode 100644 contrib/bind9/lib/isc/pthreads/include/isc/thread.h delete mode 100644 contrib/bind9/lib/isc/pthreads/mutex.c delete mode 100644 contrib/bind9/lib/isc/pthreads/thread.c delete mode 100644 contrib/bind9/lib/isc/quota.c delete mode 100644 contrib/bind9/lib/isc/random.c delete mode 100644 contrib/bind9/lib/isc/ratelimiter.c delete mode 100644 contrib/bind9/lib/isc/refcount.c delete mode 100644 contrib/bind9/lib/isc/region.c delete mode 100644 contrib/bind9/lib/isc/result.c delete mode 100644 contrib/bind9/lib/isc/rwlock.c delete mode 100644 contrib/bind9/lib/isc/serial.c delete mode 100644 contrib/bind9/lib/isc/sha1.c delete mode 100644 contrib/bind9/lib/isc/sha2.c delete mode 100644 contrib/bind9/lib/isc/sockaddr.c delete mode 100644 contrib/bind9/lib/isc/sparc64/Makefile.in delete mode 100644 contrib/bind9/lib/isc/sparc64/include/Makefile.in delete mode 100644 contrib/bind9/lib/isc/sparc64/include/isc/Makefile.in delete mode 100644 contrib/bind9/lib/isc/sparc64/include/isc/atomic.h delete mode 100644 contrib/bind9/lib/isc/string.c delete mode 100644 contrib/bind9/lib/isc/strtoul.c delete mode 100644 contrib/bind9/lib/isc/symtab.c delete mode 100644 contrib/bind9/lib/isc/task.c delete mode 100644 contrib/bind9/lib/isc/task_p.h delete mode 100644 contrib/bind9/lib/isc/taskpool.c delete mode 100644 contrib/bind9/lib/isc/timer.c delete mode 100644 contrib/bind9/lib/isc/timer_p.h delete mode 100644 contrib/bind9/lib/isc/unix/Makefile.in delete mode 100644 contrib/bind9/lib/isc/unix/app.c delete mode 100644 contrib/bind9/lib/isc/unix/dir.c delete mode 100644 contrib/bind9/lib/isc/unix/entropy.c delete mode 100644 contrib/bind9/lib/isc/unix/errno2result.c delete mode 100644 contrib/bind9/lib/isc/unix/errno2result.h delete mode 100644 contrib/bind9/lib/isc/unix/file.c delete mode 100644 contrib/bind9/lib/isc/unix/fsaccess.c delete mode 100644 contrib/bind9/lib/isc/unix/ifiter_getifaddrs.c delete mode 100644 contrib/bind9/lib/isc/unix/ifiter_ioctl.c delete mode 100644 contrib/bind9/lib/isc/unix/ifiter_sysctl.c delete mode 100644 contrib/bind9/lib/isc/unix/include/Makefile.in delete mode 100644 contrib/bind9/lib/isc/unix/include/isc/Makefile.in delete mode 100644 contrib/bind9/lib/isc/unix/include/isc/dir.h delete mode 100644 contrib/bind9/lib/isc/unix/include/isc/int.h delete mode 100644 contrib/bind9/lib/isc/unix/include/isc/keyboard.h delete mode 100644 contrib/bind9/lib/isc/unix/include/isc/net.h delete mode 100644 contrib/bind9/lib/isc/unix/include/isc/netdb.h delete mode 100644 contrib/bind9/lib/isc/unix/include/isc/offset.h delete mode 100644 contrib/bind9/lib/isc/unix/include/isc/stat.h delete mode 100644 contrib/bind9/lib/isc/unix/include/isc/stdtime.h delete mode 100644 contrib/bind9/lib/isc/unix/include/isc/strerror.h delete mode 100644 contrib/bind9/lib/isc/unix/include/isc/syslog.h delete mode 100644 contrib/bind9/lib/isc/unix/include/isc/time.h delete mode 100644 contrib/bind9/lib/isc/unix/interfaceiter.c delete mode 100644 contrib/bind9/lib/isc/unix/ipv6.c delete mode 100644 contrib/bind9/lib/isc/unix/keyboard.c delete mode 100644 contrib/bind9/lib/isc/unix/net.c delete mode 100644 contrib/bind9/lib/isc/unix/os.c delete mode 100644 contrib/bind9/lib/isc/unix/resource.c delete mode 100644 contrib/bind9/lib/isc/unix/socket.c delete mode 100644 contrib/bind9/lib/isc/unix/socket_p.h delete mode 100644 contrib/bind9/lib/isc/unix/stdio.c delete mode 100644 contrib/bind9/lib/isc/unix/stdtime.c delete mode 100644 contrib/bind9/lib/isc/unix/strerror.c delete mode 100644 contrib/bind9/lib/isc/unix/syslog.c delete mode 100644 contrib/bind9/lib/isc/unix/time.c delete mode 100644 contrib/bind9/lib/isc/version.c delete mode 100644 contrib/bind9/lib/isc/x86_32/Makefile.in delete mode 100644 contrib/bind9/lib/isc/x86_32/include/Makefile.in delete mode 100644 contrib/bind9/lib/isc/x86_32/include/isc/Makefile.in delete mode 100644 contrib/bind9/lib/isc/x86_32/include/isc/atomic.h delete mode 100644 contrib/bind9/lib/isc/x86_64/Makefile.in delete mode 100644 contrib/bind9/lib/isc/x86_64/include/Makefile.in delete mode 100644 contrib/bind9/lib/isc/x86_64/include/isc/Makefile.in delete mode 100644 contrib/bind9/lib/isc/x86_64/include/isc/atomic.h delete mode 100644 contrib/bind9/lib/isccc/Makefile.in delete mode 100644 contrib/bind9/lib/isccc/alist.c delete mode 100644 contrib/bind9/lib/isccc/api delete mode 100644 contrib/bind9/lib/isccc/base64.c delete mode 100644 contrib/bind9/lib/isccc/cc.c delete mode 100644 contrib/bind9/lib/isccc/ccmsg.c delete mode 100644 contrib/bind9/lib/isccc/include/Makefile.in delete mode 100644 contrib/bind9/lib/isccc/include/isccc/Makefile.in delete mode 100644 contrib/bind9/lib/isccc/include/isccc/alist.h delete mode 100644 contrib/bind9/lib/isccc/include/isccc/base64.h delete mode 100644 contrib/bind9/lib/isccc/include/isccc/cc.h delete mode 100644 contrib/bind9/lib/isccc/include/isccc/ccmsg.h delete mode 100644 contrib/bind9/lib/isccc/include/isccc/events.h delete mode 100644 contrib/bind9/lib/isccc/include/isccc/lib.h delete mode 100644 contrib/bind9/lib/isccc/include/isccc/result.h delete mode 100644 contrib/bind9/lib/isccc/include/isccc/sexpr.h delete mode 100644 contrib/bind9/lib/isccc/include/isccc/symtab.h delete mode 100644 contrib/bind9/lib/isccc/include/isccc/symtype.h delete mode 100644 contrib/bind9/lib/isccc/include/isccc/types.h delete mode 100644 contrib/bind9/lib/isccc/include/isccc/util.h delete mode 100644 contrib/bind9/lib/isccc/include/isccc/version.h delete mode 100644 contrib/bind9/lib/isccc/lib.c delete mode 100644 contrib/bind9/lib/isccc/result.c delete mode 100644 contrib/bind9/lib/isccc/sexpr.c delete mode 100644 contrib/bind9/lib/isccc/symtab.c delete mode 100644 contrib/bind9/lib/isccc/version.c delete mode 100644 contrib/bind9/lib/isccfg/Makefile.in delete mode 100644 contrib/bind9/lib/isccfg/aclconf.c delete mode 100644 contrib/bind9/lib/isccfg/api delete mode 100644 contrib/bind9/lib/isccfg/include/Makefile.in delete mode 100644 contrib/bind9/lib/isccfg/include/isccfg/Makefile.in delete mode 100644 contrib/bind9/lib/isccfg/include/isccfg/aclconf.h delete mode 100644 contrib/bind9/lib/isccfg/include/isccfg/cfg.h delete mode 100644 contrib/bind9/lib/isccfg/include/isccfg/grammar.h delete mode 100644 contrib/bind9/lib/isccfg/include/isccfg/log.h delete mode 100644 contrib/bind9/lib/isccfg/include/isccfg/namedconf.h delete mode 100644 contrib/bind9/lib/isccfg/include/isccfg/version.h delete mode 100644 contrib/bind9/lib/isccfg/log.c delete mode 100644 contrib/bind9/lib/isccfg/namedconf.c delete mode 100644 contrib/bind9/lib/isccfg/parser.c delete mode 100644 contrib/bind9/lib/isccfg/version.c delete mode 100644 contrib/bind9/lib/lwres/Makefile.in delete mode 100644 contrib/bind9/lib/lwres/api delete mode 100644 contrib/bind9/lib/lwres/assert_p.h delete mode 100644 contrib/bind9/lib/lwres/context.c delete mode 100644 contrib/bind9/lib/lwres/context_p.h delete mode 100644 contrib/bind9/lib/lwres/gai_strerror.c delete mode 100644 contrib/bind9/lib/lwres/getaddrinfo.c delete mode 100644 contrib/bind9/lib/lwres/gethost.c delete mode 100644 contrib/bind9/lib/lwres/getipnode.c delete mode 100644 contrib/bind9/lib/lwres/getnameinfo.c delete mode 100644 contrib/bind9/lib/lwres/getrrset.c delete mode 100644 contrib/bind9/lib/lwres/herror.c delete mode 100644 contrib/bind9/lib/lwres/include/Makefile.in delete mode 100644 contrib/bind9/lib/lwres/include/lwres/Makefile.in delete mode 100644 contrib/bind9/lib/lwres/include/lwres/context.h delete mode 100644 contrib/bind9/lib/lwres/include/lwres/int.h delete mode 100644 contrib/bind9/lib/lwres/include/lwres/ipv6.h delete mode 100644 contrib/bind9/lib/lwres/include/lwres/lang.h delete mode 100644 contrib/bind9/lib/lwres/include/lwres/list.h delete mode 100644 contrib/bind9/lib/lwres/include/lwres/lwbuffer.h delete mode 100644 contrib/bind9/lib/lwres/include/lwres/lwpacket.h delete mode 100644 contrib/bind9/lib/lwres/include/lwres/lwres.h delete mode 100644 contrib/bind9/lib/lwres/include/lwres/netdb.h.in delete mode 100644 contrib/bind9/lib/lwres/include/lwres/platform.h.in delete mode 100644 contrib/bind9/lib/lwres/include/lwres/result.h delete mode 100644 contrib/bind9/lib/lwres/include/lwres/stdlib.h delete mode 100644 contrib/bind9/lib/lwres/include/lwres/version.h delete mode 100644 contrib/bind9/lib/lwres/lwbuffer.c delete mode 100644 contrib/bind9/lib/lwres/lwconfig.c delete mode 100644 contrib/bind9/lib/lwres/lwinetaton.c delete mode 100644 contrib/bind9/lib/lwres/lwinetntop.c delete mode 100644 contrib/bind9/lib/lwres/lwinetpton.c delete mode 100644 contrib/bind9/lib/lwres/lwpacket.c delete mode 100644 contrib/bind9/lib/lwres/lwres_gabn.c delete mode 100644 contrib/bind9/lib/lwres/lwres_gnba.c delete mode 100644 contrib/bind9/lib/lwres/lwres_grbn.c delete mode 100644 contrib/bind9/lib/lwres/lwres_noop.c delete mode 100644 contrib/bind9/lib/lwres/lwresutil.c delete mode 100644 contrib/bind9/lib/lwres/man/Makefile.in delete mode 100644 contrib/bind9/lib/lwres/man/lwres.3 delete mode 100644 contrib/bind9/lib/lwres/man/lwres.docbook delete mode 100644 contrib/bind9/lib/lwres/man/lwres.html delete mode 100644 contrib/bind9/lib/lwres/man/lwres_buffer.3 delete mode 100644 contrib/bind9/lib/lwres/man/lwres_buffer.docbook delete mode 100644 contrib/bind9/lib/lwres/man/lwres_buffer.html delete mode 100644 contrib/bind9/lib/lwres/man/lwres_config.3 delete mode 100644 contrib/bind9/lib/lwres/man/lwres_config.docbook delete mode 100644 contrib/bind9/lib/lwres/man/lwres_config.html delete mode 100644 contrib/bind9/lib/lwres/man/lwres_context.3 delete mode 100644 contrib/bind9/lib/lwres/man/lwres_context.docbook delete mode 100644 contrib/bind9/lib/lwres/man/lwres_context.html delete mode 100644 contrib/bind9/lib/lwres/man/lwres_gabn.3 delete mode 100644 contrib/bind9/lib/lwres/man/lwres_gabn.docbook delete mode 100644 contrib/bind9/lib/lwres/man/lwres_gabn.html delete mode 100644 contrib/bind9/lib/lwres/man/lwres_gai_strerror.3 delete mode 100644 contrib/bind9/lib/lwres/man/lwres_gai_strerror.docbook delete mode 100644 contrib/bind9/lib/lwres/man/lwres_gai_strerror.html delete mode 100644 contrib/bind9/lib/lwres/man/lwres_getaddrinfo.3 delete mode 100644 contrib/bind9/lib/lwres/man/lwres_getaddrinfo.docbook delete mode 100644 contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html delete mode 100644 contrib/bind9/lib/lwres/man/lwres_gethostent.3 delete mode 100644 contrib/bind9/lib/lwres/man/lwres_gethostent.docbook delete mode 100644 contrib/bind9/lib/lwres/man/lwres_gethostent.html delete mode 100644 contrib/bind9/lib/lwres/man/lwres_getipnode.3 delete mode 100644 contrib/bind9/lib/lwres/man/lwres_getipnode.docbook delete mode 100644 contrib/bind9/lib/lwres/man/lwres_getipnode.html delete mode 100644 contrib/bind9/lib/lwres/man/lwres_getnameinfo.3 delete mode 100644 contrib/bind9/lib/lwres/man/lwres_getnameinfo.docbook delete mode 100644 contrib/bind9/lib/lwres/man/lwres_getnameinfo.html delete mode 100644 contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.3 delete mode 100644 contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.docbook delete mode 100644 contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.html delete mode 100644 contrib/bind9/lib/lwres/man/lwres_gnba.3 delete mode 100644 contrib/bind9/lib/lwres/man/lwres_gnba.docbook delete mode 100644 contrib/bind9/lib/lwres/man/lwres_gnba.html delete mode 100644 contrib/bind9/lib/lwres/man/lwres_hstrerror.3 delete mode 100644 contrib/bind9/lib/lwres/man/lwres_hstrerror.docbook delete mode 100644 contrib/bind9/lib/lwres/man/lwres_hstrerror.html delete mode 100644 contrib/bind9/lib/lwres/man/lwres_inetntop.3 delete mode 100644 contrib/bind9/lib/lwres/man/lwres_inetntop.docbook delete mode 100644 contrib/bind9/lib/lwres/man/lwres_inetntop.html delete mode 100644 contrib/bind9/lib/lwres/man/lwres_noop.3 delete mode 100644 contrib/bind9/lib/lwres/man/lwres_noop.docbook delete mode 100644 contrib/bind9/lib/lwres/man/lwres_noop.html delete mode 100644 contrib/bind9/lib/lwres/man/lwres_packet.3 delete mode 100644 contrib/bind9/lib/lwres/man/lwres_packet.docbook delete mode 100644 contrib/bind9/lib/lwres/man/lwres_packet.html delete mode 100644 contrib/bind9/lib/lwres/man/lwres_resutil.3 delete mode 100644 contrib/bind9/lib/lwres/man/lwres_resutil.docbook delete mode 100644 contrib/bind9/lib/lwres/man/lwres_resutil.html delete mode 100644 contrib/bind9/lib/lwres/print.c delete mode 100644 contrib/bind9/lib/lwres/print_p.h delete mode 100644 contrib/bind9/lib/lwres/strtoul.c delete mode 100644 contrib/bind9/lib/lwres/unix/Makefile.in delete mode 100644 contrib/bind9/lib/lwres/unix/include/Makefile.in delete mode 100644 contrib/bind9/lib/lwres/unix/include/lwres/Makefile.in delete mode 100644 contrib/bind9/lib/lwres/unix/include/lwres/net.h delete mode 100644 contrib/bind9/lib/lwres/version.c delete mode 100644 contrib/bind9/libtool.m4 delete mode 100644 contrib/bind9/ltmain.sh delete mode 100644 contrib/bind9/make/Makefile.in delete mode 100644 contrib/bind9/make/includes.in delete mode 100644 contrib/bind9/make/mkdep.in delete mode 100644 contrib/bind9/make/rules.in delete mode 100755 contrib/bind9/mkinstalldirs delete mode 100644 contrib/bind9/version create mode 100644 doc/Makefile.in create mode 100644 doc/arm/Bv9ARM-book.xml create mode 100644 doc/arm/Bv9ARM.ch01.html create mode 100644 doc/arm/Bv9ARM.ch02.html create mode 100644 doc/arm/Bv9ARM.ch03.html create mode 100644 doc/arm/Bv9ARM.ch04.html create mode 100644 doc/arm/Bv9ARM.ch05.html create mode 100644 doc/arm/Bv9ARM.ch06.html create mode 100644 doc/arm/Bv9ARM.ch07.html create mode 100644 doc/arm/Bv9ARM.ch08.html create mode 100644 doc/arm/Bv9ARM.ch09.html create mode 100644 doc/arm/Bv9ARM.ch10.html create mode 100644 doc/arm/Bv9ARM.html create mode 100755 doc/arm/Bv9ARM.pdf create mode 100644 doc/arm/Makefile.in create mode 100644 doc/arm/README-SGML create mode 100644 doc/arm/isc-logo.eps create mode 100644 doc/arm/isc-logo.pdf create mode 100644 doc/arm/man.dig.html create mode 100644 doc/arm/man.dnssec-keygen.html create mode 100644 doc/arm/man.dnssec-signzone.html create mode 100644 doc/arm/man.host.html create mode 100644 doc/arm/man.named-checkconf.html create mode 100644 doc/arm/man.named-checkzone.html create mode 100644 doc/arm/man.named.html create mode 100644 doc/arm/man.rndc-confgen.html create mode 100644 doc/arm/man.rndc.conf.html create mode 100644 doc/arm/man.rndc.html create mode 100644 doc/draft/draft-baba-dnsext-acl-reqts-01.txt create mode 100644 doc/draft/draft-daigle-napstr-04.txt create mode 100644 doc/draft/draft-danisch-dns-rr-smtp-03.txt create mode 100644 doc/draft/draft-dnsext-opcode-discover-02.txt create mode 100644 doc/draft/draft-durand-dnsop-dynreverse-00.txt create mode 100644 doc/draft/draft-ietf-dnsext-2929bis-01.txt create mode 100644 doc/draft/draft-ietf-dnsext-axfr-clarify-05.txt create mode 100644 doc/draft/draft-ietf-dnsext-dhcid-rr-12.txt create mode 100644 doc/draft/draft-ietf-dnsext-dns-name-p-s-00.txt create mode 100644 doc/draft/draft-ietf-dnsext-dnssec-2535typecode-change-06.txt create mode 100644 doc/draft/draft-ietf-dnsext-dnssec-bis-updates-01.txt create mode 100644 doc/draft/draft-ietf-dnsext-dnssec-experiments-01.txt create mode 100644 doc/draft/draft-ietf-dnsext-dnssec-online-signing-02.txt create mode 100644 doc/draft/draft-ietf-dnsext-dnssec-opt-in-07.txt create mode 100644 doc/draft/draft-ietf-dnsext-dnssec-rsasha256-00.txt create mode 100644 doc/draft/draft-ietf-dnsext-dnssec-trans-02.txt create mode 100644 doc/draft/draft-ietf-dnsext-ds-sha256-05.txt create mode 100644 doc/draft/draft-ietf-dnsext-ecc-key-07.txt create mode 100644 doc/draft/draft-ietf-dnsext-interop3597-02.txt create mode 100644 doc/draft/draft-ietf-dnsext-keyrr-key-signing-flag-12.txt create mode 100644 doc/draft/draft-ietf-dnsext-mdns-43.txt create mode 100644 doc/draft/draft-ietf-dnsext-nsec3-04.txt create mode 100644 doc/draft/draft-ietf-dnsext-nsid-01.txt create mode 100644 doc/draft/draft-ietf-dnsext-rfc2536bis-dsa-06.txt create mode 100644 doc/draft/draft-ietf-dnsext-rfc2538bis-04.txt create mode 100644 doc/draft/draft-ietf-dnsext-rfc2539bis-dhk-06.txt create mode 100644 doc/draft/draft-ietf-dnsext-signed-nonexistence-requirements-01.txt create mode 100644 doc/draft/draft-ietf-dnsext-tkey-renewal-mode-05.txt create mode 100644 doc/draft/draft-ietf-dnsext-trustupdate-threshold-00.txt create mode 100644 doc/draft/draft-ietf-dnsext-trustupdate-timers-02.txt create mode 100644 doc/draft/draft-ietf-dnsext-tsig-sha-06.txt create mode 100644 doc/draft/draft-ietf-dnsext-wcard-clarify-10.txt create mode 100644 doc/draft/draft-ietf-dnsop-bad-dns-res-05.txt create mode 100644 doc/draft/draft-ietf-dnsop-dnssec-operational-practices-08.txt create mode 100644 doc/draft/draft-ietf-dnsop-inaddr-required-07.txt create mode 100644 doc/draft/draft-ietf-dnsop-ipv6-dns-configuration-06.txt create mode 100644 doc/draft/draft-ietf-dnsop-ipv6-dns-issues-11.txt create mode 100644 doc/draft/draft-ietf-dnsop-ipv6-transport-guidelines-01.txt create mode 100644 doc/draft/draft-ietf-dnsop-key-rollover-requirements-02.txt create mode 100644 doc/draft/draft-ietf-dnsop-respsize-02.txt create mode 100644 doc/draft/draft-ietf-dnsop-serverid-06.txt create mode 100644 doc/draft/draft-ietf-enum-e164-gstn-np-05.txt create mode 100644 doc/draft/draft-ietf-ipv6-node-requirements-08.txt create mode 100644 doc/draft/draft-ietf-secsh-dns-05.txt create mode 100644 doc/draft/draft-ihren-dnsext-threshold-validation-00.txt create mode 100644 doc/draft/draft-kato-dnsop-local-zones-00.txt create mode 100644 doc/draft/draft-park-ipv6-extensions-dns-pnp-00.txt create mode 100644 doc/draft/update create mode 100644 doc/misc/Makefile.in create mode 100644 doc/misc/dnssec create mode 100644 doc/misc/format-options.pl create mode 100644 doc/misc/ipv6 create mode 100644 doc/misc/migration create mode 100644 doc/misc/migration-4to9 create mode 100644 doc/misc/options create mode 100644 doc/misc/rfc-compliance create mode 100644 doc/misc/roadmap create mode 100644 doc/misc/sdb create mode 100644 doc/rfc/index create mode 100644 doc/rfc/rfc1032.txt create mode 100644 doc/rfc/rfc1033.txt create mode 100644 doc/rfc/rfc1034.txt create mode 100644 doc/rfc/rfc1035.txt create mode 100644 doc/rfc/rfc1101.txt create mode 100644 doc/rfc/rfc1122.txt create mode 100644 doc/rfc/rfc1123.txt create mode 100644 doc/rfc/rfc1183.txt create mode 100644 doc/rfc/rfc1348.txt create mode 100644 doc/rfc/rfc1535.txt create mode 100644 doc/rfc/rfc1536.txt create mode 100644 doc/rfc/rfc1537.txt create mode 100644 doc/rfc/rfc1591.txt create mode 100644 doc/rfc/rfc1611.txt create mode 100644 doc/rfc/rfc1612.txt create mode 100644 doc/rfc/rfc1706.txt create mode 100644 doc/rfc/rfc1712.txt create mode 100644 doc/rfc/rfc1750.txt create mode 100644 doc/rfc/rfc1876.txt create mode 100644 doc/rfc/rfc1886.txt create mode 100644 doc/rfc/rfc1982.txt create mode 100644 doc/rfc/rfc1995.txt create mode 100644 doc/rfc/rfc1996.txt create mode 100644 doc/rfc/rfc2052.txt create mode 100644 doc/rfc/rfc2104.txt create mode 100644 doc/rfc/rfc2119.txt create mode 100644 doc/rfc/rfc2133.txt create mode 100644 doc/rfc/rfc2136.txt create mode 100644 doc/rfc/rfc2137.txt create mode 100644 doc/rfc/rfc2163.txt create mode 100644 doc/rfc/rfc2168.txt create mode 100644 doc/rfc/rfc2181.txt create mode 100644 doc/rfc/rfc2230.txt create mode 100644 doc/rfc/rfc2308.txt create mode 100644 doc/rfc/rfc2317.txt create mode 100644 doc/rfc/rfc2373.txt create mode 100644 doc/rfc/rfc2374.txt create mode 100644 doc/rfc/rfc2375.txt create mode 100644 doc/rfc/rfc2418.txt create mode 100644 doc/rfc/rfc2535.txt create mode 100644 doc/rfc/rfc2536.txt create mode 100644 doc/rfc/rfc2537.txt create mode 100644 doc/rfc/rfc2538.txt create mode 100644 doc/rfc/rfc2539.txt create mode 100644 doc/rfc/rfc2540.txt create mode 100644 doc/rfc/rfc2541.txt create mode 100644 doc/rfc/rfc2553.txt create mode 100644 doc/rfc/rfc2671.txt create mode 100644 doc/rfc/rfc2672.txt create mode 100644 doc/rfc/rfc2673.txt create mode 100644 doc/rfc/rfc2782.txt create mode 100644 doc/rfc/rfc2825.txt create mode 100644 doc/rfc/rfc2826.txt create mode 100644 doc/rfc/rfc2845.txt create mode 100644 doc/rfc/rfc2874.txt create mode 100644 doc/rfc/rfc2915.txt create mode 100644 doc/rfc/rfc2929.txt create mode 100644 doc/rfc/rfc2930.txt create mode 100644 doc/rfc/rfc2931.txt create mode 100644 doc/rfc/rfc3007.txt create mode 100644 doc/rfc/rfc3008.txt create mode 100644 doc/rfc/rfc3071.txt create mode 100644 doc/rfc/rfc3090.txt create mode 100644 doc/rfc/rfc3110.txt create mode 100644 doc/rfc/rfc3123.txt create mode 100644 doc/rfc/rfc3152.txt create mode 100644 doc/rfc/rfc3197.txt create mode 100644 doc/rfc/rfc3225.txt create mode 100644 doc/rfc/rfc3226.txt create mode 100644 doc/rfc/rfc3258.txt create mode 100644 doc/rfc/rfc3363.txt create mode 100644 doc/rfc/rfc3364.txt create mode 100644 doc/rfc/rfc3425.txt create mode 100644 doc/rfc/rfc3445.txt create mode 100644 doc/rfc/rfc3467.txt create mode 100644 doc/rfc/rfc3490.txt create mode 100644 doc/rfc/rfc3491.txt create mode 100644 doc/rfc/rfc3492.txt create mode 100644 doc/rfc/rfc3493.txt create mode 100644 doc/rfc/rfc3513.txt create mode 100644 doc/rfc/rfc3596.txt create mode 100644 doc/rfc/rfc3597.txt create mode 100644 doc/rfc/rfc3645.txt create mode 100644 doc/rfc/rfc3655.txt create mode 100644 doc/rfc/rfc3658.txt create mode 100644 doc/rfc/rfc3757.txt create mode 100644 doc/rfc/rfc3833.txt create mode 100644 doc/rfc/rfc3845.txt create mode 100644 doc/rfc/rfc3901.txt create mode 100644 doc/rfc/rfc4025.txt create mode 100644 doc/rfc/rfc4033.txt create mode 100644 doc/rfc/rfc4034.txt create mode 100644 doc/rfc/rfc4035.txt create mode 100644 doc/rfc/rfc4074.txt create mode 100644 doc/rfc/rfc4159.txt create mode 100644 doc/rfc/rfc4193.txt create mode 100644 doc/rfc/rfc4255.txt create mode 100644 doc/rfc/rfc4343.txt create mode 100644 doc/rfc/rfc4367.txt create mode 100644 doc/rfc/rfc4398.txt create mode 100644 doc/rfc/rfc4408.txt create mode 100644 doc/rfc/rfc4431.txt create mode 100644 doc/rfc/rfc4470.txt create mode 100644 doc/rfc/rfc4634.txt create mode 100644 doc/rfc/rfc4641.txt create mode 100644 doc/rfc/rfc952.txt create mode 100755 install-sh create mode 100644 isc-config.sh.in create mode 100644 lib/Makefile.in create mode 100644 lib/bind/Makefile.in create mode 100644 lib/bind/README create mode 100644 lib/bind/aclocal.m4 create mode 100644 lib/bind/api create mode 100644 lib/bind/bsd/Makefile.in create mode 100644 lib/bind/bsd/daemon.c create mode 100644 lib/bind/bsd/ftruncate.c create mode 100644 lib/bind/bsd/gettimeofday.c create mode 100644 lib/bind/bsd/mktemp.c create mode 100644 lib/bind/bsd/putenv.c create mode 100644 lib/bind/bsd/readv.c create mode 100644 lib/bind/bsd/setenv.c create mode 100644 lib/bind/bsd/setitimer.c create mode 100644 lib/bind/bsd/strcasecmp.c create mode 100644 lib/bind/bsd/strdup.c create mode 100644 lib/bind/bsd/strerror.c create mode 100644 lib/bind/bsd/strpbrk.c create mode 100644 lib/bind/bsd/strsep.c create mode 100644 lib/bind/bsd/strtoul.c create mode 100644 lib/bind/bsd/utimes.c create mode 100644 lib/bind/bsd/writev.c create mode 100644 lib/bind/config.h.in create mode 100755 lib/bind/configure create mode 100644 lib/bind/configure.in create mode 100644 lib/bind/dst/Makefile.in create mode 100644 lib/bind/dst/dst_api.c create mode 100644 lib/bind/dst/dst_internal.h create mode 100644 lib/bind/dst/hmac_link.c create mode 100644 lib/bind/dst/md5.h create mode 100644 lib/bind/dst/md5_dgst.c create mode 100644 lib/bind/dst/md5_locl.h create mode 100644 lib/bind/dst/support.c create mode 100644 lib/bind/include/Makefile.in create mode 100644 lib/bind/include/arpa/inet.h create mode 100644 lib/bind/include/arpa/nameser.h create mode 100644 lib/bind/include/arpa/nameser_compat.h create mode 100644 lib/bind/include/fd_setsize.h create mode 100644 lib/bind/include/hesiod.h create mode 100644 lib/bind/include/irp.h create mode 100644 lib/bind/include/irs.h create mode 100644 lib/bind/include/isc/assertions.h create mode 100644 lib/bind/include/isc/ctl.h create mode 100644 lib/bind/include/isc/dst.h create mode 100644 lib/bind/include/isc/eventlib.h create mode 100644 lib/bind/include/isc/heap.h create mode 100644 lib/bind/include/isc/irpmarshall.h create mode 100644 lib/bind/include/isc/list.h create mode 100644 lib/bind/include/isc/logging.h create mode 100644 lib/bind/include/isc/memcluster.h create mode 100644 lib/bind/include/isc/misc.h create mode 100644 lib/bind/include/isc/tree.h create mode 100644 lib/bind/include/netdb.h create mode 100644 lib/bind/include/netgroup.h create mode 100644 lib/bind/include/res_update.h create mode 100644 lib/bind/include/resolv.h create mode 100644 lib/bind/include/resolv_mt.h create mode 100644 lib/bind/inet/Makefile.in create mode 100644 lib/bind/inet/inet_addr.c create mode 100644 lib/bind/inet/inet_cidr_ntop.c create mode 100644 lib/bind/inet/inet_cidr_pton.c create mode 100644 lib/bind/inet/inet_data.c create mode 100644 lib/bind/inet/inet_lnaof.c create mode 100644 lib/bind/inet/inet_makeaddr.c create mode 100644 lib/bind/inet/inet_net_ntop.c create mode 100644 lib/bind/inet/inet_net_pton.c create mode 100644 lib/bind/inet/inet_neta.c create mode 100644 lib/bind/inet/inet_netof.c create mode 100644 lib/bind/inet/inet_network.c create mode 100644 lib/bind/inet/inet_ntoa.c create mode 100644 lib/bind/inet/inet_ntop.c create mode 100644 lib/bind/inet/inet_pton.c create mode 100644 lib/bind/inet/nsap_addr.c create mode 100644 lib/bind/irs/Makefile.in create mode 100644 lib/bind/irs/dns.c create mode 100644 lib/bind/irs/dns_gr.c create mode 100644 lib/bind/irs/dns_ho.c create mode 100644 lib/bind/irs/dns_nw.c create mode 100644 lib/bind/irs/dns_p.h create mode 100644 lib/bind/irs/dns_pr.c create mode 100644 lib/bind/irs/dns_pw.c create mode 100644 lib/bind/irs/dns_sv.c create mode 100644 lib/bind/irs/gai_strerror.c create mode 100644 lib/bind/irs/gen.c create mode 100644 lib/bind/irs/gen_gr.c create mode 100644 lib/bind/irs/gen_ho.c create mode 100644 lib/bind/irs/gen_ng.c create mode 100644 lib/bind/irs/gen_nw.c create mode 100644 lib/bind/irs/gen_p.h create mode 100644 lib/bind/irs/gen_pr.c create mode 100644 lib/bind/irs/gen_pw.c create mode 100644 lib/bind/irs/gen_sv.c create mode 100644 lib/bind/irs/getaddrinfo.c create mode 100644 lib/bind/irs/getgrent.c create mode 100644 lib/bind/irs/getgrent_r.c create mode 100644 lib/bind/irs/gethostent.c create mode 100644 lib/bind/irs/gethostent_r.c create mode 100644 lib/bind/irs/getnameinfo.c create mode 100644 lib/bind/irs/getnetent.c create mode 100644 lib/bind/irs/getnetent_r.c create mode 100644 lib/bind/irs/getnetgrent.c create mode 100644 lib/bind/irs/getnetgrent_r.c create mode 100644 lib/bind/irs/getprotoent.c create mode 100644 lib/bind/irs/getprotoent_r.c create mode 100644 lib/bind/irs/getpwent.c create mode 100644 lib/bind/irs/getpwent_r.c create mode 100644 lib/bind/irs/getservent.c create mode 100644 lib/bind/irs/getservent_r.c create mode 100644 lib/bind/irs/hesiod.c create mode 100644 lib/bind/irs/hesiod_p.h create mode 100644 lib/bind/irs/irp.c create mode 100644 lib/bind/irs/irp_gr.c create mode 100644 lib/bind/irs/irp_ho.c create mode 100644 lib/bind/irs/irp_ng.c create mode 100644 lib/bind/irs/irp_nw.c create mode 100644 lib/bind/irs/irp_p.h create mode 100644 lib/bind/irs/irp_pr.c create mode 100644 lib/bind/irs/irp_pw.c create mode 100644 lib/bind/irs/irp_sv.c create mode 100644 lib/bind/irs/irpmarshall.c create mode 100644 lib/bind/irs/irs_data.c create mode 100644 lib/bind/irs/irs_data.h create mode 100644 lib/bind/irs/irs_p.h create mode 100644 lib/bind/irs/lcl.c create mode 100644 lib/bind/irs/lcl_gr.c create mode 100644 lib/bind/irs/lcl_ho.c create mode 100644 lib/bind/irs/lcl_ng.c create mode 100644 lib/bind/irs/lcl_nw.c create mode 100644 lib/bind/irs/lcl_p.h create mode 100644 lib/bind/irs/lcl_pr.c create mode 100644 lib/bind/irs/lcl_pw.c create mode 100644 lib/bind/irs/lcl_sv.c create mode 100644 lib/bind/irs/nis.c create mode 100644 lib/bind/irs/nis_gr.c create mode 100644 lib/bind/irs/nis_ho.c create mode 100644 lib/bind/irs/nis_ng.c create mode 100644 lib/bind/irs/nis_nw.c create mode 100644 lib/bind/irs/nis_p.h create mode 100644 lib/bind/irs/nis_pr.c create mode 100644 lib/bind/irs/nis_pw.c create mode 100644 lib/bind/irs/nis_sv.c create mode 100644 lib/bind/irs/nul_ng.c create mode 100644 lib/bind/irs/pathnames.h create mode 100644 lib/bind/irs/util.c create mode 100644 lib/bind/isc/Makefile.in create mode 100644 lib/bind/isc/assertions.c create mode 100644 lib/bind/isc/assertions.mdoc create mode 100644 lib/bind/isc/base64.c create mode 100644 lib/bind/isc/bitncmp.c create mode 100644 lib/bind/isc/bitncmp.mdoc create mode 100644 lib/bind/isc/ctl_clnt.c create mode 100644 lib/bind/isc/ctl_p.c create mode 100644 lib/bind/isc/ctl_p.h create mode 100644 lib/bind/isc/ctl_srvr.c create mode 100644 lib/bind/isc/ev_connects.c create mode 100644 lib/bind/isc/ev_files.c create mode 100644 lib/bind/isc/ev_streams.c create mode 100644 lib/bind/isc/ev_timers.c create mode 100644 lib/bind/isc/ev_waits.c create mode 100644 lib/bind/isc/eventlib.c create mode 100644 lib/bind/isc/eventlib.mdoc create mode 100644 lib/bind/isc/eventlib_p.h create mode 100644 lib/bind/isc/heap.c create mode 100644 lib/bind/isc/heap.mdoc create mode 100644 lib/bind/isc/hex.c create mode 100644 lib/bind/isc/logging.c create mode 100644 lib/bind/isc/logging.mdoc create mode 100644 lib/bind/isc/logging_p.h create mode 100644 lib/bind/isc/memcluster.c create mode 100644 lib/bind/isc/memcluster.mdoc create mode 100644 lib/bind/isc/movefile.c create mode 100644 lib/bind/isc/tree.c create mode 100644 lib/bind/isc/tree.mdoc create mode 100644 lib/bind/make/includes.in create mode 100644 lib/bind/make/mkdep.in create mode 100644 lib/bind/make/rules.in create mode 100755 lib/bind/mkinstalldirs create mode 100644 lib/bind/nameser/Makefile.in create mode 100644 lib/bind/nameser/ns_date.c create mode 100644 lib/bind/nameser/ns_name.c create mode 100644 lib/bind/nameser/ns_netint.c create mode 100644 lib/bind/nameser/ns_parse.c create mode 100644 lib/bind/nameser/ns_print.c create mode 100644 lib/bind/nameser/ns_samedomain.c create mode 100644 lib/bind/nameser/ns_sign.c create mode 100644 lib/bind/nameser/ns_ttl.c create mode 100644 lib/bind/nameser/ns_verify.c create mode 100644 lib/bind/port/Makefile.in create mode 100644 lib/bind/port/freebsd/Makefile.in create mode 100644 lib/bind/port/freebsd/include/Makefile.in create mode 100644 lib/bind/port/freebsd/include/sys/bitypes.h create mode 100644 lib/bind/port_after.h.in create mode 100644 lib/bind/port_before.h.in create mode 100644 lib/bind/resolv/Makefile.in create mode 100644 lib/bind/resolv/herror.c create mode 100644 lib/bind/resolv/mtctxres.c create mode 100644 lib/bind/resolv/res_comp.c create mode 100644 lib/bind/resolv/res_data.c create mode 100644 lib/bind/resolv/res_debug.c create mode 100644 lib/bind/resolv/res_debug.h create mode 100644 lib/bind/resolv/res_findzonecut.c create mode 100644 lib/bind/resolv/res_init.c create mode 100644 lib/bind/resolv/res_mkquery.c create mode 100644 lib/bind/resolv/res_mkupdate.c create mode 100644 lib/bind/resolv/res_mkupdate.h create mode 100644 lib/bind/resolv/res_private.h create mode 100644 lib/bind/resolv/res_query.c create mode 100644 lib/bind/resolv/res_send.c create mode 100644 lib/bind/resolv/res_sendsigned.c create mode 100644 lib/bind/resolv/res_update.c create mode 100644 lib/bind9/Makefile.in create mode 100644 lib/bind9/api create mode 100644 lib/bind9/check.c create mode 100644 lib/bind9/getaddresses.c create mode 100644 lib/bind9/include/Makefile.in create mode 100644 lib/bind9/include/bind9/Makefile.in create mode 100644 lib/bind9/include/bind9/check.h create mode 100644 lib/bind9/include/bind9/getaddresses.h create mode 100644 lib/bind9/include/bind9/version.h create mode 100644 lib/bind9/version.c create mode 100644 lib/dns/Makefile.in create mode 100644 lib/dns/acache.c create mode 100644 lib/dns/acl.c create mode 100644 lib/dns/adb.c create mode 100644 lib/dns/api create mode 100644 lib/dns/byaddr.c create mode 100644 lib/dns/cache.c create mode 100644 lib/dns/callbacks.c create mode 100644 lib/dns/compress.c create mode 100644 lib/dns/db.c create mode 100644 lib/dns/dbiterator.c create mode 100644 lib/dns/dbtable.c create mode 100644 lib/dns/diff.c create mode 100644 lib/dns/dispatch.c create mode 100644 lib/dns/dlz.c create mode 100644 lib/dns/dnssec.c create mode 100644 lib/dns/ds.c create mode 100644 lib/dns/dst_api.c create mode 100644 lib/dns/dst_internal.h create mode 100644 lib/dns/dst_lib.c create mode 100644 lib/dns/dst_openssl.h create mode 100644 lib/dns/dst_parse.c create mode 100644 lib/dns/dst_parse.h create mode 100644 lib/dns/dst_result.c create mode 100644 lib/dns/forward.c create mode 100644 lib/dns/gen-unix.h create mode 100644 lib/dns/gen.c create mode 100644 lib/dns/gssapi_link.c create mode 100644 lib/dns/gssapictx.c create mode 100644 lib/dns/hmac_link.c create mode 100644 lib/dns/include/Makefile.in create mode 100644 lib/dns/include/dns/Makefile.in create mode 100644 lib/dns/include/dns/acache.h create mode 100644 lib/dns/include/dns/acl.h create mode 100644 lib/dns/include/dns/adb.h create mode 100644 lib/dns/include/dns/bit.h create mode 100644 lib/dns/include/dns/byaddr.h create mode 100644 lib/dns/include/dns/cache.h create mode 100644 lib/dns/include/dns/callbacks.h create mode 100644 lib/dns/include/dns/cert.h create mode 100644 lib/dns/include/dns/compress.h create mode 100644 lib/dns/include/dns/db.h create mode 100644 lib/dns/include/dns/dbiterator.h create mode 100644 lib/dns/include/dns/dbtable.h create mode 100644 lib/dns/include/dns/diff.h create mode 100644 lib/dns/include/dns/dispatch.h create mode 100644 lib/dns/include/dns/dlz.h create mode 100644 lib/dns/include/dns/dnssec.h create mode 100644 lib/dns/include/dns/ds.h create mode 100644 lib/dns/include/dns/events.h create mode 100644 lib/dns/include/dns/fixedname.h create mode 100644 lib/dns/include/dns/forward.h create mode 100644 lib/dns/include/dns/journal.h create mode 100644 lib/dns/include/dns/keyflags.h create mode 100644 lib/dns/include/dns/keytable.h create mode 100644 lib/dns/include/dns/keyvalues.h create mode 100644 lib/dns/include/dns/lib.h create mode 100644 lib/dns/include/dns/log.h create mode 100644 lib/dns/include/dns/lookup.h create mode 100644 lib/dns/include/dns/master.h create mode 100644 lib/dns/include/dns/masterdump.h create mode 100644 lib/dns/include/dns/message.h create mode 100644 lib/dns/include/dns/name.h create mode 100644 lib/dns/include/dns/ncache.h create mode 100644 lib/dns/include/dns/nsec.h create mode 100644 lib/dns/include/dns/opcode.h create mode 100644 lib/dns/include/dns/order.h create mode 100644 lib/dns/include/dns/peer.h create mode 100644 lib/dns/include/dns/portlist.h create mode 100644 lib/dns/include/dns/rbt.h create mode 100644 lib/dns/include/dns/rcode.h create mode 100644 lib/dns/include/dns/rdata.h create mode 100644 lib/dns/include/dns/rdataclass.h create mode 100644 lib/dns/include/dns/rdatalist.h create mode 100644 lib/dns/include/dns/rdataset.h create mode 100644 lib/dns/include/dns/rdatasetiter.h create mode 100644 lib/dns/include/dns/rdataslab.h create mode 100644 lib/dns/include/dns/rdatatype.h create mode 100644 lib/dns/include/dns/request.h create mode 100644 lib/dns/include/dns/resolver.h create mode 100644 lib/dns/include/dns/result.h create mode 100644 lib/dns/include/dns/rootns.h create mode 100644 lib/dns/include/dns/sdb.h create mode 100644 lib/dns/include/dns/sdlz.h create mode 100644 lib/dns/include/dns/secalg.h create mode 100644 lib/dns/include/dns/secproto.h create mode 100644 lib/dns/include/dns/soa.h create mode 100644 lib/dns/include/dns/ssu.h create mode 100644 lib/dns/include/dns/stats.h create mode 100644 lib/dns/include/dns/tcpmsg.h create mode 100644 lib/dns/include/dns/time.h create mode 100644 lib/dns/include/dns/timer.h create mode 100644 lib/dns/include/dns/tkey.h create mode 100644 lib/dns/include/dns/tsig.h create mode 100644 lib/dns/include/dns/ttl.h create mode 100644 lib/dns/include/dns/types.h create mode 100644 lib/dns/include/dns/validator.h create mode 100644 lib/dns/include/dns/version.h create mode 100644 lib/dns/include/dns/view.h create mode 100644 lib/dns/include/dns/xfrin.h create mode 100644 lib/dns/include/dns/zone.h create mode 100644 lib/dns/include/dns/zonekey.h create mode 100644 lib/dns/include/dns/zt.h create mode 100644 lib/dns/include/dst/Makefile.in create mode 100644 lib/dns/include/dst/dst.h create mode 100644 lib/dns/include/dst/gssapi.h create mode 100644 lib/dns/include/dst/lib.h create mode 100644 lib/dns/include/dst/result.h create mode 100644 lib/dns/journal.c create mode 100644 lib/dns/key.c create mode 100644 lib/dns/keytable.c create mode 100644 lib/dns/lib.c create mode 100644 lib/dns/log.c create mode 100644 lib/dns/lookup.c create mode 100644 lib/dns/master.c create mode 100644 lib/dns/masterdump.c create mode 100644 lib/dns/message.c create mode 100644 lib/dns/name.c create mode 100644 lib/dns/ncache.c create mode 100644 lib/dns/nsec.c create mode 100644 lib/dns/openssl_link.c create mode 100644 lib/dns/openssldh_link.c create mode 100644 lib/dns/openssldsa_link.c create mode 100644 lib/dns/opensslrsa_link.c create mode 100644 lib/dns/order.c create mode 100644 lib/dns/peer.c create mode 100644 lib/dns/portlist.c create mode 100644 lib/dns/rbt.c create mode 100644 lib/dns/rbtdb.c create mode 100644 lib/dns/rbtdb.h create mode 100644 lib/dns/rbtdb64.c create mode 100644 lib/dns/rbtdb64.h create mode 100644 lib/dns/rcode.c create mode 100644 lib/dns/rdata.c create mode 100644 lib/dns/rdata/any_255/tsig_250.c create mode 100644 lib/dns/rdata/any_255/tsig_250.h create mode 100644 lib/dns/rdata/ch_3/a_1.c create mode 100644 lib/dns/rdata/ch_3/a_1.h create mode 100644 lib/dns/rdata/generic/afsdb_18.c create mode 100644 lib/dns/rdata/generic/afsdb_18.h create mode 100644 lib/dns/rdata/generic/cert_37.c create mode 100644 lib/dns/rdata/generic/cert_37.h create mode 100644 lib/dns/rdata/generic/cname_5.c create mode 100644 lib/dns/rdata/generic/cname_5.h create mode 100644 lib/dns/rdata/generic/dlv_32769.c create mode 100644 lib/dns/rdata/generic/dlv_32769.h create mode 100644 lib/dns/rdata/generic/dname_39.c create mode 100644 lib/dns/rdata/generic/dname_39.h create mode 100644 lib/dns/rdata/generic/dnskey_48.c create mode 100644 lib/dns/rdata/generic/dnskey_48.h create mode 100644 lib/dns/rdata/generic/ds_43.c create mode 100644 lib/dns/rdata/generic/ds_43.h create mode 100644 lib/dns/rdata/generic/gpos_27.c create mode 100644 lib/dns/rdata/generic/gpos_27.h create mode 100644 lib/dns/rdata/generic/hinfo_13.c create mode 100644 lib/dns/rdata/generic/hinfo_13.h create mode 100644 lib/dns/rdata/generic/ipseckey_45.c create mode 100644 lib/dns/rdata/generic/ipseckey_45.h create mode 100644 lib/dns/rdata/generic/isdn_20.c create mode 100644 lib/dns/rdata/generic/isdn_20.h create mode 100644 lib/dns/rdata/generic/key_25.c create mode 100644 lib/dns/rdata/generic/key_25.h create mode 100644 lib/dns/rdata/generic/loc_29.c create mode 100644 lib/dns/rdata/generic/loc_29.h create mode 100644 lib/dns/rdata/generic/mb_7.c create mode 100644 lib/dns/rdata/generic/mb_7.h create mode 100644 lib/dns/rdata/generic/md_3.c create mode 100644 lib/dns/rdata/generic/md_3.h create mode 100644 lib/dns/rdata/generic/mf_4.c create mode 100644 lib/dns/rdata/generic/mf_4.h create mode 100644 lib/dns/rdata/generic/mg_8.c create mode 100644 lib/dns/rdata/generic/mg_8.h create mode 100644 lib/dns/rdata/generic/minfo_14.c create mode 100644 lib/dns/rdata/generic/minfo_14.h create mode 100644 lib/dns/rdata/generic/mr_9.c create mode 100644 lib/dns/rdata/generic/mr_9.h create mode 100644 lib/dns/rdata/generic/mx_15.c create mode 100644 lib/dns/rdata/generic/mx_15.h create mode 100644 lib/dns/rdata/generic/ns_2.c create mode 100644 lib/dns/rdata/generic/ns_2.h create mode 100644 lib/dns/rdata/generic/nsec_47.c create mode 100644 lib/dns/rdata/generic/nsec_47.h create mode 100644 lib/dns/rdata/generic/null_10.c create mode 100644 lib/dns/rdata/generic/null_10.h create mode 100644 lib/dns/rdata/generic/nxt_30.c create mode 100644 lib/dns/rdata/generic/nxt_30.h create mode 100644 lib/dns/rdata/generic/opt_41.c create mode 100644 lib/dns/rdata/generic/opt_41.h create mode 100644 lib/dns/rdata/generic/proforma.c create mode 100644 lib/dns/rdata/generic/proforma.h create mode 100644 lib/dns/rdata/generic/ptr_12.c create mode 100644 lib/dns/rdata/generic/ptr_12.h create mode 100644 lib/dns/rdata/generic/rp_17.c create mode 100644 lib/dns/rdata/generic/rp_17.h create mode 100644 lib/dns/rdata/generic/rrsig_46.c create mode 100644 lib/dns/rdata/generic/rrsig_46.h create mode 100644 lib/dns/rdata/generic/rt_21.c create mode 100644 lib/dns/rdata/generic/rt_21.h create mode 100644 lib/dns/rdata/generic/sig_24.c create mode 100644 lib/dns/rdata/generic/sig_24.h create mode 100644 lib/dns/rdata/generic/soa_6.c create mode 100644 lib/dns/rdata/generic/soa_6.h create mode 100644 lib/dns/rdata/generic/spf_99.c create mode 100644 lib/dns/rdata/generic/spf_99.h create mode 100644 lib/dns/rdata/generic/sshfp_44.c create mode 100644 lib/dns/rdata/generic/sshfp_44.h create mode 100644 lib/dns/rdata/generic/tkey_249.c create mode 100644 lib/dns/rdata/generic/tkey_249.h create mode 100644 lib/dns/rdata/generic/txt_16.c create mode 100644 lib/dns/rdata/generic/txt_16.h create mode 100644 lib/dns/rdata/generic/unspec_103.c create mode 100644 lib/dns/rdata/generic/unspec_103.h create mode 100644 lib/dns/rdata/generic/x25_19.c create mode 100644 lib/dns/rdata/generic/x25_19.h create mode 100644 lib/dns/rdata/hs_4/a_1.c create mode 100644 lib/dns/rdata/hs_4/a_1.h create mode 100644 lib/dns/rdata/in_1/a6_38.c create mode 100644 lib/dns/rdata/in_1/a6_38.h create mode 100644 lib/dns/rdata/in_1/a_1.c create mode 100644 lib/dns/rdata/in_1/a_1.h create mode 100644 lib/dns/rdata/in_1/aaaa_28.c create mode 100644 lib/dns/rdata/in_1/aaaa_28.h create mode 100644 lib/dns/rdata/in_1/apl_42.c create mode 100644 lib/dns/rdata/in_1/apl_42.h create mode 100644 lib/dns/rdata/in_1/kx_36.c create mode 100644 lib/dns/rdata/in_1/kx_36.h create mode 100644 lib/dns/rdata/in_1/naptr_35.c create mode 100644 lib/dns/rdata/in_1/naptr_35.h create mode 100644 lib/dns/rdata/in_1/nsap-ptr_23.c create mode 100644 lib/dns/rdata/in_1/nsap-ptr_23.h create mode 100644 lib/dns/rdata/in_1/nsap_22.c create mode 100644 lib/dns/rdata/in_1/nsap_22.h create mode 100644 lib/dns/rdata/in_1/px_26.c create mode 100644 lib/dns/rdata/in_1/px_26.h create mode 100644 lib/dns/rdata/in_1/srv_33.c create mode 100644 lib/dns/rdata/in_1/srv_33.h create mode 100644 lib/dns/rdata/in_1/wks_11.c create mode 100644 lib/dns/rdata/in_1/wks_11.h create mode 100644 lib/dns/rdata/rdatastructpre.h create mode 100644 lib/dns/rdata/rdatastructsuf.h create mode 100644 lib/dns/rdatalist.c create mode 100644 lib/dns/rdatalist_p.h create mode 100644 lib/dns/rdataset.c create mode 100644 lib/dns/rdatasetiter.c create mode 100644 lib/dns/rdataslab.c create mode 100644 lib/dns/request.c create mode 100644 lib/dns/resolver.c create mode 100644 lib/dns/result.c create mode 100644 lib/dns/rootns.c create mode 100644 lib/dns/sdb.c create mode 100644 lib/dns/sdlz.c create mode 100644 lib/dns/soa.c create mode 100644 lib/dns/ssu.c create mode 100644 lib/dns/stats.c create mode 100644 lib/dns/tcpmsg.c create mode 100644 lib/dns/time.c create mode 100644 lib/dns/timer.c create mode 100644 lib/dns/tkey.c create mode 100644 lib/dns/tsig.c create mode 100644 lib/dns/ttl.c create mode 100644 lib/dns/validator.c create mode 100644 lib/dns/version.c create mode 100644 lib/dns/view.c create mode 100644 lib/dns/xfrin.c create mode 100644 lib/dns/zone.c create mode 100644 lib/dns/zonekey.c create mode 100644 lib/dns/zt.c create mode 100644 lib/isc/Makefile.in create mode 100644 lib/isc/alpha/Makefile.in create mode 100644 lib/isc/alpha/include/Makefile.in create mode 100644 lib/isc/alpha/include/isc/Makefile.in create mode 100644 lib/isc/alpha/include/isc/atomic.h create mode 100644 lib/isc/api create mode 100644 lib/isc/arm/include/isc/atomic.h create mode 100644 lib/isc/assertions.c create mode 100644 lib/isc/base64.c create mode 100644 lib/isc/bitstring.c create mode 100644 lib/isc/buffer.c create mode 100644 lib/isc/bufferlist.c create mode 100644 lib/isc/commandline.c create mode 100644 lib/isc/entropy.c create mode 100644 lib/isc/error.c create mode 100644 lib/isc/event.c create mode 100644 lib/isc/fsaccess.c create mode 100644 lib/isc/hash.c create mode 100644 lib/isc/heap.c create mode 100644 lib/isc/hex.c create mode 100644 lib/isc/hmacmd5.c create mode 100644 lib/isc/hmacsha.c create mode 100644 lib/isc/ia64/Makefile.in create mode 100644 lib/isc/ia64/include/Makefile.in create mode 100644 lib/isc/ia64/include/isc/Makefile.in create mode 100644 lib/isc/ia64/include/isc/atomic.h create mode 100644 lib/isc/include/Makefile.in create mode 100644 lib/isc/include/isc/Makefile.in create mode 100644 lib/isc/include/isc/app.h create mode 100644 lib/isc/include/isc/assertions.h create mode 100644 lib/isc/include/isc/base64.h create mode 100644 lib/isc/include/isc/bitstring.h create mode 100644 lib/isc/include/isc/boolean.h create mode 100644 lib/isc/include/isc/buffer.h create mode 100644 lib/isc/include/isc/bufferlist.h create mode 100644 lib/isc/include/isc/commandline.h create mode 100644 lib/isc/include/isc/entropy.h create mode 100644 lib/isc/include/isc/error.h create mode 100644 lib/isc/include/isc/event.h create mode 100644 lib/isc/include/isc/eventclass.h create mode 100644 lib/isc/include/isc/file.h create mode 100644 lib/isc/include/isc/formatcheck.h create mode 100644 lib/isc/include/isc/fsaccess.h create mode 100644 lib/isc/include/isc/hash.h create mode 100644 lib/isc/include/isc/heap.h create mode 100644 lib/isc/include/isc/hex.h create mode 100644 lib/isc/include/isc/hmacmd5.h create mode 100644 lib/isc/include/isc/hmacsha.h create mode 100644 lib/isc/include/isc/interfaceiter.h create mode 100644 lib/isc/include/isc/ipv6.h create mode 100644 lib/isc/include/isc/lang.h create mode 100644 lib/isc/include/isc/lex.h create mode 100644 lib/isc/include/isc/lfsr.h create mode 100644 lib/isc/include/isc/lib.h create mode 100644 lib/isc/include/isc/list.h create mode 100644 lib/isc/include/isc/log.h create mode 100644 lib/isc/include/isc/magic.h create mode 100644 lib/isc/include/isc/md5.h create mode 100644 lib/isc/include/isc/mem.h create mode 100644 lib/isc/include/isc/msgcat.h create mode 100644 lib/isc/include/isc/msgs.h create mode 100644 lib/isc/include/isc/mutexblock.h create mode 100644 lib/isc/include/isc/netaddr.h create mode 100644 lib/isc/include/isc/netscope.h create mode 100644 lib/isc/include/isc/ondestroy.h create mode 100644 lib/isc/include/isc/os.h create mode 100644 lib/isc/include/isc/parseint.h create mode 100644 lib/isc/include/isc/platform.h.in create mode 100644 lib/isc/include/isc/print.h create mode 100644 lib/isc/include/isc/quota.h create mode 100644 lib/isc/include/isc/random.h create mode 100644 lib/isc/include/isc/ratelimiter.h create mode 100644 lib/isc/include/isc/refcount.h create mode 100644 lib/isc/include/isc/region.h create mode 100644 lib/isc/include/isc/resource.h create mode 100644 lib/isc/include/isc/result.h create mode 100644 lib/isc/include/isc/resultclass.h create mode 100644 lib/isc/include/isc/rwlock.h create mode 100644 lib/isc/include/isc/serial.h create mode 100644 lib/isc/include/isc/sha1.h create mode 100644 lib/isc/include/isc/sha2.h create mode 100644 lib/isc/include/isc/sockaddr.h create mode 100644 lib/isc/include/isc/socket.h create mode 100644 lib/isc/include/isc/stdio.h create mode 100644 lib/isc/include/isc/stdlib.h create mode 100644 lib/isc/include/isc/string.h create mode 100644 lib/isc/include/isc/symtab.h create mode 100644 lib/isc/include/isc/task.h create mode 100644 lib/isc/include/isc/taskpool.h create mode 100644 lib/isc/include/isc/timer.h create mode 100644 lib/isc/include/isc/types.h create mode 100644 lib/isc/include/isc/util.h create mode 100644 lib/isc/include/isc/version.h create mode 100644 lib/isc/inet_aton.c create mode 100644 lib/isc/inet_ntop.c create mode 100644 lib/isc/inet_pton.c create mode 100644 lib/isc/lex.c create mode 100644 lib/isc/lfsr.c create mode 100644 lib/isc/lib.c create mode 100644 lib/isc/log.c create mode 100644 lib/isc/md5.c create mode 100644 lib/isc/mem.c create mode 100644 lib/isc/mips/Makefile.in create mode 100644 lib/isc/mips/include/Makefile.in create mode 100644 lib/isc/mips/include/isc/Makefile.in create mode 100644 lib/isc/mips/include/isc/atomic.h create mode 100644 lib/isc/mutexblock.c create mode 100644 lib/isc/netaddr.c create mode 100644 lib/isc/netscope.c create mode 100644 lib/isc/nls/Makefile.in create mode 100644 lib/isc/nls/msgcat.c create mode 100644 lib/isc/noatomic/Makefile.in create mode 100644 lib/isc/noatomic/include/Makefile.in create mode 100644 lib/isc/noatomic/include/isc/Makefile.in create mode 100644 lib/isc/noatomic/include/isc/atomic.h create mode 100644 lib/isc/nothreads/Makefile.in create mode 100644 lib/isc/nothreads/condition.c create mode 100644 lib/isc/nothreads/include/Makefile.in create mode 100644 lib/isc/nothreads/include/isc/Makefile.in create mode 100644 lib/isc/nothreads/include/isc/condition.h create mode 100644 lib/isc/nothreads/include/isc/mutex.h create mode 100644 lib/isc/nothreads/include/isc/once.h create mode 100644 lib/isc/nothreads/include/isc/thread.h create mode 100644 lib/isc/nothreads/mutex.c create mode 100644 lib/isc/nothreads/thread.c create mode 100644 lib/isc/ondestroy.c create mode 100644 lib/isc/parseint.c create mode 100644 lib/isc/powerpc/Makefile.in create mode 100644 lib/isc/powerpc/include/Makefile.in create mode 100644 lib/isc/powerpc/include/isc/Makefile.in create mode 100644 lib/isc/powerpc/include/isc/atomic.h create mode 100644 lib/isc/print.c create mode 100644 lib/isc/pthreads/Makefile.in create mode 100644 lib/isc/pthreads/condition.c create mode 100644 lib/isc/pthreads/include/Makefile.in create mode 100644 lib/isc/pthreads/include/isc/Makefile.in create mode 100644 lib/isc/pthreads/include/isc/condition.h create mode 100644 lib/isc/pthreads/include/isc/mutex.h create mode 100644 lib/isc/pthreads/include/isc/once.h create mode 100644 lib/isc/pthreads/include/isc/thread.h create mode 100644 lib/isc/pthreads/mutex.c create mode 100644 lib/isc/pthreads/thread.c create mode 100644 lib/isc/quota.c create mode 100644 lib/isc/random.c create mode 100644 lib/isc/ratelimiter.c create mode 100644 lib/isc/refcount.c create mode 100644 lib/isc/region.c create mode 100644 lib/isc/result.c create mode 100644 lib/isc/rwlock.c create mode 100644 lib/isc/serial.c create mode 100644 lib/isc/sha1.c create mode 100644 lib/isc/sha2.c create mode 100644 lib/isc/sockaddr.c create mode 100644 lib/isc/sparc64/Makefile.in create mode 100644 lib/isc/sparc64/include/Makefile.in create mode 100644 lib/isc/sparc64/include/isc/Makefile.in create mode 100644 lib/isc/sparc64/include/isc/atomic.h create mode 100644 lib/isc/string.c create mode 100644 lib/isc/strtoul.c create mode 100644 lib/isc/symtab.c create mode 100644 lib/isc/task.c create mode 100644 lib/isc/task_p.h create mode 100644 lib/isc/taskpool.c create mode 100644 lib/isc/timer.c create mode 100644 lib/isc/timer_p.h create mode 100644 lib/isc/unix/Makefile.in create mode 100644 lib/isc/unix/app.c create mode 100644 lib/isc/unix/dir.c create mode 100644 lib/isc/unix/entropy.c create mode 100644 lib/isc/unix/errno2result.c create mode 100644 lib/isc/unix/errno2result.h create mode 100644 lib/isc/unix/file.c create mode 100644 lib/isc/unix/fsaccess.c create mode 100644 lib/isc/unix/ifiter_getifaddrs.c create mode 100644 lib/isc/unix/ifiter_ioctl.c create mode 100644 lib/isc/unix/ifiter_sysctl.c create mode 100644 lib/isc/unix/include/Makefile.in create mode 100644 lib/isc/unix/include/isc/Makefile.in create mode 100644 lib/isc/unix/include/isc/dir.h create mode 100644 lib/isc/unix/include/isc/int.h create mode 100644 lib/isc/unix/include/isc/keyboard.h create mode 100644 lib/isc/unix/include/isc/net.h create mode 100644 lib/isc/unix/include/isc/netdb.h create mode 100644 lib/isc/unix/include/isc/offset.h create mode 100644 lib/isc/unix/include/isc/stat.h create mode 100644 lib/isc/unix/include/isc/stdtime.h create mode 100644 lib/isc/unix/include/isc/strerror.h create mode 100644 lib/isc/unix/include/isc/syslog.h create mode 100644 lib/isc/unix/include/isc/time.h create mode 100644 lib/isc/unix/interfaceiter.c create mode 100644 lib/isc/unix/ipv6.c create mode 100644 lib/isc/unix/keyboard.c create mode 100644 lib/isc/unix/net.c create mode 100644 lib/isc/unix/os.c create mode 100644 lib/isc/unix/resource.c create mode 100644 lib/isc/unix/socket.c create mode 100644 lib/isc/unix/socket_p.h create mode 100644 lib/isc/unix/stdio.c create mode 100644 lib/isc/unix/stdtime.c create mode 100644 lib/isc/unix/strerror.c create mode 100644 lib/isc/unix/syslog.c create mode 100644 lib/isc/unix/time.c create mode 100644 lib/isc/version.c create mode 100644 lib/isc/x86_32/Makefile.in create mode 100644 lib/isc/x86_32/include/Makefile.in create mode 100644 lib/isc/x86_32/include/isc/Makefile.in create mode 100644 lib/isc/x86_32/include/isc/atomic.h create mode 100644 lib/isc/x86_64/Makefile.in create mode 100644 lib/isc/x86_64/include/Makefile.in create mode 100644 lib/isc/x86_64/include/isc/Makefile.in create mode 100644 lib/isc/x86_64/include/isc/atomic.h create mode 100644 lib/isccc/Makefile.in create mode 100644 lib/isccc/alist.c create mode 100644 lib/isccc/api create mode 100644 lib/isccc/base64.c create mode 100644 lib/isccc/cc.c create mode 100644 lib/isccc/ccmsg.c create mode 100644 lib/isccc/include/Makefile.in create mode 100644 lib/isccc/include/isccc/Makefile.in create mode 100644 lib/isccc/include/isccc/alist.h create mode 100644 lib/isccc/include/isccc/base64.h create mode 100644 lib/isccc/include/isccc/cc.h create mode 100644 lib/isccc/include/isccc/ccmsg.h create mode 100644 lib/isccc/include/isccc/events.h create mode 100644 lib/isccc/include/isccc/lib.h create mode 100644 lib/isccc/include/isccc/result.h create mode 100644 lib/isccc/include/isccc/sexpr.h create mode 100644 lib/isccc/include/isccc/symtab.h create mode 100644 lib/isccc/include/isccc/symtype.h create mode 100644 lib/isccc/include/isccc/types.h create mode 100644 lib/isccc/include/isccc/util.h create mode 100644 lib/isccc/include/isccc/version.h create mode 100644 lib/isccc/lib.c create mode 100644 lib/isccc/result.c create mode 100644 lib/isccc/sexpr.c create mode 100644 lib/isccc/symtab.c create mode 100644 lib/isccc/version.c create mode 100644 lib/isccfg/Makefile.in create mode 100644 lib/isccfg/aclconf.c create mode 100644 lib/isccfg/api create mode 100644 lib/isccfg/include/Makefile.in create mode 100644 lib/isccfg/include/isccfg/Makefile.in create mode 100644 lib/isccfg/include/isccfg/aclconf.h create mode 100644 lib/isccfg/include/isccfg/cfg.h create mode 100644 lib/isccfg/include/isccfg/grammar.h create mode 100644 lib/isccfg/include/isccfg/log.h create mode 100644 lib/isccfg/include/isccfg/namedconf.h create mode 100644 lib/isccfg/include/isccfg/version.h create mode 100644 lib/isccfg/log.c create mode 100644 lib/isccfg/namedconf.c create mode 100644 lib/isccfg/parser.c create mode 100644 lib/isccfg/version.c create mode 100644 lib/lwres/Makefile.in create mode 100644 lib/lwres/api create mode 100644 lib/lwres/assert_p.h create mode 100644 lib/lwres/context.c create mode 100644 lib/lwres/context_p.h create mode 100644 lib/lwres/gai_strerror.c create mode 100644 lib/lwres/getaddrinfo.c create mode 100644 lib/lwres/gethost.c create mode 100644 lib/lwres/getipnode.c create mode 100644 lib/lwres/getnameinfo.c create mode 100644 lib/lwres/getrrset.c create mode 100644 lib/lwres/herror.c create mode 100644 lib/lwres/include/Makefile.in create mode 100644 lib/lwres/include/lwres/Makefile.in create mode 100644 lib/lwres/include/lwres/context.h create mode 100644 lib/lwres/include/lwres/int.h create mode 100644 lib/lwres/include/lwres/ipv6.h create mode 100644 lib/lwres/include/lwres/lang.h create mode 100644 lib/lwres/include/lwres/list.h create mode 100644 lib/lwres/include/lwres/lwbuffer.h create mode 100644 lib/lwres/include/lwres/lwpacket.h create mode 100644 lib/lwres/include/lwres/lwres.h create mode 100644 lib/lwres/include/lwres/netdb.h.in create mode 100644 lib/lwres/include/lwres/platform.h.in create mode 100644 lib/lwres/include/lwres/result.h create mode 100644 lib/lwres/include/lwres/stdlib.h create mode 100644 lib/lwres/include/lwres/version.h create mode 100644 lib/lwres/lwbuffer.c create mode 100644 lib/lwres/lwconfig.c create mode 100644 lib/lwres/lwinetaton.c create mode 100644 lib/lwres/lwinetntop.c create mode 100644 lib/lwres/lwinetpton.c create mode 100644 lib/lwres/lwpacket.c create mode 100644 lib/lwres/lwres_gabn.c create mode 100644 lib/lwres/lwres_gnba.c create mode 100644 lib/lwres/lwres_grbn.c create mode 100644 lib/lwres/lwres_noop.c create mode 100644 lib/lwres/lwresutil.c create mode 100644 lib/lwres/man/Makefile.in create mode 100644 lib/lwres/man/lwres.3 create mode 100644 lib/lwres/man/lwres.docbook create mode 100644 lib/lwres/man/lwres.html create mode 100644 lib/lwres/man/lwres_buffer.3 create mode 100644 lib/lwres/man/lwres_buffer.docbook create mode 100644 lib/lwres/man/lwres_buffer.html create mode 100644 lib/lwres/man/lwres_config.3 create mode 100644 lib/lwres/man/lwres_config.docbook create mode 100644 lib/lwres/man/lwres_config.html create mode 100644 lib/lwres/man/lwres_context.3 create mode 100644 lib/lwres/man/lwres_context.docbook create mode 100644 lib/lwres/man/lwres_context.html create mode 100644 lib/lwres/man/lwres_gabn.3 create mode 100644 lib/lwres/man/lwres_gabn.docbook create mode 100644 lib/lwres/man/lwres_gabn.html create mode 100644 lib/lwres/man/lwres_gai_strerror.3 create mode 100644 lib/lwres/man/lwres_gai_strerror.docbook create mode 100644 lib/lwres/man/lwres_gai_strerror.html create mode 100644 lib/lwres/man/lwres_getaddrinfo.3 create mode 100644 lib/lwres/man/lwres_getaddrinfo.docbook create mode 100644 lib/lwres/man/lwres_getaddrinfo.html create mode 100644 lib/lwres/man/lwres_gethostent.3 create mode 100644 lib/lwres/man/lwres_gethostent.docbook create mode 100644 lib/lwres/man/lwres_gethostent.html create mode 100644 lib/lwres/man/lwres_getipnode.3 create mode 100644 lib/lwres/man/lwres_getipnode.docbook create mode 100644 lib/lwres/man/lwres_getipnode.html create mode 100644 lib/lwres/man/lwres_getnameinfo.3 create mode 100644 lib/lwres/man/lwres_getnameinfo.docbook create mode 100644 lib/lwres/man/lwres_getnameinfo.html create mode 100644 lib/lwres/man/lwres_getrrsetbyname.3 create mode 100644 lib/lwres/man/lwres_getrrsetbyname.docbook create mode 100644 lib/lwres/man/lwres_getrrsetbyname.html create mode 100644 lib/lwres/man/lwres_gnba.3 create mode 100644 lib/lwres/man/lwres_gnba.docbook create mode 100644 lib/lwres/man/lwres_gnba.html create mode 100644 lib/lwres/man/lwres_hstrerror.3 create mode 100644 lib/lwres/man/lwres_hstrerror.docbook create mode 100644 lib/lwres/man/lwres_hstrerror.html create mode 100644 lib/lwres/man/lwres_inetntop.3 create mode 100644 lib/lwres/man/lwres_inetntop.docbook create mode 100644 lib/lwres/man/lwres_inetntop.html create mode 100644 lib/lwres/man/lwres_noop.3 create mode 100644 lib/lwres/man/lwres_noop.docbook create mode 100644 lib/lwres/man/lwres_noop.html create mode 100644 lib/lwres/man/lwres_packet.3 create mode 100644 lib/lwres/man/lwres_packet.docbook create mode 100644 lib/lwres/man/lwres_packet.html create mode 100644 lib/lwres/man/lwres_resutil.3 create mode 100644 lib/lwres/man/lwres_resutil.docbook create mode 100644 lib/lwres/man/lwres_resutil.html create mode 100644 lib/lwres/print.c create mode 100644 lib/lwres/print_p.h create mode 100644 lib/lwres/strtoul.c create mode 100644 lib/lwres/unix/Makefile.in create mode 100644 lib/lwres/unix/include/Makefile.in create mode 100644 lib/lwres/unix/include/lwres/Makefile.in create mode 100644 lib/lwres/unix/include/lwres/net.h create mode 100644 lib/lwres/version.c create mode 100644 libtool.m4 create mode 100644 ltmain.sh create mode 100644 make/Makefile.in create mode 100644 make/includes.in create mode 100644 make/mkdep.in create mode 100644 make/rules.in create mode 100755 mkinstalldirs create mode 100644 version diff --git a/CHANGES b/CHANGES new file mode 100644 index 0000000..06b6052 --- /dev/null +++ b/CHANGES @@ -0,0 +1,7120 @@ + + --- 9.4.2 released --- + --- 9.4.2rc2 released --- + +2259. [bug] Reverse incorrect LIBINTERFACE bump of libisc + in 9.4.2rc1. Applications built against 9.4.2rc1 + will need to be rebuilt. + +2258. [bug] Fallback from IXFR/TSIG to SOA/AXFR/TSIG broken. + [RT #17241] + +2257. [bug] win32: Use the full path to vcredist_x86.exe when + calling it. [RT #17222] + +2256. [bug] win32: Correctly register the installation location of + bindevt.dll. [RT #17159] + +2255. [bug] L.ROOT-SERVERS.NET is now 199.7.83.42. + +2254. [bug] timer.c:dispatch() failed to lock timer->lock + when reading timer->idle allowing it to see + intermediate values as timer->idle was reset by + isc_timer_touch(). [RT #17243] + + --- 9.4.2rc1 released --- + +2251. [doc] Update memstatistics-file documentation to reflect + reality. Note there is behaviour change for BIND 9.5. + [RT #17113] + +2249. [bug] Only set Authentic Data bit if client requested + DNSSEC, per RFC 3655 [RT #17175] + +2248. [cleanup] Fix several errors reported by Coverity. [RT #17160] + +2245. [bug] Validating lack of DS records at trust anchors wasn't + working. [RT #17151] + +2238. [bug] It was possible to trigger a REQUIRE when a + validation was cancelled. [RT #17106] + +2237. [bug] libbind: res_init() was not thread aware. [RT #17123] + +2236. [bug] dnssec-signzone failed to preserve the case of + of wildcard owner names. [RT #17085] + +2235. [bug] was not being installed. [RT #17135] + +2234. [port] Correct some compiler warnings on SCO OSr5 [RT #17134] + +2232. [bug] dns_adb_findaddrinfo() could fail and return + ISC_R_SUCCESS. [RT #17137] + +2231. [bug] Building dlzbdb (contrib/dlz/bin/dlzbdb) was broken. + [RT #17088] + +2230. [bug] We could INSIST reading a corrupted journal. + [RT #17132] + +2228. [contrib] contrib: Change 2188 was incomplete. + +2227. [cleanup] Tidied up the FAQ. [RT #17121] + +2225. [bug] More support for systems with no IPv4 addresses. + [RT #17111] + +2224. [bug] Defer journal compaction if a xfrin is in progress. + [RT #17119] + +2223. [bug] Make a new journal when compacting. [RT #17119] + +2221. [bug] Set the event result code to reflect the actual + record returned to caller when a cache update is + rejected due to a more credible answer existing. + [RT #17017] + +2220. [bug] win32: Address a race condition in final shutdown of + the Windows socket code. [RT #17028] + +2219. [bug] Apply zone consistancy checks to additions, not + removals, when updating. [RT #17049] + +2218. [bug] Remove unnecessary REQUIRE from dns_validator_create(). + [RT #16976] + +2216. [cleanup] Fix a number of errors reported by Coverity. + [RT #17094] + +2215. [bug] Bad REQUIRE check isc_hmacsha1_verify(). [RT #17094] + +2214. [bug] Deregister OpenSSL lock callback when cleaning + up. Reorder OpenSSL cleanup so that RAND_cleanup() + is called before the locks are destroyed. [RT #17098] + +2213. [bug] SIG0 diagnostic failure messages were looking at the + wrong status code. [RT #17101] + +2212. [func] 'host -m' now causes memory statistics and active + memory to be printed at exit. [RT 17028] + +2210. [bug] Deleting class specific records via UPDATE could + fail. [RT #17074] + +2209. [port] osx: linking against user supplied static OpenSSL + libraries failed as the system ones were still being + found. [RT #17078] + +2208. [port] win32: make sure both build methods produce the + same output. [RT #17058] + +2207. [port] Some implementations of getaddrinfo() fail to set + ai_canonname correctly. [RT #17061] + + --- 9.4.2b1 released --- + +2206. [security] "allow-query-cache" and "allow-recursion" now + cross inherit from each other. + + If allow-query-cache is not set in named.conf then + allow-recursion is used if set, otherwise allow-query + is used if set, otherwise the default (localnets; + localhost;) is used. + + If allow-recursion is not set in named.conf then + allow-query-cache is used if set, otherwise allow-query + is used if set, otherwise the default (localnets; + localhost;) is used. + + [RT #16987] + +2205. [bug] libbind: change #2119 broke thread support. [RT #16982] + +2203. [security] Query id generation was cryptographically weak. + [RT # 16915] + +2202. [security] The default acls for allow-query-cache and + allow-recursion were not being applied. [RT #16960] + +2200. [bug] The search for cached NSEC records was stopping to + early leading to excessive DLV queries. [RT #16930] + +2199. [bug] win32: don't call WSAStartup() while loading dlls. + [RT #16911] + +2198. [bug] win32: RegCloseKey() could be called when + RegOpenKeyEx() failed. [RT #16911] + +2197. [bug] Add INSIST to catch negative responses which are + not setting the event result code appropriately. + [RT #16909] + +2196. [port] win32: yield processor while waiting for once to + to complete. [RT #16958] + +2194. [bug] Close journal before calling 'done' in xfrin.c. + +2193. [port] win32: BINDInstall.exe is now linked statically. + [RT #16906] + +2192. [port] win32: use vcredist_x86.exe to install Visual + Studio's redistributable dlls if building with + Visual Stdio 2005 or later. + +2189. [bug] Handle socket() returning EINTR. [RT #15949] + +2188. [contrib] queryperf: autoconf changes to make the search for + libresolv or libbind more robust. [RT #16299] + +2187. [bug] query_addds(), query_addwildcardproof() and + query_addnxrrsetnsec() should take a version + arguement. [RT #16368] + +2186. [port] cygwin: libbind: check for struct sockaddr_storage + independently of IPv6. [RT #16482] + +2185. [port] sunos: libbind: check for ssize_t, memmove() and + memchr(). [RT #16463] + +2183. [bug] dnssec-signzone didn't handle offline private keys + well. [RT #16832] + +2182. [bug] dns_dispatch_createtcp() and dispatch_createudp() + could return ISC_R_SUCCESS when they ran out of + memory. [RT #16365] + +2181. [port] sunos: libbind: add paths.h from BIND 8. [RT #16462] + +2180. [cleanup] Remove bit test from 'compress_test' as they + are no longer needed. [RT #16497] + +2178. [bug] 'rndc reload' of a slave or stub zone resulted in + a reference leak. [RT #16867] + +2177. [bug] Array bounds overrun on read (rcodetext) at + debug level 10+. [RT #16798] + +2176. [contrib] dbus update to handle race condition during + initialisation (Bugzilla 235809). [RT #16842] + +2175. [bug] win32: windows broadcast condition variable support + was broken. [RT #16592] + +2174. [bug] I/O errors should always be fatal when reading + master files. [RT #16825] + +2173. [port] win32: When compiling with MSVS 2005 SP1 we also + need to ship Microsoft.VC80.MFCLOC. + +2171. [bug] Handle breaks in DNSSEC trust chains where the parent + servers are not DS aware (DS queries to the parent + return a referral to the child). + +2170. [func] Add acache processing to test suite. [RT #16711] + +2169. [bug] host, nslookup: when reporting NXDOMAIN report the + given name and not the last name searched for. + [RT #16763] + +2168. [bug] nsupdate: in non-interactive mode treat syntax errors + as fatal errors. [RT #16785] + +2167. [bug] When re-using a automatic zone named failed to + attach it to the new view. [RT #16786] + +2166. [bug] When running in batch mode, dig could misinterpret + a server address as a name to be looked up, causing + unexpected output. [RT #16743] + +2164. [bug] The code to determine how named-checkzone / + named-compilezone was called failed under windows. + [RT #16764] + +2162. [func] Allow "rrset-order fixed" to be disabled at compile + time. [RT #16665] + +2161. [bug] 'rndc flush' could report a false success. [RT #16698] + +2160. [bug] libisc wasn't handling NULL ifa_addr pointers returned + from getifaddrs(). [RT #16708] + +2159. [bug] Array bounds overrun in acache processing. [RT #16710] + +2158. [bug] ns_client_isself() failed to initialise key + leading to a REQUIRE failure. [RT #16688] + +2156. [bug] Fix node reference leaks in lookup.c:lookup_find(), + resolver.c:validated() and resolver.c:cache_name(). + Fix a memory leak in rbtdb.c:free_noqname(). + Make lookup.c:lookup_find() robust against + event leaks. [RT #16685] + +2155. [contrib] SQLite sdb module from jaboydjr@netwalk.com. + [RT #16694] + +2153. [bug] nsupdate could leak memory. [RT #16691] + +2152. [cleanup] Use sizeof(buf) instead of fixed number in + dighost.c:get_trusted_key(). [RT #16678] + +2151. [bug] Missing newline in usage message for journalprint. + [RT #16679] + +2150. [bug] 'rrset-order cyclic' uniformly distribute the + starting point for the first response for a given + RRset. [RT #16655] + +2149. [bug] isc_mem_checkdestroyed() failed to abort on + if there were still active memory contexts. + [RT #16672] + +2147. [bug] libbind: remove potential buffer overflow from + hmac_link.c. [RT #16437] + +2146. [cleanup] Silence Linux's spurious "obsolete setsockopt + SO_BSDCOMPAT" message. [RT #16641] + +2145. [bug] Check DS/DLV digest lengths for known digests. + [RT #16622] + +2144. [cleanup] Suppress logging of SERVFAIL from forwarders. + [RT #16619] + +2143. [bug] We failed to restart the IPv6 client when the + kernel failed to return the destination the + packet was sent to. [RT #16613] + +2142. [bug] Handle master files with a modification time that + matches the epoch. [RT# 16612] + +2141. [bug] dig/host should not be setting IDN_ASCCHECK (IDN + equivalent of LDH checks). [RT #16609] + +2140. [bug] libbind: missing unlock on pthread_key_create() + failures. [RT #16654] + +2139. [bug] dns_view_find() was being called with wrong type + in adb.c. [RT #16670] + +2119. [compat] libbind: allow res_init() to succeed enough to + return the default domain even if it was unable + to allocate memory. + + --- 9.4.1 released --- + +2172. [bug] query_addsoa() was being called with a non zone db. + [RT #16834] + + --- 9.4.0 released --- + +2138. [bug] Lock order reversal in resolver.c. [RT #16653] + +2137. [port] Mips little endian and/or mips 64 bit are now + supported for atomic operations. [RT#16648] + +2136. [bug] nslookup/host looped if there was no search list + and the host didn't exist. [RT #16657] + +2135. [bug] Uninitialised rdataset in sdlz.c. [RT# 16656] + +2133. [port] powerpc: Support both IBM and MacOS Power PC + assembler syntaxes. [RT #16647] + +2132. [bug] Missing unlock on out of memory in + dns_dispatchmgr_setudp(). + +2131. [contrib] dlz/mysql: AXFR was broken. [RT #16630] + +2128. [doc] xsltproc --nonet, update DTD versions. [RT #16635] + + --- 9.4.0rc2 released --- + +2127. [port] Improved OpenSSL 0.9.8 support. [RT #16563] + +2126. [security] Serialise validation of type ANY responses. [RT #16555] + +2125. [bug] dns_zone_getzeronosoattl() REQUIRE failure if DLZ + was defined. [RT #16574] + +2124. [security] It was possible to dereference a freed fetch + context. [RT #16584] + +2120. [doc] Fix markup on nsupdate man page. [RT #16556] + + --- 9.4.0rc1 released --- + +2118. [bug] Handle response with long chains of domain name + compression pointers which point to other compression + pointers. [RT #16427] + +2117. [bug] DNSSEC fixes: named could fail to cache NSEC records + which could lead to validation failures. named didn't + handle negative DS responses that were in the process + of being validated. Check CNAME bit before accepting + NODATA proof. To be able to ignore a child NSEC there + must be SOA (and NS) set in the bitmap. [RT #16399] + +2116. [bug] 'rndc reload' could cause the cache to continually + be cleaned. [RT #16401] + +2115. [bug] 'rndc reconfig' could trigger a INSIST if the + number of masters for a zone was reduced. [RT #16444] + +2114. [bug] dig/host/nslookup: searches for names with multiple + labels were failing. [RT #16447] + +2113. [bug] nsupdate: if a zone is specified it should be used + for server discover. [RT# 16455] + +2112. [security] Warn if weak RSA exponent is used. [RT #16460] + +2111. [bug] Fix a number of errors reported by Coverity. + [RT #16507] + +2110. [bug] "minimal-response yes;" interacted badly with BIND 8 + priming queries. [RT #16491] + +2109. [port] libbind: silence aix 5.3 compiler warnings. [RT #16502] + +2107. [bug] dighost.c: more cleanup of buffers. [RT #16499] + +2104. [port] Fix Solaris SMF error message. + +2103. [port] Add /usr/sfw to list of locations for OpenSSL + under Solaris. + +2102. [port] Silence solaris 10 warnings. + + --- 9.4.0b4 released --- + +2101. [bug] OpenSSL version checks were not quite right. + [RT #16476] + +2100. [port] win32: copy libeay32.dll to Build\Debug. + Copy Debug\named-checkzone to Debug\named-compilezone. + +2099. [port] win32: more manifiest issues. + +2098. [bug] Race in rbtdb.c:no_references(), which occasionally + triggered an INSIST failure about the node lock + reference. [RT #16411] + + --- 9.4.0b3 released --- + +2097. [bug] named could reference a destroyed memory context + after being reloaded / reconfigured. [RT #16428] + +2096. [bug] libbind: handle applications that fail to detect + res_init() failures better. + +2095. [port] libbind: alway prototype inet_cidr_ntop_ipv6() and + net_cidr_ntop_ipv6(). [RT #16388] + +2094. [contrib] Update named-bootconf. [RT# 16404] + +2093. [bug] named-checkzone -s was broken. + +2092. [bug] win32: dig, host, nslookup. Use registry config + if resolv.conf does not exist or no nameservers + listed. [RT #15877] + +2091. [port] dighost.c: race condition on cleanup. [RT #16417] + +2090. [port] win32: Visual C++ 2005 command line manifest support. + [RT #16417] + +2089. [security] Raise the minimum safe OpenSSL versions to + OpenSSL 0.9.7l and OpenSSL 0.9.8d. Versions + prior to these have known security flaws which + are (potentially) exploitable in named. [RT #16391] + +2088. [security] Change the default RSA exponent from 3 to 65537. + [RT #16391] + +2087. [port] libisc failed to compile on OS's w/o a vsnprintf. + [RT #16382] + +2086. [port] libbind: FreeBSD now has get*by*_r() functions. + [RT #16403] + +2085. [doc] win32: added index.html and README to zip. [RT #16201] + +2084. [contrib] dbus update for 9.3.3rc2. + +2083. [port] win32: Visual C++ 2005 support. + +2082. [doc] Document 'cache-file' as a test only option. + + --- 9.4.0b2 released --- + +2081. [port] libbind: minor 64-bit portability fix in memcluster.c. + [RT #16360] + +2080. [port] libbind: res_init.c did not compile on older versions + of Solaris. [RT #16363] + +2079. [bug] The lame cache was not handling multiple types + correctly. [RT #16361] + +2078. [bug] dnssec-checkzone output style "default" was badly + named. It is now called "relative". [RT #16326] + +2077. [bug] 'dnssec-signzone -O raw' wasn't outputing the + complete signed zone. [RT #16326] + +2076. [bug] Several files were missing #include + causing build failures on OSF. [RT #16341] + +2075. [bug] The spillat timer event hander could leak memory. + [RT #16357] + +2074. [bug] dns_request_createvia2(), dns_request_createvia3(), + dns_request_createraw2() and dns_request_createraw3() + failed to send multiple UDP requests. [RT #16349] + +2073. [bug] Incorrect semantics check for update policy "wildcard". + [RT #16353] + +2072. [bug] We were not generating valid HMAC SHA digests. + [RT #16320] + +2071. [port] Test whether gcc accepts -fno-strict-aliasing. + [RT #16324] + +2070. [bug] The remote address was not always displayed when + reporting dispatch failures. [RT #16315] + +2069. [bug] Cross compiling was not working. [RT #16330] + +2068. [cleanup] Lower incremental tuning message to debug 1. + [RT #16319] + +2067. [bug] 'rndc' could close the socket too early triggering + a INSIST under Windows. [RT #16317] + +2066. [security] Handle SIG queries gracefully. [RT #16300] + +2065. [bug] libbind: probe for HPUX prototypes for + endprotoent_r() and endservent_r(). [RT 16313] + +2064. [bug] libbind: silence AIX compiler warnings. [RT #16218] + +2063. [bug] Change #1955 introduced a bug which caused the first + 'rndc flush' call to not free memory. [RT #16244] + +2062. [bug] 'dig +nssearch' was reusing a buffer before it had + been returned by the socket code. [RT #16307] + +2061. [bug] Accept expired wildcard message reversed. [RT #16296] + +2060. [bug] Enabling DLZ support could leave views partially + configured. [RT #16295] + + --- 9.4.0b1 released --- + +2059. [bug] Search into cache rbtdb could trigger an INSIST + failure while cleaning up a stale rdataset. + [RT #16292] + +2058. [bug] Adjust how we calculate rtt estimates in the presence + of authoritative servers that drop EDNS and/or CD + requests. Also fallback to EDNS/512 and plain DNS + faster for zones with less than 3 servers. [RT #16187] + +2057. [bug] Make setting "ra" dependent on both allow-query-cache + and allow-recursion. [RT #16290] + +2056. [bug] dig: ixfr= was not being treated case insensitively + at all times. [RT #15955] + +2055. [bug] Missing goto after dropping multicast query. + [RT #15944] + +2054. [port] freebsd: do not explicitly link against -lpthread. + [RT #16170] + +2053. [port] netbsd:libbind: silence compiler warnings. [RT #16220] + +2052. [bug] 'rndc' improve connect failed message to report + the failing address. [RT #15978] + +2051. [port] More strtol() fixes. [RT #16249] + +2050. [bug] Parsing of NSAP records was not case insensitive. + [RT #16287] + +2049. [bug] Restore SOA before AXFR when falling back from + a attempted IXFR when transfering in a zone. + Allow a initial SOA query before attempting + a AXFR to be requested. [RT #16156] + +2048. [bug] It was possible to loop forever when using + avoid-v4-udp-ports / avoid-v6-udp-ports when + the OS always returned the same local port. + [RT #16182] + +2047. [bug] Failed to initialise the interface flags to zero. + [RT #16245] + +2046. [bug] rbtdb.c:rdataset_setadditional() could cause duplicate + cleanup [RT #16247]. + +2045. [func] Use lock buckets for acache entries to limit memory + consumption. [RT #16183] + +2044. [port] Add support for atomic operations for Itanium. + [RT #16179] + +2043. [port] nsupdate/nslookup: Force the flushing of the prompt + for interactive sessions. [RT#16148] + +2042. [bug] named-checkconf was incorrectly rejecting the + logging category "config". [RT #16117] + +2041. [bug] "configure --with-dlz-bdb=yes" produced a bad + set of libraries to be linked. [RT #16129] + +2040. [bug] rbtdb no_references() could trigger an INSIST + failure with --enable-atomic. [RT #16022] + +2039. [func] Check that all buffers passed to the socket code + have been retrieved when the socket event is freed. + [RT #16122] + +2038. [bug] dig/nslookup/host was unlinking from wrong list + when handling errors. [RT #16122] + +2037. [func] When unlinking the first or last element in a list + check that the list head points to the element to + be unlinked. [RT #15959] + +2036. [bug] 'rndc recursing' could cause trigger a REQUIRE. + [RT #16075] + +2034. [bug] gcc: set -fno-strict-aliasing. [RT #16124] + +2033. [bug] We wern't creating multiple client memory contexts + on demand as expected. [RT #16095] + + --- 9.4.0a6 released --- + +2032. [bug] Remove a INSIST in query_addadditional2(). [RT #16074] + +2031. [bug] Emit a error message when "rndc refresh" is called on + a non slave/stub zone. [RT # 16073] + +2030. [bug] We were being overly conservative when disabling + openssl engine support. [RT #16030] + +2029. [bug] host printed out the server multiple times when + specified on the command line. [RT #15992] + +2028. [port] linux: socket.c compatability for old systems. + [RT #16015] + +2027. [port] libbind: Solaris x86 support. [RT #16020] + +2026. [bug] Rate limit the two recursive client exceeded messages. + [RT #16044] + +2025. [func] Update "zone serial unchanged" message. [RT #16026] + +2024. [bug] named emited spurious "zone serial unchanged" + messages on reload. [RT #16027] + +2023. [bug] "make install" should create ${localstatedir}/run and + ${sysconfdir} if they do not exist. [RT #16033] + +2022. [bug] If dnssec validation is disabled only assert CD if + CD was requested. [RT #16037] + +2021. [bug] dnssec-enable no; triggered a REQUIRE. [RT #16037] + +2020. [bug] rdataset_setadditional() could leak memory. [RT #16034] + +2019. [tuning] Reduce the amount of work performed per quantum + when cleaning the cache. [RT #15986] + +2018. [bug] Checking if the HMAC MD5 private file was broken. + [RT #15960] + +2017. [bug] allow-query default was not correct. [RT #15946] + +2016. [bug] Return a partial answer if recursion is not + allowed but requested and we had the answer + to the original qname. [RT #15945] + + --- 9.4.0a5 released --- + +2015. [cleanup] use-additional-cache is now acache-enable for + consistancy. Default acache-enable off in BIND 9.4 + as it requires memory usage to be configured. + It may be enabled by default in BIND 9.5 once we + have more experience with it. + +2014. [func] Statistics about acache now recorded and sent + to log. [RT #15976] + +2013. [bug] Handle unexpected TSIGs on unsigned AXFR/IXFR + responses more gracefully. [RT #15941] + +2012. [func] Don't insert new acache entries if acache is full. + [RT #15970] + +2011. [func] dnssec-signzone can now update the SOA record of + the signed zone, either as an increment or as the + system time(). [RT #15633] + + --- 9.4.0a4 released --- + +2009. [bug] libbind: coverity fixes. [RT #15808] + +2008. [func] It is now posssible to enable/disable DNSSEC + validation from rndc. This is useful for the + mobile hosts where the current connection point + breaks DNSSEC (firewall/proxy). [RT #15592] + + rndc validation newstate [view] + +2007. [func] It is now possible to explicitly enable DNSSEC + validation. default dnssec-validation no; to + be changed to yes in 9.5.0. [RT #15674] + +2006. [security] Allow-query-cache and allow-recursion now default + to the builtin acls "localnets" and "localhost". + + This is being done to make caching servers less + attractive as reflective amplifying targets for + spoofed traffic. This still leave authoritative + servers exposed. + + The best fix is for full BCP 38 deployment to + remove spoofed traffic. + +2005. [bug] libbind: Retransmission timeouts should be + based on which attempt it is to the nameserver + and not the nameserver itself. [RT #13548] + +2004. [bug] dns_tsig_sign() could pass a NULL pointer to + dst_context_destroy() when cleaning up after a + error. [RT #15835] + +2003. [bug] libbind: The DNS name/address lookup functions could + occasionally follow a random pointer due to + structures not being completely zeroed. [RT #15806] + +2002. [bug] libbind: tighten the constraints on when + struct addrinfo._ai_pad exists. [RT #15783] + +2001. [func] Check the KSK flag when updating a secure dynamic zone. + New zone option "update-check-ksk yes;". [RT #15817] + +2000. [bug] memmove()/strtol() fix was incomplete. [RT #15812] + +1999. [func] Implement "rrset-order fixed". [RT #13662] + +1998. [bug] Restrict handling of fifos as sockets to just SunOS. + This allows named to connect to entropy gathering + daemons that use fifos instead of sockets. [RT #15840] + +1997. [bug] Named was failing to replace negative cache entries + when a positive one for the type was learnt. + [RT #15818] + +1996. [bug] nsupdate: if a zone has been specified it should + appear in the output of 'show'. [RT #15797] + +1995. [bug] 'host' was reporting multiple "is an alias" messages. + [RT #15702] + +1994. [port] OpenSSL 0.9.8 support. [RT #15694] + +1993. [bug] Log messsage, via syslog, were missing the space + after the timestamp if "print-time yes" was specified. + [RT #15844] + +1992. [bug] Not all incoming zone transfer messages included the + view. [RT #15825] + +1991. [cleanup] The configuration data, once read, should be treated + as readonly. Expand the use of const to enforce this + at compile time. [RT #15813] + +1990. [bug] libbind: isc's override of broken gettimeofday() + implementions was not always effective. + [RT #15709] + +1989. [bug] win32: don't check the service password when + re-installing. [RT #15882] + +1988. [bug] Remove a bus error from the SHA256/SHA512 support. + [RT #15878] + +1987. [func] DS/DLV SHA256 digest algorithm support. [RT #15608] + +1986. [func] Report when a zone is removed. [RT #15849] + +1985. [protocol] DLV has now been assigned a official type code of + 32769. [RT #15807] + + Note: care should be taken to ensure you upgrade + both named and dnssec-signzone at the same time for + zones with DLV records where named is the master + server for the zone. Also any zones that contain + DLV records should be removed when upgrading a slave + zone. You do not however have to upgrade all + servers for a zone with DLV records simultaniously. + +1984. [func] dig, nslookup and host now advertise a 4096 byte + EDNS UDP buffer size by default. [RT #15855] + +1983. [func] Two new update policies. "selfsub" and "selfwild". + [RT #12895] + +1982. [bug] DNSKEY was being accepted on the parent side of + a delegation. KEY is still accepted there for + RFC 3007 validated updates. [RT #15620] + +1981. [bug] win32: condition.c:wait() could fail to reattain + the mutex lock. + +1980. [func] dnssec-signzone: output the SOA record as the + first record in the signed zone. [RT #15758] + +1979. [port] linux: allow named to drop core after changing + user ids. [RT #15753] + +1978. [port] Handle systems which have a broken recvmsg(). + [RT #15742] + +1977. [bug] Silence noisy log message. [RT #15704] + +1976. [bug] Handle systems with no IPv4 addresses. [RT #15695] + +1975. [bug] libbind: isc_gethexstring() could misparse multi-line + hex strings with comments. [RT #15814] + +1974. [doc] List each of the zone types and associated zone + options separately in the ARM. + +1973. [func] TSIG HMACSHA1, HMACSHA224, HMACSHA256, HMACSHA384 and + HMACSHA512 support. [RT #13606] + +1972. [contrib] DBUS dynamic forwarders integation from + Jason Vas Dias . + +1971. [port] linux: make detection of missing IF_NAMESIZE more + robust. [RT #15443] + +1970. [bug] nsupdate: adjust UDP timeout when falling back to + unsigned SOA query. [RT #15775] + +1969. [bug] win32: the socket code was freeing the socket + structure too early. [RT #15776] + +1968. [bug] Missing lock in resolver.c:validated(). [RT #15739] + +1967. [func] dig/nslookup/host: warn about missing "QR". [RT #15779] + +1966. [bug] Don't set CD when we have fallen back to plain DNS. + [RT #15727] + +1965. [func] Suppress spurious "recusion requested but not + available" warning with 'dig +qr'. [RT #15780]. + +1964. [func] Separate out MX and SRV to CNAME checks. [RT #15723] + +1963. [port] Tru64 4.0E doesn't support send() and recv(). + [RT #15586] + +1962. [bug] Named failed to clear old update-policy when it + was removed. [RT #15491] + +1961. [bug] Check the port and address of responses forwarded + to dispatch. [RT #15474] + +1960. [bug] Update code should set NSEC ttls from SOA MINIMUM. + [RT #15465] + +1959. [func] Control the zeroing of the negative response TTL to + a soa query. Defaults "zero-no-soa-ttl yes;" and + "zero-no-soa-ttl-cache no;". [RT #15460] + +1958. [bug] Named failed to update the zone's secure state + until the zone was reloaded. [RT #15412] + +1957. [bug] Dig mishandled responses to class ANY queries. + [RT #15402] + +1956. [bug] Improve cross compile support, 'gen' is now built + by native compiler. See README for additional + cross compile support information. [RT #15148] + +1955. [bug] Pre-allocate the cache cleaning interator. [RT #14998] + +1954. [func] Named now falls back to advertising EDNS with a + 512 byte receive buffer if the initial EDNS queries + fail. [RT #14852] + +1953. [func] The maximum EDNS UDP response named will send can + now be set in named.conf (max-udp-size). This is + independent of the advertised receive buffer + (edns-udp-size). [RT #14852] + +1952. [port] hpux: tell the linker to build a runtime link + path "-Wl,+b:". [RT #14816]. + +1951. [security] Drop queries from particular well known ports. + Don't return FORMERR to queries from particular + well known ports. [RT #15636] + +1950. [port] Solaris 2.5.1 and earlier cannot bind() then connect() + a TCP socket. This prevents the source address being + set for TCP connections. [RT #15628] + +1949. [func] Addition memory leakage checks. [RT #15544] + +1948. [bug] If was possible to trigger a REQUIRE failure in + xfrin.c:maybe_free() if named ran out of memory. + [RT #15568] + +1947. [func] It is now possible to configure named to accept + expired RRSIGs. Default "dnssec-accept-expired no;". + Setting "dnssec-accept-expired yes;" leaves named + vulnerable to replay attacks. [RT #14685] + +1946. [bug] resume_dslookup() could trigger a REQUIRE failure + when using forwarders. [RT #15549] + +1945. [cleanup] dnssec-keygen: RSA (RSAMD5) is nolonger recommended. + To generate a RSAMD5 key you must explicitly request + RSAMD5. [RT #13780] + +1944. [cleanup] isc_hash_create() does not need a read/write lock. + [RT #15522] + +1943. [bug] Set the loadtime after rolling forward the journal. + [RT #15647] + +1597. [func] Allow notify-source and query-source to be specified + on a per server basis similar to transfer-source. + [RT #6496] + + --- 9.4.0a3 released --- + +1942. [bug] If the name of a DNSKEY match that of one in + trusted-keys do not attempt to validate the DNSKEY + using the parents DS RRset. [RT #15649] + +1941. [bug] ncache_adderesult() should set eresult even if no + rdataset is passed to it. [RT #15642] + +1940. [bug] Fixed a number of error conditions reported by + Coverity. + +1939. [bug] The resolver could dereference a null pointer after + validation if all the queries have timed out. + [RT #15528] + +1938. [bug] The validator was not correctly handling unsecure + negative responses at or below a SEP. [RT #15528] + +1937. [bug] sdlz doesn't handle RRSIG records. [RT #15564] + +1936. [bug] The validator could leak memory. [RT #15544] + +1935. [bug] 'acache' was DO sensitive. [RT #15430] + +1934. [func] Validate pending NS RRsets, in the authority section, + prior to returning them if it can be done without + requiring DNSKEYs to be fetched. [RT #15430] + +1919. [contrib] queryperf: a set of new features: collecting/printing + response delays, printing intermediate results, and + adjusting query rate for the "target" qps. + + --- 9.4.0a2 released --- + +1933. [bug] dump_rdataset_raw() had a incorrect INSIST. [RT #15534] + +1932. [bug] hpux: LDFLAGS was getting corrupted. [RT #15530] + +1931. [bug] Per-client mctx could require a huge amount of memory, + particularly for a busy caching server. [RT #15519] + +1930. [port] HPUX: ia64 support. [RT #15473] + +1929. [port] FreeBSD: extend use of PTHREAD_SCOPE_SYSTEM. + +1928. [bug] Race in rbtdb.c:currentversion(). [RT #15517] + +1927. [bug] Access to soanode or nsnode in rbtdb violated the + lock order rule and could cause a dead lock. + [RT# 15518] + +1926. [bug] The Windows installer did not check for empty + passwords. BINDinstall was being installed in + the wrong place. [RT #15483] + +1925. [port] All outer level AC_TRY_RUNs need cross compiling + defaults. [RT #15469] + +1924. [port] libbind: hpux ia64 support. [RT #15473] + +1923. [bug] ns_client_detach() called too early. [RT #15499] + +1922. [bug] check-tool.c:setup_logging() missing call to + dns_log_setcontext(). + +1921. [bug] Client memory contexts were not using internal + malloc. [RT# 15434] + +1920. [bug] The cache rbtdb lock array was too small to + have the desired performance characteristics. + [RT #15454] + + --- 9.4.0a1 released --- + +1918. [bug] Memory leak when checking acls. [RT #15391] + +1917. [doc] funcsynopsisinfo wasn't being treated as verbatim + when generating man pages. [RT #15385] + +1916. [func] Integrate contibuted IDN code from JPNIC. [RT #15383] + +1915. [bug] dig +ndots was broken. [RT #15215] + +1914. [protocol] DS is required to accept mnemonic algorithms + (RFC 4034). Still emit numeric algorithms for + compatability with RFC 3658. [RT #15354] + +1913. [func] Integrate contibuted DLZ code into named. [RT #11382] + +1912. [port] aix: atomic locking for powerpc. [RT #15020] + +1911. [bug] Update windows socket code. [RT #14965] + +1910. [bug] dig's +sigchase code overhauled. [RT #14933] + +1909. [bug] The DLV code has been re-worked to make no longer + query order sensitive. [RT #14933] + +1908. [func] dig now warns if 'RA' is not set in the answer when + 'RD' was set in the query. host/nslookup skip servers + that fail to set 'RA' when 'RD' is set unless a server + is explicitly set. [RT #15005] + +1907. [func] host/nslookup now continue (default)/fail on SERVFAIL. + [RT #15006] + +1906. [func] dig now has a '-q queryname' and '+showsearch' options. + [RT #15034] + +1905. [bug] Strings returned from cfg_obj_asstring() should be + treated as read-only. The prototype for + cfg_obj_asstring() has been updated to reflect this. + [RT #15256] + +1904. [func] Automatic empty zone creation for D.F.IP6.ARPA and + friends. Note: RFC 1918 zones are not yet covered by + this but are likely to be in a future release. + + New options: empty-server, empty-contact, + empty-zones-enable and disable-empty-zone. + +1903. [func] ISC string copy API. + +1902. [func] Attempt to make the amount of work performed in a + iteration self tuning. The covers nodes clean from + the cache per iteration, nodes written to disk when + rewriting a master file and nodes destroyed per + iteration when destroying a zone or a cache. + [RT #14996] + +1901. [cleanup] Don't add DNSKEY records to the additional section. + +1900. [bug] ixfr-from-differences failed to ensure that the + serial number increased. [RT #15036] + +1899. [func] named-checkconf now validates update-policy entries. + [RT #14963] + +1898. [bug] Extend ISC_SOCKADDR_FORMATSIZE and + ISC_NETADDR_FORMATSIZE to allow for scope details. + +1897. [func] x86 and x86_64 now have separate atomic locking + implementations. + +1896. [bug] Recursive clients soft quota support wasn't working + as expected. [RT #15103] + +1895. [bug] A escaped character is, potentially, converted to + the output character set too early. [RT #14666] + +1894. [doc] Review ARM for BIND 9.4. + +1893. [port] Use uintptr_t if available. [RT #14606] + +1892. [func] Support for SPF rdata type. [RT #15033] + +1891. [port] freebsd: pthread_mutex_init can fail if it runs out + of memory. [RT #14995] + +1890. [func] Raise the UDP recieve buffer size to 32k if it is + less than 32k. [RT #14953] + +1889. [port] sunos: non blocking i/o support. [RT #14951] + +1888. [func] Support for IPSECKEY rdata type. [RT #14967] + +1887. [bug] The cache could delete expired records too fast for + clients with a virtual time in the past. [RT #14991] + +1886. [bug] fctx_create() could return success even though it + failed. [RT #14993] + +1885. [func] dig: report the number of extra bytes still left in + the packet after processing all the records. + +1884. [cleanup] dighost.c: move external declarations into . + +1883. [bug] dnssec-signzone, dnssec-keygen: handle negative debug + levels. [RT #14962] + +1882. [func] Limit the number of recursive clients that can be + waiting for a single query () to + resolve. New options clients-per-query and + max-clients-per-query. + +1881. [func] Add a system test for named-checkconf. [RT #14931] + +1880. [func] The lame cache is now done on a + basis as some servers only appear to be lame for + certain query types. [RT #14916] + +1879. [func] "USE INTERNAL MALLOC" is now runtime selectable. + [RT #14892] + +1878. [func] Detect duplicates of UDP queries we are recursing on + and drop them. New stats category "duplicate". + [RT #2471] + +1877. [bug] Fix unreasonably low quantum on call to + dns_rbt_destroy2(). Remove unnecessay unhash_node() + call. [RT #14919] + +1876. [func] Additional memory debugging support to track size + and mctx arguments. [RT #14814] + +1875. [bug] process_dhtkey() was using the wrong memory context + to free some memory. [RT #14890] + +1874. [port] sunos: portability fixes. [RT #14814] + +1873. [port] win32: isc__errno2result() now reports its caller. + [RT #13753] + +1872. [port] win32: Handle ERROR_NETNAME_DELETED. [RT #13753] + +1870. [func] Added framework for handling multiple EDNS versions. + [RT #14873] + +1869. [func] dig can now specify the EDNS version when making + a query. [RT #14873] + +1868. [func] edns-udp-size can now be overridden on a per + server basis. [RT #14851] + +1867. [bug] It was possible to trigger a INSIST in + dlv_validatezonekey(). [RT #14846] + +1866. [bug] resolv.conf parse errors were being ignored by + dig/host/nslookup. [RT #14841] + +1865. [bug] Silently ignore nameservers in /etc/resolv.conf with + bad addresses. [RT #14841] + +1864. [bug] Don't try the alternative transfer source if you + got a answer / transfer with the main source + address. [RT #14802] + +1863. [bug] rrset-order "fixed" error messages not complete. + +1862. [func] Add additional zone data constancy checks. + named-checkzone has extended checking of NS, MX and + SRV record and the hosts they reference. + named has extended post zone load checks. + New zone options: check-mx and integrity-check. + [RT #4940] + +1861. [bug] dig could trigger a INSIST on certain malformed + responses. [RT #14801] + +1860. [port] solaris 2.8: hack_shutup_pthreadmutexinit was + incorrectly set. [RT #14775] + +1859. [func] Add support for CH A record. [RT #14695] + +1858. [bug] The flush-zones-on-shutdown option wasn't being + parsed. [RT #14686] + +1857. [bug] named could trigger a INSIST() if reconfigured / + reloaded too fast. [RT #14673] + +1856. [doc] Switch Docbook toolchain from DSSSL to XSL. + [RT #11398] + +1855. [bug] ixfr-from-differences was failing to detect changes + of ttl due to dns_diff_subtract() was ignoring the ttl + of records. [RT #14616] + +1854. [bug] lwres also needs to know the print format for + (long long). [RT #13754] + +1853. [bug] Rework how DLV interacts with proveunsecure(). + [RT #13605] + +1852. [cleanup] Remove last vestiges of dnssec-signkey and + dnssec-makekeyset (removed from Makefile years ago). + +1851. [doc] Doxygen comment markup. [RT #11398] + +1850. [bug] Memory leak in lwres_getipnodebyaddr(). [RT #14591] + +1849. [doc] All forms of the man pages (docbook, man, html) should + have consistant copyright dates. + +1848. [bug] Improve SMF integration. [RT #13238] + +1847. [bug] isc_ondestroy_init() is called too late in + dns_rbtdb_create()/dns_rbtdb64_create(). + [RT #13661] + +1846. [contrib] query-loc-0.3.0 from Stephane Bortzmeyer + . + +1845. [bug] Improve error reporting to distingish between + accept()/fcntl() and socket()/fcntl() errors. + [RT #13745] + +1844. [bug] inet_pton() accepted more that 4 hexadecimal digits + for each 16 bit piece of the IPv6 address. The text + representation of a IPv6 address has been tighted + to disallow this (draft-ietf-ipv6-addr-arch-v4-02.txt). + [RT #5662] + +1843. [cleanup] CINCLUDES takes precedence over CFLAGS. This helps + when CFLAGS contains "-I /usr/local/include" + resulting in old header files being used. + +1842. [port] cmsg_len() could produce incorrect results on + some platform. [RT #13744] + +1841. [bug] "dig +nssearch" now makes a recursive query to + find the list of nameservers to query. [RT #13694] + +1840. [func] dnssec-signzone can now randomize signature end times + (dnssec-signzone -j jitter). [RT #13609] + +1839. [bug] was not being installed. + +1838. [cleanup] Don't allow Linux capabilities to be inherited. + [RT #13707] + +1837. [bug] Compile time option ISC_FACILITY was not effective + for 'named -u '. [RT #13714] + +1836. [cleanup] Silence compiler warnings in hash_test.c. + +1835. [bug] Update dnssec-signzone's usage message. [RT #13657] + +1834. [bug] Bad memset in rdata_test.c. [RT #13658] + +1833. [bug] Race condition in isc_mutex_lock_profile(). [RT #13660] + +1832. [bug] named fails to return BADKEY on unknown TSIG algorithm. + [RT #13620] + +1831. [doc] Update named-checkzone documentation. [RT#13604] + +1830. [bug] adb lame cache has sence of test reversed. [RT #13600] + +1829. [bug] win32: "pid-file none;" broken. [RT #13563] + +1828. [bug] isc_rwlock_init() failed to properly cleanup if it + encountered a error. [RT #13549] + +1827. [bug] host: update usage message for '-a'. [RT #37116] + +1826. [bug] Missing DESTROYLOCK() in isc_mem_createx() on out + of memory error. [RT #13537] + +1825. [bug] Missing UNLOCK() on out of memory error from in + rbtdb.c:subtractrdataset(). [RT #13519] + +1824. [bug] Memory leak on dns_zone_setdbtype() failure. + [RT #13510] + +1823. [bug] Wrong macro used to check for point to point interface. + [RT#13418] + +1822. [bug] check-names test for RT was reversed. [RT #13382] + +1820. [bug] Gracefully handle acl loops. [RT #13659] + +1819. [bug] The validator needed to check both the algorithm and + digest types of the DS to determine if it could be + used to introduce a secure zone. [RT #13593] + +1818. [bug] 'named-checkconf -z' triggered an INSIST. [RT #13599] + +1817. [func] Add support for additional zone file formats for + improving loading performance. The masterfile-format + option in named.conf can be used to specify a + non-default format. A separate command + named-compilezone was provided to generate zone files + in the new format. Additionally, the -I and -O options + for dnssec-signzone specify the input and output + formats. + +1816. [port] UnixWare: failed to compile lib/isc/unix/net.c. + [RT #13597] + +1815. [bug] nsupdate triggered a REQUIRE if the server was set + without also setting the zone and it encountered + a CNAME and was using TSIG. [RT #13086] + +1814. [func] UNIX domain controls are now supported. + +1813. [func] Restructured the data locking framework using + architecture dependent atomic operations (when + available), improving response performance on + multi-processor machines significantly. + x86, x86_64, alpha, powerpc, and mips are currently + supported. + +1812. [port] win32: IN6_IS_ADDR_UNSPECIFIED macro is incorrect. + [RT #13453] + +1811. [func] Preserve the case of domain names in rdata during + zone transfers. [RT #13547] + +1810. [bug] configure, lib/bind/configure make different default + decisions about whether to do a threaded build. + [RT #13212] + +1809. [bug] "make distclean" failed for libbind if the platform + is not supported. + +1808. [bug] zone.c:notify_zone() contained a race condition, + zone->db could change underneath it. [RT #13511] + +1807. [bug] When forwarding (forward only) set the active domain + from the forward zone name. [RT #13526] + +1806. [bug] The resolver returned the wrong result when a CNAME / + DNAME was encountered when fetching glue from a + secure namespace. [RT #13501] + +1805. [bug] Pending status was not being cleared when DLV was + active. [RT #13501] + +1804. [bug] Ensure that if we are queried for glue that it fits + in the additional section or TC is set to tell the + client to retry using TCP. [RT #10114] + +1803. [bug] dnssec-signzone sometimes failed to remove old + RRSIGs. [RT #13483] + +1802. [bug] Handle connection resets better. [RT #11280] + +1801. [func] Report differences between hints and real NS rrset + and associated address records. + +1800. [bug] Changes #1719 allowed a INSIST to be triggered. + [RT #13428] + +1799. [bug] 'rndc flushname' failed to flush negative cache + entries. [RT #13438] + +1798. [func] The server syntax has been extended to support a + range of servers. [RT #11132] + +1797. [func] named-checkconf now check acls to verify that they + only refer to existing acls. [RT #13101] + +1796. [func] "rndc freeze/thaw" now freezes/thaws all zones. + +1795. [bug] "rndc dumpdb" was not fully documented. Minor + formating issues with "rndc dumpdb -all". [RT #13396] + +1794. [func] Named and named-checkzone can now both check for + non-terminal wildcard records. + +1793. [func] Extend adjusting TTL warning messages. [RT #13378] + +1792. [func] New zone option "notify-delay". Specify a minimum + delay between sets of NOTIFY messages. + +1791. [bug] 'host -t a' still printed out AAAA and MX records. + [RT #13230] + +1790. [cleanup] Move lib/dns/sec/dst up into lib/dns. This should + allow parallel make to succeed. + +1789. [bug] Prerequisite test for tkey and dnssec could fail + with "configure --with-libtool". + +1788. [bug] libbind9.la/libbind9.so needs to link against + libisccfg.la/libisccfg.so. + +1787. [port] HPUX: both "cc" and "gcc" need -Wl,+vnocompatwarnings. + +1786. [port] AIX: libt_api needs to be taught to look for + T_testlist in the main executable (--with-libtool). + [RT #13239] + +1785. [bug] libbind9.la/libbind9.so needs to link against + libisc.la/libisc.so. + +1784. [cleanup] "libtool -allow-undefined" is the default. + Leave hooks in configure to allow it to be set + if needed in the future. + +1783. [cleanup] We only need one copy of libtool.m4, ltmain.sh in the + source tree. + +1782. [port] OSX: --with-libtool + --enable-libbind broke on + __evOptMonoTime. [RT #13219] + +1781. [port] FreeBSD 5.3: set PTHREAD_SCOPE_SYSTEM. [RT #12810] + +1780. [bug] Update libtool to 1.5.10. + +1779. [port] OSF 5.1: libtool didn't handle -pthread correctly. + +1778. [port] HUX 11.11: fix broken IN6ADDR_ANY_INIT and + IN6ADDR_LOOPBACK_INIT macros. + +1777. [port] OSF 5.1: fix broken IN6ADDR_ANY_INIT and + IN6ADDR_LOOPBACK_INIT macros. + +1776. [port] Solaris 2.9: fix broken IN6ADDR_ANY_INIT and + IN6ADDR_LOOPBACK_INIT macros. + +1775. [bug] Only compile getnetent_r.c when threaded. [RT #13205] + +1774. [port] Aix: Silence compiler warnings / build failures. + [RT #13154] + +1773. [bug] Fast retry on host / net unreachable. [RT #13153] + +1770. [bug] named-checkconf failed to report missing a missing + file clause for rbt{64} master/hint zones. [RT#13009] + +1769. [port] win32: change compiler flags /MTd ==> /MDd, + /MT ==> /MD. + +1768. [bug] nsecnoexistnodata() could be called with a non-NSEC + rdataset. [RT #12907] + +1767. [port] Builds on IPv6 platforms without IPv6 Advanced API + support for (struct in6_pktinfo) failed. [RT #13077] + +1766. [bug] Update the master file timestamp on successful refresh + as well as the journal's timestamp. [RT# 13062] + +1765. [bug] configure --with-openssl=auto failed. [RT #12937] + +1764. [bug] dns_zone_replacedb failed to emit a error message + if there was no SOA record in the replacment db. + [RT #13016] + +1763. [func] Perform sanity checks on NS records which refer to + 'in zone' names. [RT #13002] + +1762. [bug] isc_interfaceiter_create() could return ISC_R_SUCCESS + even when it failed. [RT #12995] + +1761. [bug] 'rndc dumpdb' didn't report unassociated entries. + [RT #12971] + +1760. [bug] Host / net unreachable was not penalising rtt + estimates. [RT #12970] + +1759. [bug] Named failed to startup if the OS supported IPv6 + but had no IPv6 interfaces configured. [RT #12942] + +1758. [func] Don't send notify messages to self. [RT #12933] + +1757. [func] host now can turn on memory debugging flags with '-m'. + +1756. [func] named-checkconf now checks the logging configuration. + [RT #12352] + +1755. [func] allow-update is now settable at the options / view + level. [RT #6636] + +1754. [bug] We wern't always attempting to query the parent + server for the DS records at the zone cut. + [RT #12774] + +1753. [bug] Don't serve a slave zone which has no NS records. + [RT #12894] + +1752. [port] Move isc_app_start() to after ns_os_daemonise() + as some fork() implementations unblock the signals + that are blocked by isc_app_start(). [RT #12810] + +1751. [bug] --enable-getifaddrs failed under linux. [RT #12867] + +1750. [port] lib/bind/make/rules.in:subdirs was not bash friendly. + [RT #12864] + +1749. [bug] 'check-names response ignore;' failed to ignore. + [RT #12866] + +1748. [func] dig now returns the byte count for axfr/ixfr. + +1747. [bug] BIND 8 compatability: named/named-checkconf failed + to parse "host-statistics-max" in named.conf. + +1746. [func] Make public the function to read a key file, + dst_key_read_public(). [RT #12450] + +1745. [bug] Dig/host/nslookup accept replies from link locals + regardless of scope if no scope was specified when + query was sent. [RT #12745] + +1744. [bug] If tuple2msgname() failed to convert a tuple to + a name a REQUIRE could be triggered. [RT #12796] + +1743. [bug] If isc_taskmgr_create() was not able to create the + requested number of worker threads then destruction + of the manager would trigger an INSIST() failure. + [RT #12790] + +1742. [bug] Deleting all records at a node then adding a + previously existing record, in a single UPDATE + transaction, failed to leave / regenerate the + associated RRSIG records. [RT #12788] + +1741. [bug] Deleting all records at a node in a secure zone + using a update-policy grant failed. [RT #12787] + +1740. [bug] Replace rbt's hash algorithm as it performed badly + with certain zones. [RT #12729] + + NOTE: a hash context now needs to be established + via isc_hash_create() if the application was not + already doing this. + +1739. [bug] dns_rbt_deletetree() could incorrectly return + ISC_R_QUOTA. [RT #12695] + +1738. [bug] Enable overrun checking by default. [RT #12695] + +1737. [bug] named failed if more than 16 masters were specified. + [RT #12627] + +1736. [bug] dst_key_fromnamedfile() could fail to read a + public key. [RT #12687] + +1735. [bug] 'dig +sigtrace' could die with a REQUIRE failure. + [RE #12688] + +1734. [cleanup] 'rndc-confgen -a -t' remove extra '/' in path. + [RT #12588] + +1733. [bug] Return non-zero exit status on initial load failure. + [RT #12658] + +1732. [bug] 'rrset-order name "*"' wasn't being applied to ".". + [RT #12467] + +1731. [port] darwin: relax version test in ifconfig.sh. + [RT #12581] + +1730. [port] Determine the length type used by the socket API. + [RT #12581] + +1729. [func] Improve check-names error messages. + +1728. [doc] Update check-names documentation. + +1727. [bug] named-checkzone: check-names support didn't match + documentation. + +1726. [port] aix5: add support for aix5. + +1725. [port] linux: update error message on interaction of threads, + capabilities and setuid support (named -u). [RT #12541] + +1724. [bug] Look for DNSKEY records with "dig +sigtrace". + [RT #12557] + +1723. [cleanup] Silence compiler warnings from t_tasks.c. [RT #12493] + +1722. [bug] Don't commit the journal on malformed ixfr streams. + [RT #12519] + +1721. [bug] Error message from the journal processing were not + always identifing the relevent journal. [RT #12519] + +1720. [bug] 'dig +chase' did not terminate on a RFC 2308 Type 1 + negative response. [RT #12506] + +1719. [bug] named was not correctly caching a RFC 2308 Type 1 + negative response. [RT #12506] + +1718. [bug] nsupdate was not handling RFC 2308 Type 3 negative + responses when looking for the zone / master server. + [RT #12506] + +1717. [port] solaris: ifconfig.sh did not support Solaris 10. + "ifconfig.sh down" didn't work for Solaris 9. + +1716. [doc] named.conf(5) was being installed in the wrong + location. [RT# 12441] + +1715. [func] 'dig +trace' now randomly selects the next servers + to try. Report if there is a bad delegation. + +1714. [bug] dig/host/nslookup were only trying the first + address when a nameserver was specified by name. + [RT #12286] + +1713. [port] linux: extend capset failure message to say: + please ensure that the capset kernel module is + loaded. see insmod(8) + +1712. [bug] Missing FULLCHECK for "trusted-key" in dig. + +1711. [func] 'rndc unfreeze' has been deprecated by 'rndc thaw'. + +1710. [func] 'rndc notify zone [class [view]]' resend the NOTIFY + messages for the specified zone. [RT #9479] + +1709. [port] solaris: add SMF support from Sun. + +1708. [cleanup] Replaced dns_fullname_hash() with dns_name_fullhash() + for conformance to the name space convention. Binary + backward compatibility to the old function name is + provided. [RT #12376] + +1707. [contrib] sdb/ldap updated to version 1.0-beta. + +1706. [bug] 'rndc stop' failed to cause zones to be flushed + sometimes. [RT #12328] + +1705. [func] Allow the journal's name to be changed via named.conf. + +1704. [port] lwres needed a snprintf() implementation for + platforms without snprintf(). Add missing + "#include ". [RT #12321] + +1703. [bug] named would loop sending NOTIFY messages when it + failed to receive a response. [RT #12322] + +1702. [bug] also-notify should not be applied to builtin zones. + [RT #12323] + +1701. [doc] A minimal named.conf man page. + +1700. [func] nslookup is no longer to be treated as deprecated. + Remove "deprecated" warning message. Add man page. + +1699. [bug] dnssec-signzone can generate "not exact" errors + when resigning. [RT #12281] + +1698. [doc] Use reserved IPv6 documentation prefix. + +1697. [bug] xxx-source{,-v6} was not effective when it + specified one of listening addresses and a + different port than the listening port. [RT #12257] + +1696. [bug] dnssec-signzone failed to clean out nodes that + consisted of only NSEC and RRSIG records. + [RT #12154] + +1695. [bug] DS records when forwarding require special handling. + [RT #12133] + +1694. [bug] Report if the builtin views of "_default" / "_bind" + are defined in named.conf. [RT #12023] + +1693. [bug] max-journal-size was not effective for master zones + with ixfr-from-differences set. [RT# 12024] + +1692. [bug] Don't set -I, -L and -R flags when libcrypto is in + /usr/lib. [RT #11971] + +1691. [bug] sdb's attachversion was not complete. [RT #11990] + +1690. [bug] Delay detaching view from the client until UPDATE + processing completes when shutting down. [RT #11714] + +1689. [bug] DNS_NAME_TOREGION() and DNS_NAME_SPLIT() macros + contained gratuitous semicolons. [RT #11707] + +1688. [bug] LDFLAGS was not supported. + +1687. [bug] Race condition in dispatch. [RT #10272] + +1686. [bug] Named sent a extraneous NOTIFY when it received a + redundant UPDATE request. [RT #11943] + +1685. [bug] Change #1679 loop tests weren't quite right. + +1684. [func] ixfr-from-differences now takes master and slave in + addition to yes and no at the options and view levels. + +1683. [bug] dig +sigchase could leak memory. [RT #11445] + +1682. [port] Update configure test for (long long) printf format. + [RT #5066] + +1681. [bug] Only set SO_REUSEADDR when a port is specified in + isc_socket_bind(). [RT #11742] + +1680. [func] rndc: the source address can now be specified. + +1679. [bug] When there was a single nameserver with multiple + addresses for a zone not all addresses were tried. + [RT #11706] + +1678. [bug] RRSIG should use TYPEXXXXX for unknown types. + +1677. [bug] dig: +aaonly didn't work, +aaflag undocumented. + +1676. [func] New option "allow-query-cache". This lets + allow-query be used to specify the default zone + access level rather than having to have every + zone override the global value. allow-query-cache + can be set at both the options and view levels. + If allow-query-cache is not set allow-query applies. + +1675. [bug] named would sometimes add extra NSEC records to + the authority section. + +1674. [port] linux: increase buffer size used to scan + /proc/net/if_inet6. + +1673. [port] linux: issue a error messages if IPv6 interface + scans fails. + +1672. [cleanup] Tests which only function in a threaded build + now return R:THREADONLY (rather than R:UNTESTED) + in a non-threaded build. + +1671. [contrib] queryperf: add NAPTR to the list of known types. + +1670. [func] Log UPDATE requests to slave zones without an acl as + "disabled" at debug level 3. [RT# 11657] + +1668. [bug] DIG_SIGCHASE was making bin/dig/host dump core. + +1667. [port] linux: not all versions have IF_NAMESIZE. + +1666. [bug] The optional port on hostnames in dual-stack-servers + was being ignored. + +1665. [func] rndc now allows addresses to be set in the + server clauses. + +1664. [bug] nsupdate needed KEY for SIG(0), not DNSKEY. + +1663. [func] Look for OpenSSL by default. + +1662. [bug] Change #1658 failed to change one use of 'type' + to 'keytype'. + +1661. [bug] Restore dns_name_concatenate() call in + adb.c:set_target(). [RT #11582] + +1660. [bug] win32: connection_reset_fix() was being called + unconditionally. [RT #11595] + +1659. [cleanup] Cleanup some messages that were referring to KEY vs + DNSKEY, NXT vs NSEC and SIG vs RRSIG. + +1658. [func] Update dnssec-keygen to default to KEY for HMAC-MD5 + and DH. Tighten which options apply to KEY and + DNSKEY records. + +1657. [doc] ARM: document query log output. + +1656. [doc] Update DNSSEC description in ARM to cover DS, NSEC + DNSKEY and RRSIG. [RT #11542] + +1655. [bug] Logging multiple versions w/o a size was broken. + [RT #11446] + +1654. [bug] isc_result_totext() contained array bounds read + error. + +1653. [func] Add key type checking to dst_key_fromfilename(), + DST_TYPE_KEY should be used to read TSIG, TKEY and + SIG(0) keys. + +1652. [bug] TKEY still uses KEY. + +1651. [bug] dig: process multiple dash options. + +1650. [bug] dig, nslookup: flush standard out after each command. + +1649. [bug] Silence "unexpected non-minimal diff" message. + [RT #11206] + +1648. [func] Update dnssec-lookaside named.conf syntax to support + multiple dnssec-lookaside namespaces (not yet + implemented). + +1647. [bug] It was possible trigger a INSIST when chasing a DS + record that required walking back over a empty node. + [RT #11445] + +1646. [bug] win32: logging file versions didn't work with + non-UNC filenames. [RT#11486] + +1645. [bug] named could trigger a REQUIRE failure if multiple + masters with keys are specified. + +1644. [bug] Update the journal modification time after a + sucessfull refresh query. [RT #11436] + +1643. [bug] dns_db_closeversion() could leak memory / node + references. [RT #11163] + +1642. [port] Support OpenSSL implementations which don't have + DSA support. [RT #11360] + +1641. [bug] Update the check-names description in ARM. [RT #11389] + +1640. [bug] win32: isc_socket_cancel(ISC_SOCKCANCEL_ACCEPT) was + incorrectly closing the socket. [RT #11291] + +1639. [func] Initial dlv system test. + +1638. [bug] "ixfr-from-differences" could generate a REQUIRE + failure if the journal open failed. [RT #11347] + +1637. [bug] Node reference leak on error in addnoqname(). + +1636. [bug] The dump done callback could get ISC_R_SUCCESS even if + a error had occured. The database version no longer + matched the version of the database that was dumped. + +1635. [bug] Memory leak on error in query_addds(). + +1634. [bug] named didn't supply a useful error message when it + detected duplicate views. [RT #11208] + +1633. [bug] named should return NOTIMP to update requests to a + slaves without a allow-update-forwarding acl specified. + [RT #11331] + +1632. [bug] nsupdate failed to send prerequisite only UPDATE + messages. [RT #11288] + +1631. [bug] dns_journal_compact() could sometimes corrupt the + journal. [RT #11124] + +1630. [contrib] queryperf: add support for IPv6 transport. + +1629. [func] dig now supports IPv6 scoped addresses with the + extended format in the local-server part. [RT #8753] + +1628. [bug] Typo in Compaq Trucluster support. [RT# 11264] + +1627. [bug] win32: sockets were not being closed when the + last external reference was removed. [RT# 11179] + +1626. [bug] --enable-getifaddrs was broken. [RT#11259] + +1625. [bug] named failed to load/transfer RFC2535 signed zones + which contained CNAMES. [RT# 11237] + +1624. [bug] zonemgr_putio() call should be locked. [RT# 11163] + +1623. [bug] A serial number of zero was being displayed in the + "sending notifies" log message when also-notify was + used. [RT #11177] + +1622. [func] probe the system to see if IPV6_(RECV)PKTINFO is + available, and suppress wildcard binding if not. + +1621. [bug] match-destinations did not work for IPv6 TCP queries. + [RT# 11156] + +1620. [func] When loading a zone report if it is signed. [RT #11149] + +1619. [bug] Missing ISC_LIST_UNLINK in end_reserved_dispatches(). + [RT# 11118] + +1618. [bug] Fencepost errors in dns_name_ishostname() and + dns_name_ismailbox() could trigger a INSIST(). + +1617. [port] win32: VC++ 6.0 support. + +1616. [compat] Ensure that named's version is visible in the core + dump. [RT #11127] + +1615. [port] Define ISC_SOCKADDR_LEN_T based on _BSD_SOCKLEN_T_ if + it is defined. + +1614. [port] win32: silence resource limit messages. [RT# 11101] + +1613. [bug] Builds would fail on machines w/o a if_nametoindex(). + Missing #ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX/#endif. + [RT #11119] + +1612. [bug] check-names at the option/view level could trigger + an INSIST. [RT# 11116] + +1611. [bug] solaris: IPv6 interface scanning failed to cope with + no active IPv6 interfaces. + +1610. [bug] On dual stack machines "dig -b" failed to set the + address type to be looked up with "@server". + [RT #11069] + +1609. [func] dig now has support to chase DNSSEC signature chains. + Requires -DDIG_SIGCHASE=1 to be set in STD_CDEFINES. + + DNSSEC validation code in dig coded by Olivier Courtay + (olivier.courtay@irisa.fr) for the IDsA project + (http://idsa.irisa.fr). + +1608. [func] dig and host now accept -4/-6 to select IP transport + to use when making queries. + +1607. [bug] dig, host and nslookup were still using random() + to generate query ids. [RT# 11013] + +1606. [bug] DLV insecurity proof was failing. + +1605. [func] New dns_db_find() option DNS_DBFIND_COVERINGNSEC. + +1604. [bug] A xfrout_ctx_create() failure would result in + xfrout_ctx_destroy() being called with a + partially initialized structure. + +1603. [bug] nsupdate: set interactive based on isatty(). + [RT# 10929] + +1602. [bug] Logging to a file failed unless a size was specified. + [RT# 10925] + +1601. [bug] Silence spurious warning 'both "recursion no;" and + "allow-recursion" active' warning from view "_bind". + [RT# 10920] + +1600. [bug] Duplicate zone pre-load checks were not case + insensitive. + +1599. [bug] Fix memory leak on error path when checking named.conf. + +1598. [func] Specify that certain parts of the namespace must + be secure (dnssec-must-be-secure). + +1596. [func] Accept 'notify-source' style syntax for query-source. + +1595. [func] New notify type 'master-only'. Enable notify for + master zones only. + +1594. [bug] 'rndc dumpdb' could prevent named from answering + queries while the dump was in progress. [RT #10565] + +1593. [bug] rndc should return "unknown command" to unknown + commands. [RT# 10642] + +1592. [bug] configure_view() could leak a dispatch. [RT# 10675] + +1591. [bug] libbind: updated to BIND 8.4.5. + +1590. [port] netbsd: update thread support. + +1589. [func] DNSSEC lookaside validation. + +1588. [bug] win32: TCP sockets could become blocked. [RT #10115] + +1587. [bug] dns_message_settsigkey() failed to clear existing key. + [RT #10590] + +1586. [func] "check-names" is now implemented. + +1585. [placeholder] + +1584. [bug] "make test" failed with a read only source tree. + [RT #10461] + +1583. [bug] Records add via UPDATE failed to get the correct trust + level. [RT #10452] + +1582. [bug] rrset-order failed to work on RRsets with more + than 32 elements. [RT #10381] + +1581. [func] Disable DNSSEC support by default. To enable + DNSSEC specify "dnssec-enable yes;" in named.conf. + +1580. [bug] Zone destruction on final detach takes a long time. + [RT #3746] + +1579. [bug] Multiple task managers could not be created. + +1578. [bug] Don't use CLASS E IPv4 addresses when resolving. + [RT #10346] + +1577. [bug] Use isc_uint32_t in ultrasparc optimizer bug + workaround code. [RT #10331] + +1576. [bug] Race condition in dns_dispatch_addresponse(). + [RT# 10272] + +1575. [func] Log TSIG name on TSIG verify failure. [RT #4404] + +1574. [bug] Don't attempt to open the controls socket(s) when + running tests. [RT #9091] + +1573. [port] linux: update to libtool 1.5.2 so that + "make install DESTDIR=/xx" works with + "configure --with-libtool". [RT #9941] + +1572. [bug] nsupdate: sign the soa query to find the enclosing + zone if the server is specified. [RT #10148] + +1571. [bug] rbt:hash_node() could fail leaving the hash table + in an inconsistent state. [RT #10208] + +1570. [bug] nsupdate failed to handle classes other than IN. + New keyword 'class' which sets the default class. + [RT #10202] + +1569. [func] nsupdate new command 'answer' which displays the + complete answer message to the last update. + +1568. [bug] nsupdate now reports that the update failed in + interactive mode. [RT# 10236] + +1567. [bug] B.ROOT-SERVERS.NET is now 192.228.79.201. + +1566. [port] Support for the cmsg framework on Solaris and HP/UX. + This also solved the problem that match-destinations + for IPv6 addresses did not work on these systems. + [RT #10221] + +1565. [bug] CD flag should be copied to outgoing queries unless + the query is under a secure entry point in which case + CD should be set. + +1564. [func] Attempt to provide a fallback entropy source to be + used if named is running chrooted and named is unable + to open entropy source within the chroot area. + [RT #10133] + +1563. [bug] Gracefully fail when unable to obtain neither an IPv4 + nor an IPv6 dispatch. [RT #10230] + +1562. [bug] isc_socket_create() and isc_socket_accept() could + leak memory under error conditions. [RT #10230] + +1561. [bug] It was possible to release the same name twice if + named ran out of memory. [RT #10197] + +1560. [port] FreeBSD: work around FreeBSD 5.2 mapping EAI_NODATA + and EAI_NONAME to the same value. + +1559. [port] named should ignore SIGFSZ. + +1558. [func] New DNSSEC 'disable-algorithms'. Support entry into + child zones for which we don't have a supported + algorithm. Such child zones are treated as unsigned. + +1557. [func] Implement missing DNSSEC tests for + * NOQNAME proof with wildcard answers. + * NOWILDARD proof with NXDOMAIN. + Cache and return NOQNAME with wildcard answers. + +1556. [bug] nsupdate now treats all names as fully qualified. + [RT #6427] + +1555. [func] 'rrset-order cyclic' no longer has a random starting + point per query. [RT #7572] + +1554. [bug] dig, host, nslookup failed when no nameservers + were specified in /etc/resolv.conf. [RT #8232] + +1553. [bug] The windows socket code could stop accepting + connections. [RT#10115] + +1552. [bug] Accept NOTIFY requests from mapped masters if + matched-mapped is set. [RT #10049] + +1551. [port] Open "/dev/null" before calling chroot(). + +1550. [port] Call tzset(), if available, before calling chroot(). + +1549. [func] named-checkzone can now write out the zone contents + in a easily parsable format (-D and -o). + +1548. [bug] When parsing APL records it was possible to silently + accept out of range ADDRESSFAMILY values. [RT# 9979] + +1547. [bug] Named wasted memory recording duplicate lame zone + entries. [RT #9341] + +1546. [bug] We were rejecting valid secure CNAME to negative + answers. + +1545. [bug] It was possible to leak memory if named was unable to + bind to the specified transfer source and TSIG was + being used. [RT #10120] + +1544. [bug] Named would logged a single entry to a file despite it + being over the specified size limit. + +1543. [bug] Logging using "versions unlimited" did not work. + +1542. [placeholder] + +1541. [func] NSEC now uses new bitmap format. + +1540. [bug] "rndc reload " was silently accepted. + [RT #8934] + +1539. [bug] Open UDP sockets for notify-source and transfer-source + that use reserved ports at startup. [RT #9475] + +1538. [placeholder] rt9997 + +1537. [func] New option "querylog". If set specify whether query + logging is to be enabled or disabled at startup. + +1536. [bug] Windows socket code failed to log a error description + when returning ISC_R_UNEXPECTED. [RT #9998] + +1535. [placeholder] + +1534. [bug] Race condition when priming cache. [RT# 9940] + +1533. [func] Warn if both "recursion no;" and "allow-recursion" + are active. [RT# 4389] + +1532. [port] netbsd: the configure test for + requires . + +1531. [port] AIX more libtool fixes. + +1530. [bug] It was possible to trigger a INSIST() failure if a + slave master file was removed at just the correct + moment. [RT #9462] + +1529. [bug] "notify explicit;" failed to log that NOTIFY messages + were being sent for the zone. [RT# 9442] + +1528. [cleanup] Simplify some dns_name_ functions based on the + deprecation of bitstring labels. + +1527. [cleanup] Reduce the number of gettimeofday() calls without + losing necessary timer granularity. + +1526. [func] Implemented "additional section caching (or acache)", + an internal cache framework for additional section + content to improve response performance. Several + configuration options were provided to control the + behavior. + +1525. [bug] dns_cache_create() could trigger a REQUIRE + failure in isc_mem_put() during error cleanup. + [RT# 9360] + +1524. [port] AIX needs to be able to resolve all symbols when + creating shared libraries (--with-libtool). + +1523. [bug] Fix race condition in rbtdb. [RT# 9189] + +1522. [bug] dns_db_findnode() relax the requirements on 'name'. + [RT# 9286] + +1521. [bug] dns_view_createresolver() failed to check the + result from isc_mem_create(). [RT# 9294] + +1520. [protocol] Add SSHFP (SSH Finger Print) type. + +1519. [bug] dnssec-signzone:nsec_setbit() computed the wrong + length of the new bitmap. + +1518. [bug] dns_nsec_buildrdata(), and hence dns_nsec_build(), + contained a off-by-one error when working out the + number of octets in the bitmap. + +1517. [port] Support for IPv6 interface scanning on HP/UX and + TrueUNIX 5.1. + +1516. [func] Roll the DNSSEC types to RRSIG, NSEC and DNSKEY. + +1515. [func] Allow transfer source to be set in a server statement. + [RT #6496] + +1514. [bug] named: isc_hash_destroy() was being called too early. + [RT #9160] + +1513. [doc] Add "US" to root-delegation-only exclude list. + +1512. [bug] Extend the delegation-only logging to return query + type, class and responding nameserver. + +1511. [bug] delegation-only was generating false positives + on negative answers from subzones. + +1510. [func] New view option "root-delegation-only". Apply + delegation-only check to all TLDs and root. + Note there are some TLDs that are NOT delegation + only (e.g. DE, LV, US and MUSEUM) these can be excluded + from the checks by using exclude. + + root-delegation-only exclude { + "DE"; "LV"; "US"; "MUSEUM"; + }; + +1509. [bug] Hint zones should accept delegation-only. Forward + zone should not accept delegation-only. + +1508. [bug] Don't apply delegation-only checks to answers from + forwarders. + +1507. [bug] Handle BIND 8 style returns to NS queries to parents + when making delegation-only checks. + +1506. [bug] Wrong return type for dns_view_isdelegationonly(). + +1505. [bug] Uninitialized rdataset in sdb. [RT #8750] + +1504. [func] New zone type "delegation-only". + +1503. [port] win32: install libeay32.dll outside of system32. + +1502. [bug] nsupdate: adjust timeouts for UPDATE requests over TCP. + +1501. [func] Allow TCP queue length to be specified via + named.conf, tcp-listen-queue. + +1500. [bug] host failed to lookup MX records. Also look up + AAAA records. + +1499. [bug] isc_random need to be seeded better if arc4random() + is not used. + +1498. [port] bsdos: 5.x support. + +1497. [placeholder] + +1496. [port] test for pthread_attr_setstacksize(). + +1495. [cleanup] Replace hash functions with universal hash. + +1494. [security] Turn on RSA BLINDING as a precaution. + +1493. [placeholder] + +1492. [cleanup] Preserve rwlock quota context when upgrading / + downgrading. [RT #5599] + +1491. [bug] dns_master_dump*() would produce extraneous $ORIGIN + lines. [RT #6206] + +1490. [bug] Accept reading state as well as working state in + ns_client_next(). [RT #6813] + +1489. [compat] Treat 'allow-update' on slave zones as a warning. + [RT #3469] + +1488. [bug] Don't override trust levels for glue addresses. + [RT #5764] + +1487. [bug] A REQUIRE() failure could be triggered if a zone was + queued for transfer and the zone was then removed. + [RT #6189] + +1486. [bug] isc_print_snprintf() '%%' consumed one too many format + characters. [RT# 8230] + +1485. [bug] gen failed to handle high type values. [RT #6225] + +1484. [bug] The number of records reported after a AXFR was wrong. + [RT #6229] + +1483. [bug] dig axfr failed if the message id in the answer failed + to match that in the request. Only the id in the first + message is required to match. [RT #8138] + +1482. [bug] named could fail to start if the kernel supports + IPv6 but no interfaces are configured. Similarly + for IPv4. [RT #6229] + +1481. [bug] Refresh and stub queries failed to use masters keys + if specified. [RT #7391] + +1480. [bug] Provide replay protection for rndc commands. Full + replay protection requires both rndc and named to + be updated. Partial replay protection (limited + exposure after restart) is provided if just named + is updated. + +1479. [bug] cfg_create_tuple() failed to handle out of + memory cleanup. parse_list() would leak memory + on syntax errors. + +1478. [port] ifconfig.sh didn't account for other virtual + interfaces. It now takes a optional argument + to specify the first interface number. [RT #3907] + +1477. [bug] memory leak using stub zones and TSIG. + +1476. [placeholder] + +1475. [port] Probe for old sprintf(). + +1474. [port] Provide strtoul() and memmove() for platforms + without them. + +1473. [bug] create_map() and create_string() failed to handle out + of memory cleanup. [RT #6813] + +1472. [contrib] idnkit-1.0 from JPNIC, replaces mdnkit. + +1471. [bug] libbind: updated to BIND 8.4.0. + +1470. [bug] Incorrect length passed to snprintf. [RT #5966] + +1469. [func] Log end of outgoing zone transfer at same level + as the start of transfer is logged. [RT #4441] + +1468. [func] Internal zones are no longer counted for + 'rndc status'. [RT #4706] + +1467. [func] $GENERATES now supports optional class and ttl. + +1466. [bug] lwresd configuration errors resulted in memory + and lock leaks. [RT #5228] + +1465. [bug] isc_base64_decodestring() and isc_base64_tobuffer() + failed to check that trailing bits were zero allowing + some invalid base64 strings to be accepted. [RT #5397] + +1464. [bug] Preserve "out of zone" data for outgoing zone + transfers. [RT #5192] + +1463. [bug] dns_rdata_from{wire,struct}() failed to catch bad + NXT bit maps. [RT #5577] + +1462. [bug] parse_sizeval() failed to check the token type. + [RT #5586] + +1461. [bug] Remove deadlock from rbtdb code. [RT #5599] + +1460. [bug] inet_pton() failed to reject certain malformed + IPv6 literals. + +1459. [placeholder] + +1458. [cleanup] sprintf() -> snprintf(). + +1457. [port] Provide strlcat() and strlcpy() for platforms without + them. + +1456. [contrib] gen-data-queryperf.py from Stephane Bortzmeyer. + +1455. [bug] missing from server grammar in + doc/misc/options. [RT #5616] + +1454. [port] Use getifaddrs() if available for interface scanning. + --disable-getifaddrs to override. Glibc currently + has a getifaddrs() that does not support IPv6. + Use --enable-getifaddrs=glibc to force the use of + this version under linux machines. + +1453. [doc] ARM: $GENERATE example wasn't accurate. [RT #5298] + +1452. [placeholder] + +1451. [bug] rndc-confgen didn't exit with a error code for all + failures. [RT #5209] + +1450. [bug] Fetching expired glue failed under certain + circumstances. [RT #5124] + +1449. [bug] query_addbestns() didn't handle running out of memory + gracefully. + +1448. [bug] Handle empty wildcards labels. + +1447. [bug] We were casting (unsigned int) to and from (void *). + rdataset->private4 is now rdataset->privateuint4 + to reflect a type change. + +1446. [func] Implemented undocumented alternate transfer sources + from BIND 8. See use-alt-transfer-source, + alt-transfer-source and alt-transfer-source-v6. + + SECURITY: use-alt-transfer-source is ENABLED unless + you are using views. This may cause a security risk + resulting in accidental disclosure of wrong zone + content if the master supplying different source + content based on IP address. If you are not certain + ISC recommends setting use-alt-transfer-source no; + +1445. [bug] DNS_ADBFIND_STARTATROOT broke stub zones. This has + been replaced with DNS_ADBFIND_STARTATZONE which + causes the search to start using the closest zone. + +1444. [func] dns_view_findzonecut2() allows you to specify if the + cache should be searched for zone cuts. + +1443. [func] Masters lists can now be specified and referenced + in zone masters clauses and other masters lists. + +1442. [func] New functions for manipulating port lists: + dns_portlist_create(), dns_portlist_add(), + dns_portlist_remove(), dns_portlist_match(), + dns_portlist_attach() and dns_portlist_detach(). + +1441. [func] It is now possible to tell dig to bind to a specific + source port. + +1440. [func] It is now possible to tell named to avoid using + certain source ports (avoid-v4-udp-ports, + avoid-v6-udp-ports). + +1439. [bug] Named could return NOERROR with certain NOTIFY + failures. Return NOTAUTH if the NOTIFY zone is + not being served. + +1438. [func] Log TSIG (if any) when logging NOTIFY requests. + +1437. [bug] Leave space for stdio to work in. [RT #5033] + +1436. [func] dns_zonemgr_resumexfrs() can be used to restart + stalled transfers. + +1435. [bug] zmgr_resume_xfrs() was being called read locked + rather than write locked. zmgr_resume_xfrs() + was not being called if the zone was being + shutdown. + +1434. [bug] "rndc reconfig" failed to initiate the initial + zone transfer of new slave zones. + +1433. [bug] named could trigger a REQUIRE failure if it could + not get a file descriptor when attempting to write + a master file. [RT #4347] + +1432. [func] The advertised EDNS UDP buffer size can now be set + via named.conf (edns-udp-size). + +1431. [bug] isc_print_snprintf() "%s" with precision could walk off + end of argument. [RT #5191] + +1430. [port] linux: IPv6 interface scanning support. + +1429. [bug] Prevent the cache getting locked to old servers. + +1428. [placeholder] + +1427. [bug] Race condition in adb with threaded build. + +1426. [placeholder] + +1425. [port] linux/libbind: define __USE_MISC when testing *_r() + function prototypes in netdb.h. [RT #4921] + +1424. [bug] EDNS version not being correctly printed. + +1423. [contrib] queryperf: added A6 and SRV. + +1422. [func] Log name/type/class when denying a query. [RT #4663] + +1421. [func] Differentiate updates that don't succeed due to + prerequisites (unsuccessful) vs other reasons + (failed). + +1420. [port] solaris: work around gcc optimizer bug. + +1419. [port] openbsd: use /dev/arandom. [RT #4950] + +1418. [bug] 'rndc reconfig' did not cause new slaves to load. + +1417. [func] ID.SERVER/CHAOS is now a built in zone. + See "server-id" for how to configure. + +1416. [bug] Empty node should return NOERROR NODATA, not NXDOMAIN. + [RT #4715] + +1415. [func] DS TTL now derived from NS ttl. NXT TTL now derived + from SOA MINIMUM. + +1414. [func] Support for KSK flag. + +1413. [func] Explicitly request the (re-)generation of DS records + from keysets (dnssec-signzone -g). + +1412. [func] You can now specify servers to be tried if a nameserver + has IPv6 address and you only support IPv4 or the + reverse. See dual-stack-servers. + +1411. [bug] empty nodes should stop wildcard matches. [RT #4802] + +1410. [func] Handle records that live in the parent zone, e.g. DS. + +1409. [bug] DS should have attribute DNS_RDATATYPEATTR_DNSSEC. + +1408. [bug] "make distclean" was not complete. [RT #4700] + +1407. [bug] lfsr incorrectly implements the shift register. + [RT #4617] + +1406. [bug] dispatch initializes one of the LFSR's with a incorrect + polynomial. [RT #4617] + +1405. [func] Use arc4random() if available. + +1404. [bug] libbind: ns_name_ntol() could overwrite a zero length + buffer. + +1403. [func] dnssec-signzone, dnssec-keygen, dnssec-makekeyset + dnssec-signkey now report their version in the + usage message. + +1402. [cleanup] A6 has been moved to experimental and is no longer + fully supported. + +1401. [bug] adb wasn't clearing state when the timer expired. + +1400. [bug] Block the addition of wildcard NS records by IXFR + or UPDATE. [RT #3502] + +1399. [bug] Use serial number arithmetic when testing SIG + timestamps. [RT #4268] + +1398. [doc] ARM: notify-also should have been also-notify. + [RT #4345] + +1397. [bug] J.ROOT-SERVERS.NET is now 192.58.128.30. + +1396. [func] dnssec-signzone: adjust the default signing time by + 1 hour to allow for clock skew. + +1395. [port] OpenSSL 0.9.7 defines CRYPTO_LOCK_ENGINE but doesn't + have a working implementation. [RT #4079] + +1394. [func] It is now possible to check if a particular element is + in a acl. Remove duplicate entries from the localnets + acl. + +1393. [port] Bind to individual IPv6 interfaces if IPV6_IPV6ONLY + is not available in the kernel to prevent accidently + listening on IPv4 interfaces. + +1392. [bug] named-checkzone: update usage. + +1391. [func] Add support for IPv6 scoped addresses in named. + +1390. [func] host now supports ixfr. + +1389. [bug] named could fail to rotate long log files. [RT #3666] + +1388. [port] irix: check for sys/sysctl.h and NET_RT_IFLIST before + defining HAVE_IFLIST_SYSCTL. [RT #3770] + +1387. [bug] named could crash due to an access to invalid memory + space (which caused an assertion failure) in + incremental cleaning. [RT #3588] + +1386. [bug] named-checkzone -z stopped on errors in a zone. + [RT #3653] + +1385. [bug] Setting serial-query-rate to 10 would trigger a + REQUIRE failure. + +1384. [bug] host was incompatible with BIND 8 in its exit code and + in the output with the -l option. [RT #3536] + +1383. [func] Track the serial number in a IXFR response and log if + a mismatch occurs. This is a more specific error than + "not exact". [RT #3445] + +1382. [bug] make install failed with --enable-libbind. [RT #3656] + +1381. [bug] named failed to correctly process answers that + contained DNAME records where the resulting CNAME + resulted in a negative answer. + +1380. [func] 'rndc recursing' dump recursing queries to + 'recursing-file = "named.recursing";'. + +1379. [func] 'rndc status' now reports tcp and recursion quota + states. + +1378. [func] Improved positive feedback for 'rndc {reload|refresh}. + +1377. [func] dns_zone_load{new}() now reports if the zone was + loaded, queued for loading to up to date. + +1376. [func] New function dns_zone_logc() to log to specified + category. + +1375. [func] 'rndc dumpdb' now dumps the adb cache along with the + data cache. + +1374. [func] dns_adb_dump() now logs the lame zones associated + with each server. + +1373. [bug] Recovery from expired glue failed under certain + circumstances. + +1372. [bug] named crashes with an assertion failure on exit when + sharing the same port for listening and querying, and + changing listening addresses several times. [RT# 3509] + +1371. [bug] notify-source-v6, transfer-source-v6 and + query-source-v6 with explicit addresses and using the + same ports as named was listening on could interfere + with named's ability to answer queries sent to those + addresses. + +1370. [bug] dig '+[no]recurse' was incorrectly documented. + +1369. [bug] Adding an NS record as the lexicographically last + record in a secure zone didn't work. + +1368. [func] remove support for bitstring labels. + +1367. [func] Use response times to select forwarders. + +1366. [contrib] queryperf usage was incomplete. Add '-h' for help. + +1365. [func] "localhost" and "localnets" acls now include IPv6 + addresses / prefixes. + +1364. [func] Log file name when unable to open memory statistics + and dump database files. [RT# 3437] + +1363. [func] Listen-on-v6 now supports specific addresses. + +1362. [bug] remove IFF_RUNNING test when scanning interfaces. + +1361. [func] log the reason for rejecting a server when resolving + queries. + +1360. [bug] --enable-libbind would fail when not built in the + source tree for certain OS's. + +1359. [security] Support patches OpenSSL libraries. + http://www.cert.org/advisories/CA-2002-23.html + +1358. [bug] It was possible to trigger a INSIST when debugging + large dynamic updates. [RT #3390] + +1357. [bug] nsupdate was extremely wasteful of memory. + +1356. [tuning] Reduce the number of events / quantum for zone tasks. + +1355. [bug] Fix DNSSEC wildcard proof for CNAME/DNAME. + +1354. [doc] lwres man pages had illegal nroff. + +1353. [contrib] sdb/ldap to version 0.9. + +1352. [bug] dig, host, nslookup when falling back to TCP use the + current search entry (if any). [RT #3374] + +1351. [bug] lwres_getipnodebyname() returned the wrong name + when given a IPv4 literal, af=AF_INET6 and AI_MAPPED + was set. + +1350. [bug] dns_name_fromtext() failed to handle too many labels + gracefully. + +1349. [security] Minimum OpenSSL version now 0.9.6e (was 0.9.5a). + http://www.cert.org/advisories/CA-2002-23.html + +1348. [port] win32: Rewrote code to use I/O Completion Ports + in socket.c and eliminating a host of socket + errors. Performance is enhanced. + +1347. [placeholder] + +1346. [placeholder] + +1345. [port] Use a explicit -Wformat with gcc. Not all versions + include it in -Wall. + +1344. [func] Log if the serial number on the master has gone + backwards. + If you have multiple machines specified in the masters + clause you may want to set 'multi-master yes;' to + suppress this warning. + +1343. [func] Log successful notifies received (info). Adjust log + level for failed notifies to notice. + +1342. [func] Log remote address with TCP dispatch failures. + +1341. [func] Allow a rate limiter to be stalled. + +1340. [bug] Delay and spread out the startup refresh load. + +1339. [func] dig, host and nslookup now use IP6.ARPA for nibble + lookups. Bit string lookups are no longer attempted. + +1338. [placeholder] + +1337. [placeholder] + +1336. [func] Nibble lookups under IP6.ARPA are now supported by + dns_byaddr_create(). dns_byaddr_createptrname() is + deprecated, use dns_byaddr_createptrname2() instead. + +1335. [bug] When performing a nonexistence proof, the validator + should discard parent NXTs from higher in the DNS. + +1334. [bug] When signing/verifying rdatasets, duplicate rdatas + need to be suppressed. + +1333. [contrib] queryperf now reports a summary of returned + rcodes (-c), rcodes are printed in mnemonic form (-v). + +1332. [func] Report the current serial with periodic commits when + rolling forward the journal. + +1331. [func] Generate DNSSEC wildcard proofs. + +1330. [bug] When processing events (non-threaded) only allow + the task one chance to use to use its quantum. + +1329. [func] named-checkzone will now check if nameservers that + appear to be IP addresses. Available modes "fail", + "warn" (default) and "ignore" the results of the + check. + +1328. [bug] The validator could incorrectly verify an invalid + negative proof. + +1327. [bug] The validator would incorrectly mark data as insecure + when seeing a bogus signature before a correct + signature. + +1326. [bug] DNAME/CNAME signatures were not being cached when + validation was not being performed. [RT #3284] + +1325. [bug] If the tcpquota was exhausted it was possible to + to trigger a INSIST() failure. + +1324. [port] darwin: ifconfig.sh now supports darwin. + +1323. [port] linux: Slackware 4.0 needs . [RT #3205] + +1322. [bug] dnssec-signzone usage message was misleading. + +1321. [bug] If the last RRset in a zone is glue, dnssec-signzone + would incorrectly duplicate its output and sign it. + +1320. [doc] query-source-v6 was missing from options section. + [RT #3218] + +1319. [func] libbind: log attempts to exploit #1318. + +1318. [bug] libbind: Remote buffer overrun. + +1317. [port] libbind: TrueUNIX 5.1 does not like __align as a + element name. + +1316. [bug] libbind: gethostans() could get out of sync parsing + the response if there was a very long CNAME chain. + +1315. [bug] Options should apply to the internal _bind view. + +1314. [port] Handle ECONNRESET from sendmsg() [unix]. + +1313. [func] Query log now says if the query was signed (S) or + if EDNS was used (E). + +1312. [func] Log TSIG key used w/ outgoing zone transfers. + +1311. [bug] lwres_getrrsetbyname leaked memory. [RT #3159] + +1310. [bug] 'rndc stop' failed to cause zones to be flushed + sometimes. [RT #3157] + +1309. [func] Log that a zone transfer was covered by a TSIG. + +1308. [func] DS (delegation signer) support. + +1307. [bug] nsupdate: allow white space base64 key data. + +1306. [bug] Badly encoded LOC record when the size, horizontal + precision or vertical precision was 0.1m. + +1305. [bug] Document that internal zones are included in the + rndc status results. + +1304. [func] New function: dns_zone_name(). + +1303. [func] Option 'flush-zones-on-shutdown ;'. + +1302. [func] Extended rndc dumpdb to support dumping of zones and + view selection: 'dumpdb [-all|-zones|-cache] [view]'. + +1301. [func] New category 'update-security'. + +1300. [port] Compaq Trucluster support. + +1299. [bug] Set AI_ADDRCONFIG when looking up addresses + via getaddrinfo() (affects dig, host, nslookup, rndc + and nsupdate). + +1298. [bug] The CINCLUDES macro in lib/dns/sec/dst/Makefile + could be left with a trailing "\" after configure + has been run. + +1297. [port] linux: make handling EINVAL from socket() no longer + conditional on #ifdef LINUX. + +1296. [bug] isc_log_closefilelogs() needed to lock the log + context. + +1295. [bug] isc_log_setdebuglevel() needed to lock the log + context. + +1294. [func] libbind: no longer attempts bit string labels for + IPv6 reverse resolution. Try IP6.ARPA then IP6.INT + for nibble style resolution. + +1293. [func] Entropy can now be retrieved from EGDs. [RT #2438] + +1292. [func] Enable IPv6 support when using ioctl style interface + scanning and OS supports SIOCGLIFADDR using struct + if_laddrreq. + +1291. [func] Enable IPv6 support when using sysctl style interface + scanning. + +1290. [func] "dig axfr" now reports the number of messages + as well as the number of records. + +1289. [port] See if -ldl is required for OpenSSL? [RT #2672] + +1288. [bug] Adjusted REQUIRE's in lib/dns/name.c to better + reflect written requirements. + +1287. [bug] REQUIRE that DNS_DBADD_MERGE only be set when adding + a rdataset to a zone db in the rbtdb implementation of + addrdataset. + +1286. [bug] dns_name_downcase() enforce requirement that + target != NULL or name->buffer != NULL. + +1285. [func] lwres: probe the system to see what address families + are currently in use. + +1284. [bug] The RTT estimate on unused servers was not aged. + [RT #2569] + +1283. [func] Use "dataready" accept filter if available. + +1282. [port] libbind: hpux 11.11 interface scanning. + +1281. [func] Log zone when unable to get private keys to update + zone. Log zone when NXT records are missing from + secure zone. + +1280. [bug] libbind: escape '(' and ')' when converting to + presentation form. + +1279. [port] Darwin uses (unsigned long) for size_t. [RT #2590] + +1278. [func] dig: now supports +[no]cl +[no]ttlid. + +1277. [func] You can now create your own customized printing + styles: dns_master_stylecreate() and + dns_master_styledestroy(). + +1276. [bug] libbind: const pointer conflicts in res_debug.c. + +1275. [port] libbind: hpux: treat all hpux systems as BIG_ENDIAN. + +1274. [bug] Memory leak in lwres_gnbarequest_parse(). + +1273. [port] libbind: solaris: 64 bit binary compatibility. + +1272. [contrib] Berkeley DB 4.0 sdb implementation from + Nuno Miguel Rodrigues . + +1271. [bug] "recursion available: {denied,approved}" was too + confusing. + +1270. [bug] Check that system inet_pton() and inet_ntop() support + AF_INET6. + +1269. [port] Openserver: ifconfig.sh support. + +1268. [port] Openserver: the value FD_SETSIZE depends on whether + is included or not. Be consistent. + +1267. [func] isc_file_openunique() now creates file using mode + 0666 rather than 0600. + +1266. [bug] ISC_LINK_INIT, ISC_LINK_UNLINK, ISC_LIST_DEQUEUE, + __ISC_LINK_UNLINKUNSAFE and __ISC_LIST_DEQUEUEUNSAFE + are not C++ compatible, use *_TYPE versions instead. + +1265. [bug] libbind: LINK_INIT and UNLINK were not compatible with + C++, use LINK_INIT_TYPE and UNLINK_TYPE instead. + +1264. [placeholder] + +1263. [bug] Reference after free error if dns_dispatchmgr_create() + failed. + +1262. [bug] ns_server_destroy() failed to set *serverp to NULL. + +1261. [func] libbind: ns_sign2() and ns_sign_tcp() now provide + support for compressed TSIG owner names. + +1260. [func] libbind: res_update can now update IPv6 servers, + new function res_findzonecut2(). + +1259. [bug] libbind: get_salen() IPv6 support was broken for OSs + w/o sa_len. + +1258. [bug] libbind: res_nametotype() and res_nametoclass() were + broken. + +1257. [bug] Failure to write pid-file should not be fatal on + reload. [RT #2861] + +1256. [contrib] 'queryperf' now has EDNS (-e) + DNSSEC DO (-D) support. + +1255. [bug] When verifying that an NXT proves nonexistence, check + the rcode of the message and only do the matching NXT + check. That is, for NXDOMAIN responses, check that + the name is in the range between the NXT owner and + next name, and for NOERROR NODATA responses, check + that the type is not present in the NXT bitmap. + +1254. [func] preferred-glue option from BIND 8.3. + +1253. [bug] The dnssec system test failed to remove the correct + files. + +1252. [bug] Dig, host and nslookup were not checking the address + the answer was coming from against the address it was + sent to. [RT# 2692] + +1251. [port] win32: a make file contained absolute version specific + references. + +1250. [func] Nsupdate will report the address the update was + sent to. + +1249. [bug] Missing masters clause was not handled gracefully. + [RT #2703] + +1248. [bug] DESTDIR was not being propagated between makes. + +1247. [bug] Don't reset the interface index for link/site local + addresses. [RT #2576] + +1246. [func] New functions isc_sockaddr_issitelocal(), + isc_sockaddr_islinklocal(), isc_netaddr_issitelocal() + and isc_netaddr_islinklocal(). + +1245. [bug] Treat ENOBUFS, ENOMEM and ENFILE as soft errors for + accept(). + +1244. [bug] Receiving a TCP message from a blackhole address would + prevent further messages being received over that + interface. + +1243. [bug] It was possible to trigger a REQUIRE() in + dns_message_findtype(). [RT #2659] + +1242. [bug] named-checkzone failed if a journal existed. [RT #2657] + +1241. [bug] Drop received UDP messages with a zero source port + as these are invariably forged. [RT #2621] + +1240. [bug] It was possible to leak zone references by + specifying an incorrect zone to rndc. + +1239. [bug] Under certain circumstances named could continue to + use a name after it had been freed triggering + INSIST() failures. [RT #2614] + +1238. [bug] It is possible to lockup the server when shutting down + if notifies were being processed. [RT #2591] + +1237. [bug] nslookup: "set q=type" failed. + +1236. [bug] dns_rdata{class,type}_fromtext() didn't handle non + NULL terminated text regions. [RT #2588] + +1235. [func] Report 'out of memory' errors from openssl. + +1234. [bug] contrib/sdb: 'zonetodb' failed to call + dns_result_register(). DNS_R_SEENINCLUDE should not + be fatal. + +1233. [bug] The flags field of a KEY record can be expressed in + hex as well as decimal. + +1232. [bug] unix/errno2result() didn't handle EADDRNOTAVAIL. + +1231. [port] HPUX 11.11 recvmsg() can return spurious EADDRNOTAVAIL. + +1230. [bug] isccc_cc_isreply() and isccc_cc_isack() were broken. + +1229. [bug] named would crash if it received a TSIG signed + query as part of an AXFR response. [RT #2570] + +1228. [bug] 'make install' did not depend on 'make all'. [RT #2559] + +1227. [bug] dns_lex_getmastertoken() now returns ISC_R_BADNUMBER + if a number was expected and some other token was + found. [RT#2532] + +1226. [func] Use EDNS for zone refresh queries. [RT #2551] + +1225. [func] dns_message_setopt() no longer requires that + dns_message_renderbegin() to have been called. + +1224. [bug] 'rrset-order' and 'sortlist' should be additive + not exclusive. + +1223. [func] 'rrset-order' partially works 'cyclic' and 'random' + are supported. + +1222. [bug] Specifying 'port *' did not always result in a system + selected (non-reserved) port being used. [RT #2537] + +1221. [bug] Zone types 'master', 'slave' and 'stub' were not being + compared case insensitively. [RT #2542] + +1220. [func] Support for APL rdata type. + +1219. [func] Named now reports the TSIG extended error code when + signature verification fails. [RT #1651] + +1218. [bug] Named incorrectly returned SERVFAIL rather than + NOTAUTH when there was a TSIG BADTIME error. [RT #2519] + +1217. [func] Report locations of previous key definition when a + duplicate is detected. + +1216. [bug] Multiple server clauses for the same server were not + reported. [RT #2514] + +1215. [port] solaris: add support to ifconfig.sh for x86 2.5.1 + +1214. [bug] Win32: isc_file_renameunique() could leave zero length + files behind. + +1213. [func] Report view associated with client if it is not a + standard view (_default or _bind). + +1212. [port] libbind: 64k answer buffers were causing stack space + to be exceeded for certain OS. Use heap space instead. + +1211. [bug] dns_name_fromtext() incorrectly handled certain + valid octal bitlabels. [RT #2483] + +1210. [bug] libbind: getnameinfo() failed to lookup IPv4 mapped / + compatible addresses. [RT #2461] + +1209. [bug] Dig, host, nslookup were not checking the message ids + on the responses. [RT #2454] + +1208. [bug] dns_master_load*() failed to log a error message if + an error was detected when parsing the ownername of + a record. [RT #2448] + +1207. [bug] libbind: getaddrinfo() could call freeaddrinfo() with + an invalid pointer. + +1206. [bug] SERVFAIL and NOTIMP responses to an EDNS query should + trigger a non-EDNS retry. + +1205. [bug] OPT, TSIG and TKEY cannot be used to set the "class" + of the message. [RT #2449] + +1204. [bug] libbind: res_nupdate() failed to update the name + server addresses before sending the update. + +1203. [func] Report locations of previous acl and zone definitions + when a duplicate is detected. + +1202. [func] New functions: cfg_obj_line() and cfg_obj_file(). + +1201. [bug] Require that if 'callbacks' is passed to + dns_rdata_fromtext(), callbacks->error and + callbacks->warn are initialized. + +1200. [bug] Log 'errno' that we are unable to convert to + isc_result_t. [RT #2404] + +1199. [doc] ARM reference to RFC 2157 should have been RFC 1918. + [RT #2436] + +1198. [bug] OPT printing style was not consistent with the way the + header fields are printed. The DO bit was not reported + if set. Report if any of the MBZ bits are set. + +1197. [bug] Attempts to define the same acl multiple times were not + detected. + +1196. [contrib] update mdnkit to 2.2.3. + +1195. [bug] Attempts to redefine builtin acls should be caught. + [RT #2403] + +1194. [bug] Not all duplicate zone definitions were being detected + at the named.conf checking stage. [RT #2431] + +1193. [bug] dig +besteffort parsing didn't handle packet + truncation. dns_message_parse() has new flag + DNS_MESSAGE_IGNORETRUNCATION. + +1192. [bug] The seconds fields in LOC records were restricted + to three decimal places. More decimal places should + be allowed but warned about. + +1191. [bug] A dynamic update removing the last non-apex name in + a secure zone would fail. [RT #2399] + +1190. [func] Add the "rndc freeze" and "rndc unfreeze" commands. + [RT #2394] + +1189. [bug] On some systems, malloc(0) returns NULL, which + could cause the caller to report an out of memory + error. [RT #2398] + +1188. [bug] Dynamic updates of a signed zone would fail if + some of the zone private keys were unavailable. + +1187. [bug] named was incorrectly returning DNSSEC records + in negative responses when the DO bit was not set. + +1186. [bug] isc_hex_tobuffer(,,length = 0) failed to unget the + EOL token when reading to end of line. + +1185. [bug] libbind: don't assume statp->_u._ext.ext is valid + unless RES_INIT is set when calling res_*init(). + +1184. [bug] libbind: call res_ndestroy() if RES_INIT is set + when res_*init() is called. + +1183. [bug] Handle ENOSR error when writing to the internal + control pipe. [RT #2395] + +1182. [bug] The server could throw an assertion failure when + constructing a negative response packet. + +1181. [func] Add the "key-directory" configuration statement, + which allows the server to look for online signing + keys in alternate directories. + +1180. [func] dnssec-keygen should always generate keys with + protocol 3 (DNSSEC), since it's less confusing + that way. + +1179. [func] Add SIG(0) support to nsupdate. + +1178. [bug] Follow and cache (if appropriate) A6 and other + data chains to completion in the additional section. + +1177. [func] Report view when loading zones if it is not a + standard view (_default or _bind). [RT #2270] + +1176. [doc] Document that allow-v6-synthesis is only performed + for clients that are supplied recursive service. + [RT #2260] + +1175. [bug] named-checkzone and named-checkconf failed to call + dns_result_register() at startup which could + result in runtime exceptions when printing + "out of memory" errors. [RT #2335] + +1174. [bug] Win32: add WSAECONNRESET to the expected errors + from connect(). [RT #2308] + +1173. [bug] Potential memory leaks in isc_log_create() and + isc_log_settag(). [RT #2336] + +1172. [doc] Add CERT, GPOS, KX, NAPTR, NSAP, PX and TXT to + table of RR types in ARM. + +1171. [func] Added function isc_region_compare(), updated files in + lib/dns to use this function instead of local one. + +1170. [bug] Don't attempt to print the token when a I/O error + occurs when parsing named.conf. [RT #2275] + +1169. [func] Identify recursive queries in the query log. + +1168. [bug] Empty also-notify clauses were not handled. [RT #2309] + +1167. [contrib] nslint-2.1a3 (from author). + +1166. [bug] "Not Implemented" should be reported as NOTIMP, + not NOTIMPL. [RT #2281] + +1165. [bug] We were rejecting notify-source{-v6} in zone clauses. + +1164. [bug] Empty masters clauses in slave / stub zones were not + handled gracefully. [RT #2262] + +1163. [func] isc_time_formattimestamp() now includes the year. + +1162. [bug] The allow-notify option was not accepted in slave + zone statements. + +1161. [bug] named-checkzone looped on unbalanced brackets. + [RT #2248] + +1160. [bug] Generating Diffie-Hellman keys longer than 1024 + bits could fail. [RT #2241] + +1159. [bug] MD and MF are not permitted to be loaded by RFC1123. + +1158. [func] Report the client's address when logging notify + messages. + +1157. [func] match-clients and match-destinations now accept + keys. [RT #2045] + +1156. [port] The configure test for strsep() incorrectly + succeeded on certain patched versions of + AIX 4.3.3. [RT #2190] + +1155. [func] Recover from master files being removed from under + us. + +1154. [bug] Don't attempt to obtain the netmask of a interface + if there is no address configured. [RT #2176] + +1153. [func] 'rndc {stop|halt} -p' now reports the process id + of the instance of named being shutdown. + +1152. [bug] libbind: read buffer overflows. + +1151. [bug] nslookup failed to check that the arguments to + the port, timeout, and retry options were + valid integers and in range. [RT #2099] + +1150. [bug] named incorrectly accepted TTL values + containing plus or minus signs, such as + 1d+1h-1s. + +1149. [func] New function isc_parse_uint32(). + +1148. [func] 'rndc-confgen -a' now provides positive feedback. + +1147. [func] Set IPV6_V6ONLY on IPv6 sockets if supported by + the OS. listen-on-v6 { any; }; should no longer + result in IPv4 queries be accepted. Similarly + control { inet :: ... }; should no longer result + in IPv4 connections being accepted. This can be + overridden at compile time by defining + ISC_ALLOW_MAPPED=1. + +1146. [func] Allow IPV6_IPV6ONLY to be set/cleared on a socket if + supported by the OS by a new function + isc_socket_ipv6only(). + +1145. [func] "host" no longer reports a NOERROR/NODATA response + by printing nothing. [RT #2065] + +1144. [bug] rndc-confgen would crash if both the -a and -t + options were specified. [RT #2159] + +1143. [bug] When a trusted-keys statement was present and named + was built without crypto support, it would leak memory. + +1142. [bug] dnssec-signzone would fail to delete temporary files + in some failure cases. [RT #2144] + +1141. [bug] When named rejected a control message, it would + leak a file descriptor and memory. It would also + fail to respond, causing rndc to hang. + [RT #2139, #2164] + +1140. [bug] rndc-confgen did not accept IPv6 addresses as arguments + to the -s option. [RT #2138] + +1139. [func] It is now possible to flush a given name from the + cache(s) via 'rndc flushname name [view]'. [RT #2051] + +1138. [func] It is now possible to flush a given name from the + cache by calling the new function + dns_cache_flushname(). + +1137. [func] It is now possible to flush a given name from the + ADB by calling the new function dns_adb_flushname(). + +1136. [bug] CNAME records synthesized from DNAMEs did not + have a TTL of zero as required by RFC2672. + [RT #2129] + +1135. [func] You can now override the default syslog() facility for + named/lwresd at compile time. [RT #1982] + +1134. [bug] Multi-threaded servers could deadlock in ferror() + when reloading zone files. [RT #1951, #1998] + +1133. [bug] IN6_IS_ADDR_LOOPBACK was not portably defined on + platforms without IN6_IS_ADDR_LOOPBACK. [RT #2106] + +1132. [func] Improve UPDATE prerequisite failure diagnostic messages. + +1131. [bug] The match-destinations view option did not work with + IPv6 destinations. [RT #2073, #2074] + +1130. [bug] Log messages reporting an out-of-range serial number + did not include the out-of-range number but the + following token. [RT #2076] + +1129. [bug] Multi-threaded servers could crash under heavy + resolution load due to a race condition. [RT #2018] + +1128. [func] sdb drivers can now provide RR data in either text + or wire format, the latter using the new functions + dns_sdb_putrdata() and dns_sdb_putnamedrdata(). + +1127. [func] rndc: If the server to contact has multiple addresses, + try all of them. + +1126. [bug] The server could access a freed event if shut + down while a client start event was pending + delivery. [RT #2061] + +1125. [bug] rndc: -k option was missing from usage message. + [RT #2057] + +1124. [doc] dig: +[no]dnssec, +[no]besteffort and +[no]fail + are now documented. [RT #2052] + +1123. [bug] dig +[no]fail did not match description. [RT #2052] + +1122. [tuning] Resolution timeout reduced from 90 to 30 seconds. + [RT #2046] + +1121. [bug] The server could attempt to access a NULL zone + table if shut down while resolving. + [RT #1587, #2054] + +1120. [bug] Errors in options were not fatal. [RT #2002] + +1119. [func] Added support in Win32 for NTFS file/directory ACL's + for access control. + +1118. [bug] On multi-threaded servers, a race condition + could cause an assertion failure in resolver.c + during resolver shutdown. [RT #2029] + +1117. [port] The configure check for in6addr_loopback incorrectly + succeeded on AIX 4.3 when compiling with -O2 + because the test code was optimized away. + [RT #2016] + +1116. [bug] Setting transfers in a server clause, transfers-in, + or transfers-per-ns to a value greater than + 2147483647 disabled transfers. [RT #2002] + +1115. [func] Set maximum values for cleaning-interval, + heartbeat-interval, interface-interval, + max-transfer-idle-in, max-transfer-idle-out, + max-transfer-time-in, max-transfer-time-out, + statistics-interval of 28 days and + sig-validity-interval of 3660 days. [RT #2002] + +1114. [port] Ignore more accept() errors. [RT #2021] + +1113. [bug] The allow-update-forwarding option was ignored + when specified in a view. [RT #2014] + +1112. [placeholder] + +1111. [bug] Multi-threaded servers could deadlock processing + recursive queries due to a locking hierarchy + violation in adb.c. [RT #2017] + +1110. [bug] dig should only accept valid abbreviations of +options. + [RT #2003] + +1109. [bug] nsupdate accepted illegal ttl values. + +1108. [bug] On Win32, rndc was hanging when named was not running + due to failure to select for exceptional conditions + in select(). [RT #1870] + +1107. [bug] nsupdate could catch an assertion failure if an + invalid domain name was given as the argument to + the "zone" command. + +1106. [bug] After seeing an out of range TTL, nsupdate would + treat all TTLs as out of range. [RT #2001] + +1105. [port] OpenUNIX 8 enable threads by default. [RT #1970] + +1104. [bug] Invalid arguments to the transfer-format option + could cause an assertion failure. [RT #1995] + +1103. [port] OpenUNIX 8 support (ifconfig.sh). [RT #1970] + +1102. [doc] Note that query logging is enabled by directing the + queries category to a channel. + +1101. [bug] Array bounds read error in lwres_gai_strerror. + +1100. [bug] libbind: DNSSEC key ids were computed incorrectly. + +1099. [cleanup] libbind: defining REPORT_ERRORS in lib/bind/dst caused + compile time errors. + +1098. [bug] libbind: HMAC-MD5 key files are now mode 0600. + +1097. [func] libbind: RES_PRF_TRUNC for dig. + +1096. [func] libbind: "DNSSEC OK" (DO) support. + +1095. [func] libbind: resolver option: no-tld-query. disables + trying unqualified as a tld. no_tld_query is also + supported for FreeBSD compatibility. + +1094. [func] libbind: add support gcc's format string checking. + +1093. [doc] libbind: miscellaneous nroff fixes. + +1092. [bug] libbind: get*by*() failed to check if res_init() had + been called. + +1091. [bug] libbind: misplaced va_end(). + +1090. [bug] libbind: dns_ho.c:add_hostent() was not returning + the amount of memory consumed resulting in garbage + address being returned. Alignment calculations were + wasting space. We weren't suppressing duplicate + addresses. + +1089. [func] libbind: inet_{cidr,net}_{pton,ntop}() now have IPv6 + support. + +1088. [port] libbind: MPE/iX C.70 (incomplete) + +1087. [bug] libbind: struct __res_state too large on 64 bit arch. + +1086. [port] libbind: sunos: old sprintf. + +1085. [port] libbind: solaris: sys_nerr and sys_errlist do not + exist when compiling in 64 bit mode. + +1084. [cleanup] libbind: gai_strerror() rewritten. + +1083. [bug] The default control channel listened on the + wildcard address, not the loopback as documented. + [RT #1975] + +1082. [bug] The -g option to named incorrectly caused logging + to be sent to syslog in addition to stderr. + [RT #1974] + +1081. [bug] Multicast queries were incorrectly identified + based on the source address, not the destination + address. + +1080. [bug] BIND 8 compatibility: accept bare IP prefixes + as the second element of a two-element top level + sort list statement. [RT #1964] + +1079. [bug] BIND 8 compatibility: accept bare elements at top + level of sort list treating them as if they were + a single element list. [RT #1963] + +1078. [bug] We failed to correct bad tv_usec values in one case. + [RT #1966] + +1077. [func] Do not accept further recursive clients when + the total number of recursive lookups being + processed exceeds max-recursive-clients, even + if some of the lookups are internally generated. + [RT #1915, #1938] + +1076. [bug] A badly defined global key could trigger an assertion + on load/reload if views were used. [RT #1947] + +1075. [bug] Out-of-range network prefix lengths were not + reported. [RT #1954] + +1074. [bug] Running out of memory in dump_rdataset() could + cause an assertion failure. [RT #1946] + +1073. [bug] The ADB cache cleaning should also be space driven. + [RT #1915, #1938] + +1072. [bug] The TCP client quota could be exceeded when + recursion occurred. [RT #1937] + +1071. [bug] Sockets listening for TCP DNS connections + specified an excessive listen backlog. [RT #1937] + +1070. [bug] Copy DNSSEC OK (DO) to response as specified by + draft-ietf-dnsext-dnssec-okbit-03.txt. + +1069. [placeholder] + +1068. [bug] errno could be overwritten by catgets(). [RT #1921] + +1067. [func] Allow quotas to be soft, isc_quota_soft(). + +1066. [bug] Provide a thread safe wrapper for strerror(). + [RT #1689] + +1065. [func] Runtime support to select new / old style interface + scanning using ioctls. + +1064. [bug] Do not shut down active network interfaces if we + are unable to scan the interface list. [RT #1921] + +1063. [bug] libbind: "make install" was failing on IRIX. + [RT #1919] + +1062. [bug] If the control channel listener socket was shut + down before server exit, the listener object could + be freed twice. [RT #1916] + +1061. [bug] If periodic cache cleaning happened to start + while cleaning due to reaching the configured + maximum cache size was in progress, the server + could catch an assertion failure. [RT #1912] + +1060. [func] Move refresh, stub and notify UDP retry processing + into dns_request. + +1059. [func] dns_request now support will now retry UDP queries, + dns_request_createvia2() and dns_request_createraw2(). + +1058. [func] Limited lifetime ticker timers are now available, + isc_timertype_limited. + +1057. [bug] Reloading the server after adding a "file" clause + to a zone statement could cause the server to + crash due to a typo in change 1016. + +1056. [bug] Rndc could catch an assertion failure on SIGINT due + to an uninitialized variable. [RT #1908] + +1055. [func] Version and hostname queries can now be disabled + using "version none;" and "hostname none;", + respectively. + +1054. [bug] On Win32, cfg_categories and cfg_modules need to be + exported from the libisccfg DLL. + +1053. [bug] Dig did not increase its timeout when receiving + AXFRs unless the +time option was used. [RT #1904] + +1052. [bug] Journals were not being created in binary mode + resulting in "journal format not recognized" error + under Win32. [RT #1889] + +1051. [bug] Do not ignore a network interface completely just + because it has a noncontiguous netmask. Instead, + omit it from the localnets ACL and issue a warning. + [RT #1891] + +1050. [bug] Log messages reporting malformed IP addresses in + address lists such as that of the forwarders option + failed to include the correct error code, file + name, and line number. [RT #1890] + +1049. [func] "pid-file none;" will disable writing a pid file. + [RT #1848] + +1048. [bug] Servers built with -DISC_MEM_USE_INTERNAL_MALLOC=1 + didn't work. + +1047. [bug] named was incorrectly refusing all requests signed + with a TSIG key derived from an unsigned TKEY + negotiation with a NOERROR response. [RT #1886] + +1046. [bug] The help message for the --with-openssl configure + option was inaccurate. [RT #1880] + +1045. [bug] It was possible to skip saving glue for a nameserver + for a stub zone. + +1044. [bug] Specifying allow-transfer, notify-source, or + notify-source-v6 in a stub zone was not treated + as an error. + +1043. [bug] Specifying a transfer-source or transfer-source-v6 + option in the zone statement for a master zone was + not treated as an error. [RT #1876] + +1042. [bug] The "config" logging category did not work properly. + [RT #1873] + +1041. [bug] Dig/host/nslookup could catch an assertion failure + on SIGINT due to an uninitialized variable. [RT #1867] + +1040. [bug] Multiple listen-on-v6 options with different ports + were not accepted. [RT #1875] + +1039. [bug] Negative responses with CNAMEs in the answer section + were cached incorrectly. [RT #1862] + +1038. [bug] In servers configured with a tkey-domain option, + TKEY queries with an owner name other than the root + could cause an assertion failure. [RT #1866, #1869] + +1037. [bug] Negative responses whose authority section contain + SOA or NS records whose owner names are not equal + equal to or parents of the query name should be + rejected. [RT #1862] + +1036. [func] Silently drop requests received via multicast as + long as there is no final multicast DNS standard. + +1035. [bug] If we respond to multicast queries (which we + currently do not), respond from a unicast address + as specified in RFC 1123. [RT #137] + +1034. [bug] Ignore the RD bit on multicast queries as specified + in RFC 1123. [RT #137] + +1033. [bug] Always respond to requests with an unsupported opcode + with NOTIMP, even if we don't have a matching view + or cannot determine the class. + +1032. [func] hostname.bind/txt/chaos now returns the name of + the machine hosting the nameserver. This is useful + in diagnosing problems with anycast servers. + +1031. [bug] libbind.a: isc__gettimeofday() infinite recursion. + [RT #1858] + +1030. [bug] On systems with no resolv.conf file, nsupdate + exited with an error rather than defaulting + to using the loopback address. [RT #1836] + +1029. [bug] Some named.conf errors did not cause the loading + of the configuration file to return a failure + status even though they were logged. [RT #1847] + +1028. [bug] On Win32, dig/host/nslookup looked for resolv.conf + in the wrong directory. [RT #1833] + +1027. [bug] RRs having the reserved type 0 should be rejected. + [RT #1471] + +1026. [placeholder] + +1025. [bug] Don't use multicast addresses to resolve iterative + queries. [RT #101] + +1024. [port] Compilation failed on HP-UX 11.11 due to + incompatible use of the SIOCGLIFCONF macro + name. [RT #1831] + +1023. [func] Accept hints without TTLs. + +1022. [bug] Don't report empty root hints as "extra data". + [RT #1802] + +1021. [bug] On Win32, log message timestamps were one month + later than they should have been, and the server + would exhibit unspecified behavior in December. + +1020. [bug] IXFR log messages did not distinguish between + true IXFRs, AXFR-style IXFRs, and mere version + polls. [RT #1811] + +1019. [bug] The value of the lame-ttl option was limited to 18000 + seconds, not 1800 seconds as documented. [RT #1803] + +1018. [bug] The default log channel was not always initialized + correctly. [RT #1813] + +1017. [bug] When specifying TSIG keys to dig and nsupdate using + the -k option, they must be HMAC-MD5 keys. [RT #1810] + +1016. [bug] Slave zones with no backup file were re-transferred + on every server reload. + +1015. [bug] Log channels that had a "versions" option but no + "size" option failed to create numbered log + files. [RT #1783] + +1014. [bug] Some queries would cause statistics counters to + increment more than once or not at all. [RT #1321] + +1013. [bug] It was possible to cancel a query twice when marking + a server as bogus or by having a blackhole acl. + [RT #1776] + +1012. [bug] The -p option to named did not behave as documented. + +1011. [cleanup] Removed isc_dir_current(). + +1010. [bug] The server could attempt to execute a command channel + command after initiating server shutdown, causing + an assertion failure. [RT #1766] + +1009. [port] OpenUNIX 8 support. [RT #1728] + +1008. [port] libtool.m4, ltmain.sh from libtool-1.4.2. + +1007. [port] config.guess, config.sub from autoconf-2.52. + +1006. [bug] If a KEY RR was found missing during DNSSEC validation, + an assertion failure could subsequently be triggered + in the resolver. [RT #1763] + +1005. [bug] Don't copy nonzero RCODEs from request to response. + [RT #1765] + +1004. [port] Deal with recvfrom() returning EHOSTDOWN. [RT #1770] + +1003. [func] Add the +retry option to dig. + +1002. [bug] When reporting an unknown class name in named.conf, + including the file name and line number. [RT #1759] + +1001. [bug] win32 socket code doio_recv was not catching a + WSACONNRESET error when a client was timing out + the request and closing its socket. [RT #1745] + +1000. [bug] BIND 8 compatibility: accept "HESIOD" as an alias + for class "HS". [RT #1759] + + 999. [func] "rndc retransfer zone [class [view]]" added. + [RT #1752] + + 998. [func] named-checkzone now has arguments to specify the + chroot directory (-t) and working directory (-w). + [RT #1755] + + 997. [func] Add support for RSA-SHA1 keys (RFC3110). + + 996. [func] Issue warning if the configuration filename contains + the chroot path. + + 995. [bug] dig, host, nslookup: using a raw IPv6 address as a + target address should be fatal on a IPv4 only system. + + 994. [func] Treat non-authoritative responses to queries for type + NS as referrals even if the NS records are in the + answer section, because BIND 8 servers incorrectly + send them that way. This is necessary for DNSSEC + validation of the NS records of a secure zone to + succeed when the parent is a BIND 8 server. [RT #1706] + + 993. [func] dig: -v now reports the version. + + 992. [doc] dig: ~/.digrc is now documented. + + 991. [func] Lower UDP refresh timeout messages to level + debug 1. + + 990. [bug] The rndc-confgen man page was not installed. + + 989. [bug] Report filename if $INCLUDE fails for file related + errors. [RT #1736] + + 988. [bug] 'additional-from-auth no;' did not work reliably + in the case of queries answered from the cache. + [RT #1436] + + 987. [bug] "dig -help" didn't show "+[no]stats". + + 986. [bug] "dig +noall" failed to clear stats and command + printing. + + 985. [func] Consider network interfaces to be up iff they have + a nonzero IP address rather than based on the + IFF_UP flag. [RT #1160] + + 984. [bug] Multi-threading should be enabled by default on + Solaris 2.7 and newer, but it wasn't. + + 983. [func] The server now supports generating IXFR difference + sequences for non-dynamic zones by comparing zone + versions, when enabled using the new config + option "ixfr-from-differences". [RT #1727] + + 982. [func] If "memstatistics-file" is set in options the memory + statistics will be written to it. + + 981. [func] The dnssec tools can now take multiple '-r randomfile' + arguments. + + 980. [bug] Incoming zone transfers restarting after an error + could trigger an assertion failure. [RT #1692] + + 979. [func] Incremental master file dumping. dns_master_dumpinc(), + dns_master_dumptostreaminc(), dns_dumpctx_attach(), + dns_dumpctx_detach(), dns_dumpctx_cancel(), + dns_dumpctx_db() and dns_dumpctx_version(). + + 978. [bug] dns_db_attachversion() had an invalid REQUIRE() + condition. + + 977. [bug] Improve "not at top of zone" error message. + + 976. [func] named-checkconf can now test load master zones + (named-checkconf -z). [RT #1468] + + 975. [bug] "max-cache-size default;" as a view option + caused an assertion failure. + + 974. [bug] "max-cache-size unlimited;" as a global option + was not accepted. + + 973. [bug] Failed to log the question name when logging: + "bad zone transfer request: non-authoritative zone + (NOTAUTH)". + + 972. [bug] The file modification time code in zone.c was using the + wrong epoch. [RT #1667] + + 971. [placeholder] + + 970. [func] 'max-journal-size' can now be used to set a target + size for a journal. + + 969. [func] dig now supports the undocumented dig 8 feature + of allowing arbitrary labels, not just dotted + decimal quads, with the -x option. This can be + used to conveniently look up RFC2317 names as in + "dig -x 10.0.0.0-127". [RT #827, #1576, #1598] + + 968. [bug] On win32, the isc_time_now() function was unnecessarily + calling strtime(). [RT #1671] + + 967. [bug] On win32, the link for bindevt was not including the + required resource file to enable the event viewer + to interpret the error messages in the event log, + [RT #1668] + + 966. [placeholder] + + 965. [bug] Including data other than root server NS and A + records in the root hint file could cause a rbtdb + node reference leak. [RT #1581, #1618] + + 964. [func] Warn if data other than root server NS and A records + are found in the root hint file. [RT #1581, #1618] + + 963. [bug] Bad ISC_LANG_ENDDECLS. [RT #1645] + + 962. [bug] libbind: bad "#undef", don't attempt to install + non-existant nlist.h. [RT #1640] + + 961. [bug] Tried to use a IPV6 feature when ISC_PLATFORM_HAVEIPV6 + was not defined. [RT #1482] + + 960. [port] liblwres failed to build on systems with support for + getrrsetbyname() in the OS. [RT #1592] + + 959. [port] On FreeBSD, determine the number of CPUs by calling + sysctlbyname(). [RT #1584] + + 958. [port] ssize_t is not available on all platforms. [RT #1607] + + 957. [bug] sys/select.h inclusion was broken on older platforms. + [RT #1607] + + 956. [bug] ns_g_autorndcfile changed to ns_g_keyfile + in named/win32/os.c due to code changes in + change #953. win32 .make file for rndc-confgen + updated to add include path for os.h header. + + --- 9.2.0rc1 released --- + + 955. [bug] When using views, the zone's class was not being + inherited from the view's class. [RT #1583] + + 954. [bug] When requesting AXFRs or IXFRs using dig, host, or + nslookup, the RD bit should not be set as zone + transfers are inherently nonrecursive. [RT #1575] + + 953. [func] The /var/run/named.key file from change #843 + has been replaced by /etc/rndc.key. Both + named and rndc will look for this file and use + it to configure a default control channel key + if not already configured using a different + method (rndc.conf / controls). Unlike + named.key, rndc.key is not created automatically; + it must be created by manually running + "rndc-confgen -a". + + 952. [bug] The server required manual intervention to serve the + affected zones if it died between creating a journal + and committing the first change to it. + + 951. [bug] CFLAGS was not passed to the linker when + linking some of the test programs under + bin/tests. [RT #1555]. + + 950. [bug] Explicit TTLs did not properly override $TTL + due to a bug in change 834. [RT #1558] + + 949. [bug] host was unable to print records larger than 512 + bytes. [RT #1557] + + --- 9.2.0b2 released --- + + 948. [port] Integrated support for building on Windows NT / + Windows 2000. + + 947. [bug] dns_rdata_soa_t had a badly named element "mname" which + was really the RNAME field from RFC1035. To avoid + confusion and silent errors that would occur it the + "origin" and "mname" elements were given their correct + names "mname" and "rname" respectively, the "mname" + element is renamed to "contact". + + 946. [cleanup] doc/misc/options is now machine-generated from the + configuration parser syntax tables, and therefore + more likely to be correct. + + 945. [func] Add the new view-specific options + "match-destinations" and "match-recursive-only". + + 944. [func] Check for expired signatures on load. + + 943. [bug] The server could crash when receiving a command + via rndc if the configuration file listed only + nonexistent keys in the controls statement. [RT #1530] + + 942. [port] libbind: GETNETBYADDR_ADDR_T was not correctly + defined on some platforms. + + 941. [bug] The configuration checker crashed if a slave + zone didn't contain a masters statement. [RT #1514] + + 940. [bug] Double zone locking failure on error path. [RT #1510] + + --- 9.2.0b1 released --- + + 939. [port] Add the --disable-linux-caps option to configure for + systems that manage capabilities outside of named. + [RT #1503] + + 938. [placeholder] + + 937. [bug] A race when shutting down a zone could trigger a + INSIST() failure. [RT #1034] + + 936. [func] Warn about IPv4 addresses that are not complete + dotted quads. [RT #1084] + + 935. [bug] inet_pton failed to reject leading zeros. + + 934. [port] Deal with systems where accept() spuriously returns + ECONNRESET. + + 933. [bug] configure failed doing libbind on platforms not + supported by BIND 8. [RT #1496] + + --- 9.2.0a3 released --- + + 932. [bug] Use INSTALL_SCRIPT, not INSTALL_PROGRAM, + when installing isc-config.sh. + [RT #198, #1466] + + 931. [bug] The controls statement only attempted to verify + messages using the first key in the key list. + (9.2.0a1/a2 only). + + 930. [func] Query performance testing tool added as + contrib/queryperf. + + 929. [placeholder] + + 928. [bug] nsupdate would send empty update packets if the + send (or empty line) command was run after + another send but before any new updates or + prerequisites were specified. It should simply + ignore this command. + + 927. [bug] Don't hold the zone lock for the entire dump to disk. + [RT #1423] + + 926. [bug] The resolver could deadlock with the ADB when + shutting down (multi-threaded builds only). + [RT #1324] + + 925. [cleanup] Remove openssl from the distribution; require that + --with-openssl be specified if DNSSEC is needed. + + 924. [port] Extend support for pre-RFC2133 IPv6 implementation. + [RT #987] + + 923. [bug] Multiline TSIG secrets (and other multiline strings) + were not accepted in named.conf. [RT #1469] + + 922. [func] Added two new lwres_getrrsetbyname() result codes, + ERR_NONAME and ERR_NODATA. + + 921. [bug] lwres returned an incorrect error code if it received + a truncated message. + + 920. [func] Increase the lwres receive buffer size to 16K. + [RT #1451] + + 919. [placeholder] + + 918. [func] In nsupdate, TSIG errors are no longer treated as + fatal errors. + + 917. [func] New nsupdate command 'key', allowing TSIG keys to + be specified in the nsupdate command stream rather + than the command line. + + 916. [bug] Specifying type ixfr to dig without specifying + a serial number failed in unexpected ways. + + 915. [func] The named-checkconf and named-checkzone programs + now have a '-v' option for printing their version. + [RT #1151] + + 914. [bug] Global 'server' statements were rejected when + using views, even though they were accepted + in 9.1. [RT #1368] + + 913. [bug] Cache cleaning was not sufficiently aggressive. + [RT #1441, #1444] + + 912. [bug] Attempts to set the 'additional-from-cache' or + 'additional-from-auth' option to 'no' in a + server with recursion enabled will now + be ignored and cause a warning message. + [RT #1145] + + 911. [placeholder] + + 910. [port] Some pre-RFC2133 IPv6 implementations do not define + IN6ADDR_ANY_INIT. [RT #1416] + + 909. [placeholder] + + 908. [func] New program, rndc-confgen, to simplify setting up rndc. + + 907. [func] The ability to get entropy from either the + random device, a user-provided file or from + the keyboard was migrated from the DNSSEC tools + to libisc as isc_entropy_usebestsource(). + + 906. [port] Separated the system independent portion of + lib/isc/unix/entropy.c into lib/isc/entropy.c + and added lib/isc/win32/entropy.c. + + 905. [bug] Configuring a forward "zone" for the root domain + did not work. [RT #1418] + + 904. [bug] The server would leak memory if attempting to use + an expired TSIG key. [RT #1406] + + 903. [bug] dig should not crash when receiving a TCP packet + of length 0. + + 902. [bug] The -d option was ignored if both -t and -g were also + specified. + + 901. [placeholder] + + 900. [bug] A config.guess update changed the system identification + string of FreeBSD systems; configure and + bin/tests/system/ifconfig.sh now recognize the new + string. + + --- 9.2.0a2 released --- + + 899. [bug] lib/dns/soa.c failed to compile on many platforms + due to inappropriate use of a void value. + [RT #1372, #1373, #1386, #1387, #1395] + + 898. [bug] "dig" failed to set a nonzero exit status + on UDP query timeout. [RT #1323] + + 897. [bug] A config.guess update changed the system identification + string of UnixWare systems; configure now recognizes + the new string. + + 896. [bug] If a configuration file is set on named's command line + and it has a relative pathname, the current directory + (after any possible jailing resulting from named -t) + will be prepended to it so that reloading works + properly even when a directory option is present. + + 895. [func] New function, isc_dir_current(), akin to POSIX's + getcwd(). + + 894. [bug] When using the DNSSEC tools, a message intended to warn + when the keyboard was being used because of the lack + of a suitable random device was not being printed. + + 893. [func] Removed isc_file_test() and added isc_file_exists() + for the basic functionality that was being added + with isc_file_test(). + + 892. [placeholder] + + 891. [bug] Return an error when a SIG(0) signed response to + an unsigned query is seen. This should actually + do the verification, but it's not currently + possible. [RT #1391] + + 890. [cleanup] The man pages no longer require the mandoc macros + and should now format cleanly using most versions of + nroff, and HTML versions of the man pages have been + added. Both are generated from DocBook source. + + 889. [port] Eliminated blank lines before .TH in nroff man + pages since they cause problems with some versions + of nroff. [RT #1390] + + 888. [bug] Don't die when using TKEY to delete a nonexistent + TSIG key. [RT #1392] + + 887. [port] Detect broken compilers that can't call static + functions from inline functions. [RT #1212] + + 886. [placeholder] + + 885. [placeholder] + + 884. [placeholder] + + 883. [placeholder] + + 882. [placeholder] + + 881. [placeholder] + + 880. [placeholder] + + 879. [placeholder] + + 878. [placeholder] + + 877. [placeholder] + + 876. [placeholder] + + 875. [placeholder] + + 874. [placeholder] + + 873. [placeholder] + + 872. [placeholder] + + 871. [placeholder] + + 870. [placeholder] + + 869. [placeholder] + + 868. [placeholder] + + 867. [placeholder] + + 866. [func] Close debug only file channels when debug is set to + zero. [RT #1246] + + 865. [bug] The new configuration parser did not allow + the optional debug level in a "severity debug" + clause of a logging channel to be omitted. + This is now allowed and treated as "severity + debug 1;" like it does in BIND 8.2.4, not as + "severity debug 0;" like it did in BIND 9.1. + [RT #1367] + + 864. [cleanup] Multi-threading is now enabled by default on + OSF1, Solaris 2.7 and newer, AIX, IRIX, and HP-UX. + + 863. [bug] If an error occurred while an outgoing zone transfer + was starting up, the server could access a domain + name that had already been freed when logging a + message saying that the transfer was starting. + [RT #1383] + + 862. [bug] Use after realloc(), non portable pointer arithmetic in + grmerge(). + + 861. [port] Add support for Mac OS X, by making it equivalent + to Darwin. This was derived from the config.guess + file shipped with Mac OS X. [RT #1355] + + 860. [func] Drop cross class glue in zone transfers. + + 859. [bug] Cache cleaning now won't swamp the CPU if there + is a persistent overlimit condition. + + 858. [func] isc_mem_setwater() no longer requires that when the + callback function is non-NULL then its hi_water + argument must be greater than its lo_water argument + (they can now be equal) or that they be non-zero. + + 857. [cleanup] Use ISC_MAGIC() to define all magic numbers for + structs, for our friends in EBCDIC-land. + + 856. [func] Allow partial rdatasets to be returned in answer and + authority sections to help non-TCP capable clients + recover from truncation. [RT #1301] + + 855. [bug] Stop spurious "using RFC 1035 TTL semantics" warnings. + + 854. [bug] The config parser didn't properly handle config + options that were specified in units of time other + than seconds. [RT #1372] + + 853. [bug] configure_view_acl() failed to detach existing acls. + [RT #1374] + + 852. [bug] Handle responses from servers which do not know + about IXFR. + + 851. [cleanup] The obsolete support-ixfr option was not properly + ignored. + + --- 9.2.0a1 released --- + + 850. [bug] dns_rbt_findnode() would not find nodes that were + split on a bitstring label somewhere other than in + the last label of the node. [RT #1351] + + 849. [func] will ensure INADDR_LOOPBACK is defined. + + 848. [func] A minimum max-cache-size of two megabytes is enforced + by the cache cleaner. + + 847. [func] Added isc_file_test(), which currently only has + some very basic functionality to test for the + existence of a file, whether a pathname is absolute, + or whether a pathname is the fundamental representation + of the current directory. It is intended that this + function can be expanded to test other things a + programmer might want to know about a file. + + 846. [func] A non-zero 'param' to dst_key_generate() when making an + hmac-md5 key means that good entropy is not required. + + 845. [bug] The access rights on the public file of a symmetric + key are now restricted as soon as the file is opened, + rather than after it has been written and closed. + + 844. [func] will ensure INADDR_LOOPBACK is defined, + just as does. + + 843. [func] If no controls statement is present in named.conf, + or if any inet phrase of a controls statement is + lacking a keys clause, then a key will be automatically + generated by named and an rndc.conf-style file + named named.key will be written that uses it. rndc + will use this file only if its normal configuration + file, or one provided on the command line, does not + exist. + + 842. [func] 'rndc flush' now takes an optional view. + + 841. [bug] When sdb modules were not declared threadsafe, their + create and destroy functions were not serialized. + + 840. [bug] The config file parser could print the wrong file + name if an error was detected after an included file + was parsed. [RT #1353] + + 839. [func] Dump packets for which there was no view or that the + class could not be determined to category "unmatched". + + 838. [port] UnixWare 7.x.x is now suported by + bin/tests/system/ifconfig.sh. + + 837. [cleanup] Multi-threading is now enabled by default only on + OSF1, Solaris 2.7 and newer, and AIX. + + 836. [func] Upgraded libtool to 1.4. + + 835. [bug] The dispatcher could enter a busy loop if + it got an I/O error receiving on a UDP socket. + [RT #1293] + + 834. [func] Accept (but warn about) master files beginning with + an SOA record without an explicit TTL field and + lacking a $TTL directive, by using the SOA MINTTL + as a default TTL. This is for backwards compatibility + with old versions of BIND 8, which accepted such + files without warning although they are illegal + according to RFC1035. + + 833. [cleanup] Moved dns_soa_*() from to + , and extended them to support + all the integer-valued fields of the SOA RR. + + 832. [bug] The default location for named.conf in named-checkconf + should depend on --sysconfdir like it does in named. + [RT #1258] + + 831. [placeholder] + + 830. [func] Implement 'rndc status'. + + 829. [bug] The DNS_R_ZONECUT result code should only be returned + when an ANY query is made with DNS_DBFIND_GLUEOK set. + In all other ANY query cases, returning the delegation + is better. + + 828. [bug] The errno value from recvfrom() could be overwritten + by logging code. [RT #1293] + + 827. [bug] When an IXFR protocol error occurs, the slave + should retry with AXFR. + + 826. [bug] Some IXFR protocol errors were not detected. + + 825. [bug] zone.c:ns_query() detached from the wrong zone + reference. [RT #1264] + + 824. [bug] Correct line numbers reported by dns_master_load(). + [RT #1263] + + 823. [func] The output of "dig -h" now goes to stdout so that it + can easily be piped through "more". [RT #1254] + + 822. [bug] Sending nxrrset prerequisites would crash nsupdate. + [RT #1248] + + 821. [bug] The program name used when logging to syslog should + be stripped of leading path components. + [RT #1178, #1232] + + 820. [bug] Name server address lookups failed to follow + A6 chains into the glue of local authoritative + zones. + + 819. [bug] In certain cases, the resolver's attempts to + restart an address lookup at the root could cause + the fetch to deadlock (with itself) instead of + restarting. [RT #1225] + + 818. [bug] Certain pathological responses to ANY queries could + cause an assertion failure. [RT #1218] + + 817. [func] Adjust timeouts for dialup zone queries. + + 816. [bug] Report potential problems with log file accessibility + at configuration time, since such problems can't + reliably be reported at the time they actually occur. + + 815. [bug] If a log file was specified with a path separator + character (i.e. "/") in its name and the directory + did not exist, the log file's name was treated as + though it were the directory name. [RT #1189] + + 814. [bug] Socket objects left over from accept() failures + were incorrectly destroyed, causing corruption + of socket manager data structures. + + 813. [bug] File descriptors exceeding FD_SETSIZE were handled + badly. [RT #1192] + + 812. [bug] dig sometimes printed incomplete IXFR responses + due to an uninitialized variable. [RT #1188] + + 811. [bug] Parentheses were not quoted in zone dumps. [RT #1194] + + 810. [bug] The signer name in SIG records was not properly + downcased when signing/verifying records. [RT #1186] + + 809. [bug] Configuring a non-local address as a transfer-source + could cause an assertion failure during load. + + 808. [func] Add 'rndc flush' to flush the server's cache. + + 807. [bug] When setting up TCP connections for incoming zone + transfers, the transfer-source port was not + ignored like it should be. + + 806. [bug] DNS_R_SEENINCLUDE was failing to propagate back up + the calling stack to the zone maintence level, causing + zones to not reload when an included file was touched + but the top-level zone file was not. + + 805. [bug] When using "forward only", missing root hints should + not cause queries to fail. [RT #1143] + + 804. [bug] Attempting to obtain entropy could fail in some + situations. This would be most common on systems + with user-space threads. [RT #1131] + + 803. [bug] Treat all SIG queries as if they have the CD bit set, + otherwise no data will be returned [RT #749] + + 802. [bug] DNSSEC key tags were computed incorrectly in almost + all cases. [RT #1146] + + 801. [bug] nsupdate should treat lines beginning with ';' as + comments. [RT #1139] + + 800. [bug] dnssec-signzone produced incorrect statistics for + large zones. [RT #1133] + + 799. [bug] The ADB didn't find AAAA glue in a zone unless A6 + glue was also present. + + 798. [bug] nsupdate should be able to reject bad input lines + and continue. [RT #1130] + + 797. [func] Issue a warning if the 'directory' option contains + a relative path. [RT #269] + + 796. [func] When a size limit is associated with a log file, + only roll it when the size is reached, not every + time the log file is opened. [RT #1096] + + 795. [func] Add the +multiline option to dig. [RT #1095] + + 794. [func] Implement the "port" and "default-port" statements + in rndc.conf. + + 793. [cleanup] The DNSSEC tools could create filenames that were + illegal or contained shell metacharacters. They + now use a different text encoding of names that + doesn't have these problems. [RT #1101] + + 792. [cleanup] Replace the OMAPI command channel protocol with a + simpler one. + + 791. [bug] The command channel now works over IPv6. + + 790. [bug] Wildcards created using dynamic update or IXFR + could fail to match. [RT #1111] + + 789. [bug] The "localhost" and "localnets" ACLs did not match + when used as the second element of a two-element + sortlist item. + + 788. [func] Add the "match-mapped-addresses" option, which + causes IPv6 v4mapped addresses to be treated as + IPv4 addresses for the purpose of acl matching. + + 787. [bug] The DNSSEC tools failed to downcase domain + names when mapping them into file names. + + 786. [bug] When DNSSEC signing/verifying data, owner names were + not properly downcased. + + 785. [bug] A race condition in the resolver could cause + an assertion failure. [RT #673, #872, #1048] + + 784. [bug] nsupdate and other programs would not quit properly + if some signals were blocked by the caller. [RT #1081] + + 783. [bug] Following CNAMEs could cause an assertion failure + when either using an sdb database or under very + rare conditions. + + 782. [func] Implement the "serial-query-rate" option. + + 781. [func] Avoid error packet loops by dropping duplicate FORMERR + responses. [RT #1006] + + 780. [bug] Error handling code dealing with out of memory or + other rare errors could lead to assertion failures + by calling functions on unitialized names. [RT #1065] + + 779. [func] Added the "minimal-responses" option. + + 778. [bug] When starting cache cleaning, cleaning_timer_action() + returned without first pausing the iterator, which + could cause deadlock. [RT #998] + + 777. [bug] An empty forwarders list in a zone failed to override + global forwarders. [RT #995] + + 776. [func] Improved error reporting in denied messages. [RT #252] + + 775. [placeholder] + + 774. [func] max-cache-size is implemented. + + 773. [func] Added isc_rwlock_trylock() to attempt to lock without + blocking. + + 772. [bug] Owner names could be incorrectly omitted from cache + dumps in the presence of negative caching entries. + [RT #991] + + 771. [cleanup] TSIG errors related to unsynchronized clocks + are logged better. [RT #919] + + 770. [func] Add the "edns yes_or_no" statement to the server + clause. [RT #524] + + 769. [func] Improved error reporting when parsing rdata. [RT #740] + + 768. [bug] The server did not emit an SOA when a CNAME + or DNAME chain ended in NXDOMAIN in an + authoritative zone. + + 767. [placeholder] + + 766. [bug] A few cases in query_find() could leak fname. + This would trigger the mpctx->allocated == 0 + assertion when the server exited. + [RT #739, #776, #798, #812, #818, #821, #845, + #892, #935, #966] + + 765. [func] ACL names are once again case insensitive, like + in BIND 8. [RT #252] + + 764. [func] Configuration files now allow "include" directives + in more places, such as inside the "view" statement. + [RT #377, #728, #860] + + 763. [func] Configuration files no longer have reserved words. + [RT #731, #753] + + 762. [cleanup] The named.conf and rndc.conf file parsers have + been completely rewritten. + + 761. [bug] _REENTRANT was still defined when building with + --disable-threads. + + 760. [contrib] Significant enhancements to the pgsql sdb driver. + + 759. [bug] The resolver didn't turn off "avoid fetches" mode + when restarting, possibly causing resolution + to fail when it should not. This bug only affected + platforms which support both IPv4 and IPv6. [RT #927] + + 758. [bug] The "avoid fetches" code did not treat negative + cache entries correctly, causing fetches that would + be useful to be avoided. This bug only affected + platforms which support both IPv4 and IPv6. [RT #927] + + 757. [func] Log zone transfers. + + 756. [bug] dns_zone_load() could "return" success when no master + file was configured. + + 755. [bug] Fix incorrectly formatted log messages in zone.c. + + 754. [bug] Certain failure conditions sending UDP packets + could cause the server to retry the transmission + indefinitely. [RT #902] + + 753. [bug] dig, host, and nslookup would fail to contact a + remote server if getaddrinfo() returned an IPv6 + address on a system that doesn't support IPv6. + [RT #917] + + 752. [func] Correct bad tv_usec elements returned by + gettimeofday(). + + 751. [func] Log successful zone loads / transfers. [RT #898] + + 750. [bug] A query should not match a DNAME whose trust level + is pending. [RT #916] + + 749. [bug] When a query matched a DNAME in a secure zone, the + server did not return the signature of the DNAME. + [RT #915] + + 748. [doc] List supported RFCs in doc/misc/rfc-compliance. + [RT #781] + + 747. [bug] The code to determine whether an IXFR was possible + did not properly check for a database that could + not have a journal. [RT #865, #908] + + 746. [bug] The sdb didn't clone rdatasets properly, causing + a crash when the server followed delegations. [RT #905] + + 745. [func] Report the owner name of records that fail + semantic checks while loading. + + 744. [bug] When returning DNS_R_CNAME or DNS_R_DNAME as the + result of an ANY or SIG query, the resolver failed + to setup the return event's rdatasets, causing an + assertion failure in the query code. [RT #881] + + 743. [bug] Receiving a large number of certain malformed + answers could cause named to stop responding. + [RT #861] + + 742. [placeholder] + + 741. [port] Support openssl-engine. [RT #709] + + 740. [port] Handle openssl library mismatches slightly better. + + 739. [port] Look for /dev/random in configure, rather than + assuming it will be there for only a predefined + set of OSes. + + 738. [bug] If a non-threadsafe sdb driver supported AXFR and + received an AXFR request, it would deadlock or die + with an assertion failure. [RT #852] + + 737. [port] stdtime.c failed to compile on certain platforms. + + 736. [func] New functions isc_task_{begin,end}exclusive(). + + 735. [doc] Add BIND 4 migration notes. + + 734. [bug] An attempt to re-lock the zone lock could occur if + the server was shutdown during a zone tranfer. + [RT #830] + + 733. [bug] Reference counts of dns_acl_t objects need to be + locked but were not. [RT #801, #821] + + 732. [bug] Glue with 0 TTL could also cause SERVFAIL. [RT #828] + + 731. [bug] Certain zone errors could cause named-checkzone to + fail ungracefully. [RT #819] + + 730. [bug] lwres_getaddrinfo() returns the correct result when + it fails to contact a server. [RT #768] + + 729. [port] pthread_setconcurrency() needs to be called on Solaris. + + 728. [bug] Fix comment processing on master file directives. + [RT# 757] + + 727. [port] Work around OS bug where accept() succeeds but + fails to fill in the peer address of the accepted + connection, by treating it as an error rather than + an assertion failure. [RT #809] + + 726. [func] Implement the "trace" and "notrace" commands in rndc. + + 725. [bug] Installing man pages could fail. + + 724. [func] New libisc functions isc_netaddr_any(), + isc_netaddr_any6(). + + 723. [bug] Referrals whose NS RRs had a 0 TTL caused the resolver + to return DNS_R_SERVFAIL. [RT #783] + + 722. [func] Allow incremental loads to be canceled. + + 721. [cleanup] Load manager and dns_master_loadfilequota() are no + more. + + 720. [bug] Server could enter infinite loop in + dispatch.c:do_cancel(). [RT #733] + + 719. [bug] Rapid reloads could trigger an assertion failure. + [RT #743, #763] + + 718. [cleanup] "internal" is no longer a reserved word in named.conf. + [RT #753, #731] + + 717. [bug] Certain TKEY processing failure modes could + reference an uninitialized variable, causing the + server to crash. [RT #750] + + 716. [bug] The first line of a $INCLUDE master file was lost if + an origin was specified. [RT #744] + + 715. [bug] Resolving some A6 chains could cause an assertion + failure in adb.c. [RT #738] + + 714. [bug] Preserve interval timers across reloads unless changed. + [RT# 729] + + 713. [func] named-checkconf takes '-t directory' similar to named. + [RT #726] + + 712. [bug] Sending a large signed update message caused an + assertion failure. [RT #718] + + 711. [bug] The libisc and liblwres implementations of + inet_ntop contained an off by one error. + + 710. [func] The forwarders statement now takes an optional + port. [RT #418] + + 709. [bug] ANY or SIG queries for data with a TTL of 0 + would return SERVFAIL. [RT #620] + + 708. [bug] When building with --with-openssl, the openssl headers + included with BIND 9 should not be used. [RT #702] + + 707. [func] The "filename" argument to named-checkzone is no + longer optional, to reduce confusion. [RT #612] + + 706. [bug] Zones with an explicit "allow-update { none; };" + were considered dynamic and therefore not reloaded + on SIGHUP or "rndc reload". + + 705. [port] Work out resource limit type for use where rlim_t is + not available. [RT #695] + + 704. [port] RLIMIT_NOFILE is not available on all platforms. + [RT #695] + + 703. [port] sys/select.h is needed on older platforms. [RT #695] + + 702. [func] If the address 0.0.0.0 is seen in resolv.conf, + use 127.0.0.1 instead. [RT #693] + + 701. [func] Root hints are now fully optional. Class IN + views use compiled-in hints by default, as + before. Non-IN views with no root hints now + provide authoritative service but not recursion. + A warning is logged if a view has neither root + hints nor authoritative data for the root. [RT #696] + + 700. [bug] $GENERATE range check was wrong. [RT #688] + + 699. [bug] The lexer mishandled empty quoted strings. [RT #694] + + 698. [bug] Aborting nsupdate with ^C would lead to several + race conditions. + + 697. [bug] nsupdate was not compatible with the undocumented + BIND 8 behavior of ignoring TTLs in "update delete" + commands. [RT #693] + + 696. [bug] lwresd would die with an assertion failure when passed + a zero-length name. [RT #692] + + 695. [bug] If the resolver attempted to query a blackholed or + bogus server, the resolution would fail immediately. + + 694. [bug] $GENERATE did not produce the last entry. + [RT #682, #683] + + 693. [bug] An empty lwres statement in named.conf caused + the server to crash while loading. + + 692. [bug] Deal with systems that have getaddrinfo() but not + gai_strerror(). [RT #679] + + 691. [bug] Configuring per-view forwarders caused an assertion + failure. [RT #675, #734] + + 690. [func] $GENERATE now supports DNAME. [RT #654] + + 689. [doc] man pages are now installed. [RT #210] + + 688. [func] "make tags" now works on systems with the + "Exuberant Ctags" etags. + + 687. [bug] Only say we have IPv6, with sufficent functionality, + if it has actually been tested. [RT #586] + + 686. [bug] dig and nslookup can now be properly aborted during + blocking operations. [RT #568] + + 685. [bug] nslookup should use the search list/domain options + from resolv.conf by default. [RT #405, #630] + + 684. [bug] Memory leak with view forwarders. [RT #656] + + 683. [bug] File descriptor leak in isc_lex_openfile(). + + 682. [bug] nslookup displayed SOA records incorrectly. [RT #665] + + 681. [bug] $GENERATE specifying output format was broken. [RT #653] + + 680. [bug] dns_rdata_fromstruct() mishandled options bigger + than 255 octets. + + 679. [bug] $INCLUDE could leak memory and file descriptors on + reload. [RT #639] + + 678. [bug] "transfer-format one-answer;" could trigger an assertion + failure. [RT #646] + + 677. [bug] dnssec-signzone would occasionally use the wrong ttl + for database operations and fail. [RT #643] + + 676. [bug] Log messages about lame servers to category + 'lame-servers' rather than 'resolver', so as not + to be gratuitously incompatible with BIND 8. + + 675. [bug] TKEY queries could cause the server to leak + memory. + + 674. [func] Allow messages to be TSIG signed / verified using + a offset from the current time. + + 673. [func] The server can now convert RFC1886-style recursive + lookup requests into RFC2874-style lookups, when + enabled using the new option "allow-v6-synthesis". + + 672. [bug] The wrong time was in the "time signed" field when + replying with BADTIME error. + + 671. [bug] The message code was failing to parse a message with + no question section and a TSIG record. [RT #628] + + 670. [bug] The lwres replacements for getaddrinfo and + getipnodebyname didn't properly check for the + existence of the sockaddr sa_len field. + + 669. [bug] dnssec-keygen now makes the public key file + non-world-readable for symmetric keys. [RT #403] + + 668. [func] named-checkzone now reports multiple errors in master + files. + + 667. [bug] On Linux, running named with the -u option and a + non-world-readable configuration file didn't work. + [RT #626] + + 666. [bug] If a request sent by dig is longer than 512 bytes, + use TCP. + + 665. [bug] Signed responses were not sent when the size of the + TSIG + question exceeded the maximum message size. + [RT #628] + + 664. [bug] The t_tasks and t_timers module tests are now skipped + when building without threads, since they require + threads. + + 663. [func] Accept a size_spec, not just an integer, in the + (unimplemented and ignored) max-ixfr-log-size option + for compatibility with recent versions of BIND 8. + [RT #613] + + 662. [bug] dns_rdata_fromtext() failed to log certain errors. + + 661. [bug] Certain UDP IXFR requests caused an assertion failure + (mpctx->allocated == 0). [RT #355, #394, #623] + + 660. [port] Detect multiple CPUs on HP-UX and IRIX. + + 659. [performance] Rewrite the name compression code to be much faster. + + 658. [cleanup] Remove all vestiges of 16 bit global compression. + + 657. [bug] When a listen-on statement in an lwres block does not + specify a port, use 921, not 53. Also update the + listen-on documentation. [RT #616] + + 656. [func] Treat an unescaped newline in a quoted string as + an error. This means that TXT records with missing + close quotes should have meaningful errors printed. + + 655. [bug] Improve error reporting on unexpected eof when loading + zones. [RT #611] + + 654. [bug] Origin was being forgotten in TCP retries in dig. + [RT #574] + + 653. [bug] +defname option in dig was reversed in sense. + [RT #549] + + 652. [bug] zone_saveunique() did not report the new name. + + 651. [func] The AD bit in responses now has the meaning + specified in . + + 650. [bug] SIG(0) records were being generated and verified + incorrectly. [RT #606] + + 649. [bug] It was possible to join to an already running fctx + after it had "cloned" its events, but before it sent + them. In this case, the event of the newly joined + fetch would not contain the answer, and would + trigger the INSIST() in fctx_sendevents(). In + BIND 9.0, this bug did not trigger an INSIST(), but + caused the fetch to fail with a SERVFAIL result. + [RT #588, #597, #605, #607] + + 648. [port] Add support for pre-RFC2133 IPv6 implementations. + + 647. [bug] Resolver queries sent after following multiple + referrals had excessively long retransmission + timeouts due to incorrectly counting the referrals + as "restarts". + + 646. [bug] The UnixWare ISC_PLATFORM_FIXIN6INADDR fix in isc/net.h + didn't _cleanly_ fix the problem it was trying to fix. + + 645. [port] BSD/OS 3.0 needs pthread_init(). [RT #603] + + 644. [bug] #622 needed more work. [RT #562] + + 643. [bug] xfrin error messages made more verbose, added class + of the zone. [RT# 599] + + 642. [bug] Break the exit_check() race in the zone module. + [RT #598] + + --- 9.1.0b2 released --- + + 641. [bug] $GENERATE caused a uninitialized link to be used. + [RT #595] + + 640. [bug] Memory leak in error path could cause + "mpctx->allocated == 0" failure. [RT #584] + + 639. [bug] Reading entropy from the keyboard would sometimes fail. + [RT #591] + + 638. [port] lib/isc/random.c needed to explicitly include time.h + to get a prototype for time() when pthreads was not + being used. [RT #592] + + 637. [port] Use isc_u?int64_t instead of (unsigned) long long in + lib/isc/print.c. Also allow lib/isc/print.c to + be compiled even if the platform does not need it. + [RT #592] + + 636. [port] Shut up MSVC++ about a possible loss of precision + in the ISC__BUFFER_PUTUINT*() macros. [RT #592] + + 635. [bug] Reloading a server with a configured blackhole list + would cause an assertion. [RT #590] + + 634. [bug] A log file will completely stop being written when + it reaches the maximum size in all cases, not just + when versioning is also enabled. [RT #570] + + 633. [port] Cope with rlim_t missing on BSD/OS systems. [RT #575] + + 632. [bug] The index array of the journal file was + corrupted as it was written to disk. + + 631. [port] Build without thread support on systems without + pthreads. + + 630. [bug] Locking failure in zone code. [RT #582] + + 629. [bug] 9.1.0b1 dereferenced a null pointer and crashed + when responding to a UDP IXFR request. + + 628. [bug] If the root hints contained only AAAA addresses, + named would be unable to perform resolution. + + 627. [bug] The EDNS0 blackhole detection code of change 324 + waited for three retransmissions to each server, + which takes much too long when a domain has many + name servers and all of them drop EDNS0 queries. + Now we retry without EDNS0 after three consecutive + timeouts, even if they are all from different + servers. [RT #143] + + 626. [bug] The lightweight resolver daemon no longer crashes + when asked for a SIG rrset. [RT #558] + + 625. [func] Zones now inherit their class from the enclosing view. + + 624. [bug] The zone object could get timer events after it had + been destroyed, causing a server crash. [RT #571] + + 623. [func] Added "named-checkconf" and "named-checkzone" program + for syntax checking named.conf files and zone files, + respectively. + + 622. [bug] A canceled request could be destroyed before + dns_request_destroy() was called. [RT #562] + + 621. [port] Disable IPv6 at runtime if IPv6 sockets are unusable. + This mostly affects Red Hat Linux 7.0, which has + conflicts between libc and the kernel. + + 620. [bug] dns_master_load*inc() now require 'task' and 'load' + to be non-null. Also 'done' will not be called if + dns_master_load*inc() fails immediately. [RT #565] + + 619. [placeholder] + + 618. [bug] Queries to a signed zone could sometimes cause + an assertion failure. + + 617. [bug] When using dynamic update to add a new RR to an + existing RRset with a different TTL, the journal + entries generated from the update did not include + explicit deletions and re-additions of the existing + RRs to update their TTL to the new value. + + 616. [func] dnssec-signzone -t output now includes performance + statistics. + + 615. [bug] dnssec-signzone did not like child keysets signed + by multiple keys. + + 614. [bug] Checks for uninitialized link fields were prone + to false positives, causing assertion failures. + The checks are now disabled by default and may + be re-enabled by defining ISC_LIST_CHECKINIT. + + 613. [bug] "rndc reload zone" now reloads primary zones. + It previously only updated slave and stub zones, + if an SOA query indicated an out of date serial. + + 612. [cleanup] Shutup a ridiculously noisy HP-UX compiler that + complains relentlessly about how its treatment + of 'const' has changed as well as how casting + sometimes tightens alignment constraints. + + 611. [func] allow-notify can be used to permit processing of + notify messages from hosts other than a slave's + masters. + + 610. [func] rndc dumpdb is now supported. + + 609. [bug] getrrsetbyname() would crash lwresd if the server + found more SIGs than answers. [RT #554] + + 608. [func] dnssec-signzone now adds a comment to the zone + with the time the file was signed. + + 607. [bug] nsupdate would fail if it encountered a CNAME or + DNAME in a response to an SOA query. [RT #515] + + 606. [bug] Compiling with --disable-threads failed due + to isc_thread_self() being incorrectly defined + as an integer rather than a function. + + 605. [func] New function isc_lex_getlasttokentext(). + + 604. [bug] The named.conf parser could print incorrect line + numbers when long comments were present. + + 603. [bug] Make dig handle multiple types or classes on the same + query more correctly. + + 602. [func] Cope automatically with UnixWare's broken + IN6_IS_ADDR_* macros. [RT #539] + + 601. [func] Return a non-zero exit code if an update fails + in nsupdate. + + 600. [bug] Reverse lookups sometimes failed in dig, etc... + + 599. [func] Added four new functions to the libisc log API to + support i18n messages. isc_log_iwrite(), + isc_log_ivwrite(), isc_log_iwrite1() and + isc_log_ivwrite1() were added. + + 598. [bug] An update-policy statement would cause the server + to assert while loading. [RT #536] + + 597. [func] dnssec-signzone is now multi-threaded. + + 596. [bug] DNS_RDATASLAB_FORCE and DNS_RDATASLAB_EXACT are + not mutually exclusive. + + 595. [port] On Linux 2.2, socket() returns EINVAL when it + should return EAFNOSUPPORT. Work around this. + [RT #531] + + 594. [func] sdb drivers are now assumed to not be thread-safe + unless the DNS_SDBFLAG_THREADSAFE flag is supplied. + + 593. [bug] If a secure zone was missing all its NXTs and + a dynamic update was attempted, the server entered + an infinite loop. + + 592. [bug] The sig-validity-interval option now specifies a + number of days, not seconds. This matches the + documentation. [RT #529] + + --- 9.1.0b1 released --- + + 591. [bug] Work around non-reentrancy in openssl by disabling + precomputation in keys. + + 590. [doc] There are now man pages for the lwres library in + doc/man/lwres. + + 589. [bug] The server could deadlock if a zone was updated + while being transferred out. + + 588. [bug] ctx->in_use was not being correctly initialized when + when pushing a file for $INCLUDE. [RT #523] + + 587. [func] A warning is now printed if the "allow-update" + option allows updates based on the source IP + address, to alert users to the fact that this + is insecure and becoming increasingly so as + servers capable of update forwarding are being + deployed. + + 586. [bug] multiple views with the same name were fatal. [RT #516] + + 585. [func] dns_db_addrdataset() and and dns_rdataslab_merge() + now support 'exact' additions in a similar manner to + dns_db_subtractrdataset() and dns_rdataslab_subtract(). + + 584. [func] You can now say 'notify explicit'; to suppress + notification of the servers listed in NS records + and notify only those servers listed in the + 'also-notify' option. + + 583. [func] "rndc querylog" will now toggle logging of + queries, like "ndc querylog" in BIND 8. + + 582. [bug] dns_zone_idetach() failed to lock the zone. + [RT #199, #463] + + 581. [bug] log severity was not being correctly processed. + [RT #485] + + 580. [func] Ignore trailing garbage on incoming DNS packets, + for interoperability with broken server + implementations. [RT #491] + + 579. [bug] nsupdate did not take a filename to read update from. + [RT #492] + + 578. [func] New config option "notify-source", to specify the + source address for notify messages. + + 577. [func] Log illegal RDATA combinations. e.g. multiple + singlton types, cname and other data. + + 576. [doc] isc_log_create() description did not match reality. + + 575. [bug] isc_log_create() was not setting internal state + correctly to reflect the default channels created. + + 574. [bug] TSIG signed queries sent by the resolver would fail to + have their responses validated and would leak memory. + + 573. [bug] The journal files of IXFRed slave zones were + inadvertantly discarded on server reload, causing + "journal out of sync with zone" errors on subsequent + reloads. [RT #482] + + 572. [bug] Quoted strings were not accepted as key names in + address match lists. + + 571. [bug] It was possible to create an rdataset of singleton + type which had more than one rdata. [RT #154] + [RT #279] + + 570. [bug] rbtdb.c allowed zones containing nodes which had + both a CNAME and "other data". [RT #154] + + 569. [func] The DNSSEC AD bit will not be set on queries which + have not requested a DNSSEC response. + + 568. [func] Add sample simple database drivers in contrib/sdb. + + 567. [bug] Setting the zone transfer timeout to zero caused an + assertion failure. [RT #302] + + 566. [func] New public function dns_timer_setidle(). + + 565. [func] Log queries more like BIND 8: query logging is now + done to category "queries", level "info". [RT #169] + + 564. [func] Add sortlist support to lwresd. + + 563. [func] New public functions dns_rdatatype_format() and + dns_rdataclass_format(), for convenient formatting + of rdata type/class mnemonics in log messages. + + 562. [cleanup] Moved lib/dns/*conf.c to bin/named where they belong. + + 561. [func] The 'datasize', 'stacksize', 'coresize' and 'files' + clauses of the options{} statement are now implemented. + + 560. [bug] dns_name_split did not properly the resulting prefix + when a maximal length bitstring label was split which + was preceded by another bitstring label. [RT #429] + + 559. [bug] dns_name_split did not properly create the suffix + when splitting within a maximal length bitstring label. + + 558. [func] New functions, isc_resource_getlimit and + isc_resource_setlimit. + + 557. [func] Symbolic constants for libisc integral types. + + 556. [func] The DNSSEC OK bit in the EDNS extended flags + is now implemented. Responses to queries without + this bit set will not contain any DNSSEC records. + + 555. [bug] A slave server attempting a zone transfer could + crash with an assertion failure on certain + malformed responses from the master. [RT #457] + + 554. [bug] In some cases, not all of the dnssec tools were + properly installed. + + 553. [bug] Incoming zone transfers deferred due to quota + were not started when quota was increased but + only when a transfer in progress finished. [RT #456] + + 552. [bug] We were not correctly detecting the end of all c-style + comments. [RT #455] + + 551. [func] Implemented the 'sortlist' option. + + 550. [func] Support unknown rdata types and classes. + + 549. [bug] "make" did not immediately abort the build when a + subdirectory make failed [RT #450]. + + 548. [func] The lexer now ungets tokens more correctly. + + 547. [placeholder] + + 546. [func] Option 'lame-ttl' is now implemented. + + 545. [func] Name limit and counting options removed from dig; + they didn't work properly, and cannot be correctly + implemented without significant changes. + + 544. [func] Add statistics option, enable statistics-file option, + add RNDC option "dump-statistics" to write out a + query statistics file. + + 543. [doc] The 'port' option is now documented. + + 542. [func] Add support for update forwarding as required for + full compliance with RFC2136. It is turned off + by default and can be enabled using the + 'allow-update-forwarding' option. + + 541. [func] Add bogus server support. + + 540. [func] Add dialup support. + + 539. [func] Support the blackhole option. + + 538. [bug] fix buffer overruns by 1 in lwres_getnameinfo(). + + 537. [placeholder] + + 536. [func] Use transfer-source{-v6} when sending refresh queries. + Transfer-source{-v6} now take a optional port + parameter for setting the UDP source port. The port + parameter is ignored for TCP. + + 535. [func] Use transfer-source{-v6} when forwarding update + requests. + + 534. [func] Ancestors have been removed from RBT chains. Ancestor + information can be discerned via node parent pointers. + + 533. [func] Incorporated name hashing into the RBT database to + improve search speed. + + 532. [func] Implement DNS UPDATE pseudo records using + DNS_RDATA_UPDATE flag. + + 531. [func] Rdata really should be initialized before being assigned + to (dns_rdata_fromwire(), dns_rdata_fromtext(), + dns_rdata_clone(), dns_rdata_fromregion()), + check that it is. + + 530. [func] New function dns_rdata_invalidate(). + + 529. [bug] 521 contained a bug which caused zones to always + reload. [RT #410] + + 528. [func] The ISC_LIST_XXXX macros now perform sanity checks + on their arguments. ISC_LIST_XXXXUNSAFE can be use + to skip the checks however use with caution. + + 527. [func] New function dns_rdata_clone(). + + 526. [bug] nsupdate incorrectly refused to add RRs with a TTL + of 0. + + 525. [func] New arguments 'options' for dns_db_subtractrdataset(), + and 'flags' for dns_rdataslab_subtract() allowing you + to request that the RR's must exist prior to deletion. + DNS_R_NOTEXACT is returned if the condition is not met. + + 524. [func] The 'forward' and 'forwarders' statement in + non-forward zones should work now. + + 523. [doc] The source to the Administrator Reference Manual is + now an XML file using the DocBook DTD, and is included + in the distribution. The plain text version of the + ARM is temporarily unavailable while we figure out + how to generate readable plain text from the XML. + + 522. [func] The lightweight resolver daemon can now use + a real configuration file, and its functionality + can be provided by a name server. Also, the -p and -P + options to lwresd have been reversed. + + 521. [bug] Detect master files which contain $INCLUDE and always + reload. [RT #196] + + 520. [bug] Upgraded libtool to 1.3.5, which makes shared + library builds almost work on AIX (and possibly + others). + + 519. [bug] dns_name_split() would improperly split some bitstring + labels, zeroing a few of the least signficant bits in + the prefix part. When such an improperly created + prefix was returned to the RBT database, the bogus + label was dutifully stored, corrupting the tree. + [RT #369] + + 518. [bug] The resolver did not realize that a DNAME which was + "the answer" to the client's query was "the answer", + and such queries would fail. [RT #399] + + 517. [bug] The resolver's DNAME code would trigger an assertion + if there was more than one DNAME in the chain. + [RT #399] + + 516. [bug] Cache lookups which had a NULL node pointer, e.g. + those by dns_view_find(), and which would match a + DNAME, would trigger an INSIST(!search.need_cleanup) + assertion. [RT #399] + + 515. [bug] The ssu table was not being attached / detached + by dns_zone_[sg]etssutable. [RT#397] + + 514. [func] Retry refresh and notify queries if they timeout. + [RT #388] + + 513. [func] New functionality added to rdnc and server to allow + individual zones to be refreshed or reloaded. + + 512. [bug] The zone transfer code could throw an execption with + an invalid IXFR stream. + + 511. [bug] The message code could throw an assertion on an + out of memory failure. [RT #392] + + 510. [bug] Remove spurious view notify warning. [RT #376] + + 509. [func] Add support for write of zone files on shutdown. + + 508. [func] dns_message_parse() can now do a best-effort + attempt, which should allow dig to print more invalid + messages. + + 507. [func] New functions dns_zone_flush(), dns_zt_flushanddetach() + and dns_view_flushanddetach(). + + 506. [func] Do not fail to start on errors in zone files. + + 505. [bug] nsupdate was printing "unknown result code". [RT #373] + + 504. [bug] The zone was not being marked as dirty when updated via + IXFR. + + 503. [bug] dumptime was not being set along with + DNS_ZONEFLG_NEEDDUMP. + + 502. [func] On a SERVFAIL reply, DiG will now try the next server + in the list, unless the +fail option is specified. + + 501. [bug] Incorrect port numbers were being displayed by + nslookup. [RT #352] + + 500. [func] Nearly useless +details option removed from DiG. + + 499. [func] In DiG, specifying a class with -c or type with -t + changes command-line parsing so that classes and + types are only recognized if following -c or -t. + This allows hosts with the same name as a class or + type to be looked up. + + 498. [doc] There is now a man page for "dig" + in doc/man/bin/dig.1. + + 497. [bug] The error messages printed when an IP match list + contained a network address with a nonzero host + part where not sufficiently detailed. [RT #365] + + 496. [bug] named didn't sanity check numeric parameters. [RT #361] + + 495. [bug] nsupdate was unable to handle large records. [RT #368] + + 494. [func] Do not cache NXDOMAIN responses for SOA queries. + + 493. [func] Return non-cachable (ttl = 0) NXDOMAIN responses + for SOA queries. This makes it easier to locate + the containing zone without polluting intermediate + caches. + + 492. [bug] attempting to reload a zone caused the server fail + to shutdown cleanly. [RT #360] + + 491. [bug] nsupdate would segfault when sending certain + prerequisites with empty RDATA. [RT #356] + + 490. [func] When a slave/stub zone has not yet successfully + obtained an SOA containing the zone's configured + retry time, perform the SOA query retries using + exponential backoff. [RT #337] + + 489. [func] The zone manager now has a "i/o" queue. + + 488. [bug] Locks weren't properly destroyed in some cases. + + 487. [port] flockfile() is not defined on all systems. + + 486. [bug] nslookup: "set all" and "server" commands showed + the incorrect port number if a port other than 53 + was specified. [RT #352] + + 485. [func] When dig had more than one server to query, it would + send all of the messages at the same time. Add + rate limiting of the transmitted messages. + + 484. [bug] When the server was reloaded after removing addresses + from the named.conf "listen-on" statement, sockets + were still listening on the removed addresses due + to reference count loops. [RT #325] + + 483. [bug] nslookup: "set all" showed a "search" option but it + was not settable. + + 482. [bug] nslookup: a plain "server" or "lserver" should be + treated as a lookup. + + 481. [bug] nslookup:get_next_command() stack size could exceed + per thread limit. + + 480. [bug] strtok() is not thread safe. [RT #349] + + 479. [func] The test suite can now be run by typing "make check" + or "make test" at the top level. + + 478. [bug] "make install" failed if the directory specified with + --prefix did not already exist. + + 477. [bug] The the isc-config.sh script could be installed before + its directory was created. [RT #324] + + 476. [bug] A zone could expire while a zone transfer was in + progress triggering a INSIST failure. [RT #329] + + 475. [bug] query_getzonedb() sometimes returned a non-null version + on failure. This caused assertion failures when + generating query responses where names subject to + additional section processing pointed to a zone + to which access had been denied by means of the + allow-query option. [RT #336] + + 474. [bug] The mnemonic of the CHAOS class is CH according to + RFC1035, but it was printed and read only as CHAOS. + We now accept both forms as input, and print it + as CH. [RT #305] + + 473. [bug] nsupdate overran the end of the list of name servers + when no servers could be reached, typically causing + it to print the error message "dns_request_create: + not implemented". + + 472. [bug] Off-by-one error caused isc_time_add() to sometimes + produce invalid time values. + + 471. [bug] nsupdate didn't compile on HP/UX 10.20 + + 470. [func] $GENERATE is now supported. See also + doc/misc/migration. + + 469. [bug] "query-source address * port 53;" now works. + + 468. [bug] dns_master_load*() failed to report file and line + number in certain error conditions. + + 467. [bug] dns_master_load*() failed to log an error if + pushfile() failed. + + 466. [bug] dns_master_load*() could return success when it failed. + + 465. [cleanup] Allow 0 to be set as an omapi_value_t value by + omapi_value_storeint(). + + 464. [cleanup] Build with openssl's RSA code instead of dnssafe. + + 463. [bug] nsupdate sent malformed SOA queries to the second + and subsequent name servers in resolv.conf if the + query sent to the first one failed. + + 462. [bug] --disable-ipv6 should work now. + + 461. [bug] Specifying an unknown key in the "keys" clause of the + "controls" statement caused a NULL pointer dereference. + [RT #316] + + 460. [bug] Much of the DNSSEC code only worked with class IN. + + 459. [bug] Nslookup processed the "set" command incorrectly. + + 458. [bug] Nslookup didn't properly check class and type values. + [RT #305] + + 457. [bug] Dig/host/hslookup didn't properly handle connect + timeouts in certain situations, causing an + unnecessary warning message to be printed. + + 456. [bug] Stub zones were not resetting the refresh and expire + counters, loadtime or clearing the DNS_ZONE_REFRESH + (refresh in progress) flag upon successful update. + This disabled further refreshing of the stub zone, + causing it to eventually expire. [RT #300] + + 455. [doc] Document IPv4 prefix notation does not require a + dotted decimal quad but may be just dotted decimal. + + 454. [bug] Enforce dotted decimal and dotted decimal quad where + documented as such in named.conf. [RT #304, RT #311] + + 453. [bug] Warn if the obsolete option "maintain-ixfr-base" + is specified in named.conf. [RT #306] + + 452. [bug] Warn if the unimplemented option "statistics-file" + is specified in named.conf. [RT #301] + + 451. [func] Update forwarding implememted. + + 450. [func] New function ns_client_sendraw(). + + 449. [bug] isc_bitstring_copy() only works correctly if the + two bitstrings have the same lsb0 value, but this + requirement was not documented, nor was there a + REQUIRE for it. + + 448. [bug] Host output formatting change, to match v8. [RT #255] + + 447. [bug] Dig didn't properly retry in TCP mode after + a truncated reply. [RT #277] + + 446. [bug] Confusing notify log message. [RT #298] + + 445. [bug] Doing a 0 bit isc_bitstring_copy() of an lsb0 + bitstring triggered a REQUIRE statement. The REQUIRE + statement was incorrect. [RT #297] + + 444. [func] "recursion denied" messages are always logged at + debug level 1, now, rather than sometimes at ERROR. + This silences these warnings in the usual case, where + some clients set the RD bit in all queries. + + 443. [bug] When loading a master file failed because of an + unrecognized RR type name, the error message + did not include the file name and line number. + [RT #285] + + 442. [bug] TSIG signed messages that did not match any view + crashed the server. [RT #290] + + 441. [bug] Nodes obscured by a DNAME were inaccessible even + when DNS_DBFIND_GLUEOK was set. + + 440. [func] New function dns_zone_forwardupdate(). + + 439. [func] New function dns_request_createraw(). + + 438. [func] New function dns_message_getrawmessage(). + + 437. [func] Log NOTIFY activity to the notify channel. + + 436. [bug] If recvmsg() returned EHOSTUNREACH or ENETUNREACH, + which sometimes happens on Linux, named would enter + a busy loop. Also, unexpected socket errors were + not logged at a high enough logging level to be + useful in diagnosing this situation. [RT #275] + + 435. [bug] dns_zone_dump() overwrote existing zone files + rather than writing to a temporary file and + renaming. This could lead to empty or partial + zone files being left around in certain error + conditions involving the initial transfer of a + slave zone, interfering with subsequent server + startup. [RT #282] + + 434. [func] New function isc_file_isabsolute(). + + 433. [func] isc_base64_decodestring() now accepts newlines + within the base64 data. This makes it possible + to break up the key data in a "trusted-keys" + statement into multiple lines. [RT #284] + + 432. [func] Added refresh/retry jitter. The actual refresh/ + retry time is now a random value between 75% and + 100% of the configured value. + + 431. [func] Log at ISC_LOG_INFO when a zone is successfully + loaded. + + 430. [bug] Rewrote the lightweight resolver client management + code to handle shutdown correctly and general + cleanup. + + 429. [bug] The space reserved for a TSIG record in a response + was 2 bytes too short, leading to message + generation failures. + + 428. [bug] rbtdb.c:find_closest_nxt() erroneously returned + DNS_R_BADDB for nodes which had neither NXT nor SIG NXT + (e.g. glue). This could cause SERVFAILs when + generating negative responses in a secure zone. + + 427. [bug] Avoid going into an infinite loop when the validator + gets a negative response to a key query where the + records are signed by the missing key. + + 426. [bug] Attempting to generate an oversized RSA key could + cause dnssec-keygen to dump core. + + 425. [bug] Warn about the auth-nxdomain default value change + if there is no auth-nxdomain statement in the + config file. [RT #287] + + 424. [bug] notify_createmessage() could trigger an assertion + failure when creating the notify message failed, + e.g. due to corrupt zones with multiple SOA records. + [RT #279] + + 423. [bug] When responding to a recusive query, errors that occur + after following a CNAME should cause the query to fail. + [RT #274] + + 422. [func] get rid of isc_random_t, and make isc_random_get() + and isc_random_jitter() use rand() internally + instead of local state. Note that isc_random_*() + functions are only for weak, non-critical "randomness" + such as timing jitter and such. + + 421. [bug] nslookup would exit when given a blank line as input. + + 420. [bug] nslookup failed to implement the "exit" command. + + 419. [bug] The certificate type PKIX was misspelled as SKIX. + + 418. [bug] At debug levels >= 10, getting an unexpected + socket receive error would crash the server + while trying to log the error message. + + 417. [func] Add isc_app_block() and isc_app_unblock(), which + allow an application to handle signals while + blocking. + + 416. [bug] Slave zones with no master file tried to use a + NULL pointer for a journal file name when they + received an IXFR. [RT #273] + + 415. [bug] The logging code leaked file descriptors. + + 414. [bug] Server did not shut down until all incoming zone + transfers were finished. + + 413. [bug] Notify could attempt to use the zone database after + it had been unloaded. [RT#267] + + 412. [bug] named -v didn't print the version. + + 411. [bug] A typo in the HS A code caused an assertion failure. + + 410. [bug] lwres_gethostbyname() and company set lwres_h_errno + to a random value on success. + + 409. [bug] If named was shut down early in the startup + process, ns_omapi_shutdown() would attempt to lock + an unintialized mutex. [RT #262] + + 408. [bug] stub zones could leak memory and reference counts if + all the masters were unreachable. + + 407. [bug] isc_rwlock_lock() would needlessly block + readers when it reached the read quota even + if no writers were waiting. + + 406. [bug] Log messages were occasionally lost or corrupted + due to a race condition in isc_log_doit(). + + 405. [func] Add support for selective forwarding (forward zones) + + 404. [bug] The request library didn't completely work with IPv6. + + 403. [bug] "host" did not use the search list. + + 402. [bug] Treat undefined acls as errors, rather than + warning and then later throwing an assertion. + [RT #252] + + 401. [func] Added simple database API. + + 400. [bug] SIG(0) signing and verifying was done incorrectly. + [RT #249] + + 399. [bug] When reloading the server with a config file + containing a syntax error, it could catch an + assertion failure trying to perform zone + maintenance on, or sending notifies from, + tentatively created zones whose views were + never fully configured and lacked an address + database and request manager. + + 398. [bug] "dig" sometimes caught an assertion failure when + using TSIG, depending on the key length. + + 397. [func] Added utility functions dns_view_gettsig() and + dns_view_getpeertsig(). + + 396. [doc] There is now a man page for "nsupdate" + in doc/man/bin/nsupdate.8. + + 395. [bug] nslookup printed incorrect RR type mnemonics + for RRs of type >= 21 [RT #237]. + + 394. [bug] Current name was not propagated via $INCLUDE. + + 393. [func] Initial answer while loading (awl) support. + Entry points: dns_master_loadfileinc(), + dns_master_loadstreaminc(), dns_master_loadbufferinc(). + Note: calls to dns_master_load*inc() should be rate + be rate limited so as to not use up all file + descriptors. + + 392. [func] Add ISC_R_FAMILYNOSUPPORT. Returned when OS does + not support the given address family requested. + + 391. [clarity] ISC_R_FAMILY -> ISC_R_FAMILYMISMATCH. + + 390. [func] The function dns_zone_setdbtype() now takes + an argc/argv style vector of words and sets + both the zone database type and its arguments, + making the functions dns_zone_adddbarg() + and dns_zone_cleardbargs() unnecessary. + + 389. [bug] Attempting to send a reqeust over IPv6 using + dns_request_create() on a system without IPv6 + support caused an assertion failure [RT #235]. + + 388. [func] dig and host can now do reverse ipv6 lookups. + + 387. [func] Add dns_byaddr_createptrname(), which converts + an address into the name used by a PTR query. + + 386. [bug] Missing strdup() of ACL name caused random + ACL matching failures [RT #228]. + + 385. [cleanup] Removed functions dns_zone_equal(), dns_zone_print(), + and dns_zt_print(). + + 384. [bug] nsupdate was incorrectly limiting TTLs to 65535 instead + of 2147483647. + + 383. [func] When writing a master file, print the SOA and NS + records (and their SIGs) before other records. + + 382. [bug] named -u failed on many Linux systems where the + libc provided kernel headers do not match + the current kernel. + + 381. [bug] Check for IPV6_RECVPKTINFO and use it instead of + IPV6_PKTINFO if found. [RT #229] + + 380. [bug] nsupdate didn't work with IPv6. + + 379. [func] New library function isc_sockaddr_anyofpf(). + + 378. [func] named and lwresd will log the command line arguments + they were started with in the "starting ..." message. + + 377. [bug] When additional data lookups were refused due to + "allow-query", the databases were still being + attached causing reference leaks. + + 376. [bug] The server should always use good entropy when + performing cryptographic functions needing entropy. + + 375. [bug] Per-zone "allow-query" did not properly override the + view/global one for CNAME targets and additional + data [RT #220]. + + 374. [bug] SOA in authoritative negative responses had wrong TTL. + + 373. [func] nslookup is now installed by "make install". + + 372. [bug] Deal with Microsoft DNS servers appending two bytes of + garbage to zone transfer requests. + + 371. [bug] At high debug levels, doing an outgoing zone transfer + of a very large RRset could cause an assertion failure + during logging. + + 370. [bug] The error messages for rollforward failures were + overly terse. + + 369. [func] Support new named.conf options, view and zone + statements: + + max-retry-time, min-retry-time, + max-refresh-time, min-refresh-time. + + 368. [func] Restructure the internal ".bind" view so that more + zones can be added to it. + + 367. [bug] Allow proper selection of server on nslookup command + line. + + 366. [func] Allow use of '-' batch file in dig for stdin. + + 365. [bug] nsupdate -k leaked memory. + + 364. [func] Added additional-from-{cache,auth} + + 363. [placeholder] + + 362. [bug] rndc no longer aborts if the configuration file is + missing an options statement. [RT #209] + + 361. [func] When the RBT find or chain functions set the name and + origin for a node that stores the root label + the name is now set to an empty name, instead of ".", + to simplify later use of the name and origin by + dns_name_concatenate(), dns_name_totext() or + dns_name_format(). + + 360. [func] dns_name_totext() and dns_name_format() now allow + an empty name to be passed, which is formatted as "@". + + 359. [bug] dnssec-signzone occasionally signed glue records. + + 358. [cleanup] Rename the intermediate files used by the dnssec + programs. + + 357. [bug] The zone file parser crashed if the argument + to $INCLUDE was a quoted string. + + 356. [cleanup] isc_task_send no longer requires event->sender to + be non-null. + + 355. [func] Added isc_dir_createunique(), similar to mkdtemp(). + + 354. [doc] Man pages for the dnssec tools are now included in + the distribution, in doc/man/dnssec. + + 353. [bug] double increment in lwres/gethost.c:copytobuf(). + [RT# 187] + + 352. [bug] Race condition in dns_client_t startup could cause + an assertion failure. + + 351. [bug] Constructing a response with rcode SERVFAIL to a TSIG + signed query could crash the server. + + 350. [bug] Also-notify lists specified in the global options + block were not correctly reference counted, causing + a memory leak. + + 349. [bug] Processing a query with the CD bit set now works + as expected. + + 348. [func] New boolean named.conf options 'additional-from-auth' + and 'additional-from-cache' now supported in view and + global options statement. + + 347. [bug] Don't crash if an argument is left off options in dig. + + 346. [placeholder] + + 345. [bug] Large-scale changes/cleanups to dig: + * Significantly improve structure handling + * Don't pre-load entire batch files + * Add name/rr counting/limiting + * Fix SIGINT handling + * Shorten timeouts to match v8's behavior + + 344. [bug] When shutting down, lwresd sometimes tried + to shut down its client tasks twice, + triggering an assertion. + + 343. [bug] Although zone maintenance SOA queries and + notify requests were signed with TSIG keys + when configured for the server in case, + the TSIG was not verified on the response. + + 342. [bug] The wrong name was being passed to + dns_name_dup() when generating a TSIG + key using TKEY. + + 341. [func] Support 'key' clause in named.conf zone masters + statement to allow authentication via TSIG keys: + + masters { + 10.0.0.1 port 5353 key "foo"; + 10.0.0.2 ; + }; + + 340. [bug] The top-level COPYRIGHT file was missing from + the distribution. + + 339. [bug] DNSSEC validation of the response to an ANY + query at a name with a CNAME RR in a secure + zone triggered an assertion failure. + + 338. [bug] lwresd logged to syslog as named, not lwresd. + + 337. [bug] "dig" did not recognize "nsap-ptr" as an RR type + on the command line. + + 336. [bug] "dig -f" used 64 k of memory for each line in + the file. It now uses much less, though still + proportionally to the file size. + + 335. [bug] named would occasionally attempt recursion when + it was disallowed or undesired. + + 334. [func] Added hmac-md5 to libisc. + + 333. [bug] The resolver incorrectly accepted referrals to + domains that were not parents of the query name, + causing assertion failures. + + 332. [func] New function dns_name_reset(). + + 331. [bug] Only log "recursion denied" if RD is set. [RT #178] + + 330. [bug] Many debugging messages were partially formatted + even when debugging was turned off, causing a + significant decrease in query performance. + + 329. [func] omapi_auth_register() now takes a size_t argument for + the length of a key's secret data. Previously + OMAPI only stored secrets up to the first NUL byte. + + 328. [func] Added isc_base64_decodestring(). + + 327. [bug] rndc.conf parser wasn't correctly recognising an IP + address where a host specification was required. + + 326. [func] 'keys' in an 'inet' control statement is now + required and must have at least one item in it. + A "not supported" warning is now issued if a 'unix' + control channel is defined. + + 325. [bug] isc_lex_gettoken was processing octal strings when + ISC_LEXOPT_CNUMBER was not set. + + 324. [func] In the resolver, turn EDNS0 off if there is no + response after a number of retransmissions. + This is to allow queries some chance of succeeding + even if all the authoritative servers of a zone + silently discard EDNS0 requests instead of + sending an error response like they ought to. + + 323. [bug] dns_rbt_findname() did not ignore empty rbt nodes. + Because of this, servers authoritative for a parent + and grandchild zone but not authoritative for the + intervening child zone did not correctly issue + referrals to the servers of the child zone. + + 322. [bug] Queries for KEY RRs are now sent to the parent + server before the authoritative one, making + DNSSEC insecurity proofs work in many cases + where they previously didn't. + + 321. [bug] When synthesizing a CNAME RR for a DNAME + response, query_addcname() failed to intitialize + the type and class of the CNAME dns_rdata_t, + causing random failures. + + 320. [func] Multiple rndc changes: parses an rndc.conf file, + uses authentication to talk to named, command + line syntax changed. This will all be described + in the ARM. + + 319. [func] The named.conf "controls" statement is now used + to configure the OMAPI command channel. + + 318. [func] dns_c_ndcctx_destroy() could never return anything + except ISC_R_SUCCESS; made it have void return instead. + + 317. [func] Use callbacks from libomapi to determine if a + new connection is valid, and if a key requested + to be used with that connection is valid. + + 316. [bug] Generate a warning if we detect an unexpected + but treat as . + + 315. [bug] Handle non-empty blanks lines. [RT #163] + + 314. [func] The named.conf controls statement can now have + more than one key specified for the inet clause. + + 313. [bug] When parsing resolv.conf, don't terminate on an + error. Instead, parse as much as possible, but + still return an error if one was found. + + 312. [bug] Increase the number of allowed elements in the + resolv.conf search path from 6 to 8. If there + are more than this, ignore the remainder rather + than returning a failure in lwres_conf_parse. + + 311. [bug] lwres_conf_parse failed when the first line of + resolv.conf was empty or a comment. + + 310. [func] Changes to named.conf "controls" statement (inet + subtype only) + + - support "keys" clause + + controls { + inet * port 1024 + allow { any; } keys { "foo"; } + } + + - allow "port xxx" to be left out of statement, + in which case it defaults to omapi's default port + of 953. + + 309. [bug] When sending a referral, the server did not look + for name server addresses as glue in the zone + holding the NS RRset in the case where this zone + was not the same as the one where it looked for + name server addresses as authoritative data. + + 308. [bug] Treat a SOA record not at top of zone as an error + when loading a zone. [RT #154] + + 307. [bug] When canceling a query, the resolver didn't check for + isc_socket_sendto() calls that did not yet have their + completion events posted, so it could (rarely) end up + destroying the query context and then want to use + it again when the send event posted, triggering an + assertion as it tried to cancel an already-canceled + query. [RT #77] + + 306. [bug] Reading HMAC-MD5 private key files didn't work. + + 305. [bug] When reloading the server with a config file + containing a syntax error, it could catch an + assertion failure trying to perform zone + maintenance on tentatively created zones whose + views were never fully configured and lacked + an address database. + + 304. [bug] If more than LWRES_CONFMAXNAMESERVERS servers + are listed in resolv.conf, silently ignore them + instead of returning failure. + + 303. [bug] Add additional sanity checks to differentiate a AXFR + response vs a IXFR response. [RT #157] + + 302. [bug] In dig, host, and nslookup, MXNAME should be large + enough to hold any legal domain name in presentation + format + terminating NULL. + + 301. [bug] Uninitialized pointer in host:printmessage(). [RT #159] + + 300. [bug] Using both and didn't work + on platforms lacking IPv6 because each included their + own ipv6 header file for the missing definitions. Now + each library's ipv6.h defines the wrapper symbol of + the other (ISC_IPV6_H and LWRES_IPV6_H). + + 299. [cleanup] Get the user and group information before changing the + root directory, so the administrator does not need to + keep a copy of the user and group databases in the + chroot'ed environment. Suggested by Hakan Olsson. + + 298. [bug] A mutex deadlock occurred during shutdown of the + interface manager under certain conditions. + Digital Unix systems were the most affected. + + 297. [bug] Specifying a key name that wasn't fully qualified + in certain parts of the config file could cause + an assertion failure. + + 296. [bug] "make install" from a separate build directory + failed unless configure had been run in the source + directory, too. + + 295. [bug] When invoked with type==CNAME and a message + not constructed by dns_message_parse(), + dns_message_findname() failed to find anything + due to checking for attribute bits that are set + only in dns_message_parse(). This caused an + infinite loop when constructing the response to + an ANY query at a CNAME in a secure zone. + + 294. [bug] If we run out of space in while processing glue + when reading a master file and commit "current name" + reverts to "name_current" instead of staying as + "name_glue". + + 293. [port] Add support for FreeBSD 4.0 system tests. + + 292. [bug] Due to problems with the way some operating systems + handle simultaneous listening on IPv4 and IPv6 + addresses, the server no longer listens on IPv6 + addresses by default. To revert to the previous + behavior, specify "listen-on-v6 { any; };" in + the config file. + + 291. [func] Caching servers no longer send outgoing queries + over TCP just because the incoming recursive query + was a TCP one. + + 290. [cleanup] +twiddle option to dig (for testing only) removed. + + 289. [cleanup] dig is now installed in $bindir instead of $sbindir. + host is now installed in $bindir. (Be sure to remove + any $sbindir/dig from a previous release.) + + 288. [func] rndc is now installed by "make install" into $sbindir. + + 287. [bug] rndc now works again as "rndc 127.1 reload" (for + only that task). Parsing its configuration file and + using digital signatures for authentication has been + disabled until named supports the "controls" statement, + post-9.0.0. + + 286. [bug] On Solaris 2, when named inherited a signal state + where SIGHUP had the SIG_IGN action, SIGHUP would + be ignored rather than causing the server to reload + its configuration. + + 285. [bug] A change made to the dst API for beta4 inadvertently + broke OMAPI's creation of a dst key from an incoming + message, causing an assertion to be triggered. Fixed. + + 284. [func] The DNSSEC key generation and signing tools now + generate randomness from keyboard input on systems + that lack /dev/random. + + 283. [cleanup] The 'lwresd' program is now a link to 'named'. + + 282. [bug] The lexer now returns ISC_R_RANGE if parsed integer is + too big for an unsigned long. + + 281. [bug] Fixed list of recognized config file category names. + + 280. [func] Add isc-config.sh, which can be used to more + easily build applications that link with + our libraries. + + 279. [bug] Private omapi function symbols shared between + two or more files in libomapi.a were not namespace + protected using the ISC convention of starting with + the library name and two underscores ("omapi__"...) + + 278. [bug] bin/named/logconf.c:category_fromconf() didn't take + note of when isc_log_categorybyname() wasn't able + to find the category name and would then apply the + channel list of the unknown category to all categories. + + 277. [bug] isc_log_categorybyname() and isc_log_modulebyname() + would fail to find the first member of any category + or module array apart from the internal defaults. + Thus, for example, the "notify" category was improperly + configured by named. + + 276. [bug] dig now supports maximum sized TCP messages. + + 275. [bug] The definition of lwres_gai_strerror() was missing + the lwres_ prefix. + + 274. [bug] TSIG AXFR verify failed when talking to a BIND 8 + server. + + 273. [func] The default for the 'transfer-format' option is + now 'many-answers'. This will break zone transfers + to BIND 4.9.5 and older unless there is an explicit + 'one-answer' configuration. + + 272. [bug] The sending of large TCP responses was canceled + in mid-transmission due to a race condition + caused by the failure to set the client object's + "newstate" variable correctly when transitioning + to the "working" state. + + 271. [func] Attempt to probe the number of cpus in named + if unspecified rather than defaulting to 1. + + 270. [func] Allow maximum sized TCP answers. + + 269. [bug] Failed DNSSEC validations could cause an assertion + failure by causing clone_results() to be called with + with hevent->node == NULL. + + 268. [doc] A plain text version of the Administrator + Reference Manual is now included in the distribution, + as doc/arm/Bv9ARM.txt. + + 267. [func] Nsupdate is now provided in the distribution. + + 266. [bug] zone.c:save_nsrrset() node was not initialized. + + 265. [bug] dns_request_create() now works for TCP. + + 264. [func] Dispatch can not take TCP sockets in connecting + state. Set DNS_DISPATCHATTR_CONNECTED when calling + dns_dispatch_createtcp() for connected TCP sockets + or call dns_dispatch_starttcp() when the socket is + connected. + + 263. [func] New logging channel type 'stderr' + + channel some-name { + stderr; + severity error; + } + + 262. [bug] 'master' was not initialized in zone.c:stub_callback(). + + 261. [func] Add dns_zone_markdirty(). + + 260. [bug] Running named as a non-root user failed on Linux + kernels new enough to support retaining capabilities + after setuid(). + + 259. [func] New random-device and random-seed-file statements + for global options block of named.conf. Both accept + a single string argument. + + 258. [bug] Fixed printing of lwres_addr_t.address field. + + 257. [bug] The server detached the last zone manager reference + too early, while it could still be in use by queries. + This manifested itself as assertion failures during the + shutdown process for busy name servers. [RT #133] + + 256. [func] isc_ratelimiter_t now has attach/detach semantics, and + isc_ratelimiter_shutdown guarantees that the rate + limiter is detached from its task. + + 255. [func] New function dns_zonemgr_attach(). + + 254. [bug] Suppress "query denied" messages on additional data + lookups. + + --- 9.0.0b4 released --- + + 253. [func] resolv.conf parser now recognises ';' and '#' as + comments (anywhere in line, not just as the beginning). + + 252. [bug] resolv.conf parser mishandled masks on sortlists. + It also aborted when an unrecognized keyword was seen, + now it silently ignores the entire line. + + 251. [bug] lwresd caught an assertion failure on startup. + + 250. [bug] fixed handling of size+unit when value would be too + large for internal representation. + + 249. [cleanup] max-cache-size config option now takes a size-spec + like 'datasize', except 'default' is not allowed. + + 248. [bug] global lame-ttl option was not being printed when + config structures were written out. + + 247. [cleanup] Rename cache-size config option to max-cache-size. + + 246. [func] Rename global option cachesize to cache-size and + add corresponding option to view statement. + + 245. [bug] If an uncompressed name will take more than 255 + bytes and the buffer is sufficiently long, + dns_name_fromwire should return DNS_R_FORMERR, + not ISC_R_NOSPACE. This bug caused cause the + server to catch an assertion failure when it + received a query for a name longer than 255 + bytes. + + 244. [bug] empty named.conf file and empty options statement are + now parsed properly. + + 243. [func] new cachesize option for named.conf + + 242. [cleanup] fixed incorrect warning about auth-nxdomain usage. + + 241. [cleanup] nscount and soacount have been removed from the + dns_master_*() argument lists. + + 240. [func] databases now come in three flavours: zone, cache + and stub. + + 239. [func] If ISC_MEM_DEBUG is enabled, the variable + isc_mem_debugging controls whether messages + are printed or not. + + 238. [cleanup] A few more compilation warnings have been quieted: + + missing sigwait prototype on BSD/OS 4.0/4.0.1. + + PTHREAD_ONCE_INIT unbraced initializer warnings on + Solaris 2.8. + + IN6ADDR_ANY_INIT unbraced initializer warnings on + BSD/OS 4.*, Linux and Solaris 2.8. + + 237. [bug] If connect() returned ENOBUFS when the resolver was + initiating a TCP query, the socket didn't get + destroyed, and the server did not shut down cleanly. + + 236. [func] Added new listen-on-v6 config file statement. + + 235. [func] Consider it a config file error if a listen-on + statement has an IPv6 address in it, or a + listen-on-v6 statement has an IPv4 address in it. + + 234. [bug] Allow a trusted-key's first field (domain-name) be + either a quoted or an unquoted string, instead of + requiring a quoted string. + + 233. [cleanup] Convert all config structure integer values to unsigned + integer (isc_uint32_t) to match grammer. + + 232. [bug] Allow slave zones to not have a file. + + 231. [func] Support new 'port' clause in config file options + section. Causes 'listen-on', 'masters' and + 'also-notify' statements to use its value instead of + default (53). + + 230. [func] Replace the dst sign/verify API with a cleaner one. + + 229. [func] Support config file sig-validity-interval statement + in options, views and zone statements (master + zones only). + + 228. [cleanup] Logging messages in config module stripped of + trailing period. + + 227. [cleanup] The enumerated identifiers dns_rdataclass_*, + dns_rcode_*, dns_opcode_*, and dns_trust_* are + also now cast to their appropriate types, as with + dns_rdatatype_* in item number 225 below. + + 226. [func] dns_name_totext() now always prints the root name as + '.', even when omit_final_dot is true. + + 225. [cleanup] The enumerated dns_rdatatype_* identifiers are now + cast to dns_rdatatype_t via macros of their same name + so that they are of the proper integral type wherever + a dns_rdatatype_t is needed. + + 224. [cleanup] The entire project builds cleanly with gcc's + -Wcast-qual and -Wwrite-strings warnings enabled, + which is now the default when using gcc. (Warnings + from confparser.c, because of yacc's code, are + unfortunately to be expected.) + + 223. [func] Several functions were reprototyped to qualify one + or more of their arguments with "const". Similarly, + several functions that return pointers now have + those pointers qualified with const. + + 222. [bug] The global 'also-notify' option was ignored. + + 221. [bug] An uninitialized variable was sometimes passed to + dns_rdata_freestruct() when loading a zone, causing + an assertion failure. + + 220. [cleanup] Set the default outgoing port in the view, and + set it in sockaddrs returned from the ADB. + [31-May-2000 explorer] + + 219. [bug] Signed truncated messages more correctly follow + the respective specs. + + 218. [func] When an rdataset is signed, its ttl is normalized + based on the signature validity period. + + 217. [func] Also-notify and trusted-keys can now be used in + the 'view' statement. + + 216. [func] The 'max-cache-ttl' and 'max-ncache-ttl' options + now work. + + 215. [bug] Failures at certain points in request processing + could cause the assertion INSIST(client->lockview + == NULL) to be triggered. + + 214. [func] New public function isc_netaddr_format(), for + formatting network addresses in log messages. + + 213. [bug] Don't leak memory when reloading the zone if + an update-policy clause was present in the old zone. + + 212. [func] Added dns_message_get/settsigkey, to make TSIG + key management reasonable. + + 211. [func] The 'key' and 'server' statements can now occur + inside 'view' statements. + + 210. [bug] The 'allow-transfer' option was ignored for slave + zones, and the 'transfers-per-ns' option was + was ignored for all zones. + + 209. [cleanup] Upgraded openssl files to new version 0.9.5a + + 208. [func] Added ISC_OFFSET_MAXIMUM for the maximum value + of an isc_offset_t. + + 207. [func] The dnssec tools properly use the logging subsystem. + + 206. [cleanup] dst now stores the key name as a dns_name_t, not + a char *. + + 205. [cleanup] On IRIX, turn off the mostly harmless warnings 1692 + ("prototyped function redeclared without prototype") + and 1552 ("variable ... set but not used") when + compiling in the lib/dns/sec/{dnssafe,openssl} + directories, which contain code imported from outside + sources. + + 204. [cleanup] On HP/UX, pass +vnocompatwarnings to the linker + to quiet the warnings that "The linked output may not + run on a PA 1.x system." + + 203. [func] notify and zone soa queries are now tsig signed when + appropriate. + + 202. [func] isc_lex_getsourceline() changed from returning int + to returning unsigned long, the type of its underlying + counter. + + 201. [cleanup] Removed the test/sdig program, it has been + replaced by bin/dig/dig. + + --- 9.0.0b3 released --- + + 200. [bug] Failures in sending query responses to clients + (e.g., running out of network buffers) were + not logged. + + 199. [bug] isc_heap_delete() sometimes violated the heap + invariant, causing timer events not to be posted + when due. + + 198. [func] Dispatch managers hold memory pools which + any managed dispatcher may use. This allows + us to avoid dipping into the memory context for + most allocations. [19-May-2000 explorer] + + 197. [bug] When an incoming AXFR or IXFR completes, the + zone's internal state is refreshed from the + SOA data. [19-May-2000 explorer] + + 196. [func] Dispatchers can be shared easily between views + and/or interfaces. [19-May-2000 explorer] + + 195. [bug] Including the NXT record of the root domain + in a negative response caused an assertion + failure. + + 194. [doc] The PDF version of the Administrator's Reference + Manual is no longer included in the ISC BIND9 + distribution. + + 193. [func] changed dst_key_free() prototype. + + 192. [bug] Zone configuration validation is now done at end + of config file parsing, and before loading + callbacks. + + 191. [func] Patched to compile on UnixWare 7.x. This platform + is not directly supported by the ISC. + + 190. [cleanup] The DNSSEC tools have been moved to a separate + directory dnssec/ and given the following new, + more descriptive names: + + dnssec-keygen + dnssec-signzone + dnssec-signkey + dnssec-makekeyset + + Their command line arguments have also been changed to + be more consistent. dnssec-keygen now prints the + name of the generated key files (sans extension) + on standard output to simplify its use in automated + scripts. + + 189. [func] isc_time_secondsastimet(), a new function, will ensure + that the number of seconds in an isc_time_t does not + exceed the range of a time_t, or return ISC_R_RANGE. + Similarly, isc_time_now(), isc_time_nowplusinterval(), + isc_time_add() and isc_time_subtract() now check the + range for overflow/underflow. In the case of + isc_time_subtract, this changed a calling requirement + (ie, something that could generate an assertion) + into merely a condition that returns an error result. + isc_time_add() and isc_time_subtract() were void- + valued before but now return isc_result_t. + + 188. [func] Log a warning message when an incoming zone transfer + contains out-of-zone data. + + 187. [func] isc_ratelimter_enqueue() has an additional argument + 'task'. + + 186. [func] dns_request_getresponse() has an additional argument + 'preserve_order'. + + 185. [bug] Fixed up handling of ISC_MEMCLUSTER_LEGACY. Several + public functions did not have an isc__ prefix, and + referred to functions that had previously been + renamed. + + 184. [cleanup] Variables/functions which began with two leading + underscores were made to conform to the ANSI/ISO + standard, which says that such names are reserved. + + 183. [func] ISC_LOG_PRINTTAG option for log channels. Useful + for logging the program name or other identifier. + + 182. [cleanup] New commandline parameters for dnssec tools + + 181. [func] Added dst_key_buildfilename and dst_key_parsefilename + + 180. [func] New isc_result_t ISC_R_RANGE. Supersedes DNS_R_RANGE. + + 179. [func] options named.conf statement *must* now come + before any zone or view statements. + + 178. [func] Post-load of named.conf check verifies a slave zone + has non-empty list of masters defined. + + 177. [func] New per-zone boolean: + + enable-zone yes | no ; + + intended to let a zone be disabled without having + to comment out the entire zone statement. + + 176. [func] New global and per-view option: + + max-cache-ttl number + + 175. [func] New global and per-view option: + + additional-data internal | minimal | maximal; + + 174. [func] New public function isc_sockaddr_format(), for + formatting socket addresses in log messages. + + 173. [func] Keep a queue of zones waiting for zone transfer + quota so that a new transfer can be dispatched + immediately whenever quota becomes available. + + 172. [bug] $TTL directive was sometimes missing from dumped + master files because totext_ctx_init() failed to + initialize ctx->current_ttl_valid. + + 171. [cleanup] On NetBSD systems, the mit-pthreads or + unproven-pthreads library is now always used + unless --with-ptl2 is explicitly specified on + the configure command line. The + --with-mit-pthreads option is no longer needed + and has been removed. + + 170. [cleanup] Remove inter server consistancy checks from zone, + these should return as a separate module in 9.1. + dns_zone_checkservers(), dns_zone_checkparents(), + dns_zone_checkchildren(), dns_zone_checkglue(). + + Remove dns_zone_setadb(), dns_zone_setresolver(), + dns_zone_setrequestmgr() these should now be found + via the view. + + 169. [func] ratelimiter can now process N events per interval. + + 168. [bug] include statements in named.conf caused syntax errors + due to not consuming the semicolon ending the include + statement before switching input streams. + + 167. [bug] Make lack of masters for a slave zone a soft error. + + 166. [bug] Keygen was overwriting existing keys if key_id + conflicted, now it will retry, and non-null keys + with key_id == 0 are not generated anymore. Key + was not able to generate NOAUTHCONF DSA key, + increased RSA key size to 2048 bits. + + 165. [cleanup] Silence "end-of-loop condition not reached" warnings + from Solaris compiler. + + 164. [func] Added functions isc_stdio_open(), isc_stdio_close(), + isc_stdio_seek(), isc_stdio_read(), isc_stdio_write(), + isc_stdio_flush(), isc_stdio_sync(), isc_file_remove() + to encapsulate nonportable usage of errno and sync. + + 163. [func] Added result codes ISC_R_FILENOTFOUND and + ISC_R_FILEEXISTS. + + 162. [bug] Ensure proper range for arguments to ctype.h functions. + + 161. [cleanup] error in yyparse prototype that only HPUX caught. + + 160. [cleanup] getnet*() are not going to be implemented at this + stage. + + 159. [func] Redefinition of config file elements is now an + error (instead of a warning). + + 158. [bug] Log channel and category list copy routines + weren't assigning properly to output parameter. + + 157. [port] Fix missing prototype for getopt(). + + 156. [func] Support new 'database' statement in zone. + + database "quoted-string"; + + 155. [bug] ns_notify_start() was not detaching the found zone. + + 154. [func] The signer now logs libdns warnings to stderr even when + not verbose, and in a nicer format. + + 153. [func] dns_rdata_tostruct() 'mctx' is now optional. If 'mctx' + is NULL then you need to preserve the 'rdata' until + you have finished using the structure as there may be + references to the associated memory. If 'mctx' is + non-NULL it is guaranteed that there are no references + to memory associated with 'rdata'. + + dns_rdata_freestruct() must be called if 'mctx' was + non-NULL and may safely be called if 'mctx' was NULL. + + 152. [bug] keygen dumped core if domain name argument was omitted + from command line. + + 151. [func] Support 'disabled' statement in zone config (causes + zone to be parsed and then ignored). Currently must + come after the 'type' clause. + + 150. [func] Support optional ports in masters and also-notify + statements: + + masters [ port xxx ] { y.y.y.y [ port zzz ] ; } + + 149. [cleanup] Removed usused argument 'olist' from + dns_c_view_unsetordering(). + + 148. [cleanup] Stop issuing some warnings about some configuration + file statements that were not implemented, but now are. + + 147. [bug] Changed yacc union size to be smaller for yaccs that + put yacc-stack on the real stack. + + 146. [cleanup] More general redundant header file cleanup. Rather + than continuing to itemize every header which changed, + this changelog entry just notes that if a header file + did not need another header file that it was including + in order to provide its advertized functionality, the + inclusion of the other header file was removed. See + util/check-includes for how this was tested. + + 145. [cleanup] Added and ISC_LANG_BEGINDECLS/ + ISC_LANG_ENDDECLS to header files that had function + prototypes, and removed it from those that did not. + + 144. [cleanup] libdns header files too numerous to name were made + to conform to the same style for multiple inclusion + protection. + + 143. [func] Added function dns_rdatatype_isknown(). + + 142. [cleanup] does not need or + . + + 141. [bug] Corrupt requests with multiple questions could + cause an assertion failure. + + 140. [cleanup] does not need or . + + 139. [cleanup] now includes instead of + and . + + 138. [cleanup] isc_strtouq moved from str.[ch] to string.[ch] and + renamed isc_string_touint64. isc_strsep moved from + strsep.c to string.c and renamed isc_string_separate. + + 137. [cleanup] , , + , and + made to conform to the same style for multiple + inclusion protection. + + 136. [cleanup] , , + and Win32's needed + ISC_LANG_BEGINDECLS/ISC_LANG_ENDDECLS. + + 135. [cleanup] Win32's did not need + or , now uses in place + of , and needed ISC_LANG_BEGINDECLS + and ISC_LANG_ENDDECLS. + + 134. [cleanup] does not need . + + 133. [cleanup] needs . + + 132. [cleanup] does not need , but does + need . + + 131. [cleanup] and need + for ISC_R_* codes used in macros. + + 130. [cleanup] does not need or + , and now includes + instead of . + + 129. [bug] The 'default_debug' log channel was not set up when + 'category default' was present in the config file + + 128. [cleanup] had ISC_LANG_BEGINDECLS instead of + ISC_LANG_ENDDECLS at end of header. + + 127. [cleanup] The contracts for the comparision routines + dns_name_fullcompare(), dns_name_compare(), + dns_name_rdatacompare(), and dns_rdata_compare() now + specify that the order value returned is < 0, 0, or > 0 + instead of -1, 0, or 1. + + 126. [cleanup] and need . + + 125. [cleanup] , , , + , , , and + do not need . + + 124. [func] signer now imports parent's zone key signature + and creates null keys/sets zone status bit for + children when necessary + + 123. [cleanup] does not need . + + 122. [cleanup] does not need or + . + + 121. [cleanup] does not need or + . Multiple inclusion protection + symbol fixed from ISC_SYMBOL_H to ISC_SYMTAB_H. + isc_symtab_t moved to . + + 120. [cleanup] does not need , + , , or + . + + 119. [cleanup] structure definitions for generic rdata structures do + not have _generic_ in their names. + + 118. [cleanup] libdns.a is now namespace-clean, on NetBSD, excepting + YACC crust (yyparse, etc) [2000-apr-27 explorer] + + 117. [cleanup] libdns.a changes: + dns_zone_clearnotify() and dns_zone_addnotify() + are replaced by dns_zone_setnotifyalso(). + dns_zone_clearmasters() and dns_zone_addmaster() + are replaced by dns_zone_setmasters(). + + 116. [func] Added for isc_offset_t (aka off_t + on Unix systems). + + 115. [port] Shut up the -Wmissing-declarations warning about + 's __sputaux on BSD/OS pre-4.1. + + 114. [cleanup] does not need or + . + + 113. [func] Utility programs dig and host added. + + 112. [cleanup] does not need . + + 111. [cleanup] does not need or + . + + 110. [cleanup] does not need or + . + + 109. [bug] "make depend" did nothing for + bin/tests/{db,mem,sockaddr,tasks,timers}/. + + 108. [cleanup] DNS_SETBIT/DNS_GETBIT/DNS_CLEARBIT moved from + to and renamed to + DNS_BIT_SET/DNS_BIT_GET/DNS_BIT_CLEAR. + + 107. [func] Add keysigner and keysettool. + + 106. [func] Allow dnssec verifications to ignore the validity + period. Used by several of the dnssec tools. + + 105. [doc] doc/dev/coding.html expanded with other + implicit conventions the developers have used. + + 104. [bug] Made compress_add and compress_find static to + lib/dns/compress.c. + + 103. [func] libisc buffer API changes for : + Added: + isc_buffer_base(b) (pointer) + isc_buffer_current(b) (pointer) + isc_buffer_active(b) (pointer) + isc_buffer_used(b) (pointer) + isc_buffer_length(b) (int) + isc_buffer_usedlength(b) (int) + isc_buffer_consumedlength(b) (int) + isc_buffer_remaininglength(b) (int) + isc_buffer_activelength(b) (int) + isc_buffer_availablelength(b) (int) + Removed: + ISC_BUFFER_USEDCOUNT(b) + ISC_BUFFER_AVAILABLECOUNT(b) + isc_buffer_type(b) + Changed names: + isc_buffer_used(b, r) -> + isc_buffer_usedregion(b, r) + isc_buffer_available(b, r) -> + isc_buffer_available_region(b, r) + isc_buffer_consumed(b, r) -> + isc_buffer_consumedregion(b, r) + isc_buffer_active(b, r) -> + isc_buffer_activeregion(b, r) + isc_buffer_remaining(b, r) -> + isc_buffer_remainingregion(b, r) + + Buffer types were removed, so the ISC_BUFFERTYPE_* + macros are no more, and the type argument to + isc_buffer_init and isc_buffer_allocate were removed. + isc_buffer_putstr is now void (instead of isc_result_t) + and requires that the caller ensure that there + is enough available buffer space for the string. + + 102. [port] Correctly detect inet_aton, inet_pton and inet_ptop + on BSD/OS 4.1. + + 101. [cleanup] Quieted EGCS warnings from lib/isc/print.c. + + 100. [cleanup] does not need or + . isc_random_t moved to . + + 99. [cleanup] Rate limiter now has separate shutdown() and + destroy() functions, and it guarantees that all + queued events are delivered even in the shutdown case. + + 98. [cleanup] does not need or + unless ISC_PLATFORM_NEEDVSNPRINTF is defined. + + 97. [cleanup] does not need or + . + + 96. [cleanup] does not need . + + 95. [cleanup] does not need . + + 94. [cleanup] Some installed header files did not compile as C++. + + 93. [cleanup] does not need . + + 92. [cleanup] does not need , , + or . + + 91. [cleanup] does not need or + . + + 90. [cleanup] Removed unneeded ISC_LANG_BEGINDECLS/ISC_LANG_ENDDECLS + from . + + 89. [cleanup] does not need . + + 88. [cleanup] does not need or + . isc_interface_t and isc_interfaceiter_t + moved to . + + 87. [cleanup] does not need , + or . + + 86. [cleanup] isc_bufferlist_t moved from to + . + + 85. [cleanup] does not need , + , , or + . + + 84. [func] allow-query ACL checks now apply to all data + added to a response. + + 83. [func] If the server is authoritative for both a + delegating zone and its (nonsecure) delegatee, and + a query is made for a KEY RR at the top of the + delegatee, then the server will look for a KEY + in the delegator if it is not found in the delegatee. + + 82. [cleanup] does not need . + + 81. [cleanup] and do not need + . + + 80. [cleanup] does not need or . + + 79. [cleanup] does not need . + + 78. [cleanup] lwres_conftest renamed to lwresconf_test for + consistency with other *_test programs. + + 77. [cleanup] typedef of isc_time_t and isc_interval_t moved from + to . + + 76. [cleanup] Rewrote keygen. + + 75. [func] Don't load a zone if its database file is older + than the last time the zone was loaded. + + 74. [cleanup] Removed mktemplate.o and ufile.o from libisc.a, + subsumed by file.o. + + 73. [func] New "file" API in libisc, including new function + isc_file_getmodtime, isc_mktemplate renamed to + isc_file_mktemplate and isc_ufile renamed to + isc_file_openunique. By no means an exhaustive API, + it is just what's needed for now. + + 72. [func] DNS_RBTFIND_NOPREDECESSOR and DNS_RBTFIND_NOOPTIONS + added for dns_rbt_findnode, the former to disable the + setting of the chain to the predecessor, and the + latter to make clear when no options are set. + + 71. [cleanup] Made explicit the implicit REQUIREs of + isc_time_seconds, isc_time_nanoseconds, and + isc_time_subtract. + + 70. [func] isc_time_set() added. + + 69. [bug] The zone object's master and also-notify lists grew + longer with each server reload. + + 68. [func] Partial support for SIG(0) on incoming messages. + + 67. [performance] Allow use of alternate (compile-time supplied) + OpenSSL libraries/headers. + + 66. [func] Data in authoritative zones should have a trust level + beyond secure. + + 65. [cleanup] Removed obsolete typedef of dns_zone_callbackarg_t + from . + + 64. [func] The RBT, DB, and zone table APIs now allow the + caller find the most-enclosing superdomain of + a name. + + 63. [func] Generate NOTIFY messages. + + 62. [func] Add UDP refresh support. + + 61. [cleanup] Use single quotes consistently in log messages. + + 60. [func] Catch and disallow singleton types on message + parse. + + 59. [bug] Cause net/host unreachable to be a hard error + when sending and receiving. + + 58. [bug] bin/named/query.c could sometimes trigger the + (client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) + == 0 assertion in query_newname(). + + 57. [func] Added dns_nxt_typepresent() + + 56. [bug] SIG records were not properly returned in cached + negative answers. + + 55. [bug] Responses containing multiple names in the authority + section were not negatively cached. + + 54. [bug] If a fetch with sigrdataset==NULL joined one with + sigrdataset!=NULL or vice versa, the resolver + could catch an assertion or lose signature data, + respectively. + + 53. [port] freebsd 4.0: lib/isc/unix/socket.c requires + . + + 52. [bug] rndc: taskmgr and socketmgr were not initialized + to NULL. + + 51. [cleanup] dns/compress.h and dns/zt.h did not need to include + dns/rbt.h; it was needed only by compress.c and zt.c. + + 50. [func] RBT deletion no longer requires a valid chain to work, + and dns_rbt_deletenode was added. + + 49. [func] Each cache now has its own mctx. + + 48. [func] isc_task_create() no longer takes an mctx. + isc_task_mem() has been eliminated. + + 47. [func] A number of modules now use memory context reference + counting. + + 46. [func] Memory contexts are now reference counted. + Added isc_mem_inuse() and isc_mem_preallocate(). + Renamed isc_mem_destroy_check() to + isc_mem_setdestroycheck(). + + 45. [bug] The trusted-key statement incorrectly loaded keys. + + 44. [bug] Don't include authority data if it would force us + to unset the AD bit in the message. + + 43. [bug] DNSSEC verification of cached rdatasets was failing. + + 42. [cleanup] Simplified logging of messages with embedded domain + names by introducing a new convenience function + dns_name_format(). + + 41. [func] Use PR_SET_KEEPCAPS on Linux 2.3.99-pre3 and later + to allow 'named' to run as a non-root user while + retaining the ability to bind() to privileged + ports. + + 40. [func] Introduced new logging category "dnssec" and + logging module "dns/validator". + + 39. [cleanup] Moved the typedefs for isc_region_t, isc_textregion_t, + and isc_lex_t to . + + 38. [bug] TSIG signed incoming zone transfers work now. + + 37. [bug] If the first RR in an incoming zone transfer was + not an SOA, the server died with an assertion failure + instead of just reporting an error. + + 36. [cleanup] Change DNS_R_SUCCESS (and others) to ISC_R_SUCCESS + + 35. [performance] Log messages which are of a level too high to be + logged by any channel in the logging configuration + will not cause the log mutex to be locked. + + 34. [bug] Recursion was allowed even with 'recursion no'. + + 33. [func] The RBT now maintains a parent pointer at each node. + + 32. [cleanup] bin/lwresd/client.c needs for memset() + prototype. + + 31. [bug] Use ${LIBTOOL} to compile bin/named/main.@O@. + + 30. [func] config file grammer change to support optional + class type for a view. + + 29. [func] support new config file view options: + + auth-nxdomain recursion query-source + query-source-v6 transfer-source + transfer-source-v6 max-transfer-time-out + max-transfer-idle-out transfer-format + request-ixfr provide-ixfr cleaning-interval + fetch-glue notify rfc2308-type1 lame-ttl + max-ncache-ttl min-roots + + 28. [func] support lame-ttl, min-roots and serial-queries + config global options. + + 27. [bug] Only include on BSD/OS 4.[01]*. + Including it on other platforms (eg, NetBSD) can + cause a forced #error from the C preprocessor. + + 26. [func] new match-clients statement in config file view. + + 25. [bug] make install failed to install and + . + + 24. [cleanup] Eliminate some unnecessary #includes of header + files from header files. + + 23. [cleanup] Provide more context in log messages about client + requests, using a new function ns_client_log(). + + 22. [bug] SIGs weren't returned in the answer section when + the query resulted in a fetch. + + 21. [port] Look at STD_CINCLUDES after CINCLUDES during + compilation, so additional system include directories + can be searched but header files in the bind9 source + tree with conflicting names take precedence. This + avoids issues with installed versions of dnssafe and + openssl. + + 20. [func] Configuration file post-load validation of zones + failed if there were no zones. + + 19. [bug] dns_zone_notifyreceive() failed to unlock the zone + lock in certain error cases. + + 18. [bug] Use AC_TRY_LINK rather than AC_TRY_COMPILE in + configure.in to check for presence of in6addr_any. + + 17. [func] Do configuration file post-load validation of zones. + + 16. [bug] put quotes around key names on config file + output to avoid possible keyword clashes. + + 15. [func] Add dns_name_dupwithoffsets(). This function is + improves comparison performance for duped names. + + 14. [bug] free_rbtdb() could have 'put' unallocated memory in + an unlikely error path. + + 13. [bug] lib/dns/master.c and lib/dns/xfrin.c didn't ignore + out-of-zone data. + + 12. [bug] Fixed possible unitialized variable error. + + 11. [bug] axfr_rrstream_first() didn't check the result code of + db_rr_iterator_first(), possibly causing an assertion + to be triggered later. + + 10. [bug] A bug in the code which makes EDNS0 OPT records in + bin/named/client.c and lib/dns/resolver.c could + trigger an assertion. + + 9. [cleanup] replaced bit-setting code in confctx.c and replaced + repeated code with macro calls. + + 8. [bug] Shutdown of incoming zone transfer accessed + freed memory. + + 7. [cleanup] removed 'listen-on' from view statement. + + 6. [bug] quote RR names when generating config file to + prevent possible clash with config file keywords + (such as 'key'). + + 5. [func] syntax change to named.conf file: new ssu grant/deny + statements must now be enclosed by an 'update-policy' + block. + + 4. [port] bin/named/unix/os.c didn't compile on systems with + linux 2.3 kernel includes due to conflicts between + C library includes and the kernel includes. We now + get only what we need from , and + avoid pulling in other linux kernel .h files. + + 3. [bug] TKEYs go in the answer section of responses, not + the additional section. + + 2. [bug] Generating cryptographic randomness failed on + systems without /dev/random. + + 1. [bug] The installdirs rule in + lib/isc/unix/include/isc/Makefile.in had a typo which + prevented the isc directory from being created if it + didn't exist. + + --- 9.0.0b2 released --- + +# This tells Emacs to use hard tabs in this file. +# Local Variables: +# indent-tabs-mode: t +# End: diff --git a/COPYRIGHT b/COPYRIGHT new file mode 100644 index 0000000..48141e7 --- /dev/null +++ b/COPYRIGHT @@ -0,0 +1,30 @@ +Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") +Copyright (C) 1996-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: COPYRIGHT,v 1.9.18.4 2007/08/28 07:19:54 tbox Exp $ + +Portions Copyright (C) 1996-2001 Nominum, Inc. + +Permission to use, copy, modify, and 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 NOMINUM DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM 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. diff --git a/FAQ b/FAQ new file mode 100644 index 0000000..90b3ca0 --- /dev/null +++ b/FAQ @@ -0,0 +1,781 @@ +Frequently Asked Questions about BIND 9 + +Copyright © 2004-2007 Internet Systems Consortium, Inc. ("ISC") + +Copyright © 2000-2003 Internet Software Consortium. + +----------------------------------------------------------------------- + +1. Compilation and Installation Questions + +Q: I'm trying to compile BIND 9, and "make" is failing due to files not + being found. Why? + +A: Using a parallel or distributed "make" to build BIND 9 is not + supported, and doesn't work. If you are using one of these, use normal + make or gmake instead. + +Q: Isn't "make install" supposed to generate a default named.conf? + +A: Short Answer: No. + + Long Answer: There really isn't a default configuration which fits any + site perfectly. There are lots of decisions that need to be made and + there is no consensus on what the defaults should be. For example + FreeBSD uses /etc/namedb as the location where the configuration files + for named are stored. Others use /var/named. + + What addresses to listen on? For a laptop on the move a lot you may + only want to listen on the loop back interfaces. + + Who do you offer recursive service to? Is there are firewall to + consider? If so is it stateless or stateful. Are you directly on the + Internet? Are you on a private network? Are you on a NAT'd network? The + answers to all these questions change how you configure even a caching + name server. + +2. Configuration and Setup Questions + +Q: Why does named log the warning message "no TTL specified - using SOA + MINTTL instead"? + +A: Your zone file is illegal according to RFC1035. It must either have a + line like: + + $TTL 86400 + + at the beginning, or the first record in it must have a TTL field, like + the "84600" in this example: + + example.com. 86400 IN SOA ns hostmaster ( 1 3600 1800 1814400 3600 ) + +Q: Why do I get errors like "dns_zone_load: zone foo/IN: loading master + file bar: ran out of space"? + +A: This is often caused by TXT records with missing close quotes. Check + that all TXT records containing quoted strings have both open and close + quotes. + +Q: How do I restrict people from looking up the server version? + +A: Put a "version" option containing something other than the real version + in the "options" section of named.conf. Note doing this will not + prevent attacks and may impede people trying to diagnose problems with + your server. Also it is possible to "fingerprint" nameservers to + determine their version. + +Q: How do I restrict only remote users from looking up the server version? + +A: The following view statement will intercept lookups as the internal + view that holds the version information will be matched last. The + caveats of the previous answer still apply, of course. + + view "chaos" chaos { + match-clients { ; }; + allow-query { none; }; + zone "." { + type hint; + file "/dev/null"; // or any empty file + }; + }; + +Q: What do "no source of entropy found" or "could not open entropy source + foo" mean? + +A: The server requires a source of entropy to perform certain operations, + mostly DNSSEC related. These messages indicate that you have no source + of entropy. On systems with /dev/random or an equivalent, it is used by + default. A source of entropy can also be defined using the + random-device option in named.conf. + +Q: I'm trying to use TSIG to authenticate dynamic updates or zone + transfers. I'm sure I have the keys set up correctly, but the server is + rejecting the TSIG. Why? + +A: This may be a clock skew problem. Check that the the clocks on the + client and server are properly synchronised (e.g., using ntp). + +Q: I see a log message like the following. Why? + + couldn't open pid file '/var/run/named.pid': Permission denied + +A: You are most likely running named as a non-root user, and that user + does not have permission to write in /var/run. The common ways of + fixing this are to create a /var/run/named directory owned by the named + user and set pid-file to "/var/run/named/named.pid", or set pid-file to + "named.pid", which will put the file in the directory specified by the + directory option (which, in this case, must be writable by the named + user). + +Q: I can query the nameserver from the nameserver but not from other + machines. Why? + +A: This is usually the result of the firewall configuration stopping the + queries and / or the replies. + +Q: How can I make a server a slave for both an internal and an external + view at the same time? When I tried, both views on the slave were + transferred from the same view on the master. + +A: You will need to give the master and slave multiple IP addresses and + use those to make sure you reach the correct view on the other machine. + + Master: 10.0.1.1 (internal), 10.0.1.2 (external, IP alias) + internal: + match-clients { !10.0.1.2; !10.0.1.4; 10.0.1/24; }; + notify-source 10.0.1.1; + transfer-source 10.0.1.1; + query-source address 10.0.1.1; + external: + match-clients { any; }; + recursion no; // don't offer recursion to the world + notify-source 10.0.1.2; + transfer-source 10.0.1.2; + query-source address 10.0.1.2; + + Slave: 10.0.1.3 (internal), 10.0.1.4 (external, IP alias) + internal: + match-clients { !10.0.1.2; !10.0.1.4; 10.0.1/24; }; + notify-source 10.0.1.3; + transfer-source 10.0.1.3; + query-source address 10.0.1.3; + external: + match-clients { any; }; + recursion no; // don't offer recursion to the world + notify-source 10.0.1.4; + transfer-source 10.0.1.4; + query-source address 10.0.1.4; + + You put the external address on the alias so that all the other dns + clients on these boxes see the internal view by default. + +A: BIND 9.3 and later: Use TSIG to select the appropriate view. + + Master 10.0.1.1: + key "external" { + algorithm hmac-md5; + secret "xxxxxxxx"; + }; + view "internal" { + match-clients { !key external; 10.0.1/24; }; + ... + }; + view "external" { + match-clients { key external; any; }; + server 10.0.1.2 { keys external; }; + recursion no; + ... + }; + + Slave 10.0.1.2: + key "external" { + algorithm hmac-md5; + secret "xxxxxxxx"; + }; + view "internal" { + match-clients { !key external; 10.0.1/24; }; + ... + }; + view "external" { + match-clients { key external; any; }; + server 10.0.1.1 { keys external; }; + recursion no; + ... + }; + +Q: I get error messages like "multiple RRs of singleton type" and "CNAME + and other data" when transferring a zone. What does this mean? + +A: These indicate a malformed master zone. You can identify the exact + records involved by transferring the zone using dig then running + named-checkzone on it. + + dig axfr example.com @master-server > tmp + named-checkzone example.com tmp + + A CNAME record cannot exist with the same name as another record except + for the DNSSEC records which prove its existence (NSEC). + + RFC 1034, Section 3.6.2: "If a CNAME RR is present at a node, no other + data should be present; this ensures that the data for a canonical name + and its aliases cannot be different. This rule also insures that a + cached CNAME can be used without checking with an authoritative server + for other RR types." + +Q: I get error messages like "named.conf:99: unexpected end of input" + where 99 is the last line of named.conf. + +A: Some text editors (notepad and wordpad) fail to put a line title + indication (e.g. CR/LF) on the last line of a text file. This can be + fixed by "adding" a blank line to the end of the file. Named expects to + see EOF immediately after EOL and treats text files where this is not + met as truncated. + +Q: How do I share a dynamic zone between multiple views? + +A: You choose one view to be master and the second a slave and transfer + the zone between views. + + Master 10.0.1.1: + key "external" { + algorithm hmac-md5; + secret "xxxxxxxx"; + }; + + key "mykey" { + algorithm hmac-md5; + secret "yyyyyyyy"; + }; + + view "internal" { + match-clients { !key external; 10.0.1/24; }; + server 10.0.1.1 { + /* Deliver notify messages to external view. */ + keys { external; }; + }; + zone "example.com" { + type master; + file "internal/example.db"; + allow-update { key mykey; }; + notify-also { 10.0.1.1; }; + }; + }; + + view "external" { + match-clients { key external; any; }; + zone "example.com" { + type slave; + file "external/example.db"; + masters { 10.0.1.1; }; + transfer-source { 10.0.1.1; }; + // allow-update-forwarding { any; }; + // allow-notify { ... }; + }; + }; + +Q: I get a error message like "zone wireless.ietf56.ietf.org/IN: loading + master file primaries/wireless.ietf56.ietf.org: no owner". + +A: This error is produced when a line in the master file contains leading + white space (tab/space) but the is no current record owner name to + inherit the name from. Usually this is the result of putting white + space before a comment, forgetting the "@" for the SOA record, or + indenting the master file. + +Q: Why are my logs in GMT (UTC). + +A: You are running chrooted (-t) and have not supplied local timezone + information in the chroot area. + + FreeBSD: /etc/localtime + Solaris: /etc/TIMEZONE and /usr/share/lib/zoneinfo + OSF: /etc/zoneinfo/localtime + + See also tzset(3) and zic(8). + +Q: I get "rndc: connect failed: connection refused" when I try to run + rndc. + +A: This is usually a configuration error. + + First ensure that named is running and no errors are being reported at + startup (/var/log/messages or equivalent). Running "named -g " from a title can help at this point. + + Secondly ensure that named is configured to use rndc either by + "rndc-confgen -a", rndc-confgen or manually. The Administrators + Reference manual has details on how to do this. + + Old versions of rndc-confgen used localhost rather than 127.0.0.1 in / + etc/rndc.conf for the default server. Update /etc/rndc.conf if + necessary so that the default server listed in /etc/rndc.conf matches + the addresses used in named.conf. "localhost" has two address + (127.0.0.1 and ::1). + + If you use "rndc-confgen -a" and named is running with -t or -u ensure + that /etc/rndc.conf has the correct ownership and that a copy is in the + chroot area. You can do this by re-running "rndc-confgen -a" with + appropriate -t and -u arguments. + +Q: I get "transfer of 'example.net/IN' from 192.168.4.12#53: failed while + receiving responses: permission denied" error messages. + +A: These indicate a filesystem permission error preventing named creating + / renaming the temporary file. These will usually also have other + associated error messages like + + "dumping master file: sl/tmp-XXXX5il3sQ: open: permission denied" + + Named needs write permission on the directory containing the file. + Named writes the new cache file to a temporary file then renames it to + the name specified in named.conf to ensure that the contents are always + complete. This is to prevent named loading a partial zone in the event + of power failure or similar interrupting the write of the master file. + + Note file names are relative to the directory specified in options and + any chroot directory ([/][]). + + If named is invoked as "named -t /chroot/DNS" with the following + named.conf then "/chroot/DNS/var/named/sl" needs to be writable by the + user named is running as. + + options { + directory "/var/named"; + }; + + zone "example.net" { + type slave; + file "sl/example.net"; + masters { 192.168.4.12; }; + }; + +Q: I want to forward all DNS queries from my caching nameserver to another + server. But there are some domains which have to be served locally, via + rbldnsd. + + How do I achieve this ? + +A: options { + forward only; + forwarders { ; }; + }; + + zone "sbl-xbl.spamhaus.org" { + type forward; forward only; + forwarders { port 530; }; + }; + + zone "list.dsbl.org" { + type forward; forward only; + forwarders { port 530; }; + }; + + +Q: Can you help me understand how BIND 9 uses memory to store DNS zones? + + Some times it seems to take several times the amount of memory it needs + to store the zone. + +A: When reloading a zone named my have multiple copies of the zone in + memory at one time. The zone it is serving and the one it is loading. + If reloads are ultra fast it can have more still. + + e.g. Ones that are transferring out, the one that it is serving and the + one that is loading. + + BIND 8 destroyed the zone before loading and also killed off outgoing + transfers of the zone. + + The new strategy allows slaves to get copies of the new zone regardless + of how often the master is loaded compared to the transfer time. The + slave might skip some intermediate versions but the transfers will + complete and it will keep reasonably in sync with the master. + + The new strategy also allows the master to recover from syntax and + other errors in the master file as it still has an in-core copy of the + old contents. + +3. General Questions + +Q: I keep getting log messages like the following. Why? + + Dec 4 23:47:59 client 10.0.0.1#1355: updating zone 'example.com/IN': + update failed: 'RRset exists (value dependent)' prerequisite not + satisfied (NXRRSET) + +A: DNS updates allow the update request to test to see if certain + conditions are met prior to proceeding with the update. The message + above is saying that conditions were not met and the update is not + proceeding. See doc/rfc/rfc2136.txt for more details on prerequisites. + +Q: I keep getting log messages like the following. Why? + + Jun 21 12:00:00.000 client 10.0.0.1#1234: update denied + +A: Someone is trying to update your DNS data using the RFC2136 Dynamic + Update protocol. Windows 2000 machines have a habit of sending dynamic + update requests to DNS servers without being specifically configured to + do so. If the update requests are coming from a Windows 2000 machine, + see http://support.microsoft.com/support/kb/articles/q246/8/04.asp for + information about how to turn them off. + +Q: When I do a "dig . ns", many of the A records for the root servers are + missing. Why? + +A: This is normal and harmless. It is a somewhat confusing side effect of + the way BIND 9 does RFC2181 trust ranking and of the efforts BIND 9 + makes to avoid promoting glue into answers. + + When BIND 9 first starts up and primes its cache, it receives the root + server addresses as additional data in an authoritative response from a + root server, and these records are eligible for inclusion as additional + data in responses. Subsequently it receives a subset of the root server + addresses as additional data in a non-authoritative (referral) response + from a root server. This causes the addresses to now be considered + non-authoritative (glue) data, which is not eligible for inclusion in + responses. + + The server does have a complete set of root server addresses cached at + all times, it just may not include all of them as additional data, + depending on whether they were last received as answers or as glue. You + can always look up the addresses with explicit queries like "dig + a.root-servers.net A". + +Q: Why don't my zones reload when I do an "rndc reload" or SIGHUP? + +A: A zone can be updated either by editing zone files and reloading the + server or by dynamic update, but not both. If you have enabled dynamic + update for a zone using the "allow-update" option, you are not supposed + to edit the zone file by hand, and the server will not attempt to + reload it. + +Q: Why is named listening on UDP port other than 53? + +A: Named uses a system selected port to make queries of other nameservers. + This behaviour can be overridden by using query-source to lock down the + port and/or address. See also notify-source and transfer-source. + +Q: I get warning messages like "zone example.com/IN: refresh: failure + trying master 1.2.3.4#53: timed out". + +A: Check that you can make UDP queries from the slave to the master + + dig +norec example.com soa @1.2.3.4 + + You could be generating queries faster than the slave can cope with. + Lower the serial query rate. + + serial-query-rate 5; // default 20 + +Q: I don't get RRSIG's returned when I use "dig +dnssec". + +A: You need to ensure DNSSEC is enabled (dnssec-enable yes;). + +Q: Can a NS record refer to a CNAME. + +A: No. The rules for glue (copies of the *address* records in the parent + zones) and additional section processing do not allow it to work. + + You would have to add both the CNAME and address records (A/AAAA) as + glue to the parent zone and have CNAMEs be followed when doing + additional section processing to make it work. No nameserver + implementation supports either of these requirements. + +Q: What does "RFC 1918 response from Internet for 0.0.0.10.IN-ADDR.ARPA" + mean? + +A: If the IN-ADDR.ARPA name covered refers to a internal address space you + are using then you have failed to follow RFC 1918 usage rules and are + leaking queries to the Internet. You should establish your own zones + for these addresses to prevent you querying the Internet's name servers + for these addresses. Please see http://as112.net/ for details of the + problems you are causing and the counter measures that have had to be + deployed. + + If you are not using these private addresses then a client has queried + for them. You can just ignore the messages, get the offending client to + stop sending you these messages as they are most probably leaking them + or setup your own zones empty zones to serve answers to these queries. + + zone "10.IN-ADDR.ARPA" { + type master; + file "empty"; + }; + + zone "16.172.IN-ADDR.ARPA" { + type master; + file "empty"; + }; + + ... + + zone "31.172.IN-ADDR.ARPA" { + type master; + file "empty"; + }; + + zone "168.192.IN-ADDR.ARPA" { + type master; + file "empty"; + }; + + empty: + @ 10800 IN SOA . . ( + 1 3600 1200 604800 10800 ) + @ 10800 IN NS . + + Note + + Future versions of named are likely to do this automatically. + +Q: Will named be affected by the 2007 changes to daylight savings rules in + the US. + +A: No, so long as the machines internal clock (as reported by "date -u") + remains at UTC. The only visible change if you fail to upgrade your OS, + if you are in a affected area, will be that log messages will be a hour + out during the period where the old rules do not match the new rules. + + For most OS's this change just means that you need to update the + conversion rules from UTC to local time. Normally this involves + updating a file in /etc (which sets the default timezone for the + machine) and possibly a directory which has all the conversion rules + for the world (e.g. /usr/share/zoneinfo). When updating the OS do not + forget to update any chroot areas as well. See your OS's documentation + for more details. + + The local timezone conversion rules can also be done on a individual + basis by setting the TZ environment variable appropriately. See your + OS's documentation for more details. + +Q: Is there a bugzilla (or other tool) database that mere mortals can have + (read-only) access to for bind? + +A: No. The BIND 9 bug database is kept closed for a number of reasons. + These include, but are not limited to, that the database contains + proprietory information from people reporting bugs. The database has in + the past and may in future contain unfixed bugs which are capable of + bringing down most of the Internet's DNS infrastructure. + + The release pages for each version contain up to date lists of bugs + that have been fixed post release. That is as close as we can get to + providing a bug database. + +4. Operating-System Specific Questions + +4.1. HPUX + +Q: I get the following error trying to configure BIND: + + checking if unistd.h or sys/types.h defines fd_set... no + configure: error: need either working unistd.h or sys/select.h + +A: You have attempted to configure BIND with the bundled C compiler. This + compiler does not meet the minimum compiler requirements to for + building BIND. You need to install a ANSI C compiler and / or teach + configure how to find the ANSI C compiler. The later can be done by + adjusting the PATH environment variable and / or specifying the + compiler via CC. + + ./configure CC= ... + +4.2. Linux + +Q: Why do I get the following errors: + + general: errno2result.c:109: unexpected error: + general: unable to convert errno to isc_result: 14: Bad address + client: UDP client handler shutting down due to fatal receive error: unexpected error + +A: This is the result of a Linux kernel bug. + + See: http://marc.theaimsgroup.com/?l=linux-netdev&m=113081708031466&w=2 + +Q: Why do I see 5 (or more) copies of named on Linux? + +A: Linux threads each show up as a process under ps. The approximate + number of threads running is n+4, where n is the number of CPUs. Note + that the amount of memory used is not cumulative; if each process is + using 10M of memory, only a total of 10M is used. + + Newer versions of Linux's ps command hide the individual threads and + require -L to display them. + +Q: Why does BIND 9 log "permission denied" errors accessing its + configuration files or zones on my Linux system even though it is + running as root? + +A: On Linux, BIND 9 drops most of its root privileges on startup. This + including the privilege to open files owned by other users. Therefore, + if the server is running as root, the configuration files and zone + files should also be owned by root. + +Q: I get the error message "named: capset failed: Operation not permitted" + when starting named. + +A: The capability module, part of "Linux Security Modules/LSM", has not + been loaded into the kernel. See insmod(8). + +Q: I'm running BIND on Red Hat Enterprise Linux or Fedora Core - + + Why can't named update slave zone database files? + + Why can't named create DDNS journal files or update the master zones + from journals? + + Why can't named create custom log files? + +A: Red Hat Security Enhanced Linux (SELinux) policy security protections : + + Red Hat have adopted the National Security Agency's SELinux security + policy ( see http://www.nsa.gov/selinux ) and recommendations for BIND + security , which are more secure than running named in a chroot and + make use of the bind-chroot environment unnecessary . + + By default, named is not allowed by the SELinux policy to write, create + or delete any files EXCEPT in these directories: + + $ROOTDIR/var/named/slaves + $ROOTDIR/var/named/data + $ROOTDIR/var/tmp + + + where $ROOTDIR may be set in /etc/sysconfig/named if bind-chroot is + installed. + + The SELinux policy particularly does NOT allow named to modify the + $ROOTDIR/var/named directory, the default location for master zone + database files. + + SELinux policy overrules file access permissions - so even if all the + files under /var/named have ownership named:named and mode rw-rw-r--, + named will still not be able to write or create files except in the + directories above, with SELinux in Enforcing mode. + + So, to allow named to update slave or DDNS zone files, it is best to + locate them in $ROOTDIR/var/named/slaves, with named.conf zone + statements such as: + + zone "slave.zone." IN { + type slave; + file "slaves/slave.zone.db"; + ... + }; + zone "ddns.zone." IN { + type master; + allow-updates {...}; + file "slaves/ddns.zone.db"; + }; + + + To allow named to create its cache dump and statistics files, for + example, you could use named.conf options statements such as: + + options { + ... + dump-file "/var/named/data/cache_dump.db"; + statistics-file "/var/named/data/named_stats.txt"; + ... + }; + + + You can also tell SELinux to allow named to update any zone database + files, by setting the SELinux tunable boolean parameter + 'named_write_master_zones=1', using the system-config-securitylevel + GUI, using the 'setsebool' command, or in /etc/selinux/targeted/ + booleans. + + You can disable SELinux protection for named entirely by setting the + 'named_disable_trans=1' SELinux tunable boolean parameter. + + The SELinux named policy defines these SELinux contexts for named: + + named_zone_t : for zone database files - $ROOTDIR/var/named/* + named_conf_t : for named configuration files - $ROOTDIR/etc/{named,rndc}.* + named_cache_t: for files modifiable by named - $ROOTDIR/var/{tmp,named/{slaves,data}} + + + If you want to retain use of the SELinux policy for named, and put + named files in different locations, you can do so by changing the + context of the custom file locations . + + To create a custom configuration file location, e.g. '/root/ + named.conf', to use with the 'named -c' option, do: + + # chcon system_u:object_r:named_conf_t /root/named.conf + + + To create a custom modifiable named data location, e.g. '/var/log/ + named' for a log file, do: + + # chcon system_u:object_r:named_cache_t /var/log/named + + + To create a custom zone file location, e.g. /root/zones/, do: + + # chcon system_u:object_r:named_zone_t /root/zones/{.,*} + + + See these man-pages for more information : selinux(8), named_selinux + (8), chcon(1), setsebool(8) + +4.3. Windows + +Q: Zone transfers from my BIND 9 master to my Windows 2000 slave fail. + Why? + +A: This may be caused by a bug in the Windows 2000 DNS server where DNS + messages larger than 16K are not handled properly. This can be worked + around by setting the option "transfer-format one-answer;". Also check + whether your zone contains domain names with embedded spaces or other + special characters, like "John\032Doe\213s\032Computer", since such + names have been known to cause Windows 2000 slaves to incorrectly + reject the zone. + +Q: I get "Error 1067" when starting named under Windows. + +A: This is the service manager saying that named exited. You need to + examine the Application log in the EventViewer to find out why. + + Common causes are that you failed to create "named.conf" (usually "C:\ + windows\dns\etc\named.conf") or failed to specify the directory in + named.conf. + + options { + Directory "C:\windows\dns\etc"; + }; + +4.4. FreeBSD + +Q: I have FreeBSD 4.x and "rndc-confgen -a" just sits there. + +A: /dev/random is not configured. Use rndcontrol(8) to tell the kernel to + use certain interrupts as a source of random events. You can make this + permanent by setting rand_irqs in /etc/rc.conf. + + /etc/rc.conf + rand_irqs="3 14 15" + + See also http://people.freebsd.org/~dougb/randomness.html + +4.5. Solaris + +Q: How do I integrate BIND 9 and Solaris SMF + +A: Sun has a blog entry describing how to do this. + + http://blogs.sun.com/roller/page/anay/Weblog?catname=%2FSolaris + +4.6. Apple Mac OS X + +Q: How do I run BIND 9 on Apple Mac OS X? + +A: If you run Tiger(Mac OS 10.4) or later then this is all you need to do: + + % sudo rndc-confgen > /etc/rndc.conf + + Copy the key statement from /etc/rndc.conf into /etc/rndc.key, e.g.: + + key "rndc-key" { + algorithm hmac-md5; + secret "uvceheVuqf17ZwIcTydddw=="; + }; + + Then start the relevant service: + + % sudo service org.isc.named start + + This is persistent upon a reboot, so you will have to do it only once. + +A: Alternatively you can just generate /etc/rndc.key by running: + + % sudo rndc-confgen -a + + Then start the relevant service: + + % sudo service org.isc.named start + + Named will look for /etc/rndc.key when it starts if it doesn't have a + controls section or the existing controls are missing keys sub-clauses. + This is persistent upon a reboot, so you will have to do it only once. + diff --git a/FAQ.xml b/FAQ.xml new file mode 100644 index 0000000..0f864ef --- /dev/null +++ b/FAQ.xml @@ -0,0 +1,1347 @@ + + + + + +
+ Frequently Asked Questions about BIND 9 + + + 2004 + 2005 + 2006 + 2007 + Internet Systems Consortium, Inc. ("ISC") + + + 2000 + 2001 + 2002 + 2003 + Internet Software Consortium. + + + + + Compilation and Installation Questions + + + + + I'm trying to compile BIND 9, and "make" is failing due to + files not being found. Why? + + + + + Using a parallel or distributed "make" to build BIND 9 is + not supported, and doesn't work. If you are using one of + these, use normal make or gmake instead. + + + + + + + + Isn't "make install" supposed to generate a default named.conf? + + + + + Short Answer: No. + + + Long Answer: There really isn't a default configuration which fits + any site perfectly. There are lots of decisions that need to + be made and there is no consensus on what the defaults should be. + For example FreeBSD uses /etc/namedb as the location where the + configuration files for named are stored. Others use /var/named. + + + What addresses to listen on? For a laptop on the move a lot + you may only want to listen on the loop back interfaces. + + + Who do you offer recursive service to? Is there are firewall + to consider? If so is it stateless or stateful. Are you + directly on the Internet? Are you on a private network? Are + you on a NAT'd network? The answers + to all these questions change how you configure even a + caching name server. + + + + + + + Configuration and Setup Questions + + + + + + Why does named log the warning message no TTL specified - + using SOA MINTTL instead? + + + + + Your zone file is illegal according to RFC1035. It must either + have a line like: + + + +$TTL 86400 + + + at the beginning, or the first record in it must have a TTL field, + like the "84600" in this example: + + + +example.com. 86400 IN SOA ns hostmaster ( 1 3600 1800 1814400 3600 ) + + + + + + + + + Why do I get errors like dns_zone_load: zone foo/IN: loading + master file bar: ran out of space? + + + + + This is often caused by TXT records with missing close + quotes. Check that all TXT records containing quoted strings + have both open and close quotes. + + + + + + + + + How do I restrict people from looking up the server version? + + + + + Put a "version" option containing something other than the + real version in the "options" section of named.conf. Note + doing this will not prevent attacks and may impede people + trying to diagnose problems with your server. Also it is + possible to "fingerprint" nameservers to determine their + version. + + + + + + + + + How do I restrict only remote users from looking up the + server version? + + + + + The following view statement will intercept lookups as the + internal view that holds the version information will be + matched last. The caveats of the previous answer still + apply, of course. + + + +view "chaos" chaos { + match-clients { <those to be refused>; }; + allow-query { none; }; + zone "." { + type hint; + file "/dev/null"; // or any empty file + }; +}; + + + + + + + + + What do no source of entropy found or could not + open entropy source foo mean? + + + + + The server requires a source of entropy to perform certain + operations, mostly DNSSEC related. These messages indicate + that you have no source of entropy. On systems with + /dev/random or an equivalent, it is used by default. A + source of entropy can also be defined using the random-device + option in named.conf. + + + + + + + + + I'm trying to use TSIG to authenticate dynamic updates or + zone transfers. I'm sure I have the keys set up correctly, + but the server is rejecting the TSIG. Why? + + + + + This may be a clock skew problem. Check that the the clocks + on the client and server are properly synchronised (e.g., + using ntp). + + + + + + + + I see a log message like the following. Why? + + + couldn't open pid file '/var/run/named.pid': Permission denied + + + + + You are most likely running named as a non-root user, and + that user does not have permission to write in /var/run. + The common ways of fixing this are to create a /var/run/named + directory owned by the named user and set pid-file to + "/var/run/named/named.pid", or set pid-file to "named.pid", + which will put the file in the directory specified by the + directory option (which, in this case, must be writable by + the named user). + + + + + + + + I can query the nameserver from the nameserver but not from other + machines. Why? + + + + + This is usually the result of the firewall configuration stopping + the queries and / or the replies. + + + + + + + + How can I make a server a slave for both an internal and + an external view at the same time? When I tried, both views + on the slave were transferred from the same view on the master. + + + + + You will need to give the master and slave multiple IP + addresses and use those to make sure you reach the correct + view on the other machine. + + + +Master: 10.0.1.1 (internal), 10.0.1.2 (external, IP alias) + internal: + match-clients { !10.0.1.2; !10.0.1.4; 10.0.1/24; }; + notify-source 10.0.1.1; + transfer-source 10.0.1.1; + query-source address 10.0.1.1; + external: + match-clients { any; }; + recursion no; // don't offer recursion to the world + notify-source 10.0.1.2; + transfer-source 10.0.1.2; + query-source address 10.0.1.2; + +Slave: 10.0.1.3 (internal), 10.0.1.4 (external, IP alias) + internal: + match-clients { !10.0.1.2; !10.0.1.4; 10.0.1/24; }; + notify-source 10.0.1.3; + transfer-source 10.0.1.3; + query-source address 10.0.1.3; + external: + match-clients { any; }; + recursion no; // don't offer recursion to the world + notify-source 10.0.1.4; + transfer-source 10.0.1.4; + query-source address 10.0.1.4; + + + You put the external address on the alias so that all the other + dns clients on these boxes see the internal view by default. + + + + + BIND 9.3 and later: Use TSIG to select the appropriate view. + + + +Master 10.0.1.1: + key "external" { + algorithm hmac-md5; + secret "xxxxxxxx"; + }; + view "internal" { + match-clients { !key external; 10.0.1/24; }; + ... + }; + view "external" { + match-clients { key external; any; }; + server 10.0.1.2 { keys external; }; + recursion no; + ... + }; + +Slave 10.0.1.2: + key "external" { + algorithm hmac-md5; + secret "xxxxxxxx"; + }; + view "internal" { + match-clients { !key external; 10.0.1/24; }; + ... + }; + view "external" { + match-clients { key external; any; }; + server 10.0.1.1 { keys external; }; + recursion no; + ... + }; + + + + + + + + I get error messages like multiple RRs of singleton type + and CNAME and other data when transferring a zone. What + does this mean? + + + + + These indicate a malformed master zone. You can identify + the exact records involved by transferring the zone using + dig then running named-checkzone on it. + + + +dig axfr example.com @master-server > tmp +named-checkzone example.com tmp + + + A CNAME record cannot exist with the same name as another record + except for the DNSSEC records which prove its existence (NSEC). + + + RFC 1034, Section 3.6.2: If a CNAME RR is present at a node, + no other data should be present; this ensures that the data for a + canonical name and its aliases cannot be different. This rule also + insures that a cached CNAME can be used without checking with an + authoritative server for other RR types. + + + + + + + + I get error messages like named.conf:99: unexpected end + of input where 99 is the last line of named.conf. + + + + + Some text editors (notepad and wordpad) fail to put a line + title indication (e.g. CR/LF) on the last line of a + text file. This can be fixed by "adding" a blank line to + the end of the file. Named expects to see EOF immediately + after EOL and treats text files where this is not met as + truncated. + + + + + + + + How do I share a dynamic zone between multiple views? + + + + + You choose one view to be master and the second a slave and + transfer the zone between views. + + + +Master 10.0.1.1: + key "external" { + algorithm hmac-md5; + secret "xxxxxxxx"; + }; + + key "mykey" { + algorithm hmac-md5; + secret "yyyyyyyy"; + }; + + view "internal" { + match-clients { !key external; 10.0.1/24; }; + server 10.0.1.1 { + /* Deliver notify messages to external view. */ + keys { external; }; + }; + zone "example.com" { + type master; + file "internal/example.db"; + allow-update { key mykey; }; + notify-also { 10.0.1.1; }; + }; + }; + + view "external" { + match-clients { key external; any; }; + zone "example.com" { + type slave; + file "external/example.db"; + masters { 10.0.1.1; }; + transfer-source { 10.0.1.1; }; + // allow-update-forwarding { any; }; + // allow-notify { ... }; + }; + }; + + + + + + + + I get a error message like zone wireless.ietf56.ietf.org/IN: + loading master file primaries/wireless.ietf56.ietf.org: no + owner. + + + + + This error is produced when a line in the master file + contains leading white space (tab/space) but the is no + current record owner name to inherit the name from. Usually + this is the result of putting white space before a comment, + forgetting the "@" for the SOA record, or indenting the master + file. + + + + + + + + Why are my logs in GMT (UTC). + + + + + You are running chrooted (-t) and have not supplied local timezone + information in the chroot area. + + + FreeBSD: /etc/localtime + Solaris: /etc/TIMEZONE and /usr/share/lib/zoneinfo + OSF: /etc/zoneinfo/localtime + + + See also tzset(3) and zic(8). + + + + + + + + I get rndc: connect failed: connection refused when + I try to run rndc. + + + + + This is usually a configuration error. + + + First ensure that named is running and no errors are being + reported at startup (/var/log/messages or equivalent). + Running "named -g <usual arguments>" from a title + can help at this point. + + + Secondly ensure that named is configured to use rndc either + by "rndc-confgen -a", rndc-confgen or manually. The + Administrators Reference manual has details on how to do + this. + + + Old versions of rndc-confgen used localhost rather than + 127.0.0.1 in /etc/rndc.conf for the default server. Update + /etc/rndc.conf if necessary so that the default server + listed in /etc/rndc.conf matches the addresses used in + named.conf. "localhost" has two address (127.0.0.1 and + ::1). + + + If you use "rndc-confgen -a" and named is running with -t or -u + ensure that /etc/rndc.conf has the correct ownership and that + a copy is in the chroot area. You can do this by re-running + "rndc-confgen -a" with appropriate -t and -u arguments. + + + + + + + + I get transfer of 'example.net/IN' from 192.168.4.12#53: + failed while receiving responses: permission denied error + messages. + + + + + These indicate a filesystem permission error preventing + named creating / renaming the temporary file. These will + usually also have other associated error messages like + + + +"dumping master file: sl/tmp-XXXX5il3sQ: open: permission denied" + + + Named needs write permission on the directory containing + the file. Named writes the new cache file to a temporary + file then renames it to the name specified in named.conf + to ensure that the contents are always complete. This is + to prevent named loading a partial zone in the event of + power failure or similar interrupting the write of the + master file. + + + Note file names are relative to the directory specified in + options and any chroot directory ([<chroot + dir>/][<options dir>]). + + + + If named is invoked as "named -t /chroot/DNS" with + the following named.conf then "/chroot/DNS/var/named/sl" + needs to be writable by the user named is running as. + + +options { + directory "/var/named"; +}; + +zone "example.net" { + type slave; + file "sl/example.net"; + masters { 192.168.4.12; }; +}; + + + + + + + + I want to forward all DNS queries from my caching nameserver to + another server. But there are some domains which have to be + served locally, via rbldnsd. + + + How do I achieve this ? + + + + +options { + forward only; + forwarders { <ip.of.primary.nameserver>; }; +}; + +zone "sbl-xbl.spamhaus.org" { + type forward; forward only; + forwarders { <ip.of.rbldns.server> port 530; }; +}; + +zone "list.dsbl.org" { + type forward; forward only; + forwarders { <ip.of.rbldns.server> port 530; }; +}; + + + + + + + + Can you help me understand how BIND 9 uses memory to store + DNS zones? + + + Some times it seems to take several times the amount of + memory it needs to store the zone. + + + + + When reloading a zone named my have multiple copies of + the zone in memory at one time. The zone it is serving + and the one it is loading. If reloads are ultra fast it + can have more still. + + + e.g. Ones that are transferring out, the one that it is + serving and the one that is loading. + + + BIND 8 destroyed the zone before loading and also killed + off outgoing transfers of the zone. + + + The new strategy allows slaves to get copies of the new + zone regardless of how often the master is loaded compared + to the transfer time. The slave might skip some intermediate + versions but the transfers will complete and it will keep + reasonably in sync with the master. + + + The new strategy also allows the master to recover from + syntax and other errors in the master file as it still + has an in-core copy of the old contents. + + + + + + + General Questions + + + + + I keep getting log messages like the following. Why? + + + Dec 4 23:47:59 client 10.0.0.1#1355: updating zone + 'example.com/IN': update failed: 'RRset exists (value + dependent)' prerequisite not satisfied (NXRRSET) + + + + + DNS updates allow the update request to test to see if + certain conditions are met prior to proceeding with the + update. The message above is saying that conditions were + not met and the update is not proceeding. See doc/rfc/rfc2136.txt + for more details on prerequisites. + + + + + + + + I keep getting log messages like the following. Why? + + + Jun 21 12:00:00.000 client 10.0.0.1#1234: update denied + + + + + Someone is trying to update your DNS data using the RFC2136 + Dynamic Update protocol. Windows 2000 machines have a habit + of sending dynamic update requests to DNS servers without + being specifically configured to do so. If the update + requests are coming from a Windows 2000 machine, see + + http://support.microsoft.com/support/kb/articles/q246/8/04.asp + + for information about how to turn them off. + + + + + + + + When I do a "dig . ns", many of the A records for the root + servers are missing. Why? + + + + + This is normal and harmless. It is a somewhat confusing + side effect of the way BIND 9 does RFC2181 trust ranking + and of the efforts BIND 9 makes to avoid promoting glue + into answers. + + + When BIND 9 first starts up and primes its cache, it receives + the root server addresses as additional data in an authoritative + response from a root server, and these records are eligible + for inclusion as additional data in responses. Subsequently + it receives a subset of the root server addresses as + additional data in a non-authoritative (referral) response + from a root server. This causes the addresses to now be + considered non-authoritative (glue) data, which is not + eligible for inclusion in responses. + + + The server does have a complete set of root server addresses + cached at all times, it just may not include all of them + as additional data, depending on whether they were last + received as answers or as glue. You can always look up the + addresses with explicit queries like "dig a.root-servers.net A". + + + + + + + + Why don't my zones reload when I do an "rndc reload" or SIGHUP? + + + + + A zone can be updated either by editing zone files and + reloading the server or by dynamic update, but not both. + If you have enabled dynamic update for a zone using the + "allow-update" option, you are not supposed to edit the + zone file by hand, and the server will not attempt to reload + it. + + + + + + + + Why is named listening on UDP port other than 53? + + + + + Named uses a system selected port to make queries of other + nameservers. This behaviour can be overridden by using + query-source to lock down the port and/or address. See + also notify-source and transfer-source. + + + + + + + + I get warning messages like zone example.com/IN: refresh: + failure trying master 1.2.3.4#53: timed out. + + + + + Check that you can make UDP queries from the slave to the master + + + +dig +norec example.com soa @1.2.3.4 + + + You could be generating queries faster than the slave can + cope with. Lower the serial query rate. + + + +serial-query-rate 5; // default 20 + + + + + + + + I don't get RRSIG's returned when I use "dig +dnssec". + + + + + You need to ensure DNSSEC is enabled (dnssec-enable yes;). + + + + + + + + Can a NS record refer to a CNAME. + + + + + No. The rules for glue (copies of the *address* records + in the parent zones) and additional section processing do + not allow it to work. + + + You would have to add both the CNAME and address records + (A/AAAA) as glue to the parent zone and have CNAMEs be + followed when doing additional section processing to make + it work. No nameserver implementation supports either of + these requirements. + + + + + + + + What does RFC 1918 response from Internet for + 0.0.0.10.IN-ADDR.ARPA mean? + + + + + If the IN-ADDR.ARPA name covered refers to a internal address + space you are using then you have failed to follow RFC 1918 + usage rules and are leaking queries to the Internet. You + should establish your own zones for these addresses to prevent + you querying the Internet's name servers for these addresses. + Please see http://as112.net/ + for details of the problems you are causing and the counter + measures that have had to be deployed. + + + If you are not using these private addresses then a client + has queried for them. You can just ignore the messages, + get the offending client to stop sending you these messages + as they are most probably leaking them or setup your own zones + empty zones to serve answers to these queries. + + + +zone "10.IN-ADDR.ARPA" { + type master; + file "empty"; +}; + +zone "16.172.IN-ADDR.ARPA" { + type master; + file "empty"; +}; + +... + +zone "31.172.IN-ADDR.ARPA" { + type master; + file "empty"; +}; + +zone "168.192.IN-ADDR.ARPA" { + type master; + file "empty"; +}; + +empty: +@ 10800 IN SOA <name-of-server>. <contact-email>. ( + 1 3600 1200 604800 10800 ) +@ 10800 IN NS <name-of-server>. + + + + Future versions of named are likely to do this automatically. + + + + + + + + + Will named be affected by the 2007 changes to daylight savings + rules in the US. + + + + + No, so long as the machines internal clock (as reported + by "date -u") remains at UTC. The only visible change + if you fail to upgrade your OS, if you are in a affected + area, will be that log messages will be a hour out during + the period where the old rules do not match the new rules. + + + For most OS's this change just means that you need to + update the conversion rules from UTC to local time. + Normally this involves updating a file in /etc (which + sets the default timezone for the machine) and possibly + a directory which has all the conversion rules for the + world (e.g. /usr/share/zoneinfo). When updating the OS + do not forget to update any chroot areas as well. + See your OS's documentation for more details. + + + The local timezone conversion rules can also be done on + a individual basis by setting the TZ environment variable + appropriately. See your OS's documentation for more + details. + + + + + + + + Is there a bugzilla (or other tool) database that mere + mortals can have (read-only) access to for bind? + + + + + No. The BIND 9 bug database is kept closed for a number + of reasons. These include, but are not limited to, that + the database contains proprietory information from people + reporting bugs. The database has in the past and may in + future contain unfixed bugs which are capable of bringing + down most of the Internet's DNS infrastructure. + + + The release pages for each version contain up to date + lists of bugs that have been fixed post release. That + is as close as we can get to providing a bug database. + + + + + + + Operating-System Specific Questions + + HPUX + + + + I get the following error trying to configure BIND: +checking if unistd.h or sys/types.h defines fd_set... no +configure: error: need either working unistd.h or sys/select.h + + + + + You have attempted to configure BIND with the bundled C compiler. + This compiler does not meet the minimum compiler requirements to + for building BIND. You need to install a ANSI C compiler and / or + teach configure how to find the ANSI C compiler. The later can + be done by adjusting the PATH environment variable and / or + specifying the compiler via CC. + + + ./configure CC=<compiler> ... + + + + + + + Linux + + + + + Why do I get the following errors: +general: errno2result.c:109: unexpected error: +general: unable to convert errno to isc_result: 14: Bad address +client: UDP client handler shutting down due to fatal receive error: unexpected error + + + + + This is the result of a Linux kernel bug. + + + See: + http://marc.theaimsgroup.com/?l=linux-netdev&m=113081708031466&w=2 + + + + + + + + Why do I see 5 (or more) copies of named on Linux? + + + + + Linux threads each show up as a process under ps. The + approximate number of threads running is n+4, where n is + the number of CPUs. Note that the amount of memory used + is not cumulative; if each process is using 10M of memory, + only a total of 10M is used. + + + Newer versions of Linux's ps command hide the individual threads + and require -L to display them. + + + + + + + + Why does BIND 9 log permission denied errors accessing + its configuration files or zones on my Linux system even + though it is running as root? + + + + + On Linux, BIND 9 drops most of its root privileges on + startup. This including the privilege to open files owned + by other users. Therefore, if the server is running as + root, the configuration files and zone files should also + be owned by root. + + + + + + + + I get the error message named: capset failed: Operation + not permitted when starting named. + + + + + The capability module, part of "Linux Security Modules/LSM", + has not been loaded into the kernel. See insmod(8). + + + + + + + + I'm running BIND on Red Hat Enterprise Linux or Fedora Core - + + + Why can't named update slave zone database files? + + + Why can't named create DDNS journal files or update + the master zones from journals? + + + Why can't named create custom log files? + + + + + + Red Hat Security Enhanced Linux (SELinux) policy security + protections : + + + + Red Hat have adopted the National Security Agency's + SELinux security policy ( see http://www.nsa.gov/selinux + ) and recommendations for BIND security , which are more + secure than running named in a chroot and make use of + the bind-chroot environment unnecessary . + + + + By default, named is not allowed by the SELinux policy + to write, create or delete any files EXCEPT in these + directories: + + +$ROOTDIR/var/named/slaves +$ROOTDIR/var/named/data +$ROOTDIR/var/tmp + + + where $ROOTDIR may be set in /etc/sysconfig/named if + bind-chroot is installed. + + + + The SELinux policy particularly does NOT allow named to modify + the $ROOTDIR/var/named directory, the default location for master + zone database files. + + + + SELinux policy overrules file access permissions - so + even if all the files under /var/named have ownership + named:named and mode rw-rw-r--, named will still not be + able to write or create files except in the directories + above, with SELinux in Enforcing mode. + + + + So, to allow named to update slave or DDNS zone files, + it is best to locate them in $ROOTDIR/var/named/slaves, + with named.conf zone statements such as: + + +zone "slave.zone." IN { + type slave; + file "slaves/slave.zone.db"; + ... +}; +zone "ddns.zone." IN { + type master; + allow-updates {...}; + file "slaves/ddns.zone.db"; +}; + + + + + + To allow named to create its cache dump and statistics + files, for example, you could use named.conf options + statements such as: + + +options { + ... + dump-file "/var/named/data/cache_dump.db"; + statistics-file "/var/named/data/named_stats.txt"; + ... +}; + + + + + + You can also tell SELinux to allow named to update any + zone database files, by setting the SELinux tunable boolean + parameter 'named_write_master_zones=1', using the + system-config-securitylevel GUI, using the 'setsebool' + command, or in /etc/selinux/targeted/booleans. + + + + You can disable SELinux protection for named entirely by + setting the 'named_disable_trans=1' SELinux tunable boolean + parameter. + + + + The SELinux named policy defines these SELinux contexts for named: + + +named_zone_t : for zone database files - $ROOTDIR/var/named/* +named_conf_t : for named configuration files - $ROOTDIR/etc/{named,rndc}.* +named_cache_t: for files modifiable by named - $ROOTDIR/var/{tmp,named/{slaves,data}} + + + + + + If you want to retain use of the SELinux policy for named, + and put named files in different locations, you can do + so by changing the context of the custom file locations + . + + + + To create a custom configuration file location, e.g. + '/root/named.conf', to use with the 'named -c' option, + do: + + +# chcon system_u:object_r:named_conf_t /root/named.conf + + + + + + To create a custom modifiable named data location, e.g. + '/var/log/named' for a log file, do: + + +# chcon system_u:object_r:named_cache_t /var/log/named + + + + + + To create a custom zone file location, e.g. /root/zones/, do: + + +# chcon system_u:object_r:named_zone_t /root/zones/{.,*} + + + + + + See these man-pages for more information : selinux(8), + named_selinux(8), chcon(1), setsebool(8) + + + + + + + Windows + + + + + Zone transfers from my BIND 9 master to my Windows 2000 + slave fail. Why? + + + + + This may be caused by a bug in the Windows 2000 DNS server + where DNS messages larger than 16K are not handled properly. + This can be worked around by setting the option "transfer-format + one-answer;". Also check whether your zone contains domain + names with embedded spaces or other special characters, + like "John\032Doe\213s\032Computer", since such names have + been known to cause Windows 2000 slaves to incorrectly + reject the zone. + + + + + + + + I get Error 1067 when starting named under Windows. + + + + + This is the service manager saying that named exited. You + need to examine the Application log in the EventViewer to + find out why. + + + Common causes are that you failed to create "named.conf" + (usually "C:\windows\dns\etc\named.conf") or failed to + specify the directory in named.conf. + + + +options { + Directory "C:\windows\dns\etc"; +}; + + + + + + + FreeBSD + + + + + I have FreeBSD 4.x and "rndc-confgen -a" just sits there. + + + + + /dev/random is not configured. Use rndcontrol(8) to tell + the kernel to use certain interrupts as a source of random + events. You can make this permanent by setting rand_irqs + in /etc/rc.conf. + + + +/etc/rc.conf +rand_irqs="3 14 15" + + + See also + + http://people.freebsd.org/~dougb/randomness.html + + + + + + + + Solaris + + + + + How do I integrate BIND 9 and Solaris SMF + + + + + Sun has a blog entry describing how to do this. + + + + http://blogs.sun.com/roller/page/anay/Weblog?catname=%2FSolaris + + + + + + + + + + +
diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..9ff0f64 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,68 @@ +# Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 1998-2002 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: Makefile.in,v 1.43.18.6 2007/09/03 23:46:21 tbox Exp $ + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +@BIND9_VERSION@ + +SUBDIRS = make lib bin doc @LIBBIND@ +TARGETS = + +@BIND9_MAKE_RULES@ + +distclean:: + @if [ "X@LIBBIND@" = "X" ] ; then \ + i=lib/bind; \ + echo "making $@ in `pwd`/$$i"; \ + (cd $$i; ${MAKE} ${MAKEDEFS} $@) || exit 1; \ + fi + +distclean:: + rm -f config.cache config.h config.log config.status TAGS + rm -f libtool isc-config.sh configure.lineno + rm -f util/conf.sh docutil/docbook2man-wrapper.sh + +# XXX we should clean libtool stuff too. Only do this after we add rules +# to make it. +maintainer-clean:: + rm -f configure + +installdirs: + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${bindir} \ + ${DESTDIR}${localstatedir}/run ${DESTDIR}${sysconfdir} + +install:: isc-config.sh installdirs + ${INSTALL_SCRIPT} isc-config.sh ${DESTDIR}${bindir} + +tags: + rm -f TAGS + find lib bin -name "*.[ch]" -print | @ETAGS@ - + +check: test + +test: + (cd bin/tests && ${MAKE} ${MAKEDEFS} test) + +FAQ: FAQ.xml + ${XSLTPROC} doc/xsl/isc-docbook-text.xsl FAQ.xml | \ + LC_ALL=C ${W3M} -T text/html -dump -cols 72 >$@.tmp + mv $@.tmp $@ + +clean:: + rm -f FAQ.tmp diff --git a/README b/README new file mode 100644 index 0000000..20fd84a --- /dev/null +++ b/README @@ -0,0 +1,601 @@ +BIND 9 + + BIND version 9 is a major rewrite of nearly all aspects of the + underlying BIND architecture. Some of the important features of + BIND 9 are: + + - DNS Security + DNSSEC (signed zones) + TSIG (signed DNS requests) + + - IP version 6 + Answers DNS queries on IPv6 sockets + IPv6 resource records (AAAA) + Experimental IPv6 Resolver Library + + - DNS Protocol Enhancements + IXFR, DDNS, Notify, EDNS0 + Improved standards conformance + + - Views + One server process can provide multiple "views" of + the DNS namespace, e.g. an "inside" view to certain + clients, and an "outside" view to others. + + - Multiprocessor Support + + - Improved Portability Architecture + + + BIND version 9 development has been underwritten by the following + organizations: + + Sun Microsystems, Inc. + Hewlett Packard + Compaq Computer Corporation + IBM + Process Software Corporation + Silicon Graphics, Inc. + Network Associates, Inc. + U.S. Defense Information Systems Agency + USENIX Association + Stichting NLnet - NLnet Foundation + Nominum, Inc. + + +BIND 9.4.2 + + BIND 9.4.2 is a maintenance release, containing fixes for + a number of bugs in 9.4.1. + + Warning: If you installed BIND 9.4.2rc1 then any applications + linked against this release candidate will need to be rebuilt. + +BIND 9.4.1 + + BIND 9.4.1 is a security release, containing a fix for + a security bugs in 9.4.0. + +BIND 9.4.0 + + BIND 9.4.0 has a number of new features over 9.3, + including: + + Implemented "additional section caching" (or "acache"), an + internal cache framework for additional section content to + improve response performance. Several configuration options + were provided to control the behavior. + + New notify type 'master-only'. Enable notify for master + zones only. + + Accept 'notify-source' style syntax for query-source. + + rndc now allows addresses to be set in the server clauses. + + New option "allow-query-cache". This lets allow-query be + used to specify the default zone access level rather than + having to have every zone override the global value. + allow-query-cache can be set at both the options and view + levels. If allow-query-cache is not set then allow-recursion + is used if set, otherwise allow-query is used if set, otherwise + the default (localhost; localnets;) is used. + + rndc: the source address can now be specified. + + ixfr-from-differences now takes master and slave in addition + to yes and no at the options and view levels. + + Allow the journal's name to be changed via named.conf. + + 'rndc notify zone [class [view]]' resend the NOTIFY messages + for the specified zone. + + 'dig +trace' now randomly selects the next servers to try. + Report if there is a bad delegation. + + Improve check-names error messages. + + Make public the function to read a key file, dst_key_read_public(). + + dig now returns the byte count for axfr/ixfr. + + allow-update is now settable at the options / view level. + + named-checkconf now checks the logging configuration. + + host now can turn on memory debugging flags with '-m'. + + Don't send notify messages to self. + + Perform sanity checks on NS records which refer to 'in zone' names. + + New zone option "notify-delay". Specify a minimum delay + between sets of NOTIFY messages. + + Extend adjusting TTL warning messages. + + Named and named-checkzone can now both check for non-terminal + wildcard records. + + "rndc freeze/thaw" now freezes/thaws all zones. + + named-checkconf now check acls to verify that they only + refer to existing acls. + + The server syntax has been extended to support a range of + servers. + + Report differences between hints and real NS rrset and + associated address records. + + Preserve the case of domain names in rdata during zone + transfers. + + Restructured the data locking framework using architecture + dependent atomic operations (when available), improving + response performance on multi-processor machines significantly. + x86, x86_64, alpha, powerpc, and mips are currently supported. + + UNIX domain controls are now supported. + + Add support for additional zone file formats for improving + loading performance. The masterfile-format option in + named.conf can be used to specify a non-default format. A + separate command named-compilezone was provided to generate + zone files in the new format. Additionally, the -I and -O + options for dnssec-signzone specify the input and output + formats. + + dnssec-signzone can now randomize signature end times + (dnssec-signzone -j jitter). + + Add support for CH A record. + + Add additional zone data consistancy checks. named-checkzone + has extended checking of NS, MX and SRV record and the hosts + they reference. named has extended post zone load checks. + New zone options: check-mx and integrity-check. + + edns-udp-size can now be overridden on a per server basis. + + dig can now specify the EDNS version when making a query. + + Added framework for handling multiple EDNS versions. + + Additional memory debugging support to track size and mctx + arguments. + + Detect duplicates of UDP queries we are recursing on and + drop them. New stats category "duplicates". + + Memory management. "USE INTERNAL MALLOC" is now runtime selectable. + + The lame cache is now done on a basis + as some servers only appear to be lame for certain query + types. + + Limit the number of recursive clients that can be waiting + for a single query () to resolve. New + options clients-per-query and max-clients-per-query. + + dig: report the number of extra bytes still left in the + packet after processing all the records. + + Support for IPSECKEY rdata type. + + Raise the UDP receive buffer size to 32k if it is less than 32k. + + x86 and x86_64 now have separate atomic locking implementations. + + named-checkconf now validates update-policy entries. + + Attempt to make the amount of work performed in a iteration + self tuning. The covers nodes clean from the cache per + iteration, nodes written to disk when rewriting a master + file and nodes destroyed per iteration when destroying a + zone or a cache. + + ISC string copy API. + + Automatic empty zone creation for D.F.IP6.ARPA and friends. + Note: RFC 1918 zones are not yet covered by this but are + likely to be in a future release. + + New options: empty-server, empty-contact, empty-zones-enable + and disable-empty-zone. + + dig now has a '-q queryname' and '+showsearch' options. + + host/nslookup now continue (default)/fail on SERVFAIL. + + dig now warns if 'RA' is not set in the answer when 'RD' + was set in the query. host/nslookup skip servers that fail + to set 'RA' when 'RD' is set unless a server is explicitly + set. + + Integrate contributed DLZ code into named. + + Integrate contributed IDN code from JPNIC. + + Validate pending NS RRsets, in the authority section, prior + to returning them if it can be done without requiring DNSKEYs + to be fetched. + + It is now possible to configure named to accept expired + RRSIGs. Default "dnssec-accept-expired no;". Setting + "dnssec-accept-expired yes;" leaves named vulnerable to + replay attacks. + + Additional memory leakage checks. + + The maximum EDNS UDP response named will send can now be + set in named.conf (max-udp-size). This is independent of + the advertised receive buffer (edns-udp-size). + + Named now falls back to advertising EDNS with a 512 byte + receive buffer if the initial EDNS queries fail. + + Control the zeroing of the negative response TTL to a soa + query. Defaults "zero-no-soa-ttl yes;" and + "zero-no-soa-ttl-cache no;". + + Separate out MX and SRV to CNAME checks. + + dig/nslookup/host: warn about missing "QR". + + TSIG HMACSHA1, HMACSHA224, HMACSHA256, HMACSHA384 and + HMACSHA512 support. + + dnssec-signzone: output the SOA record as the first record + in the signed zone. + + Two new update policies. "selfsub" and "selfwild". + + dig, nslookup and host now advertise a 4096 byte EDNS UDP + buffer size by default. + + Report when a zone is removed. + + DS/DLV SHA256 digest algorithm support. + + Implement "rrset-order fixed". + + Check the KSK flag when updating a secure dynamic zone. + New zone option "update-check-ksk yes;". + + It is now possible to explicitly enable DNSSEC validation. + default dnssec-validation no; to be changed to yes in 9.5.0. + + It is now possible to enable/disable DNSSEC validation + from rndc. This is useful for the mobile hosts where the + current connection point breaks DNSSEC (firewall/proxy). + + rndc validation newstate [view] + + dnssec-signzone can now update the SOA record of the signed + zone, either as an increment or as the system time(). + + Statistics about acache now recorded and sent to log. + + libbind: corresponds to that from BIND 8.4.7. + +BIND 9.3.0 + + BIND 9.3.0 has a number of new features over 9.2, + including: + + DNSSEC is now DS based (RFC 3658). + See also RFC 3845, doc/draft/draft-ietf-dnsext-dnssec-*. + + DNSSEC lookaside validation. + + check-names is now implemented. + rrset-order in more complete. + + IPv4/IPv6 transition support, dual-stack-servers. + + IXFR deltas can now be generated when loading master files, + ixfr-from-differences. + + It is now possible to specify the size of a journal, max-journal-size. + + It is now possible to define a named set of master servers to be + used in masters clause, masters. + + The advertised EDNS UDP size can now be set, edns-udp-size. + + allow-v6-synthesis has been obsoleted. + + NOTE: + * Zones containing MD and MF will now be rejected. + * dig, nslookup name. now report "Not Implemented" as + NOTIMP rather than NOTIMPL. This will have impact on scripts + that are looking for NOTIMPL. + + libbind: corresponds to that from BIND 8.4.5. + +BIND 9.2.0 + + BIND 9.2.0 has a number of new features over 9.1, + including: + + - The size of the cache can now be limited using the + "max-cache-size" option. + + - The server can now automatically convert RFC1886-style + recursive lookup requests into RFC2874-style lookups, + when enabled using the new option "allow-v6-synthesis". + This allows stub resolvers that support AAAA records + but not A6 record chains or binary labels to perform + lookups in domains that make use of these IPv6 DNS + features. + + - Performance has been improved. + + - The man pages now use the more portable "man" macros + rather than the "mandoc" macros, and are installed + by "make install". + + - The named.conf parser has been completely rewritten. + It now supports "include" directives in more + places such as inside "view" statements, and it no + longer has any reserved words. + + - The "rndc status" command is now implemented. + + - rndc can now be configured automatically. + + - A BIND 8 compatible stub resolver library is now + included in lib/bind. + + - OpenSSL has been removed from the distribution. This + means that to use DNSSEC, OpenSSL must be installed and + the --with-openssl option must be supplied to configure. + This does not apply to the use of TSIG, which does not + require OpenSSL. + + - The source distribution now builds on Windows NT/2000. + See win32utils/readme1.txt and win32utils/win32-build.txt + for details. + + This distribution also includes a new lightweight stub + resolver library and associated resolver daemon that fully + support forward and reverse lookups of both IPv4 and IPv6 + addresses. This library is considered experimental and + is not a complete replacement for the BIND 8 resolver library. + Applications that use the BIND 8 res_* functions to perform + DNS lookups or dynamic updates still need to be linked against + the BIND 8 libraries. For DNS lookups, they can also use the + new "getrrsetbyname()" API. + + BIND 9.2 is capable of acting as an authoritative server + for DNSSEC secured zones. This functionality is believed to + be stable and complete except for lacking support for + verifications involving wildcard records in secure zones. + + When acting as a caching server, BIND 9.2 can be configured + to perform DNSSEC secure resolution on behalf of its clients. + This part of the DNSSEC implementation is still considered + experimental. For detailed information about the state of the + DNSSEC implementation, see the file doc/misc/dnssec. + + There are a few known bugs: + + On some systems, IPv6 and IPv4 sockets interact in + unexpected ways. For details, see doc/misc/ipv6. + To reduce the impact of these problems, the server + no longer listens for requests on IPv6 addresses + by default. If you need to accept DNS queries over + IPv6, you must specify "listen-on-v6 { any; };" + in the named.conf options statement. + + FreeBSD prior to 4.2 (and 4.2 if running as non-root) + and OpenBSD prior to 2.8 log messages like + "fcntl(8, F_SETFL, 4): Inappropriate ioctl for device". + This is due to a bug in "/dev/random" and impacts the + server's DNSSEC support. + + OS X 10.1.4 (Darwin 5.4), OS X 10.1.5 (Darwin 5.5) and + OS X 10.2 (Darwin 6.0) reports errors like + "fcntl(3, F_SETFL, 4): Operation not supported by device". + This is due to a bug in "/dev/random" and impacts the + server's DNSSEC support. + + --with-libtool does not work on AIX. + + --with-libtool does not work on SunOS 4. configure + requires "printf" which is not available. + + A bug in the Windows 2000 DNS server can cause zone transfers + from a BIND 9 server to a W2K server to fail. For details, + see the "Zone Transfers" section in doc/misc/migration. + + For a detailed list of user-visible changes from + previous releases, see the CHANGES file. + + +Building + + BIND 9 currently requires a UNIX system with an ANSI C compiler, + basic POSIX support, and a 64 bit integer type. + + We've had successful builds and tests on the following systems: + + COMPAQ Tru64 UNIX 5.1B + FreeBSD 4.10, 5.2.1, 6.2 + HP-UX 11.11 + NetBSD 1.5 + Slackware Linux 8.1 + Solaris 8, 9, 9 (x86) + Windows NT/2000/XP/2003 + + Additionally, we have unverified reports of success building + previous versions of BIND 9 from users of the following systems: + + AIX 5L + SuSE Linux 7.0 + Slackware Linux 7.x, 8.0 + Red Hat Linux 7.1 + Debian GNU/Linux 2.2 and 3.0 + Mandrake 8.1 + OpenBSD 2.6, 2.8, 2.9, 3.1, 3.6, 3.8 + UnixWare 7.1.1 + HP-UX 10.20 + BSD/OS 4.2 + Mac OS X 10.1, 10.3.8 + + To build, just + + ./configure + make + + Do not use a parallel "make". + + Several environment variables that can be set before running + configure will affect compilation: + + CC + The C compiler to use. configure tries to figure + out the right one for supported systems. + + CFLAGS + C compiler flags. Defaults to include -g and/or -O2 + as supported by the compiler. + + STD_CINCLUDES + System header file directories. Can be used to specify + where add-on thread or IPv6 support is, for example. + Defaults to empty string. + + STD_CDEFINES + Any additional preprocessor symbols you want defined. + Defaults to empty string. + + Possible settings: + Change the default syslog facility of named/lwresd. + -DISC_FACILITY=LOG_LOCAL0 + Enable DNSSEC signature chasing support in dig. + -DDIG_SIGCHASE=1 (sets -DDIG_SIGCHASE_TD=1 and + -DDIG_SIGCHASE_BU=1) + Disable dropping queries from particular well known ports. + -DNS_CLIENT_DROPPORT=0 + Disable support for "rrset-order fixed". + -DDNS_RDATASET_FIXED=0 + + LDFLAGS + Linker flags. Defaults to empty string. + + The following need to be set when cross compiling. + + BUILD_CC + The native C compiler. + BUILD_CFLAGS (optional) + BUILD_CPPFLAGS (optional) + Possible Settings: + -DNEED_OPTARG=1 (optarg is not declared in ) + BUILD_LDFLAGS (optional) + BUILD_LIBS (optional) + + To build shared libraries, specify "--with-libtool" on the + configure command line. + + For the server to support DNSSEC, you need to build it + with crypto support. You must have OpenSSL 0.9.5a + or newer installed and specify "--with-openssl" on the + configure command line. If OpenSSL is installed under + a nonstandard prefix, you can tell configure where to + look for it using "--with-openssl=/prefix". + + To build libbind (the BIND 8 resolver library), specify + "--enable-libbind" on the configure command line. + + On some platforms, BIND 9 can be built with multithreading + support, allowing it to take advantage of multiple CPUs. + You can specify whether to build a multithreaded BIND 9 + by specifying "--enable-threads" or "--disable-threads" + on the configure command line. The default is operating + system dependent. + + If your operating system has integrated support for IPv6, it + will be used automatically. If you have installed KAME IPv6 + separately, use "--with-kame[=PATH]" to specify its location. + + "make install" will install "named" and the various BIND 9 libraries. + By default, installation is into /usr/local, but this can be changed + with the "--prefix" option when running "configure". + + You may specify the option "--sysconfdir" to set the directory + where configuration files like "named.conf" go by default, + and "--localstatedir" to set the default parent directory + of "run/named.pid". For backwards compatibility with BIND 8, + --sysconfdir defaults to "/etc" and --localstatedir defaults to + "/var" if no --prefix option is given. If there is a --prefix + option, sysconfdir defaults to "$prefix/etc" and localstatedir + defaults to "$prefix/var". + + To see additional configure options, run "configure --help". + Note that the help message does not reflect the BIND 8 + compatibility defaults for sysconfdir and localstatedir. + + If you're planning on making changes to the BIND 9 source, you + should also "make depend". If you're using Emacs, you might find + "make tags" helpful. + + If you need to re-run configure please run "make distclean" first. + This will ensure that all the option changes take. + + Building with gcc is not supported, unless gcc is the vendor's usual + compiler (e.g. the various BSD systems, Linux). + + Known compiler issues: + * gcc-3.2.1 and gcc-3.1.1 is known to cause problems with solaris-x86. + * gcc prior to gcc-3.2.3 ultrasparc generates incorrect code at -02. + * gcc-3.3.5 powerpc generates incorrect code at -02. + * Irix, MipsPRO 7.4.1m is known to cause problems. + + A limited test suite can be run with "make test". Many of + the tests require you to configure a set of virtual IP addresses + on your system, and some require Perl; see bin/tests/system/README + for details. + + +Documentation + + The BIND 9 Administrator Reference Manual is included with the + source distribution in DocBook XML and HTML format, in the + doc/arm directory. + + Some of the programs in the BIND 9 distribution have man pages + in their directories. In particular, the command line + options of "named" are documented in /bin/named/named.8. + There is now also a set of man pages for the lwres library. + + If you are upgrading from BIND 8, please read the migration + notes in doc/misc/migration. If you are upgrading from + BIND 4, read doc/misc/migration-4to9. + + Frequently asked questions and their answers can be found in + FAQ. + + +Bug Reports and Mailing Lists + + Bugs reports should be sent to + + bind9-bugs@isc.org + + To join the BIND Users mailing list, send mail to + + bind-users-request@isc.org + + archives of which can be found via + + http://www.isc.org/ops/lists/ + + If you're planning on making changes to the BIND 9 source + code, you might want to join the BIND Forum as a Worker. + This gives you access to the bind-workers@isc.org mailing + list and pre-release access to the code. + + http://www.isc.org/sw/guild/bf/ diff --git a/README.idnkit b/README.idnkit new file mode 100644 index 0000000..316f879 --- /dev/null +++ b/README.idnkit @@ -0,0 +1,112 @@ + + BIND-9 IDN patch + + Japan Network Information Center (JPNIC) + + +* What is this patch for? + +This patch adds internationalized domain name (IDN) support to BIND-9. +You'll get internationalized version of dig/host/nslookup commands. + + + internationalized dig/host/nslookup + dig/host/nslookup accepts non-ASCII domain names in the local + codeset (such as Shift JIS, Big5 or ISO8859-1) determined by + the locale information. The domain names are normalized and + converted to the encoding on the DNS protocol, and sent to DNS + servers. The replies are converted back to the local codeset + and displayed. + + +* Compilation & installation + +0. Prerequisite + +You have to build and install idnkit before building this patched version +of bind-9. + +1. Running configure script + +Run `configure' in the top directory. See `README' for the +configuration options. + +This patch adds the following 4 options to `configure'. You should +at least specify `--with-idn' option to enable IDN support. + + --with-idn[=IDN_PREFIX] + To enable IDN support, you have to specify `--with-idn' option. + The argument IDN_PREFIX is the install prefix of idnkit. If + IDN_PREFIX is omitted, PREFIX (derived from `--prefix=PREFIX') + is assumed. + + --with-libiconv[=LIBICONV_PREFIX] + Specify this option if idnkit you have installed links GNU + libiconv. The argument LIBICONV_PREFIX is install prefix of + GNU libiconv. If the argument is omitted, PREFIX (derived + from `--prefix=PREFIX') is assumed. + + `--with-libiconv' is shorthand option for GNU libiconv. + + --with-libiconv=/usr/local + + This is equivalent to: + + --with-iconv='-L/usr/local/lib -R/usr/local/lib -liconv' + + `--with-libiconv' assumes that your C compiler has `-R' + option, and that the option adds the specified run-time path + to an exacutable binary. If `-R' option of your compiler has + different meaning, or your compiler lacks the option, you + should use `--with-iconv' option instead. Binary command + without run-time path information might be unexecutable. + In that case, you would see an error message like: + + error in loading shared libraries: libiconv.so.2: cannot + open shared object file + + If both `--with-libiconv' and `--with-iconv' options are + specified, `--with-iconv' is prior to `--with-libiconv'. + + --with-iconv=ICONV_LIBSPEC + If your libc doens't provide iconv(), you need to specify the + library containing iconv() with this option. `ICONV_LIBSPEC' + is the argument(s) to `cc' or `ld' to link the library, for + example, `--with-iconv="-L/usr/local/lib -liconv"'. + You don't need to specify the header file directory for "iconv.h" + to the compiler, as it isn't included directly by bind-9 with + this patch. + + --with-idnlib=IDN_LIBSPEC + With this option, you can explicitly specify the argument(s) + to `cc' or `ld' to link the idnkit's library, `libidnkit'. If + this option is not specified, `-L${PREFIX}/lib -lidnkit' is + assumed, where ${PREFIX} is the installation prefix specified + with `--with-idn' option above. You may need to use this + option to specify extra argments, for example, + `--with-idnlib="-L/usr/local/lib -R/usr/local/lib -lidnkit"'. + +Please consult `README' for other configuration options. + +Note that if you want to specify some extra header file directories, +you should use the environment variable STD_CINCLUDES instead of +CFLAGS, as described in README. + +2. Compilation and installation + +After running "configure", just do + + make + make install + +for compiling and installing. + + +* Contact information + +Please see http//www.nic.ad.jp/en/idn/ for the latest news +about idnkit and this patch. + +Bug reports and comments on this kit should be sent to +mdnkit-bugs@nic.ad.jp and idn-cmt@nic.ad.jp, respectively. + +; $Id: README.idnkit,v 1.2.2.2 2005/09/12 02:12:08 marka Exp $ diff --git a/acconfig.h b/acconfig.h new file mode 100644 index 0000000..e8f7d52 --- /dev/null +++ b/acconfig.h @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: acconfig.h,v 1.44.18.5 2005/04/29 00:15:20 marka Exp $ */ + +/*! \file */ + +/*** + *** This file is not to be included by any public header files, because + *** it does not get installed. + ***/ +@TOP@ + +/** define to `int' if doesn't define. */ +#undef ssize_t + +/** define on DEC OSF to enable 4.4BSD style sa_len support */ +#undef _SOCKADDR_LEN + +/** define if your system needs pthread_init() before using pthreads */ +#undef NEED_PTHREAD_INIT + +/** define if your system has sigwait() */ +#undef HAVE_SIGWAIT + +/** define if sigwait() is the UnixWare flavor */ +#undef HAVE_UNIXWARE_SIGWAIT + +/** define on Solaris to get sigwait() to work using pthreads semantics */ +#undef _POSIX_PTHREAD_SEMANTICS + +/** define if LinuxThreads is in use */ +#undef HAVE_LINUXTHREADS + +/** define if sysconf() is available */ +#undef HAVE_SYSCONF + +/** define if sysctlbyname() is available */ +#undef HAVE_SYSCTLBYNAME + +/** define if catgets() is available */ +#undef HAVE_CATGETS + +/** define if getifaddrs() exists */ +#undef HAVE_GETIFADDRS + +/** define if you have the NET_RT_IFLIST sysctl variable and sys/sysctl.h */ +#undef HAVE_IFLIST_SYSCTL + +/** define if chroot() is available */ +#undef HAVE_CHROOT + +/** define if tzset() is available */ +#undef HAVE_TZSET + +/** define if struct addrinfo exists */ +#undef HAVE_ADDRINFO + +/** define if getaddrinfo() exists */ +#undef HAVE_GETADDRINFO + +/** define if gai_strerror() exists */ +#undef HAVE_GAISTRERROR + +/** define if arc4random() exists */ +#undef HAVE_ARC4RANDOM + +/** + * define if pthread_setconcurrency() should be called to tell the + * OS how many threads we might want to run. + */ +#undef CALL_PTHREAD_SETCONCURRENCY + +/** define if IPv6 is not disabled */ +#undef WANT_IPV6 + +/** define if flockfile() is available */ +#undef HAVE_FLOCKFILE + +/** define if getc_unlocked() is available */ +#undef HAVE_GETCUNLOCKED + +/** Shut up warnings about sputaux in stdio.h on BSD/OS pre-4.1 */ +#undef SHUTUP_SPUTAUX +#ifdef SHUTUP_SPUTAUX +struct __sFILE; +extern __inline int __sputaux(int _c, struct __sFILE *_p); +#endif + +/** Shut up warnings about missing sigwait prototype on BSD/OS 4.0* */ +#undef SHUTUP_SIGWAIT +#ifdef SHUTUP_SIGWAIT +int sigwait(const unsigned int *set, int *sig); +#endif + +/** Shut up warnings from gcc -Wcast-qual on BSD/OS 4.1. */ +#undef SHUTUP_STDARG_CAST +#if defined(SHUTUP_STDARG_CAST) && defined(__GNUC__) +#include /** Grr. Must be included *every time*. */ +/** + * The silly continuation line is to keep configure from + * commenting out the #undef. + */ + +#undef \ + va_start +#define va_start(ap, last) \ + do { \ + union { const void *konst; long *var; } _u; \ + _u.konst = &(last); \ + ap = (va_list)(_u.var + __va_words(__typeof(last))); \ + } while (0) +#endif /** SHUTUP_STDARG_CAST && __GNUC__ */ + +/** define if the system has a random number generating device */ +#undef PATH_RANDOMDEV + +/** define if pthread_attr_getstacksize() is available */ +#undef HAVE_PTHREAD_ATTR_GETSTACKSIZE + +/** define if pthread_attr_setstacksize() is available */ +#undef HAVE_PTHREAD_ATTR_SETSTACKSIZE + +/** define if you have strerror in the C library. */ +#undef HAVE_STRERROR + +/** Define if you are running under Compaq TruCluster. */ +#undef HAVE_TRUCLUSTER + +/* Define if OpenSSL includes DSA support */ +#undef HAVE_OPENSSL_DSA + +/* Define to the length type used by the socket API (socklen_t, size_t, int). */ +#undef ISC_SOCKADDR_LEN_T + +/* Define if threads need PTHREAD_SCOPE_SYSTEM */ +#undef NEED_PTHREAD_SCOPE_SYSTEM diff --git a/bin/Makefile.in b/bin/Makefile.in new file mode 100644 index 0000000..2e29f94 --- /dev/null +++ b/bin/Makefile.in @@ -0,0 +1,25 @@ +# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 1998-2001 Internet Software Consortium. +# +# Permission to use, copy, modify, and 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: Makefile.in,v 1.23 2004/03/05 04:57:10 marka Exp $ + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +SUBDIRS = named rndc dig dnssec tests nsupdate check +TARGETS = + +@BIND9_MAKE_RULES@ diff --git a/bin/check/Makefile.in b/bin/check/Makefile.in new file mode 100644 index 0000000..cd9ecf6 --- /dev/null +++ b/bin/check/Makefile.in @@ -0,0 +1,98 @@ +# Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2000-2003 Internet Software Consortium. +# +# Permission to use, copy, modify, and 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: Makefile.in,v 1.24.18.6 2006/06/09 00:54:08 marka Exp $ + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +@BIND9_VERSION@ + +@BIND9_MAKE_INCLUDES@ + +CINCLUDES = ${BIND9_INCLUDES} ${DNS_INCLUDES} ${ISCCFG_INCLUDES} \ + ${ISC_INCLUDES} + +CDEFINES = -DNAMED_CONFFILE=\"${sysconfdir}/named.conf\" +CWARNINGS = + +DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ +ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ +ISCLIBS = ../../lib/isc/libisc.@A@ +BIND9LIBS = ../../lib/bind9/libbind9.@A@ + +DNSDEPLIBS = ../../lib/dns/libdns.@A@ +ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ +ISCDEPLIBS = ../../lib/isc/libisc.@A@ +BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ + +LIBS = @LIBS@ + +SUBDIRS = + +# Alphabetically +TARGETS = named-checkconf@EXEEXT@ named-checkzone@EXEEXT@ + +# Alphabetically +SRCS = named-checkconf.c named-checkzone.c check-tool.c + +MANPAGES = named-checkconf.8 named-checkzone.8 + +HTMLPAGES = named-checkconf.html named-checkzone.html + +MANOBJS = ${MANPAGES} ${HTMLPAGES} + +@BIND9_MAKE_RULES@ + +named-checkconf.@O@: named-checkconf.c + ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ + -DVERSION=\"${VERSION}\" \ + -c ${srcdir}/named-checkconf.c + +named-checkzone.@O@: named-checkzone.c + ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ + -DVERSION=\"${VERSION}\" \ + -c ${srcdir}/named-checkzone.c + +named-checkconf@EXEEXT@: named-checkconf.@O@ check-tool.@O@ ${ISCDEPLIBS} \ + ${ISCCFGDEPLIBS} ${BIND9DEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ + named-checkconf.@O@ check-tool.@O@ ${BIND9LIBS} ${ISCCFGLIBS} \ + ${DNSLIBS} ${ISCLIBS} ${LIBS} + +named-checkzone@EXEEXT@: named-checkzone.@O@ check-tool.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ + named-checkzone.@O@ check-tool.@O@ ${ISCCFGLIBS} ${DNSLIBS} \ + ${ISCLIBS} ${LIBS} + +doc man:: ${MANOBJS} + +docclean manclean maintainer-clean:: + rm -f ${MANOBJS} + +installdirs: + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 + +install:: named-checkconf@EXEEXT@ named-checkzone@EXEEXT@ installdirs + ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named-checkconf@EXEEXT@ ${DESTDIR}${sbindir} + ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named-checkzone@EXEEXT@ ${DESTDIR}${sbindir} + (cd ${DESTDIR}${sbindir}; rm -f named-compilezone@EXEEXT@; ${LINK_PROGRAM} named-checkzone@EXEEXT@ named-compilezone@EXEEXT@) + for m in ${MANPAGES}; do ${INSTALL_DATA} ${srcdir}/$$m ${DESTDIR}${mandir}/man8; done + (cd ${DESTDIR}${mandir}/man8; rm -f named-compilezone.8; ${LINK_PROGRAM} named-checkzone.8 named-compilezone.8) + +clean distclean:: + rm -f ${TARGETS} r1.htm diff --git a/bin/check/check-tool.c b/bin/check/check-tool.c new file mode 100644 index 0000000..1f5f1cd --- /dev/null +++ b/bin/check/check-tool.c @@ -0,0 +1,543 @@ +/* + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000-2002 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: check-tool.c,v 1.10.18.18 2007/09/13 05:04:01 each Exp $ */ + +/*! \file */ + +#include + +#include + +#include "check-tool.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef HAVE_ADDRINFO +#ifdef HAVE_GETADDRINFO +#ifdef HAVE_GAISTRERROR +#define USE_GETADDRINFO +#endif +#endif +#endif + +#define CHECK(r) \ + do { \ + result = (r); \ + if (result != ISC_R_SUCCESS) \ + goto cleanup; \ + } while (0) + +static const char *dbtype[] = { "rbt" }; + +int debug = 0; +isc_boolean_t nomerge = ISC_TRUE; +isc_boolean_t docheckmx = ISC_TRUE; +isc_boolean_t dochecksrv = ISC_TRUE; +isc_boolean_t docheckns = ISC_TRUE; +unsigned int zone_options = DNS_ZONEOPT_CHECKNS | + DNS_ZONEOPT_CHECKMX | + DNS_ZONEOPT_MANYERRORS | + DNS_ZONEOPT_CHECKNAMES | + DNS_ZONEOPT_CHECKINTEGRITY | + DNS_ZONEOPT_CHECKWILDCARD | + DNS_ZONEOPT_WARNMXCNAME | + DNS_ZONEOPT_WARNSRVCNAME; + +/* + * This needs to match the list in bin/named/log.c. + */ +static isc_logcategory_t categories[] = { + { "", 0 }, + { "client", 0 }, + { "network", 0 }, + { "update", 0 }, + { "queries", 0 }, + { "unmatched", 0 }, + { "update-security", 0 }, + { NULL, 0 } +}; + +static isc_boolean_t +checkns(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner, + dns_rdataset_t *a, dns_rdataset_t *aaaa) +{ +#ifdef USE_GETADDRINFO + dns_rdataset_t *rdataset; + dns_rdata_t rdata = DNS_RDATA_INIT; + struct addrinfo hints, *ai, *cur; + char namebuf[DNS_NAME_FORMATSIZE + 1]; + char ownerbuf[DNS_NAME_FORMATSIZE]; + char addrbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123")]; + isc_boolean_t answer = ISC_TRUE; + isc_boolean_t match; + const char *type; + void *ptr = NULL; + int result; + + REQUIRE(a == NULL || !dns_rdataset_isassociated(a) || + a->type == dns_rdatatype_a); + REQUIRE(aaaa == NULL || !dns_rdataset_isassociated(aaaa) || + aaaa->type == dns_rdatatype_aaaa); + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_CANONNAME; + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + dns_name_format(name, namebuf, sizeof(namebuf) - 1); + /* + * Turn off search. + */ + if (dns_name_countlabels(name) > 1U) + strcat(namebuf, "."); + dns_name_format(owner, ownerbuf, sizeof(ownerbuf)); + + result = getaddrinfo(namebuf, NULL, &hints, &ai); + dns_name_format(name, namebuf, sizeof(namebuf) - 1); + switch (result) { + case 0: + /* + * Work around broken getaddrinfo() implementations that + * fail to set ai_canonname on first entry. + */ + cur = ai; + while (cur != NULL && cur->ai_canonname == NULL && + cur->ai_next != NULL) + cur = cur->ai_next; + if (cur != NULL && cur->ai_canonname != NULL && + strcasecmp(ai->ai_canonname, namebuf) != 0) { + dns_zone_log(zone, ISC_LOG_ERROR, + "%s/NS '%s' (out of zone) " + "is a CNAME (illegal)", + ownerbuf, namebuf); + /* XXX950 make fatal for 9.5.0 */ + /* answer = ISC_FALSE; */ + } + break; + case EAI_NONAME: +#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) + case EAI_NODATA: +#endif + dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' (out of zone) " + "has no addresses records (A or AAAA)", + ownerbuf, namebuf); + /* XXX950 make fatal for 9.5.0 */ + return (ISC_TRUE); + + default: + dns_zone_log(zone, ISC_LOG_WARNING, + "getaddrinfo(%s) failed: %s", + namebuf, gai_strerror(result)); + return (ISC_TRUE); + } + if (a == NULL || aaaa == NULL) + return (answer); + /* + * Check that all glue records really exist. + */ + if (!dns_rdataset_isassociated(a)) + goto checkaaaa; + result = dns_rdataset_first(a); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(a, &rdata); + match = ISC_FALSE; + for (cur = ai; cur != NULL; cur = cur->ai_next) { + if (cur->ai_family != AF_INET) + continue; + ptr = &((struct sockaddr_in *)(cur->ai_addr))->sin_addr; + if (memcmp(ptr, rdata.data, rdata.length) == 0) { + match = ISC_TRUE; + break; + } + } + if (!match) { + dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' " + "extra GLUE A record (%s)", + ownerbuf, namebuf, + inet_ntop(AF_INET, rdata.data, + addrbuf, sizeof(addrbuf))); + /* XXX950 make fatal for 9.5.0 */ + /* answer = ISC_FALSE; */ + } + dns_rdata_reset(&rdata); + result = dns_rdataset_next(a); + } + + checkaaaa: + if (!dns_rdataset_isassociated(aaaa)) + goto checkmissing; + result = dns_rdataset_first(aaaa); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(aaaa, &rdata); + match = ISC_FALSE; + for (cur = ai; cur != NULL; cur = cur->ai_next) { + if (cur->ai_family != AF_INET6) + continue; + ptr = &((struct sockaddr_in6 *)(cur->ai_addr))->sin6_addr; + if (memcmp(ptr, rdata.data, rdata.length) == 0) { + match = ISC_TRUE; + break; + } + } + if (!match) { + dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' " + "extra GLUE AAAA record (%s)", + ownerbuf, namebuf, + inet_ntop(AF_INET6, rdata.data, + addrbuf, sizeof(addrbuf))); + /* XXX950 make fatal for 9.5.0. */ + /* answer = ISC_FALSE; */ + } + dns_rdata_reset(&rdata); + result = dns_rdataset_next(aaaa); + } + + checkmissing: + /* + * Check that all addresses appear in the glue. + */ + for (cur = ai; cur != NULL; cur = cur->ai_next) { + switch (cur->ai_family) { + case AF_INET: + rdataset = a; + ptr = &((struct sockaddr_in *)(cur->ai_addr))->sin_addr; + type = "A"; + break; + case AF_INET6: + rdataset = aaaa; + ptr = &((struct sockaddr_in6 *)(cur->ai_addr))->sin6_addr; + type = "AAAA"; + break; + default: + continue; + } + match = ISC_FALSE; + if (dns_rdataset_isassociated(rdataset)) + result = dns_rdataset_first(rdataset); + else + result = ISC_R_FAILURE; + while (result == ISC_R_SUCCESS && !match) { + dns_rdataset_current(rdataset, &rdata); + if (memcmp(ptr, rdata.data, rdata.length) == 0) + match = ISC_TRUE; + dns_rdata_reset(&rdata); + result = dns_rdataset_next(rdataset); + } + if (!match) { + dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' " + "missing GLUE %s record (%s)", + ownerbuf, namebuf, type, + inet_ntop(cur->ai_family, ptr, + addrbuf, sizeof(addrbuf))); + /* XXX950 make fatal for 9.5.0. */ + /* answer = ISC_FALSE; */ + } + } + freeaddrinfo(ai); + return (answer); +#else + return (ISC_TRUE); +#endif +} + +static isc_boolean_t +checkmx(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) { +#ifdef USE_GETADDRINFO + struct addrinfo hints, *ai, *cur; + char namebuf[DNS_NAME_FORMATSIZE + 1]; + char ownerbuf[DNS_NAME_FORMATSIZE]; + int result; + int level = ISC_LOG_ERROR; + isc_boolean_t answer = ISC_TRUE; + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_CANONNAME; + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + dns_name_format(name, namebuf, sizeof(namebuf) - 1); + /* + * Turn off search. + */ + if (dns_name_countlabels(name) > 1U) + strcat(namebuf, "."); + dns_name_format(owner, ownerbuf, sizeof(ownerbuf)); + + result = getaddrinfo(namebuf, NULL, &hints, &ai); + dns_name_format(name, namebuf, sizeof(namebuf) - 1); + switch (result) { + case 0: + /* + * Work around broken getaddrinfo() implementations that + * fail to set ai_canonname on first entry. + */ + cur = ai; + while (cur != NULL && cur->ai_canonname == NULL && + cur->ai_next != NULL) + cur = cur->ai_next; + if (cur != NULL && cur->ai_canonname != NULL && + strcasecmp(cur->ai_canonname, namebuf) != 0) { + if ((zone_options & DNS_ZONEOPT_WARNMXCNAME) != 0) + level = ISC_LOG_WARNING; + if ((zone_options & DNS_ZONEOPT_IGNOREMXCNAME) == 0) { + dns_zone_log(zone, ISC_LOG_WARNING, + "%s/MX '%s' (out of zone) " + "is a CNAME (illegal)", + ownerbuf, namebuf); + if (level == ISC_LOG_ERROR) + answer = ISC_FALSE; + } + } + freeaddrinfo(ai); + return (answer); + + case EAI_NONAME: +#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) + case EAI_NODATA: +#endif + dns_zone_log(zone, ISC_LOG_ERROR, "%s/MX '%s' (out of zone) " + "has no addresses records (A or AAAA)", + ownerbuf, namebuf); + /* XXX950 make fatal for 9.5.0. */ + return (ISC_TRUE); + + default: + dns_zone_log(zone, ISC_LOG_WARNING, + "getaddrinfo(%s) failed: %s", + namebuf, gai_strerror(result)); + return (ISC_TRUE); + } +#else + return (ISC_TRUE); +#endif +} + +static isc_boolean_t +checksrv(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) { +#ifdef USE_GETADDRINFO + struct addrinfo hints, *ai, *cur; + char namebuf[DNS_NAME_FORMATSIZE + 1]; + char ownerbuf[DNS_NAME_FORMATSIZE]; + int result; + int level = ISC_LOG_ERROR; + isc_boolean_t answer = ISC_TRUE; + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_CANONNAME; + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + dns_name_format(name, namebuf, sizeof(namebuf) - 1); + /* + * Turn off search. + */ + if (dns_name_countlabels(name) > 1U) + strcat(namebuf, "."); + dns_name_format(owner, ownerbuf, sizeof(ownerbuf)); + + result = getaddrinfo(namebuf, NULL, &hints, &ai); + dns_name_format(name, namebuf, sizeof(namebuf) - 1); + switch (result) { + case 0: + /* + * Work around broken getaddrinfo() implementations that + * fail to set ai_canonname on first entry. + */ + cur = ai; + while (cur != NULL && cur->ai_canonname == NULL && + cur->ai_next != NULL) + cur = cur->ai_next; + if (cur != NULL && cur->ai_canonname != NULL && + strcasecmp(cur->ai_canonname, namebuf) != 0) { + if ((zone_options & DNS_ZONEOPT_WARNSRVCNAME) != 0) + level = ISC_LOG_WARNING; + if ((zone_options & DNS_ZONEOPT_IGNORESRVCNAME) == 0) { + dns_zone_log(zone, level, + "%s/SRV '%s' (out of zone) " + "is a CNAME (illegal)", + ownerbuf, namebuf); + if (level == ISC_LOG_ERROR) + answer = ISC_FALSE; + } + } + freeaddrinfo(ai); + return (answer); + + case EAI_NONAME: +#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) + case EAI_NODATA: +#endif + dns_zone_log(zone, ISC_LOG_ERROR, "%s/SRV '%s' (out of zone) " + "has no addresses records (A or AAAA)", + ownerbuf, namebuf); + /* XXX950 make fatal for 9.5.0. */ + return (ISC_TRUE); + + default: + dns_zone_log(zone, ISC_LOG_WARNING, + "getaddrinfo(%s) failed: %s", + namebuf, gai_strerror(result)); + return (ISC_TRUE); + } +#else + return (ISC_TRUE); +#endif +} + +isc_result_t +setup_logging(isc_mem_t *mctx, isc_log_t **logp) { + isc_logdestination_t destination; + isc_logconfig_t *logconfig = NULL; + isc_log_t *log = NULL; + + RUNTIME_CHECK(isc_log_create(mctx, &log, &logconfig) == ISC_R_SUCCESS); + isc_log_registercategories(log, categories); + isc_log_setcontext(log); + dns_log_init(log); + dns_log_setcontext(log); + cfg_log_init(log); + + destination.file.stream = stdout; + destination.file.name = NULL; + destination.file.versions = ISC_LOG_ROLLNEVER; + destination.file.maximum_size = 0; + RUNTIME_CHECK(isc_log_createchannel(logconfig, "stderr", + ISC_LOG_TOFILEDESC, + ISC_LOG_DYNAMIC, + &destination, 0) == ISC_R_SUCCESS); + RUNTIME_CHECK(isc_log_usechannel(logconfig, "stderr", + NULL, NULL) == ISC_R_SUCCESS); + + *logp = log; + return (ISC_R_SUCCESS); +} + +/*% load the zone */ +isc_result_t +load_zone(isc_mem_t *mctx, const char *zonename, const char *filename, + dns_masterformat_t fileformat, const char *classname, + dns_zone_t **zonep) +{ + isc_result_t result; + dns_rdataclass_t rdclass; + isc_textregion_t region; + isc_buffer_t buffer; + dns_fixedname_t fixorigin; + dns_name_t *origin; + dns_zone_t *zone = NULL; + + REQUIRE(zonep == NULL || *zonep == NULL); + + if (debug) + fprintf(stderr, "loading \"%s\" from \"%s\" class \"%s\"\n", + zonename, filename, classname); + + CHECK(dns_zone_create(&zone, mctx)); + + dns_zone_settype(zone, dns_zone_master); + + isc_buffer_init(&buffer, zonename, strlen(zonename)); + isc_buffer_add(&buffer, strlen(zonename)); + dns_fixedname_init(&fixorigin); + origin = dns_fixedname_name(&fixorigin); + CHECK(dns_name_fromtext(origin, &buffer, dns_rootname, + ISC_FALSE, NULL)); + CHECK(dns_zone_setorigin(zone, origin)); + CHECK(dns_zone_setdbtype(zone, 1, (const char * const *) dbtype)); + CHECK(dns_zone_setfile2(zone, filename, fileformat)); + + DE_CONST(classname, region.base); + region.length = strlen(classname); + CHECK(dns_rdataclass_fromtext(&rdclass, ®ion)); + + dns_zone_setclass(zone, rdclass); + dns_zone_setoption(zone, zone_options, ISC_TRUE); + dns_zone_setoption(zone, DNS_ZONEOPT_NOMERGE, nomerge); + if (docheckmx) + dns_zone_setcheckmx(zone, checkmx); + if (docheckns) + dns_zone_setcheckns(zone, checkns); + if (dochecksrv) + dns_zone_setchecksrv(zone, checksrv); + + CHECK(dns_zone_load(zone)); + if (zonep != NULL) { + *zonep = zone; + zone = NULL; + } + + cleanup: + if (zone != NULL) + dns_zone_detach(&zone); + return (result); +} + +/*% 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) +{ + isc_result_t result; + FILE *output = stdout; + + if (debug) { + if (filename != NULL) + fprintf(stderr, "dumping \"%s\" to \"%s\"\n", + zonename, filename); + else + fprintf(stderr, "dumping \"%s\"\n", zonename); + } + + if (filename != NULL) { + result = isc_stdio_open(filename, "w+", &output); + + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "could not open output " + "file \"%s\" for writing\n", filename); + return (ISC_R_FAILURE); + } + } + + result = dns_zone_dumptostream2(zone, output, fileformat, style); + + if (filename != NULL) + (void)isc_stdio_close(output); + + return (result); +} diff --git a/bin/check/check-tool.h b/bin/check/check-tool.h new file mode 100644 index 0000000..ef9017f --- /dev/null +++ b/bin/check/check-tool.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000-2002 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: check-tool.h,v 1.7.18.4 2005/06/20 01:19:25 marka Exp $ */ + +#ifndef CHECK_TOOL_H +#define CHECK_TOOL_H + +/*! \file */ + +#include +#include + +#include +#include + +ISC_LANG_BEGINDECLS + +isc_result_t +setup_logging(isc_mem_t *mctx, isc_log_t **logp); + +isc_result_t +load_zone(isc_mem_t *mctx, const char *zonename, const char *filename, + dns_masterformat_t fileformat, const char *classname, + dns_zone_t **zonep); + +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); + +extern int debug; +extern isc_boolean_t nomerge; +extern isc_boolean_t docheckmx; +extern isc_boolean_t docheckns; +extern isc_boolean_t dochecksrv; +extern unsigned int zone_options; + +ISC_LANG_ENDDECLS + +#endif diff --git a/bin/check/named-checkconf.8 b/bin/check/named-checkconf.8 new file mode 100644 index 0000000..364e6b9 --- /dev/null +++ b/bin/check/named-checkconf.8 @@ -0,0 +1,89 @@ +.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2000-2002 Internet Software Consortium. +.\" +.\" Permission to use, copy, modify, and 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: named-checkconf.8,v 1.16.18.13 2007/06/20 02:26:58 marka Exp $ +.\" +.hy 0 +.ad l +.\" Title: named\-checkconf +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.71.1 +.\" Date: June 14, 2000 +.\" Manual: BIND9 +.\" Source: BIND9 +.\" +.TH "NAMED\-CHECKCONF" "8" "June 14, 2000" "BIND9" "BIND9" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +named\-checkconf \- named configuration file syntax checking tool +.SH "SYNOPSIS" +.HP 16 +\fBnamed\-checkconf\fR [\fB\-v\fR] [\fB\-j\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] {filename} [\fB\-z\fR] +.SH "DESCRIPTION" +.PP +\fBnamed\-checkconf\fR +checks the syntax, but not the semantics, of a named configuration file. +.SH "OPTIONS" +.PP +\-t \fIdirectory\fR +.RS 4 +Chroot to +\fIdirectory\fR +so that include directives in the configuration file are processed as if run by a similarly chrooted named. +.RE +.PP +\-v +.RS 4 +Print the version of the +\fBnamed\-checkconf\fR +program and exit. +.RE +.PP +\-z +.RS 4 +Perform a test load of all master zones found in +\fInamed.conf\fR. +.RE +.PP +\-j +.RS 4 +When loading a zonefile read the journal if it exists. +.RE +.PP +filename +.RS 4 +The name of the configuration file to be checked. If not specified, it defaults to +\fI/etc/named.conf\fR. +.RE +.SH "RETURN VALUES" +.PP +\fBnamed\-checkconf\fR +returns an exit status of 1 if errors were detected and 0 otherwise. +.SH "SEE ALSO" +.PP +\fBnamed\fR(8), +\fBnamed\-checkzone\fR(8), +BIND 9 Administrator Reference Manual. +.SH "AUTHOR" +.PP +Internet Systems Consortium +.SH "COPYRIGHT" +Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") +.br +Copyright \(co 2000\-2002 Internet Software Consortium. +.br diff --git a/bin/check/named-checkconf.c b/bin/check/named-checkconf.c new file mode 100644 index 0000000..cc63153 --- /dev/null +++ b/bin/check/named-checkconf.c @@ -0,0 +1,488 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2002 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: named-checkconf.c,v 1.28.18.14 2006/02/28 03:10:47 marka Exp $ */ + +/*! \file */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#include "check-tool.h" + +isc_log_t *logc = NULL; + +#define CHECK(r)\ + do { \ + result = (r); \ + if (result != ISC_R_SUCCESS) \ + goto cleanup; \ + } while (0) + +/*% usage */ +static void +usage(void) { + fprintf(stderr, "usage: named-checkconf [-j] [-v] [-z] [-t directory] " + "[named.conf]\n"); + exit(1); +} + +/*% directory callback */ +static isc_result_t +directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) { + isc_result_t result; + const char *directory; + + REQUIRE(strcasecmp("directory", clausename) == 0); + + UNUSED(arg); + UNUSED(clausename); + + /* + * Change directory. + */ + directory = cfg_obj_asstring(obj); + result = isc_dir_chdir(directory); + if (result != ISC_R_SUCCESS) { + cfg_obj_log(obj, logc, ISC_LOG_ERROR, + "change directory to '%s' failed: %s\n", + directory, isc_result_totext(result)); + return (result); + } + + return (ISC_R_SUCCESS); +} + +static isc_boolean_t +get_maps(const cfg_obj_t **maps, const char *name, const cfg_obj_t **obj) { + int i; + for (i = 0;; i++) { + if (maps[i] == NULL) + return (ISC_FALSE); + if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS) + return (ISC_TRUE); + } +} + +static isc_boolean_t +get_checknames(const cfg_obj_t **maps, const cfg_obj_t **obj) { + const cfg_listelt_t *element; + const cfg_obj_t *checknames; + const cfg_obj_t *type; + const cfg_obj_t *value; + isc_result_t result; + int i; + + for (i = 0;; i++) { + if (maps[i] == NULL) + return (ISC_FALSE); + checknames = NULL; + result = cfg_map_get(maps[i], "check-names", &checknames); + if (result != ISC_R_SUCCESS) + continue; + if (checknames != NULL && !cfg_obj_islist(checknames)) { + *obj = checknames; + return (ISC_TRUE); + } + for (element = cfg_list_first(checknames); + element != NULL; + element = cfg_list_next(element)) { + value = cfg_listelt_value(element); + type = cfg_tuple_get(value, "type"); + if (strcasecmp(cfg_obj_asstring(type), "master") != 0) + continue; + *obj = cfg_tuple_get(value, "mode"); + return (ISC_TRUE); + } + } +} + +static isc_result_t +config_get(const cfg_obj_t **maps, const char *name, const cfg_obj_t **obj) { + int i; + + for (i = 0;; i++) { + if (maps[i] == NULL) + return (ISC_R_NOTFOUND); + if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS) + return (ISC_R_SUCCESS); + } +} + +/*% configure the zone */ +static isc_result_t +configure_zone(const char *vclass, const char *view, + const cfg_obj_t *zconfig, const cfg_obj_t *vconfig, + const cfg_obj_t *config, isc_mem_t *mctx) +{ + int i = 0; + isc_result_t result; + const char *zclass; + const char *zname; + const char *zfile; + const cfg_obj_t *maps[4]; + const cfg_obj_t *zoptions = NULL; + const cfg_obj_t *classobj = NULL; + const cfg_obj_t *typeobj = NULL; + const cfg_obj_t *fileobj = NULL; + const cfg_obj_t *dbobj = NULL; + const cfg_obj_t *obj = NULL; + const cfg_obj_t *fmtobj = NULL; + dns_masterformat_t masterformat; + + zone_options = DNS_ZONEOPT_CHECKNS | DNS_ZONEOPT_MANYERRORS; + + zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); + classobj = cfg_tuple_get(zconfig, "class"); + if (!cfg_obj_isstring(classobj)) + zclass = vclass; + else + zclass = cfg_obj_asstring(classobj); + + zoptions = cfg_tuple_get(zconfig, "options"); + maps[i++] = zoptions; + if (vconfig != NULL) + maps[i++] = cfg_tuple_get(vconfig, "options"); + if (config != NULL) { + cfg_map_get(config, "options", &obj); + if (obj != NULL) + maps[i++] = obj; + } + maps[i++] = NULL; + + cfg_map_get(zoptions, "type", &typeobj); + if (typeobj == NULL) + return (ISC_R_FAILURE); + if (strcasecmp(cfg_obj_asstring(typeobj), "master") != 0) + return (ISC_R_SUCCESS); + cfg_map_get(zoptions, "database", &dbobj); + if (dbobj != NULL) + return (ISC_R_SUCCESS); + cfg_map_get(zoptions, "file", &fileobj); + if (fileobj == NULL) + return (ISC_R_FAILURE); + zfile = cfg_obj_asstring(fileobj); + + obj = NULL; + if (get_maps(maps, "check-mx", &obj)) { + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + zone_options |= DNS_ZONEOPT_CHECKMX; + zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; + } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { + zone_options |= DNS_ZONEOPT_CHECKMX; + zone_options |= DNS_ZONEOPT_CHECKMXFAIL; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + zone_options &= ~DNS_ZONEOPT_CHECKMX; + zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; + } else + INSIST(0); + } else { + zone_options |= DNS_ZONEOPT_CHECKMX; + zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; + } + + obj = NULL; + if (get_maps(maps, "check-integrity", &obj)) { + if (cfg_obj_asboolean(obj)) + zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; + else + zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY; + } + + obj = NULL; + if (get_maps(maps, "check-mx-cname", &obj)) { + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + zone_options |= DNS_ZONEOPT_WARNMXCNAME; + zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; + } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { + zone_options &= ~DNS_ZONEOPT_WARNMXCNAME; + zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + zone_options |= DNS_ZONEOPT_WARNMXCNAME; + zone_options |= DNS_ZONEOPT_IGNOREMXCNAME; + } else + INSIST(0); + } else { + zone_options |= DNS_ZONEOPT_WARNMXCNAME; + zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; + } + + obj = NULL; + if (get_maps(maps, "check-srv-cname", &obj)) { + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + zone_options |= DNS_ZONEOPT_WARNSRVCNAME; + zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; + } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { + zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME; + zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + zone_options |= DNS_ZONEOPT_WARNSRVCNAME; + zone_options |= DNS_ZONEOPT_IGNORESRVCNAME; + } else + INSIST(0); + } else { + zone_options |= DNS_ZONEOPT_WARNSRVCNAME; + zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; + } + + obj = NULL; + if (get_maps(maps, "check-sibling", &obj)) { + if (cfg_obj_asboolean(obj)) + zone_options |= DNS_ZONEOPT_CHECKSIBLING; + else + zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; + } + + obj = NULL; + if (get_checknames(maps, &obj)) { + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + zone_options |= DNS_ZONEOPT_CHECKNAMES; + zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; + } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { + zone_options |= DNS_ZONEOPT_CHECKNAMES; + zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + zone_options &= ~DNS_ZONEOPT_CHECKNAMES; + zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; + } else + INSIST(0); + } else { + zone_options |= DNS_ZONEOPT_CHECKNAMES; + zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL; + } + + masterformat = dns_masterformat_text; + fmtobj = NULL; + result = config_get(maps, "masterfile-format", &fmtobj); + if (result == ISC_R_SUCCESS) { + const char *masterformatstr = cfg_obj_asstring(fmtobj); + if (strcasecmp(masterformatstr, "text") == 0) + masterformat = dns_masterformat_text; + else if (strcasecmp(masterformatstr, "raw") == 0) + masterformat = dns_masterformat_raw; + else + INSIST(0); + } + + result = load_zone(mctx, zname, zfile, masterformat, zclass, NULL); + if (result != ISC_R_SUCCESS) + fprintf(stderr, "%s/%s/%s: %s\n", view, zname, zclass, + dns_result_totext(result)); + return(result); +} + +/*% configure a view */ +static isc_result_t +configure_view(const char *vclass, const char *view, const cfg_obj_t *config, + const cfg_obj_t *vconfig, isc_mem_t *mctx) +{ + const cfg_listelt_t *element; + const cfg_obj_t *voptions; + const cfg_obj_t *zonelist; + isc_result_t result = ISC_R_SUCCESS; + isc_result_t tresult; + + voptions = NULL; + if (vconfig != NULL) + voptions = cfg_tuple_get(vconfig, "options"); + + zonelist = NULL; + if (voptions != NULL) + (void)cfg_map_get(voptions, "zone", &zonelist); + else + (void)cfg_map_get(config, "zone", &zonelist); + + for (element = cfg_list_first(zonelist); + element != NULL; + element = cfg_list_next(element)) + { + const cfg_obj_t *zconfig = cfg_listelt_value(element); + tresult = configure_zone(vclass, view, zconfig, vconfig, + config, mctx); + if (tresult != ISC_R_SUCCESS) + result = tresult; + } + return (result); +} + + +/*% load zones from the configuration */ +static isc_result_t +load_zones_fromconfig(const cfg_obj_t *config, isc_mem_t *mctx) { + const cfg_listelt_t *element; + const cfg_obj_t *classobj; + const cfg_obj_t *views; + const cfg_obj_t *vconfig; + const char *vclass; + isc_result_t result = ISC_R_SUCCESS; + isc_result_t tresult; + + views = NULL; + + (void)cfg_map_get(config, "view", &views); + for (element = cfg_list_first(views); + element != NULL; + element = cfg_list_next(element)) + { + const char *vname; + + vclass = "IN"; + vconfig = cfg_listelt_value(element); + if (vconfig != NULL) { + classobj = cfg_tuple_get(vconfig, "class"); + if (cfg_obj_isstring(classobj)) + vclass = cfg_obj_asstring(classobj); + } + vname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name")); + tresult = configure_view(vclass, vname, config, vconfig, mctx); + if (tresult != ISC_R_SUCCESS) + result = tresult; + } + + if (views == NULL) { + tresult = configure_view("IN", "_default", config, NULL, mctx); + if (tresult != ISC_R_SUCCESS) + result = tresult; + } + return (result); +} + +/*% The main processing routine */ +int +main(int argc, char **argv) { + int c; + cfg_parser_t *parser = NULL; + cfg_obj_t *config = NULL; + const char *conffile = NULL; + isc_mem_t *mctx = NULL; + isc_result_t result; + int exit_status = 0; + isc_entropy_t *ectx = NULL; + isc_boolean_t load_zones = ISC_FALSE; + + while ((c = isc_commandline_parse(argc, argv, "djt:vz")) != EOF) { + switch (c) { + case 'd': + debug++; + break; + + case 'j': + nomerge = ISC_FALSE; + break; + + case 't': + result = isc_dir_chroot(isc_commandline_argument); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "isc_dir_chroot: %s\n", + isc_result_totext(result)); + exit(1); + } + result = isc_dir_chdir("/"); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "isc_dir_chdir: %s\n", + isc_result_totext(result)); + exit(1); + } + break; + + case 'v': + printf(VERSION "\n"); + exit(0); + + case 'z': + load_zones = ISC_TRUE; + docheckmx = ISC_FALSE; + docheckns = ISC_FALSE; + dochecksrv = ISC_FALSE; + break; + + default: + usage(); + } + } + + if (argv[isc_commandline_index] != NULL) + conffile = argv[isc_commandline_index]; + if (conffile == NULL || conffile[0] == '\0') + conffile = NAMED_CONFFILE; + + RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); + + RUNTIME_CHECK(setup_logging(mctx, &logc) == ISC_R_SUCCESS); + + RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS); + RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE) + == ISC_R_SUCCESS); + + dns_result_register(); + + RUNTIME_CHECK(cfg_parser_create(mctx, logc, &parser) == ISC_R_SUCCESS); + + cfg_parser_setcallback(parser, directory_callback, NULL); + + if (cfg_parse_file(parser, conffile, &cfg_type_namedconf, &config) != + ISC_R_SUCCESS) + exit(1); + + result = bind9_check_namedconf(config, logc, mctx); + if (result != ISC_R_SUCCESS) + exit_status = 1; + + if (result == ISC_R_SUCCESS && load_zones) { + result = load_zones_fromconfig(config, mctx); + if (result != ISC_R_SUCCESS) + exit_status = 1; + } + + cfg_obj_destroy(parser, &config); + + cfg_parser_destroy(&parser); + + dns_name_destroy(); + + isc_log_destroy(&logc); + + isc_hash_destroy(); + isc_entropy_detach(&ectx); + + isc_mem_destroy(&mctx); + + return (exit_status); +} diff --git a/bin/check/named-checkconf.docbook b/bin/check/named-checkconf.docbook new file mode 100644 index 0000000..af7a73d --- /dev/null +++ b/bin/check/named-checkconf.docbook @@ -0,0 +1,161 @@ +]> + + + + + + June 14, 2000 + + + + named-checkconf + 8 + BIND9 + + + + + 2004 + 2005 + 2007 + Internet Systems Consortium, Inc. ("ISC") + + + 2000 + 2001 + 2002 + Internet Software Consortium. + + + + + named-checkconf + named configuration file syntax checking tool + + + + + named-checkconf + + + + filename + + + + + + DESCRIPTION + named-checkconf + checks the syntax, but not the semantics, of a named + configuration file. + + + + + OPTIONS + + + + -t directory + + + Chroot to directory so that + include + directives in the configuration file are processed as if + run by a similarly chrooted named. + + + + + + -v + + + Print the version of the named-checkconf + program and exit. + + + + + + -z + + + Perform a test load of all master zones found in + named.conf. + + + + + + -j + + + When loading a zonefile read the journal if it exists. + + + + + + filename + + + The name of the configuration file to be checked. If not + specified, it defaults to /etc/named.conf. + + + + + + + + + + RETURN VALUES + named-checkconf + returns an exit status of 1 if + errors were detected and 0 otherwise. + + + + + SEE ALSO + + named8 + , + + named-checkzone8 + , + BIND 9 Administrator Reference Manual. + + + + + AUTHOR + Internet Systems Consortium + + + + diff --git a/bin/check/named-checkconf.html b/bin/check/named-checkconf.html new file mode 100644 index 0000000..910df0d --- /dev/null +++ b/bin/check/named-checkconf.html @@ -0,0 +1,92 @@ + + + + + +named-checkconf + + +
+
+
+

Name

+

named-checkconf — named configuration file syntax checking tool

+
+
+

Synopsis

+

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

+
+
+

DESCRIPTION

+

named-checkconf + checks the syntax, but not the semantics, of a named + configuration file. +

+
+
+

OPTIONS

+
+
-t directory
+

+ Chroot to directory so that + include + directives in the configuration file are processed as if + run by a similarly chrooted named. +

+
-v
+

+ Print the version of the named-checkconf + program and exit. +

+
-z
+

+ Perform a test load of all master zones found in + named.conf. +

+
-j
+

+ When loading a zonefile read the journal if it exists. +

+
filename
+

+ The name of the configuration file to be checked. If not + specified, it defaults to /etc/named.conf. +

+
+
+
+

RETURN VALUES

+

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

+
+
+

SEE ALSO

+

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

+
+
+

AUTHOR

+

Internet Systems Consortium +

+
+
+ diff --git a/bin/check/named-checkzone.8 b/bin/check/named-checkzone.8 new file mode 100644 index 0000000..bd538ac --- /dev/null +++ b/bin/check/named-checkzone.8 @@ -0,0 +1,269 @@ +.\" Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2000-2002 Internet Software Consortium. +.\" +.\" Permission to use, copy, modify, and 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: named-checkzone.8,v 1.18.18.23 2007/06/20 02:26:58 marka Exp $ +.\" +.hy 0 +.ad l +.\" Title: named\-checkzone +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.71.1 +.\" Date: June 13, 2000 +.\" Manual: BIND9 +.\" Source: BIND9 +.\" +.TH "NAMED\-CHECKZONE" "8" "June 13, 2000" "BIND9" "BIND9" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +named\-checkzone, named\-compilezone \- zone file validity checking or converting tool +.SH "SYNOPSIS" +.HP 16 +\fBnamed\-checkzone\fR [\fB\-d\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\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-S\ \fR\fB\fImode\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\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\-o\ \fR\fB\fIfilename\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {zonename} {filename} +.SH "DESCRIPTION" +.PP +\fBnamed\-checkzone\fR +checks the syntax and integrity of a zone file. It performs the same checks as +\fBnamed\fR +does when loading a zone. This makes +\fBnamed\-checkzone\fR +useful for checking zone files before configuring them into a name server. +.PP +\fBnamed\-compilezone\fR +is similar to +\fBnamed\-checkzone\fR, but it always dumps the zone contents to a specified file in a specified format. Additionally, it applies stricter check levels by default, since the dump output will be used as an actual zone file loaded by +\fBnamed\fR. When manually specified otherwise, the check levels must at least be as strict as those specified in the +\fBnamed\fR +configuration file. +.SH "OPTIONS" +.PP +\-d +.RS 4 +Enable debugging. +.RE +.PP +\-q +.RS 4 +Quiet mode \- exit code only. +.RE +.PP +\-v +.RS 4 +Print the version of the +\fBnamed\-checkzone\fR +program and exit. +.RE +.PP +\-j +.RS 4 +When loading the zone file read the journal if it exists. +.RE +.PP +\-c \fIclass\fR +.RS 4 +Specify the class of the zone. If not specified "IN" is assumed. +.RE +.PP +\-i \fImode\fR +.RS 4 +Perform post\-load zone integrity checks. Possible modes are +\fB"full"\fR +(default), +\fB"full\-sibling"\fR, +\fB"local"\fR, +\fB"local\-sibling"\fR +and +\fB"none"\fR. +.sp +Mode +\fB"full"\fR +checks that MX records refer to A or AAAA record (both in\-zone and out\-of\-zone hostnames). Mode +\fB"local"\fR +only checks MX records which refer to in\-zone hostnames. +.sp +Mode +\fB"full"\fR +checks that SRV records refer to A or AAAA record (both in\-zone and out\-of\-zone hostnames). Mode +\fB"local"\fR +only checks SRV records which refer to in\-zone hostnames. +.sp +Mode +\fB"full"\fR +checks that delegation NS records refer to A or AAAA record (both in\-zone and out\-of\-zone hostnames). It also checks that glue address records in the zone match those advertised by the child. Mode +\fB"local"\fR +only checks NS records which refer to in\-zone hostnames or that some required glue exists, that is when the nameserver is in a child zone. +.sp +Mode +\fB"full\-sibling"\fR +and +\fB"local\-sibling"\fR +disable sibling glue checks but are otherwise the same as +\fB"full"\fR +and +\fB"local"\fR +respectively. +.sp +Mode +\fB"none"\fR +disables the checks. +.RE +.PP +\-f \fIformat\fR +.RS 4 +Specify the format of the zone file. Possible formats are +\fB"text"\fR +(default) and +\fB"raw"\fR. +.RE +.PP +\-F \fIformat\fR +.RS 4 +Specify the format of the output file specified. 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. +.RE +.PP +\-k \fImode\fR +.RS 4 +Perform +\fB"check\-names"\fR +checks with the specified failure mode. Possible modes are +\fB"fail"\fR +(default for +\fBnamed\-compilezone\fR), +\fB"warn"\fR +(default for +\fBnamed\-checkzone\fR) and +\fB"ignore"\fR. +.RE +.PP +\-m \fImode\fR +.RS 4 +Specify whether MX records should be checked to see if they are addresses. Possible modes are +\fB"fail"\fR, +\fB"warn"\fR +(default) and +\fB"ignore"\fR. +.RE +.PP +\-M \fImode\fR +.RS 4 +Check if a MX record refers to a CNAME. Possible modes are +\fB"fail"\fR, +\fB"warn"\fR +(default) and +\fB"ignore"\fR. +.RE +.PP +\-n \fImode\fR +.RS 4 +Specify whether NS records should be checked to see if they are addresses. Possible modes are +\fB"fail"\fR +(default for +\fBnamed\-compilezone\fR), +\fB"warn"\fR +(default for +\fBnamed\-checkzone\fR) and +\fB"ignore"\fR. +.RE +.PP +\-o \fIfilename\fR +.RS 4 +Write zone output to +\fIfilename\fR. This is mandatory for +\fBnamed\-compilezone\fR. +.RE +.PP +\-s \fIstyle\fR +.RS 4 +Specify the style of the dumped zone file. Possible styles are +\fB"full"\fR +(default) and +\fB"relative"\fR. The full format is most suitable for processing automatically by a separate script. On the other hand, the relative format is more human\-readable and is thus suitable for editing by hand. For +\fBnamed\-checkzone\fR +this does not cause any effects unless it dumps the zone contents. It also does not have any meaning if the output format is not text. +.RE +.PP +\-S \fImode\fR +.RS 4 +Check if a SRV record refers to a CNAME. Possible modes are +\fB"fail"\fR, +\fB"warn"\fR +(default) and +\fB"ignore"\fR. +.RE +.PP +\-t \fIdirectory\fR +.RS 4 +Chroot to +\fIdirectory\fR +so that include directives in the configuration file are processed as if run by a similarly chrooted named. +.RE +.PP +\-w \fIdirectory\fR +.RS 4 +chdir to +\fIdirectory\fR +so that relative filenames in master file $INCLUDE directives work. This is similar to the directory clause in +\fInamed.conf\fR. +.RE +.PP +\-D +.RS 4 +Dump zone file in canonical format. This is always enabled for +\fBnamed\-compilezone\fR. +.RE +.PP +\-W \fImode\fR +.RS 4 +Specify whether to check for non\-terminal wildcards. Non\-terminal wildcards are almost always the result of a failure to understand the wildcard matching algorithm (RFC 1034). Possible modes are +\fB"warn"\fR +(default) and +\fB"ignore"\fR. +.RE +.PP +zonename +.RS 4 +The domain name of the zone being checked. +.RE +.PP +filename +.RS 4 +The name of the zone file. +.RE +.SH "RETURN VALUES" +.PP +\fBnamed\-checkzone\fR +returns an exit status of 1 if errors were detected and 0 otherwise. +.SH "SEE ALSO" +.PP +\fBnamed\fR(8), +\fBnamed\-checkconf\fR(8), +RFC 1035, +BIND 9 Administrator Reference Manual. +.SH "AUTHOR" +.PP +Internet Systems Consortium +.SH "COPYRIGHT" +Copyright \(co 2004\-2007 Internet Systems Consortium, Inc. ("ISC") +.br +Copyright \(co 2000\-2002 Internet Software Consortium. +.br diff --git a/bin/check/named-checkzone.c b/bin/check/named-checkzone.c new file mode 100644 index 0000000..08e958e --- /dev/null +++ b/bin/check/named-checkzone.c @@ -0,0 +1,429 @@ +/* + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-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: named-checkzone.c,v 1.29.18.19 2007/08/28 07:19:55 tbox Exp $ */ + +/*! \file */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "check-tool.h" + +static int quiet = 0; +static isc_mem_t *mctx = NULL; +static isc_entropy_t *ectx = NULL; +dns_zone_t *zone = NULL; +dns_zonetype_t zonetype = dns_zone_master; +static int dumpzone = 0; +static const char *output_filename; +static char *prog_name = NULL; +static const dns_master_style_t *outputstyle = NULL; +static enum { progmode_check, progmode_compile } progmode; + +#define ERRRET(result, function) \ + do { \ + if (result != ISC_R_SUCCESS) { \ + if (!quiet) \ + fprintf(stderr, "%s() returned %s\n", \ + function, dns_result_totext(result)); \ + return (result); \ + } \ + } while (0) + +static void +usage(void) { + fprintf(stderr, + "usage: %s [-djqvD] [-c class] [-o output] " + "[-f inputformat] [-F outputformat] " + "[-t directory] [-w directory] [-k (ignore|warn|fail)] " + "[-n (ignore|warn|fail)] [-m (ignore|warn|fail)] " + "[-i (full|local|none)] [-M (ignore|warn|fail)] " + "[-S (ignore|warn|fail)] [-W (ignore|warn)] " + "zonename filename\n", prog_name); + exit(1); +} + +static void +destroy(void) { + if (zone != NULL) + dns_zone_detach(&zone); + dns_name_destroy(); +} + +/*% main processing routine */ +int +main(int argc, char **argv) { + int c; + char *origin = NULL; + char *filename = NULL; + isc_log_t *lctx = NULL; + isc_result_t result; + char classname_in[] = "IN"; + char *classname = classname_in; + const char *workdir = NULL; + const char *inputformatstr = NULL; + const char *outputformatstr = NULL; + dns_masterformat_t inputformat = dns_masterformat_text; + dns_masterformat_t outputformat = dns_masterformat_text; + + outputstyle = &dns_master_style_full; + + prog_name = strrchr(argv[0], '/'); + if (prog_name == NULL) + prog_name = strrchr(argv[0], '\\'); + if (prog_name != NULL) + prog_name++; + else + prog_name = argv[0]; + /* + * Libtool doesn't preserve the program name prior to final + * installation. Remove the libtool prefix ("lt-"). + */ + if (strncmp(prog_name, "lt-", 3) == 0) + prog_name += 3; + if (strcmp(prog_name, "named-checkzone") == 0) + progmode = progmode_check; + else if (strcmp(prog_name, "named-compilezone") == 0) + progmode = progmode_compile; + else + INSIST(0); + + /* Compilation specific defaults */ + if (progmode == progmode_compile) { + zone_options |= (DNS_ZONEOPT_CHECKNS | + DNS_ZONEOPT_FATALNS | + DNS_ZONEOPT_CHECKNAMES | + DNS_ZONEOPT_CHECKNAMESFAIL | + DNS_ZONEOPT_CHECKWILDCARD); + } + +#define ARGCMP(X) (strcmp(isc_commandline_argument, X) == 0) + + while ((c = isc_commandline_parse(argc, argv, + "c:df:i:jk:m:n:qs:t:o:vw:DF:M:S:W:")) + != EOF) { + switch (c) { + case 'c': + classname = isc_commandline_argument; + break; + + case 'd': + debug++; + break; + + case 'i': + if (ARGCMP("full")) { + zone_options |= DNS_ZONEOPT_CHECKINTEGRITY | + DNS_ZONEOPT_CHECKSIBLING; + docheckmx = ISC_TRUE; + docheckns = ISC_TRUE; + dochecksrv = ISC_TRUE; + } else if (ARGCMP("full-sibling")) { + zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; + zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; + docheckmx = ISC_TRUE; + docheckns = ISC_TRUE; + dochecksrv = ISC_TRUE; + } else if (ARGCMP("local")) { + zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; + zone_options |= DNS_ZONEOPT_CHECKSIBLING; + docheckmx = ISC_FALSE; + docheckns = ISC_FALSE; + dochecksrv = ISC_FALSE; + } else if (ARGCMP("local-sibling")) { + zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; + zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; + docheckmx = ISC_FALSE; + docheckns = ISC_FALSE; + dochecksrv = ISC_FALSE; + } else if (ARGCMP("none")) { + zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY; + zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; + docheckmx = ISC_FALSE; + docheckns = ISC_FALSE; + dochecksrv = ISC_FALSE; + } else { + fprintf(stderr, "invalid argument to -i: %s\n", + isc_commandline_argument); + exit(1); + } + break; + + case 'f': + inputformatstr = isc_commandline_argument; + break; + + case 'F': + outputformatstr = isc_commandline_argument; + break; + + case 'j': + nomerge = ISC_FALSE; + break; + + case 'k': + if (ARGCMP("warn")) { + zone_options |= DNS_ZONEOPT_CHECKNAMES; + zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; + } else if (ARGCMP("fail")) { + zone_options |= DNS_ZONEOPT_CHECKNAMES | + DNS_ZONEOPT_CHECKNAMESFAIL; + } else if (ARGCMP("ignore")) { + zone_options &= ~(DNS_ZONEOPT_CHECKNAMES | + DNS_ZONEOPT_CHECKNAMESFAIL); + } else { + fprintf(stderr, "invalid argument to -k: %s\n", + isc_commandline_argument); + exit(1); + } + break; + + case 'n': + if (ARGCMP("ignore")) { + zone_options &= ~(DNS_ZONEOPT_CHECKNS| + DNS_ZONEOPT_FATALNS); + } else if (ARGCMP("warn")) { + zone_options |= DNS_ZONEOPT_CHECKNS; + zone_options &= ~DNS_ZONEOPT_FATALNS; + } else if (ARGCMP("fail")) { + zone_options |= DNS_ZONEOPT_CHECKNS| + DNS_ZONEOPT_FATALNS; + } else { + fprintf(stderr, "invalid argument to -n: %s\n", + isc_commandline_argument); + exit(1); + } + break; + + case 'm': + if (ARGCMP("warn")) { + zone_options |= DNS_ZONEOPT_CHECKMX; + zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; + } else if (ARGCMP("fail")) { + zone_options |= DNS_ZONEOPT_CHECKMX | + DNS_ZONEOPT_CHECKMXFAIL; + } else if (ARGCMP("ignore")) { + zone_options &= ~(DNS_ZONEOPT_CHECKMX | + DNS_ZONEOPT_CHECKMXFAIL); + } else { + fprintf(stderr, "invalid argument to -m: %s\n", + isc_commandline_argument); + exit(1); + } + break; + + case 'q': + quiet++; + break; + + case 't': + result = isc_dir_chroot(isc_commandline_argument); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "isc_dir_chroot: %s: %s\n", + isc_commandline_argument, + isc_result_totext(result)); + exit(1); + } + result = isc_dir_chdir("/"); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "isc_dir_chdir: %s\n", + isc_result_totext(result)); + exit(1); + } + break; + + case 's': + if (ARGCMP("full")) + outputstyle = &dns_master_style_full; + else if (ARGCMP("relative")) { + outputstyle = &dns_master_style_default; + } else { + fprintf(stderr, + "unknown or unsupported style: %s\n", + isc_commandline_argument); + exit(1); + } + break; + + case 'o': + output_filename = isc_commandline_argument; + break; + + case 'v': + printf(VERSION "\n"); + exit(0); + + case 'w': + workdir = isc_commandline_argument; + break; + + case 'D': + dumpzone++; + break; + + case 'M': + if (ARGCMP("fail")) { + zone_options &= ~DNS_ZONEOPT_WARNMXCNAME; + zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; + } else if (ARGCMP("warn")) { + zone_options |= DNS_ZONEOPT_WARNMXCNAME; + zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; + } else if (ARGCMP("ignore")) { + zone_options |= DNS_ZONEOPT_WARNMXCNAME; + zone_options |= DNS_ZONEOPT_IGNOREMXCNAME; + } else { + fprintf(stderr, "invalid argument to -M: %s\n", + isc_commandline_argument); + exit(1); + } + break; + + case 'S': + if (ARGCMP("fail")) { + zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME; + zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; + } else if (ARGCMP("warn")) { + zone_options |= DNS_ZONEOPT_WARNSRVCNAME; + zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; + } else if (ARGCMP("ignore")) { + zone_options |= DNS_ZONEOPT_WARNSRVCNAME; + zone_options |= DNS_ZONEOPT_IGNORESRVCNAME; + } else { + fprintf(stderr, "invalid argument to -S: %s\n", + isc_commandline_argument); + exit(1); + } + break; + + case 'W': + if (ARGCMP("warn")) + zone_options |= DNS_ZONEOPT_CHECKWILDCARD; + else if (ARGCMP("ignore")) + zone_options &= ~DNS_ZONEOPT_CHECKWILDCARD; + break; + + default: + usage(); + } + } + + if (progmode == progmode_compile) { + dumpzone = 1; /* always dump */ + if (output_filename == NULL) { + fprintf(stderr, + "output file required, but not specified\n"); + usage(); + } + } + + if (workdir != NULL) { + result = isc_dir_chdir(workdir); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "isc_dir_chdir: %s: %s\n", + workdir, isc_result_totext(result)); + exit(1); + } + } + + if (inputformatstr != NULL) { + if (strcasecmp(inputformatstr, "text") == 0) + inputformat = dns_masterformat_text; + else if (strcasecmp(inputformatstr, "raw") == 0) + inputformat = dns_masterformat_raw; + else { + fprintf(stderr, "unknown file format: %s\n", + inputformatstr); + exit(1); + } + } + + if (outputformatstr != NULL) { + if (strcasecmp(outputformatstr, "text") == 0) + outputformat = dns_masterformat_text; + else if (strcasecmp(outputformatstr, "raw") == 0) + outputformat = dns_masterformat_raw; + else { + fprintf(stderr, "unknown file format: %s\n", + outputformatstr); + exit(1); + } + } + + if (isc_commandline_index + 2 > argc) + usage(); + + RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); + if (!quiet) + RUNTIME_CHECK(setup_logging(mctx, &lctx) == ISC_R_SUCCESS); + RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS); + RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE) + == ISC_R_SUCCESS); + + dns_result_register(); + + origin = argv[isc_commandline_index++]; + filename = argv[isc_commandline_index++]; + result = load_zone(mctx, origin, filename, inputformat, classname, + &zone); + + if (result == ISC_R_SUCCESS && dumpzone) { + if (!quiet && progmode == progmode_compile) { + fprintf(stdout, "dump zone to %s...", output_filename); + fflush(stdout); + } + result = dump_zone(origin, zone, output_filename, + outputformat, outputstyle); + if (!quiet && progmode == progmode_compile) + fprintf(stdout, "done\n"); + } + + if (!quiet && result == ISC_R_SUCCESS) + fprintf(stdout, "OK\n"); + destroy(); + if (lctx != NULL) + isc_log_destroy(&lctx); + isc_hash_destroy(); + isc_entropy_detach(&ectx); + isc_mem_destroy(&mctx); + return ((result == ISC_R_SUCCESS) ? 0 : 1); +} diff --git a/bin/check/named-checkzone.docbook b/bin/check/named-checkzone.docbook new file mode 100644 index 0000000..11b85ef --- /dev/null +++ b/bin/check/named-checkzone.docbook @@ -0,0 +1,443 @@ +]> + + + + + + June 13, 2000 + + + + named-checkzone + 8 + BIND9 + + + + + 2004 + 2005 + 2006 + 2007 + Internet Systems Consortium, Inc. ("ISC") + + + 2000 + 2001 + 2002 + Internet Software Consortium. + + + + + named-checkzone + named-compilezone + zone file validity checking or converting tool + + + + + named-checkzone + + + + + + + + + + + + + + + + + + + + zonename + filename + + + named-compilezone + + + + + + + + + + + + + + + + + + + zonename + filename + + + + + DESCRIPTION + named-checkzone + checks the syntax and integrity of a zone file. It performs the + same checks as named does when loading a + zone. This makes named-checkzone useful for + checking zone files before configuring them into a name server. + + + named-compilezone is similar to + named-checkzone, but it always dumps the + zone contents to a specified file in a specified format. + Additionally, it applies stricter check levels by default, + since the dump output will be used as an actual zone file + loaded by named. + When manually specified otherwise, the check levels must at + least be as strict as those specified in the + named configuration file. + + + + + OPTIONS + + + + -d + + + Enable debugging. + + + + + + -q + + + Quiet mode - exit code only. + + + + + + -v + + + Print the version of the named-checkzone + program and exit. + + + + + + -j + + + When loading the zone file read the journal if it exists. + + + + + + -c class + + + Specify the class of the zone. If not specified "IN" is assumed. + + + + + + -i mode + + + Perform post-load zone integrity checks. Possible modes are + "full" (default), + "full-sibling", + "local", + "local-sibling" and + "none". + + + Mode "full" checks that MX records + refer to A or AAAA record (both in-zone and out-of-zone + hostnames). Mode "local" only + checks MX records which refer to in-zone hostnames. + + + Mode "full" checks that SRV records + refer to A or AAAA record (both in-zone and out-of-zone + hostnames). Mode "local" only + checks SRV records which refer to in-zone hostnames. + + + Mode "full" checks that delegation NS + records refer to A or AAAA record (both in-zone and out-of-zone + hostnames). It also checks that glue address records + in the zone match those advertised by the child. + Mode "local" only checks NS records which + refer to in-zone hostnames or that some required glue exists, + that is when the nameserver is in a child zone. + + + Mode "full-sibling" and + "local-sibling" disable sibling glue + checks but are otherwise the same as "full" + and "local" respectively. + + + Mode "none" disables the checks. + + + + + + -f format + + + Specify the format of the zone file. + Possible formats are "text" (default) + 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. + + + + + + -k mode + + + Perform "check-names" checks with the + specified failure mode. + Possible modes are "fail" + (default for named-compilezone), + "warn" + (default for named-checkzone) and + "ignore". + + + + + + -m mode + + + Specify whether MX records should be checked to see if they + are addresses. Possible modes are "fail", + "warn" (default) and + "ignore". + + + + + + -M mode + + + Check if a MX record refers to a CNAME. + Possible modes are "fail", + "warn" (default) and + "ignore". + + + + + + -n mode + + + Specify whether NS records should be checked to see if they + are addresses. + Possible modes are "fail" + (default for named-compilezone), + "warn" + (default for named-checkzone) and + "ignore". + + + + + + -o filename + + + Write zone output to filename. + This is mandatory for named-compilezone. + + + + + + -s style + + + Specify the style of the dumped zone file. + Possible styles are "full" (default) + and "relative". + The full format is most suitable for processing + automatically by a separate script. + On the other hand, the relative format is more + human-readable and is thus suitable for editing by hand. + For named-checkzone + this does not cause any effects unless it dumps the zone + contents. + It also does not have any meaning if the output format + is not text. + + + + + + -S mode + + + Check if a SRV record refers to a CNAME. + Possible modes are "fail", + "warn" (default) and + "ignore". + + + + + + -t directory + + + Chroot to directory so that + include + directives in the configuration file are processed as if + run by a similarly chrooted named. + + + + + + -w directory + + + chdir to directory so that + relative + filenames in master file $INCLUDE directives work. This + is similar to the directory clause in + named.conf. + + + + + + -D + + + Dump zone file in canonical format. + This is always enabled for named-compilezone. + + + + + + -W mode + + + Specify whether to check for non-terminal wildcards. + Non-terminal wildcards are almost always the result of a + failure to understand the wildcard matching algorithm (RFC 1034). + Possible modes are "warn" (default) + and + "ignore". + + + + + + zonename + + + The domain name of the zone being checked. + + + + + + filename + + + The name of the zone file. + + + + + + + + + + RETURN VALUES + named-checkzone + returns an exit status of 1 if + errors were detected and 0 otherwise. + + + + + SEE ALSO + + named8 + , + + named-checkconf8 + , + RFC 1035, + BIND 9 Administrator Reference Manual. + + + + + AUTHOR + Internet Systems Consortium + + + + diff --git a/bin/check/named-checkzone.html b/bin/check/named-checkzone.html new file mode 100644 index 0000000..0e1015d --- /dev/null +++ b/bin/check/named-checkzone.html @@ -0,0 +1,256 @@ + + + + + +named-checkzone + + +
+
+
+

Name

+

named-checkzone, named-compilezone — zone file validity checking or converting tool

+
+
+

Synopsis

+

named-checkzone [-d] [-j] [-q] [-v] [-c class] [-f format] [-F format] [-i mode] [-k mode] [-m mode] [-M mode] [-n mode] [-o filename] [-s style] [-S mode] [-t directory] [-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] [-o filename] [-s style] [-t directory] [-w directory] [-D] [-W mode] {zonename} {filename}

+
+
+

DESCRIPTION

+

named-checkzone + checks the syntax and integrity of a zone file. It performs the + same checks as named does when loading a + zone. This makes named-checkzone useful for + checking zone files before configuring them into a name server. +

+

+ named-compilezone is similar to + named-checkzone, but it always dumps the + zone contents to a specified file in a specified format. + Additionally, it applies stricter check levels by default, + since the dump output will be used as an actual zone file + loaded by named. + When manually specified otherwise, the check levels must at + least be as strict as those specified in the + named configuration file. +

+
+
+

OPTIONS

+
+
-d
+

+ Enable debugging. +

+
-q
+

+ Quiet mode - exit code only. +

+
-v
+

+ Print the version of the named-checkzone + program and exit. +

+
-j
+

+ When loading the zone file read the journal if it exists. +

+
-c class
+

+ Specify the class of the zone. If not specified "IN" is assumed. +

+
-i mode
+
+

+ Perform post-load zone integrity checks. Possible modes are + "full" (default), + "full-sibling", + "local", + "local-sibling" and + "none". +

+

+ Mode "full" checks that MX records + refer to A or AAAA record (both in-zone and out-of-zone + hostnames). Mode "local" only + checks MX records which refer to in-zone hostnames. +

+

+ Mode "full" checks that SRV records + refer to A or AAAA record (both in-zone and out-of-zone + hostnames). Mode "local" only + checks SRV records which refer to in-zone hostnames. +

+

+ Mode "full" checks that delegation NS + records refer to A or AAAA record (both in-zone and out-of-zone + hostnames). It also checks that glue address records + in the zone match those advertised by the child. + Mode "local" only checks NS records which + refer to in-zone hostnames or that some required glue exists, + that is when the nameserver is in a child zone. +

+

+ Mode "full-sibling" and + "local-sibling" disable sibling glue + checks but are otherwise the same as "full" + and "local" respectively. +

+

+ Mode "none" disables the checks. +

+
+
-f format
+

+ Specify the format of the zone file. + Possible formats are "text" (default) + 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. +

+
-k mode
+

+ Perform "check-names" checks with the + specified failure mode. + Possible modes are "fail" + (default for named-compilezone), + "warn" + (default for named-checkzone) and + "ignore". +

+
-m mode
+

+ Specify whether MX records should be checked to see if they + are addresses. Possible modes are "fail", + "warn" (default) and + "ignore". +

+
-M mode
+

+ Check if a MX record refers to a CNAME. + Possible modes are "fail", + "warn" (default) and + "ignore". +

+
-n mode
+

+ Specify whether NS records should be checked to see if they + are addresses. + Possible modes are "fail" + (default for named-compilezone), + "warn" + (default for named-checkzone) and + "ignore". +

+
-o filename
+

+ Write zone output to filename. + This is mandatory for named-compilezone. +

+
-s style
+

+ Specify the style of the dumped zone file. + Possible styles are "full" (default) + and "relative". + The full format is most suitable for processing + automatically by a separate script. + On the other hand, the relative format is more + human-readable and is thus suitable for editing by hand. + For named-checkzone + this does not cause any effects unless it dumps the zone + contents. + It also does not have any meaning if the output format + is not text. +

+
-S mode
+

+ Check if a SRV record refers to a CNAME. + Possible modes are "fail", + "warn" (default) and + "ignore". +

+
-t directory
+

+ Chroot to directory so that + include + directives in the configuration file are processed as if + run by a similarly chrooted named. +

+
-w directory
+

+ chdir to directory so that + relative + filenames in master file $INCLUDE directives work. This + is similar to the directory clause in + named.conf. +

+
-D
+

+ Dump zone file in canonical format. + This is always enabled for named-compilezone. +

+
-W mode
+

+ Specify whether to check for non-terminal wildcards. + Non-terminal wildcards are almost always the result of a + failure to understand the wildcard matching algorithm (RFC 1034). + Possible modes are "warn" (default) + and + "ignore". +

+
zonename
+

+ The domain name of the zone being checked. +

+
filename
+

+ The name of the zone file. +

+
+
+
+

RETURN VALUES

+

named-checkzone + returns an exit status of 1 if + errors were detected and 0 otherwise. +

+
+
+

SEE ALSO

+

named(8), + named-checkconf(8), + RFC 1035, + BIND 9 Administrator Reference Manual. +

+
+
+

AUTHOR

+

Internet Systems Consortium +

+
+
+ diff --git a/bin/dig/Makefile.in b/bin/dig/Makefile.in new file mode 100644 index 0000000..836b7f2 --- /dev/null +++ b/bin/dig/Makefile.in @@ -0,0 +1,101 @@ +# Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2000-2002 Internet Software Consortium. +# +# Permission to use, copy, modify, and 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: Makefile.in,v 1.33.18.6 2005/09/09 14:11:04 marka Exp $ + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +@BIND9_VERSION@ + +@BIND9_MAKE_INCLUDES@ + +CINCLUDES = -I${srcdir}/include ${DNS_INCLUDES} ${BIND9_INCLUDES} \ + ${ISC_INCLUDES} ${LWRES_INCLUDES} + +CDEFINES = -DVERSION=\"${VERSION}\" +CWARNINGS = + +ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ +DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ +BIND9LIBS = ../../lib/bind9/libbind9.@A@ +ISCLIBS = ../../lib/isc/libisc.@A@ +LWRESLIBS = ../../lib/lwres/liblwres.@A@ + +ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ +DNSDEPLIBS = ../../lib/dns/libdns.@A@ +BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ +ISCDEPLIBS = ../../lib/isc/libisc.@A@ +LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@ + +DEPLIBS = ${DNSDEPLIBS} ${BIND9DEPLIBS} ${ISCDEPLIBS} ${ISCCFGDEPLIBS} \ + ${LWRESDEPLIBS} + +LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCLIBS} \ + ${ISCCFGLIBS} @IDNLIBS@ @LIBS@ + +SUBDIRS = + +TARGETS = dig@EXEEXT@ host@EXEEXT@ nslookup@EXEEXT@ + +OBJS = dig.@O@ dighost.@O@ host.@O@ nslookup.@O@ + +UOBJS = + +SRCS = dig.c dighost.c host.c nslookup.c + +MANPAGES = dig.1 host.1 nslookup.1 + +HTMLPAGES = dig.html host.html nslookup.html + +MANOBJS = ${MANPAGES} ${HTMLPAGES} + +@BIND9_MAKE_RULES@ + +dig@EXEEXT@: dig.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ + dig.@O@ dighost.@O@ ${UOBJS} ${LIBS} + +host@EXEEXT@: host.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ + host.@O@ dighost.@O@ ${UOBJS} ${LIBS} + +nslookup@EXEEXT@: nslookup.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ + nslookup.@O@ dighost.@O@ ${UOBJS} ${LIBS} + +doc man:: ${MANOBJS} + +docclean manclean maintainer-clean:: + rm -f ${MANOBJS} + +clean distclean maintainer-clean:: + rm -f ${TARGETS} + +installdirs: + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${bindir} + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man1 + +install:: dig@EXEEXT@ host@EXEEXT@ nslookup@EXEEXT@ installdirs + ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} \ + dig@EXEEXT@ ${DESTDIR}${bindir} + ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} \ + host@EXEEXT@ ${DESTDIR}${bindir} + ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} \ + nslookup@EXEEXT@ ${DESTDIR}${bindir} + for m in ${MANPAGES}; do \ + ${INSTALL_DATA} ${srcdir}/$$m ${DESTDIR}${mandir}/man1; \ + done diff --git a/bin/dig/dig.1 b/bin/dig/dig.1 new file mode 100644 index 0000000..bf53280 --- /dev/null +++ b/bin/dig/dig.1 @@ -0,0 +1,557 @@ +.\" Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2000-2003 Internet Software Consortium. +.\" +.\" Permission to use, copy, modify, and 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: dig.1,v 1.23.18.22 2007/05/16 06:11:27 marka Exp $ +.\" +.hy 0 +.ad l +.\" Title: dig +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.71.1 +.\" Date: Jun 30, 2000 +.\" Manual: BIND9 +.\" Source: BIND9 +.\" +.TH "DIG" "1" "Jun 30, 2000" "BIND9" "BIND9" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +dig \- DNS lookup utility +.SH "SYNOPSIS" +.HP 4 +\fBdig\fR [@server] [\fB\-b\ \fR\fB\fIaddress\fR\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIfilename\fR\fR] [\fB\-k\ \fR\fB\fIfilename\fR\fR] [\fB\-p\ \fR\fB\fIport#\fR\fR] [\fB\-q\ \fR\fB\fIname\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-x\ \fR\fB\fIaddr\fR\fR] [\fB\-y\ \fR\fB\fI[hmac:]\fR\fIname:key\fR\fR] [\fB\-4\fR] [\fB\-6\fR] [name] [type] [class] [queryopt...] +.HP 4 +\fBdig\fR [\fB\-h\fR] +.HP 4 +\fBdig\fR [global\-queryopt...] [query...] +.SH "DESCRIPTION" +.PP +\fBdig\fR +(domain information groper) is a flexible tool for interrogating DNS name servers. It performs DNS lookups and displays the answers that are returned from the name server(s) that were queried. Most DNS administrators use +\fBdig\fR +to troubleshoot DNS problems because of its flexibility, ease of use and clarity of output. Other lookup tools tend to have less functionality than +\fBdig\fR. +.PP +Although +\fBdig\fR +is normally used with command\-line arguments, it also has a batch mode of operation for reading lookup requests from a file. A brief summary of its command\-line arguments and options is printed when the +\fB\-h\fR +option is given. Unlike earlier versions, the BIND 9 implementation of +\fBdig\fR +allows multiple lookups to be issued from the command line. +.PP +Unless it is told to query a specific name server, +\fBdig\fR +will try each of the servers listed in +\fI/etc/resolv.conf\fR. +.PP +When no command line arguments or options are given, will perform an NS query for "." (the root). +.PP +It is possible to set per\-user defaults for +\fBdig\fR +via +\fI${HOME}/.digrc\fR. This file is read and any options in it are applied before the command line arguments. +.PP +The IN and CH class names overlap with the IN and CH top level domains names. Either use the +\fB\-t\fR +and +\fB\-c\fR +options to specify the type and class or use the +\fB\-q\fR +the specify the domain name or use "IN." and "CH." when looking up these top level domains. +.SH "SIMPLE USAGE" +.PP +A typical invocation of +\fBdig\fR +looks like: +.sp +.RS 4 +.nf + dig @server name type +.fi +.RE +.sp +where: +.PP +\fBserver\fR +.RS 4 +is the name or IP address of the name server to query. This can be an IPv4 address in dotted\-decimal notation or an IPv6 address in colon\-delimited notation. When the supplied +\fIserver\fR +argument is a hostname, +\fBdig\fR +resolves that name before querying that name server. If no +\fIserver\fR +argument is provided, +\fBdig\fR +consults +\fI/etc/resolv.conf\fR +and queries the name servers listed there. The reply from the name server that responds is displayed. +.RE +.PP +\fBname\fR +.RS 4 +is the name of the resource record that is to be looked up. +.RE +.PP +\fBtype\fR +.RS 4 +indicates what type of query is required \(em ANY, A, MX, SIG, etc. +\fItype\fR +can be any valid query type. If no +\fItype\fR +argument is supplied, +\fBdig\fR +will perform a lookup for an A record. +.RE +.SH "OPTIONS" +.PP +The +\fB\-b\fR +option sets the source IP address of the query to +\fIaddress\fR. This must be a valid address on one of the host's network interfaces or "0.0.0.0" or "::". An optional port may be specified by appending "#" +.PP +The default query class (IN for internet) is overridden by the +\fB\-c\fR +option. +\fIclass\fR +is any valid class, such as HS for Hesiod records or CH for Chaosnet records. +.PP +The +\fB\-f\fR +option makes +\fBdig \fR +operate in batch mode by reading a list of lookup requests to process from the file +\fIfilename\fR. The file contains a number of queries, one per line. Each entry in the file should be organized in the same way they would be presented as queries to +\fBdig\fR +using the command\-line interface. +.PP +If a non\-standard port number is to be queried, the +\fB\-p\fR +option is used. +\fIport#\fR +is the port number that +\fBdig\fR +will send its queries instead of the standard DNS port number 53. This option would be used to test a name server that has been configured to listen for queries on a non\-standard port number. +.PP +The +\fB\-4\fR +option forces +\fBdig\fR +to only use IPv4 query transport. The +\fB\-6\fR +option forces +\fBdig\fR +to only use IPv6 query transport. +.PP +The +\fB\-t\fR +option sets the query type to +\fItype\fR. It can be any valid query type which is supported in BIND 9. The default query type is "A", unless the +\fB\-x\fR +option is supplied to indicate a reverse lookup. A zone transfer can be requested by specifying a type of AXFR. When an incremental zone transfer (IXFR) is required, +\fItype\fR +is set to +ixfr=N. The incremental zone transfer will contain the changes made to the zone since the serial number in the zone's SOA record was +\fIN\fR. +.PP +The +\fB\-q\fR +option sets the query name to +\fIname\fR. This useful do distinguish the +\fIname\fR +from other arguments. +.PP +Reverse lookups \(em mapping addresses to names \(em are simplified by the +\fB\-x\fR +option. +\fIaddr\fR +is an IPv4 address in dotted\-decimal notation, or a colon\-delimited IPv6 address. When this option is used, there is no need to provide the +\fIname\fR, +\fIclass\fR +and +\fItype\fR +arguments. +\fBdig\fR +automatically performs a lookup for a name like +11.12.13.10.in\-addr.arpa +and sets the query type and class to PTR and IN respectively. By default, IPv6 addresses are looked up using nibble format under the IP6.ARPA domain. To use the older RFC1886 method using the IP6.INT domain specify the +\fB\-i\fR +option. Bit string labels (RFC2874) are now experimental and are not attempted. +.PP +To sign the DNS queries sent by +\fBdig\fR +and their responses using transaction signatures (TSIG), specify a TSIG key file using the +\fB\-k\fR +option. You can also specify the TSIG key itself on the command line using the +\fB\-y\fR +option; +\fIhmac\fR +is the type of the TSIG, default HMAC\-MD5, +\fIname\fR +is the name of the TSIG key and +\fIkey\fR +is the actual key. The key is a base\-64 encoded string, typically generated by +\fBdnssec\-keygen\fR(8). Caution should be taken when using the +\fB\-y\fR +option on multi\-user systems as the key can be visible in the output from +\fBps\fR(1) +or in the shell's history file. When using TSIG authentication with +\fBdig\fR, the name server that is queried needs to know the key and algorithm that is being used. In BIND, this is done by providing appropriate +\fBkey\fR +and +\fBserver\fR +statements in +\fInamed.conf\fR. +.SH "QUERY OPTIONS" +.PP +\fBdig\fR +provides a number of query options which affect the way in which lookups are made and the results displayed. Some of these set or reset flag bits in the query header, some determine which sections of the answer get printed, and others determine the timeout and retry strategies. +.PP +Each query option is identified by a keyword preceded by a plus sign (+). Some keywords set or reset an option. These may be preceded by the string +no +to negate the meaning of that keyword. Other keywords assign values to options like the timeout interval. They have the form +\fB+keyword=value\fR. The query options are: +.PP +\fB+[no]tcp\fR +.RS 4 +Use [do not use] TCP when querying name servers. The default behavior is to use UDP unless an AXFR or IXFR query is requested, in which case a TCP connection is used. +.RE +.PP +\fB+[no]vc\fR +.RS 4 +Use [do not use] TCP when querying name servers. This alternate syntax to +\fI+[no]tcp\fR +is provided for backwards compatibility. The "vc" stands for "virtual circuit". +.RE +.PP +\fB+[no]ignore\fR +.RS 4 +Ignore truncation in UDP responses instead of retrying with TCP. By default, TCP retries are performed. +.RE +.PP +\fB+domain=somename\fR +.RS 4 +Set the search list to contain the single domain +\fIsomename\fR, as if specified in a +\fBdomain\fR +directive in +\fI/etc/resolv.conf\fR, and enable search list processing as if the +\fI+search\fR +option were given. +.RE +.PP +\fB+[no]search\fR +.RS 4 +Use [do not use] the search list defined by the searchlist or domain directive in +\fIresolv.conf\fR +(if any). The search list is not used by default. +.RE +.PP +\fB+[no]showsearch\fR +.RS 4 +Perform [do not perform] a search showing intermediate results. +.RE +.PP +\fB+[no]defname\fR +.RS 4 +Deprecated, treated as a synonym for +\fI+[no]search\fR +.RE +.PP +\fB+[no]aaonly\fR +.RS 4 +Sets the "aa" flag in the query. +.RE +.PP +\fB+[no]aaflag\fR +.RS 4 +A synonym for +\fI+[no]aaonly\fR. +.RE +.PP +\fB+[no]adflag\fR +.RS 4 +Set [do not set] the AD (authentic data) bit in the query. The AD bit currently has a standard meaning only in responses, not in queries, but the ability to set the bit in the query is provided for completeness. +.RE +.PP +\fB+[no]cdflag\fR +.RS 4 +Set [do not set] the CD (checking disabled) bit in the query. This requests the server to not perform DNSSEC validation of responses. +.RE +.PP +\fB+[no]cl\fR +.RS 4 +Display [do not display] the CLASS when printing the record. +.RE +.PP +\fB+[no]ttlid\fR +.RS 4 +Display [do not display] the TTL when printing the record. +.RE +.PP +\fB+[no]recurse\fR +.RS 4 +Toggle the setting of the RD (recursion desired) bit in the query. This bit is set by default, which means +\fBdig\fR +normally sends recursive queries. Recursion is automatically disabled when the +\fI+nssearch\fR +or +\fI+trace\fR +query options are used. +.RE +.PP +\fB+[no]nssearch\fR +.RS 4 +When this option is set, +\fBdig\fR +attempts to find the authoritative name servers for the zone containing the name being looked up and display the SOA record that each name server has for the zone. +.RE +.PP +\fB+[no]trace\fR +.RS 4 +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, +\fBdig\fR +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. +.RE +.PP +\fB+[no]cmd\fR +.RS 4 +Toggles the printing of the initial comment in the output identifying the version of +\fBdig\fR +and the query options that have been applied. This comment is printed by default. +.RE +.PP +\fB+[no]short\fR +.RS 4 +Provide a terse answer. The default is to print the answer in a verbose form. +.RE +.PP +\fB+[no]identify\fR +.RS 4 +Show [or do not show] the IP address and port number that supplied the answer when the +\fI+short\fR +option is enabled. If short form answers are requested, the default is not to show the source address and port number of the server that provided the answer. +.RE +.PP +\fB+[no]comments\fR +.RS 4 +Toggle the display of comment lines in the output. The default is to print comments. +.RE +.PP +\fB+[no]stats\fR +.RS 4 +This query option toggles the printing of statistics: when the query was made, the size of the reply and so on. The default behavior is to print the query statistics. +.RE +.PP +\fB+[no]qr\fR +.RS 4 +Print [do not print] the query as it is sent. By default, the query is not printed. +.RE +.PP +\fB+[no]question\fR +.RS 4 +Print [do not print] the question section of a query when an answer is returned. The default is to print the question section as a comment. +.RE +.PP +\fB+[no]answer\fR +.RS 4 +Display [do not display] the answer section of a reply. The default is to display it. +.RE +.PP +\fB+[no]authority\fR +.RS 4 +Display [do not display] the authority section of a reply. The default is to display it. +.RE +.PP +\fB+[no]additional\fR +.RS 4 +Display [do not display] the additional section of a reply. The default is to display it. +.RE +.PP +\fB+[no]all\fR +.RS 4 +Set or clear all display flags. +.RE +.PP +\fB+time=T\fR +.RS 4 +Sets the timeout for a query to +\fIT\fR +seconds. The default timeout is 5 seconds. An attempt to set +\fIT\fR +to less than 1 will result in a query timeout of 1 second being applied. +.RE +.PP +\fB+tries=T\fR +.RS 4 +Sets the number of times to try UDP queries to server to +\fIT\fR +instead of the default, 3. If +\fIT\fR +is less than or equal to zero, the number of tries is silently rounded up to 1. +.RE +.PP +\fB+retry=T\fR +.RS 4 +Sets the number of times to retry UDP queries to server to +\fIT\fR +instead of the default, 2. Unlike +\fI+tries\fR, this does not include the initial query. +.RE +.PP +\fB+ndots=D\fR +.RS 4 +Set the number of dots that have to appear in +\fIname\fR +to +\fID\fR +for it to be considered absolute. The default value is that defined using the ndots statement in +\fI/etc/resolv.conf\fR, or 1 if no ndots statement is present. Names with fewer dots are interpreted as relative names and will be searched for in the domains listed in the +\fBsearch\fR +or +\fBdomain\fR +directive in +\fI/etc/resolv.conf\fR. +.RE +.PP +\fB+bufsize=B\fR +.RS 4 +Set the UDP message buffer size advertised using EDNS0 to +\fIB\fR +bytes. The maximum and minimum sizes of this buffer are 65535 and 0 respectively. Values outside this range are rounded up or down appropriately. Values other than zero will cause a EDNS query to be sent. +.RE +.PP +\fB+edns=#\fR +.RS 4 +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. +\fB+noedns\fR +clears the remembered EDNS version. +.RE +.PP +\fB+[no]multiline\fR +.RS 4 +Print records like the SOA records in a verbose multi\-line format with human\-readable comments. The default is to print each record on a single line, to facilitate machine parsing of the +\fBdig\fR +output. +.RE +.PP +\fB+[no]fail\fR +.RS 4 +Do not try the next server if you receive a SERVFAIL. The default is to not try the next server which is the reverse of normal stub resolver behavior. +.RE +.PP +\fB+[no]besteffort\fR +.RS 4 +Attempt to display the contents of messages which are malformed. The default is to not display malformed answers. +.RE +.PP +\fB+[no]dnssec\fR +.RS 4 +Requests DNSSEC records be sent by setting the DNSSEC OK bit (DO) in the OPT record in the additional section of the query. +.RE +.PP +\fB+[no]sigchase\fR +.RS 4 +Chase DNSSEC signature chains. Requires dig be compiled with \-DDIG_SIGCHASE. +.RE +.PP +\fB+trusted\-key=####\fR +.RS 4 +Specifies a file containing trusted keys to be used with +\fB+sigchase\fR. Each DNSKEY record must be on its own line. +.sp +If not specified +\fBdig\fR +will look for +\fI/etc/trusted\-key.key\fR +then +\fItrusted\-key.key\fR +in the current directory. +.sp +Requires dig be compiled with \-DDIG_SIGCHASE. +.RE +.PP +\fB+[no]topdown\fR +.RS 4 +When chasing DNSSEC signature chains perform a top\-down validation. Requires dig be compiled with \-DDIG_SIGCHASE. +.RE +.SH "MULTIPLE QUERIES" +.PP +The BIND 9 implementation of +\fBdig \fR +supports specifying multiple queries on the command line (in addition to supporting the +\fB\-f\fR +batch file option). Each of those queries can be supplied with its own set of flags, options and query options. +.PP +In this case, each +\fIquery\fR +argument represent an individual query in the command\-line syntax described above. Each consists of any of the standard options and flags, the name to be looked up, an optional query type and class and any query options that should be applied to that query. +.PP +A global set of query options, which should be applied to all queries, can also be supplied. These global query options must precede the first tuple of name, class, type, options, flags, and query options supplied on the command line. Any global query options (except the +\fB+[no]cmd\fR +option) can be overridden by a query\-specific set of query options. For example: +.sp +.RS 4 +.nf +dig +qr www.isc.org any \-x 127.0.0.1 isc.org ns +noqr +.fi +.RE +.sp +shows how +\fBdig\fR +could be used from the command line to make three lookups: an ANY query for +www.isc.org, a reverse lookup of 127.0.0.1 and a query for the NS records of +isc.org. A global query option of +\fI+qr\fR +is applied, so that +\fBdig\fR +shows the initial query it made for each lookup. The final query has a local query option of +\fI+noqr\fR +which means that +\fBdig\fR +will not print the initial query when it looks up the NS records for +isc.org. +.SH "IDN SUPPORT" +.PP +If +\fBdig\fR +has been built with IDN (internationalized domain name) support, it can accept and display non\-ASCII domain names. +\fBdig\fR +appropriately converts character encoding of domain name before sending a request to DNS server or displaying a reply from the server. If you'd like to turn off the IDN support for some reason, defines the +\fBIDN_DISABLE\fR +environment variable. The IDN support is disabled if the variable is set when +\fBdig\fR +runs. +.SH "FILES" +.PP +\fI/etc/resolv.conf\fR +.PP +\fI${HOME}/.digrc\fR +.SH "SEE ALSO" +.PP +\fBhost\fR(1), +\fBnamed\fR(8), +\fBdnssec\-keygen\fR(8), +RFC1035. +.SH "BUGS" +.PP +There are probably too many query options. +.SH "COPYRIGHT" +Copyright \(co 2004\-2007 Internet Systems Consortium, Inc. ("ISC") +.br +Copyright \(co 2000\-2003 Internet Software Consortium. +.br diff --git a/bin/dig/dig.c b/bin/dig/dig.c new file mode 100644 index 0000000..ba5d87b --- /dev/null +++ b/bin/dig/dig.c @@ -0,0 +1,1797 @@ +/* + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000-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: dig.c,v 1.186.18.29 2007/08/28 07:19:55 tbox Exp $ */ + +/*! \file */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define ADD_STRING(b, s) { \ + if (strlen(s) >= isc_buffer_availablelength(b)) \ + return (ISC_R_NOSPACE); \ + else \ + isc_buffer_putstr(b, s); \ +} + +#define DIG_MAX_ADDRESSES 20 + +dig_lookup_t *default_lookup = NULL; + +static char *batchname = NULL; +static FILE *batchfp = NULL; +static char *argv0; +static int addresscount = 0; + +static char domainopt[DNS_NAME_MAXTEXT]; + +static isc_boolean_t short_form = ISC_FALSE, printcmd = ISC_TRUE, + ip6_int = ISC_FALSE, plusquest = ISC_FALSE, pluscomm = ISC_FALSE, + multiline = ISC_FALSE, nottl = ISC_FALSE, noclass = ISC_FALSE; + +/*% opcode text */ +static const char *opcodetext[] = { + "QUERY", + "IQUERY", + "STATUS", + "RESERVED3", + "NOTIFY", + "UPDATE", + "RESERVED6", + "RESERVED7", + "RESERVED8", + "RESERVED9", + "RESERVED10", + "RESERVED11", + "RESERVED12", + "RESERVED13", + "RESERVED14", + "RESERVED15" +}; + +/*% return code text */ +static const char *rcodetext[] = { + "NOERROR", + "FORMERR", + "SERVFAIL", + "NXDOMAIN", + "NOTIMP", + "REFUSED", + "YXDOMAIN", + "YXRRSET", + "NXRRSET", + "NOTAUTH", + "NOTZONE", + "RESERVED11", + "RESERVED12", + "RESERVED13", + "RESERVED14", + "RESERVED15", + "BADVERS" +}; + +/*% print usage */ +static void +print_usage(FILE *fp) { + fputs( +"Usage: dig [@global-server] [domain] [q-type] [q-class] {q-opt}\n" +" {global-d-opt} host [@local-server] {local-d-opt}\n" +" [ host [@local-server] {local-d-opt} [...]]\n", fp); +} + +static void +usage(void) { + print_usage(stderr); + fputs("\nUse \"dig -h\" (or \"dig -h | more\") " + "for complete list of options\n", stderr); + exit(1); +} + +/*% version */ +static void +version(void) { + fputs("DiG " VERSION "\n", stderr); +} + +/*% help */ +static void +help(void) { + print_usage(stdout); + fputs( +"Where: domain is in the Domain Name System\n" +" q-class is one of (in,hs,ch,...) [default: in]\n" +" q-type is one of (a,any,mx,ns,soa,hinfo,axfr,txt,...) [default:a]\n" +" (Use ixfr=version for type ixfr)\n" +" q-opt is one of:\n" +" -x dot-notation (shortcut for in-addr lookups)\n" +" -i (IP6.INT reverse IPv6 lookups)\n" +" -f filename (batch mode)\n" +" -b address[#port] (bind to source address/port)\n" +" -p port (specify port number)\n" +" -q name (specify query name)\n" +" -t type (specify query type)\n" +" -c class (specify query class)\n" +" -k keyfile (specify tsig key file)\n" +" -y [hmac:]name:key (specify named base64 tsig key)\n" +" -4 (use IPv4 query transport only)\n" +" -6 (use IPv6 query transport only)\n" +" d-opt is of the form +keyword[=value], where keyword is:\n" +" +[no]vc (TCP mode)\n" +" +[no]tcp (TCP mode, alternate syntax)\n" +" +time=### (Set query timeout) [5]\n" +" +tries=### (Set number of UDP attempts) [3]\n" +" +retry=### (Set number of UDP retries) [2]\n" +" +domain=### (Set default domainname)\n" +" +bufsize=### (Set EDNS0 Max UDP packet size)\n" +" +ndots=### (Set NDOTS value)\n" +" +edns=### (Set EDNS version)\n" +" +[no]search (Set whether to use searchlist)\n" +" +[no]showsearch (Search with intermediate results)\n" +" +[no]defname (Ditto)\n" +" +[no]recurse (Recursive mode)\n" +" +[no]ignore (Don't revert to TCP for TC responses.)" +"\n" +" +[no]fail (Don't try next server on SERVFAIL)\n" +" +[no]besteffort (Try to parse even illegal messages)\n" +" +[no]aaonly (Set AA flag in query (+[no]aaflag))\n" +" +[no]adflag (Set AD flag in query)\n" +" +[no]cdflag (Set CD flag in query)\n" +" +[no]cl (Control display of class in records)\n" +" +[no]cmd (Control display of command line)\n" +" +[no]comments (Control display of comment lines)\n" +" +[no]question (Control display of question)\n" +" +[no]answer (Control display of answer)\n" +" +[no]authority (Control display of authority)\n" +" +[no]additional (Control display of additional)\n" +" +[no]stats (Control display of statistics)\n" +" +[no]short (Disable everything except short\n" +" form of answer)\n" +" +[no]ttlid (Control display of ttls in records)\n" +" +[no]all (Set or clear all display flags)\n" +" +[no]qr (Print question before sending)\n" +" +[no]nssearch (Search all authoritative nameservers)\n" +" +[no]identify (ID responders in short answers)\n" +" +[no]trace (Trace delegation down from root)\n" +" +[no]dnssec (Request DNSSEC records)\n" +#ifdef DIG_SIGCHASE +" +[no]sigchase (Chase DNSSEC signatures)\n" +" +trusted-key=#### (Trusted Key when chasing DNSSEC sigs)\n" +#if DIG_SIGCHASE_TD +" +[no]topdown (Do DNSSEC validation top down mode)\n" +#endif +#endif +" +[no]multiline (Print records in an expanded format)\n" +" global d-opts and servers (before host name) affect all queries.\n" +" local d-opts and servers (after host name) affect only that lookup.\n" +" -h (print help and exit)\n" +" -v (print version and exit)\n", + stdout); +} + +/*% + * Callback from dighost.c to print the received message. + */ +void +received(int bytes, isc_sockaddr_t *from, dig_query_t *query) { + isc_uint64_t diff; + isc_time_t now; + time_t tnow; + char fromtext[ISC_SOCKADDR_FORMATSIZE]; + + isc_sockaddr_format(from, fromtext, sizeof(fromtext)); + + TIME_NOW(&now); + + if (query->lookup->stats && !short_form) { + diff = isc_time_microdiff(&now, &query->time_sent); + printf(";; Query time: %ld msec\n", (long int)diff/1000); + printf(";; SERVER: %s(%s)\n", fromtext, query->servname); + time(&tnow); + printf(";; WHEN: %s", ctime(&tnow)); + if (query->lookup->doing_xfr) { + printf(";; XFR size: %u records (messages %u, " + "bytes %" ISC_PRINT_QUADFORMAT "u)\n", + query->rr_count, query->msg_count, + query->byte_count); + } else { + printf(";; MSG SIZE rcvd: %u\n", bytes); + + } + if (key != NULL) { + if (!validated) + puts(";; WARNING -- Some TSIG could not " + "be validated"); + } + if ((key == NULL) && (keysecret[0] != 0)) { + puts(";; WARNING -- TSIG key was not used."); + } + puts(""); + } else if (query->lookup->identify && !short_form) { + diff = isc_time_microdiff(&now, &query->time_sent); + printf(";; Received %" ISC_PRINT_QUADFORMAT "u bytes " + "from %s(%s) in %d ms\n\n", + query->lookup->doing_xfr ? + query->byte_count : (isc_uint64_t)bytes, + fromtext, query->servname, + (int)diff/1000); + } +} + +/* + * Callback from dighost.c to print that it is trying a server. + * Not used in dig. + * XXX print_trying + */ +void +trying(char *frm, dig_lookup_t *lookup) { + UNUSED(frm); + UNUSED(lookup); +} + +/*% + * Internal print routine used to print short form replies. + */ +static isc_result_t +say_message(dns_rdata_t *rdata, dig_query_t *query, isc_buffer_t *buf) { + isc_result_t result; + isc_uint64_t diff; + isc_time_t now; + char store[sizeof("12345678901234567890")]; + + if (query->lookup->trace || query->lookup->ns_search_only) { + result = dns_rdatatype_totext(rdata->type, buf); + if (result != ISC_R_SUCCESS) + return (result); + ADD_STRING(buf, " "); + } + result = dns_rdata_totext(rdata, NULL, buf); + check_result(result, "dns_rdata_totext"); + if (query->lookup->identify) { + TIME_NOW(&now); + diff = isc_time_microdiff(&now, &query->time_sent); + ADD_STRING(buf, " from server "); + ADD_STRING(buf, query->servname); + snprintf(store, 19, " in %d ms.", (int)diff/1000); + ADD_STRING(buf, store); + } + ADD_STRING(buf, "\n"); + return (ISC_R_SUCCESS); +} + +/*% + * short_form message print handler. Calls above say_message() + */ +static isc_result_t +short_answer(dns_message_t *msg, dns_messagetextflag_t flags, + isc_buffer_t *buf, dig_query_t *query) +{ + dns_name_t *name; + dns_rdataset_t *rdataset; + isc_buffer_t target; + isc_result_t result, loopresult; + dns_name_t empty_name; + char t[4096]; + dns_rdata_t rdata = DNS_RDATA_INIT; + + UNUSED(flags); + + dns_name_init(&empty_name, NULL); + result = dns_message_firstname(msg, DNS_SECTION_ANSWER); + if (result == ISC_R_NOMORE) + return (ISC_R_SUCCESS); + else if (result != ISC_R_SUCCESS) + return (result); + + for (;;) { + name = NULL; + dns_message_currentname(msg, DNS_SECTION_ANSWER, &name); + + isc_buffer_init(&target, t, sizeof(t)); + + for (rdataset = ISC_LIST_HEAD(name->list); + rdataset != NULL; + rdataset = ISC_LIST_NEXT(rdataset, link)) { + loopresult = dns_rdataset_first(rdataset); + while (loopresult == ISC_R_SUCCESS) { + dns_rdataset_current(rdataset, &rdata); + result = say_message(&rdata, query, + buf); + check_result(result, "say_message"); + loopresult = dns_rdataset_next(rdataset); + dns_rdata_reset(&rdata); + } + } + result = dns_message_nextname(msg, DNS_SECTION_ANSWER); + if (result == ISC_R_NOMORE) + break; + else if (result != ISC_R_SUCCESS) + return (result); + } + + return (ISC_R_SUCCESS); +} +#ifdef DIG_SIGCHASE +isc_result_t +printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset, + isc_buffer_t *target) +{ + isc_result_t result; + dns_master_style_t *style = NULL; + unsigned int styleflags = 0; + + if (rdataset == NULL || owner_name == NULL || target == NULL) + return(ISC_FALSE); + + styleflags |= DNS_STYLEFLAG_REL_OWNER; + if (nottl) + styleflags |= DNS_STYLEFLAG_NO_TTL; + if (noclass) + styleflags |= DNS_STYLEFLAG_NO_CLASS; + if (multiline) { + styleflags |= DNS_STYLEFLAG_OMIT_OWNER; + styleflags |= DNS_STYLEFLAG_OMIT_CLASS; + styleflags |= DNS_STYLEFLAG_REL_DATA; + styleflags |= DNS_STYLEFLAG_OMIT_TTL; + styleflags |= DNS_STYLEFLAG_TTL; + styleflags |= DNS_STYLEFLAG_MULTILINE; + styleflags |= DNS_STYLEFLAG_COMMENT; + } + if (multiline || (nottl && noclass)) + result = dns_master_stylecreate(&style, styleflags, + 24, 24, 24, 32, 80, 8, mctx); + else if (nottl || noclass) + result = dns_master_stylecreate(&style, styleflags, + 24, 24, 32, 40, 80, 8, mctx); + else + result = dns_master_stylecreate(&style, styleflags, + 24, 32, 40, 48, 80, 8, mctx); + check_result(result, "dns_master_stylecreate"); + + result = dns_master_rdatasettotext(owner_name, rdataset, style, target); + + if (style != NULL) + dns_master_styledestroy(&style, mctx); + + return(result); +} +#endif + +/* + * Callback from dighost.c to print the reply from a server + */ +isc_result_t +printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) { + isc_result_t result; + dns_messagetextflag_t flags; + isc_buffer_t *buf = NULL; + unsigned int len = OUTPUTBUF; + dns_master_style_t *style = NULL; + unsigned int styleflags = 0; + + styleflags |= DNS_STYLEFLAG_REL_OWNER; + if (nottl) + styleflags |= DNS_STYLEFLAG_NO_TTL; + if (noclass) + styleflags |= DNS_STYLEFLAG_NO_CLASS; + if (multiline) { + styleflags |= DNS_STYLEFLAG_OMIT_OWNER; + styleflags |= DNS_STYLEFLAG_OMIT_CLASS; + styleflags |= DNS_STYLEFLAG_REL_DATA; + styleflags |= DNS_STYLEFLAG_OMIT_TTL; + styleflags |= DNS_STYLEFLAG_TTL; + styleflags |= DNS_STYLEFLAG_MULTILINE; + styleflags |= DNS_STYLEFLAG_COMMENT; + } + if (multiline || (nottl && noclass)) + result = dns_master_stylecreate(&style, styleflags, + 24, 24, 24, 32, 80, 8, mctx); + else if (nottl || noclass) + result = dns_master_stylecreate(&style, styleflags, + 24, 24, 32, 40, 80, 8, mctx); + else + result = dns_master_stylecreate(&style, styleflags, + 24, 32, 40, 48, 80, 8, mctx); + check_result(result, "dns_master_stylecreate"); + + if (query->lookup->cmdline[0] != 0) { + if (!short_form) + fputs(query->lookup->cmdline, stdout); + query->lookup->cmdline[0]=0; + } + debug("printmessage(%s %s %s)", headers ? "headers" : "noheaders", + query->lookup->comments ? "comments" : "nocomments", + short_form ? "short_form" : "long_form"); + + flags = 0; + if (!headers) { + flags |= DNS_MESSAGETEXTFLAG_NOHEADERS; + flags |= DNS_MESSAGETEXTFLAG_NOCOMMENTS; + } + if (!query->lookup->comments) + flags |= DNS_MESSAGETEXTFLAG_NOCOMMENTS; + + result = ISC_R_SUCCESS; + + result = isc_buffer_allocate(mctx, &buf, len); + check_result(result, "isc_buffer_allocate"); + + if (query->lookup->comments && !short_form) { + if (query->lookup->cmdline[0] != 0) + printf("; %s\n", query->lookup->cmdline); + if (msg == query->lookup->sendmsg) + printf(";; Sending:\n"); + else + printf(";; Got answer:\n"); + + if (headers) { + printf(";; ->>HEADER<<- opcode: %s, status: %s, " + "id: %u\n", + opcodetext[msg->opcode], rcodetext[msg->rcode], + msg->id); + printf(";; flags:"); + if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) + printf(" qr"); + if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) + printf(" aa"); + if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) + printf(" tc"); + if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) + printf(" rd"); + if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) + printf(" ra"); + if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0) + printf(" ad"); + if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0) + printf(" cd"); + + printf("; QUERY: %u, ANSWER: %u, " + "AUTHORITY: %u, ADDITIONAL: %u\n", + msg->counts[DNS_SECTION_QUESTION], + msg->counts[DNS_SECTION_ANSWER], + msg->counts[DNS_SECTION_AUTHORITY], + msg->counts[DNS_SECTION_ADDITIONAL]); + + if (msg != query->lookup->sendmsg && + (msg->flags & DNS_MESSAGEFLAG_RD) != 0 && + (msg->flags & DNS_MESSAGEFLAG_RA) == 0) + printf(";; WARNING: recursion requested " + "but not available\n"); + } + if (msg != query->lookup->sendmsg && extrabytes != 0U) + printf(";; WARNING: Messages has %u extra byte%s at " + "end\n", extrabytes, extrabytes != 0 ? "s" : ""); + } + +repopulate_buffer: + + if (query->lookup->comments && headers && !short_form) { + result = dns_message_pseudosectiontotext(msg, + DNS_PSEUDOSECTION_OPT, + style, flags, buf); + if (result == ISC_R_NOSPACE) { +buftoosmall: + len += OUTPUTBUF; + isc_buffer_free(&buf); + result = isc_buffer_allocate(mctx, &buf, len); + if (result == ISC_R_SUCCESS) + goto repopulate_buffer; + else + goto cleanup; + } + check_result(result, + "dns_message_pseudosectiontotext"); + } + + if (query->lookup->section_question && headers) { + if (!short_form) { + result = dns_message_sectiontotext(msg, + DNS_SECTION_QUESTION, + style, flags, buf); + if (result == ISC_R_NOSPACE) + goto buftoosmall; + check_result(result, "dns_message_sectiontotext"); + } + } + if (query->lookup->section_answer) { + if (!short_form) { + result = dns_message_sectiontotext(msg, + DNS_SECTION_ANSWER, + style, flags, buf); + if (result == ISC_R_NOSPACE) + goto buftoosmall; + check_result(result, "dns_message_sectiontotext"); + } else { + result = short_answer(msg, flags, buf, query); + if (result == ISC_R_NOSPACE) + goto buftoosmall; + check_result(result, "short_answer"); + } + } + if (query->lookup->section_authority) { + if (!short_form) { + result = dns_message_sectiontotext(msg, + DNS_SECTION_AUTHORITY, + style, flags, buf); + if (result == ISC_R_NOSPACE) + goto buftoosmall; + check_result(result, "dns_message_sectiontotext"); + } + } + if (query->lookup->section_additional) { + if (!short_form) { + result = dns_message_sectiontotext(msg, + DNS_SECTION_ADDITIONAL, + style, flags, buf); + if (result == ISC_R_NOSPACE) + goto buftoosmall; + check_result(result, "dns_message_sectiontotext"); + /* + * Only print the signature on the first record. + */ + if (headers) { + result = dns_message_pseudosectiontotext( + msg, + DNS_PSEUDOSECTION_TSIG, + style, flags, buf); + if (result == ISC_R_NOSPACE) + goto buftoosmall; + check_result(result, + "dns_message_pseudosectiontotext"); + result = dns_message_pseudosectiontotext( + msg, + DNS_PSEUDOSECTION_SIG0, + style, flags, buf); + if (result == ISC_R_NOSPACE) + goto buftoosmall; + check_result(result, + "dns_message_pseudosectiontotext"); + } + } + } + + if (headers && query->lookup->comments && !short_form) + printf("\n"); + + printf("%.*s", (int)isc_buffer_usedlength(buf), + (char *)isc_buffer_base(buf)); + isc_buffer_free(&buf); + +cleanup: + if (style != NULL) + dns_master_styledestroy(&style, mctx); + return (result); +} + +/*% + * print the greeting message when the program first starts up. + */ +static void +printgreeting(int argc, char **argv, dig_lookup_t *lookup) { + int i; + int remaining; + static isc_boolean_t first = ISC_TRUE; + char append[MXNAME]; + + if (printcmd) { + lookup->cmdline[sizeof(lookup->cmdline) - 1] = 0; + snprintf(lookup->cmdline, sizeof(lookup->cmdline), + "%s; <<>> DiG " VERSION " <<>>", + first?"\n":""); + i = 1; + while (i < argc) { + snprintf(append, sizeof(append), " %s", argv[i++]); + remaining = sizeof(lookup->cmdline) - + strlen(lookup->cmdline) - 1; + strncat(lookup->cmdline, append, remaining); + } + remaining = sizeof(lookup->cmdline) - + strlen(lookup->cmdline) - 1; + strncat(lookup->cmdline, "\n", remaining); + if (first && addresscount != 0) { + snprintf(append, sizeof(append), + "; (%d server%s found)\n", + addresscount, + addresscount > 1 ? "s" : ""); + remaining = sizeof(lookup->cmdline) - + strlen(lookup->cmdline) - 1; + strncat(lookup->cmdline, append, remaining); + } + if (first) { + snprintf(append, sizeof(append), + ";; global options: %s %s\n", + short_form ? "short_form" : "", + printcmd ? "printcmd" : ""); + first = ISC_FALSE; + remaining = sizeof(lookup->cmdline) - + strlen(lookup->cmdline) - 1; + strncat(lookup->cmdline, append, remaining); + } + } +} + +static isc_uint32_t +parse_uint(char *arg, const char *desc, isc_uint32_t max) { + isc_result_t result; + isc_uint32_t tmp; + + result = isc_parse_uint32(&tmp, arg, 10); + if (result == ISC_R_SUCCESS && tmp > max) + result = ISC_R_RANGE; + if (result != ISC_R_SUCCESS) + fatal("%s '%s': %s", desc, arg, isc_result_totext(result)); + return (tmp); +} + +/*% + * We're not using isc_commandline_parse() here since the command line + * syntax of dig is quite a bit different from that which can be described + * by that routine. + * XXX doc options + */ + +static void +plus_option(char *option, isc_boolean_t is_batchfile, + dig_lookup_t *lookup) +{ + char option_store[256]; + char *cmd, *value, *ptr; + isc_boolean_t state = ISC_TRUE; +#ifdef DIG_SIGCHASE + size_t n; +#endif + + strncpy(option_store, option, sizeof(option_store)); + option_store[sizeof(option_store)-1]=0; + ptr = option_store; + cmd = next_token(&ptr,"="); + if (cmd == NULL) { + printf(";; Invalid option %s\n", option_store); + return; + } + value = ptr; + if (strncasecmp(cmd, "no", 2)==0) { + cmd += 2; + state = ISC_FALSE; + } + +#define FULLCHECK(A) \ + do { \ + size_t _l = strlen(cmd); \ + if (_l >= sizeof(A) || strncasecmp(cmd, A, _l) != 0) \ + goto invalid_option; \ + } while (0) +#define FULLCHECK2(A, B) \ + do { \ + size_t _l = strlen(cmd); \ + if ((_l >= sizeof(A) || strncasecmp(cmd, A, _l) != 0) && \ + (_l >= sizeof(B) || strncasecmp(cmd, B, _l) != 0)) \ + goto invalid_option; \ + } while (0) + + switch (cmd[0]) { + case 'a': + switch (cmd[1]) { + case 'a': /* aaonly / aaflag */ + FULLCHECK2("aaonly", "aaflag"); + lookup->aaonly = state; + break; + case 'd': + switch (cmd[2]) { + case 'd': /* additional */ + FULLCHECK("additional"); + lookup->section_additional = state; + break; + case 'f': /* adflag */ + FULLCHECK("adflag"); + lookup->adflag = state; + break; + default: + goto invalid_option; + } + break; + case 'l': /* all */ + FULLCHECK("all"); + lookup->section_question = state; + lookup->section_authority = state; + lookup->section_answer = state; + lookup->section_additional = state; + lookup->comments = state; + lookup->stats = state; + printcmd = state; + break; + case 'n': /* answer */ + FULLCHECK("answer"); + lookup->section_answer = state; + break; + case 'u': /* authority */ + FULLCHECK("authority"); + lookup->section_authority = state; + break; + default: + goto invalid_option; + } + break; + case 'b': + switch (cmd[1]) { + case 'e':/* besteffort */ + FULLCHECK("besteffort"); + lookup->besteffort = state; + break; + case 'u':/* bufsize */ + FULLCHECK("bufsize"); + if (value == NULL) + goto need_value; + if (!state) + goto invalid_option; + lookup->udpsize = (isc_uint16_t) parse_uint(value, + "buffer size", COMMSIZE); + break; + default: + goto invalid_option; + } + break; + case 'c': + switch (cmd[1]) { + case 'd':/* cdflag */ + FULLCHECK("cdflag"); + lookup->cdflag = state; + break; + case 'l': /* cl */ + FULLCHECK("cl"); + noclass = ISC_TF(!state); + break; + case 'm': /* cmd */ + FULLCHECK("cmd"); + printcmd = state; + break; + case 'o': /* comments */ + FULLCHECK("comments"); + lookup->comments = state; + if (lookup == default_lookup) + pluscomm = state; + break; + default: + goto invalid_option; + } + break; + case 'd': + switch (cmd[1]) { + case 'e': /* defname */ + FULLCHECK("defname"); + usesearch = state; + break; + case 'n': /* dnssec */ + FULLCHECK("dnssec"); + if (state && lookup->edns == -1) + lookup->edns = 0; + lookup->dnssec = state; + break; + case 'o': /* domain */ + FULLCHECK("domain"); + if (value == NULL) + goto need_value; + if (!state) + goto invalid_option; + strncpy(domainopt, value, sizeof(domainopt)); + domainopt[sizeof(domainopt)-1] = '\0'; + break; + default: + goto invalid_option; + } + break; + case 'e': + FULLCHECK("edns"); + if (!state) { + lookup->edns = -1; + break; + } + if (value == NULL) + goto need_value; + lookup->edns = (isc_int16_t) parse_uint(value, "edns", 255); + break; + case 'f': /* fail */ + FULLCHECK("fail"); + lookup->servfail_stops = state; + break; + case 'i': + switch (cmd[1]) { + case 'd': /* identify */ + FULLCHECK("identify"); + lookup->identify = state; + break; + case 'g': /* ignore */ + default: /* Inherets default for compatibility */ + FULLCHECK("ignore"); + lookup->ignore = ISC_TRUE; + } + break; + case 'm': /* multiline */ + FULLCHECK("multiline"); + multiline = state; + break; + case 'n': + switch (cmd[1]) { + case 'd': /* ndots */ + FULLCHECK("ndots"); + if (value == NULL) + goto need_value; + if (!state) + goto invalid_option; + ndots = parse_uint(value, "ndots", MAXNDOTS); + break; + case 's': /* nssearch */ + FULLCHECK("nssearch"); + lookup->ns_search_only = state; + if (state) { + lookup->trace_root = ISC_TRUE; + lookup->recurse = ISC_TRUE; + lookup->identify = ISC_TRUE; + lookup->stats = ISC_FALSE; + lookup->comments = ISC_FALSE; + lookup->section_additional = ISC_FALSE; + lookup->section_authority = ISC_FALSE; + lookup->section_question = ISC_FALSE; + lookup->rdtype = dns_rdatatype_ns; + lookup->rdtypeset = ISC_TRUE; + short_form = ISC_TRUE; + } + break; + default: + goto invalid_option; + } + break; + case 'q': + switch (cmd[1]) { + case 'r': /* qr */ + FULLCHECK("qr"); + qr = state; + break; + case 'u': /* question */ + FULLCHECK("question"); + lookup->section_question = state; + if (lookup == default_lookup) + plusquest = state; + break; + default: + goto invalid_option; + } + break; + case 'r': + switch (cmd[1]) { + case 'e': + switch (cmd[2]) { + case 'c': /* recurse */ + FULLCHECK("recurse"); + lookup->recurse = state; + break; + case 't': /* retry / retries */ + FULLCHECK2("retry", "retries"); + if (value == NULL) + goto need_value; + if (!state) + goto invalid_option; + lookup->retries = parse_uint(value, "retries", + MAXTRIES - 1); + lookup->retries++; + break; + default: + goto invalid_option; + } + break; + default: + goto invalid_option; + } + break; + case 's': + switch (cmd[1]) { + case 'e': /* search */ + FULLCHECK("search"); + usesearch = state; + break; + case 'h': + if (cmd[2] != 'o') + goto invalid_option; + switch (cmd[3]) { + case 'r': /* short */ + FULLCHECK("short"); + short_form = state; + if (state) { + printcmd = ISC_FALSE; + lookup->section_additional = ISC_FALSE; + lookup->section_answer = ISC_TRUE; + lookup->section_authority = ISC_FALSE; + lookup->section_question = ISC_FALSE; + lookup->comments = ISC_FALSE; + lookup->stats = ISC_FALSE; + } + break; + case 'w': /* showsearch */ + FULLCHECK("showsearch"); + showsearch = state; + usesearch = state; + break; + default: + goto invalid_option; + } + break; +#ifdef DIG_SIGCHASE + case 'i': /* sigchase */ + FULLCHECK("sigchase"); + lookup->sigchase = state; + if (lookup->sigchase) + lookup->dnssec = ISC_TRUE; + break; +#endif + case 't': /* stats */ + FULLCHECK("stats"); + lookup->stats = state; + break; + default: + goto invalid_option; + } + break; + case 't': + switch (cmd[1]) { + case 'c': /* tcp */ + FULLCHECK("tcp"); + if (!is_batchfile) + lookup->tcp_mode = state; + break; + case 'i': /* timeout */ + FULLCHECK("timeout"); + if (value == NULL) + goto need_value; + if (!state) + goto invalid_option; + timeout = parse_uint(value, "timeout", MAXTIMEOUT); + if (timeout == 0) + timeout = 1; + break; +#if DIG_SIGCHASE_TD + case 'o': /* topdown */ + FULLCHECK("topdown"); + lookup->do_topdown = state; + break; +#endif + case 'r': + switch (cmd[2]) { + case 'a': /* trace */ + FULLCHECK("trace"); + lookup->trace = state; + lookup->trace_root = state; + if (state) { + lookup->recurse = ISC_FALSE; + lookup->identify = ISC_TRUE; + lookup->comments = ISC_FALSE; + lookup->stats = ISC_FALSE; + lookup->section_additional = ISC_FALSE; + lookup->section_authority = ISC_TRUE; + lookup->section_question = ISC_FALSE; + } + break; + case 'i': /* tries */ + FULLCHECK("tries"); + if (value == NULL) + goto need_value; + if (!state) + goto invalid_option; + lookup->retries = parse_uint(value, "tries", + MAXTRIES); + if (lookup->retries == 0) + lookup->retries = 1; + break; +#ifdef DIG_SIGCHASE + case 'u': /* trusted-key */ + FULLCHECK("trusted-key"); + if (value == NULL) + goto need_value; + if (!state) + goto invalid_option; + n = strlcpy(trustedkey, ptr, + sizeof(trustedkey)); + if (n >= sizeof(trustedkey)) + fatal("trusted key too large"); + break; +#endif + default: + goto invalid_option; + } + break; + case 't': /* ttlid */ + FULLCHECK("ttlid"); + nottl = ISC_TF(!state); + break; + default: + goto invalid_option; + } + break; + case 'v': + FULLCHECK("vc"); + if (!is_batchfile) + lookup->tcp_mode = state; + break; + default: + invalid_option: + need_value: + fprintf(stderr, "Invalid option: +%s\n", + option); + usage(); + } + return; +} + +/*% + * #ISC_TRUE returned if value was used + */ +static const char *single_dash_opts = "46dhimnv"; +static const char *dash_opts = "46bcdfhikmnptvyx"; +static isc_boolean_t +dash_option(char *option, char *next, dig_lookup_t **lookup, + isc_boolean_t *open_type_class, isc_boolean_t *need_clone, + isc_boolean_t config_only, int argc, char **argv, + isc_boolean_t *firstarg) +{ + char opt, *value, *ptr, *ptr2, *ptr3; + isc_result_t result; + isc_boolean_t value_from_next; + isc_textregion_t tr; + dns_rdatatype_t rdtype; + dns_rdataclass_t rdclass; + char textname[MXNAME]; + struct in_addr in4; + struct in6_addr in6; + in_port_t srcport; + char *hash, *cmd; + + while (strpbrk(option, single_dash_opts) == &option[0]) { + /* + * Since the -[46dhimnv] options do not take an argument, + * account for them (in any number and/or combination) + * if they appear as the first character(s) of a q-opt. + */ + opt = option[0]; + switch (opt) { + case '4': + if (have_ipv4) { + isc_net_disableipv6(); + have_ipv6 = ISC_FALSE; + } else { + fatal("can't find IPv4 networking"); + return (ISC_FALSE); + } + break; + case '6': + if (have_ipv6) { + isc_net_disableipv4(); + have_ipv4 = ISC_FALSE; + } else { + fatal("can't find IPv6 networking"); + return (ISC_FALSE); + } + break; + case 'd': + ptr = strpbrk(&option[1], dash_opts); + if (ptr != &option[1]) { + cmd = option; + FULLCHECK("debug"); + debugging = ISC_TRUE; + return (ISC_FALSE); + } else + debugging = ISC_TRUE; + break; + case 'h': + help(); + exit(0); + break; + case 'i': + ip6_int = ISC_TRUE; + break; + case 'm': /* memdebug */ + /* memdebug is handled in preparse_args() */ + break; + case 'n': + /* deprecated */ + break; + case 'v': + version(); + exit(0); + break; + } + if (strlen(option) > 1U) + option = &option[1]; + else + return (ISC_FALSE); + } + opt = option[0]; + if (strlen(option) > 1U) { + value_from_next = ISC_FALSE; + value = &option[1]; + } else { + value_from_next = ISC_TRUE; + value = next; + } + if (value == NULL) + goto invalid_option; + switch (opt) { + case 'b': + hash = strchr(value, '#'); + if (hash != NULL) { + srcport = (in_port_t) + parse_uint(hash + 1, + "port number", MAXPORT); + *hash = '\0'; + } else + srcport = 0; + if (have_ipv6 && inet_pton(AF_INET6, value, &in6) == 1) { + isc_sockaddr_fromin6(&bind_address, &in6, srcport); + isc_net_disableipv4(); + } else if (have_ipv4 && inet_pton(AF_INET, value, &in4) == 1) { + isc_sockaddr_fromin(&bind_address, &in4, srcport); + isc_net_disableipv6(); + } else { + if (hash != NULL) + *hash = '#'; + fatal("invalid address %s", value); + } + if (hash != NULL) + *hash = '#'; + specified_source = ISC_TRUE; + return (value_from_next); + case 'c': + if ((*lookup)->rdclassset) { + fprintf(stderr, ";; Warning, extra class option\n"); + } + *open_type_class = ISC_FALSE; + tr.base = value; + tr.length = strlen(value); + result = dns_rdataclass_fromtext(&rdclass, + (isc_textregion_t *)&tr); + if (result == ISC_R_SUCCESS) { + (*lookup)->rdclass = rdclass; + (*lookup)->rdclassset = ISC_TRUE; + } else + fprintf(stderr, ";; Warning, ignoring " + "invalid class %s\n", + value); + return (value_from_next); + case 'f': + batchname = value; + return (value_from_next); + case 'k': + strncpy(keyfile, value, sizeof(keyfile)); + keyfile[sizeof(keyfile)-1]=0; + return (value_from_next); + case 'p': + port = (in_port_t) parse_uint(value, "port number", MAXPORT); + return (value_from_next); + case 'q': + if (!config_only) { + if (*need_clone) + (*lookup) = clone_lookup(default_lookup, + ISC_TRUE); + *need_clone = ISC_TRUE; + strncpy((*lookup)->textname, value, + sizeof((*lookup)->textname)); + (*lookup)->textname[sizeof((*lookup)->textname)-1]=0; + (*lookup)->trace_root = ISC_TF((*lookup)->trace || + (*lookup)->ns_search_only); + (*lookup)->new_search = ISC_TRUE; + if (*firstarg) { + printgreeting(argc, argv, *lookup); + *firstarg = ISC_FALSE; + } + ISC_LIST_APPEND(lookup_list, (*lookup), link); + debug("looking up %s", (*lookup)->textname); + } + return (value_from_next); + case 't': + *open_type_class = ISC_FALSE; + if (strncasecmp(value, "ixfr=", 5) == 0) { + rdtype = dns_rdatatype_ixfr; + result = ISC_R_SUCCESS; + } else { + tr.base = value; + tr.length = strlen(value); + result = dns_rdatatype_fromtext(&rdtype, + (isc_textregion_t *)&tr); + if (result == ISC_R_SUCCESS && + rdtype == dns_rdatatype_ixfr) { + result = DNS_R_UNKNOWN; + } + } + if (result == ISC_R_SUCCESS) { + if ((*lookup)->rdtypeset) { + fprintf(stderr, ";; Warning, " + "extra type option\n"); + } + if (rdtype == dns_rdatatype_ixfr) { + (*lookup)->rdtype = dns_rdatatype_ixfr; + (*lookup)->rdtypeset = ISC_TRUE; + (*lookup)->ixfr_serial = + parse_uint(&value[5], "serial number", + MAXSERIAL); + (*lookup)->section_question = plusquest; + (*lookup)->comments = pluscomm; + } else { + (*lookup)->rdtype = rdtype; + (*lookup)->rdtypeset = ISC_TRUE; + if (rdtype == dns_rdatatype_axfr) { + (*lookup)->section_question = plusquest; + (*lookup)->comments = pluscomm; + } + (*lookup)->ixfr_serial = ISC_FALSE; + } + } else + fprintf(stderr, ";; Warning, ignoring " + "invalid type %s\n", + value); + return (value_from_next); + case 'y': + ptr = next_token(&value,":"); /* hmac type or name */ + if (ptr == NULL) { + usage(); + } + ptr2 = next_token(&value, ":"); /* name or secret */ + if (ptr2 == NULL) + usage(); + ptr3 = next_token(&value,":"); /* secret or NULL */ + if (ptr3 != NULL) { + if (strcasecmp(ptr, "hmac-md5") == 0) { + hmacname = DNS_TSIG_HMACMD5_NAME; + digestbits = 0; + } else if (strncasecmp(ptr, "hmac-md5-", 9) == 0) { + hmacname = DNS_TSIG_HMACMD5_NAME; + digestbits = parse_uint(&ptr[9], + "digest-bits [0..128]", + 128); + digestbits = (digestbits + 7) & ~0x7U; + } else if (strcasecmp(ptr, "hmac-sha1") == 0) { + hmacname = DNS_TSIG_HMACSHA1_NAME; + digestbits = 0; + } else if (strncasecmp(ptr, "hmac-sha1-", 10) == 0) { + hmacname = DNS_TSIG_HMACSHA1_NAME; + digestbits = parse_uint(&ptr[10], + "digest-bits [0..160]", + 160); + digestbits = (digestbits + 7) & ~0x7U; + } else if (strcasecmp(ptr, "hmac-sha224") == 0) { + hmacname = DNS_TSIG_HMACSHA224_NAME; + digestbits = 0; + } else if (strncasecmp(ptr, "hmac-sha224-", 12) == 0) { + hmacname = DNS_TSIG_HMACSHA224_NAME; + digestbits = parse_uint(&ptr[12], + "digest-bits [0..224]", + 224); + digestbits = (digestbits + 7) & ~0x7U; + } else if (strcasecmp(ptr, "hmac-sha256") == 0) { + hmacname = DNS_TSIG_HMACSHA256_NAME; + digestbits = 0; + } else if (strncasecmp(ptr, "hmac-sha256-", 12) == 0) { + hmacname = DNS_TSIG_HMACSHA256_NAME; + digestbits = parse_uint(&ptr[12], + "digest-bits [0..256]", + 256); + digestbits = (digestbits + 7) & ~0x7U; + } else if (strcasecmp(ptr, "hmac-sha384") == 0) { + hmacname = DNS_TSIG_HMACSHA384_NAME; + digestbits = 0; + } else if (strncasecmp(ptr, "hmac-sha384-", 12) == 0) { + hmacname = DNS_TSIG_HMACSHA384_NAME; + digestbits = parse_uint(&ptr[12], + "digest-bits [0..384]", + 384); + digestbits = (digestbits + 7) & ~0x7U; + } else if (strcasecmp(ptr, "hmac-sha512") == 0) { + hmacname = DNS_TSIG_HMACSHA512_NAME; + digestbits = 0; + } else if (strncasecmp(ptr, "hmac-sha512-", 12) == 0) { + hmacname = DNS_TSIG_HMACSHA512_NAME; + digestbits = parse_uint(&ptr[12], + "digest-bits [0..512]", + 512); + digestbits = (digestbits + 7) & ~0x7U; + } else { + fprintf(stderr, ";; Warning, ignoring " + "invalid TSIG algorithm %s\n", ptr); + return (value_from_next); + } + ptr = ptr2; + ptr2 = ptr3; + } else { + hmacname = DNS_TSIG_HMACMD5_NAME; + digestbits = 0; + } + strncpy(keynametext, ptr, sizeof(keynametext)); + keynametext[sizeof(keynametext)-1]=0; + strncpy(keysecret, ptr2, sizeof(keysecret)); + keysecret[sizeof(keysecret)-1]=0; + return (value_from_next); + case 'x': + if (*need_clone) + *lookup = clone_lookup(default_lookup, ISC_TRUE); + *need_clone = ISC_TRUE; + if (get_reverse(textname, sizeof(textname), value, + ip6_int, ISC_FALSE) == ISC_R_SUCCESS) { + strncpy((*lookup)->textname, textname, + sizeof((*lookup)->textname)); + debug("looking up %s", (*lookup)->textname); + (*lookup)->trace_root = ISC_TF((*lookup)->trace || + (*lookup)->ns_search_only); + (*lookup)->ip6_int = ip6_int; + if (!(*lookup)->rdtypeset) + (*lookup)->rdtype = dns_rdatatype_ptr; + if (!(*lookup)->rdclassset) + (*lookup)->rdclass = dns_rdataclass_in; + (*lookup)->new_search = ISC_TRUE; + if (*firstarg) { + printgreeting(argc, argv, *lookup); + *firstarg = ISC_FALSE; + } + ISC_LIST_APPEND(lookup_list, *lookup, link); + } else { + fprintf(stderr, "Invalid IP address %s\n", value); + exit(1); + } + return (value_from_next); + invalid_option: + default: + fprintf(stderr, "Invalid option: -%s\n", option); + usage(); + } + return (ISC_FALSE); +} + +/*% + * Because we may be trying to do memory allocation recording, we're going + * to need to parse the arguments for the -m *before* we start the main + * argument parsing routine. + * + * I'd prefer not to have to do this, but I am not quite sure how else to + * fix the problem. Argument parsing in dig involves memory allocation + * by its nature, so it can't be done in the main argument parser. + */ +static void +preparse_args(int argc, char **argv) { + int rc; + char **rv; + char *option; + + rc = argc; + rv = argv; + for (rc--, rv++; rc > 0; rc--, rv++) { + if (rv[0][0] != '-') + continue; + option = &rv[0][1]; + while (strpbrk(option, single_dash_opts) == &option[0]) { + if (option[0] == 'm') { + memdebugging = ISC_TRUE; + isc_mem_debugging = ISC_MEM_DEBUGTRACE | + ISC_MEM_DEBUGRECORD; + return; + } + option = &option[1]; + } + } +} + +static void +getaddresses(dig_lookup_t *lookup, const char *host) { + isc_result_t result; + isc_sockaddr_t sockaddrs[DIG_MAX_ADDRESSES]; + isc_netaddr_t netaddr; + int count, i; + dig_server_t *srv; + char tmp[ISC_NETADDR_FORMATSIZE]; + + result = bind9_getaddresses(host, 0, sockaddrs, + DIG_MAX_ADDRESSES, &count); + if (result != ISC_R_SUCCESS) + fatal("couldn't get address for '%s': %s", + host, isc_result_totext(result)); + + for (i = 0; i < count; i++) { + isc_netaddr_fromsockaddr(&netaddr, &sockaddrs[i]); + isc_netaddr_format(&netaddr, tmp, sizeof(tmp)); + srv = make_server(tmp, host); + ISC_LIST_APPEND(lookup->my_server_list, srv, link); + } + addresscount = count; +} + +static void +parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, + int argc, char **argv) { + isc_result_t result; + isc_textregion_t tr; + isc_boolean_t firstarg = ISC_TRUE; + dig_lookup_t *lookup = NULL; + dns_rdatatype_t rdtype; + dns_rdataclass_t rdclass; + isc_boolean_t open_type_class = ISC_TRUE; + char batchline[MXNAME]; + int bargc; + char *bargv[64]; + int rc; + char **rv; +#ifndef NOPOSIX + char *homedir; + char rcfile[256]; +#endif + char *input; + int i; + isc_boolean_t need_clone = ISC_TRUE; + + /* + * The semantics for parsing the args is a bit complex; if + * we don't have a host yet, make the arg apply globally, + * otherwise make it apply to the latest host. This is + * a bit different than the previous versions, but should + * form a consistent user interface. + * + * First, create a "default lookup" which won't actually be used + * anywhere, except for cloning into new lookups + */ + + debug("parse_args()"); + if (!is_batchfile) { + debug("making new lookup"); + default_lookup = make_empty_lookup(); + +#ifndef NOPOSIX + /* + * Treat ${HOME}/.digrc as a special batchfile + */ + INSIST(batchfp == NULL); + homedir = getenv("HOME"); + if (homedir != NULL) { + unsigned int n; + n = snprintf(rcfile, sizeof(rcfile), "%s/.digrc", + homedir); + if (n < sizeof(rcfile)) + batchfp = fopen(rcfile, "r"); + } + if (batchfp != NULL) { + while (fgets(batchline, sizeof(batchline), + batchfp) != 0) { + debug("config line %s", batchline); + bargc = 1; + input = batchline; + bargv[bargc] = next_token(&input, " \t\r\n"); + while ((bargv[bargc] != NULL) && + (bargc < 62)) { + bargc++; + bargv[bargc] = + next_token(&input, " \t\r\n"); + } + + bargv[0] = argv[0]; + argv0 = argv[0]; + + for(i = 0; i < bargc; i++) + debug(".digrc argv %d: %s", + i, bargv[i]); + parse_args(ISC_TRUE, ISC_TRUE, bargc, + (char **)bargv); + } + fclose(batchfp); + } +#endif + } + + if (is_batchfile && !config_only) { + /* Processing '-f batchfile'. */ + lookup = clone_lookup(default_lookup, ISC_TRUE); + need_clone = ISC_FALSE; + } else + lookup = default_lookup; + + rc = argc; + rv = argv; + for (rc--, rv++; rc > 0; rc--, rv++) { + debug("main parsing %s", rv[0]); + if (strncmp(rv[0], "%", 1) == 0) + break; + if (strncmp(rv[0], "@", 1) == 0) { + getaddresses(lookup, &rv[0][1]); + } else if (rv[0][0] == '+') { + plus_option(&rv[0][1], is_batchfile, + lookup); + } else if (rv[0][0] == '-') { + if (rc <= 1) { + if (dash_option(&rv[0][1], NULL, + &lookup, &open_type_class, + &need_clone, config_only, + argc, argv, &firstarg)) { + rc--; + rv++; + } + } else { + if (dash_option(&rv[0][1], rv[1], + &lookup, &open_type_class, + &need_clone, config_only, + argc, argv, &firstarg)) { + rc--; + rv++; + } + } + } else { + /* + * Anything which isn't an option + */ + if (open_type_class) { + if (strncasecmp(rv[0], "ixfr=", 5) == 0) { + rdtype = dns_rdatatype_ixfr; + result = ISC_R_SUCCESS; + } else { + tr.base = rv[0]; + tr.length = strlen(rv[0]); + result = dns_rdatatype_fromtext(&rdtype, + (isc_textregion_t *)&tr); + if (result == ISC_R_SUCCESS && + rdtype == dns_rdatatype_ixfr) { + result = DNS_R_UNKNOWN; + fprintf(stderr, ";; Warning, " + "ixfr requires a " + "serial number\n"); + continue; + } + } + if (result == ISC_R_SUCCESS) { + if (lookup->rdtypeset) { + fprintf(stderr, ";; Warning, " + "extra type option\n"); + } + if (rdtype == dns_rdatatype_ixfr) { + lookup->rdtype = + dns_rdatatype_ixfr; + lookup->rdtypeset = ISC_TRUE; + lookup->ixfr_serial = + parse_uint(&rv[0][5], + "serial number", + MAXSERIAL); + lookup->section_question = + plusquest; + lookup->comments = pluscomm; + } else { + lookup->rdtype = rdtype; + lookup->rdtypeset = ISC_TRUE; + if (rdtype == + dns_rdatatype_axfr) { + lookup->section_question = + plusquest; + lookup->comments = pluscomm; + } + lookup->ixfr_serial = ISC_FALSE; + } + continue; + } + result = dns_rdataclass_fromtext(&rdclass, + (isc_textregion_t *)&tr); + if (result == ISC_R_SUCCESS) { + if (lookup->rdclassset) { + fprintf(stderr, ";; Warning, " + "extra class option\n"); + } + lookup->rdclass = rdclass; + lookup->rdclassset = ISC_TRUE; + continue; + } + } + + if (!config_only) { + if (need_clone) + lookup = clone_lookup(default_lookup, + ISC_TRUE); + need_clone = ISC_TRUE; + strncpy(lookup->textname, rv[0], + sizeof(lookup->textname)); + lookup->textname[sizeof(lookup->textname)-1]=0; + lookup->trace_root = ISC_TF(lookup->trace || + lookup->ns_search_only); + lookup->new_search = ISC_TRUE; + if (firstarg) { + printgreeting(argc, argv, lookup); + firstarg = ISC_FALSE; + } + ISC_LIST_APPEND(lookup_list, lookup, link); + debug("looking up %s", lookup->textname); + } + /* XXX Error message */ + } + } + + /* + * If we have a batchfile, seed the lookup list with the + * first entry, then trust the callback in dighost_shutdown + * to get the rest + */ + if ((batchname != NULL) && !(is_batchfile)) { + if (strcmp(batchname, "-") == 0) + batchfp = stdin; + else + batchfp = fopen(batchname, "r"); + if (batchfp == NULL) { + perror(batchname); + if (exitcode < 8) + exitcode = 8; + fatal("couldn't open specified batch file"); + } + /* XXX Remove code dup from shutdown code */ + next_line: + if (fgets(batchline, sizeof(batchline), batchfp) != 0) { + bargc = 1; + debug("batch line %s", batchline); + if (batchline[0] == '\r' || batchline[0] == '\n' + || batchline[0] == '#' || batchline[0] == ';') + goto next_line; + input = batchline; + bargv[bargc] = next_token(&input, " \t\r\n"); + while ((bargv[bargc] != NULL) && (bargc < 14)) { + bargc++; + bargv[bargc] = next_token(&input, " \t\r\n"); + } + + bargv[0] = argv[0]; + argv0 = argv[0]; + + for(i = 0; i < bargc; i++) + debug("batch argv %d: %s", i, bargv[i]); + parse_args(ISC_TRUE, ISC_FALSE, bargc, (char **)bargv); + return; + } + return; + } + /* + * If no lookup specified, search for root + */ + if ((lookup_list.head == NULL) && !config_only) { + if (need_clone) + lookup = clone_lookup(default_lookup, ISC_TRUE); + need_clone = ISC_TRUE; + lookup->trace_root = ISC_TF(lookup->trace || + lookup->ns_search_only); + lookup->new_search = ISC_TRUE; + strcpy(lookup->textname, "."); + lookup->rdtype = dns_rdatatype_ns; + lookup->rdtypeset = ISC_TRUE; + if (firstarg) { + printgreeting(argc, argv, lookup); + firstarg = ISC_FALSE; + } + ISC_LIST_APPEND(lookup_list, lookup, link); + } + if (!need_clone) + destroy_lookup(lookup); +} + +/* + * Callback from dighost.c to allow program-specific shutdown code. + * Here, we're possibly reading from a batch file, then shutting down + * for real if there's nothing in the batch file to read. + */ +void +dighost_shutdown(void) { + char batchline[MXNAME]; + int bargc; + char *bargv[16]; + char *input; + int i; + + if (batchname == NULL) { + isc_app_shutdown(); + return; + } + + fflush(stdout); + if (feof(batchfp)) { + batchname = NULL; + isc_app_shutdown(); + if (batchfp != stdin) + fclose(batchfp); + return; + } + + if (fgets(batchline, sizeof(batchline), batchfp) != 0) { + debug("batch line %s", batchline); + bargc = 1; + input = batchline; + bargv[bargc] = next_token(&input, " \t\r\n"); + while ((bargv[bargc] != NULL) && (bargc < 14)) { + bargc++; + bargv[bargc] = next_token(&input, " \t\r\n"); + } + + bargv[0] = argv0; + + for(i = 0; i < bargc; i++) + debug("batch argv %d: %s", i, bargv[i]); + parse_args(ISC_TRUE, ISC_FALSE, bargc, (char **)bargv); + start_lookup(); + } else { + batchname = NULL; + if (batchfp != stdin) + fclose(batchfp); + isc_app_shutdown(); + return; + } +} + +/*% Main processing routine for dig */ +int +main(int argc, char **argv) { + isc_result_t result; + + ISC_LIST_INIT(lookup_list); + ISC_LIST_INIT(server_list); + ISC_LIST_INIT(search_list); + + debug("main()"); + preparse_args(argc, argv); + progname = argv[0]; + result = isc_app_start(); + check_result(result, "isc_app_start"); + setup_libs(); + parse_args(ISC_FALSE, ISC_FALSE, argc, argv); + setup_system(); + if (domainopt[0] != '\0') { + set_search_domain(domainopt); + usesearch = ISC_TRUE; + } + result = isc_app_onrun(mctx, global_task, onrun_callback, NULL); + check_result(result, "isc_app_onrun"); + isc_app_run(); + destroy_lookup(default_lookup); + if (batchname != NULL) { + if (batchfp != stdin) + fclose(batchfp); + batchname = NULL; + } +#ifdef DIG_SIGCHASE + clean_trustedkey(); +#endif + cancel_all(); + destroy_libs(); + isc_app_finish(); + return (exitcode); +} diff --git a/bin/dig/dig.docbook b/bin/dig/dig.docbook new file mode 100644 index 0000000..6a28b88 --- /dev/null +++ b/bin/dig/dig.docbook @@ -0,0 +1,936 @@ +]> + + + + + + + Jun 30, 2000 + + + + dig + 1 + BIND9 + + + + dig + DNS lookup utility + + + + + 2004 + 2005 + 2006 + 2007 + Internet Systems Consortium, Inc. ("ISC") + + + 2000 + 2001 + 2002 + 2003 + Internet Software Consortium. + + + + + + dig + @server + + + + + + + + + + + + name + type + class + queryopt + + + + dig + + + + + dig + global-queryopt + query + + + + + DESCRIPTION + dig + (domain information groper) is a flexible tool + for interrogating DNS name servers. It performs DNS lookups and + displays the answers that are returned from the name server(s) that + were queried. Most DNS administrators use dig to + troubleshoot DNS problems because of its flexibility, ease of use and + clarity of output. Other lookup tools tend to have less functionality + than dig. + + + + Although dig is normally used with + command-line + arguments, it also has a batch mode of operation for reading lookup + requests from a file. A brief summary of its command-line arguments + and options is printed when the option is given. + Unlike earlier versions, the BIND 9 implementation of + dig allows multiple lookups to be issued + from the + command line. + + + + Unless it is told to query a specific name server, + dig will try each of the servers listed + in + /etc/resolv.conf. + + + + When no command line arguments or options are given, will perform an + NS query for "." (the root). + + + + It is possible to set per-user defaults for dig via + ${HOME}/.digrc. This file is read and + any options in it + are applied before the command line arguments. + + + + The IN and CH class names overlap with the IN and CH top level + domains names. Either use the and + options to specify the type and class or + use the the specify the domain name or + use "IN." and "CH." when looking up these top level domains. + + + + + + SIMPLE USAGE + + + A typical invocation of dig looks like: + dig @server name type + where: + + + + + server + + + is the name or IP address of the name server to query. This can + be an IPv4 + address in dotted-decimal notation or an IPv6 + address in colon-delimited notation. When the supplied + server argument is a + hostname, + dig resolves that name before + querying that name + server. If no server + argument is provided, + dig consults /etc/resolv.conf + and queries the name servers listed there. The reply from the + name + server that responds is displayed. + + + + + + name + + + is the name of the resource record that is to be looked up. + + + + + + type + + + indicates what type of query is required — + ANY, A, MX, SIG, etc. + type can be any valid query + type. If no + type argument is supplied, + dig will perform a lookup for an + A record. + + + + + + + + + + + OPTIONS + + + The option sets the source IP address of the query + to address. This must be a valid + address on + one of the host's network interfaces or "0.0.0.0" or "::". An optional + port + may be specified by appending "#<port>" + + + + The default query class (IN for internet) is overridden by the + option. class is + any valid + class, such as HS for Hesiod records or CH for Chaosnet records. + + + + The option makes dig + operate + in batch mode by reading a list of lookup requests to process from the + file filename. The file contains a + number of + queries, one per line. Each entry in the file should be organized in + the same way they would be presented as queries to + dig using the command-line interface. + + + + If a non-standard port number is to be queried, the + option is used. port# is + the port number that dig will send its + queries + instead of the standard DNS port number 53. This option would be used + to test a name server that has been configured to listen for queries + on a non-standard port number. + + + + The option forces dig + to only + use IPv4 query transport. The option forces + dig to only use IPv6 query transport. + + + + The option sets the query type to + type. It can be any valid query type + which is + supported in BIND 9. The default query type is "A", unless the + option is supplied to indicate a reverse lookup. + A zone transfer can be requested by specifying a type of AXFR. When + an incremental zone transfer (IXFR) is required, + type is set to ixfr=N. + The incremental zone transfer will contain the changes made to the zone + since the serial number in the zone's SOA record was + N. + + + + The option sets the query name to + name. This useful do distinguish the + name from other arguments. + + + + Reverse lookups — mapping addresses to names — are simplified by the + option. addr is + an IPv4 + address in dotted-decimal notation, or a colon-delimited IPv6 address. + When this option is used, there is no need to provide the + name, class and + type arguments. dig + automatically performs a lookup for a name like + 11.12.13.10.in-addr.arpa and sets the + query type and + class to PTR and IN respectively. By default, IPv6 addresses are + looked up using nibble format under the IP6.ARPA domain. + To use the older RFC1886 method using the IP6.INT domain + specify the option. Bit string labels (RFC2874) + are now experimental and are not attempted. + + + + To sign the DNS queries sent by dig and + their + responses using transaction signatures (TSIG), specify a TSIG key file + using the option. You can also specify the TSIG + key itself on the command line using the option; + hmac is the type of the TSIG, default HMAC-MD5, + name is the name of the TSIG key and + key is the actual key. The key is a + base-64 + encoded string, typically generated by + + dnssec-keygen8 + . + + Caution should be taken when using the option on + multi-user systems as the key can be visible in the output from + + ps1 + + or in the shell's history file. When + using TSIG authentication with dig, the name + server that is queried needs to know the key and algorithm that is + being used. In BIND, this is done by providing appropriate + key and server statements in + named.conf. + + + + + + QUERY OPTIONS + + dig + provides a number of query options which affect + the way in which lookups are made and the results displayed. Some of + these set or reset flag bits in the query header, some determine which + sections of the answer get printed, and others determine the timeout + and retry strategies. + + + + Each query option is identified by a keyword preceded by a plus sign + (+). Some keywords set or reset an + option. These may be preceded + by the string no to negate the meaning of + that keyword. Other + keywords assign values to options like the timeout interval. They + have the form . + The query options are: + + + + + + + + Use [do not use] TCP when querying name servers. The default + behavior is to use UDP unless an AXFR or IXFR query is + requested, in + which case a TCP connection is used. + + + + + + + + + Use [do not use] TCP when querying name servers. This alternate + syntax to +[no]tcp is + provided for backwards + compatibility. The "vc" stands for "virtual circuit". + + + + + + + + + Ignore truncation in UDP responses instead of retrying with TCP. + By + default, TCP retries are performed. + + + + + + + + + Set the search list to contain the single domain + somename, as if specified in + a + domain directive in + /etc/resolv.conf, and enable + search list + processing as if the +search + option were given. + + + + + + + + + Use [do not use] the search list defined by the searchlist or + domain + directive in resolv.conf (if + any). + The search list is not used by default. + + + + + + + + + Perform [do not perform] a search showing intermediate + results. + + + + + + + + + Deprecated, treated as a synonym for +[no]search + + + + + + + + + Sets the "aa" flag in the query. + + + + + + + + + A synonym for +[no]aaonly. + + + + + + + + + Set [do not set] the AD (authentic data) bit in the query. The + AD bit + currently has a standard meaning only in responses, not in + queries, + but the ability to set the bit in the query is provided for + completeness. + + + + + + + + + Set [do not set] the CD (checking disabled) bit in the query. + This + requests the server to not perform DNSSEC validation of + responses. + + + + + + + + + Display [do not display] the CLASS when printing the record. + + + + + + + + + Display [do not display] the TTL when printing the record. + + + + + + + + + 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. + + + + + + + + + When this option is set, dig + attempts to find the + authoritative name servers for the zone containing the name + being + looked up and display the SOA record that each name server has + for the + zone. + + + + + + + + + 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. + + + + + + + + + Toggles the printing of the initial comment in the output + identifying + the version of dig and the query + options that have + been applied. This comment is printed by default. + + + + + + + + + Provide a terse answer. The default is to print the answer in a + verbose form. + + + + + + + + + Show [or do not show] the IP address and port number that + supplied the + answer when the +short option + is enabled. If + short form answers are requested, the default is not to show the + source address and port number of the server that provided the + answer. + + + + + + + + + Toggle the display of comment lines in the output. The default + is to + print comments. + + + + + + + + + This query option toggles the printing of statistics: when the + query + was made, the size of the reply and so on. The default + behavior is + to print the query statistics. + + + + + + + + + Print [do not print] the query as it is sent. + By default, the query is not printed. + + + + + + + + + Print [do not print] the question section of a query when an + answer is + returned. The default is to print the question section as a + comment. + + + + + + + + + Display [do not display] the answer section of a reply. The + default + is to display it. + + + + + + + + + Display [do not display] the authority section of a reply. The + default is to display it. + + + + + + + + + Display [do not display] the additional section of a reply. + The default is to display it. + + + + + + + + + Set or clear all display flags. + + + + + + + + + + Sets the timeout for a query to + T seconds. The default + timeout is 5 seconds. + An attempt to set T to less + than 1 will result + in a query timeout of 1 second being applied. + + + + + + + + + Sets the number of times to try UDP queries to server to + T instead of the default, 3. + If + T is less than or equal to + zero, the number of + tries is silently rounded up to 1. + + + + + + + + + Sets the number of times to retry UDP queries to server to + T instead of the default, 2. + Unlike + +tries, this does not include + the initial + query. + + + + + + + + + Set the number of dots that have to appear in + name to D for it to be + considered absolute. The default value is that defined using + the + ndots statement in /etc/resolv.conf, or 1 if no + ndots statement is present. Names with fewer dots are + interpreted as + relative names and will be searched for in the domains listed in + the + or directive in + /etc/resolv.conf. + + + + + + + + + Set the UDP message buffer size advertised using EDNS0 to + B bytes. The maximum and minimum sizes + of this buffer are 65535 and 0 respectively. Values outside + this range are rounded up or down appropriately. + Values other than zero will cause a EDNS query to be sent. + + + + + + + + + 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. + + + + + + + + + Print records like the SOA records in a verbose multi-line + format with human-readable comments. The default is to print + each record on a single line, to facilitate machine parsing + of the dig output. + + + + + + + + + Do not try the next server if you receive a SERVFAIL. The + default is + to not try the next server which is the reverse of normal stub + resolver + behavior. + + + + + + + + + Attempt to display the contents of messages which are malformed. + The default is to not display malformed answers. + + + + + + + + + Requests DNSSEC records be sent by setting the DNSSEC OK bit + (DO) + in the OPT record in the additional section of the query. + + + + + + + + + Chase DNSSEC signature chains. Requires dig be compiled with + -DDIG_SIGCHASE. + + + + + + + + + Specifies a file containing trusted keys to be used with + . Each DNSKEY record must be + on its own line. + + + If not specified dig will look for + /etc/trusted-key.key then + trusted-key.key in the current directory. + + + Requires dig be compiled with -DDIG_SIGCHASE. + + + + + + + + + When chasing DNSSEC signature chains perform a top-down + validation. + Requires dig be compiled with -DDIG_SIGCHASE. + + + + + + + + + + + + + MULTIPLE QUERIES + + + The BIND 9 implementation of dig + supports + specifying multiple queries on the command line (in addition to + supporting the batch file option). Each of those + queries can be supplied with its own set of flags, options and query + options. + + + + In this case, each query argument + represent an + individual query in the command-line syntax described above. Each + consists of any of the standard options and flags, the name to be + looked up, an optional query type and class and any query options that + should be applied to that query. + + + + A global set of query options, which should be applied to all queries, + can also be supplied. These global query options must precede the + first tuple of name, class, type, options, flags, and query options + supplied on the command line. Any global query options (except + the option) can be + overridden by a query-specific set of query options. For example: + +dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr + + shows how dig could be used from the + command line + to make three lookups: an ANY query for www.isc.org, a + reverse lookup of 127.0.0.1 and a query for the NS records of + isc.org. + + A global query option of +qr is + applied, so + that dig shows the initial query it made + for each + lookup. The final query has a local query option of + +noqr which means that dig + will not print the initial query when it looks up the NS records for + isc.org. + + + + + + IDN SUPPORT + + If dig has been built with IDN (internationalized + domain name) support, it can accept and display non-ASCII domain names. + dig appropriately converts character encoding of + domain name before sending a request to DNS server or displaying a + reply from the server. + If you'd like to turn off the IDN support for some reason, defines + the IDN_DISABLE environment variable. + The IDN support is disabled if the variable is set when + dig runs. + + + + + FILES + /etc/resolv.conf + + ${HOME}/.digrc + + + + + SEE ALSO + + host1 + , + + named8 + , + + dnssec-keygen8 + , + RFC1035. + + + + + BUGS + + There are probably too many query options. + + + diff --git a/bin/dig/dig.html b/bin/dig/dig.html new file mode 100644 index 0000000..afdaa4f --- /dev/null +++ b/bin/dig/dig.html @@ -0,0 +1,629 @@ + + + + + +dig + + +
+
+
+

Name

+

dig — DNS lookup utility

+
+
+

Synopsis

+

dig [@server] [-b address] [-c class] [-f filename] [-k filename] [-p port#] [-q name] [-t type] [-x addr] [-y [hmac:]name:key] [-4] [-6] [name] [type] [class] [queryopt...]

+

dig [-h]

+

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

+
+
+

DESCRIPTION

+

dig + (domain information groper) is a flexible tool + for interrogating DNS name servers. It performs DNS lookups and + displays the answers that are returned from the name server(s) that + were queried. Most DNS administrators use dig to + troubleshoot DNS problems because of its flexibility, ease of use and + clarity of output. Other lookup tools tend to have less functionality + than dig. +

+

+ Although dig is normally used with + command-line + arguments, it also has a batch mode of operation for reading lookup + requests from a file. A brief summary of its command-line arguments + and options is printed when the -h option is given. + Unlike earlier versions, the BIND 9 implementation of + dig allows multiple lookups to be issued + from the + command line. +

+

+ Unless it is told to query a specific name server, + dig will try each of the servers listed + in + /etc/resolv.conf. +

+

+ When no command line arguments or options are given, will perform an + NS query for "." (the root). +

+

+ It is possible to set per-user defaults for dig via + ${HOME}/.digrc. This file is read and + any options in it + are applied before the command line arguments. +

+

+ The IN and CH class names overlap with the IN and CH top level + domains names. Either use the -t and + -c options to specify the type and class or + use the -q the specify the domain name or + use "IN." and "CH." when looking up these top level domains. +

+
+
+

SIMPLE USAGE

+

+ A typical invocation of dig looks like: +

+
 dig @server name type 
+

+ where: + +

+
+
server
+

+ is the name or IP address of the name server to query. This can + be an IPv4 + address in dotted-decimal notation or an IPv6 + address in colon-delimited notation. When the supplied + server argument is a + hostname, + dig resolves that name before + querying that name + server. If no server + argument is provided, + dig consults /etc/resolv.conf + and queries the name servers listed there. The reply from the + name + server that responds is displayed. +

+
name
+

+ is the name of the resource record that is to be looked up. +

+
type
+

+ indicates what type of query is required — + ANY, A, MX, SIG, etc. + type can be any valid query + type. If no + type argument is supplied, + dig will perform a lookup for an + A record. +

+
+

+

+
+
+

OPTIONS

+

+ The -b option sets the source IP address of the query + to address. This must be a valid + address on + one of the host's network interfaces or "0.0.0.0" or "::". An optional + port + may be specified by appending "#<port>" +

+

+ The default query class (IN for internet) is overridden by the + -c option. class is + any valid + class, such as HS for Hesiod records or CH for Chaosnet records. +

+

+ The -f option makes dig + operate + in batch mode by reading a list of lookup requests to process from the + file filename. The file contains a + number of + queries, one per line. Each entry in the file should be organized in + the same way they would be presented as queries to + dig using the command-line interface. +

+

+ If a non-standard port number is to be queried, the + -p option is used. port# is + the port number that dig will send its + queries + instead of the standard DNS port number 53. This option would be used + to test a name server that has been configured to listen for queries + on a non-standard port number. +

+

+ The -4 option forces dig + to only + use IPv4 query transport. The -6 option forces + dig to only use IPv6 query transport. +

+

+ The -t option sets the query type to + type. It can be any valid query type + which is + supported in BIND 9. The default query type is "A", unless the + -x option is supplied to indicate a reverse lookup. + A zone transfer can be requested by specifying a type of AXFR. When + an incremental zone transfer (IXFR) is required, + type is set to ixfr=N. + The incremental zone transfer will contain the changes made to the zone + since the serial number in the zone's SOA record was + N. +

+

+ The -q option sets the query name to + name. This useful do distinguish the + name from other arguments. +

+

+ Reverse lookups — mapping addresses to names — are simplified by the + -x option. addr is + an IPv4 + address in dotted-decimal notation, or a colon-delimited IPv6 address. + When this option is used, there is no need to provide the + name, class and + type arguments. dig + automatically performs a lookup for a name like + 11.12.13.10.in-addr.arpa and sets the + query type and + class to PTR and IN respectively. By default, IPv6 addresses are + looked up using nibble format under the IP6.ARPA domain. + To use the older RFC1886 method using the IP6.INT domain + specify the -i option. Bit string labels (RFC2874) + are now experimental and are not attempted. +

+

+ To sign the DNS queries sent by dig and + their + responses using transaction signatures (TSIG), specify a TSIG key file + using the -k option. You can also specify the TSIG + key itself on the command line using the -y option; + hmac is the type of the TSIG, default HMAC-MD5, + name is the name of the TSIG key and + key is the actual key. The key is a + base-64 + encoded string, typically generated by + dnssec-keygen(8). + + Caution should be taken when using the -y option on + multi-user systems as the key can be visible in the output from + ps(1) + or in the shell's history file. When + using TSIG authentication with dig, the name + server that is queried needs to know the key and algorithm that is + being used. In BIND, this is done by providing appropriate + key and server statements in + named.conf. +

+
+
+

QUERY OPTIONS

+

dig + provides a number of query options which affect + the way in which lookups are made and the results displayed. Some of + these set or reset flag bits in the query header, some determine which + sections of the answer get printed, and others determine the timeout + and retry strategies. +

+

+ Each query option is identified by a keyword preceded by a plus sign + (+). Some keywords set or reset an + option. These may be preceded + by the string no to negate the meaning of + that keyword. Other + keywords assign values to options like the timeout interval. They + have the form +keyword=value. + The query options are: + +

+
+
+[no]tcp
+

+ Use [do not use] TCP when querying name servers. The default + behavior is to use UDP unless an AXFR or IXFR query is + requested, in + which case a TCP connection is used. +

+
+[no]vc
+

+ Use [do not use] TCP when querying name servers. This alternate + syntax to +[no]tcp is + provided for backwards + compatibility. The "vc" stands for "virtual circuit". +

+
+[no]ignore
+

+ Ignore truncation in UDP responses instead of retrying with TCP. + By + default, TCP retries are performed. +

+
+domain=somename
+

+ Set the search list to contain the single domain + somename, as if specified in + a + domain directive in + /etc/resolv.conf, and enable + search list + processing as if the +search + option were given. +

+
+[no]search
+

+ Use [do not use] the search list defined by the searchlist or + domain + directive in resolv.conf (if + any). + The search list is not used by default. +

+
+[no]showsearch
+

+ Perform [do not perform] a search showing intermediate + results. +

+
+[no]defname
+

+ Deprecated, treated as a synonym for +[no]search +

+
+[no]aaonly
+

+ Sets the "aa" flag in the query. +

+
+[no]aaflag
+

+ A synonym for +[no]aaonly. +

+
+[no]adflag
+

+ Set [do not set] the AD (authentic data) bit in the query. The + AD bit + currently has a standard meaning only in responses, not in + queries, + but the ability to set the bit in the query is provided for + completeness. +

+
+[no]cdflag
+

+ Set [do not set] the CD (checking disabled) bit in the query. + This + requests the server to not perform DNSSEC validation of + responses. +

+
+[no]cl
+

+ Display [do not display] the CLASS when printing the record. +

+
+[no]ttlid
+

+ Display [do not display] the TTL when printing the record. +

+
+[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. +

+
+[no]nssearch
+

+ When this option is set, dig + attempts to find the + authoritative name servers for the zone containing the name + being + looked up and display the SOA record that each name server has + for the + 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. +

+
+[no]cmd
+

+ Toggles the printing of the initial comment in the output + identifying + the version of dig and the query + options that have + been applied. This comment is printed by default. +

+
+[no]short
+

+ Provide a terse answer. The default is to print the answer in a + verbose form. +

+
+[no]identify
+

+ Show [or do not show] the IP address and port number that + supplied the + answer when the +short option + is enabled. If + short form answers are requested, the default is not to show the + source address and port number of the server that provided the + answer. +

+
+[no]comments
+

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

+
+[no]stats
+

+ This query option toggles the printing of statistics: when the + query + was made, the size of the reply and so on. The default + behavior is + to print the query statistics. +

+
+[no]qr
+

+ Print [do not print] the query as it is sent. + By default, the query is not printed. +

+
+[no]question
+

+ Print [do not print] the question section of a query when an + answer is + returned. The default is to print the question section as a + comment. +

+
+[no]answer
+

+ Display [do not display] the answer section of a reply. The + default + is to display it. +

+
+[no]authority
+

+ Display [do not display] the authority section of a reply. The + default is to display it. +

+
+[no]additional
+

+ Display [do not display] the additional section of a reply. + The default is to display it. +

+
+[no]all
+

+ Set or clear all display flags. +

+
+time=T
+

+ + Sets the timeout for a query to + T seconds. The default + timeout is 5 seconds. + An attempt to set T to less + than 1 will result + in a query timeout of 1 second being applied. +

+
+tries=T
+

+ Sets the number of times to try UDP queries to server to + T instead of the default, 3. + If + T is less than or equal to + zero, the number of + tries is silently rounded up to 1. +

+
+retry=T
+

+ Sets the number of times to retry UDP queries to server to + T instead of the default, 2. + Unlike + +tries, this does not include + the initial + query. +

+
+ndots=D
+

+ Set the number of dots that have to appear in + name to D for it to be + considered absolute. The default value is that defined using + the + ndots statement in /etc/resolv.conf, or 1 if no + ndots statement is present. Names with fewer dots are + interpreted as + relative names and will be searched for in the domains listed in + the + search or domain directive in + /etc/resolv.conf. +

+
+bufsize=B
+

+ Set the UDP message buffer size advertised using EDNS0 to + B bytes. The maximum and minimum sizes + of this buffer are 65535 and 0 respectively. Values outside + this range are rounded up or down appropriately. + Values other than zero will cause a EDNS query to be sent. +

+
+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. +

+
+[no]multiline
+

+ Print records like the SOA records in a verbose multi-line + format with human-readable comments. The default is to print + each record on a single line, to facilitate machine parsing + of the dig output. +

+
+[no]fail
+

+ Do not try the next server if you receive a SERVFAIL. The + default is + to not try the next server which is the reverse of normal stub + resolver + behavior. +

+
+[no]besteffort
+

+ Attempt to display the contents of messages which are malformed. + The default is to not display malformed answers. +

+
+[no]dnssec
+

+ Requests DNSSEC records be sent by setting the DNSSEC OK bit + (DO) + in the OPT record in the additional section of the query. +

+
+[no]sigchase
+

+ Chase DNSSEC signature chains. Requires dig be compiled with + -DDIG_SIGCHASE. +

+
+trusted-key=####
+
+

+ Specifies a file containing trusted keys to be used with + +sigchase. Each DNSKEY record must be + on its own line. +

+

+ If not specified dig will look for + /etc/trusted-key.key then + trusted-key.key in the current directory. +

+

+ Requires dig be compiled with -DDIG_SIGCHASE. +

+
+
+[no]topdown
+

+ When chasing DNSSEC signature chains perform a top-down + validation. + Requires dig be compiled with -DDIG_SIGCHASE. +

+
+

+ +

+
+
+

MULTIPLE QUERIES

+

+ The BIND 9 implementation of dig + supports + specifying multiple queries on the command line (in addition to + supporting the -f batch file option). Each of those + queries can be supplied with its own set of flags, options and query + options. +

+

+ In this case, each query argument + represent an + individual query in the command-line syntax described above. Each + consists of any of the standard options and flags, the name to be + looked up, an optional query type and class and any query options that + should be applied to that query. +

+

+ A global set of query options, which should be applied to all queries, + can also be supplied. These global query options must precede the + first tuple of name, class, type, options, flags, and query options + supplied on the command line. Any global query options (except + the +[no]cmd option) can be + overridden by a query-specific set of query options. For example: +

+
+dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
+
+

+ shows how dig could be used from the + command line + to make three lookups: an ANY query for www.isc.org, a + reverse lookup of 127.0.0.1 and a query for the NS records of + isc.org. + + A global query option of +qr is + applied, so + that dig shows the initial query it made + for each + lookup. The final query has a local query option of + +noqr which means that dig + will not print the initial query when it looks up the NS records for + isc.org. +

+
+
+

IDN SUPPORT

+

+ If dig has been built with IDN (internationalized + domain name) support, it can accept and display non-ASCII domain names. + dig appropriately converts character encoding of + domain name before sending a request to DNS server or displaying a + reply from the server. + If you'd like to turn off the IDN support for some reason, defines + the IDN_DISABLE environment variable. + The IDN support is disabled if the variable is set when + dig runs. +

+
+
+

FILES

+

/etc/resolv.conf +

+

${HOME}/.digrc +

+
+
+

SEE ALSO

+

host(1), + named(8), + dnssec-keygen(8), + RFC1035. +

+
+
+

BUGS

+

+ There are probably too many query options. +

+
+
+ diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c new file mode 100644 index 0000000..6e7c16b --- /dev/null +++ b/bin/dig/dighost.c @@ -0,0 +1,5399 @@ +/* + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000-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: dighost.c,v 1.259.18.43 2007/08/28 07:19:55 tbox Exp $ */ + +/*! \file + * \note + * Notice to programmers: Do not use this code as an example of how to + * use the ISC library to perform DNS lookups. Dig and Host both operate + * on the request level, since they allow fine-tuning of output and are + * intended as debugging tools. As a result, they perform many of the + * functions which could be better handled using the dns_resolver + * functions in most applications. + */ + +#include +#include +#include +#include +#include + +#ifdef HAVE_LOCALE_H +#include +#endif + +#ifdef WITH_IDN +#include +#include +#include +#include +#endif + +#include +#ifdef DIG_SIGCHASE +#include +#include +#include +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#ifdef DIG_SIGCHASE +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#if ! defined(NS_INADDRSZ) +#define NS_INADDRSZ 4 +#endif + +#if ! defined(NS_IN6ADDRSZ) +#define NS_IN6ADDRSZ 16 +#endif + +static lwres_context_t *lwctx = NULL; +static lwres_conf_t *lwconf; + +dig_lookuplist_t lookup_list; +dig_serverlist_t server_list; +dig_searchlistlist_t search_list; + +isc_boolean_t + check_ra = ISC_FALSE, + have_ipv4 = ISC_FALSE, + have_ipv6 = ISC_FALSE, + specified_source = ISC_FALSE, + free_now = ISC_FALSE, + cancel_now = ISC_FALSE, + usesearch = ISC_FALSE, + showsearch = ISC_FALSE, + qr = ISC_FALSE, + is_dst_up = ISC_FALSE; +in_port_t port = 53; +unsigned int timeout = 0; +unsigned int extrabytes; +isc_mem_t *mctx = NULL; +isc_taskmgr_t *taskmgr = NULL; +isc_task_t *global_task = NULL; +isc_timermgr_t *timermgr = NULL; +isc_socketmgr_t *socketmgr = NULL; +isc_sockaddr_t bind_address; +isc_sockaddr_t bind_any; +int sendcount = 0; +int recvcount = 0; +int sockcount = 0; +int ndots = -1; +int tries = 3; +int lookup_counter = 0; + +#ifdef WITH_IDN +static void initialize_idn(void); +static isc_result_t output_filter(isc_buffer_t *buffer, + unsigned int used_org, + isc_boolean_t absolute); +static idn_result_t append_textname(char *name, const char *origin, + size_t namesize); +static void idn_check_result(idn_result_t r, const char *msg); + +#define MAXDLEN 256 +int idnoptions = 0; +#endif + +/*% + * Exit Codes: + * + *\li 0 Everything went well, including things like NXDOMAIN + *\li 1 Usage error + *\li 7 Got too many RR's or Names + *\li 8 Couldn't open batch file + *\li 9 No reply from server + *\li 10 Internal error + */ +int exitcode = 0; +int fatalexit = 0; +char keynametext[MXNAME]; +char keyfile[MXNAME] = ""; +char keysecret[MXNAME] = ""; +dns_name_t *hmacname = NULL; +unsigned int digestbits = 0; +isc_buffer_t *namebuf = NULL; +dns_tsigkey_t *key = NULL; +isc_boolean_t validated = ISC_TRUE; +isc_entropy_t *entp = NULL; +isc_mempool_t *commctx = NULL; +isc_boolean_t debugging = ISC_FALSE; +isc_boolean_t memdebugging = ISC_FALSE; +char *progname = NULL; +isc_mutex_t lookup_lock; +dig_lookup_t *current_lookup = NULL; + +#ifdef DIG_SIGCHASE + +isc_result_t get_trusted_key(isc_mem_t *mctx); +dns_rdataset_t * sigchase_scanname(dns_rdatatype_t type, + dns_rdatatype_t covers, + isc_boolean_t *lookedup, + dns_name_t *rdata_name); +dns_rdataset_t * chase_scanname_section(dns_message_t *msg, + dns_name_t *name, + dns_rdatatype_t type, + dns_rdatatype_t covers, + int section); +isc_result_t advanced_rrsearch(dns_rdataset_t **rdataset, + dns_name_t *name, + dns_rdatatype_t type, + dns_rdatatype_t covers, + isc_boolean_t *lookedup); +isc_result_t sigchase_verify_sig_key(dns_name_t *name, + dns_rdataset_t *rdataset, + dst_key_t* dnsseckey, + dns_rdataset_t *sigrdataset, + isc_mem_t *mctx); +isc_result_t sigchase_verify_sig(dns_name_t *name, + dns_rdataset_t *rdataset, + dns_rdataset_t *keyrdataset, + dns_rdataset_t *sigrdataset, + isc_mem_t *mctx); +isc_result_t sigchase_verify_ds(dns_name_t *name, + dns_rdataset_t *keyrdataset, + dns_rdataset_t *dsrdataset, + isc_mem_t *mctx); +void sigchase(dns_message_t *msg); +void print_rdata(dns_rdata_t *rdata, isc_mem_t *mctx); +void print_rdataset(dns_name_t *name, + dns_rdataset_t *rdataset, isc_mem_t *mctx); +void dup_name(dns_name_t *source, dns_name_t* target, + isc_mem_t *mctx); +void free_name(dns_name_t *name, isc_mem_t *mctx); +void dump_database(void); +void dump_database_section(dns_message_t *msg, int section); +dns_rdataset_t * search_type(dns_name_t *name, dns_rdatatype_t type, + dns_rdatatype_t covers); +isc_result_t contains_trusted_key(dns_name_t *name, + dns_rdataset_t *rdataset, + dns_rdataset_t *sigrdataset, + isc_mem_t *mctx); +void print_type(dns_rdatatype_t type); +isc_result_t prove_nx_domain(dns_message_t * msg, + dns_name_t * name, + dns_name_t * rdata_name, + dns_rdataset_t ** rdataset, + dns_rdataset_t ** sigrdataset); +isc_result_t prove_nx_type(dns_message_t * msg, dns_name_t *name, + dns_rdataset_t *nsec, + dns_rdataclass_t class, + dns_rdatatype_t type, + dns_name_t * rdata_name, + dns_rdataset_t ** rdataset, + dns_rdataset_t ** sigrdataset); +isc_result_t prove_nx(dns_message_t * msg, dns_name_t * name, + dns_rdataclass_t class, + dns_rdatatype_t type, + dns_name_t * rdata_name, + dns_rdataset_t ** rdataset, + dns_rdataset_t ** sigrdataset); +static void nameFromString(const char *str, dns_name_t *p_ret); +int inf_name(dns_name_t * name1, dns_name_t * name2); +isc_result_t opentmpkey(isc_mem_t *mctx, const char *file, + char **tempp, FILE **fp); +isc_result_t removetmpkey(isc_mem_t *mctx, const char *file); +void clean_trustedkey(void); +void insert_trustedkey(dst_key_t * key); +#if DIG_SIGCHASE_BU +isc_result_t getneededrr(dns_message_t *msg); +void sigchase_bottom_up(dns_message_t *msg); +void sigchase_bu(dns_message_t *msg); +#endif +#if DIG_SIGCHASE_TD +isc_result_t initialization(dns_name_t *name); +isc_result_t prepare_lookup(dns_name_t *name); +isc_result_t grandfather_pb_test(dns_name_t * zone_name, + dns_rdataset_t *sigrdataset); +isc_result_t child_of_zone(dns_name_t *name, + dns_name_t *zone_name, + dns_name_t *child_name); +void sigchase_td(dns_message_t *msg); +#endif +char trustedkey[MXNAME] = ""; + +dns_rdataset_t *chase_rdataset = NULL; +dns_rdataset_t *chase_sigrdataset = NULL; +dns_rdataset_t *chase_dsrdataset = NULL; +dns_rdataset_t *chase_sigdsrdataset = NULL; +dns_rdataset_t *chase_keyrdataset = NULL; +dns_rdataset_t *chase_sigkeyrdataset = NULL; +dns_rdataset_t *chase_nsrdataset = NULL; + +dns_name_t chase_name; /* the query name */ +#if DIG_SIGCHASE_TD +/* + * the current name is the parent name when we follow delegation + */ +dns_name_t chase_current_name; +/* + * the child name is used for delegation (NS DS responses in AUTHORITY section) + */ +dns_name_t chase_authority_name; +#endif +#if DIG_SIGCHASE_BU +dns_name_t chase_signame; +#endif + + +isc_boolean_t chase_siglookedup = ISC_FALSE; +isc_boolean_t chase_keylookedup = ISC_FALSE; +isc_boolean_t chase_sigkeylookedup = ISC_FALSE; +isc_boolean_t chase_dslookedup = ISC_FALSE; +isc_boolean_t chase_sigdslookedup = ISC_FALSE; +#if DIG_SIGCHASE_TD +isc_boolean_t chase_nslookedup = ISC_FALSE; +isc_boolean_t chase_lookedup = ISC_FALSE; + + +isc_boolean_t delegation_follow = ISC_FALSE; +isc_boolean_t grandfather_pb = ISC_FALSE; +isc_boolean_t have_response = ISC_FALSE; +isc_boolean_t have_delegation_ns = ISC_FALSE; +dns_message_t * error_message = NULL; +#endif + +isc_boolean_t dsvalidating = ISC_FALSE; +isc_boolean_t chase_name_dup = ISC_FALSE; + +ISC_LIST(dig_message_t) chase_message_list; +ISC_LIST(dig_message_t) chase_message_list2; + + +#define MAX_TRUSTED_KEY 5 +typedef struct struct_trusted_key_list { + dst_key_t * key[MAX_TRUSTED_KEY]; + int nb_tk; +} struct_tk_list; + +struct_tk_list tk_list = { {NULL, NULL, NULL, NULL, NULL}, 0}; + +#endif + +#define DIG_MAX_ADDRESSES 20 + +/*% + * Apply and clear locks at the event level in global task. + * Can I get rid of these using shutdown events? XXX + */ +#define LOCK_LOOKUP {\ + debug("lock_lookup %s:%d", __FILE__, __LINE__);\ + check_result(isc_mutex_lock((&lookup_lock)), "isc_mutex_lock");\ + debug("success");\ +} +#define UNLOCK_LOOKUP {\ + debug("unlock_lookup %s:%d", __FILE__, __LINE__);\ + check_result(isc_mutex_unlock((&lookup_lock)),\ + "isc_mutex_unlock");\ +} + +static void +cancel_lookup(dig_lookup_t *lookup); + +static void +recv_done(isc_task_t *task, isc_event_t *event); + +static void +send_udp(dig_query_t *query); + +static void +connect_timeout(isc_task_t *task, isc_event_t *event); + +static void +launch_next_query(dig_query_t *query, isc_boolean_t include_question); + + +static void * +mem_alloc(void *arg, size_t size) { + return (isc_mem_get(arg, size)); +} + +static void +mem_free(void *arg, void *mem, size_t size) { + isc_mem_put(arg, mem, size); +} + +char * +next_token(char **stringp, const char *delim) { + char *res; + + do { + res = strsep(stringp, delim); + if (res == NULL) + break; + } while (*res == '\0'); + return (res); +} + +static int +count_dots(char *string) { + char *s; + int i = 0; + + s = string; + while (*s != '\0') { + if (*s == '.') + i++; + s++; + } + return (i); +} + +static void +hex_dump(isc_buffer_t *b) { + unsigned int len; + isc_region_t r; + + isc_buffer_usedregion(b, &r); + + printf("%d bytes\n", r.length); + for (len = 0; len < r.length; len++) { + printf("%02x ", r.base[len]); + if (len % 16 == 15) + printf("\n"); + } + if (len % 16 != 0) + printf("\n"); +} + +/*% + * Append 'len' bytes of 'text' at '*p', failing with + * ISC_R_NOSPACE if that would advance p past 'end'. + */ +static isc_result_t +append(const char *text, int len, char **p, char *end) { + if (len > end - *p) + return (ISC_R_NOSPACE); + memcpy(*p, text, len); + *p += len; + return (ISC_R_SUCCESS); +} + +static isc_result_t +reverse_octets(const char *in, char **p, char *end) { + char *dot = strchr(in, '.'); + int len; + if (dot != NULL) { + isc_result_t result; + result = reverse_octets(dot + 1, p, end); + if (result != ISC_R_SUCCESS) + return (result); + result = append(".", 1, p, end); + if (result != ISC_R_SUCCESS) + return (result); + len = dot - in; + } else { + len = strlen(in); + } + return (append(in, len, p, end)); +} + +isc_result_t +get_reverse(char *reverse, size_t len, char *value, isc_boolean_t ip6_int, + isc_boolean_t strict) +{ + int r; + isc_result_t result; + isc_netaddr_t addr; + + addr.family = AF_INET6; + r = inet_pton(AF_INET6, value, &addr.type.in6); + if (r > 0) { + /* This is a valid IPv6 address. */ + dns_fixedname_t fname; + dns_name_t *name; + unsigned int options = 0; + + if (ip6_int) + options |= DNS_BYADDROPT_IPV6INT; + dns_fixedname_init(&fname); + name = dns_fixedname_name(&fname); + result = dns_byaddr_createptrname2(&addr, options, name); + if (result != ISC_R_SUCCESS) + return (result); + dns_name_format(name, reverse, len); + return (ISC_R_SUCCESS); + } else { + /* + * Not a valid IPv6 address. Assume IPv4. + * If 'strict' is not set, construct the + * in-addr.arpa name by blindly reversing + * octets whether or not they look like integers, + * so that this can be used for RFC2317 names + * and such. + */ + char *p = reverse; + char *end = reverse + len; + if (strict && inet_pton(AF_INET, value, &addr.type.in) != 1) + return (DNS_R_BADDOTTEDQUAD); + result = reverse_octets(value, &p, end); + if (result != ISC_R_SUCCESS) + return (result); + /* Append .in-addr.arpa. and a terminating NUL. */ + result = append(".in-addr.arpa.", 15, &p, end); + if (result != ISC_R_SUCCESS) + return (result); + return (ISC_R_SUCCESS); + } +} + +void +fatal(const char *format, ...) { + va_list args; + + fprintf(stderr, "%s: ", progname); + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, "\n"); + if (exitcode < 10) + exitcode = 10; + if (fatalexit != 0) + exitcode = fatalexit; + exit(exitcode); +} + +void +debug(const char *format, ...) { + va_list args; + + if (debugging) { + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, "\n"); + } +} + +void +check_result(isc_result_t result, const char *msg) { + if (result != ISC_R_SUCCESS) { + fatal("%s: %s", msg, isc_result_totext(result)); + } +} + +/*% + * Create a server structure, which is part of the lookup structure. + * This is little more than a linked list of servers to query in hopes + * of finding the answer the user is looking for + */ +dig_server_t * +make_server(const char *servname, const char *userarg) { + dig_server_t *srv; + + REQUIRE(servname != NULL); + + debug("make_server(%s)", servname); + srv = isc_mem_allocate(mctx, sizeof(struct dig_server)); + if (srv == NULL) + fatal("memory allocation failure in %s:%d", + __FILE__, __LINE__); + strncpy(srv->servername, servname, MXNAME); + strncpy(srv->userarg, userarg, MXNAME); + srv->servername[MXNAME-1] = 0; + srv->userarg[MXNAME-1] = 0; + ISC_LINK_INIT(srv, link); + return (srv); +} + +static int +addr2af(int lwresaddrtype) +{ + int af = 0; + + switch (lwresaddrtype) { + case LWRES_ADDRTYPE_V4: + af = AF_INET; + break; + + case LWRES_ADDRTYPE_V6: + af = AF_INET6; + break; + } + + return (af); +} + +/*% + * Create a copy of the server list from the lwres configuration structure. + * The dest list must have already had ISC_LIST_INIT applied. + */ +static void +copy_server_list(lwres_conf_t *confdata, dig_serverlist_t *dest) { + dig_server_t *newsrv; + char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; + int af; + int i; + + debug("copy_server_list()"); + for (i = 0; i < confdata->nsnext; i++) { + af = addr2af(confdata->nameservers[i].family); + + lwres_net_ntop(af, confdata->nameservers[i].address, + tmp, sizeof(tmp)); + newsrv = make_server(tmp, tmp); + ISC_LINK_INIT(newsrv, link); + ISC_LIST_ENQUEUE(*dest, newsrv, link); + } +} + +void +flush_server_list(void) { + dig_server_t *s, *ps; + + debug("flush_server_list()"); + s = ISC_LIST_HEAD(server_list); + while (s != NULL) { + ps = s; + s = ISC_LIST_NEXT(s, link); + ISC_LIST_DEQUEUE(server_list, ps, link); + isc_mem_free(mctx, ps); + } +} + +void +set_nameserver(char *opt) { + isc_result_t result; + isc_sockaddr_t sockaddrs[DIG_MAX_ADDRESSES]; + isc_netaddr_t netaddr; + int count, i; + dig_server_t *srv; + char tmp[ISC_NETADDR_FORMATSIZE]; + + if (opt == NULL) + return; + + result = bind9_getaddresses(opt, 0, sockaddrs, + DIG_MAX_ADDRESSES, &count); + if (result != ISC_R_SUCCESS) + fatal("couldn't get address for '%s': %s", + opt, isc_result_totext(result)); + + flush_server_list(); + + for (i = 0; i < count; i++) { + isc_netaddr_fromsockaddr(&netaddr, &sockaddrs[i]); + isc_netaddr_format(&netaddr, tmp, sizeof(tmp)); + srv = make_server(tmp, opt); + if (srv == NULL) + fatal("memory allocation failure"); + ISC_LIST_APPEND(server_list, srv, link); + } +} + +static isc_result_t +add_nameserver(lwres_conf_t *confdata, const char *addr, int af) { + + int i = confdata->nsnext; + + if (confdata->nsnext >= LWRES_CONFMAXNAMESERVERS) + return (ISC_R_FAILURE); + + switch (af) { + case AF_INET: + confdata->nameservers[i].family = LWRES_ADDRTYPE_V4; + confdata->nameservers[i].length = NS_INADDRSZ; + break; + case AF_INET6: + confdata->nameservers[i].family = LWRES_ADDRTYPE_V6; + confdata->nameservers[i].length = NS_IN6ADDRSZ; + break; + default: + return (ISC_R_FAILURE); + } + + if (lwres_net_pton(af, addr, &confdata->nameservers[i].address) == 1) { + confdata->nsnext++; + return (ISC_R_SUCCESS); + } + return (ISC_R_FAILURE); +} + +/*% + * Produce a cloned server list. The dest list must have already had + * ISC_LIST_INIT applied. + */ +void +clone_server_list(dig_serverlist_t src, dig_serverlist_t *dest) { + dig_server_t *srv, *newsrv; + + debug("clone_server_list()"); + srv = ISC_LIST_HEAD(src); + while (srv != NULL) { + newsrv = make_server(srv->servername, srv->userarg); + ISC_LINK_INIT(newsrv, link); + ISC_LIST_ENQUEUE(*dest, newsrv, link); + srv = ISC_LIST_NEXT(srv, link); + } +} + +/*% + * Create an empty lookup structure, which holds all the information needed + * to get an answer to a user's question. This structure contains two + * linked lists: the server list (servers to query) and the query list + * (outstanding queries which have been made to the listed servers). + */ +dig_lookup_t * +make_empty_lookup(void) { + dig_lookup_t *looknew; + + debug("make_empty_lookup()"); + + INSIST(!free_now); + + looknew = isc_mem_allocate(mctx, sizeof(struct dig_lookup)); + if (looknew == NULL) + fatal("memory allocation failure in %s:%d", + __FILE__, __LINE__); + looknew->pending = ISC_TRUE; + looknew->textname[0] = 0; + looknew->cmdline[0] = 0; + looknew->rdtype = dns_rdatatype_a; + looknew->qrdtype = dns_rdatatype_a; + looknew->rdclass = dns_rdataclass_in; + looknew->rdtypeset = ISC_FALSE; + looknew->rdclassset = ISC_FALSE; + looknew->sendspace = NULL; + looknew->sendmsg = NULL; + looknew->name = NULL; + looknew->oname = NULL; + looknew->timer = NULL; + looknew->xfr_q = NULL; + looknew->current_query = NULL; + looknew->doing_xfr = ISC_FALSE; + looknew->ixfr_serial = ISC_FALSE; + looknew->trace = ISC_FALSE; + looknew->trace_root = ISC_FALSE; + looknew->identify = ISC_FALSE; + looknew->identify_previous_line = ISC_FALSE; + looknew->ignore = ISC_FALSE; + looknew->servfail_stops = ISC_TRUE; + looknew->besteffort = ISC_TRUE; + looknew->dnssec = ISC_FALSE; +#ifdef DIG_SIGCHASE + looknew->sigchase = ISC_FALSE; +#if DIG_SIGCHASE_TD + looknew->do_topdown = ISC_FALSE; + looknew->trace_root_sigchase = ISC_FALSE; + looknew->rdtype_sigchaseset = ISC_FALSE; + looknew->rdtype_sigchase = dns_rdatatype_any; + looknew->qrdtype_sigchase = dns_rdatatype_any; + looknew->rdclass_sigchase = dns_rdataclass_in; + looknew->rdclass_sigchaseset = ISC_FALSE; +#endif +#endif + looknew->udpsize = 0; + looknew->edns = -1; + looknew->recurse = ISC_TRUE; + looknew->aaonly = ISC_FALSE; + looknew->adflag = ISC_FALSE; + looknew->cdflag = ISC_FALSE; + looknew->ns_search_only = ISC_FALSE; + looknew->origin = NULL; + looknew->tsigctx = NULL; + looknew->querysig = NULL; + looknew->retries = tries; + looknew->nsfound = 0; + looknew->tcp_mode = ISC_FALSE; + looknew->ip6_int = ISC_FALSE; + looknew->comments = ISC_TRUE; + looknew->stats = ISC_TRUE; + looknew->section_question = ISC_TRUE; + looknew->section_answer = ISC_TRUE; + looknew->section_authority = ISC_TRUE; + looknew->section_additional = ISC_TRUE; + looknew->new_search = ISC_FALSE; + looknew->done_as_is = ISC_FALSE; + looknew->need_search = ISC_FALSE; + ISC_LINK_INIT(looknew, link); + ISC_LIST_INIT(looknew->q); + ISC_LIST_INIT(looknew->my_server_list); + return (looknew); +} + +/*% + * Clone a lookup, perhaps copying the server list. This does not clone + * the query list, since it will be regenerated by the setup_lookup() + * function, nor does it queue up the new lookup for processing. + * Caution: If you don't clone the servers, you MUST clone the server + * list seperately from somewhere else, or construct it by hand. + */ +dig_lookup_t * +clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) { + dig_lookup_t *looknew; + + debug("clone_lookup()"); + + INSIST(!free_now); + + looknew = make_empty_lookup(); + INSIST(looknew != NULL); + strncpy(looknew->textname, lookold->textname, MXNAME); +#if DIG_SIGCHASE_TD + strncpy(looknew->textnamesigchase, lookold->textnamesigchase, MXNAME); +#endif + strncpy(looknew->cmdline, lookold->cmdline, MXNAME); + looknew->textname[MXNAME-1] = 0; + looknew->rdtype = lookold->rdtype; + looknew->qrdtype = lookold->qrdtype; + looknew->rdclass = lookold->rdclass; + looknew->rdtypeset = lookold->rdtypeset; + looknew->rdclassset = lookold->rdclassset; + looknew->doing_xfr = lookold->doing_xfr; + looknew->ixfr_serial = lookold->ixfr_serial; + looknew->trace = lookold->trace; + looknew->trace_root = lookold->trace_root; + looknew->identify = lookold->identify; + looknew->identify_previous_line = lookold->identify_previous_line; + looknew->ignore = lookold->ignore; + looknew->servfail_stops = lookold->servfail_stops; + looknew->besteffort = lookold->besteffort; + looknew->dnssec = lookold->dnssec; +#ifdef DIG_SIGCHASE + looknew->sigchase = lookold->sigchase; +#if DIG_SIGCHASE_TD + looknew->do_topdown = lookold->do_topdown; + looknew->trace_root_sigchase = lookold->trace_root_sigchase; + looknew->rdtype_sigchaseset = lookold->rdtype_sigchaseset; + looknew->rdtype_sigchase = lookold->rdtype_sigchase; + looknew->qrdtype_sigchase = lookold->qrdtype_sigchase; + looknew->rdclass_sigchase = lookold->rdclass_sigchase; + looknew->rdclass_sigchaseset = lookold->rdclass_sigchaseset; +#endif +#endif + looknew->udpsize = lookold->udpsize; + looknew->edns = lookold->edns; + looknew->recurse = lookold->recurse; + looknew->aaonly = lookold->aaonly; + looknew->adflag = lookold->adflag; + looknew->cdflag = lookold->cdflag; + looknew->ns_search_only = lookold->ns_search_only; + looknew->tcp_mode = lookold->tcp_mode; + looknew->comments = lookold->comments; + looknew->stats = lookold->stats; + looknew->section_question = lookold->section_question; + looknew->section_answer = lookold->section_answer; + looknew->section_authority = lookold->section_authority; + looknew->section_additional = lookold->section_additional; + looknew->retries = lookold->retries; + looknew->tsigctx = NULL; + looknew->need_search = lookold->need_search; + looknew->done_as_is = lookold->done_as_is; + + if (servers) + clone_server_list(lookold->my_server_list, + &looknew->my_server_list); + return (looknew); +} + +/*% + * Requeue a lookup for further processing, perhaps copying the server + * list. The new lookup structure is returned to the caller, and is + * queued for processing. If servers are not cloned in the requeue, they + * must be added before allowing the current event to complete, since the + * completion of the event may result in the next entry on the lookup + * queue getting run. + */ +dig_lookup_t * +requeue_lookup(dig_lookup_t *lookold, isc_boolean_t servers) { + dig_lookup_t *looknew; + + debug("requeue_lookup()"); + + lookup_counter++; + if (lookup_counter > LOOKUP_LIMIT) + fatal("too many lookups"); + + looknew = clone_lookup(lookold, servers); + INSIST(looknew != NULL); + + debug("before insertion, init@%p -> %p, new@%p -> %p", + lookold, lookold->link.next, looknew, looknew->link.next); + ISC_LIST_PREPEND(lookup_list, looknew, link); + debug("after insertion, init -> %p, new = %p, new -> %p", + lookold, looknew, looknew->link.next); + return (looknew); +} + + +static void +setup_text_key(void) { + isc_result_t result; + dns_name_t keyname; + isc_buffer_t secretbuf; + int secretsize; + unsigned char *secretstore; + + debug("setup_text_key()"); + result = isc_buffer_allocate(mctx, &namebuf, MXNAME); + check_result(result, "isc_buffer_allocate"); + dns_name_init(&keyname, NULL); + check_result(result, "dns_name_init"); + isc_buffer_putstr(namebuf, keynametext); + secretsize = strlen(keysecret) * 3 / 4; + secretstore = isc_mem_allocate(mctx, secretsize); + if (secretstore == NULL) + fatal("memory allocation failure in %s:%d", + __FILE__, __LINE__); + isc_buffer_init(&secretbuf, secretstore, secretsize); + result = isc_base64_decodestring(keysecret, &secretbuf); + if (result != ISC_R_SUCCESS) + goto failure; + + secretsize = isc_buffer_usedlength(&secretbuf); + + result = dns_name_fromtext(&keyname, namebuf, + dns_rootname, ISC_FALSE, + namebuf); + if (result != ISC_R_SUCCESS) + goto failure; + + result = dns_tsigkey_create(&keyname, hmacname, secretstore, + secretsize, ISC_FALSE, NULL, 0, 0, mctx, + NULL, &key); + failure: + if (result != ISC_R_SUCCESS) + printf(";; Couldn't create key %s: %s\n", + keynametext, isc_result_totext(result)); + else + dst_key_setbits(key->key, digestbits); + + isc_mem_free(mctx, secretstore); + dns_name_invalidate(&keyname); + isc_buffer_free(&namebuf); +} + +static void +setup_file_key(void) { + isc_result_t result; + dst_key_t *dstkey = NULL; + + debug("setup_file_key()"); + result = dst_key_fromnamedfile(keyfile, DST_TYPE_PRIVATE | DST_TYPE_KEY, + mctx, &dstkey); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "Couldn't read key from %s: %s\n", + keyfile, isc_result_totext(result)); + goto failure; + } + + switch (dst_key_alg(dstkey)) { + case DST_ALG_HMACMD5: + hmacname = DNS_TSIG_HMACMD5_NAME; + break; + case DST_ALG_HMACSHA1: + hmacname = DNS_TSIG_HMACSHA1_NAME; + break; + case DST_ALG_HMACSHA224: + hmacname = DNS_TSIG_HMACSHA224_NAME; + break; + case DST_ALG_HMACSHA256: + hmacname = DNS_TSIG_HMACSHA256_NAME; + break; + case DST_ALG_HMACSHA384: + hmacname = DNS_TSIG_HMACSHA384_NAME; + break; + case DST_ALG_HMACSHA512: + hmacname = DNS_TSIG_HMACSHA512_NAME; + break; + default: + printf(";; Couldn't create key %s: bad algorithm\n", + keynametext); + goto failure; + } + result = dns_tsigkey_createfromkey(dst_key_name(dstkey), hmacname, + dstkey, ISC_FALSE, NULL, 0, 0, + mctx, NULL, &key); + if (result != ISC_R_SUCCESS) { + printf(";; Couldn't create key %s: %s\n", + keynametext, isc_result_totext(result)); + goto failure; + } + dstkey = NULL; + failure: + if (dstkey != NULL) + dst_key_free(&dstkey); +} + +static dig_searchlist_t * +make_searchlist_entry(char *domain) { + dig_searchlist_t *search; + search = isc_mem_allocate(mctx, sizeof(*search)); + if (search == NULL) + fatal("memory allocation failure in %s:%d", + __FILE__, __LINE__); + strncpy(search->origin, domain, MXNAME); + search->origin[MXNAME-1] = 0; + ISC_LINK_INIT(search, link); + return (search); +} + +static void +create_search_list(lwres_conf_t *confdata) { + int i; + dig_searchlist_t *search; + + debug("create_search_list()"); + ISC_LIST_INIT(search_list); + + for (i = 0; i < confdata->searchnxt; i++) { + search = make_searchlist_entry(confdata->search[i]); + ISC_LIST_APPEND(search_list, search, link); + } +} + +/*% + * Setup the system as a whole, reading key information and resolv.conf + * settings. + */ +void +setup_system(void) { + dig_searchlist_t *domain = NULL; + lwres_result_t lwresult; + + debug("setup_system()"); + + lwresult = lwres_context_create(&lwctx, mctx, mem_alloc, mem_free, 1); + if (lwresult != LWRES_R_SUCCESS) + fatal("lwres_context_create failed"); + + lwresult = lwres_conf_parse(lwctx, RESOLV_CONF); + if (lwresult != LWRES_R_SUCCESS && lwresult != LWRES_R_NOTFOUND) + fatal("parse of %s failed", RESOLV_CONF); + + lwconf = lwres_conf_get(lwctx); + + /* Make the search list */ + if (lwconf->searchnxt > 0) + create_search_list(lwconf); + else { /* No search list. Use the domain name if any */ + if (lwconf->domainname != NULL) { + domain = make_searchlist_entry(lwconf->domainname); + ISC_LIST_INITANDAPPEND(search_list, domain, link); + domain = NULL; + } + } + + if (ndots == -1) { + ndots = lwconf->ndots; + debug("ndots is %d.", ndots); + } + + /* If we don't find a nameserver fall back to localhost */ + if (lwconf->nsnext == 0) { + if (have_ipv4) { + lwresult = add_nameserver(lwconf, "127.0.0.1", AF_INET); + if (lwresult != ISC_R_SUCCESS) + fatal("add_nameserver failed"); + } + if (have_ipv6) { + lwresult = add_nameserver(lwconf, "::1", AF_INET6); + if (lwresult != ISC_R_SUCCESS) + fatal("add_nameserver failed"); + } + } + + if (ISC_LIST_EMPTY(server_list)) + copy_server_list(lwconf, &server_list); + +#ifdef WITH_IDN + initialize_idn(); +#endif + + if (keyfile[0] != 0) + setup_file_key(); + else if (keysecret[0] != 0) + setup_text_key(); +#ifdef DIG_SIGCHASE + /* Setup the list of messages for +sigchase */ + ISC_LIST_INIT(chase_message_list); + ISC_LIST_INIT(chase_message_list2); + dns_name_init(&chase_name, NULL); +#if DIG_SIGCHASE_TD + dns_name_init(&chase_current_name, NULL); + dns_name_init(&chase_authority_name, NULL); +#endif +#if DIG_SIGCHASE_BU + dns_name_init(&chase_signame, NULL); +#endif + +#endif + +} + +static void +clear_searchlist(void) { + dig_searchlist_t *search; + while ((search = ISC_LIST_HEAD(search_list)) != NULL) { + ISC_LIST_UNLINK(search_list, search, link); + isc_mem_free(mctx, search); + } +} + +/*% + * Override the search list derived from resolv.conf by 'domain'. + */ +void +set_search_domain(char *domain) { + dig_searchlist_t *search; + + clear_searchlist(); + search = make_searchlist_entry(domain); + ISC_LIST_APPEND(search_list, search, link); +} + +/*% + * Setup the ISC and DNS libraries for use by the system. + */ +void +setup_libs(void) { + isc_result_t result; + + debug("setup_libs()"); + + result = isc_net_probeipv4(); + if (result == ISC_R_SUCCESS) + have_ipv4 = ISC_TRUE; + + result = isc_net_probeipv6(); + if (result == ISC_R_SUCCESS) + have_ipv6 = ISC_TRUE; + if (!have_ipv6 && !have_ipv4) + fatal("can't find either v4 or v6 networking"); + + result = isc_mem_create(0, 0, &mctx); + check_result(result, "isc_mem_create"); + + result = isc_taskmgr_create(mctx, 1, 0, &taskmgr); + check_result(result, "isc_taskmgr_create"); + + result = isc_task_create(taskmgr, 0, &global_task); + check_result(result, "isc_task_create"); + + result = isc_timermgr_create(mctx, &timermgr); + check_result(result, "isc_timermgr_create"); + + result = isc_socketmgr_create(mctx, &socketmgr); + check_result(result, "isc_socketmgr_create"); + + result = isc_entropy_create(mctx, &entp); + check_result(result, "isc_entropy_create"); + + result = dst_lib_init(mctx, entp, 0); + check_result(result, "dst_lib_init"); + is_dst_up = ISC_TRUE; + + result = isc_mempool_create(mctx, COMMSIZE, &commctx); + check_result(result, "isc_mempool_create"); + isc_mempool_setname(commctx, "COMMPOOL"); + /* + * 6 and 2 set as reasonable parameters for 3 or 4 nameserver + * systems. + */ + isc_mempool_setfreemax(commctx, 6); + isc_mempool_setfillcount(commctx, 2); + + result = isc_mutex_init(&lookup_lock); + check_result(result, "isc_mutex_init"); + + dns_result_register(); +} + +/*% + * Add EDNS0 option record to a message. Currently, the only supported + * options are UDP buffer size and the DO bit. + */ +static void +add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_uint16_t edns, + isc_boolean_t dnssec) +{ + dns_rdataset_t *rdataset = NULL; + dns_rdatalist_t *rdatalist = NULL; + dns_rdata_t *rdata = NULL; + isc_result_t result; + + debug("add_opt()"); + result = dns_message_gettemprdataset(msg, &rdataset); + check_result(result, "dns_message_gettemprdataset"); + dns_rdataset_init(rdataset); + result = dns_message_gettemprdatalist(msg, &rdatalist); + check_result(result, "dns_message_gettemprdatalist"); + result = dns_message_gettemprdata(msg, &rdata); + check_result(result, "dns_message_gettemprdata"); + + debug("setting udp size of %d", udpsize); + rdatalist->type = dns_rdatatype_opt; + rdatalist->covers = 0; + rdatalist->rdclass = udpsize; + rdatalist->ttl = edns << 16; + if (dnssec) + rdatalist->ttl |= DNS_MESSAGEEXTFLAG_DO; + rdata->data = NULL; + rdata->length = 0; + ISC_LIST_INIT(rdatalist->rdata); + ISC_LIST_APPEND(rdatalist->rdata, rdata, link); + dns_rdatalist_tordataset(rdatalist, rdataset); + result = dns_message_setopt(msg, rdataset); + check_result(result, "dns_message_setopt"); +} + +/*% + * Add a question section to a message, asking for the specified name, + * type, and class. + */ +static void +add_question(dns_message_t *message, dns_name_t *name, + dns_rdataclass_t rdclass, dns_rdatatype_t rdtype) +{ + dns_rdataset_t *rdataset; + isc_result_t result; + + debug("add_question()"); + rdataset = NULL; + result = dns_message_gettemprdataset(message, &rdataset); + check_result(result, "dns_message_gettemprdataset()"); + dns_rdataset_init(rdataset); + dns_rdataset_makequestion(rdataset, rdclass, rdtype); + ISC_LIST_APPEND(name->list, rdataset, link); +} + +/*% + * Check if we're done with all the queued lookups, which is true iff + * all sockets, sends, and recvs are accounted for (counters == 0), + * and the lookup list is empty. + * If we are done, pass control back out to dighost_shutdown() (which is + * part of dig.c, host.c, or nslookup.c) to either shutdown the system as + * a whole or reseed the lookup list. + */ +static void +check_if_done(void) { + debug("check_if_done()"); + debug("list %s", ISC_LIST_EMPTY(lookup_list) ? "empty" : "full"); + if (ISC_LIST_EMPTY(lookup_list) && current_lookup == NULL && + sendcount == 0) { + INSIST(sockcount == 0); + INSIST(recvcount == 0); + debug("shutting down"); + dighost_shutdown(); + } +} + +/*% + * Clear out a query when we're done with it. WARNING: This routine + * WILL invalidate the query pointer. + */ +static void +clear_query(dig_query_t *query) { + dig_lookup_t *lookup; + + REQUIRE(query != NULL); + + debug("clear_query(%p)", query); + + lookup = query->lookup; + + if (lookup->current_query == query) + lookup->current_query = NULL; + + ISC_LIST_UNLINK(lookup->q, query, link); + if (ISC_LINK_LINKED(&query->recvbuf, link)) + ISC_LIST_DEQUEUE(query->recvlist, &query->recvbuf, + link); + if (ISC_LINK_LINKED(&query->lengthbuf, link)) + ISC_LIST_DEQUEUE(query->lengthlist, &query->lengthbuf, + link); + INSIST(query->recvspace != NULL); + if (query->sock != NULL) { + isc_socket_detach(&query->sock); + sockcount--; + debug("sockcount=%d", sockcount); + } + isc_mempool_put(commctx, query->recvspace); + isc_buffer_invalidate(&query->recvbuf); + isc_buffer_invalidate(&query->lengthbuf); + if (query->waiting_senddone) + query->pending_free = ISC_TRUE; + else + isc_mem_free(mctx, query); +} + +/*% + * Try and clear out a lookup if we're done with it. Return ISC_TRUE if + * the lookup was successfully cleared. If ISC_TRUE is returned, the + * lookup pointer has been invalidated. + */ +static isc_boolean_t +try_clear_lookup(dig_lookup_t *lookup) { + dig_query_t *q; + + REQUIRE(lookup != NULL); + + debug("try_clear_lookup(%p)", lookup); + + if (ISC_LIST_HEAD(lookup->q) != NULL) { + if (debugging) { + q = ISC_LIST_HEAD(lookup->q); + while (q != NULL) { + debug("query to %s still pending", q->servname); + q = ISC_LIST_NEXT(q, link); + } + } + return (ISC_FALSE); + } + + /* + * At this point, we know there are no queries on the lookup, + * so can make it go away also. + */ + destroy_lookup(lookup); + return (ISC_TRUE); +} + +void +destroy_lookup(dig_lookup_t *lookup) { + dig_server_t *s; + void *ptr; + + debug("destroy"); + s = ISC_LIST_HEAD(lookup->my_server_list); + while (s != NULL) { + debug("freeing server %p belonging to %p", s, lookup); + ptr = s; + s = ISC_LIST_NEXT(s, link); + ISC_LIST_DEQUEUE(lookup->my_server_list, + (dig_server_t *)ptr, link); + isc_mem_free(mctx, ptr); + } + if (lookup->sendmsg != NULL) + dns_message_destroy(&lookup->sendmsg); + if (lookup->querysig != NULL) { + debug("freeing buffer %p", lookup->querysig); + isc_buffer_free(&lookup->querysig); + } + if (lookup->timer != NULL) + isc_timer_detach(&lookup->timer); + if (lookup->sendspace != NULL) + isc_mempool_put(commctx, lookup->sendspace); + + if (lookup->tsigctx != NULL) + dst_context_destroy(&lookup->tsigctx); + + isc_mem_free(mctx, lookup); +} + +/*% + * If we can, start the next lookup in the queue running. + * This assumes that the lookup on the head of the queue hasn't been + * started yet. It also removes the lookup from the head of the queue, + * setting the current_lookup pointer pointing to it. + */ +void +start_lookup(void) { + debug("start_lookup()"); + if (cancel_now) + return; + + /* + * If there's a current lookup running, we really shouldn't get + * here. + */ + INSIST(current_lookup == NULL); + + current_lookup = ISC_LIST_HEAD(lookup_list); + /* + * Put the current lookup somewhere so cancel_all can find it + */ + if (current_lookup != NULL) { + ISC_LIST_DEQUEUE(lookup_list, current_lookup, link); +#if DIG_SIGCHASE_TD + if (current_lookup->do_topdown && + !current_lookup->rdtype_sigchaseset) { + dst_key_t *trustedkey = NULL; + isc_buffer_t *b = NULL; + isc_region_t r; + isc_result_t result; + dns_name_t query_name; + dns_name_t *key_name; + int i; + + result = get_trusted_key(mctx); + if (result != ISC_R_SUCCESS) { + printf("\n;; No trusted key, " + "+sigchase option is disabled\n"); + current_lookup->sigchase = ISC_FALSE; + goto novalidation; + } + dns_name_init(&query_name, NULL); + nameFromString(current_lookup->textname, &query_name); + + for (i = 0; i < tk_list.nb_tk; i++) { + key_name = dst_key_name(tk_list.key[i]); + + if (dns_name_issubdomain(&query_name, + key_name) == ISC_TRUE) + trustedkey = tk_list.key[i]; + /* + * Verifier que la temp est bien la plus basse + * WARNING + */ + } + if (trustedkey == NULL) { + printf("\n;; The queried zone: "); + dns_name_print(&query_name, stdout); + printf(" isn't a subdomain of any Trusted Keys" + ": +sigchase option is disable\n"); + current_lookup->sigchase = ISC_FALSE; + free_name(&query_name, mctx); + goto novalidation; + } + free_name(&query_name, mctx); + + current_lookup->rdtype_sigchase + = current_lookup->rdtype; + current_lookup->rdtype_sigchaseset + = current_lookup->rdtypeset; + current_lookup->rdtype = dns_rdatatype_ns; + + current_lookup->qrdtype_sigchase + = current_lookup->qrdtype; + current_lookup->qrdtype = dns_rdatatype_ns; + + current_lookup->rdclass_sigchase + = current_lookup->rdclass; + current_lookup->rdclass_sigchaseset + = current_lookup->rdclassset; + current_lookup->rdclass = dns_rdataclass_in; + + strncpy(current_lookup->textnamesigchase, + current_lookup->textname, MXNAME); + + current_lookup->trace_root_sigchase = ISC_TRUE; + + result = isc_buffer_allocate(mctx, &b, BUFSIZE); + check_result(result, "isc_buffer_allocate"); + result = dns_name_totext(dst_key_name(trustedkey), + ISC_FALSE, b); + check_result(result, "dns_name_totext"); + isc_buffer_usedregion(b, &r); + r.base[r.length] = '\0'; + strncpy(current_lookup->textname, (char*)r.base, + MXNAME); + isc_buffer_free(&b); + + nameFromString(current_lookup->textnamesigchase, + &chase_name); + + dns_name_init(&chase_authority_name, NULL); + } + novalidation: +#endif + setup_lookup(current_lookup); + do_lookup(current_lookup); + } else { + check_if_done(); + } +} + +/*% + * If we can, clear the current lookup and start the next one running. + * This calls try_clear_lookup, so may invalidate the lookup pointer. + */ +static void +check_next_lookup(dig_lookup_t *lookup) { + + INSIST(!free_now); + + debug("check_next_lookup(%p)", lookup); + + if (ISC_LIST_HEAD(lookup->q) != NULL) { + debug("still have a worker"); + return; + } + if (try_clear_lookup(lookup)) { + current_lookup = NULL; + start_lookup(); + } +} + +/*% + * Create and queue a new lookup as a followup to the current lookup, + * based on the supplied message and section. This is used in trace and + * name server search modes to start a new lookup using servers from + * NS records in a reply. Returns the number of followup lookups made. + */ +static int +followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section) +{ + dig_lookup_t *lookup = NULL; + dig_server_t *srv = NULL; + dns_rdataset_t *rdataset = NULL; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_name_t *name = NULL; + isc_result_t result; + isc_boolean_t success = ISC_FALSE; + int numLookups = 0; + dns_name_t *domain; + isc_boolean_t horizontal = ISC_FALSE, bad = ISC_FALSE; + + INSIST(!free_now); + + debug("following up %s", query->lookup->textname); + + for (result = dns_message_firstname(msg, section); + result == ISC_R_SUCCESS; + result = dns_message_nextname(msg, section)) { + name = NULL; + dns_message_currentname(msg, section, &name); + + if (section == DNS_SECTION_AUTHORITY) { + rdataset = NULL; + result = dns_message_findtype(name, dns_rdatatype_soa, + 0, &rdataset); + if (result == ISC_R_SUCCESS) + return (0); + } + rdataset = NULL; + result = dns_message_findtype(name, dns_rdatatype_ns, 0, + &rdataset); + if (result != ISC_R_SUCCESS) + continue; + + debug("found NS set"); + + if (query->lookup->trace && !query->lookup->trace_root) { + dns_namereln_t namereln; + unsigned int nlabels; + int order; + + domain = dns_fixedname_name(&query->lookup->fdomain); + namereln = dns_name_fullcompare(name, domain, + &order, &nlabels); + if (namereln == dns_namereln_equal) { + if (!horizontal) + printf(";; BAD (HORIZONTAL) REFERRAL\n"); + horizontal = ISC_TRUE; + } else if (namereln != dns_namereln_subdomain) { + if (!bad) + printf(";; BAD REFERRAL\n"); + bad = ISC_TRUE; + continue; + } + } + + for (result = dns_rdataset_first(rdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(rdataset)) { + char namestr[DNS_NAME_FORMATSIZE]; + dns_rdata_ns_t ns; + + if (query->lookup->trace_root && + query->lookup->nsfound >= MXSERV) + break; + + dns_rdataset_current(rdataset, &rdata); + + query->lookup->nsfound++; + (void)dns_rdata_tostruct(&rdata, &ns, NULL); + dns_name_format(&ns.name, namestr, sizeof(namestr)); + dns_rdata_freestruct(&ns); + + /* Initialize lookup if we've not yet */ + debug("found NS %d %s", numLookups, namestr); + numLookups++; + if (!success) { + success = ISC_TRUE; + lookup_counter++; + lookup = requeue_lookup(query->lookup, + ISC_FALSE); + cancel_lookup(query->lookup); + lookup->doing_xfr = ISC_FALSE; + if (!lookup->trace_root && + section == DNS_SECTION_ANSWER) + lookup->trace = ISC_FALSE; + else + lookup->trace = query->lookup->trace; + lookup->ns_search_only = + query->lookup->ns_search_only; + lookup->trace_root = ISC_FALSE; + if (lookup->ns_search_only) + lookup->recurse = ISC_FALSE; + dns_fixedname_init(&lookup->fdomain); + domain = dns_fixedname_name(&lookup->fdomain); + dns_name_copy(name, domain, NULL); + } + srv = make_server(namestr, namestr); + debug("adding server %s", srv->servername); + ISC_LIST_APPEND(lookup->my_server_list, srv, link); + dns_rdata_reset(&rdata); + } + } + + if (lookup == NULL && + section == DNS_SECTION_ANSWER && + (query->lookup->trace || query->lookup->ns_search_only)) + return (followup_lookup(msg, query, DNS_SECTION_AUTHORITY)); + + /* + * Randomize the order the nameserver will be tried. + */ + if (numLookups > 1) { + isc_uint32_t i, j; + dig_serverlist_t my_server_list; + + ISC_LIST_INIT(my_server_list); + + for (i = numLookups; i > 0; i--) { + isc_random_get(&j); + j %= i; + srv = ISC_LIST_HEAD(lookup->my_server_list); + while (j-- > 0) + srv = ISC_LIST_NEXT(srv, link); + ISC_LIST_DEQUEUE(lookup->my_server_list, srv, link); + ISC_LIST_APPEND(my_server_list, srv, link); + } + ISC_LIST_APPENDLIST(lookup->my_server_list, + my_server_list, link); + } + + return (numLookups); +} + +/*% + * Create and queue a new lookup using the next origin from the search + * list, read in setup_system(). + * + * Return ISC_TRUE iff there was another searchlist entry. + */ +static isc_boolean_t +next_origin(dns_message_t *msg, dig_query_t *query) { + dig_lookup_t *lookup; + dig_searchlist_t *search; + + UNUSED(msg); + + INSIST(!free_now); + + debug("next_origin()"); + debug("following up %s", query->lookup->textname); + + if (!usesearch) + /* + * We're not using a search list, so don't even think + * about finding the next entry. + */ + return (ISC_FALSE); + if (query->lookup->origin == NULL && !query->lookup->need_search) + /* + * Then we just did rootorg; there's nothing left. + */ + return (ISC_FALSE); + if (query->lookup->origin == NULL && query->lookup->need_search) { + lookup = requeue_lookup(query->lookup, ISC_TRUE); + lookup->origin = ISC_LIST_HEAD(search_list); + lookup->need_search = ISC_FALSE; + } else { + search = ISC_LIST_NEXT(query->lookup->origin, link); + if (search == NULL && query->lookup->done_as_is) + return (ISC_FALSE); + lookup = requeue_lookup(query->lookup, ISC_TRUE); + lookup->origin = search; + } + cancel_lookup(query->lookup); + return (ISC_TRUE); +} + +/*% + * Insert an SOA record into the sendmessage in a lookup. Used for + * creating IXFR queries. + */ +static void +insert_soa(dig_lookup_t *lookup) { + isc_result_t result; + dns_rdata_soa_t soa; + dns_rdata_t *rdata = NULL; + dns_rdatalist_t *rdatalist = NULL; + dns_rdataset_t *rdataset = NULL; + dns_name_t *soaname = NULL; + + debug("insert_soa()"); + soa.mctx = mctx; + soa.serial = lookup->ixfr_serial; + soa.refresh = 0; + soa.retry = 0; + soa.expire = 0; + soa.minimum = 0; + soa.common.rdclass = lookup->rdclass; + soa.common.rdtype = dns_rdatatype_soa; + + dns_name_init(&soa.origin, NULL); + dns_name_init(&soa.contact, NULL); + + dns_name_clone(dns_rootname, &soa.origin); + dns_name_clone(dns_rootname, &soa.contact); + + isc_buffer_init(&lookup->rdatabuf, lookup->rdatastore, + sizeof(lookup->rdatastore)); + + result = dns_message_gettemprdata(lookup->sendmsg, &rdata); + check_result(result, "dns_message_gettemprdata"); + + result = dns_rdata_fromstruct(rdata, lookup->rdclass, + dns_rdatatype_soa, &soa, + &lookup->rdatabuf); + check_result(result, "isc_rdata_fromstruct"); + + result = dns_message_gettemprdatalist(lookup->sendmsg, &rdatalist); + check_result(result, "dns_message_gettemprdatalist"); + + result = dns_message_gettemprdataset(lookup->sendmsg, &rdataset); + check_result(result, "dns_message_gettemprdataset"); + + dns_rdatalist_init(rdatalist); + rdatalist->type = dns_rdatatype_soa; + rdatalist->rdclass = lookup->rdclass; + rdatalist->covers = 0; + rdatalist->ttl = 0; + ISC_LIST_INIT(rdatalist->rdata); + ISC_LIST_APPEND(rdatalist->rdata, rdata, link); + + dns_rdataset_init(rdataset); + dns_rdatalist_tordataset(rdatalist, rdataset); + + result = dns_message_gettempname(lookup->sendmsg, &soaname); + check_result(result, "dns_message_gettempname"); + dns_name_init(soaname, NULL); + dns_name_clone(lookup->name, soaname); + ISC_LIST_INIT(soaname->list); + ISC_LIST_APPEND(soaname->list, rdataset, link); + dns_message_addname(lookup->sendmsg, soaname, DNS_SECTION_AUTHORITY); +} + +/*% + * Setup the supplied lookup structure, making it ready to start sending + * queries to servers. Create and initialize the message to be sent as + * well as the query structures and buffer space for the replies. If the + * server list is empty, clone it from the system default list. + */ +void +setup_lookup(dig_lookup_t *lookup) { + isc_result_t result; + isc_uint32_t id; + int len; + dig_server_t *serv; + dig_query_t *query; + isc_buffer_t b; + dns_compress_t cctx; + char store[MXNAME]; +#ifdef WITH_IDN + idn_result_t mr; + char utf8_textname[MXNAME], utf8_origin[MXNAME], idn_textname[MXNAME]; +#endif + +#ifdef WITH_IDN + result = dns_name_settotextfilter(output_filter); + check_result(result, "dns_name_settotextfilter"); +#endif + + REQUIRE(lookup != NULL); + INSIST(!free_now); + + debug("setup_lookup(%p)", lookup); + + result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, + &lookup->sendmsg); + check_result(result, "dns_message_create"); + + if (lookup->new_search) { + debug("resetting lookup counter."); + lookup_counter = 0; + } + + if (ISC_LIST_EMPTY(lookup->my_server_list)) { + debug("cloning server list"); + clone_server_list(server_list, &lookup->my_server_list); + } + result = dns_message_gettempname(lookup->sendmsg, &lookup->name); + check_result(result, "dns_message_gettempname"); + dns_name_init(lookup->name, NULL); + + isc_buffer_init(&lookup->namebuf, lookup->namespace, + sizeof(lookup->namespace)); + isc_buffer_init(&lookup->onamebuf, lookup->onamespace, + sizeof(lookup->onamespace)); + +#ifdef WITH_IDN + /* + * We cannot convert `textname' and `origin' separately. + * `textname' doesn't contain TLD, but local mapping needs + * TLD. + */ + mr = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, lookup->textname, + utf8_textname, sizeof(utf8_textname)); + idn_check_result(mr, "convert textname to UTF-8"); +#endif + + /* + * If the name has too many dots, force the origin to be NULL + * (which produces an absolute lookup). Otherwise, take the origin + * we have if there's one in the struct already. If it's NULL, + * take the first entry in the searchlist iff either usesearch + * is TRUE or we got a domain line in the resolv.conf file. + */ + if (lookup->new_search) { +#ifdef WITH_IDN + if ((count_dots(utf8_textname) >= ndots) || !usesearch) { + lookup->origin = NULL; /* Force abs lookup */ + lookup->done_as_is = ISC_TRUE; + lookup->need_search = usesearch; + } else if (lookup->origin == NULL && usesearch) { + lookup->origin = ISC_LIST_HEAD(search_list); + lookup->need_search = ISC_FALSE; + } +#else + if ((count_dots(lookup->textname) >= ndots) || !usesearch) { + lookup->origin = NULL; /* Force abs lookup */ + lookup->done_as_is = ISC_TRUE; + lookup->need_search = usesearch; + } else if (lookup->origin == NULL && usesearch) { + lookup->origin = ISC_LIST_HEAD(search_list); + lookup->need_search = ISC_FALSE; + } +#endif + } + +#ifdef WITH_IDN + if (lookup->origin != NULL) { + mr = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, + lookup->origin->origin, utf8_origin, + sizeof(utf8_origin)); + idn_check_result(mr, "convert origin to UTF-8"); + mr = append_textname(utf8_textname, utf8_origin, + sizeof(utf8_textname)); + idn_check_result(mr, "append origin to textname"); + } + mr = idn_encodename(idnoptions | IDN_LOCALMAP | IDN_NAMEPREP | + IDN_IDNCONV | IDN_LENCHECK, utf8_textname, + idn_textname, sizeof(idn_textname)); + idn_check_result(mr, "convert UTF-8 textname to IDN encoding"); +#else + if (lookup->origin != NULL) { + debug("trying origin %s", lookup->origin->origin); + result = dns_message_gettempname(lookup->sendmsg, + &lookup->oname); + check_result(result, "dns_message_gettempname"); + dns_name_init(lookup->oname, NULL); + /* XXX Helper funct to conv char* to name? */ + len = strlen(lookup->origin->origin); + isc_buffer_init(&b, lookup->origin->origin, len); + isc_buffer_add(&b, len); + result = dns_name_fromtext(lookup->oname, &b, dns_rootname, + ISC_FALSE, &lookup->onamebuf); + if (result != ISC_R_SUCCESS) { + dns_message_puttempname(lookup->sendmsg, + &lookup->name); + dns_message_puttempname(lookup->sendmsg, + &lookup->oname); + fatal("'%s' is not in legal name syntax (%s)", + lookup->origin->origin, + isc_result_totext(result)); + } + if (lookup->trace && lookup->trace_root) { + dns_name_clone(dns_rootname, lookup->name); + } else { + len = strlen(lookup->textname); + isc_buffer_init(&b, lookup->textname, len); + isc_buffer_add(&b, len); + result = dns_name_fromtext(lookup->name, &b, + lookup->oname, ISC_FALSE, + &lookup->namebuf); + } + if (result != ISC_R_SUCCESS) { + dns_message_puttempname(lookup->sendmsg, + &lookup->name); + dns_message_puttempname(lookup->sendmsg, + &lookup->oname); + fatal("'%s' is not in legal name syntax (%s)", + lookup->textname, isc_result_totext(result)); + } + dns_message_puttempname(lookup->sendmsg, &lookup->oname); + } else +#endif + { + debug("using root origin"); + if (lookup->trace && lookup->trace_root) + dns_name_clone(dns_rootname, lookup->name); + else { +#ifdef WITH_IDN + len = strlen(idn_textname); + isc_buffer_init(&b, idn_textname, len); + isc_buffer_add(&b, len); + result = dns_name_fromtext(lookup->name, &b, + dns_rootname, + ISC_FALSE, + &lookup->namebuf); +#else + len = strlen(lookup->textname); + isc_buffer_init(&b, lookup->textname, len); + isc_buffer_add(&b, len); + result = dns_name_fromtext(lookup->name, &b, + dns_rootname, + ISC_FALSE, + &lookup->namebuf); +#endif + } + if (result != ISC_R_SUCCESS) { + dns_message_puttempname(lookup->sendmsg, + &lookup->name); + isc_buffer_init(&b, store, MXNAME); + fatal("'%s' is not a legal name " + "(%s)", lookup->textname, + isc_result_totext(result)); + } + } + dns_name_format(lookup->name, store, sizeof(store)); + trying(store, lookup); + INSIST(dns_name_isabsolute(lookup->name)); + + isc_random_get(&id); + lookup->sendmsg->id = (unsigned short)id & 0xFFFF; + lookup->sendmsg->opcode = dns_opcode_query; + lookup->msgcounter = 0; + /* + * If this is a trace request, completely disallow recursion, since + * it's meaningless for traces. + */ + if (lookup->trace || (lookup->ns_search_only && !lookup->trace_root)) + lookup->recurse = ISC_FALSE; + + if (lookup->recurse && + lookup->rdtype != dns_rdatatype_axfr && + lookup->rdtype != dns_rdatatype_ixfr) { + debug("recursive query"); + lookup->sendmsg->flags |= DNS_MESSAGEFLAG_RD; + } + + /* XXX aaflag */ + if (lookup->aaonly) { + debug("AA query"); + lookup->sendmsg->flags |= DNS_MESSAGEFLAG_AA; + } + + if (lookup->adflag) { + debug("AD query"); + lookup->sendmsg->flags |= DNS_MESSAGEFLAG_AD; + } + + if (lookup->cdflag) { + debug("CD query"); + lookup->sendmsg->flags |= DNS_MESSAGEFLAG_CD; + } + + dns_message_addname(lookup->sendmsg, lookup->name, + DNS_SECTION_QUESTION); + + if (lookup->trace && lookup->trace_root) { + lookup->qrdtype = lookup->rdtype; + lookup->rdtype = dns_rdatatype_ns; + } + + if ((lookup->rdtype == dns_rdatatype_axfr) || + (lookup->rdtype == dns_rdatatype_ixfr)) { + lookup->doing_xfr = ISC_TRUE; + /* + * Force TCP mode if we're doing an xfr. + * XXX UDP ixfr's would be useful + */ + lookup->tcp_mode = ISC_TRUE; + } + + add_question(lookup->sendmsg, lookup->name, lookup->rdclass, + lookup->rdtype); + + /* add_soa */ + if (lookup->rdtype == dns_rdatatype_ixfr) + insert_soa(lookup); + + /* XXX Insist this? */ + lookup->tsigctx = NULL; + lookup->querysig = NULL; + if (key != NULL) { + debug("initializing keys"); + result = dns_message_settsigkey(lookup->sendmsg, key); + check_result(result, "dns_message_settsigkey"); + } + + lookup->sendspace = isc_mempool_get(commctx); + if (lookup->sendspace == NULL) + fatal("memory allocation failure"); + + result = dns_compress_init(&cctx, -1, mctx); + check_result(result, "dns_compress_init"); + + debug("starting to render the message"); + isc_buffer_init(&lookup->renderbuf, lookup->sendspace, COMMSIZE); + result = dns_message_renderbegin(lookup->sendmsg, &cctx, + &lookup->renderbuf); + check_result(result, "dns_message_renderbegin"); + if (lookup->udpsize > 0 || lookup->dnssec || lookup->edns > -1) { + if (lookup->udpsize == 0) + lookup->udpsize = 4096; + if (lookup->edns < 0) + lookup->edns = 0; + add_opt(lookup->sendmsg, lookup->udpsize, + lookup->edns, lookup->dnssec); + } + + result = dns_message_rendersection(lookup->sendmsg, + DNS_SECTION_QUESTION, 0); + check_result(result, "dns_message_rendersection"); + result = dns_message_rendersection(lookup->sendmsg, + DNS_SECTION_AUTHORITY, 0); + check_result(result, "dns_message_rendersection"); + result = dns_message_renderend(lookup->sendmsg); + check_result(result, "dns_message_renderend"); + debug("done rendering"); + + dns_compress_invalidate(&cctx); + + /* + * Force TCP mode if the request is larger than 512 bytes. + */ + if (isc_buffer_usedlength(&lookup->renderbuf) > 512) + lookup->tcp_mode = ISC_TRUE; + + lookup->pending = ISC_FALSE; + + for (serv = ISC_LIST_HEAD(lookup->my_server_list); + serv != NULL; + serv = ISC_LIST_NEXT(serv, link)) { + query = isc_mem_allocate(mctx, sizeof(dig_query_t)); + if (query == NULL) + fatal("memory allocation failure in %s:%d", + __FILE__, __LINE__); + debug("create query %p linked to lookup %p", + query, lookup); + query->lookup = lookup; + query->waiting_connect = ISC_FALSE; + query->waiting_senddone = ISC_FALSE; + query->pending_free = ISC_FALSE; + query->recv_made = ISC_FALSE; + query->first_pass = ISC_TRUE; + query->first_soa_rcvd = ISC_FALSE; + query->second_rr_rcvd = ISC_FALSE; + query->first_repeat_rcvd = ISC_FALSE; + query->warn_id = ISC_TRUE; + query->first_rr_serial = 0; + query->second_rr_serial = 0; + query->servname = serv->servername; + query->userarg = serv->userarg; + query->rr_count = 0; + query->msg_count = 0; + query->byte_count = 0; + ISC_LINK_INIT(query, link); + ISC_LIST_INIT(query->recvlist); + ISC_LIST_INIT(query->lengthlist); + query->sock = NULL; + query->recvspace = isc_mempool_get(commctx); + if (query->recvspace == NULL) + fatal("memory allocation failure"); + + isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE); + isc_buffer_init(&query->lengthbuf, query->lengthspace, 2); + isc_buffer_init(&query->slbuf, query->slspace, 2); + query->sendbuf = lookup->renderbuf; + + ISC_LINK_INIT(query, link); + ISC_LIST_ENQUEUE(lookup->q, query, link); + } + /* XXX qrflag, print_query, etc... */ + if (!ISC_LIST_EMPTY(lookup->q) && qr) { + extrabytes = 0; + printmessage(ISC_LIST_HEAD(lookup->q), lookup->sendmsg, + ISC_TRUE); + } +} + +/*% + * Event handler for send completion. Track send counter, and clear out + * the query if the send was canceled. + */ +static void +send_done(isc_task_t *_task, isc_event_t *event) { + isc_socketevent_t *sevent = (isc_socketevent_t *)event; + isc_buffer_t *b = NULL; + dig_query_t *query, *next; + dig_lookup_t *l; + + REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE); + + UNUSED(_task); + + LOCK_LOOKUP; + + debug("send_done()"); + sendcount--; + debug("sendcount=%d", sendcount); + INSIST(sendcount >= 0); + + for (b = ISC_LIST_HEAD(sevent->bufferlist); + b != NULL; + b = ISC_LIST_HEAD(sevent->bufferlist)) + ISC_LIST_DEQUEUE(sevent->bufferlist, b, link); + + query = event->ev_arg; + query->waiting_senddone = ISC_FALSE; + l = query->lookup; + + if (l->ns_search_only && !l->trace_root) { + debug("sending next, since searching"); + next = ISC_LIST_NEXT(query, link); + if (next != NULL) + send_udp(next); + } + + isc_event_free(&event); + + if (query->pending_free) + isc_mem_free(mctx, query); + + check_if_done(); + UNLOCK_LOOKUP; +} + +/*% + * Cancel a lookup, sending isc_socket_cancel() requests to all outstanding + * IO sockets. The cancel handlers should take care of cleaning up the + * query and lookup structures + */ +static void +cancel_lookup(dig_lookup_t *lookup) { + dig_query_t *query, *next; + + debug("cancel_lookup()"); + query = ISC_LIST_HEAD(lookup->q); + while (query != NULL) { + next = ISC_LIST_NEXT(query, link); + if (query->sock != NULL) { + isc_socket_cancel(query->sock, global_task, + ISC_SOCKCANCEL_ALL); + check_if_done(); + } else { + clear_query(query); + } + query = next; + } + if (lookup->timer != NULL) + isc_timer_detach(&lookup->timer); + lookup->pending = ISC_FALSE; + lookup->retries = 0; +} + +static void +bringup_timer(dig_query_t *query, unsigned int default_timeout) { + dig_lookup_t *l; + unsigned int local_timeout; + isc_result_t result; + + debug("bringup_timer()"); + /* + * If the timer already exists, that means we're calling this + * a second time (for a retry). Don't need to recreate it, + * just reset it. + */ + l = query->lookup; + if (ISC_LIST_NEXT(query, link) != NULL) + local_timeout = SERVER_TIMEOUT; + else { + if (timeout == 0) + local_timeout = default_timeout; + else + local_timeout = timeout; + } + debug("have local timeout of %d", local_timeout); + isc_interval_set(&l->interval, local_timeout, 0); + if (l->timer != NULL) + isc_timer_detach(&l->timer); + result = isc_timer_create(timermgr, isc_timertype_once, NULL, + &l->interval, global_task, connect_timeout, + l, &l->timer); + check_result(result, "isc_timer_create"); +} + +static void +connect_done(isc_task_t *task, isc_event_t *event); + +/*% + * Unlike send_udp, this can't be called multiple times with the same + * query. When we retry TCP, we requeue the whole lookup, which should + * start anew. + */ +static void +send_tcp_connect(dig_query_t *query) { + isc_result_t result; + dig_query_t *next; + dig_lookup_t *l; + + debug("send_tcp_connect(%p)", query); + + l = query->lookup; + query->waiting_connect = ISC_TRUE; + query->lookup->current_query = query; + get_address(query->servname, port, &query->sockaddr); + + if (specified_source && + (isc_sockaddr_pf(&query->sockaddr) != + isc_sockaddr_pf(&bind_address))) { + printf(";; Skipping server %s, incompatible " + "address family\n", query->servname); + query->waiting_connect = ISC_FALSE; + next = ISC_LIST_NEXT(query, link); + l = query->lookup; + clear_query(query); + if (next == NULL) { + printf(";; No acceptable nameservers\n"); + check_next_lookup(l); + return; + } + send_tcp_connect(next); + return; + } + INSIST(query->sock == NULL); + result = isc_socket_create(socketmgr, + isc_sockaddr_pf(&query->sockaddr), + isc_sockettype_tcp, &query->sock); + check_result(result, "isc_socket_create"); + sockcount++; + debug("sockcount=%d", sockcount); + if (specified_source) + result = isc_socket_bind(query->sock, &bind_address); + else { + if ((isc_sockaddr_pf(&query->sockaddr) == AF_INET) && + have_ipv4) + isc_sockaddr_any(&bind_any); + else + isc_sockaddr_any6(&bind_any); + result = isc_socket_bind(query->sock, &bind_any); + } + check_result(result, "isc_socket_bind"); + bringup_timer(query, TCP_TIMEOUT); + result = isc_socket_connect(query->sock, &query->sockaddr, + global_task, connect_done, query); + check_result(result, "isc_socket_connect"); + /* + * If we're at the endgame of a nameserver search, we need to + * immediately bring up all the queries. Do it here. + */ + if (l->ns_search_only && !l->trace_root) { + debug("sending next, since searching"); + next = ISC_LIST_NEXT(query, link); + if (next != NULL) + send_tcp_connect(next); + } +} + +/*% + * Send a UDP packet to the remote nameserver, possible starting the + * recv action as well. Also make sure that the timer is running and + * is properly reset. + */ +static void +send_udp(dig_query_t *query) { + dig_lookup_t *l = NULL; + isc_result_t result; + + debug("send_udp(%p)", query); + + l = query->lookup; + bringup_timer(query, UDP_TIMEOUT); + l->current_query = query; + debug("working on lookup %p, query %p", query->lookup, query); + if (!query->recv_made) { + /* XXX Check the sense of this, need assertion? */ + query->waiting_connect = ISC_FALSE; + get_address(query->servname, port, &query->sockaddr); + + result = isc_socket_create(socketmgr, + isc_sockaddr_pf(&query->sockaddr), + isc_sockettype_udp, &query->sock); + check_result(result, "isc_socket_create"); + sockcount++; + debug("sockcount=%d", sockcount); + if (specified_source) { + result = isc_socket_bind(query->sock, &bind_address); + } else { + isc_sockaddr_anyofpf(&bind_any, + isc_sockaddr_pf(&query->sockaddr)); + result = isc_socket_bind(query->sock, &bind_any); + } + check_result(result, "isc_socket_bind"); + + query->recv_made = ISC_TRUE; + ISC_LINK_INIT(&query->recvbuf, link); + ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, + link); + debug("recving with lookup=%p, query=%p, sock=%p", + query->lookup, query, query->sock); + result = isc_socket_recvv(query->sock, &query->recvlist, 1, + global_task, recv_done, query); + check_result(result, "isc_socket_recvv"); + recvcount++; + debug("recvcount=%d", recvcount); + } + ISC_LIST_INIT(query->sendlist); + ISC_LIST_ENQUEUE(query->sendlist, &query->sendbuf, link); + debug("sending a request"); + TIME_NOW(&query->time_sent); + INSIST(query->sock != NULL); + query->waiting_senddone = ISC_TRUE; + result = isc_socket_sendtov(query->sock, &query->sendlist, + global_task, send_done, query, + &query->sockaddr, NULL); + check_result(result, "isc_socket_sendtov"); + sendcount++; +} + +/*% + * IO timeout handler, used for both connect and recv timeouts. If + * retries are still allowed, either resend the UDP packet or queue a + * new TCP lookup. Otherwise, cancel the lookup. + */ +static void +connect_timeout(isc_task_t *task, isc_event_t *event) { + dig_lookup_t *l = NULL; + dig_query_t *query = NULL, *cq; + + UNUSED(task); + REQUIRE(event->ev_type == ISC_TIMEREVENT_IDLE); + + debug("connect_timeout()"); + + LOCK_LOOKUP; + l = event->ev_arg; + query = l->current_query; + isc_event_free(&event); + + INSIST(!free_now); + + if ((query != NULL) && (query->lookup->current_query != NULL) && + (ISC_LIST_NEXT(query->lookup->current_query, link) != NULL)) { + debug("trying next server..."); + cq = query->lookup->current_query; + if (!l->tcp_mode) + send_udp(ISC_LIST_NEXT(cq, link)); + else + send_tcp_connect(ISC_LIST_NEXT(cq, link)); + UNLOCK_LOOKUP; + return; + } + + if (l->retries > 1) { + if (!l->tcp_mode) { + l->retries--; + debug("resending UDP request to first server"); + send_udp(ISC_LIST_HEAD(l->q)); + } else { + debug("making new TCP request, %d tries left", + l->retries); + l->retries--; + requeue_lookup(l, ISC_TRUE); + cancel_lookup(l); + check_next_lookup(l); + } + } else { + fputs(l->cmdline, stdout); + printf(";; connection timed out; no servers could be " + "reached\n"); + cancel_lookup(l); + check_next_lookup(l); + if (exitcode < 9) + exitcode = 9; + } + UNLOCK_LOOKUP; +} + +/*% + * Event handler for the TCP recv which gets the length header of TCP + * packets. Start the next recv of length bytes. + */ +static void +tcp_length_done(isc_task_t *task, isc_event_t *event) { + isc_socketevent_t *sevent; + isc_buffer_t *b = NULL; + isc_result_t result; + dig_query_t *query = NULL; + dig_lookup_t *l; + isc_uint16_t length; + + REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE); + INSIST(!free_now); + + UNUSED(task); + + debug("tcp_length_done()"); + + LOCK_LOOKUP; + sevent = (isc_socketevent_t *)event; + query = event->ev_arg; + + recvcount--; + INSIST(recvcount >= 0); + + b = ISC_LIST_HEAD(sevent->bufferlist); + INSIST(b == &query->lengthbuf); + ISC_LIST_DEQUEUE(sevent->bufferlist, b, link); + + if (sevent->result == ISC_R_CANCELED) { + isc_event_free(&event); + l = query->lookup; + clear_query(query); + check_next_lookup(l); + UNLOCK_LOOKUP; + return; + } + if (sevent->result != ISC_R_SUCCESS) { + char sockstr[ISC_SOCKADDR_FORMATSIZE]; + isc_sockaddr_format(&query->sockaddr, sockstr, + sizeof(sockstr)); + printf(";; communications error to %s: %s\n", + sockstr, isc_result_totext(sevent->result)); + l = query->lookup; + isc_socket_detach(&query->sock); + sockcount--; + debug("sockcount=%d", sockcount); + INSIST(sockcount >= 0); + isc_event_free(&event); + clear_query(query); + check_next_lookup(l); + UNLOCK_LOOKUP; + return; + } + length = isc_buffer_getuint16(b); + if (length == 0) { + isc_event_free(&event); + launch_next_query(query, ISC_FALSE); + UNLOCK_LOOKUP; + return; + } + + /* + * Even though the buffer was already init'ed, we need + * to redo it now, to force the length we want. + */ + isc_buffer_invalidate(&query->recvbuf); + isc_buffer_init(&query->recvbuf, query->recvspace, length); + ENSURE(ISC_LIST_EMPTY(query->recvlist)); + ISC_LINK_INIT(&query->recvbuf, link); + ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, link); + debug("recving with lookup=%p, query=%p", query->lookup, query); + result = isc_socket_recvv(query->sock, &query->recvlist, length, task, + recv_done, query); + check_result(result, "isc_socket_recvv"); + recvcount++; + debug("resubmitted recv request with length %d, recvcount=%d", + length, recvcount); + isc_event_free(&event); + UNLOCK_LOOKUP; +} + +/*% + * For transfers that involve multiple recvs (XFR's in particular), + * launch the next recv. + */ +static void +launch_next_query(dig_query_t *query, isc_boolean_t include_question) { + isc_result_t result; + dig_lookup_t *l; + + INSIST(!free_now); + + debug("launch_next_query()"); + + if (!query->lookup->pending) { + debug("ignoring launch_next_query because !pending"); + isc_socket_detach(&query->sock); + sockcount--; + debug("sockcount=%d", sockcount); + INSIST(sockcount >= 0); + query->waiting_connect = ISC_FALSE; + l = query->lookup; + clear_query(query); + check_next_lookup(l); + return; + } + + isc_buffer_clear(&query->slbuf); + isc_buffer_clear(&query->lengthbuf); + isc_buffer_putuint16(&query->slbuf, (isc_uint16_t) query->sendbuf.used); + ISC_LIST_INIT(query->sendlist); + ISC_LINK_INIT(&query->slbuf, link); + ISC_LIST_ENQUEUE(query->sendlist, &query->slbuf, link); + if (include_question) + ISC_LIST_ENQUEUE(query->sendlist, &query->sendbuf, link); + ISC_LINK_INIT(&query->lengthbuf, link); + ISC_LIST_ENQUEUE(query->lengthlist, &query->lengthbuf, link); + + result = isc_socket_recvv(query->sock, &query->lengthlist, 0, + global_task, tcp_length_done, query); + check_result(result, "isc_socket_recvv"); + recvcount++; + debug("recvcount=%d", recvcount); + if (!query->first_soa_rcvd) { + debug("sending a request in launch_next_query"); + TIME_NOW(&query->time_sent); + query->waiting_senddone = ISC_TRUE; + result = isc_socket_sendv(query->sock, &query->sendlist, + global_task, send_done, query); + check_result(result, "isc_socket_sendv"); + sendcount++; + debug("sendcount=%d", sendcount); + } + query->waiting_connect = ISC_FALSE; +#if 0 + check_next_lookup(query->lookup); +#endif + return; +} + +/*% + * Event handler for TCP connect complete. Make sure the connection was + * successful, then pass into launch_next_query to actually send the + * question. + */ +static void +connect_done(isc_task_t *task, isc_event_t *event) { + isc_socketevent_t *sevent = NULL; + dig_query_t *query = NULL, *next; + dig_lookup_t *l; + + UNUSED(task); + + REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT); + INSIST(!free_now); + + debug("connect_done()"); + + LOCK_LOOKUP; + sevent = (isc_socketevent_t *)event; + query = sevent->ev_arg; + + INSIST(query->waiting_connect); + + query->waiting_connect = ISC_FALSE; + + if (sevent->result == ISC_R_CANCELED) { + debug("in cancel handler"); + isc_socket_detach(&query->sock); + sockcount--; + INSIST(sockcount >= 0); + debug("sockcount=%d", sockcount); + query->waiting_connect = ISC_FALSE; + isc_event_free(&event); + l = query->lookup; + clear_query(query); + check_next_lookup(l); + UNLOCK_LOOKUP; + return; + } + if (sevent->result != ISC_R_SUCCESS) { + char sockstr[ISC_SOCKADDR_FORMATSIZE]; + + debug("unsuccessful connection: %s", + isc_result_totext(sevent->result)); + isc_sockaddr_format(&query->sockaddr, sockstr, sizeof(sockstr)); + if (sevent->result != ISC_R_CANCELED) + printf(";; Connection to %s(%s) for %s failed: " + "%s.\n", sockstr, + query->servname, query->lookup->textname, + isc_result_totext(sevent->result)); + isc_socket_detach(&query->sock); + sockcount--; + INSIST(sockcount >= 0); + /* XXX Clean up exitcodes */ + if (exitcode < 9) + exitcode = 9; + debug("sockcount=%d", sockcount); + query->waiting_connect = ISC_FALSE; + isc_event_free(&event); + l = query->lookup; + if (l->current_query != NULL) + next = ISC_LIST_NEXT(l->current_query, link); + else + next = NULL; + clear_query(query); + if (next != NULL) { + bringup_timer(next, TCP_TIMEOUT); + send_tcp_connect(next); + } else { + check_next_lookup(l); + } + UNLOCK_LOOKUP; + return; + } + launch_next_query(query, ISC_TRUE); + isc_event_free(&event); + UNLOCK_LOOKUP; +} + +/*% + * Check if the ongoing XFR needs more data before it's complete, using + * the semantics of IXFR and AXFR protocols. Much of the complexity of + * this routine comes from determining when an IXFR is complete. + * ISC_FALSE means more data is on the way, and the recv has been issued. + */ +static isc_boolean_t +check_for_more_data(dig_query_t *query, dns_message_t *msg, + isc_socketevent_t *sevent) +{ + dns_rdataset_t *rdataset = NULL; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdata_soa_t soa; + isc_uint32_t serial; + isc_result_t result; + + debug("check_for_more_data()"); + + /* + * By the time we're in this routine, we know we're doing + * either an AXFR or IXFR. If there's no second_rr_type, + * then we don't yet know which kind of answer we got back + * from the server. Here, we're going to walk through the + * rr's in the message, acting as necessary whenever we hit + * an SOA rr. + */ + + query->msg_count++; + query->byte_count += sevent->n; + result = dns_message_firstname(msg, DNS_SECTION_ANSWER); + if (result != ISC_R_SUCCESS) { + puts("; Transfer failed."); + return (ISC_TRUE); + } + do { + dns_name_t *name; + name = NULL; + dns_message_currentname(msg, DNS_SECTION_ANSWER, + &name); + for (rdataset = ISC_LIST_HEAD(name->list); + rdataset != NULL; + rdataset = ISC_LIST_NEXT(rdataset, link)) { + result = dns_rdataset_first(rdataset); + if (result != ISC_R_SUCCESS) + continue; + do { + query->rr_count++; + dns_rdata_reset(&rdata); + dns_rdataset_current(rdataset, &rdata); + /* + * If this is the first rr, make sure + * it's an SOA + */ + if ((!query->first_soa_rcvd) && + (rdata.type != dns_rdatatype_soa)) { + puts("; Transfer failed. " + "Didn't start with SOA answer."); + return (ISC_TRUE); + } + if ((!query->second_rr_rcvd) && + (rdata.type != dns_rdatatype_soa)) { + query->second_rr_rcvd = ISC_TRUE; + query->second_rr_serial = 0; + debug("got the second rr as nonsoa"); + goto next_rdata; + } + + /* + * If the record is anything except an SOA + * now, just continue on... + */ + if (rdata.type != dns_rdatatype_soa) + goto next_rdata; + /* Now we have an SOA. Work with it. */ + debug("got an SOA"); + (void)dns_rdata_tostruct(&rdata, &soa, NULL); + serial = soa.serial; + dns_rdata_freestruct(&soa); + if (!query->first_soa_rcvd) { + query->first_soa_rcvd = ISC_TRUE; + query->first_rr_serial = serial; + debug("this is the first %d", + query->lookup->ixfr_serial); + if (query->lookup->ixfr_serial >= + serial) + goto doexit; + goto next_rdata; + } + if (query->lookup->rdtype == + dns_rdatatype_axfr) { + debug("doing axfr, got second SOA"); + goto doexit; + } + if (!query->second_rr_rcvd) { + if (query->first_rr_serial == serial) { + debug("doing ixfr, got " + "empty zone"); + goto doexit; + } + debug("this is the second %d", + query->lookup->ixfr_serial); + query->second_rr_rcvd = ISC_TRUE; + query->second_rr_serial = serial; + goto next_rdata; + } + if (query->second_rr_serial == 0) { + /* + * If the second RR was a non-SOA + * record, and we're getting any + * other SOA, then this is an + * AXFR, and we're done. + */ + debug("done, since axfr"); + goto doexit; + } + /* + * If we get to this point, we're doing an + * IXFR and have to start really looking + * at serial numbers. + */ + if (query->first_rr_serial == serial) { + debug("got a match for ixfr"); + if (!query->first_repeat_rcvd) { + query->first_repeat_rcvd = + ISC_TRUE; + goto next_rdata; + } + debug("done with ixfr"); + goto doexit; + } + debug("meaningless soa %d", serial); + next_rdata: + result = dns_rdataset_next(rdataset); + } while (result == ISC_R_SUCCESS); + } + result = dns_message_nextname(msg, DNS_SECTION_ANSWER); + } while (result == ISC_R_SUCCESS); + launch_next_query(query, ISC_FALSE); + return (ISC_FALSE); + doexit: + received(sevent->n, &sevent->address, query); + return (ISC_TRUE); +} + +/*% + * Event handler for recv complete. Perform whatever actions are necessary, + * based on the specifics of the user's request. + */ +static void +recv_done(isc_task_t *task, isc_event_t *event) { + isc_socketevent_t *sevent = NULL; + dig_query_t *query = NULL; + isc_buffer_t *b = NULL; + dns_message_t *msg = NULL; +#ifdef DIG_SIGCHASE + dig_message_t *chase_msg = NULL; + dig_message_t *chase_msg2 = NULL; +#endif + isc_result_t result; + dig_lookup_t *n, *l; + isc_boolean_t docancel = ISC_FALSE; + isc_boolean_t match = ISC_TRUE; + unsigned int parseflags; + dns_messageid_t id; + unsigned int msgflags; +#ifdef DIG_SIGCHASE + isc_result_t do_sigchase = ISC_FALSE; + + dns_message_t *msg_temp = NULL; + isc_region_t r; + isc_buffer_t *buf = NULL; +#endif + + UNUSED(task); + INSIST(!free_now); + + debug("recv_done()"); + + LOCK_LOOKUP; + recvcount--; + debug("recvcount=%d", recvcount); + INSIST(recvcount >= 0); + + query = event->ev_arg; + debug("lookup=%p, query=%p", query->lookup, query); + + l = query->lookup; + + REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE); + sevent = (isc_socketevent_t *)event; + + b = ISC_LIST_HEAD(sevent->bufferlist); + INSIST(b == &query->recvbuf); + ISC_LIST_DEQUEUE(sevent->bufferlist, &query->recvbuf, link); + + if ((l->tcp_mode) && (l->timer != NULL)) + isc_timer_touch(l->timer); + if ((!l->pending && !l->ns_search_only) || cancel_now) { + debug("no longer pending. Got %s", + isc_result_totext(sevent->result)); + query->waiting_connect = ISC_FALSE; + + isc_event_free(&event); + clear_query(query); + check_next_lookup(l); + UNLOCK_LOOKUP; + return; + } + + if (sevent->result != ISC_R_SUCCESS) { + if (sevent->result == ISC_R_CANCELED) { + debug("in recv cancel handler"); + query->waiting_connect = ISC_FALSE; + } else { + printf(";; communications error: %s\n", + isc_result_totext(sevent->result)); + isc_socket_detach(&query->sock); + sockcount--; + debug("sockcount=%d", sockcount); + INSIST(sockcount >= 0); + } + isc_event_free(&event); + clear_query(query); + check_next_lookup(l); + UNLOCK_LOOKUP; + return; + } + + if (!l->tcp_mode && + !isc_sockaddr_compare(&sevent->address, &query->sockaddr, + ISC_SOCKADDR_CMPADDR| + ISC_SOCKADDR_CMPPORT| + ISC_SOCKADDR_CMPSCOPE| + ISC_SOCKADDR_CMPSCOPEZERO)) { + char buf1[ISC_SOCKADDR_FORMATSIZE]; + char buf2[ISC_SOCKADDR_FORMATSIZE]; + isc_sockaddr_t any; + + if (isc_sockaddr_pf(&query->sockaddr) == AF_INET) + isc_sockaddr_any(&any); + else + isc_sockaddr_any6(&any); + + /* + * We don't expect a match when the packet is + * sent to 0.0.0.0, :: or to a multicast addresses. + * XXXMPA broadcast needs to be handled here as well. + */ + if ((!isc_sockaddr_eqaddr(&query->sockaddr, &any) && + !isc_sockaddr_ismulticast(&query->sockaddr)) || + isc_sockaddr_getport(&query->sockaddr) != + isc_sockaddr_getport(&sevent->address)) { + isc_sockaddr_format(&sevent->address, buf1, + sizeof(buf1)); + isc_sockaddr_format(&query->sockaddr, buf2, + sizeof(buf2)); + printf(";; reply from unexpected source: %s," + " expected %s\n", buf1, buf2); + match = ISC_FALSE; + } + } + + result = dns_message_peekheader(b, &id, &msgflags); + if (result != ISC_R_SUCCESS || l->sendmsg->id != id) { + match = ISC_FALSE; + if (l->tcp_mode) { + isc_boolean_t fail = ISC_TRUE; + if (result == ISC_R_SUCCESS) { + if (!query->first_soa_rcvd || + query->warn_id) + printf(";; %s: ID mismatch: " + "expected ID %u, got %u\n", + query->first_soa_rcvd ? + "WARNING" : "ERROR", + l->sendmsg->id, id); + if (query->first_soa_rcvd) + fail = ISC_FALSE; + query->warn_id = ISC_FALSE; + } else + printf(";; ERROR: short " + "(< header size) message\n"); + if (fail) { + isc_event_free(&event); + clear_query(query); + check_next_lookup(l); + UNLOCK_LOOKUP; + return; + } + match = ISC_TRUE; + } else if (result == ISC_R_SUCCESS) + printf(";; Warning: ID mismatch: " + "expected ID %u, got %u\n", l->sendmsg->id, id); + else + printf(";; Warning: short " + "(< header size) message received\n"); + } + + if (result == ISC_R_SUCCESS && (msgflags & DNS_MESSAGEFLAG_QR) == 0) + printf(";; Warning: query response not set\n"); + + if (!match) { + isc_buffer_invalidate(&query->recvbuf); + isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE); + ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, link); + result = isc_socket_recvv(query->sock, &query->recvlist, 1, + global_task, recv_done, query); + check_result(result, "isc_socket_recvv"); + recvcount++; + isc_event_free(&event); + UNLOCK_LOOKUP; + return; + } + + result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg); + check_result(result, "dns_message_create"); + + if (key != NULL) { + if (l->querysig == NULL) { + debug("getting initial querysig"); + result = dns_message_getquerytsig(l->sendmsg, mctx, + &l->querysig); + check_result(result, "dns_message_getquerytsig"); + } + result = dns_message_setquerytsig(msg, l->querysig); + check_result(result, "dns_message_setquerytsig"); + result = dns_message_settsigkey(msg, key); + check_result(result, "dns_message_settsigkey"); + msg->tsigctx = l->tsigctx; + l->tsigctx = NULL; + if (l->msgcounter != 0) + msg->tcp_continuation = 1; + l->msgcounter++; + } + + debug("before parse starts"); + parseflags = DNS_MESSAGEPARSE_PRESERVEORDER; +#ifdef DIG_SIGCHASE + if (!l->sigchase) { + do_sigchase = ISC_FALSE; + } else { + parseflags = 0; + do_sigchase = ISC_TRUE; + } +#endif + if (l->besteffort) { + parseflags |= DNS_MESSAGEPARSE_BESTEFFORT; + parseflags |= DNS_MESSAGEPARSE_IGNORETRUNCATION; + } + result = dns_message_parse(msg, b, parseflags); + if (result == DNS_R_RECOVERABLE) { + printf(";; Warning: Message parser reports malformed " + "message packet.\n"); + result = ISC_R_SUCCESS; + } + if (result != ISC_R_SUCCESS) { + printf(";; Got bad packet: %s\n", isc_result_totext(result)); + hex_dump(b); + query->waiting_connect = ISC_FALSE; + dns_message_destroy(&msg); + isc_event_free(&event); + clear_query(query); + cancel_lookup(l); + check_next_lookup(l); + UNLOCK_LOOKUP; + return; + } + if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0 && + !l->ignore && !l->tcp_mode) { + printf(";; Truncated, retrying in TCP mode.\n"); + n = requeue_lookup(l, ISC_TRUE); + n->tcp_mode = ISC_TRUE; + n->origin = query->lookup->origin; + dns_message_destroy(&msg); + isc_event_free(&event); + clear_query(query); + cancel_lookup(l); + check_next_lookup(l); + UNLOCK_LOOKUP; + return; + } + if ((msg->rcode == dns_rcode_servfail && !l->servfail_stops) || + (check_ra && (msg->flags & DNS_MESSAGEFLAG_RA) == 0 && l->recurse)) + { + dig_query_t *next = ISC_LIST_NEXT(query, link); + if (l->current_query == query) + l->current_query = NULL; + if (next != NULL) { + debug("sending query %p\n", next); + if (l->tcp_mode) + send_tcp_connect(next); + else + send_udp(next); + } + /* + * If our query is at the head of the list and there + * is no next, we're the only one left, so fall + * through to print the message. + */ + if ((ISC_LIST_HEAD(l->q) != query) || + (ISC_LIST_NEXT(query, link) != NULL)) { + if( l->comments == ISC_TRUE ) + printf(";; Got %s from %s, " + "trying next server\n", + msg->rcode == dns_rcode_servfail ? + "SERVFAIL reply" : + "recursion not available", + query->servname); + clear_query(query); + check_next_lookup(l); + dns_message_destroy(&msg); + isc_event_free(&event); + UNLOCK_LOOKUP; + return; + } + } + + if (key != NULL) { + result = dns_tsig_verify(&query->recvbuf, msg, NULL, NULL); + if (result != ISC_R_SUCCESS) { + printf(";; Couldn't verify signature: %s\n", + isc_result_totext(result)); + validated = ISC_FALSE; + } + l->tsigctx = msg->tsigctx; + msg->tsigctx = NULL; + if (l->querysig != NULL) { + debug("freeing querysig buffer %p", l->querysig); + isc_buffer_free(&l->querysig); + } + result = dns_message_getquerytsig(msg, mctx, &l->querysig); + check_result(result,"dns_message_getquerytsig"); + } + + extrabytes = isc_buffer_remaininglength(b); + + debug("after parse"); + if (l->doing_xfr && l->xfr_q == NULL) { + l->xfr_q = query; + /* + * Once we are in the XFR message, increase + * the timeout to much longer, so brief network + * outages won't cause the XFR to abort + */ + if (timeout != INT_MAX && l->timer != NULL) { + unsigned int local_timeout; + + if (timeout == 0) { + if (l->tcp_mode) + local_timeout = TCP_TIMEOUT * 4; + else + local_timeout = UDP_TIMEOUT * 4; + } else { + if (timeout < (INT_MAX / 4)) + local_timeout = timeout * 4; + else + local_timeout = INT_MAX; + } + debug("have local timeout of %d", local_timeout); + isc_interval_set(&l->interval, local_timeout, 0); + result = isc_timer_reset(l->timer, + isc_timertype_once, + NULL, + &l->interval, + ISC_FALSE); + check_result(result, "isc_timer_reset"); + } + } + + if (!l->doing_xfr || l->xfr_q == query) { + if (msg->rcode != dns_rcode_noerror && + (l->origin != NULL || l->need_search)) { + if (!next_origin(msg, query) || showsearch) { + printmessage(query, msg, ISC_TRUE); + received(b->used, &sevent->address, query); + } + } else if (!l->trace && !l->ns_search_only) { +#ifdef DIG_SIGCHASE + if (!do_sigchase) +#endif + printmessage(query, msg, ISC_TRUE); + } else if (l->trace) { + int n = 0; + int count = msg->counts[DNS_SECTION_ANSWER]; + + debug("in TRACE code"); + if (!l->ns_search_only) + printmessage(query, msg, ISC_TRUE); + + l->rdtype = l->qrdtype; + if (l->trace_root || (l->ns_search_only && count > 0)) { + if (!l->trace_root) + l->rdtype = dns_rdatatype_soa; + n = followup_lookup(msg, query, + DNS_SECTION_ANSWER); + l->trace_root = ISC_FALSE; + } else if (count == 0) + n = followup_lookup(msg, query, + DNS_SECTION_AUTHORITY); + if (n == 0) + docancel = ISC_TRUE; + } else { + debug("in NSSEARCH code"); + + if (l->trace_root) { + /* + * This is the initial NS query. + */ + int n; + + l->rdtype = dns_rdatatype_soa; + n = followup_lookup(msg, query, + DNS_SECTION_ANSWER); + if (n == 0) + docancel = ISC_TRUE; + l->trace_root = ISC_FALSE; + } else +#ifdef DIG_SIGCHASE + if (!do_sigchase) +#endif + printmessage(query, msg, ISC_TRUE); + } +#ifdef DIG_SIGCHASE + if (do_sigchase) { + chase_msg = isc_mem_allocate(mctx, + sizeof(dig_message_t)); + if (chase_msg == NULL) { + fatal("Memory allocation failure in %s:%d", + __FILE__, __LINE__); + } + ISC_LIST_INITANDAPPEND(chase_message_list, chase_msg, + link); + if (dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, + &msg_temp) != ISC_R_SUCCESS) { + fatal("dns_message_create in %s:%d", + __FILE__, __LINE__); + } + + isc_buffer_usedregion(b, &r); + result = isc_buffer_allocate(mctx, &buf, r.length); + + check_result(result, "isc_buffer_allocate"); + result = isc_buffer_copyregion(buf, &r); + check_result(result, "isc_buffer_copyregion"); + + result = dns_message_parse(msg_temp, buf, 0); + + isc_buffer_free(&buf); + chase_msg->msg = msg_temp; + + chase_msg2 = isc_mem_allocate(mctx, + sizeof(dig_message_t)); + if (chase_msg2 == NULL) { + fatal("Memory allocation failure in %s:%d", + __FILE__, __LINE__); + } + ISC_LIST_INITANDAPPEND(chase_message_list2, chase_msg2, + link); + chase_msg2->msg = msg; + } +#endif + } + +#ifdef DIG_SIGCHASE + if (l->sigchase && ISC_LIST_EMPTY(lookup_list)) { + sigchase(msg_temp); + } +#endif + + if (l->pending) + debug("still pending."); + if (l->doing_xfr) { + if (query != l->xfr_q) { + dns_message_destroy(&msg); + isc_event_free(&event); + query->waiting_connect = ISC_FALSE; + UNLOCK_LOOKUP; + return; + } + if (!docancel) + docancel = check_for_more_data(query, msg, sevent); + if (docancel) { + dns_message_destroy(&msg); + clear_query(query); + cancel_lookup(l); + check_next_lookup(l); + } + } else { + + if (msg->rcode == dns_rcode_noerror || l->origin == NULL) { + +#ifdef DIG_SIGCHASE + if (!l->sigchase) +#endif + received(b->used, &sevent->address, query); + } + + if (!query->lookup->ns_search_only) + query->lookup->pending = ISC_FALSE; + if (!query->lookup->ns_search_only || + query->lookup->trace_root || docancel) { +#ifdef DIG_SIGCHASE + if (!do_sigchase) +#endif + dns_message_destroy(&msg); + + cancel_lookup(l); + } + clear_query(query); + check_next_lookup(l); + } + if (msg != NULL) { +#ifdef DIG_SIGCHASE + if (do_sigchase) + msg = NULL; + else +#endif + dns_message_destroy(&msg); + } + isc_event_free(&event); + UNLOCK_LOOKUP; +} + +/*% + * Turn a name into an address, using system-supplied routines. This is + * used in looking up server names, etc... and needs to use system-supplied + * routines, since they may be using a non-DNS system for these lookups. + */ +void +get_address(char *host, in_port_t port, isc_sockaddr_t *sockaddr) { + int count; + isc_result_t result; + + isc_app_block(); + result = bind9_getaddresses(host, port, sockaddr, 1, &count); + isc_app_unblock(); + if (result != ISC_R_SUCCESS) + fatal("couldn't get address for '%s': %s", + host, isc_result_totext(result)); + INSIST(count == 1); +} + +/*% + * Initiate either a TCP or UDP lookup + */ +void +do_lookup(dig_lookup_t *lookup) { + + REQUIRE(lookup != NULL); + + debug("do_lookup()"); + lookup->pending = ISC_TRUE; + if (lookup->tcp_mode) + send_tcp_connect(ISC_LIST_HEAD(lookup->q)); + else + send_udp(ISC_LIST_HEAD(lookup->q)); +} + +/*% + * Start everything in action upon task startup. + */ +void +onrun_callback(isc_task_t *task, isc_event_t *event) { + UNUSED(task); + + isc_event_free(&event); + LOCK_LOOKUP; + start_lookup(); + UNLOCK_LOOKUP; +} + +/*% + * Make everything on the lookup queue go away. Mainly used by the + * SIGINT handler. + */ +void +cancel_all(void) { + dig_lookup_t *l, *n; + dig_query_t *q, *nq; + + debug("cancel_all()"); + + LOCK_LOOKUP; + if (free_now) { + UNLOCK_LOOKUP; + return; + } + cancel_now = ISC_TRUE; + if (current_lookup != NULL) { + if (current_lookup->timer != NULL) + isc_timer_detach(¤t_lookup->timer); + q = ISC_LIST_HEAD(current_lookup->q); + while (q != NULL) { + debug("cancelling query %p, belonging to %p", + q, current_lookup); + nq = ISC_LIST_NEXT(q, link); + if (q->sock != NULL) { + isc_socket_cancel(q->sock, NULL, + ISC_SOCKCANCEL_ALL); + } else { + clear_query(q); + } + q = nq; + } + } + l = ISC_LIST_HEAD(lookup_list); + while (l != NULL) { + n = ISC_LIST_NEXT(l, link); + ISC_LIST_DEQUEUE(lookup_list, l, link); + try_clear_lookup(l); + l = n; + } + UNLOCK_LOOKUP; +} + +/*% + * Destroy all of the libs we are using, and get everything ready for a + * clean shutdown. + */ +void +destroy_libs(void) { +#ifdef DIG_SIGCHASE + void * ptr; + dig_message_t *chase_msg; +#endif +#ifdef WITH_IDN + isc_result_t result; +#endif + + debug("destroy_libs()"); + if (global_task != NULL) { + debug("freeing task"); + isc_task_detach(&global_task); + } + /* + * The taskmgr_destroy() call blocks until all events are cleared + * from the task. + */ + if (taskmgr != NULL) { + debug("freeing taskmgr"); + isc_taskmgr_destroy(&taskmgr); + } + LOCK_LOOKUP; + REQUIRE(sockcount == 0); + REQUIRE(recvcount == 0); + REQUIRE(sendcount == 0); + + INSIST(ISC_LIST_HEAD(lookup_list) == NULL); + INSIST(current_lookup == NULL); + INSIST(!free_now); + + free_now = ISC_TRUE; + + lwres_conf_clear(lwctx); + lwres_context_destroy(&lwctx); + + flush_server_list(); + + clear_searchlist(); + +#ifdef WITH_IDN + result = dns_name_settotextfilter(NULL); + check_result(result, "dns_name_settotextfilter"); +#endif + dns_name_destroy(); + + if (commctx != NULL) { + debug("freeing commctx"); + isc_mempool_destroy(&commctx); + } + if (socketmgr != NULL) { + debug("freeing socketmgr"); + isc_socketmgr_destroy(&socketmgr); + } + if (timermgr != NULL) { + debug("freeing timermgr"); + isc_timermgr_destroy(&timermgr); + } + if (key != NULL) { + debug("freeing key %p", key); + dns_tsigkey_detach(&key); + } + if (namebuf != NULL) + isc_buffer_free(&namebuf); + + if (is_dst_up) { + debug("destroy DST lib"); + dst_lib_destroy(); + is_dst_up = ISC_FALSE; + } + if (entp != NULL) { + debug("detach from entropy"); + isc_entropy_detach(&entp); + } + + UNLOCK_LOOKUP; + DESTROYLOCK(&lookup_lock); +#ifdef DIG_SIGCHASE + + debug("Destroy the messages kept for sigchase"); + /* Destroy the messages kept for sigchase */ + chase_msg = ISC_LIST_HEAD(chase_message_list); + + while (chase_msg != NULL) { + INSIST(chase_msg->msg != NULL); + dns_message_destroy(&(chase_msg->msg)); + ptr = chase_msg; + chase_msg = ISC_LIST_NEXT(chase_msg, link); + isc_mem_free(mctx, ptr); + } + + chase_msg = ISC_LIST_HEAD(chase_message_list2); + + while (chase_msg != NULL) { + INSIST(chase_msg->msg != NULL); + dns_message_destroy(&(chase_msg->msg)); + ptr = chase_msg; + chase_msg = ISC_LIST_NEXT(chase_msg, link); + isc_mem_free(mctx, ptr); + } + if (dns_name_dynamic(&chase_name)) + free_name(&chase_name, mctx); +#if DIG_SIGCHASE_TD + if (dns_name_dynamic(&chase_current_name)) + free_name(&chase_current_name, mctx); + if (dns_name_dynamic(&chase_authority_name)) + free_name(&chase_authority_name, mctx); +#endif +#if DIG_SIGCHASE_BU + if (dns_name_dynamic(&chase_signame)) + free_name(&chase_signame, mctx); +#endif + + debug("Destroy memory"); + +#endif + if (memdebugging != 0) + isc_mem_stats(mctx, stderr); + if (mctx != NULL) + isc_mem_destroy(&mctx); +} + +#ifdef WITH_IDN +static void +initialize_idn(void) { + idn_result_t r; + isc_result_t result; + +#ifdef HAVE_SETLOCALE + /* Set locale */ + (void)setlocale(LC_ALL, ""); +#endif + /* Create configuration context. */ + r = idn_nameinit(1); + if (r != idn_success) + fatal("idn api initialization failed: %s", + idn_result_tostring(r)); + + /* Set domain name -> text post-conversion filter. */ + result = dns_name_settotextfilter(output_filter); + check_result(result, "dns_name_settotextfilter"); +} + +static isc_result_t +output_filter(isc_buffer_t *buffer, unsigned int used_org, + isc_boolean_t absolute) +{ + char tmp1[MAXDLEN], tmp2[MAXDLEN]; + size_t fromlen, tolen; + isc_boolean_t end_with_dot; + + /* + * Copy contents of 'buffer' to 'tmp1', supply trailing dot + * if 'absolute' is true, and terminate with NUL. + */ + fromlen = isc_buffer_usedlength(buffer) - used_org; + if (fromlen >= MAXDLEN) + return (ISC_R_SUCCESS); + memcpy(tmp1, (char *)isc_buffer_base(buffer) + used_org, fromlen); + end_with_dot = (tmp1[fromlen - 1] == '.') ? ISC_TRUE : ISC_FALSE; + if (absolute && !end_with_dot) { + fromlen++; + if (fromlen >= MAXDLEN) + return (ISC_R_SUCCESS); + tmp1[fromlen - 1] = '.'; + } + tmp1[fromlen] = '\0'; + + /* + * Convert contents of 'tmp1' to local encoding. + */ + if (idn_decodename(IDN_DECODE_APP, tmp1, tmp2, MAXDLEN) != idn_success) + return (ISC_R_SUCCESS); + strcpy(tmp1, tmp2); + + /* + * Copy the converted contents in 'tmp1' back to 'buffer'. + * If we have appended trailing dot, remove it. + */ + tolen = strlen(tmp1); + if (absolute && !end_with_dot && tmp1[tolen - 1] == '.') + tolen--; + + if (isc_buffer_length(buffer) < used_org + tolen) + return (ISC_R_NOSPACE); + + isc_buffer_subtract(buffer, isc_buffer_usedlength(buffer) - used_org); + memcpy(isc_buffer_used(buffer), tmp1, tolen); + isc_buffer_add(buffer, tolen); + + return (ISC_R_SUCCESS); +} + +static idn_result_t +append_textname(char *name, const char *origin, size_t namesize) { + size_t namelen = strlen(name); + size_t originlen = strlen(origin); + + /* Already absolute? */ + if (namelen > 0 && name[namelen - 1] == '.') + return idn_success; + + /* Append dot and origin */ + + if (namelen + 1 + originlen >= namesize) + return idn_buffer_overflow; + + name[namelen++] = '.'; + (void)strcpy(name + namelen, origin); + return idn_success; +} + +static void +idn_check_result(idn_result_t r, const char *msg) { + if (r != idn_success) { + exitcode = 1; + fatal("%s: %s", msg, idn_result_tostring(r)); + } +} +#endif /* WITH_IDN */ + +#ifdef DIG_SIGCHASE +void +print_type(dns_rdatatype_t type) +{ + isc_buffer_t * b = NULL; + isc_result_t result; + isc_region_t r; + + result = isc_buffer_allocate(mctx, &b, 4000); + check_result(result, "isc_buffer_allocate"); + + result = dns_rdatatype_totext(type, b); + check_result(result, "print_type"); + + isc_buffer_usedregion(b, &r); + r.base[r.length] = '\0'; + + printf("%s", r.base); + + isc_buffer_free(&b); +} + +void +dump_database_section(dns_message_t *msg, int section) +{ + dns_name_t *msg_name=NULL; + + dns_rdataset_t *rdataset; + + do { + dns_message_currentname(msg, section, &msg_name); + + for (rdataset = ISC_LIST_HEAD(msg_name->list); rdataset != NULL; + rdataset = ISC_LIST_NEXT(rdataset, link)) { + dns_name_print(msg_name, stdout); + printf("\n"); + print_rdataset(msg_name, rdataset, mctx); + printf("end\n"); + } + msg_name = NULL; + } while (dns_message_nextname(msg, section) == ISC_R_SUCCESS); +} + +void +dump_database(void) { + dig_message_t * msg; + + for (msg = ISC_LIST_HEAD(chase_message_list); msg != NULL; + msg = ISC_LIST_NEXT(msg, link)) { + if (dns_message_firstname(msg->msg, DNS_SECTION_ANSWER) + == ISC_R_SUCCESS) + dump_database_section(msg->msg, DNS_SECTION_ANSWER); + + if (dns_message_firstname(msg->msg, DNS_SECTION_AUTHORITY) + == ISC_R_SUCCESS) + dump_database_section(msg->msg, DNS_SECTION_AUTHORITY); + + if (dns_message_firstname(msg->msg, DNS_SECTION_ADDITIONAL) + == ISC_R_SUCCESS) + dump_database_section(msg->msg, DNS_SECTION_ADDITIONAL); + } +} + + +dns_rdataset_t * +search_type(dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers) { + dns_rdataset_t *rdataset; + dns_rdata_sig_t siginfo; + dns_rdata_t sigrdata; + isc_result_t result; + + for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; + rdataset = ISC_LIST_NEXT(rdataset, link)) { + if (type == dns_rdatatype_any) { + if (rdataset->type != dns_rdatatype_rrsig) + return (rdataset); + } else if ((type == dns_rdatatype_rrsig) && + (rdataset->type == dns_rdatatype_rrsig)) { + dns_rdata_init(&sigrdata); + result = dns_rdataset_first(rdataset); + check_result(result, "empty rdataset"); + dns_rdataset_current(rdataset, &sigrdata); + result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL); + check_result(result, "sigrdata tostruct siginfo"); + + if ((siginfo.covered == covers) || + (covers == dns_rdatatype_any)) { + dns_rdata_reset(&sigrdata); + dns_rdata_freestruct(&siginfo); + return (rdataset); + } + dns_rdata_reset(&sigrdata); + dns_rdata_freestruct(&siginfo); + } else if (rdataset->type == type) + return (rdataset); + } + return (NULL); +} + +dns_rdataset_t * +chase_scanname_section(dns_message_t *msg, dns_name_t *name, + dns_rdatatype_t type, dns_rdatatype_t covers, + int section) +{ + dns_rdataset_t *rdataset; + dns_name_t *msg_name = NULL; + + do { + dns_message_currentname(msg, section, &msg_name); + if (dns_name_compare(msg_name, name) == 0) { + rdataset = search_type(msg_name, type, covers); + if (rdataset != NULL) + return (rdataset); + } + msg_name = NULL; + } while (dns_message_nextname(msg, section) == ISC_R_SUCCESS); + + return (NULL); +} + + +dns_rdataset_t * +chase_scanname(dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers) +{ + dns_rdataset_t *rdataset = NULL; + dig_message_t * msg; + + for (msg = ISC_LIST_HEAD(chase_message_list2); msg != NULL; + msg = ISC_LIST_NEXT(msg, link)) { + if (dns_message_firstname(msg->msg, DNS_SECTION_ANSWER) + == ISC_R_SUCCESS) + rdataset = chase_scanname_section(msg->msg, name, + type, covers, + DNS_SECTION_ANSWER); + if (rdataset != NULL) + return (rdataset); + if (dns_message_firstname(msg->msg, DNS_SECTION_AUTHORITY) + == ISC_R_SUCCESS) + rdataset = + chase_scanname_section(msg->msg, name, + type, covers, + DNS_SECTION_AUTHORITY); + if (rdataset != NULL) + return (rdataset); + if (dns_message_firstname(msg->msg, DNS_SECTION_ADDITIONAL) + == ISC_R_SUCCESS) + rdataset = + chase_scanname_section(msg->msg, name, type, + covers, + DNS_SECTION_ADDITIONAL); + if (rdataset != NULL) + return (rdataset); + } + + return (NULL); +} + +dns_rdataset_t * +sigchase_scanname(dns_rdatatype_t type, dns_rdatatype_t covers, + isc_boolean_t * lookedup, dns_name_t *rdata_name) +{ + dig_lookup_t *lookup; + isc_buffer_t *b = NULL; + isc_region_t r; + isc_result_t result; + dns_rdataset_t * temp; + dns_rdatatype_t querytype; + + temp = chase_scanname(rdata_name, type, covers); + if (temp != NULL) + return (temp); + + if (*lookedup == ISC_TRUE) + return (NULL); + + lookup = clone_lookup(current_lookup, ISC_TRUE); + lookup->trace_root = ISC_FALSE; + lookup->new_search = ISC_TRUE; + + result = isc_buffer_allocate(mctx, &b, BUFSIZE); + check_result(result, "isc_buffer_allocate"); + result = dns_name_totext(rdata_name, ISC_FALSE, b); + check_result(result, "dns_name_totext"); + isc_buffer_usedregion(b, &r); + r.base[r.length] = '\0'; + strcpy(lookup->textname, (char*)r.base); + isc_buffer_free(&b); + + if (type == dns_rdatatype_rrsig) + querytype = covers; + else + querytype = type; + + if (querytype == 0 || querytype == 255) { + printf("Error in the queried type: %d\n", querytype); + return (NULL); + } + + lookup->rdtype = querytype; + lookup->rdtypeset = ISC_TRUE; + lookup->qrdtype = querytype; + *lookedup = ISC_TRUE; + + ISC_LIST_APPEND(lookup_list, lookup, link); + printf("\n\nLaunch a query to find a RRset of type "); + print_type(type); + printf(" for zone: %s\n", lookup->textname); + return (NULL); +} + +void +insert_trustedkey(dst_key_t * key) +{ + if (key == NULL) + return; + if (tk_list.nb_tk >= MAX_TRUSTED_KEY) + return; + + tk_list.key[tk_list.nb_tk++] = key; + return; +} + +void +clean_trustedkey() +{ + int i = 0; + + for (i= 0; i < MAX_TRUSTED_KEY; i++) { + if (tk_list.key[i] != NULL) { + dst_key_free(&tk_list.key[i]); + tk_list.key[i] = NULL; + } else + break; + } + tk_list.nb_tk = 0; + return; +} + +char alphnum[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + +isc_result_t +removetmpkey(isc_mem_t *mctx, const char *file) +{ + char *tempnamekey = NULL; + int tempnamekeylen; + isc_result_t result; + + tempnamekeylen = strlen(file)+10; + + tempnamekey = isc_mem_allocate(mctx, tempnamekeylen); + if (tempnamekey == NULL) + return (ISC_R_NOMEMORY); + + memset(tempnamekey, 0, tempnamekeylen); + + strcat(tempnamekey, file); + strcat(tempnamekey,".key"); + isc_file_remove(tempnamekey); + + result = isc_file_remove(tempnamekey); + isc_mem_free(mctx, tempnamekey); + return (result); +} + +isc_result_t +opentmpkey(isc_mem_t *mctx, const char *file, char **tempp, FILE **fp) { + FILE *f = NULL; + isc_result_t result; + char *tempname = NULL; + char *tempnamekey = NULL; + int tempnamelen; + int tempnamekeylen; + char *x; + char *cp; + isc_uint32_t which; + + while (1) { + tempnamelen = strlen(file) + 20; + tempname = isc_mem_allocate(mctx, tempnamelen); + if (tempname == NULL) + return (ISC_R_NOMEMORY); + memset(tempname, 0, tempnamelen); + + result = isc_file_mktemplate(file, tempname, tempnamelen); + if (result != ISC_R_SUCCESS) + goto cleanup; + + cp = tempname; + while (*cp != '\0') + cp++; + if (cp == tempname) { + isc_mem_free(mctx, tempname); + return (ISC_R_FAILURE); + } + + x = cp--; + while (cp >= tempname && *cp == 'X') { + isc_random_get(&which); + *cp = alphnum[which % (sizeof(alphnum) - 1)]; + x = cp--; + } + + tempnamekeylen = tempnamelen+5; + tempnamekey = isc_mem_allocate(mctx, tempnamekeylen); + if (tempnamekey == NULL) + return (ISC_R_NOMEMORY); + + memset(tempnamekey, 0, tempnamekeylen); + strncpy(tempnamekey, tempname, tempnamelen); + strcat(tempnamekey ,".key"); + + + if (isc_file_exists(tempnamekey)) { + isc_mem_free(mctx, tempnamekey); + isc_mem_free(mctx, tempname); + continue; + } + + if ((f = fopen(tempnamekey, "w")) == NULL) { + printf("get_trusted_key(): trusted key not found %s\n", + tempnamekey); + return (ISC_R_FAILURE); + } + break; + } + isc_mem_free(mctx, tempnamekey); + *tempp = tempname; + *fp = f; + return (ISC_R_SUCCESS); + + cleanup: + isc_mem_free(mctx, tempname); + + return (result); +} + + +isc_result_t +get_trusted_key(isc_mem_t *mctx) +{ + isc_result_t result; + const char *filename = NULL; + char *filetemp = NULL; + char buf[1500]; + FILE *fp, *fptemp; + dst_key_t *key = NULL; + + result = isc_file_exists(trustedkey); + if (result != ISC_TRUE) { + result = isc_file_exists("/etc/trusted-key.key"); + if (result != ISC_TRUE) { + result = isc_file_exists("./trusted-key.key"); + if (result != ISC_TRUE) + return (ISC_R_FAILURE); + else + filename = "./trusted-key.key"; + } else + filename = "/etc/trusted-key.key"; + } else + filename = trustedkey; + + if (filename == NULL) { + printf("No trusted key\n"); + return (ISC_R_FAILURE); + } + + if ((fp = fopen(filename, "r")) == NULL) { + printf("get_trusted_key(): trusted key not found %s\n", + filename); + return (ISC_R_FAILURE); + } + while (fgets(buf, sizeof(buf), fp) != NULL) { + result = opentmpkey(mctx,"tmp_file", &filetemp, &fptemp); + if (result != ISC_R_SUCCESS) { + fclose(fp); + return (ISC_R_FAILURE); + } + if (fputs(buf, fptemp) < 0) { + fclose(fp); + fclose(fptemp); + return (ISC_R_FAILURE); + } + fclose(fptemp); + result = dst_key_fromnamedfile(filetemp, DST_TYPE_PUBLIC, + mctx, &key); + removetmpkey(mctx, filetemp); + isc_mem_free(mctx, filetemp); + if (result != ISC_R_SUCCESS) { + fclose(fp); + return (ISC_R_FAILURE); + } + insert_trustedkey(key); +#if 0 + dst_key_tofile(key, DST_TYPE_PUBLIC,"/tmp"); +#endif + key = NULL; + } + return (ISC_R_SUCCESS); +} + + +static void +nameFromString(const char *str, dns_name_t *p_ret) { + size_t len = strlen(str); + isc_result_t result; + isc_buffer_t buffer; + dns_fixedname_t fixedname; + + REQUIRE(p_ret != NULL); + REQUIRE(str != NULL); + + isc_buffer_init(&buffer, str, len); + isc_buffer_add(&buffer, len); + + dns_fixedname_init(&fixedname); + result = dns_name_fromtext(dns_fixedname_name(&fixedname), &buffer, + dns_rootname, ISC_TRUE, NULL); + check_result(result, "nameFromString"); + + if (dns_name_dynamic(p_ret)) + free_name(p_ret, mctx); + + result = dns_name_dup(dns_fixedname_name(&fixedname), mctx, p_ret); + check_result(result, "nameFromString"); +} + + +#if DIG_SIGCHASE_TD +isc_result_t +prepare_lookup(dns_name_t *name) +{ + isc_result_t result; + dig_lookup_t *lookup = NULL; + dig_server_t *s; + void *ptr; + + lookup = clone_lookup(current_lookup, ISC_TRUE); + lookup->trace_root = ISC_FALSE; + lookup->new_search = ISC_TRUE; + lookup->trace_root_sigchase = ISC_FALSE; + + strncpy(lookup->textname, lookup->textnamesigchase, MXNAME); + + lookup->rdtype = lookup->rdtype_sigchase; + lookup->rdtypeset = ISC_TRUE; + lookup->qrdtype = lookup->qrdtype_sigchase; + + s = ISC_LIST_HEAD(lookup->my_server_list); + while (s != NULL) { + debug("freeing server %p belonging to %p", + s, lookup); + ptr = s; + s = ISC_LIST_NEXT(s, link); + ISC_LIST_DEQUEUE(lookup->my_server_list, + (dig_server_t *)ptr, link); + isc_mem_free(mctx, ptr); + } + + + for (result = dns_rdataset_first(chase_nsrdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(chase_nsrdataset)) { + char namestr[DNS_NAME_FORMATSIZE]; + dns_rdata_ns_t ns; + dns_rdata_t rdata = DNS_RDATA_INIT; + dig_server_t * srv = NULL; +#define __FOLLOW_GLUE__ +#ifdef __FOLLOW_GLUE__ + isc_buffer_t *b = NULL; + isc_result_t result; + isc_region_t r; + dns_rdataset_t *rdataset = NULL; + isc_boolean_t true = ISC_TRUE; +#endif + + memset(namestr, 0, DNS_NAME_FORMATSIZE); + + dns_rdataset_current(chase_nsrdataset, &rdata); + + (void)dns_rdata_tostruct(&rdata, &ns, NULL); + + + +#ifdef __FOLLOW_GLUE__ + + result = advanced_rrsearch(&rdataset, &ns.name, + dns_rdatatype_aaaa, + dns_rdatatype_any, &true); + if (result == ISC_R_SUCCESS) { + for (result = dns_rdataset_first(rdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(rdataset)) { + dns_rdata_t aaaa = DNS_RDATA_INIT; + dns_rdataset_current(rdataset, &aaaa); + + result = isc_buffer_allocate(mctx, &b, 80); + check_result(result, "isc_buffer_allocate"); + + dns_rdata_totext(&aaaa, &ns.name, b); + isc_buffer_usedregion(b, &r); + r.base[r.length] = '\0'; + strncpy(namestr, (char*)r.base, + DNS_NAME_FORMATSIZE); + isc_buffer_free(&b); + dns_rdata_reset(&aaaa); + + + srv = make_server(namestr, namestr); + + ISC_LIST_APPEND(lookup->my_server_list, + srv, link); + } + } + + rdataset = NULL; + result = advanced_rrsearch(&rdataset, &ns.name, dns_rdatatype_a, + dns_rdatatype_any, &true); + if (result == ISC_R_SUCCESS) { + for (result = dns_rdataset_first(rdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(rdataset)) { + dns_rdata_t a = DNS_RDATA_INIT; + dns_rdataset_current(rdataset, &a); + + result = isc_buffer_allocate(mctx, &b, 80); + check_result(result, "isc_buffer_allocate"); + + dns_rdata_totext(&a, &ns.name, b); + isc_buffer_usedregion(b, &r); + r.base[r.length] = '\0'; + strncpy(namestr, (char*)r.base, + DNS_NAME_FORMATSIZE); + isc_buffer_free(&b); + dns_rdata_reset(&a); + printf("ns name: %s\n", namestr); + + + srv = make_server(namestr, namestr); + + ISC_LIST_APPEND(lookup->my_server_list, + srv, link); + } + } +#else + + dns_name_format(&ns.name, namestr, sizeof(namestr)); + printf("ns name: "); + dns_name_print(&ns.name, stdout); + printf("\n"); + srv = make_server(namestr, namestr); + + ISC_LIST_APPEND(lookup->my_server_list, srv, link); + +#endif + dns_rdata_freestruct(&ns); + dns_rdata_reset(&rdata); + + } + + ISC_LIST_APPEND(lookup_list, lookup, link); + printf("\nLaunch a query to find a RRset of type "); + print_type(lookup->rdtype); + printf(" for zone: %s", lookup->textname); + printf(" with nameservers:"); + printf("\n"); + print_rdataset(name, chase_nsrdataset, mctx); + return (ISC_R_SUCCESS); +} + + +isc_result_t +child_of_zone(dns_name_t * name, dns_name_t * zone_name, + dns_name_t * child_name) +{ + dns_namereln_t name_reln; + int orderp; + unsigned int nlabelsp; + + name_reln = dns_name_fullcompare(name, zone_name, &orderp, &nlabelsp); + if (name_reln != dns_namereln_subdomain || + dns_name_countlabels(name) <= dns_name_countlabels(zone_name) + 1) { + printf("\n;; ERROR : "); + dns_name_print(name, stdout); + printf(" is not a subdomain of: "); + dns_name_print(zone_name, stdout); + printf(" FAILED\n\n"); + return (ISC_R_FAILURE); + } + + dns_name_getlabelsequence(name, + dns_name_countlabels(name) - + dns_name_countlabels(zone_name) -1, + dns_name_countlabels(zone_name) +1, + child_name); + return (ISC_R_SUCCESS); +} + +isc_result_t +grandfather_pb_test(dns_name_t *zone_name, dns_rdataset_t *sigrdataset) +{ + isc_result_t result; + dns_rdata_t sigrdata; + dns_rdata_sig_t siginfo; + + result = dns_rdataset_first(sigrdataset); + check_result(result, "empty RRSIG dataset"); + dns_rdata_init(&sigrdata); + + do { + dns_rdataset_current(sigrdataset, &sigrdata); + + result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL); + check_result(result, "sigrdata tostruct siginfo"); + + if (dns_name_compare(&siginfo.signer, zone_name) == 0) { + dns_rdata_freestruct(&siginfo); + dns_rdata_reset(&sigrdata); + return (ISC_R_SUCCESS); + } + + dns_rdata_freestruct(&siginfo); + + } while (dns_rdataset_next(chase_sigkeyrdataset) == ISC_R_SUCCESS); + + dns_rdata_reset(&sigrdata); + + return (ISC_R_FAILURE); +} + + +isc_result_t +initialization(dns_name_t *name) +{ + isc_result_t result; + isc_boolean_t true = ISC_TRUE; + + chase_nsrdataset = NULL; + result = advanced_rrsearch(&chase_nsrdataset, name, dns_rdatatype_ns, + dns_rdatatype_any, &true); + if (result != ISC_R_SUCCESS) { + printf("\n;; NS RRset is missing to continue validation:" + " FAILED\n\n"); + return (ISC_R_FAILURE); + } + INSIST(chase_nsrdataset != NULL); + prepare_lookup(name); + + dup_name(name, &chase_current_name, mctx); + + return (ISC_R_SUCCESS); +} +#endif + +void +print_rdataset(dns_name_t *name, dns_rdataset_t *rdataset, isc_mem_t *mctx) +{ + isc_buffer_t *b = NULL; + isc_result_t result; + isc_region_t r; + + result = isc_buffer_allocate(mctx, &b, 9000); + check_result(result, "isc_buffer_allocate"); + + printrdataset(name, rdataset, b); + + isc_buffer_usedregion(b, &r); + r.base[r.length] = '\0'; + + + printf("%s\n", r.base); + + isc_buffer_free(&b); +} + + +void +dup_name(dns_name_t *source, dns_name_t *target, isc_mem_t *mctx) { + isc_result_t result; + + if (dns_name_dynamic(target)) + free_name(target, mctx); + result = dns_name_dup(source, mctx, target); + check_result(result, "dns_name_dup"); +} + +void +free_name(dns_name_t *name, isc_mem_t *mctx) { + dns_name_free(name, mctx); + dns_name_init(name, NULL); +} + +/* + * + * take a DNSKEY RRset and the RRSIG RRset corresponding in parameter + * return ISC_R_SUCCESS if the DNSKEY RRset contains a trusted_key + * and the RRset is valid + * return ISC_R_NOTFOUND if not contains trusted key + or if the RRset isn't valid + * return ISC_R_FAILURE if problem + * + */ +isc_result_t +contains_trusted_key(dns_name_t *name, dns_rdataset_t *rdataset, + dns_rdataset_t *sigrdataset, + isc_mem_t *mctx) +{ + isc_result_t result; + dns_rdata_t rdata; + dst_key_t *trustedKey = NULL; + dst_key_t *dnsseckey = NULL; + int i; + + if (name == NULL || rdataset == NULL) + return (ISC_R_FAILURE); + + result = dns_rdataset_first(rdataset); + check_result(result, "empty rdataset"); + dns_rdata_init(&rdata); + + do { + dns_rdataset_current(rdataset, &rdata); + INSIST(rdata.type == dns_rdatatype_dnskey); + + result = dns_dnssec_keyfromrdata(name, &rdata, + mctx, &dnsseckey); + check_result(result, "dns_dnssec_keyfromrdata"); + + + for (i = 0; i < tk_list.nb_tk; i++) { + if (dst_key_compare(tk_list.key[i], dnsseckey) + == ISC_TRUE) { + dns_rdata_reset(&rdata); + + printf(";; Ok, find a Trusted Key in the " + "DNSKEY RRset: %d\n", + dst_key_id(dnsseckey)); + if (sigchase_verify_sig_key(name, rdataset, + dnsseckey, + sigrdataset, + mctx) + == ISC_R_SUCCESS) { + dst_key_free(&dnsseckey); + dnsseckey = NULL; + return (ISC_R_SUCCESS); + } + } + } + + dns_rdata_reset(&rdata); + if (dnsseckey != NULL) + dst_key_free(&dnsseckey); + } while (dns_rdataset_next(rdataset) == ISC_R_SUCCESS); + + if (trustedKey != NULL) + dst_key_free(&trustedKey); + trustedKey = NULL; + + return (ISC_R_NOTFOUND); +} + +isc_result_t +sigchase_verify_sig(dns_name_t *name, dns_rdataset_t *rdataset, + dns_rdataset_t *keyrdataset, + dns_rdataset_t *sigrdataset, + isc_mem_t *mctx) +{ + isc_result_t result; + dns_rdata_t keyrdata; + dst_key_t *dnsseckey = NULL; + + result = dns_rdataset_first(keyrdataset); + check_result(result, "empty DNSKEY dataset"); + dns_rdata_init(&keyrdata); + + do { + dns_rdataset_current(keyrdataset, &keyrdata); + INSIST(keyrdata.type == dns_rdatatype_dnskey); + + result = dns_dnssec_keyfromrdata(name, &keyrdata, + mctx, &dnsseckey); + check_result(result, "dns_dnssec_keyfromrdata"); + + result = sigchase_verify_sig_key(name, rdataset, dnsseckey, + sigrdataset, mctx); + if (result == ISC_R_SUCCESS) { + dns_rdata_reset(&keyrdata); + dst_key_free(&dnsseckey); + return (ISC_R_SUCCESS); + } + dst_key_free(&dnsseckey); + } while (dns_rdataset_next(chase_keyrdataset) == ISC_R_SUCCESS); + + dns_rdata_reset(&keyrdata); + + return (ISC_R_NOTFOUND); +} + +isc_result_t +sigchase_verify_sig_key(dns_name_t *name, dns_rdataset_t *rdataset, + dst_key_t *dnsseckey, dns_rdataset_t *sigrdataset, + isc_mem_t *mctx) +{ + isc_result_t result; + dns_rdata_t sigrdata; + dns_rdata_sig_t siginfo; + + result = dns_rdataset_first(sigrdataset); + check_result(result, "empty RRSIG dataset"); + dns_rdata_init(&sigrdata); + + do { + dns_rdataset_current(sigrdataset, &sigrdata); + + result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL); + check_result(result, "sigrdata tostruct siginfo"); + + /* + * Test if the id of the DNSKEY is + * the id of the DNSKEY signer's + */ + if (siginfo.keyid == dst_key_id(dnsseckey)) { + + result = dns_rdataset_first(rdataset); + check_result(result, "empty DS dataset"); + + result = dns_dnssec_verify(name, rdataset, dnsseckey, + ISC_FALSE, mctx, &sigrdata); + + printf(";; VERIFYING "); + print_type(rdataset->type); + printf(" RRset for "); + dns_name_print(name, stdout); + printf(" with DNSKEY:%d: %s\n", dst_key_id(dnsseckey), + isc_result_totext(result)); + + if (result == ISC_R_SUCCESS) { + dns_rdata_reset(&sigrdata); + return (result); + } + } + dns_rdata_freestruct(&siginfo); + + } while (dns_rdataset_next(chase_sigkeyrdataset) == ISC_R_SUCCESS); + + dns_rdata_reset(&sigrdata); + + return (ISC_R_NOTFOUND); +} + + +isc_result_t +sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset, + dns_rdataset_t *dsrdataset, isc_mem_t *mctx) +{ + isc_result_t result; + dns_rdata_t keyrdata; + dns_rdata_t newdsrdata; + dns_rdata_t dsrdata; + dns_rdata_ds_t dsinfo; + dst_key_t *dnsseckey = NULL; + unsigned char dsbuf[DNS_DS_BUFFERSIZE]; + + result = dns_rdataset_first(dsrdataset); + check_result(result, "empty DSset dataset"); + dns_rdata_init(&dsrdata); + do { + dns_rdataset_current(dsrdataset, &dsrdata); + + result = dns_rdata_tostruct(&dsrdata, &dsinfo, NULL); + check_result(result, "dns_rdata_tostruct for DS"); + + result = dns_rdataset_first(keyrdataset); + check_result(result, "empty KEY dataset"); + dns_rdata_init(&keyrdata); + + do { + dns_rdataset_current(keyrdataset, &keyrdata); + INSIST(keyrdata.type == dns_rdatatype_dnskey); + + result = dns_dnssec_keyfromrdata(name, &keyrdata, + mctx, &dnsseckey); + check_result(result, "dns_dnssec_keyfromrdata"); + + /* + * Test if the id of the DNSKEY is the + * id of DNSKEY referenced by the DS + */ + if (dsinfo.key_tag == dst_key_id(dnsseckey)) { + dns_rdata_init(&newdsrdata); + + result = dns_ds_buildrdata(name, &keyrdata, + dsinfo.digest_type, + dsbuf, &newdsrdata); + dns_rdata_freestruct(&dsinfo); + + if (result != ISC_R_SUCCESS) { + dns_rdata_reset(&keyrdata); + dns_rdata_reset(&newdsrdata); + dns_rdata_reset(&dsrdata); + dst_key_free(&dnsseckey); + dns_rdata_freestruct(&dsinfo); + printf("Oops: impossible to build" + " new DS rdata\n"); + return (result); + } + + + if (dns_rdata_compare(&dsrdata, + &newdsrdata) == 0) { + printf(";; OK a DS valids a DNSKEY" + " in the RRset\n"); + printf(";; Now verify that this" + " DNSKEY validates the " + "DNSKEY RRset\n"); + + result = sigchase_verify_sig_key(name, + keyrdataset, + dnsseckey, + chase_sigkeyrdataset, + mctx); + if (result == ISC_R_SUCCESS) { + dns_rdata_reset(&keyrdata); + dns_rdata_reset(&newdsrdata); + dns_rdata_reset(&dsrdata); + dst_key_free(&dnsseckey); + + return (result); + } + } else { + printf(";; This DS is NOT the DS for" + " the chasing KEY: FAILED\n"); + } + + dns_rdata_reset(&newdsrdata); + } + dst_key_free(&dnsseckey); + dnsseckey = NULL; + } while (dns_rdataset_next(chase_keyrdataset) == ISC_R_SUCCESS); + dns_rdata_reset(&keyrdata); + + } while (dns_rdataset_next(chase_dsrdataset) == ISC_R_SUCCESS); +#if 0 + dns_rdata_reset(&dsrdata); WARNING +#endif + + return (ISC_R_NOTFOUND); +} + +/* + * + * take a pointer on a rdataset in parameter and try to resolv it. + * the searched rrset is a rrset on 'name' with type 'type' + * (and if the type is a rrsig the signature cover 'covers'). + * the lookedup is to known if you have already done the query on the net. + * ISC_R_SUCCESS: if we found the rrset + * ISC_R_NOTFOUND: we do not found the rrset in cache + * and we do a query on the net + * ISC_R_FAILURE: rrset not found + */ +isc_result_t +advanced_rrsearch(dns_rdataset_t **rdataset, dns_name_t *name, + dns_rdatatype_t type, dns_rdatatype_t covers, + isc_boolean_t *lookedup) +{ + isc_boolean_t tmplookedup; + + INSIST(rdataset != NULL); + + if (*rdataset != NULL) + return (ISC_R_SUCCESS); + + tmplookedup = *lookedup; + if ((*rdataset = sigchase_scanname(type, covers, + lookedup, name)) == NULL) { + if (tmplookedup) + return (ISC_R_FAILURE); + return (ISC_R_NOTFOUND); + } + *lookedup = ISC_FALSE; + return (ISC_R_SUCCESS); +} + + + +#if DIG_SIGCHASE_TD +void +sigchase_td(dns_message_t *msg) +{ + isc_result_t result; + dns_name_t *name = NULL; + isc_boolean_t have_answer = ISC_FALSE; + isc_boolean_t true = ISC_TRUE; + + if ((result = dns_message_firstname(msg, DNS_SECTION_ANSWER)) + == ISC_R_SUCCESS) { + dns_message_currentname(msg, DNS_SECTION_ANSWER, &name); + if (current_lookup->trace_root_sigchase) { + initialization(name); + return; + } + have_answer = true; + } else { + if (!current_lookup->trace_root_sigchase) { + result = dns_message_firstname(msg, + DNS_SECTION_AUTHORITY); + if (result == ISC_R_SUCCESS) + dns_message_currentname(msg, + DNS_SECTION_AUTHORITY, + &name); + chase_nsrdataset + = chase_scanname_section(msg, name, + dns_rdatatype_ns, + dns_rdatatype_any, + DNS_SECTION_AUTHORITY); + dup_name(name, &chase_authority_name, mctx); + if (chase_nsrdataset != NULL) { + have_delegation_ns = ISC_TRUE; + printf("no response but there is a delegation" + " in authority section:"); + dns_name_print(name, stdout); + printf("\n"); + } else { + printf("no response and no delegation in " + "authority section but a reference" + " to: "); + dns_name_print(name, stdout); + printf("\n"); + error_message = msg; + } + } else { + printf(";; NO ANSWERS: %s\n", + isc_result_totext(result)); + free_name(&chase_name, mctx); + clean_trustedkey(); + return; + } + } + + + if (have_answer) { + chase_rdataset + = chase_scanname_section(msg, &chase_name, + current_lookup + ->rdtype_sigchase, + dns_rdatatype_any, + DNS_SECTION_ANSWER); + if (chase_rdataset != NULL) + have_response = ISC_TRUE; + } + + result = advanced_rrsearch(&chase_keyrdataset, + &chase_current_name, + dns_rdatatype_dnskey, + dns_rdatatype_any, + &chase_keylookedup); + if (result == ISC_R_FAILURE) { + printf("\n;; DNSKEY is missing to continue validation:" + " FAILED\n\n"); + goto cleanandgo; + } + if (result == ISC_R_NOTFOUND) + return; + INSIST(chase_keyrdataset != NULL); + printf("\n;; DNSKEYset:\n"); + print_rdataset(&chase_current_name , chase_keyrdataset, mctx); + + + result = advanced_rrsearch(&chase_sigkeyrdataset, + &chase_current_name, + dns_rdatatype_rrsig, + dns_rdatatype_dnskey, + &chase_sigkeylookedup); + if (result == ISC_R_FAILURE) { + printf("\n;; RRSIG of DNSKEY is missing to continue validation:" + " FAILED\n\n"); + goto cleanandgo; + } + if (result == ISC_R_NOTFOUND) + return; + INSIST(chase_sigkeyrdataset != NULL); + printf("\n;; RRSIG of the DNSKEYset:\n"); + print_rdataset(&chase_current_name , chase_sigkeyrdataset, mctx); + + + if (!chase_dslookedup && !chase_nslookedup) { + if (!delegation_follow) { + result = contains_trusted_key(&chase_current_name, + chase_keyrdataset, + chase_sigkeyrdataset, + mctx); + } else { + INSIST(chase_dsrdataset != NULL); + INSIST(chase_sigdsrdataset != NULL); + result = sigchase_verify_ds(&chase_current_name, + chase_keyrdataset, + chase_dsrdataset, + mctx); + } + + if (result != ISC_R_SUCCESS) { + printf("\n;; chain of trust can't be validated:" + " FAILED\n\n"); + goto cleanandgo; + } else { + chase_dsrdataset = NULL; + chase_sigdsrdataset = NULL; + } + } + + if (have_response || (!have_delegation_ns && !have_response)) { + /* test if it's a grand father case */ + + if (have_response) { + result = advanced_rrsearch(&chase_sigrdataset, + &chase_name, + dns_rdatatype_rrsig, + current_lookup + ->rdtype_sigchase, + &true); + if (result == ISC_R_FAILURE) { + printf("\n;; RRset is missing to continue" + " validation SHOULD NOT APPEND:" + " FAILED\n\n"); + goto cleanandgo; + } + + } else { + result = advanced_rrsearch(&chase_sigrdataset, + &chase_authority_name, + dns_rdatatype_rrsig, + dns_rdatatype_any, + &true); + if (result == ISC_R_FAILURE) { + printf("\n;; RRSIG is missing to continue" + " validation SHOULD NOT APPEND:" + " FAILED\n\n"); + goto cleanandgo; + } + } + result = grandfather_pb_test(&chase_current_name, + chase_sigrdataset); + if (result != ISC_R_SUCCESS) { + dns_name_t tmp_name; + + printf("\n;; We are in a Grand Father Problem:" + " See 2.2.1 in RFC 3568\n"); + chase_rdataset = NULL; + chase_sigrdataset = NULL; + have_response = ISC_FALSE; + have_delegation_ns = ISC_FALSE; + + dns_name_init(&tmp_name, NULL); + result = child_of_zone(&chase_name, &chase_current_name, + &tmp_name); + if (dns_name_dynamic(&chase_authority_name)) + free_name(&chase_authority_name, mctx); + dup_name(&tmp_name, &chase_authority_name, mctx); + printf(";; and we try to continue chain of trust" + " validation of the zone: "); + dns_name_print(&chase_authority_name, stdout); + printf("\n"); + have_delegation_ns = ISC_TRUE; + } else { + if (have_response) + goto finalstep; + else + chase_sigrdataset = NULL; + } + } + + if (have_delegation_ns) { + chase_nsrdataset = NULL; + result = advanced_rrsearch(&chase_nsrdataset, + &chase_authority_name, + dns_rdatatype_ns, + dns_rdatatype_any, + &chase_nslookedup); + if (result == ISC_R_FAILURE) { + printf("\n;;NSset is missing to continue validation:" + " FAILED\n\n"); + goto cleanandgo; + } + if (result == ISC_R_NOTFOUND) { + return; + } + INSIST(chase_nsrdataset != NULL); + + result = advanced_rrsearch(&chase_dsrdataset, + &chase_authority_name, + dns_rdatatype_ds, + dns_rdatatype_any, + &chase_dslookedup); + if (result == ISC_R_FAILURE) { + printf("\n;; DSset is missing to continue validation:" + " FAILED\n\n"); + goto cleanandgo; + } + if (result == ISC_R_NOTFOUND) + return; + INSIST(chase_dsrdataset != NULL); + printf("\n;; DSset:\n"); + print_rdataset(&chase_authority_name , chase_dsrdataset, mctx); + + result = advanced_rrsearch(&chase_sigdsrdataset, + &chase_authority_name, + dns_rdatatype_rrsig, + dns_rdatatype_ds, + &true); + if (result != ISC_R_SUCCESS) { + printf("\n;; DSset is missing to continue validation:" + " FAILED\n\n"); + goto cleanandgo; + } + printf("\n;; RRSIGset of DSset\n"); + print_rdataset(&chase_authority_name, + chase_sigdsrdataset, mctx); + INSIST(chase_sigdsrdataset != NULL); + + result = sigchase_verify_sig(&chase_authority_name, + chase_dsrdataset, + chase_keyrdataset, + chase_sigdsrdataset, mctx); + if (result != ISC_R_SUCCESS) { + printf("\n;; Impossible to verify the DSset:" + " FAILED\n\n"); + goto cleanandgo; + } + chase_keyrdataset = NULL; + chase_sigkeyrdataset = NULL; + + + prepare_lookup(&chase_authority_name); + + have_response = ISC_FALSE; + have_delegation_ns = ISC_FALSE; + delegation_follow = ISC_TRUE; + error_message = NULL; + dup_name(&chase_authority_name, &chase_current_name, mctx); + free_name(&chase_authority_name, mctx); + return; + } + + + if (error_message != NULL) { + dns_rdataset_t *rdataset; + dns_rdataset_t *sigrdataset; + dns_name_t rdata_name; + isc_result_t ret = ISC_R_FAILURE; + + dns_name_init(&rdata_name, NULL); + result = prove_nx(error_message, &chase_name, + current_lookup->rdclass_sigchase, + current_lookup->rdtype_sigchase, &rdata_name, + &rdataset, &sigrdataset); + if (rdataset == NULL || sigrdataset == NULL || + dns_name_countlabels(&rdata_name) == 0) { + printf("\n;; Impossible to verify the non-existence," + " the NSEC RRset can't be validated:" + " FAILED\n\n"); + goto cleanandgo; + } + ret = sigchase_verify_sig(&rdata_name, rdataset, + chase_keyrdataset, + sigrdataset, mctx); + if (ret != ISC_R_SUCCESS) { + free_name(&rdata_name, mctx); + printf("\n;; Impossible to verify the NSEC RR to prove" + " the non-existence : FAILED\n\n"); + goto cleanandgo; + } + free_name(&rdata_name, mctx); + if (result != ISC_R_SUCCESS) { + printf("\n;; Impossible to verify the non-existence:" + " FAILED\n\n"); + goto cleanandgo; + } else { + printf("\n;; OK the query doesn't have response but" + " we have validate this fact : SUCCESS\n\n"); + goto cleanandgo; + } + } + + cleanandgo: + printf(";; cleanandgo \n"); + if (dns_name_dynamic(&chase_current_name)) + free_name(&chase_current_name, mctx); + if (dns_name_dynamic(&chase_authority_name)) + free_name(&chase_authority_name, mctx); + clean_trustedkey(); + return; + + finalstep : + result = advanced_rrsearch(&chase_rdataset, &chase_name, + current_lookup->rdtype_sigchase, + dns_rdatatype_any , + &true); + if (result == ISC_R_FAILURE) { + printf("\n;; RRsig of RRset is missing to continue validation" + " SHOULD NOT APPEND: FAILED\n\n"); + goto cleanandgo; + } + result = sigchase_verify_sig(&chase_name, chase_rdataset, + chase_keyrdataset, + chase_sigrdataset, mctx); + if (result != ISC_R_SUCCESS) { + printf("\n;; Impossible to verify the RRset : FAILED\n\n"); + /* + printf("RRset:\n"); + print_rdataset(&chase_name , chase_rdataset, mctx); + printf("DNSKEYset:\n"); + print_rdataset(&chase_name , chase_keyrdataset, mctx); + printf("RRSIG of RRset:\n"); + print_rdataset(&chase_name , chase_sigrdataset, mctx); + printf("\n"); + */ + goto cleanandgo; + } else { + printf("\n;; The Answer:\n"); + print_rdataset(&chase_name , chase_rdataset, mctx); + + printf("\n;; FINISH : we have validate the DNSSEC chain" + " of trust: SUCCESS\n\n"); + goto cleanandgo; + } +} + +#endif + + +#if DIG_SIGCHASE_BU + +isc_result_t +getneededrr(dns_message_t *msg) +{ + isc_result_t result; + dns_name_t *name = NULL; + dns_rdata_t sigrdata; + dns_rdata_sig_t siginfo; + isc_boolean_t true = ISC_TRUE; + + if ((result = dns_message_firstname(msg, DNS_SECTION_ANSWER)) + != ISC_R_SUCCESS) { + printf(";; NO ANSWERS: %s\n", isc_result_totext(result)); + + if (chase_name.ndata == NULL) + return (ISC_R_ADDRNOTAVAIL); + } else { + dns_message_currentname(msg, DNS_SECTION_ANSWER, &name); + } + + /* What do we chase? */ + if (chase_rdataset == NULL) { + result = advanced_rrsearch(&chase_rdataset, name, + dns_rdatatype_any, + dns_rdatatype_any, &true); + if (result != ISC_R_SUCCESS) { + printf("\n;; No Answers: Validation FAILED\n\n"); + return (ISC_R_NOTFOUND); + } + dup_name(name, &chase_name, mctx); + printf(";; RRset to chase:\n"); + print_rdataset(&chase_name, chase_rdataset, mctx); + } + INSIST(chase_rdataset != NULL); + + + if (chase_sigrdataset == NULL) { + result = advanced_rrsearch(&chase_sigrdataset, name, + dns_rdatatype_rrsig, + chase_rdataset->type, + &chase_siglookedup); + if (result == ISC_R_FAILURE) { + printf("\n;; RRSIG is missing for continue validation:" + " FAILED\n\n"); + if (dns_name_dynamic(&chase_name)) + free_name(&chase_name, mctx); + return (ISC_R_NOTFOUND); + } + if (result == ISC_R_NOTFOUND) { + return (ISC_R_NOTFOUND); + } + printf("\n;; RRSIG of the RRset to chase:\n"); + print_rdataset(&chase_name, chase_sigrdataset, mctx); + } + INSIST(chase_sigrdataset != NULL); + + + /* first find the DNSKEY name */ + result = dns_rdataset_first(chase_sigrdataset); + check_result(result, "empty RRSIG dataset"); + dns_rdata_init(&sigrdata); + dns_rdataset_current(chase_sigrdataset, &sigrdata); + result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL); + check_result(result, "sigrdata tostruct siginfo"); + dup_name(&siginfo.signer, &chase_signame, mctx); + dns_rdata_freestruct(&siginfo); + dns_rdata_reset(&sigrdata); + + /* Do we have a key? */ + if (chase_keyrdataset == NULL) { + result = advanced_rrsearch(&chase_keyrdataset, + &chase_signame, + dns_rdatatype_dnskey, + dns_rdatatype_any, + &chase_keylookedup); + if (result == ISC_R_FAILURE) { + printf("\n;; DNSKEY is missing to continue validation:" + " FAILED\n\n"); + free_name(&chase_signame, mctx); + if (dns_name_dynamic(&chase_name)) + free_name(&chase_name, mctx); + return (ISC_R_NOTFOUND); + } + if (result == ISC_R_NOTFOUND) { + free_name(&chase_signame, mctx); + return (ISC_R_NOTFOUND); + } + printf("\n;; DNSKEYset that signs the RRset to chase:\n"); + print_rdataset(&chase_signame, chase_keyrdataset, mctx); + } + INSIST(chase_keyrdataset != NULL); + + if (chase_sigkeyrdataset == NULL) { + result = advanced_rrsearch(&chase_sigkeyrdataset, + &chase_signame, + dns_rdatatype_rrsig, + dns_rdatatype_dnskey, + &chase_sigkeylookedup); + if (result == ISC_R_FAILURE) { + printf("\n;; RRSIG for DNSKEY is missing to continue" + " validation : FAILED\n\n"); + free_name(&chase_signame, mctx); + if (dns_name_dynamic(&chase_name)) + free_name(&chase_name, mctx); + return (ISC_R_NOTFOUND); + } + if (result == ISC_R_NOTFOUND) { + free_name(&chase_signame, mctx); + return (ISC_R_NOTFOUND); + } + printf("\n;; RRSIG of the DNSKEYset that signs the " + "RRset to chase:\n"); + print_rdataset(&chase_signame, chase_sigkeyrdataset, mctx); + } + INSIST(chase_sigkeyrdataset != NULL); + + + if (chase_dsrdataset == NULL) { + result = advanced_rrsearch(&chase_dsrdataset, &chase_signame, + dns_rdatatype_ds, + dns_rdatatype_any, + &chase_dslookedup); + if (result == ISC_R_FAILURE) { + printf("\n;; WARNING There is no DS for the zone: "); + dns_name_print(&chase_signame, stdout); + printf("\n"); + } + if (result == ISC_R_NOTFOUND) { + free_name(&chase_signame, mctx); + return (ISC_R_NOTFOUND); + } + if (chase_dsrdataset != NULL) { + printf("\n;; DSset of the DNSKEYset\n"); + print_rdataset(&chase_signame, chase_dsrdataset, mctx); + } + } + + if (chase_dsrdataset != NULL) { + /* + * if there is no RRSIG of DS, + * we don't want to search on the network + */ + result = advanced_rrsearch(&chase_sigdsrdataset, + &chase_signame, + dns_rdatatype_rrsig, + dns_rdatatype_ds, &true); + if (result == ISC_R_FAILURE) { + printf(";; WARNING : NO RRSIG DS : RRSIG DS" + " should come with DS\n"); + /* + * We continue even the DS couldn't be validated, + * because the DNSKEY could be a Trusted Key. + */ + chase_dsrdataset = NULL; + } else { + printf("\n;; RRSIG of the DSset of the DNSKEYset\n"); + print_rdataset(&chase_signame, chase_sigdsrdataset, + mctx); + } + } + return (1); +} + + + +void +sigchase_bu(dns_message_t *msg) +{ + isc_result_t result; + int ret; + + if (tk_list.nb_tk == 0) { + result = get_trusted_key(mctx); + if (result != ISC_R_SUCCESS) { + printf("No trusted keys present\n"); + return; + } + } + + + ret = getneededrr(msg); + if (ret == ISC_R_NOTFOUND) + return; + + if (ret == ISC_R_ADDRNOTAVAIL) { + /* We have no response */ + dns_rdataset_t *rdataset; + dns_rdataset_t *sigrdataset; + dns_name_t rdata_name; + dns_name_t query_name; + + + dns_name_init(&query_name, NULL); + dns_name_init(&rdata_name, NULL); + nameFromString(current_lookup->textname, &query_name); + + result = prove_nx(msg, &query_name, current_lookup->rdclass, + current_lookup->rdtype, &rdata_name, + &rdataset, &sigrdataset); + free_name(&query_name, mctx); + if (rdataset == NULL || sigrdataset == NULL || + dns_name_countlabels(&rdata_name) == 0) { + printf("\n;; Impossible to verify the Non-existence," + " the NSEC RRset can't be validated: " + "FAILED\n\n"); + clean_trustedkey(); + return; + } + + if (result != ISC_R_SUCCESS) { + printf("\n No Answers and impossible to prove the" + " unsecurity : Validation FAILED\n\n"); + clean_trustedkey(); + return; + } + printf(";; An NSEC prove the non-existence of a answers," + " Now we want validate this NSEC\n"); + + dup_name(&rdata_name, &chase_name, mctx); + free_name(&rdata_name, mctx); + chase_rdataset = rdataset; + chase_sigrdataset = sigrdataset; + chase_keyrdataset = NULL; + chase_sigkeyrdataset = NULL; + chase_dsrdataset = NULL; + chase_sigdsrdataset = NULL; + chase_siglookedup = ISC_FALSE; + chase_keylookedup = ISC_FALSE; + chase_dslookedup = ISC_FALSE; + chase_sigdslookedup = ISC_FALSE; + sigchase(msg); + clean_trustedkey(); + return; + } + + + printf("\n\n\n;; WE HAVE MATERIAL, WE NOW DO VALIDATION\n"); + + result = sigchase_verify_sig(&chase_name, chase_rdataset, + chase_keyrdataset, + chase_sigrdataset, mctx); + if (result != ISC_R_SUCCESS) { + free_name(&chase_name, mctx); + free_name(&chase_signame, mctx); + printf(";; No DNSKEY is valid to check the RRSIG" + " of the RRset: FAILED\n"); + clean_trustedkey(); + return; + } + printf(";; OK We found DNSKEY (or more) to validate the RRset\n"); + + result = contains_trusted_key(&chase_signame, chase_keyrdataset, + chase_sigkeyrdataset, mctx); + if (result == ISC_R_SUCCESS) { + free_name(&chase_name, mctx); + free_name(&chase_signame, mctx); + printf("\n;; Ok this DNSKEY is a Trusted Key," + " DNSSEC validation is ok: SUCCESS\n\n"); + clean_trustedkey(); + return; + } + + printf(";; Now, we are going to validate this DNSKEY by the DS\n"); + + if (chase_dsrdataset == NULL) { + free_name(&chase_name, mctx); + free_name(&chase_signame, mctx); + printf(";; the DNSKEY isn't trusted-key and there isn't" + " DS to validate the DNSKEY: FAILED\n"); + clean_trustedkey(); + return; + } + + result = sigchase_verify_ds(&chase_signame, chase_keyrdataset, + chase_dsrdataset, mctx); + if (result != ISC_R_SUCCESS) { + free_name(&chase_signame, mctx); + free_name(&chase_name, mctx); + printf(";; ERROR no DS validates a DNSKEY in the" + " DNSKEY RRset: FAILED\n"); + clean_trustedkey(); + return; + } else + printf(";; OK this DNSKEY (validated by the DS) validates" + " the RRset of the DNSKEYs, thus the DNSKEY validates" + " the RRset\n"); + INSIST(chase_sigdsrdataset != NULL); + + dup_name(&chase_signame, &chase_name, mctx); + free_name(&chase_signame, mctx); + chase_rdataset = chase_dsrdataset; + chase_sigrdataset = chase_sigdsrdataset; + chase_keyrdataset = NULL; + chase_sigkeyrdataset = NULL; + chase_dsrdataset = NULL; + chase_sigdsrdataset = NULL; + chase_siglookedup = chase_keylookedup = ISC_FALSE; + chase_dslookedup = chase_sigdslookedup = ISC_FALSE; + + printf(";; Now, we want to validate the DS : recursive call\n"); + sigchase(msg); + return; +} +#endif + +void +sigchase(dns_message_t *msg) { +#if DIG_SIGCHASE_TD + if (current_lookup->do_topdown) { + sigchase_td(msg); + return; + } +#endif +#if DIG_SIGCHASE_BU + sigchase_bu(msg); + return; +#endif +} + + +/* + * return 1 if name1 < name2 + * 0 if name1 == name2 + * -1 if name1 > name2 + * and -2 if problem + */ +int +inf_name(dns_name_t *name1, dns_name_t *name2) +{ + dns_label_t label1; + dns_label_t label2; + unsigned int nblabel1; + unsigned int nblabel2; + int min_lum_label; + int i; + int ret = -2; + + nblabel1 = dns_name_countlabels(name1); + nblabel2 = dns_name_countlabels(name2); + + if (nblabel1 >= nblabel2) + min_lum_label = nblabel2; + else + min_lum_label = nblabel1; + + + for (i=1 ; i < min_lum_label; i++) { + dns_name_getlabel(name1, nblabel1 -1 - i, &label1); + dns_name_getlabel(name2, nblabel2 -1 - i, &label2); + if ((ret = isc_region_compare(&label1, &label2)) != 0) { + if (ret < 0) + return (-1); + else if (ret > 0) + return (1); + } + } + if (nblabel1 == nblabel2) + return (0); + + if (nblabel1 < nblabel2) + return (-1); + else + return (1); +} + +/** + * + * + * + */ +isc_result_t +prove_nx_domain(dns_message_t *msg, + dns_name_t *name, + dns_name_t *rdata_name, + dns_rdataset_t **rdataset, + dns_rdataset_t **sigrdataset) +{ + isc_result_t ret = ISC_R_FAILURE; + isc_result_t result = ISC_R_NOTFOUND; + dns_rdataset_t *nsecset = NULL; + dns_rdataset_t *signsecset = NULL ; + dns_rdata_t nsec = DNS_RDATA_INIT; + dns_name_t *nsecname; + dns_rdata_nsec_t nsecstruct; + + if ((result = dns_message_firstname(msg, DNS_SECTION_AUTHORITY)) + != ISC_R_SUCCESS) { + printf(";; nothing in authority section : impossible to" + " validate the non-existence : FAILED\n"); + return (ISC_R_FAILURE); + } + + do { + nsecname = NULL; + dns_message_currentname(msg, DNS_SECTION_AUTHORITY, &nsecname); + nsecset = search_type(nsecname, dns_rdatatype_nsec, + dns_rdatatype_any); + if (nsecset == NULL) + continue; + + printf("There is a NSEC for this zone in the" + " AUTHORITY section:\n"); + print_rdataset(nsecname, nsecset, mctx); + + for (result = dns_rdataset_first(nsecset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(nsecset)) { + dns_rdataset_current(nsecset, &nsec); + + + signsecset + = chase_scanname_section(msg, nsecname, + dns_rdatatype_rrsig, + dns_rdatatype_nsec, + DNS_SECTION_AUTHORITY); + if (signsecset == NULL) { + printf(";; no RRSIG NSEC in authority section:" + " impossible to validate the " + "non-existence: FAILED\n"); + return (ISC_R_FAILURE); + } + + ret = dns_rdata_tostruct(&nsec, &nsecstruct, NULL); + check_result(ret,"dns_rdata_tostruct"); + + if ((inf_name(nsecname, &nsecstruct.next) == 1 && + inf_name(name, &nsecstruct.next) == 1) || + (inf_name(name, nsecname) == 1 && + inf_name(&nsecstruct.next, name) == 1)) { + dns_rdata_freestruct(&nsecstruct); + *rdataset = nsecset; + *sigrdataset = signsecset; + dup_name(nsecname, rdata_name, mctx); + + return (ISC_R_SUCCESS); + } + + dns_rdata_freestruct(&nsecstruct); + } + } while (dns_message_nextname(msg, DNS_SECTION_AUTHORITY) + == ISC_R_SUCCESS); + + *rdataset = NULL; + *sigrdataset = NULL; + rdata_name = NULL; + return (ISC_R_FAILURE); +} + +/** + * + * + * + * + * + */ +isc_result_t +prove_nx_type(dns_message_t *msg, dns_name_t *name, dns_rdataset_t *nsecset, + dns_rdataclass_t class, dns_rdatatype_t type, + dns_name_t *rdata_name, dns_rdataset_t **rdataset, + dns_rdataset_t **sigrdataset) +{ + isc_result_t ret; + dns_rdataset_t *signsecset; + dns_rdata_t nsec = DNS_RDATA_INIT; + + UNUSED(class); + + ret = dns_rdataset_first(nsecset); + check_result(ret,"dns_rdataset_first"); + + dns_rdataset_current(nsecset, &nsec); + + ret = dns_nsec_typepresent(&nsec, type); + if (ret == ISC_R_SUCCESS) + printf("OK the NSEC said that the type doesn't exist \n"); + + signsecset = chase_scanname_section(msg, name, + dns_rdatatype_rrsig, + dns_rdatatype_nsec, + DNS_SECTION_AUTHORITY); + if (signsecset == NULL) { + printf("There isn't RRSIG NSEC for the zone \n"); + return (ISC_R_FAILURE); + } + dup_name(name, rdata_name, mctx); + *rdataset = nsecset; + *sigrdataset = signsecset; + + return (ret); +} + +/** + * + * + * + * + */ +isc_result_t +prove_nx(dns_message_t *msg, dns_name_t *name, dns_rdataclass_t class, + dns_rdatatype_t type, dns_name_t *rdata_name, + dns_rdataset_t **rdataset, dns_rdataset_t **sigrdataset) +{ + isc_result_t ret; + dns_rdataset_t *nsecset = NULL; + + printf("We want to prove the non-existance of a type of rdata %d" + " or of the zone: \n", type); + + if ((ret = dns_message_firstname(msg, DNS_SECTION_AUTHORITY)) + != ISC_R_SUCCESS) { + printf(";; nothing in authority section : impossible to" + " validate the non-existence : FAILED\n"); + return (ISC_R_FAILURE); + } + + nsecset = chase_scanname_section(msg, name, dns_rdatatype_nsec, + dns_rdatatype_any, + DNS_SECTION_AUTHORITY); + if (nsecset != NULL) { + printf("We have a NSEC for this zone :OK\n"); + ret = prove_nx_type(msg, name, nsecset, class, + type, rdata_name, rdataset, + sigrdataset); + if (ret != ISC_R_SUCCESS) { + printf("prove_nx: ERROR type exist\n"); + return (ret); + } else { + printf("prove_nx: OK type does not exist\n"); + return (ISC_R_SUCCESS); + } + } else { + printf("there is no NSEC for this zone: validating " + "that the zone doesn't exist\n"); + ret = prove_nx_domain(msg, name, rdata_name, + rdataset, sigrdataset); + return (ret); + } + /* Never get here */ +} +#endif diff --git a/bin/dig/host.1 b/bin/dig/host.1 new file mode 100644 index 0000000..ee537bd --- /dev/null +++ b/bin/dig/host.1 @@ -0,0 +1,219 @@ +.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2000-2002 Internet Software Consortium. +.\" +.\" Permission to use, copy, modify, and 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: host.1,v 1.14.18.14 2007/05/09 03:33:12 marka Exp $ +.\" +.hy 0 +.ad l +.\" Title: host +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.71.1 +.\" Date: Jun 30, 2000 +.\" Manual: BIND9 +.\" Source: BIND9 +.\" +.TH "HOST" "1" "Jun 30, 2000" "BIND9" "BIND9" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +host \- DNS lookup utility +.SH "SYNOPSIS" +.HP 5 +\fBhost\fR [\fB\-aCdlnrsTwv\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-N\ \fR\fB\fIndots\fR\fR] [\fB\-R\ \fR\fB\fInumber\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-W\ \fR\fB\fIwait\fR\fR] [\fB\-m\ \fR\fB\fIflag\fR\fR] [\fB\-4\fR] [\fB\-6\fR] {name} [server] +.SH "DESCRIPTION" +.PP +\fBhost\fR +is a simple utility for performing DNS lookups. It is normally used to convert names to IP addresses and vice versa. When no arguments or options are given, +\fBhost\fR +prints a short summary of its command line arguments and options. +.PP +\fIname\fR +is the domain name that is to be looked up. It can also be a dotted\-decimal IPv4 address or a colon\-delimited IPv6 address, in which case +\fBhost\fR +will by default perform a reverse lookup for that address. +\fIserver\fR +is an optional argument which is either the name or IP address of the name server that +\fBhost\fR +should query instead of the server or servers listed in +\fI/etc/resolv.conf\fR. +.PP +The +\fB\-a\fR +(all) option is equivalent to setting the +\fB\-v\fR +option and asking +\fBhost\fR +to make a query of type ANY. +.PP +When the +\fB\-C\fR +option is used, +\fBhost\fR +will attempt to display the SOA records for zone +\fIname\fR +from all the listed authoritative name servers for that zone. The list of name servers is defined by the NS records that are found for the zone. +.PP +The +\fB\-c\fR +option instructs to make a DNS query of class +\fIclass\fR. This can be used to lookup Hesiod or Chaosnet class resource records. The default class is IN (Internet). +.PP +Verbose output is generated by +\fBhost\fR +when the +\fB\-d\fR +or +\fB\-v\fR +option is used. The two options are equivalent. They have been provided for backwards compatibility. In previous versions, the +\fB\-d\fR +option switched on debugging traces and +\fB\-v\fR +enabled verbose output. +.PP +List mode is selected by the +\fB\-l\fR +option. This makes +\fBhost\fR +perform a zone transfer for zone +\fIname\fR. Transfer the zone printing out the NS, PTR and address records (A/AAAA). If combined with +\fB\-a\fR +all records will be printed. +.PP +The +\fB\-i\fR +option specifies that reverse lookups of IPv6 addresses should use the IP6.INT domain as defined in RFC1886. The default is to use IP6.ARPA. +.PP +The +\fB\-N\fR +option sets the number of dots that have to be in +\fIname\fR +for it to be considered absolute. The default value is that defined using the ndots statement in +\fI/etc/resolv.conf\fR, or 1 if no ndots statement is present. Names with fewer dots are interpreted as relative names and will be searched for in the domains listed in the +\fBsearch\fR +or +\fBdomain\fR +directive in +\fI/etc/resolv.conf\fR. +.PP +The number of UDP retries for a lookup can be changed with the +\fB\-R\fR +option. +\fInumber\fR +indicates how many times +\fBhost\fR +will repeat a query that does not get answered. The default number of retries is 1. If +\fInumber\fR +is negative or zero, the number of retries will default to 1. +.PP +Non\-recursive queries can be made via the +\fB\-r\fR +option. Setting this option clears the +\fBRD\fR +\(em recursion desired \(em bit in the query which +\fBhost\fR +makes. This should mean that the name server receiving the query will not attempt to resolve +\fIname\fR. The +\fB\-r\fR +option enables +\fBhost\fR +to mimic the behavior of a name server by making non\-recursive queries and expecting to receive answers to those queries that are usually referrals to other name servers. +.PP +By default +\fBhost\fR +uses UDP when making queries. The +\fB\-T\fR +option makes it use a TCP connection when querying the name server. TCP will be automatically selected for queries that require it, such as zone transfer (AXFR) requests. +.PP +The +\fB\-4\fR +option forces +\fBhost\fR +to only use IPv4 query transport. The +\fB\-6\fR +option forces +\fBhost\fR +to only use IPv6 query transport. +.PP +The +\fB\-t\fR +option is used to select the query type. +\fItype\fR +can be any recognized query type: CNAME, NS, SOA, SIG, KEY, AXFR, etc. When no query type is specified, +\fBhost\fR +automatically selects an appropriate query type. By default it looks for A records, but if the +\fB\-C\fR +option was given, queries will be made for SOA records, and if +\fIname\fR +is a dotted\-decimal IPv4 address or colon\-delimited IPv6 address, +\fBhost\fR +will query for PTR records. If a query type of IXFR is chosen the starting serial number can be specified by appending an equal followed by the starting serial number (e.g. \-t IXFR=12345678). +.PP +The time to wait for a reply can be controlled through the +\fB\-W\fR +and +\fB\-w\fR +options. The +\fB\-W\fR +option makes +\fBhost\fR +wait for +\fIwait\fR +seconds. If +\fIwait\fR +is less than one, the wait interval is set to one second. When the +\fB\-w\fR +option is used, +\fBhost\fR +will effectively wait forever for a reply. The time to wait for a response will be set to the number of seconds given by the hardware's maximum value for an integer quantity. +.PP +The +\fB\-s\fR +option tells +\fBhost\fR +\fInot\fR +to send the query to the next nameserver if any server responds with a SERVFAIL response, which is the reverse of normal stub resolver behavior. +.PP +The +\fB\-m\fR +can be used to set the memory usage debugging flags +\fIrecord\fR, +\fIusage\fR +and +\fItrace\fR. +.SH "IDN SUPPORT" +.PP +If +\fBhost\fR +has been built with IDN (internationalized domain name) support, it can accept and display non\-ASCII domain names. +\fBhost\fR +appropriately converts character encoding of domain name before sending a request to DNS server or displaying a reply from the server. If you'd like to turn off the IDN support for some reason, defines the +\fBIDN_DISABLE\fR +environment variable. The IDN support is disabled if the variable is set when +\fBhost\fR +runs. +.SH "FILES" +.PP +\fI/etc/resolv.conf\fR +.SH "SEE ALSO" +.PP +\fBdig\fR(1), +\fBnamed\fR(8). +.SH "COPYRIGHT" +Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") +.br +Copyright \(co 2000\-2002 Internet Software Consortium. +.br diff --git a/bin/dig/host.c b/bin/dig/host.c new file mode 100644 index 0000000..33025d5 --- /dev/null +++ b/bin/dig/host.c @@ -0,0 +1,861 @@ +/* + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000-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: host.c,v 1.94.18.19 2007/08/28 07:19:55 tbox Exp $ */ + +/*! \file */ + +#include +#include +#include + +#ifdef HAVE_LOCALE_H +#include +#endif + +#ifdef WITH_IDN +#include +#include +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static isc_boolean_t short_form = ISC_TRUE, listed_server = ISC_FALSE; +static isc_boolean_t default_lookups = ISC_TRUE; +static int seen_error = -1; +static isc_boolean_t list_addresses = ISC_TRUE; +static dns_rdatatype_t list_type = dns_rdatatype_a; +static isc_boolean_t printed_server = ISC_FALSE; + +static const char *opcodetext[] = { + "QUERY", + "IQUERY", + "STATUS", + "RESERVED3", + "NOTIFY", + "UPDATE", + "RESERVED6", + "RESERVED7", + "RESERVED8", + "RESERVED9", + "RESERVED10", + "RESERVED11", + "RESERVED12", + "RESERVED13", + "RESERVED14", + "RESERVED15" +}; + +static const char *rcodetext[] = { + "NOERROR", + "FORMERR", + "SERVFAIL", + "NXDOMAIN", + "NOTIMP", + "REFUSED", + "YXDOMAIN", + "YXRRSET", + "NXRRSET", + "NOTAUTH", + "NOTZONE", + "RESERVED11", + "RESERVED12", + "RESERVED13", + "RESERVED14", + "RESERVED15", + "BADVERS" +}; + +struct rtype { + unsigned int type; + const char *text; +}; + +struct rtype rtypes[] = { + { 1, "has address" }, + { 2, "name server" }, + { 5, "is an alias for" }, + { 11, "has well known services" }, + { 12, "domain name pointer" }, + { 13, "host information" }, + { 15, "mail is handled by" }, + { 16, "descriptive text" }, + { 19, "x25 address" }, + { 20, "ISDN address" }, + { 24, "has signature" }, + { 25, "has key" }, + { 28, "has IPv6 address" }, + { 29, "location" }, + { 0, NULL } +}; + +static void +show_usage(void) { + fputs( +"Usage: host [-aCdlriTwv] [-c class] [-N ndots] [-t type] [-W time]\n" +" [-R number] [-m flag] hostname [server]\n" +" -a is equivalent to -v -t ANY\n" +" -c specifies query class for non-IN data\n" +" -C compares SOA records on authoritative nameservers\n" +" -d is equivalent to -v\n" +" -l lists all hosts in a domain, using AXFR\n" +" -i IP6.INT reverse lookups\n" +" -N changes the number of dots allowed before root lookup is done\n" +" -r disables recursive processing\n" +" -R specifies number of retries for UDP packets\n" +" -s a SERVFAIL response should stop query\n" +" -t specifies the query type\n" +" -T enables TCP/IP mode\n" +" -v enables verbose output\n" +" -w specifies to wait forever for a reply\n" +" -W specifies how long to wait for a reply\n" +" -4 use IPv4 query transport only\n" +" -6 use IPv6 query transport only\n" +" -m set memory debugging flag (trace|record|usage)\n", stderr); + exit(1); +} + +void +dighost_shutdown(void) { + isc_app_shutdown(); +} + +void +received(int bytes, isc_sockaddr_t *from, dig_query_t *query) { + isc_time_t now; + int diff; + + if (!short_form) { + char fromtext[ISC_SOCKADDR_FORMATSIZE]; + isc_sockaddr_format(from, fromtext, sizeof(fromtext)); + TIME_NOW(&now); + diff = (int) isc_time_microdiff(&now, &query->time_sent); + printf("Received %u bytes from %s in %d ms\n", + bytes, fromtext, diff/1000); + } +} + +void +trying(char *frm, dig_lookup_t *lookup) { + UNUSED(lookup); + + if (!short_form) + printf("Trying \"%s\"\n", frm); +} + +static void +say_message(dns_name_t *name, const char *msg, dns_rdata_t *rdata, + dig_query_t *query) +{ + isc_buffer_t *b = NULL; + char namestr[DNS_NAME_FORMATSIZE]; + isc_region_t r; + isc_result_t result; + unsigned int bufsize = BUFSIZ; + + dns_name_format(name, namestr, sizeof(namestr)); + retry: + result = isc_buffer_allocate(mctx, &b, bufsize); + check_result(result, "isc_buffer_allocate"); + result = dns_rdata_totext(rdata, NULL, b); + if (result == ISC_R_NOSPACE) { + isc_buffer_free(&b); + bufsize *= 2; + goto retry; + } + check_result(result, "dns_rdata_totext"); + isc_buffer_usedregion(b, &r); + if (query->lookup->identify_previous_line) { + printf("Nameserver %s:\n\t", + query->servname); + } + printf("%s %s %.*s", namestr, + msg, (int)r.length, (char *)r.base); + if (query->lookup->identify) { + printf(" on server %s", query->servname); + } + printf("\n"); + isc_buffer_free(&b); +} +#ifdef DIG_SIGCHASE +/* Just for compatibility : not use in host program */ +isc_result_t +printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset, + isc_buffer_t *target) +{ + UNUSED(owner_name); + UNUSED(rdataset); + UNUSED(target); + return(ISC_FALSE); +} +#endif +static isc_result_t +printsection(dns_message_t *msg, dns_section_t sectionid, + const char *section_name, isc_boolean_t headers, + dig_query_t *query) +{ + dns_name_t *name, *print_name; + dns_rdataset_t *rdataset; + dns_rdata_t rdata = DNS_RDATA_INIT; + isc_buffer_t target; + isc_result_t result, loopresult; + isc_region_t r; + dns_name_t empty_name; + char t[4096]; + isc_boolean_t first; + isc_boolean_t no_rdata; + + if (sectionid == DNS_SECTION_QUESTION) + no_rdata = ISC_TRUE; + else + no_rdata = ISC_FALSE; + + if (headers) + printf(";; %s SECTION:\n", section_name); + + dns_name_init(&empty_name, NULL); + + result = dns_message_firstname(msg, sectionid); + if (result == ISC_R_NOMORE) + return (ISC_R_SUCCESS); + else if (result != ISC_R_SUCCESS) + return (result); + + for (;;) { + name = NULL; + dns_message_currentname(msg, sectionid, &name); + + isc_buffer_init(&target, t, sizeof(t)); + first = ISC_TRUE; + print_name = name; + + for (rdataset = ISC_LIST_HEAD(name->list); + rdataset != NULL; + rdataset = ISC_LIST_NEXT(rdataset, link)) { + if (query->lookup->rdtype == dns_rdatatype_axfr && + !((!list_addresses && + (list_type == dns_rdatatype_any || + rdataset->type == list_type)) || + (list_addresses && + (rdataset->type == dns_rdatatype_a || + rdataset->type == dns_rdatatype_aaaa || + rdataset->type == dns_rdatatype_ns || + rdataset->type == dns_rdatatype_ptr)))) + continue; + if (!short_form) { + result = dns_rdataset_totext(rdataset, + print_name, + ISC_FALSE, + no_rdata, + &target); + if (result != ISC_R_SUCCESS) + return (result); +#ifdef USEINITALWS + if (first) { + print_name = &empty_name; + first = ISC_FALSE; + } +#else + UNUSED(first); /* Shut up compiler. */ +#endif + } else { + loopresult = dns_rdataset_first(rdataset); + while (loopresult == ISC_R_SUCCESS) { + struct rtype *t; + const char *rtt; + char typebuf[DNS_RDATATYPE_FORMATSIZE]; + char typebuf2[DNS_RDATATYPE_FORMATSIZE + + 20]; + dns_rdataset_current(rdataset, &rdata); + + for (t = rtypes; t->text != NULL; t++) { + if (t->type == rdata.type) { + rtt = t->text; + goto found; + } + } + + dns_rdatatype_format(rdata.type, + typebuf, + sizeof(typebuf)); + snprintf(typebuf2, sizeof(typebuf2), + "has %s record", typebuf); + rtt = typebuf2; + found: + say_message(print_name, rtt, + &rdata, query); + dns_rdata_reset(&rdata); + loopresult = + dns_rdataset_next(rdataset); + } + } + } + if (!short_form) { + isc_buffer_usedregion(&target, &r); + if (no_rdata) + printf(";%.*s", (int)r.length, + (char *)r.base); + else + printf("%.*s", (int)r.length, (char *)r.base); + } + + result = dns_message_nextname(msg, sectionid); + if (result == ISC_R_NOMORE) + break; + else if (result != ISC_R_SUCCESS) + return (result); + } + + return (ISC_R_SUCCESS); +} + +static isc_result_t +printrdata(dns_message_t *msg, dns_rdataset_t *rdataset, dns_name_t *owner, + const char *set_name, isc_boolean_t headers) +{ + isc_buffer_t target; + isc_result_t result; + isc_region_t r; + char t[4096]; + + UNUSED(msg); + if (headers) + printf(";; %s SECTION:\n", set_name); + + isc_buffer_init(&target, t, sizeof(t)); + + result = dns_rdataset_totext(rdataset, owner, ISC_FALSE, ISC_FALSE, + &target); + if (result != ISC_R_SUCCESS) + return (result); + isc_buffer_usedregion(&target, &r); + printf("%.*s", (int)r.length, (char *)r.base); + + return (ISC_R_SUCCESS); +} + +static void +chase_cnamechain(dns_message_t *msg, dns_name_t *qname) { + isc_result_t result; + dns_rdataset_t *rdataset; + dns_rdata_cname_t cname; + dns_rdata_t rdata = DNS_RDATA_INIT; + unsigned int i = msg->counts[DNS_SECTION_ANSWER]; + + while (i-- > 0) { + rdataset = NULL; + result = dns_message_findname(msg, DNS_SECTION_ANSWER, qname, + dns_rdatatype_cname, 0, NULL, + &rdataset); + if (result != ISC_R_SUCCESS) + return; + result = dns_rdataset_first(rdataset); + check_result(result, "dns_rdataset_first"); + dns_rdata_reset(&rdata); + dns_rdataset_current(rdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &cname, NULL); + check_result(result, "dns_rdata_tostruct"); + dns_name_copy(&cname.cname, qname, NULL); + dns_rdata_freestruct(&cname); + } +} + +isc_result_t +printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) { + isc_boolean_t did_flag = ISC_FALSE; + dns_rdataset_t *opt, *tsig = NULL; + dns_name_t *tsigname; + isc_result_t result = ISC_R_SUCCESS; + int force_error; + + UNUSED(headers); + + /* + * We get called multiple times. + * Preserve any existing error status. + */ + force_error = (seen_error == 1) ? 1 : 0; + seen_error = 1; + if (listed_server && !printed_server) { + char sockstr[ISC_SOCKADDR_FORMATSIZE]; + + printf("Using domain server:\n"); + printf("Name: %s\n", query->userarg); + isc_sockaddr_format(&query->sockaddr, sockstr, + sizeof(sockstr)); + printf("Address: %s\n", sockstr); + printf("Aliases: \n\n"); + printed_server = ISC_TRUE; + } + + if (msg->rcode != 0) { + char namestr[DNS_NAME_FORMATSIZE]; + dns_name_format(query->lookup->name, namestr, sizeof(namestr)); + printf("Host %s not found: %d(%s)\n", + (msg->rcode != dns_rcode_nxdomain) ? namestr : + query->lookup->textname, msg->rcode, + rcodetext[msg->rcode]); + return (ISC_R_SUCCESS); + } + + if (default_lookups && query->lookup->rdtype == dns_rdatatype_a) { + char namestr[DNS_NAME_FORMATSIZE]; + dig_lookup_t *lookup; + dns_fixedname_t fixed; + dns_name_t *name; + + /* Add AAAA and MX lookups. */ + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + dns_name_copy(query->lookup->name, name, NULL); + chase_cnamechain(msg, name); + dns_name_format(name, namestr, sizeof(namestr)); + lookup = clone_lookup(query->lookup, ISC_FALSE); + if (lookup != NULL) { + strncpy(lookup->textname, namestr, + sizeof(lookup->textname)); + lookup->textname[sizeof(lookup->textname)-1] = 0; + lookup->rdtype = dns_rdatatype_aaaa; + lookup->rdtypeset = ISC_TRUE; + lookup->origin = NULL; + lookup->retries = tries; + ISC_LIST_APPEND(lookup_list, lookup, link); + } + lookup = clone_lookup(query->lookup, ISC_FALSE); + if (lookup != NULL) { + strncpy(lookup->textname, namestr, + sizeof(lookup->textname)); + lookup->textname[sizeof(lookup->textname)-1] = 0; + lookup->rdtype = dns_rdatatype_mx; + lookup->rdtypeset = ISC_TRUE; + lookup->origin = NULL; + lookup->retries = tries; + ISC_LIST_APPEND(lookup_list, lookup, link); + } + } + + if (!short_form) { + printf(";; ->>HEADER<<- opcode: %s, status: %s, id: %u\n", + opcodetext[msg->opcode], rcodetext[msg->rcode], + msg->id); + printf(";; flags: "); + if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) { + printf("qr"); + did_flag = ISC_TRUE; + } + if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) { + printf("%saa", did_flag ? " " : ""); + did_flag = ISC_TRUE; + } + if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { + printf("%stc", did_flag ? " " : ""); + did_flag = ISC_TRUE; + } + if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) { + printf("%srd", did_flag ? " " : ""); + did_flag = ISC_TRUE; + } + if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) { + printf("%sra", did_flag ? " " : ""); + did_flag = ISC_TRUE; + } + if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0) { + printf("%sad", did_flag ? " " : ""); + did_flag = ISC_TRUE; + } + if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0) { + printf("%scd", did_flag ? " " : ""); + did_flag = ISC_TRUE; + } + printf("; QUERY: %u, ANSWER: %u, " + "AUTHORITY: %u, ADDITIONAL: %u\n", + msg->counts[DNS_SECTION_QUESTION], + msg->counts[DNS_SECTION_ANSWER], + msg->counts[DNS_SECTION_AUTHORITY], + msg->counts[DNS_SECTION_ADDITIONAL]); + opt = dns_message_getopt(msg); + if (opt != NULL) + printf(";; EDNS: version: %u, udp=%u\n", + (unsigned int)((opt->ttl & 0x00ff0000) >> 16), + (unsigned int)opt->rdclass); + tsigname = NULL; + tsig = dns_message_gettsig(msg, &tsigname); + if (tsig != NULL) + printf(";; PSEUDOSECTIONS: TSIG\n"); + } + if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_QUESTION]) && + !short_form) { + printf("\n"); + result = printsection(msg, DNS_SECTION_QUESTION, "QUESTION", + ISC_TRUE, query); + if (result != ISC_R_SUCCESS) + return (result); + } + if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER])) { + if (!short_form) + printf("\n"); + result = printsection(msg, DNS_SECTION_ANSWER, "ANSWER", + ISC_TF(!short_form), query); + if (result != ISC_R_SUCCESS) + return (result); + } + + if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_AUTHORITY]) && + !short_form) { + printf("\n"); + result = printsection(msg, DNS_SECTION_AUTHORITY, "AUTHORITY", + ISC_TRUE, query); + if (result != ISC_R_SUCCESS) + return (result); + } + if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ADDITIONAL]) && + !short_form) { + printf("\n"); + result = printsection(msg, DNS_SECTION_ADDITIONAL, + "ADDITIONAL", ISC_TRUE, query); + if (result != ISC_R_SUCCESS) + return (result); + } + if ((tsig != NULL) && !short_form) { + printf("\n"); + result = printrdata(msg, tsig, tsigname, + "PSEUDOSECTION TSIG", ISC_TRUE); + if (result != ISC_R_SUCCESS) + return (result); + } + if (!short_form) + printf("\n"); + + if (short_form && !default_lookups && + ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER])) { + char namestr[DNS_NAME_FORMATSIZE]; + char typestr[DNS_RDATATYPE_FORMATSIZE]; + dns_name_format(query->lookup->name, namestr, sizeof(namestr)); + dns_rdatatype_format(query->lookup->rdtype, typestr, + sizeof(typestr)); + printf("%s has no %s record\n", namestr, typestr); + } + seen_error = force_error; + return (result); +} + +static const char * optstring = "46ac:dilnm:rst:vwCDN:R:TW:"; + +static void +pre_parse_args(int argc, char **argv) { + int c; + + while ((c = isc_commandline_parse(argc, argv, optstring)) != -1) { + switch (c) { + case 'm': + memdebugging = ISC_TRUE; + if (strcasecmp("trace", isc_commandline_argument) == 0) + isc_mem_debugging |= ISC_MEM_DEBUGTRACE; + else if (!strcasecmp("record", + isc_commandline_argument) == 0) + isc_mem_debugging |= ISC_MEM_DEBUGRECORD; + else if (strcasecmp("usage", + isc_commandline_argument) == 0) + isc_mem_debugging |= ISC_MEM_DEBUGUSAGE; + break; + + case '4': break; + case '6': break; + case 'a': break; + case 'c': break; + case 'd': break; + case 'i': break; + case 'l': break; + case 'n': break; + case 'r': break; + case 's': break; + case 't': break; + case 'v': break; + case 'w': break; + case 'C': break; + case 'D': break; + case 'N': break; + case 'R': break; + case 'T': break; + case 'W': break; + default: + show_usage(); + } + } + isc_commandline_reset = ISC_TRUE; + isc_commandline_index = 1; +} + +static void +parse_args(isc_boolean_t is_batchfile, int argc, char **argv) { + char hostname[MXNAME]; + dig_lookup_t *lookup; + int c; + char store[MXNAME]; + isc_textregion_t tr; + isc_result_t result = ISC_R_SUCCESS; + dns_rdatatype_t rdtype; + dns_rdataclass_t rdclass; + isc_uint32_t serial = 0; + + UNUSED(is_batchfile); + + lookup = make_empty_lookup(); + + lookup->servfail_stops = ISC_FALSE; + lookup->comments = ISC_FALSE; + + while ((c = isc_commandline_parse(argc, argv, optstring)) != -1) { + switch (c) { + case 'l': + lookup->tcp_mode = ISC_TRUE; + lookup->rdtype = dns_rdatatype_axfr; + lookup->rdtypeset = ISC_TRUE; + fatalexit = 3; + break; + case 'v': + case 'd': + short_form = ISC_FALSE; + break; + case 'r': + lookup->recurse = ISC_FALSE; + break; + case 't': + if (strncasecmp(isc_commandline_argument, + "ixfr=", 5) == 0) { + rdtype = dns_rdatatype_ixfr; + /* XXXMPA add error checking */ + serial = strtoul(isc_commandline_argument + 5, + NULL, 10); + result = ISC_R_SUCCESS; + } else { + tr.base = isc_commandline_argument; + tr.length = strlen(isc_commandline_argument); + result = dns_rdatatype_fromtext(&rdtype, + (isc_textregion_t *)&tr); + } + + if (result != ISC_R_SUCCESS) { + fatalexit = 2; + fatal("invalid type: %s\n", + isc_commandline_argument); + } + if (!lookup->rdtypeset || + lookup->rdtype != dns_rdatatype_axfr) + lookup->rdtype = rdtype; + lookup->rdtypeset = ISC_TRUE; +#ifdef WITH_IDN + idnoptions = 0; +#endif + if (rdtype == dns_rdatatype_axfr) { + /* -l -t any -v */ + list_type = dns_rdatatype_any; + short_form = ISC_FALSE; + lookup->tcp_mode = ISC_TRUE; + } else if (rdtype == dns_rdatatype_ixfr) { + lookup->ixfr_serial = serial; + list_type = rdtype; +#ifdef WITH_IDN + } else if (rdtype == dns_rdatatype_a || + rdtype == dns_rdatatype_aaaa || + rdtype == dns_rdatatype_mx) { + idnoptions = IDN_ASCCHECK; + list_type = rdtype; +#endif + } else + list_type = rdtype; + list_addresses = ISC_FALSE; + default_lookups = ISC_FALSE; + break; + case 'c': + tr.base = isc_commandline_argument; + tr.length = strlen(isc_commandline_argument); + result = dns_rdataclass_fromtext(&rdclass, + (isc_textregion_t *)&tr); + + if (result != ISC_R_SUCCESS) { + fatalexit = 2; + fatal("invalid class: %s\n", + isc_commandline_argument); + } else { + lookup->rdclass = rdclass; + lookup->rdclassset = ISC_TRUE; + } + default_lookups = ISC_FALSE; + break; + case 'a': + if (!lookup->rdtypeset || + lookup->rdtype != dns_rdatatype_axfr) + lookup->rdtype = dns_rdatatype_any; + list_type = dns_rdatatype_any; + list_addresses = ISC_FALSE; + lookup->rdtypeset = ISC_TRUE; + short_form = ISC_FALSE; + default_lookups = ISC_FALSE; + break; + case 'i': + lookup->ip6_int = ISC_TRUE; + break; + case 'n': + /* deprecated */ + break; + case 'm': + /* Handled by pre_parse_args(). */ + break; + case 'w': + /* + * The timer routines are coded such that + * timeout==MAXINT doesn't enable the timer + */ + timeout = INT_MAX; + break; + case 'W': + timeout = atoi(isc_commandline_argument); + if (timeout < 1) + timeout = 1; + break; + case 'R': + tries = atoi(isc_commandline_argument) + 1; + if (tries < 2) + tries = 2; + break; + case 'T': + lookup->tcp_mode = ISC_TRUE; + break; + case 'C': + debug("showing all SOAs"); + lookup->rdtype = dns_rdatatype_ns; + lookup->rdtypeset = ISC_TRUE; + lookup->rdclass = dns_rdataclass_in; + lookup->rdclassset = ISC_TRUE; + lookup->ns_search_only = ISC_TRUE; + lookup->trace_root = ISC_TRUE; + lookup->identify_previous_line = ISC_TRUE; + default_lookups = ISC_FALSE; + break; + case 'N': + debug("setting NDOTS to %s", + isc_commandline_argument); + ndots = atoi(isc_commandline_argument); + break; + case 'D': + debugging = ISC_TRUE; + break; + case '4': + if (have_ipv4) { + isc_net_disableipv6(); + have_ipv6 = ISC_FALSE; + } else + fatal("can't find IPv4 networking"); + break; + case '6': + if (have_ipv6) { + isc_net_disableipv4(); + have_ipv4 = ISC_FALSE; + } else + fatal("can't find IPv6 networking"); + break; + case 's': + lookup->servfail_stops = ISC_TRUE; + break; + } + } + + lookup->retries = tries; + + if (isc_commandline_index >= argc) + show_usage(); + + strncpy(hostname, argv[isc_commandline_index], sizeof(hostname)); + hostname[sizeof(hostname)-1]=0; + if (argc > isc_commandline_index + 1) { + set_nameserver(argv[isc_commandline_index+1]); + debug("server is %s", argv[isc_commandline_index+1]); + listed_server = ISC_TRUE; + } else + check_ra = ISC_TRUE; + + lookup->pending = ISC_FALSE; + if (get_reverse(store, sizeof(store), hostname, + lookup->ip6_int, ISC_TRUE) == ISC_R_SUCCESS) { + strncpy(lookup->textname, store, sizeof(lookup->textname)); + lookup->textname[sizeof(lookup->textname)-1] = 0; + lookup->rdtype = dns_rdatatype_ptr; + lookup->rdtypeset = ISC_TRUE; + default_lookups = ISC_FALSE; + } else { + strncpy(lookup->textname, hostname, sizeof(lookup->textname)); + lookup->textname[sizeof(lookup->textname)-1]=0; + } + lookup->new_search = ISC_TRUE; + ISC_LIST_APPEND(lookup_list, lookup, link); + + usesearch = ISC_TRUE; +} + +int +main(int argc, char **argv) { + isc_result_t result; + + tries = 2; + + ISC_LIST_INIT(lookup_list); + ISC_LIST_INIT(server_list); + ISC_LIST_INIT(search_list); + + fatalexit = 1; +#ifdef WITH_IDN + idnoptions = IDN_ASCCHECK; +#endif + + debug("main()"); + progname = argv[0]; + pre_parse_args(argc, argv); + result = isc_app_start(); + check_result(result, "isc_app_start"); + setup_libs(); + parse_args(ISC_FALSE, argc, argv); + setup_system(); + result = isc_app_onrun(mctx, global_task, onrun_callback, NULL); + check_result(result, "isc_app_onrun"); + isc_app_run(); + cancel_all(); + destroy_libs(); + isc_app_finish(); + return ((seen_error == 0) ? 0 : 1); +} diff --git a/bin/dig/host.docbook b/bin/dig/host.docbook new file mode 100644 index 0000000..8ab7679 --- /dev/null +++ b/bin/dig/host.docbook @@ -0,0 +1,277 @@ +]> + + + + + + + Jun 30, 2000 + + + + host + 1 + BIND9 + + + + host + DNS lookup utility + + + + + 2004 + 2005 + 2007 + Internet Systems Consortium, Inc. ("ISC") + + + 2000 + 2001 + 2002 + Internet Software Consortium. + + + + + + host + + + + + + + + + + name + server + + + + + DESCRIPTION + + host + is a simple utility for performing DNS lookups. + It is normally used to convert names to IP addresses and vice versa. + When no arguments or options are given, + host + prints a short summary of its command line arguments and options. + + + name is the domain name that is to be + looked + up. It can also be a dotted-decimal IPv4 address or a colon-delimited + IPv6 address, in which case host will by + default + perform a reverse lookup for that address. + server is an optional argument which + is either + the name or IP address of the name server that host + should query instead of the server or servers listed in + /etc/resolv.conf. + + + + The (all) option is equivalent to setting the + option and asking host to make + a query of type ANY. + + + + When the option is used, host + will attempt to display the SOA records for zone + name from all the listed + authoritative name + servers for that zone. The list of name servers is defined by the NS + records that are found for the zone. + + + + The option instructs to make a DNS query of class + class. This can be used to lookup + Hesiod or + Chaosnet class resource records. The default class is IN (Internet). + + + + Verbose output is generated by host when + the + or option is used. The two + options are equivalent. They have been provided for backwards + compatibility. In previous versions, the option + switched on debugging traces and enabled verbose + output. + + + + List mode is selected by the option. This makes + host perform a zone transfer for zone + name. Transfer the zone printing out + the NS, PTR + and address records (A/AAAA). If combined with + all records will be printed. + + + + The + option specifies that reverse lookups of IPv6 addresses should + use the IP6.INT domain as defined in RFC1886. + The default is to use IP6.ARPA. + + + + The option sets the number of dots that have to be + in name for it to be considered + absolute. The + default value is that defined using the ndots statement in + /etc/resolv.conf, or 1 if no ndots + statement is + present. Names with fewer dots are interpreted as relative names and + will be searched for in the domains listed in the search + or domain directive in + /etc/resolv.conf. + + + + The number of UDP retries for a lookup can be changed with the + option. number + indicates + how many times host will repeat a query + that does + not get answered. The default number of retries is 1. If + number is negative or zero, the + number of + retries will default to 1. + + + + Non-recursive queries can be made via the option. + Setting this option clears the RD — recursion + desired — bit in the query which host makes. + This should mean that the name server receiving the query will not + attempt to resolve name. The + option enables host + to mimic + the behavior of a name server by making non-recursive queries and + expecting to receive answers to those queries that are usually + referrals to other name servers. + + + + By default host uses UDP when making + queries. The + option makes it use a TCP connection when querying + the name server. TCP will be automatically selected for queries that + require it, such as zone transfer (AXFR) requests. + + + + The option forces host to only + use IPv4 query transport. The option forces + host to only use IPv6 query transport. + + + + The option is used to select the query type. + type can be any recognized query + type: CNAME, + NS, SOA, SIG, KEY, AXFR, etc. When no query type is specified, + host automatically selects an appropriate + query + type. By default it looks for A records, but if the + option was given, queries will be made for SOA + records, and if name is a + dotted-decimal IPv4 + address or colon-delimited IPv6 address, host will + query for PTR records. If a query type of IXFR is chosen the starting + serial number can be specified by appending an equal followed by the + starting serial number (e.g. -t IXFR=12345678). + + + + The time to wait for a reply can be controlled through the + and options. The + option makes host + wait for + wait seconds. If wait + is less than one, the wait interval is set to one second. When the + option is used, host + will + effectively wait forever for a reply. The time to wait for a response + will be set to the number of seconds given by the hardware's maximum + value for an integer quantity. + + + + The option tells host + not to send the query to the next nameserver + if any server responds with a SERVFAIL response, which is the + reverse of normal stub resolver behavior. + + + + The can be used to set the memory usage debugging + flags + record, usage and + trace. + + + + + IDN SUPPORT + + If host has been built with IDN (internationalized + domain name) support, it can accept and display non-ASCII domain names. + host appropriately converts character encoding of + domain name before sending a request to DNS server or displaying a + reply from the server. + If you'd like to turn off the IDN support for some reason, defines + the IDN_DISABLE environment variable. + The IDN support is disabled if the variable is set when + host runs. + + + + + FILES + /etc/resolv.conf + + + + + SEE ALSO + + dig1 + , + + named8 + . + + + + diff --git a/bin/dig/host.html b/bin/dig/host.html new file mode 100644 index 0000000..adc9883 --- /dev/null +++ b/bin/dig/host.html @@ -0,0 +1,212 @@ + + + + + +host + + +
+
+
+

Name

+

host — DNS lookup utility

+
+
+

Synopsis

+

host [-aCdlnrsTwv] [-c class] [-N ndots] [-R number] [-t type] [-W wait] [-m flag] [-4] [-6] {name} [server]

+
+
+

DESCRIPTION

+

host + is a simple utility for performing DNS lookups. + It is normally used to convert names to IP addresses and vice versa. + When no arguments or options are given, + host + prints a short summary of its command line arguments and options. +

+

name is the domain name that is to be + looked + up. It can also be a dotted-decimal IPv4 address or a colon-delimited + IPv6 address, in which case host will by + default + perform a reverse lookup for that address. + server is an optional argument which + is either + the name or IP address of the name server that host + should query instead of the server or servers listed in + /etc/resolv.conf. +

+

+ The -a (all) option is equivalent to setting the + -v option and asking host to make + a query of type ANY. +

+

+ When the -C option is used, host + will attempt to display the SOA records for zone + name from all the listed + authoritative name + servers for that zone. The list of name servers is defined by the NS + records that are found for the zone. +

+

+ The -c option instructs to make a DNS query of class + class. This can be used to lookup + Hesiod or + Chaosnet class resource records. The default class is IN (Internet). +

+

+ Verbose output is generated by host when + the + -d or -v option is used. The two + options are equivalent. They have been provided for backwards + compatibility. In previous versions, the -d option + switched on debugging traces and -v enabled verbose + output. +

+

+ List mode is selected by the -l option. This makes + host perform a zone transfer for zone + name. Transfer the zone printing out + the NS, PTR + and address records (A/AAAA). If combined with -a + all records will be printed. +

+

+ The -i + option specifies that reverse lookups of IPv6 addresses should + use the IP6.INT domain as defined in RFC1886. + The default is to use IP6.ARPA. +

+

+ The -N option sets the number of dots that have to be + in name for it to be considered + absolute. The + default value is that defined using the ndots statement in + /etc/resolv.conf, or 1 if no ndots + statement is + present. Names with fewer dots are interpreted as relative names and + will be searched for in the domains listed in the search + or domain directive in + /etc/resolv.conf. +

+

+ The number of UDP retries for a lookup can be changed with the + -R option. number + indicates + how many times host will repeat a query + that does + not get answered. The default number of retries is 1. If + number is negative or zero, the + number of + retries will default to 1. +

+

+ Non-recursive queries can be made via the -r option. + Setting this option clears the RD — recursion + desired — bit in the query which host makes. + This should mean that the name server receiving the query will not + attempt to resolve name. The + -r option enables host + to mimic + the behavior of a name server by making non-recursive queries and + expecting to receive answers to those queries that are usually + referrals to other name servers. +

+

+ By default host uses UDP when making + queries. The + -T option makes it use a TCP connection when querying + the name server. TCP will be automatically selected for queries that + require it, such as zone transfer (AXFR) requests. +

+

+ The -4 option forces host to only + use IPv4 query transport. The -6 option forces + host to only use IPv6 query transport. +

+

+ The -t option is used to select the query type. + type can be any recognized query + type: CNAME, + NS, SOA, SIG, KEY, AXFR, etc. When no query type is specified, + host automatically selects an appropriate + query + type. By default it looks for A records, but if the + -C option was given, queries will be made for SOA + records, and if name is a + dotted-decimal IPv4 + address or colon-delimited IPv6 address, host will + query for PTR records. If a query type of IXFR is chosen the starting + serial number can be specified by appending an equal followed by the + starting serial number (e.g. -t IXFR=12345678). +

+

+ The time to wait for a reply can be controlled through the + -W and -w options. The + -W option makes host + wait for + wait seconds. If wait + is less than one, the wait interval is set to one second. When the + -w option is used, host + will + effectively wait forever for a reply. The time to wait for a response + will be set to the number of seconds given by the hardware's maximum + value for an integer quantity. +

+

+ The -s option tells host + not to send the query to the next nameserver + if any server responds with a SERVFAIL response, which is the + reverse of normal stub resolver behavior. +

+

+ The -m can be used to set the memory usage debugging + flags + record, usage and + trace. +

+
+
+

IDN SUPPORT

+

+ If host has been built with IDN (internationalized + domain name) support, it can accept and display non-ASCII domain names. + host appropriately converts character encoding of + domain name before sending a request to DNS server or displaying a + reply from the server. + If you'd like to turn off the IDN support for some reason, defines + the IDN_DISABLE environment variable. + The IDN support is disabled if the variable is set when + host runs. +

+
+
+

FILES

+

/etc/resolv.conf +

+
+
+

SEE ALSO

+

dig(1), + named(8). +

+
+
+ diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h new file mode 100644 index 0000000..02ae4d2 --- /dev/null +++ b/bin/dig/include/dig/dig.h @@ -0,0 +1,405 @@ +/* + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000-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: dig.h,v 1.82.18.23 2007/08/28 07:19:55 tbox Exp $ */ + +#ifndef DIG_H +#define DIG_H + +/*! \file */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MXSERV 20 +#define MXNAME (DNS_NAME_MAXTEXT+1) +#define MXRD 32 +/*% Buffer Size */ +#define BUFSIZE 512 +#define COMMSIZE 0xffff +#ifndef RESOLV_CONF +/*% location of resolve.conf */ +#define RESOLV_CONF "/etc/resolv.conf" +#endif +/*% output buffer */ +#define OUTPUTBUF 32767 +/*% Max RR Limit */ +#define MAXRRLIMIT 0xffffffff +#define MAXTIMEOUT 0xffff +/*% Max number of tries */ +#define MAXTRIES 0xffffffff +/*% Max number of dots */ +#define MAXNDOTS 0xffff +/*% Max number of ports */ +#define MAXPORT 0xffff +/*% Max serial number */ +#define MAXSERIAL 0xffffffff + +/*% Default TCP Timeout */ +#define TCP_TIMEOUT 10 +/*% Default UDP Timeout */ +#define UDP_TIMEOUT 5 + +#define SERVER_TIMEOUT 1 + +#define LOOKUP_LIMIT 64 +/*% + * Lookup_limit is just a limiter, keeping too many lookups from being + * created. It's job is mainly to prevent the program from running away + * in a tight loop of constant lookups. It's value is arbitrary. + */ + +/* + * Defaults for the sigchase suboptions. Consolidated here because + * these control the layout of dig_lookup_t (among other things). + */ +#ifdef DIG_SIGCHASE +#ifndef DIG_SIGCHASE_BU +#define DIG_SIGCHASE_BU 1 +#endif +#ifndef DIG_SIGCHASE_TD +#define DIG_SIGCHASE_TD 1 +#endif +#endif + +ISC_LANG_BEGINDECLS + +typedef struct dig_lookup dig_lookup_t; +typedef struct dig_query dig_query_t; +typedef struct dig_server dig_server_t; +#ifdef DIG_SIGCHASE +typedef struct dig_message dig_message_t; +#endif +typedef ISC_LIST(dig_server_t) dig_serverlist_t; +typedef struct dig_searchlist dig_searchlist_t; + +/*% The dig_lookup structure */ +struct dig_lookup { + isc_boolean_t + pending, /*%< Pending a successful answer */ + waiting_connect, + doing_xfr, + ns_search_only, /*%< dig +nssearch, host -C */ + identify, /*%< Append an "on server " message */ + identify_previous_line, /*% Prepend a "Nameserver :" + message, with newline and tab */ + ignore, + recurse, + aaonly, + adflag, + cdflag, + trace, /*% dig +trace */ + trace_root, /*% initial query for either +trace or +nssearch */ + tcp_mode, + ip6_int, + comments, + stats, + section_question, + section_answer, + section_authority, + section_additional, + servfail_stops, + new_search, + need_search, + done_as_is, + besteffort, + dnssec; +#ifdef DIG_SIGCHASE +isc_boolean_t sigchase; +#if DIG_SIGCHASE_TD + isc_boolean_t do_topdown, + trace_root_sigchase, + rdtype_sigchaseset, + rdclass_sigchaseset; + /* Name we are going to validate RRset */ + char textnamesigchase[MXNAME]; +#endif +#endif + + char textname[MXNAME]; /*% Name we're going to be looking up */ + char cmdline[MXNAME]; + dns_rdatatype_t rdtype; + dns_rdatatype_t qrdtype; +#if DIG_SIGCHASE_TD + dns_rdatatype_t rdtype_sigchase; + dns_rdatatype_t qrdtype_sigchase; + dns_rdataclass_t rdclass_sigchase; +#endif + dns_rdataclass_t rdclass; + isc_boolean_t rdtypeset; + isc_boolean_t rdclassset; + char namespace[BUFSIZE]; + char onamespace[BUFSIZE]; + isc_buffer_t namebuf; + isc_buffer_t onamebuf; + isc_buffer_t renderbuf; + char *sendspace; + dns_name_t *name; + isc_timer_t *timer; + isc_interval_t interval; + dns_message_t *sendmsg; + dns_name_t *oname; + ISC_LINK(dig_lookup_t) link; + ISC_LIST(dig_query_t) q; + dig_query_t *current_query; + dig_serverlist_t my_server_list; + dig_searchlist_t *origin; + dig_query_t *xfr_q; + isc_uint32_t retries; + int nsfound; + isc_uint16_t udpsize; + isc_int16_t edns; + isc_uint32_t ixfr_serial; + isc_buffer_t rdatabuf; + char rdatastore[MXNAME]; + dst_context_t *tsigctx; + isc_buffer_t *querysig; + isc_uint32_t msgcounter; + dns_fixedname_t fdomain; +}; + +/*% The dig_query structure */ +struct dig_query { + dig_lookup_t *lookup; + isc_boolean_t waiting_connect, + pending_free, + waiting_senddone, + first_pass, + first_soa_rcvd, + second_rr_rcvd, + first_repeat_rcvd, + recv_made, + warn_id; + isc_uint32_t first_rr_serial; + isc_uint32_t second_rr_serial; + isc_uint32_t msg_count; + isc_uint32_t rr_count; + char *servname; + char *userarg; + isc_bufferlist_t sendlist, + recvlist, + lengthlist; + isc_buffer_t recvbuf, + lengthbuf, + slbuf; + char *recvspace, + lengthspace[4], + slspace[4]; + isc_socket_t *sock; + ISC_LINK(dig_query_t) link; + isc_sockaddr_t sockaddr; + isc_time_t time_sent; + isc_uint64_t byte_count; + isc_buffer_t sendbuf; +}; + +struct dig_server { + char servername[MXNAME]; + char userarg[MXNAME]; + ISC_LINK(dig_server_t) link; +}; + +struct dig_searchlist { + char origin[MXNAME]; + ISC_LINK(dig_searchlist_t) link; +}; +#ifdef DIG_SIGCHASE +struct dig_message { + dns_message_t *msg; + ISC_LINK(dig_message_t) link; +}; +#endif + +typedef ISC_LIST(dig_searchlist_t) dig_searchlistlist_t; +typedef ISC_LIST(dig_lookup_t) dig_lookuplist_t; + +/* + * Externals from dighost.c + */ + +extern dig_lookuplist_t lookup_list; +extern dig_serverlist_t server_list; +extern dig_searchlistlist_t search_list; +extern unsigned int extrabytes; + +extern isc_boolean_t check_ra, have_ipv4, have_ipv6, specified_source, + usesearch, showsearch, qr; +extern in_port_t port; +extern unsigned int timeout; +extern isc_mem_t *mctx; +extern dns_messageid_t id; +extern int sendcount; +extern int ndots; +extern int lookup_counter; +extern int exitcode; +extern isc_sockaddr_t bind_address; +extern char keynametext[MXNAME]; +extern char keyfile[MXNAME]; +extern char keysecret[MXNAME]; +extern dns_name_t *hmacname; +extern unsigned int digestbits; +#ifdef DIG_SIGCHASE +extern char trustedkey[MXNAME]; +#endif +extern dns_tsigkey_t *key; +extern isc_boolean_t validated; +extern isc_taskmgr_t *taskmgr; +extern isc_task_t *global_task; +extern isc_boolean_t free_now; +extern isc_boolean_t debugging, memdebugging; + +extern char *progname; +extern int tries; +extern int fatalexit; +#ifdef WITH_IDN +extern int idnoptions; +#endif + +/* + * Routines in dighost.c. + */ +void +get_address(char *host, in_port_t port, isc_sockaddr_t *sockaddr); + +isc_result_t +get_reverse(char *reverse, size_t len, char *value, isc_boolean_t ip6_int, + isc_boolean_t strict); + +void +fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); + +void +debug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); + +void +check_result(isc_result_t result, const char *msg); + +void +setup_lookup(dig_lookup_t *lookup); + +void +destroy_lookup(dig_lookup_t *lookup); + +void +do_lookup(dig_lookup_t *lookup); + +void +start_lookup(void); + +void +onrun_callback(isc_task_t *task, isc_event_t *event); + +int +dhmain(int argc, char **argv); + +void +setup_libs(void); + +void +setup_system(void); + +dig_lookup_t * +requeue_lookup(dig_lookup_t *lookold, isc_boolean_t servers); + +dig_lookup_t * +make_empty_lookup(void); + +dig_lookup_t * +clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers); + +dig_server_t * +make_server(const char *servname, const char *userarg); + +void +flush_server_list(void); + +void +set_nameserver(char *opt); + +void +clone_server_list(dig_serverlist_t src, + dig_serverlist_t *dest); + +void +cancel_all(void); + +void +destroy_libs(void); + +void +set_search_domain(char *domain); + +#ifdef DIG_SIGCHASE +void +clean_trustedkey(void); +#endif + +/* + * Routines to be defined in dig.c, host.c, and nslookup.c. + */ +#ifdef DIG_SIGCHASE +isc_result_t +printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset, + isc_buffer_t *target); +#endif + +isc_result_t +printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers); +/*%< + * Print the final result of the lookup. + */ + +void +received(int bytes, isc_sockaddr_t *from, dig_query_t *query); +/*%< + * Print a message about where and when the response + * was received from, like the final comment in the + * output of "dig". + */ + +void +trying(char *frm, dig_lookup_t *lookup); + +void +dighost_shutdown(void); + +char * +next_token(char **stringp, const char *delim); + +#ifdef DIG_SIGCHASE +/* Chasing functions */ +dns_rdataset_t * +chase_scanname(dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers); +void +chase_sig(dns_message_t *msg); +#endif + +ISC_LANG_ENDDECLS + +#endif diff --git a/bin/dig/nslookup.1 b/bin/dig/nslookup.1 new file mode 100644 index 0000000..a453c2f --- /dev/null +++ b/bin/dig/nslookup.1 @@ -0,0 +1,252 @@ +.\" Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") +.\" +.\" Permission to use, copy, modify, and 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: nslookup.1,v 1.1.10.14 2007/05/16 06:11:27 marka Exp $ +.\" +.hy 0 +.ad l +.\" Title: nslookup +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.71.1 +.\" Date: Jun 30, 2000 +.\" Manual: BIND9 +.\" Source: BIND9 +.\" +.TH "NSLOOKUP" "1" "Jun 30, 2000" "BIND9" "BIND9" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +nslookup \- query Internet name servers interactively +.SH "SYNOPSIS" +.HP 9 +\fBnslookup\fR [\fB\-option\fR] [name\ |\ \-] [server] +.SH "DESCRIPTION" +.PP +\fBNslookup\fR +is a program to query Internet domain name servers. +\fBNslookup\fR +has two modes: interactive and non\-interactive. Interactive mode allows the user to query name servers for information about various hosts and domains or to print a list of hosts in a domain. Non\-interactive mode is used to print just the name and requested information for a host or domain. +.SH "ARGUMENTS" +.PP +Interactive mode is entered in the following cases: +.TP 4 +1. +when no arguments are given (the default name server will be used) +.TP 4 +2. +when the first argument is a hyphen (\-) and the second argument is the host name or Internet address of a name server. +.sp +.RE +.PP +Non\-interactive mode is used when the name or Internet address of the host to be looked up is given as the first argument. The optional second argument specifies the host name or address of a name server. +.PP +Options can also be specified on the command line if they precede the arguments and are prefixed with a hyphen. For example, to change the default query type to host information, and the initial timeout to 10 seconds, type: +.sp .RS 4 .nf nslookup \-query=hinfo \-timeout=10 .fi .RE +.SH "INTERACTIVE COMMANDS" +.PP +\fBhost\fR [server] +.RS 4 +Look up information for host using the current default server or using server, if specified. If host is an Internet address and the query type is A or PTR, the name of the host is returned. If host is a name and does not have a trailing period, the search list is used to qualify the name. +.sp +To look up a host not in the current domain, append a period to the name. +.RE +.PP +\fBserver\fR \fIdomain\fR +.RS 4 +.RE +.PP +\fBlserver\fR \fIdomain\fR +.RS 4 +Change the default server to +\fIdomain\fR; +\fBlserver\fR +uses the initial server to look up information about +\fIdomain\fR, while +\fBserver\fR +uses the current default server. If an authoritative answer can't be found, the names of servers that might have the answer are returned. +.RE +.PP +\fBroot\fR +.RS 4 +not implemented +.RE +.PP +\fBfinger\fR +.RS 4 +not implemented +.RE +.PP +\fBls\fR +.RS 4 +not implemented +.RE +.PP +\fBview\fR +.RS 4 +not implemented +.RE +.PP +\fBhelp\fR +.RS 4 +not implemented +.RE +.PP +\fB?\fR +.RS 4 +not implemented +.RE +.PP +\fBexit\fR +.RS 4 +Exits the program. +.RE +.PP +\fBset\fR \fIkeyword\fR\fI[=value]\fR +.RS 4 +This command is used to change state information that affects the lookups. Valid keywords are: +.RS 4 +.PP +\fBall\fR +.RS 4 +Prints the current values of the frequently used options to +\fBset\fR. Information about the current default server and host is also printed. +.RE +.PP +\fBclass=\fR\fIvalue\fR +.RS 4 +Change the query class to one of: +.RS 4 +.PP +\fBIN\fR +.RS 4 +the Internet class +.RE +.PP +\fBCH\fR +.RS 4 +the Chaos class +.RE +.PP +\fBHS\fR +.RS 4 +the Hesiod class +.RE +.PP +\fBANY\fR +.RS 4 +wildcard +.RE +.RE +.IP "" 4 +The class specifies the protocol group of the information. +.sp +(Default = IN; abbreviation = cl) +.RE +.PP +\fB \fR\fB\fI[no]\fR\fR\fBdebug\fR +.RS 4 +Turn on or off the display of the full response packet and any intermediate response packets when searching. +.sp +(Default = nodebug; abbreviation = +[no]deb) +.RE +.PP +\fB \fR\fB\fI[no]\fR\fR\fBd2\fR +.RS 4 +Turn debugging mode on or off. This displays more about what nslookup is doing. +.sp +(Default = nod2) +.RE +.PP +\fBdomain=\fR\fIname\fR +.RS 4 +Sets the search list to +\fIname\fR. +.RE +.PP +\fB \fR\fB\fI[no]\fR\fR\fBsearch\fR +.RS 4 +If the lookup request contains at least one period but doesn't end with a trailing period, append the domain names in the domain search list to the request until an answer is received. +.sp +(Default = search) +.RE +.PP +\fBport=\fR\fIvalue\fR +.RS 4 +Change the default TCP/UDP name server port to +\fIvalue\fR. +.sp +(Default = 53; abbreviation = po) +.RE +.PP +\fBquerytype=\fR\fIvalue\fR +.RS 4 +.RE +.PP +\fBtype=\fR\fIvalue\fR +.RS 4 +Change the type of the information query. +.sp +(Default = A; abbreviations = q, ty) +.RE +.PP +\fB \fR\fB\fI[no]\fR\fR\fBrecurse\fR +.RS 4 +Tell the name server to query other servers if it does not have the information. +.sp +(Default = recurse; abbreviation = [no]rec) +.RE +.PP +\fBretry=\fR\fInumber\fR +.RS 4 +Set the number of retries to number. +.RE +.PP +\fBtimeout=\fR\fInumber\fR +.RS 4 +Change the initial timeout interval for waiting for a reply to number seconds. +.RE +.PP +\fB \fR\fB\fI[no]\fR\fR\fBvc\fR +.RS 4 +Always use a virtual circuit when sending requests to the server. +.sp +(Default = novc) +.RE +.PP +\fB \fR\fB\fI[no]\fR\fR\fBfail\fR +.RS 4 +Try the next nameserver if a nameserver responds with SERVFAIL or a referral (nofail) or terminate query (fail) on such a response. +.sp +(Default = nofail) +.RE +.RE +.IP "" 4 +.RE +.SH "FILES" +.PP +\fI/etc/resolv.conf\fR +.SH "SEE ALSO" +.PP +\fBdig\fR(1), +\fBhost\fR(1), +\fBnamed\fR(8). +.SH "AUTHOR" +.PP +Andrew Cherenson +.SH "COPYRIGHT" +Copyright \(co 2004\-2007 Internet Systems Consortium, Inc. ("ISC") +.br diff --git a/bin/dig/nslookup.c b/bin/dig/nslookup.c new file mode 100644 index 0000000..3327c6e --- /dev/null +++ b/bin/dig/nslookup.c @@ -0,0 +1,891 @@ +/* + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000-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: nslookup.c,v 1.101.18.15 2007/08/28 07:19:55 tbox Exp $ */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static isc_boolean_t short_form = ISC_TRUE, + tcpmode = ISC_FALSE, + identify = ISC_FALSE, stats = ISC_TRUE, + comments = ISC_TRUE, section_question = ISC_TRUE, + section_answer = ISC_TRUE, section_authority = ISC_TRUE, + section_additional = ISC_TRUE, recurse = ISC_TRUE, + aaonly = ISC_FALSE, nofail = ISC_TRUE; + +static isc_boolean_t in_use = ISC_FALSE; +static char defclass[MXRD] = "IN"; +static char deftype[MXRD] = "A"; +static isc_event_t *global_event = NULL; + +static char domainopt[DNS_NAME_MAXTEXT]; + +static const char *rcodetext[] = { + "NOERROR", + "FORMERR", + "SERVFAIL", + "NXDOMAIN", + "NOTIMP", + "REFUSED", + "YXDOMAIN", + "YXRRSET", + "NXRRSET", + "NOTAUTH", + "NOTZONE", + "RESERVED11", + "RESERVED12", + "RESERVED13", + "RESERVED14", + "RESERVED15", + "BADVERS" +}; + +static const char *rtypetext[] = { + "rtype_0 = ", /* 0 */ + "internet address = ", /* 1 */ + "nameserver = ", /* 2 */ + "md = ", /* 3 */ + "mf = ", /* 4 */ + "canonical name = ", /* 5 */ + "soa = ", /* 6 */ + "mb = ", /* 7 */ + "mg = ", /* 8 */ + "mr = ", /* 9 */ + "rtype_10 = ", /* 10 */ + "protocol = ", /* 11 */ + "name = ", /* 12 */ + "hinfo = ", /* 13 */ + "minfo = ", /* 14 */ + "mail exchanger = ", /* 15 */ + "text = ", /* 16 */ + "rp = ", /* 17 */ + "afsdb = ", /* 18 */ + "x25 address = ", /* 19 */ + "isdn address = ", /* 20 */ + "rt = ", /* 21 */ + "nsap = ", /* 22 */ + "nsap_ptr = ", /* 23 */ + "signature = ", /* 24 */ + "key = ", /* 25 */ + "px = ", /* 26 */ + "gpos = ", /* 27 */ + "has AAAA address ", /* 28 */ + "loc = ", /* 29 */ + "next = ", /* 30 */ + "rtype_31 = ", /* 31 */ + "rtype_32 = ", /* 32 */ + "service = ", /* 33 */ + "rtype_34 = ", /* 34 */ + "naptr = ", /* 35 */ + "kx = ", /* 36 */ + "cert = ", /* 37 */ + "v6 address = ", /* 38 */ + "dname = ", /* 39 */ + "rtype_40 = ", /* 40 */ + "optional = " /* 41 */ +}; + +#define N_KNOWN_RRTYPES (sizeof(rtypetext) / sizeof(rtypetext[0])) + +static void flush_lookup_list(void); +static void getinput(isc_task_t *task, isc_event_t *event); + +void +dighost_shutdown(void) { + isc_event_t *event = global_event; + + flush_lookup_list(); + debug("dighost_shutdown()"); + + if (!in_use) { + isc_app_shutdown(); + return; + } + + isc_task_send(global_task, &event); +} + +static void +printsoa(dns_rdata_t *rdata) { + dns_rdata_soa_t soa; + isc_result_t result; + char namebuf[DNS_NAME_FORMATSIZE]; + + result = dns_rdata_tostruct(rdata, &soa, NULL); + check_result(result, "dns_rdata_tostruct"); + + dns_name_format(&soa.origin, namebuf, sizeof(namebuf)); + printf("\torigin = %s\n", namebuf); + dns_name_format(&soa.contact, namebuf, sizeof(namebuf)); + printf("\tmail addr = %s\n", namebuf); + printf("\tserial = %u\n", soa.serial); + printf("\trefresh = %u\n", soa.refresh); + printf("\tretry = %u\n", soa.retry); + printf("\texpire = %u\n", soa.expire); + printf("\tminimum = %u\n", soa.minimum); + dns_rdata_freestruct(&soa); +} + +static void +printa(dns_rdata_t *rdata) { + isc_result_t result; + char text[sizeof("255.255.255.255")]; + isc_buffer_t b; + + isc_buffer_init(&b, text, sizeof(text)); + result = dns_rdata_totext(rdata, NULL, &b); + check_result(result, "dns_rdata_totext"); + printf("Address: %.*s\n", (int)isc_buffer_usedlength(&b), + (char *)isc_buffer_base(&b)); +} +#ifdef DIG_SIGCHASE +/* Just for compatibility : not use in host program */ +isc_result_t +printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset, + isc_buffer_t *target) +{ + UNUSED(owner_name); + UNUSED(rdataset); + UNUSED(target); + return(ISC_FALSE); +} +#endif +static void +printrdata(dns_rdata_t *rdata) { + isc_result_t result; + isc_buffer_t *b = NULL; + unsigned int size = 1024; + isc_boolean_t done = ISC_FALSE; + + if (rdata->type < N_KNOWN_RRTYPES) + printf("%s", rtypetext[rdata->type]); + else + printf("rdata_%d = ", rdata->type); + + while (!done) { + result = isc_buffer_allocate(mctx, &b, size); + if (result != ISC_R_SUCCESS) + check_result(result, "isc_buffer_allocate"); + result = dns_rdata_totext(rdata, NULL, b); + if (result == ISC_R_SUCCESS) { + printf("%.*s\n", (int)isc_buffer_usedlength(b), + (char *)isc_buffer_base(b)); + done = ISC_TRUE; + } else if (result != ISC_R_NOSPACE) + check_result(result, "dns_rdata_totext"); + isc_buffer_free(&b); + size *= 2; + } +} + +static isc_result_t +printsection(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers, + dns_section_t section) { + isc_result_t result, loopresult; + dns_name_t *name; + dns_rdataset_t *rdataset = NULL; + dns_rdata_t rdata = DNS_RDATA_INIT; + char namebuf[DNS_NAME_FORMATSIZE]; + + UNUSED(query); + UNUSED(headers); + + debug("printsection()"); + + result = dns_message_firstname(msg, section); + if (result == ISC_R_NOMORE) + return (ISC_R_SUCCESS); + else if (result != ISC_R_SUCCESS) + return (result); + for (;;) { + name = NULL; + dns_message_currentname(msg, section, + &name); + for (rdataset = ISC_LIST_HEAD(name->list); + rdataset != NULL; + rdataset = ISC_LIST_NEXT(rdataset, link)) { + loopresult = dns_rdataset_first(rdataset); + while (loopresult == ISC_R_SUCCESS) { + dns_rdataset_current(rdataset, &rdata); + switch (rdata.type) { + case dns_rdatatype_a: + if (section != DNS_SECTION_ANSWER) + goto def_short_section; + dns_name_format(name, namebuf, + sizeof(namebuf)); + printf("Name:\t%s\n", namebuf); + printa(&rdata); + break; + case dns_rdatatype_soa: + dns_name_format(name, namebuf, + sizeof(namebuf)); + printf("%s\n", namebuf); + printsoa(&rdata); + break; + default: + def_short_section: + dns_name_format(name, namebuf, + sizeof(namebuf)); + printf("%s\t", namebuf); + printrdata(&rdata); + break; + } + dns_rdata_reset(&rdata); + loopresult = dns_rdataset_next(rdataset); + } + } + result = dns_message_nextname(msg, section); + if (result == ISC_R_NOMORE) + break; + else if (result != ISC_R_SUCCESS) { + return (result); + } + } + return (ISC_R_SUCCESS); +} + +static isc_result_t +detailsection(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers, + dns_section_t section) { + isc_result_t result, loopresult; + dns_name_t *name; + dns_rdataset_t *rdataset = NULL; + dns_rdata_t rdata = DNS_RDATA_INIT; + char namebuf[DNS_NAME_FORMATSIZE]; + + UNUSED(query); + + debug("detailsection()"); + + if (headers) { + switch (section) { + case DNS_SECTION_QUESTION: + puts(" QUESTIONS:"); + break; + case DNS_SECTION_ANSWER: + puts(" ANSWERS:"); + break; + case DNS_SECTION_AUTHORITY: + puts(" AUTHORITY RECORDS:"); + break; + case DNS_SECTION_ADDITIONAL: + puts(" ADDITIONAL RECORDS:"); + break; + } + } + + result = dns_message_firstname(msg, section); + if (result == ISC_R_NOMORE) + return (ISC_R_SUCCESS); + else if (result != ISC_R_SUCCESS) + return (result); + for (;;) { + name = NULL; + dns_message_currentname(msg, section, + &name); + for (rdataset = ISC_LIST_HEAD(name->list); + rdataset != NULL; + rdataset = ISC_LIST_NEXT(rdataset, link)) { + if (section == DNS_SECTION_QUESTION) { + dns_name_format(name, namebuf, + sizeof(namebuf)); + printf("\t%s, ", namebuf); + dns_rdatatype_format(rdataset->type, + namebuf, + sizeof(namebuf)); + printf("type = %s, ", namebuf); + dns_rdataclass_format(rdataset->rdclass, + namebuf, + sizeof(namebuf)); + printf("class = %s\n", namebuf); + } + loopresult = dns_rdataset_first(rdataset); + while (loopresult == ISC_R_SUCCESS) { + dns_rdataset_current(rdataset, &rdata); + + dns_name_format(name, namebuf, + sizeof(namebuf)); + printf(" -> %s\n", namebuf); + + switch (rdata.type) { + case dns_rdatatype_soa: + printsoa(&rdata); + break; + default: + printf("\t"); + printrdata(&rdata); + } + dns_rdata_reset(&rdata); + loopresult = dns_rdataset_next(rdataset); + } + } + result = dns_message_nextname(msg, section); + if (result == ISC_R_NOMORE) + break; + else if (result != ISC_R_SUCCESS) { + return (result); + } + } + return (ISC_R_SUCCESS); +} + +void +received(int bytes, isc_sockaddr_t *from, dig_query_t *query) +{ + UNUSED(bytes); + UNUSED(from); + UNUSED(query); +} + +void +trying(char *frm, dig_lookup_t *lookup) { + UNUSED(frm); + UNUSED(lookup); + +} + +isc_result_t +printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) { + char servtext[ISC_SOCKADDR_FORMATSIZE]; + + debug("printmessage()"); + + isc_sockaddr_format(&query->sockaddr, servtext, sizeof(servtext)); + printf("Server:\t\t%s\n", query->userarg); + printf("Address:\t%s\n", servtext); + + puts(""); + + if (!short_form) { + isc_boolean_t headers = ISC_TRUE; + puts("------------"); + /* detailheader(query, msg);*/ + detailsection(query, msg, headers, DNS_SECTION_QUESTION); + detailsection(query, msg, headers, DNS_SECTION_ANSWER); + detailsection(query, msg, headers, DNS_SECTION_AUTHORITY); + detailsection(query, msg, headers, DNS_SECTION_ADDITIONAL); + puts("------------"); + } + + if (msg->rcode != 0) { + char nametext[DNS_NAME_FORMATSIZE]; + dns_name_format(query->lookup->name, + nametext, sizeof(nametext)); + printf("** server can't find %s: %s\n", + (msg->rcode != dns_rcode_nxdomain) ? nametext : + query->lookup->textname, rcodetext[msg->rcode]); + debug("returning with rcode == 0"); + return (ISC_R_SUCCESS); + } + + if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) + puts("Non-authoritative answer:"); + if (!ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER])) + printsection(query, msg, headers, DNS_SECTION_ANSWER); + else + printf("*** Can't find %s: No answer\n", + query->lookup->textname); + + if (((msg->flags & DNS_MESSAGEFLAG_AA) == 0) && + (query->lookup->rdtype != dns_rdatatype_a)) { + puts("\nAuthoritative answers can be found from:"); + printsection(query, msg, headers, + DNS_SECTION_AUTHORITY); + printsection(query, msg, headers, + DNS_SECTION_ADDITIONAL); + } + return (ISC_R_SUCCESS); +} + +static void +show_settings(isc_boolean_t full, isc_boolean_t serv_only) { + dig_server_t *srv; + isc_sockaddr_t sockaddr; + dig_searchlist_t *listent; + + srv = ISC_LIST_HEAD(server_list); + + while (srv != NULL) { + char sockstr[ISC_SOCKADDR_FORMATSIZE]; + + get_address(srv->servername, port, &sockaddr); + isc_sockaddr_format(&sockaddr, sockstr, sizeof(sockstr)); + printf("Default server: %s\nAddress: %s\n", + srv->userarg, sockstr); + if (!full) + return; + srv = ISC_LIST_NEXT(srv, link); + } + if (serv_only) + return; + printf("\nSet options:\n"); + printf(" %s\t\t\t%s\t\t%s\n", + tcpmode ? "vc" : "novc", + short_form ? "nodebug" : "debug", + debugging ? "d2" : "nod2"); + printf(" %s\t\t%s\n", + usesearch ? "search" : "nosearch", + recurse ? "recurse" : "norecurse"); + printf(" timeout = %d\t\tretry = %d\tport = %d\n", + timeout, tries, port); + printf(" querytype = %-8s\tclass = %s\n", deftype, defclass); + printf(" srchlist = "); + for (listent = ISC_LIST_HEAD(search_list); + listent != NULL; + listent = ISC_LIST_NEXT(listent, link)) { + printf("%s", listent->origin); + if (ISC_LIST_NEXT(listent, link) != NULL) + printf("/"); + } + printf("\n"); +} + +static isc_boolean_t +testtype(char *typetext) { + isc_result_t result; + isc_textregion_t tr; + dns_rdatatype_t rdtype; + + tr.base = typetext; + tr.length = strlen(typetext); + result = dns_rdatatype_fromtext(&rdtype, &tr); + if (result == ISC_R_SUCCESS) + return (ISC_TRUE); + else { + printf("unknown query type: %s\n", typetext); + return (ISC_FALSE); + } +} + +static isc_boolean_t +testclass(char *typetext) { + isc_result_t result; + isc_textregion_t tr; + dns_rdataclass_t rdclass; + + tr.base = typetext; + tr.length = strlen(typetext); + result = dns_rdataclass_fromtext(&rdclass, &tr); + if (result == ISC_R_SUCCESS) + return (ISC_TRUE); + else { + printf("unknown query class: %s\n", typetext); + return (ISC_FALSE); + } +} + +static void +safecpy(char *dest, char *src, int size) { + strncpy(dest, src, size); + dest[size-1] = 0; +} + +static isc_result_t +parse_uint(isc_uint32_t *uip, const char *value, isc_uint32_t max, + const char *desc) { + isc_uint32_t n; + isc_result_t result = isc_parse_uint32(&n, value, 10); + if (result == ISC_R_SUCCESS && n > max) + result = ISC_R_RANGE; + if (result != ISC_R_SUCCESS) { + printf("invalid %s '%s': %s\n", desc, + value, isc_result_totext(result)); + return result; + } + *uip = n; + return (ISC_R_SUCCESS); +} + +static void +set_port(const char *value) { + isc_uint32_t n; + isc_result_t result = parse_uint(&n, value, 65535, "port"); + if (result == ISC_R_SUCCESS) + port = (isc_uint16_t) n; +} + +static void +set_timeout(const char *value) { + isc_uint32_t n; + isc_result_t result = parse_uint(&n, value, UINT_MAX, "timeout"); + if (result == ISC_R_SUCCESS) + timeout = n; +} + +static void +set_tries(const char *value) { + isc_uint32_t n; + isc_result_t result = parse_uint(&n, value, INT_MAX, "tries"); + if (result == ISC_R_SUCCESS) + tries = n; +} + +static void +setoption(char *opt) { + if (strncasecmp(opt, "all", 4) == 0) { + show_settings(ISC_TRUE, ISC_FALSE); + } else if (strncasecmp(opt, "class=", 6) == 0) { + if (testclass(&opt[6])) + safecpy(defclass, &opt[6], sizeof(defclass)); + } else if (strncasecmp(opt, "cl=", 3) == 0) { + if (testclass(&opt[3])) + safecpy(defclass, &opt[3], sizeof(defclass)); + } else if (strncasecmp(opt, "type=", 5) == 0) { + if (testtype(&opt[5])) + safecpy(deftype, &opt[5], sizeof(deftype)); + } else if (strncasecmp(opt, "ty=", 3) == 0) { + if (testtype(&opt[3])) + safecpy(deftype, &opt[3], sizeof(deftype)); + } else if (strncasecmp(opt, "querytype=", 10) == 0) { + if (testtype(&opt[10])) + safecpy(deftype, &opt[10], sizeof(deftype)); + } else if (strncasecmp(opt, "query=", 6) == 0) { + if (testtype(&opt[6])) + safecpy(deftype, &opt[6], sizeof(deftype)); + } else if (strncasecmp(opt, "qu=", 3) == 0) { + if (testtype(&opt[3])) + safecpy(deftype, &opt[3], sizeof(deftype)); + } else if (strncasecmp(opt, "q=", 2) == 0) { + if (testtype(&opt[2])) + safecpy(deftype, &opt[2], sizeof(deftype)); + } else if (strncasecmp(opt, "domain=", 7) == 0) { + safecpy(domainopt, &opt[7], sizeof(domainopt)); + set_search_domain(domainopt); + usesearch = ISC_TRUE; + } else if (strncasecmp(opt, "do=", 3) == 0) { + safecpy(domainopt, &opt[3], sizeof(domainopt)); + set_search_domain(domainopt); + usesearch = ISC_TRUE; + } else if (strncasecmp(opt, "port=", 5) == 0) { + set_port(&opt[5]); + } else if (strncasecmp(opt, "po=", 3) == 0) { + set_port(&opt[3]); + } else if (strncasecmp(opt, "timeout=", 8) == 0) { + set_timeout(&opt[8]); + } else if (strncasecmp(opt, "t=", 2) == 0) { + set_timeout(&opt[2]); + } else if (strncasecmp(opt, "rec", 3) == 0) { + recurse = ISC_TRUE; + } else if (strncasecmp(opt, "norec", 5) == 0) { + recurse = ISC_FALSE; + } else if (strncasecmp(opt, "retry=", 6) == 0) { + set_tries(&opt[6]); + } else if (strncasecmp(opt, "ret=", 4) == 0) { + set_tries(&opt[4]); + } else if (strncasecmp(opt, "def", 3) == 0) { + usesearch = ISC_TRUE; + } else if (strncasecmp(opt, "nodef", 5) == 0) { + usesearch = ISC_FALSE; + } else if (strncasecmp(opt, "vc", 3) == 0) { + tcpmode = ISC_TRUE; + } else if (strncasecmp(opt, "novc", 5) == 0) { + tcpmode = ISC_FALSE; + } else if (strncasecmp(opt, "deb", 3) == 0) { + short_form = ISC_FALSE; + showsearch = ISC_TRUE; + } else if (strncasecmp(opt, "nodeb", 5) == 0) { + short_form = ISC_TRUE; + showsearch = ISC_FALSE; + } else if (strncasecmp(opt, "d2", 2) == 0) { + debugging = ISC_TRUE; + } else if (strncasecmp(opt, "nod2", 4) == 0) { + debugging = ISC_FALSE; + } else if (strncasecmp(opt, "search", 3) == 0) { + usesearch = ISC_TRUE; + } else if (strncasecmp(opt, "nosearch", 5) == 0) { + usesearch = ISC_FALSE; + } else if (strncasecmp(opt, "sil", 3) == 0) { + /* deprecation_msg = ISC_FALSE; */ + } else if (strncasecmp(opt, "fail", 3) == 0) { + nofail=ISC_FALSE; + } else if (strncasecmp(opt, "nofail", 3) == 0) { + nofail=ISC_TRUE; + } else { + printf("*** Invalid option: %s\n", opt); + } +} + +static void +addlookup(char *opt) { + dig_lookup_t *lookup; + isc_result_t result; + isc_textregion_t tr; + dns_rdatatype_t rdtype; + dns_rdataclass_t rdclass; + char store[MXNAME]; + + debug("addlookup()"); + tr.base = deftype; + tr.length = strlen(deftype); + result = dns_rdatatype_fromtext(&rdtype, &tr); + if (result != ISC_R_SUCCESS) { + printf("unknown query type: %s\n", deftype); + rdclass = dns_rdatatype_a; + } + tr.base = defclass; + tr.length = strlen(defclass); + result = dns_rdataclass_fromtext(&rdclass, &tr); + if (result != ISC_R_SUCCESS) { + printf("unknown query class: %s\n", defclass); + rdclass = dns_rdataclass_in; + } + lookup = make_empty_lookup(); + if (get_reverse(store, sizeof(store), opt, lookup->ip6_int, ISC_TRUE) + == ISC_R_SUCCESS) { + safecpy(lookup->textname, store, sizeof(lookup->textname)); + lookup->rdtype = dns_rdatatype_ptr; + lookup->rdtypeset = ISC_TRUE; + } else { + safecpy(lookup->textname, opt, sizeof(lookup->textname)); + lookup->rdtype = rdtype; + lookup->rdtypeset = ISC_TRUE; + } + lookup->rdclass = rdclass; + lookup->rdclassset = ISC_TRUE; + lookup->trace = ISC_FALSE; + lookup->trace_root = lookup->trace; + lookup->ns_search_only = ISC_FALSE; + lookup->identify = identify; + lookup->recurse = recurse; + lookup->aaonly = aaonly; + lookup->retries = tries; + lookup->udpsize = 0; + lookup->comments = comments; + lookup->tcp_mode = tcpmode; + lookup->stats = stats; + lookup->section_question = section_question; + lookup->section_answer = section_answer; + lookup->section_authority = section_authority; + lookup->section_additional = section_additional; + lookup->new_search = ISC_TRUE; + if (nofail) + lookup->servfail_stops = ISC_FALSE; + ISC_LIST_INIT(lookup->q); + ISC_LINK_INIT(lookup, link); + ISC_LIST_APPEND(lookup_list, lookup, link); + lookup->origin = NULL; + ISC_LIST_INIT(lookup->my_server_list); + debug("looking up %s", lookup->textname); +} + +static void +get_next_command(void) { + char *buf; + char *ptr, *arg; + char *input; + + fflush(stdout); + buf = isc_mem_allocate(mctx, COMMSIZE); + if (buf == NULL) + fatal("memory allocation failure"); + fputs("> ", stderr); + fflush(stderr); + isc_app_block(); + ptr = fgets(buf, COMMSIZE, stdin); + isc_app_unblock(); + if (ptr == NULL) { + in_use = ISC_FALSE; + goto cleanup; + } + input = buf; + ptr = next_token(&input, " \t\r\n"); + if (ptr == NULL) + goto cleanup; + arg = next_token(&input, " \t\r\n"); + if ((strcasecmp(ptr, "set") == 0) && + (arg != NULL)) + setoption(arg); + else if ((strcasecmp(ptr, "server") == 0) || + (strcasecmp(ptr, "lserver") == 0)) { + isc_app_block(); + set_nameserver(arg); + check_ra = ISC_FALSE; + isc_app_unblock(); + show_settings(ISC_TRUE, ISC_TRUE); + } else if (strcasecmp(ptr, "exit") == 0) { + in_use = ISC_FALSE; + goto cleanup; + } else if (strcasecmp(ptr, "help") == 0 || + strcasecmp(ptr, "?") == 0) { + printf("The '%s' command is not yet implemented.\n", ptr); + goto cleanup; + } else if (strcasecmp(ptr, "finger") == 0 || + strcasecmp(ptr, "root") == 0 || + strcasecmp(ptr, "ls") == 0 || + strcasecmp(ptr, "view") == 0) { + printf("The '%s' command is not implemented.\n", ptr); + goto cleanup; + } else + addlookup(ptr); + cleanup: + isc_mem_free(mctx, buf); +} + +static void +parse_args(int argc, char **argv) { + isc_boolean_t have_lookup = ISC_FALSE; + + usesearch = ISC_TRUE; + for (argc--, argv++; argc > 0; argc--, argv++) { + debug("main parsing %s", argv[0]); + if (argv[0][0] == '-') { + if (argv[0][1] != 0) + setoption(&argv[0][1]); + else + have_lookup = ISC_TRUE; + } else { + if (!have_lookup) { + have_lookup = ISC_TRUE; + in_use = ISC_TRUE; + addlookup(argv[0]); + } else { + set_nameserver(argv[0]); + check_ra = ISC_FALSE; + } + } + } +} + +static void +flush_lookup_list(void) { + dig_lookup_t *l, *lp; + dig_query_t *q, *qp; + dig_server_t *s, *sp; + + lookup_counter = 0; + l = ISC_LIST_HEAD(lookup_list); + while (l != NULL) { + q = ISC_LIST_HEAD(l->q); + while (q != NULL) { + if (q->sock != NULL) { + isc_socket_cancel(q->sock, NULL, + ISC_SOCKCANCEL_ALL); + isc_socket_detach(&q->sock); + } + if (ISC_LINK_LINKED(&q->recvbuf, link)) + ISC_LIST_DEQUEUE(q->recvlist, &q->recvbuf, + link); + if (ISC_LINK_LINKED(&q->lengthbuf, link)) + ISC_LIST_DEQUEUE(q->lengthlist, &q->lengthbuf, + link); + isc_buffer_invalidate(&q->recvbuf); + isc_buffer_invalidate(&q->lengthbuf); + qp = q; + q = ISC_LIST_NEXT(q, link); + ISC_LIST_DEQUEUE(l->q, qp, link); + isc_mem_free(mctx, qp); + } + s = ISC_LIST_HEAD(l->my_server_list); + while (s != NULL) { + sp = s; + s = ISC_LIST_NEXT(s, link); + ISC_LIST_DEQUEUE(l->my_server_list, sp, link); + isc_mem_free(mctx, sp); + + } + if (l->sendmsg != NULL) + dns_message_destroy(&l->sendmsg); + if (l->timer != NULL) + isc_timer_detach(&l->timer); + lp = l; + l = ISC_LIST_NEXT(l, link); + ISC_LIST_DEQUEUE(lookup_list, lp, link); + isc_mem_free(mctx, lp); + } +} + +static void +getinput(isc_task_t *task, isc_event_t *event) { + UNUSED(task); + if (global_event == NULL) + global_event = event; + while (in_use) { + get_next_command(); + if (ISC_LIST_HEAD(lookup_list) != NULL) { + start_lookup(); + return; + } + } + isc_app_shutdown(); +} + +int +main(int argc, char **argv) { + isc_result_t result; + + ISC_LIST_INIT(lookup_list); + ISC_LIST_INIT(server_list); + ISC_LIST_INIT(search_list); + + check_ra = ISC_TRUE; + + result = isc_app_start(); + check_result(result, "isc_app_start"); + + setup_libs(); + progname = argv[0]; + + parse_args(argc, argv); + + setup_system(); + if (domainopt[0] != '\0') + set_search_domain(domainopt); + if (in_use) + result = isc_app_onrun(mctx, global_task, onrun_callback, + NULL); + else + result = isc_app_onrun(mctx, global_task, getinput, NULL); + check_result(result, "isc_app_onrun"); + in_use = ISC_TF(!in_use); + + (void)isc_app_run(); + + puts(""); + debug("done, and starting to shut down"); + if (global_event != NULL) + isc_event_free(&global_event); + cancel_all(); + destroy_libs(); + isc_app_finish(); + + return (0); +} diff --git a/bin/dig/nslookup.docbook b/bin/dig/nslookup.docbook new file mode 100644 index 0000000..dff5fa3 --- /dev/null +++ b/bin/dig/nslookup.docbook @@ -0,0 +1,496 @@ +]> + + + + + + + + Jun 30, 2000 + + + + nslookup + 1 + BIND9 + + + + nslookup + query Internet name servers interactively + + + + + 2004 + 2005 + 2006 + 2007 + Internet Systems Consortium, Inc. ("ISC") + + + + + + nslookup + + name | - + server + + + + + DESCRIPTION + Nslookup + is a program to query Internet domain name servers. Nslookup + has two modes: interactive and non-interactive. Interactive mode allows + the user to query name servers for information about various hosts and + domains or to print a list of hosts in a domain. Non-interactive mode + is + used to print just the name and requested information for a host or + domain. + + + + + ARGUMENTS + + Interactive mode is entered in the following cases: + + + + when no arguments are given (the default name server will be used) + + + + + when the first argument is a hyphen (-) and the second argument is + the host name or Internet address of a name server. + + + + + + + Non-interactive mode is used when the name or Internet address of the + host to be looked up is given as the first argument. The optional second + argument specifies the host name or address of a name server. + + + + Options can also be specified on the command line if they precede the + arguments and are prefixed with a hyphen. For example, to + change the default query type to host information, and the initial + timeout to 10 seconds, type: + + +nslookup -query=hinfo -timeout=10 + + + + + + + + INTERACTIVE COMMANDS + + + host server + + + Look up information for host using the current default server or + using server, if specified. If host is an Internet address and + the query type is A or PTR, the name of the host is returned. + If host is a name and does not have a trailing period, the + search list is used to qualify the name. + + + + To look up a host not in the current domain, append a period to + the name. + + + + + + server domain + + + + + + lserver domain + + + Change the default server to domain; lserver uses the initial + server to look up information about domain, while server uses + the current default server. If an authoritative answer can't be + found, the names of servers that might have the answer are + returned. + + + + + + root + + + not implemented + + + + + + finger + + + not implemented + + + + + + ls + + + not implemented + + + + + + view + + + not implemented + + + + + + help + + + not implemented + + + + + + ? + + + not implemented + + + + + + exit + + + Exits the program. + + + + + + set + keyword=value + + + This command is used to change state information that affects + the lookups. Valid keywords are: + + + all + + + Prints the current values of the frequently used + options to set. + Information about the current default + server and host is also printed. + + + + + + class=value + + + Change the query class to one of: + + + IN + + + the Internet class + + + + + CH + + + the Chaos class + + + + + HS + + + the Hesiod class + + + + + ANY + + + wildcard + + + + + The class specifies the protocol group of the information. + + + + (Default = IN; abbreviation = cl) + + + + + + + nodebug + + + Turn on or off the display of the full response packet and + any intermediate response packets when searching. + + + (Default = nodebug; abbreviation = nodeb) + + + + + + + nod2 + + + Turn debugging mode on or off. This displays more about + what nslookup is doing. + + + (Default = nod2) + + + + + + domain=name + + + Sets the search list to name. + + + + + + + nosearch + + + If the lookup request contains at least one period but + doesn't end with a trailing period, append the domain + names in the domain search list to the request until an + answer is received. + + + (Default = search) + + + + + + port=value + + + Change the default TCP/UDP name server port to value. + + + (Default = 53; abbreviation = po) + + + + + + querytype=value + + + + + + + type=value + + + Change the type of the information query. + + + (Default = A; abbreviations = q, ty) + + + + + + + norecurse + + + Tell the name server to query other servers if it does not + have the + information. + + + (Default = recurse; abbreviation = [no]rec) + + + + + + retry=number + + + Set the number of retries to number. + + + + + + timeout=number + + + Change the initial timeout interval for waiting for a + reply to number seconds. + + + + + + + novc + + + Always use a virtual circuit when sending requests to the + server. + + + (Default = novc) + + + + + + + nofail + + + Try the next nameserver if a nameserver responds with + SERVFAIL or a referral (nofail) or terminate query + (fail) on such a response. + + + (Default = nofail) + + + + + + + + + + + + + FILES + /etc/resolv.conf + + + + + SEE ALSO + + dig1 + , + + host1 + , + + named8 + . + + + + + Author + + Andrew Cherenson + + + diff --git a/bin/dig/nslookup.html b/bin/dig/nslookup.html new file mode 100644 index 0000000..46ae43c --- /dev/null +++ b/bin/dig/nslookup.html @@ -0,0 +1,307 @@ + + + + + +nslookup + + +
+
+
+

Name

+

nslookup — query Internet name servers interactively

+
+
+

Synopsis

+

nslookup [-option] [name | -] [server]

+
+
+

DESCRIPTION

+

Nslookup + is a program to query Internet domain name servers. Nslookup + has two modes: interactive and non-interactive. Interactive mode allows + the user to query name servers for information about various hosts and + domains or to print a list of hosts in a domain. Non-interactive mode + is + used to print just the name and requested information for a host or + domain. +

+
+
+

ARGUMENTS

+

+ Interactive mode is entered in the following cases: +

+
    +
  1. + when no arguments are given (the default name server will be used) +

  2. +
  3. + when the first argument is a hyphen (-) and the second argument is + the host name or Internet address of a name server. +

  4. +
+

+

+

+ Non-interactive mode is used when the name or Internet address of the + host to be looked up is given as the first argument. The optional second + argument specifies the host name or address of a name server. +

+

+ Options can also be specified on the command line if they precede the + arguments and are prefixed with a hyphen. For example, to + change the default query type to host information, and the initial + timeout to 10 seconds, type: +

+
+nslookup -query=hinfo  -timeout=10
+
+

+

+
+
+

INTERACTIVE COMMANDS

+
+
host [server]
+
+

+ Look up information for host using the current default server or + using server, if specified. If host is an Internet address and + the query type is A or PTR, the name of the host is returned. + If host is a name and does not have a trailing period, the + search list is used to qualify the name. +

+

+ To look up a host not in the current domain, append a period to + the name. +

+
+
server domain
+

+
lserver domain
+

+ Change the default server to domain; lserver uses the initial + server to look up information about domain, while server uses + the current default server. If an authoritative answer can't be + found, the names of servers that might have the answer are + returned. +

+
root
+

+ not implemented +

+
finger
+

+ not implemented +

+
ls
+

+ not implemented +

+
view
+

+ not implemented +

+
help
+

+ not implemented +

+
?
+

+ not implemented +

+
exit
+

+ Exits the program. +

+
set + keyword[=value]
+
+

+ This command is used to change state information that affects + the lookups. Valid keywords are: +

+
+
all
+

+ Prints the current values of the frequently used + options to set. + Information about the current default + server and host is also printed. +

+
class=value
+
+

+ Change the query class to one of: +

+
+
IN
+

+ the Internet class +

+
CH
+

+ the Chaos class +

+
HS
+

+ the Hesiod class +

+
ANY
+

+ wildcard +

+
+

+ The class specifies the protocol group of the information. + +

+

+ (Default = IN; abbreviation = cl) +

+
+
+ [no]debug
+
+

+ Turn on or off the display of the full response packet and + any intermediate response packets when searching. +

+

+ (Default = nodebug; abbreviation = [no]deb) +

+
+
+ [no]d2
+
+

+ Turn debugging mode on or off. This displays more about + what nslookup is doing. +

+

+ (Default = nod2) +

+
+
domain=name
+

+ Sets the search list to name. +

+
+ [no]search
+
+

+ If the lookup request contains at least one period but + doesn't end with a trailing period, append the domain + names in the domain search list to the request until an + answer is received. +

+

+ (Default = search) +

+
+
port=value
+
+

+ Change the default TCP/UDP name server port to value. +

+

+ (Default = 53; abbreviation = po) +

+
+
querytype=value
+

+
type=value
+
+

+ Change the type of the information query. +

+

+ (Default = A; abbreviations = q, ty) +

+
+
+ [no]recurse
+
+

+ Tell the name server to query other servers if it does not + have the + information. +

+

+ (Default = recurse; abbreviation = [no]rec) +

+
+
retry=number
+

+ Set the number of retries to number. +

+
timeout=number
+

+ Change the initial timeout interval for waiting for a + reply to number seconds. +

+
+ [no]vc
+
+

+ Always use a virtual circuit when sending requests to the + server. +

+

+ (Default = novc) +

+
+
+ [no]fail
+
+

+ Try the next nameserver if a nameserver responds with + SERVFAIL or a referral (nofail) or terminate query + (fail) on such a response. +

+

+ (Default = nofail) +

+
+
+

+

+
+
+
+
+

FILES

+

/etc/resolv.conf +

+
+
+

SEE ALSO

+

dig(1), + host(1), + named(8). +

+
+
+

Author

+

+ Andrew Cherenson +

+
+
+ diff --git a/bin/dnssec/Makefile.in b/bin/dnssec/Makefile.in new file mode 100644 index 0000000..b94dca7 --- /dev/null +++ b/bin/dnssec/Makefile.in @@ -0,0 +1,83 @@ +# Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2000-2002 Internet Software Consortium. +# +# Permission to use, copy, modify, and 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: Makefile.in,v 1.26.18.4 2005/05/02 00:26:11 marka Exp $ + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +@BIND9_VERSION@ + +@BIND9_MAKE_INCLUDES@ + +CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} + +CDEFINES = -DVERSION=\"${VERSION}\" +CWARNINGS = + +DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ +ISCLIBS = ../../lib/isc/libisc.@A@ + +DNSDEPLIBS = ../../lib/dns/libdns.@A@ +ISCDEPLIBS = ../../lib/isc/libisc.@A@ + +DEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS} + +LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@ + +# Alphabetically +TARGETS = dnssec-keygen@EXEEXT@ dnssec-signzone@EXEEXT@ + +OBJS = dnssectool.@O@ + +SRCS = dnssec-keygen.c dnssec-signzone.c dnssectool.c + +MANPAGES = dnssec-keygen.8 dnssec-signzone.8 + +HTMLPAGES = dnssec-keygen.html dnssec-signzone.html + +MANOBJS = ${MANPAGES} ${HTMLPAGES} + +@BIND9_MAKE_RULES@ + +dnssec-keygen@EXEEXT@: dnssec-keygen.@O@ ${OBJS} ${DEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ + dnssec-keygen.@O@ ${OBJS} ${LIBS} + +dnssec-signzone.@O@: dnssec-signzone.c + ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -DVERSION=\"${VERSION}\" \ + -c ${srcdir}/dnssec-signzone.c + +dnssec-signzone@EXEEXT@: dnssec-signzone.@O@ ${OBJS} ${DEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ + dnssec-signzone.@O@ ${OBJS} ${LIBS} + +doc man:: ${MANOBJS} + +docclean manclean maintainer-clean:: + rm -f ${MANOBJS} + +installdirs: + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 + +install:: ${TARGETS} installdirs + for t in ${TARGETS}; do ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} $$t ${DESTDIR}${sbindir}; done + for m in ${MANPAGES}; do ${INSTALL_DATA} ${srcdir}/$$m ${DESTDIR}${mandir}/man8; done + +clean distclean:: + rm -f ${TARGETS} + diff --git a/bin/dnssec/dnssec-keygen.8 b/bin/dnssec/dnssec-keygen.8 new file mode 100644 index 0000000..542190b --- /dev/null +++ b/bin/dnssec/dnssec-keygen.8 @@ -0,0 +1,200 @@ +.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2000-2003 Internet Software Consortium. +.\" +.\" Permission to use, copy, modify, and 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: dnssec-keygen.8,v 1.23.18.14 2007/05/09 03:33:12 marka Exp $ +.\" +.hy 0 +.ad l +.\" Title: dnssec\-keygen +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.71.1 +.\" Date: June 30, 2000 +.\" Manual: BIND9 +.\" Source: BIND9 +.\" +.TH "DNSSEC\-KEYGEN" "8" "June 30, 2000" "BIND9" "BIND9" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +dnssec\-keygen \- DNSSEC key generation tool +.SH "SYNOPSIS" +.HP 14 +\fBdnssec\-keygen\fR {\-a\ \fIalgorithm\fR} {\-b\ \fIkeysize\fR} {\-n\ \fInametype\fR} [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-e\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-g\ \fR\fB\fIgenerator\fR\fR] [\fB\-h\fR] [\fB\-k\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-s\ \fR\fB\fIstrength\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] {name} +.SH "DESCRIPTION" +.PP +\fBdnssec\-keygen\fR +generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures), as defined in RFC 2845. +.SH "OPTIONS" +.PP +\-a \fIalgorithm\fR +.RS 4 +Selects the cryptographic algorithm. The value of +\fBalgorithm\fR +must be one of RSAMD5 (RSA) or RSASHA1, DSA, DH (Diffie Hellman), or HMAC\-MD5. These values are case insensitive. +.sp +Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. For TSIG, HMAC\-MD5 is mandatory. +.sp +Note 2: HMAC\-MD5 and DH automatically set the \-k flag. +.RE +.PP +\-b \fIkeysize\fR +.RS 4 +Specifies the number of bits in the key. The choice of key size depends on the algorithm used. RSAMD5 / RSASHA1 keys must be between 512 and 2048 bits. Diffie Hellman keys must be between 128 and 4096 bits. DSA keys must be between 512 and 1024 bits and an exact multiple of 64. HMAC\-MD5 keys must be between 1 and 512 bits. +.RE +.PP +\-n \fInametype\fR +.RS 4 +Specifies the owner type of the key. The value of +\fBnametype\fR +must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive. +.RE +.PP +\-c \fIclass\fR +.RS 4 +Indicates that the DNS record containing the key should have the specified class. If not specified, class IN is used. +.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 flag is KSK (Key Signing Key) DNSKEY. +.RE +.PP +\-g \fIgenerator\fR +.RS 4 +If generating a Diffie Hellman key, use this generator. Allowed values are 2 and 5. If no generator is specified, a known prime from RFC 2539 will be used if possible; otherwise the default is 2. +.RE +.PP +\-h +.RS 4 +Prints a short summary of the options and arguments to +\fBdnssec\-keygen\fR. +.RE +.PP +\-k +.RS 4 +Generate KEY records rather than DNSKEY records. +.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. +.RE +.PP +\-r \fIrandomdev\fR +.RS 4 +Specifies the source of randomness. If the operating system does not provide a +\fI/dev/random\fR +or equivalent device, the default source of randomness is keyboard input. +\fIrandomdev\fR +specifies the name of a character device or file containing random data to be used instead of the default. The special value +\fIkeyboard\fR +indicates that keyboard input should be used. +.RE +.PP +\-s \fIstrength\fR +.RS 4 +Specifies the strength value of the key. The strength is a number between 0 and 15, and currently has no defined purpose in DNSSEC. +.RE +.PP +\-t \fItype\fR +.RS 4 +Indicates the use of the key. +\fBtype\fR +must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF. AUTH refers to the ability to authenticate data, and CONF the ability to encrypt data. +.RE +.PP +\-v \fIlevel\fR +.RS 4 +Sets the debugging level. +.RE +.SH "GENERATED KEYS" +.PP +When +\fBdnssec\-keygen\fR +completes successfully, it prints a string of the form +\fIKnnnn.+aaa+iiiii\fR +to the standard output. This is an identification string for the key it has generated. +.TP 4 +\(bu +\fInnnn\fR +is the key name. +.TP 4 +\(bu +\fIaaa\fR +is the numeric representation of the algorithm. +.TP 4 +\(bu +\fIiiiii\fR +is the key identifier (or footprint). +.PP +\fBdnssec\-keygen\fR +creates two files, with names based on the printed string. +\fIKnnnn.+aaa+iiiii.key\fR +contains the public key, and +\fIKnnnn.+aaa+iiiii.private\fR +contains the private key. +.PP +The +\fI.key\fR +file contains a DNS KEY record that can be inserted into a zone file (directly or with a $INCLUDE statement). +.PP +The +\fI.private\fR +file contains algorithm\-specific fields. For obvious security reasons, this file does not have general read permission. +.PP +Both +\fI.key\fR +and +\fI.private\fR +files are generated for symmetric encryption algorithms such as HMAC\-MD5, even though the public and private key are equivalent. +.SH "EXAMPLE" +.PP +To generate a 768\-bit DSA key for the domain +\fBexample.com\fR, the following command would be issued: +.PP +\fBdnssec\-keygen \-a DSA \-b 768 \-n ZONE example.com\fR +.PP +The command would print a string of the form: +.PP +\fBKexample.com.+003+26160\fR +.PP +In this example, +\fBdnssec\-keygen\fR +creates the files +\fIKexample.com.+003+26160.key\fR +and +\fIKexample.com.+003+26160.private\fR. +.SH "SEE ALSO" +.PP +\fBdnssec\-signzone\fR(8), +BIND 9 Administrator Reference Manual, +RFC 2535, +RFC 2845, +RFC 2539. +.SH "AUTHOR" +.PP +Internet Systems Consortium +.SH "COPYRIGHT" +Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") +.br +Copyright \(co 2000\-2003 Internet Software Consortium. +.br diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c new file mode 100644 index 0000000..0b57f6d --- /dev/null +++ b/bin/dnssec/dnssec-keygen.c @@ -0,0 +1,512 @@ +/* + * Portions Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 1999-2003 Internet Software Consortium. + * Portions Copyright (C) 1995-2000 by Network Associates, Inc. + * + * 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 AND NETWORK ASSOCIATES 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: dnssec-keygen.c,v 1.66.18.10 2007/08/28 07:19:55 tbox Exp $ */ + +/*! \file */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dnssectool.h" + +#define MAX_RSA 4096 /* should be long enough... */ + +const char *program = "dnssec-keygen"; +int verbose; + +static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 | HMAC-MD5 |" + " HMAC-SHA1 | HMAC-SHA224 | HMAC-SHA256 | " + " HMAC-SHA384 | HMAC-SHA512"; + +static isc_boolean_t +dsa_size_ok(int size) { + return (ISC_TF(size >= 512 && size <= 1024 && size % 64 == 0)); +} + +static void +usage(void) { + fprintf(stderr, "Usage:\n"); + fprintf(stderr, " %s -a alg -b bits -n type [options] name\n\n", + program); + fprintf(stderr, "Version: %s\n", VERSION); + fprintf(stderr, "Required options:\n"); + fprintf(stderr, " -a algorithm: %s\n", algs); + fprintf(stderr, " -b key size, in bits:\n"); + fprintf(stderr, " RSAMD5:\t\t[512..%d]\n", MAX_RSA); + fprintf(stderr, " RSASHA1:\t\t[512..%d]\n", MAX_RSA); + fprintf(stderr, " DH:\t\t[128..4096]\n"); + fprintf(stderr, " DSA:\t\t[512..1024] and divisible by 64\n"); + fprintf(stderr, " HMAC-MD5:\t[1..512]\n"); + fprintf(stderr, " HMAC-SHA1:\t[1..160]\n"); + fprintf(stderr, " HMAC-SHA224:\t[1..224]\n"); + fprintf(stderr, " HMAC-SHA256:\t[1..256]\n"); + fprintf(stderr, " HMAC-SHA384:\t[1..384]\n"); + fprintf(stderr, " HMAC-SHA512:\t[1..512]\n"); + fprintf(stderr, " -n nametype: ZONE | HOST | ENTITY | USER | OTHER\n"); + fprintf(stderr, " name: owner of the key\n"); + fprintf(stderr, "Other options:\n"); + fprintf(stderr, " -c (default: IN)\n"); + fprintf(stderr, " -d (0 => max, default)\n"); + fprintf(stderr, " -e use large exponent (RSAMD5/RSASHA1 only)\n"); + fprintf(stderr, " -f keyflag: KSK\n"); + fprintf(stderr, " -g use specified generator " + "(DH only)\n"); + fprintf(stderr, " -t : " + "AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF " + "(default: AUTHCONF)\n"); + fprintf(stderr, " -p : " + "default: 3 [dnssec]\n"); + fprintf(stderr, " -s strength value this key signs DNS " + "records with (default: 0)\n"); + fprintf(stderr, " -r : a file containing random data\n"); + fprintf(stderr, " -v \n"); + fprintf(stderr, " -k : generate a TYPE=KEY key\n"); + fprintf(stderr, "Output:\n"); + fprintf(stderr, " K++.key, " + "K++.private\n"); + + exit (-1); +} + +int +main(int argc, char **argv) { + char *algname = NULL, *nametype = NULL, *type = NULL; + char *classname = NULL; + char *endp; + dst_key_t *key = NULL, *oldkey; + dns_fixedname_t fname; + dns_name_t *name; + isc_uint16_t flags = 0, ksk = 0; + dns_secalg_t alg; + isc_boolean_t conflict = ISC_FALSE, null_key = ISC_FALSE; + isc_mem_t *mctx = NULL; + int ch, rsa_exp = 0, generator = 0, param = 0; + int protocol = -1, size = -1, signatory = 0; + isc_result_t ret; + isc_textregion_t r; + char filename[255]; + isc_buffer_t buf; + isc_log_t *log = NULL; + isc_entropy_t *ectx = NULL; + dns_rdataclass_t rdclass; + int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC; + int dbits = 0; + + if (argc == 1) + usage(); + + RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); + + dns_result_register(); + + while ((ch = isc_commandline_parse(argc, argv, + "a:b:c:d:ef:g:kn:t:p:s:r:v:h")) != -1) + { + switch (ch) { + case 'a': + algname = isc_commandline_argument; + break; + case 'b': + size = strtol(isc_commandline_argument, &endp, 10); + if (*endp != '\0' || size < 0) + fatal("-b requires a non-negative number"); + break; + case 'c': + classname = isc_commandline_argument; + break; + case 'd': + dbits = strtol(isc_commandline_argument, &endp, 10); + if (*endp != '\0' || dbits < 0) + fatal("-d requires a non-negative number"); + break; + case 'e': + rsa_exp = 1; + break; + case 'f': + if (strcasecmp(isc_commandline_argument, "KSK") == 0) + ksk = DNS_KEYFLAG_KSK; + else + fatal("unknown flag '%s'", + isc_commandline_argument); + break; + case 'g': + generator = strtol(isc_commandline_argument, + &endp, 10); + if (*endp != '\0' || generator <= 0) + fatal("-g requires a positive number"); + break; + case 'k': + options |= DST_TYPE_KEY; + break; + case 'n': + nametype = isc_commandline_argument; + break; + case 't': + type = isc_commandline_argument; + break; + case 'p': + protocol = strtol(isc_commandline_argument, &endp, 10); + if (*endp != '\0' || protocol < 0 || protocol > 255) + fatal("-p must be followed by a number " + "[0..255]"); + break; + case 's': + signatory = strtol(isc_commandline_argument, + &endp, 10); + if (*endp != '\0' || signatory < 0 || signatory > 15) + fatal("-s must be followed by a number " + "[0..15]"); + break; + case 'r': + setup_entropy(mctx, isc_commandline_argument, &ectx); + break; + case 'v': + endp = NULL; + verbose = strtol(isc_commandline_argument, &endp, 0); + if (*endp != '\0') + fatal("-v must be followed by a number"); + break; + + case 'h': + usage(); + default: + fprintf(stderr, "%s: invalid argument -%c\n", + program, ch); + usage(); + } + } + + if (ectx == NULL) + setup_entropy(mctx, NULL, &ectx); + ret = dst_lib_init(mctx, ectx, + ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); + if (ret != ISC_R_SUCCESS) + fatal("could not initialize dst"); + + setup_logging(verbose, mctx, &log); + + if (argc < isc_commandline_index + 1) + fatal("the key name was not specified"); + if (argc > isc_commandline_index + 1) + fatal("extraneous arguments"); + + if (algname == NULL) + fatal("no algorithm was specified"); + if (strcasecmp(algname, "RSA") == 0) { + fprintf(stderr, "The use of RSA (RSAMD5) is not recommended.\n" + "If you still wish to use RSA (RSAMD5) please " + "specify \"-a RSAMD5\"\n"); + return (1); + } else if (strcasecmp(algname, "HMAC-MD5") == 0) { + options |= DST_TYPE_KEY; + alg = DST_ALG_HMACMD5; + } else if (strcasecmp(algname, "HMAC-SHA1") == 0) { + options |= DST_TYPE_KEY; + alg = DST_ALG_HMACSHA1; + } else if (strcasecmp(algname, "HMAC-SHA224") == 0) { + options |= DST_TYPE_KEY; + alg = DST_ALG_HMACSHA224; + } else if (strcasecmp(algname, "HMAC-SHA256") == 0) { + options |= DST_TYPE_KEY; + alg = DST_ALG_HMACSHA256; + } else if (strcasecmp(algname, "HMAC-SHA384") == 0) { + options |= DST_TYPE_KEY; + alg = DST_ALG_HMACSHA384; + } else if (strcasecmp(algname, "HMAC-SHA512") == 0) { + options |= DST_TYPE_KEY; + alg = DST_ALG_HMACSHA512; + } else { + r.base = algname; + r.length = strlen(algname); + ret = dns_secalg_fromtext(&alg, &r); + if (ret != ISC_R_SUCCESS) + fatal("unknown algorithm %s", algname); + if (alg == DST_ALG_DH) + options |= DST_TYPE_KEY; + } + + if (type != NULL && (options & DST_TYPE_KEY) != 0) { + if (strcasecmp(type, "NOAUTH") == 0) + flags |= DNS_KEYTYPE_NOAUTH; + else if (strcasecmp(type, "NOCONF") == 0) + flags |= DNS_KEYTYPE_NOCONF; + else if (strcasecmp(type, "NOAUTHCONF") == 0) { + flags |= (DNS_KEYTYPE_NOAUTH | DNS_KEYTYPE_NOCONF); + if (size < 0) + size = 0; + } + else if (strcasecmp(type, "AUTHCONF") == 0) + /* nothing */; + else + fatal("invalid type %s", type); + } + + if (size < 0) + fatal("key size not specified (-b option)"); + + switch (alg) { + case DNS_KEYALG_RSAMD5: + case DNS_KEYALG_RSASHA1: + if (size != 0 && (size < 512 || size > MAX_RSA)) + fatal("RSA key size %d out of range", size); + break; + case DNS_KEYALG_DH: + if (size != 0 && (size < 128 || size > 4096)) + fatal("DH key size %d out of range", size); + break; + case DNS_KEYALG_DSA: + if (size != 0 && !dsa_size_ok(size)) + fatal("invalid DSS key size: %d", size); + break; + case DST_ALG_HMACMD5: + if (size < 1 || size > 512) + fatal("HMAC-MD5 key size %d out of range", size); + if (dbits != 0 && (dbits < 80 || dbits > 128)) + fatal("HMAC-MD5 digest bits %d out of range", dbits); + if ((dbits % 8) != 0) + fatal("HMAC-MD5 digest bits %d not divisible by 8", + dbits); + break; + case DST_ALG_HMACSHA1: + if (size < 1 || size > 160) + fatal("HMAC-SHA1 key size %d out of range", size); + if (dbits != 0 && (dbits < 80 || dbits > 160)) + fatal("HMAC-SHA1 digest bits %d out of range", dbits); + if ((dbits % 8) != 0) + fatal("HMAC-SHA1 digest bits %d not divisible by 8", + dbits); + break; + case DST_ALG_HMACSHA224: + if (size < 1 || size > 224) + fatal("HMAC-SHA224 key size %d out of range", size); + if (dbits != 0 && (dbits < 112 || dbits > 224)) + fatal("HMAC-SHA224 digest bits %d out of range", dbits); + if ((dbits % 8) != 0) + fatal("HMAC-SHA224 digest bits %d not divisible by 8", + dbits); + break; + case DST_ALG_HMACSHA256: + if (size < 1 || size > 256) + fatal("HMAC-SHA256 key size %d out of range", size); + if (dbits != 0 && (dbits < 128 || dbits > 256)) + fatal("HMAC-SHA256 digest bits %d out of range", dbits); + if ((dbits % 8) != 0) + fatal("HMAC-SHA256 digest bits %d not divisible by 8", + dbits); + break; + case DST_ALG_HMACSHA384: + if (size < 1 || size > 384) + fatal("HMAC-384 key size %d out of range", size); + if (dbits != 0 && (dbits < 192 || dbits > 384)) + fatal("HMAC-SHA384 digest bits %d out of range", dbits); + if ((dbits % 8) != 0) + fatal("HMAC-SHA384 digest bits %d not divisible by 8", + dbits); + break; + case DST_ALG_HMACSHA512: + if (size < 1 || size > 512) + fatal("HMAC-SHA512 key size %d out of range", size); + if (dbits != 0 && (dbits < 256 || dbits > 512)) + fatal("HMAC-SHA512 digest bits %d out of range", dbits); + if ((dbits % 8) != 0) + fatal("HMAC-SHA512 digest bits %d not divisible by 8", + dbits); + break; + } + + if (!(alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_RSASHA1) && + 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"); + + if (nametype == NULL) + fatal("no nametype specified"); + if (strcasecmp(nametype, "zone") == 0) + flags |= DNS_KEYOWNER_ZONE; + else if ((options & DST_TYPE_KEY) != 0) { /* KEY */ + if (strcasecmp(nametype, "host") == 0 || + strcasecmp(nametype, "entity") == 0) + flags |= DNS_KEYOWNER_ENTITY; + else if (strcasecmp(nametype, "user") == 0) + flags |= DNS_KEYOWNER_USER; + else + fatal("invalid KEY nametype %s", nametype); + } else if (strcasecmp(nametype, "other") != 0) /* DNSKEY */ + fatal("invalid DNSKEY nametype %s", nametype); + + rdclass = strtoclass(classname); + + if ((options & DST_TYPE_KEY) != 0) /* KEY */ + flags |= signatory; + else if ((flags & DNS_KEYOWNER_ZONE) != 0) /* DNSKEY */ + flags |= ksk; + + if (protocol == -1) + protocol = DNS_KEYPROTO_DNSSEC; + else if ((options & DST_TYPE_KEY) == 0 && + protocol != DNS_KEYPROTO_DNSSEC) + fatal("invalid DNSKEY protocol: %d", protocol); + + if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) { + if (size > 0) + fatal("specified null key with non-zero size"); + if ((flags & DNS_KEYFLAG_SIGNATORYMASK) != 0) + fatal("specified null key with signing authority"); + } + + if ((flags & DNS_KEYFLAG_OWNERMASK) == DNS_KEYOWNER_ZONE && + (alg == DNS_KEYALG_DH || alg == DST_ALG_HMACMD5 || + alg == DST_ALG_HMACSHA1 || alg == DST_ALG_HMACSHA224 || + alg == DST_ALG_HMACSHA256 || alg == DST_ALG_HMACSHA384 || + alg == DST_ALG_HMACSHA512)) + fatal("a key with algorithm '%s' cannot be a zone key", + algname); + + dns_fixedname_init(&fname); + name = dns_fixedname_name(&fname); + isc_buffer_init(&buf, argv[isc_commandline_index], + strlen(argv[isc_commandline_index])); + isc_buffer_add(&buf, strlen(argv[isc_commandline_index])); + ret = dns_name_fromtext(name, &buf, dns_rootname, ISC_FALSE, NULL); + if (ret != ISC_R_SUCCESS) + fatal("invalid key name %s: %s", argv[isc_commandline_index], + isc_result_totext(ret)); + + switch(alg) { + case DNS_KEYALG_RSAMD5: + case DNS_KEYALG_RSASHA1: + param = rsa_exp; + break; + case DNS_KEYALG_DH: + param = generator; + break; + case DNS_KEYALG_DSA: + case DST_ALG_HMACMD5: + case DST_ALG_HMACSHA1: + case DST_ALG_HMACSHA224: + case DST_ALG_HMACSHA256: + case DST_ALG_HMACSHA384: + case DST_ALG_HMACSHA512: + param = 0; + break; + } + + if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) + null_key = ISC_TRUE; + + isc_buffer_init(&buf, filename, sizeof(filename) - 1); + + do { + conflict = ISC_FALSE; + oldkey = NULL; + + /* generate the key */ + ret = dst_key_generate(name, alg, size, param, flags, protocol, + rdclass, mctx, &key); + isc_entropy_stopcallbacksources(ectx); + + if (ret != ISC_R_SUCCESS) { + char namestr[DNS_NAME_FORMATSIZE]; + char algstr[ALG_FORMATSIZE]; + dns_name_format(name, namestr, sizeof(namestr)); + alg_format(alg, algstr, sizeof(algstr)); + fatal("failed to generate key %s/%s: %s\n", + namestr, algstr, isc_result_totext(ret)); + exit(-1); + } + + dst_key_setbits(key, dbits); + + /* + * Try to read a key with the same name, alg and id from disk. + * If there is one we must continue generating a new one + * unless we were asked to generate a null key, in which + * case we return failure. + */ + ret = dst_key_fromfile(name, dst_key_id(key), alg, + DST_TYPE_PRIVATE, NULL, mctx, &oldkey); + /* do not overwrite an existing key */ + if (ret == ISC_R_SUCCESS) { + dst_key_free(&oldkey); + conflict = ISC_TRUE; + if (null_key) + break; + } + if (conflict == ISC_TRUE) { + if (verbose > 0) { + isc_buffer_clear(&buf); + ret = dst_key_buildfilename(key, 0, NULL, &buf); + fprintf(stderr, + "%s: %s already exists, " + "generating a new key\n", + program, filename); + } + dst_key_free(&key); + } + + } while (conflict == ISC_TRUE); + + if (conflict) + fatal("cannot generate a null key when a key with id 0 " + "already exists"); + + ret = dst_key_tofile(key, options, NULL); + if (ret != ISC_R_SUCCESS) { + char keystr[KEY_FORMATSIZE]; + key_format(key, keystr, sizeof(keystr)); + fatal("failed to write key %s: %s\n", keystr, + isc_result_totext(ret)); + } + + isc_buffer_clear(&buf); + ret = dst_key_buildfilename(key, 0, NULL, &buf); + printf("%s\n", filename); + dst_key_free(&key); + + cleanup_logging(&log); + cleanup_entropy(&ectx); + dst_lib_destroy(); + dns_name_destroy(); + if (verbose > 10) + isc_mem_stats(mctx, stdout); + isc_mem_destroy(&mctx); + + return (0); +} diff --git a/bin/dnssec/dnssec-keygen.docbook b/bin/dnssec/dnssec-keygen.docbook new file mode 100644 index 0000000..8e81cb4 --- /dev/null +++ b/bin/dnssec/dnssec-keygen.docbook @@ -0,0 +1,359 @@ +]> + + + + + + June 30, 2000 + + + + dnssec-keygen + 8 + BIND9 + + + + dnssec-keygen + DNSSEC key generation tool + + + + + 2004 + 2005 + 2007 + Internet Systems Consortium, Inc. ("ISC") + + + 2000 + 2001 + 2002 + 2003 + Internet Software Consortium. + + + + + + dnssec-keygen + -a algorithm + -b keysize + -n nametype + + + + + + + + + + + + name + + + + + 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 + TSIG (Transaction Signatures), as defined in RFC 2845. + + + + + OPTIONS + + + + -a algorithm + + + Selects the cryptographic algorithm. The value of + must be one of RSAMD5 (RSA) or RSASHA1, + DSA, DH (Diffie Hellman), or HMAC-MD5. These values + are case insensitive. + + + Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement + algorithm, + and DSA is recommended. For TSIG, HMAC-MD5 is mandatory. + + + Note 2: HMAC-MD5 and DH automatically set the -k flag. + + + + + + -b keysize + + + Specifies the number of bits in the key. The choice of key + size depends on the algorithm used. RSAMD5 / RSASHA1 keys must be + between + 512 and 2048 bits. Diffie Hellman keys must be between + 128 and 4096 bits. DSA keys must be between 512 and 1024 + bits and an exact multiple of 64. HMAC-MD5 keys must be + between 1 and 512 bits. + + + + + + -n nametype + + + Specifies the owner type of the key. The value of + must either be ZONE (for a DNSSEC + zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with + a host (KEY)), + USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). + These values are + case insensitive. + + + + + + -c class + + + Indicates that the DNS record containing the key should have + the specified class. If not specified, class IN is used. + + + + + + -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. + The only recognized flag is KSK (Key Signing Key) DNSKEY. + + + + + + -g generator + + + If generating a Diffie Hellman key, use this generator. + Allowed values are 2 and 5. If no generator + is specified, a known prime from RFC 2539 will be used + if possible; otherwise the default is 2. + + + + + + -h + + + Prints a short summary of the options and arguments to + dnssec-keygen. + + + + + + -k + + + Generate KEY records rather than DNSKEY records. + + + + + + -p protocol + + + 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. + + + + + + -r randomdev + + + Specifies the source of randomness. If the operating + system does not provide a /dev/random + or equivalent device, the default source of randomness + is keyboard input. randomdev + specifies + the name of a character device or file containing random + data to be used instead of the default. The special value + keyboard indicates that keyboard + input should be used. + + + + + + -s strength + + + Specifies the strength value of the key. The strength is + a number between 0 and 15, and currently has no defined + purpose in DNSSEC. + + + + + + -t type + + + Indicates the use of the key. must be + one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default + is AUTHCONF. AUTH refers to the ability to authenticate + data, and CONF the ability to encrypt data. + + + + + + -v level + + + Sets the debugging level. + + + + + + + + + GENERATED KEYS + + When dnssec-keygen completes + successfully, + it prints a string of the form Knnnn.+aaa+iiiii + to the standard output. This is an identification string for + the key it has generated. + + + + nnnn is the key name. + + + + aaa is the numeric representation + of the + algorithm. + + + + iiiii is the key identifier (or + footprint). + + + + dnssec-keygen + creates two files, with names based + on the printed string. Knnnn.+aaa+iiiii.key + contains the public key, and + Knnnn.+aaa+iiiii.private contains the + private + key. + + + The .key file contains a DNS KEY record + that + can be inserted into a zone file (directly or with a $INCLUDE + statement). + + + The .private file contains + algorithm-specific + fields. For obvious security reasons, this file does not have + general read permission. + + + Both .key and .private + files are generated for symmetric encryption algorithms such as + HMAC-MD5, even though the public and private key are equivalent. + + + + + EXAMPLE + + To generate a 768-bit DSA key for the domain + example.com, the following command would be + issued: + + dnssec-keygen -a DSA -b 768 -n ZONE example.com + + + The command would print a string of the form: + + Kexample.com.+003+26160 + + + In this example, dnssec-keygen creates + the files Kexample.com.+003+26160.key + and + Kexample.com.+003+26160.private. + + + + + SEE ALSO + + dnssec-signzone8 + , + BIND 9 Administrator Reference Manual, + RFC 2535, + RFC 2845, + RFC 2539. + + + + + AUTHOR + Internet Systems Consortium + + + + diff --git a/bin/dnssec/dnssec-keygen.html b/bin/dnssec/dnssec-keygen.html new file mode 100644 index 0000000..7ad747f --- /dev/null +++ b/bin/dnssec/dnssec-keygen.html @@ -0,0 +1,232 @@ + + + + + +dnssec-keygen + + +
+
+
+

Name

+

dnssec-keygen — DNSSEC key generation tool

+
+
+

Synopsis

+

dnssec-keygen {-a algorithm} {-b keysize} {-n nametype} [-c class] [-e] [-f flag] [-g generator] [-h] [-k] [-p protocol] [-r randomdev] [-s strength] [-t type] [-v level] {name}

+
+
+

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 + TSIG (Transaction Signatures), as defined in RFC 2845. +

+
+
+

OPTIONS

+
+
-a algorithm
+
+

+ Selects the cryptographic algorithm. The value of + algorithm must be one of RSAMD5 (RSA) or RSASHA1, + DSA, DH (Diffie Hellman), or HMAC-MD5. These values + are case insensitive. +

+

+ Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement + algorithm, + and DSA is recommended. For TSIG, HMAC-MD5 is mandatory. +

+

+ Note 2: HMAC-MD5 and DH automatically set the -k flag. +

+
+
-b keysize
+

+ Specifies the number of bits in the key. The choice of key + size depends on the algorithm used. RSAMD5 / RSASHA1 keys must be + between + 512 and 2048 bits. Diffie Hellman keys must be between + 128 and 4096 bits. DSA keys must be between 512 and 1024 + bits and an exact multiple of 64. HMAC-MD5 keys must be + between 1 and 512 bits. +

+
-n nametype
+

+ Specifies the owner type of the key. The value of + nametype must either be ZONE (for a DNSSEC + zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with + a host (KEY)), + USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). + These values are + case insensitive. +

+
-c class
+

+ Indicates that the DNS record containing the key should have + the specified class. If not specified, class IN is used. +

+
-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. + The only recognized flag is KSK (Key Signing Key) DNSKEY. +

+
-g generator
+

+ If generating a Diffie Hellman key, use this generator. + Allowed values are 2 and 5. If no generator + is specified, a known prime from RFC 2539 will be used + if possible; otherwise the default is 2. +

+
-h
+

+ Prints a short summary of the options and arguments to + dnssec-keygen. +

+
-k
+

+ Generate KEY records rather than DNSKEY records. +

+
-p protocol
+

+ 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. +

+
-r randomdev
+

+ Specifies the source of randomness. If the operating + system does not provide a /dev/random + or equivalent device, the default source of randomness + is keyboard input. randomdev + specifies + the name of a character device or file containing random + data to be used instead of the default. The special value + keyboard indicates that keyboard + input should be used. +

+
-s strength
+

+ Specifies the strength value of the key. The strength is + a number between 0 and 15, and currently has no defined + purpose in DNSSEC. +

+
-t type
+

+ Indicates the use of the key. type must be + one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default + is AUTHCONF. AUTH refers to the ability to authenticate + data, and CONF the ability to encrypt data. +

+
-v level
+

+ Sets the debugging level. +

+
+
+
+

GENERATED KEYS

+

+ When dnssec-keygen completes + successfully, + it prints a string of the form Knnnn.+aaa+iiiii + to the standard output. This is an identification string for + the key it has generated. +

+
    +
  • nnnn is the key name. +

  • +
  • aaa is the numeric representation + of the + algorithm. +

  • +
  • iiiii is the key identifier (or + footprint). +

  • +
+

dnssec-keygen + creates two files, with names based + on the printed string. Knnnn.+aaa+iiiii.key + contains the public key, and + Knnnn.+aaa+iiiii.private contains the + private + key. +

+

+ The .key file contains a DNS KEY record + that + can be inserted into a zone file (directly or with a $INCLUDE + statement). +

+

+ The .private file contains + algorithm-specific + fields. For obvious security reasons, this file does not have + general read permission. +

+

+ Both .key and .private + files are generated for symmetric encryption algorithms such as + HMAC-MD5, even though the public and private key are equivalent. +

+
+
+

EXAMPLE

+

+ To generate a 768-bit DSA key for the domain + example.com, the following command would be + issued: +

+

dnssec-keygen -a DSA -b 768 -n ZONE example.com +

+

+ The command would print a string of the form: +

+

Kexample.com.+003+26160 +

+

+ In this example, dnssec-keygen creates + the files Kexample.com.+003+26160.key + and + Kexample.com.+003+26160.private. +

+
+
+

SEE ALSO

+

dnssec-signzone(8), + BIND 9 Administrator Reference Manual, + RFC 2535, + RFC 2845, + RFC 2539. +

+
+
+

AUTHOR

+

Internet Systems Consortium +

+
+
+ diff --git a/bin/dnssec/dnssec-signzone.8 b/bin/dnssec/dnssec-signzone.8 new file mode 100644 index 0000000..d150c3f --- /dev/null +++ b/bin/dnssec/dnssec-signzone.8 @@ -0,0 +1,272 @@ +.\" Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2000-2003 Internet Software Consortium. +.\" +.\" Permission to use, copy, modify, and 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: dnssec-signzone.8,v 1.28.18.17 2007/05/09 03:33:12 marka Exp $ +.\" +.hy 0 +.ad l +.\" Title: dnssec\-signzone +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.71.1 +.\" Date: June 30, 2000 +.\" Manual: BIND9 +.\" Source: BIND9 +.\" +.TH "DNSSEC\-SIGNZONE" "8" "June 30, 2000" "BIND9" "BIND9" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +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\fIend\-time\fR\fR] [\fB\-f\ \fR\fB\fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\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\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-t\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-z\fR] {zonefile} [key...] +.SH "DESCRIPTION" +.PP +\fBdnssec\-signzone\fR +signs a zone. It generates NSEC and RRSIG records and produces a signed version of the zone. The security status of delegations from the signed zone (that is, whether the child zones are secure or not) is determined by the presence or absence of a +\fIkeyset\fR +file for each child zone. +.SH "OPTIONS" +.PP +\-a +.RS 4 +Verify all generated signatures. +.RE +.PP +\-c \fIclass\fR +.RS 4 +Specifies the DNS class of the zone. +.RE +.PP +\-k \fIkey\fR +.RS 4 +Treat specified key as a key signing key ignoring any key flags. This option may be specified multiple times. +.RE +.PP +\-l \fIdomain\fR +.RS 4 +Generate a DLV set in addition to the key (DNSKEY) and DS sets. The domain is appended to the name of the records. +.RE +.PP +\-d \fIdirectory\fR +.RS 4 +Look for +\fIkeyset\fR +files in +\fBdirectory\fR +as the directory +.RE +.PP +\-g +.RS 4 +Generate DS records for child zones from keyset files. Existing DS records will be removed. +.RE +.PP +\-s \fIstart\-time\fR +.RS 4 +Specify the date and time when the generated RRSIG records become valid. This can be either an absolute or relative time. An absolute start time is indicated by a number in YYYYMMDDHHMMSS notation; 20000530144500 denotes 14:45:00 UTC on May 30th, 2000. A relative start time is indicated by +N, which is N seconds from the current time. If no +\fBstart\-time\fR +is specified, the current time minus 1 hour (to allow for clock skew) is used. +.RE +.PP +\-e \fIend\-time\fR +.RS 4 +Specify the date and time when the generated RRSIG records expire. 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 +\fBend\-time\fR +is specified, 30 days from the start time is used as a default. +.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. +.RE +.PP +\-h +.RS 4 +Prints a short summary of the options and arguments to +\fBdnssec\-signzone\fR. +.RE +.PP +\-i \fIinterval\fR +.RS 4 +When a previously\-signed zone is passed as input, records may be resigned. The +\fBinterval\fR +option specifies the cycle interval as an offset from the current time (in seconds). If a RRSIG record expires after the cycle interval, it is retained. Otherwise, it is considered to be expiring soon, and it will be replaced. +.sp +The default cycle interval is one quarter of the difference between the signature end and start times. So if neither +\fBend\-time\fR +or +\fBstart\-time\fR +are specified, +\fBdnssec\-signzone\fR +generates signatures that are valid for 30 days, with a cycle interval of 7.5 days. Therefore, if any existing RRSIG records are due to expire in less than 7.5 days, they would be replaced. +.RE +.PP +\-I \fIinput\-format\fR +.RS 4 +The format of the input zone file. Possible formats are +\fB"text"\fR +(default) and +\fB"raw"\fR. This option is primarily intended to be used for dynamic signed zones so that the dumped zone file in a non\-text format containing updates can be signed directly. The use of this option does not make much sense for non\-dynamic zones. +.RE +.PP +\-j \fIjitter\fR +.RS 4 +When signing a zone with a fixed signature lifetime, all RRSIG records issued at the time of signing expires simultaneously. If the zone is incrementally signed, i.e. a previously\-signed zone is passed as input to the signer, all expired signatures have to be regenerated at about the same time. The +\fBjitter\fR +option specifies a jitter window that will be used to randomize the signature expire time, thus spreading incremental signature regeneration over time. +.sp +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 +\-n \fIncpus\fR +.RS 4 +Specifies the number of threads to use. By default, one thread is started for each detected CPU. +.RE +.PP +\-N \fIsoa\-serial\-format\fR +.RS 4 +The SOA serial number format of the signed zone. Possible formats are +\fB"keep"\fR +(default), +\fB"increment"\fR +and +\fB"unixtime"\fR. +.RS 4 +.PP +\fB"keep"\fR +.RS 4 +Do not modify the SOA serial number. +.RE +.PP +\fB"increment"\fR +.RS 4 +Increment the SOA serial number using RFC 1982 arithmetics. +.RE +.PP +\fB"unixtime"\fR +.RS 4 +Set the SOA serial number to the number of seconds since epoch. +.RE +.RE +.RE +.PP +\-o \fIorigin\fR +.RS 4 +The zone origin. If not specified, the name of the zone file is assumed to be the origin. +.RE +.PP +\-O \fIoutput\-format\fR +.RS 4 +The format of the output file containing the signed zone. Possible formats are +\fB"text"\fR +(default) and +\fB"raw"\fR. +.RE +.PP +\-p +.RS 4 +Use pseudo\-random data when signing the zone. This is faster, but less secure, than using real random data. This option may be useful when signing large zones or when the entropy source is limited. +.RE +.PP +\-r \fIrandomdev\fR +.RS 4 +Specifies the source of randomness. If the operating system does not provide a +\fI/dev/random\fR +or equivalent device, the default source of randomness is keyboard input. +\fIrandomdev\fR +specifies the name of a character device or file containing random data to be used instead of the default. The special value +\fIkeyboard\fR +indicates that keyboard input should be used. +.RE +.PP +\-t +.RS 4 +Print statistics at completion. +.RE +.PP +\-v \fIlevel\fR +.RS 4 +Sets the debugging level. +.RE +.PP +\-z +.RS 4 +Ignore KSK flag on key when determining what to sign. +.RE +.PP +zonefile +.RS 4 +The file containing the zone to be signed. +.RE +.PP +key +.RS 4 +Specify which keys should be used to sign the zone. If no keys are specified, then the zone will be examined for DNSKEY records at the zone apex. If these are found and there are matching private keys, in the current directory, then these will be used for signing. +.RE +.SH "EXAMPLE" +.PP +The following command signs the +\fBexample.com\fR +zone with the DSA key generated by +\fBdnssec\-keygen\fR +(Kexample.com.+003+17247). The zone's keys must be in the master file (\fIdb.example.com\fR). This invocation looks for +\fIkeyset\fR +files, in the current directory, so that DS records can be generated from them (\fB\-g\fR). +.sp +.RS 4 +.nf +% dnssec\-signzone \-g \-o example.com db.example.com \\ +Kexample.com.+003+17247 +db.example.com.signed +% +.fi +.RE +.PP +In the above example, +\fBdnssec\-signzone\fR +creates the file +\fIdb.example.com.signed\fR. This file should be referenced in a zone statement in a +\fInamed.conf\fR +file. +.PP +This example re\-signs a previously signed zone with default parameters. The private keys are assumed to be in the current directory. +.sp +.RS 4 +.nf +% cp db.example.com.signed db.example.com +% dnssec\-signzone \-o example.com db.example.com +db.example.com.signed +% +.fi +.RE +.SH "SEE ALSO" +.PP +\fBdnssec\-keygen\fR(8), +BIND 9 Administrator Reference Manual, +RFC 2535. +.SH "AUTHOR" +.PP +Internet Systems Consortium +.SH "COPYRIGHT" +Copyright \(co 2004\-2007 Internet Systems Consortium, Inc. ("ISC") +.br +Copyright \(co 2000\-2003 Internet Software Consortium. +.br diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c new file mode 100644 index 0000000..46cd4a7 --- /dev/null +++ b/bin/dnssec/dnssec-signzone.c @@ -0,0 +1,2333 @@ +/* + * Portions Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 1999-2003 Internet Software Consortium. + * Portions Copyright (C) 1995-2000 by Network Associates, Inc. + * + * 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 AND NETWORK ASSOCIATES 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: dnssec-signzone.c,v 1.177.18.24 2007/08/28 07:20:00 tbox Exp $ */ + +/*! \file */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dnssectool.h" + +const char *program = "dnssec-signzone"; +int verbose; + +#define BUFSIZE 2048 +#define MAXDSKEYS 8 + +typedef struct signer_key_struct signer_key_t; + +struct signer_key_struct { + dst_key_t *key; + isc_boolean_t issigningkey; + isc_boolean_t isdsk; + isc_boolean_t isksk; + unsigned int position; + ISC_LINK(signer_key_t) link; +}; + +#define SIGNER_EVENTCLASS ISC_EVENTCLASS(0x4453) +#define SIGNER_EVENT_WRITE (SIGNER_EVENTCLASS + 0) +#define SIGNER_EVENT_WORK (SIGNER_EVENTCLASS + 1) + +#define SOA_SERIAL_KEEP 0 +#define SOA_SERIAL_INCREMENT 1 +#define SOA_SERIAL_UNIXTIME 2 + +typedef struct signer_event sevent_t; +struct signer_event { + ISC_EVENT_COMMON(sevent_t); + dns_fixedname_t *fname; + dns_dbnode_t *node; +}; + +static ISC_LIST(signer_key_t) keylist; +static unsigned int keycount = 0; +static isc_stdtime_t starttime = 0, endtime = 0, now; +static int cycle = -1; +static int jitter = 0; +static isc_boolean_t tryverify = ISC_FALSE; +static isc_boolean_t printstats = ISC_FALSE; +static isc_mem_t *mctx = NULL; +static isc_entropy_t *ectx = NULL; +static dns_ttl_t zonettl; +static FILE *fp; +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 unsigned int nsigned = 0, nretained = 0, ndropped = 0; +static unsigned int nverified = 0, nverifyfailed = 0; +static const char *directory; +static isc_mutex_t namelock, statslock; +static isc_taskmgr_t *taskmgr = NULL; +static dns_db_t *gdb; /* The database */ +static dns_dbversion_t *gversion; /* The database version */ +static dns_dbiterator_t *gdbiter; /* The database iterator */ +static dns_rdataclass_t gclass; /* The class */ +static dns_name_t *gorigin; /* The database origin */ +static isc_task_t *master = NULL; +static unsigned int ntasks = 0; +static isc_boolean_t shuttingdown = ISC_FALSE, finished = ISC_FALSE; +static unsigned int assigned = 0, completed = 0; +static isc_boolean_t nokeys = ISC_FALSE; +static isc_boolean_t removefile = ISC_FALSE; +static isc_boolean_t generateds = ISC_FALSE; +static isc_boolean_t ignoreksk = ISC_FALSE; +static dns_name_t *dlv = NULL; +static dns_fixedname_t dlv_fixed; +static dns_master_style_t *dsstyle = NULL; +static unsigned int serialformat = SOA_SERIAL_KEEP; + +#define INCSTAT(counter) \ + if (printstats) { \ + LOCK(&statslock); \ + counter++; \ + UNLOCK(&statslock); \ + } + +static void +sign(isc_task_t *task, isc_event_t *event); + + +static inline 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 void +dumpnode(dns_name_t *name, dns_dbnode_t *node) { + isc_result_t result; + + if (outputformat != dns_masterformat_text) + return; + result = dns_master_dumpnodetostream(mctx, gdb, gversion, node, name, + masterstyle, fp); + check_result(result, "dns_master_dumpnodetostream"); +} + +static signer_key_t * +newkeystruct(dst_key_t *dstkey, isc_boolean_t signwithkey) { + signer_key_t *key; + + key = isc_mem_get(mctx, sizeof(signer_key_t)); + if (key == NULL) + fatal("out of memory"); + key->key = dstkey; + if ((dst_key_flags(dstkey) & DNS_KEYFLAG_KSK) != 0) { + key->issigningkey = signwithkey; + key->isksk = ISC_TRUE; + key->isdsk = ISC_FALSE; + } else { + key->issigningkey = signwithkey; + key->isksk = ISC_FALSE; + key->isdsk = ISC_TRUE; + } + key->position = keycount++; + ISC_LINK_INIT(key, link); + return (key); +} + +static void +signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdata_t *rdata, + dst_key_t *key, isc_buffer_t *b) +{ + isc_result_t result; + isc_stdtime_t jendtime; + + jendtime = (jitter != 0) ? isc_random_jitter(endtime, jitter) : endtime; + result = dns_dnssec_sign(name, rdataset, key, &starttime, &jendtime, + mctx, b, rdata); + isc_entropy_stopcallbacksources(ectx); + if (result != ISC_R_SUCCESS) { + char keystr[KEY_FORMATSIZE]; + key_format(key, keystr, sizeof(keystr)); + fatal("dnskey '%s' failed to sign data: %s", + keystr, isc_result_totext(result)); + } + INCSTAT(nsigned); + + if (tryverify) { + result = dns_dnssec_verify(name, rdataset, key, + ISC_TRUE, mctx, rdata); + if (result == ISC_R_SUCCESS) { + vbprintf(3, "\tsignature verified\n"); + INCSTAT(nverified); + } else { + vbprintf(3, "\tsignature failed to verify\n"); + INCSTAT(nverifyfailed); + } + } +} + +static inline isc_boolean_t +issigningkey(signer_key_t *key) { + return (key->issigningkey); +} + +static inline isc_boolean_t +iszonekey(signer_key_t *key) { + return (ISC_TF(dns_name_equal(dst_key_name(key->key), gorigin) && + dst_key_iszonekey(key->key))); +} + +/*% + * Finds the key that generated a RRSIG, if possible. First look at the keys + * that we've loaded already, and then see if there's a key on disk. + */ +static signer_key_t * +keythatsigned(dns_rdata_rrsig_t *rrsig) { + isc_result_t result; + dst_key_t *pubkey = NULL, *privkey = NULL; + signer_key_t *key; + + key = ISC_LIST_HEAD(keylist); + while (key != NULL) { + if (rrsig->keyid == dst_key_id(key->key) && + rrsig->algorithm == dst_key_alg(key->key) && + dns_name_equal(&rrsig->signer, dst_key_name(key->key))) + return key; + key = ISC_LIST_NEXT(key, link); + } + + result = dst_key_fromfile(&rrsig->signer, rrsig->keyid, + rrsig->algorithm, DST_TYPE_PUBLIC, + NULL, mctx, &pubkey); + if (result != ISC_R_SUCCESS) + return (NULL); + + result = dst_key_fromfile(&rrsig->signer, rrsig->keyid, + rrsig->algorithm, + DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, + NULL, mctx, &privkey); + if (result == ISC_R_SUCCESS) { + dst_key_free(&pubkey); + key = newkeystruct(privkey, ISC_FALSE); + } else + key = newkeystruct(pubkey, ISC_FALSE); + ISC_LIST_APPEND(keylist, key, link); + return (key); +} + +/*% + * Check to see if we expect to find a key at this name. If we see a RRSIG + * and can't find the signing key that we expect to find, we drop the rrsig. + * I'm not sure if this is completely correct, but it seems to work. + */ +static isc_boolean_t +expecttofindkey(dns_name_t *name) { + unsigned int options = DNS_DBFIND_NOWILD; + dns_fixedname_t fname; + isc_result_t result; + char namestr[DNS_NAME_FORMATSIZE]; + + dns_fixedname_init(&fname); + result = dns_db_find(gdb, name, gversion, dns_rdatatype_dnskey, options, + 0, NULL, dns_fixedname_name(&fname), NULL, NULL); + switch (result) { + case ISC_R_SUCCESS: + case DNS_R_NXDOMAIN: + case DNS_R_NXRRSET: + return (ISC_TRUE); + case DNS_R_DELEGATION: + case DNS_R_CNAME: + case DNS_R_DNAME: + return (ISC_FALSE); + } + dns_name_format(name, namestr, sizeof(namestr)); + fatal("failure looking for '%s DNSKEY' in database: %s", + namestr, isc_result_totext(result)); + return (ISC_FALSE); /* removes a warning */ +} + +static inline isc_boolean_t +setverifies(dns_name_t *name, dns_rdataset_t *set, signer_key_t *key, + dns_rdata_t *rrsig) +{ + isc_result_t result; + result = dns_dnssec_verify(name, set, key->key, ISC_FALSE, mctx, rrsig); + if (result == ISC_R_SUCCESS) { + INCSTAT(nverified); + return (ISC_TRUE); + } else { + INCSTAT(nverifyfailed); + return (ISC_FALSE); + } +} + +/*% + * Signs a set. Goes through contortions to decide if each RRSIG should + * be dropped or retained, and then determines if any new SIGs need to + * be generated. + */ +static void +signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name, + dns_rdataset_t *set) +{ + dns_rdataset_t sigset; + dns_rdata_t sigrdata = DNS_RDATA_INIT; + dns_rdata_rrsig_t rrsig; + signer_key_t *key; + isc_result_t result; + isc_boolean_t nosigs = ISC_FALSE; + isc_boolean_t *wassignedby, *nowsignedby; + int arraysize; + dns_difftuple_t *tuple; + dns_ttl_t ttl; + int i; + char namestr[DNS_NAME_FORMATSIZE]; + char typestr[TYPE_FORMATSIZE]; + char sigstr[SIG_FORMATSIZE]; + + dns_name_format(name, namestr, sizeof(namestr)); + type_format(set->type, typestr, sizeof(typestr)); + + ttl = ISC_MIN(set->ttl, endtime - starttime); + + dns_rdataset_init(&sigset); + result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_rrsig, + set->type, 0, &sigset, NULL); + if (result == ISC_R_NOTFOUND) { + result = ISC_R_SUCCESS; + nosigs = ISC_TRUE; + } + if (result != ISC_R_SUCCESS) + fatal("failed while looking for '%s RRSIG %s': %s", + namestr, typestr, isc_result_totext(result)); + + vbprintf(1, "%s/%s:\n", namestr, typestr); + + arraysize = keycount; + if (!nosigs) + arraysize += dns_rdataset_count(&sigset); + wassignedby = isc_mem_get(mctx, arraysize * sizeof(isc_boolean_t)); + nowsignedby = isc_mem_get(mctx, arraysize * sizeof(isc_boolean_t)); + if (wassignedby == NULL || nowsignedby == NULL) + fatal("out of memory"); + + for (i = 0; i < arraysize; i++) + wassignedby[i] = nowsignedby[i] = ISC_FALSE; + + if (nosigs) + result = ISC_R_NOMORE; + else + result = dns_rdataset_first(&sigset); + + while (result == ISC_R_SUCCESS) { + isc_boolean_t expired, future; + isc_boolean_t keep = ISC_FALSE, resign = ISC_FALSE; + + dns_rdataset_current(&sigset, &sigrdata); + + result = dns_rdata_tostruct(&sigrdata, &rrsig, NULL); + check_result(result, "dns_rdata_tostruct"); + + future = isc_serial_lt(now, rrsig.timesigned); + + key = keythatsigned(&rrsig); + sig_format(&rrsig, sigstr, sizeof(sigstr)); + if (key != NULL && issigningkey(key)) + expired = isc_serial_gt(now + cycle, rrsig.timeexpire); + else + expired = isc_serial_gt(now, rrsig.timeexpire); + + if (isc_serial_gt(rrsig.timesigned, rrsig.timeexpire)) { + /* rrsig is dropped and not replaced */ + vbprintf(2, "\trrsig by %s dropped - " + "invalid validity period\n", + sigstr); + } else if (key == NULL && !future && + expecttofindkey(&rrsig.signer)) + { + /* rrsig is dropped and not replaced */ + vbprintf(2, "\trrsig by %s dropped - " + "private dnskey not found\n", + sigstr); + } else if (key == NULL || future) { + vbprintf(2, "\trrsig by %s %s - dnskey not found\n", + expired ? "retained" : "dropped", sigstr); + if (!expired) + keep = ISC_TRUE; + } else if (issigningkey(key)) { + if (!expired && setverifies(name, set, key, &sigrdata)) + { + vbprintf(2, "\trrsig by %s retained\n", sigstr); + keep = ISC_TRUE; + wassignedby[key->position] = ISC_TRUE; + nowsignedby[key->position] = ISC_TRUE; + } else { + vbprintf(2, "\trrsig by %s dropped - %s\n", + sigstr, + expired ? "expired" : + "failed to verify"); + wassignedby[key->position] = ISC_TRUE; + resign = ISC_TRUE; + } + } else if (iszonekey(key)) { + if (!expired && setverifies(name, set, key, &sigrdata)) + { + vbprintf(2, "\trrsig by %s retained\n", sigstr); + keep = ISC_TRUE; + wassignedby[key->position] = ISC_TRUE; + nowsignedby[key->position] = ISC_TRUE; + } else { + vbprintf(2, "\trrsig by %s dropped - %s\n", + sigstr, + expired ? "expired" : + "failed to verify"); + wassignedby[key->position] = ISC_TRUE; + } + } else if (!expired) { + vbprintf(2, "\trrsig by %s retained\n", sigstr); + keep = ISC_TRUE; + } else { + vbprintf(2, "\trrsig by %s expired\n", sigstr); + } + + if (keep) { + nowsignedby[key->position] = ISC_TRUE; + INCSTAT(nretained); + if (sigset.ttl != ttl) { + vbprintf(2, "\tfixing ttl %s\n", sigstr); + tuple = NULL; + result = dns_difftuple_create(mctx, + DNS_DIFFOP_DEL, + name, sigset.ttl, + &sigrdata, + &tuple); + check_result(result, "dns_difftuple_create"); + dns_diff_append(del, &tuple); + result = dns_difftuple_create(mctx, + DNS_DIFFOP_ADD, + name, ttl, + &sigrdata, + &tuple); + check_result(result, "dns_difftuple_create"); + dns_diff_append(add, &tuple); + } + } else { + tuple = NULL; + result = dns_difftuple_create(mctx, DNS_DIFFOP_DEL, + name, sigset.ttl, + &sigrdata, &tuple); + check_result(result, "dns_difftuple_create"); + dns_diff_append(del, &tuple); + INCSTAT(ndropped); + } + + if (resign) { + isc_buffer_t b; + dns_rdata_t trdata = DNS_RDATA_INIT; + unsigned char array[BUFSIZE]; + char keystr[KEY_FORMATSIZE]; + + INSIST(!keep); + + key_format(key->key, keystr, sizeof(keystr)); + vbprintf(1, "\tresigning with dnskey %s\n", keystr); + isc_buffer_init(&b, array, sizeof(array)); + signwithkey(name, set, &trdata, key->key, &b); + nowsignedby[key->position] = ISC_TRUE; + tuple = NULL; + result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, + name, ttl, &trdata, + &tuple); + check_result(result, "dns_difftuple_create"); + dns_diff_append(add, &tuple); + } + + dns_rdata_reset(&sigrdata); + dns_rdata_freestruct(&rrsig); + result = dns_rdataset_next(&sigset); + } + if (result == ISC_R_NOMORE) + result = ISC_R_SUCCESS; + + check_result(result, "dns_rdataset_first/next"); + if (dns_rdataset_isassociated(&sigset)) + dns_rdataset_disassociate(&sigset); + + for (key = ISC_LIST_HEAD(keylist); + key != NULL; + key = ISC_LIST_NEXT(key, link)) + { + isc_buffer_t b; + dns_rdata_t trdata; + unsigned char array[BUFSIZE]; + char keystr[KEY_FORMATSIZE]; + + if (nowsignedby[key->position]) + continue; + + if (!key->issigningkey) + continue; + if (!(ignoreksk || key->isdsk || + (key->isksk && + set->type == dns_rdatatype_dnskey && + dns_name_equal(name, gorigin)))) + continue; + + key_format(key->key, keystr, sizeof(keystr)); + vbprintf(1, "\tsigning with dnskey %s\n", keystr); + dns_rdata_init(&trdata); + isc_buffer_init(&b, array, sizeof(array)); + signwithkey(name, set, &trdata, key->key, &b); + tuple = NULL; + result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, + ttl, &trdata, &tuple); + check_result(result, "dns_difftuple_create"); + dns_diff_append(add, &tuple); + } + + isc_mem_put(mctx, wassignedby, arraysize * sizeof(isc_boolean_t)); + isc_mem_put(mctx, nowsignedby, arraysize * sizeof(isc_boolean_t)); +} + +static void +opendb(const char *prefix, dns_name_t *name, dns_rdataclass_t rdclass, + dns_db_t **dbp) +{ + char filename[256]; + isc_buffer_t b; + isc_result_t result; + + isc_buffer_init(&b, filename, sizeof(filename)); + if (directory != NULL) { + isc_buffer_putstr(&b, directory); + if (directory[strlen(directory) - 1] != '/') + isc_buffer_putstr(&b, "/"); + } + isc_buffer_putstr(&b, prefix); + result = dns_name_tofilenametext(name, ISC_FALSE, &b); + check_result(result, "dns_name_tofilenametext()"); + if (isc_buffer_availablelength(&b) == 0) { + char namestr[DNS_NAME_FORMATSIZE]; + dns_name_format(name, namestr, sizeof(namestr)); + fatal("name '%s' is too long", namestr); + } + isc_buffer_putuint8(&b, 0); + + result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, + rdclass, 0, NULL, dbp); + check_result(result, "dns_db_create()"); + + result = dns_db_load(*dbp, filename); + if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) + dns_db_detach(dbp); +} + +/*% + * Loads the key set for a child zone, if there is one, and builds DS records. + */ +static isc_result_t +loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) { + dns_db_t *db = NULL; + dns_dbversion_t *ver = NULL; + dns_dbnode_t *node = NULL; + isc_result_t result; + dns_rdataset_t keyset; + dns_rdata_t key, ds; + unsigned char dsbuf[DNS_DS_BUFFERSIZE]; + dns_diff_t diff; + dns_difftuple_t *tuple = NULL; + + opendb("keyset-", name, gclass, &db); + if (db == NULL) + return (ISC_R_NOTFOUND); + + result = dns_db_findnode(db, name, ISC_FALSE, &node); + if (result != ISC_R_SUCCESS) { + dns_db_detach(&db); + return (DNS_R_BADDB); + } + dns_rdataset_init(&keyset); + result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, 0, + &keyset, NULL); + if (result != ISC_R_SUCCESS) { + dns_db_detachnode(db, &node); + dns_db_detach(&db); + return (result); + } + + vbprintf(2, "found DNSKEY records\n"); + + result = dns_db_newversion(db, &ver); + check_result(result, "dns_db_newversion"); + + dns_diff_init(mctx, &diff); + + for (result = dns_rdataset_first(&keyset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(&keyset)) + { + dns_rdata_init(&key); + dns_rdata_init(&ds); + dns_rdataset_current(&keyset, &key); + result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA1, + dsbuf, &ds); + check_result(result, "dns_ds_buildrdata"); + + result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, + ttl, &ds, &tuple); + check_result(result, "dns_difftuple_create"); + dns_diff_append(&diff, &tuple); + + dns_rdata_reset(&ds); + result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA256, + dsbuf, &ds); + check_result(result, "dns_ds_buildrdata"); + + result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, + ttl, &ds, &tuple); + check_result(result, "dns_difftuple_create"); + dns_diff_append(&diff, &tuple); + } + result = dns_diff_apply(&diff, db, ver); + check_result(result, "dns_diff_apply"); + dns_diff_clear(&diff); + + dns_db_closeversion(db, &ver, ISC_TRUE); + + result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ds, 0, 0, + dsset, NULL); + check_result(result, "dns_db_findrdataset"); + + dns_rdataset_disassociate(&keyset); + dns_db_detachnode(db, &node); + dns_db_detach(&db); + return (result); +} + +static isc_boolean_t +nsec_setbit(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdatatype_t type, + unsigned int val) +{ + isc_result_t result; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdata_nsec_t nsec; + unsigned int newlen; + unsigned char bitmap[8192 + 512]; + unsigned char nsecdata[8192 + 512 + DNS_NAME_MAXWIRE]; + isc_boolean_t answer = ISC_FALSE; + unsigned int i, len, window; + int octet; + + result = dns_rdataset_first(rdataset); + check_result(result, "dns_rdataset_first()"); + dns_rdataset_current(rdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &nsec, NULL); + check_result(result, "dns_rdata_tostruct"); + + INSIST(nsec.len <= sizeof(bitmap)); + + newlen = 0; + + memset(bitmap, 0, sizeof(bitmap)); + for (i = 0; i < nsec.len; i += len) { + INSIST(i + 2 <= nsec.len); + window = nsec.typebits[i]; + len = nsec.typebits[i+1]; + i += 2; + INSIST(len > 0 && len <= 32); + INSIST(i + len <= nsec.len); + memmove(&bitmap[window * 32 + 512], &nsec.typebits[i], len); + } + set_bit(bitmap + 512, type, val); + for (window = 0; window < 256; window++) { + for (octet = 31; octet >= 0; octet--) + if (bitmap[window * 32 + 512 + octet] != 0) + break; + if (octet < 0) + continue; + bitmap[newlen] = window; + bitmap[newlen + 1] = octet + 1; + newlen += 2; + /* + * Overlapping move. + */ + memmove(&bitmap[newlen], &bitmap[window * 32 + 512], octet + 1); + newlen += octet + 1; + } + if (newlen != nsec.len || + memcmp(nsec.typebits, bitmap, newlen) != 0) { + dns_rdata_t newrdata = DNS_RDATA_INIT; + isc_buffer_t b; + dns_diff_t diff; + dns_difftuple_t *tuple = NULL; + + dns_diff_init(mctx, &diff); + result = dns_difftuple_create(mctx, DNS_DIFFOP_DEL, name, + rdataset->ttl, &rdata, &tuple); + check_result(result, "dns_difftuple_create"); + dns_diff_append(&diff, &tuple); + + nsec.typebits = bitmap; + nsec.len = newlen; + isc_buffer_init(&b, nsecdata, sizeof(nsecdata)); + result = dns_rdata_fromstruct(&newrdata, rdata.rdclass, + dns_rdatatype_nsec, &nsec, + &b); + check_result(result, "dns_rdata_fromstruct"); + + result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, + name, rdataset->ttl, + &newrdata, &tuple); + check_result(result, "dns_difftuple_create"); + dns_diff_append(&diff, &tuple); + result = dns_diff_apply(&diff, gdb, gversion); + check_result(result, "dns_difftuple_apply"); + dns_diff_clear(&diff); + answer = ISC_TRUE; + } + dns_rdata_freestruct(&nsec); + return (answer); +} + +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)); +} + +/*% + * Signs all records at a name. This mostly just signs each set individually, + * but also adds the RRSIG bit to any NSECs generated earlier, deals with + * parent/child KEY signatures, and handles other exceptional cases. + */ +static void +signname(dns_dbnode_t *node, dns_name_t *name) { + isc_result_t result; + dns_rdataset_t rdataset; + dns_rdatasetiter_t *rdsiter; + isc_boolean_t isdelegation = ISC_FALSE; + isc_boolean_t hasds = ISC_FALSE; + isc_boolean_t changed = ISC_FALSE; + dns_diff_t del, add; + char namestr[DNS_NAME_FORMATSIZE]; + isc_uint32_t nsttl = 0; + + dns_name_format(name, namestr, sizeof(namestr)); + + /* + * Determine if this is a delegation point. + */ + if (delegation(name, node, &nsttl)) + isdelegation = ISC_TRUE; + + /* + * If this is a delegation point, look for a DS set. + */ + if (isdelegation) { + dns_rdataset_t dsset; + dns_rdataset_t sigdsset; + + dns_rdataset_init(&dsset); + dns_rdataset_init(&sigdsset); + result = dns_db_findrdataset(gdb, node, gversion, + dns_rdatatype_ds, + 0, 0, &dsset, &sigdsset); + if (result == ISC_R_SUCCESS) { + dns_rdataset_disassociate(&dsset); + if (generateds) { + result = dns_db_deleterdataset(gdb, node, + gversion, + dns_rdatatype_ds, + 0); + check_result(result, "dns_db_deleterdataset"); + } else + hasds = ISC_TRUE; + } + if (generateds) { + result = loadds(name, nsttl, &dsset); + if (result == ISC_R_SUCCESS) { + result = dns_db_addrdataset(gdb, node, + gversion, 0, + &dsset, 0, NULL); + check_result(result, "dns_db_addrdataset"); + hasds = ISC_TRUE; + dns_rdataset_disassociate(&dsset); + if (dns_rdataset_isassociated(&sigdsset)) + dns_rdataset_disassociate(&sigdsset); + } else if (dns_rdataset_isassociated(&sigdsset)) { + result = dns_db_deleterdataset(gdb, node, + gversion, + dns_rdatatype_rrsig, + dns_rdatatype_ds); + check_result(result, "dns_db_deleterdataset"); + dns_rdataset_disassociate(&sigdsset); + } + } else if (dns_rdataset_isassociated(&sigdsset)) + dns_rdataset_disassociate(&sigdsset); + } + + /* + * Make sure that NSEC bits are appropriately set. + */ + dns_rdataset_init(&rdataset); + RUNTIME_CHECK(dns_db_findrdataset(gdb, node, gversion, + dns_rdatatype_nsec, 0, 0, &rdataset, + NULL) == ISC_R_SUCCESS); + if (!nokeys) + changed = nsec_setbit(name, &rdataset, dns_rdatatype_rrsig, 1); + if (changed) { + dns_rdataset_disassociate(&rdataset); + RUNTIME_CHECK(dns_db_findrdataset(gdb, node, gversion, + dns_rdatatype_nsec, 0, 0, + &rdataset, + NULL) == ISC_R_SUCCESS); + } + if (hasds) + (void)nsec_setbit(name, &rdataset, dns_rdatatype_ds, 1); + else + (void)nsec_setbit(name, &rdataset, dns_rdatatype_ds, 0); + dns_rdataset_disassociate(&rdataset); + + /* + * Now iterate through the rdatasets. + */ + dns_diff_init(mctx, &del); + dns_diff_init(mctx, &add); + rdsiter = NULL; + result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); + check_result(result, "dns_db_allrdatasets()"); + result = dns_rdatasetiter_first(rdsiter); + while (result == ISC_R_SUCCESS) { + dns_rdatasetiter_current(rdsiter, &rdataset); + + /* If this is a RRSIG set, skip it. */ + if (rdataset.type == dns_rdatatype_rrsig) + goto skip; + + /* + * If this name is a delegation point, skip all records + * except NSEC and DS sets. Otherwise check that there + * isn't a DS record. + */ + if (isdelegation) { + if (rdataset.type != dns_rdatatype_nsec && + rdataset.type != dns_rdatatype_ds) + goto skip; + } else if (rdataset.type == dns_rdatatype_ds) { + char namebuf[DNS_NAME_FORMATSIZE]; + dns_name_format(name, namebuf, sizeof(namebuf)); + fatal("'%s': found DS RRset without NS RRset\n", + namebuf); + } + + signset(&del, &add, node, name, &rdataset); + + skip: + dns_rdataset_disassociate(&rdataset); + result = dns_rdatasetiter_next(rdsiter); + } + if (result != ISC_R_NOMORE) + fatal("rdataset iteration for name '%s' failed: %s", + namestr, isc_result_totext(result)); + + dns_rdatasetiter_destroy(&rdsiter); + + result = dns_diff_applysilently(&del, gdb, gversion); + if (result != ISC_R_SUCCESS) + fatal("failed to delete SIGs at node '%s': %s", + namestr, isc_result_totext(result)); + + result = dns_diff_applysilently(&add, gdb, gversion); + if (result != ISC_R_SUCCESS) + fatal("failed to add SIGs at node '%s': %s", + namestr, isc_result_totext(result)); + + dns_diff_clear(&del); + dns_diff_clear(&add); +} + +static inline isc_boolean_t +active_node(dns_dbnode_t *node) { + dns_rdatasetiter_t *rdsiter = NULL; + dns_rdatasetiter_t *rdsiter2 = NULL; + isc_boolean_t active = ISC_FALSE; + isc_result_t result; + dns_rdataset_t rdataset; + dns_rdatatype_t type; + dns_rdatatype_t covers; + isc_boolean_t found; + + dns_rdataset_init(&rdataset); + result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); + check_result(result, "dns_db_allrdatasets()"); + result = dns_rdatasetiter_first(rdsiter); + while (result == ISC_R_SUCCESS) { + dns_rdatasetiter_current(rdsiter, &rdataset); + if (rdataset.type != dns_rdatatype_nsec && + rdataset.type != dns_rdatatype_rrsig) + active = ISC_TRUE; + dns_rdataset_disassociate(&rdataset); + if (!active) + result = dns_rdatasetiter_next(rdsiter); + else + result = ISC_R_NOMORE; + } + if (result != ISC_R_NOMORE) + fatal("rdataset iteration failed: %s", + isc_result_totext(result)); + + if (!active) { + /*% + * The node is empty of everything but NSEC / RRSIG records. + */ + for (result = dns_rdatasetiter_first(rdsiter); + result == ISC_R_SUCCESS; + result = dns_rdatasetiter_next(rdsiter)) { + dns_rdatasetiter_current(rdsiter, &rdataset); + result = dns_db_deleterdataset(gdb, node, gversion, + rdataset.type, + rdataset.covers); + check_result(result, "dns_db_deleterdataset()"); + dns_rdataset_disassociate(&rdataset); + } + if (result != ISC_R_NOMORE) + fatal("rdataset iteration failed: %s", + isc_result_totext(result)); + } else { + /* + * Delete RRSIGs for types that no longer exist. + */ + result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter2); + 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, &rdataset); + type = rdataset.type; + covers = rdataset.covers; + dns_rdataset_disassociate(&rdataset); + if (type != dns_rdatatype_rrsig) + continue; + found = ISC_FALSE; + for (result = dns_rdatasetiter_first(rdsiter2); + !found && result == ISC_R_SUCCESS; + result = dns_rdatasetiter_next(rdsiter2)) { + dns_rdatasetiter_current(rdsiter2, &rdataset); + if (rdataset.type == covers) + found = ISC_TRUE; + dns_rdataset_disassociate(&rdataset); + } + if (!found) { + if (result != ISC_R_NOMORE) + fatal("rdataset iteration failed: %s", + isc_result_totext(result)); + result = dns_db_deleterdataset(gdb, node, + gversion, type, + covers); + check_result(result, + "dns_db_deleterdataset(rrsig)"); + } else if (result != ISC_R_NOMORE && + result != ISC_R_SUCCESS) + fatal("rdataset iteration failed: %s", + isc_result_totext(result)); + } + if (result != ISC_R_NOMORE) + fatal("rdataset iteration failed: %s", + isc_result_totext(result)); + dns_rdatasetiter_destroy(&rdsiter2); + } + dns_rdatasetiter_destroy(&rdsiter); + + return (active); +} + +/*% + * Extracts the TTL from the SOA. + */ +static dns_ttl_t +soattl(void) { + dns_rdataset_t soaset; + dns_fixedname_t fname; + dns_name_t *name; + isc_result_t result; + dns_ttl_t ttl; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdata_soa_t soa; + + dns_fixedname_init(&fname); + name = dns_fixedname_name(&fname); + dns_rdataset_init(&soaset); + result = dns_db_find(gdb, gorigin, gversion, dns_rdatatype_soa, + 0, 0, NULL, name, &soaset, NULL); + if (result != ISC_R_SUCCESS) + fatal("failed to find an SOA at the zone apex: %s", + isc_result_totext(result)); + + result = dns_rdataset_first(&soaset); + check_result(result, "dns_rdataset_first"); + dns_rdataset_current(&soaset, &rdata); + result = dns_rdata_tostruct(&rdata, &soa, NULL); + check_result(result, "dns_rdata_tostruct"); + ttl = soa.minimum; + dns_rdataset_disassociate(&soaset); + return (ttl); +} + +/*% + * Increment (or set if nonzero) the SOA serial + */ +static isc_result_t +setsoaserial(isc_uint32_t serial) { + isc_result_t result; + dns_dbnode_t *node = NULL; + dns_rdataset_t rdataset; + dns_rdata_t rdata = DNS_RDATA_INIT; + isc_uint32_t old_serial, new_serial; + + result = dns_db_getoriginnode(gdb, &node); + if (result != ISC_R_SUCCESS) + return result; + + dns_rdataset_init(&rdataset); + + result = dns_db_findrdataset(gdb, node, gversion, + dns_rdatatype_soa, 0, + 0, &rdataset, NULL); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = dns_rdataset_first(&rdataset); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + dns_rdataset_current(&rdataset, &rdata); + + old_serial = dns_soa_getserial(&rdata); + + if (serial) { + /* Set SOA serial to the value provided. */ + new_serial = serial; + } else { + /* Increment SOA serial using RFC 1982 arithmetics */ + new_serial = (old_serial + 1) & 0xFFFFFFFF; + if (new_serial == 0) + new_serial = 1; + } + + /* If the new serial is not likely to cause a zone transfer + * (a/ixfr) from servers having the old serial, warn the user. + * + * RFC1982 section 7 defines the maximum increment to be + * (2^(32-1))-1. Using u_int32_t arithmetic, we can do a single + * comparison. (5 - 6 == (2^32)-1, not negative-one) + */ + if (new_serial == old_serial || + (new_serial - old_serial) > 0x7fffffffU) + fprintf(stderr, "%s: warning: Serial number not advanced, " + "zone may not transfer\n", program); + + dns_soa_setserial(new_serial, &rdata); + + result = dns_db_deleterdataset(gdb, node, gversion, + dns_rdatatype_soa, 0); + check_result(result, "dns_db_deleterdataset"); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = dns_db_addrdataset(gdb, node, gversion, + 0, &rdataset, 0, NULL); + check_result(result, "dns_db_addrdataset"); + if (result != ISC_R_SUCCESS) + goto cleanup; + +cleanup: + dns_rdataset_disassociate(&rdataset); + if (node != NULL) + dns_db_detachnode(gdb, &node); + dns_rdata_reset(&rdata); + + return (result); +} + +/*% + * Delete any RRSIG records at a node. + */ +static void +cleannode(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node) { + dns_rdatasetiter_t *rdsiter = NULL; + dns_rdataset_t set; + isc_result_t result, dresult; + + if (outputformat != dns_masterformat_text) + return; + + dns_rdataset_init(&set); + result = dns_db_allrdatasets(db, node, version, 0, &rdsiter); + check_result(result, "dns_db_allrdatasets"); + result = dns_rdatasetiter_first(rdsiter); + while (result == ISC_R_SUCCESS) { + isc_boolean_t destroy = ISC_FALSE; + dns_rdatatype_t covers = 0; + dns_rdatasetiter_current(rdsiter, &set); + if (set.type == dns_rdatatype_rrsig) { + covers = set.covers; + destroy = ISC_TRUE; + } + dns_rdataset_disassociate(&set); + result = dns_rdatasetiter_next(rdsiter); + if (destroy) { + dresult = dns_db_deleterdataset(db, node, version, + dns_rdatatype_rrsig, + covers); + check_result(dresult, "dns_db_deleterdataset"); + } + } + if (result != ISC_R_NOMORE) + fatal("rdataset iteration failed: %s", + isc_result_totext(result)); + dns_rdatasetiter_destroy(&rdsiter); +} + +/*% + * Set up the iterator and global state before starting the tasks. + */ +static void +presign(void) { + isc_result_t result; + + gdbiter = NULL; + result = dns_db_createiterator(gdb, ISC_FALSE, &gdbiter); + check_result(result, "dns_db_createiterator()"); + + result = dns_dbiterator_first(gdbiter); + check_result(result, "dns_dbiterator_first()"); +} + +/*% + * Clean up the iterator and global state after the tasks complete. + */ +static void +postsign(void) { + dns_dbiterator_destroy(&gdbiter); +} + +/*% + * Sign the apex of the zone. + */ +static void +signapex(void) { + dns_dbnode_t *node = NULL; + dns_fixedname_t fixed; + dns_name_t *name; + isc_result_t result; + + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + result = dns_dbiterator_current(gdbiter, &node, name); + check_result(result, "dns_dbiterator_current()"); + signname(node, name); + dumpnode(name, node); + cleannode(gdb, gversion, node); + dns_db_detachnode(gdb, &node); + result = dns_dbiterator_next(gdbiter); + if (result == ISC_R_NOMORE) + finished = ISC_TRUE; + else if (result != ISC_R_SUCCESS) + fatal("failure iterating database: %s", + isc_result_totext(result)); +} + +/*% + * Assigns a node to a worker thread. This is protected by the master task's + * lock. + */ +static void +assignwork(isc_task_t *task, isc_task_t *worker) { + dns_fixedname_t *fname; + dns_name_t *name; + dns_dbnode_t *node; + sevent_t *sevent; + dns_rdataset_t nsec; + isc_boolean_t found; + isc_result_t result; + + if (shuttingdown) + return; + + if (finished) { + if (assigned == completed) { + isc_task_detach(&task); + isc_app_shutdown(); + } + return; + } + + fname = isc_mem_get(mctx, sizeof(dns_fixedname_t)); + if (fname == NULL) + fatal("out of memory"); + dns_fixedname_init(fname); + name = dns_fixedname_name(fname); + node = NULL; + found = ISC_FALSE; + LOCK(&namelock); + while (!found) { + result = dns_dbiterator_current(gdbiter, &node, name); + if (result != ISC_R_SUCCESS) + fatal("failure iterating database: %s", + isc_result_totext(result)); + dns_rdataset_init(&nsec); + result = dns_db_findrdataset(gdb, node, gversion, + dns_rdatatype_nsec, 0, 0, + &nsec, NULL); + if (result == ISC_R_SUCCESS) + found = ISC_TRUE; + else + dumpnode(name, node); + if (dns_rdataset_isassociated(&nsec)) + dns_rdataset_disassociate(&nsec); + if (!found) + dns_db_detachnode(gdb, &node); + + result = dns_dbiterator_next(gdbiter); + if (result == ISC_R_NOMORE) { + finished = ISC_TRUE; + break; + } else if (result != ISC_R_SUCCESS) + fatal("failure iterating database: %s", + isc_result_totext(result)); + } + UNLOCK(&namelock); + if (!found) { + if (assigned == completed) { + isc_task_detach(&task); + isc_app_shutdown(); + } + isc_mem_put(mctx, fname, sizeof(dns_fixedname_t)); + return; + } + sevent = (sevent_t *) + isc_event_allocate(mctx, task, SIGNER_EVENT_WORK, + sign, NULL, sizeof(sevent_t)); + if (sevent == NULL) + fatal("failed to allocate event\n"); + + sevent->node = node; + sevent->fname = fname; + isc_task_send(worker, ISC_EVENT_PTR(&sevent)); + assigned++; +} + +/*% + * Start a worker task + */ +static void +startworker(isc_task_t *task, isc_event_t *event) { + isc_task_t *worker; + + worker = (isc_task_t *)event->ev_arg; + assignwork(task, worker); + isc_event_free(&event); +} + +/*% + * Write a node to the output file, and restart the worker task. + */ +static void +writenode(isc_task_t *task, isc_event_t *event) { + isc_task_t *worker; + sevent_t *sevent = (sevent_t *)event; + + completed++; + worker = (isc_task_t *)event->ev_sender; + dumpnode(dns_fixedname_name(sevent->fname), sevent->node); + cleannode(gdb, gversion, sevent->node); + dns_db_detachnode(gdb, &sevent->node); + isc_mem_put(mctx, sevent->fname, sizeof(dns_fixedname_t)); + assignwork(task, worker); + isc_event_free(&event); +} + +/*% + * Sign a database node. + */ +static void +sign(isc_task_t *task, isc_event_t *event) { + dns_fixedname_t *fname; + dns_dbnode_t *node; + sevent_t *sevent, *wevent; + + sevent = (sevent_t *)event; + node = sevent->node; + fname = sevent->fname; + isc_event_free(&event); + + signname(node, dns_fixedname_name(fname)); + wevent = (sevent_t *) + isc_event_allocate(mctx, task, SIGNER_EVENT_WRITE, + writenode, NULL, sizeof(sevent_t)); + if (wevent == NULL) + fatal("failed to allocate event\n"); + wevent->node = node; + wevent->fname = fname; + isc_task_send(master, ISC_EVENT_PTR(&wevent)); +} + +/*% + * Generate NSEC records for the zone. + */ +static void +nsecify(void) { + dns_dbiterator_t *dbiter = NULL; + dns_dbnode_t *node = NULL, *nextnode = NULL; + dns_fixedname_t fname, fnextname, fzonecut; + dns_name_t *name, *nextname, *zonecut; + isc_boolean_t done = ISC_FALSE; + isc_result_t result; + + 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, ISC_FALSE, &dbiter); + check_result(result, "dns_db_createiterator()"); + + result = dns_dbiterator_first(dbiter); + check_result(result, "dns_dbiterator_first()"); + + while (!done) { + dns_dbiterator_current(dbiter, &node, name); + if (delegation(name, node, NULL)) { + zonecut = dns_fixedname_name(&fzonecut); + dns_name_copy(name, zonecut, NULL); + } + result = dns_dbiterator_next(dbiter); + nextnode = NULL; + while (result == ISC_R_SUCCESS) { + isc_boolean_t active = ISC_FALSE; + result = dns_dbiterator_current(dbiter, &nextnode, + nextname); + if (result != ISC_R_SUCCESS) + break; + active = active_node(nextnode); + if (!active) { + dns_db_detachnode(gdb, &nextnode); + result = dns_dbiterator_next(dbiter); + continue; + } + 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) { + dns_name_clone(gorigin, nextname); + done = ISC_TRUE; + } else if (result != ISC_R_SUCCESS) + fatal("iterating through the database failed: %s", + isc_result_totext(result)); + result = dns_nsec_build(gdb, gversion, node, nextname, + zonettl); + check_result(result, "dns_nsec_build()"); + dns_db_detachnode(gdb, &node); + } + + dns_dbiterator_destroy(&dbiter); +} + +/*% + * Load the zone file from disk + */ +static void +loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) { + isc_buffer_t b; + int len; + dns_fixedname_t fname; + dns_name_t *name; + isc_result_t result; + + len = strlen(origin); + isc_buffer_init(&b, origin, len); + isc_buffer_add(&b, len); + + dns_fixedname_init(&fname); + name = dns_fixedname_name(&fname); + result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL); + if (result != ISC_R_SUCCESS) + fatal("failed converting name '%s' to dns format: %s", + origin, isc_result_totext(result)); + + result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone, + rdclass, 0, NULL, db); + check_result(result, "dns_db_create()"); + + result = dns_db_load2(*db, file, inputformat); + if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) + fatal("failed loading zone from '%s': %s", + file, isc_result_totext(result)); +} + +/*% + * Finds all public zone keys in the zone, and attempts to load the + * private keys from disk. + */ +static void +loadzonekeys(dns_db_t *db) { + dns_dbnode_t *node; + dns_dbversion_t *currentversion; + isc_result_t result; + dst_key_t *keys[20]; + unsigned int nkeys, i; + + currentversion = NULL; + dns_db_currentversion(db, ¤tversion); + + node = NULL; + result = dns_db_findnode(db, gorigin, ISC_FALSE, &node); + if (result != ISC_R_SUCCESS) + fatal("failed to find the zone's origin: %s", + isc_result_totext(result)); + + result = dns_dnssec_findzonekeys(db, currentversion, node, gorigin, + mctx, 20, keys, &nkeys); + if (result == ISC_R_NOTFOUND) + result = ISC_R_SUCCESS; + if (result != ISC_R_SUCCESS) + fatal("failed to find the zone keys: %s", + isc_result_totext(result)); + + for (i = 0; i < nkeys; i++) { + signer_key_t *key; + + key = newkeystruct(keys[i], dst_key_isprivate(keys[i])); + ISC_LIST_APPEND(keylist, key, link); + } + dns_db_detachnode(db, &node); + dns_db_closeversion(db, ¤tversion, ISC_FALSE); +} + +/*% + * Finds all public zone keys in the zone. + */ +static void +loadzonepubkeys(dns_db_t *db) { + dns_dbversion_t *currentversion = NULL; + dns_dbnode_t *node = NULL; + dns_rdataset_t rdataset; + dns_rdata_t rdata = DNS_RDATA_INIT; + dst_key_t *pubkey; + signer_key_t *key; + isc_result_t result; + + dns_db_currentversion(db, ¤tversion); + + result = dns_db_findnode(db, 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(&rdataset); + result = dns_db_findrdataset(db, node, currentversion, + dns_rdatatype_dnskey, 0, 0, &rdataset, NULL); + if (result != ISC_R_SUCCESS) + fatal("failed to find keys at the zone apex: %s", + isc_result_totext(result)); + result = dns_rdataset_first(&rdataset); + check_result(result, "dns_rdataset_first"); + while (result == ISC_R_SUCCESS) { + pubkey = NULL; + dns_rdata_reset(&rdata); + dns_rdataset_current(&rdataset, &rdata); + result = dns_dnssec_keyfromrdata(gorigin, &rdata, mctx, + &pubkey); + if (result != ISC_R_SUCCESS) + goto next; + if (!dst_key_iszonekey(pubkey)) { + dst_key_free(&pubkey); + goto next; + } + + key = newkeystruct(pubkey, ISC_FALSE); + ISC_LIST_APPEND(keylist, key, link); + next: + result = dns_rdataset_next(&rdataset); + } + dns_rdataset_disassociate(&rdataset); + dns_db_detachnode(db, &node); + dns_db_closeversion(db, ¤tversion, ISC_FALSE); +} + +static void +warnifallksk(dns_db_t *db) { + dns_dbversion_t *currentversion = NULL; + dns_dbnode_t *node = NULL; + dns_rdataset_t rdataset; + dns_rdata_t rdata = DNS_RDATA_INIT; + isc_result_t result; + dns_rdata_key_t key; + isc_boolean_t have_non_ksk = ISC_FALSE; + + dns_db_currentversion(db, ¤tversion); + + result = dns_db_findnode(db, 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(&rdataset); + result = dns_db_findrdataset(db, node, currentversion, + dns_rdatatype_dnskey, 0, 0, &rdataset, NULL); + if (result != ISC_R_SUCCESS) + fatal("failed to find keys at the zone apex: %s", + isc_result_totext(result)); + result = dns_rdataset_first(&rdataset); + check_result(result, "dns_rdataset_first"); + while (result == ISC_R_SUCCESS) { + dns_rdata_reset(&rdata); + dns_rdataset_current(&rdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &key, NULL); + check_result(result, "dns_rdata_tostruct"); + if ((key.flags & DNS_KEYFLAG_KSK) == 0) { + have_non_ksk = ISC_TRUE; + result = ISC_R_NOMORE; + } else + result = dns_rdataset_next(&rdataset); + } + dns_rdataset_disassociate(&rdataset); + dns_db_detachnode(db, &node); + dns_db_closeversion(db, ¤tversion, ISC_FALSE); + if (!have_non_ksk && !ignoreksk) + fprintf(stderr, "%s: warning: No non-KSK dnskey found. " + "Supply non-KSK dnskey or use '-z'.\n", + program); +} + +static void +writeset(const char *prefix, dns_rdatatype_t type) { + char *filename; + char namestr[DNS_NAME_FORMATSIZE]; + dns_db_t *db = NULL; + dns_dbversion_t *version = NULL; + dns_diff_t diff; + dns_difftuple_t *tuple = NULL; + dns_fixedname_t fixed; + dns_name_t *name; + dns_rdata_t rdata, ds; + isc_boolean_t have_ksk = ISC_FALSE; + isc_boolean_t have_non_ksk = ISC_FALSE; + isc_buffer_t b; + isc_buffer_t namebuf; + isc_region_t r; + isc_result_t result; + signer_key_t *key; + unsigned char dsbuf[DNS_DS_BUFFERSIZE]; + unsigned char keybuf[DST_KEY_MAXSIZE]; + unsigned int filenamelen; + const dns_master_style_t *style = + (type == dns_rdatatype_dnskey) ? masterstyle : dsstyle; + + isc_buffer_init(&namebuf, namestr, sizeof(namestr)); + result = dns_name_tofilenametext(gorigin, ISC_FALSE, &namebuf); + check_result(result, "dns_name_tofilenametext"); + isc_buffer_putuint8(&namebuf, 0); + filenamelen = strlen(prefix) + strlen(namestr); + if (directory != NULL) + filenamelen += strlen(directory) + 1; + filename = isc_mem_get(mctx, filenamelen + 1); + if (filename == NULL) + fatal("out of memory"); + if (directory != NULL) + sprintf(filename, "%s/", directory); + else + filename[0] = 0; + strcat(filename, prefix); + strcat(filename, namestr); + + dns_diff_init(mctx, &diff); + + for (key = ISC_LIST_HEAD(keylist); + key != NULL; + key = ISC_LIST_NEXT(key, link)) + if (!key->isksk) { + have_non_ksk = ISC_TRUE; + break; + } + + for (key = ISC_LIST_HEAD(keylist); + key != NULL; + key = ISC_LIST_NEXT(key, link)) + if (key->isksk) { + have_ksk = ISC_TRUE; + break; + } + + if (type == dns_rdatatype_dlv) { + dns_name_t tname; + unsigned int labels; + + dns_name_init(&tname, NULL); + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + labels = dns_name_countlabels(gorigin); + dns_name_getlabelsequence(gorigin, 0, labels - 1, &tname); + result = dns_name_concatenate(&tname, dlv, name, NULL); + check_result(result, "dns_name_concatenate"); + } else + name = gorigin; + + for (key = ISC_LIST_HEAD(keylist); + key != NULL; + key = ISC_LIST_NEXT(key, link)) + { + if (have_ksk && have_non_ksk && !key->isksk) + continue; + dns_rdata_init(&rdata); + dns_rdata_init(&ds); + isc_buffer_init(&b, keybuf, sizeof(keybuf)); + result = dst_key_todns(key->key, &b); + check_result(result, "dst_key_todns"); + isc_buffer_usedregion(&b, &r); + dns_rdata_fromregion(&rdata, gclass, dns_rdatatype_dnskey, &r); + if (type != dns_rdatatype_dnskey) { + result = dns_ds_buildrdata(gorigin, &rdata, + DNS_DSDIGEST_SHA1, + dsbuf, &ds); + check_result(result, "dns_ds_buildrdata"); + if (type == dns_rdatatype_dlv) + ds.type = dns_rdatatype_dlv; + result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, + name, 0, &ds, &tuple); + check_result(result, "dns_difftuple_create"); + dns_diff_append(&diff, &tuple); + + dns_rdata_reset(&ds); + result = dns_ds_buildrdata(gorigin, &rdata, + DNS_DSDIGEST_SHA256, + dsbuf, &ds); + check_result(result, "dns_ds_buildrdata"); + if (type == dns_rdatatype_dlv) + ds.type = dns_rdatatype_dlv; + result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, + name, 0, &ds, &tuple); + + } else + result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, + gorigin, zonettl, + &rdata, &tuple); + check_result(result, "dns_difftuple_create"); + dns_diff_append(&diff, &tuple); + } + + result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, + gclass, 0, NULL, &db); + check_result(result, "dns_db_create"); + + result = dns_db_newversion(db, &version); + check_result(result, "dns_db_newversion"); + + result = dns_diff_apply(&diff, db, version); + check_result(result, "dns_diff_apply"); + dns_diff_clear(&diff); + + result = dns_master_dump(mctx, db, version, style, filename); + check_result(result, "dns_master_dump"); + + isc_mem_put(mctx, filename, filenamelen + 1); + + dns_db_closeversion(db, &version, ISC_FALSE); + dns_db_detach(&db); +} + +static void +print_time(FILE *fp) { + time_t currenttime; + + if (outputformat != dns_masterformat_text) + return; + + currenttime = time(NULL); + fprintf(fp, "; File written on %s", ctime(¤ttime)); +} + +static void +print_version(FILE *fp) { + if (outputformat != dns_masterformat_text) + return; + + fprintf(fp, "; dnssec_signzone version " VERSION "\n"); +} + +static void +usage(void) { + fprintf(stderr, "Usage:\n"); + fprintf(stderr, "\t%s [options] zonefile [keys]\n", program); + + fprintf(stderr, "\n"); + + fprintf(stderr, "Version: %s\n", VERSION); + + fprintf(stderr, "Options: (default value in parenthesis) \n"); + fprintf(stderr, "\t-c class (IN)\n"); + fprintf(stderr, "\t-d directory\n"); + fprintf(stderr, "\t\tdirectory to find keyset files (.)\n"); + fprintf(stderr, "\t-g:\t"); + fprintf(stderr, "generate DS records from keyset files\n"); + fprintf(stderr, "\t-s [YYYYMMDDHHMMSS|+offset]:\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 " + "(now + 30 days)\n"); + fprintf(stderr, "\t-i interval:\n"); + fprintf(stderr, "\t\tcycle interval - resign " + "if < interval from end ( (end-start)/4 )\n"); + fprintf(stderr, "\t-j jitter:\n"); + fprintf(stderr, "\t\trandomize signature end time up to jitter seconds\n"); + fprintf(stderr, "\t-v debuglevel (0)\n"); + fprintf(stderr, "\t-o origin:\n"); + fprintf(stderr, "\t\tzone origin (name of zonefile)\n"); + fprintf(stderr, "\t-f outfile:\n"); + fprintf(stderr, "\t\tfile the signed zone is written in " + "(zonefile + .signed)\n"); + fprintf(stderr, "\t-I format:\n"); + fprintf(stderr, "\t\tfile format of input zonefile (text)\n"); + fprintf(stderr, "\t-O format:\n"); + 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-r randomdev:\n"); + fprintf(stderr, "\t\ta file containing random data\n"); + fprintf(stderr, "\t-a:\t"); + fprintf(stderr, "verify generated signatures\n"); + fprintf(stderr, "\t-p:\t"); + fprintf(stderr, "use pseudorandom data (faster but less secure)\n"); + fprintf(stderr, "\t-t:\t"); + fprintf(stderr, "print statistics\n"); + fprintf(stderr, "\t-n ncpus (number of cpus present)\n"); + fprintf(stderr, "\t-k key_signing_key\n"); + fprintf(stderr, "\t-l lookasidezone\n"); + fprintf(stderr, "\t-z:\t"); + fprintf(stderr, "ignore KSK flag in DNSKEYs"); + + fprintf(stderr, "\n"); + + fprintf(stderr, "Signing Keys: "); + fprintf(stderr, "(default: all zone keys that have private keys)\n"); + fprintf(stderr, "\tkeyfile (Kname+alg+tag)\n"); + exit(0); +} + +static void +removetempfile(void) { + if (removefile) + isc_file_remove(tempfile); +} + +static void +print_stats(isc_time_t *timer_start, isc_time_t *timer_finish) { + isc_uint64_t runtime_us; /* Runtime in microseconds */ + isc_uint64_t runtime_ms; /* Runtime in milliseconds */ + isc_uint64_t sig_ms; /* Signatures per millisecond */ + + runtime_us = isc_time_microdiff(timer_finish, timer_start); + + 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); + runtime_ms = runtime_us / 1000; + printf("Runtime in seconds: %7u.%03u\n", + (unsigned int) (runtime_ms / 1000), + (unsigned int) (runtime_ms % 1000)); + if (runtime_us > 0) { + sig_ms = ((isc_uint64_t)nsigned * 1000000000) / runtime_us; + printf("Signatures per second: %7u.%03u\n", + (unsigned int) sig_ms / 1000, + (unsigned int) sig_ms % 1000); + } +} + +int +main(int argc, char *argv[]) { + int i, ch; + char *startstr = NULL, *endstr = NULL, *classname = NULL; + char *origin = NULL, *file = NULL, *output = NULL; + char *inputformatstr = NULL, *outputformatstr = NULL; + char *serialformatstr = NULL; + char *dskeyfile[MAXDSKEYS]; + int ndskeys = 0; + char *endp; + isc_time_t timer_start, timer_finish; + signer_key_t *key; + isc_result_t result; + isc_log_t *log = NULL; + isc_boolean_t pseudorandom = ISC_FALSE; + unsigned int eflags; + isc_boolean_t free_output = ISC_FALSE; + int tempfilelen; + dns_rdataclass_t rdclass; + isc_task_t **tasks = NULL; + isc_buffer_t b; + int len; + + masterstyle = &dns_master_style_explicitttl; + + check_result(isc_app_start(), "isc_app_start"); + + result = isc_mem_create(0, 0, &mctx); + if (result != ISC_R_SUCCESS) + fatal("out of memory"); + + dns_result_register(); + + while ((ch = isc_commandline_parse(argc, argv, + "ac:d:e:f:ghi:I:j:k:l:n:N:o:O:pr:s:Stv:z")) + != -1) { + switch (ch) { + case 'a': + tryverify = ISC_TRUE; + break; + + case 'c': + classname = isc_commandline_argument; + break; + + case 'd': + directory = isc_commandline_argument; + break; + + case 'e': + endstr = isc_commandline_argument; + break; + + case 'f': + output = isc_commandline_argument; + break; + + case 'g': + generateds = ISC_TRUE; + break; + + case 'h': + default: + usage(); + break; + + case 'i': + endp = NULL; + cycle = strtol(isc_commandline_argument, &endp, 0); + if (*endp != '\0' || cycle < 0) + fatal("cycle period must be numeric and " + "positive"); + break; + + case 'I': + inputformatstr = isc_commandline_argument; + break; + + case 'j': + endp = NULL; + jitter = strtol(isc_commandline_argument, &endp, 0); + if (*endp != '\0' || jitter < 0) + fatal("jitter must be numeric and positive"); + break; + + case 'l': + dns_fixedname_init(&dlv_fixed); + len = strlen(isc_commandline_argument); + isc_buffer_init(&b, isc_commandline_argument, len); + isc_buffer_add(&b, len); + + dns_fixedname_init(&dlv_fixed); + dlv = dns_fixedname_name(&dlv_fixed); + result = dns_name_fromtext(dlv, &b, dns_rootname, + ISC_FALSE, NULL); + check_result(result, "dns_name_fromtext(dlv)"); + break; + + case 'k': + if (ndskeys == MAXDSKEYS) + fatal("too many key-signing keys specified"); + dskeyfile[ndskeys++] = isc_commandline_argument; + break; + + case 'n': + endp = NULL; + ntasks = strtol(isc_commandline_argument, &endp, 0); + if (*endp != '\0' || ntasks > ISC_INT32_MAX) + fatal("number of cpus must be numeric"); + break; + + case 'N': + serialformatstr = isc_commandline_argument; + break; + + case 'o': + origin = isc_commandline_argument; + break; + + case 'O': + outputformatstr = isc_commandline_argument; + break; + + case 'p': + pseudorandom = ISC_TRUE; + break; + + case 'r': + setup_entropy(mctx, isc_commandline_argument, &ectx); + break; + + case 's': + startstr = isc_commandline_argument; + break; + + case 'S': + /* This is intentionally undocumented */ + /* -S: simple output style */ + masterstyle = &dns_master_style_simple; + break; + + case 't': + printstats = ISC_TRUE; + break; + + case 'v': + endp = NULL; + verbose = strtol(isc_commandline_argument, &endp, 0); + if (*endp != '\0') + fatal("verbose level must be numeric"); + break; + + case 'z': + ignoreksk = ISC_TRUE; + break; + } + } + + if (ectx == NULL) + setup_entropy(mctx, NULL, &ectx); + eflags = ISC_ENTROPY_BLOCKING; + if (!pseudorandom) + eflags |= ISC_ENTROPY_GOODONLY; + + result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); + if (result != ISC_R_SUCCESS) + fatal("could not create hash context"); + + result = dst_lib_init(mctx, ectx, eflags); + if (result != ISC_R_SUCCESS) + fatal("could not initialize dst"); + + isc_stdtime_get(&now); + + if (startstr != NULL) + starttime = strtotime(startstr, now, now); + else + starttime = now - 3600; /* Allow for some clock skew. */ + + if (endstr != NULL) + endtime = strtotime(endstr, now, starttime); + else + endtime = starttime + (30 * 24 * 60 * 60); + + if (cycle == -1) + cycle = (endtime - starttime) / 4; + + if (ntasks == 0) + ntasks = isc_os_ncpus(); + vbprintf(4, "using %d cpus\n", ntasks); + + rdclass = strtoclass(classname); + + setup_logging(verbose, mctx, &log); + + argc -= isc_commandline_index; + argv += isc_commandline_index; + + if (argc < 1) + usage(); + + file = argv[0]; + + argc -= 1; + argv += 1; + + if (origin == NULL) + origin = file; + + if (output == NULL) { + free_output = ISC_TRUE; + output = isc_mem_allocate(mctx, + strlen(file) + strlen(".signed") + 1); + if (output == NULL) + fatal("out of memory"); + sprintf(output, "%s.signed", file); + } + + if (inputformatstr != NULL) { + if (strcasecmp(inputformatstr, "text") == 0) + inputformat = dns_masterformat_text; + else if (strcasecmp(inputformatstr, "raw") == 0) + inputformat = dns_masterformat_raw; + else + fatal("unknown file format: %s\n", inputformatstr); + } + + if (outputformatstr != NULL) { + if (strcasecmp(outputformatstr, "text") == 0) + outputformat = dns_masterformat_text; + else if (strcasecmp(outputformatstr, "raw") == 0) + outputformat = dns_masterformat_raw; + else + fatal("unknown file format: %s\n", outputformatstr); + } + + if (serialformatstr != NULL) { + if (strcasecmp(serialformatstr, "keep") == 0) + serialformat = SOA_SERIAL_KEEP; + else if (strcasecmp(serialformatstr, "increment") == 0 || + strcasecmp(serialformatstr, "incr") == 0) + serialformat = SOA_SERIAL_INCREMENT; + else if (strcasecmp(serialformatstr, "unixtime") == 0) + serialformat = SOA_SERIAL_UNIXTIME; + else + fatal("unknown soa serial format: %s\n", serialformatstr); + } + + result = dns_master_stylecreate(&dsstyle, DNS_STYLEFLAG_NO_TTL, + 0, 24, 0, 0, 0, 8, mctx); + check_result(result, "dns_master_stylecreate"); + + + gdb = NULL; + TIME_NOW(&timer_start); + loadzone(file, origin, rdclass, &gdb); + gorigin = dns_db_origin(gdb); + gclass = dns_db_class(gdb); + zonettl = soattl(); + + ISC_LIST_INIT(keylist); + + if (argc == 0) { + loadzonekeys(gdb); + } else { + for (i = 0; i < argc; i++) { + dst_key_t *newkey = NULL; + + result = dst_key_fromnamedfile(argv[i], + DST_TYPE_PUBLIC | + DST_TYPE_PRIVATE, + mctx, &newkey); + if (result != ISC_R_SUCCESS) + fatal("cannot load dnskey %s: %s", argv[i], + isc_result_totext(result)); + + key = ISC_LIST_HEAD(keylist); + while (key != NULL) { + dst_key_t *dkey = key->key; + if (dst_key_id(dkey) == dst_key_id(newkey) && + dst_key_alg(dkey) == dst_key_alg(newkey) && + dns_name_equal(dst_key_name(dkey), + dst_key_name(newkey))) + { + if (!dst_key_isprivate(dkey)) + fatal("cannot sign zone with " + "non-private dnskey %s", + argv[i]); + break; + } + key = ISC_LIST_NEXT(key, link); + } + if (key == NULL) { + key = newkeystruct(newkey, ISC_TRUE); + ISC_LIST_APPEND(keylist, key, link); + } else + dst_key_free(&newkey); + } + + loadzonepubkeys(gdb); + } + + for (i = 0; i < ndskeys; i++) { + dst_key_t *newkey = NULL; + + result = dst_key_fromnamedfile(dskeyfile[i], + DST_TYPE_PUBLIC | + DST_TYPE_PRIVATE, + mctx, &newkey); + if (result != ISC_R_SUCCESS) + fatal("cannot load dnskey %s: %s", dskeyfile[i], + isc_result_totext(result)); + + key = ISC_LIST_HEAD(keylist); + while (key != NULL) { + dst_key_t *dkey = key->key; + if (dst_key_id(dkey) == dst_key_id(newkey) && + dst_key_alg(dkey) == dst_key_alg(newkey) && + dns_name_equal(dst_key_name(dkey), + dst_key_name(newkey))) + { + /* Override key flags. */ + key->issigningkey = ISC_TRUE; + key->isksk = ISC_TRUE; + key->isdsk = ISC_FALSE; + dst_key_free(&dkey); + key->key = newkey; + break; + } + key = ISC_LIST_NEXT(key, link); + } + if (key == NULL) { + /* Override dnskey flags. */ + key = newkeystruct(newkey, ISC_TRUE); + key->isksk = ISC_TRUE; + key->isdsk = ISC_FALSE; + ISC_LIST_APPEND(keylist, key, link); + } + } + + if (ISC_LIST_EMPTY(keylist)) { + fprintf(stderr, "%s: warning: No keys specified or found\n", + program); + nokeys = ISC_TRUE; + } + + warnifallksk(gdb); + + gversion = NULL; + result = dns_db_newversion(gdb, &gversion); + check_result(result, "dns_db_newversion()"); + + switch (serialformat) { + case SOA_SERIAL_INCREMENT: + setsoaserial(0); + break; + case SOA_SERIAL_UNIXTIME: + setsoaserial(now); + break; + case SOA_SERIAL_KEEP: + default: + /* do nothing */ + break; + } + + nsecify(); + + if (!nokeys) { + writeset("keyset-", dns_rdatatype_dnskey); + writeset("dsset-", dns_rdatatype_ds); + if (dlv != NULL) { + writeset("dlvset-", dns_rdatatype_dlv); + } + } + + 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"); + + fp = NULL; + result = isc_file_openunique(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); + + result = isc_taskmgr_create(mctx, ntasks, 0, &taskmgr); + if (result != ISC_R_SUCCESS) + fatal("failed to create task manager: %s", + isc_result_totext(result)); + + master = NULL; + result = isc_task_create(taskmgr, 0, &master); + if (result != ISC_R_SUCCESS) + fatal("failed to create task: %s", isc_result_totext(result)); + + tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *)); + if (tasks == NULL) + fatal("out of memory"); + for (i = 0; i < (int)ntasks; i++) { + tasks[i] = NULL; + result = isc_task_create(taskmgr, 0, &tasks[i]); + if (result != ISC_R_SUCCESS) + fatal("failed to create task: %s", + isc_result_totext(result)); + } + + RUNTIME_CHECK(isc_mutex_init(&namelock) == ISC_R_SUCCESS); + if (printstats) + RUNTIME_CHECK(isc_mutex_init(&statslock) == ISC_R_SUCCESS); + + presign(); + signapex(); + if (!finished) { + /* + * There is more work to do. Spread it out over multiple + * processors if possible. + */ + for (i = 0; i < (int)ntasks; i++) { + result = isc_app_onrun(mctx, master, startworker, + tasks[i]); + if (result != ISC_R_SUCCESS) + fatal("failed to start task: %s", + isc_result_totext(result)); + } + (void)isc_app_run(); + if (!finished) + fatal("process aborted by user"); + } else + isc_task_detach(&master); + shuttingdown = ISC_TRUE; + for (i = 0; i < (int)ntasks; i++) + isc_task_detach(&tasks[i]); + isc_taskmgr_destroy(&taskmgr); + isc_mem_put(mctx, tasks, ntasks * sizeof(isc_task_t *)); + postsign(); + + if (outputformat != dns_masterformat_text) { + result = dns_master_dumptostream2(mctx, gdb, gversion, + masterstyle, outputformat, + fp); + check_result(result, "dns_master_dumptostream2"); + } + + 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); + + dns_db_closeversion(gdb, &gversion, ISC_FALSE); + dns_db_detach(&gdb); + + while (!ISC_LIST_EMPTY(keylist)) { + key = ISC_LIST_HEAD(keylist); + ISC_LIST_UNLINK(keylist, key, link); + dst_key_free(&key->key); + isc_mem_put(mctx, key, sizeof(signer_key_t)); + } + + isc_mem_put(mctx, tempfile, tempfilelen); + + if (free_output) + isc_mem_free(mctx, output); + + dns_master_styledestroy(&dsstyle, mctx); + + cleanup_logging(&log); + dst_lib_destroy(); + isc_hash_destroy(); + cleanup_entropy(&ectx); + dns_name_destroy(); + if (verbose > 10) + isc_mem_stats(mctx, stdout); + isc_mem_destroy(&mctx); + + (void) isc_app_finish(); + + if (printstats) { + TIME_NOW(&timer_finish); + print_stats(&timer_start, &timer_finish); + } + + return (0); +} diff --git a/bin/dnssec/dnssec-signzone.docbook b/bin/dnssec/dnssec-signzone.docbook new file mode 100644 index 0000000..8d92831 --- /dev/null +++ b/bin/dnssec/dnssec-signzone.docbook @@ -0,0 +1,476 @@ +]> + + + + + + June 30, 2000 + + + + dnssec-signzone + 8 + BIND9 + + + + dnssec-signzone + DNSSEC zone signing tool + + + + + 2004 + 2005 + 2006 + 2007 + Internet Systems Consortium, Inc. ("ISC") + + + 2000 + 2001 + 2002 + 2003 + Internet Software Consortium. + + + + + + dnssec-signzone + + + + + + + + + + + + + + + + + + + + + + zonefile + key + + + + + DESCRIPTION + dnssec-signzone + signs a zone. It generates + NSEC and RRSIG records and produces a signed version of the + zone. The security status of delegations from the signed zone + (that is, whether the child zones are secure or not) is + determined by the presence or absence of a + keyset file for each child zone. + + + + + OPTIONS + + + + -a + + + Verify all generated signatures. + + + + + + -c class + + + Specifies the DNS class of the zone. + + + + + + -k key + + + Treat specified key as a key signing key ignoring any + key flags. This option may be specified multiple times. + + + + + + -l domain + + + Generate a DLV set in addition to the key (DNSKEY) and DS sets. + The domain is appended to the name of the records. + + + + + + -d directory + + + Look for keyset files in + as the directory + + + + + + -g + + + Generate DS records for child zones from keyset files. + Existing DS records will be removed. + + + + + + -s start-time + + + Specify the date and time when the generated RRSIG records + become valid. This can be either an absolute or relative + time. An absolute start time is indicated by a number + in YYYYMMDDHHMMSS notation; 20000530144500 denotes + 14:45:00 UTC on May 30th, 2000. A relative start time is + indicated by +N, which is N seconds from the current time. + If no is specified, the current + time minus 1 hour (to allow for clock skew) is used. + + + + + + -e end-time + + + Specify the date and time when the generated RRSIG records + expire. 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, 30 days from the start time is used as a default. + + + + + + -f output-file + + + The name of the output file containing the signed zone. The + default is to append .signed to + the + input filename. + + + + + + -h + + + Prints a short summary of the options and arguments to + dnssec-signzone. + + + + + + -i interval + + + When a previously-signed zone is passed as input, records + may be resigned. The option + specifies the cycle interval as an offset from the current + time (in seconds). If a RRSIG record expires after the + cycle interval, it is retained. Otherwise, it is considered + to be expiring soon, and it will be replaced. + + + The default cycle interval is one quarter of the difference + between the signature end and start times. So if neither + or + are specified, dnssec-signzone + generates + signatures that are valid for 30 days, with a cycle + interval of 7.5 days. Therefore, if any existing RRSIG records + are due to expire in less than 7.5 days, they would be + replaced. + + + + + + -I input-format + + + The format of the input zone file. + Possible formats are "text" (default) + and "raw". + This option is primarily intended to be used for dynamic + signed zones so that the dumped zone file in a non-text + format containing updates can be signed directly. + The use of this option does not make much sense for + non-dynamic zones. + + + + + + -j jitter + + + When signing a zone with a fixed signature lifetime, all + RRSIG records issued at the time of signing expires + simultaneously. If the zone is incrementally signed, i.e. + a previously-signed zone is passed as input to the signer, + all expired signatures have to be regenerated at about the + same time. The option specifies a + jitter window that will be used to randomize the signature + expire time, thus spreading incremental signature + regeneration over time. + + + 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. + + + + + + -n ncpus + + + Specifies the number of threads to use. By default, one + thread is started for each detected CPU. + + + + + + -N soa-serial-format + + + The SOA serial number format of the signed zone. + Possible formats are "keep" (default), + "increment" and + "unixtime". + + + + + "keep" + + Do not modify the SOA serial number. + + + + + "increment" + + Increment the SOA serial number using RFC 1982 + arithmetics. + + + + + "unixtime" + + Set the SOA serial number to the number of seconds + since epoch. + + + + + + + + + -o origin + + + The zone origin. If not specified, the name of the zone file + is assumed to be the origin. + + + + + + -O output-format + + + The format of the output file containing the signed zone. + Possible formats are "text" (default) + and "raw". + + + + + + -p + + + Use pseudo-random data when signing the zone. This is faster, + but less secure, than using real random data. This option + may be useful when signing large zones or when the entropy + source is limited. + + + + + + -r randomdev + + + Specifies the source of randomness. If the operating + system does not provide a /dev/random + or equivalent device, the default source of randomness + is keyboard input. randomdev + specifies + the name of a character device or file containing random + data to be used instead of the default. The special value + keyboard indicates that keyboard + input should be used. + + + + + + -t + + + Print statistics at completion. + + + + + + -v level + + + Sets the debugging level. + + + + + + -z + + + Ignore KSK flag on key when determining what to sign. + + + + + + zonefile + + + The file containing the zone to be signed. + + + + + + key + + + Specify which keys should be used to sign the zone. If + no keys are specified, then the zone will be examined + for DNSKEY records at the zone apex. If these are found and + there are matching private keys, in the current directory, + then these will be used for signing. + + + + + + + + + EXAMPLE + + The following command signs the example.com + zone with the DSA key generated by dnssec-keygen + (Kexample.com.+003+17247). The zone's keys must be in the master + file (db.example.com). This invocation looks + for keyset files, in the current directory, + so that DS records can be generated from them (-g). + +% dnssec-signzone -g -o example.com db.example.com \ +Kexample.com.+003+17247 +db.example.com.signed +% + + In the above example, dnssec-signzone creates + the file db.example.com.signed. This + file should be referenced in a zone statement in a + named.conf file. + + + This example re-signs a previously signed zone with default parameters. + The private keys are assumed to be in the current directory. + +% cp db.example.com.signed db.example.com +% dnssec-signzone -o example.com db.example.com +db.example.com.signed +% + + + + SEE ALSO + + dnssec-keygen8 + , + BIND 9 Administrator Reference Manual, + RFC 2535. + + + + + AUTHOR + Internet Systems Consortium + + + + diff --git a/bin/dnssec/dnssec-signzone.html b/bin/dnssec/dnssec-signzone.html new file mode 100644 index 0000000..e794d4c --- /dev/null +++ b/bin/dnssec/dnssec-signzone.html @@ -0,0 +1,285 @@ + + + + + +dnssec-signzone + + +
+
+
+

Name

+

dnssec-signzone — DNSSEC zone signing tool

+
+
+

Synopsis

+

dnssec-signzone [-a] [-c class] [-d directory] [-e end-time] [-f output-file] [-g] [-h] [-k key] [-l domain] [-i interval] [-I input-format] [-j jitter] [-N soa-serial-format] [-o origin] [-O output-format] [-p] [-r randomdev] [-s start-time] [-t] [-v level] [-z] {zonefile} [key...]

+
+
+

DESCRIPTION

+

dnssec-signzone + signs a zone. It generates + NSEC and RRSIG records and produces a signed version of the + zone. The security status of delegations from the signed zone + (that is, whether the child zones are secure or not) is + determined by the presence or absence of a + keyset file for each child zone. +

+
+
+

OPTIONS

+
+
-a
+

+ Verify all generated signatures. +

+
-c class
+

+ Specifies the DNS class of the zone. +

+
-k key
+

+ Treat specified key as a key signing key ignoring any + key flags. This option may be specified multiple times. +

+
-l domain
+

+ Generate a DLV set in addition to the key (DNSKEY) and DS sets. + The domain is appended to the name of the records. +

+
-d directory
+

+ Look for keyset files in + directory as the directory +

+
-g
+

+ Generate DS records for child zones from keyset files. + Existing DS records will be removed. +

+
-s start-time
+

+ Specify the date and time when the generated RRSIG records + become valid. This can be either an absolute or relative + time. An absolute start time is indicated by a number + in YYYYMMDDHHMMSS notation; 20000530144500 denotes + 14:45:00 UTC on May 30th, 2000. A relative start time is + indicated by +N, which is N seconds from the current time. + If no start-time is specified, the current + time minus 1 hour (to allow for clock skew) is used. +

+
-e end-time
+

+ Specify the date and time when the generated RRSIG records + expire. 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 end-time is + specified, 30 days from the start time is used as a default. +

+
-f output-file
+

+ The name of the output file containing the signed zone. The + default is to append .signed to + the + input filename. +

+
-h
+

+ Prints a short summary of the options and arguments to + dnssec-signzone. +

+
-i interval
+
+

+ When a previously-signed zone is passed as input, records + may be resigned. The interval option + specifies the cycle interval as an offset from the current + time (in seconds). If a RRSIG record expires after the + cycle interval, it is retained. Otherwise, it is considered + to be expiring soon, and it will be replaced. +

+

+ The default cycle interval is one quarter of the difference + between the signature end and start times. So if neither + end-time or start-time + are specified, dnssec-signzone + generates + signatures that are valid for 30 days, with a cycle + interval of 7.5 days. Therefore, if any existing RRSIG records + are due to expire in less than 7.5 days, they would be + replaced. +

+
+
-I input-format
+

+ The format of the input zone file. + Possible formats are "text" (default) + and "raw". + This option is primarily intended to be used for dynamic + signed zones so that the dumped zone file in a non-text + format containing updates can be signed directly. + The use of this option does not make much sense for + non-dynamic zones. +

+
-j jitter
+
+

+ When signing a zone with a fixed signature lifetime, all + RRSIG records issued at the time of signing expires + simultaneously. If the zone is incrementally signed, i.e. + a previously-signed zone is passed as input to the signer, + all expired signatures have to be regenerated at about the + same time. The jitter option specifies a + jitter window that will be used to randomize the signature + expire time, thus spreading incremental signature + regeneration over time. +

+

+ 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. +

+
+
-n ncpus
+

+ Specifies the number of threads to use. By default, one + thread is started for each detected CPU. +

+
-N soa-serial-format
+
+

+ The SOA serial number format of the signed zone. + Possible formats are "keep" (default), + "increment" and + "unixtime". +

+
+
"keep"
+

Do not modify the SOA serial number.

+
"increment"
+

Increment the SOA serial number using RFC 1982 + arithmetics.

+
"unixtime"
+

Set the SOA serial number to the number of seconds + since epoch.

+
+
+
-o origin
+

+ The zone origin. If not specified, the name of the zone file + is assumed to be the origin. +

+
-O output-format
+

+ The format of the output file containing the signed zone. + Possible formats are "text" (default) + and "raw". +

+
-p
+

+ Use pseudo-random data when signing the zone. This is faster, + but less secure, than using real random data. This option + may be useful when signing large zones or when the entropy + source is limited. +

+
-r randomdev
+

+ Specifies the source of randomness. If the operating + system does not provide a /dev/random + or equivalent device, the default source of randomness + is keyboard input. randomdev + specifies + the name of a character device or file containing random + data to be used instead of the default. The special value + keyboard indicates that keyboard + input should be used. +

+
-t
+

+ Print statistics at completion. +

+
-v level
+

+ Sets the debugging level. +

+
-z
+

+ Ignore KSK flag on key when determining what to sign. +

+
zonefile
+

+ The file containing the zone to be signed. +

+
key
+

+ Specify which keys should be used to sign the zone. If + no keys are specified, then the zone will be examined + for DNSKEY records at the zone apex. If these are found and + there are matching private keys, in the current directory, + then these will be used for signing. +

+
+
+
+

EXAMPLE

+

+ The following command signs the example.com + zone with the DSA key generated by dnssec-keygen + (Kexample.com.+003+17247). The zone's keys must be in the master + file (db.example.com). This invocation looks + for keyset files, in the current directory, + so that DS records can be generated from them (-g). +

+
% dnssec-signzone -g -o example.com db.example.com \
+Kexample.com.+003+17247
+db.example.com.signed
+%
+

+ In the above example, dnssec-signzone creates + the file db.example.com.signed. This + file should be referenced in a zone statement in a + named.conf file. +

+

+ This example re-signs a previously signed zone with default parameters. + The private keys are assumed to be in the current directory. +

+
% cp db.example.com.signed db.example.com
+% dnssec-signzone -o example.com db.example.com
+db.example.com.signed
+%
+
+
+

SEE ALSO

+

dnssec-keygen(8), + BIND 9 Administrator Reference Manual, + RFC 2535. +

+
+
+

AUTHOR

+

Internet Systems Consortium +

+
+
+ diff --git a/bin/dnssec/dnssectool.c b/bin/dnssec/dnssectool.c new file mode 100644 index 0000000..4f95540 --- /dev/null +++ b/bin/dnssec/dnssectool.c @@ -0,0 +1,313 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: dnssectool.c,v 1.40.18.3 2005/07/01 03:55:28 marka Exp $ */ + +/*! \file */ + +/*% + * DNSSEC Support Routines. + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dnssectool.h" + +extern int verbose; +extern const char *program; + +typedef struct entropysource entropysource_t; + +struct entropysource { + isc_entropysource_t *source; + isc_mem_t *mctx; + ISC_LINK(entropysource_t) link; +}; + +static ISC_LIST(entropysource_t) sources; +static fatalcallback_t *fatalcallback = NULL; + +void +fatal(const char *format, ...) { + va_list args; + + fprintf(stderr, "%s: ", program); + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, "\n"); + if (fatalcallback != NULL) + (*fatalcallback)(); + exit(1); +} + +void +setfatalcallback(fatalcallback_t *callback) { + fatalcallback = callback; +} + +void +check_result(isc_result_t result, const char *message) { + if (result != ISC_R_SUCCESS) + fatal("%s: %s", message, isc_result_totext(result)); +} + +void +vbprintf(int level, const char *fmt, ...) { + va_list ap; + if (level > verbose) + return; + va_start(ap, fmt); + fprintf(stderr, "%s: ", program); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +void +type_format(const dns_rdatatype_t type, char *cp, unsigned int size) { + isc_buffer_t b; + isc_region_t r; + isc_result_t result; + + isc_buffer_init(&b, cp, size - 1); + result = dns_rdatatype_totext(type, &b); + check_result(result, "dns_rdatatype_totext()"); + isc_buffer_usedregion(&b, &r); + r.base[r.length] = 0; +} + +void +alg_format(const dns_secalg_t alg, char *cp, unsigned int size) { + isc_buffer_t b; + isc_region_t r; + isc_result_t result; + + isc_buffer_init(&b, cp, size - 1); + result = dns_secalg_totext(alg, &b); + check_result(result, "dns_secalg_totext()"); + isc_buffer_usedregion(&b, &r); + r.base[r.length] = 0; +} + +void +sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size) { + char namestr[DNS_NAME_FORMATSIZE]; + char algstr[DNS_NAME_FORMATSIZE]; + + dns_name_format(&sig->signer, namestr, sizeof(namestr)); + alg_format(sig->algorithm, algstr, sizeof(algstr)); + snprintf(cp, size, "%s/%s/%d", namestr, algstr, sig->keyid); +} + +void +key_format(const dst_key_t *key, char *cp, unsigned int size) { + char namestr[DNS_NAME_FORMATSIZE]; + char algstr[DNS_NAME_FORMATSIZE]; + + dns_name_format(dst_key_name(key), namestr, sizeof(namestr)); + alg_format((dns_secalg_t) dst_key_alg(key), algstr, sizeof(algstr)); + snprintf(cp, size, "%s/%s/%d", namestr, algstr, dst_key_id(key)); +} + +void +setup_logging(int verbose, isc_mem_t *mctx, isc_log_t **logp) { + isc_result_t result; + isc_logdestination_t destination; + isc_logconfig_t *logconfig = NULL; + isc_log_t *log = NULL; + int level; + + if (verbose < 0) + verbose = 0; + switch (verbose) { + case 0: + /* + * We want to see warnings about things like out-of-zone + * data in the master file even when not verbose. + */ + level = ISC_LOG_WARNING; + break; + case 1: + level = ISC_LOG_INFO; + break; + default: + level = ISC_LOG_DEBUG(verbose - 2 + 1); + break; + } + + RUNTIME_CHECK(isc_log_create(mctx, &log, &logconfig) == ISC_R_SUCCESS); + isc_log_setcontext(log); + dns_log_init(log); + dns_log_setcontext(log); + + RUNTIME_CHECK(isc_log_settag(logconfig, program) == ISC_R_SUCCESS); + + /* + * Set up a channel similar to default_stderr except: + * - the logging level is passed in + * - the program name and logging level are printed + * - no time stamp is printed + */ + destination.file.stream = stderr; + destination.file.name = NULL; + destination.file.versions = ISC_LOG_ROLLNEVER; + destination.file.maximum_size = 0; + result = isc_log_createchannel(logconfig, "stderr", + ISC_LOG_TOFILEDESC, + level, + &destination, + ISC_LOG_PRINTTAG|ISC_LOG_PRINTLEVEL); + check_result(result, "isc_log_createchannel()"); + + RUNTIME_CHECK(isc_log_usechannel(logconfig, "stderr", + NULL, NULL) == ISC_R_SUCCESS); + + *logp = log; +} + +void +cleanup_logging(isc_log_t **logp) { + isc_log_t *log; + + REQUIRE(logp != NULL); + + log = *logp; + if (log == NULL) + return; + isc_log_destroy(&log); + isc_log_setcontext(NULL); + dns_log_setcontext(NULL); + logp = NULL; +} + +void +setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) { + isc_result_t result; + isc_entropysource_t *source = NULL; + entropysource_t *elt; + int usekeyboard = ISC_ENTROPY_KEYBOARDMAYBE; + + REQUIRE(ectx != NULL); + + if (*ectx == NULL) { + result = isc_entropy_create(mctx, ectx); + if (result != ISC_R_SUCCESS) + fatal("could not create entropy object"); + ISC_LIST_INIT(sources); + } + + if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) { + usekeyboard = ISC_ENTROPY_KEYBOARDYES; + randomfile = NULL; + } + + result = isc_entropy_usebestsource(*ectx, &source, randomfile, + usekeyboard); + + if (result != ISC_R_SUCCESS) + fatal("could not initialize entropy source: %s", + isc_result_totext(result)); + + if (source != NULL) { + elt = isc_mem_get(mctx, sizeof(*elt)); + if (elt == NULL) + fatal("out of memory"); + elt->source = source; + elt->mctx = mctx; + ISC_LINK_INIT(elt, link); + ISC_LIST_APPEND(sources, elt, link); + } +} + +void +cleanup_entropy(isc_entropy_t **ectx) { + entropysource_t *source; + while (!ISC_LIST_EMPTY(sources)) { + source = ISC_LIST_HEAD(sources); + ISC_LIST_UNLINK(sources, source, link); + isc_entropy_destroysource(&source->source); + isc_mem_put(source->mctx, source, sizeof(*source)); + } + isc_entropy_detach(ectx); +} + +isc_stdtime_t +strtotime(const char *str, isc_int64_t now, isc_int64_t base) { + isc_int64_t val, offset; + isc_result_t result; + char *endp; + + if (str[0] == '+') { + offset = strtol(str + 1, &endp, 0); + if (*endp != '\0') + fatal("time value %s is invalid", str); + val = base + offset; + } else if (strncmp(str, "now+", 4) == 0) { + offset = strtol(str + 4, &endp, 0); + if (*endp != '\0') + fatal("time value %s is invalid", str); + val = now + offset; + } else if (strlen(str) == 8U) { + char timestr[15]; + sprintf(timestr, "%s000000", str); + result = dns_time64_fromtext(timestr, &val); + if (result != ISC_R_SUCCESS) + fatal("time value %s is invalid", str); + } else { + result = dns_time64_fromtext(str, &val); + if (result != ISC_R_SUCCESS) + fatal("time value %s is invalid", str); + } + + return ((isc_stdtime_t) val); +} + +dns_rdataclass_t +strtoclass(const char *str) { + isc_textregion_t r; + dns_rdataclass_t rdclass; + isc_result_t ret; + + if (str == NULL) + return dns_rdataclass_in; + DE_CONST(str, r.base); + r.length = strlen(str); + ret = dns_rdataclass_fromtext(&rdclass, &r); + if (ret != ISC_R_SUCCESS) + fatal("unknown class %s", str); + return (rdclass); +} diff --git a/bin/dnssec/dnssectool.h b/bin/dnssec/dnssectool.h new file mode 100644 index 0000000..c5f3648 --- /dev/null +++ b/bin/dnssec/dnssectool.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: dnssectool.h,v 1.18 2004/03/05 04:57:41 marka Exp $ */ + +#ifndef DNSSECTOOL_H +#define DNSSECTOOL_H 1 + +#include +#include +#include +#include + +typedef void (fatalcallback_t)(void); + +void +fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); + +void +setfatalcallback(fatalcallback_t *callback); + +void +check_result(isc_result_t result, const char *message); + +void +vbprintf(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3); + +void +type_format(const dns_rdatatype_t type, char *cp, unsigned int size); +#define TYPE_FORMATSIZE 10 + +void +alg_format(const dns_secalg_t alg, char *cp, unsigned int size); +#define ALG_FORMATSIZE 10 + +void +sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size); +#define SIG_FORMATSIZE (DNS_NAME_FORMATSIZE + ALG_FORMATSIZE + sizeof("65535")) + +void +key_format(const dst_key_t *key, char *cp, unsigned int size); +#define KEY_FORMATSIZE (DNS_NAME_FORMATSIZE + ALG_FORMATSIZE + sizeof("65535")) + +void +setup_logging(int verbose, isc_mem_t *mctx, isc_log_t **logp); + +void +cleanup_logging(isc_log_t **logp); + +void +setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx); + +void +cleanup_entropy(isc_entropy_t **ectx); + +isc_stdtime_t +strtotime(const char *str, isc_int64_t now, isc_int64_t base); + +dns_rdataclass_t +strtoclass(const char *str); + +#endif /* DNSSEC_DNSSECTOOL_H */ diff --git a/bin/named/Makefile.in b/bin/named/Makefile.in new file mode 100644 index 0000000..a809e59c --- /dev/null +++ b/bin/named/Makefile.in @@ -0,0 +1,145 @@ +# Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 1998-2002 Internet Software Consortium. +# +# Permission to use, copy, modify, and 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: Makefile.in,v 1.80.18.7 2005/09/05 00:18:10 marka Exp $ + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +@BIND9_VERSION@ + +@BIND9_MAKE_INCLUDES@ + +# +# Add database drivers here. +# +DBDRIVER_OBJS = +DBDRIVER_SRCS = +DBDRIVER_INCLUDES = +DBDRIVER_LIBS = + +DLZ_DRIVER_DIR = ${top_srcdir}/contrib/dlz/drivers + +DLZDRIVER_OBJS = @DLZ_DRIVER_OBJS@ +DLZDRIVER_SRCS = @DLZ_DRIVER_SRCS@ +DLZDRIVER_INCLUDES = @DLZ_DRIVER_INCLUDES@ +DLZDRIVER_LIBS = @DLZ_DRIVER_LIBS@ + +CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include \ + ${LWRES_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} \ + ${ISCCFG_INCLUDES} ${ISCCC_INCLUDES} ${ISC_INCLUDES} \ + ${DLZDRIVER_INCLUDES} ${DBDRIVER_INCLUDES} + +CDEFINES = @USE_DLZ@ + +CWARNINGS = + +DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ +ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ +ISCCCLIBS = ../../lib/isccc/libisccc.@A@ +ISCLIBS = ../../lib/isc/libisc.@A@ +LWRESLIBS = ../../lib/lwres/liblwres.@A@ +BIND9LIBS = ../../lib/bind9/libbind9.@A@ + +DNSDEPLIBS = ../../lib/dns/libdns.@A@ +ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ +ISCCCDEPLIBS = ../../lib/isccc/libisccc.@A@ +ISCDEPLIBS = ../../lib/isc/libisc.@A@ +LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@ +BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ + +DEPLIBS = ${LWRESDEPLIBS} ${DNSDEPLIBS} ${BIND9DEPLIBS} \ + ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${ISCDEPLIBS} + +LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \ + ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCLIBS} \ + ${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBS@ + +SUBDIRS = unix + +TARGETS = named@EXEEXT@ lwresd@EXEEXT@ + +OBJS = builtin.@O@ client.@O@ config.@O@ control.@O@ \ + controlconf.@O@ interfacemgr.@O@ \ + listenlist.@O@ log.@O@ logconf.@O@ main.@O@ notify.@O@ \ + query.@O@ server.@O@ sortlist.@O@ \ + tkeyconf.@O@ tsigconf.@O@ update.@O@ xfrout.@O@ \ + zoneconf.@O@ \ + lwaddr.@O@ lwresd.@O@ lwdclient.@O@ lwderror.@O@ lwdgabn.@O@ \ + lwdgnba.@O@ lwdgrbn.@O@ lwdnoop.@O@ lwsearch.@O@ \ + ${DLZDRIVER_OBJS} ${DBDRIVER_OBJS} + +UOBJS = unix/os.@O@ + +SRCS = builtin.c client.c config.c control.c \ + controlconf.c interfacemgr.c \ + listenlist.c log.c logconf.c main.c notify.c \ + query.c server.c sortlist.c \ + tkeyconf.c tsigconf.c update.c xfrout.c \ + zoneconf.c \ + lwaddr.c lwresd.c lwdclient.c lwderror.c lwdgabn.c \ + lwdgnba.c lwdgrbn.c lwdnoop.c lwsearch.c \ + ${DLZDRIVER_SRCS} ${DBDRIVER_SRCS} + +MANPAGES = named.8 lwresd.8 named.conf.5 + +HTMLPAGES = named.html lwresd.html named.conf.html + +MANOBJS = ${MANPAGES} ${HTMLPAGES} + +@BIND9_MAKE_RULES@ + +main.@O@: main.c + ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ + -DVERSION=\"${VERSION}\" \ + -DNS_LOCALSTATEDIR=\"${localstatedir}\" \ + -DNS_SYSCONFDIR=\"${sysconfdir}\" -c ${srcdir}/main.c + +config.@O@: config.c + ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ + -DVERSION=\"${VERSION}\" \ + -DNS_LOCALSTATEDIR=\"${localstatedir}\" \ + -c ${srcdir}/config.c + +named@EXEEXT@: ${OBJS} ${UOBJS} ${DEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ + ${OBJS} ${UOBJS} ${LIBS} + +lwresd@EXEEXT@: named@EXEEXT@ + rm -f lwresd@EXEEXT@ + @LN@ named@EXEEXT@ lwresd@EXEEXT@ + +doc man:: ${MANOBJS} + +docclean manclean maintainer-clean:: + rm -f ${MANOBJS} + +clean distclean maintainer-clean:: + rm -f ${TARGETS} ${OBJS} + +installdirs: + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man5 + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 + +install:: named@EXEEXT@ lwresd@EXEEXT@ installdirs + ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named@EXEEXT@ ${DESTDIR}${sbindir} + (cd ${DESTDIR}${sbindir}; rm -f lwresd@EXEEXT@; @LN@ named@EXEEXT@ lwresd@EXEEXT@) + ${INSTALL_DATA} ${srcdir}/named.8 ${DESTDIR}${mandir}/man8 + ${INSTALL_DATA} ${srcdir}/lwresd.8 ${DESTDIR}${mandir}/man8 + ${INSTALL_DATA} ${srcdir}/named.conf.5 ${DESTDIR}${mandir}/man5 + +@DLZ_DRIVER_RULES@ diff --git a/bin/named/builtin.c b/bin/named/builtin.c new file mode 100644 index 0000000..06cbd4a --- /dev/null +++ b/bin/named/builtin.c @@ -0,0 +1,307 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2001-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: builtin.c,v 1.5.18.5 2005/08/23 04:12:38 marka Exp $ */ + +/*! \file + * \brief + * The built-in "version", "hostname", "id", "authors" and "empty" databases. + */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +typedef struct builtin builtin_t; + +static isc_result_t do_version_lookup(dns_sdblookup_t *lookup); +static isc_result_t do_hostname_lookup(dns_sdblookup_t *lookup); +static isc_result_t do_authors_lookup(dns_sdblookup_t *lookup); +static isc_result_t do_id_lookup(dns_sdblookup_t *lookup); +static isc_result_t do_empty_lookup(dns_sdblookup_t *lookup); + +/* + * We can't use function pointers as the db_data directly + * because ANSI C does not guarantee that function pointers + * can safely be cast to void pointers and back. + */ + +struct builtin { + isc_result_t (*do_lookup)(dns_sdblookup_t *lookup); + char *server; + char *contact; +}; + +static builtin_t version_builtin = { do_version_lookup, NULL, NULL }; +static builtin_t hostname_builtin = { do_hostname_lookup, NULL, NULL }; +static builtin_t authors_builtin = { do_authors_lookup, NULL, NULL }; +static builtin_t id_builtin = { do_id_lookup, NULL, NULL }; +static builtin_t empty_builtin = { do_empty_lookup, NULL, NULL }; + +static dns_sdbimplementation_t *builtin_impl; + +static isc_result_t +builtin_lookup(const char *zone, const char *name, void *dbdata, + dns_sdblookup_t *lookup) +{ + builtin_t *b = (builtin_t *) dbdata; + + UNUSED(zone); + + if (strcmp(name, "@") == 0) + return (b->do_lookup(lookup)); + else + return (ISC_R_NOTFOUND); +} + +static isc_result_t +put_txt(dns_sdblookup_t *lookup, const char *text) { + unsigned char buf[256]; + unsigned int len = strlen(text); + if (len > 255) + len = 255; /* Silently truncate */ + buf[0] = len; + memcpy(&buf[1], text, len); + return (dns_sdb_putrdata(lookup, dns_rdatatype_txt, 0, buf, len + 1)); +} + +static isc_result_t +do_version_lookup(dns_sdblookup_t *lookup) { + if (ns_g_server->version_set) { + if (ns_g_server->version == NULL) + return (ISC_R_SUCCESS); + else + return (put_txt(lookup, ns_g_server->version)); + } else { + return (put_txt(lookup, ns_g_version)); + } +} + +static isc_result_t +do_hostname_lookup(dns_sdblookup_t *lookup) { + if (ns_g_server->hostname_set) { + if (ns_g_server->hostname == NULL) + return (ISC_R_SUCCESS); + else + return (put_txt(lookup, ns_g_server->hostname)); + } else { + char buf[256]; + isc_result_t result = ns_os_gethostname(buf, sizeof(buf)); + if (result != ISC_R_SUCCESS) + return (result); + return (put_txt(lookup, buf)); + } +} + +static isc_result_t +do_authors_lookup(dns_sdblookup_t *lookup) { + isc_result_t result; + const char **p; + static const char *authors[] = { + "Mark Andrews", + "James Brister", + "Ben Cottrell", + "Michael Graff", + "Andreas Gustafsson", + "Bob Halley", + "David Lawrence", + "Danny Mayer", + "Damien Neil", + "Matt Nelson", + "Michael Sawyer", + "Brian Wellington", + NULL + }; + + /* + * If a version string is specified, disable the authors.bind zone. + */ + if (ns_g_server->version_set) + return (ISC_R_SUCCESS); + + for (p = authors; *p != NULL; p++) { + result = put_txt(lookup, *p); + if (result != ISC_R_SUCCESS) + return (result); + } + return (ISC_R_SUCCESS); +} + +static isc_result_t +do_id_lookup(dns_sdblookup_t *lookup) { + + if (ns_g_server->server_usehostname) { + char buf[256]; + isc_result_t result = ns_os_gethostname(buf, sizeof(buf)); + if (result != ISC_R_SUCCESS) + return (result); + return (put_txt(lookup, buf)); + } + + if (ns_g_server->server_id == NULL) + return (ISC_R_SUCCESS); + else + return (put_txt(lookup, ns_g_server->server_id)); +} + +static isc_result_t +do_empty_lookup(dns_sdblookup_t *lookup) { + + UNUSED(lookup); + return (ISC_R_SUCCESS); +} + +static isc_result_t +builtin_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) { + isc_result_t result; + const char *contact = "hostmaster"; + const char *server = "@"; + builtin_t *b = (builtin_t *) dbdata; + + UNUSED(zone); + UNUSED(dbdata); + + if (b == &empty_builtin) { + server = "."; + contact = "."; + } else { + if (b->server != NULL) + server = b->server; + if (b->contact != NULL) + contact = b->contact; + } + + result = dns_sdb_putsoa(lookup, server, contact, 0); + if (result != ISC_R_SUCCESS) + return (ISC_R_FAILURE); + + result = dns_sdb_putrr(lookup, "ns", 0, server); + if (result != ISC_R_SUCCESS) + return (ISC_R_FAILURE); + + return (ISC_R_SUCCESS); +} + +static isc_result_t +builtin_create(const char *zone, int argc, char **argv, + void *driverdata, void **dbdata) +{ + REQUIRE(argc >= 1); + + UNUSED(zone); + UNUSED(driverdata); + + if (strcmp(argv[0], "empty") == 0) { + if (argc != 3) + return (DNS_R_SYNTAX); + } else if (argc != 1) + return (DNS_R_SYNTAX); + + if (strcmp(argv[0], "version") == 0) + *dbdata = &version_builtin; + else if (strcmp(argv[0], "hostname") == 0) + *dbdata = &hostname_builtin; + else if (strcmp(argv[0], "authors") == 0) + *dbdata = &authors_builtin; + else if (strcmp(argv[0], "id") == 0) + *dbdata = &id_builtin; + else if (strcmp(argv[0], "empty") == 0) { + builtin_t *empty; + char *server; + char *contact; + /* + * We don't want built-in zones to fail. Fallback to + * the static configuration if memory allocation fails. + */ + empty = isc_mem_get(ns_g_mctx, sizeof(*empty)); + server = isc_mem_strdup(ns_g_mctx, argv[1]); + contact = isc_mem_strdup(ns_g_mctx, argv[2]); + if (empty == NULL || server == NULL || contact == NULL) { + *dbdata = &empty_builtin; + if (server != NULL) + isc_mem_free(ns_g_mctx, server); + if (contact != NULL) + isc_mem_free(ns_g_mctx, contact); + if (empty != NULL) + isc_mem_put(ns_g_mctx, empty, sizeof (*empty)); + } else { + memcpy(empty, &empty_builtin, sizeof (empty_builtin)); + empty->server = server; + empty->contact = contact; + *dbdata = empty; + } + } else + return (ISC_R_NOTIMPLEMENTED); + return (ISC_R_SUCCESS); +} + +static void +builtin_destroy(const char *zone, void *driverdata, void **dbdata) { + builtin_t *b = (builtin_t *) *dbdata; + + UNUSED(zone); + UNUSED(driverdata); + + /* + * Don't free the static versions. + */ + if (*dbdata == &version_builtin || *dbdata == &hostname_builtin || + *dbdata == &authors_builtin || *dbdata == &id_builtin || + *dbdata == &empty_builtin) + return; + + isc_mem_free(ns_g_mctx, b->server); + isc_mem_free(ns_g_mctx, b->contact); + isc_mem_put(ns_g_mctx, b, sizeof (*b)); +} + +static dns_sdbmethods_t builtin_methods = { + builtin_lookup, + builtin_authority, + NULL, /* allnodes */ + builtin_create, + builtin_destroy +}; + +isc_result_t +ns_builtin_init(void) { + RUNTIME_CHECK(dns_sdb_register("_builtin", &builtin_methods, NULL, + DNS_SDBFLAG_RELATIVEOWNER | + DNS_SDBFLAG_RELATIVERDATA, + ns_g_mctx, &builtin_impl) + == ISC_R_SUCCESS); + return (ISC_R_SUCCESS); +} + +void +ns_builtin_deinit(void) { + dns_sdb_unregister(&builtin_impl); +} diff --git a/bin/named/client.c b/bin/named/client.c new file mode 100644 index 0000000..b0e9cdd --- /dev/null +++ b/bin/named/client.c @@ -0,0 +1,2643 @@ +/* + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-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: client.c,v 1.219.18.28 2007/08/28 07:20:00 tbox Exp $ */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/*** + *** Client + ***/ + +/*! \file + * Client Routines + * + * Important note! + * + * All client state changes, other than that from idle to listening, occur + * as a result of events. This guarantees serialization and avoids the + * need for locking. + * + * If a routine is ever created that allows someone other than the client's + * task to change the client, then the client will have to be locked. + */ + +#define NS_CLIENT_TRACE +#ifdef NS_CLIENT_TRACE +#define CTRACE(m) ns_client_log(client, \ + NS_LOGCATEGORY_CLIENT, \ + NS_LOGMODULE_CLIENT, \ + ISC_LOG_DEBUG(3), \ + "%s", (m)) +#define MTRACE(m) isc_log_write(ns_g_lctx, \ + NS_LOGCATEGORY_GENERAL, \ + NS_LOGMODULE_CLIENT, \ + ISC_LOG_DEBUG(3), \ + "clientmgr @%p: %s", manager, (m)) +#else +#define CTRACE(m) ((void)(m)) +#define MTRACE(m) ((void)(m)) +#endif + +#define TCP_CLIENT(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0) + +#define TCP_BUFFER_SIZE (65535 + 2) +#define SEND_BUFFER_SIZE 4096 +#define RECV_BUFFER_SIZE 4096 + +#ifdef ISC_PLATFORM_USETHREADS +#define NMCTXS 100 +/*%< + * Number of 'mctx pools' for clients. (Should this be configurable?) + * When enabling threads, we use a pool of memory contexts shared by + * client objects, since concurrent access to a shared context would cause + * heavy contentions. The above constant is expected to be enough for + * completely avoiding contentions among threads for an authoritative-only + * server. + */ +#else +#define NMCTXS 0 +/*%< + * If named with built without thread, simply share manager's context. Using + * a separate context in this case would simply waste memory. + */ +#endif + +/*% nameserver client manager structure */ +struct ns_clientmgr { + /* Unlocked. */ + unsigned int magic; + isc_mem_t * mctx; + isc_taskmgr_t * taskmgr; + isc_timermgr_t * timermgr; + isc_mutex_t lock; + /* Locked by lock. */ + isc_boolean_t exiting; + client_list_t active; /*%< Active clients */ + client_list_t recursing; /*%< Recursing clients */ + client_list_t inactive; /*%< To be recycled */ +#if NMCTXS > 0 + /*%< mctx pool for clients. */ + unsigned int nextmctx; + isc_mem_t * mctxpool[NMCTXS]; +#endif +}; + +#define MANAGER_MAGIC ISC_MAGIC('N', 'S', 'C', 'm') +#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, MANAGER_MAGIC) + +/*! + * Client object states. Ordering is significant: higher-numbered + * states are generally "more active", meaning that the client can + * have more dynamically allocated data, outstanding events, etc. + * In the list below, any such properties listed for state N + * also apply to any state > N. + * + * To force the client into a less active state, set client->newstate + * to that state and call exit_check(). This will cause any + * activities defined for higher-numbered states to be aborted. + */ + +#define NS_CLIENTSTATE_FREED 0 +/*%< + * The client object no longer exists. + */ + +#define NS_CLIENTSTATE_INACTIVE 1 +/*%< + * The client object exists and has a task and timer. + * Its "query" struct and sendbuf are initialized. + * It is on the client manager's list of inactive clients. + * It has a message and OPT, both in the reset state. + */ + +#define NS_CLIENTSTATE_READY 2 +/*%< + * The client object is either a TCP or a UDP one, and + * it is associated with a network interface. It is on the + * client manager's list of active clients. + * + * If it is a TCP client object, it has a TCP listener socket + * and an outstanding TCP listen request. + * + * If it is a UDP client object, it has a UDP listener socket + * and an outstanding UDP receive request. + */ + +#define NS_CLIENTSTATE_READING 3 +/*%< + * The client object is a TCP client object that has received + * a connection. It has a tcpsocket, tcpmsg, TCP quota, and an + * outstanding TCP read request. This state is not used for + * UDP client objects. + */ + +#define NS_CLIENTSTATE_WORKING 4 +/*%< + * The client object has received a request and is working + * on it. It has a view, and it may have any of a non-reset OPT, + * recursion quota, and an outstanding write request. + */ + +#define NS_CLIENTSTATE_MAX 9 +/*%< + * Sentinel value used to indicate "no state". When client->newstate + * has this value, we are not attempting to exit the current state. + * Must be greater than any valid state. + */ + +/* + * Enable ns_client_dropport() by default. + */ +#ifndef NS_CLIENT_DROPPORT +#define NS_CLIENT_DROPPORT 1 +#endif + +unsigned int ns_client_requests; + +static void client_read(ns_client_t *client); +static void client_accept(ns_client_t *client); +static void client_udprecv(ns_client_t *client); +static void clientmgr_destroy(ns_clientmgr_t *manager); +static isc_boolean_t exit_check(ns_client_t *client); +static void ns_client_endrequest(ns_client_t *client); +static void ns_client_checkactive(ns_client_t *client); +static void client_start(isc_task_t *task, isc_event_t *event); +static void client_request(isc_task_t *task, isc_event_t *event); +static void ns_client_dumpmessage(ns_client_t *client, const char *reason); + +void +ns_client_recursing(ns_client_t *client) { + REQUIRE(NS_CLIENT_VALID(client)); + + LOCK(&client->manager->lock); + ISC_LIST_UNLINK(*client->list, client, link); + ISC_LIST_APPEND(client->manager->recursing, client, link); + client->list = &client->manager->recursing; + UNLOCK(&client->manager->lock); +} + +void +ns_client_killoldestquery(ns_client_t *client) { + ns_client_t *oldest; + REQUIRE(NS_CLIENT_VALID(client)); + + LOCK(&client->manager->lock); + oldest = ISC_LIST_HEAD(client->manager->recursing); + if (oldest != NULL) { + ns_query_cancel(oldest); + ISC_LIST_UNLINK(*oldest->list, oldest, link); + ISC_LIST_APPEND(client->manager->active, oldest, link); + oldest->list = &client->manager->active; + } + UNLOCK(&client->manager->lock); +} + +void +ns_client_settimeout(ns_client_t *client, unsigned int seconds) { + isc_result_t result; + isc_interval_t interval; + + isc_interval_set(&interval, seconds, 0); + result = isc_timer_reset(client->timer, isc_timertype_once, NULL, + &interval, ISC_FALSE); + client->timerset = ISC_TRUE; + if (result != ISC_R_SUCCESS) { + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_ERROR, + "setting timeout: %s", + isc_result_totext(result)); + /* Continue anyway. */ + } +} + +/*% + * Check for a deactivation or shutdown request and take appropriate + * action. Returns ISC_TRUE if either is in progress; in this case + * the caller must no longer use the client object as it may have been + * freed. + */ +static isc_boolean_t +exit_check(ns_client_t *client) { + ns_clientmgr_t *locked_manager = NULL; + ns_clientmgr_t *destroy_manager = NULL; + + REQUIRE(NS_CLIENT_VALID(client)); + + if (client->state <= client->newstate) + return (ISC_FALSE); /* Business as usual. */ + + INSIST(client->newstate < NS_CLIENTSTATE_WORKING); + + /* + * We need to detach from the view early when shutting down + * the server to break the following vicious circle: + * + * - The resolver will not shut down until the view refcount is zero + * - The view refcount does not go to zero until all clients detach + * - The client does not detach from the view until references is zero + * - references does not go to zero until the resolver has shut down + * + * Keep the view attached until any outstanding updates complete. + */ + if (client->nupdates == 0 && + client->newstate == NS_CLIENTSTATE_FREED && client->view != NULL) + dns_view_detach(&client->view); + + if (client->state == NS_CLIENTSTATE_WORKING) { + INSIST(client->newstate <= NS_CLIENTSTATE_READING); + /* + * Let the update processing complete. + */ + if (client->nupdates > 0) + return (ISC_TRUE); + /* + * We are trying to abort request processing. + */ + if (client->nsends > 0) { + isc_socket_t *socket; + if (TCP_CLIENT(client)) + socket = client->tcpsocket; + else + socket = client->udpsocket; + isc_socket_cancel(socket, client->task, + ISC_SOCKCANCEL_SEND); + } + + if (! (client->nsends == 0 && client->nrecvs == 0 && + client->references == 0)) + { + /* + * Still waiting for I/O cancel completion. + * or lingering references. + */ + return (ISC_TRUE); + } + /* + * I/O cancel is complete. Burn down all state + * related to the current request. Ensure that + * the client is on the active list and not the + * recursing list. + */ + LOCK(&client->manager->lock); + if (client->list == &client->manager->recursing) { + ISC_LIST_UNLINK(*client->list, client, link); + ISC_LIST_APPEND(client->manager->active, client, link); + client->list = &client->manager->active; + } + UNLOCK(&client->manager->lock); + ns_client_endrequest(client); + + client->state = NS_CLIENTSTATE_READING; + INSIST(client->recursionquota == NULL); + if (NS_CLIENTSTATE_READING == client->newstate) { + client_read(client); + client->newstate = NS_CLIENTSTATE_MAX; + return (ISC_TRUE); /* We're done. */ + } + } + + if (client->state == NS_CLIENTSTATE_READING) { + /* + * We are trying to abort the current TCP connection, + * if any. + */ + INSIST(client->recursionquota == NULL); + INSIST(client->newstate <= NS_CLIENTSTATE_READY); + if (client->nreads > 0) + dns_tcpmsg_cancelread(&client->tcpmsg); + if (! client->nreads == 0) { + /* Still waiting for read cancel completion. */ + return (ISC_TRUE); + } + + if (client->tcpmsg_valid) { + dns_tcpmsg_invalidate(&client->tcpmsg); + client->tcpmsg_valid = ISC_FALSE; + } + if (client->tcpsocket != NULL) { + CTRACE("closetcp"); + isc_socket_detach(&client->tcpsocket); + } + + if (client->tcpquota != NULL) + isc_quota_detach(&client->tcpquota); + + if (client->timerset) { + (void)isc_timer_reset(client->timer, + isc_timertype_inactive, + NULL, NULL, ISC_TRUE); + client->timerset = ISC_FALSE; + } + + client->peeraddr_valid = ISC_FALSE; + + client->state = NS_CLIENTSTATE_READY; + INSIST(client->recursionquota == NULL); + + /* + * Now the client is ready to accept a new TCP connection + * or UDP request, but we may have enough clients doing + * that already. Check whether this client needs to remain + * active and force it to go inactive if not. + */ + ns_client_checkactive(client); + + if (NS_CLIENTSTATE_READY == client->newstate) { + if (TCP_CLIENT(client)) { + client_accept(client); + } else + client_udprecv(client); + client->newstate = NS_CLIENTSTATE_MAX; + return (ISC_TRUE); + } + } + + if (client->state == NS_CLIENTSTATE_READY) { + INSIST(client->newstate <= NS_CLIENTSTATE_INACTIVE); + /* + * We are trying to enter the inactive state. + */ + if (client->naccepts > 0) + isc_socket_cancel(client->tcplistener, client->task, + ISC_SOCKCANCEL_ACCEPT); + + if (! (client->naccepts == 0)) { + /* Still waiting for accept cancel completion. */ + return (ISC_TRUE); + } + /* Accept cancel is complete. */ + + if (client->nrecvs > 0) + isc_socket_cancel(client->udpsocket, client->task, + ISC_SOCKCANCEL_RECV); + if (! (client->nrecvs == 0)) { + /* Still waiting for recv cancel completion. */ + return (ISC_TRUE); + } + /* Recv cancel is complete. */ + + if (client->nctls > 0) { + /* Still waiting for control event to be delivered */ + return (ISC_TRUE); + } + + /* Deactivate the client. */ + if (client->interface) + ns_interface_detach(&client->interface); + + INSIST(client->naccepts == 0); + INSIST(client->recursionquota == NULL); + if (client->tcplistener != NULL) + isc_socket_detach(&client->tcplistener); + + if (client->udpsocket != NULL) + isc_socket_detach(&client->udpsocket); + + if (client->dispatch != NULL) + dns_dispatch_detach(&client->dispatch); + + client->attributes = 0; + client->mortal = ISC_FALSE; + + LOCK(&client->manager->lock); + /* + * Put the client on the inactive list. If we are aiming for + * the "freed" state, it will be removed from the inactive + * list shortly, and we need to keep the manager locked until + * that has been done, lest the manager decide to reactivate + * the dying client inbetween. + */ + locked_manager = client->manager; + ISC_LIST_UNLINK(*client->list, client, link); + ISC_LIST_APPEND(client->manager->inactive, client, link); + client->list = &client->manager->inactive; + client->state = NS_CLIENTSTATE_INACTIVE; + INSIST(client->recursionquota == NULL); + + if (client->state == client->newstate) { + client->newstate = NS_CLIENTSTATE_MAX; + goto unlock; + } + } + + if (client->state == NS_CLIENTSTATE_INACTIVE) { + INSIST(client->newstate == NS_CLIENTSTATE_FREED); + /* + * We are trying to free the client. + * + * When "shuttingdown" is true, either the task has received + * its shutdown event or no shutdown event has ever been + * set up. Thus, we have no outstanding shutdown + * event at this point. + */ + REQUIRE(client->state == NS_CLIENTSTATE_INACTIVE); + + INSIST(client->recursionquota == NULL); + + ns_query_free(client); + isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE); + isc_event_free((isc_event_t **)&client->sendevent); + isc_event_free((isc_event_t **)&client->recvevent); + isc_timer_detach(&client->timer); + + if (client->tcpbuf != NULL) + isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); + if (client->opt != NULL) { + INSIST(dns_rdataset_isassociated(client->opt)); + dns_rdataset_disassociate(client->opt); + dns_message_puttemprdataset(client->message, &client->opt); + } + dns_message_destroy(&client->message); + if (client->manager != NULL) { + ns_clientmgr_t *manager = client->manager; + if (locked_manager == NULL) { + LOCK(&manager->lock); + locked_manager = manager; + } + ISC_LIST_UNLINK(*client->list, client, link); + client->list = NULL; + if (manager->exiting && + ISC_LIST_EMPTY(manager->active) && + ISC_LIST_EMPTY(manager->inactive) && + ISC_LIST_EMPTY(manager->recursing)) + destroy_manager = manager; + } + /* + * Detaching the task must be done after unlinking from + * the manager's lists because the manager accesses + * client->task. + */ + if (client->task != NULL) + isc_task_detach(&client->task); + + CTRACE("free"); + client->magic = 0; + isc_mem_putanddetach(&client->mctx, client, sizeof(*client)); + + goto unlock; + } + + unlock: + if (locked_manager != NULL) { + UNLOCK(&locked_manager->lock); + locked_manager = NULL; + } + + /* + * Only now is it safe to destroy the client manager (if needed), + * because we have accessed its lock for the last time. + */ + if (destroy_manager != NULL) + clientmgr_destroy(destroy_manager); + + return (ISC_TRUE); +} + +/*% + * The client's task has received the client's control event + * as part of the startup process. + */ +static void +client_start(isc_task_t *task, isc_event_t *event) { + ns_client_t *client = (ns_client_t *) event->ev_arg; + + INSIST(task == client->task); + + UNUSED(task); + + INSIST(client->nctls == 1); + client->nctls--; + + if (exit_check(client)) + return; + + if (TCP_CLIENT(client)) { + client_accept(client); + } else { + client_udprecv(client); + } +} + + +/*% + * The client's task has received a shutdown event. + */ +static void +client_shutdown(isc_task_t *task, isc_event_t *event) { + ns_client_t *client; + + REQUIRE(event != NULL); + REQUIRE(event->ev_type == ISC_TASKEVENT_SHUTDOWN); + client = event->ev_arg; + REQUIRE(NS_CLIENT_VALID(client)); + REQUIRE(task == client->task); + + UNUSED(task); + + CTRACE("shutdown"); + + isc_event_free(&event); + + if (client->shutdown != NULL) { + (client->shutdown)(client->shutdown_arg, ISC_R_SHUTTINGDOWN); + client->shutdown = NULL; + client->shutdown_arg = NULL; + } + + client->newstate = NS_CLIENTSTATE_FREED; + (void)exit_check(client); +} + +static void +ns_client_endrequest(ns_client_t *client) { + INSIST(client->naccepts == 0); + INSIST(client->nreads == 0); + INSIST(client->nsends == 0); + INSIST(client->nrecvs == 0); + INSIST(client->nupdates == 0); + INSIST(client->state == NS_CLIENTSTATE_WORKING); + + CTRACE("endrequest"); + + if (client->next != NULL) { + (client->next)(client); + client->next = NULL; + } + + if (client->view != NULL) + dns_view_detach(&client->view); + if (client->opt != NULL) { + INSIST(dns_rdataset_isassociated(client->opt)); + dns_rdataset_disassociate(client->opt); + dns_message_puttemprdataset(client->message, &client->opt); + } + + client->udpsize = 512; + client->extflags = 0; + client->ednsversion = -1; + dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE); + + if (client->recursionquota != NULL) + isc_quota_detach(&client->recursionquota); + + /* + * Clear all client attributes that are specific to + * the request; that's all except the TCP flag. + */ + client->attributes &= NS_CLIENTATTR_TCP; +} + +static void +ns_client_checkactive(ns_client_t *client) { + if (client->mortal) { + /* + * This client object should normally go inactive + * at this point, but if we have fewer active client + * objects than desired due to earlier quota exhaustion, + * keep it active to make up for the shortage. + */ + isc_boolean_t need_another_client = ISC_FALSE; + if (TCP_CLIENT(client)) { + LOCK(&client->interface->lock); + if (client->interface->ntcpcurrent < + client->interface->ntcptarget) + need_another_client = ISC_TRUE; + UNLOCK(&client->interface->lock); + } else { + /* + * The UDP client quota is enforced by making + * requests fail rather than by not listening + * for new ones. Therefore, there is always a + * full set of UDP clients listening. + */ + } + if (! need_another_client) { + /* + * We don't need this client object. Recycle it. + */ + if (client->newstate >= NS_CLIENTSTATE_INACTIVE) + client->newstate = NS_CLIENTSTATE_INACTIVE; + } + } +} + +void +ns_client_next(ns_client_t *client, isc_result_t result) { + int newstate; + + REQUIRE(NS_CLIENT_VALID(client)); + REQUIRE(client->state == NS_CLIENTSTATE_WORKING || + client->state == NS_CLIENTSTATE_READING); + + CTRACE("next"); + + if (result != ISC_R_SUCCESS) + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), + "request failed: %s", isc_result_totext(result)); + + /* + * An error processing a TCP request may have left + * the connection out of sync. To be safe, we always + * sever the connection when result != ISC_R_SUCCESS. + */ + if (result == ISC_R_SUCCESS && TCP_CLIENT(client)) + newstate = NS_CLIENTSTATE_READING; + else + newstate = NS_CLIENTSTATE_READY; + + if (client->newstate > newstate) + client->newstate = newstate; + (void)exit_check(client); +} + + +static void +client_senddone(isc_task_t *task, isc_event_t *event) { + ns_client_t *client; + isc_socketevent_t *sevent = (isc_socketevent_t *) event; + + REQUIRE(sevent != NULL); + REQUIRE(sevent->ev_type == ISC_SOCKEVENT_SENDDONE); + client = sevent->ev_arg; + REQUIRE(NS_CLIENT_VALID(client)); + REQUIRE(task == client->task); + REQUIRE(sevent == client->sendevent); + + UNUSED(task); + + CTRACE("senddone"); + + if (sevent->result != ISC_R_SUCCESS) + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_WARNING, + "error sending response: %s", + isc_result_totext(sevent->result)); + + INSIST(client->nsends > 0); + client->nsends--; + + if (client->tcpbuf != NULL) { + INSIST(TCP_CLIENT(client)); + isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); + client->tcpbuf = NULL; + } + + if (exit_check(client)) + return; + + ns_client_next(client, ISC_R_SUCCESS); +} + +/*% + * We only want to fail with ISC_R_NOSPACE when called from + * ns_client_sendraw() and not when called from ns_client_send(), + * tcpbuffer is NULL when called from ns_client_sendraw() and + * length != 0. tcpbuffer != NULL when called from ns_client_send() + * and length == 0. + */ + +static isc_result_t +client_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer, + isc_buffer_t *tcpbuffer, isc_uint32_t length, + unsigned char *sendbuf, unsigned char **datap) +{ + unsigned char *data; + isc_uint32_t bufsize; + isc_result_t result; + + INSIST(datap != NULL); + INSIST((tcpbuffer == NULL && length != 0) || + (tcpbuffer != NULL && length == 0)); + + if (TCP_CLIENT(client)) { + INSIST(client->tcpbuf == NULL); + if (length + 2 > TCP_BUFFER_SIZE) { + result = ISC_R_NOSPACE; + goto done; + } + client->tcpbuf = isc_mem_get(client->mctx, TCP_BUFFER_SIZE); + if (client->tcpbuf == NULL) { + result = ISC_R_NOMEMORY; + goto done; + } + data = client->tcpbuf; + if (tcpbuffer != NULL) { + isc_buffer_init(tcpbuffer, data, TCP_BUFFER_SIZE); + isc_buffer_init(buffer, data + 2, TCP_BUFFER_SIZE - 2); + } else { + isc_buffer_init(buffer, data, TCP_BUFFER_SIZE); + INSIST(length <= 0xffff); + isc_buffer_putuint16(buffer, (isc_uint16_t)length); + } + } else { + data = sendbuf; + if (client->udpsize < SEND_BUFFER_SIZE) + bufsize = client->udpsize; + else + bufsize = SEND_BUFFER_SIZE; + if (length > bufsize) { + result = ISC_R_NOSPACE; + goto done; + } + isc_buffer_init(buffer, data, bufsize); + } + *datap = data; + result = ISC_R_SUCCESS; + + done: + return (result); +} + +static isc_result_t +client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) { + struct in6_pktinfo *pktinfo; + isc_result_t result; + isc_region_t r; + isc_sockaddr_t *address; + isc_socket_t *socket; + isc_netaddr_t netaddr; + int match; + unsigned int sockflags = ISC_SOCKFLAG_IMMEDIATE; + + if (TCP_CLIENT(client)) { + socket = client->tcpsocket; + address = NULL; + } else { + socket = client->udpsocket; + address = &client->peeraddr; + + isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); + if (ns_g_server->blackholeacl != NULL && + dns_acl_match(&netaddr, NULL, + ns_g_server->blackholeacl, + &ns_g_server->aclenv, + &match, NULL) == ISC_R_SUCCESS && + match > 0) + return (DNS_R_BLACKHOLED); + sockflags |= ISC_SOCKFLAG_NORETRY; + } + + if ((client->attributes & NS_CLIENTATTR_PKTINFO) != 0 && + (client->attributes & NS_CLIENTATTR_MULTICAST) == 0) + pktinfo = &client->pktinfo; + else + pktinfo = NULL; + + isc_buffer_usedregion(buffer, &r); + + CTRACE("sendto"); + + result = isc_socket_sendto2(socket, &r, client->task, + address, pktinfo, + client->sendevent, sockflags); + if (result == ISC_R_SUCCESS || result == ISC_R_INPROGRESS) { + client->nsends++; + if (result == ISC_R_SUCCESS) + client_senddone(client->task, + (isc_event_t *)client->sendevent); + result = ISC_R_SUCCESS; + } + return (result); +} + +void +ns_client_sendraw(ns_client_t *client, dns_message_t *message) { + isc_result_t result; + unsigned char *data; + isc_buffer_t buffer; + isc_region_t r; + isc_region_t *mr; + unsigned char sendbuf[SEND_BUFFER_SIZE]; + + REQUIRE(NS_CLIENT_VALID(client)); + + CTRACE("sendraw"); + + mr = dns_message_getrawmessage(message); + if (mr == NULL) { + result = ISC_R_UNEXPECTEDEND; + goto done; + } + + result = client_allocsendbuf(client, &buffer, NULL, mr->length, + sendbuf, &data); + if (result != ISC_R_SUCCESS) + goto done; + + /* + * Copy message to buffer and fixup id. + */ + isc_buffer_availableregion(&buffer, &r); + result = isc_buffer_copyregion(&buffer, mr); + if (result != ISC_R_SUCCESS) + goto done; + r.base[0] = (client->message->id >> 8) & 0xff; + r.base[1] = client->message->id & 0xff; + + result = client_sendpkg(client, &buffer); + if (result == ISC_R_SUCCESS) + return; + + done: + if (client->tcpbuf != NULL) { + isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); + client->tcpbuf = NULL; + } + ns_client_next(client, result); +} + +void +ns_client_send(ns_client_t *client) { + isc_result_t result; + unsigned char *data; + isc_buffer_t buffer; + isc_buffer_t tcpbuffer; + isc_region_t r; + dns_compress_t cctx; + isc_boolean_t cleanup_cctx = ISC_FALSE; + unsigned char sendbuf[SEND_BUFFER_SIZE]; + unsigned int dnssec_opts; + unsigned int preferred_glue; + + REQUIRE(NS_CLIENT_VALID(client)); + + CTRACE("send"); + + if ((client->attributes & NS_CLIENTATTR_RA) != 0) + client->message->flags |= DNS_MESSAGEFLAG_RA; + + if ((client->attributes & NS_CLIENTATTR_WANTDNSSEC) != 0) + dnssec_opts = 0; + else + dnssec_opts = DNS_MESSAGERENDER_OMITDNSSEC; + + preferred_glue = 0; + if (client->view != NULL) { + if (client->view->preferred_glue == dns_rdatatype_a) + preferred_glue = DNS_MESSAGERENDER_PREFER_A; + else if (client->view->preferred_glue == dns_rdatatype_aaaa) + preferred_glue = DNS_MESSAGERENDER_PREFER_AAAA; + } + + /* + * XXXRTH The following doesn't deal with TCP buffer resizing. + */ + result = client_allocsendbuf(client, &buffer, &tcpbuffer, 0, + sendbuf, &data); + if (result != ISC_R_SUCCESS) + goto done; + + result = dns_compress_init(&cctx, -1, client->mctx); + if (result != ISC_R_SUCCESS) + goto done; + cleanup_cctx = ISC_TRUE; + + result = dns_message_renderbegin(client->message, &cctx, &buffer); + if (result != ISC_R_SUCCESS) + goto done; + if (client->opt != NULL) { + result = dns_message_setopt(client->message, client->opt); + /* + * XXXRTH dns_message_setopt() should probably do this... + */ + client->opt = NULL; + if (result != ISC_R_SUCCESS) + goto done; + } + result = dns_message_rendersection(client->message, + DNS_SECTION_QUESTION, 0); + if (result == ISC_R_NOSPACE) { + client->message->flags |= DNS_MESSAGEFLAG_TC; + goto renderend; + } + if (result != ISC_R_SUCCESS) + goto done; + result = dns_message_rendersection(client->message, + DNS_SECTION_ANSWER, + DNS_MESSAGERENDER_PARTIAL | + dnssec_opts); + if (result == ISC_R_NOSPACE) { + client->message->flags |= DNS_MESSAGEFLAG_TC; + goto renderend; + } + if (result != ISC_R_SUCCESS) + goto done; + result = dns_message_rendersection(client->message, + DNS_SECTION_AUTHORITY, + DNS_MESSAGERENDER_PARTIAL | + dnssec_opts); + if (result == ISC_R_NOSPACE) { + client->message->flags |= DNS_MESSAGEFLAG_TC; + goto renderend; + } + if (result != ISC_R_SUCCESS) + goto done; + result = dns_message_rendersection(client->message, + DNS_SECTION_ADDITIONAL, + preferred_glue | dnssec_opts); + if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE) + goto done; + renderend: + result = dns_message_renderend(client->message); + + if (result != ISC_R_SUCCESS) + goto done; + + if (cleanup_cctx) { + dns_compress_invalidate(&cctx); + cleanup_cctx = ISC_FALSE; + } + + if (TCP_CLIENT(client)) { + isc_buffer_usedregion(&buffer, &r); + isc_buffer_putuint16(&tcpbuffer, (isc_uint16_t) r.length); + isc_buffer_add(&tcpbuffer, r.length); + result = client_sendpkg(client, &tcpbuffer); + } else + result = client_sendpkg(client, &buffer); + if (result == ISC_R_SUCCESS) + return; + + done: + if (client->tcpbuf != NULL) { + isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); + client->tcpbuf = NULL; + } + + if (cleanup_cctx) + dns_compress_invalidate(&cctx); + + ns_client_next(client, result); +} + +#if NS_CLIENT_DROPPORT +#define DROPPORT_NO 0 +#define DROPPORT_REQUEST 1 +#define DROPPORT_RESPONSE 2 +/*% + * ns_client_dropport determines if certain requests / responses + * should be dropped based on the port number. + * + * Returns: + * \li 0: Don't drop. + * \li 1: Drop request. + * \li 2: Drop (error) response. + */ +static int +ns_client_dropport(in_port_t port) { + switch (port) { + case 7: /* echo */ + case 13: /* daytime */ + case 19: /* chargen */ + case 37: /* time */ + return (DROPPORT_REQUEST); + case 464: /* kpasswd */ + return (DROPPORT_RESPONSE); + } + return (DROPPORT_NO); +} +#endif + +void +ns_client_error(ns_client_t *client, isc_result_t result) { + dns_rcode_t rcode; + dns_message_t *message; + + REQUIRE(NS_CLIENT_VALID(client)); + + CTRACE("error"); + + message = client->message; + rcode = dns_result_torcode(result); + +#if NS_CLIENT_DROPPORT + /* + * Don't send FORMERR to ports on the drop port list. + */ + if (rcode == dns_rcode_formerr && + ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) != + DROPPORT_NO) { + char buf[64]; + isc_buffer_t b; + + isc_buffer_init(&b, buf, sizeof(buf) - 1); + if (dns_rcode_totext(rcode, &b) != ISC_R_SUCCESS) + isc_buffer_putstr(&b, "UNKNOWN RCODE"); + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), + "dropped error (%.*s) response: suspicious port", + (int)isc_buffer_usedlength(&b), buf); + ns_client_next(client, ISC_R_SUCCESS); + return; + } +#endif + + /* + * Message may be an in-progress reply that we had trouble + * with, in which case QR will be set. We need to clear QR before + * calling dns_message_reply() to avoid triggering an assertion. + */ + message->flags &= ~DNS_MESSAGEFLAG_QR; + /* + * AA and AD shouldn't be set. + */ + message->flags &= ~(DNS_MESSAGEFLAG_AA | DNS_MESSAGEFLAG_AD); + result = dns_message_reply(message, ISC_TRUE); + if (result != ISC_R_SUCCESS) { + /* + * It could be that we've got a query with a good header, + * but a bad question section, so we try again with + * want_question_section set to ISC_FALSE. + */ + result = dns_message_reply(message, ISC_FALSE); + if (result != ISC_R_SUCCESS) { + ns_client_next(client, result); + return; + } + } + message->rcode = rcode; + + /* + * FORMERR loop avoidance: If we sent a FORMERR message + * with the same ID to the same client less than two + * seconds ago, assume that we are in an infinite error + * packet dialog with a server for some protocol whose + * error responses look enough like DNS queries to + * elicit a FORMERR response. Drop a packet to break + * the loop. + */ + if (rcode == dns_rcode_formerr) { + if (isc_sockaddr_equal(&client->peeraddr, + &client->formerrcache.addr) && + message->id == client->formerrcache.id && + client->requesttime - client->formerrcache.time < 2) { + /* Drop packet. */ + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), + "possible error packet loop, " + "FORMERR dropped"); + ns_client_next(client, result); + return; + } + client->formerrcache.addr = client->peeraddr; + client->formerrcache.time = client->requesttime; + client->formerrcache.id = message->id; + } + ns_client_send(client); +} + +static inline isc_result_t +client_addopt(ns_client_t *client) { + dns_rdataset_t *rdataset; + dns_rdatalist_t *rdatalist; + dns_rdata_t *rdata; + isc_result_t result; + dns_view_t *view; + dns_resolver_t *resolver; + isc_uint16_t udpsize; + + REQUIRE(client->opt == NULL); /* XXXRTH free old. */ + + rdatalist = NULL; + result = dns_message_gettemprdatalist(client->message, &rdatalist); + if (result != ISC_R_SUCCESS) + return (result); + rdata = NULL; + result = dns_message_gettemprdata(client->message, &rdata); + if (result != ISC_R_SUCCESS) + return (result); + rdataset = NULL; + result = dns_message_gettemprdataset(client->message, &rdataset); + if (result != ISC_R_SUCCESS) + return (result); + dns_rdataset_init(rdataset); + + rdatalist->type = dns_rdatatype_opt; + rdatalist->covers = 0; + + /* + * Set the maximum UDP buffer size. + */ + view = client->view; + resolver = (view != NULL) ? view->resolver : NULL; + if (resolver != NULL) + udpsize = dns_resolver_getudpsize(resolver); + else + udpsize = ns_g_udpsize; + rdatalist->rdclass = udpsize; + + /* + * Set EXTENDED-RCODE, VERSION and Z to 0. + */ + rdatalist->ttl = (client->extflags & DNS_MESSAGEEXTFLAG_REPLYPRESERVE); + + /* + * No EDNS options in the default case. + */ + rdata->data = NULL; + rdata->length = 0; + rdata->rdclass = rdatalist->rdclass; + rdata->type = rdatalist->type; + rdata->flags = 0; + + ISC_LIST_INIT(rdatalist->rdata); + ISC_LIST_APPEND(rdatalist->rdata, rdata, link); + RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) + == ISC_R_SUCCESS); + + client->opt = rdataset; + + return (ISC_R_SUCCESS); +} + +static inline isc_boolean_t +allowed(isc_netaddr_t *addr, dns_name_t *signer, dns_acl_t *acl) { + int match; + isc_result_t result; + + if (acl == NULL) + return (ISC_TRUE); + result = dns_acl_match(addr, signer, acl, &ns_g_server->aclenv, + &match, NULL); + if (result == ISC_R_SUCCESS && match > 0) + return (ISC_TRUE); + return (ISC_FALSE); +} + +/* + * Callback to see if a non-recursive query coming from 'srcaddr' to + * 'destaddr', with optional key 'mykey' for class 'rdclass' would be + * delivered to 'myview'. + * + * We run this unlocked as both the view list and the interface list + * are updated when the approprite task has exclusivity. + */ +isc_boolean_t +ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey, + isc_sockaddr_t *srcaddr, isc_sockaddr_t *dstaddr, + dns_rdataclass_t rdclass, void *arg) +{ + dns_view_t *view; + dns_tsigkey_t *key = NULL; + dns_name_t *tsig = NULL; + isc_netaddr_t netsrc; + isc_netaddr_t netdst; + + UNUSED(arg); + + if (!ns_interfacemgr_listeningon(ns_g_server->interfacemgr, dstaddr)) + return (ISC_FALSE); + + isc_netaddr_fromsockaddr(&netsrc, srcaddr); + isc_netaddr_fromsockaddr(&netdst, dstaddr); + + for (view = ISC_LIST_HEAD(ns_g_server->viewlist); + view != NULL; + view = ISC_LIST_NEXT(view, link)) { + + if (view->matchrecursiveonly) + continue; + + if (rdclass != view->rdclass) + continue; + + if (mykey != NULL) { + isc_boolean_t match; + isc_result_t result; + + tsig = &mykey->name; + result = dns_view_gettsig(view, tsig, &key); + if (result != ISC_R_SUCCESS) + continue; + match = dst_key_compare(mykey->key, key->key); + dns_tsigkey_detach(&key); + if (!match) + continue; + } + + if (allowed(&netsrc, tsig, view->matchclients) && + allowed(&netdst, tsig, view->matchdestinations)) + break; + } + return (ISC_TF(view == myview)); +} + +/* + * Handle an incoming request event from the socket (UDP case) + * or tcpmsg (TCP case). + */ +static void +client_request(isc_task_t *task, isc_event_t *event) { + ns_client_t *client; + isc_socketevent_t *sevent; + isc_result_t result; + isc_result_t sigresult = ISC_R_SUCCESS; + isc_buffer_t *buffer; + isc_buffer_t tbuffer; + dns_view_t *view; + dns_rdataset_t *opt; + isc_boolean_t ra; /* Recursion available. */ + isc_netaddr_t netaddr; + isc_netaddr_t destaddr; + int match; + dns_messageid_t id; + unsigned int flags; + isc_boolean_t notimp; + + REQUIRE(event != NULL); + client = event->ev_arg; + REQUIRE(NS_CLIENT_VALID(client)); + REQUIRE(task == client->task); + + INSIST(client->recursionquota == NULL); + + INSIST(client->state == + TCP_CLIENT(client) ? + NS_CLIENTSTATE_READING : + NS_CLIENTSTATE_READY); + + ns_client_requests++; + + if (event->ev_type == ISC_SOCKEVENT_RECVDONE) { + INSIST(!TCP_CLIENT(client)); + sevent = (isc_socketevent_t *)event; + REQUIRE(sevent == client->recvevent); + isc_buffer_init(&tbuffer, sevent->region.base, sevent->n); + isc_buffer_add(&tbuffer, sevent->n); + buffer = &tbuffer; + result = sevent->result; + if (result == ISC_R_SUCCESS) { + client->peeraddr = sevent->address; + client->peeraddr_valid = ISC_TRUE; + } + if ((sevent->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) { + client->attributes |= NS_CLIENTATTR_PKTINFO; + client->pktinfo = sevent->pktinfo; + } + if ((sevent->attributes & ISC_SOCKEVENTATTR_MULTICAST) != 0) + client->attributes |= NS_CLIENTATTR_MULTICAST; + client->nrecvs--; + } else { + INSIST(TCP_CLIENT(client)); + REQUIRE(event->ev_type == DNS_EVENT_TCPMSG); + REQUIRE(event->ev_sender == &client->tcpmsg); + buffer = &client->tcpmsg.buffer; + result = client->tcpmsg.result; + INSIST(client->nreads == 1); + /* + * client->peeraddr was set when the connection was accepted. + */ + client->nreads--; + } + + if (exit_check(client)) + goto cleanup; + client->state = client->newstate = NS_CLIENTSTATE_WORKING; + + isc_task_getcurrenttime(task, &client->requesttime); + client->now = client->requesttime; + + if (result != ISC_R_SUCCESS) { + if (TCP_CLIENT(client)) { + ns_client_next(client, result); + } else { + if (result != ISC_R_CANCELED) + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, + ISC_LOG_ERROR, + "UDP client handler shutting " + "down due to fatal receive " + "error: %s", + isc_result_totext(result)); + isc_task_shutdown(client->task); + } + goto cleanup; + } + + isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); + +#if NS_CLIENT_DROPPORT + if (ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) == + DROPPORT_REQUEST) { + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), + "dropped request: suspicious port"); + ns_client_next(client, ISC_R_SUCCESS); + goto cleanup; + } +#endif + + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), + "%s request", + TCP_CLIENT(client) ? "TCP" : "UDP"); + + /* + * Check the blackhole ACL for UDP only, since TCP is done in + * client_newconn. + */ + if (!TCP_CLIENT(client)) { + + if (ns_g_server->blackholeacl != NULL && + dns_acl_match(&netaddr, NULL, ns_g_server->blackholeacl, + &ns_g_server->aclenv, + &match, NULL) == ISC_R_SUCCESS && + match > 0) + { + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), + "blackholed UDP datagram"); + ns_client_next(client, ISC_R_SUCCESS); + goto cleanup; + } + } + + /* + * Silently drop multicast requests for the present. + * XXXMPA look at when/if mDNS spec stabilizes. + */ + if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) { + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), + "dropping multicast request"); + ns_client_next(client, DNS_R_REFUSED); + goto cleanup; + } + + result = dns_message_peekheader(buffer, &id, &flags); + if (result != ISC_R_SUCCESS) { + /* + * There isn't enough header to determine whether + * this was a request or a response. Drop it. + */ + ns_client_next(client, result); + goto cleanup; + } + + /* + * The client object handles requests, not responses. + * If this is a UDP response, forward it to the dispatcher. + * If it's a TCP response, discard it here. + */ + if ((flags & DNS_MESSAGEFLAG_QR) != 0) { + if (TCP_CLIENT(client)) { + CTRACE("unexpected response"); + ns_client_next(client, DNS_R_FORMERR); + goto cleanup; + } else { + dns_dispatch_importrecv(client->dispatch, event); + ns_client_next(client, ISC_R_SUCCESS); + goto cleanup; + } + } + + /* + * Hash the incoming request here as it is after + * dns_dispatch_importrecv(). + */ + dns_dispatch_hash(&client->now, sizeof(client->now)); + dns_dispatch_hash(isc_buffer_base(buffer), + isc_buffer_usedlength(buffer)); + + /* + * It's a request. Parse it. + */ + result = dns_message_parse(client->message, buffer, 0); + if (result != ISC_R_SUCCESS) { + /* + * Parsing the request failed. Send a response + * (typically FORMERR or SERVFAIL). + */ + ns_client_error(client, result); + goto cleanup; + } + + switch (client->message->opcode) { + case dns_opcode_query: + case dns_opcode_update: + case dns_opcode_notify: + notimp = ISC_FALSE; + break; + case dns_opcode_iquery: + default: + notimp = ISC_TRUE; + break; + } + + client->message->rcode = dns_rcode_noerror; + + /* RFC1123 section 6.1.3.2 */ + if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) + client->message->flags &= ~DNS_MESSAGEFLAG_RD; + + /* + * Deal with EDNS. + */ + opt = dns_message_getopt(client->message); + if (opt != NULL) { + /* + * Set the client's UDP buffer size. + */ + client->udpsize = opt->rdclass; + + /* + * If the requested UDP buffer size is less than 512, + * ignore it and use 512. + */ + if (client->udpsize < 512) + client->udpsize = 512; + + /* + * Get the flags out of the OPT record. + */ + client->extflags = (isc_uint16_t)(opt->ttl & 0xFFFF); + + /* + * Do we understand this version of EDNS? + * + * XXXRTH need library support for this! + */ + client->ednsversion = (opt->ttl & 0x00FF0000) >> 16; + if (client->ednsversion > 0) { + result = client_addopt(client); + if (result == ISC_R_SUCCESS) + result = DNS_R_BADVERS; + ns_client_error(client, result); + goto cleanup; + } + /* + * Create an OPT for our reply. + */ + result = client_addopt(client); + if (result != ISC_R_SUCCESS) { + ns_client_error(client, result); + goto cleanup; + } + } + + if (client->message->rdclass == 0) { + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), + "message class could not be determined"); + ns_client_dumpmessage(client, + "message class could not be determined"); + ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_FORMERR); + goto cleanup; + } + + /* + * Determine the destination address. If the receiving interface is + * bound to a specific address, we simply use it regardless of the + * address family. All IPv4 queries should fall into this case. + * Otherwise, if this is a TCP query, get the address from the + * receiving socket (this needs a system call and can be heavy). + * For IPv6 UDP queries, we get this from the pktinfo structure (if + * supported). + * If all the attempts fail (this can happen due to memory shortage, + * etc), we regard this as an error for safety. + */ + if ((client->interface->flags & NS_INTERFACEFLAG_ANYADDR) == 0) + isc_netaddr_fromsockaddr(&destaddr, &client->interface->addr); + else { + result = ISC_R_FAILURE; + + if (TCP_CLIENT(client)) { + isc_sockaddr_t destsockaddr; + + result = isc_socket_getsockname(client->tcpsocket, + &destsockaddr); + if (result == ISC_R_SUCCESS) + isc_netaddr_fromsockaddr(&destaddr, + &destsockaddr); + } + if (result != ISC_R_SUCCESS && + client->interface->addr.type.sa.sa_family == AF_INET6 && + (client->attributes & NS_CLIENTATTR_PKTINFO) != 0) { + isc_uint32_t zone = 0; + + /* + * XXXJT technically, we should convert the receiving + * interface ID to a proper scope zone ID. However, + * due to the fact there is no standard API for this, + * we only handle link-local addresses and use the + * interface index as link ID. Despite the assumption, + * it should cover most typical cases. + */ + if (IN6_IS_ADDR_LINKLOCAL(&client->pktinfo.ipi6_addr)) + zone = (isc_uint32_t)client->pktinfo.ipi6_ifindex; + + isc_netaddr_fromin6(&destaddr, + &client->pktinfo.ipi6_addr); + isc_netaddr_setzone(&destaddr, zone); + result = ISC_R_SUCCESS; + } + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "failed to get request's " + "destination: %s", + isc_result_totext(result)); + ns_client_next(client, ISC_R_SUCCESS); + goto cleanup; + } + } + + /* + * Find a view that matches the client's source address. + */ + for (view = ISC_LIST_HEAD(ns_g_server->viewlist); + view != NULL; + view = ISC_LIST_NEXT(view, link)) { + if (client->message->rdclass == view->rdclass || + client->message->rdclass == dns_rdataclass_any) + { + dns_name_t *tsig = NULL; + sigresult = dns_message_rechecksig(client->message, + view); + if (sigresult == ISC_R_SUCCESS) + tsig = client->message->tsigname; + + if (allowed(&netaddr, tsig, view->matchclients) && + allowed(&destaddr, tsig, view->matchdestinations) && + !((client->message->flags & DNS_MESSAGEFLAG_RD) + == 0 && view->matchrecursiveonly)) + { + dns_view_attach(view, &client->view); + break; + } + } + } + + if (view == NULL) { + char classname[DNS_RDATACLASS_FORMATSIZE]; + + /* + * Do a dummy TSIG verification attempt so that the + * response will have a TSIG if the query did, as + * required by RFC2845. + */ + isc_buffer_t b; + isc_region_t *r; + + dns_message_resetsig(client->message); + + r = dns_message_getrawmessage(client->message); + isc_buffer_init(&b, r->base, r->length); + isc_buffer_add(&b, r->length); + (void)dns_tsig_verify(&b, client->message, NULL, NULL); + + dns_rdataclass_format(client->message->rdclass, classname, + sizeof(classname)); + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), + "no matching view in class '%s'", classname); + ns_client_dumpmessage(client, "no matching view in class"); + ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_REFUSED); + goto cleanup; + } + + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(5), + "using view '%s'", view->name); + + /* + * Check for a signature. We log bad signatures regardless of + * whether they ultimately cause the request to be rejected or + * not. We do not log the lack of a signature unless we are + * debugging. + */ + client->signer = NULL; + dns_name_init(&client->signername, NULL); + result = dns_message_signer(client->message, &client->signername); + if (result == ISC_R_SUCCESS) { + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), + "request has valid signature"); + client->signer = &client->signername; + } else if (result == ISC_R_NOTFOUND) { + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), + "request is not signed"); + } else if (result == DNS_R_NOIDENTITY) { + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), + "request is signed by a nonauthoritative key"); + } else { + char tsigrcode[64]; + isc_buffer_t b; + dns_name_t *name = NULL; + dns_rcode_t status; + isc_result_t tresult; + + /* There is a signature, but it is bad. */ + if (dns_message_gettsig(client->message, &name) != NULL) { + char namebuf[DNS_NAME_FORMATSIZE]; + dns_name_format(name, namebuf, sizeof(namebuf)); + status = client->message->tsigstatus; + isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1); + tresult = dns_tsigrcode_totext(status, &b); + INSIST(tresult == ISC_R_SUCCESS); + tsigrcode[isc_buffer_usedlength(&b)] = '\0'; + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_CLIENT, ISC_LOG_ERROR, + "request has invalid signature: " + "TSIG %s: %s (%s)", namebuf, + isc_result_totext(result), tsigrcode); + } else { + status = client->message->sig0status; + isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1); + tresult = dns_tsigrcode_totext(status, &b); + INSIST(tresult == ISC_R_SUCCESS); + tsigrcode[isc_buffer_usedlength(&b)] = '\0'; + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_CLIENT, ISC_LOG_ERROR, + "request has invalid signature: %s (%s)", + isc_result_totext(result), tsigrcode); + } + /* + * Accept update messages signed by unknown keys so that + * update forwarding works transparently through slaves + * that don't have all the same keys as the master. + */ + if (!(client->message->tsigstatus == dns_tsigerror_badkey && + client->message->opcode == dns_opcode_update)) { + ns_client_error(client, sigresult); + goto cleanup; + } + } + + /* + * Decide whether recursive service is available to this client. + * We do this here rather than in the query code so that we can + * set the RA bit correctly on all kinds of responses, not just + * responses to ordinary queries. Note if you can't query the + * cache there is no point in setting RA. + */ + ra = ISC_FALSE; + if (client->view->resolver != NULL && + client->view->recursion == ISC_TRUE && + ns_client_checkaclsilent(client, client->view->recursionacl, + ISC_TRUE) == ISC_R_SUCCESS && + ns_client_checkaclsilent(client, client->view->queryacl, + ISC_TRUE) == ISC_R_SUCCESS) + ra = ISC_TRUE; + + if (ra == ISC_TRUE) + client->attributes |= NS_CLIENTATTR_RA; + + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_CLIENT, + ISC_LOG_DEBUG(3), ra ? "recursion available" : + "recursion not available"); + + /* + * Adjust maximum UDP response size for this client. + */ + if (client->udpsize > 512) { + dns_peer_t *peer = NULL; + isc_uint16_t udpsize = view->maxudp; + (void) dns_peerlist_peerbyaddr(view->peers, &netaddr, &peer); + if (peer != NULL) + dns_peer_getmaxudp(peer, &udpsize); + if (client->udpsize > udpsize) + client->udpsize = udpsize; + } + + /* + * Dispatch the request. + */ + switch (client->message->opcode) { + case dns_opcode_query: + CTRACE("query"); + ns_query_start(client); + break; + case dns_opcode_update: + CTRACE("update"); + ns_client_settimeout(client, 60); + ns_update_start(client, sigresult); + break; + case dns_opcode_notify: + CTRACE("notify"); + ns_client_settimeout(client, 60); + ns_notify_start(client); + break; + case dns_opcode_iquery: + CTRACE("iquery"); + ns_client_error(client, DNS_R_NOTIMP); + break; + default: + CTRACE("unknown opcode"); + ns_client_error(client, DNS_R_NOTIMP); + } + + cleanup: + return; +} + +static void +client_timeout(isc_task_t *task, isc_event_t *event) { + ns_client_t *client; + + REQUIRE(event != NULL); + REQUIRE(event->ev_type == ISC_TIMEREVENT_LIFE || + event->ev_type == ISC_TIMEREVENT_IDLE); + client = event->ev_arg; + REQUIRE(NS_CLIENT_VALID(client)); + REQUIRE(task == client->task); + REQUIRE(client->timer != NULL); + + UNUSED(task); + + CTRACE("timeout"); + + isc_event_free(&event); + + if (client->shutdown != NULL) { + (client->shutdown)(client->shutdown_arg, ISC_R_TIMEDOUT); + client->shutdown = NULL; + client->shutdown_arg = NULL; + } + + if (client->newstate > NS_CLIENTSTATE_READY) + client->newstate = NS_CLIENTSTATE_READY; + (void)exit_check(client); +} + +static isc_result_t +get_clientmctx(ns_clientmgr_t *manager, isc_mem_t **mctxp) { + isc_mem_t *clientmctx; +#if NMCTXS > 0 + isc_result_t result; +#endif + + /* + * Caller must be holding the manager lock. + */ +#if NMCTXS > 0 + INSIST(manager->nextmctx < NMCTXS); + clientmctx = manager->mctxpool[manager->nextmctx]; + if (clientmctx == NULL) { + result = isc_mem_create(0, 0, &clientmctx); + if (result != ISC_R_SUCCESS) + return (result); + + manager->mctxpool[manager->nextmctx] = clientmctx; + manager->nextmctx++; + if (manager->nextmctx == NMCTXS) + manager->nextmctx = 0; + } +#else + clientmctx = manager->mctx; +#endif + + isc_mem_attach(clientmctx, mctxp); + + return (ISC_R_SUCCESS); +} + +static isc_result_t +client_create(ns_clientmgr_t *manager, ns_client_t **clientp) { + ns_client_t *client; + isc_result_t result; + isc_mem_t *mctx = NULL; + + /* + * Caller must be holding the manager lock. + * + * Note: creating a client does not add the client to the + * manager's client list or set the client's manager pointer. + * The caller is responsible for that. + */ + + REQUIRE(clientp != NULL && *clientp == NULL); + + result = get_clientmctx(manager, &mctx); + if (result != ISC_R_SUCCESS) + return (result); + + client = isc_mem_get(mctx, sizeof(*client)); + if (client == NULL) { + isc_mem_detach(&mctx); + return (ISC_R_NOMEMORY); + } + client->mctx = mctx; + + client->task = NULL; + result = isc_task_create(manager->taskmgr, 0, &client->task); + if (result != ISC_R_SUCCESS) + goto cleanup_client; + isc_task_setname(client->task, "client", client); + + client->timer = NULL; + result = isc_timer_create(manager->timermgr, isc_timertype_inactive, + NULL, NULL, client->task, client_timeout, + client, &client->timer); + if (result != ISC_R_SUCCESS) + goto cleanup_task; + client->timerset = ISC_FALSE; + + client->message = NULL; + result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTPARSE, + &client->message); + if (result != ISC_R_SUCCESS) + goto cleanup_timer; + + /* XXXRTH Hardwired constants */ + + client->sendevent = (isc_socketevent_t *) + isc_event_allocate(client->mctx, client, + ISC_SOCKEVENT_SENDDONE, + client_senddone, client, + sizeof(isc_socketevent_t)); + if (client->sendevent == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup_message; + } + + client->recvbuf = isc_mem_get(client->mctx, RECV_BUFFER_SIZE); + if (client->recvbuf == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup_sendevent; + } + + client->recvevent = (isc_socketevent_t *) + isc_event_allocate(client->mctx, client, + ISC_SOCKEVENT_RECVDONE, + client_request, client, + sizeof(isc_socketevent_t)); + if (client->recvevent == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup_recvbuf; + } + + client->magic = NS_CLIENT_MAGIC; + client->manager = NULL; + client->state = NS_CLIENTSTATE_INACTIVE; + client->newstate = NS_CLIENTSTATE_MAX; + client->naccepts = 0; + client->nreads = 0; + client->nsends = 0; + client->nrecvs = 0; + client->nupdates = 0; + client->nctls = 0; + client->references = 0; + client->attributes = 0; + client->view = NULL; + client->dispatch = NULL; + client->udpsocket = NULL; + client->tcplistener = NULL; + client->tcpsocket = NULL; + client->tcpmsg_valid = ISC_FALSE; + client->tcpbuf = NULL; + client->opt = NULL; + client->udpsize = 512; + client->extflags = 0; + client->ednsversion = -1; + client->next = NULL; + client->shutdown = NULL; + client->shutdown_arg = NULL; + dns_name_init(&client->signername, NULL); + client->mortal = ISC_FALSE; + client->tcpquota = NULL; + client->recursionquota = NULL; + client->interface = NULL; + client->peeraddr_valid = ISC_FALSE; + ISC_EVENT_INIT(&client->ctlevent, sizeof(client->ctlevent), 0, NULL, + NS_EVENT_CLIENTCONTROL, client_start, client, client, + NULL, NULL); + /* + * Initialize FORMERR cache to sentinel value that will not match + * any actual FORMERR response. + */ + isc_sockaddr_any(&client->formerrcache.addr); + client->formerrcache.time = 0; + client->formerrcache.id = 0; + ISC_LINK_INIT(client, link); + client->list = NULL; + + /* + * We call the init routines for the various kinds of client here, + * after we have created an otherwise valid client, because some + * of them call routines that REQUIRE(NS_CLIENT_VALID(client)). + */ + result = ns_query_init(client); + if (result != ISC_R_SUCCESS) + goto cleanup_recvevent; + + result = isc_task_onshutdown(client->task, client_shutdown, client); + if (result != ISC_R_SUCCESS) + goto cleanup_query; + + CTRACE("create"); + + *clientp = client; + + return (ISC_R_SUCCESS); + + cleanup_query: + ns_query_free(client); + + cleanup_recvevent: + isc_event_free((isc_event_t **)&client->recvevent); + + cleanup_recvbuf: + isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE); + + cleanup_sendevent: + isc_event_free((isc_event_t **)&client->sendevent); + + client->magic = 0; + + cleanup_message: + dns_message_destroy(&client->message); + + cleanup_timer: + isc_timer_detach(&client->timer); + + cleanup_task: + isc_task_detach(&client->task); + + cleanup_client: + isc_mem_putanddetach(&client->mctx, client, sizeof(*client)); + + return (result); +} + +static void +client_read(ns_client_t *client) { + isc_result_t result; + + CTRACE("read"); + + result = dns_tcpmsg_readmessage(&client->tcpmsg, client->task, + client_request, client); + if (result != ISC_R_SUCCESS) + goto fail; + + /* + * Set a timeout to limit the amount of time we will wait + * for a request on this TCP connection. + */ + ns_client_settimeout(client, 30); + + client->state = client->newstate = NS_CLIENTSTATE_READING; + INSIST(client->nreads == 0); + INSIST(client->recursionquota == NULL); + client->nreads++; + + return; + fail: + ns_client_next(client, result); +} + +static void +client_newconn(isc_task_t *task, isc_event_t *event) { + ns_client_t *client = event->ev_arg; + isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event; + isc_result_t result; + + REQUIRE(event->ev_type == ISC_SOCKEVENT_NEWCONN); + REQUIRE(NS_CLIENT_VALID(client)); + REQUIRE(client->task == task); + + UNUSED(task); + + INSIST(client->state == NS_CLIENTSTATE_READY); + + INSIST(client->naccepts == 1); + client->naccepts--; + + LOCK(&client->interface->lock); + INSIST(client->interface->ntcpcurrent > 0); + client->interface->ntcpcurrent--; + UNLOCK(&client->interface->lock); + + /* + * We must take ownership of the new socket before the exit + * check to make sure it gets destroyed if we decide to exit. + */ + if (nevent->result == ISC_R_SUCCESS) { + client->tcpsocket = nevent->newsocket; + client->state = NS_CLIENTSTATE_READING; + INSIST(client->recursionquota == NULL); + + (void)isc_socket_getpeername(client->tcpsocket, + &client->peeraddr); + client->peeraddr_valid = ISC_TRUE; + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), + "new TCP connection"); + } else { + /* + * XXXRTH What should we do? We're trying to accept but + * it didn't work. If we just give up, then TCP + * service may eventually stop. + * + * For now, we just go idle. + * + * Going idle is probably the right thing if the + * I/O was canceled. + */ + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), + "accept failed: %s", + isc_result_totext(nevent->result)); + } + + if (exit_check(client)) + goto freeevent; + + if (nevent->result == ISC_R_SUCCESS) { + int match; + isc_netaddr_t netaddr; + + isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); + + if (ns_g_server->blackholeacl != NULL && + dns_acl_match(&netaddr, NULL, + ns_g_server->blackholeacl, + &ns_g_server->aclenv, + &match, NULL) == ISC_R_SUCCESS && + match > 0) + { + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), + "blackholed connection attempt"); + client->newstate = NS_CLIENTSTATE_READY; + (void)exit_check(client); + goto freeevent; + } + + INSIST(client->tcpmsg_valid == ISC_FALSE); + dns_tcpmsg_init(client->mctx, client->tcpsocket, + &client->tcpmsg); + client->tcpmsg_valid = ISC_TRUE; + + /* + * Let a new client take our place immediately, before + * we wait for a request packet. If we don't, + * telnetting to port 53 (once per CPU) will + * deny service to legititmate TCP clients. + */ + result = isc_quota_attach(&ns_g_server->tcpquota, + &client->tcpquota); + if (result == ISC_R_SUCCESS) + result = ns_client_replace(client); + if (result != ISC_R_SUCCESS) { + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_WARNING, + "no more TCP clients: %s", + isc_result_totext(result)); + } + + client_read(client); + } + + freeevent: + isc_event_free(&event); +} + +static void +client_accept(ns_client_t *client) { + isc_result_t result; + + CTRACE("accept"); + + result = isc_socket_accept(client->tcplistener, client->task, + client_newconn, client); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_socket_accept() failed: %s", + isc_result_totext(result)); + /* + * XXXRTH What should we do? We're trying to accept but + * it didn't work. If we just give up, then TCP + * service may eventually stop. + * + * For now, we just go idle. + */ + return; + } + INSIST(client->naccepts == 0); + client->naccepts++; + LOCK(&client->interface->lock); + client->interface->ntcpcurrent++; + UNLOCK(&client->interface->lock); +} + +static void +client_udprecv(ns_client_t *client) { + isc_result_t result; + isc_region_t r; + + CTRACE("udprecv"); + + r.base = client->recvbuf; + r.length = RECV_BUFFER_SIZE; + result = isc_socket_recv2(client->udpsocket, &r, 1, + client->task, client->recvevent, 0); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_socket_recv2() failed: %s", + isc_result_totext(result)); + /* + * This cannot happen in the current implementation, since + * isc_socket_recv2() cannot fail if flags == 0. + * + * If this does fail, we just go idle. + */ + return; + } + INSIST(client->nrecvs == 0); + client->nrecvs++; +} + +void +ns_client_attach(ns_client_t *source, ns_client_t **targetp) { + REQUIRE(NS_CLIENT_VALID(source)); + REQUIRE(targetp != NULL && *targetp == NULL); + + source->references++; + ns_client_log(source, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), + "ns_client_attach: ref = %d", source->references); + *targetp = source; +} + +void +ns_client_detach(ns_client_t **clientp) { + ns_client_t *client = *clientp; + + client->references--; + INSIST(client->references >= 0); + *clientp = NULL; + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), + "ns_client_detach: ref = %d", client->references); + (void)exit_check(client); +} + +isc_boolean_t +ns_client_shuttingdown(ns_client_t *client) { + return (ISC_TF(client->newstate == NS_CLIENTSTATE_FREED)); +} + +isc_result_t +ns_client_replace(ns_client_t *client) { + isc_result_t result; + + CTRACE("replace"); + + result = ns_clientmgr_createclients(client->manager, + 1, client->interface, + (TCP_CLIENT(client) ? + ISC_TRUE : ISC_FALSE)); + if (result != ISC_R_SUCCESS) + return (result); + + /* + * The responsibility for listening for new requests is hereby + * transferred to the new client. Therefore, the old client + * should refrain from listening for any more requests. + */ + client->mortal = ISC_TRUE; + + return (ISC_R_SUCCESS); +} + +/*** + *** Client Manager + ***/ + +static void +clientmgr_destroy(ns_clientmgr_t *manager) { +#if NMCTXS > 0 + int i; +#endif + + REQUIRE(ISC_LIST_EMPTY(manager->active)); + REQUIRE(ISC_LIST_EMPTY(manager->inactive)); + REQUIRE(ISC_LIST_EMPTY(manager->recursing)); + + MTRACE("clientmgr_destroy"); + +#if NMCTXS > 0 + for (i = 0; i < NMCTXS; i++) { + if (manager->mctxpool[i] != NULL) + isc_mem_detach(&manager->mctxpool[i]); + } +#endif + + DESTROYLOCK(&manager->lock); + manager->magic = 0; + isc_mem_put(manager->mctx, manager, sizeof(*manager)); +} + +isc_result_t +ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, + isc_timermgr_t *timermgr, ns_clientmgr_t **managerp) +{ + ns_clientmgr_t *manager; + isc_result_t result; +#if NMCTXS > 0 + int i; +#endif + + manager = isc_mem_get(mctx, sizeof(*manager)); + if (manager == NULL) + return (ISC_R_NOMEMORY); + + result = isc_mutex_init(&manager->lock); + if (result != ISC_R_SUCCESS) + goto cleanup_manager; + + manager->mctx = mctx; + manager->taskmgr = taskmgr; + manager->timermgr = timermgr; + manager->exiting = ISC_FALSE; + ISC_LIST_INIT(manager->active); + ISC_LIST_INIT(manager->inactive); + ISC_LIST_INIT(manager->recursing); +#if NMCTXS > 0 + manager->nextmctx = 0; + for (i = 0; i < NMCTXS; i++) + manager->mctxpool[i] = NULL; /* will be created on-demand */ +#endif + manager->magic = MANAGER_MAGIC; + + MTRACE("create"); + + *managerp = manager; + + return (ISC_R_SUCCESS); + + cleanup_manager: + isc_mem_put(manager->mctx, manager, sizeof(*manager)); + + return (result); +} + +void +ns_clientmgr_destroy(ns_clientmgr_t **managerp) { + ns_clientmgr_t *manager; + ns_client_t *client; + isc_boolean_t need_destroy = ISC_FALSE; + + REQUIRE(managerp != NULL); + manager = *managerp; + REQUIRE(VALID_MANAGER(manager)); + + MTRACE("destroy"); + + LOCK(&manager->lock); + + manager->exiting = ISC_TRUE; + + for (client = ISC_LIST_HEAD(manager->recursing); + client != NULL; + client = ISC_LIST_NEXT(client, link)) + isc_task_shutdown(client->task); + + for (client = ISC_LIST_HEAD(manager->active); + client != NULL; + client = ISC_LIST_NEXT(client, link)) + isc_task_shutdown(client->task); + + for (client = ISC_LIST_HEAD(manager->inactive); + client != NULL; + client = ISC_LIST_NEXT(client, link)) + isc_task_shutdown(client->task); + + if (ISC_LIST_EMPTY(manager->active) && + ISC_LIST_EMPTY(manager->inactive) && + ISC_LIST_EMPTY(manager->recursing)) + need_destroy = ISC_TRUE; + + UNLOCK(&manager->lock); + + if (need_destroy) + clientmgr_destroy(manager); + + *managerp = NULL; +} + +isc_result_t +ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, + ns_interface_t *ifp, isc_boolean_t tcp) +{ + isc_result_t result = ISC_R_SUCCESS; + unsigned int i; + ns_client_t *client; + + REQUIRE(VALID_MANAGER(manager)); + REQUIRE(n > 0); + + MTRACE("createclients"); + + /* + * We MUST lock the manager lock for the entire client creation + * process. If we didn't do this, then a client could get a + * shutdown event and disappear out from under us. + */ + + LOCK(&manager->lock); + + for (i = 0; i < n; i++) { + isc_event_t *ev; + /* + * Allocate a client. First try to get a recycled one; + * if that fails, make a new one. + */ + client = ISC_LIST_HEAD(manager->inactive); + if (client != NULL) { + MTRACE("recycle"); + ISC_LIST_UNLINK(manager->inactive, client, link); + client->list = NULL; + } else { + MTRACE("create new"); + result = client_create(manager, &client); + if (result != ISC_R_SUCCESS) + break; + } + + ns_interface_attach(ifp, &client->interface); + client->state = NS_CLIENTSTATE_READY; + INSIST(client->recursionquota == NULL); + + if (tcp) { + client->attributes |= NS_CLIENTATTR_TCP; + isc_socket_attach(ifp->tcpsocket, + &client->tcplistener); + } else { + isc_socket_t *sock; + + dns_dispatch_attach(ifp->udpdispatch, + &client->dispatch); + sock = dns_dispatch_getsocket(client->dispatch); + isc_socket_attach(sock, &client->udpsocket); + } + client->manager = manager; + ISC_LIST_APPEND(manager->active, client, link); + client->list = &manager->active; + + INSIST(client->nctls == 0); + client->nctls++; + ev = &client->ctlevent; + isc_task_send(client->task, &ev); + } + if (i != 0) { + /* + * We managed to create at least one client, so we + * declare victory. + */ + result = ISC_R_SUCCESS; + } + + UNLOCK(&manager->lock); + + return (result); +} + +isc_sockaddr_t * +ns_client_getsockaddr(ns_client_t *client) { + return (&client->peeraddr); +} + +isc_result_t +ns_client_checkaclsilent(ns_client_t *client, dns_acl_t *acl, + isc_boolean_t default_allow) +{ + isc_result_t result; + int match; + isc_netaddr_t netaddr; + + if (acl == NULL) { + if (default_allow) + goto allow; + else + goto deny; + } + + isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); + + result = dns_acl_match(&netaddr, client->signer, acl, + &ns_g_server->aclenv, + &match, NULL); + if (result != ISC_R_SUCCESS) + goto deny; /* Internal error, already logged. */ + if (match > 0) + goto allow; + goto deny; /* Negative match or no match. */ + + allow: + return (ISC_R_SUCCESS); + + deny: + return (DNS_R_REFUSED); +} + +isc_result_t +ns_client_checkacl(ns_client_t *client, + const char *opname, dns_acl_t *acl, + isc_boolean_t default_allow, int log_level) +{ + isc_result_t result = + ns_client_checkaclsilent(client, acl, default_allow); + + if (result == ISC_R_SUCCESS) + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), + "%s approved", opname); + else + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_CLIENT, + log_level, "%s denied", opname); + return (result); +} + +static void +ns_client_name(ns_client_t *client, char *peerbuf, size_t len) { + if (client->peeraddr_valid) + isc_sockaddr_format(&client->peeraddr, peerbuf, len); + else + snprintf(peerbuf, len, "@%p", client); +} + +void +ns_client_logv(ns_client_t *client, isc_logcategory_t *category, + isc_logmodule_t *module, int level, const char *fmt, va_list ap) +{ + char msgbuf[2048]; + char peerbuf[ISC_SOCKADDR_FORMATSIZE]; + const char *name = ""; + const char *sep = ""; + + vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); + ns_client_name(client, peerbuf, sizeof(peerbuf)); + if (client->view != NULL && strcmp(client->view->name, "_bind") != 0 && + strcmp(client->view->name, "_default") != 0) { + name = client->view->name; + sep = ": view "; + } + + isc_log_write(ns_g_lctx, category, module, level, + "client %s%s%s: %s", peerbuf, sep, name, msgbuf); +} + +void +ns_client_log(ns_client_t *client, isc_logcategory_t *category, + isc_logmodule_t *module, int level, const char *fmt, ...) +{ + va_list ap; + + if (! isc_log_wouldlog(ns_g_lctx, level)) + return; + + va_start(ap, fmt); + ns_client_logv(client, category, module, level, fmt, ap); + va_end(ap); +} + +void +ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type, + dns_rdataclass_t rdclass, char *buf, size_t len) +{ + char namebuf[DNS_NAME_FORMATSIZE]; + char typebuf[DNS_RDATATYPE_FORMATSIZE]; + char classbuf[DNS_RDATACLASS_FORMATSIZE]; + + dns_name_format(name, namebuf, sizeof(namebuf)); + dns_rdatatype_format(type, typebuf, sizeof(typebuf)); + dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf)); + (void)snprintf(buf, len, "%s '%s/%s/%s'", msg, namebuf, typebuf, + classbuf); +} + +static void +ns_client_dumpmessage(ns_client_t *client, const char *reason) { + isc_buffer_t buffer; + char *buf = NULL; + int len = 1024; + isc_result_t result; + + /* + * Note that these are multiline debug messages. We want a newline + * to appear in the log after each message. + */ + + do { + buf = isc_mem_get(client->mctx, len); + if (buf == NULL) + break; + isc_buffer_init(&buffer, buf, len); + result = dns_message_totext(client->message, + &dns_master_style_debug, + 0, &buffer); + if (result == ISC_R_NOSPACE) { + isc_mem_put(client->mctx, buf, len); + len += 1024; + } else if (result == ISC_R_SUCCESS) + ns_client_log(client, NS_LOGCATEGORY_UNMATCHED, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), + "%s\n%.*s", reason, + (int)isc_buffer_usedlength(&buffer), + buf); + } while (result == ISC_R_NOSPACE); + + if (buf != NULL) + isc_mem_put(client->mctx, buf, len); +} + +void +ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) { + ns_client_t *client; + char namebuf[DNS_NAME_FORMATSIZE]; + char peerbuf[ISC_SOCKADDR_FORMATSIZE]; + const char *name; + const char *sep; + + REQUIRE(VALID_MANAGER(manager)); + + LOCK(&manager->lock); + client = ISC_LIST_HEAD(manager->recursing); + while (client != NULL) { + ns_client_name(client, peerbuf, sizeof(peerbuf)); + if (client->view != NULL && + strcmp(client->view->name, "_bind") != 0 && + strcmp(client->view->name, "_default") != 0) { + name = client->view->name; + sep = ": view "; + } else { + name = ""; + sep = ""; + } + dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); + fprintf(f, "; client %s%s%s: '%s' requesttime %d\n", + peerbuf, sep, name, namebuf, client->requesttime); + client = ISC_LIST_NEXT(client, link); + } + UNLOCK(&manager->lock); +} + +void +ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) { + + if (client->manager != NULL) + LOCK(&client->manager->lock); + if (client->query.restarts > 0) { + /* + * client->query.qname was dynamically allocated. + */ + dns_message_puttempname(client->message, + &client->query.qname); + } + client->query.qname = name; + if (client->manager != NULL) + UNLOCK(&client->manager->lock); +} diff --git a/bin/named/config.c b/bin/named/config.c new file mode 100644 index 0000000..e2dc833 --- /dev/null +++ b/bin/named/config.c @@ -0,0 +1,796 @@ +/* + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 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: config.c,v 1.47.18.32 2007/09/13 05:04:01 each Exp $ */ + +/*! \file */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +/*% default configuration */ +static char defaultconf[] = "\ +options {\n\ +# blackhole {none;};\n" +#ifndef WIN32 +" coresize default;\n\ + datasize default;\n\ + files default;\n\ + stacksize default;\n" +#endif +" deallocate-on-exit true;\n\ +# directory \n\ + dump-file \"named_dump.db\";\n\ + fake-iquery no;\n\ + has-old-clients false;\n\ + heartbeat-interval 60;\n\ + host-statistics no;\n\ + interface-interval 60;\n\ + listen-on {any;};\n\ + listen-on-v6 {none;};\n\ + match-mapped-addresses no;\n\ + memstatistics-file \"named.memstats\";\n\ + multiple-cnames no;\n\ +# named-xfer ;\n\ +# pid-file \"" NS_LOCALSTATEDIR "/named.pid\"; /* or /lwresd.pid */\n\ + port 53;\n\ + recursing-file \"named.recursing\";\n\ +" +#ifdef PATH_RANDOMDEV +"\ + random-device \"" PATH_RANDOMDEV "\";\n\ +" +#endif +"\ + recursive-clients 1000;\n\ + rrset-order {type NS order random; order cyclic; };\n\ + serial-queries 20;\n\ + serial-query-rate 20;\n\ + server-id none;\n\ + statistics-file \"named.stats\";\n\ + statistics-interval 60;\n\ + tcp-clients 100;\n\ + tcp-listen-queue 3;\n\ +# tkey-dhkey \n\ +# tkey-gssapi-credential \n\ +# tkey-domain \n\ + transfers-per-ns 2;\n\ + transfers-in 10;\n\ + transfers-out 10;\n\ + treat-cr-as-space true;\n\ + use-id-pool true;\n\ + use-ixfr true;\n\ + edns-udp-size 4096;\n\ + max-udp-size 4096;\n\ +\n\ + /* view */\n\ + allow-notify {none;};\n\ + allow-update-forwarding {none;};\n\ + allow-query-cache { localnets; localhost; };\n\ + allow-recursion { localnets; localhost; };\n\ +# allow-v6-synthesis ;\n\ +# sortlist \n\ +# topology \n\ + auth-nxdomain false;\n\ + minimal-responses false;\n\ + recursion true;\n\ + provide-ixfr true;\n\ + request-ixfr true;\n\ + fetch-glue no;\n\ + rfc2308-type1 no;\n\ + additional-from-auth true;\n\ + additional-from-cache true;\n\ + query-source address *;\n\ + query-source-v6 address *;\n\ + notify-source *;\n\ + notify-source-v6 *;\n\ + cleaning-interval 60;\n\ + min-roots 2;\n\ + lame-ttl 600;\n\ + max-ncache-ttl 10800; /* 3 hours */\n\ + max-cache-ttl 604800; /* 1 week */\n\ + transfer-format many-answers;\n\ + max-cache-size 0;\n\ + check-names master fail;\n\ + check-names slave warn;\n\ + check-names response ignore;\n\ + check-mx warn;\n\ + acache-enable no;\n\ + acache-cleaning-interval 60;\n\ + max-acache-size 0;\n\ + dnssec-enable yes;\n\ + dnssec-validation no; /* Make yes for 9.5. */ \n\ + dnssec-accept-expired no;\n\ + clients-per-query 10;\n\ + max-clients-per-query 100;\n\ + zero-no-soa-ttl-cache no;\n\ +" + +" /* zone */\n\ + allow-query {any;};\n\ + allow-transfer {any;};\n\ + notify yes;\n\ +# also-notify \n\ + notify-delay 5;\n\ + dialup no;\n\ +# forward \n\ +# forwarders \n\ + maintain-ixfr-base no;\n\ +# max-ixfr-log-size \n\ + transfer-source *;\n\ + transfer-source-v6 *;\n\ + alt-transfer-source *;\n\ + alt-transfer-source-v6 *;\n\ + max-transfer-time-in 120;\n\ + max-transfer-time-out 120;\n\ + max-transfer-idle-in 60;\n\ + max-transfer-idle-out 60;\n\ + max-retry-time 1209600; /* 2 weeks */\n\ + min-retry-time 500;\n\ + max-refresh-time 2419200; /* 4 weeks */\n\ + min-refresh-time 300;\n\ + multi-master no;\n\ + sig-validity-interval 30; /* days */\n\ + zone-statistics false;\n\ + max-journal-size unlimited;\n\ + ixfr-from-differences false;\n\ + check-wildcard yes;\n\ + check-sibling yes;\n\ + check-integrity yes;\n\ + check-mx-cname warn;\n\ + check-srv-cname warn;\n\ + zero-no-soa-ttl yes;\n\ + update-check-ksk yes;\n\ +};\n\ +" + +"#\n\ +# Zones in the \"_bind\" view are NOT counted in the count of zones.\n\ +#\n\ +view \"_bind\" chaos {\n\ + recursion no;\n\ + notify no;\n\ +\n\ + zone \"version.bind\" chaos {\n\ + type master;\n\ + database \"_builtin version\";\n\ + };\n\ +\n\ + zone \"hostname.bind\" chaos {\n\ + type master;\n\ + database \"_builtin hostname\";\n\ + };\n\ +\n\ + zone \"authors.bind\" chaos {\n\ + type master;\n\ + database \"_builtin authors\";\n\ + };\n\ + zone \"id.server\" chaos {\n\ + type master;\n\ + database \"_builtin id\";\n\ + };\n\ +};\n\ +"; + +isc_result_t +ns_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf) { + isc_buffer_t b; + + isc_buffer_init(&b, defaultconf, sizeof(defaultconf) - 1); + isc_buffer_add(&b, sizeof(defaultconf) - 1); + return (cfg_parse_buffer(parser, &b, &cfg_type_namedconf, conf)); +} + +isc_result_t +ns_config_get(const cfg_obj_t **maps, const char *name, const cfg_obj_t **obj) { + int i; + + for (i = 0;; i++) { + if (maps[i] == NULL) + return (ISC_R_NOTFOUND); + if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS) + return (ISC_R_SUCCESS); + } +} + +isc_result_t +ns_checknames_get(const cfg_obj_t **maps, const char *which, + const cfg_obj_t **obj) +{ + const cfg_listelt_t *element; + const cfg_obj_t *checknames; + const cfg_obj_t *type; + const cfg_obj_t *value; + int i; + + for (i = 0;; i++) { + if (maps[i] == NULL) + return (ISC_R_NOTFOUND); + checknames = NULL; + if (cfg_map_get(maps[i], "check-names", &checknames) == ISC_R_SUCCESS) { + /* + * Zone map entry is not a list. + */ + if (checknames != NULL && !cfg_obj_islist(checknames)) { + *obj = checknames; + return (ISC_R_SUCCESS); + } + for (element = cfg_list_first(checknames); + element != NULL; + element = cfg_list_next(element)) { + value = cfg_listelt_value(element); + type = cfg_tuple_get(value, "type"); + if (strcasecmp(cfg_obj_asstring(type), which) == 0) { + *obj = cfg_tuple_get(value, "mode"); + return (ISC_R_SUCCESS); + } + } + + } + } +} + +int +ns_config_listcount(const cfg_obj_t *list) { + const cfg_listelt_t *e; + int i = 0; + + for (e = cfg_list_first(list); e != NULL; e = cfg_list_next(e)) + i++; + + return (i); +} + +isc_result_t +ns_config_getclass(const cfg_obj_t *classobj, dns_rdataclass_t defclass, + dns_rdataclass_t *classp) { + isc_textregion_t r; + isc_result_t result; + + if (!cfg_obj_isstring(classobj)) { + *classp = defclass; + return (ISC_R_SUCCESS); + } + DE_CONST(cfg_obj_asstring(classobj), r.base); + r.length = strlen(r.base); + result = dns_rdataclass_fromtext(classp, &r); + if (result != ISC_R_SUCCESS) + cfg_obj_log(classobj, ns_g_lctx, ISC_LOG_ERROR, + "unknown class '%s'", r.base); + return (result); +} + +isc_result_t +ns_config_gettype(const cfg_obj_t *typeobj, dns_rdatatype_t deftype, + dns_rdatatype_t *typep) { + isc_textregion_t r; + isc_result_t result; + + if (!cfg_obj_isstring(typeobj)) { + *typep = deftype; + return (ISC_R_SUCCESS); + } + DE_CONST(cfg_obj_asstring(typeobj), r.base); + r.length = strlen(r.base); + result = dns_rdatatype_fromtext(typep, &r); + if (result != ISC_R_SUCCESS) + cfg_obj_log(typeobj, ns_g_lctx, ISC_LOG_ERROR, + "unknown type '%s'", r.base); + return (result); +} + +dns_zonetype_t +ns_config_getzonetype(const cfg_obj_t *zonetypeobj) { + dns_zonetype_t ztype = dns_zone_none; + const char *str; + + str = cfg_obj_asstring(zonetypeobj); + if (strcasecmp(str, "master") == 0) + ztype = dns_zone_master; + else if (strcasecmp(str, "slave") == 0) + ztype = dns_zone_slave; + else if (strcasecmp(str, "stub") == 0) + ztype = dns_zone_stub; + else + INSIST(0); + return (ztype); +} + +isc_result_t +ns_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list, + in_port_t defport, isc_mem_t *mctx, + isc_sockaddr_t **addrsp, isc_uint32_t *countp) +{ + int count, i = 0; + const cfg_obj_t *addrlist; + const cfg_obj_t *portobj; + const cfg_listelt_t *element; + isc_sockaddr_t *addrs; + in_port_t port; + isc_result_t result; + + INSIST(addrsp != NULL && *addrsp == NULL); + INSIST(countp != NULL); + + addrlist = cfg_tuple_get(list, "addresses"); + count = ns_config_listcount(addrlist); + + portobj = cfg_tuple_get(list, "port"); + if (cfg_obj_isuint32(portobj)) { + isc_uint32_t val = cfg_obj_asuint32(portobj); + if (val > ISC_UINT16_MAX) { + cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, + "port '%u' out of range", val); + return (ISC_R_RANGE); + } + port = (in_port_t) val; + } else if (defport != 0) + port = defport; + else { + result = ns_config_getport(config, &port); + if (result != ISC_R_SUCCESS) + return (result); + } + + addrs = isc_mem_get(mctx, count * sizeof(isc_sockaddr_t)); + if (addrs == NULL) + return (ISC_R_NOMEMORY); + + for (element = cfg_list_first(addrlist); + element != NULL; + element = cfg_list_next(element), i++) + { + INSIST(i < count); + addrs[i] = *cfg_obj_assockaddr(cfg_listelt_value(element)); + if (isc_sockaddr_getport(&addrs[i]) == 0) + isc_sockaddr_setport(&addrs[i], port); + } + INSIST(i == count); + + *addrsp = addrs; + *countp = count; + + return (ISC_R_SUCCESS); +} + +void +ns_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp, + isc_uint32_t count) +{ + INSIST(addrsp != NULL && *addrsp != NULL); + + isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t)); + *addrsp = NULL; +} + +static isc_result_t +get_masters_def(const cfg_obj_t *cctx, const char *name, + const cfg_obj_t **ret) +{ + isc_result_t result; + const cfg_obj_t *masters = NULL; + const cfg_listelt_t *elt; + + result = cfg_map_get(cctx, "masters", &masters); + if (result != ISC_R_SUCCESS) + return (result); + for (elt = cfg_list_first(masters); + elt != NULL; + elt = cfg_list_next(elt)) { + const cfg_obj_t *list; + const char *listname; + + list = cfg_listelt_value(elt); + listname = cfg_obj_asstring(cfg_tuple_get(list, "name")); + + if (strcasecmp(listname, name) == 0) { + *ret = list; + return (ISC_R_SUCCESS); + } + } + return (ISC_R_NOTFOUND); +} + +isc_result_t +ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list, + isc_mem_t *mctx, isc_sockaddr_t **addrsp, + dns_name_t ***keysp, isc_uint32_t *countp) +{ + isc_uint32_t addrcount = 0, keycount = 0, i = 0; + isc_uint32_t listcount = 0, l = 0, j; + isc_uint32_t stackcount = 0, pushed = 0; + isc_result_t result; + const cfg_listelt_t *element; + const cfg_obj_t *addrlist; + const cfg_obj_t *portobj; + in_port_t port; + dns_fixedname_t fname; + isc_sockaddr_t *addrs = NULL; + dns_name_t **keys = NULL; + struct { const char *name; } *lists = NULL; + struct { + const cfg_listelt_t *element; + in_port_t port; + } *stack = NULL; + + REQUIRE(addrsp != NULL && *addrsp == NULL); + REQUIRE(keysp != NULL && *keysp == NULL); + REQUIRE(countp != NULL); + + newlist: + addrlist = cfg_tuple_get(list, "addresses"); + portobj = cfg_tuple_get(list, "port"); + if (cfg_obj_isuint32(portobj)) { + isc_uint32_t val = cfg_obj_asuint32(portobj); + if (val > ISC_UINT16_MAX) { + cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, + "port '%u' out of range", val); + result = ISC_R_RANGE; + goto cleanup; + } + port = (in_port_t) val; + } else { + result = ns_config_getport(config, &port); + if (result != ISC_R_SUCCESS) + goto cleanup; + } + + result = ISC_R_NOMEMORY; + + element = cfg_list_first(addrlist); + resume: + for ( ; + element != NULL; + element = cfg_list_next(element)) + { + const cfg_obj_t *addr; + const cfg_obj_t *key; + const char *keystr; + isc_buffer_t b; + + addr = cfg_tuple_get(cfg_listelt_value(element), + "masterselement"); + key = cfg_tuple_get(cfg_listelt_value(element), "key"); + + if (!cfg_obj_issockaddr(addr)) { + const char *listname = cfg_obj_asstring(addr); + isc_result_t tresult; + + /* Grow lists? */ + if (listcount == l) { + void * new; + isc_uint32_t newlen = listcount + 16; + size_t newsize, oldsize; + + newsize = newlen * sizeof(*lists); + oldsize = listcount * sizeof(*lists); + new = isc_mem_get(mctx, newsize); + if (new == NULL) + goto cleanup; + if (listcount != 0) { + memcpy(new, lists, oldsize); + isc_mem_put(mctx, lists, oldsize); + } + lists = new; + listcount = newlen; + } + /* Seen? */ + for (j = 0; j < l; j++) + if (strcasecmp(lists[j].name, listname) == 0) + break; + if (j < l) + continue; + tresult = get_masters_def(config, listname, &list); + if (tresult == ISC_R_NOTFOUND) { + cfg_obj_log(addr, ns_g_lctx, ISC_LOG_ERROR, + "masters \"%s\" not found", listname); + + result = tresult; + goto cleanup; + } + if (tresult != ISC_R_SUCCESS) + goto cleanup; + lists[l++].name = listname; + /* Grow stack? */ + if (stackcount == pushed) { + void * new; + isc_uint32_t newlen = stackcount + 16; + size_t newsize, oldsize; + + newsize = newlen * sizeof(*stack); + oldsize = stackcount * sizeof(*stack); + new = isc_mem_get(mctx, newsize); + if (new == NULL) + goto cleanup; + if (stackcount != 0) { + memcpy(new, stack, oldsize); + isc_mem_put(mctx, stack, oldsize); + } + stack = new; + stackcount = newlen; + } + /* + * We want to resume processing this list on the + * next element. + */ + stack[pushed].element = cfg_list_next(element); + stack[pushed].port = port; + pushed++; + goto newlist; + } + + if (i == addrcount) { + void * new; + isc_uint32_t newlen = addrcount + 16; + size_t newsize, oldsize; + + newsize = newlen * sizeof(isc_sockaddr_t); + oldsize = addrcount * sizeof(isc_sockaddr_t); + new = isc_mem_get(mctx, newsize); + if (new == NULL) + goto cleanup; + if (addrcount != 0) { + memcpy(new, addrs, oldsize); + isc_mem_put(mctx, addrs, oldsize); + } + addrs = new; + addrcount = newlen; + + newsize = newlen * sizeof(dns_name_t *); + oldsize = keycount * sizeof(dns_name_t *); + new = isc_mem_get(mctx, newsize); + if (new == NULL) + goto cleanup; + if (keycount != 0) { + memcpy(new, keys, oldsize); + isc_mem_put(mctx, keys, oldsize); + } + keys = new; + keycount = newlen; + } + + addrs[i] = *cfg_obj_assockaddr(addr); + if (isc_sockaddr_getport(&addrs[i]) == 0) + isc_sockaddr_setport(&addrs[i], port); + keys[i] = NULL; + if (!cfg_obj_isstring(key)) { + i++; + continue; + } + keys[i] = isc_mem_get(mctx, sizeof(dns_name_t)); + if (keys[i] == NULL) + goto cleanup; + dns_name_init(keys[i], NULL); + + keystr = cfg_obj_asstring(key); + isc_buffer_init(&b, keystr, strlen(keystr)); + isc_buffer_add(&b, strlen(keystr)); + dns_fixedname_init(&fname); + result = dns_name_fromtext(dns_fixedname_name(&fname), &b, + dns_rootname, ISC_FALSE, NULL); + if (result != ISC_R_SUCCESS) + goto cleanup; + result = dns_name_dup(dns_fixedname_name(&fname), mctx, + keys[i]); + if (result != ISC_R_SUCCESS) + goto cleanup; + i++; + } + if (pushed != 0) { + pushed--; + element = stack[pushed].element; + port = stack[pushed].port; + goto resume; + } + if (i < addrcount) { + void * new; + size_t newsize, oldsize; + + newsize = i * sizeof(isc_sockaddr_t); + oldsize = addrcount * sizeof(isc_sockaddr_t); + if (i != 0) { + new = isc_mem_get(mctx, newsize); + if (new == NULL) + goto cleanup; + memcpy(new, addrs, newsize); + } else + new = NULL; + isc_mem_put(mctx, addrs, oldsize); + addrs = new; + addrcount = i; + + newsize = i * sizeof(dns_name_t *); + oldsize = keycount * sizeof(dns_name_t *); + if (i != 0) { + new = isc_mem_get(mctx, newsize); + if (new == NULL) + goto cleanup; + memcpy(new, keys, newsize); + } else + new = NULL; + isc_mem_put(mctx, keys, oldsize); + keys = new; + keycount = i; + } + + if (lists != NULL) + isc_mem_put(mctx, lists, listcount * sizeof(*lists)); + if (stack != NULL) + isc_mem_put(mctx, stack, stackcount * sizeof(*stack)); + + INSIST(keycount == addrcount); + + *addrsp = addrs; + *keysp = keys; + *countp = addrcount; + + return (ISC_R_SUCCESS); + + cleanup: + if (addrs != NULL) + isc_mem_put(mctx, addrs, addrcount * sizeof(isc_sockaddr_t)); + if (keys != NULL) { + for (j = 0; j <= i; j++) { + if (keys[j] == NULL) + continue; + if (dns_name_dynamic(keys[j])) + dns_name_free(keys[j], mctx); + isc_mem_put(mctx, keys[j], sizeof(dns_name_t)); + } + isc_mem_put(mctx, keys, keycount * sizeof(dns_name_t *)); + } + if (lists != NULL) + isc_mem_put(mctx, lists, listcount * sizeof(*lists)); + if (stack != NULL) + isc_mem_put(mctx, stack, stackcount * sizeof(*stack)); + return (result); +} + +void +ns_config_putipandkeylist(isc_mem_t *mctx, isc_sockaddr_t **addrsp, + dns_name_t ***keysp, isc_uint32_t count) +{ + unsigned int i; + dns_name_t **keys = *keysp; + + INSIST(addrsp != NULL && *addrsp != NULL); + + isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t)); + for (i = 0; i < count; i++) { + if (keys[i] == NULL) + continue; + if (dns_name_dynamic(keys[i])) + dns_name_free(keys[i], mctx); + isc_mem_put(mctx, keys[i], sizeof(dns_name_t)); + } + isc_mem_put(mctx, *keysp, count * sizeof(dns_name_t *)); + *addrsp = NULL; + *keysp = NULL; +} + +isc_result_t +ns_config_getport(const cfg_obj_t *config, in_port_t *portp) { + const cfg_obj_t *maps[3]; + const cfg_obj_t *options = NULL; + const cfg_obj_t *portobj = NULL; + isc_result_t result; + int i; + + (void)cfg_map_get(config, "options", &options); + i = 0; + if (options != NULL) + maps[i++] = options; + maps[i++] = ns_g_defaults; + maps[i] = NULL; + + result = ns_config_get(maps, "port", &portobj); + INSIST(result == ISC_R_SUCCESS); + if (cfg_obj_asuint32(portobj) >= ISC_UINT16_MAX) { + cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, + "port '%u' out of range", + cfg_obj_asuint32(portobj)); + return (ISC_R_RANGE); + } + *portp = (in_port_t)cfg_obj_asuint32(portobj); + return (ISC_R_SUCCESS); +} + +struct keyalgorithms { + const char *str; + enum { hmacnone, hmacmd5, hmacsha1, hmacsha224, + hmacsha256, hmacsha384, hmacsha512 } hmac; + isc_uint16_t size; +} algorithms[] = { + { "hmac-md5", hmacmd5, 128 }, + { "hmac-md5.sig-alg.reg.int", hmacmd5, 0 }, + { "hmac-md5.sig-alg.reg.int.", hmacmd5, 0 }, + { "hmac-sha1", hmacsha1, 160 }, + { "hmac-sha224", hmacsha224, 224 }, + { "hmac-sha256", hmacsha256, 256 }, + { "hmac-sha384", hmacsha384, 384 }, + { "hmac-sha512", hmacsha512, 512 }, + { NULL, hmacnone, 0 } +}; + +isc_result_t +ns_config_getkeyalgorithm(const char *str, dns_name_t **name, + isc_uint16_t *digestbits) +{ + int i; + size_t len = 0; + isc_uint16_t bits; + isc_result_t result; + + for (i = 0; algorithms[i].str != NULL; i++) { + len = strlen(algorithms[i].str); + if (strncasecmp(algorithms[i].str, str, len) == 0 && + (str[len] == '\0' || + (algorithms[i].size != 0 && str[len] == '-'))) + break; + } + if (algorithms[i].str == NULL) + return (ISC_R_NOTFOUND); + if (str[len] == '-') { + result = isc_parse_uint16(&bits, str + len + 1, 10); + if (result != ISC_R_SUCCESS) + return (result); + if (bits > algorithms[i].size) + return (ISC_R_RANGE); + } else if (algorithms[i].size == 0) + bits = 128; + else + bits = algorithms[i].size; + + if (name != NULL) { + switch (algorithms[i].hmac) { + case hmacmd5: *name = dns_tsig_hmacmd5_name; break; + case hmacsha1: *name = dns_tsig_hmacsha1_name; break; + case hmacsha224: *name = dns_tsig_hmacsha224_name; break; + case hmacsha256: *name = dns_tsig_hmacsha256_name; break; + case hmacsha384: *name = dns_tsig_hmacsha384_name; break; + case hmacsha512: *name = dns_tsig_hmacsha512_name; break; + default: + INSIST(0); + } + } + if (digestbits != NULL) + *digestbits = bits; + return (ISC_R_SUCCESS); +} diff --git a/bin/named/control.c b/bin/named/control.c new file mode 100644 index 0000000..3f2d52e --- /dev/null +++ b/bin/named/control.c @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 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: control.c,v 1.20.10.10 2007/09/13 23:46:26 tbox Exp $ */ + +/*! \file */ + +#include + + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#ifdef HAVE_LIBSCF +#include +#endif + +static isc_boolean_t +command_compare(const char *text, const char *command) { + unsigned int commandlen = strlen(command); + if (strncasecmp(text, command, commandlen) == 0 && + (text[commandlen] == '\0' || + text[commandlen] == ' ' || + text[commandlen] == '\t')) + return (ISC_TRUE); + return (ISC_FALSE); +} + +/*% + * This function is called to process the incoming command + * when a control channel message is received. + */ +isc_result_t +ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) { + isccc_sexpr_t *data; + char *command; + isc_result_t result; +#ifdef HAVE_LIBSCF + ns_smf_want_disable = 0; +#endif + + data = isccc_alist_lookup(message, "_data"); + if (data == NULL) { + /* + * No data section. + */ + return (ISC_R_FAILURE); + } + + result = isccc_cc_lookupstring(data, "type", &command); + if (result != ISC_R_SUCCESS) { + /* + * We have no idea what this is. + */ + return (result); + } + + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_CONTROL, ISC_LOG_DEBUG(1), + "received control channel command '%s'", + command); + + /* + * Compare the 'command' parameter against all known control commands. + */ + if (command_compare(command, NS_COMMAND_RELOAD)) { + result = ns_server_reloadcommand(ns_g_server, command, text); + } else if (command_compare(command, NS_COMMAND_RECONFIG)) { + result = ns_server_reconfigcommand(ns_g_server, command); + } else if (command_compare(command, NS_COMMAND_REFRESH)) { + result = ns_server_refreshcommand(ns_g_server, command, text); + } else if (command_compare(command, NS_COMMAND_RETRANSFER)) { + result = ns_server_retransfercommand(ns_g_server, command); + } else if (command_compare(command, NS_COMMAND_HALT)) { +#ifdef HAVE_LIBSCF + /* + * If we are managed by smf(5), AND in chroot, then + * we cannot connect to the smf repository, so just + * return with an appropriate message back to rndc. + */ + if (ns_smf_got_instance == 1 && ns_smf_chroot == 1) { + result = ns_smf_add_message(text); + return (result); + } + /* + * If we are managed by smf(5) but not in chroot, + * try to disable ourselves the smf way. + */ + if (ns_smf_got_instance == 1 && ns_smf_chroot == 0) + ns_smf_want_disable = 1; + /* + * If ns_smf_got_instance = 0, ns_smf_chroot + * is not relevant and we fall through to + * isc_app_shutdown below. + */ +#endif + ns_server_flushonshutdown(ns_g_server, ISC_FALSE); + ns_os_shutdownmsg(command, text); + isc_app_shutdown(); + result = ISC_R_SUCCESS; + } else if (command_compare(command, NS_COMMAND_STOP)) { +#ifdef HAVE_LIBSCF + if (ns_smf_got_instance == 1 && ns_smf_chroot == 1) { + result = ns_smf_add_message(text); + return (result); + } + if (ns_smf_got_instance == 1 && ns_smf_chroot == 0) + ns_smf_want_disable = 1; +#endif + ns_server_flushonshutdown(ns_g_server, ISC_TRUE); + ns_os_shutdownmsg(command, text); + isc_app_shutdown(); + result = ISC_R_SUCCESS; + } else if (command_compare(command, NS_COMMAND_DUMPSTATS)) { + result = ns_server_dumpstats(ns_g_server); + } else if (command_compare(command, NS_COMMAND_QUERYLOG)) { + result = ns_server_togglequerylog(ns_g_server); + } else if (command_compare(command, NS_COMMAND_DUMPDB)) { + ns_server_dumpdb(ns_g_server, command); + result = ISC_R_SUCCESS; + } else if (command_compare(command, NS_COMMAND_TRACE)) { + result = ns_server_setdebuglevel(ns_g_server, command); + } else if (command_compare(command, NS_COMMAND_NOTRACE)) { + ns_g_debuglevel = 0; + isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); + result = ISC_R_SUCCESS; + } else if (command_compare(command, NS_COMMAND_FLUSH)) { + result = ns_server_flushcache(ns_g_server, command); + } else if (command_compare(command, NS_COMMAND_FLUSHNAME)) { + result = ns_server_flushname(ns_g_server, command); + } else if (command_compare(command, NS_COMMAND_STATUS)) { + result = ns_server_status(ns_g_server, text); + } else if (command_compare(command, NS_COMMAND_FREEZE)) { + result = ns_server_freeze(ns_g_server, ISC_TRUE, command); + } else if (command_compare(command, NS_COMMAND_UNFREEZE) || + command_compare(command, NS_COMMAND_THAW)) { + result = ns_server_freeze(ns_g_server, ISC_FALSE, command); + } else if (command_compare(command, NS_COMMAND_RECURSING)) { + result = ns_server_dumprecursing(ns_g_server); + } else if (command_compare(command, NS_COMMAND_TIMERPOKE)) { + result = ISC_R_SUCCESS; + isc_timermgr_poke(ns_g_timermgr); + } else if (command_compare(command, NS_COMMAND_NULL)) { + result = ISC_R_SUCCESS; + } else if (command_compare(command, NS_COMMAND_NOTIFY)) { + result = ns_server_notifycommand(ns_g_server, command, text); + } else if (command_compare(command, NS_COMMAND_VALIDATION)) { + result = ns_server_validation(ns_g_server, command); + } else { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, + "unknown control channel command '%s'", + command); + result = DNS_R_UNKNOWNCOMMAND; + } + + return (result); +} diff --git a/bin/named/controlconf.c b/bin/named/controlconf.c new file mode 100644 index 0000000..3e36446 --- /dev/null +++ b/bin/named/controlconf.c @@ -0,0 +1,1461 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2001-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: controlconf.c,v 1.40.18.10 2006/12/07 04:53:02 marka Exp $ */ + +/*! \file */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +/* + * Note: Listeners and connections are not locked. All event handlers are + * executed by the server task, and all callers of exported routines must + * be running under the server task. + */ + +typedef struct controlkey controlkey_t; +typedef ISC_LIST(controlkey_t) controlkeylist_t; + +typedef struct controlconnection controlconnection_t; +typedef ISC_LIST(controlconnection_t) controlconnectionlist_t; + +typedef struct controllistener controllistener_t; +typedef ISC_LIST(controllistener_t) controllistenerlist_t; + +struct controlkey { + char * keyname; + isc_region_t secret; + ISC_LINK(controlkey_t) link; +}; + +struct controlconnection { + isc_socket_t * sock; + isccc_ccmsg_t ccmsg; + isc_boolean_t ccmsg_valid; + isc_boolean_t sending; + isc_timer_t * timer; + unsigned char buffer[2048]; + controllistener_t * listener; + isc_uint32_t nonce; + ISC_LINK(controlconnection_t) link; +}; + +struct controllistener { + ns_controls_t * controls; + isc_mem_t * mctx; + isc_task_t * task; + isc_sockaddr_t address; + isc_socket_t * sock; + dns_acl_t * acl; + isc_boolean_t listening; + isc_boolean_t exiting; + controlkeylist_t keys; + controlconnectionlist_t connections; + isc_sockettype_t type; + isc_uint32_t perm; + isc_uint32_t owner; + isc_uint32_t group; + ISC_LINK(controllistener_t) link; +}; + +struct ns_controls { + ns_server_t *server; + controllistenerlist_t listeners; + isc_boolean_t shuttingdown; + isccc_symtab_t *symtab; +}; + +static void control_newconn(isc_task_t *task, isc_event_t *event); +static void control_recvmessage(isc_task_t *task, isc_event_t *event); + +#define CLOCKSKEW 300 + +static void +free_controlkey(controlkey_t *key, isc_mem_t *mctx) { + if (key->keyname != NULL) + isc_mem_free(mctx, key->keyname); + if (key->secret.base != NULL) + isc_mem_put(mctx, key->secret.base, key->secret.length); + isc_mem_put(mctx, key, sizeof(*key)); +} + +static void +free_controlkeylist(controlkeylist_t *keylist, isc_mem_t *mctx) { + while (!ISC_LIST_EMPTY(*keylist)) { + controlkey_t *key = ISC_LIST_HEAD(*keylist); + ISC_LIST_UNLINK(*keylist, key, link); + free_controlkey(key, mctx); + } +} + +static void +free_listener(controllistener_t *listener) { + INSIST(listener->exiting); + INSIST(!listener->listening); + INSIST(ISC_LIST_EMPTY(listener->connections)); + + if (listener->sock != NULL) + isc_socket_detach(&listener->sock); + + free_controlkeylist(&listener->keys, listener->mctx); + + if (listener->acl != NULL) + dns_acl_detach(&listener->acl); + + isc_mem_put(listener->mctx, listener, sizeof(*listener)); +} + +static void +maybe_free_listener(controllistener_t *listener) { + if (listener->exiting && + !listener->listening && + ISC_LIST_EMPTY(listener->connections)) + free_listener(listener); +} + +static void +maybe_free_connection(controlconnection_t *conn) { + controllistener_t *listener = conn->listener; + + if (conn->timer != NULL) + isc_timer_detach(&conn->timer); + + if (conn->ccmsg_valid) { + isccc_ccmsg_cancelread(&conn->ccmsg); + return; + } + + if (conn->sending) { + isc_socket_cancel(conn->sock, listener->task, + ISC_SOCKCANCEL_SEND); + return; + } + + ISC_LIST_UNLINK(listener->connections, conn, link); + isc_mem_put(listener->mctx, conn, sizeof(*conn)); +} + +static void +shutdown_listener(controllistener_t *listener) { + controlconnection_t *conn; + controlconnection_t *next; + + if (!listener->exiting) { + char socktext[ISC_SOCKADDR_FORMATSIZE]; + + ISC_LIST_UNLINK(listener->controls->listeners, listener, link); + + isc_sockaddr_format(&listener->address, socktext, + sizeof(socktext)); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, + "stopping command channel on %s", socktext); + if (listener->type == isc_sockettype_unix) + isc_socket_cleanunix(&listener->address, ISC_TRUE); + listener->exiting = ISC_TRUE; + } + + for (conn = ISC_LIST_HEAD(listener->connections); + conn != NULL; + conn = next) + { + next = ISC_LIST_NEXT(conn, link); + maybe_free_connection(conn); + } + + if (listener->listening) + isc_socket_cancel(listener->sock, listener->task, + ISC_SOCKCANCEL_ACCEPT); + + maybe_free_listener(listener); +} + +static isc_boolean_t +address_ok(isc_sockaddr_t *sockaddr, dns_acl_t *acl) { + isc_netaddr_t netaddr; + isc_result_t result; + int match; + + isc_netaddr_fromsockaddr(&netaddr, sockaddr); + + result = dns_acl_match(&netaddr, NULL, acl, + &ns_g_server->aclenv, &match, NULL); + + if (result != ISC_R_SUCCESS || match <= 0) + return (ISC_FALSE); + else + return (ISC_TRUE); +} + +static isc_result_t +control_accept(controllistener_t *listener) { + isc_result_t result; + result = isc_socket_accept(listener->sock, + listener->task, + control_newconn, listener); + if (result != ISC_R_SUCCESS) + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_socket_accept() failed: %s", + isc_result_totext(result)); + else + listener->listening = ISC_TRUE; + return (result); +} + +static isc_result_t +control_listen(controllistener_t *listener) { + isc_result_t result; + + result = isc_socket_listen(listener->sock, 0); + if (result != ISC_R_SUCCESS) + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_socket_listen() failed: %s", + isc_result_totext(result)); + return (result); +} + +static void +control_next(controllistener_t *listener) { + (void)control_accept(listener); +} + +static void +control_senddone(isc_task_t *task, isc_event_t *event) { + isc_socketevent_t *sevent = (isc_socketevent_t *) event; + controlconnection_t *conn = event->ev_arg; + controllistener_t *listener = conn->listener; + isc_socket_t *sock = (isc_socket_t *)sevent->ev_sender; + isc_result_t result; + + REQUIRE(conn->sending); + + UNUSED(task); + + conn->sending = ISC_FALSE; + + if (sevent->result != ISC_R_SUCCESS && + sevent->result != ISC_R_CANCELED) + { + char socktext[ISC_SOCKADDR_FORMATSIZE]; + isc_sockaddr_t peeraddr; + + (void)isc_socket_getpeername(sock, &peeraddr); + isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, + "error sending command response to %s: %s", + socktext, isc_result_totext(sevent->result)); + } + isc_event_free(&event); + + result = isccc_ccmsg_readmessage(&conn->ccmsg, listener->task, + control_recvmessage, conn); + if (result != ISC_R_SUCCESS) { + isc_socket_detach(&conn->sock); + maybe_free_connection(conn); + maybe_free_listener(listener); + } +} + +static inline void +log_invalid(isccc_ccmsg_t *ccmsg, isc_result_t result) { + char socktext[ISC_SOCKADDR_FORMATSIZE]; + isc_sockaddr_t peeraddr; + + (void)isc_socket_getpeername(ccmsg->sock, &peeraddr); + isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_CONTROL, ISC_LOG_ERROR, + "invalid command from %s: %s", + socktext, isc_result_totext(result)); +} + +static void +control_recvmessage(isc_task_t *task, isc_event_t *event) { + controlconnection_t *conn; + controllistener_t *listener; + controlkey_t *key; + isccc_sexpr_t *request = NULL; + isccc_sexpr_t *response = NULL; + isccc_region_t ccregion; + isccc_region_t secret; + isc_stdtime_t now; + isc_buffer_t b; + isc_region_t r; + isc_uint32_t len; + isc_buffer_t text; + char textarray[1024]; + isc_result_t result; + isc_result_t eresult; + isccc_sexpr_t *_ctrl; + isccc_time_t sent; + isccc_time_t exp; + isc_uint32_t nonce; + + REQUIRE(event->ev_type == ISCCC_EVENT_CCMSG); + + conn = event->ev_arg; + listener = conn->listener; + secret.rstart = NULL; + + /* Is the server shutting down? */ + if (listener->controls->shuttingdown) + goto cleanup; + + if (conn->ccmsg.result != ISC_R_SUCCESS) { + if (conn->ccmsg.result != ISC_R_CANCELED && + conn->ccmsg.result != ISC_R_EOF) + log_invalid(&conn->ccmsg, conn->ccmsg.result); + goto cleanup; + } + + request = NULL; + + for (key = ISC_LIST_HEAD(listener->keys); + key != NULL; + key = ISC_LIST_NEXT(key, link)) + { + ccregion.rstart = isc_buffer_base(&conn->ccmsg.buffer); + ccregion.rend = isc_buffer_used(&conn->ccmsg.buffer); + if (secret.rstart != NULL) + isc_mem_put(listener->mctx, secret.rstart, + REGION_SIZE(secret)); + secret.rstart = isc_mem_get(listener->mctx, key->secret.length); + if (secret.rstart == NULL) + goto cleanup; + memcpy(secret.rstart, key->secret.base, key->secret.length); + secret.rend = secret.rstart + key->secret.length; + result = isccc_cc_fromwire(&ccregion, &request, &secret); + if (result == ISC_R_SUCCESS) + break; + else if (result == ISCCC_R_BADAUTH) { + /* + * For some reason, request is non-NULL when + * isccc_cc_fromwire returns ISCCC_R_BADAUTH. + */ + if (request != NULL) + isccc_sexpr_free(&request); + } else { + log_invalid(&conn->ccmsg, result); + goto cleanup; + } + } + + if (key == NULL) { + log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH); + goto cleanup; + } + + /* We shouldn't be getting a reply. */ + if (isccc_cc_isreply(request)) { + log_invalid(&conn->ccmsg, ISC_R_FAILURE); + goto cleanup; + } + + isc_stdtime_get(&now); + + /* + * Limit exposure to replay attacks. + */ + _ctrl = isccc_alist_lookup(request, "_ctrl"); + if (_ctrl == NULL) { + log_invalid(&conn->ccmsg, ISC_R_FAILURE); + goto cleanup; + } + + if (isccc_cc_lookupuint32(_ctrl, "_tim", &sent) == ISC_R_SUCCESS) { + if ((sent + CLOCKSKEW) < now || (sent - CLOCKSKEW) > now) { + log_invalid(&conn->ccmsg, ISCCC_R_CLOCKSKEW); + goto cleanup; + } + } else { + log_invalid(&conn->ccmsg, ISC_R_FAILURE); + goto cleanup; + } + + /* + * Expire messages that are too old. + */ + if (isccc_cc_lookupuint32(_ctrl, "_exp", &exp) == ISC_R_SUCCESS && + now > exp) { + log_invalid(&conn->ccmsg, ISCCC_R_EXPIRED); + goto cleanup; + } + + /* + * Duplicate suppression (required for UDP). + */ + isccc_cc_cleansymtab(listener->controls->symtab, now); + result = isccc_cc_checkdup(listener->controls->symtab, request, now); + if (result != ISC_R_SUCCESS) { + if (result == ISC_R_EXISTS) + result = ISCCC_R_DUPLICATE; + log_invalid(&conn->ccmsg, result); + goto cleanup; + } + + if (conn->nonce != 0 && + (isccc_cc_lookupuint32(_ctrl, "_nonce", &nonce) != ISC_R_SUCCESS || + conn->nonce != nonce)) { + log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH); + goto cleanup; + } + + /* + * Establish nonce. + */ + while (conn->nonce == 0) + isc_random_get(&conn->nonce); + + isc_buffer_init(&text, textarray, sizeof(textarray)); + eresult = ns_control_docommand(request, &text); + + result = isccc_cc_createresponse(request, now, now + 60, &response); + if (result != ISC_R_SUCCESS) + goto cleanup; + if (eresult != ISC_R_SUCCESS) { + isccc_sexpr_t *data; + + data = isccc_alist_lookup(response, "_data"); + if (data != NULL) { + const char *estr = isc_result_totext(eresult); + if (isccc_cc_definestring(data, "err", estr) == NULL) + goto cleanup; + } + } + + if (isc_buffer_usedlength(&text) > 0) { + isccc_sexpr_t *data; + + data = isccc_alist_lookup(response, "_data"); + if (data != NULL) { + char *str = (char *)isc_buffer_base(&text); + if (isccc_cc_definestring(data, "text", str) == NULL) + goto cleanup; + } + } + + _ctrl = isccc_alist_lookup(response, "_ctrl"); + if (_ctrl == NULL || + isccc_cc_defineuint32(_ctrl, "_nonce", conn->nonce) == NULL) + goto cleanup; + + ccregion.rstart = conn->buffer + 4; + ccregion.rend = conn->buffer + sizeof(conn->buffer); + result = isccc_cc_towire(response, &ccregion, &secret); + if (result != ISC_R_SUCCESS) + goto cleanup; + isc_buffer_init(&b, conn->buffer, 4); + len = sizeof(conn->buffer) - REGION_SIZE(ccregion); + isc_buffer_putuint32(&b, len - 4); + r.base = conn->buffer; + r.length = len; + + result = isc_socket_send(conn->sock, &r, task, control_senddone, conn); + if (result != ISC_R_SUCCESS) + goto cleanup; + conn->sending = ISC_TRUE; + + if (secret.rstart != NULL) + isc_mem_put(listener->mctx, secret.rstart, + REGION_SIZE(secret)); + if (request != NULL) + isccc_sexpr_free(&request); + if (response != NULL) + isccc_sexpr_free(&response); + return; + + cleanup: + if (secret.rstart != NULL) + isc_mem_put(listener->mctx, secret.rstart, + REGION_SIZE(secret)); + isc_socket_detach(&conn->sock); + isccc_ccmsg_invalidate(&conn->ccmsg); + conn->ccmsg_valid = ISC_FALSE; + maybe_free_connection(conn); + maybe_free_listener(listener); + if (request != NULL) + isccc_sexpr_free(&request); + if (response != NULL) + isccc_sexpr_free(&response); +} + +static void +control_timeout(isc_task_t *task, isc_event_t *event) { + controlconnection_t *conn = event->ev_arg; + + UNUSED(task); + + isc_timer_detach(&conn->timer); + maybe_free_connection(conn); + + isc_event_free(&event); +} + +static isc_result_t +newconnection(controllistener_t *listener, isc_socket_t *sock) { + controlconnection_t *conn; + isc_interval_t interval; + isc_result_t result; + + conn = isc_mem_get(listener->mctx, sizeof(*conn)); + if (conn == NULL) + return (ISC_R_NOMEMORY); + + conn->sock = sock; + isccc_ccmsg_init(listener->mctx, sock, &conn->ccmsg); + conn->ccmsg_valid = ISC_TRUE; + conn->sending = ISC_FALSE; + conn->timer = NULL; + isc_interval_set(&interval, 60, 0); + result = isc_timer_create(ns_g_timermgr, isc_timertype_once, + NULL, &interval, listener->task, + control_timeout, conn, &conn->timer); + if (result != ISC_R_SUCCESS) + goto cleanup; + + conn->listener = listener; + conn->nonce = 0; + ISC_LINK_INIT(conn, link); + + result = isccc_ccmsg_readmessage(&conn->ccmsg, listener->task, + control_recvmessage, conn); + if (result != ISC_R_SUCCESS) + goto cleanup; + isccc_ccmsg_setmaxsize(&conn->ccmsg, 2048); + + ISC_LIST_APPEND(listener->connections, conn, link); + return (ISC_R_SUCCESS); + + cleanup: + isccc_ccmsg_invalidate(&conn->ccmsg); + if (conn->timer != NULL) + isc_timer_detach(&conn->timer); + isc_mem_put(listener->mctx, conn, sizeof(*conn)); + return (result); +} + +static void +control_newconn(isc_task_t *task, isc_event_t *event) { + isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event; + controllistener_t *listener = event->ev_arg; + isc_socket_t *sock; + isc_sockaddr_t peeraddr; + isc_result_t result; + + UNUSED(task); + + listener->listening = ISC_FALSE; + + if (nevent->result != ISC_R_SUCCESS) { + if (nevent->result == ISC_R_CANCELED) { + shutdown_listener(listener); + goto cleanup; + } + goto restart; + } + + sock = nevent->newsocket; + (void)isc_socket_getpeername(sock, &peeraddr); + if (listener->type == isc_sockettype_tcp && + !address_ok(&peeraddr, listener->acl)) { + char socktext[ISC_SOCKADDR_FORMATSIZE]; + isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, + "rejected command channel message from %s", + socktext); + isc_socket_detach(&sock); + goto restart; + } + + result = newconnection(listener, sock); + if (result != ISC_R_SUCCESS) { + char socktext[ISC_SOCKADDR_FORMATSIZE]; + isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, + "dropped command channel from %s: %s", + socktext, isc_result_totext(result)); + isc_socket_detach(&sock); + goto restart; + } + + restart: + control_next(listener); + cleanup: + isc_event_free(&event); +} + +static void +controls_shutdown(ns_controls_t *controls) { + controllistener_t *listener; + controllistener_t *next; + + for (listener = ISC_LIST_HEAD(controls->listeners); + listener != NULL; + listener = next) + { + /* + * This is asynchronous. As listeners shut down, they will + * call their callbacks. + */ + next = ISC_LIST_NEXT(listener, link); + shutdown_listener(listener); + } +} + +void +ns_controls_shutdown(ns_controls_t *controls) { + controls_shutdown(controls); + controls->shuttingdown = ISC_TRUE; +} + +static isc_result_t +cfgkeylist_find(const cfg_obj_t *keylist, const char *keyname, + const cfg_obj_t **objp) +{ + const cfg_listelt_t *element; + const char *str; + const cfg_obj_t *obj; + + for (element = cfg_list_first(keylist); + element != NULL; + element = cfg_list_next(element)) + { + obj = cfg_listelt_value(element); + str = cfg_obj_asstring(cfg_map_getname(obj)); + if (strcasecmp(str, keyname) == 0) + break; + } + if (element == NULL) + return (ISC_R_NOTFOUND); + obj = cfg_listelt_value(element); + *objp = obj; + return (ISC_R_SUCCESS); +} + +static isc_result_t +controlkeylist_fromcfg(const cfg_obj_t *keylist, isc_mem_t *mctx, + controlkeylist_t *keyids) +{ + const cfg_listelt_t *element; + char *newstr = NULL; + const char *str; + const cfg_obj_t *obj; + controlkey_t *key; + + for (element = cfg_list_first(keylist); + element != NULL; + element = cfg_list_next(element)) + { + obj = cfg_listelt_value(element); + str = cfg_obj_asstring(obj); + newstr = isc_mem_strdup(mctx, str); + if (newstr == NULL) + goto cleanup; + key = isc_mem_get(mctx, sizeof(*key)); + if (key == NULL) + goto cleanup; + key->keyname = newstr; + key->secret.base = NULL; + key->secret.length = 0; + ISC_LINK_INIT(key, link); + ISC_LIST_APPEND(*keyids, key, link); + newstr = NULL; + } + return (ISC_R_SUCCESS); + + cleanup: + if (newstr != NULL) + isc_mem_free(mctx, newstr); + free_controlkeylist(keyids, mctx); + return (ISC_R_NOMEMORY); +} + +static void +register_keys(const cfg_obj_t *control, const cfg_obj_t *keylist, + controlkeylist_t *keyids, isc_mem_t *mctx, const char *socktext) +{ + controlkey_t *keyid, *next; + const cfg_obj_t *keydef; + char secret[1024]; + isc_buffer_t b; + isc_result_t result; + + /* + * Find the keys corresponding to the keyids used by this listener. + */ + for (keyid = ISC_LIST_HEAD(*keyids); keyid != NULL; keyid = next) { + next = ISC_LIST_NEXT(keyid, link); + + result = cfgkeylist_find(keylist, keyid->keyname, &keydef); + if (result != ISC_R_SUCCESS) { + cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, + "couldn't find key '%s' for use with " + "command channel %s", + keyid->keyname, socktext); + ISC_LIST_UNLINK(*keyids, keyid, link); + free_controlkey(keyid, mctx); + } else { + const cfg_obj_t *algobj = NULL; + const cfg_obj_t *secretobj = NULL; + const char *algstr = NULL; + const char *secretstr = NULL; + + (void)cfg_map_get(keydef, "algorithm", &algobj); + (void)cfg_map_get(keydef, "secret", &secretobj); + INSIST(algobj != NULL && secretobj != NULL); + + algstr = cfg_obj_asstring(algobj); + secretstr = cfg_obj_asstring(secretobj); + + if (ns_config_getkeyalgorithm(algstr, NULL, NULL) != + ISC_R_SUCCESS) + { + cfg_obj_log(control, ns_g_lctx, + ISC_LOG_WARNING, + "unsupported algorithm '%s' in " + "key '%s' for use with command " + "channel %s", + algstr, keyid->keyname, socktext); + ISC_LIST_UNLINK(*keyids, keyid, link); + free_controlkey(keyid, mctx); + continue; + } + + isc_buffer_init(&b, secret, sizeof(secret)); + result = isc_base64_decodestring(secretstr, &b); + + if (result != ISC_R_SUCCESS) { + cfg_obj_log(keydef, ns_g_lctx, ISC_LOG_WARNING, + "secret for key '%s' on " + "command channel %s: %s", + keyid->keyname, socktext, + isc_result_totext(result)); + ISC_LIST_UNLINK(*keyids, keyid, link); + free_controlkey(keyid, mctx); + continue; + } + + keyid->secret.length = isc_buffer_usedlength(&b); + keyid->secret.base = isc_mem_get(mctx, + keyid->secret.length); + if (keyid->secret.base == NULL) { + cfg_obj_log(keydef, ns_g_lctx, ISC_LOG_WARNING, + "couldn't register key '%s': " + "out of memory", keyid->keyname); + ISC_LIST_UNLINK(*keyids, keyid, link); + free_controlkey(keyid, mctx); + break; + } + memcpy(keyid->secret.base, isc_buffer_base(&b), + keyid->secret.length); + } + } +} + +#define CHECK(x) \ + do { \ + result = (x); \ + if (result != ISC_R_SUCCESS) \ + goto cleanup; \ + } while (0) + +static isc_result_t +get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) { + isc_result_t result; + cfg_parser_t *pctx = NULL; + cfg_obj_t *config = NULL; + const cfg_obj_t *key = NULL; + const cfg_obj_t *algobj = NULL; + const cfg_obj_t *secretobj = NULL; + const char *algstr = NULL; + const char *secretstr = NULL; + controlkey_t *keyid = NULL; + char secret[1024]; + isc_buffer_t b; + + CHECK(cfg_parser_create(mctx, ns_g_lctx, &pctx)); + CHECK(cfg_parse_file(pctx, ns_g_keyfile, &cfg_type_rndckey, &config)); + CHECK(cfg_map_get(config, "key", &key)); + + keyid = isc_mem_get(mctx, sizeof(*keyid)); + if (keyid == NULL) + CHECK(ISC_R_NOMEMORY); + keyid->keyname = isc_mem_strdup(mctx, + cfg_obj_asstring(cfg_map_getname(key))); + keyid->secret.base = NULL; + keyid->secret.length = 0; + ISC_LINK_INIT(keyid, link); + if (keyid->keyname == NULL) + CHECK(ISC_R_NOMEMORY); + + CHECK(bind9_check_key(key, ns_g_lctx)); + + (void)cfg_map_get(key, "algorithm", &algobj); + (void)cfg_map_get(key, "secret", &secretobj); + INSIST(algobj != NULL && secretobj != NULL); + + algstr = cfg_obj_asstring(algobj); + secretstr = cfg_obj_asstring(secretobj); + + if (ns_config_getkeyalgorithm(algstr, NULL, NULL) != ISC_R_SUCCESS) { + cfg_obj_log(key, ns_g_lctx, + ISC_LOG_WARNING, + "unsupported algorithm '%s' in " + "key '%s' for use with command " + "channel", + algstr, keyid->keyname); + goto cleanup; + } + + isc_buffer_init(&b, secret, sizeof(secret)); + result = isc_base64_decodestring(secretstr, &b); + + if (result != ISC_R_SUCCESS) { + cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, + "secret for key '%s' on command channel: %s", + keyid->keyname, isc_result_totext(result)); + CHECK(result); + } + + keyid->secret.length = isc_buffer_usedlength(&b); + keyid->secret.base = isc_mem_get(mctx, + keyid->secret.length); + if (keyid->secret.base == NULL) { + cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, + "couldn't register key '%s': " + "out of memory", keyid->keyname); + CHECK(ISC_R_NOMEMORY); + } + memcpy(keyid->secret.base, isc_buffer_base(&b), + keyid->secret.length); + ISC_LIST_APPEND(*keyids, keyid, link); + keyid = NULL; + result = ISC_R_SUCCESS; + + cleanup: + if (keyid != NULL) + free_controlkey(keyid, mctx); + if (config != NULL) + cfg_obj_destroy(pctx, &config); + if (pctx != NULL) + cfg_parser_destroy(&pctx); + return (result); +} + +/* + * Ensures that both '*global_keylistp' and '*control_keylistp' are + * valid or both are NULL. + */ +static void +get_key_info(const cfg_obj_t *config, const cfg_obj_t *control, + const cfg_obj_t **global_keylistp, + const cfg_obj_t **control_keylistp) +{ + isc_result_t result; + const cfg_obj_t *control_keylist = NULL; + const cfg_obj_t *global_keylist = NULL; + + REQUIRE(global_keylistp != NULL && *global_keylistp == NULL); + REQUIRE(control_keylistp != NULL && *control_keylistp == NULL); + + control_keylist = cfg_tuple_get(control, "keys"); + + if (!cfg_obj_isvoid(control_keylist) && + cfg_list_first(control_keylist) != NULL) { + result = cfg_map_get(config, "key", &global_keylist); + + if (result == ISC_R_SUCCESS) { + *global_keylistp = global_keylist; + *control_keylistp = control_keylist; + } + } +} + +static void +update_listener(ns_controls_t *cp, controllistener_t **listenerp, + const cfg_obj_t *control, const cfg_obj_t *config, + isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx, + const char *socktext, isc_sockettype_t type) +{ + controllistener_t *listener; + const cfg_obj_t *allow; + const cfg_obj_t *global_keylist = NULL; + const cfg_obj_t *control_keylist = NULL; + dns_acl_t *new_acl = NULL; + controlkeylist_t keys; + isc_result_t result = ISC_R_SUCCESS; + + for (listener = ISC_LIST_HEAD(cp->listeners); + listener != NULL; + listener = ISC_LIST_NEXT(listener, link)) + if (isc_sockaddr_equal(addr, &listener->address)) + break; + + if (listener == NULL) { + *listenerp = NULL; + return; + } + + /* + * There is already a listener for this sockaddr. + * Update the access list and key information. + * + * First try to deal with the key situation. There are a few + * possibilities: + * (a) It had an explicit keylist and still has an explicit keylist. + * (b) It had an automagic key and now has an explicit keylist. + * (c) It had an explicit keylist and now needs an automagic key. + * (d) It has an automagic key and still needs the automagic key. + * + * (c) and (d) are the annoying ones. The caller needs to know + * that it should use the automagic configuration for key information + * in place of the named.conf configuration. + * + * XXXDCL There is one other hazard that has not been dealt with, + * the problem that if a key change is being caused by a control + * channel reload, then the response will be with the new key + * and not able to be decrypted by the client. + */ + if (control != NULL) + get_key_info(config, control, &global_keylist, + &control_keylist); + + if (control_keylist != NULL) { + INSIST(global_keylist != NULL); + + ISC_LIST_INIT(keys); + result = controlkeylist_fromcfg(control_keylist, + listener->mctx, &keys); + if (result == ISC_R_SUCCESS) { + free_controlkeylist(&listener->keys, listener->mctx); + listener->keys = keys; + register_keys(control, global_keylist, &listener->keys, + listener->mctx, socktext); + } + } else { + free_controlkeylist(&listener->keys, listener->mctx); + result = get_rndckey(listener->mctx, &listener->keys); + } + + if (result != ISC_R_SUCCESS && global_keylist != NULL) { + /* + * This message might be a little misleading since the + * "new keys" might in fact be identical to the old ones, + * but tracking whether they are identical just for the + * sake of avoiding this message would be too much trouble. + */ + if (control != NULL) + cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, + "couldn't install new keys for " + "command channel %s: %s", + socktext, isc_result_totext(result)); + else + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, + "couldn't install new keys for " + "command channel %s: %s", + socktext, isc_result_totext(result)); + } + + /* + * Now, keep the old access list unless a new one can be made. + */ + if (control != NULL && type == isc_sockettype_tcp) { + allow = cfg_tuple_get(control, "allow"); + result = cfg_acl_fromconfig(allow, config, ns_g_lctx, + aclconfctx, listener->mctx, + &new_acl); + } else { + result = dns_acl_any(listener->mctx, &new_acl); + } + + if (result == ISC_R_SUCCESS) { + dns_acl_detach(&listener->acl); + dns_acl_attach(new_acl, &listener->acl); + dns_acl_detach(&new_acl); + /* XXXDCL say the old acl is still used? */ + } else if (control != NULL) + cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, + "couldn't install new acl for " + "command channel %s: %s", + socktext, isc_result_totext(result)); + else + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, + "couldn't install new acl for " + "command channel %s: %s", + socktext, isc_result_totext(result)); + + if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) { + isc_uint32_t perm, owner, group; + perm = cfg_obj_asuint32(cfg_tuple_get(control, "perm")); + owner = cfg_obj_asuint32(cfg_tuple_get(control, "owner")); + group = cfg_obj_asuint32(cfg_tuple_get(control, "group")); + result = ISC_R_SUCCESS; + if (listener->perm != perm || listener->owner != owner || + listener->group != group) + result = isc_socket_permunix(&listener->address, perm, + owner, group); + if (result == ISC_R_SUCCESS) { + listener->perm = perm; + listener->owner = owner; + listener->group = group; + } else if (control != NULL) + cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, + "couldn't update ownership/permission for " + "command channel %s", socktext); + } + + *listenerp = listener; +} + +static void +add_listener(ns_controls_t *cp, controllistener_t **listenerp, + const cfg_obj_t *control, const cfg_obj_t *config, + isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx, + const char *socktext, isc_sockettype_t type) +{ + isc_mem_t *mctx = cp->server->mctx; + controllistener_t *listener; + const cfg_obj_t *allow; + const cfg_obj_t *global_keylist = NULL; + const cfg_obj_t *control_keylist = NULL; + dns_acl_t *new_acl = NULL; + isc_result_t result = ISC_R_SUCCESS; + + listener = isc_mem_get(mctx, sizeof(*listener)); + if (listener == NULL) + result = ISC_R_NOMEMORY; + + if (result == ISC_R_SUCCESS) { + listener->controls = cp; + listener->mctx = mctx; + listener->task = cp->server->task; + listener->address = *addr; + listener->sock = NULL; + listener->listening = ISC_FALSE; + listener->exiting = ISC_FALSE; + listener->acl = NULL; + listener->type = type; + listener->perm = 0; + listener->owner = 0; + listener->group = 0; + ISC_LINK_INIT(listener, link); + ISC_LIST_INIT(listener->keys); + ISC_LIST_INIT(listener->connections); + + /* + * Make the acl. + */ + if (control != NULL && type == isc_sockettype_tcp) { + allow = cfg_tuple_get(control, "allow"); + result = cfg_acl_fromconfig(allow, config, ns_g_lctx, + aclconfctx, mctx, &new_acl); + } else { + result = dns_acl_any(mctx, &new_acl); + } + } + + if (result == ISC_R_SUCCESS) { + dns_acl_attach(new_acl, &listener->acl); + dns_acl_detach(&new_acl); + + if (config != NULL) + get_key_info(config, control, &global_keylist, + &control_keylist); + + if (control_keylist != NULL) { + result = controlkeylist_fromcfg(control_keylist, + listener->mctx, + &listener->keys); + if (result == ISC_R_SUCCESS) + register_keys(control, global_keylist, + &listener->keys, + listener->mctx, socktext); + } else + result = get_rndckey(mctx, &listener->keys); + + if (result != ISC_R_SUCCESS && control != NULL) + cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, + "couldn't install keys for " + "command channel %s: %s", + socktext, isc_result_totext(result)); + } + + if (result == ISC_R_SUCCESS) { + int pf = isc_sockaddr_pf(&listener->address); + if ((pf == AF_INET && isc_net_probeipv4() != ISC_R_SUCCESS) || +#ifdef ISC_PLATFORM_HAVESYSUNH + (pf == AF_UNIX && isc_net_probeunix() != ISC_R_SUCCESS) || +#endif + (pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS)) + result = ISC_R_FAMILYNOSUPPORT; + } + + if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) + isc_socket_cleanunix(&listener->address, ISC_FALSE); + + if (result == ISC_R_SUCCESS) + result = isc_socket_create(ns_g_socketmgr, + isc_sockaddr_pf(&listener->address), + type, &listener->sock); + + if (result == ISC_R_SUCCESS) + result = isc_socket_bind(listener->sock, + &listener->address); + + if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) { + listener->perm = cfg_obj_asuint32(cfg_tuple_get(control, + "perm")); + listener->owner = cfg_obj_asuint32(cfg_tuple_get(control, + "owner")); + listener->group = cfg_obj_asuint32(cfg_tuple_get(control, + "group")); + result = isc_socket_permunix(&listener->address, listener->perm, + listener->owner, listener->group); + } + if (result == ISC_R_SUCCESS) + result = control_listen(listener); + + if (result == ISC_R_SUCCESS) + result = control_accept(listener); + + if (result == ISC_R_SUCCESS) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, + "command channel listening on %s", socktext); + *listenerp = listener; + + } else { + if (listener != NULL) { + listener->exiting = ISC_TRUE; + free_listener(listener); + } + + if (control != NULL) + cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, + "couldn't add command channel %s: %s", + socktext, isc_result_totext(result)); + else + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, + "couldn't add command channel %s: %s", + socktext, isc_result_totext(result)); + + *listenerp = NULL; + } + + /* XXXDCL return error results? fail hard? */ +} + +isc_result_t +ns_controls_configure(ns_controls_t *cp, const cfg_obj_t *config, + cfg_aclconfctx_t *aclconfctx) +{ + controllistener_t *listener; + controllistenerlist_t new_listeners; + const cfg_obj_t *controlslist = NULL; + const cfg_listelt_t *element, *element2; + char socktext[ISC_SOCKADDR_FORMATSIZE]; + + ISC_LIST_INIT(new_listeners); + + /* + * Get the list of named.conf 'controls' statements. + */ + (void)cfg_map_get(config, "controls", &controlslist); + + /* + * Run through the new control channel list, noting sockets that + * are already being listened on and moving them to the new list. + * + * Identifying duplicate addr/port combinations is left to either + * the underlying config code, or to the bind attempt getting an + * address-in-use error. + */ + if (controlslist != NULL) { + for (element = cfg_list_first(controlslist); + element != NULL; + element = cfg_list_next(element)) { + const cfg_obj_t *controls; + const cfg_obj_t *inetcontrols = NULL; + + controls = cfg_listelt_value(element); + (void)cfg_map_get(controls, "inet", &inetcontrols); + if (inetcontrols == NULL) + continue; + + for (element2 = cfg_list_first(inetcontrols); + element2 != NULL; + element2 = cfg_list_next(element2)) { + const cfg_obj_t *control; + const cfg_obj_t *obj; + isc_sockaddr_t addr; + + /* + * The parser handles BIND 8 configuration file + * syntax, so it allows unix phrases as well + * inet phrases with no keys{} clause. + */ + control = cfg_listelt_value(element2); + + obj = cfg_tuple_get(control, "address"); + addr = *cfg_obj_assockaddr(obj); + if (isc_sockaddr_getport(&addr) == 0) + isc_sockaddr_setport(&addr, + NS_CONTROL_PORT); + + isc_sockaddr_format(&addr, socktext, + sizeof(socktext)); + + isc_log_write(ns_g_lctx, + NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_CONTROL, + ISC_LOG_DEBUG(9), + "processing control channel %s", + socktext); + + update_listener(cp, &listener, control, config, + &addr, aclconfctx, socktext, + isc_sockettype_tcp); + + if (listener != NULL) + /* + * Remove the listener from the old + * list, so it won't be shut down. + */ + ISC_LIST_UNLINK(cp->listeners, + listener, link); + else + /* + * This is a new listener. + */ + add_listener(cp, &listener, control, + config, &addr, aclconfctx, + socktext, + isc_sockettype_tcp); + + if (listener != NULL) + ISC_LIST_APPEND(new_listeners, + listener, link); + } + } + for (element = cfg_list_first(controlslist); + element != NULL; + element = cfg_list_next(element)) { + const cfg_obj_t *controls; + const cfg_obj_t *unixcontrols = NULL; + + controls = cfg_listelt_value(element); + (void)cfg_map_get(controls, "unix", &unixcontrols); + if (unixcontrols == NULL) + continue; + + for (element2 = cfg_list_first(unixcontrols); + element2 != NULL; + element2 = cfg_list_next(element2)) { + const cfg_obj_t *control; + const cfg_obj_t *path; + isc_sockaddr_t addr; + isc_result_t result; + + /* + * The parser handles BIND 8 configuration file + * syntax, so it allows unix phrases as well + * inet phrases with no keys{} clause. + */ + control = cfg_listelt_value(element2); + + path = cfg_tuple_get(control, "path"); + result = isc_sockaddr_frompath(&addr, + cfg_obj_asstring(path)); + if (result != ISC_R_SUCCESS) { + isc_log_write(ns_g_lctx, + NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_CONTROL, + ISC_LOG_DEBUG(9), + "control channel '%s': %s", + cfg_obj_asstring(path), + isc_result_totext(result)); + continue; + } + + isc_log_write(ns_g_lctx, + NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_CONTROL, + ISC_LOG_DEBUG(9), + "processing control channel '%s'", + cfg_obj_asstring(path)); + + update_listener(cp, &listener, control, config, + &addr, aclconfctx, + cfg_obj_asstring(path), + isc_sockettype_unix); + + if (listener != NULL) + /* + * Remove the listener from the old + * list, so it won't be shut down. + */ + ISC_LIST_UNLINK(cp->listeners, + listener, link); + else + /* + * This is a new listener. + */ + add_listener(cp, &listener, control, + config, &addr, aclconfctx, + cfg_obj_asstring(path), + isc_sockettype_unix); + + if (listener != NULL) + ISC_LIST_APPEND(new_listeners, + listener, link); + } + } + } else { + int i; + + for (i = 0; i < 2; i++) { + isc_sockaddr_t addr; + + if (i == 0) { + struct in_addr localhost; + + if (isc_net_probeipv4() != ISC_R_SUCCESS) + continue; + localhost.s_addr = htonl(INADDR_LOOPBACK); + isc_sockaddr_fromin(&addr, &localhost, 0); + } else { + if (isc_net_probeipv6() != ISC_R_SUCCESS) + continue; + isc_sockaddr_fromin6(&addr, + &in6addr_loopback, 0); + } + isc_sockaddr_setport(&addr, NS_CONTROL_PORT); + + isc_sockaddr_format(&addr, socktext, sizeof(socktext)); + + update_listener(cp, &listener, NULL, NULL, + &addr, NULL, socktext, + isc_sockettype_tcp); + + if (listener != NULL) + /* + * Remove the listener from the old + * list, so it won't be shut down. + */ + ISC_LIST_UNLINK(cp->listeners, + listener, link); + else + /* + * This is a new listener. + */ + add_listener(cp, &listener, NULL, NULL, + &addr, NULL, socktext, + isc_sockettype_tcp); + + if (listener != NULL) + ISC_LIST_APPEND(new_listeners, + listener, link); + } + } + + /* + * ns_control_shutdown() will stop whatever is on the global + * listeners list, which currently only has whatever sockaddrs + * were in the previous configuration (if any) that do not + * remain in the current configuration. + */ + controls_shutdown(cp); + + /* + * Put all of the valid listeners on the listeners list. + * Anything already on listeners in the process of shutting + * down will be taken care of by listen_done(). + */ + ISC_LIST_APPENDLIST(cp->listeners, new_listeners, link); + return (ISC_R_SUCCESS); +} + +isc_result_t +ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp) { + isc_mem_t *mctx = server->mctx; + isc_result_t result; + ns_controls_t *controls = isc_mem_get(mctx, sizeof(*controls)); + + if (controls == NULL) + return (ISC_R_NOMEMORY); + controls->server = server; + ISC_LIST_INIT(controls->listeners); + controls->shuttingdown = ISC_FALSE; + controls->symtab = NULL; + result = isccc_cc_createsymtab(&controls->symtab); + if (result != ISC_R_SUCCESS) { + isc_mem_put(server->mctx, controls, sizeof(*controls)); + return (result); + } + *ctrlsp = controls; + return (ISC_R_SUCCESS); +} + +void +ns_controls_destroy(ns_controls_t **ctrlsp) { + ns_controls_t *controls = *ctrlsp; + + REQUIRE(ISC_LIST_EMPTY(controls->listeners)); + + isccc_symtab_destroy(&controls->symtab); + isc_mem_put(controls->server->mctx, controls, sizeof(*controls)); + *ctrlsp = NULL; +} diff --git a/bin/named/include/named/builtin.h b/bin/named/include/named/builtin.h new file mode 100644 index 0000000..37a3e76 --- /dev/null +++ b/bin/named/include/named/builtin.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: builtin.h,v 1.2.18.2 2005/04/29 00:15:34 marka Exp $ */ + +#ifndef NAMED_BUILTIN_H +#define NAMED_BUILTIN_H 1 + +/*! \file */ + +#include + +isc_result_t ns_builtin_init(void); + +void ns_builtin_deinit(void); + +#endif /* NAMED_BUILTIN_H */ diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h new file mode 100644 index 0000000..0cf7985 --- /dev/null +++ b/bin/named/include/named/client.h @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: client.h,v 1.69.18.9 2006/06/06 00:11:41 marka Exp $ */ + +#ifndef NAMED_CLIENT_H +#define NAMED_CLIENT_H 1 + +/***** + ***** Module Info + *****/ + +/*! \file + * \brief + * This module defines two objects, ns_client_t and ns_clientmgr_t. + * + * An ns_client_t object handles incoming DNS requests from clients + * on a given network interface. + * + * Each ns_client_t object can handle only one TCP connection or UDP + * request at a time. Therefore, several ns_client_t objects are + * typically created to serve each network interface, e.g., one + * for handling TCP requests and a few (one per CPU) for handling + * UDP requests. + * + * Incoming requests are classified as queries, zone transfer + * requests, update requests, notify requests, etc, and handed off + * to the appropriate request handler. When the request has been + * fully handled (which can be much later), the ns_client_t must be + * notified of this by calling one of the following functions + * exactly once in the context of its task: + * \code + * ns_client_send() (sending a non-error response) + * ns_client_sendraw() (sending a raw response) + * ns_client_error() (sending an error response) + * ns_client_next() (sending no response) + *\endcode + * This will release any resources used by the request and + * and allow the ns_client_t to listen for the next request. + * + * A ns_clientmgr_t manages a number of ns_client_t objects. + * New ns_client_t objects are created by calling + * ns_clientmgr_createclients(). They are destroyed by + * destroying their manager. + */ + +/*** + *** Imports + ***/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +/*** + *** Types + ***/ + +typedef ISC_LIST(ns_client_t) client_list_t; + +/*% nameserver client structure */ +struct ns_client { + unsigned int magic; + isc_mem_t * mctx; + ns_clientmgr_t * manager; + int state; + int newstate; + int naccepts; + int nreads; + int nsends; + int nrecvs; + int nupdates; + int nctls; + int references; + unsigned int attributes; + isc_task_t * task; + dns_view_t * view; + dns_dispatch_t * dispatch; + isc_socket_t * udpsocket; + isc_socket_t * tcplistener; + isc_socket_t * tcpsocket; + unsigned char * tcpbuf; + dns_tcpmsg_t tcpmsg; + isc_boolean_t tcpmsg_valid; + isc_timer_t * timer; + isc_boolean_t timerset; + dns_message_t * message; + isc_socketevent_t * sendevent; + isc_socketevent_t * recvevent; + unsigned char * recvbuf; + dns_rdataset_t * opt; + isc_uint16_t udpsize; + isc_uint16_t extflags; + isc_int16_t ednsversion; /* -1 noedns */ + void (*next)(ns_client_t *); + void (*shutdown)(void *arg, isc_result_t result); + void *shutdown_arg; + ns_query_t query; + isc_stdtime_t requesttime; + isc_stdtime_t now; + dns_name_t signername; /*%< [T]SIG key name */ + dns_name_t * signer; /*%< NULL if not valid sig */ + isc_boolean_t mortal; /*%< Die after handling request */ + isc_quota_t *tcpquota; + isc_quota_t *recursionquota; + ns_interface_t *interface; + isc_sockaddr_t peeraddr; + isc_boolean_t peeraddr_valid; + struct in6_pktinfo pktinfo; + isc_event_t ctlevent; + /*% + * Information about recent FORMERR response(s), for + * FORMERR loop avoidance. This is separate for each + * client object rather than global only to avoid + * the need for locking. + */ + struct { + isc_sockaddr_t addr; + isc_stdtime_t time; + dns_messageid_t id; + } formerrcache; + ISC_LINK(ns_client_t) link; + /*% + * The list 'link' is part of, or NULL if not on any list. + */ + client_list_t *list; +}; + +#define NS_CLIENT_MAGIC ISC_MAGIC('N','S','C','c') +#define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC) + +#define NS_CLIENTATTR_TCP 0x01 +#define NS_CLIENTATTR_RA 0x02 /*%< Client gets recusive service */ +#define NS_CLIENTATTR_PKTINFO 0x04 /*%< pktinfo is valid */ +#define NS_CLIENTATTR_MULTICAST 0x08 /*%< recv'd from multicast */ +#define NS_CLIENTATTR_WANTDNSSEC 0x10 /*%< include dnssec records */ + +extern unsigned int ns_client_requests; + +/*** + *** Functions + ***/ + +/*% + * Note! These ns_client_ routines MUST be called ONLY from the client's + * task in order to ensure synchronization. + */ + +void +ns_client_send(ns_client_t *client); +/*% + * Finish processing the current client request and + * send client->message as a response. + * \brief + * Note! These ns_client_ routines MUST be called ONLY from the client's + * task in order to ensure synchronization. + */ + +void +ns_client_sendraw(ns_client_t *client, dns_message_t *msg); +/*% + * Finish processing the current client request and + * send msg as a response using client->message->id for the id. + */ + +void +ns_client_error(ns_client_t *client, isc_result_t result); +/*% + * Finish processing the current client request and return + * an error response to the client. The error response + * will have an RCODE determined by 'result'. + */ + +void +ns_client_next(ns_client_t *client, isc_result_t result); +/*% + * Finish processing the current client request, + * return no response to the client. + */ + +isc_boolean_t +ns_client_shuttingdown(ns_client_t *client); +/*% + * Return ISC_TRUE iff the client is currently shutting down. + */ + +void +ns_client_attach(ns_client_t *source, ns_client_t **target); +/*% + * Attach '*targetp' to 'source'. + */ + +void +ns_client_detach(ns_client_t **clientp); +/*% + * Detach '*clientp' from its client. + */ + +isc_result_t +ns_client_replace(ns_client_t *client); +/*% + * Try to replace the current client with a new one, so that the + * current one can go off and do some lengthy work without + * leaving the dispatch/socket without service. + */ + +void +ns_client_settimeout(ns_client_t *client, unsigned int seconds); +/*% + * Set a timer in the client to go off in the specified amount of time. + */ + +isc_result_t +ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, + isc_timermgr_t *timermgr, ns_clientmgr_t **managerp); +/*% + * Create a client manager. + */ + +void +ns_clientmgr_destroy(ns_clientmgr_t **managerp); +/*% + * Destroy a client manager and all ns_client_t objects + * managed by it. + */ + +isc_result_t +ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, + ns_interface_t *ifp, isc_boolean_t tcp); +/*% + * Create up to 'n' clients listening on interface 'ifp'. + * If 'tcp' is ISC_TRUE, the clients will listen for TCP connections, + * otherwise for UDP requests. + */ + +isc_sockaddr_t * +ns_client_getsockaddr(ns_client_t *client); +/*% + * Get the socket address of the client whose request is + * currently being processed. + */ + +isc_result_t +ns_client_checkaclsilent(ns_client_t *client,dns_acl_t *acl, + isc_boolean_t default_allow); + +/*% + * Convenience function for client request ACL checking. + * + * Check the current client request against 'acl'. If 'acl' + * is NULL, allow the request iff 'default_allow' is ISC_TRUE. + * + * Notes: + *\li This is appropriate for checking allow-update, + * allow-query, allow-transfer, etc. It is not appropriate + * for checking the blackhole list because we treat positive + * matches as "allow" and negative matches as "deny"; in + * the case of the blackhole list this would be backwards. + * + * Requires: + *\li 'client' points to a valid client. + *\li 'acl' points to a valid ACL, or is NULL. + * + * Returns: + *\li ISC_R_SUCCESS if the request should be allowed + * \li ISC_R_REFUSED if the request should be denied + *\li No other return values are possible. + */ + +isc_result_t +ns_client_checkacl(ns_client_t *client, + const char *opname, dns_acl_t *acl, + isc_boolean_t default_allow, + int log_level); +/*% + * Like ns_client_checkacl, but also logs the outcome of the + * check at log level 'log_level' if denied, and at debug 3 + * if approved. Log messages will refer to the request as + * an 'opname' request. + * + * Requires: + *\li Those of ns_client_checkaclsilent(), and: + * + *\li 'opname' points to a null-terminated string. + */ + +void +ns_client_log(ns_client_t *client, isc_logcategory_t *category, + isc_logmodule_t *module, int level, + const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); + +void +ns_client_logv(ns_client_t *client, isc_logcategory_t *category, + isc_logmodule_t *module, int level, const char *fmt, va_list ap) ISC_FORMAT_PRINTF(5, 0); + +void +ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type, + dns_rdataclass_t rdclass, char *buf, size_t len); + +#define NS_CLIENT_ACLMSGSIZE(x) \ + (DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + \ + DNS_RDATACLASS_FORMATSIZE + sizeof(x) + sizeof("'/'")) + +void +ns_client_recursing(ns_client_t *client); +/*% + * Add client to end of th recursing list. + */ + +void +ns_client_killoldestquery(ns_client_t *client); +/*% + * Kill the oldest recursive query (recursing list head). + */ + +void +ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager); +/*% + * Dump the outstanding recursive queries to 'f'. + */ + +void +ns_client_qnamereplace(ns_client_t *client, dns_name_t *name); +/*% + * Replace the qname. + */ + +isc_boolean_t +ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey, + isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, + dns_rdataclass_t rdclass, void *arg); +/*% + * Isself callback. + */ + +#endif /* NAMED_CLIENT_H */ diff --git a/bin/named/include/named/config.h b/bin/named/include/named/config.h new file mode 100644 index 0000000..e8e6038 --- /dev/null +++ b/bin/named/include/named/config.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2001, 2002 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: config.h,v 1.6.18.6 2006/02/28 03:10:47 marka Exp $ */ + +#ifndef NAMED_CONFIG_H +#define NAMED_CONFIG_H 1 + +/*! \file */ + +#include + +#include +#include + +isc_result_t +ns_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf); + +isc_result_t +ns_config_get(const cfg_obj_t **maps, const char* name, const cfg_obj_t **obj); + +isc_result_t +ns_checknames_get(const cfg_obj_t **maps, const char* name, + const cfg_obj_t **obj); + +int +ns_config_listcount(const cfg_obj_t *list); + +isc_result_t +ns_config_getclass(const cfg_obj_t *classobj, dns_rdataclass_t defclass, + dns_rdataclass_t *classp); + +isc_result_t +ns_config_gettype(const cfg_obj_t *typeobj, dns_rdatatype_t deftype, + dns_rdatatype_t *typep); + +dns_zonetype_t +ns_config_getzonetype(const cfg_obj_t *zonetypeobj); + +isc_result_t +ns_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list, + in_port_t defport, isc_mem_t *mctx, + isc_sockaddr_t **addrsp, isc_uint32_t *countp); + +void +ns_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp, + isc_uint32_t count); + +isc_result_t +ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list, + isc_mem_t *mctx, isc_sockaddr_t **addrsp, + dns_name_t ***keys, isc_uint32_t *countp); + +void +ns_config_putipandkeylist(isc_mem_t *mctx, isc_sockaddr_t **addrsp, + dns_name_t ***keys, isc_uint32_t count); + +isc_result_t +ns_config_getport(const cfg_obj_t *config, in_port_t *portp); + +isc_result_t +ns_config_getkeyalgorithm(const char *str, dns_name_t **name, + isc_uint16_t *digestbits); + +#endif /* NAMED_CONFIG_H */ diff --git a/bin/named/include/named/control.h b/bin/named/include/named/control.h new file mode 100644 index 0000000..5b7e5f4 --- /dev/null +++ b/bin/named/include/named/control.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2001-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: control.h,v 1.14.18.8 2006/03/09 23:46:20 marka Exp $ */ + +#ifndef NAMED_CONTROL_H +#define NAMED_CONTROL_H 1 + +/*! \file + * \brief + * The name server command channel. + */ + +#include + +#include + +#include + +#define NS_CONTROL_PORT 953 + +#define NS_COMMAND_STOP "stop" +#define NS_COMMAND_HALT "halt" +#define NS_COMMAND_RELOAD "reload" +#define NS_COMMAND_RECONFIG "reconfig" +#define NS_COMMAND_REFRESH "refresh" +#define NS_COMMAND_RETRANSFER "retransfer" +#define NS_COMMAND_DUMPSTATS "stats" +#define NS_COMMAND_QUERYLOG "querylog" +#define NS_COMMAND_DUMPDB "dumpdb" +#define NS_COMMAND_TRACE "trace" +#define NS_COMMAND_NOTRACE "notrace" +#define NS_COMMAND_FLUSH "flush" +#define NS_COMMAND_FLUSHNAME "flushname" +#define NS_COMMAND_STATUS "status" +#define NS_COMMAND_FREEZE "freeze" +#define NS_COMMAND_UNFREEZE "unfreeze" +#define NS_COMMAND_THAW "thaw" +#define NS_COMMAND_TIMERPOKE "timerpoke" +#define NS_COMMAND_RECURSING "recursing" +#define NS_COMMAND_NULL "null" +#define NS_COMMAND_NOTIFY "notify" +#define NS_COMMAND_VALIDATION "validation" + +isc_result_t +ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp); +/*%< + * Create an initial, empty set of command channels for 'server'. + */ + +void +ns_controls_destroy(ns_controls_t **ctrlsp); +/*%< + * Destroy a set of command channels. + * + * Requires: + * Shutdown of the channels has completed. + */ + +isc_result_t +ns_controls_configure(ns_controls_t *controls, const cfg_obj_t *config, + cfg_aclconfctx_t *aclconfctx); +/*%< + * Configure zero or more command channels into 'controls' + * as defined in the configuration parse tree 'config'. + * The channels will evaluate ACLs in the context of + * 'aclconfctx'. + */ + +void +ns_controls_shutdown(ns_controls_t *controls); +/*%< + * Initiate shutdown of all the command channels in 'controls'. + */ + +isc_result_t +ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text); + +#endif /* NAMED_CONTROL_H */ diff --git a/bin/named/include/named/globals.h b/bin/named/include/named/globals.h new file mode 100644 index 0000000..11f3989 --- /dev/null +++ b/bin/named/include/named/globals.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: globals.h,v 1.64.18.4 2006/03/02 00:37:21 marka Exp $ */ + +#ifndef NAMED_GLOBALS_H +#define NAMED_GLOBALS_H 1 + +/*! \file */ + +#include +#include +#include + +#include + +#include + +#include + +#undef EXTERN +#undef INIT +#ifdef NS_MAIN +#define EXTERN +#define INIT(v) = (v) +#else +#define EXTERN extern +#define INIT(v) +#endif + +EXTERN isc_mem_t * ns_g_mctx INIT(NULL); +EXTERN unsigned int ns_g_cpus INIT(0); +EXTERN isc_taskmgr_t * ns_g_taskmgr INIT(NULL); +EXTERN dns_dispatchmgr_t * ns_g_dispatchmgr INIT(NULL); +EXTERN isc_entropy_t * ns_g_entropy INIT(NULL); +EXTERN isc_entropy_t * ns_g_fallbackentropy INIT(NULL); + +/* + * XXXRTH We're going to want multiple timer managers eventually. One + * for really short timers, another for client timers, and one + * for zone timers. + */ +EXTERN isc_timermgr_t * ns_g_timermgr INIT(NULL); +EXTERN isc_socketmgr_t * ns_g_socketmgr INIT(NULL); +EXTERN cfg_parser_t * ns_g_parser INIT(NULL); +EXTERN const char * ns_g_version INIT(VERSION); +EXTERN in_port_t ns_g_port INIT(0); +EXTERN in_port_t lwresd_g_listenport INIT(0); + +EXTERN ns_server_t * ns_g_server INIT(NULL); + +EXTERN isc_boolean_t ns_g_lwresdonly INIT(ISC_FALSE); + +/* + * Logging. + */ +EXTERN isc_log_t * ns_g_lctx INIT(NULL); +EXTERN isc_logcategory_t * ns_g_categories INIT(NULL); +EXTERN isc_logmodule_t * ns_g_modules INIT(NULL); +EXTERN unsigned int ns_g_debuglevel INIT(0); + +/* + * Current configuration information. + */ +EXTERN cfg_obj_t * ns_g_config INIT(NULL); +EXTERN const cfg_obj_t * ns_g_defaults INIT(NULL); +EXTERN const char * ns_g_conffile INIT(NS_SYSCONFDIR + "/named.conf"); +EXTERN const char * ns_g_keyfile INIT(NS_SYSCONFDIR + "/rndc.key"); +EXTERN const char * lwresd_g_conffile INIT(NS_SYSCONFDIR + "/lwresd.conf"); +EXTERN const char * lwresd_g_resolvconffile INIT("/etc" + "/resolv.conf"); +EXTERN isc_boolean_t ns_g_conffileset INIT(ISC_FALSE); +EXTERN isc_boolean_t lwresd_g_useresolvconf INIT(ISC_FALSE); +EXTERN isc_uint16_t ns_g_udpsize INIT(4096); + +/* + * Initial resource limits. + */ +EXTERN isc_resourcevalue_t ns_g_initstacksize INIT(0); +EXTERN isc_resourcevalue_t ns_g_initdatasize INIT(0); +EXTERN isc_resourcevalue_t ns_g_initcoresize INIT(0); +EXTERN isc_resourcevalue_t ns_g_initopenfiles INIT(0); + +/* + * Misc. + */ +EXTERN isc_boolean_t ns_g_coreok INIT(ISC_TRUE); +EXTERN const char * ns_g_chrootdir INIT(NULL); +EXTERN isc_boolean_t ns_g_foreground INIT(ISC_FALSE); +EXTERN isc_boolean_t ns_g_logstderr INIT(ISC_FALSE); + +EXTERN const char * ns_g_defaultpidfile INIT(NS_LOCALSTATEDIR + "/run/named.pid"); +EXTERN const char * lwresd_g_defaultpidfile INIT(NS_LOCALSTATEDIR + "/run/lwresd.pid"); +EXTERN const char * ns_g_username INIT(NULL); + +EXTERN int ns_g_listen INIT(3); + +#undef EXTERN +#undef INIT + +#endif /* NAMED_GLOBALS_H */ diff --git a/bin/named/include/named/interfacemgr.h b/bin/named/include/named/interfacemgr.h new file mode 100644 index 0000000..42279ff --- /dev/null +++ b/bin/named/include/named/interfacemgr.h @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2002 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: interfacemgr.h,v 1.26.18.4 2005/04/27 05:00:35 sra Exp $ */ + +#ifndef NAMED_INTERFACEMGR_H +#define NAMED_INTERFACEMGR_H 1 + +/***** + ***** Module Info + *****/ + +/*! \file + * \brief + * The interface manager monitors the operating system's list + * of network interfaces, creating and destroying listeners + * as needed. + * + * Reliability: + *\li No impact expected. + * + * Resources: + * + * Security: + * \li The server will only be able to bind to the DNS port on + * newly discovered interfaces if it is running as root. + * + * Standards: + *\li The API for scanning varies greatly among operating systems. + * This module attempts to hide the differences. + */ + +/*** + *** Imports + ***/ + +#include +#include +#include + +#include + +#include +#include + +/*** + *** Types + ***/ + +#define IFACE_MAGIC ISC_MAGIC('I',':','-',')') +#define NS_INTERFACE_VALID(t) ISC_MAGIC_VALID(t, IFACE_MAGIC) + +#define NS_INTERFACEFLAG_ANYADDR 0x01U /*%< bound to "any" address */ + +/*% The nameserver interface structure */ +struct ns_interface { + unsigned int magic; /*%< Magic number. */ + ns_interfacemgr_t * mgr; /*%< Interface manager. */ + isc_mutex_t lock; + int references; /*%< Locked */ + unsigned int generation; /*%< Generation number. */ + isc_sockaddr_t addr; /*%< Address and port. */ + unsigned int flags; /*%< Interface characteristics */ + char name[32]; /*%< Null terminated. */ + dns_dispatch_t * udpdispatch; /*%< UDP dispatcher. */ + isc_socket_t * tcpsocket; /*%< TCP socket. */ + int ntcptarget; /*%< Desired number of concurrent + TCP accepts */ + int ntcpcurrent; /*%< Current ditto, locked */ + ns_clientmgr_t * clientmgr; /*%< Client manager. */ + ISC_LINK(ns_interface_t) link; +}; + +/*** + *** Functions + ***/ + +isc_result_t +ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, + isc_socketmgr_t *socketmgr, + dns_dispatchmgr_t *dispatchmgr, + ns_interfacemgr_t **mgrp); +/*% + * Create a new interface manager. + * + * Initially, the new manager will not listen on any interfaces. + * Call ns_interfacemgr_setlistenon() and/or ns_interfacemgr_setlistenon6() + * to set nonempty listen-on lists. + */ + +void +ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target); + +void +ns_interfacemgr_detach(ns_interfacemgr_t **targetp); + +void +ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr); + +void +ns_interfacemgr_scan(ns_interfacemgr_t *mgr, isc_boolean_t verbose); +/*% + * Scan the operatings system's list of network interfaces + * and create listeners when new interfaces are discovered. + * Shut down the sockets for interfaces that go away. + * + * This should be called once on server startup and then + * periodically according to the 'interface-interval' option + * in named.conf. + */ + +void +ns_interfacemgr_adjust(ns_interfacemgr_t *mgr, ns_listenlist_t *list, + isc_boolean_t verbose); +/*% + * Similar to ns_interfacemgr_scan(), but this function also tries to see the + * need for an explicit listen-on when a list element in 'list' is going to + * override an already-listening a wildcard interface. + * + * This function does not update localhost and localnets ACLs. + * + * This should be called once on server startup, after configuring views and + * zones. + */ + +void +ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value); +/*% + * Set the IPv4 "listen-on" list of 'mgr' to 'value'. + * The previous IPv4 listen-on list is freed. + */ + +void +ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value); +/*% + * Set the IPv6 "listen-on" list of 'mgr' to 'value'. + * The previous IPv6 listen-on list is freed. + */ + +dns_aclenv_t * +ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr); + +void +ns_interface_attach(ns_interface_t *source, ns_interface_t **target); + +void +ns_interface_detach(ns_interface_t **targetp); + +void +ns_interface_shutdown(ns_interface_t *ifp); +/*% + * Stop listening for queries on interface 'ifp'. + * May safely be called multiple times. + */ + +void +ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr); + +isc_boolean_t +ns_interfacemgr_listeningon(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr); + +#endif /* NAMED_INTERFACEMGR_H */ diff --git a/bin/named/include/named/listenlist.h b/bin/named/include/named/listenlist.h new file mode 100644 index 0000000..cdca026 --- /dev/null +++ b/bin/named/include/named/listenlist.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: listenlist.h,v 1.11.18.2 2005/04/29 00:15:34 marka Exp $ */ + +#ifndef NAMED_LISTENLIST_H +#define NAMED_LISTENLIST_H 1 + +/***** + ***** Module Info + *****/ + +/*! \file + * \brief + * "Listen lists", as in the "listen-on" configuration statement. + */ + +/*** + *** Imports + ***/ +#include + +#include + +/*** + *** Types + ***/ + +typedef struct ns_listenelt ns_listenelt_t; +typedef struct ns_listenlist ns_listenlist_t; + +struct ns_listenelt { + isc_mem_t * mctx; + in_port_t port; + dns_acl_t * acl; + ISC_LINK(ns_listenelt_t) link; +}; + +struct ns_listenlist { + isc_mem_t * mctx; + int refcount; + ISC_LIST(ns_listenelt_t) elts; +}; + +/*** + *** Functions + ***/ + +isc_result_t +ns_listenelt_create(isc_mem_t *mctx, in_port_t port, + dns_acl_t *acl, ns_listenelt_t **target); +/*% + * Create a listen-on list element. + */ + +void +ns_listenelt_destroy(ns_listenelt_t *elt); +/*% + * Destroy a listen-on list element. + */ + +isc_result_t +ns_listenlist_create(isc_mem_t *mctx, ns_listenlist_t **target); +/*% + * Create a new, empty listen-on list. + */ + +void +ns_listenlist_attach(ns_listenlist_t *source, ns_listenlist_t **target); +/*% + * Attach '*target' to '*source'. + */ + +void +ns_listenlist_detach(ns_listenlist_t **listp); +/*% + * Detach 'listp'. + */ + +isc_result_t +ns_listenlist_default(isc_mem_t *mctx, in_port_t port, + isc_boolean_t enabled, ns_listenlist_t **target); +/*% + * Create a listen-on list with default contents, matching + * all addresses with port 'port' (if 'enabled' is ISC_TRUE), + * or no addresses (if 'enabled' is ISC_FALSE). + */ + +#endif /* NAMED_LISTENLIST_H */ + + diff --git a/bin/named/include/named/log.h b/bin/named/include/named/log.h new file mode 100644 index 0000000..6d6e648 --- /dev/null +++ b/bin/named/include/named/log.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2002 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: log.h,v 1.21.18.2 2005/04/29 00:15:35 marka Exp $ */ + +#ifndef NAMED_LOG_H +#define NAMED_LOG_H 1 + +/*! \file */ + +#include +#include + +#include + +#include /* Required for ns_g_(categories|modules). */ + +/* Unused slot 0. */ +#define NS_LOGCATEGORY_CLIENT (&ns_g_categories[1]) +#define NS_LOGCATEGORY_NETWORK (&ns_g_categories[2]) +#define NS_LOGCATEGORY_UPDATE (&ns_g_categories[3]) +#define NS_LOGCATEGORY_QUERIES (&ns_g_categories[4]) +#define NS_LOGCATEGORY_UNMATCHED (&ns_g_categories[5]) +#define NS_LOGCATEGORY_UPDATE_SECURITY (&ns_g_categories[6]) + +/* + * Backwards compatibility. + */ +#define NS_LOGCATEGORY_GENERAL ISC_LOGCATEGORY_GENERAL + +#define NS_LOGMODULE_MAIN (&ns_g_modules[0]) +#define NS_LOGMODULE_CLIENT (&ns_g_modules[1]) +#define NS_LOGMODULE_SERVER (&ns_g_modules[2]) +#define NS_LOGMODULE_QUERY (&ns_g_modules[3]) +#define NS_LOGMODULE_INTERFACEMGR (&ns_g_modules[4]) +#define NS_LOGMODULE_UPDATE (&ns_g_modules[5]) +#define NS_LOGMODULE_XFER_IN (&ns_g_modules[6]) +#define NS_LOGMODULE_XFER_OUT (&ns_g_modules[7]) +#define NS_LOGMODULE_NOTIFY (&ns_g_modules[8]) +#define NS_LOGMODULE_CONTROL (&ns_g_modules[9]) +#define NS_LOGMODULE_LWRESD (&ns_g_modules[10]) + +isc_result_t +ns_log_init(isc_boolean_t safe); +/*% + * Initialize the logging system and set up an initial default + * logging default configuration that will be used until the + * config file has been read. + * + * If 'safe' is true, use a default configuration that refrains + * from opening files. This is to avoid creating log files + * as root. + */ + +isc_result_t +ns_log_setdefaultchannels(isc_logconfig_t *lcfg); +/*% + * Set up logging channels according to the named defaults, which + * may differ from the logging library defaults. Currently, + * this just means setting up default_debug. + */ + +isc_result_t +ns_log_setsafechannels(isc_logconfig_t *lcfg); +/*% + * Like ns_log_setdefaultchannels(), but omits any logging to files. + */ + +isc_result_t +ns_log_setdefaultcategory(isc_logconfig_t *lcfg); +/*% + * Set up "category default" to go to the right places. + */ + +isc_result_t +ns_log_setunmatchedcategory(isc_logconfig_t *lcfg); +/*% + * Set up "category unmatched" to go to the right places. + */ + +void +ns_log_shutdown(void); + +#endif /* NAMED_LOG_H */ diff --git a/bin/named/include/named/logconf.h b/bin/named/include/named/logconf.h new file mode 100644 index 0000000..79df5c6 --- /dev/null +++ b/bin/named/include/named/logconf.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: logconf.h,v 1.11.18.4 2006/03/02 00:37:21 marka Exp $ */ + +#ifndef NAMED_LOGCONF_H +#define NAMED_LOGCONF_H 1 + +/*! \file */ + +#include + +isc_result_t +ns_log_configure(isc_logconfig_t *logconf, const cfg_obj_t *logstmt); +/*%< + * Set up the logging configuration in '*logconf' according to + * the named.conf data in 'logstmt'. + */ + +#endif /* NAMED_LOGCONF_H */ diff --git a/bin/named/include/named/lwaddr.h b/bin/named/include/named/lwaddr.h new file mode 100644 index 0000000..552d1d4 --- /dev/null +++ b/bin/named/include/named/lwaddr.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: lwaddr.h,v 1.4.18.2 2005/04/29 00:15:35 marka Exp $ */ + +/*! \file */ + +#include +#include + +isc_result_t +lwaddr_netaddr_fromlwresaddr(isc_netaddr_t *na, lwres_addr_t *la); + +isc_result_t +lwaddr_sockaddr_fromlwresaddr(isc_sockaddr_t *sa, lwres_addr_t *la, + in_port_t port); + +isc_result_t +lwaddr_lwresaddr_fromnetaddr(lwres_addr_t *la, isc_netaddr_t *na); + +isc_result_t +lwaddr_lwresaddr_fromsockaddr(lwres_addr_t *la, isc_sockaddr_t *sa); diff --git a/bin/named/include/named/lwdclient.h b/bin/named/include/named/lwdclient.h new file mode 100644 index 0000000..591b86c --- /dev/null +++ b/bin/named/include/named/lwdclient.h @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: lwdclient.h,v 1.14.18.2 2005/04/29 00:15:36 marka Exp $ */ + +#ifndef NAMED_LWDCLIENT_H +#define NAMED_LWDCLIENT_H 1 + +/*! \file */ + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#define LWRD_EVENTCLASS ISC_EVENTCLASS(4242) + +#define LWRD_SHUTDOWN (LWRD_EVENTCLASS + 0x0001) + +/*% Lighweight Resolver Daemon Client */ +struct ns_lwdclient { + isc_sockaddr_t address; /*%< where to reply */ + struct in6_pktinfo pktinfo; + isc_boolean_t pktinfo_valid; + ns_lwdclientmgr_t *clientmgr; /*%< our parent */ + ISC_LINK(ns_lwdclient_t) link; + unsigned int state; + void *arg; /*%< packet processing state */ + + /* + * Received data info. + */ + unsigned char buffer[LWRES_RECVLENGTH]; /*%< receive buffer */ + isc_uint32_t recvlength; /*%< length recv'd */ + lwres_lwpacket_t pkt; + + /*% + * Send data state. If sendbuf != buffer (that is, the send buffer + * isn't our receive buffer) it will be freed to the lwres_context_t. + */ + unsigned char *sendbuf; + isc_uint32_t sendlength; + isc_buffer_t recv_buffer; + + /*% + * gabn (get address by name) state info. + */ + dns_adbfind_t *find; + dns_adbfind_t *v4find; + dns_adbfind_t *v6find; + unsigned int find_wanted; /*%< Addresses we want */ + dns_fixedname_t query_name; + dns_fixedname_t target_name; + ns_lwsearchctx_t searchctx; + lwres_gabnresponse_t gabn; + + /*% + * gnba (get name by address) state info. + */ + lwres_gnbaresponse_t gnba; + dns_byaddr_t *byaddr; + unsigned int options; + isc_netaddr_t na; + + /*% + * grbn (get rrset by name) state info. + * + * Note: this also uses target_name and searchctx. + */ + lwres_grbnresponse_t grbn; + dns_lookup_t *lookup; + dns_rdatatype_t rdtype; + + /*% + * Alias and address info. This is copied up to the gabn/gnba + * structures eventually. + * + * XXXMLG We can keep all of this in a client since we only service + * three packet types right now. If we started handling more, + * we'd need to use "arg" above and allocate/destroy things. + */ + char *aliases[LWRES_MAX_ALIASES]; + isc_uint16_t aliaslen[LWRES_MAX_ALIASES]; + lwres_addr_t addrs[LWRES_MAX_ADDRS]; +}; + +/*% + * Client states. + * + * _IDLE The client is not doing anything at all. + * + * _RECV The client is waiting for data after issuing a socket recv(). + * + * _RECVDONE Data has been received, and is being processed. + * + * _FINDWAIT An adb (or other) request was made that cannot be satisfied + * immediately. An event will wake the client up. + * + * _SEND All data for a response has completed, and a reply was + * sent via a socket send() call. + * + * Badly formatted state table: + * + * IDLE -> RECV when client has a recv() queued. + * + * RECV -> RECVDONE when recvdone event received. + * + * RECVDONE -> SEND if the data for a reply is at hand. + * RECVDONE -> FINDWAIT if more searching is needed, and events will + * eventually wake us up again. + * + * FINDWAIT -> SEND when enough data was received to reply. + * + * SEND -> IDLE when a senddone event was received. + * + * At any time -> IDLE on error. Sometimes this will be -> SEND + * instead, if enough data is on hand to reply with a meaningful + * error. + * + * Packets which are badly formatted may or may not get error returns. + */ +#define NS_LWDCLIENT_STATEIDLE 1 +#define NS_LWDCLIENT_STATERECV 2 +#define NS_LWDCLIENT_STATERECVDONE 3 +#define NS_LWDCLIENT_STATEFINDWAIT 4 +#define NS_LWDCLIENT_STATESEND 5 +#define NS_LWDCLIENT_STATESENDDONE 6 + +#define NS_LWDCLIENT_ISIDLE(c) \ + ((c)->state == NS_LWDCLIENT_STATEIDLE) +#define NS_LWDCLIENT_ISRECV(c) \ + ((c)->state == NS_LWDCLIENT_STATERECV) +#define NS_LWDCLIENT_ISRECVDONE(c) \ + ((c)->state == NS_LWDCLIENT_STATERECVDONE) +#define NS_LWDCLIENT_ISFINDWAIT(c) \ + ((c)->state == NS_LWDCLIENT_STATEFINDWAIT) +#define NS_LWDCLIENT_ISSEND(c) \ + ((c)->state == NS_LWDCLIENT_STATESEND) + +/*% + * Overall magic test that means we're not idle. + */ +#define NS_LWDCLIENT_ISRUNNING(c) (!NS_LWDCLIENT_ISIDLE(c)) + +#define NS_LWDCLIENT_SETIDLE(c) \ + ((c)->state = NS_LWDCLIENT_STATEIDLE) +#define NS_LWDCLIENT_SETRECV(c) \ + ((c)->state = NS_LWDCLIENT_STATERECV) +#define NS_LWDCLIENT_SETRECVDONE(c) \ + ((c)->state = NS_LWDCLIENT_STATERECVDONE) +#define NS_LWDCLIENT_SETFINDWAIT(c) \ + ((c)->state = NS_LWDCLIENT_STATEFINDWAIT) +#define NS_LWDCLIENT_SETSEND(c) \ + ((c)->state = NS_LWDCLIENT_STATESEND) +#define NS_LWDCLIENT_SETSENDDONE(c) \ + ((c)->state = NS_LWDCLIENT_STATESENDDONE) + +/*% lightweight daemon client manager */ +struct ns_lwdclientmgr { + ns_lwreslistener_t *listener; + isc_mem_t *mctx; + isc_socket_t *sock; /*%< socket to use */ + dns_view_t *view; + lwres_context_t *lwctx; /*%< lightweight proto context */ + isc_task_t *task; /*%< owning task */ + unsigned int flags; + ISC_LINK(ns_lwdclientmgr_t) link; + ISC_LIST(ns_lwdclient_t) idle; /*%< idle client slots */ + ISC_LIST(ns_lwdclient_t) running; /*%< running clients */ +}; + +#define NS_LWDCLIENTMGR_FLAGRECVPENDING 0x00000001 +#define NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN 0x00000002 + +isc_result_t +ns_lwdclientmgr_create(ns_lwreslistener_t *, unsigned int, isc_taskmgr_t *); + +void +ns_lwdclient_initialize(ns_lwdclient_t *, ns_lwdclientmgr_t *); + +isc_result_t +ns_lwdclient_startrecv(ns_lwdclientmgr_t *); + +void +ns_lwdclient_stateidle(ns_lwdclient_t *); + +void +ns_lwdclient_recv(isc_task_t *, isc_event_t *); + +void +ns_lwdclient_shutdown(isc_task_t *, isc_event_t *); + +void +ns_lwdclient_send(isc_task_t *, isc_event_t *); + +isc_result_t +ns_lwdclient_sendreply(ns_lwdclient_t *client, isc_region_t *r); + +/* + * Processing functions of various types. + */ +void ns_lwdclient_processgabn(ns_lwdclient_t *, lwres_buffer_t *); +void ns_lwdclient_processgnba(ns_lwdclient_t *, lwres_buffer_t *); +void ns_lwdclient_processgrbn(ns_lwdclient_t *, lwres_buffer_t *); +void ns_lwdclient_processnoop(ns_lwdclient_t *, lwres_buffer_t *); + +void ns_lwdclient_errorpktsend(ns_lwdclient_t *, isc_uint32_t); + +void ns_lwdclient_log(int level, const char *format, ...) + ISC_FORMAT_PRINTF(2, 3); + +#endif /* NAMED_LWDCLIENT_H */ diff --git a/bin/named/include/named/lwresd.h b/bin/named/include/named/lwresd.h new file mode 100644 index 0000000..ef93fcd --- /dev/null +++ b/bin/named/include/named/lwresd.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: lwresd.h,v 1.13.18.4 2006/03/02 00:37:21 marka Exp $ */ + +#ifndef NAMED_LWRESD_H +#define NAMED_LWRESD_H 1 + +/*! \file */ + +#include +#include + +#include + +#include + +struct ns_lwresd { + unsigned int magic; + + isc_mutex_t lock; + dns_view_t *view; + ns_lwsearchlist_t *search; + unsigned int ndots; + isc_mem_t *mctx; + isc_boolean_t shutting_down; + unsigned int refs; +}; + +struct ns_lwreslistener { + unsigned int magic; + + isc_mutex_t lock; + isc_mem_t *mctx; + isc_sockaddr_t address; + ns_lwresd_t *manager; + isc_socket_t *sock; + unsigned int refs; + ISC_LIST(ns_lwdclientmgr_t) cmgrs; + ISC_LINK(ns_lwreslistener_t) link; +}; + +/*% + * Configure lwresd. + */ +isc_result_t +ns_lwresd_configure(isc_mem_t *mctx, const cfg_obj_t *config); + +isc_result_t +ns_lwresd_parseeresolvconf(isc_mem_t *mctx, cfg_parser_t *pctx, + cfg_obj_t **configp); + +/*% + * Trigger shutdown. + */ +void +ns_lwresd_shutdown(void); + +/* + * Manager functions + */ +/*% create manager */ +isc_result_t +ns_lwdmanager_create(isc_mem_t *mctx, const cfg_obj_t *lwres, + ns_lwresd_t **lwresdp); + +/*% attach to manager */ +void +ns_lwdmanager_attach(ns_lwresd_t *source, ns_lwresd_t **targetp); + +/*% detach from manager */ +void +ns_lwdmanager_detach(ns_lwresd_t **lwresdp); + +/* + * Listener functions + */ +/*% attach to listener */ +void +ns_lwreslistener_attach(ns_lwreslistener_t *source, + ns_lwreslistener_t **targetp); + +/*% detach from lister */ +void +ns_lwreslistener_detach(ns_lwreslistener_t **listenerp); + +/*% link client manager */ +void +ns_lwreslistener_unlinkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm); + +/*% unlink client manager */ +void +ns_lwreslistener_linkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm); + + + + +/* + * INTERNAL FUNCTIONS. + */ +void * +ns__lwresd_memalloc(void *arg, size_t size); + +void +ns__lwresd_memfree(void *arg, void *mem, size_t size); + +#endif /* NAMED_LWRESD_H */ diff --git a/bin/named/include/named/lwsearch.h b/bin/named/include/named/lwsearch.h new file mode 100644 index 0000000..b85e401 --- /dev/null +++ b/bin/named/include/named/lwsearch.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: lwsearch.h,v 1.5.18.2 2005/04/29 00:15:36 marka Exp $ */ + +#ifndef NAMED_LWSEARCH_H +#define NAMED_LWSEARCH_H 1 + +#include +#include +#include + +#include + +#include + +/*! \file + * \brief + * Lightweight resolver search list types and routines. + * + * An ns_lwsearchlist_t holds a list of search path elements. + * + * An ns_lwsearchctx stores the state of search list during a lookup + * operation. + */ + +/*% An ns_lwsearchlist_t holds a list of search path elements. */ +struct ns_lwsearchlist { + unsigned int magic; + + isc_mutex_t lock; + isc_mem_t *mctx; + unsigned int refs; + dns_namelist_t names; +}; +/*% An ns_lwsearchctx stores the state of search list during a lookup operation. */ +struct ns_lwsearchctx { + dns_name_t *relname; + dns_name_t *searchname; + unsigned int ndots; + ns_lwsearchlist_t *list; + isc_boolean_t doneexact; + isc_boolean_t exactfirst; +}; + +isc_result_t +ns_lwsearchlist_create(isc_mem_t *mctx, ns_lwsearchlist_t **listp); +/*%< + * Create an empty search list object. + */ + +void +ns_lwsearchlist_attach(ns_lwsearchlist_t *source, ns_lwsearchlist_t **target); +/*%< + * Attach to a search list object. + */ + +void +ns_lwsearchlist_detach(ns_lwsearchlist_t **listp); +/*%< + * Detach from a search list object. + */ + +isc_result_t +ns_lwsearchlist_append(ns_lwsearchlist_t *list, dns_name_t *name); +/*%< + * Append an element to a search list. This creates a copy of the name. + */ + +void +ns_lwsearchctx_init(ns_lwsearchctx_t *sctx, ns_lwsearchlist_t *list, + dns_name_t *name, unsigned int ndots); +/*%< + * Creates a search list context structure. + */ + +void +ns_lwsearchctx_first(ns_lwsearchctx_t *sctx); +/*%< + * Moves the search list context iterator to the first element, which + * is usually the exact name. + */ + +isc_result_t +ns_lwsearchctx_next(ns_lwsearchctx_t *sctx); +/*%< + * Moves the search list context iterator to the next element. + */ + +isc_result_t +ns_lwsearchctx_current(ns_lwsearchctx_t *sctx, dns_name_t *absname); +/*%< + * Obtains the current name to be looked up. This involves either + * concatenating the name with a search path element, making an + * exact name absolute, or doing nothing. + */ + +#endif /* NAMED_LWSEARCH_H */ diff --git a/bin/named/include/named/main.h b/bin/named/include/named/main.h new file mode 100644 index 0000000..dd4fe8c --- /dev/null +++ b/bin/named/include/named/main.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2002 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: main.h,v 1.11.18.2 2005/04/29 00:15:37 marka Exp $ */ + +#ifndef NAMED_MAIN_H +#define NAMED_MAIN_H 1 + +/*! \file */ + +void +ns_main_earlyfatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); + +void +ns_main_earlywarning(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); + +void +ns_main_setmemstats(const char *); + +#endif /* NAMED_MAIN_H */ diff --git a/bin/named/include/named/notify.h b/bin/named/include/named/notify.h new file mode 100644 index 0000000..106d70c --- /dev/null +++ b/bin/named/include/named/notify.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: notify.h,v 1.10.18.2 2005/04/29 00:15:37 marka Exp $ */ + +#ifndef NAMED_NOTIFY_H +#define NAMED_NOTIFY_H 1 + +#include +#include + +/*** + *** Module Info + ***/ + +/*! \file + * \brief + * RFC1996 + * A Mechanism for Prompt Notification of Zone Changes (DNS NOTIFY) + */ + +/*** + *** Functions. + ***/ + +void +ns_notify_start(ns_client_t *client); + +/*%< + * Examines the incoming message to determine apporiate zone. + * Returns FORMERR if there is not exactly one question. + * Returns REFUSED if we do not serve the listed zone. + * Pass the message to the zone module for processing + * and returns the return status. + * + * Requires + *\li client to be valid. + */ + +#endif /* NAMED_NOTIFY_H */ + diff --git a/bin/named/include/named/ns_smf_globals.h b/bin/named/include/named/ns_smf_globals.h new file mode 100644 index 0000000..06df2ba --- /dev/null +++ b/bin/named/include/named/ns_smf_globals.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and 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: ns_smf_globals.h,v 1.2.2.4 2005/05/13 01:32:46 marka Exp $ */ + +#ifndef NS_SMF_GLOBALS_H +#define NS_SMF_GLOBALS_H 1 + +#include + +#undef EXTERN +#undef INIT +#ifdef NS_MAIN +#define EXTERN +#define INIT(v) = (v) +#else +#define EXTERN extern +#define INIT(v) +#endif + +EXTERN unsigned int ns_smf_got_instance INIT(0); +EXTERN unsigned int ns_smf_chroot INIT(0); +EXTERN unsigned int ns_smf_want_disable INIT(0); + +isc_result_t ns_smf_add_message(isc_buffer_t *text); +isc_result_t ns_smf_get_instance(char **name, int debug, isc_mem_t *mctx); + +#undef EXTERN +#undef INIT + +#endif /* NS_SMF_GLOBALS_H */ diff --git a/bin/named/include/named/query.h b/bin/named/include/named/query.h new file mode 100644 index 0000000..741212f --- /dev/null +++ b/bin/named/include/named/query.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2002 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: query.h,v 1.36.18.2 2005/04/29 00:15:37 marka Exp $ */ + +#ifndef NAMED_QUERY_H +#define NAMED_QUERY_H 1 + +/*! \file */ + +#include +#include +#include + +#include + +#include + +/*% nameserver database version structure */ +typedef struct ns_dbversion { + dns_db_t *db; + dns_dbversion_t *version; + isc_boolean_t queryok; + ISC_LINK(struct ns_dbversion) link; +} ns_dbversion_t; + +/*% nameserver query structure */ +struct ns_query { + unsigned int attributes; + unsigned int restarts; + isc_boolean_t timerset; + dns_name_t * qname; + dns_name_t * origqname; + unsigned int dboptions; + unsigned int fetchoptions; + dns_db_t * gluedb; + dns_db_t * authdb; + dns_zone_t * authzone; + isc_boolean_t authdbset; + isc_boolean_t isreferral; + isc_mutex_t fetchlock; + dns_fetch_t * fetch; + isc_bufferlist_t namebufs; + ISC_LIST(ns_dbversion_t) activeversions; + ISC_LIST(ns_dbversion_t) freeversions; +}; + +#define NS_QUERYATTR_RECURSIONOK 0x0001 +#define NS_QUERYATTR_CACHEOK 0x0002 +#define NS_QUERYATTR_PARTIALANSWER 0x0004 +#define NS_QUERYATTR_NAMEBUFUSED 0x0008 +#define NS_QUERYATTR_RECURSING 0x0010 +#define NS_QUERYATTR_CACHEGLUEOK 0x0020 +#define NS_QUERYATTR_QUERYOKVALID 0x0040 +#define NS_QUERYATTR_QUERYOK 0x0080 +#define NS_QUERYATTR_WANTRECURSION 0x0100 +#define NS_QUERYATTR_SECURE 0x0200 +#define NS_QUERYATTR_NOAUTHORITY 0x0400 +#define NS_QUERYATTR_NOADDITIONAL 0x0800 + +isc_result_t +ns_query_init(ns_client_t *client); + +void +ns_query_free(ns_client_t *client); + +void +ns_query_start(ns_client_t *client); + +void +ns_query_cancel(ns_client_t *client); + +#endif /* NAMED_QUERY_H */ diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h new file mode 100644 index 0000000..54d1dae --- /dev/null +++ b/bin/named/include/named/server.h @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: server.h,v 1.73.18.8 2006/03/09 23:46:20 marka Exp $ */ + +#ifndef NAMED_SERVER_H +#define NAMED_SERVER_H 1 + +/*! \file */ + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define NS_EVENTCLASS ISC_EVENTCLASS(0x4E43) +#define NS_EVENT_RELOAD (NS_EVENTCLASS + 0) +#define NS_EVENT_CLIENTCONTROL (NS_EVENTCLASS + 1) + +/*% + * Name server state. Better here than in lots of separate global variables. + */ +struct ns_server { + unsigned int magic; + isc_mem_t * mctx; + + isc_task_t * task; + + /* Configurable data. */ + isc_quota_t xfroutquota; + isc_quota_t tcpquota; + isc_quota_t recursionquota; + dns_acl_t *blackholeacl; + char * statsfile; /*%< Statistics file name */ + char * dumpfile; /*%< Dump file name */ + char * recfile; /*%< Recursive file name */ + isc_boolean_t version_set; /*%< User has set version */ + char * version; /*%< User-specified version */ + isc_boolean_t hostname_set; /*%< User has set hostname */ + char * hostname; /*%< User-specified hostname */ + /*% Use hostname for server id */ + isc_boolean_t server_usehostname; + char * server_id; /*%< User-specified server id */ + + /*% + * Current ACL environment. This defines the + * current values of the localhost and localnets + * ACLs. + */ + dns_aclenv_t aclenv; + + /* Server data structures. */ + dns_loadmgr_t * loadmgr; + dns_zonemgr_t * zonemgr; + dns_viewlist_t viewlist; + ns_interfacemgr_t * interfacemgr; + dns_db_t * in_roothints; + dns_tkeyctx_t * tkeyctx; + + isc_timer_t * interface_timer; + isc_timer_t * heartbeat_timer; + isc_timer_t * pps_timer; + + isc_uint32_t interface_interval; + isc_uint32_t heartbeat_interval; + + isc_mutex_t reload_event_lock; + isc_event_t * reload_event; + + isc_boolean_t flushonshutdown; + isc_boolean_t log_queries; /*%< For BIND 8 compatibility */ + + isc_uint64_t * querystats; /*%< Query statistics counters */ + + ns_controls_t * controls; /*%< Control channels */ + unsigned int dispatchgen; + ns_dispatchlist_t dispatches; + + dns_acache_t *acache; +}; + +#define NS_SERVER_MAGIC ISC_MAGIC('S','V','E','R') +#define NS_SERVER_VALID(s) ISC_MAGIC_VALID(s, NS_SERVER_MAGIC) + +void +ns_server_create(isc_mem_t *mctx, ns_server_t **serverp); +/*%< + * Create a server object with default settings. + * This function either succeeds or causes the program to exit + * with a fatal error. + */ + +void +ns_server_destroy(ns_server_t **serverp); +/*%< + * Destroy a server object, freeing its memory. + */ + +void +ns_server_reloadwanted(ns_server_t *server); +/*%< + * Inform a server that a reload is wanted. This function + * may be called asynchronously, from outside the server's task. + * If a reload is already scheduled or in progress, the call + * is ignored. + */ + +void +ns_server_flushonshutdown(ns_server_t *server, isc_boolean_t flush); +/*%< + * Inform the server that the zones should be flushed to disk on shutdown. + */ + +isc_result_t +ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t *text); +/*%< + * Act on a "reload" command from the command channel. + */ + +isc_result_t +ns_server_reconfigcommand(ns_server_t *server, char *args); +/*%< + * Act on a "reconfig" command from the command channel. + */ + +isc_result_t +ns_server_notifycommand(ns_server_t *server, char *args, isc_buffer_t *text); +/*%< + * Act on a "notify" command from the command channel. + */ + +isc_result_t +ns_server_refreshcommand(ns_server_t *server, char *args, isc_buffer_t *text); +/*%< + * Act on a "refresh" command from the command channel. + */ + +isc_result_t +ns_server_retransfercommand(ns_server_t *server, char *args); +/*%< + * Act on a "retransfer" command from the command channel. + */ + +isc_result_t +ns_server_togglequerylog(ns_server_t *server); +/*%< + * Toggle logging of queries, as in BIND 8. + */ + +/*% + * Dump the current statistics to the statistics file. + */ +isc_result_t +ns_server_dumpstats(ns_server_t *server); + +/*% + * Dump the current cache to the dump file. + */ +isc_result_t +ns_server_dumpdb(ns_server_t *server, char *args); + +/*% + * Change or increment the server debug level. + */ +isc_result_t +ns_server_setdebuglevel(ns_server_t *server, char *args); + +/*% + * Flush the server's cache(s) + */ +isc_result_t +ns_server_flushcache(ns_server_t *server, char *args); + +/*% + * Flush a particular name from the server's cache(s) + */ +isc_result_t +ns_server_flushname(ns_server_t *server, char *args); + +/*% + * Report the server's status. + */ +isc_result_t +ns_server_status(ns_server_t *server, isc_buffer_t *text); + +/*% + * Enable or disable updates for a zone. + */ +isc_result_t +ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args); + +/*% + * Dump the current recursive queries. + */ +isc_result_t +ns_server_dumprecursing(ns_server_t *server); + +/*% + * Maintain a list of dispatches that require reserved ports. + */ +void +ns_add_reserved_dispatch(ns_server_t *server, const isc_sockaddr_t *addr); + +/*% + * Enable or disable dnssec validation. + */ +isc_result_t +ns_server_validation(ns_server_t *server, char *args); + +#endif /* NAMED_SERVER_H */ diff --git a/bin/named/include/named/sortlist.h b/bin/named/include/named/sortlist.h new file mode 100644 index 0000000..f849be2 --- /dev/null +++ b/bin/named/include/named/sortlist.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: sortlist.h,v 1.5.18.4 2006/03/02 00:37:21 marka Exp $ */ + +#ifndef NAMED_SORTLIST_H +#define NAMED_SORTLIST_H 1 + +/*! \file */ + +#include + +#include + +/*% + * Type for callback functions that rank addresses. + */ +typedef int +(*dns_addressorderfunc_t)(const isc_netaddr_t *address, const void *arg); + +/*% + * Return value type for setup_sortlist. + */ +typedef enum { + NS_SORTLISTTYPE_NONE, + NS_SORTLISTTYPE_1ELEMENT, + NS_SORTLISTTYPE_2ELEMENT +} ns_sortlisttype_t; + +ns_sortlisttype_t +ns_sortlist_setup(dns_acl_t *acl, isc_netaddr_t *clientaddr, + const void **argp); +/*%< + * Find the sortlist statement in 'acl' that applies to 'clientaddr', if any. + * + * If a 1-element sortlist item applies, return NS_SORTLISTTYPE_1ELEMENT and + * make '*argp' point to the matching subelement. + * + * If a 2-element sortlist item applies, return NS_SORTLISTTYPE_2ELEMENT and + * make '*argp' point to ACL that forms the second element. + * + * If no sortlist item applies, return NS_SORTLISTTYPE_NONE and set '*argp' + * to NULL. + */ + +int +ns_sortlist_addrorder1(const isc_netaddr_t *addr, const void *arg); +/*%< + * Find the sort order of 'addr' in 'arg', the matching element + * of a 1-element top-level sortlist statement. + */ + +int +ns_sortlist_addrorder2(const isc_netaddr_t *addr, const void *arg); +/*%< + * Find the sort order of 'addr' in 'arg', a topology-like + * ACL forming the second element in a 2-element top-level + * sortlist statement. + */ + +void +ns_sortlist_byaddrsetup(dns_acl_t *sortlist_acl, isc_netaddr_t *client_addr, + dns_addressorderfunc_t *orderp, + const void **argp); +/*%< + * Find the sortlist statement in 'acl' that applies to 'clientaddr', if any. + * If a sortlist statement applies, return in '*orderp' a pointer to a function + * for ranking network addresses based on that sortlist statement, and in + * '*argp' an argument to pass to said function. If no sortlist statement + * applies, set '*orderp' and '*argp' to NULL. + */ + +#endif /* NAMED_SORTLIST_H */ diff --git a/bin/named/include/named/tkeyconf.h b/bin/named/include/named/tkeyconf.h new file mode 100644 index 0000000..946944d --- /dev/null +++ b/bin/named/include/named/tkeyconf.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: tkeyconf.h,v 1.10.18.4 2006/03/02 00:37:21 marka Exp $ */ + +#ifndef NS_TKEYCONF_H +#define NS_TKEYCONF_H 1 + +/*! \file */ + +#include +#include + +#include + +ISC_LANG_BEGINDECLS + +isc_result_t +ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx, + isc_entropy_t *ectx, dns_tkeyctx_t **tctxp); +/*%< + * Create a TKEY context and configure it, including the default DH key + * and default domain, according to 'options'. + * + * Requires: + *\li 'cfg' is a valid configuration options object. + *\li 'mctx' is not NULL + *\li 'ectx' is not NULL + *\li 'tctx' is not NULL + *\li '*tctx' is NULL + * + * Returns: + *\li ISC_R_SUCCESS + *\li ISC_R_NOMEMORY + */ + +ISC_LANG_ENDDECLS + +#endif /* NS_TKEYCONF_H */ diff --git a/bin/named/include/named/tsigconf.h b/bin/named/include/named/tsigconf.h new file mode 100644 index 0000000..a18eede --- /dev/null +++ b/bin/named/include/named/tsigconf.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: tsigconf.h,v 1.10.18.4 2006/03/02 00:37:21 marka Exp $ */ + +#ifndef NS_TSIGCONF_H +#define NS_TSIGCONF_H 1 + +/*! \file */ + +#include +#include + +ISC_LANG_BEGINDECLS + +isc_result_t +ns_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig, + isc_mem_t *mctx, dns_tsig_keyring_t **ringp); +/*%< + * Create a TSIG key ring and configure it according to the 'key' + * statements in the global and view configuration objects. + * + * Requires: + * \li 'config' is not NULL. + * \li 'mctx' is not NULL + * \li 'ring' is not NULL, and '*ring' is NULL + * + * Returns: + * \li ISC_R_SUCCESS + * \li ISC_R_NOMEMORY + */ + +ISC_LANG_ENDDECLS + +#endif /* NS_TSIGCONF_H */ diff --git a/bin/named/include/named/types.h b/bin/named/include/named/types.h new file mode 100644 index 0000000..abc25d5 --- /dev/null +++ b/bin/named/include/named/types.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: types.h,v 1.21.18.2 2005/04/29 00:15:38 marka Exp $ */ + +#ifndef NAMED_TYPES_H +#define NAMED_TYPES_H 1 + +/*! \file */ + +#include + +typedef struct ns_client ns_client_t; +typedef struct ns_clientmgr ns_clientmgr_t; +typedef struct ns_query ns_query_t; +typedef struct ns_server ns_server_t; +typedef struct ns_interface ns_interface_t; +typedef struct ns_interfacemgr ns_interfacemgr_t; +typedef struct ns_lwresd ns_lwresd_t; +typedef struct ns_lwreslistener ns_lwreslistener_t; +typedef struct ns_lwdclient ns_lwdclient_t; +typedef struct ns_lwdclientmgr ns_lwdclientmgr_t; +typedef struct ns_lwsearchlist ns_lwsearchlist_t; +typedef struct ns_lwsearchctx ns_lwsearchctx_t; +typedef struct ns_controls ns_controls_t; +typedef struct ns_dispatch ns_dispatch_t; +typedef ISC_LIST(ns_dispatch_t) ns_dispatchlist_t; + +#endif /* NAMED_TYPES_H */ diff --git a/bin/named/include/named/update.h b/bin/named/include/named/update.h new file mode 100644 index 0000000..37daa95 --- /dev/null +++ b/bin/named/include/named/update.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: update.h,v 1.9.18.2 2005/04/29 00:15:39 marka Exp $ */ + +#ifndef NAMED_UPDATE_H +#define NAMED_UPDATE_H 1 + +/***** + ***** Module Info + *****/ + +/*! \file + * \brief + * RFC2136 Dynamic Update + */ + +/*** + *** Imports + ***/ + +#include +#include + +/*** + *** Types. + ***/ + +/*** + *** Functions + ***/ + +void +ns_update_start(ns_client_t *client, isc_result_t sigresult); + +#endif /* NAMED_UPDATE_H */ diff --git a/bin/named/include/named/xfrout.h b/bin/named/include/named/xfrout.h new file mode 100644 index 0000000..82e0e66 --- /dev/null +++ b/bin/named/include/named/xfrout.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: xfrout.h,v 1.8.18.2 2005/04/29 00:15:39 marka Exp $ */ + +#ifndef NAMED_XFROUT_H +#define NAMED_XFROUT_H 1 + +/***** + ***** Module Info + *****/ + +/*! \file + * \brief + * Outgoing zone transfers (AXFR + IXFR). + */ + +/*** + *** Functions + ***/ + +void +ns_xfr_start(ns_client_t *client, dns_rdatatype_t xfrtype); + +#endif /* NAMED_XFROUT_H */ diff --git a/bin/named/include/named/zoneconf.h b/bin/named/include/named/zoneconf.h new file mode 100644 index 0000000..61737a2 --- /dev/null +++ b/bin/named/include/named/zoneconf.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2002 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: zoneconf.h,v 1.19.18.5 2006/03/02 00:37:21 marka Exp $ */ + +#ifndef NS_ZONECONF_H +#define NS_ZONECONF_H 1 + +/*! \file */ + +#include +#include + +#include +#include + +ISC_LANG_BEGINDECLS + +isc_result_t +ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, + const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac, + dns_zone_t *zone); +/*%< + * Configure or reconfigure a zone according to the named.conf + * data in 'cctx' and 'czone'. + * + * The zone origin is not configured, it is assumed to have been set + * at zone creation time. + * + * Require: + * \li 'lctx' to be initialized or NULL. + * \li 'cctx' to be initialized or NULL. + * \li 'ac' to point to an initialized ns_aclconfctx_t. + * \li 'czone' to be initialized. + * \li 'zone' to be initialized. + */ + +isc_boolean_t +ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig); +/*%< + * If 'zone' can be safely reconfigured according to the configuration + * data in 'zconfig', return ISC_TRUE. If the configuration data is so + * different from the current zone state that the zone needs to be destroyed + * and recreated, return ISC_FALSE. + */ + +ISC_LANG_ENDDECLS + +#endif /* NS_ZONECONF_H */ diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c new file mode 100644 index 0000000..db41031 --- /dev/null +++ b/bin/named/interfacemgr.c @@ -0,0 +1,978 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2002 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: interfacemgr.c,v 1.76.18.8 2006/07/20 01:10:30 marka Exp $ */ + +/*! \file */ + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#define IFMGR_MAGIC ISC_MAGIC('I', 'F', 'M', 'G') +#define NS_INTERFACEMGR_VALID(t) ISC_MAGIC_VALID(t, IFMGR_MAGIC) + +#define IFMGR_COMMON_LOGARGS \ + ns_g_lctx, NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR + +/*% nameserver interface manager structure */ +struct ns_interfacemgr { + unsigned int magic; /*%< Magic number. */ + int references; + isc_mutex_t lock; + isc_mem_t * mctx; /*%< Memory context. */ + isc_taskmgr_t * taskmgr; /*%< Task manager. */ + isc_socketmgr_t * socketmgr; /*%< Socket manager. */ + dns_dispatchmgr_t * dispatchmgr; + unsigned int generation; /*%< Current generation no. */ + ns_listenlist_t * listenon4; + ns_listenlist_t * listenon6; + dns_aclenv_t aclenv; /*%< Localhost/localnets ACLs */ + ISC_LIST(ns_interface_t) interfaces; /*%< List of interfaces. */ + ISC_LIST(isc_sockaddr_t) listenon; +}; + +static void +purge_old_interfaces(ns_interfacemgr_t *mgr); + +static void +clearlistenon(ns_interfacemgr_t *mgr); + +isc_result_t +ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, + isc_socketmgr_t *socketmgr, + dns_dispatchmgr_t *dispatchmgr, + ns_interfacemgr_t **mgrp) +{ + isc_result_t result; + ns_interfacemgr_t *mgr; + + REQUIRE(mctx != NULL); + REQUIRE(mgrp != NULL); + REQUIRE(*mgrp == NULL); + + mgr = isc_mem_get(mctx, sizeof(*mgr)); + if (mgr == NULL) + return (ISC_R_NOMEMORY); + + result = isc_mutex_init(&mgr->lock); + if (result != ISC_R_SUCCESS) + goto cleanup_mem; + + mgr->mctx = mctx; + mgr->taskmgr = taskmgr; + mgr->socketmgr = socketmgr; + mgr->dispatchmgr = dispatchmgr; + mgr->generation = 1; + mgr->listenon4 = NULL; + mgr->listenon6 = NULL; + + ISC_LIST_INIT(mgr->interfaces); + ISC_LIST_INIT(mgr->listenon); + + /* + * The listen-on lists are initially empty. + */ + result = ns_listenlist_create(mctx, &mgr->listenon4); + if (result != ISC_R_SUCCESS) + goto cleanup_mem; + ns_listenlist_attach(mgr->listenon4, &mgr->listenon6); + + result = dns_aclenv_init(mctx, &mgr->aclenv); + if (result != ISC_R_SUCCESS) + goto cleanup_listenon; + + mgr->references = 1; + mgr->magic = IFMGR_MAGIC; + *mgrp = mgr; + return (ISC_R_SUCCESS); + + cleanup_listenon: + ns_listenlist_detach(&mgr->listenon4); + ns_listenlist_detach(&mgr->listenon6); + cleanup_mem: + isc_mem_put(mctx, mgr, sizeof(*mgr)); + return (result); +} + +static void +ns_interfacemgr_destroy(ns_interfacemgr_t *mgr) { + REQUIRE(NS_INTERFACEMGR_VALID(mgr)); + dns_aclenv_destroy(&mgr->aclenv); + ns_listenlist_detach(&mgr->listenon4); + ns_listenlist_detach(&mgr->listenon6); + clearlistenon(mgr); + DESTROYLOCK(&mgr->lock); + mgr->magic = 0; + isc_mem_put(mgr->mctx, mgr, sizeof(*mgr)); +} + +dns_aclenv_t * +ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr) { + return (&mgr->aclenv); +} + +void +ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target) { + REQUIRE(NS_INTERFACEMGR_VALID(source)); + LOCK(&source->lock); + INSIST(source->references > 0); + source->references++; + UNLOCK(&source->lock); + *target = source; +} + +void +ns_interfacemgr_detach(ns_interfacemgr_t **targetp) { + isc_result_t need_destroy = ISC_FALSE; + ns_interfacemgr_t *target = *targetp; + REQUIRE(target != NULL); + REQUIRE(NS_INTERFACEMGR_VALID(target)); + LOCK(&target->lock); + REQUIRE(target->references > 0); + target->references--; + if (target->references == 0) + need_destroy = ISC_TRUE; + UNLOCK(&target->lock); + if (need_destroy) + ns_interfacemgr_destroy(target); + *targetp = NULL; +} + +void +ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr) { + REQUIRE(NS_INTERFACEMGR_VALID(mgr)); + + /*% + * Shut down and detach all interfaces. + * By incrementing the generation count, we make purge_old_interfaces() + * consider all interfaces "old". + */ + mgr->generation++; + purge_old_interfaces(mgr); +} + + +static isc_result_t +ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, + const char *name, ns_interface_t **ifpret) +{ + ns_interface_t *ifp; + isc_result_t result; + + REQUIRE(NS_INTERFACEMGR_VALID(mgr)); + ifp = isc_mem_get(mgr->mctx, sizeof(*ifp)); + if (ifp == NULL) + return (ISC_R_NOMEMORY); + ifp->mgr = NULL; + ifp->generation = mgr->generation; + ifp->addr = *addr; + ifp->flags = 0; + strncpy(ifp->name, name, sizeof(ifp->name)); + ifp->name[sizeof(ifp->name)-1] = '\0'; + ifp->clientmgr = NULL; + + result = isc_mutex_init(&ifp->lock); + if (result != ISC_R_SUCCESS) + goto lock_create_failure; + + result = ns_clientmgr_create(mgr->mctx, mgr->taskmgr, + ns_g_timermgr, + &ifp->clientmgr); + if (result != ISC_R_SUCCESS) { + isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, + "ns_clientmgr_create() failed: %s", + isc_result_totext(result)); + goto clientmgr_create_failure; + } + + ifp->udpdispatch = NULL; + + ifp->tcpsocket = NULL; + /* + * Create a single TCP client object. It will replace itself + * with a new one as soon as it gets a connection, so the actual + * connections will be handled in parallel even though there is + * only one client initially. + */ + ifp->ntcptarget = 1; + ifp->ntcpcurrent = 0; + + ISC_LINK_INIT(ifp, link); + + ns_interfacemgr_attach(mgr, &ifp->mgr); + ISC_LIST_APPEND(mgr->interfaces, ifp, link); + + ifp->references = 1; + ifp->magic = IFACE_MAGIC; + *ifpret = ifp; + + return (ISC_R_SUCCESS); + + clientmgr_create_failure: + DESTROYLOCK(&ifp->lock); + lock_create_failure: + ifp->magic = 0; + isc_mem_put(mgr->mctx, ifp, sizeof(*ifp)); + + return (ISC_R_UNEXPECTED); +} + +static isc_result_t +ns_interface_listenudp(ns_interface_t *ifp) { + isc_result_t result; + unsigned int attrs; + unsigned int attrmask; + + attrs = 0; + attrs |= DNS_DISPATCHATTR_UDP; + if (isc_sockaddr_pf(&ifp->addr) == AF_INET) + attrs |= DNS_DISPATCHATTR_IPV4; + else + attrs |= DNS_DISPATCHATTR_IPV6; + attrs |= DNS_DISPATCHATTR_NOLISTEN; + attrmask = 0; + attrmask |= DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP; + attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6; + result = dns_dispatch_getudp(ifp->mgr->dispatchmgr, ns_g_socketmgr, + ns_g_taskmgr, &ifp->addr, + 4096, 1000, 32768, 8219, 8237, + attrs, attrmask, &ifp->udpdispatch); + if (result != ISC_R_SUCCESS) { + isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, + "could not listen on UDP socket: %s", + isc_result_totext(result)); + goto udp_dispatch_failure; + } + + result = ns_clientmgr_createclients(ifp->clientmgr, ns_g_cpus, + ifp, ISC_FALSE); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "UDP ns_clientmgr_createclients(): %s", + isc_result_totext(result)); + goto addtodispatch_failure; + } + return (ISC_R_SUCCESS); + + addtodispatch_failure: + dns_dispatch_changeattributes(ifp->udpdispatch, 0, + DNS_DISPATCHATTR_NOLISTEN); + dns_dispatch_detach(&ifp->udpdispatch); + udp_dispatch_failure: + return (result); +} + +static isc_result_t +ns_interface_accepttcp(ns_interface_t *ifp) { + isc_result_t result; + + /* + * Open a TCP socket. + */ + result = isc_socket_create(ifp->mgr->socketmgr, + isc_sockaddr_pf(&ifp->addr), + isc_sockettype_tcp, + &ifp->tcpsocket); + if (result != ISC_R_SUCCESS) { + isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, + "creating TCP socket: %s", + isc_result_totext(result)); + goto tcp_socket_failure; + } +#ifndef ISC_ALLOW_MAPPED + isc_socket_ipv6only(ifp->tcpsocket, ISC_TRUE); +#endif + result = isc_socket_bind(ifp->tcpsocket, &ifp->addr); + if (result != ISC_R_SUCCESS) { + isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, + "binding TCP socket: %s", + isc_result_totext(result)); + goto tcp_bind_failure; + } + result = isc_socket_listen(ifp->tcpsocket, ns_g_listen); + if (result != ISC_R_SUCCESS) { + isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, + "listening on TCP socket: %s", + isc_result_totext(result)); + goto tcp_listen_failure; + } + + /* + * If/when there a multiple filters listen to the + * result. + */ + (void)isc_socket_filter(ifp->tcpsocket, "dataready"); + + result = ns_clientmgr_createclients(ifp->clientmgr, + ifp->ntcptarget, ifp, + ISC_TRUE); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "TCP ns_clientmgr_createclients(): %s", + isc_result_totext(result)); + goto accepttcp_failure; + } + return (ISC_R_SUCCESS); + + accepttcp_failure: + tcp_listen_failure: + tcp_bind_failure: + isc_socket_detach(&ifp->tcpsocket); + tcp_socket_failure: + return (ISC_R_SUCCESS); +} + +static isc_result_t +ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, + const char *name, ns_interface_t **ifpret, + isc_boolean_t accept_tcp) +{ + isc_result_t result; + ns_interface_t *ifp = NULL; + REQUIRE(ifpret != NULL && *ifpret == NULL); + + result = ns_interface_create(mgr, addr, name, &ifp); + if (result != ISC_R_SUCCESS) + return (result); + + result = ns_interface_listenudp(ifp); + if (result != ISC_R_SUCCESS) + goto cleanup_interface; + + if (accept_tcp == ISC_TRUE) { + result = ns_interface_accepttcp(ifp); + if (result != ISC_R_SUCCESS) { + /* + * XXXRTH We don't currently have a way to easily stop + * dispatch service, so we currently return + * ISC_R_SUCCESS (the UDP stuff will work even if TCP + * creation failed). This will be fixed later. + */ + result = ISC_R_SUCCESS; + } + } + *ifpret = ifp; + return (ISC_R_SUCCESS); + + cleanup_interface: + ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link); + ns_interface_detach(&ifp); + return (result); +} + +void +ns_interface_shutdown(ns_interface_t *ifp) { + if (ifp->clientmgr != NULL) + ns_clientmgr_destroy(&ifp->clientmgr); +} + +static void +ns_interface_destroy(ns_interface_t *ifp) { + isc_mem_t *mctx = ifp->mgr->mctx; + REQUIRE(NS_INTERFACE_VALID(ifp)); + + ns_interface_shutdown(ifp); + + if (ifp->udpdispatch != NULL) { + dns_dispatch_changeattributes(ifp->udpdispatch, 0, + DNS_DISPATCHATTR_NOLISTEN); + dns_dispatch_detach(&ifp->udpdispatch); + } + if (ifp->tcpsocket != NULL) + isc_socket_detach(&ifp->tcpsocket); + + DESTROYLOCK(&ifp->lock); + + ns_interfacemgr_detach(&ifp->mgr); + + ifp->magic = 0; + isc_mem_put(mctx, ifp, sizeof(*ifp)); +} + +void +ns_interface_attach(ns_interface_t *source, ns_interface_t **target) { + REQUIRE(NS_INTERFACE_VALID(source)); + LOCK(&source->lock); + INSIST(source->references > 0); + source->references++; + UNLOCK(&source->lock); + *target = source; +} + +void +ns_interface_detach(ns_interface_t **targetp) { + isc_result_t need_destroy = ISC_FALSE; + ns_interface_t *target = *targetp; + REQUIRE(target != NULL); + REQUIRE(NS_INTERFACE_VALID(target)); + LOCK(&target->lock); + REQUIRE(target->references > 0); + target->references--; + if (target->references == 0) + need_destroy = ISC_TRUE; + UNLOCK(&target->lock); + if (need_destroy) + ns_interface_destroy(target); + *targetp = NULL; +} + +/*% + * Search the interface list for an interface whose address and port + * both match those of 'addr'. Return a pointer to it, or NULL if not found. + */ +static ns_interface_t * +find_matching_interface(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) { + ns_interface_t *ifp; + for (ifp = ISC_LIST_HEAD(mgr->interfaces); ifp != NULL; + ifp = ISC_LIST_NEXT(ifp, link)) { + if (isc_sockaddr_equal(&ifp->addr, addr)) + break; + } + return (ifp); +} + +/*% + * Remove any interfaces whose generation number is not the current one. + */ +static void +purge_old_interfaces(ns_interfacemgr_t *mgr) { + ns_interface_t *ifp, *next; + for (ifp = ISC_LIST_HEAD(mgr->interfaces); ifp != NULL; ifp = next) { + INSIST(NS_INTERFACE_VALID(ifp)); + next = ISC_LIST_NEXT(ifp, link); + if (ifp->generation != mgr->generation) { + char sabuf[256]; + ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link); + isc_sockaddr_format(&ifp->addr, sabuf, sizeof(sabuf)); + isc_log_write(IFMGR_COMMON_LOGARGS, + ISC_LOG_INFO, + "no longer listening on %s", sabuf); + ns_interface_shutdown(ifp); + ns_interface_detach(&ifp); + } + } +} + +static isc_result_t +clearacl(isc_mem_t *mctx, dns_acl_t **aclp) { + dns_acl_t *newacl = NULL; + isc_result_t result; + result = dns_acl_create(mctx, 10, &newacl); + if (result != ISC_R_SUCCESS) + return (result); + dns_acl_detach(aclp); + dns_acl_attach(newacl, aclp); + dns_acl_detach(&newacl); + return (ISC_R_SUCCESS); +} + +static isc_boolean_t +listenon_is_ip6_any(ns_listenelt_t *elt) { + if (elt->acl->length != 1) + return (ISC_FALSE); + if (elt->acl->elements[0].negative == ISC_FALSE && + elt->acl->elements[0].type == dns_aclelementtype_any) + return (ISC_TRUE); /* listen-on-v6 { any; } */ + return (ISC_FALSE); /* All others */ +} + +static isc_result_t +setup_locals(ns_interfacemgr_t *mgr, isc_interface_t *interface) { + isc_result_t result; + dns_aclelement_t elt; + unsigned int family; + unsigned int prefixlen; + + family = interface->address.family; + + elt.type = dns_aclelementtype_ipprefix; + elt.negative = ISC_FALSE; + elt.u.ip_prefix.address = interface->address; + elt.u.ip_prefix.prefixlen = (family == AF_INET) ? 32 : 128; + result = dns_acl_appendelement(mgr->aclenv.localhost, &elt); + if (result != ISC_R_SUCCESS) + return (result); + + result = isc_netaddr_masktoprefixlen(&interface->netmask, + &prefixlen); + + /* Non contigious netmasks not allowed by IPv6 arch. */ + if (result != ISC_R_SUCCESS && family == AF_INET6) + return (result); + + if (result != ISC_R_SUCCESS) { + isc_log_write(IFMGR_COMMON_LOGARGS, + ISC_LOG_WARNING, + "omitting IPv4 interface %s from " + "localnets ACL: %s", + interface->name, + isc_result_totext(result)); + } else { + elt.u.ip_prefix.prefixlen = prefixlen; + if (dns_acl_elementmatch(mgr->aclenv.localnets, &elt, + NULL) == ISC_R_NOTFOUND) { + result = dns_acl_appendelement(mgr->aclenv.localnets, + &elt); + if (result != ISC_R_SUCCESS) + return (result); + } + } + + return (ISC_R_SUCCESS); +} + +static void +setup_listenon(ns_interfacemgr_t *mgr, isc_interface_t *interface, + in_port_t port) +{ + isc_sockaddr_t *addr; + isc_sockaddr_t *old; + + addr = isc_mem_get(mgr->mctx, sizeof(*addr)); + if (addr == NULL) + return; + + isc_sockaddr_fromnetaddr(addr, &interface->address, port); + + for (old = ISC_LIST_HEAD(mgr->listenon); + old != NULL; + old = ISC_LIST_NEXT(old, link)) + if (isc_sockaddr_equal(addr, old)) + break; + + if (old != NULL) + isc_mem_put(mgr->mctx, addr, sizeof(*addr)); + else + ISC_LIST_APPEND(mgr->listenon, addr, link); +} + +static void +clearlistenon(ns_interfacemgr_t *mgr) { + isc_sockaddr_t *old; + + old = ISC_LIST_HEAD(mgr->listenon); + while (old != NULL) { + ISC_LIST_UNLINK(mgr->listenon, old, link); + isc_mem_put(mgr->mctx, old, sizeof(*old)); + old = ISC_LIST_HEAD(mgr->listenon); + } +} + +static isc_result_t +do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, + isc_boolean_t verbose) +{ + isc_interfaceiter_t *iter = NULL; + isc_boolean_t scan_ipv4 = ISC_FALSE; + isc_boolean_t scan_ipv6 = ISC_FALSE; + isc_boolean_t adjusting = ISC_FALSE; + isc_boolean_t ipv6only = ISC_TRUE; + isc_boolean_t ipv6pktinfo = ISC_TRUE; + isc_result_t result; + isc_netaddr_t zero_address, zero_address6; + ns_listenelt_t *le; + isc_sockaddr_t listen_addr; + ns_interface_t *ifp; + isc_boolean_t log_explicit = ISC_FALSE; + isc_boolean_t dolistenon; + + if (ext_listen != NULL) + adjusting = ISC_TRUE; + + if (isc_net_probeipv6() == ISC_R_SUCCESS) + scan_ipv6 = ISC_TRUE; +#ifdef WANT_IPV6 + else + isc_log_write(IFMGR_COMMON_LOGARGS, + verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1), + "no IPv6 interfaces found"); +#endif + + if (isc_net_probeipv4() == ISC_R_SUCCESS) + scan_ipv4 = ISC_TRUE; + else + isc_log_write(IFMGR_COMMON_LOGARGS, + verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1), + "no IPv4 interfaces found"); + + /* + * A special, but typical case; listen-on-v6 { any; }. + * When we can make the socket IPv6-only, open a single wildcard + * socket for IPv6 communication. Otherwise, make separate socket + * for each IPv6 address in order to avoid accepting IPv4 packets + * as the form of mapped addresses unintentionally unless explicitly + * allowed. + */ +#ifndef ISC_ALLOW_MAPPED + if (scan_ipv6 == ISC_TRUE && + isc_net_probe_ipv6only() != ISC_R_SUCCESS) { + ipv6only = ISC_FALSE; + log_explicit = ISC_TRUE; + } +#endif + if (scan_ipv6 == ISC_TRUE && + isc_net_probe_ipv6pktinfo() != ISC_R_SUCCESS) { + ipv6pktinfo = ISC_FALSE; + log_explicit = ISC_TRUE; + } + if (scan_ipv6 == ISC_TRUE && ipv6only && ipv6pktinfo) { + for (le = ISC_LIST_HEAD(mgr->listenon6->elts); + le != NULL; + le = ISC_LIST_NEXT(le, link)) { + struct in6_addr in6a; + + if (!listenon_is_ip6_any(le)) + continue; + + in6a = in6addr_any; + isc_sockaddr_fromin6(&listen_addr, &in6a, le->port); + + ifp = find_matching_interface(mgr, &listen_addr); + if (ifp != NULL) { + ifp->generation = mgr->generation; + } else { + isc_log_write(IFMGR_COMMON_LOGARGS, + ISC_LOG_INFO, + "listening on IPv6 " + "interfaces, port %u", + le->port); + result = ns_interface_setup(mgr, &listen_addr, + "", &ifp, + ISC_TRUE); + if (result == ISC_R_SUCCESS) + ifp->flags |= NS_INTERFACEFLAG_ANYADDR; + else + isc_log_write(IFMGR_COMMON_LOGARGS, + ISC_LOG_ERROR, + "listening on all IPv6 " + "interfaces failed"); + /* Continue. */ + } + } + } + + isc_netaddr_any(&zero_address); + isc_netaddr_any6(&zero_address6); + + result = isc_interfaceiter_create(mgr->mctx, &iter); + if (result != ISC_R_SUCCESS) + return (result); + + if (adjusting == ISC_FALSE) { + result = clearacl(mgr->mctx, &mgr->aclenv.localhost); + if (result != ISC_R_SUCCESS) + goto cleanup_iter; + result = clearacl(mgr->mctx, &mgr->aclenv.localnets); + if (result != ISC_R_SUCCESS) + goto cleanup_iter; + clearlistenon(mgr); + } + + for (result = isc_interfaceiter_first(iter); + result == ISC_R_SUCCESS; + result = isc_interfaceiter_next(iter)) + { + isc_interface_t interface; + ns_listenlist_t *ll; + unsigned int family; + + result = isc_interfaceiter_current(iter, &interface); + if (result != ISC_R_SUCCESS) + break; + + family = interface.address.family; + if (family != AF_INET && family != AF_INET6) + continue; + if (scan_ipv4 == ISC_FALSE && family == AF_INET) + continue; + if (scan_ipv6 == ISC_FALSE && family == AF_INET6) + continue; + + /* + * Test for the address being nonzero rather than testing + * INTERFACE_F_UP, because on some systems the latter + * follows the media state and we could end up ignoring + * the interface for an entire rescan interval due to + * a temporary media glitch at rescan time. + */ + if (family == AF_INET && + isc_netaddr_equal(&interface.address, &zero_address)) { + continue; + } + if (family == AF_INET6 && + isc_netaddr_equal(&interface.address, &zero_address6)) { + continue; + } + + if (adjusting == ISC_FALSE) { + result = setup_locals(mgr, &interface); + if (result != ISC_R_SUCCESS) + goto ignore_interface; + } + + ll = (family == AF_INET) ? mgr->listenon4 : mgr->listenon6; + dolistenon = ISC_TRUE; + for (le = ISC_LIST_HEAD(ll->elts); + le != NULL; + le = ISC_LIST_NEXT(le, link)) + { + int match; + isc_boolean_t ipv6_wildcard = ISC_FALSE; + isc_netaddr_t listen_netaddr; + isc_sockaddr_t listen_sockaddr; + + /* + * Construct a socket address for this IP/port + * combination. + */ + if (family == AF_INET) { + isc_netaddr_fromin(&listen_netaddr, + &interface.address.type.in); + } else { + isc_netaddr_fromin6(&listen_netaddr, + &interface.address.type.in6); + isc_netaddr_setzone(&listen_netaddr, + interface.address.zone); + } + isc_sockaddr_fromnetaddr(&listen_sockaddr, + &listen_netaddr, + le->port); + + /* + * See if the address matches the listen-on statement; + * if not, ignore the interface. + */ + (void)dns_acl_match(&listen_netaddr, NULL, le->acl, + &mgr->aclenv, &match, NULL); + if (match <= 0) + continue; + + if (adjusting == ISC_FALSE && dolistenon == ISC_TRUE) { + setup_listenon(mgr, &interface, le->port); + dolistenon = ISC_FALSE; + } + + /* + * The case of "any" IPv6 address will require + * special considerations later, so remember it. + */ + if (family == AF_INET6 && ipv6only && ipv6pktinfo && + listenon_is_ip6_any(le)) + ipv6_wildcard = ISC_TRUE; + + /* + * When adjusting interfaces with extra a listening + * list, see if the address matches the extra list. + * If it does, and is also covered by a wildcard + * interface, we need to listen on the address + * explicitly. + */ + if (adjusting == ISC_TRUE) { + ns_listenelt_t *ele; + + match = 0; + for (ele = ISC_LIST_HEAD(ext_listen->elts); + ele != NULL; + ele = ISC_LIST_NEXT(ele, link)) { + (void)dns_acl_match(&listen_netaddr, + NULL, ele->acl, + NULL, &match, NULL); + if (match > 0 && ele->port == le->port) + break; + else + match = 0; + } + if (ipv6_wildcard == ISC_TRUE && match == 0) + continue; + } + + ifp = find_matching_interface(mgr, &listen_sockaddr); + if (ifp != NULL) { + ifp->generation = mgr->generation; + } else { + char sabuf[ISC_SOCKADDR_FORMATSIZE]; + + if (adjusting == ISC_FALSE && + ipv6_wildcard == ISC_TRUE) + continue; + + if (log_explicit && family == AF_INET6 && + !adjusting && listenon_is_ip6_any(le)) { + isc_log_write(IFMGR_COMMON_LOGARGS, + verbose ? ISC_LOG_INFO : + ISC_LOG_DEBUG(1), + "IPv6 socket API is " + "incomplete; explicitly " + "binding to each IPv6 " + "address separately"); + log_explicit = ISC_FALSE; + } + isc_sockaddr_format(&listen_sockaddr, + sabuf, sizeof(sabuf)); + isc_log_write(IFMGR_COMMON_LOGARGS, + ISC_LOG_INFO, + "%s" + "listening on %s interface " + "%s, %s", + (adjusting == ISC_TRUE) ? + "additionally " : "", + (family == AF_INET) ? + "IPv4" : "IPv6", + interface.name, sabuf); + + result = ns_interface_setup(mgr, + &listen_sockaddr, + interface.name, + &ifp, + (adjusting == ISC_TRUE) ? + ISC_FALSE : + ISC_TRUE); + + if (result != ISC_R_SUCCESS) { + isc_log_write(IFMGR_COMMON_LOGARGS, + ISC_LOG_ERROR, + "creating %s interface " + "%s failed; interface " + "ignored", + (family == AF_INET) ? + "IPv4" : "IPv6", + interface.name); + } + /* Continue. */ + } + + } + continue; + + ignore_interface: + isc_log_write(IFMGR_COMMON_LOGARGS, + ISC_LOG_ERROR, + "ignoring %s interface %s: %s", + (family == AF_INET) ? "IPv4" : "IPv6", + interface.name, isc_result_totext(result)); + continue; + } + if (result != ISC_R_NOMORE) + UNEXPECTED_ERROR(__FILE__, __LINE__, + "interface iteration failed: %s", + isc_result_totext(result)); + else + result = ISC_R_SUCCESS; + cleanup_iter: + isc_interfaceiter_destroy(&iter); + return (result); +} + +static void +ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, + isc_boolean_t verbose) +{ + isc_boolean_t purge = ISC_TRUE; + + REQUIRE(NS_INTERFACEMGR_VALID(mgr)); + + mgr->generation++; /* Increment the generation count. */ + + if (do_scan(mgr, ext_listen, verbose) != ISC_R_SUCCESS) + purge = ISC_FALSE; + + /* + * Now go through the interface list and delete anything that + * does not have the current generation number. This is + * how we catch interfaces that go away or change their + * addresses. + */ + if (purge) + purge_old_interfaces(mgr); + + /* + * Warn if we are not listening on any interface, unless + * we're in lwresd-only mode, in which case that is to + * be expected. + */ + if (ext_listen == NULL && + ISC_LIST_EMPTY(mgr->interfaces) && ! ns_g_lwresdonly) { + isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING, + "not listening on any interfaces"); + } +} + +void +ns_interfacemgr_scan(ns_interfacemgr_t *mgr, isc_boolean_t verbose) { + ns_interfacemgr_scan0(mgr, NULL, verbose); +} + +void +ns_interfacemgr_adjust(ns_interfacemgr_t *mgr, ns_listenlist_t *list, + isc_boolean_t verbose) +{ + ns_interfacemgr_scan0(mgr, list, verbose); +} + +void +ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value) { + LOCK(&mgr->lock); + ns_listenlist_detach(&mgr->listenon4); + ns_listenlist_attach(value, &mgr->listenon4); + UNLOCK(&mgr->lock); +} + +void +ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value) { + LOCK(&mgr->lock); + ns_listenlist_detach(&mgr->listenon6); + ns_listenlist_attach(value, &mgr->listenon6); + UNLOCK(&mgr->lock); +} + +void +ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr) { + ns_interface_t *interface; + + LOCK(&mgr->lock); + interface = ISC_LIST_HEAD(mgr->interfaces); + while (interface != NULL) { + if (interface->clientmgr != NULL) + ns_client_dumprecursing(f, interface->clientmgr); + interface = ISC_LIST_NEXT(interface, link); + } + UNLOCK(&mgr->lock); +} + +isc_boolean_t +ns_interfacemgr_listeningon(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) { + isc_sockaddr_t *old; + + old = ISC_LIST_HEAD(mgr->listenon); + for (old = ISC_LIST_HEAD(mgr->listenon); + old != NULL; + old = ISC_LIST_NEXT(old, link)) + if (isc_sockaddr_equal(old, addr)) + return (ISC_TRUE); + return (ISC_FALSE); +} diff --git a/bin/named/listenlist.c b/bin/named/listenlist.c new file mode 100644 index 0000000..7e70ac9 --- /dev/null +++ b/bin/named/listenlist.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: listenlist.c,v 1.10.18.2 2005/04/29 00:15:22 marka Exp $ */ + +/*! \file */ + +#include + +#include +#include + +#include + +#include + +static void +destroy(ns_listenlist_t *list); + +isc_result_t +ns_listenelt_create(isc_mem_t *mctx, in_port_t port, + dns_acl_t *acl, ns_listenelt_t **target) +{ + ns_listenelt_t *elt = NULL; + REQUIRE(target != NULL && *target == NULL); + elt = isc_mem_get(mctx, sizeof(*elt)); + if (elt == NULL) + return (ISC_R_NOMEMORY); + elt->mctx = mctx; + ISC_LINK_INIT(elt, link); + elt->port = port; + elt->acl = acl; + *target = elt; + return (ISC_R_SUCCESS); +} + +void +ns_listenelt_destroy(ns_listenelt_t *elt) { + if (elt->acl != NULL) + dns_acl_detach(&elt->acl); + isc_mem_put(elt->mctx, elt, sizeof(*elt)); +} + +isc_result_t +ns_listenlist_create(isc_mem_t *mctx, ns_listenlist_t **target) { + ns_listenlist_t *list = NULL; + REQUIRE(target != NULL && *target == NULL); + list = isc_mem_get(mctx, sizeof(*list)); + if (list == NULL) + return (ISC_R_NOMEMORY); + list->mctx = mctx; + list->refcount = 1; + ISC_LIST_INIT(list->elts); + *target = list; + return (ISC_R_SUCCESS); +} + +static void +destroy(ns_listenlist_t *list) { + ns_listenelt_t *elt, *next; + for (elt = ISC_LIST_HEAD(list->elts); + elt != NULL; + elt = next) + { + next = ISC_LIST_NEXT(elt, link); + ns_listenelt_destroy(elt); + } + isc_mem_put(list->mctx, list, sizeof(*list)); +} + +void +ns_listenlist_attach(ns_listenlist_t *source, ns_listenlist_t **target) { + INSIST(source->refcount > 0); + source->refcount++; + *target = source; +} + +void +ns_listenlist_detach(ns_listenlist_t **listp) { + ns_listenlist_t *list = *listp; + INSIST(list->refcount > 0); + list->refcount--; + if (list->refcount == 0) + destroy(list); + *listp = NULL; +} + +isc_result_t +ns_listenlist_default(isc_mem_t *mctx, in_port_t port, + isc_boolean_t enabled, ns_listenlist_t **target) +{ + isc_result_t result; + dns_acl_t *acl = NULL; + ns_listenelt_t *elt = NULL; + ns_listenlist_t *list = NULL; + + REQUIRE(target != NULL && *target == NULL); + if (enabled) + result = dns_acl_any(mctx, &acl); + else + result = dns_acl_none(mctx, &acl); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = ns_listenelt_create(mctx, port, acl, &elt); + if (result != ISC_R_SUCCESS) + goto cleanup_acl; + + result = ns_listenlist_create(mctx, &list); + if (result != ISC_R_SUCCESS) + goto cleanup_listenelt; + + ISC_LIST_APPEND(list->elts, elt, link); + + *target = list; + return (ISC_R_SUCCESS); + + cleanup_listenelt: + ns_listenelt_destroy(elt); + cleanup_acl: + dns_acl_detach(&acl); + cleanup: + return (result); +} diff --git a/bin/named/log.c b/bin/named/log.c new file mode 100644 index 0000000..af75bab --- /dev/null +++ b/bin/named/log.c @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2002 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: log.c,v 1.37.18.6 2006/06/09 00:54:08 marka Exp $ */ + +/*! \file */ + +#include + +#include + +#include + +#include + +#ifndef ISC_FACILITY +#define ISC_FACILITY LOG_DAEMON +#endif + +/*% + * When adding a new category, be sure to add the appropriate + * #define to and to update the list in + * bin/check/check-tool.c. + */ +static isc_logcategory_t categories[] = { + { "", 0 }, + { "client", 0 }, + { "network", 0 }, + { "update", 0 }, + { "queries", 0 }, + { "unmatched", 0 }, + { "update-security", 0 }, + { NULL, 0 } +}; + +/*% + * When adding a new module, be sure to add the appropriate + * #define to . + */ +static isc_logmodule_t modules[] = { + { "main", 0 }, + { "client", 0 }, + { "server", 0 }, + { "query", 0 }, + { "interfacemgr", 0 }, + { "update", 0 }, + { "xfer-in", 0 }, + { "xfer-out", 0 }, + { "notify", 0 }, + { "control", 0 }, + { "lwresd", 0 }, + { NULL, 0 } +}; + +isc_result_t +ns_log_init(isc_boolean_t safe) { + isc_result_t result; + isc_logconfig_t *lcfg = NULL; + + ns_g_categories = categories; + ns_g_modules = modules; + + /* + * Setup a logging context. + */ + result = isc_log_create(ns_g_mctx, &ns_g_lctx, &lcfg); + if (result != ISC_R_SUCCESS) + return (result); + + /* + * named-checktool.c:setup_logging() needs to be kept in sync. + */ + isc_log_registercategories(ns_g_lctx, ns_g_categories); + isc_log_registermodules(ns_g_lctx, ns_g_modules); + isc_log_setcontext(ns_g_lctx); + dns_log_init(ns_g_lctx); + dns_log_setcontext(ns_g_lctx); + cfg_log_init(ns_g_lctx); + + if (safe) + result = ns_log_setsafechannels(lcfg); + else + result = ns_log_setdefaultchannels(lcfg); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = ns_log_setdefaultcategory(lcfg); + if (result != ISC_R_SUCCESS) + goto cleanup; + + return (ISC_R_SUCCESS); + + cleanup: + isc_log_destroy(&ns_g_lctx); + isc_log_setcontext(NULL); + dns_log_setcontext(NULL); + + return (result); +} + +isc_result_t +ns_log_setdefaultchannels(isc_logconfig_t *lcfg) { + isc_result_t result; + isc_logdestination_t destination; + + /* + * By default, the logging library makes "default_debug" log to + * stderr. In BIND, we want to override this and log to named.run + * instead, unless the the -g option was given. + */ + if (! ns_g_logstderr) { + destination.file.stream = NULL; + destination.file.name = "named.run"; + destination.file.versions = ISC_LOG_ROLLNEVER; + destination.file.maximum_size = 0; + result = isc_log_createchannel(lcfg, "default_debug", + ISC_LOG_TOFILE, + ISC_LOG_DYNAMIC, + &destination, + ISC_LOG_PRINTTIME| + ISC_LOG_DEBUGONLY); + if (result != ISC_R_SUCCESS) + goto cleanup; + } + +#if ISC_FACILITY != LOG_DAEMON + destination.facility = ISC_FACILITY; + result = isc_log_createchannel(lcfg, "default_syslog", + ISC_LOG_TOSYSLOG, ISC_LOG_INFO, + &destination, 0); + if (result != ISC_R_SUCCESS) + goto cleanup; +#endif + + /* + * Set the initial debug level. + */ + isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); + + result = ISC_R_SUCCESS; + + cleanup: + return (result); +} + +isc_result_t +ns_log_setsafechannels(isc_logconfig_t *lcfg) { + isc_result_t result; +#if ISC_FACILITY != LOG_DAEMON + isc_logdestination_t destination; +#endif + + if (! ns_g_logstderr) { + result = isc_log_createchannel(lcfg, "default_debug", + ISC_LOG_TONULL, + ISC_LOG_DYNAMIC, + NULL, 0); + if (result != ISC_R_SUCCESS) + goto cleanup; + + /* + * Setting the debug level to zero should get the output + * discarded a bit faster. + */ + isc_log_setdebuglevel(ns_g_lctx, 0); + } else { + isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); + } + +#if ISC_FACILITY != LOG_DAEMON + destination.facility = ISC_FACILITY; + result = isc_log_createchannel(lcfg, "default_syslog", + ISC_LOG_TOSYSLOG, ISC_LOG_INFO, + &destination, 0); + if (result != ISC_R_SUCCESS) + goto cleanup; +#endif + + result = ISC_R_SUCCESS; + + cleanup: + return (result); +} + +isc_result_t +ns_log_setdefaultcategory(isc_logconfig_t *lcfg) { + isc_result_t result; + + if (! ns_g_logstderr) { + result = isc_log_usechannel(lcfg, "default_syslog", + ISC_LOGCATEGORY_DEFAULT, NULL); + if (result != ISC_R_SUCCESS) + goto cleanup; + } + + result = isc_log_usechannel(lcfg, "default_debug", + ISC_LOGCATEGORY_DEFAULT, NULL); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = ISC_R_SUCCESS; + + cleanup: + return (result); +} + +isc_result_t +ns_log_setunmatchedcategory(isc_logconfig_t *lcfg) { + isc_result_t result; + + result = isc_log_usechannel(lcfg, "null", + NS_LOGCATEGORY_UNMATCHED, NULL); + return (result); +} + +void +ns_log_shutdown(void) { + isc_log_destroy(&ns_g_lctx); + isc_log_setcontext(NULL); + dns_log_setcontext(NULL); +} diff --git a/bin/named/logconf.c b/bin/named/logconf.c new file mode 100644 index 0000000..ce815f4 --- /dev/null +++ b/bin/named/logconf.c @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: logconf.c,v 1.35.18.5 2006/03/02 00:37:21 marka Exp $ */ + +/*! \file */ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#define CHECK(op) \ + do { result = (op); \ + if (result != ISC_R_SUCCESS) goto cleanup; \ + } while (0) + +/*% + * Set up a logging category according to the named.conf data + * in 'ccat' and add it to 'lctx'. + */ +static isc_result_t +category_fromconf(const cfg_obj_t *ccat, isc_logconfig_t *lctx) { + isc_result_t result; + const char *catname; + isc_logcategory_t *category; + isc_logmodule_t *module; + const cfg_obj_t *destinations = NULL; + const cfg_listelt_t *element = NULL; + + catname = cfg_obj_asstring(cfg_tuple_get(ccat, "name")); + category = isc_log_categorybyname(ns_g_lctx, catname); + if (category == NULL) { + cfg_obj_log(ccat, ns_g_lctx, ISC_LOG_ERROR, + "unknown logging category '%s' ignored", + catname); + /* + * Allow further processing by returning success. + */ + return (ISC_R_SUCCESS); + } + + module = NULL; + + destinations = cfg_tuple_get(ccat, "destinations"); + for (element = cfg_list_first(destinations); + element != NULL; + element = cfg_list_next(element)) + { + const cfg_obj_t *channel = cfg_listelt_value(element); + const char *channelname = cfg_obj_asstring(channel); + + result = isc_log_usechannel(lctx, channelname, category, + module); + if (result != ISC_R_SUCCESS) { + isc_log_write(ns_g_lctx, CFG_LOGCATEGORY_CONFIG, + NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "logging channel '%s': %s", channelname, + isc_result_totext(result)); + return (result); + } + } + return (ISC_R_SUCCESS); +} + +/*% + * Set up a logging channel according to the named.conf data + * in 'cchan' and add it to 'lctx'. + */ +static isc_result_t +channel_fromconf(const cfg_obj_t *channel, isc_logconfig_t *lctx) { + isc_result_t result; + isc_logdestination_t dest; + unsigned int type; + unsigned int flags = 0; + int level; + const char *channelname; + const cfg_obj_t *fileobj = NULL; + const cfg_obj_t *syslogobj = NULL; + const cfg_obj_t *nullobj = NULL; + const cfg_obj_t *stderrobj = NULL; + const cfg_obj_t *severity = NULL; + int i; + + channelname = cfg_obj_asstring(cfg_map_getname(channel)); + + (void)cfg_map_get(channel, "file", &fileobj); + (void)cfg_map_get(channel, "syslog", &syslogobj); + (void)cfg_map_get(channel, "null", &nullobj); + (void)cfg_map_get(channel, "stderr", &stderrobj); + + i = 0; + if (fileobj != NULL) + i++; + if (syslogobj != NULL) + i++; + if (nullobj != NULL) + i++; + if (stderrobj != NULL) + i++; + + if (i != 1) { + cfg_obj_log(channel, ns_g_lctx, ISC_LOG_ERROR, + "channel '%s': exactly one of file, syslog, " + "null, and stderr must be present", channelname); + return (ISC_R_FAILURE); + } + + type = ISC_LOG_TONULL; + + if (fileobj != NULL) { + const cfg_obj_t *pathobj = cfg_tuple_get(fileobj, "file"); + const cfg_obj_t *sizeobj = cfg_tuple_get(fileobj, "size"); + const cfg_obj_t *versionsobj = + cfg_tuple_get(fileobj, "versions"); + isc_int32_t versions = ISC_LOG_ROLLNEVER; + isc_offset_t size = 0; + + type = ISC_LOG_TOFILE; + + if (versionsobj != NULL && cfg_obj_isuint32(versionsobj)) + versions = cfg_obj_asuint32(versionsobj); + if (versionsobj != NULL && cfg_obj_isstring(versionsobj) && + strcasecmp(cfg_obj_asstring(versionsobj), "unlimited") == 0) + versions = ISC_LOG_ROLLINFINITE; + if (sizeobj != NULL && + cfg_obj_isuint64(sizeobj) && + cfg_obj_asuint64(sizeobj) < ISC_OFFSET_MAXIMUM) + size = (isc_offset_t)cfg_obj_asuint64(sizeobj); + dest.file.stream = NULL; + dest.file.name = cfg_obj_asstring(pathobj); + dest.file.versions = versions; + dest.file.maximum_size = size; + } else if (syslogobj != NULL) { + int facility = LOG_DAEMON; + + type = ISC_LOG_TOSYSLOG; + + if (cfg_obj_isstring(syslogobj)) { + const char *facilitystr = cfg_obj_asstring(syslogobj); + (void)isc_syslog_facilityfromstring(facilitystr, + &facility); + } + dest.facility = facility; + } else if (stderrobj != NULL) { + type = ISC_LOG_TOFILEDESC; + dest.file.stream = stderr; + dest.file.name = NULL; + dest.file.versions = ISC_LOG_ROLLNEVER; + dest.file.maximum_size = 0; + } + + /* + * Munge flags. + */ + { + const cfg_obj_t *printcat = NULL; + const cfg_obj_t *printsev = NULL; + const cfg_obj_t *printtime = NULL; + + (void)cfg_map_get(channel, "print-category", &printcat); + (void)cfg_map_get(channel, "print-severity", &printsev); + (void)cfg_map_get(channel, "print-time", &printtime); + + if (printcat != NULL && cfg_obj_asboolean(printcat)) + flags |= ISC_LOG_PRINTCATEGORY; + if (printtime != NULL && cfg_obj_asboolean(printtime)) + flags |= ISC_LOG_PRINTTIME; + if (printsev != NULL && cfg_obj_asboolean(printsev)) + flags |= ISC_LOG_PRINTLEVEL; + } + + level = ISC_LOG_INFO; + if (cfg_map_get(channel, "severity", &severity) == ISC_R_SUCCESS) { + if (cfg_obj_isstring(severity)) { + const char *str = cfg_obj_asstring(severity); + if (strcasecmp(str, "critical") == 0) + level = ISC_LOG_CRITICAL; + else if (strcasecmp(str, "error") == 0) + level = ISC_LOG_ERROR; + else if (strcasecmp(str, "warning") == 0) + level = ISC_LOG_WARNING; + else if (strcasecmp(str, "notice") == 0) + level = ISC_LOG_NOTICE; + else if (strcasecmp(str, "info") == 0) + level = ISC_LOG_INFO; + else if (strcasecmp(str, "dynamic") == 0) + level = ISC_LOG_DYNAMIC; + } else + /* debug */ + level = cfg_obj_asuint32(severity); + } + + result = isc_log_createchannel(lctx, channelname, + type, level, &dest, flags); + + if (result == ISC_R_SUCCESS && type == ISC_LOG_TOFILE) { + FILE *fp; + + /* + * Test that the file can be opened, since isc_log_open() + * can't effectively report failures when called in + * isc_log_doit(). + */ + result = isc_stdio_open(dest.file.name, "a", &fp); + if (result != ISC_R_SUCCESS) + isc_log_write(ns_g_lctx, CFG_LOGCATEGORY_CONFIG, + NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "logging channel '%s' file '%s': %s", + channelname, dest.file.name, + isc_result_totext(result)); + else + (void)isc_stdio_close(fp); + + /* + * Allow named to continue by returning success. + */ + result = ISC_R_SUCCESS; + } + + return (result); +} + +isc_result_t +ns_log_configure(isc_logconfig_t *logconf, const cfg_obj_t *logstmt) { + isc_result_t result; + const cfg_obj_t *channels = NULL; + const cfg_obj_t *categories = NULL; + const cfg_listelt_t *element; + isc_boolean_t default_set = ISC_FALSE; + isc_boolean_t unmatched_set = ISC_FALSE; + const cfg_obj_t *catname; + + CHECK(ns_log_setdefaultchannels(logconf)); + + (void)cfg_map_get(logstmt, "channel", &channels); + for (element = cfg_list_first(channels); + element != NULL; + element = cfg_list_next(element)) + { + const cfg_obj_t *channel = cfg_listelt_value(element); + CHECK(channel_fromconf(channel, logconf)); + } + + (void)cfg_map_get(logstmt, "category", &categories); + for (element = cfg_list_first(categories); + element != NULL; + element = cfg_list_next(element)) + { + const cfg_obj_t *category = cfg_listelt_value(element); + CHECK(category_fromconf(category, logconf)); + if (!default_set) { + catname = cfg_tuple_get(category, "name"); + if (strcmp(cfg_obj_asstring(catname), "default") == 0) + default_set = ISC_TRUE; + } + if (!unmatched_set) { + catname = cfg_tuple_get(category, "name"); + if (strcmp(cfg_obj_asstring(catname), "unmatched") == 0) + unmatched_set = ISC_TRUE; + } + } + + if (!default_set) + CHECK(ns_log_setdefaultcategory(logconf)); + + if (!unmatched_set) + CHECK(ns_log_setunmatchedcategory(logconf)); + + return (ISC_R_SUCCESS); + + cleanup: + if (logconf != NULL) + isc_logconfig_destroy(&logconf); + return (result); +} diff --git a/bin/named/lwaddr.c b/bin/named/lwaddr.c new file mode 100644 index 0000000..78c2b0b --- /dev/null +++ b/bin/named/lwaddr.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: lwaddr.c,v 1.4.18.2 2005/04/29 00:15:23 marka Exp $ */ + +/*! \file */ + +#include + +#include + +#include +#include +#include + +#include + +#include + +/*% + * Convert addresses from lwres to isc format. + */ +isc_result_t +lwaddr_netaddr_fromlwresaddr(isc_netaddr_t *na, lwres_addr_t *la) { + if (la->family != LWRES_ADDRTYPE_V4 && la->family != LWRES_ADDRTYPE_V6) + return (ISC_R_FAMILYNOSUPPORT); + + if (la->family == LWRES_ADDRTYPE_V4) { + struct in_addr ina; + memcpy(&ina.s_addr, la->address, 4); + isc_netaddr_fromin(na, &ina); + } else { + struct in6_addr ina6; + memcpy(&ina6.s6_addr, la->address, 16); + isc_netaddr_fromin6(na, &ina6); + } + return (ISC_R_SUCCESS); +} + +isc_result_t +lwaddr_sockaddr_fromlwresaddr(isc_sockaddr_t *sa, lwres_addr_t *la, + in_port_t port) +{ + isc_netaddr_t na; + isc_result_t result; + + result = lwaddr_netaddr_fromlwresaddr(&na, la); + if (result != ISC_R_SUCCESS) + return (result); + isc_sockaddr_fromnetaddr(sa, &na, port); + return (ISC_R_SUCCESS); +} + +/*% + * Convert addresses from isc to lwres format. + */ + +isc_result_t +lwaddr_lwresaddr_fromnetaddr(lwres_addr_t *la, isc_netaddr_t *na) { + if (na->family != AF_INET && na->family != AF_INET6) + return (ISC_R_FAMILYNOSUPPORT); + + if (na->family == AF_INET) { + la->family = LWRES_ADDRTYPE_V4; + la->length = 4; + memcpy(la->address, &na->type.in, 4); + } else { + la->family = LWRES_ADDRTYPE_V6; + la->length = 16; + memcpy(la->address, &na->type.in, 16); + } + return (ISC_R_SUCCESS); +} + +isc_result_t +lwaddr_lwresaddr_fromsockaddr(lwres_addr_t *la, isc_sockaddr_t *sa) { + isc_netaddr_t na; + isc_netaddr_fromsockaddr(&na, sa); + return (lwaddr_lwresaddr_fromnetaddr(la, &na)); +} diff --git a/bin/named/lwdclient.c b/bin/named/lwdclient.c new file mode 100644 index 0000000..68069ed --- /dev/null +++ b/bin/named/lwdclient.c @@ -0,0 +1,467 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: lwdclient.c,v 1.17.18.2 2005/04/29 00:15:23 marka Exp $ */ + +/*! \file */ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#define SHUTTINGDOWN(cm) ((cm->flags & NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN) != 0) + +static void +lwdclientmgr_shutdown_callback(isc_task_t *task, isc_event_t *ev); + +void +ns_lwdclient_log(int level, const char *format, ...) { + va_list args; + + va_start(args, format); + isc_log_vwrite(dns_lctx, + DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB, + ISC_LOG_DEBUG(level), format, args); + va_end(args); +} + +isc_result_t +ns_lwdclientmgr_create(ns_lwreslistener_t *listener, unsigned int nclients, + isc_taskmgr_t *taskmgr) +{ + ns_lwresd_t *lwresd = listener->manager; + ns_lwdclientmgr_t *cm; + ns_lwdclient_t *client; + unsigned int i; + isc_result_t result = ISC_R_FAILURE; + + cm = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclientmgr_t)); + if (cm == NULL) + return (ISC_R_NOMEMORY); + + cm->listener = NULL; + ns_lwreslistener_attach(listener, &cm->listener); + cm->mctx = lwresd->mctx; + cm->sock = NULL; + isc_socket_attach(listener->sock, &cm->sock); + cm->view = lwresd->view; + cm->lwctx = NULL; + cm->task = NULL; + cm->flags = 0; + ISC_LINK_INIT(cm, link); + ISC_LIST_INIT(cm->idle); + ISC_LIST_INIT(cm->running); + + if (lwres_context_create(&cm->lwctx, cm->mctx, + ns__lwresd_memalloc, ns__lwresd_memfree, + LWRES_CONTEXT_SERVERMODE) + != ISC_R_SUCCESS) + goto errout; + + for (i = 0; i < nclients; i++) { + client = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclient_t)); + if (client != NULL) { + ns_lwdclient_log(50, "created client %p, manager %p", + client, cm); + ns_lwdclient_initialize(client, cm); + } + } + + /* + * If we could create no clients, clean up and return. + */ + if (ISC_LIST_EMPTY(cm->idle)) + goto errout; + + result = isc_task_create(taskmgr, 0, &cm->task); + if (result != ISC_R_SUCCESS) + goto errout; + + /* + * This MUST be last, since there is no way to cancel an onshutdown... + */ + result = isc_task_onshutdown(cm->task, lwdclientmgr_shutdown_callback, + cm); + if (result != ISC_R_SUCCESS) + goto errout; + + ns_lwreslistener_linkcm(listener, cm); + + return (ISC_R_SUCCESS); + + errout: + client = ISC_LIST_HEAD(cm->idle); + while (client != NULL) { + ISC_LIST_UNLINK(cm->idle, client, link); + isc_mem_put(lwresd->mctx, client, sizeof(*client)); + client = ISC_LIST_HEAD(cm->idle); + } + + if (cm->task != NULL) + isc_task_detach(&cm->task); + + if (cm->lwctx != NULL) + lwres_context_destroy(&cm->lwctx); + + isc_mem_put(lwresd->mctx, cm, sizeof(*cm)); + return (result); +} + +static void +lwdclientmgr_destroy(ns_lwdclientmgr_t *cm) { + ns_lwdclient_t *client; + ns_lwreslistener_t *listener; + + if (!SHUTTINGDOWN(cm)) + return; + + /* + * run through the idle list and free the clients there. Idle + * clients do not have a recv running nor do they have any finds + * or similar running. + */ + client = ISC_LIST_HEAD(cm->idle); + while (client != NULL) { + ns_lwdclient_log(50, "destroying client %p, manager %p", + client, cm); + ISC_LIST_UNLINK(cm->idle, client, link); + isc_mem_put(cm->mctx, client, sizeof(*client)); + client = ISC_LIST_HEAD(cm->idle); + } + + if (!ISC_LIST_EMPTY(cm->running)) + return; + + lwres_context_destroy(&cm->lwctx); + cm->view = NULL; + isc_socket_detach(&cm->sock); + isc_task_detach(&cm->task); + + listener = cm->listener; + ns_lwreslistener_unlinkcm(listener, cm); + ns_lwdclient_log(50, "destroying manager %p", cm); + isc_mem_put(cm->mctx, cm, sizeof(*cm)); + ns_lwreslistener_detach(&listener); +} + +static void +process_request(ns_lwdclient_t *client) { + lwres_buffer_t b; + isc_result_t result; + + lwres_buffer_init(&b, client->buffer, client->recvlength); + lwres_buffer_add(&b, client->recvlength); + + result = lwres_lwpacket_parseheader(&b, &client->pkt); + if (result != ISC_R_SUCCESS) { + ns_lwdclient_log(50, "invalid packet header received"); + goto restart; + } + + ns_lwdclient_log(50, "opcode %08x", client->pkt.opcode); + + switch (client->pkt.opcode) { + case LWRES_OPCODE_GETADDRSBYNAME: + ns_lwdclient_processgabn(client, &b); + return; + case LWRES_OPCODE_GETNAMEBYADDR: + ns_lwdclient_processgnba(client, &b); + return; + case LWRES_OPCODE_GETRDATABYNAME: + ns_lwdclient_processgrbn(client, &b); + return; + case LWRES_OPCODE_NOOP: + ns_lwdclient_processnoop(client, &b); + return; + default: + ns_lwdclient_log(50, "unknown opcode %08x", client->pkt.opcode); + goto restart; + } + + /* + * Drop the packet. + */ + restart: + ns_lwdclient_log(50, "restarting client %p...", client); + ns_lwdclient_stateidle(client); +} + +void +ns_lwdclient_recv(isc_task_t *task, isc_event_t *ev) { + isc_result_t result; + ns_lwdclient_t *client = ev->ev_arg; + ns_lwdclientmgr_t *cm = client->clientmgr; + isc_socketevent_t *dev = (isc_socketevent_t *)ev; + + INSIST(dev->region.base == client->buffer); + INSIST(NS_LWDCLIENT_ISRECV(client)); + + NS_LWDCLIENT_SETRECVDONE(client); + + INSIST((cm->flags & NS_LWDCLIENTMGR_FLAGRECVPENDING) != 0); + cm->flags &= ~NS_LWDCLIENTMGR_FLAGRECVPENDING; + + ns_lwdclient_log(50, + "event received: task %p, length %u, result %u (%s)", + task, dev->n, dev->result, + isc_result_totext(dev->result)); + + if (dev->result != ISC_R_SUCCESS) { + isc_event_free(&ev); + dev = NULL; + + /* + * Go idle. + */ + ns_lwdclient_stateidle(client); + + return; + } + + client->recvlength = dev->n; + client->address = dev->address; + if ((dev->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) { + client->pktinfo = dev->pktinfo; + client->pktinfo_valid = ISC_TRUE; + } else + client->pktinfo_valid = ISC_FALSE; + isc_event_free(&ev); + dev = NULL; + + result = ns_lwdclient_startrecv(cm); + if (result != ISC_R_SUCCESS) + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, + "could not start lwres " + "client handler: %s", + isc_result_totext(result)); + + process_request(client); +} + +/* + * This function will start a new recv() on a socket for this client manager. + */ +isc_result_t +ns_lwdclient_startrecv(ns_lwdclientmgr_t *cm) { + ns_lwdclient_t *client; + isc_result_t result; + isc_region_t r; + + if (SHUTTINGDOWN(cm)) { + lwdclientmgr_destroy(cm); + return (ISC_R_SUCCESS); + } + + /* + * If a recv is already running, don't bother. + */ + if ((cm->flags & NS_LWDCLIENTMGR_FLAGRECVPENDING) != 0) + return (ISC_R_SUCCESS); + + /* + * If we have no idle slots, just return success. + */ + client = ISC_LIST_HEAD(cm->idle); + if (client == NULL) + return (ISC_R_SUCCESS); + INSIST(NS_LWDCLIENT_ISIDLE(client)); + + /* + * Issue the recv. If it fails, return that it did. + */ + r.base = client->buffer; + r.length = LWRES_RECVLENGTH; + result = isc_socket_recv(cm->sock, &r, 0, cm->task, ns_lwdclient_recv, + client); + if (result != ISC_R_SUCCESS) + return (result); + + /* + * Set the flag to say we've issued a recv() call. + */ + cm->flags |= NS_LWDCLIENTMGR_FLAGRECVPENDING; + + /* + * Remove the client from the idle list, and put it on the running + * list. + */ + NS_LWDCLIENT_SETRECV(client); + ISC_LIST_UNLINK(cm->idle, client, link); + ISC_LIST_APPEND(cm->running, client, link); + + return (ISC_R_SUCCESS); +} + +static void +lwdclientmgr_shutdown_callback(isc_task_t *task, isc_event_t *ev) { + ns_lwdclientmgr_t *cm = ev->ev_arg; + ns_lwdclient_t *client; + + REQUIRE(!SHUTTINGDOWN(cm)); + + ns_lwdclient_log(50, "got shutdown event, task %p, lwdclientmgr %p", + task, cm); + + /* + * run through the idle list and free the clients there. Idle + * clients do not have a recv running nor do they have any finds + * or similar running. + */ + client = ISC_LIST_HEAD(cm->idle); + while (client != NULL) { + ns_lwdclient_log(50, "destroying client %p, manager %p", + client, cm); + ISC_LIST_UNLINK(cm->idle, client, link); + isc_mem_put(cm->mctx, client, sizeof(*client)); + client = ISC_LIST_HEAD(cm->idle); + } + + /* + * Cancel any pending I/O. + */ + isc_socket_cancel(cm->sock, task, ISC_SOCKCANCEL_ALL); + + /* + * Run through the running client list and kill off any finds + * in progress. + */ + client = ISC_LIST_HEAD(cm->running); + while (client != NULL) { + if (client->find != client->v4find + && client->find != client->v6find) + dns_adb_cancelfind(client->find); + if (client->v4find != NULL) + dns_adb_cancelfind(client->v4find); + if (client->v6find != NULL) + dns_adb_cancelfind(client->v6find); + client = ISC_LIST_NEXT(client, link); + } + + cm->flags |= NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN; + + isc_event_free(&ev); +} + +/* + * Do all the crap needed to move a client from the run queue to the idle + * queue. + */ +void +ns_lwdclient_stateidle(ns_lwdclient_t *client) { + ns_lwdclientmgr_t *cm; + isc_result_t result; + + cm = client->clientmgr; + + INSIST(client->sendbuf == NULL); + INSIST(client->sendlength == 0); + INSIST(client->arg == NULL); + INSIST(client->v4find == NULL); + INSIST(client->v6find == NULL); + + ISC_LIST_UNLINK(cm->running, client, link); + ISC_LIST_PREPEND(cm->idle, client, link); + + NS_LWDCLIENT_SETIDLE(client); + + result = ns_lwdclient_startrecv(cm); + if (result != ISC_R_SUCCESS) + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, + "could not start lwres " + "client handler: %s", + isc_result_totext(result)); +} + +void +ns_lwdclient_send(isc_task_t *task, isc_event_t *ev) { + ns_lwdclient_t *client = ev->ev_arg; + ns_lwdclientmgr_t *cm = client->clientmgr; + isc_socketevent_t *dev = (isc_socketevent_t *)ev; + + UNUSED(task); + UNUSED(dev); + + INSIST(NS_LWDCLIENT_ISSEND(client)); + INSIST(client->sendbuf == dev->region.base); + + ns_lwdclient_log(50, "task %p for client %p got send-done event", + task, client); + + if (client->sendbuf != client->buffer) + lwres_context_freemem(cm->lwctx, client->sendbuf, + client->sendlength); + client->sendbuf = NULL; + client->sendlength = 0; + + ns_lwdclient_stateidle(client); + + isc_event_free(&ev); +} + +isc_result_t +ns_lwdclient_sendreply(ns_lwdclient_t *client, isc_region_t *r) { + struct in6_pktinfo *pktinfo; + ns_lwdclientmgr_t *cm = client->clientmgr; + + if (client->pktinfo_valid) + pktinfo = &client->pktinfo; + else + pktinfo = NULL; + return (isc_socket_sendto(cm->sock, r, cm->task, ns_lwdclient_send, + client, &client->address, pktinfo)); +} + +void +ns_lwdclient_initialize(ns_lwdclient_t *client, ns_lwdclientmgr_t *cmgr) { + client->clientmgr = cmgr; + ISC_LINK_INIT(client, link); + NS_LWDCLIENT_SETIDLE(client); + client->arg = NULL; + + client->recvlength = 0; + + client->sendbuf = NULL; + client->sendlength = 0; + + client->find = NULL; + client->v4find = NULL; + client->v6find = NULL; + client->find_wanted = 0; + + client->options = 0; + client->byaddr = NULL; + + client->lookup = NULL; + + client->pktinfo_valid = ISC_FALSE; + + ISC_LIST_APPEND(cmgr->idle, client, link); +} diff --git a/bin/named/lwderror.c b/bin/named/lwderror.c new file mode 100644 index 0000000..db25824 --- /dev/null +++ b/bin/named/lwderror.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: lwderror.c,v 1.8.18.2 2005/04/29 00:15:24 marka Exp $ */ + +/*! \file */ + +#include + +#include +#include + +#include +#include + +/*% + * Generate an error packet for the client, schedule a send, and put us in + * the SEND state. + * + * The client->pkt structure will be modified to form an error return. + * The receiver needs to verify that it is in fact an error, and do the + * right thing with it. The opcode will be unchanged. The result needs + * to be set before calling this function. + * + * The only change this code makes is to set the receive buffer size to the + * size we use, set the reply bit, and recompute any security information. + */ +void +ns_lwdclient_errorpktsend(ns_lwdclient_t *client, isc_uint32_t _result) { + isc_result_t result; + int lwres; + isc_region_t r; + lwres_buffer_t b; + + REQUIRE(NS_LWDCLIENT_ISRUNNING(client)); + + /* + * Since we are only sending the packet header, we can safely toss + * the receive buffer. This means we won't need to allocate space + * for sending an error reply. This is a Good Thing. + */ + client->pkt.length = LWRES_LWPACKET_LENGTH; + client->pkt.pktflags |= LWRES_LWPACKETFLAG_RESPONSE; + client->pkt.recvlength = LWRES_RECVLENGTH; + client->pkt.authtype = 0; /* XXXMLG */ + client->pkt.authlength = 0; + client->pkt.result = _result; + + lwres_buffer_init(&b, client->buffer, LWRES_RECVLENGTH); + lwres = lwres_lwpacket_renderheader(&b, &client->pkt); + if (lwres != LWRES_R_SUCCESS) { + ns_lwdclient_stateidle(client); + return; + } + + r.base = client->buffer; + r.length = b.used; + client->sendbuf = client->buffer; + result = ns_lwdclient_sendreply(client, &r); + if (result != ISC_R_SUCCESS) { + ns_lwdclient_stateidle(client); + return; + } + + NS_LWDCLIENT_SETSEND(client); +} diff --git a/bin/named/lwdgabn.c b/bin/named/lwdgabn.c new file mode 100644 index 0000000..454d4df --- /dev/null +++ b/bin/named/lwdgabn.c @@ -0,0 +1,657 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: lwdgabn.c,v 1.15.18.5 2006/03/02 00:37:21 marka Exp $ */ + +/*! \file */ + +#include + +#include + +#include +#include +#include +#include /* Required for HP/UX (and others?) */ +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define NEED_V4(c) ((((c)->find_wanted & LWRES_ADDRTYPE_V4) != 0) \ + && ((c)->v4find == NULL)) +#define NEED_V6(c) ((((c)->find_wanted & LWRES_ADDRTYPE_V6) != 0) \ + && ((c)->v6find == NULL)) + +static isc_result_t start_find(ns_lwdclient_t *); +static void restart_find(ns_lwdclient_t *); +static void init_gabn(ns_lwdclient_t *); + +/*% + * Destroy any finds. This can be used to "start over from scratch" and + * should only be called when events are _not_ being generated by the finds. + */ +static void +cleanup_gabn(ns_lwdclient_t *client) { + ns_lwdclient_log(50, "cleaning up client %p", client); + + if (client->v6find != NULL) { + if (client->v6find == client->v4find) + client->v6find = NULL; + else + dns_adb_destroyfind(&client->v6find); + } + if (client->v4find != NULL) + dns_adb_destroyfind(&client->v4find); +} + +static void +setup_addresses(ns_lwdclient_t *client, dns_adbfind_t *find, unsigned int at) { + dns_adbaddrinfo_t *ai; + lwres_addr_t *addr; + int af; + const struct sockaddr *sa; + isc_result_t result; + + if (at == DNS_ADBFIND_INET) + af = AF_INET; + else + af = AF_INET6; + + ai = ISC_LIST_HEAD(find->list); + while (ai != NULL && client->gabn.naddrs < LWRES_MAX_ADDRS) { + sa = &ai->sockaddr.type.sa; + if (sa->sa_family != af) + goto next; + + addr = &client->addrs[client->gabn.naddrs]; + + result = lwaddr_lwresaddr_fromsockaddr(addr, &ai->sockaddr); + if (result != ISC_R_SUCCESS) + goto next; + + ns_lwdclient_log(50, "adding address %p, family %d, length %d", + addr->address, addr->family, addr->length); + + client->gabn.naddrs++; + REQUIRE(!LWRES_LINK_LINKED(addr, link)); + LWRES_LIST_APPEND(client->gabn.addrs, addr, link); + + next: + ai = ISC_LIST_NEXT(ai, publink); + } +} + +typedef struct { + isc_netaddr_t address; + int rank; +} rankedaddress; + +static int +addr_compare(const void *av, const void *bv) { + const rankedaddress *a = (const rankedaddress *) av; + const rankedaddress *b = (const rankedaddress *) bv; + return (a->rank - b->rank); +} + +static void +sort_addresses(ns_lwdclient_t *client) { + unsigned int naddrs; + rankedaddress *addrs; + isc_netaddr_t remote; + dns_addressorderfunc_t order; + const void *arg; + ns_lwresd_t *lwresd = client->clientmgr->listener->manager; + unsigned int i; + isc_result_t result; + + naddrs = client->gabn.naddrs; + + if (naddrs <= 1 || lwresd->view->sortlist == NULL) + return; + + addrs = isc_mem_get(lwresd->mctx, sizeof(rankedaddress) * naddrs); + if (addrs == NULL) + return; + + isc_netaddr_fromsockaddr(&remote, &client->address); + ns_sortlist_byaddrsetup(lwresd->view->sortlist, + &remote, &order, &arg); + if (order == NULL) { + isc_mem_put(lwresd->mctx, addrs, + sizeof(rankedaddress) * naddrs); + return; + } + for (i = 0; i < naddrs; i++) { + result = lwaddr_netaddr_fromlwresaddr(&addrs[i].address, + &client->addrs[i]); + INSIST(result == ISC_R_SUCCESS); + addrs[i].rank = (*order)(&addrs[i].address, arg); + } + qsort(addrs, naddrs, sizeof(rankedaddress), addr_compare); + for (i = 0; i < naddrs; i++) { + result = lwaddr_lwresaddr_fromnetaddr(&client->addrs[i], + &addrs[i].address); + INSIST(result == ISC_R_SUCCESS); + } + + isc_mem_put(lwresd->mctx, addrs, sizeof(rankedaddress) * naddrs); +} + +static void +generate_reply(ns_lwdclient_t *client) { + isc_result_t result; + int lwres; + isc_region_t r; + lwres_buffer_t lwb; + ns_lwdclientmgr_t *cm; + + cm = client->clientmgr; + lwb.base = NULL; + + ns_lwdclient_log(50, "generating gabn reply for client %p", client); + + /* + * We must make certain the client->find is not still active. + * If it is either the v4 or v6 answer, just set it to NULL and + * let the cleanup code destroy it. Otherwise, destroy it now. + */ + if (client->find == client->v4find || client->find == client->v6find) + client->find = NULL; + else + if (client->find != NULL) + dns_adb_destroyfind(&client->find); + + /* + * perhaps there are some here? + */ + if (NEED_V6(client) && client->v4find != NULL) + client->v6find = client->v4find; + + /* + * Run through the finds we have and wire them up to the gabn + * structure. + */ + LWRES_LIST_INIT(client->gabn.addrs); + if (client->v4find != NULL) + setup_addresses(client, client->v4find, DNS_ADBFIND_INET); + if (client->v6find != NULL) + setup_addresses(client, client->v6find, DNS_ADBFIND_INET6); + + /* + * If there are no addresses, try the next element in the search + * path, if there are any more. Otherwise, fall through into + * the error handling code below. + */ + if (client->gabn.naddrs == 0) { + do { + result = ns_lwsearchctx_next(&client->searchctx); + if (result == ISC_R_SUCCESS) { + cleanup_gabn(client); + result = start_find(client); + if (result == ISC_R_SUCCESS) + return; + } + } while (result == ISC_R_SUCCESS); + } + + /* + * Render the packet. + */ + client->pkt.recvlength = LWRES_RECVLENGTH; + client->pkt.authtype = 0; /* XXXMLG */ + client->pkt.authlength = 0; + + /* + * If there are no addresses, return failure. + */ + if (client->gabn.naddrs != 0) + client->pkt.result = LWRES_R_SUCCESS; + else + client->pkt.result = LWRES_R_NOTFOUND; + + sort_addresses(client); + + lwres = lwres_gabnresponse_render(cm->lwctx, &client->gabn, + &client->pkt, &lwb); + if (lwres != LWRES_R_SUCCESS) + goto out; + + r.base = lwb.base; + r.length = lwb.used; + client->sendbuf = r.base; + client->sendlength = r.length; + result = ns_lwdclient_sendreply(client, &r); + if (result != ISC_R_SUCCESS) + goto out; + + NS_LWDCLIENT_SETSEND(client); + + /* + * All done! + */ + cleanup_gabn(client); + + return; + + out: + cleanup_gabn(client); + + if (lwb.base != NULL) + lwres_context_freemem(client->clientmgr->lwctx, + lwb.base, lwb.length); + + ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); +} + +/* + * Take the current real name, move it to an alias slot (if any are + * open) then put this new name in as the real name for the target. + * + * Return success if it can be rendered, otherwise failure. Note that + * not having enough alias slots open is NOT a failure. + */ +static isc_result_t +add_alias(ns_lwdclient_t *client) { + isc_buffer_t b; + isc_result_t result; + isc_uint16_t naliases; + + b = client->recv_buffer; + + /* + * Render the new name to the buffer. + */ + result = dns_name_totext(dns_fixedname_name(&client->target_name), + ISC_TRUE, &client->recv_buffer); + if (result != ISC_R_SUCCESS) + return (result); + + /* + * Are there any open slots? + */ + naliases = client->gabn.naliases; + if (naliases < LWRES_MAX_ALIASES) { + client->gabn.aliases[naliases] = client->gabn.realname; + client->gabn.aliaslen[naliases] = client->gabn.realnamelen; + client->gabn.naliases++; + } + + /* + * Save this name away as the current real name. + */ + client->gabn.realname = (char *)(b.base) + b.used; + client->gabn.realnamelen = client->recv_buffer.used - b.used; + + return (ISC_R_SUCCESS); +} + +static isc_result_t +store_realname(ns_lwdclient_t *client) { + isc_buffer_t b; + isc_result_t result; + dns_name_t *tname; + + b = client->recv_buffer; + + tname = dns_fixedname_name(&client->target_name); + result = ns_lwsearchctx_current(&client->searchctx, tname); + if (result != ISC_R_SUCCESS) + return (result); + + /* + * Render the new name to the buffer. + */ + result = dns_name_totext(tname, ISC_TRUE, &client->recv_buffer); + if (result != ISC_R_SUCCESS) + return (result); + + /* + * Save this name away as the current real name. + */ + client->gabn.realname = (char *) b.base + b.used; + client->gabn.realnamelen = client->recv_buffer.used - b.used; + + return (ISC_R_SUCCESS); +} + +static void +process_gabn_finddone(isc_task_t *task, isc_event_t *ev) { + ns_lwdclient_t *client = ev->ev_arg; + isc_eventtype_t evtype; + isc_boolean_t claimed; + + ns_lwdclient_log(50, "find done for task %p, client %p", task, client); + + evtype = ev->ev_type; + isc_event_free(&ev); + + /* + * No more info to be had? If so, we have all the good stuff + * right now, so we can render things. + */ + claimed = ISC_FALSE; + if (evtype == DNS_EVENT_ADBNOMOREADDRESSES) { + if (NEED_V4(client)) { + client->v4find = client->find; + claimed = ISC_TRUE; + } + if (NEED_V6(client)) { + client->v6find = client->find; + claimed = ISC_TRUE; + } + if (client->find != NULL) { + if (claimed) + client->find = NULL; + else + dns_adb_destroyfind(&client->find); + + } + generate_reply(client); + return; + } + + /* + * We probably don't need this find anymore. We're either going to + * reissue it, or an error occurred. Either way, we're done with + * it. + */ + if ((client->find != client->v4find) + && (client->find != client->v6find)) { + dns_adb_destroyfind(&client->find); + } else { + client->find = NULL; + } + + /* + * We have some new information we can gather. Run off and fetch + * it. + */ + if (evtype == DNS_EVENT_ADBMOREADDRESSES) { + restart_find(client); + return; + } + + /* + * An error or other strangeness happened. Drop this query. + */ + cleanup_gabn(client); + ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); +} + +static void +restart_find(ns_lwdclient_t *client) { + unsigned int options; + isc_result_t result; + isc_boolean_t claimed; + + ns_lwdclient_log(50, "starting find for client %p", client); + + /* + * Issue a find for the name contained in the request. We won't + * set the bit that says "anything is good enough" -- we want it + * all. + */ + options = 0; + options |= DNS_ADBFIND_WANTEVENT; + options |= DNS_ADBFIND_RETURNLAME; + + /* + * Set the bits up here to mark that we want this address family + * and that we do not currently have a find pending. We will + * set that bit again below if it turns out we will get an event. + */ + if (NEED_V4(client)) + options |= DNS_ADBFIND_INET; + if (NEED_V6(client)) + options |= DNS_ADBFIND_INET6; + + find_again: + INSIST(client->find == NULL); + result = dns_adb_createfind(client->clientmgr->view->adb, + client->clientmgr->task, + process_gabn_finddone, client, + dns_fixedname_name(&client->target_name), + dns_rootname, 0, options, 0, + dns_fixedname_name(&client->target_name), + client->clientmgr->view->dstport, + &client->find); + + /* + * Did we get an alias? If so, save it and re-issue the query. + */ + if (result == DNS_R_ALIAS) { + ns_lwdclient_log(50, "found alias, restarting query"); + dns_adb_destroyfind(&client->find); + cleanup_gabn(client); + result = add_alias(client); + if (result != ISC_R_SUCCESS) { + ns_lwdclient_log(50, + "out of buffer space adding alias"); + ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); + return; + } + goto find_again; + } + + ns_lwdclient_log(50, "find returned %d (%s)", result, + isc_result_totext(result)); + + /* + * Did we get an error? + */ + if (result != ISC_R_SUCCESS) { + if (client->find != NULL) + dns_adb_destroyfind(&client->find); + cleanup_gabn(client); + ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); + return; + } + + claimed = ISC_FALSE; + + /* + * Did we get our answer to V4 addresses? + */ + if (NEED_V4(client) + && ((client->find->query_pending & DNS_ADBFIND_INET) == 0)) { + ns_lwdclient_log(50, "client %p ipv4 satisfied by find %p", + client, client->find); + claimed = ISC_TRUE; + client->v4find = client->find; + } + + /* + * Did we get our answer to V6 addresses? + */ + if (NEED_V6(client) + && ((client->find->query_pending & DNS_ADBFIND_INET6) == 0)) { + ns_lwdclient_log(50, "client %p ipv6 satisfied by find %p", + client, client->find); + claimed = ISC_TRUE; + client->v6find = client->find; + } + + /* + * If we're going to get an event, set our internal pending flag + * and return. When we get an event back we'll do the right + * thing, basically by calling this function again, perhaps with a + * new target name. + * + * If we have both v4 and v6, and we are still getting an event, + * we have a programming error, so die hard. + */ + if ((client->find->options & DNS_ADBFIND_WANTEVENT) != 0) { + ns_lwdclient_log(50, "event will be sent"); + INSIST(client->v4find == NULL || client->v6find == NULL); + return; + } + ns_lwdclient_log(50, "no event will be sent"); + if (claimed) + client->find = NULL; + else + dns_adb_destroyfind(&client->find); + + /* + * We seem to have everything we asked for, or at least we are + * able to respond with things we've learned. + */ + + generate_reply(client); +} + +static isc_result_t +start_find(ns_lwdclient_t *client) { + isc_result_t result; + + /* + * Initialize the real name and alias arrays in the reply we're + * going to build up. + */ + init_gabn(client); + + result = store_realname(client); + if (result != ISC_R_SUCCESS) + return (result); + restart_find(client); + return (ISC_R_SUCCESS); + +} + +static void +init_gabn(ns_lwdclient_t *client) { + int i; + + /* + * Initialize the real name and alias arrays in the reply we're + * going to build up. + */ + for (i = 0; i < LWRES_MAX_ALIASES; i++) { + client->aliases[i] = NULL; + client->aliaslen[i] = 0; + } + for (i = 0; i < LWRES_MAX_ADDRS; i++) { + client->addrs[i].family = 0; + client->addrs[i].length = 0; + memset(client->addrs[i].address, 0, LWRES_ADDR_MAXLEN); + LWRES_LINK_INIT(&client->addrs[i], link); + } + + client->gabn.naliases = 0; + client->gabn.naddrs = 0; + client->gabn.realname = NULL; + client->gabn.aliases = client->aliases; + client->gabn.realnamelen = 0; + client->gabn.aliaslen = client->aliaslen; + LWRES_LIST_INIT(client->gabn.addrs); + client->gabn.base = NULL; + client->gabn.baselen = 0; + + /* + * Set up the internal buffer to point to the receive region. + */ + isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH); +} + +/* + * When we are called, we can be assured that: + * + * client->sockaddr contains the address we need to reply to, + * + * client->pkt contains the packet header data, + * + * the packet "checks out" overall -- any MD5 hashes or crypto + * bits have been verified, + * + * "b" points to the remaining data after the packet header + * was parsed off. + * + * We are in a the RECVDONE state. + * + * From this state we will enter the SEND state if we happen to have + * everything we need or we need to return an error packet, or to the + * FINDWAIT state if we need to look things up. + */ +void +ns_lwdclient_processgabn(ns_lwdclient_t *client, lwres_buffer_t *b) { + isc_result_t result; + lwres_gabnrequest_t *req; + ns_lwdclientmgr_t *cm; + isc_buffer_t namebuf; + + REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); + + cm = client->clientmgr; + req = NULL; + + result = lwres_gabnrequest_parse(client->clientmgr->lwctx, + b, &client->pkt, &req); + if (result != LWRES_R_SUCCESS) + goto out; + if (req->name == NULL) + goto out; + + isc_buffer_init(&namebuf, req->name, req->namelen); + isc_buffer_add(&namebuf, req->namelen); + + dns_fixedname_init(&client->target_name); + dns_fixedname_init(&client->query_name); + result = dns_name_fromtext(dns_fixedname_name(&client->query_name), + &namebuf, NULL, ISC_FALSE, NULL); + if (result != ISC_R_SUCCESS) + goto out; + ns_lwsearchctx_init(&client->searchctx, + cm->listener->manager->search, + dns_fixedname_name(&client->query_name), + cm->listener->manager->ndots); + ns_lwsearchctx_first(&client->searchctx); + + client->find_wanted = req->addrtypes; + ns_lwdclient_log(50, "client %p looking for addrtypes %08x", + client, client->find_wanted); + + /* + * We no longer need to keep this around. + */ + lwres_gabnrequest_free(client->clientmgr->lwctx, &req); + + /* + * Start the find. + */ + result = start_find(client); + if (result != ISC_R_SUCCESS) + goto out; + + return; + + /* + * We're screwed. Return an error packet to our caller. + */ + out: + if (req != NULL) + lwres_gabnrequest_free(client->clientmgr->lwctx, &req); + + ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); +} diff --git a/bin/named/lwdgnba.c b/bin/named/lwdgnba.c new file mode 100644 index 0000000..a500d27 --- /dev/null +++ b/bin/named/lwdgnba.c @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000-2002 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: lwdgnba.c,v 1.16.18.2 2005/04/29 00:15:24 marka Exp $ */ + +/*! \file */ + +#include + +#include +#include /* Required for HP/UX (and others?) */ +#include + +#include +#include +#include + +#include +#include + +static void start_byaddr(ns_lwdclient_t *); + +static void +byaddr_done(isc_task_t *task, isc_event_t *event) { + ns_lwdclient_t *client; + ns_lwdclientmgr_t *cm; + dns_byaddrevent_t *bevent; + int lwres; + lwres_buffer_t lwb; + dns_name_t *name; + isc_result_t result; + lwres_result_t lwresult; + isc_region_t r; + isc_buffer_t b; + lwres_gnbaresponse_t *gnba; + isc_uint16_t naliases; + + UNUSED(task); + + lwb.base = NULL; + client = event->ev_arg; + cm = client->clientmgr; + INSIST(client->byaddr == (dns_byaddr_t *)event->ev_sender); + + bevent = (dns_byaddrevent_t *)event; + gnba = &client->gnba; + + ns_lwdclient_log(50, "byaddr event result = %s", + isc_result_totext(bevent->result)); + + result = bevent->result; + if (result != ISC_R_SUCCESS) { + dns_byaddr_destroy(&client->byaddr); + isc_event_free(&event); + bevent = NULL; + + if (client->na.family != AF_INET6 || + (client->options & DNS_BYADDROPT_IPV6INT) != 0) { + if (result == DNS_R_NCACHENXDOMAIN || + result == DNS_R_NCACHENXRRSET || + result == DNS_R_NXDOMAIN || + result == DNS_R_NXRRSET) + lwresult = LWRES_R_NOTFOUND; + else + lwresult = LWRES_R_FAILURE; + ns_lwdclient_errorpktsend(client, lwresult); + return; + } + + /* + * Fall back to ip6.int reverse if the default ip6.arpa + * fails. + */ + client->options |= DNS_BYADDROPT_IPV6INT; + + start_byaddr(client); + return; + } + + for (name = ISC_LIST_HEAD(bevent->names); + name != NULL; + name = ISC_LIST_NEXT(name, link)) + { + b = client->recv_buffer; + + result = dns_name_totext(name, ISC_TRUE, &client->recv_buffer); + if (result != ISC_R_SUCCESS) + goto out; + ns_lwdclient_log(50, "found name '%.*s'", + (int)(client->recv_buffer.used - b.used), + (char *)(b.base) + b.used); + if (gnba->realname == NULL) { + gnba->realname = (char *)(b.base) + b.used; + gnba->realnamelen = client->recv_buffer.used - b.used; + } else { + naliases = gnba->naliases; + if (naliases >= LWRES_MAX_ALIASES) + break; + gnba->aliases[naliases] = (char *)(b.base) + b.used; + gnba->aliaslen[naliases] = + client->recv_buffer.used - b.used; + gnba->naliases++; + } + } + + dns_byaddr_destroy(&client->byaddr); + isc_event_free(&event); + + /* + * Render the packet. + */ + client->pkt.recvlength = LWRES_RECVLENGTH; + client->pkt.authtype = 0; /* XXXMLG */ + client->pkt.authlength = 0; + client->pkt.result = LWRES_R_SUCCESS; + + lwres = lwres_gnbaresponse_render(cm->lwctx, + gnba, &client->pkt, &lwb); + if (lwres != LWRES_R_SUCCESS) + goto out; + + r.base = lwb.base; + r.length = lwb.used; + client->sendbuf = r.base; + client->sendlength = r.length; + result = ns_lwdclient_sendreply(client, &r); + if (result != ISC_R_SUCCESS) + goto out; + + NS_LWDCLIENT_SETSEND(client); + + return; + + out: + if (client->byaddr != NULL) + dns_byaddr_destroy(&client->byaddr); + if (lwb.base != NULL) + lwres_context_freemem(cm->lwctx, + lwb.base, lwb.length); + + if (event != NULL) + isc_event_free(&event); +} + +static void +start_byaddr(ns_lwdclient_t *client) { + isc_result_t result; + ns_lwdclientmgr_t *cm; + + cm = client->clientmgr; + + INSIST(client->byaddr == NULL); + + result = dns_byaddr_create(cm->mctx, &client->na, cm->view, + client->options, cm->task, byaddr_done, + client, &client->byaddr); + if (result != ISC_R_SUCCESS) { + ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); + return; + } +} + +static void +init_gnba(ns_lwdclient_t *client) { + int i; + + /* + * Initialize the real name and alias arrays in the reply we're + * going to build up. + */ + for (i = 0; i < LWRES_MAX_ALIASES; i++) { + client->aliases[i] = NULL; + client->aliaslen[i] = 0; + } + for (i = 0; i < LWRES_MAX_ADDRS; i++) { + client->addrs[i].family = 0; + client->addrs[i].length = 0; + memset(client->addrs[i].address, 0, LWRES_ADDR_MAXLEN); + LWRES_LINK_INIT(&client->addrs[i], link); + } + + client->gnba.naliases = 0; + client->gnba.realname = NULL; + client->gnba.aliases = client->aliases; + client->gnba.realnamelen = 0; + client->gnba.aliaslen = client->aliaslen; + client->gnba.base = NULL; + client->gnba.baselen = 0; + isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH); +} + +void +ns_lwdclient_processgnba(ns_lwdclient_t *client, lwres_buffer_t *b) { + lwres_gnbarequest_t *req; + isc_result_t result; + isc_sockaddr_t sa; + ns_lwdclientmgr_t *cm; + + REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); + INSIST(client->byaddr == NULL); + + cm = client->clientmgr; + req = NULL; + + result = lwres_gnbarequest_parse(cm->lwctx, + b, &client->pkt, &req); + if (result != LWRES_R_SUCCESS) + goto out; + if (req->addr.address == NULL) + goto out; + + client->options = 0; + if (req->addr.family == LWRES_ADDRTYPE_V4) { + client->na.family = AF_INET; + if (req->addr.length != 4) + goto out; + memcpy(&client->na.type.in, req->addr.address, 4); + } else if (req->addr.family == LWRES_ADDRTYPE_V6) { + client->na.family = AF_INET6; + if (req->addr.length != 16) + goto out; + memcpy(&client->na.type.in6, req->addr.address, 16); + } else { + goto out; + } + isc_sockaddr_fromnetaddr(&sa, &client->na, 53); + + ns_lwdclient_log(50, "client %p looking for addrtype %08x", + client, req->addr.family); + + /* + * We no longer need to keep this around. + */ + lwres_gnbarequest_free(cm->lwctx, &req); + + /* + * Initialize the real name and alias arrays in the reply we're + * going to build up. + */ + init_gnba(client); + client->options = 0; + + /* + * Start the find. + */ + start_byaddr(client); + + return; + + /* + * We're screwed. Return an error packet to our caller. + */ + out: + if (req != NULL) + lwres_gnbarequest_free(cm->lwctx, &req); + + ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); +} diff --git a/bin/named/lwdgrbn.c b/bin/named/lwdgrbn.c new file mode 100644 index 0000000..c1b2b1e --- /dev/null +++ b/bin/named/lwdgrbn.c @@ -0,0 +1,513 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: lwdgrbn.c,v 1.13.18.5 2006/12/07 23:57:58 marka Exp $ */ + +/*! \file */ + +#include + +#include +#include +#include /* Required for HP/UX (and others?) */ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static void start_lookup(ns_lwdclient_t *); + +static isc_result_t +fill_array(int *pos, dns_rdataset_t *rdataset, + int size, unsigned char **rdatas, lwres_uint16_t *rdatalen) +{ + dns_rdata_t rdata; + isc_result_t result; + isc_region_t r; + + UNUSED(size); + + dns_rdata_init(&rdata); + for (result = dns_rdataset_first(rdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(rdataset)) + { + INSIST(*pos < size); + dns_rdataset_current(rdataset, &rdata); + dns_rdata_toregion(&rdata, &r); + rdatas[*pos] = r.base; + rdatalen[*pos] = r.length; + dns_rdata_reset(&rdata); + (*pos)++; + } + if (result == ISC_R_NOMORE) + result = ISC_R_SUCCESS; + return (result); +} + +static isc_result_t +iterate_node(lwres_grbnresponse_t *grbn, dns_db_t *db, dns_dbnode_t *node, + isc_mem_t *mctx) +{ + int used = 0, count; + int size = 8, oldsize = 0; + unsigned char **rdatas = NULL, **oldrdatas = NULL, **newrdatas = NULL; + lwres_uint16_t *lens = NULL, *oldlens = NULL, *newlens = NULL; + dns_rdatasetiter_t *iter = NULL; + dns_rdataset_t set; + dns_ttl_t ttl = ISC_INT32_MAX; + lwres_uint32_t flags = LWRDATA_VALIDATED; + isc_result_t result = ISC_R_NOMEMORY; + + result = dns_db_allrdatasets(db, node, NULL, 0, &iter); + if (result != ISC_R_SUCCESS) + goto out; + + rdatas = isc_mem_get(mctx, size * sizeof(*rdatas)); + if (rdatas == NULL) + goto out; + lens = isc_mem_get(mctx, size * sizeof(*lens)); + if (lens == NULL) + goto out; + + for (result = dns_rdatasetiter_first(iter); + result == ISC_R_SUCCESS; + result = dns_rdatasetiter_next(iter)) + { + result = ISC_R_NOMEMORY; + dns_rdataset_init(&set); + dns_rdatasetiter_current(iter, &set); + + if (set.type != dns_rdatatype_rrsig) { + dns_rdataset_disassociate(&set); + continue; + } + + count = dns_rdataset_count(&set); + if (used + count > size) { + /* copy & reallocate */ + oldsize = size; + oldrdatas = rdatas; + oldlens = lens; + rdatas = NULL; + lens = NULL; + + size *= 2; + + rdatas = isc_mem_get(mctx, size * sizeof(*rdatas)); + if (rdatas == NULL) + goto out; + lens = isc_mem_get(mctx, size * sizeof(*lens)); + if (lens == NULL) + goto out; + memcpy(rdatas, oldrdatas, used * sizeof(*rdatas)); + memcpy(lens, oldlens, used * sizeof(*lens)); + isc_mem_put(mctx, oldrdatas, + oldsize * sizeof(*oldrdatas)); + isc_mem_put(mctx, oldlens, oldsize * sizeof(*oldlens)); + oldrdatas = NULL; + oldlens = NULL; + } + if (set.ttl < ttl) + ttl = set.ttl; + if (set.trust != dns_trust_secure) + flags &= (~LWRDATA_VALIDATED); + result = fill_array(&used, &set, size, rdatas, lens); + dns_rdataset_disassociate(&set); + if (result != ISC_R_SUCCESS) + goto out; + } + if (result == ISC_R_NOMORE) + result = ISC_R_SUCCESS; + if (result != ISC_R_SUCCESS) + goto out; + dns_rdatasetiter_destroy(&iter); + + /* + * If necessary, shrink and copy the arrays. + */ + if (size != used) { + result = ISC_R_NOMEMORY; + newrdatas = isc_mem_get(mctx, used * sizeof(*rdatas)); + if (newrdatas == NULL) + goto out; + newlens = isc_mem_get(mctx, used * sizeof(*lens)); + if (newlens == NULL) + goto out; + memcpy(newrdatas, rdatas, used * sizeof(*rdatas)); + memcpy(newlens, lens, used * sizeof(*lens)); + isc_mem_put(mctx, rdatas, size * sizeof(*rdatas)); + isc_mem_put(mctx, lens, size * sizeof(*lens)); + grbn->rdatas = newrdatas; + grbn->rdatalen = newlens; + } else { + grbn->rdatas = rdatas; + grbn->rdatalen = lens; + } + grbn->nrdatas = used; + grbn->ttl = ttl; + grbn->flags = flags; + return (ISC_R_SUCCESS); + + out: + dns_rdatasetiter_destroy(&iter); + if (rdatas != NULL) + isc_mem_put(mctx, rdatas, size * sizeof(*rdatas)); + if (lens != NULL) + isc_mem_put(mctx, lens, size * sizeof(*lens)); + if (oldrdatas != NULL) + isc_mem_put(mctx, oldrdatas, oldsize * sizeof(*oldrdatas)); + if (oldlens != NULL) + isc_mem_put(mctx, oldlens, oldsize * sizeof(*oldlens)); + if (newrdatas != NULL) + isc_mem_put(mctx, newrdatas, used * sizeof(*oldrdatas)); + return (result); +} + +static void +lookup_done(isc_task_t *task, isc_event_t *event) { + ns_lwdclient_t *client; + ns_lwdclientmgr_t *cm; + dns_lookupevent_t *levent; + lwres_buffer_t lwb; + dns_name_t *name; + dns_rdataset_t *rdataset; + dns_rdataset_t *sigrdataset; + isc_result_t result; + lwres_result_t lwresult; + isc_region_t r; + isc_buffer_t b; + lwres_grbnresponse_t *grbn; + int i; + + UNUSED(task); + + lwb.base = NULL; + client = event->ev_arg; + cm = client->clientmgr; + INSIST(client->lookup == (dns_lookup_t *)event->ev_sender); + + levent = (dns_lookupevent_t *)event; + grbn = &client->grbn; + + ns_lwdclient_log(50, "lookup event result = %s", + isc_result_totext(levent->result)); + + result = levent->result; + if (result != ISC_R_SUCCESS) { + dns_lookup_destroy(&client->lookup); + isc_event_free(&event); + levent = NULL; + + switch (result) { + case DNS_R_NXDOMAIN: + case DNS_R_NCACHENXDOMAIN: + result = ns_lwsearchctx_next(&client->searchctx); + if (result != ISC_R_SUCCESS) + lwresult = LWRES_R_NOTFOUND; + else { + start_lookup(client); + return; + } + break; + case DNS_R_NXRRSET: + case DNS_R_NCACHENXRRSET: + lwresult = LWRES_R_TYPENOTFOUND; + break; + default: + lwresult = LWRES_R_FAILURE; + } + ns_lwdclient_errorpktsend(client, lwresult); + return; + } + + name = levent->name; + b = client->recv_buffer; + + grbn->flags = 0; + + grbn->nrdatas = 0; + grbn->rdatas = NULL; + grbn->rdatalen = NULL; + + grbn->nsigs = 0; + grbn->sigs = NULL; + grbn->siglen = NULL; + + result = dns_name_totext(name, ISC_TRUE, &client->recv_buffer); + if (result != ISC_R_SUCCESS) + goto out; + grbn->realname = (char *)isc_buffer_used(&b); + grbn->realnamelen = isc_buffer_usedlength(&client->recv_buffer) - + isc_buffer_usedlength(&b); + ns_lwdclient_log(50, "found name '%.*s'", grbn->realnamelen, + grbn->realname); + + grbn->rdclass = cm->view->rdclass; + grbn->rdtype = client->rdtype; + + rdataset = levent->rdataset; + if (rdataset != NULL) { + /* The normal case */ + grbn->nrdatas = dns_rdataset_count(rdataset); + grbn->rdatas = isc_mem_get(cm->mctx, grbn->nrdatas * + sizeof(unsigned char *)); + if (grbn->rdatas == NULL) + goto out; + grbn->rdatalen = isc_mem_get(cm->mctx, grbn->nrdatas * + sizeof(lwres_uint16_t)); + if (grbn->rdatalen == NULL) + goto out; + + i = 0; + result = fill_array(&i, rdataset, grbn->nrdatas, grbn->rdatas, + grbn->rdatalen); + if (result != ISC_R_SUCCESS) + goto out; + INSIST(i == grbn->nrdatas); + grbn->ttl = rdataset->ttl; + if (rdataset->trust == dns_trust_secure) + grbn->flags |= LWRDATA_VALIDATED; + } else { + /* The SIG query case */ + result = iterate_node(grbn, levent->db, levent->node, + cm->mctx); + if (result != ISC_R_SUCCESS) + goto out; + } + ns_lwdclient_log(50, "filled in %d rdata%s", grbn->nrdatas, + (grbn->nrdatas == 1) ? "" : "s"); + + sigrdataset = levent->sigrdataset; + if (sigrdataset != NULL) { + grbn->nsigs = dns_rdataset_count(sigrdataset); + grbn->sigs = isc_mem_get(cm->mctx, grbn->nsigs * + sizeof(unsigned char *)); + if (grbn->sigs == NULL) + goto out; + grbn->siglen = isc_mem_get(cm->mctx, grbn->nsigs * + sizeof(lwres_uint16_t)); + if (grbn->siglen == NULL) + goto out; + + i = 0; + result = fill_array(&i, sigrdataset, grbn->nsigs, grbn->sigs, + grbn->siglen); + if (result != ISC_R_SUCCESS) + goto out; + INSIST(i == grbn->nsigs); + ns_lwdclient_log(50, "filled in %d signature%s", grbn->nsigs, + (grbn->nsigs == 1) ? "" : "s"); + } + + dns_lookup_destroy(&client->lookup); + isc_event_free(&event); + + /* + * Render the packet. + */ + client->pkt.recvlength = LWRES_RECVLENGTH; + client->pkt.authtype = 0; /* XXXMLG */ + client->pkt.authlength = 0; + client->pkt.result = LWRES_R_SUCCESS; + + lwresult = lwres_grbnresponse_render(cm->lwctx, + grbn, &client->pkt, &lwb); + if (lwresult != LWRES_R_SUCCESS) + goto out; + + isc_mem_put(cm->mctx, grbn->rdatas, + grbn->nrdatas * sizeof(unsigned char *)); + isc_mem_put(cm->mctx, grbn->rdatalen, + grbn->nrdatas * sizeof(lwres_uint16_t)); + + if (grbn->sigs != NULL) + isc_mem_put(cm->mctx, grbn->sigs, + grbn->nsigs * sizeof(unsigned char *)); + if (grbn->siglen != NULL) + isc_mem_put(cm->mctx, grbn->siglen, + grbn->nsigs * sizeof(lwres_uint16_t)); + + r.base = lwb.base; + r.length = lwb.used; + client->sendbuf = r.base; + client->sendlength = r.length; + result = ns_lwdclient_sendreply(client, &r); + if (result != ISC_R_SUCCESS) + goto out2; + + NS_LWDCLIENT_SETSEND(client); + + return; + + out: + if (grbn->rdatas != NULL) + isc_mem_put(cm->mctx, grbn->rdatas, + grbn->nrdatas * sizeof(unsigned char *)); + if (grbn->rdatalen != NULL) + isc_mem_put(cm->mctx, grbn->rdatalen, + grbn->nrdatas * sizeof(lwres_uint16_t)); + + if (grbn->sigs != NULL) + isc_mem_put(cm->mctx, grbn->sigs, + grbn->nsigs * sizeof(unsigned char *)); + if (grbn->siglen != NULL) + isc_mem_put(cm->mctx, grbn->siglen, + grbn->nsigs * sizeof(lwres_uint16_t)); + out2: + if (client->lookup != NULL) + dns_lookup_destroy(&client->lookup); + if (lwb.base != NULL) + lwres_context_freemem(cm->lwctx, lwb.base, lwb.length); + + if (event != NULL) + isc_event_free(&event); + + ns_lwdclient_log(50, "error constructing getrrsetbyname response"); + ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); +} + +static void +start_lookup(ns_lwdclient_t *client) { + isc_result_t result; + ns_lwdclientmgr_t *cm; + dns_fixedname_t absname; + + cm = client->clientmgr; + + INSIST(client->lookup == NULL); + + dns_fixedname_init(&absname); + result = ns_lwsearchctx_current(&client->searchctx, + dns_fixedname_name(&absname)); + /* + * This will return failure if relative name + suffix is too long. + * In this case, just go on to the next entry in the search path. + */ + if (result != ISC_R_SUCCESS) + start_lookup(client); + + result = dns_lookup_create(cm->mctx, + dns_fixedname_name(&absname), + client->rdtype, cm->view, + client->options, cm->task, lookup_done, + client, &client->lookup); + if (result != ISC_R_SUCCESS) { + ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); + return; + } +} + +static void +init_grbn(ns_lwdclient_t *client) { + client->grbn.rdclass = 0; + client->grbn.rdtype = 0; + client->grbn.ttl = 0; + client->grbn.nrdatas = 0; + client->grbn.realname = NULL; + client->grbn.realnamelen = 0; + client->grbn.rdatas = 0; + client->grbn.rdatalen = 0; + client->grbn.base = NULL; + client->grbn.baselen = 0; + isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH); +} + +void +ns_lwdclient_processgrbn(ns_lwdclient_t *client, lwres_buffer_t *b) { + lwres_grbnrequest_t *req; + isc_result_t result; + ns_lwdclientmgr_t *cm; + isc_buffer_t namebuf; + + REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); + INSIST(client->byaddr == NULL); + + cm = client->clientmgr; + req = NULL; + + result = lwres_grbnrequest_parse(cm->lwctx, + b, &client->pkt, &req); + if (result != LWRES_R_SUCCESS) + goto out; + if (req->name == NULL) + goto out; + + client->options = 0; + if (req->rdclass != cm->view->rdclass) + goto out; + + if (req->rdclass == dns_rdataclass_any || + req->rdtype == dns_rdatatype_any) + goto out; + + client->rdtype = req->rdtype; + + isc_buffer_init(&namebuf, req->name, req->namelen); + isc_buffer_add(&namebuf, req->namelen); + + dns_fixedname_init(&client->query_name); + result = dns_name_fromtext(dns_fixedname_name(&client->query_name), + &namebuf, NULL, ISC_FALSE, NULL); + if (result != ISC_R_SUCCESS) + goto out; + ns_lwsearchctx_init(&client->searchctx, + cm->listener->manager->search, + dns_fixedname_name(&client->query_name), + cm->listener->manager->ndots); + ns_lwsearchctx_first(&client->searchctx); + + ns_lwdclient_log(50, "client %p looking for type %d", + client, client->rdtype); + + /* + * We no longer need to keep this around. + */ + lwres_grbnrequest_free(cm->lwctx, &req); + + /* + * Initialize the real name and alias arrays in the reply we're + * going to build up. + */ + init_grbn(client); + + /* + * Start the find. + */ + start_lookup(client); + + return; + + /* + * We're screwed. Return an error packet to our caller. + */ + out: + if (req != NULL) + lwres_grbnrequest_free(cm->lwctx, &req); + + ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); +} diff --git a/bin/named/lwdnoop.c b/bin/named/lwdnoop.c new file mode 100644 index 0000000..fa591b4 --- /dev/null +++ b/bin/named/lwdnoop.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: lwdnoop.c,v 1.7.18.2 2005/04/29 00:15:25 marka Exp $ */ + +/*! \file */ + +#include + +#include +#include + +#include +#include + +void +ns_lwdclient_processnoop(ns_lwdclient_t *client, lwres_buffer_t *b) { + lwres_nooprequest_t *req; + lwres_noopresponse_t resp; + isc_result_t result; + lwres_result_t lwres; + isc_region_t r; + lwres_buffer_t lwb; + + REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); + INSIST(client->byaddr == NULL); + + req = NULL; + + result = lwres_nooprequest_parse(client->clientmgr->lwctx, + b, &client->pkt, &req); + if (result != LWRES_R_SUCCESS) + goto out; + + client->pkt.recvlength = LWRES_RECVLENGTH; + client->pkt.authtype = 0; /* XXXMLG */ + client->pkt.authlength = 0; + client->pkt.result = LWRES_R_SUCCESS; + + resp.datalength = req->datalength; + resp.data = req->data; + + lwres = lwres_noopresponse_render(client->clientmgr->lwctx, &resp, + &client->pkt, &lwb); + if (lwres != LWRES_R_SUCCESS) + goto out; + + r.base = lwb.base; + r.length = lwb.used; + client->sendbuf = r.base; + client->sendlength = r.length; + result = ns_lwdclient_sendreply(client, &r); + if (result != ISC_R_SUCCESS) + goto out; + + /* + * We can now destroy request. + */ + lwres_nooprequest_free(client->clientmgr->lwctx, &req); + + NS_LWDCLIENT_SETSEND(client); + + return; + + out: + if (req != NULL) + lwres_nooprequest_free(client->clientmgr->lwctx, &req); + + if (lwb.base != NULL) + lwres_context_freemem(client->clientmgr->lwctx, + lwb.base, lwb.length); + + ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); +} diff --git a/bin/named/lwresd.8 b/bin/named/lwresd.8 new file mode 100644 index 0000000..825645a --- /dev/null +++ b/bin/named/lwresd.8 @@ -0,0 +1,223 @@ +.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2000, 2001 Internet Software Consortium. +.\" +.\" Permission to use, copy, modify, and 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: lwresd.8,v 1.15.18.12 2007/05/16 06:11:27 marka Exp $ +.\" +.hy 0 +.ad l +.\" Title: lwresd +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.71.1 +.\" Date: June 30, 2000 +.\" Manual: BIND9 +.\" Source: BIND9 +.\" +.TH "LWRESD" "8" "June 30, 2000" "BIND9" "BIND9" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +lwresd \- lightweight resolver daemon +.SH "SYNOPSIS" +.HP 7 +\fBlwresd\fR [\fB\-c\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-C\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-d\ \fR\fB\fIdebug\-level\fR\fR] [\fB\-f\fR] [\fB\-g\fR] [\fB\-i\ \fR\fB\fIpid\-file\fR\fR] [\fB\-m\ \fR\fB\fIflag\fR\fR] [\fB\-n\ \fR\fB\fI#cpus\fR\fR] [\fB\-P\ \fR\fB\fIport\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-s\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-4\fR] [\fB\-6\fR] +.SH "DESCRIPTION" +.PP +\fBlwresd\fR +is the daemon providing name lookup services to clients that use the BIND 9 lightweight resolver library. It is essentially a stripped\-down, caching\-only name server that answers queries using the BIND 9 lightweight resolver protocol rather than the DNS protocol. +.PP +\fBlwresd\fR +listens for resolver queries on a UDP port on the IPv4 loopback interface, 127.0.0.1. This means that +\fBlwresd\fR +can only be used by processes running on the local machine. By default UDP port number 921 is used for lightweight resolver requests and responses. +.PP +Incoming lightweight resolver requests are decoded by the server which then resolves them using the DNS protocol. When the DNS lookup completes, +\fBlwresd\fR +encodes the answers in the lightweight resolver format and returns them to the client that made the request. +.PP +If +\fI/etc/resolv.conf\fR +contains any +\fBnameserver\fR +entries, +\fBlwresd\fR +sends recursive DNS queries to those servers. This is similar to the use of forwarders in a caching name server. If no +\fBnameserver\fR +entries are present, or if forwarding fails, +\fBlwresd\fR +resolves the queries autonomously starting at the root name servers, using a built\-in list of root server hints. +.SH "OPTIONS" +.PP +\-4 +.RS 4 +Use IPv4 only even if the host machine is capable of IPv6. +\fB\-4\fR +and +\fB\-6\fR +are mutually exclusive. +.RE +.PP +\-6 +.RS 4 +Use IPv6 only even if the host machine is capable of IPv4. +\fB\-4\fR +and +\fB\-6\fR +are mutually exclusive. +.RE +.PP +\-c \fIconfig\-file\fR +.RS 4 +Use +\fIconfig\-file\fR +as the configuration file instead of the default, +\fI/etc/lwresd.conf\fR. +\-c +can not be used with +\-C. +.RE +.PP +\-C \fIconfig\-file\fR +.RS 4 +Use +\fIconfig\-file\fR +as the configuration file instead of the default, +\fI/etc/resolv.conf\fR. +\-C +can not be used with +\-c. +.RE +.PP +\-d \fIdebug\-level\fR +.RS 4 +Set the daemon's debug level to +\fIdebug\-level\fR. Debugging traces from +\fBlwresd\fR +become more verbose as the debug level increases. +.RE +.PP +\-f +.RS 4 +Run the server in the foreground (i.e. do not daemonize). +.RE +.PP +\-g +.RS 4 +Run the server in the foreground and force all logging to +\fIstderr\fR. +.RE +.PP +\-i \fIpid\-file\fR +.RS 4 +Use +\fIpid\-file\fR +as the PID file instead of the default, +\fI/var/run/lwresd.pid\fR. +.RE +.PP +\-m \fIflag\fR +.RS 4 +Turn on memory usage debugging flags. Possible flags are +\fIusage\fR, +\fItrace\fR, +\fIrecord\fR, +\fIsize\fR, and +\fImctx\fR. These correspond to the ISC_MEM_DEBUGXXXX flags described in +\fI\fR. +.RE +.PP +\-n \fI#cpus\fR +.RS 4 +Create +\fI#cpus\fR +worker threads to take advantage of multiple CPUs. If not specified, +\fBlwresd\fR +will try to determine the number of CPUs present and create one thread per CPU. If it is unable to determine the number of CPUs, a single worker thread will be created. +.RE +.PP +\-P \fIport\fR +.RS 4 +Listen for lightweight resolver queries on port +\fIport\fR. If not specified, the default is port 921. +.RE +.PP +\-p \fIport\fR +.RS 4 +Send DNS lookups to port +\fIport\fR. If not specified, the default is port 53. This provides a way of testing the lightweight resolver daemon with a name server that listens for queries on a non\-standard port number. +.RE +.PP +\-s +.RS 4 +Write memory usage statistics to +\fIstdout\fR +on exit. +.RS +.B "Note:" +This option is mainly of interest to BIND 9 developers and may be removed or changed in a future release. +.RE +.RE +.PP +\-t \fIdirectory\fR +.RS 4 +Chroot to +\fIdirectory\fR +after processing the command line arguments, but before reading the configuration file. +.RS +.B "Warning:" +This option should be used in conjunction with the +\fB\-u\fR +option, as chrooting a process running as root doesn't enhance security on most systems; the way +\fBchroot(2)\fR +is defined allows a process with root privileges to escape a chroot jail. +.RE +.RE +.PP +\-u \fIuser\fR +.RS 4 +Setuid to +\fIuser\fR +after completing privileged operations, such as creating sockets that listen on privileged ports. +.RE +.PP +\-v +.RS 4 +Report the version number and exit. +.RE +.SH "FILES" +.PP +\fI/etc/resolv.conf\fR +.RS 4 +The default configuration file. +.RE +.PP +\fI/var/run/lwresd.pid\fR +.RS 4 +The default process\-id file. +.RE +.SH "SEE ALSO" +.PP +\fBnamed\fR(8), +\fBlwres\fR(3), +\fBresolver\fR(5). +.SH "AUTHOR" +.PP +Internet Systems Consortium +.SH "COPYRIGHT" +Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") +.br +Copyright \(co 2000, 2001 Internet Software Consortium. +.br diff --git a/bin/named/lwresd.c b/bin/named/lwresd.c new file mode 100644 index 0000000..a1073fa --- /dev/null +++ b/bin/named/lwresd.c @@ -0,0 +1,869 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: lwresd.c,v 1.46.18.7 2006/03/02 00:37:21 marka Exp $ */ + +/*! \file + * \brief + * Main program for the Lightweight Resolver Daemon. + * + * To paraphrase the old saying about X11, "It's not a lightweight deamon + * for resolvers, it's a deamon for lightweight resolvers". + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LWRESD_MAGIC ISC_MAGIC('L', 'W', 'R', 'D') +#define VALID_LWRESD(l) ISC_MAGIC_VALID(l, LWRESD_MAGIC) + +#define LWRESLISTENER_MAGIC ISC_MAGIC('L', 'W', 'R', 'L') +#define VALID_LWRESLISTENER(l) ISC_MAGIC_VALID(l, LWRESLISTENER_MAGIC) + +/*! + * The total number of clients we can handle will be NTASKS * NRECVS. + */ +#define NTASKS 2 /*%< tasks to create to handle lwres queries */ +#define NRECVS 2 /*%< max clients per task */ + +typedef ISC_LIST(ns_lwreslistener_t) ns_lwreslistenerlist_t; + +static ns_lwreslistenerlist_t listeners; +static isc_mutex_t listeners_lock; +static isc_once_t once = ISC_ONCE_INIT; + + +static void +initialize_mutex(void) { + RUNTIME_CHECK(isc_mutex_init(&listeners_lock) == ISC_R_SUCCESS); +} + + +/*% + * Wrappers around our memory management stuff, for the lwres functions. + */ +void * +ns__lwresd_memalloc(void *arg, size_t size) { + return (isc_mem_get(arg, size)); +} + +void +ns__lwresd_memfree(void *arg, void *mem, size_t size) { + isc_mem_put(arg, mem, size); +} + + +#define CHECK(op) \ + do { result = (op); \ + if (result != ISC_R_SUCCESS) goto cleanup; \ + } while (0) + +static isc_result_t +buffer_putstr(isc_buffer_t *b, const char *s) { + unsigned int len = strlen(s); + if (isc_buffer_availablelength(b) <= len) + return (ISC_R_NOSPACE); + isc_buffer_putmem(b, (const unsigned char *)s, len); + return (ISC_R_SUCCESS); +} + +/* + * Convert a resolv.conf file into a config structure. + */ +isc_result_t +ns_lwresd_parseeresolvconf(isc_mem_t *mctx, cfg_parser_t *pctx, + cfg_obj_t **configp) +{ + char text[4096]; + char str[16]; + isc_buffer_t b; + lwres_context_t *lwctx = NULL; + lwres_conf_t *lwc = NULL; + isc_sockaddr_t sa; + isc_netaddr_t na; + int i; + isc_result_t result; + lwres_result_t lwresult; + + lwctx = NULL; + lwresult = lwres_context_create(&lwctx, mctx, ns__lwresd_memalloc, + ns__lwresd_memfree, + LWRES_CONTEXT_SERVERMODE); + if (lwresult != LWRES_R_SUCCESS) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + + lwresult = lwres_conf_parse(lwctx, lwresd_g_resolvconffile); + if (lwresult != LWRES_R_SUCCESS) { + result = DNS_R_SYNTAX; + goto cleanup; + } + + lwc = lwres_conf_get(lwctx); + INSIST(lwc != NULL); + + isc_buffer_init(&b, text, sizeof(text)); + + CHECK(buffer_putstr(&b, "options {\n")); + + /* + * Build the list of forwarders. + */ + if (lwc->nsnext > 0) { + CHECK(buffer_putstr(&b, "\tforwarders {\n")); + + for (i = 0; i < lwc->nsnext; i++) { + CHECK(lwaddr_sockaddr_fromlwresaddr( + &sa, + &lwc->nameservers[i], + ns_g_port)); + isc_netaddr_fromsockaddr(&na, &sa); + CHECK(buffer_putstr(&b, "\t\t")); + CHECK(isc_netaddr_totext(&na, &b)); + CHECK(buffer_putstr(&b, ";\n")); + } + CHECK(buffer_putstr(&b, "\t};\n")); + } + + /* + * Build the sortlist + */ + if (lwc->sortlistnxt > 0) { + CHECK(buffer_putstr(&b, "\tsortlist {\n")); + CHECK(buffer_putstr(&b, "\t\t{\n")); + CHECK(buffer_putstr(&b, "\t\t\tany;\n")); + CHECK(buffer_putstr(&b, "\t\t\t{\n")); + for (i = 0; i < lwc->sortlistnxt; i++) { + lwres_addr_t *lwaddr = &lwc->sortlist[i].addr; + lwres_addr_t *lwmask = &lwc->sortlist[i].mask; + unsigned int mask; + + CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, lwmask, 0)); + isc_netaddr_fromsockaddr(&na, &sa); + result = isc_netaddr_masktoprefixlen(&na, &mask); + if (result != ISC_R_SUCCESS) { + char addrtext[ISC_NETADDR_FORMATSIZE]; + isc_netaddr_format(&na, addrtext, + sizeof(addrtext)); + isc_log_write(ns_g_lctx, + NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_LWRESD, + ISC_LOG_ERROR, + "processing sortlist: '%s' is " + "not a valid netmask", + addrtext); + goto cleanup; + } + + CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, lwaddr, 0)); + isc_netaddr_fromsockaddr(&na, &sa); + + CHECK(buffer_putstr(&b, "\t\t\t\t")); + CHECK(isc_netaddr_totext(&na, &b)); + snprintf(str, sizeof(str), "%u", mask); + CHECK(buffer_putstr(&b, "/")); + CHECK(buffer_putstr(&b, str)); + CHECK(buffer_putstr(&b, ";\n")); + } + CHECK(buffer_putstr(&b, "\t\t\t};\n")); + CHECK(buffer_putstr(&b, "\t\t};\n")); + CHECK(buffer_putstr(&b, "\t};\n")); + } + + CHECK(buffer_putstr(&b, "};\n\n")); + + CHECK(buffer_putstr(&b, "lwres {\n")); + + /* + * Build the search path + */ + if (lwc->searchnxt > 0) { + if (lwc->searchnxt > 0) { + CHECK(buffer_putstr(&b, "\tsearch {\n")); + for (i = 0; i < lwc->searchnxt; i++) { + CHECK(buffer_putstr(&b, "\t\t\"")); + CHECK(buffer_putstr(&b, lwc->search[i])); + CHECK(buffer_putstr(&b, "\";\n")); + } + CHECK(buffer_putstr(&b, "\t};\n")); + } + } + + /* + * Build the ndots line + */ + if (lwc->ndots != 1) { + CHECK(buffer_putstr(&b, "\tndots ")); + snprintf(str, sizeof(str), "%u", lwc->ndots); + CHECK(buffer_putstr(&b, str)); + CHECK(buffer_putstr(&b, ";\n")); + } + + /* + * Build the listen-on line + */ + if (lwc->lwnext > 0) { + CHECK(buffer_putstr(&b, "\tlisten-on {\n")); + + for (i = 0; i < lwc->lwnext; i++) { + CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, + &lwc->lwservers[i], + 0)); + isc_netaddr_fromsockaddr(&na, &sa); + CHECK(buffer_putstr(&b, "\t\t")); + CHECK(isc_netaddr_totext(&na, &b)); + CHECK(buffer_putstr(&b, ";\n")); + } + CHECK(buffer_putstr(&b, "\t};\n")); + } + + CHECK(buffer_putstr(&b, "};\n")); + +#if 0 + printf("%.*s\n", + (int)isc_buffer_usedlength(&b), + (char *)isc_buffer_base(&b)); +#endif + + lwres_conf_clear(lwctx); + lwres_context_destroy(&lwctx); + + return (cfg_parse_buffer(pctx, &b, &cfg_type_namedconf, configp)); + + cleanup: + + if (lwctx != NULL) { + lwres_conf_clear(lwctx); + lwres_context_destroy(&lwctx); + } + + return (result); +} + + +/* + * Handle lwresd manager objects + */ +isc_result_t +ns_lwdmanager_create(isc_mem_t *mctx, const cfg_obj_t *lwres, + ns_lwresd_t **lwresdp) +{ + ns_lwresd_t *lwresd; + const char *vname; + dns_rdataclass_t vclass; + const cfg_obj_t *obj, *viewobj, *searchobj; + const cfg_listelt_t *element; + isc_result_t result; + + INSIST(lwresdp != NULL && *lwresdp == NULL); + + lwresd = isc_mem_get(mctx, sizeof(ns_lwresd_t)); + if (lwresd == NULL) + return (ISC_R_NOMEMORY); + + lwresd->mctx = NULL; + isc_mem_attach(mctx, &lwresd->mctx); + lwresd->view = NULL; + lwresd->search = NULL; + lwresd->refs = 1; + + obj = NULL; + (void)cfg_map_get(lwres, "ndots", &obj); + if (obj != NULL) + lwresd->ndots = cfg_obj_asuint32(obj); + else + lwresd->ndots = 1; + + RUNTIME_CHECK(isc_mutex_init(&lwresd->lock) == ISC_R_SUCCESS); + + lwresd->shutting_down = ISC_FALSE; + + viewobj = NULL; + (void)cfg_map_get(lwres, "view", &viewobj); + if (viewobj != NULL) { + vname = cfg_obj_asstring(cfg_tuple_get(viewobj, "name")); + obj = cfg_tuple_get(viewobj, "class"); + result = ns_config_getclass(obj, dns_rdataclass_in, &vclass); + if (result != ISC_R_SUCCESS) + goto fail; + } else { + vname = "_default"; + vclass = dns_rdataclass_in; + } + + result = dns_viewlist_find(&ns_g_server->viewlist, vname, vclass, + &lwresd->view); + if (result != ISC_R_SUCCESS) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, + "couldn't find view %s", vname); + goto fail; + } + + searchobj = NULL; + (void)cfg_map_get(lwres, "search", &searchobj); + if (searchobj != NULL) { + lwresd->search = NULL; + result = ns_lwsearchlist_create(lwresd->mctx, + &lwresd->search); + if (result != ISC_R_SUCCESS) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, + "couldn't create searchlist"); + goto fail; + } + for (element = cfg_list_first(searchobj); + element != NULL; + element = cfg_list_next(element)) + { + const cfg_obj_t *search; + const char *searchstr; + isc_buffer_t namebuf; + dns_fixedname_t fname; + dns_name_t *name; + + search = cfg_listelt_value(element); + searchstr = cfg_obj_asstring(search); + + dns_fixedname_init(&fname); + name = dns_fixedname_name(&fname); + isc_buffer_init(&namebuf, searchstr, + strlen(searchstr)); + isc_buffer_add(&namebuf, strlen(searchstr)); + result = dns_name_fromtext(name, &namebuf, + dns_rootname, ISC_FALSE, + NULL); + if (result != ISC_R_SUCCESS) { + isc_log_write(ns_g_lctx, + NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_LWRESD, + ISC_LOG_WARNING, + "invalid name %s in searchlist", + searchstr); + continue; + } + + result = ns_lwsearchlist_append(lwresd->search, name); + if (result != ISC_R_SUCCESS) { + isc_log_write(ns_g_lctx, + NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_LWRESD, + ISC_LOG_WARNING, + "couldn't update searchlist"); + goto fail; + } + } + } + + lwresd->magic = LWRESD_MAGIC; + + *lwresdp = lwresd; + return (ISC_R_SUCCESS); + + fail: + if (lwresd->view != NULL) + dns_view_detach(&lwresd->view); + if (lwresd->search != NULL) + ns_lwsearchlist_detach(&lwresd->search); + if (lwresd->mctx != NULL) + isc_mem_detach(&lwresd->mctx); + isc_mem_put(mctx, lwresd, sizeof(ns_lwresd_t)); + return (result); +} + +void +ns_lwdmanager_attach(ns_lwresd_t *source, ns_lwresd_t **targetp) { + INSIST(VALID_LWRESD(source)); + INSIST(targetp != NULL && *targetp == NULL); + + LOCK(&source->lock); + source->refs++; + UNLOCK(&source->lock); + + *targetp = source; +} + +void +ns_lwdmanager_detach(ns_lwresd_t **lwresdp) { + ns_lwresd_t *lwresd; + isc_mem_t *mctx; + isc_boolean_t done = ISC_FALSE; + + INSIST(lwresdp != NULL && *lwresdp != NULL); + INSIST(VALID_LWRESD(*lwresdp)); + + lwresd = *lwresdp; + *lwresdp = NULL; + + LOCK(&lwresd->lock); + INSIST(lwresd->refs > 0); + lwresd->refs--; + if (lwresd->refs == 0) + done = ISC_TRUE; + UNLOCK(&lwresd->lock); + + if (!done) + return; + + dns_view_detach(&lwresd->view); + if (lwresd->search != NULL) + ns_lwsearchlist_detach(&lwresd->search); + mctx = lwresd->mctx; + lwresd->magic = 0; + isc_mem_put(mctx, lwresd, sizeof(*lwresd)); + isc_mem_detach(&mctx); +} + + +/* + * Handle listener objects + */ +void +ns_lwreslistener_attach(ns_lwreslistener_t *source, + ns_lwreslistener_t **targetp) +{ + INSIST(VALID_LWRESLISTENER(source)); + INSIST(targetp != NULL && *targetp == NULL); + + LOCK(&source->lock); + source->refs++; + UNLOCK(&source->lock); + + *targetp = source; +} + +void +ns_lwreslistener_detach(ns_lwreslistener_t **listenerp) { + ns_lwreslistener_t *listener; + isc_mem_t *mctx; + isc_boolean_t done = ISC_FALSE; + + INSIST(listenerp != NULL && *listenerp != NULL); + INSIST(VALID_LWRESLISTENER(*listenerp)); + + listener = *listenerp; + + LOCK(&listener->lock); + INSIST(listener->refs > 0); + listener->refs--; + if (listener->refs == 0) + done = ISC_TRUE; + UNLOCK(&listener->lock); + + if (!done) + return; + + if (listener->manager != NULL) + ns_lwdmanager_detach(&listener->manager); + + if (listener->sock != NULL) + isc_socket_detach(&listener->sock); + + listener->magic = 0; + mctx = listener->mctx; + isc_mem_put(mctx, listener, sizeof(*listener)); + isc_mem_detach(&mctx); + listenerp = NULL; +} + +static isc_result_t +listener_create(isc_mem_t *mctx, ns_lwresd_t *lwresd, + ns_lwreslistener_t **listenerp) +{ + ns_lwreslistener_t *listener; + isc_result_t result; + + REQUIRE(listenerp != NULL && *listenerp == NULL); + + listener = isc_mem_get(mctx, sizeof(ns_lwreslistener_t)); + if (listener == NULL) + return (ISC_R_NOMEMORY); + + result = isc_mutex_init(&listener->lock); + if (result != ISC_R_SUCCESS) { + isc_mem_put(mctx, listener, sizeof(ns_lwreslistener_t)); + return (result); + } + + listener->magic = LWRESLISTENER_MAGIC; + listener->refs = 1; + + listener->sock = NULL; + + listener->manager = NULL; + ns_lwdmanager_attach(lwresd, &listener->manager); + + listener->mctx = NULL; + isc_mem_attach(mctx, &listener->mctx); + + ISC_LINK_INIT(listener, link); + ISC_LIST_INIT(listener->cmgrs); + + *listenerp = listener; + return (ISC_R_SUCCESS); +} + +static isc_result_t +listener_bind(ns_lwreslistener_t *listener, isc_sockaddr_t *address) { + isc_socket_t *sock = NULL; + isc_result_t result = ISC_R_SUCCESS; + int pf; + + pf = isc_sockaddr_pf(address); + if ((pf == AF_INET && isc_net_probeipv4() != ISC_R_SUCCESS) || + (pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS)) + return (ISC_R_FAMILYNOSUPPORT); + + listener->address = *address; + + if (isc_sockaddr_getport(&listener->address) == 0) { + in_port_t port; + port = lwresd_g_listenport; + if (port == 0) + port = LWRES_UDP_PORT; + isc_sockaddr_setport(&listener->address, port); + } + + sock = NULL; + result = isc_socket_create(ns_g_socketmgr, pf, + isc_sockettype_udp, &sock); + if (result != ISC_R_SUCCESS) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, + "failed to create lwres socket: %s", + isc_result_totext(result)); + return (result); + } + + result = isc_socket_bind(sock, &listener->address); + if (result != ISC_R_SUCCESS) { + char socktext[ISC_SOCKADDR_FORMATSIZE]; + isc_sockaddr_format(&listener->address, socktext, + sizeof(socktext)); + isc_socket_detach(&sock); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, + "failed to add lwres socket: %s: %s", + socktext, isc_result_totext(result)); + return (result); + } + listener->sock = sock; + return (ISC_R_SUCCESS); +} + +static void +listener_copysock(ns_lwreslistener_t *oldlistener, + ns_lwreslistener_t *newlistener) +{ + newlistener->address = oldlistener->address; + isc_socket_attach(oldlistener->sock, &newlistener->sock); +} + +static isc_result_t +listener_startclients(ns_lwreslistener_t *listener) { + ns_lwdclientmgr_t *cm; + unsigned int i; + isc_result_t result; + + /* + * Create the client managers. + */ + result = ISC_R_SUCCESS; + for (i = 0; i < NTASKS && result == ISC_R_SUCCESS; i++) + result = ns_lwdclientmgr_create(listener, NRECVS, + ns_g_taskmgr); + + /* + * Ensure that we have created at least one. + */ + if (ISC_LIST_EMPTY(listener->cmgrs)) + return (result); + + /* + * Walk the list of clients and start each one up. + */ + LOCK(&listener->lock); + cm = ISC_LIST_HEAD(listener->cmgrs); + while (cm != NULL) { + result = ns_lwdclient_startrecv(cm); + if (result != ISC_R_SUCCESS) + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, + "could not start lwres " + "client handler: %s", + isc_result_totext(result)); + cm = ISC_LIST_NEXT(cm, link); + } + UNLOCK(&listener->lock); + + return (ISC_R_SUCCESS); +} + +static void +listener_shutdown(ns_lwreslistener_t *listener) { + ns_lwdclientmgr_t *cm; + + cm = ISC_LIST_HEAD(listener->cmgrs); + while (cm != NULL) { + isc_task_shutdown(cm->task); + cm = ISC_LIST_NEXT(cm, link); + } +} + +static isc_result_t +find_listener(isc_sockaddr_t *address, ns_lwreslistener_t **listenerp) { + ns_lwreslistener_t *listener; + + INSIST(listenerp != NULL && *listenerp == NULL); + + for (listener = ISC_LIST_HEAD(listeners); + listener != NULL; + listener = ISC_LIST_NEXT(listener, link)) + { + if (!isc_sockaddr_equal(address, &listener->address)) + continue; + *listenerp = listener; + return (ISC_R_SUCCESS); + } + return (ISC_R_NOTFOUND); +} + +void +ns_lwreslistener_unlinkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm) +{ + REQUIRE(VALID_LWRESLISTENER(listener)); + + LOCK(&listener->lock); + ISC_LIST_UNLINK(listener->cmgrs, cm, link); + UNLOCK(&listener->lock); +} + +void +ns_lwreslistener_linkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm) { + REQUIRE(VALID_LWRESLISTENER(listener)); + + /* + * This does no locking, since it's called early enough that locking + * isn't needed. + */ + ISC_LIST_APPEND(listener->cmgrs, cm, link); +} + +static isc_result_t +configure_listener(isc_sockaddr_t *address, ns_lwresd_t *lwresd, + isc_mem_t *mctx, ns_lwreslistenerlist_t *newlisteners) +{ + ns_lwreslistener_t *listener, *oldlistener = NULL; + char socktext[ISC_SOCKADDR_FORMATSIZE]; + isc_result_t result; + + (void)find_listener(address, &oldlistener); + listener = NULL; + result = listener_create(mctx, lwresd, &listener); + if (result != ISC_R_SUCCESS) { + isc_sockaddr_format(address, socktext, sizeof(socktext)); + isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, + NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, + "lwres failed to configure %s: %s", + socktext, isc_result_totext(result)); + return (result); + } + + /* + * If there's already a listener, don't rebind the socket. + */ + if (oldlistener == NULL) { + result = listener_bind(listener, address); + if (result != ISC_R_SUCCESS) { + ns_lwreslistener_detach(&listener); + return (ISC_R_SUCCESS); + } + } else + listener_copysock(oldlistener, listener); + + result = listener_startclients(listener); + if (result != ISC_R_SUCCESS) { + isc_sockaddr_format(address, socktext, sizeof(socktext)); + isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, + NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, + "lwres: failed to start %s: %s", socktext, + isc_result_totext(result)); + ns_lwreslistener_detach(&listener); + return (ISC_R_SUCCESS); + } + + if (oldlistener != NULL) { + /* + * Remove the old listener from the old list and shut it down. + */ + ISC_LIST_UNLINK(listeners, oldlistener, link); + listener_shutdown(oldlistener); + ns_lwreslistener_detach(&oldlistener); + } else { + isc_sockaddr_format(address, socktext, sizeof(socktext)); + isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, + NS_LOGMODULE_LWRESD, ISC_LOG_NOTICE, + "lwres listening on %s", socktext); + } + + ISC_LIST_APPEND(*newlisteners, listener, link); + return (result); +} + +isc_result_t +ns_lwresd_configure(isc_mem_t *mctx, const cfg_obj_t *config) { + const cfg_obj_t *lwreslist = NULL; + const cfg_obj_t *lwres = NULL; + const cfg_obj_t *listenerslist = NULL; + const cfg_listelt_t *element = NULL; + ns_lwreslistener_t *listener; + ns_lwreslistenerlist_t newlisteners; + isc_result_t result; + char socktext[ISC_SOCKADDR_FORMATSIZE]; + isc_sockaddr_t *addrs = NULL; + ns_lwresd_t *lwresd = NULL; + isc_uint32_t count = 0; + + REQUIRE(mctx != NULL); + REQUIRE(config != NULL); + + RUNTIME_CHECK(isc_once_do(&once, initialize_mutex) == ISC_R_SUCCESS); + + ISC_LIST_INIT(newlisteners); + + result = cfg_map_get(config, "lwres", &lwreslist); + if (result != ISC_R_SUCCESS) + return (ISC_R_SUCCESS); + + LOCK(&listeners_lock); + /* + * Run through the new lwres address list, noting sockets that + * are already being listened on and moving them to the new list. + * + * Identifying duplicates addr/port combinations is left to either + * the underlying config code, or to the bind attempt getting an + * address-in-use error. + */ + for (element = cfg_list_first(lwreslist); + element != NULL; + element = cfg_list_next(element)) + { + in_port_t port; + + lwres = cfg_listelt_value(element); + CHECK(ns_lwdmanager_create(mctx, lwres, &lwresd)); + + port = lwresd_g_listenport; + if (port == 0) + port = LWRES_UDP_PORT; + + listenerslist = NULL; + (void)cfg_map_get(lwres, "listen-on", &listenerslist); + if (listenerslist == NULL) { + struct in_addr localhost; + isc_sockaddr_t address; + + localhost.s_addr = htonl(INADDR_LOOPBACK); + isc_sockaddr_fromin(&address, &localhost, port); + CHECK(configure_listener(&address, lwresd, mctx, + &newlisteners)); + } else { + isc_uint32_t i; + + CHECK(ns_config_getiplist(config, listenerslist, + port, mctx, &addrs, &count)); + for (i = 0; i < count; i++) + CHECK(configure_listener(&addrs[i], lwresd, + mctx, &newlisteners)); + ns_config_putiplist(mctx, &addrs, count); + } + ns_lwdmanager_detach(&lwresd); + } + + /* + * Shutdown everything on the listeners list, and remove them from + * the list. Then put all of the new listeners on it. + */ + + while (!ISC_LIST_EMPTY(listeners)) { + listener = ISC_LIST_HEAD(listeners); + ISC_LIST_UNLINK(listeners, listener, link); + + isc_sockaddr_format(&listener->address, + socktext, sizeof(socktext)); + + listener_shutdown(listener); + ns_lwreslistener_detach(&listener); + + isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, + NS_LOGMODULE_LWRESD, ISC_LOG_NOTICE, + "lwres no longer listening on %s", socktext); + } + + cleanup: + ISC_LIST_APPENDLIST(listeners, newlisteners, link); + + if (addrs != NULL) + ns_config_putiplist(mctx, &addrs, count); + + if (lwresd != NULL) + ns_lwdmanager_detach(&lwresd); + + UNLOCK(&listeners_lock); + + return (result); +} + +void +ns_lwresd_shutdown(void) { + ns_lwreslistener_t *listener; + + RUNTIME_CHECK(isc_once_do(&once, initialize_mutex) == ISC_R_SUCCESS); + + while (!ISC_LIST_EMPTY(listeners)) { + listener = ISC_LIST_HEAD(listeners); + ISC_LIST_UNLINK(listeners, listener, link); + ns_lwreslistener_detach(&listener); + } +} diff --git a/bin/named/lwresd.docbook b/bin/named/lwresd.docbook new file mode 100644 index 0000000..5b3143e --- /dev/null +++ b/bin/named/lwresd.docbook @@ -0,0 +1,372 @@ +]> + + + + + + June 30, 2000 + + + + lwresd + 8 + BIND9 + + + + lwresd + lightweight resolver daemon + + + + + 2004 + 2005 + 2007 + Internet Systems Consortium, Inc. ("ISC") + + + 2000 + 2001 + Internet Software Consortium. + + + + + + lwresd + + + + + + + + + + + + + + + + + + + + + DESCRIPTION + + lwresd + is the daemon providing name lookup + services to clients that use the BIND 9 lightweight resolver + library. It is essentially a stripped-down, caching-only name + server that answers queries using the BIND 9 lightweight + resolver protocol rather than the DNS protocol. + + + lwresd + listens for resolver queries on a + UDP port on the IPv4 loopback interface, 127.0.0.1. This + means that lwresd can only be used by + processes running on the local machine. By default UDP port + number 921 is used for lightweight resolver requests and + responses. + + + Incoming lightweight resolver requests are decoded by the + server which then resolves them using the DNS protocol. When + the DNS lookup completes, lwresd encodes + the answers in the lightweight resolver format and returns + them to the client that made the request. + + + If /etc/resolv.conf contains any + entries, lwresd + sends recursive DNS queries to those servers. This is similar + to the use of forwarders in a caching name server. If no + entries are present, or if + forwarding fails, lwresd resolves the + queries autonomously starting at the root name servers, using + a built-in list of root server hints. + + + + + OPTIONS + + + + + -4 + + + Use IPv4 only even if the host machine is capable of IPv6. + and are mutually + exclusive. + + + + + + -6 + + + Use IPv6 only even if the host machine is capable of IPv4. + and are mutually + exclusive. + + + + + + + -c config-file + + + Use config-file as the + configuration file instead of the default, + /etc/lwresd.conf. + + -c can not be used with -C. + + + + + + -C config-file + + + Use config-file as the + configuration file instead of the default, + /etc/resolv.conf. + -C can not be used with -c. + + + + + + -d debug-level + + + Set the daemon's debug level to debug-level. + Debugging traces from lwresd become + more verbose as the debug level increases. + + + + + + -f + + + Run the server in the foreground (i.e. do not daemonize). + + + + + + -g + + + Run the server in the foreground and force all logging + to stderr. + + + + + + -i pid-file + + + Use pid-file as the + PID file instead of the default, + /var/run/lwresd.pid. + + + + + + -m flag + + + Turn on memory usage debugging flags. Possible flags are + usage, + trace, + record, + size, and + mctx. + These correspond to the ISC_MEM_DEBUGXXXX flags described in + <isc/mem.h>. + + + + + + -n #cpus + + + Create #cpus worker threads + to take advantage of multiple CPUs. If not specified, + lwresd will try to determine the + number of CPUs present and create one thread per CPU. + If it is unable to determine the number of CPUs, a + single worker thread will be created. + + + + + + -P port + + + Listen for lightweight resolver queries on port + port. If + not specified, the default is port 921. + + + + + + -p port + + + Send DNS lookups to port port. If not + specified, the default is port 53. This provides a + way of testing the lightweight resolver daemon with a + name server that listens for queries on a non-standard + port number. + + + + + + -s + + + Write memory usage statistics to stdout + on exit. + + + + This option is mainly of interest to BIND 9 developers + and may be removed or changed in a future release. + + + + + + + -t directory + + Chroot + to directory after + processing the command line arguments, but before + reading the configuration file. + + + + This option should be used in conjunction with the + option, as chrooting a process + running as root doesn't enhance security on most + systems; the way chroot(2) is + defined allows a process with root privileges to + escape a chroot jail. + + + + + + + -u user + + Setuid + to user after completing + privileged operations, such as creating sockets that + listen on privileged ports. + + + + + + -v + + + Report the version number and exit. + + + + + + + + + + FILES + + + + + /etc/resolv.conf + + + The default configuration file. + + + + + + /var/run/lwresd.pid + + + The default process-id file. + + + + + + + + + + SEE ALSO + + named8 + , + + lwres3 + , + + resolver5 + . + + + + + AUTHOR + Internet Systems Consortium + + + + diff --git a/bin/named/lwresd.html b/bin/named/lwresd.html new file mode 100644 index 0000000..b59a7cc --- /dev/null +++ b/bin/named/lwresd.html @@ -0,0 +1,225 @@ + + + + + +lwresd + + +
+
+
+

Name

+

lwresd — lightweight resolver daemon

+
+
+

Synopsis

+

lwresd [-c config-file] [-C config-file] [-d debug-level] [-f] [-g] [-i pid-file] [-m flag] [-n #cpus] [-P port] [-p port] [-s] [-t directory] [-u user] [-v] [-4] [-6]

+
+
+

DESCRIPTION

+

lwresd + is the daemon providing name lookup + services to clients that use the BIND 9 lightweight resolver + library. It is essentially a stripped-down, caching-only name + server that answers queries using the BIND 9 lightweight + resolver protocol rather than the DNS protocol. +

+

lwresd + listens for resolver queries on a + UDP port on the IPv4 loopback interface, 127.0.0.1. This + means that lwresd can only be used by + processes running on the local machine. By default UDP port + number 921 is used for lightweight resolver requests and + responses. +

+

+ Incoming lightweight resolver requests are decoded by the + server which then resolves them using the DNS protocol. When + the DNS lookup completes, lwresd encodes + the answers in the lightweight resolver format and returns + them to the client that made the request. +

+

+ If /etc/resolv.conf contains any + nameserver entries, lwresd + sends recursive DNS queries to those servers. This is similar + to the use of forwarders in a caching name server. If no + nameserver entries are present, or if + forwarding fails, lwresd resolves the + queries autonomously starting at the root name servers, using + a built-in list of root server hints. +

+
+
+

OPTIONS

+
+
-4
+

+ Use IPv4 only even if the host machine is capable of IPv6. + -4 and -6 are mutually + exclusive. +

+
-6
+

+ Use IPv6 only even if the host machine is capable of IPv4. + -4 and -6 are mutually + exclusive. +

+
-c config-file
+

+ Use config-file as the + configuration file instead of the default, + /etc/lwresd.conf. + + <term>-c</term> can not be used with <term>-C</term>. +

+
-C config-file
+

+ Use config-file as the + configuration file instead of the default, + /etc/resolv.conf. + <term>-C</term> can not be used with <term>-c</term>. +

+
-d debug-level
+

+ Set the daemon's debug level to debug-level. + Debugging traces from lwresd become + more verbose as the debug level increases. +

+
-f
+

+ Run the server in the foreground (i.e. do not daemonize). +

+
-g
+

+ Run the server in the foreground and force all logging + to stderr. +

+
-i pid-file
+

+ Use pid-file as the + PID file instead of the default, + /var/run/lwresd.pid. +

+
-m flag
+

+ Turn on memory usage debugging flags. Possible flags are + usage, + trace, + record, + size, and + mctx. + These correspond to the ISC_MEM_DEBUGXXXX flags described in + <isc/mem.h>. +

+
-n #cpus
+

+ Create #cpus worker threads + to take advantage of multiple CPUs. If not specified, + lwresd will try to determine the + number of CPUs present and create one thread per CPU. + If it is unable to determine the number of CPUs, a + single worker thread will be created. +

+
-P port
+

+ Listen for lightweight resolver queries on port + port. If + not specified, the default is port 921. +

+
-p port
+

+ Send DNS lookups to port port. If not + specified, the default is port 53. This provides a + way of testing the lightweight resolver daemon with a + name server that listens for queries on a non-standard + port number. +

+
-s
+
+

+ Write memory usage statistics to stdout + on exit. +

+
+

Note

+

+ This option is mainly of interest to BIND 9 developers + and may be removed or changed in a future release. +

+
+
+
-t directory
+
+

Chroot + to directory after + processing the command line arguments, but before + reading the configuration file. +

+
+

Warning

+

+ This option should be used in conjunction with the + -u option, as chrooting a process + running as root doesn't enhance security on most + systems; the way chroot(2) is + defined allows a process with root privileges to + escape a chroot jail. +

+
+
+
-u user
+

Setuid + to user after completing + privileged operations, such as creating sockets that + listen on privileged ports. +

+
-v
+

+ Report the version number and exit. +

+
+
+
+

FILES

+
+
/etc/resolv.conf
+

+ The default configuration file. +

+
/var/run/lwresd.pid
+

+ The default process-id file. +

+
+
+
+

SEE ALSO

+

named(8), + lwres(3), + resolver(5). +

+
+
+

AUTHOR

+

Internet Systems Consortium +

+
+
+ diff --git a/bin/named/lwsearch.c b/bin/named/lwsearch.c new file mode 100644 index 0000000..4a61f96 --- /dev/null +++ b/bin/named/lwsearch.c @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: lwsearch.c,v 1.8.18.3 2005/07/12 01:22:17 marka Exp $ */ + +/*! \file */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#define LWSEARCHLIST_MAGIC ISC_MAGIC('L', 'W', 'S', 'L') +#define VALID_LWSEARCHLIST(l) ISC_MAGIC_VALID(l, LWSEARCHLIST_MAGIC) + +isc_result_t +ns_lwsearchlist_create(isc_mem_t *mctx, ns_lwsearchlist_t **listp) { + ns_lwsearchlist_t *list; + isc_result_t result; + + REQUIRE(mctx != NULL); + REQUIRE(listp != NULL && *listp == NULL); + + list = isc_mem_get(mctx, sizeof(ns_lwsearchlist_t)); + if (list == NULL) + return (ISC_R_NOMEMORY); + + result = isc_mutex_init(&list->lock); + if (result != ISC_R_SUCCESS) { + isc_mem_put(mctx, list, sizeof(ns_lwsearchlist_t)); + return (result); + } + list->mctx = NULL; + isc_mem_attach(mctx, &list->mctx); + list->refs = 1; + ISC_LIST_INIT(list->names); + list->magic = LWSEARCHLIST_MAGIC; + + *listp = list; + return (ISC_R_SUCCESS); +} + +void +ns_lwsearchlist_attach(ns_lwsearchlist_t *source, ns_lwsearchlist_t **target) { + REQUIRE(VALID_LWSEARCHLIST(source)); + REQUIRE(target != NULL && *target == NULL); + + LOCK(&source->lock); + INSIST(source->refs > 0); + source->refs++; + INSIST(source->refs != 0); + UNLOCK(&source->lock); + + *target = source; +} + +void +ns_lwsearchlist_detach(ns_lwsearchlist_t **listp) { + ns_lwsearchlist_t *list; + isc_mem_t *mctx; + + REQUIRE(listp != NULL); + list = *listp; + REQUIRE(VALID_LWSEARCHLIST(list)); + + LOCK(&list->lock); + INSIST(list->refs > 0); + list->refs--; + UNLOCK(&list->lock); + + *listp = NULL; + if (list->refs != 0) + return; + + mctx = list->mctx; + while (!ISC_LIST_EMPTY(list->names)) { + dns_name_t *name = ISC_LIST_HEAD(list->names); + ISC_LIST_UNLINK(list->names, name, link); + dns_name_free(name, list->mctx); + isc_mem_put(list->mctx, name, sizeof(dns_name_t)); + } + list->magic = 0; + isc_mem_put(mctx, list, sizeof(ns_lwsearchlist_t)); + isc_mem_detach(&mctx); +} + +isc_result_t +ns_lwsearchlist_append(ns_lwsearchlist_t *list, dns_name_t *name) { + dns_name_t *newname; + isc_result_t result; + + REQUIRE(VALID_LWSEARCHLIST(list)); + REQUIRE(name != NULL); + + newname = isc_mem_get(list->mctx, sizeof(dns_name_t)); + if (newname == NULL) + return (ISC_R_NOMEMORY); + dns_name_init(newname, NULL); + result = dns_name_dup(name, list->mctx, newname); + if (result != ISC_R_SUCCESS) { + isc_mem_put(list->mctx, newname, sizeof(dns_name_t)); + return (result); + } + ISC_LINK_INIT(newname, link); + ISC_LIST_APPEND(list->names, newname, link); + return (ISC_R_SUCCESS); +} + +void +ns_lwsearchctx_init(ns_lwsearchctx_t *sctx, ns_lwsearchlist_t *list, + dns_name_t *name, unsigned int ndots) +{ + INSIST(sctx != NULL); + sctx->relname = name; + sctx->searchname = NULL; + sctx->doneexact = ISC_FALSE; + sctx->exactfirst = ISC_FALSE; + sctx->ndots = ndots; + if (dns_name_isabsolute(name) || list == NULL) { + sctx->list = NULL; + return; + } + sctx->list = list; + sctx->searchname = ISC_LIST_HEAD(sctx->list->names); + if (dns_name_countlabels(name) > ndots) + sctx->exactfirst = ISC_TRUE; +} + +void +ns_lwsearchctx_first(ns_lwsearchctx_t *sctx) { + REQUIRE(sctx != NULL); + UNUSED(sctx); +} + +isc_result_t +ns_lwsearchctx_next(ns_lwsearchctx_t *sctx) { + REQUIRE(sctx != NULL); + + if (sctx->list == NULL) + return (ISC_R_NOMORE); + + if (sctx->searchname == NULL) { + INSIST (!sctx->exactfirst || sctx->doneexact); + if (sctx->exactfirst || sctx->doneexact) + return (ISC_R_NOMORE); + sctx->doneexact = ISC_TRUE; + } else { + if (sctx->exactfirst && !sctx->doneexact) + sctx->doneexact = ISC_TRUE; + else { + sctx->searchname = ISC_LIST_NEXT(sctx->searchname, + link); + if (sctx->searchname == NULL && sctx->doneexact) + return (ISC_R_NOMORE); + } + } + + return (ISC_R_SUCCESS); +} + +isc_result_t +ns_lwsearchctx_current(ns_lwsearchctx_t *sctx, dns_name_t *absname) { + dns_name_t *tname; + isc_boolean_t useexact = ISC_FALSE; + + REQUIRE(sctx != NULL); + + if (sctx->list == NULL || + sctx->searchname == NULL || + (sctx->exactfirst && !sctx->doneexact)) + useexact = ISC_TRUE; + + if (useexact) { + if (dns_name_isabsolute(sctx->relname)) + tname = NULL; + else + tname = dns_rootname; + } else + tname = sctx->searchname; + + return (dns_name_concatenate(sctx->relname, tname, absname, NULL)); +} diff --git a/bin/named/main.c b/bin/named/main.c new file mode 100644 index 0000000..6b9b67e --- /dev/null +++ b/bin/named/main.c @@ -0,0 +1,926 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: main.c,v 1.136.18.17 2006/11/10 18:51:14 marka Exp $ */ + +/*! \file */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +/* + * Defining NS_MAIN provides storage declarations (rather than extern) + * for variables in named/globals.h. + */ +#define NS_MAIN 1 + +#include +#include +#include /* Explicit, though named/log.h includes it. */ +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LIBSCF +#include +#endif + +/* + * Include header files for database drivers here. + */ +/* #include "xxdb.h" */ + +/* + * Include DLZ drivers if appropriate. + */ +#ifdef DLZ +#include +#endif + +static isc_boolean_t want_stats = ISC_FALSE; +static char program_name[ISC_DIR_NAMEMAX] = "named"; +static char absolute_conffile[ISC_DIR_PATHMAX]; +static char saved_command_line[512]; +static char version[512]; + +void +ns_main_earlywarning(const char *format, ...) { + va_list args; + + va_start(args, format); + if (ns_g_lctx != NULL) { + isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_MAIN, ISC_LOG_WARNING, + format, args); + } else { + fprintf(stderr, "%s: ", program_name); + vfprintf(stderr, format, args); + fprintf(stderr, "\n"); + fflush(stderr); + } + va_end(args); +} + +void +ns_main_earlyfatal(const char *format, ...) { + va_list args; + + va_start(args, format); + if (ns_g_lctx != NULL) { + isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, + format, args); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, + "exiting (due to early fatal error)"); + } else { + fprintf(stderr, "%s: ", program_name); + vfprintf(stderr, format, args); + fprintf(stderr, "\n"); + fflush(stderr); + } + va_end(args); + + exit(1); +} + +static void +assertion_failed(const char *file, int line, isc_assertiontype_t type, + const char *cond) +{ + /* + * Handle assertion failures. + */ + + if (ns_g_lctx != NULL) { + /* + * Reset the assetion callback in case it is the log + * routines causing the assertion. + */ + isc_assertion_setcallback(NULL); + + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, + "%s:%d: %s(%s) failed", file, line, + isc_assertion_typetotext(type), cond); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, + "exiting (due to assertion failure)"); + } else { + fprintf(stderr, "%s:%d: %s(%s) failed\n", + file, line, isc_assertion_typetotext(type), cond); + fflush(stderr); + } + + if (ns_g_coreok) + abort(); + exit(1); +} + +static void +library_fatal_error(const char *file, int line, const char *format, + va_list args) ISC_FORMAT_PRINTF(3, 0); + +static void +library_fatal_error(const char *file, int line, const char *format, + va_list args) +{ + /* + * Handle isc_error_fatal() calls from our libraries. + */ + + if (ns_g_lctx != NULL) { + /* + * Reset the error callback in case it is the log + * routines causing the assertion. + */ + isc_error_setfatal(NULL); + + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, + "%s:%d: fatal error:", file, line); + isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, + format, args); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, + "exiting (due to fatal error in library)"); + } else { + fprintf(stderr, "%s:%d: fatal error: ", file, line); + vfprintf(stderr, format, args); + fprintf(stderr, "\n"); + fflush(stderr); + } + + if (ns_g_coreok) + abort(); + exit(1); +} + +static void +library_unexpected_error(const char *file, int line, const char *format, + va_list args) ISC_FORMAT_PRINTF(3, 0); + +static void +library_unexpected_error(const char *file, int line, const char *format, + va_list args) +{ + /* + * Handle isc_error_unexpected() calls from our libraries. + */ + + if (ns_g_lctx != NULL) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_MAIN, ISC_LOG_ERROR, + "%s:%d: unexpected error:", file, line); + isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_MAIN, ISC_LOG_ERROR, + format, args); + } else { + fprintf(stderr, "%s:%d: fatal error: ", file, line); + vfprintf(stderr, format, args); + fprintf(stderr, "\n"); + fflush(stderr); + } +} + +static void +lwresd_usage(void) { + fprintf(stderr, + "usage: lwresd [-4|-6] [-c conffile | -C resolvconffile] " + "[-d debuglevel]\n" + " [-f|-g] [-n number_of_cpus] [-p port] " + "[-P listen-port] [-s]\n" + " [-t chrootdir] [-u username] [-i pidfile]\n" + " [-m {usage|trace|record|size|mctx}]\n"); +} + +static void +usage(void) { + if (ns_g_lwresdonly) { + lwresd_usage(); + return; + } + fprintf(stderr, + "usage: named [-4|-6] [-c conffile] [-d debuglevel] " + "[-f|-g] [-n number_of_cpus]\n" + " [-p port] [-s] [-t chrootdir] [-u username]\n" + " [-m {usage|trace|record|size|mctx}]\n"); +} + +static void +save_command_line(int argc, char *argv[]) { + int i; + char *src; + char *dst; + char *eob; + const char truncated[] = "..."; + isc_boolean_t quoted = ISC_FALSE; + + dst = saved_command_line; + eob = saved_command_line + sizeof(saved_command_line); + + for (i = 1; i < argc && dst < eob; i++) { + *dst++ = ' '; + + src = argv[i]; + while (*src != '\0' && dst < eob) { + /* + * This won't perfectly produce a shell-independent + * pastable command line in all circumstances, but + * comes close, and for practical purposes will + * nearly always be fine. + */ + if (quoted || isalnum(*src & 0xff) || + *src == '-' || *src == '_' || + *src == '.' || *src == '/') { + *dst++ = *src++; + quoted = ISC_FALSE; + } else { + *dst++ = '\\'; + quoted = ISC_TRUE; + } + } + } + + INSIST(sizeof(saved_command_line) >= sizeof(truncated)); + + if (dst == eob) + strcpy(eob - sizeof(truncated), truncated); + else + *dst = '\0'; +} + +static int +parse_int(char *arg, const char *desc) { + char *endp; + int tmp; + long int ltmp; + + ltmp = strtol(arg, &endp, 10); + tmp = (int) ltmp; + if (*endp != '\0') + ns_main_earlyfatal("%s '%s' must be numeric", desc, arg); + if (tmp < 0 || tmp != ltmp) + ns_main_earlyfatal("%s '%s' out of range", desc, arg); + return (tmp); +} + +static struct flag_def { + const char *name; + unsigned int value; +} mem_debug_flags[] = { + { "trace", ISC_MEM_DEBUGTRACE }, + { "record", ISC_MEM_DEBUGRECORD }, + { "usage", ISC_MEM_DEBUGUSAGE }, + { "size", ISC_MEM_DEBUGSIZE }, + { "mctx", ISC_MEM_DEBUGCTX }, + { NULL, 0 } +}; + +static void +set_flags(const char *arg, struct flag_def *defs, unsigned int *ret) { + for (;;) { + const struct flag_def *def; + const char *end = strchr(arg, ','); + int arglen; + if (end == NULL) + end = arg + strlen(arg); + arglen = end - arg; + for (def = defs; def->name != NULL; def++) { + if (arglen == (int)strlen(def->name) && + memcmp(arg, def->name, arglen) == 0) { + *ret |= def->value; + goto found; + } + } + ns_main_earlyfatal("unrecognized flag '%.*s'", arglen, arg); + found: + if (*end == '\0') + break; + arg = end + 1; + } +} + +static void +parse_command_line(int argc, char *argv[]) { + int ch; + int port; + isc_boolean_t disable6 = ISC_FALSE; + isc_boolean_t disable4 = ISC_FALSE; + + save_command_line(argc, argv); + + isc_commandline_errprint = ISC_FALSE; + while ((ch = isc_commandline_parse(argc, argv, + "46c:C:d:fgi:lm:n:N:p:P:st:u:vx:")) != -1) { + switch (ch) { + case '4': + if (disable4) + ns_main_earlyfatal("cannot specify -4 and -6"); + if (isc_net_probeipv4() != ISC_R_SUCCESS) + ns_main_earlyfatal("IPv4 not supported by OS"); + isc_net_disableipv6(); + disable6 = ISC_TRUE; + break; + case '6': + if (disable6) + ns_main_earlyfatal("cannot specify -4 and -6"); + if (isc_net_probeipv6() != ISC_R_SUCCESS) + ns_main_earlyfatal("IPv6 not supported by OS"); + isc_net_disableipv4(); + disable4 = ISC_TRUE; + break; + case 'c': + ns_g_conffile = isc_commandline_argument; + lwresd_g_conffile = isc_commandline_argument; + if (lwresd_g_useresolvconf) + ns_main_earlyfatal("cannot specify -c and -C"); + ns_g_conffileset = ISC_TRUE; + break; + case 'C': + lwresd_g_resolvconffile = isc_commandline_argument; + if (ns_g_conffileset) + ns_main_earlyfatal("cannot specify -c and -C"); + lwresd_g_useresolvconf = ISC_TRUE; + break; + case 'd': + ns_g_debuglevel = parse_int(isc_commandline_argument, + "debug level"); + break; + case 'f': + ns_g_foreground = ISC_TRUE; + break; + case 'g': + ns_g_foreground = ISC_TRUE; + ns_g_logstderr = ISC_TRUE; + break; + /* XXXBEW -i should be removed */ + case 'i': + lwresd_g_defaultpidfile = isc_commandline_argument; + break; + case 'l': + ns_g_lwresdonly = ISC_TRUE; + break; + case 'm': + set_flags(isc_commandline_argument, mem_debug_flags, + &isc_mem_debugging); + break; + case 'N': /* Deprecated. */ + case 'n': + ns_g_cpus = parse_int(isc_commandline_argument, + "number of cpus"); + if (ns_g_cpus == 0) + ns_g_cpus = 1; + break; + case 'p': + port = parse_int(isc_commandline_argument, "port"); + if (port < 1 || port > 65535) + ns_main_earlyfatal("port '%s' out of range", + isc_commandline_argument); + ns_g_port = port; + break; + /* XXXBEW Should -P be removed? */ + case 'P': + port = parse_int(isc_commandline_argument, "port"); + if (port < 1 || port > 65535) + ns_main_earlyfatal("port '%s' out of range", + isc_commandline_argument); + lwresd_g_listenport = port; + break; + case 's': + /* XXXRTH temporary syntax */ + want_stats = ISC_TRUE; + break; + case 't': + /* XXXJAB should we make a copy? */ + ns_g_chrootdir = isc_commandline_argument; + break; + case 'u': + ns_g_username = isc_commandline_argument; + break; + case 'v': + printf("BIND %s\n", ns_g_version); + exit(0); + case '?': + usage(); + ns_main_earlyfatal("unknown option '-%c'", + isc_commandline_option); + default: + ns_main_earlyfatal("parsing options returned %d", ch); + } + } + + argc -= isc_commandline_index; + argv += isc_commandline_index; + + if (argc > 0) { + usage(); + ns_main_earlyfatal("extra command line arguments"); + } +} + +static isc_result_t +create_managers(void) { + isc_result_t result; +#ifdef ISC_PLATFORM_USETHREADS + unsigned int cpus_detected; +#endif + +#ifdef ISC_PLATFORM_USETHREADS + cpus_detected = isc_os_ncpus(); + if (ns_g_cpus == 0) + ns_g_cpus = cpus_detected; + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_INFO, "found %u CPU%s, using %u worker thread%s", + cpus_detected, cpus_detected == 1 ? "" : "s", + ns_g_cpus, ns_g_cpus == 1 ? "" : "s"); +#else + ns_g_cpus = 1; +#endif + result = isc_taskmgr_create(ns_g_mctx, ns_g_cpus, 0, &ns_g_taskmgr); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_taskmgr_create() failed: %s", + isc_result_totext(result)); + return (ISC_R_UNEXPECTED); + } + + result = isc_timermgr_create(ns_g_mctx, &ns_g_timermgr); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_timermgr_create() failed: %s", + isc_result_totext(result)); + return (ISC_R_UNEXPECTED); + } + + result = isc_socketmgr_create(ns_g_mctx, &ns_g_socketmgr); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_socketmgr_create() failed: %s", + isc_result_totext(result)); + return (ISC_R_UNEXPECTED); + } + + result = isc_entropy_create(ns_g_mctx, &ns_g_entropy); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_entropy_create() failed: %s", + isc_result_totext(result)); + return (ISC_R_UNEXPECTED); + } + + result = isc_hash_create(ns_g_mctx, ns_g_entropy, DNS_NAME_MAXWIRE); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_hash_create() failed: %s", + isc_result_totext(result)); + return (ISC_R_UNEXPECTED); + } + + return (ISC_R_SUCCESS); +} + +static void +destroy_managers(void) { + ns_lwresd_shutdown(); + + isc_entropy_detach(&ns_g_entropy); + if (ns_g_fallbackentropy != NULL) + isc_entropy_detach(&ns_g_fallbackentropy); + + /* + * isc_taskmgr_destroy() will block until all tasks have exited, + */ + isc_taskmgr_destroy(&ns_g_taskmgr); + isc_timermgr_destroy(&ns_g_timermgr); + isc_socketmgr_destroy(&ns_g_socketmgr); + + /* + * isc_hash_destroy() cannot be called as long as a resolver may be + * running. Calling this after isc_taskmgr_destroy() ensures the + * call is safe. + */ + isc_hash_destroy(); +} + +static void +setup(void) { + isc_result_t result; +#ifdef HAVE_LIBSCF + char *instance = NULL; +#endif + + /* + * Get the user and group information before changing the root + * directory, so the administrator does not need to keep a copy + * of the user and group databases in the chroot'ed environment. + */ + ns_os_inituserinfo(ns_g_username); + + /* + * Initialize time conversion information + */ + ns_os_tzset(); + + ns_os_opendevnull(); + +#ifdef HAVE_LIBSCF + /* Check if named is under smf control, before chroot. */ + result = ns_smf_get_instance(&instance, 0, ns_g_mctx); + /* We don't care about instance, just check if we got one. */ + if (result == ISC_R_SUCCESS) + ns_smf_got_instance = 1; + else + ns_smf_got_instance = 0; + if (instance != NULL) + isc_mem_free(ns_g_mctx, instance); +#endif /* HAVE_LIBSCF */ + +#ifdef PATH_RANDOMDEV + /* + * Initialize system's random device as fallback entropy source + * if running chroot'ed. + */ + if (ns_g_chrootdir != NULL) { + result = isc_entropy_create(ns_g_mctx, &ns_g_fallbackentropy); + if (result != ISC_R_SUCCESS) + ns_main_earlyfatal("isc_entropy_create() failed: %s", + isc_result_totext(result)); + + result = isc_entropy_createfilesource(ns_g_fallbackentropy, + PATH_RANDOMDEV); + if (result != ISC_R_SUCCESS) { + ns_main_earlywarning("could not open pre-chroot " + "entropy source %s: %s", + PATH_RANDOMDEV, + isc_result_totext(result)); + isc_entropy_detach(&ns_g_fallbackentropy); + } + } +#endif + + ns_os_chroot(ns_g_chrootdir); + + /* + * For operating systems which have a capability mechanism, now + * is the time to switch to minimal privs and change our user id. + * On traditional UNIX systems, this call will be a no-op, and we + * will change the user ID after reading the config file the first + * time. (We need to read the config file to know which possibly + * privileged ports to bind() to.) + */ + ns_os_minprivs(); + + result = ns_log_init(ISC_TF(ns_g_username != NULL)); + if (result != ISC_R_SUCCESS) + ns_main_earlyfatal("ns_log_init() failed: %s", + isc_result_totext(result)); + + /* + * Now is the time to daemonize (if we're not running in the + * foreground). We waited until now because we wanted to get + * a valid logging context setup. We cannot daemonize any later, + * because calling create_managers() will create threads, which + * would be lost after fork(). + */ + if (!ns_g_foreground) + ns_os_daemonize(); + + /* + * We call isc_app_start() here as some versions of FreeBSD's fork() + * destroys all the signal handling it sets up. + */ + result = isc_app_start(); + if (result != ISC_R_SUCCESS) + ns_main_earlyfatal("isc_app_start() failed: %s", + isc_result_totext(result)); + + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, + ISC_LOG_NOTICE, "starting BIND %s%s", ns_g_version, + saved_command_line); + + /* + * Get the initial resource limits. + */ + (void)isc_resource_getlimit(isc_resource_stacksize, + &ns_g_initstacksize); + (void)isc_resource_getlimit(isc_resource_datasize, + &ns_g_initdatasize); + (void)isc_resource_getlimit(isc_resource_coresize, + &ns_g_initcoresize); + (void)isc_resource_getlimit(isc_resource_openfiles, + &ns_g_initopenfiles); + + /* + * If the named configuration filename is relative, prepend the current + * directory's name before possibly changing to another directory. + */ + if (! isc_file_isabsolute(ns_g_conffile)) { + result = isc_file_absolutepath(ns_g_conffile, + absolute_conffile, + sizeof(absolute_conffile)); + if (result != ISC_R_SUCCESS) + ns_main_earlyfatal("could not construct absolute path of " + "configuration file: %s", + isc_result_totext(result)); + ns_g_conffile = absolute_conffile; + } + + result = create_managers(); + if (result != ISC_R_SUCCESS) + ns_main_earlyfatal("create_managers() failed: %s", + isc_result_totext(result)); + + ns_builtin_init(); + + /* + * Add calls to register sdb drivers here. + */ + /* xxdb_init(); */ + +#ifdef DLZ + /* + * Registyer any DLZ drivers. + */ + result = dlz_drivers_init(); + if (result != ISC_R_SUCCESS) + ns_main_earlyfatal("dlz_drivers_init() failed: %s", + isc_result_totext(result)); +#endif + + ns_server_create(ns_g_mctx, &ns_g_server); +} + +static void +cleanup(void) { + destroy_managers(); + + ns_server_destroy(&ns_g_server); + + ns_builtin_deinit(); + + /* + * Add calls to unregister sdb drivers here. + */ + /* xxdb_clear(); */ + +#ifdef DLZ + /* + * Unregister any DLZ drivers. + */ + dlz_drivers_clear(); +#endif + + dns_name_destroy(); + + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, + ISC_LOG_NOTICE, "exiting"); + ns_log_shutdown(); +} + +static char *memstats = NULL; + +void +ns_main_setmemstats(const char *filename) { + /* + * Caller has to ensure locking. + */ + + if (memstats != NULL) { + free(memstats); + memstats = NULL; + } + if (filename == NULL) + return; + memstats = malloc(strlen(filename) + 1); + if (memstats) + strcpy(memstats, filename); +} + +#ifdef HAVE_LIBSCF +/* + * Get FMRI for the named process. + */ +isc_result_t +ns_smf_get_instance(char **ins_name, int debug, isc_mem_t *mctx) { + scf_handle_t *h = NULL; + int namelen; + char *instance; + + REQUIRE(ins_name != NULL && *ins_name == NULL); + + if ((h = scf_handle_create(SCF_VERSION)) == NULL) { + if (debug) + UNEXPECTED_ERROR(__FILE__, __LINE__, + "scf_handle_create() failed: %s", + scf_strerror(scf_error())); + return (ISC_R_FAILURE); + } + + if (scf_handle_bind(h) == -1) { + if (debug) + UNEXPECTED_ERROR(__FILE__, __LINE__, + "scf_handle_bind() failed: %s", + scf_strerror(scf_error())); + scf_handle_destroy(h); + return (ISC_R_FAILURE); + } + + if ((namelen = scf_myname(h, NULL, 0)) == -1) { + if (debug) + UNEXPECTED_ERROR(__FILE__, __LINE__, + "scf_myname() failed: %s", + scf_strerror(scf_error())); + scf_handle_destroy(h); + return (ISC_R_FAILURE); + } + + if ((instance = isc_mem_allocate(mctx, namelen + 1)) == NULL) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "ns_smf_get_instance memory " + "allocation failed: %s", + isc_result_totext(ISC_R_NOMEMORY)); + scf_handle_destroy(h); + return (ISC_R_FAILURE); + } + + if (scf_myname(h, instance, namelen + 1) == -1) { + if (debug) + UNEXPECTED_ERROR(__FILE__, __LINE__, + "scf_myname() failed: %s", + scf_strerror(scf_error())); + scf_handle_destroy(h); + isc_mem_free(mctx, instance); + return (ISC_R_FAILURE); + } + + scf_handle_destroy(h); + *ins_name = instance; + return (ISC_R_SUCCESS); +} +#endif /* HAVE_LIBSCF */ + +int +main(int argc, char *argv[]) { + isc_result_t result; +#ifdef HAVE_LIBSCF + char *instance = NULL; +#endif + + /* + * Record version in core image. + * strings named.core | grep "named version:" + */ + strlcat(version, +#ifdef __DATE__ + "named version: BIND " VERSION " (" __DATE__ ")", +#else + "named version: BIND " VERSION, +#endif + sizeof(version)); + result = isc_file_progname(*argv, program_name, sizeof(program_name)); + if (result != ISC_R_SUCCESS) + ns_main_earlyfatal("program name too long"); + + if (strcmp(program_name, "lwresd") == 0) + ns_g_lwresdonly = ISC_TRUE; + + isc_assertion_setcallback(assertion_failed); + isc_error_setfatal(library_fatal_error); + isc_error_setunexpected(library_unexpected_error); + + ns_os_init(program_name); + + dns_result_register(); + dst_result_register(); + isccc_result_register(); + + parse_command_line(argc, argv); + + /* + * Warn about common configuration error. + */ + if (ns_g_chrootdir != NULL) { + int len = strlen(ns_g_chrootdir); + if (strncmp(ns_g_chrootdir, ns_g_conffile, len) == 0 && + (ns_g_conffile[len] == '/' || ns_g_conffile[len] == '\\')) + ns_main_earlywarning("config filename (-c %s) contains " + "chroot path (-t %s)", + ns_g_conffile, ns_g_chrootdir); + } + + result = isc_mem_create(0, 0, &ns_g_mctx); + if (result != ISC_R_SUCCESS) + ns_main_earlyfatal("isc_mem_create() failed: %s", + isc_result_totext(result)); + + setup(); + + /* + * Start things running and then wait for a shutdown request + * or reload. + */ + do { + result = isc_app_run(); + + if (result == ISC_R_RELOAD) { + ns_server_reloadwanted(ns_g_server); + } else if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_app_run(): %s", + isc_result_totext(result)); + /* + * Force exit. + */ + result = ISC_R_SUCCESS; + } + } while (result != ISC_R_SUCCESS); + +#ifdef HAVE_LIBSCF + if (ns_smf_want_disable == 1) { + result = ns_smf_get_instance(&instance, 1, ns_g_mctx); + if (result == ISC_R_SUCCESS && instance != NULL) { + if (smf_disable_instance(instance, 0) != 0) + UNEXPECTED_ERROR(__FILE__, __LINE__, + "smf_disable_instance() " + "failed for %s : %s", + instance, + scf_strerror(scf_error())); + } + if (instance != NULL) + isc_mem_free(ns_g_mctx, instance); + } +#endif /* HAVE_LIBSCF */ + + cleanup(); + + if (want_stats) { + isc_mem_stats(ns_g_mctx, stdout); + isc_mutex_stats(stdout); + } + if (memstats != NULL) { + FILE *fp = NULL; + result = isc_stdio_open(memstats, "w", &fp); + if (result == ISC_R_SUCCESS) { + isc_mem_stats(ns_g_mctx, fp); + isc_mutex_stats(fp); + isc_stdio_close(fp); + } + } + isc_mem_destroy(&ns_g_mctx); + isc_mem_checkdestroyed(stderr); + + ns_main_setmemstats(NULL); + + isc_app_finish(); + + ns_os_closedevnull(); + + ns_os_shutdown(); + + return (0); +} diff --git a/bin/named/named.8 b/bin/named/named.8 new file mode 100644 index 0000000..f5e8230 --- /dev/null +++ b/bin/named/named.8 @@ -0,0 +1,236 @@ +.\" Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2000, 2001, 2003 Internet Software Consortium. +.\" +.\" Permission to use, copy, modify, and 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: named.8,v 1.20.18.15 2007/06/20 02:26:58 marka Exp $ +.\" +.hy 0 +.ad l +.\" Title: named +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.71.1 +.\" Date: June 30, 2000 +.\" Manual: BIND9 +.\" Source: BIND9 +.\" +.TH "NAMED" "8" "June 30, 2000" "BIND9" "BIND9" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +named \- Internet domain name server +.SH "SYNOPSIS" +.HP 6 +\fBnamed\fR [\fB\-4\fR] [\fB\-6\fR] [\fB\-c\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-d\ \fR\fB\fIdebug\-level\fR\fR] [\fB\-f\fR] [\fB\-g\fR] [\fB\-m\ \fR\fB\fIflag\fR\fR] [\fB\-n\ \fR\fB\fI#cpus\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-s\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-x\ \fR\fB\fIcache\-file\fR\fR] +.SH "DESCRIPTION" +.PP +\fBnamed\fR +is a Domain Name System (DNS) server, part of the BIND 9 distribution from ISC. For more information on the DNS, see RFCs 1033, 1034, and 1035. +.PP +When invoked without arguments, +\fBnamed\fR +will read the default configuration file +\fI/etc/named.conf\fR, read any initial data, and listen for queries. +.SH "OPTIONS" +.PP +\-4 +.RS 4 +Use IPv4 only even if the host machine is capable of IPv6. +\fB\-4\fR +and +\fB\-6\fR +are mutually exclusive. +.RE +.PP +\-6 +.RS 4 +Use IPv6 only even if the host machine is capable of IPv4. +\fB\-4\fR +and +\fB\-6\fR +are mutually exclusive. +.RE +.PP +\-c \fIconfig\-file\fR +.RS 4 +Use +\fIconfig\-file\fR +as the configuration file instead of the default, +\fI/etc/named.conf\fR. To ensure that reloading the configuration file continues to work after the server has changed its working directory due to to a possible +\fBdirectory\fR +option in the configuration file, +\fIconfig\-file\fR +should be an absolute pathname. +.RE +.PP +\-d \fIdebug\-level\fR +.RS 4 +Set the daemon's debug level to +\fIdebug\-level\fR. Debugging traces from +\fBnamed\fR +become more verbose as the debug level increases. +.RE +.PP +\-f +.RS 4 +Run the server in the foreground (i.e. do not daemonize). +.RE +.PP +\-g +.RS 4 +Run the server in the foreground and force all logging to +\fIstderr\fR. +.RE +.PP +\-m \fIflag\fR +.RS 4 +Turn on memory usage debugging flags. Possible flags are +\fIusage\fR, +\fItrace\fR, +\fIrecord\fR, +\fIsize\fR, and +\fImctx\fR. These correspond to the ISC_MEM_DEBUGXXXX flags described in +\fI\fR. +.RE +.PP +\-n \fI#cpus\fR +.RS 4 +Create +\fI#cpus\fR +worker threads to take advantage of multiple CPUs. If not specified, +\fBnamed\fR +will try to determine the number of CPUs present and create one thread per CPU. If it is unable to determine the number of CPUs, a single worker thread will be created. +.RE +.PP +\-p \fIport\fR +.RS 4 +Listen for queries on port +\fIport\fR. If not specified, the default is port 53. +.RE +.PP +\-s +.RS 4 +Write memory usage statistics to +\fIstdout\fR +on exit. +.RS +.B "Note:" +This option is mainly of interest to BIND 9 developers and may be removed or changed in a future release. +.RE +.RE +.PP +\-t \fIdirectory\fR +.RS 4 +Chroot to +\fIdirectory\fR +after processing the command line arguments, but before reading the configuration file. +.RS +.B "Warning:" +This option should be used in conjunction with the +\fB\-u\fR +option, as chrooting a process running as root doesn't enhance security on most systems; the way +\fBchroot(2)\fR +is defined allows a process with root privileges to escape a chroot jail. +.RE +.RE +.PP +\-u \fIuser\fR +.RS 4 +Setuid to +\fIuser\fR +after completing privileged operations, such as creating sockets that listen on privileged ports. +.RS +.B "Note:" +On Linux, +\fBnamed\fR +uses the kernel's capability mechanism to drop all root privileges except the ability to +\fBbind(2)\fR +to a privileged port and set process resource limits. Unfortunately, this means that the +\fB\-u\fR +option only works when +\fBnamed\fR +is run on kernel 2.2.18 or later, or kernel 2.3.99\-pre3 or later, since previous kernels did not allow privileges to be retained after +\fBsetuid(2)\fR. +.RE +.RE +.PP +\-v +.RS 4 +Report the version number and exit. +.RE +.PP +\-x \fIcache\-file\fR +.RS 4 +Load data from +\fIcache\-file\fR +into the cache of the default view. +.RS +.B "Warning:" +This option must not be used. It is only of interest to BIND 9 developers and may be removed or changed in a future release. +.RE +.RE +.SH "SIGNALS" +.PP +In routine operation, signals should not be used to control the nameserver; +\fBrndc\fR +should be used instead. +.PP +SIGHUP +.RS 4 +Force a reload of the server. +.RE +.PP +SIGINT, SIGTERM +.RS 4 +Shut down the server. +.RE +.PP +The result of sending any other signals to the server is undefined. +.SH "CONFIGURATION" +.PP +The +\fBnamed\fR +configuration file is too complex to describe in detail here. A complete description is provided in the +BIND 9 Administrator Reference Manual. +.SH "FILES" +.PP +\fI/etc/named.conf\fR +.RS 4 +The default configuration file. +.RE +.PP +\fI/var/run/named.pid\fR +.RS 4 +The default process\-id file. +.RE +.SH "SEE ALSO" +.PP +RFC 1033, +RFC 1034, +RFC 1035, +\fBnamed\-checkconf\fR(8), +\fBnamed\-checkzone\fR(8), +\fBrndc\fR(8), +\fBlwresd\fR(8), +\fBnamed.conf\fR(5), +BIND 9 Administrator Reference Manual. +.SH "AUTHOR" +.PP +Internet Systems Consortium +.SH "COPYRIGHT" +Copyright \(co 2004\-2007 Internet Systems Consortium, Inc. ("ISC") +.br +Copyright \(co 2000, 2001, 2003 Internet Software Consortium. +.br diff --git a/bin/named/named.conf.5 b/bin/named/named.conf.5 new file mode 100644 index 0000000..00c92a6 --- /dev/null +++ b/bin/named/named.conf.5 @@ -0,0 +1,520 @@ +.\" Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") +.\" +.\" Permission to use, copy, modify, and 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: named.conf.5,v 1.1.2.26 2007/08/19 23:26:13 marka Exp $ +.\" +.hy 0 +.ad l +.\" Title: \fInamed.conf\fR +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.71.1 +.\" Date: Aug 13, 2004 +.\" Manual: BIND9 +.\" Source: BIND9 +.\" +.TH "\fINAMED.CONF\fR" "5" "Aug 13, 2004" "BIND9" "BIND9" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +named.conf \- configuration file for named +.SH "SYNOPSIS" +.HP 11 +\fBnamed.conf\fR +.SH "DESCRIPTION" +.PP +\fInamed.conf\fR +is the configuration file for +\fBnamed\fR. Statements are enclosed in braces and terminated with a semi\-colon. Clauses in the statements are also semi\-colon terminated. The usual comment styles are supported: +.PP +C style: /* */ +.PP +C++ style: // to end of line +.PP +Unix style: # to end of line +.SH "ACL" +.sp +.RS 4 +.nf +acl \fIstring\fR { \fIaddress_match_element\fR; ... }; +.fi +.RE +.SH "KEY" +.sp +.RS 4 +.nf +key \fIdomain_name\fR { + algorithm \fIstring\fR; + secret \fIstring\fR; +}; +.fi +.RE +.SH "MASTERS" +.sp +.RS 4 +.nf +masters \fIstring\fR [ port \fIinteger\fR ] { + ( \fImasters\fR | \fIipv4_address\fR [port \fIinteger\fR] | + \fIipv6_address\fR [port \fIinteger\fR] ) [ key \fIstring\fR ]; ... +}; +.fi +.RE +.SH "SERVER" +.sp +.RS 4 +.nf +server ( \fIipv4_address\fR\fI[/prefixlen]\fR | \fIipv6_address\fR\fI[/prefixlen]\fR ) { + bogus \fIboolean\fR; + edns \fIboolean\fR; + edns\-udp\-size \fIinteger\fR; + max\-udp\-size \fIinteger\fR; + provide\-ixfr \fIboolean\fR; + request\-ixfr \fIboolean\fR; + keys \fIserver_key\fR; + transfers \fIinteger\fR; + transfer\-format ( many\-answers | one\-answer ); + transfer\-source ( \fIipv4_address\fR | * ) + [ port ( \fIinteger\fR | * ) ]; + transfer\-source\-v6 ( \fIipv6_address\fR | * ) + [ port ( \fIinteger\fR | * ) ]; + support\-ixfr \fIboolean\fR; // obsolete +}; +.fi +.RE +.SH "TRUSTED\-KEYS" +.sp +.RS 4 +.nf +trusted\-keys { + \fIdomain_name\fR \fIflags\fR \fIprotocol\fR \fIalgorithm\fR \fIkey\fR; ... +}; +.fi +.RE +.SH "CONTROLS" +.sp +.RS 4 +.nf +controls { + inet ( \fIipv4_address\fR | \fIipv6_address\fR | * ) + [ port ( \fIinteger\fR | * ) ] + allow { \fIaddress_match_element\fR; ... } + [ keys { \fIstring\fR; ... } ]; + unix \fIunsupported\fR; // not implemented +}; +.fi +.RE +.SH "LOGGING" +.sp +.RS 4 +.nf +logging { + channel \fIstring\fR { + file \fIlog_file\fR; + syslog \fIoptional_facility\fR; + null; + stderr; + severity \fIlog_severity\fR; + print\-time \fIboolean\fR; + print\-severity \fIboolean\fR; + print\-category \fIboolean\fR; + }; + category \fIstring\fR { \fIstring\fR; ... }; +}; +.fi +.RE +.SH "LWRES" +.sp +.RS 4 +.nf +lwres { + listen\-on [ port \fIinteger\fR ] { + ( \fIipv4_address\fR | \fIipv6_address\fR ) [ port \fIinteger\fR ]; ... + }; + view \fIstring\fR \fIoptional_class\fR; + search { \fIstring\fR; ... }; + ndots \fIinteger\fR; +}; +.fi +.RE +.SH "OPTIONS" +.sp +.RS 4 +.nf +options { + avoid\-v4\-udp\-ports { \fIport\fR; ... }; + avoid\-v6\-udp\-ports { \fIport\fR; ... }; + blackhole { \fIaddress_match_element\fR; ... }; + coresize \fIsize\fR; + datasize \fIsize\fR; + directory \fIquoted_string\fR; + dump\-file \fIquoted_string\fR; + files \fIsize\fR; + heartbeat\-interval \fIinteger\fR; + host\-statistics \fIboolean\fR; // not implemented + host\-statistics\-max \fInumber\fR; // not implemented + hostname ( \fIquoted_string\fR | none ); + interface\-interval \fIinteger\fR; + listen\-on [ port \fIinteger\fR ] { \fIaddress_match_element\fR; ... }; + listen\-on\-v6 [ port \fIinteger\fR ] { \fIaddress_match_element\fR; ... }; + match\-mapped\-addresses \fIboolean\fR; + memstatistics\-file \fIquoted_string\fR; + pid\-file ( \fIquoted_string\fR | none ); + port \fIinteger\fR; + querylog \fIboolean\fR; + recursing\-file \fIquoted_string\fR; + random\-device \fIquoted_string\fR; + recursive\-clients \fIinteger\fR; + serial\-query\-rate \fIinteger\fR; + server\-id ( \fIquoted_string\fR | none |; + stacksize \fIsize\fR; + statistics\-file \fIquoted_string\fR; + statistics\-interval \fIinteger\fR; // not yet implemented + tcp\-clients \fIinteger\fR; + tcp\-listen\-queue \fIinteger\fR; + tkey\-dhkey \fIquoted_string\fR \fIinteger\fR; + tkey\-gssapi\-credential \fIquoted_string\fR; + tkey\-domain \fIquoted_string\fR; + transfers\-per\-ns \fIinteger\fR; + transfers\-in \fIinteger\fR; + transfers\-out \fIinteger\fR; + use\-ixfr \fIboolean\fR; + version ( \fIquoted_string\fR | none ); + allow\-recursion { \fIaddress_match_element\fR; ... }; + sortlist { \fIaddress_match_element\fR; ... }; + topology { \fIaddress_match_element\fR; ... }; // not implemented + auth\-nxdomain \fIboolean\fR; // default changed + minimal\-responses \fIboolean\fR; + recursion \fIboolean\fR; + rrset\-order { + [ class \fIstring\fR ] [ type \fIstring\fR ] + [ name \fIquoted_string\fR ] \fIstring\fR \fIstring\fR; ... + }; + provide\-ixfr \fIboolean\fR; + request\-ixfr \fIboolean\fR; + rfc2308\-type1 \fIboolean\fR; // not yet implemented + additional\-from\-auth \fIboolean\fR; + additional\-from\-cache \fIboolean\fR; + query\-source ( ( \fIipv4_address\fR | * ) | [ address ( \fIipv4_address\fR | * ) ] ) [ port ( \fIinteger\fR | * ) ]; + query\-source\-v6 ( ( \fIipv6_address\fR | * ) | [ address ( \fIipv6_address\fR | * ) ] ) [ port ( \fIinteger\fR | * ) ]; + cleaning\-interval \fIinteger\fR; + min\-roots \fIinteger\fR; // not implemented + lame\-ttl \fIinteger\fR; + max\-ncache\-ttl \fIinteger\fR; + max\-cache\-ttl \fIinteger\fR; + transfer\-format ( many\-answers | one\-answer ); + max\-cache\-size \fIsize_no_default\fR; + max\-acache\-size \fIsize_no_default\fR; + clients\-per\-query \fInumber\fR; + max\-clients\-per\-query \fInumber\fR; + check\-names ( master | slave | response ) + ( fail | warn | ignore ); + check\-mx ( fail | warn | ignore ); + check\-integrity \fIboolean\fR; + check\-mx\-cname ( fail | warn | ignore ); + check\-srv\-cname ( fail | warn | ignore ); + cache\-file \fIquoted_string\fR; // test option + suppress\-initial\-notify \fIboolean\fR; // not yet implemented + preferred\-glue \fIstring\fR; + dual\-stack\-servers [ port \fIinteger\fR ] { + ( \fIquoted_string\fR [port \fIinteger\fR] | + \fIipv4_address\fR [port \fIinteger\fR] | + \fIipv6_address\fR [port \fIinteger\fR] ); ... + }; + edns\-udp\-size \fIinteger\fR; + max\-udp\-size \fIinteger\fR; + root\-delegation\-only [ exclude { \fIquoted_string\fR; ... } ]; + disable\-algorithms \fIstring\fR { \fIstring\fR; ... }; + dnssec\-enable \fIboolean\fR; + dnssec\-validation \fIboolean\fR; + dnssec\-lookaside \fIstring\fR trust\-anchor \fIstring\fR; + dnssec\-must\-be\-secure \fIstring\fR \fIboolean\fR; + dnssec\-accept\-expired \fIboolean\fR; + empty\-server \fIstring\fR; + empty\-contact \fIstring\fR; + empty\-zones\-enable \fIboolean\fR; + disable\-empty\-zone \fIstring\fR; + dialup \fIdialuptype\fR; + ixfr\-from\-differences \fIixfrdiff\fR; + allow\-query { \fIaddress_match_element\fR; ... }; + allow\-query\-cache { \fIaddress_match_element\fR; ... }; + allow\-transfer { \fIaddress_match_element\fR; ... }; + allow\-update { \fIaddress_match_element\fR; ... }; + allow\-update\-forwarding { \fIaddress_match_element\fR; ... }; + update\-check\-ksk \fIboolean\fR; + masterfile\-format ( text | raw ); + notify \fInotifytype\fR; + notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; + notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; + notify\-delay \fIseconds\fR; + also\-notify [ port \fIinteger\fR ] { ( \fIipv4_address\fR | \fIipv6_address\fR ) + [ port \fIinteger\fR ]; ... }; + allow\-notify { \fIaddress_match_element\fR; ... }; + forward ( first | only ); + forwarders [ port \fIinteger\fR ] { + ( \fIipv4_address\fR | \fIipv6_address\fR ) [ port \fIinteger\fR ]; ... + }; + max\-journal\-size \fIsize_no_default\fR; + max\-transfer\-time\-in \fIinteger\fR; + max\-transfer\-time\-out \fIinteger\fR; + max\-transfer\-idle\-in \fIinteger\fR; + max\-transfer\-idle\-out \fIinteger\fR; + max\-retry\-time \fIinteger\fR; + min\-retry\-time \fIinteger\fR; + max\-refresh\-time \fIinteger\fR; + min\-refresh\-time \fIinteger\fR; + multi\-master \fIboolean\fR; + sig\-validity\-interval \fIinteger\fR; + transfer\-source ( \fIipv4_address\fR | * ) + [ port ( \fIinteger\fR | * ) ]; + transfer\-source\-v6 ( \fIipv6_address\fR | * ) + [ port ( \fIinteger\fR | * ) ]; + alt\-transfer\-source ( \fIipv4_address\fR | * ) + [ port ( \fIinteger\fR | * ) ]; + alt\-transfer\-source\-v6 ( \fIipv6_address\fR | * ) + [ port ( \fIinteger\fR | * ) ]; + use\-alt\-transfer\-source \fIboolean\fR; + zone\-statistics \fIboolean\fR; + key\-directory \fIquoted_string\fR; + zero\-no\-soa\-ttl \fIboolean\fR; + zero\-no\-soa\-ttl\-cache \fIboolean\fR; + allow\-v6\-synthesis { \fIaddress_match_element\fR; ... }; // obsolete + deallocate\-on\-exit \fIboolean\fR; // obsolete + fake\-iquery \fIboolean\fR; // obsolete + fetch\-glue \fIboolean\fR; // obsolete + has\-old\-clients \fIboolean\fR; // obsolete + maintain\-ixfr\-base \fIboolean\fR; // obsolete + max\-ixfr\-log\-size \fIsize\fR; // obsolete + multiple\-cnames \fIboolean\fR; // obsolete + named\-xfer \fIquoted_string\fR; // obsolete + serial\-queries \fIinteger\fR; // obsolete + treat\-cr\-as\-space \fIboolean\fR; // obsolete + use\-id\-pool \fIboolean\fR; // obsolete +}; +.fi +.RE +.SH "VIEW" +.sp +.RS 4 +.nf +view \fIstring\fR \fIoptional_class\fR { + match\-clients { \fIaddress_match_element\fR; ... }; + match\-destinations { \fIaddress_match_element\fR; ... }; + match\-recursive\-only \fIboolean\fR; + key \fIstring\fR { + algorithm \fIstring\fR; + secret \fIstring\fR; + }; + zone \fIstring\fR \fIoptional_class\fR { + ... + }; + server ( \fIipv4_address\fR\fI[/prefixlen]\fR | \fIipv6_address\fR\fI[/prefixlen]\fR ) { + ... + }; + trusted\-keys { + \fIstring\fR \fIinteger\fR \fIinteger\fR \fIinteger\fR \fIquoted_string\fR; ... + }; + allow\-recursion { \fIaddress_match_element\fR; ... }; + sortlist { \fIaddress_match_element\fR; ... }; + topology { \fIaddress_match_element\fR; ... }; // not implemented + auth\-nxdomain \fIboolean\fR; // default changed + minimal\-responses \fIboolean\fR; + recursion \fIboolean\fR; + rrset\-order { + [ class \fIstring\fR ] [ type \fIstring\fR ] + [ name \fIquoted_string\fR ] \fIstring\fR \fIstring\fR; ... + }; + provide\-ixfr \fIboolean\fR; + request\-ixfr \fIboolean\fR; + rfc2308\-type1 \fIboolean\fR; // not yet implemented + additional\-from\-auth \fIboolean\fR; + additional\-from\-cache \fIboolean\fR; + query\-source ( ( \fIipv4_address\fR | * ) | [ address ( \fIipv4_address\fR | * ) ] ) [ port ( \fIinteger\fR | * ) ]; + query\-source\-v6 ( ( \fIipv6_address\fR | * ) | [ address ( \fIipv6_address\fR | * ) ] ) [ port ( \fIinteger\fR | * ) ]; + cleaning\-interval \fIinteger\fR; + min\-roots \fIinteger\fR; // not implemented + lame\-ttl \fIinteger\fR; + max\-ncache\-ttl \fIinteger\fR; + max\-cache\-ttl \fIinteger\fR; + transfer\-format ( many\-answers | one\-answer ); + max\-cache\-size \fIsize_no_default\fR; + max\-acache\-size \fIsize_no_default\fR; + clients\-per\-query \fInumber\fR; + max\-clients\-per\-query \fInumber\fR; + check\-names ( master | slave | response ) + ( fail | warn | ignore ); + check\-mx ( fail | warn | ignore ); + check\-integrity \fIboolean\fR; + check\-mx\-cname ( fail | warn | ignore ); + check\-srv\-cname ( fail | warn | ignore ); + cache\-file \fIquoted_string\fR; // test option + suppress\-initial\-notify \fIboolean\fR; // not yet implemented + preferred\-glue \fIstring\fR; + dual\-stack\-servers [ port \fIinteger\fR ] { + ( \fIquoted_string\fR [port \fIinteger\fR] | + \fIipv4_address\fR [port \fIinteger\fR] | + \fIipv6_address\fR [port \fIinteger\fR] ); ... + }; + edns\-udp\-size \fIinteger\fR; + max\-udp\-size \fIinteger\fR; + root\-delegation\-only [ exclude { \fIquoted_string\fR; ... } ]; + disable\-algorithms \fIstring\fR { \fIstring\fR; ... }; + dnssec\-enable \fIboolean\fR; + dnssec\-validation \fIboolean\fR; + dnssec\-lookaside \fIstring\fR trust\-anchor \fIstring\fR; + dnssec\-must\-be\-secure \fIstring\fR \fIboolean\fR; + dnssec\-accept\-expired \fIboolean\fR; + empty\-server \fIstring\fR; + empty\-contact \fIstring\fR; + empty\-zones\-enable \fIboolean\fR; + disable\-empty\-zone \fIstring\fR; + dialup \fIdialuptype\fR; + ixfr\-from\-differences \fIixfrdiff\fR; + allow\-query { \fIaddress_match_element\fR; ... }; + allow\-query\-cache { \fIaddress_match_element\fR; ... }; + allow\-transfer { \fIaddress_match_element\fR; ... }; + allow\-update { \fIaddress_match_element\fR; ... }; + allow\-update\-forwarding { \fIaddress_match_element\fR; ... }; + update\-check\-ksk \fIboolean\fR; + masterfile\-format ( text | raw ); + notify \fInotifytype\fR; + notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; + notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; + notify\-delay \fIseconds\fR; + also\-notify [ port \fIinteger\fR ] { ( \fIipv4_address\fR | \fIipv6_address\fR ) + [ port \fIinteger\fR ]; ... }; + allow\-notify { \fIaddress_match_element\fR; ... }; + forward ( first | only ); + forwarders [ port \fIinteger\fR ] { + ( \fIipv4_address\fR | \fIipv6_address\fR ) [ port \fIinteger\fR ]; ... + }; + max\-journal\-size \fIsize_no_default\fR; + max\-transfer\-time\-in \fIinteger\fR; + max\-transfer\-time\-out \fIinteger\fR; + max\-transfer\-idle\-in \fIinteger\fR; + max\-transfer\-idle\-out \fIinteger\fR; + max\-retry\-time \fIinteger\fR; + min\-retry\-time \fIinteger\fR; + max\-refresh\-time \fIinteger\fR; + min\-refresh\-time \fIinteger\fR; + multi\-master \fIboolean\fR; + sig\-validity\-interval \fIinteger\fR; + transfer\-source ( \fIipv4_address\fR | * ) + [ port ( \fIinteger\fR | * ) ]; + transfer\-source\-v6 ( \fIipv6_address\fR | * ) + [ port ( \fIinteger\fR | * ) ]; + alt\-transfer\-source ( \fIipv4_address\fR | * ) + [ port ( \fIinteger\fR | * ) ]; + alt\-transfer\-source\-v6 ( \fIipv6_address\fR | * ) + [ port ( \fIinteger\fR | * ) ]; + use\-alt\-transfer\-source \fIboolean\fR; + zone\-statistics \fIboolean\fR; + key\-directory \fIquoted_string\fR; + zero\-no\-soa\-ttl \fIboolean\fR; + zero\-no\-soa\-ttl\-cache \fIboolean\fR; + allow\-v6\-synthesis { \fIaddress_match_element\fR; ... }; // obsolete + fetch\-glue \fIboolean\fR; // obsolete + maintain\-ixfr\-base \fIboolean\fR; // obsolete + max\-ixfr\-log\-size \fIsize\fR; // obsolete +}; +.fi +.RE +.SH "ZONE" +.sp +.RS 4 +.nf +zone \fIstring\fR \fIoptional_class\fR { + type ( master | slave | stub | hint | + forward | delegation\-only ); + file \fIquoted_string\fR; + masters [ port \fIinteger\fR ] { + ( \fImasters\fR | + \fIipv4_address\fR [port \fIinteger\fR] | + \fIipv6_address\fR [ port \fIinteger\fR ] ) [ key \fIstring\fR ]; ... + }; + database \fIstring\fR; + delegation\-only \fIboolean\fR; + check\-names ( fail | warn | ignore ); + check\-mx ( fail | warn | ignore ); + check\-integrity \fIboolean\fR; + check\-mx\-cname ( fail | warn | ignore ); + check\-srv\-cname ( fail | warn | ignore ); + dialup \fIdialuptype\fR; + ixfr\-from\-differences \fIboolean\fR; + journal \fIquoted_string\fR; + zero\-no\-soa\-ttl \fIboolean\fR; + allow\-query { \fIaddress_match_element\fR; ... }; + allow\-transfer { \fIaddress_match_element\fR; ... }; + allow\-update { \fIaddress_match_element\fR; ... }; + allow\-update\-forwarding { \fIaddress_match_element\fR; ... }; + update\-policy { + ( grant | deny ) \fIstring\fR + ( name | subdomain | wildcard | self ) \fIstring\fR + \fIrrtypelist\fR; ... + }; + update\-check\-ksk \fIboolean\fR; + masterfile\-format ( text | raw ); + notify \fInotifytype\fR; + notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; + notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; + notify\-delay \fIseconds\fR; + also\-notify [ port \fIinteger\fR ] { ( \fIipv4_address\fR | \fIipv6_address\fR ) + [ port \fIinteger\fR ]; ... }; + allow\-notify { \fIaddress_match_element\fR; ... }; + forward ( first | only ); + forwarders [ port \fIinteger\fR ] { + ( \fIipv4_address\fR | \fIipv6_address\fR ) [ port \fIinteger\fR ]; ... + }; + max\-journal\-size \fIsize_no_default\fR; + max\-transfer\-time\-in \fIinteger\fR; + max\-transfer\-time\-out \fIinteger\fR; + max\-transfer\-idle\-in \fIinteger\fR; + max\-transfer\-idle\-out \fIinteger\fR; + max\-retry\-time \fIinteger\fR; + min\-retry\-time \fIinteger\fR; + max\-refresh\-time \fIinteger\fR; + min\-refresh\-time \fIinteger\fR; + multi\-master \fIboolean\fR; + sig\-validity\-interval \fIinteger\fR; + transfer\-source ( \fIipv4_address\fR | * ) + [ port ( \fIinteger\fR | * ) ]; + transfer\-source\-v6 ( \fIipv6_address\fR | * ) + [ port ( \fIinteger\fR | * ) ]; + alt\-transfer\-source ( \fIipv4_address\fR | * ) + [ port ( \fIinteger\fR | * ) ]; + alt\-transfer\-source\-v6 ( \fIipv6_address\fR | * ) + [ port ( \fIinteger\fR | * ) ]; + use\-alt\-transfer\-source \fIboolean\fR; + zone\-statistics \fIboolean\fR; + key\-directory \fIquoted_string\fR; + ixfr\-base \fIquoted_string\fR; // obsolete + ixfr\-tmp\-file \fIquoted_string\fR; // obsolete + maintain\-ixfr\-base \fIboolean\fR; // obsolete + max\-ixfr\-log\-size \fIsize\fR; // obsolete + pubkey \fIinteger\fR \fIinteger\fR \fIinteger\fR \fIquoted_string\fR; // obsolete +}; +.fi +.RE +.SH "FILES" +.PP +\fI/etc/named.conf\fR +.SH "SEE ALSO" +.PP +\fBnamed\fR(8), +\fBnamed\-checkconf\fR(8), +\fBrndc\fR(8), +BIND 9 Administrator Reference Manual. +.SH "COPYRIGHT" +Copyright \(co 2004\-2007 Internet Systems Consortium, Inc. ("ISC") +.br diff --git a/bin/named/named.conf.docbook b/bin/named/named.conf.docbook new file mode 100644 index 0000000..e4cfcc7 --- /dev/null +++ b/bin/named/named.conf.docbook @@ -0,0 +1,597 @@ +]> + + + + + + Aug 13, 2004 + + + + named.conf + 5 + BIND9 + + + + named.conf + configuration file for named + + + + + 2004 + 2005 + 2006 + 2007 + Internet Systems Consortium, Inc. ("ISC") + + + + + + named.conf + + + + + DESCRIPTION + named.conf is the configuration file + for + named. Statements are enclosed + in braces and terminated with a semi-colon. Clauses in + the statements are also semi-colon terminated. The usual + comment styles are supported: + + + C style: /* */ + + + C++ style: // to end of line + + + Unix style: # to end of line + + + + + ACL + +acl string { address_match_element; ... }; + + + + + + KEY + +key domain_name { + algorithm string; + secret string; +}; + + + + + MASTERS + +masters string port integer { + ( masters | ipv4_address port integer | + ipv6_address port integer ) key string ; ... +}; + + + + + SERVER + +server ( ipv4_address/prefixlen | ipv6_address/prefixlen ) { + bogus boolean; + edns boolean; + edns-udp-size integer; + max-udp-size integer; + provide-ixfr boolean; + request-ixfr boolean; + keys server_key; + transfers integer; + transfer-format ( many-answers | one-answer ); + transfer-source ( ipv4_address | * ) + port ( integer | * ) ; + transfer-source-v6 ( ipv6_address | * ) + port ( integer | * ) ; + + support-ixfr boolean; // obsolete +}; + + + + + TRUSTED-KEYS + +trusted-keys { + domain_name flags protocol algorithm key; ... +}; + + + + + CONTROLS + +controls { + inet ( ipv4_address | ipv6_address | * ) + port ( integer | * ) + allow { address_match_element; ... } + keys { string; ... } ; + unix unsupported; // not implemented +}; + + + + + LOGGING + +logging { + channel string { + file log_file; + syslog optional_facility; + null; + stderr; + severity log_severity; + print-time boolean; + print-severity boolean; + print-category boolean; + }; + category string { string; ... }; +}; + + + + + LWRES + +lwres { + listen-on port integer { + ( ipv4_address | ipv6_address ) port integer ; ... + }; + view string optional_class; + search { string; ... }; + ndots integer; +}; + + + + + OPTIONS + +options { + avoid-v4-udp-ports { port; ... }; + avoid-v6-udp-ports { port; ... }; + blackhole { address_match_element; ... }; + coresize size; + datasize size; + directory quoted_string; + dump-file quoted_string; + files size; + heartbeat-interval integer; + host-statistics boolean; // not implemented + host-statistics-max number; // not implemented + hostname ( quoted_string | none ); + interface-interval integer; + listen-on port integer { address_match_element; ... }; + listen-on-v6 port integer { address_match_element; ... }; + match-mapped-addresses boolean; + memstatistics-file quoted_string; + pid-file ( quoted_string | none ); + port integer; + querylog boolean; + recursing-file quoted_string; + random-device quoted_string; + recursive-clients integer; + serial-query-rate integer; + server-id ( quoted_string | none |; + stacksize size; + statistics-file quoted_string; + statistics-interval integer; // not yet implemented + tcp-clients integer; + tcp-listen-queue integer; + tkey-dhkey quoted_string integer; + tkey-gssapi-credential quoted_string; + tkey-domain quoted_string; + transfers-per-ns integer; + transfers-in integer; + transfers-out integer; + use-ixfr boolean; + version ( quoted_string | none ); + allow-recursion { address_match_element; ... }; + sortlist { address_match_element; ... }; + topology { address_match_element; ... }; // not implemented + auth-nxdomain boolean; // default changed + minimal-responses boolean; + recursion boolean; + rrset-order { + class string type string + name quoted_string string string; ... + }; + provide-ixfr boolean; + request-ixfr boolean; + rfc2308-type1 boolean; // not yet implemented + additional-from-auth boolean; + additional-from-cache boolean; + query-source ( ( ipv4_address | * ) | address ( ipv4_address | * ) ) port ( integer | * ) ; + query-source-v6 ( ( ipv6_address | * ) | address ( ipv6_address | * ) ) port ( integer | * ) ; + cleaning-interval integer; + min-roots integer; // not implemented + lame-ttl integer; + max-ncache-ttl integer; + max-cache-ttl integer; + transfer-format ( many-answers | one-answer ); + max-cache-size size_no_default; + max-acache-size size_no_default; + clients-per-query number; + max-clients-per-query number; + check-names ( master | slave | response ) + ( fail | warn | ignore ); + check-mx ( fail | warn | ignore ); + check-integrity boolean; + check-mx-cname ( fail | warn | ignore ); + check-srv-cname ( fail | warn | ignore ); + cache-file quoted_string; // test option + suppress-initial-notify boolean; // not yet implemented + preferred-glue string; + dual-stack-servers port integer { + ( quoted_string port integer | + ipv4_address port integer | + ipv6_address port integer ); ... + }; + edns-udp-size integer; + max-udp-size integer; + root-delegation-only exclude { quoted_string; ... } ; + disable-algorithms string { string; ... }; + dnssec-enable boolean; + dnssec-validation boolean; + dnssec-lookaside string trust-anchor string; + dnssec-must-be-secure string boolean; + dnssec-accept-expired boolean; + + empty-server string; + empty-contact string; + empty-zones-enable boolean; + disable-empty-zone string; + + dialup dialuptype; + ixfr-from-differences ixfrdiff; + + allow-query { address_match_element; ... }; + allow-query-cache { address_match_element; ... }; + allow-transfer { address_match_element; ... }; + allow-update { address_match_element; ... }; + allow-update-forwarding { address_match_element; ... }; + update-check-ksk boolean; + + masterfile-format ( text | raw ); + notify notifytype; + notify-source ( ipv4_address | * ) port ( integer | * ) ; + notify-source-v6 ( ipv6_address | * ) port ( integer | * ) ; + notify-delay seconds; + also-notify port integer { ( ipv4_address | ipv6_address ) + port integer ; ... }; + allow-notify { address_match_element; ... }; + + forward ( first | only ); + forwarders port integer { + ( ipv4_address | ipv6_address ) port integer ; ... + }; + + max-journal-size size_no_default; + max-transfer-time-in integer; + max-transfer-time-out integer; + max-transfer-idle-in integer; + max-transfer-idle-out integer; + max-retry-time integer; + min-retry-time integer; + max-refresh-time integer; + min-refresh-time integer; + multi-master boolean; + sig-validity-interval integer; + + transfer-source ( ipv4_address | * ) + port ( integer | * ) ; + transfer-source-v6 ( ipv6_address | * ) + port ( integer | * ) ; + + alt-transfer-source ( ipv4_address | * ) + port ( integer | * ) ; + alt-transfer-source-v6 ( ipv6_address | * ) + port ( integer | * ) ; + use-alt-transfer-source boolean; + + zone-statistics boolean; + key-directory quoted_string; + zero-no-soa-ttl boolean; + zero-no-soa-ttl-cache boolean; + + allow-v6-synthesis { address_match_element; ... }; // obsolete + deallocate-on-exit boolean; // obsolete + fake-iquery boolean; // obsolete + fetch-glue boolean; // obsolete + has-old-clients boolean; // obsolete + maintain-ixfr-base boolean; // obsolete + max-ixfr-log-size size; // obsolete + multiple-cnames boolean; // obsolete + named-xfer quoted_string; // obsolete + serial-queries integer; // obsolete + treat-cr-as-space boolean; // obsolete + use-id-pool boolean; // obsolete +}; + + + + + VIEW + +view string optional_class { + match-clients { address_match_element; ... }; + match-destinations { address_match_element; ... }; + match-recursive-only boolean; + + key string { + algorithm string; + secret string; + }; + + zone string optional_class { + ... + }; + + server ( ipv4_address/prefixlen | ipv6_address/prefixlen ) { + ... + }; + + trusted-keys { + string integer integer integer quoted_string; ... + }; + + allow-recursion { address_match_element; ... }; + sortlist { address_match_element; ... }; + topology { address_match_element; ... }; // not implemented + auth-nxdomain boolean; // default changed + minimal-responses boolean; + recursion boolean; + rrset-order { + class string type string + name quoted_string string string; ... + }; + provide-ixfr boolean; + request-ixfr boolean; + rfc2308-type1 boolean; // not yet implemented + additional-from-auth boolean; + additional-from-cache boolean; + query-source ( ( ipv4_address | * ) | address ( ipv4_address | * ) ) port ( integer | * ) ; + query-source-v6 ( ( ipv6_address | * ) | address ( ipv6_address | * ) ) port ( integer | * ) ; + cleaning-interval integer; + min-roots integer; // not implemented + lame-ttl integer; + max-ncache-ttl integer; + max-cache-ttl integer; + transfer-format ( many-answers | one-answer ); + max-cache-size size_no_default; + max-acache-size size_no_default; + clients-per-query number; + max-clients-per-query number; + check-names ( master | slave | response ) + ( fail | warn | ignore ); + check-mx ( fail | warn | ignore ); + check-integrity boolean; + check-mx-cname ( fail | warn | ignore ); + check-srv-cname ( fail | warn | ignore ); + cache-file quoted_string; // test option + suppress-initial-notify boolean; // not yet implemented + preferred-glue string; + dual-stack-servers port integer { + ( quoted_string port integer | + ipv4_address port integer | + ipv6_address port integer ); ... + }; + edns-udp-size integer; + max-udp-size integer; + root-delegation-only exclude { quoted_string; ... } ; + disable-algorithms string { string; ... }; + dnssec-enable boolean; + dnssec-validation boolean; + dnssec-lookaside string trust-anchor string; + dnssec-must-be-secure string boolean; + dnssec-accept-expired boolean; + + empty-server string; + empty-contact string; + empty-zones-enable boolean; + disable-empty-zone string; + + dialup dialuptype; + ixfr-from-differences ixfrdiff; + + allow-query { address_match_element; ... }; + allow-query-cache { address_match_element; ... }; + allow-transfer { address_match_element; ... }; + allow-update { address_match_element; ... }; + allow-update-forwarding { address_match_element; ... }; + update-check-ksk boolean; + + masterfile-format ( text | raw ); + notify notifytype; + notify-source ( ipv4_address | * ) port ( integer | * ) ; + notify-source-v6 ( ipv6_address | * ) port ( integer | * ) ; + notify-delay seconds; + also-notify port integer { ( ipv4_address | ipv6_address ) + port integer ; ... }; + allow-notify { address_match_element; ... }; + + forward ( first | only ); + forwarders port integer { + ( ipv4_address | ipv6_address ) port integer ; ... + }; + + max-journal-size size_no_default; + max-transfer-time-in integer; + max-transfer-time-out integer; + max-transfer-idle-in integer; + max-transfer-idle-out integer; + max-retry-time integer; + min-retry-time integer; + max-refresh-time integer; + min-refresh-time integer; + multi-master boolean; + sig-validity-interval integer; + + transfer-source ( ipv4_address | * ) + port ( integer | * ) ; + transfer-source-v6 ( ipv6_address | * ) + port ( integer | * ) ; + + alt-transfer-source ( ipv4_address | * ) + port ( integer | * ) ; + alt-transfer-source-v6 ( ipv6_address | * ) + port ( integer | * ) ; + use-alt-transfer-source boolean; + + zone-statistics boolean; + key-directory quoted_string; + zero-no-soa-ttl boolean; + zero-no-soa-ttl-cache boolean; + + allow-v6-synthesis { address_match_element; ... }; // obsolete + fetch-glue boolean; // obsolete + maintain-ixfr-base boolean; // obsolete + max-ixfr-log-size size; // obsolete +}; + + + + + ZONE + +zone string optional_class { + type ( master | slave | stub | hint | + forward | delegation-only ); + file quoted_string; + + masters port integer { + ( masters | + ipv4_address port integer | + ipv6_address port integer ) key string ; ... + }; + + database string; + delegation-only boolean; + check-names ( fail | warn | ignore ); + check-mx ( fail | warn | ignore ); + check-integrity boolean; + check-mx-cname ( fail | warn | ignore ); + check-srv-cname ( fail | warn | ignore ); + dialup dialuptype; + ixfr-from-differences boolean; + journal quoted_string; + zero-no-soa-ttl boolean; + + allow-query { address_match_element; ... }; + allow-transfer { address_match_element; ... }; + allow-update { address_match_element; ... }; + allow-update-forwarding { address_match_element; ... }; + update-policy { + ( grant | deny ) string + ( name | subdomain | wildcard | self ) string + rrtypelist; ... + }; + update-check-ksk boolean; + + masterfile-format ( text | raw ); + notify notifytype; + notify-source ( ipv4_address | * ) port ( integer | * ) ; + notify-source-v6 ( ipv6_address | * ) port ( integer | * ) ; + notify-delay seconds; + also-notify port integer { ( ipv4_address | ipv6_address ) + port integer ; ... }; + allow-notify { address_match_element; ... }; + + forward ( first | only ); + forwarders port integer { + ( ipv4_address | ipv6_address ) port integer ; ... + }; + + max-journal-size size_no_default; + max-transfer-time-in integer; + max-transfer-time-out integer; + max-transfer-idle-in integer; + max-transfer-idle-out integer; + max-retry-time integer; + min-retry-time integer; + max-refresh-time integer; + min-refresh-time integer; + multi-master boolean; + sig-validity-interval integer; + + transfer-source ( ipv4_address | * ) + port ( integer | * ) ; + transfer-source-v6 ( ipv6_address | * ) + port ( integer | * ) ; + + alt-transfer-source ( ipv4_address | * ) + port ( integer | * ) ; + alt-transfer-source-v6 ( ipv6_address | * ) + port ( integer | * ) ; + use-alt-transfer-source boolean; + + zone-statistics boolean; + key-directory quoted_string; + + ixfr-base quoted_string; // obsolete + ixfr-tmp-file quoted_string; // obsolete + maintain-ixfr-base boolean; // obsolete + max-ixfr-log-size size; // obsolete + pubkey integer integer integer quoted_string; // obsolete +}; + + + + + FILES + /etc/named.conf + + + + + SEE ALSO + + named8 + , + + named-checkconf8 + , + + rndc8 + , + BIND 9 Administrator Reference Manual. + + + + diff --git a/bin/named/named.conf.html b/bin/named/named.conf.html new file mode 100644 index 0000000..09e71a3 --- /dev/null +++ b/bin/named/named.conf.html @@ -0,0 +1,554 @@ + + + + + +named.conf + + +
+
+
+

Name

+

named.conf — configuration file for named

+
+
+

Synopsis

+

named.conf

+
+
+

DESCRIPTION

+

named.conf is the configuration file + for + named. Statements are enclosed + in braces and terminated with a semi-colon. Clauses in + the statements are also semi-colon terminated. The usual + comment styles are supported: +

+

+ C style: /* */ +

+

+ C++ style: // to end of line +

+

+ Unix style: # to end of line +

+
+
+

ACL

+


+acl string { address_match_element; ... };
+
+

+
+
+

KEY

+


+key domain_name {
+ algorithm string;
+ secret string;
+};
+

+
+
+

MASTERS

+


+masters string [ port integer ] {
+ ( masters | ipv4_address [port integer] |
+ ipv6_address [port integer] ) [ key string ]; ...
+};
+

+
+
+

SERVER

+


+server ( ipv4_address[/prefixlen] | ipv6_address[/prefixlen] ) {
+ bogus boolean;
+ edns boolean;
+ edns-udp-size integer;
+ max-udp-size integer;
+ provide-ixfr boolean;
+ request-ixfr boolean;
+ keys server_key;
+ transfers integer;
+ transfer-format ( many-answers | one-answer );
+ transfer-source ( ipv4_address | * )
+ [ port ( integer | * ) ];
+ transfer-source-v6 ( ipv6_address | * )
+ [ port ( integer | * ) ];
+
+ support-ixfr boolean; // obsolete
+};
+

+
+
+

TRUSTED-KEYS

+


+trusted-keys {
+ domain_name flags protocol algorithm key; ... 
+};
+

+
+
+

CONTROLS

+


+controls {
+ inet ( ipv4_address | ipv6_address | * )
+ [ port ( integer | * ) ]
+ allow { address_match_element; ... }
+ [ keys { string; ... } ];
+ unix unsupported; // not implemented
+};
+

+
+
+

LOGGING

+


+logging {
+ channel string {
+ file log_file;
+ syslog optional_facility;
+ null;
+ stderr;
+ severity log_severity;
+ print-time boolean;
+ print-severity boolean;
+ print-category boolean;
+ };
+ category string { string; ... };
+};
+

+
+
+

LWRES

+


+lwres {
+ listen-on [ port integer ] {
+ ( ipv4_address | ipv6_address ) [ port integer ]; ...
+ };
+ view string optional_class;
+ search { string; ... };
+ ndots integer;
+};
+

+
+
+

OPTIONS

+


+options {
+ avoid-v4-udp-ports { port; ... };
+ avoid-v6-udp-ports { port; ... };
+ blackhole { address_match_element; ... };
+ coresize size;
+ datasize size;
+ directory quoted_string;
+ dump-file quoted_string;
+ files size;
+ heartbeat-interval integer;
+ host-statistics boolean; // not implemented
+ host-statistics-max number; // not implemented
+ hostname ( quoted_string | none );
+ interface-interval integer;
+ listen-on [ port integer ] { address_match_element; ... };
+ listen-on-v6 [ port integer ] { address_match_element; ... };
+ match-mapped-addresses boolean;
+ memstatistics-file quoted_string;
+ pid-file ( quoted_string | none );
+ port integer;
+ querylog boolean;
+ recursing-file quoted_string;
+ random-device quoted_string;
+ recursive-clients integer;
+ serial-query-rate integer;
+ server-id ( quoted_string | none |;
+ stacksize size;
+ statistics-file quoted_string;
+ statistics-interval integer; // not yet implemented
+ tcp-clients integer;
+ tcp-listen-queue integer;
+ tkey-dhkey quoted_string integer;
+ tkey-gssapi-credential quoted_string;
+ tkey-domain quoted_string;
+ transfers-per-ns integer;
+ transfers-in integer;
+ transfers-out integer;
+ use-ixfr boolean;
+ version ( quoted_string | none );
+ allow-recursion { address_match_element; ... };
+ sortlist { address_match_element; ... };
+ topology { address_match_element; ... }; // not implemented
+ auth-nxdomain boolean; // default changed
+ minimal-responses boolean;
+ recursion boolean;
+ rrset-order {
+ [ class string ] [ type string ]
+ [ name quoted_string string string; ...
+ };
+ provide-ixfr boolean;
+ request-ixfr boolean;
+ rfc2308-type1 boolean; // not yet implemented
+ additional-from-auth boolean;
+ additional-from-cache boolean;
+ query-source ( ( ipv4_address | * ) | [ address ( ipv4_address | * ) ] ) [ port ( integer | * ) ];
+ query-source-v6 ( ( ipv6_address | * ) | [ address ( ipv6_address | * ) ] ) [ port ( integer | * ) ];
+ cleaning-interval integer;
+ min-roots integer; // not implemented
+ lame-ttl integer;
+ max-ncache-ttl integer;
+ max-cache-ttl integer;
+ transfer-format ( many-answers | one-answer );
+ max-cache-size size_no_default;
+ max-acache-size size_no_default;
+ clients-per-query number;
+ max-clients-per-query number;
+ check-names ( master | slave | response )
+ ( fail | warn | ignore );
+ check-mx ( fail | warn | ignore );
+ check-integrity boolean;
+ check-mx-cname ( fail | warn | ignore );
+ check-srv-cname ( fail | warn | ignore );
+ cache-file quoted_string; // test option
+ suppress-initial-notify boolean; // not yet implemented
+ preferred-glue string;
+ dual-stack-servers [ port integer ] {
+ ( quoted_string [port integer] |
+ ipv4_address [port integer] |
+ ipv6_address [port integer] ); ...
+ };
+ edns-udp-size integer;
+ max-udp-size integer;
+ root-delegation-only [ exclude { quoted_string; ... } ];
+ disable-algorithms string { string; ... };
+ dnssec-enable boolean;
+ dnssec-validation boolean;
+ dnssec-lookaside string trust-anchor string;
+ dnssec-must-be-secure string boolean;
+ dnssec-accept-expired boolean;
+
+ empty-server string;
+ empty-contact string;
+ empty-zones-enable boolean;
+ disable-empty-zone string;
+
+ dialup dialuptype;
+ ixfr-from-differences ixfrdiff;
+
+ allow-query { address_match_element; ... };
+ allow-query-cache { address_match_element; ... };
+ allow-transfer { address_match_element; ... };
+ allow-update { address_match_element; ... };
+ allow-update-forwarding { address_match_element; ... };
+ update-check-ksk boolean;
+
+ masterfile-format ( text | raw );
+ notify notifytype;
+ notify-source ( ipv4_address | * ) [ port ( integer | * ) ];
+ notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ];
+ notify-delay seconds;
+ also-notify [ port integer ] { ( ipv4_address | ipv6_address )
+ [ port integer ]; ... };
+ allow-notify { address_match_element; ... };
+
+ forward ( first | only );
+ forwarders [ port integer ] {
+ ( ipv4_address | ipv6_address ) [ port integer ]; ...
+ };
+
+ max-journal-size size_no_default;
+ max-transfer-time-in integer;
+ max-transfer-time-out integer;
+ max-transfer-idle-in integer;
+ max-transfer-idle-out integer;
+ max-retry-time integer;
+ min-retry-time integer;
+ max-refresh-time integer;
+ min-refresh-time integer;
+ multi-master boolean;
+ sig-validity-interval integer;
+
+ transfer-source ( ipv4_address | * )
+ [ port ( integer | * ) ];
+ transfer-source-v6 ( ipv6_address | * )
+ [ port ( integer | * ) ];
+
+ alt-transfer-source ( ipv4_address | * )
+ [ port ( integer | * ) ];
+ alt-transfer-source-v6 ( ipv6_address | * )
+ [ port ( integer | * ) ];
+ use-alt-transfer-source boolean;
+
+ zone-statistics boolean;
+ key-directory quoted_string;
+ zero-no-soa-ttl boolean;
+ zero-no-soa-ttl-cache boolean;
+
+ allow-v6-synthesis { address_match_element; ... }; // obsolete
+ deallocate-on-exit boolean; // obsolete
+ fake-iquery boolean; // obsolete
+ fetch-glue boolean; // obsolete
+ has-old-clients boolean; // obsolete
+ maintain-ixfr-base boolean; // obsolete
+ max-ixfr-log-size size; // obsolete
+ multiple-cnames boolean; // obsolete
+ named-xfer quoted_string; // obsolete
+ serial-queries integer; // obsolete
+ treat-cr-as-space boolean; // obsolete
+ use-id-pool boolean; // obsolete
+};
+

+
+
+

VIEW

+


+view string optional_class {
+ match-clients { address_match_element; ... };
+ match-destinations { address_match_element; ... };
+ match-recursive-only boolean;
+
+ key string {
+ algorithm string;
+ secret string;
+ };
+
+ zone string optional_class {
+ ...
+ };
+
+ server ( ipv4_address[/prefixlen] | ipv6_address[/prefixlen] ) {
+ ...
+ };
+
+ trusted-keys {
+ string integer integer integer quoted_string; ...
+ };
+
+ allow-recursion { address_match_element; ... };
+ sortlist { address_match_element; ... };
+ topology { address_match_element; ... }; // not implemented
+ auth-nxdomain boolean; // default changed
+ minimal-responses boolean;
+ recursion boolean;
+ rrset-order {
+ [ class string ] [ type string ]
+ [ name quoted_string string string; ...
+ };
+ provide-ixfr boolean;
+ request-ixfr boolean;
+ rfc2308-type1 boolean; // not yet implemented
+ additional-from-auth boolean;
+ additional-from-cache boolean;
+ query-source ( ( ipv4_address | * ) | [ address ( ipv4_address | * ) ] ) [ port ( integer | * ) ];
+ query-source-v6 ( ( ipv6_address | * ) | [ address ( ipv6_address | * ) ] ) [ port ( integer | * ) ];
+ cleaning-interval integer;
+ min-roots integer; // not implemented
+ lame-ttl integer;
+ max-ncache-ttl integer;
+ max-cache-ttl integer;
+ transfer-format ( many-answers | one-answer );
+ max-cache-size size_no_default;
+ max-acache-size size_no_default;
+ clients-per-query number;
+ max-clients-per-query number;
+ check-names ( master | slave | response )
+ ( fail | warn | ignore );
+ check-mx ( fail | warn | ignore );
+ check-integrity boolean;
+ check-mx-cname ( fail | warn | ignore );
+ check-srv-cname ( fail | warn | ignore );
+ cache-file quoted_string; // test option
+ suppress-initial-notify boolean; // not yet implemented
+ preferred-glue string;
+ dual-stack-servers [ port integer ] {
+ ( quoted_string [port integer] |
+ ipv4_address [port integer] |
+ ipv6_address [port integer] ); ...
+ };
+ edns-udp-size integer;
+ max-udp-size integer;
+ root-delegation-only [ exclude { quoted_string; ... } ];
+ disable-algorithms string { string; ... };
+ dnssec-enable boolean;
+ dnssec-validation boolean;
+ dnssec-lookaside string trust-anchor string;
+ dnssec-must-be-secure string boolean;
+ dnssec-accept-expired boolean;
+
+ empty-server string;
+ empty-contact string;
+ empty-zones-enable boolean;
+ disable-empty-zone string;
+
+ dialup dialuptype;
+ ixfr-from-differences ixfrdiff;
+
+ allow-query { address_match_element; ... };
+ allow-query-cache { address_match_element; ... };
+ allow-transfer { address_match_element; ... };
+ allow-update { address_match_element; ... };
+ allow-update-forwarding { address_match_element; ... };
+ update-check-ksk boolean;
+
+ masterfile-format ( text | raw );
+ notify notifytype;
+ notify-source ( ipv4_address | * ) [ port ( integer | * ) ];
+ notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ];
+ notify-delay seconds;
+ also-notify [ port integer ] { ( ipv4_address | ipv6_address )
+ [ port integer ]; ... };
+ allow-notify { address_match_element; ... };
+
+ forward ( first | only );
+ forwarders [ port integer ] {
+ ( ipv4_address | ipv6_address ) [ port integer ]; ...
+ };
+
+ max-journal-size size_no_default;
+ max-transfer-time-in integer;
+ max-transfer-time-out integer;
+ max-transfer-idle-in integer;
+ max-transfer-idle-out integer;
+ max-retry-time integer;
+ min-retry-time integer;
+ max-refresh-time integer;
+ min-refresh-time integer;
+ multi-master boolean;
+ sig-validity-interval integer;
+
+ transfer-source ( ipv4_address | * )
+ [ port ( integer | * ) ];
+ transfer-source-v6 ( ipv6_address | * )
+ [ port ( integer | * ) ];
+
+ alt-transfer-source ( ipv4_address | * )
+ [ port ( integer | * ) ];
+ alt-transfer-source-v6 ( ipv6_address | * )
+ [ port ( integer | * ) ];
+ use-alt-transfer-source boolean;
+
+ zone-statistics boolean;
+ key-directory quoted_string;
+ zero-no-soa-ttl boolean;
+ zero-no-soa-ttl-cache boolean;
+
+ allow-v6-synthesis { address_match_element; ... }; // obsolete
+ fetch-glue boolean; // obsolete
+ maintain-ixfr-base boolean; // obsolete
+ max-ixfr-log-size size; // obsolete
+};
+

+
+
+

ZONE

+


+zone string optional_class {
+ type ( master | slave | stub | hint |
+ forward | delegation-only );
+ file quoted_string;
+
+ masters [ port integer ] {
+ ( masters |
+ ipv4_address [port integer] |
+ ipv6_address [ port integer ] ) [ key string ]; ...
+ };
+
+ database string;
+ delegation-only boolean;
+ check-names ( fail | warn | ignore );
+ check-mx ( fail | warn | ignore );
+ check-integrity boolean;
+ check-mx-cname ( fail | warn | ignore );
+ check-srv-cname ( fail | warn | ignore );
+ dialup dialuptype;
+ ixfr-from-differences boolean;
+ journal quoted_string;
+ zero-no-soa-ttl boolean;
+
+ allow-query { address_match_element; ... };
+ allow-transfer { address_match_element; ... };
+ allow-update { address_match_element; ... };
+ allow-update-forwarding { address_match_element; ... };
+ update-policy {
+ ( grant | deny ) string
+ ( name | subdomain | wildcard | self ) string
+ rrtypelist; ...
+ };
+ update-check-ksk boolean;
+
+ masterfile-format ( text | raw );
+ notify notifytype;
+ notify-source ( ipv4_address | * ) [ port ( integer | * ) ];
+ notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ];
+ notify-delay seconds;
+ also-notify [ port integer ] { ( ipv4_address | ipv6_address )
+ [ port integer ]; ... };
+ allow-notify { address_match_element; ... };
+
+ forward ( first | only );
+ forwarders [ port integer ] {
+ ( ipv4_address | ipv6_address ) [ port integer ]; ...
+ };
+
+ max-journal-size size_no_default;
+ max-transfer-time-in integer;
+ max-transfer-time-out integer;
+ max-transfer-idle-in integer;
+ max-transfer-idle-out integer;
+ max-retry-time integer;
+ min-retry-time integer;
+ max-refresh-time integer;
+ min-refresh-time integer;
+ multi-master boolean;
+ sig-validity-interval integer;
+
+ transfer-source ( ipv4_address | * )
+ [ port ( integer | * ) ];
+ transfer-source-v6 ( ipv6_address | * )
+ [ port ( integer | * ) ];
+
+ alt-transfer-source ( ipv4_address | * )
+ [ port ( integer | * ) ];
+ alt-transfer-source-v6 ( ipv6_address | * )
+ [ port ( integer | * ) ];
+ use-alt-transfer-source boolean;
+
+ zone-statistics boolean;
+ key-directory quoted_string;
+
+ ixfr-base quoted_string; // obsolete
+ ixfr-tmp-file quoted_string; // obsolete
+ maintain-ixfr-base boolean; // obsolete
+ max-ixfr-log-size size; // obsolete
+ pubkey integer integer integer quoted_string; // obsolete
+};
+

+
+
+

FILES

+

/etc/named.conf +

+
+
+

SEE ALSO

+

named(8), + named-checkconf(8), + rndc(8), + BIND 9 Administrator Reference Manual. +

+
+
+ diff --git a/bin/named/named.docbook b/bin/named/named.docbook new file mode 100644 index 0000000..74b41f5 --- /dev/null +++ b/bin/named/named.docbook @@ -0,0 +1,406 @@ +]> + + + + + + June 30, 2000 + + + + named + 8 + BIND9 + + + + named + Internet domain name server + + + + + 2004 + 2005 + 2006 + 2007 + Internet Systems Consortium, Inc. ("ISC") + + + 2000 + 2001 + 2003 + Internet Software Consortium. + + + + + + named + + + + + + + + + + + + + + + + + + + DESCRIPTION + named + is a Domain Name System (DNS) server, + part of the BIND 9 distribution from ISC. For more + information on the DNS, see RFCs 1033, 1034, and 1035. + + + When invoked without arguments, named + will + read the default configuration file + /etc/named.conf, read any initial + data, and listen for queries. + + + + + OPTIONS + + + + -4 + + + Use IPv4 only even if the host machine is capable of IPv6. + and are mutually + exclusive. + + + + + + -6 + + + Use IPv6 only even if the host machine is capable of IPv4. + and are mutually + exclusive. + + + + + -c config-file + + + Use config-file as the + configuration file instead of the default, + /etc/named.conf. To + ensure that reloading the configuration file continues + to work after the server has changed its working + directory due to to a possible + option in the configuration + file, config-file should be + an absolute pathname. + + + + + + -d debug-level + + + Set the daemon's debug level to debug-level. + Debugging traces from named become + more verbose as the debug level increases. + + + + + + -f + + + Run the server in the foreground (i.e. do not daemonize). + + + + + + -g + + + Run the server in the foreground and force all logging + to stderr. + + + + + + -m flag + + + Turn on memory usage debugging flags. Possible flags are + usage, + trace, + record, + size, and + mctx. + These correspond to the ISC_MEM_DEBUGXXXX flags described in + <isc/mem.h>. + + + + + + -n #cpus + + + Create #cpus worker threads + to take advantage of multiple CPUs. If not specified, + named will try to determine the + number of CPUs present and create one thread per CPU. + If it is unable to determine the number of CPUs, a + single worker thread will be created. + + + + + + -p port + + + Listen for queries on port port. If not + specified, the default is port 53. + + + + + + -s + + + Write memory usage statistics to stdout on exit. + + + + This option is mainly of interest to BIND 9 developers + and may be removed or changed in a future release. + + + + + + + -t directory + + Chroot + to directory after + processing the command line arguments, but before + reading the configuration file. + + + + This option should be used in conjunction with the + option, as chrooting a process + running as root doesn't enhance security on most + systems; the way chroot(2) is + defined allows a process with root privileges to + escape a chroot jail. + + + + + + + -u user + + Setuid + to user after completing + privileged operations, such as creating sockets that + listen on privileged ports. + + + + On Linux, named uses the kernel's + capability mechanism to drop all root privileges + except the ability to bind(2) to + a + privileged port and set process resource limits. + Unfortunately, this means that the + option only works when named is + run + on kernel 2.2.18 or later, or kernel 2.3.99-pre3 or + later, since previous kernels did not allow privileges + to be retained after setuid(2). + + + + + + + -v + + + Report the version number and exit. + + + + + + -x cache-file + + + Load data from cache-file into the + cache of the default view. + + + + This option must not be used. It is only of interest + to BIND 9 developers and may be removed or changed in a + future release. + + + + + + + + + + + SIGNALS + + In routine operation, signals should not be used to control + the nameserver; rndc should be used + instead. + + + + + + SIGHUP + + + Force a reload of the server. + + + + + + SIGINT, SIGTERM + + + Shut down the server. + + + + + + + + The result of sending any other signals to the server is undefined. + + + + + + CONFIGURATION + + The named configuration file is too complex + to describe in detail here. A complete description is provided + in the + BIND 9 Administrator Reference Manual. + + + + + FILES + + + + + /etc/named.conf + + + The default configuration file. + + + + + + /var/run/named.pid + + + The default process-id file. + + + + + + + + + + SEE ALSO + RFC 1033, + RFC 1034, + RFC 1035, + + named-checkconf + 8 + , + + named-checkzone + 8 + , + + rndc + 8 + , + + lwresd + 8 + , + + named.conf + 5 + , + BIND 9 Administrator Reference Manual. + + + + + AUTHOR + Internet Systems Consortium + + + + diff --git a/bin/named/named.html b/bin/named/named.html new file mode 100644 index 0000000..294ecce --- /dev/null +++ b/bin/named/named.html @@ -0,0 +1,255 @@ + + + + + +named + + +
+
+
+

Name

+

named — Internet domain name server

+
+
+

Synopsis

+

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

+
+
+

DESCRIPTION

+

named + is a Domain Name System (DNS) server, + part of the BIND 9 distribution from ISC. For more + information on the DNS, see RFCs 1033, 1034, and 1035. +

+

+ When invoked without arguments, named + will + read the default configuration file + /etc/named.conf, read any initial + data, and listen for queries. +

+
+
+

OPTIONS

+
+
-4
+

+ Use IPv4 only even if the host machine is capable of IPv6. + -4 and -6 are mutually + exclusive. +

+
-6
+

+ Use IPv6 only even if the host machine is capable of IPv4. + -4 and -6 are mutually + exclusive. +

+
-c config-file
+

+ Use config-file as the + configuration file instead of the default, + /etc/named.conf. To + ensure that reloading the configuration file continues + to work after the server has changed its working + directory due to to a possible + directory option in the configuration + file, config-file should be + an absolute pathname. +

+
-d debug-level
+

+ Set the daemon's debug level to debug-level. + Debugging traces from named become + more verbose as the debug level increases. +

+
-f
+

+ Run the server in the foreground (i.e. do not daemonize). +

+
-g
+

+ Run the server in the foreground and force all logging + to stderr. +

+
-m flag
+

+ Turn on memory usage debugging flags. Possible flags are + usage, + trace, + record, + size, and + mctx. + These correspond to the ISC_MEM_DEBUGXXXX flags described in + <isc/mem.h>. +

+
-n #cpus
+

+ Create #cpus worker threads + to take advantage of multiple CPUs. If not specified, + named will try to determine the + number of CPUs present and create one thread per CPU. + If it is unable to determine the number of CPUs, a + single worker thread will be created. +

+
-p port
+

+ Listen for queries on port port. If not + specified, the default is port 53. +

+
-s
+
+

+ Write memory usage statistics to stdout on exit. +

+
+

Note

+

+ This option is mainly of interest to BIND 9 developers + and may be removed or changed in a future release. +

+
+
+
-t directory
+
+

Chroot + to directory after + processing the command line arguments, but before + reading the configuration file. +

+
+

Warning

+

+ This option should be used in conjunction with the + -u option, as chrooting a process + running as root doesn't enhance security on most + systems; the way chroot(2) is + defined allows a process with root privileges to + escape a chroot jail. +

+
+
+
-u user
+
+

Setuid + to user after completing + privileged operations, such as creating sockets that + listen on privileged ports. +

+
+

Note

+

+ On Linux, named uses the kernel's + capability mechanism to drop all root privileges + except the ability to bind(2) to + a + privileged port and set process resource limits. + Unfortunately, this means that the -u + option only works when named is + run + on kernel 2.2.18 or later, or kernel 2.3.99-pre3 or + later, since previous kernels did not allow privileges + to be retained after setuid(2). +

+
+
+
-v
+

+ Report the version number and exit. +

+
-x cache-file
+
+

+ Load data from cache-file into the + cache of the default view. +

+
+

Warning

+

+ This option must not be used. It is only of interest + to BIND 9 developers and may be removed or changed in a + future release. +

+
+
+
+
+
+

SIGNALS

+

+ In routine operation, signals should not be used to control + the nameserver; rndc should be used + instead. +

+
+
SIGHUP
+

+ Force a reload of the server. +

+
SIGINT, SIGTERM
+

+ Shut down the server. +

+
+

+ The result of sending any other signals to the server is undefined. +

+
+
+

CONFIGURATION

+

+ The named configuration file is too complex + to describe in detail here. A complete description is provided + in the + BIND 9 Administrator Reference Manual. +

+
+
+

FILES

+
+
/etc/named.conf
+

+ The default configuration file. +

+
/var/run/named.pid
+

+ The default process-id file. +

+
+
+
+

SEE ALSO

+

RFC 1033, + RFC 1034, + RFC 1035, + named-checkconf(8), + named-checkzone(8), + rndc(8), + lwresd(8), + named.conf(5), + BIND 9 Administrator Reference Manual. +

+
+
+

AUTHOR

+

Internet Systems Consortium +

+
+
+ diff --git a/bin/named/notify.c b/bin/named/notify.c new file mode 100644 index 0000000..db2be71 --- /dev/null +++ b/bin/named/notify.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: notify.c,v 1.30.18.3 2005/04/29 00:15:26 marka Exp $ */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +/*! \file + * \brief + * This module implements notify as in RFC1996. + */ + +static void +notify_log(ns_client_t *client, int level, const char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + ns_client_logv(client, DNS_LOGCATEGORY_NOTIFY, NS_LOGMODULE_NOTIFY, + level, fmt, ap); + va_end(ap); +} + +static void +respond(ns_client_t *client, isc_result_t result) { + dns_rcode_t rcode; + dns_message_t *message; + isc_result_t msg_result; + + message = client->message; + rcode = dns_result_torcode(result); + + msg_result = dns_message_reply(message, ISC_TRUE); + if (msg_result != ISC_R_SUCCESS) + msg_result = dns_message_reply(message, ISC_FALSE); + if (msg_result != ISC_R_SUCCESS) { + ns_client_next(client, msg_result); + return; + } + message->rcode = rcode; + if (rcode == dns_rcode_noerror) + message->flags |= DNS_MESSAGEFLAG_AA; + else + message->flags &= ~DNS_MESSAGEFLAG_AA; + ns_client_send(client); +} + +void +ns_notify_start(ns_client_t *client) { + dns_message_t *request = client->message; + isc_result_t result; + dns_name_t *zonename; + dns_rdataset_t *zone_rdataset; + dns_zone_t *zone = NULL; + char namebuf[DNS_NAME_FORMATSIZE]; + char tsigbuf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")]; + dns_name_t *tsigname; + + /* + * Interpret the question section. + */ + result = dns_message_firstname(request, DNS_SECTION_QUESTION); + if (result != ISC_R_SUCCESS) { + notify_log(client, ISC_LOG_NOTICE, + "notify question section empty"); + goto formerr; + } + + /* + * The question section must contain exactly one question. + */ + zonename = NULL; + dns_message_currentname(request, DNS_SECTION_QUESTION, &zonename); + zone_rdataset = ISC_LIST_HEAD(zonename->list); + if (ISC_LIST_NEXT(zone_rdataset, link) != NULL) { + notify_log(client, ISC_LOG_NOTICE, + "notify question section contains multiple RRs"); + goto formerr; + } + + /* The zone section must have exactly one name. */ + result = dns_message_nextname(request, DNS_SECTION_ZONE); + if (result != ISC_R_NOMORE) { + notify_log(client, ISC_LOG_NOTICE, + "notify question section contains multiple RRs"); + goto formerr; + } + + /* The one rdataset must be an SOA. */ + if (zone_rdataset->type != dns_rdatatype_soa) { + notify_log(client, ISC_LOG_NOTICE, + "notify question section contains no SOA"); + goto formerr; + } + + tsigname = NULL; + if (dns_message_gettsig(request, &tsigname) != NULL) { + dns_name_format(tsigname, namebuf, sizeof(namebuf)); + snprintf(tsigbuf, sizeof(tsigbuf), ": TSIG '%s'", namebuf); + } else + tsigbuf[0] = '\0'; + dns_name_format(zonename, namebuf, sizeof(namebuf)); + result = dns_zt_find(client->view->zonetable, zonename, 0, NULL, + &zone); + if (result != ISC_R_SUCCESS) + goto notauth; + + switch (dns_zone_gettype(zone)) { + case dns_zone_master: + case dns_zone_slave: + case dns_zone_stub: /* Allow dialup passive to work. */ + notify_log(client, ISC_LOG_INFO, + "received notify for zone '%s'%s", namebuf, tsigbuf); + respond(client, dns_zone_notifyreceive(zone, + ns_client_getsockaddr(client), request)); + break; + default: + goto notauth; + } + dns_zone_detach(&zone); + return; + + notauth: + notify_log(client, ISC_LOG_NOTICE, + "received notify for zone '%s'%s: not authoritative", + namebuf, tsigbuf); + result = DNS_R_NOTAUTH; + goto failure; + + formerr: + result = DNS_R_FORMERR; + + failure: + if (zone != NULL) + dns_zone_detach(&zone); + respond(client, result); +} diff --git a/bin/named/query.c b/bin/named/query.c new file mode 100644 index 0000000..38eb9a1 --- /dev/null +++ b/bin/named/query.c @@ -0,0 +1,4603 @@ +/* + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-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: query.c,v 1.257.18.40 2007/09/26 03:08:14 each Exp $ */ + +/*! \file */ + +#include + +#include + +#include +#include + +#include +#include +#include +#ifdef DLZ +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/*% Partial answer? */ +#define PARTIALANSWER(c) (((c)->query.attributes & \ + NS_QUERYATTR_PARTIALANSWER) != 0) +/*% Use Cache? */ +#define USECACHE(c) (((c)->query.attributes & \ + NS_QUERYATTR_CACHEOK) != 0) +/*% Recursion OK? */ +#define RECURSIONOK(c) (((c)->query.attributes & \ + NS_QUERYATTR_RECURSIONOK) != 0) +/*% Recursing? */ +#define RECURSING(c) (((c)->query.attributes & \ + NS_QUERYATTR_RECURSING) != 0) +/*% Cache glue ok? */ +#define CACHEGLUEOK(c) (((c)->query.attributes & \ + NS_QUERYATTR_CACHEGLUEOK) != 0) +/*% Want Recursion? */ +#define WANTRECURSION(c) (((c)->query.attributes & \ + NS_QUERYATTR_WANTRECURSION) != 0) +/*% Want DNSSEC? */ +#define WANTDNSSEC(c) (((c)->attributes & \ + NS_CLIENTATTR_WANTDNSSEC) != 0) +/*% No authority? */ +#define NOAUTHORITY(c) (((c)->query.attributes & \ + NS_QUERYATTR_NOAUTHORITY) != 0) +/*% No additional? */ +#define NOADDITIONAL(c) (((c)->query.attributes & \ + NS_QUERYATTR_NOADDITIONAL) != 0) +/*% Secure? */ +#define SECURE(c) (((c)->query.attributes & \ + NS_QUERYATTR_SECURE) != 0) + +#if 0 +#define CTRACE(m) isc_log_write(ns_g_lctx, \ + NS_LOGCATEGORY_CLIENT, \ + NS_LOGMODULE_QUERY, \ + ISC_LOG_DEBUG(3), \ + "client %p: %s", client, (m)) +#define QTRACE(m) isc_log_write(ns_g_lctx, \ + NS_LOGCATEGORY_GENERAL, \ + NS_LOGMODULE_QUERY, \ + ISC_LOG_DEBUG(3), \ + "query %p: %s", query, (m)) +#else +#define CTRACE(m) ((void)m) +#define QTRACE(m) ((void)m) +#endif + +#define DNS_GETDB_NOEXACT 0x01U +#define DNS_GETDB_NOLOG 0x02U +#define DNS_GETDB_PARTIAL 0x04U + +typedef struct client_additionalctx { + ns_client_t *client; + dns_rdataset_t *rdataset; +} client_additionalctx_t; + +static void +query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype); + +static isc_boolean_t +validate(ns_client_t *client, dns_db_t *db, dns_name_t *name, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); + +/*% + * Increment query statistics counters. + */ +static inline void +inc_stats(ns_client_t *client, dns_statscounter_t counter) { + dns_zone_t *zone = client->query.authzone; + + REQUIRE(counter < DNS_STATS_NCOUNTERS); + + ns_g_server->querystats[counter]++; + + if (zone != NULL) { + isc_uint64_t *zonestats = dns_zone_getstatscounters(zone); + if (zonestats != NULL) + zonestats[counter]++; + } +} + +static void +query_send(ns_client_t *client) { + dns_statscounter_t counter; + if (client->message->rcode == dns_rcode_noerror) { + if (ISC_LIST_EMPTY(client->message->sections[DNS_SECTION_ANSWER])) { + if (client->query.isreferral) { + counter = dns_statscounter_referral; + } else { + counter = dns_statscounter_nxrrset; + } + } else { + counter = dns_statscounter_success; + } + } else if (client->message->rcode == dns_rcode_nxdomain) { + counter = dns_statscounter_nxdomain; + } else { + /* We end up here in case of YXDOMAIN, and maybe others */ + counter = dns_statscounter_failure; + } + inc_stats(client, counter); + ns_client_send(client); +} + +static void +query_error(ns_client_t *client, isc_result_t result) { + inc_stats(client, dns_statscounter_failure); + ns_client_error(client, result); +} + +static void +query_next(ns_client_t *client, isc_result_t result) { + if (result == DNS_R_DUPLICATE) + inc_stats(client, dns_statscounter_duplicate); + else if (result == DNS_R_DROP) + inc_stats(client, dns_statscounter_dropped); + else + inc_stats(client, dns_statscounter_failure); + ns_client_next(client, result); +} + +static inline void +query_freefreeversions(ns_client_t *client, isc_boolean_t everything) { + ns_dbversion_t *dbversion, *dbversion_next; + unsigned int i; + + for (dbversion = ISC_LIST_HEAD(client->query.freeversions), i = 0; + dbversion != NULL; + dbversion = dbversion_next, i++) + { + dbversion_next = ISC_LIST_NEXT(dbversion, link); + /* + * If we're not freeing everything, we keep the first three + * dbversions structures around. + */ + if (i > 3 || everything) { + ISC_LIST_UNLINK(client->query.freeversions, dbversion, + link); + isc_mem_put(client->mctx, dbversion, + sizeof(*dbversion)); + } + } +} + +void +ns_query_cancel(ns_client_t *client) { + LOCK(&client->query.fetchlock); + if (client->query.fetch != NULL) { + dns_resolver_cancelfetch(client->query.fetch); + + client->query.fetch = NULL; + } + UNLOCK(&client->query.fetchlock); +} + +static inline void +query_reset(ns_client_t *client, isc_boolean_t everything) { + isc_buffer_t *dbuf, *dbuf_next; + ns_dbversion_t *dbversion, *dbversion_next; + + /*% + * Reset the query state of a client to its default state. + */ + + /* + * Cancel the fetch if it's running. + */ + ns_query_cancel(client); + + /* + * Cleanup any active versions. + */ + for (dbversion = ISC_LIST_HEAD(client->query.activeversions); + dbversion != NULL; + dbversion = dbversion_next) { + dbversion_next = ISC_LIST_NEXT(dbversion, link); + dns_db_closeversion(dbversion->db, &dbversion->version, + ISC_FALSE); + dns_db_detach(&dbversion->db); + ISC_LIST_INITANDAPPEND(client->query.freeversions, + dbversion, link); + } + ISC_LIST_INIT(client->query.activeversions); + + if (client->query.authdb != NULL) + dns_db_detach(&client->query.authdb); + if (client->query.authzone != NULL) + dns_zone_detach(&client->query.authzone); + + query_freefreeversions(client, everything); + + for (dbuf = ISC_LIST_HEAD(client->query.namebufs); + dbuf != NULL; + dbuf = dbuf_next) { + dbuf_next = ISC_LIST_NEXT(dbuf, link); + if (dbuf_next != NULL || everything) { + ISC_LIST_UNLINK(client->query.namebufs, dbuf, link); + isc_buffer_free(&dbuf); + } + } + + if (client->query.restarts > 0) { + /* + * client->query.qname was dynamically allocated. + */ + dns_message_puttempname(client->message, + &client->query.qname); + } + client->query.qname = NULL; + client->query.attributes = (NS_QUERYATTR_RECURSIONOK | + NS_QUERYATTR_CACHEOK | + NS_QUERYATTR_SECURE); + client->query.restarts = 0; + client->query.timerset = ISC_FALSE; + client->query.origqname = NULL; + client->query.qname = NULL; + client->query.dboptions = 0; + client->query.fetchoptions = 0; + client->query.gluedb = NULL; + client->query.authdbset = ISC_FALSE; + client->query.isreferral = ISC_FALSE; +} + +static void +query_next_callback(ns_client_t *client) { + query_reset(client, ISC_FALSE); +} + +void +ns_query_free(ns_client_t *client) { + query_reset(client, ISC_TRUE); +} + +static inline isc_result_t +query_newnamebuf(ns_client_t *client) { + isc_buffer_t *dbuf; + isc_result_t result; + + CTRACE("query_newnamebuf"); + /*% + * Allocate a name buffer. + */ + + dbuf = NULL; + result = isc_buffer_allocate(client->mctx, &dbuf, 1024); + if (result != ISC_R_SUCCESS) { + CTRACE("query_newnamebuf: isc_buffer_allocate failed: done"); + return (result); + } + ISC_LIST_APPEND(client->query.namebufs, dbuf, link); + + CTRACE("query_newnamebuf: done"); + return (ISC_R_SUCCESS); +} + +static inline isc_buffer_t * +query_getnamebuf(ns_client_t *client) { + isc_buffer_t *dbuf; + isc_result_t result; + isc_region_t r; + + CTRACE("query_getnamebuf"); + /*% + * Return a name buffer with space for a maximal name, allocating + * a new one if necessary. + */ + + if (ISC_LIST_EMPTY(client->query.namebufs)) { + result = query_newnamebuf(client); + if (result != ISC_R_SUCCESS) { + CTRACE("query_getnamebuf: query_newnamebuf failed: done"); + return (NULL); + } + } + + dbuf = ISC_LIST_TAIL(client->query.namebufs); + INSIST(dbuf != NULL); + isc_buffer_availableregion(dbuf, &r); + if (r.length < 255) { + result = query_newnamebuf(client); + if (result != ISC_R_SUCCESS) { + CTRACE("query_getnamebuf: query_newnamebuf failed: done"); + return (NULL); + + } + dbuf = ISC_LIST_TAIL(client->query.namebufs); + isc_buffer_availableregion(dbuf, &r); + INSIST(r.length >= 255); + } + CTRACE("query_getnamebuf: done"); + return (dbuf); +} + +static inline void +query_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf) { + isc_region_t r; + + CTRACE("query_keepname"); + /*% + * 'name' is using space in 'dbuf', but 'dbuf' has not yet been + * adjusted to take account of that. We do the adjustment. + */ + + REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) != 0); + + dns_name_toregion(name, &r); + isc_buffer_add(dbuf, r.length); + dns_name_setbuffer(name, NULL); + client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED; +} + +static inline void +query_releasename(ns_client_t *client, dns_name_t **namep) { + dns_name_t *name = *namep; + + /*% + * 'name' is no longer needed. Return it to our pool of temporary + * names. If it is using a name buffer, relinquish its exclusive + * rights on the buffer. + */ + + CTRACE("query_releasename"); + if (dns_name_hasbuffer(name)) { + INSIST((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) + != 0); + client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED; + } + dns_message_puttempname(client->message, namep); + CTRACE("query_releasename: done"); +} + +static inline dns_name_t * +query_newname(ns_client_t *client, isc_buffer_t *dbuf, + isc_buffer_t *nbuf) +{ + dns_name_t *name; + isc_region_t r; + isc_result_t result; + + REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) == 0); + + CTRACE("query_newname"); + name = NULL; + result = dns_message_gettempname(client->message, &name); + if (result != ISC_R_SUCCESS) { + CTRACE("query_newname: dns_message_gettempname failed: done"); + return (NULL); + } + isc_buffer_availableregion(dbuf, &r); + isc_buffer_init(nbuf, r.base, r.length); + dns_name_init(name, NULL); + dns_name_setbuffer(name, nbuf); + client->query.attributes |= NS_QUERYATTR_NAMEBUFUSED; + + CTRACE("query_newname: done"); + return (name); +} + +static inline dns_rdataset_t * +query_newrdataset(ns_client_t *client) { + dns_rdataset_t *rdataset; + isc_result_t result; + + CTRACE("query_newrdataset"); + rdataset = NULL; + result = dns_message_gettemprdataset(client->message, &rdataset); + if (result != ISC_R_SUCCESS) { + CTRACE("query_newrdataset: " + "dns_message_gettemprdataset failed: done"); + return (NULL); + } + dns_rdataset_init(rdataset); + + CTRACE("query_newrdataset: done"); + return (rdataset); +} + +static inline void +query_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) { + dns_rdataset_t *rdataset = *rdatasetp; + + CTRACE("query_putrdataset"); + if (rdataset != NULL) { + if (dns_rdataset_isassociated(rdataset)) + dns_rdataset_disassociate(rdataset); + dns_message_puttemprdataset(client->message, rdatasetp); + } + CTRACE("query_putrdataset: done"); +} + + +static inline isc_result_t +query_newdbversion(ns_client_t *client, unsigned int n) { + unsigned int i; + ns_dbversion_t *dbversion; + + for (i = 0; i < n; i++) { + dbversion = isc_mem_get(client->mctx, sizeof(*dbversion)); + if (dbversion != NULL) { + dbversion->db = NULL; + dbversion->version = NULL; + ISC_LIST_INITANDAPPEND(client->query.freeversions, + dbversion, link); + } else { + /* + * We only return ISC_R_NOMEMORY if we couldn't + * allocate anything. + */ + if (i == 0) + return (ISC_R_NOMEMORY); + else + return (ISC_R_SUCCESS); + } + } + + return (ISC_R_SUCCESS); +} + +static inline ns_dbversion_t * +query_getdbversion(ns_client_t *client) { + isc_result_t result; + ns_dbversion_t *dbversion; + + if (ISC_LIST_EMPTY(client->query.freeversions)) { + result = query_newdbversion(client, 1); + if (result != ISC_R_SUCCESS) + return (NULL); + } + dbversion = ISC_LIST_HEAD(client->query.freeversions); + INSIST(dbversion != NULL); + ISC_LIST_UNLINK(client->query.freeversions, dbversion, link); + + return (dbversion); +} + +isc_result_t +ns_query_init(ns_client_t *client) { + isc_result_t result; + + ISC_LIST_INIT(client->query.namebufs); + ISC_LIST_INIT(client->query.activeversions); + ISC_LIST_INIT(client->query.freeversions); + client->query.restarts = 0; + client->query.timerset = ISC_FALSE; + client->query.qname = NULL; + result = isc_mutex_init(&client->query.fetchlock); + if (result != ISC_R_SUCCESS) + return (result); + client->query.fetch = NULL; + client->query.authdb = NULL; + client->query.authzone = NULL; + client->query.authdbset = ISC_FALSE; + client->query.isreferral = ISC_FALSE; + query_reset(client, ISC_FALSE); + result = query_newdbversion(client, 3); + if (result != ISC_R_SUCCESS) { + DESTROYLOCK(&client->query.fetchlock); + return (result); + } + result = query_newnamebuf(client); + if (result != ISC_R_SUCCESS) + query_freefreeversions(client, ISC_TRUE); + + return (result); +} + +static inline ns_dbversion_t * +query_findversion(ns_client_t *client, dns_db_t *db, + isc_boolean_t *newzonep) +{ + ns_dbversion_t *dbversion; + + /*% + * We may already have done a query related to this + * database. If so, we must be sure to make subsequent + * queries from the same version. + */ + for (dbversion = ISC_LIST_HEAD(client->query.activeversions); + dbversion != NULL; + dbversion = ISC_LIST_NEXT(dbversion, link)) { + if (dbversion->db == db) + break; + } + + if (dbversion == NULL) { + /* + * This is a new zone for this query. Add it to + * the active list. + */ + dbversion = query_getdbversion(client); + if (dbversion == NULL) + return (NULL); + dns_db_attach(db, &dbversion->db); + dns_db_currentversion(db, &dbversion->version); + dbversion->queryok = ISC_FALSE; + ISC_LIST_APPEND(client->query.activeversions, + dbversion, link); + *newzonep = ISC_TRUE; + } else + *newzonep = ISC_FALSE; + + return (dbversion); +} + +static inline isc_result_t +query_validatezonedb(ns_client_t *client, dns_name_t *name, + dns_rdatatype_t qtype, unsigned int options, + dns_zone_t *zone, dns_db_t *db, + dns_dbversion_t **versionp) +{ + isc_result_t result; + isc_boolean_t check_acl, new_zone; + dns_acl_t *queryacl; + ns_dbversion_t *dbversion; + + REQUIRE(zone != NULL); + REQUIRE(db != NULL); + + /* + * This limits our searching to the zone where the first name + * (the query target) was looked for. This prevents following + * CNAMES or DNAMES into other zones and prevents returning + * additional data from other zones. + */ + if (!client->view->additionalfromauth && + client->query.authdbset && + db != client->query.authdb) + goto refuse; + + /* + * If the zone has an ACL, we'll check it, otherwise + * we use the view's "allow-query" ACL. Each ACL is only checked + * once per query. + * + * Also, get the database version to use. + */ + + check_acl = ISC_TRUE; /* Keep compiler happy. */ + queryacl = NULL; + + /* + * Get the current version of this database. + */ + dbversion = query_findversion(client, db, &new_zone); + if (dbversion == NULL) { + result = DNS_R_SERVFAIL; + goto fail; + } + if (new_zone) { + check_acl = ISC_TRUE; + } else if (!dbversion->queryok) { + goto refuse; + } else { + check_acl = ISC_FALSE; + } + + queryacl = dns_zone_getqueryacl(zone); + if (queryacl == NULL) { + queryacl = client->view->queryacl; + if ((client->query.attributes & + NS_QUERYATTR_QUERYOKVALID) != 0) { + /* + * We've evaluated the view's queryacl already. If + * NS_QUERYATTR_QUERYOK is set, then the client is + * allowed to make queries, otherwise the query should + * be refused. + */ + check_acl = ISC_FALSE; + if ((client->query.attributes & + NS_QUERYATTR_QUERYOK) == 0) + goto refuse; + } else { + /* + * We haven't evaluated the view's queryacl yet. + */ + check_acl = ISC_TRUE; + } + } + + if (check_acl) { + isc_boolean_t log = ISC_TF((options & DNS_GETDB_NOLOG) == 0); + + result = ns_client_checkaclsilent(client, queryacl, ISC_TRUE); + if (log) { + char msg[NS_CLIENT_ACLMSGSIZE("query")]; + if (result == ISC_R_SUCCESS) { + if (isc_log_wouldlog(ns_g_lctx, + ISC_LOG_DEBUG(3))) + { + ns_client_aclmsg("query", name, qtype, + client->view->rdclass, + msg, sizeof(msg)); + ns_client_log(client, + DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_QUERY, + ISC_LOG_DEBUG(3), + "%s approved", msg); + } + } else { + ns_client_aclmsg("query", name, qtype, + client->view->rdclass, + msg, sizeof(msg)); + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_QUERY, ISC_LOG_INFO, + "%s denied", msg); + } + } + + if (queryacl == client->view->queryacl) { + if (result == ISC_R_SUCCESS) { + /* + * We were allowed by the default + * "allow-query" ACL. Remember this so we + * don't have to check again. + */ + client->query.attributes |= + NS_QUERYATTR_QUERYOK; + } + /* + * We've now evaluated the view's query ACL, and + * the NS_QUERYATTR_QUERYOK attribute is now valid. + */ + client->query.attributes |= NS_QUERYATTR_QUERYOKVALID; + } + + if (result != ISC_R_SUCCESS) + goto refuse; + } + + /* Approved. */ + + /* + * Remember the result of the ACL check so we + * don't have to check again. + */ + dbversion->queryok = ISC_TRUE; + + /* Transfer ownership, if necessary. */ + if (versionp != NULL) + *versionp = dbversion->version; + + return (ISC_R_SUCCESS); + + refuse: + return (DNS_R_REFUSED); + + fail: + return (result); +} + +static inline isc_result_t +query_getzonedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, + unsigned int options, dns_zone_t **zonep, dns_db_t **dbp, + dns_dbversion_t **versionp) +{ + isc_result_t result; + unsigned int ztoptions; + dns_zone_t *zone = NULL; + dns_db_t *db = NULL; + isc_boolean_t partial = ISC_FALSE; + + REQUIRE(zonep != NULL && *zonep == NULL); + REQUIRE(dbp != NULL && *dbp == NULL); + + /*% + * Find a zone database to answer the query. + */ + ztoptions = ((options & DNS_GETDB_NOEXACT) != 0) ? + DNS_ZTFIND_NOEXACT : 0; + + result = dns_zt_find(client->view->zonetable, name, ztoptions, NULL, + &zone); + if (result == DNS_R_PARTIALMATCH) + partial = ISC_TRUE; + if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) + result = dns_zone_getdb(zone, &db); + + if (result != ISC_R_SUCCESS) + goto fail; + + result = query_validatezonedb(client, name, qtype, options, zone, db, + versionp); + + if (result != ISC_R_SUCCESS) + goto fail; + + /* Transfer ownership. */ + *zonep = zone; + *dbp = db; + + if (partial && (options & DNS_GETDB_PARTIAL) != 0) + return (DNS_R_PARTIALMATCH); + return (ISC_R_SUCCESS); + + fail: + if (zone != NULL) + dns_zone_detach(&zone); + if (db != NULL) + dns_db_detach(&db); + + return (result); +} + +static inline isc_result_t +query_getcachedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, + dns_db_t **dbp, unsigned int options) +{ + isc_result_t result; + isc_boolean_t check_acl; + dns_db_t *db = NULL; + + REQUIRE(dbp != NULL && *dbp == NULL); + + /*% + * Find a cache database to answer the query. + * This may fail with DNS_R_REFUSED if the client + * is not allowed to use the cache. + */ + + if (!USECACHE(client)) + return (DNS_R_REFUSED); + dns_db_attach(client->view->cachedb, &db); + + if ((client->query.attributes & + NS_QUERYATTR_QUERYOKVALID) != 0) { + /* + * We've evaluated the view's queryacl already. If + * NS_QUERYATTR_QUERYOK is set, then the client is + * allowed to make queries, otherwise the query should + * be refused. + */ + check_acl = ISC_FALSE; + if ((client->query.attributes & + NS_QUERYATTR_QUERYOK) == 0) + goto refuse; + } else { + /* + * We haven't evaluated the view's queryacl yet. + */ + check_acl = ISC_TRUE; + } + + if (check_acl) { + isc_boolean_t log = ISC_TF((options & DNS_GETDB_NOLOG) == 0); + char msg[NS_CLIENT_ACLMSGSIZE("query (cache)")]; + + result = ns_client_checkaclsilent(client, + client->view->queryacl, + ISC_TRUE); + if (result == ISC_R_SUCCESS) { + /* + * We were allowed by the default + * "allow-query" ACL. Remember this so we + * don't have to check again. + */ + client->query.attributes |= + NS_QUERYATTR_QUERYOK; + if (log && isc_log_wouldlog(ns_g_lctx, + ISC_LOG_DEBUG(3))) + { + ns_client_aclmsg("query (cache)", name, qtype, + client->view->rdclass, + msg, sizeof(msg)); + ns_client_log(client, + DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_QUERY, + ISC_LOG_DEBUG(3), + "%s approved", msg); + } + } else if (log) { + ns_client_aclmsg("query (cache)", name, qtype, + client->view->rdclass, msg, + sizeof(msg)); + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_QUERY, ISC_LOG_INFO, + "%s denied", msg); + } + /* + * We've now evaluated the view's query ACL, and + * the NS_QUERYATTR_QUERYOK attribute is now valid. + */ + client->query.attributes |= NS_QUERYATTR_QUERYOKVALID; + + if (result != ISC_R_SUCCESS) + goto refuse; + } + + /* Approved. */ + + /* Transfer ownership. */ + *dbp = db; + + return (ISC_R_SUCCESS); + + refuse: + result = DNS_R_REFUSED; + + if (db != NULL) + dns_db_detach(&db); + + return (result); +} + + +static inline isc_result_t +query_getdb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, + unsigned int options, dns_zone_t **zonep, dns_db_t **dbp, + dns_dbversion_t **versionp, isc_boolean_t *is_zonep) +{ + isc_result_t result; + +#ifdef DLZ + isc_result_t tresult; + unsigned int namelabels; + unsigned int zonelabels; + dns_zone_t *zone = NULL; + dns_db_t *tdbp; + + REQUIRE(zonep != NULL && *zonep == NULL); + + tdbp = NULL; + + /* Calculate how many labels are in name. */ + namelabels = dns_name_countlabels(name); + zonelabels = 0; + + /* Try to find name in bind's standard database. */ + result = query_getzonedb(client, name, qtype, options, &zone, + dbp, versionp); + + /* See how many labels are in the zone's name. */ + if (result == ISC_R_SUCCESS && zone != NULL) + zonelabels = dns_name_countlabels(dns_zone_getorigin(zone)); + /* + * If # zone labels < # name labels, try to find an even better match + * Only try if a DLZ driver is loaded for this view + */ + if (zonelabels < namelabels && client->view->dlzdatabase != NULL) { + tresult = dns_dlzfindzone(client->view, name, + zonelabels, &tdbp); + /* If we successful, we found a better match. */ + if (tresult == ISC_R_SUCCESS) { + /* + * If the previous search returned a zone, detach it. + */ + if (zone != NULL) + dns_zone_detach(&zone); + + /* + * If the previous search returned a database, + * detach it. + */ + if (*dbp != NULL) + dns_db_detach(dbp); + + /* + * If the previous search returned a version, clear it. + */ + *versionp = NULL; + + /* + * Get our database version. + */ + dns_db_currentversion(tdbp, versionp); + + /* + * Be sure to return our database. + */ + *dbp = tdbp; + + /* + * We return a null zone, No stats for DLZ zones. + */ + zone = NULL; + result = tresult; + } + } +#else + result = query_getzonedb(client, name, qtype, options, + zonep, dbp, versionp); +#endif + + /* If successfull, Transfer ownership of zone. */ + if (result == ISC_R_SUCCESS) { +#ifdef DLZ + *zonep = zone; +#endif + /* + * If neither attempt above succeeded, return the cache instead + */ + *is_zonep = ISC_TRUE; + } else if (result == ISC_R_NOTFOUND) { + result = query_getcachedb(client, name, qtype, dbp, options); + *is_zonep = ISC_FALSE; + } + return (result); +} + +static inline isc_boolean_t +query_isduplicate(ns_client_t *client, dns_name_t *name, + dns_rdatatype_t type, dns_name_t **mnamep) +{ + dns_section_t section; + dns_name_t *mname = NULL; + isc_result_t result; + + CTRACE("query_isduplicate"); + + for (section = DNS_SECTION_ANSWER; + section <= DNS_SECTION_ADDITIONAL; + section++) { + result = dns_message_findname(client->message, section, + name, type, 0, &mname, NULL); + if (result == ISC_R_SUCCESS) { + /* + * We've already got this RRset in the response. + */ + CTRACE("query_isduplicate: true: done"); + return (ISC_TRUE); + } else if (result == DNS_R_NXRRSET) { + /* + * The name exists, but the rdataset does not. + */ + if (section == DNS_SECTION_ADDITIONAL) + break; + } else + RUNTIME_CHECK(result == DNS_R_NXDOMAIN); + mname = NULL; + } + + /* + * If the dns_name_t we're looking up is already in the message, + * we don't want to trigger the caller's name replacement logic. + */ + if (name == mname) + mname = NULL; + + *mnamep = mname; + + CTRACE("query_isduplicate: false: done"); + return (ISC_FALSE); +} + +static isc_result_t +query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { + ns_client_t *client = arg; + isc_result_t result, eresult; + dns_dbnode_t *node; + dns_db_t *db; + dns_name_t *fname, *mname; + dns_rdataset_t *rdataset, *sigrdataset, *trdataset; + isc_buffer_t *dbuf; + isc_buffer_t b; + dns_dbversion_t *version; + isc_boolean_t added_something, need_addname; + dns_zone_t *zone; + dns_rdatatype_t type; + + REQUIRE(NS_CLIENT_VALID(client)); + REQUIRE(qtype != dns_rdatatype_any); + + if (!WANTDNSSEC(client) && dns_rdatatype_isdnssec(qtype)) + return (ISC_R_SUCCESS); + + CTRACE("query_addadditional"); + + /* + * Initialization. + */ + eresult = ISC_R_SUCCESS; + fname = NULL; + rdataset = NULL; + sigrdataset = NULL; + trdataset = NULL; + db = NULL; + version = NULL; + node = NULL; + added_something = ISC_FALSE; + need_addname = ISC_FALSE; + zone = NULL; + + /* + * We treat type A additional section processing as if it + * were "any address type" additional section processing. + * To avoid multiple lookups, we do an 'any' database + * lookup and iterate over the node. + */ + if (qtype == dns_rdatatype_a) + type = dns_rdatatype_any; + else + type = qtype; + + /* + * Get some resources. + */ + dbuf = query_getnamebuf(client); + if (dbuf == NULL) + goto cleanup; + fname = query_newname(client, dbuf, &b); + rdataset = query_newrdataset(client); + if (fname == NULL || rdataset == NULL) + goto cleanup; + if (WANTDNSSEC(client)) { + sigrdataset = query_newrdataset(client); + if (sigrdataset == NULL) + goto cleanup; + } + + /* + * Look for a zone database that might contain authoritative + * additional data. + */ + result = query_getzonedb(client, name, qtype, DNS_GETDB_NOLOG, + &zone, &db, &version); + if (result != ISC_R_SUCCESS) + goto try_cache; + + CTRACE("query_addadditional: db_find"); + + /* + * Since we are looking for authoritative data, we do not set + * the GLUEOK flag. Glue will be looked for later, but not + * necessarily in the same database. + */ + node = NULL; + result = dns_db_find(db, name, version, type, client->query.dboptions, + client->now, &node, fname, rdataset, + sigrdataset); + if (result == ISC_R_SUCCESS) + goto found; + + if (dns_rdataset_isassociated(rdataset)) + dns_rdataset_disassociate(rdataset); + if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) + dns_rdataset_disassociate(sigrdataset); + if (node != NULL) + dns_db_detachnode(db, &node); + version = NULL; + dns_db_detach(&db); + + /* + * No authoritative data was found. The cache is our next best bet. + */ + + try_cache: + result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG); + if (result != ISC_R_SUCCESS) + /* + * Most likely the client isn't allowed to query the cache. + */ + goto try_glue; + /* + * Attempt to validate glue. + */ + if (sigrdataset == NULL) { + sigrdataset = query_newrdataset(client); + if (sigrdataset == NULL) + goto cleanup; + } + result = dns_db_find(db, name, version, type, + client->query.dboptions | DNS_DBFIND_GLUEOK, + client->now, &node, fname, rdataset, + sigrdataset); + if (result == DNS_R_GLUE && + validate(client, db, fname, rdataset, sigrdataset)) + result = ISC_R_SUCCESS; + if (!WANTDNSSEC(client)) + query_putrdataset(client, &sigrdataset); + if (result == ISC_R_SUCCESS) + goto found; + + if (dns_rdataset_isassociated(rdataset)) + dns_rdataset_disassociate(rdataset); + if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) + dns_rdataset_disassociate(sigrdataset); + if (node != NULL) + dns_db_detachnode(db, &node); + dns_db_detach(&db); + + try_glue: + /* + * No cached data was found. Glue is our last chance. + * RFC1035 sayeth: + * + * NS records cause both the usual additional section + * processing to locate a type A record, and, when used + * in a referral, a special search of the zone in which + * they reside for glue information. + * + * This is the "special search". Note that we must search + * the zone where the NS record resides, not the zone it + * points to, and that we only do the search in the delegation + * case (identified by client->query.gluedb being set). + */ + + if (client->query.gluedb == NULL) + goto cleanup; + + /* + * Don't poision caches using the bailiwick protection model. + */ + if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb))) + goto cleanup; + + dns_db_attach(client->query.gluedb, &db); + result = dns_db_find(db, name, version, type, + client->query.dboptions | DNS_DBFIND_GLUEOK, + client->now, &node, fname, rdataset, + sigrdataset); + if (!(result == ISC_R_SUCCESS || + result == DNS_R_ZONECUT || + result == DNS_R_GLUE)) + goto cleanup; + + found: + /* + * We have found a potential additional data rdataset, or + * at least a node to iterate over. + */ + query_keepname(client, fname, dbuf); + + /* + * If we have an rdataset, add it to the additional data + * section. + */ + mname = NULL; + if (dns_rdataset_isassociated(rdataset) && + !query_isduplicate(client, fname, type, &mname)) { + if (mname != NULL) { + query_releasename(client, &fname); + fname = mname; + } else + need_addname = ISC_TRUE; + ISC_LIST_APPEND(fname->list, rdataset, link); + trdataset = rdataset; + rdataset = NULL; + added_something = ISC_TRUE; + /* + * Note: we only add SIGs if we've added the type they cover, + * so we do not need to check if the SIG rdataset is already + * in the response. + */ + if (sigrdataset != NULL && + dns_rdataset_isassociated(sigrdataset)) + { + ISC_LIST_APPEND(fname->list, sigrdataset, link); + sigrdataset = NULL; + } + } + + if (qtype == dns_rdatatype_a) { + /* + * We now go looking for A and AAAA records, along with + * their signatures. + * + * XXXRTH This code could be more efficient. + */ + if (rdataset != NULL) { + if (dns_rdataset_isassociated(rdataset)) + dns_rdataset_disassociate(rdataset); + } else { + rdataset = query_newrdataset(client); + if (rdataset == NULL) + goto addname; + } + if (sigrdataset != NULL) { + if (dns_rdataset_isassociated(sigrdataset)) + dns_rdataset_disassociate(sigrdataset); + } else if (WANTDNSSEC(client)) { + sigrdataset = query_newrdataset(client); + if (sigrdataset == NULL) + goto addname; + } + result = dns_db_findrdataset(db, node, version, + dns_rdatatype_a, 0, + client->now, rdataset, + sigrdataset); + if (result == DNS_R_NCACHENXDOMAIN) + goto addname; + if (result == DNS_R_NCACHENXRRSET) { + dns_rdataset_disassociate(rdataset); + /* + * Negative cache entries don't have sigrdatasets. + */ + INSIST(sigrdataset == NULL || + ! dns_rdataset_isassociated(sigrdataset)); + } + if (result == ISC_R_SUCCESS) { + mname = NULL; + if (!query_isduplicate(client, fname, + dns_rdatatype_a, &mname)) { + if (mname != NULL) { + query_releasename(client, &fname); + fname = mname; + } else + need_addname = ISC_TRUE; + ISC_LIST_APPEND(fname->list, rdataset, link); + added_something = ISC_TRUE; + if (sigrdataset != NULL && + dns_rdataset_isassociated(sigrdataset)) + { + ISC_LIST_APPEND(fname->list, + sigrdataset, link); + sigrdataset = + query_newrdataset(client); + } + rdataset = query_newrdataset(client); + if (rdataset == NULL) + goto addname; + if (WANTDNSSEC(client) && sigrdataset == NULL) + goto addname; + } else { + dns_rdataset_disassociate(rdataset); + if (sigrdataset != NULL && + dns_rdataset_isassociated(sigrdataset)) + dns_rdataset_disassociate(sigrdataset); + } + } + result = dns_db_findrdataset(db, node, version, + dns_rdatatype_aaaa, 0, + client->now, rdataset, + sigrdataset); + if (result == DNS_R_NCACHENXDOMAIN) + goto addname; + if (result == DNS_R_NCACHENXRRSET) { + dns_rdataset_disassociate(rdataset); + INSIST(sigrdataset == NULL || + ! dns_rdataset_isassociated(sigrdataset)); + } + if (result == ISC_R_SUCCESS) { + mname = NULL; + if (!query_isduplicate(client, fname, + dns_rdatatype_aaaa, &mname)) { + if (mname != NULL) { + query_releasename(client, &fname); + fname = mname; + } else + need_addname = ISC_TRUE; + ISC_LIST_APPEND(fname->list, rdataset, link); + added_something = ISC_TRUE; + if (sigrdataset != NULL && + dns_rdataset_isassociated(sigrdataset)) + { + ISC_LIST_APPEND(fname->list, + sigrdataset, link); + sigrdataset = NULL; + } + rdataset = NULL; + } + } + } + + addname: + CTRACE("query_addadditional: addname"); + /* + * If we haven't added anything, then we're done. + */ + if (!added_something) + goto cleanup; + + /* + * We may have added our rdatasets to an existing name, if so, then + * need_addname will be ISC_FALSE. Whether we used an existing name + * or a new one, we must set fname to NULL to prevent cleanup. + */ + if (need_addname) + dns_message_addname(client->message, fname, + DNS_SECTION_ADDITIONAL); + fname = NULL; + + /* + * In a few cases, we want to add additional data for additional + * data. It's simpler to just deal with special cases here than + * to try to create a general purpose mechanism and allow the + * rdata implementations to do it themselves. + * + * This involves recursion, but the depth is limited. The + * most complex case is adding a SRV rdataset, which involves + * recursing to add address records, which in turn can cause + * recursion to add KEYs. + */ + if (type == dns_rdatatype_srv && trdataset != NULL) { + /* + * If we're adding SRV records to the additional data + * section, it's helpful if we add the SRV additional data + * as well. + */ + eresult = dns_rdataset_additionaldata(trdataset, + query_addadditional, + client); + } + + cleanup: + CTRACE("query_addadditional: cleanup"); + query_putrdataset(client, &rdataset); + if (sigrdataset != NULL) + query_putrdataset(client, &sigrdataset); + if (fname != NULL) + query_releasename(client, &fname); + if (node != NULL) + dns_db_detachnode(db, &node); + if (db != NULL) + dns_db_detach(&db); + if (zone != NULL) + dns_zone_detach(&zone); + + CTRACE("query_addadditional: done"); + return (eresult); +} + +static inline void +query_discardcache(ns_client_t *client, dns_rdataset_t *rdataset_base, + dns_rdatasetadditional_t additionaltype, + dns_rdatatype_t type, dns_zone_t **zonep, dns_db_t **dbp, + dns_dbversion_t **versionp, dns_dbnode_t **nodep, + dns_name_t *fname) +{ + dns_rdataset_t *rdataset; + + while ((rdataset = ISC_LIST_HEAD(fname->list)) != NULL) { + ISC_LIST_UNLINK(fname->list, rdataset, link); + query_putrdataset(client, &rdataset); + } + if (*versionp != NULL) + dns_db_closeversion(*dbp, versionp, ISC_FALSE); + if (*nodep != NULL) + dns_db_detachnode(*dbp, nodep); + if (*dbp != NULL) + dns_db_detach(dbp); + if (*zonep != NULL) + dns_zone_detach(zonep); + (void)dns_rdataset_putadditional(client->view->acache, rdataset_base, + additionaltype, type); +} + +static inline isc_result_t +query_iscachevalid(dns_zone_t *zone, dns_db_t *db, dns_db_t *db0, + dns_dbversion_t *version) +{ + isc_result_t result = ISC_R_SUCCESS; + dns_dbversion_t *version_current = NULL; + dns_db_t *db_current = db0; + + if (db_current == NULL) { + result = dns_zone_getdb(zone, &db_current); + if (result != ISC_R_SUCCESS) + return (result); + } + dns_db_currentversion(db_current, &version_current); + if (db_current != db || version_current != version) { + result = ISC_R_FAILURE; + goto cleanup; + } + + cleanup: + dns_db_closeversion(db_current, &version_current, ISC_FALSE); + if (db0 == NULL && db_current != NULL) + dns_db_detach(&db_current); + + return (result); +} + +static isc_result_t +query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { + client_additionalctx_t *additionalctx = arg; + dns_rdataset_t *rdataset_base; + ns_client_t *client; + isc_result_t result, eresult; + dns_dbnode_t *node, *cnode; + dns_db_t *db, *cdb; + dns_name_t *fname, *mname0, cfname; + dns_rdataset_t *rdataset, *sigrdataset; + dns_rdataset_t *crdataset, *crdataset_next; + isc_buffer_t *dbuf; + isc_buffer_t b; + dns_dbversion_t *version, *cversion; + isc_boolean_t added_something, need_addname, needadditionalcache; + isc_boolean_t need_sigrrset; + dns_zone_t *zone; + dns_rdatatype_t type; + dns_rdatasetadditional_t additionaltype; + + if (qtype != dns_rdatatype_a) { + /* + * This function is optimized for "address" types. For other + * types, use a generic routine. + * XXX: ideally, this function should be generic enough. + */ + return (query_addadditional(additionalctx->client, + name, qtype)); + } + + /* + * Initialization. + */ + rdataset_base = additionalctx->rdataset; + client = additionalctx->client; + REQUIRE(NS_CLIENT_VALID(client)); + eresult = ISC_R_SUCCESS; + fname = NULL; + rdataset = NULL; + sigrdataset = NULL; + db = NULL; + cdb = NULL; + version = NULL; + cversion = NULL; + node = NULL; + cnode = NULL; + added_something = ISC_FALSE; + need_addname = ISC_FALSE; + zone = NULL; + needadditionalcache = ISC_FALSE; + additionaltype = dns_rdatasetadditional_fromauth; + dns_name_init(&cfname, NULL); + + CTRACE("query_addadditional2"); + + /* + * We treat type A additional section processing as if it + * were "any address type" additional section processing. + * To avoid multiple lookups, we do an 'any' database + * lookup and iterate over the node. + * XXXJT: this approach can cause a suboptimal result when the cache + * DB only has partial address types and the glue DB has remaining + * ones. + */ + type = dns_rdatatype_any; + + /* + * Get some resources. + */ + dbuf = query_getnamebuf(client); + if (dbuf == NULL) + goto cleanup; + fname = query_newname(client, dbuf, &b); + if (fname == NULL) + goto cleanup; + dns_name_setbuffer(&cfname, &b); /* share the buffer */ + + /* Check additional cache */ + result = dns_rdataset_getadditional(rdataset_base, additionaltype, + type, client->view->acache, &zone, + &cdb, &cversion, &cnode, &cfname, + client->message, client->now); + if (result != ISC_R_SUCCESS) + goto findauthdb; + if (zone == NULL) { + CTRACE("query_addadditional2: auth zone not found"); + goto try_cache; + } + + /* Is the cached DB up-to-date? */ + result = query_iscachevalid(zone, cdb, NULL, cversion); + if (result != ISC_R_SUCCESS) { + CTRACE("query_addadditional2: old auth additional cache"); + query_discardcache(client, rdataset_base, additionaltype, + type, &zone, &cdb, &cversion, &cnode, + &cfname); + goto findauthdb; + } + + if (cnode == NULL) { + /* + * We have a negative cache. We don't have to check the zone + * ACL, since the result (not using this zone) would be same + * regardless of the result. + */ + CTRACE("query_addadditional2: negative auth additional cache"); + dns_db_closeversion(cdb, &cversion, ISC_FALSE); + dns_db_detach(&cdb); + dns_zone_detach(&zone); + goto try_cache; + } + + result = query_validatezonedb(client, name, qtype, DNS_GETDB_NOLOG, + zone, cdb, NULL); + if (result != ISC_R_SUCCESS) { + query_discardcache(client, rdataset_base, additionaltype, + type, &zone, &cdb, &cversion, &cnode, + &cfname); + goto try_cache; + } + + /* We've got an active cache. */ + CTRACE("query_addadditional2: auth additional cache"); + dns_db_closeversion(cdb, &cversion, ISC_FALSE); + db = cdb; + node = cnode; + dns_name_clone(&cfname, fname); + query_keepname(client, fname, dbuf); + goto foundcache; + + /* + * Look for a zone database that might contain authoritative + * additional data. + */ + findauthdb: + result = query_getzonedb(client, name, qtype, DNS_GETDB_NOLOG, + &zone, &db, &version); + if (result != ISC_R_SUCCESS) { + /* Cache the negative result */ + (void)dns_rdataset_setadditional(rdataset_base, additionaltype, + type, client->view->acache, + NULL, NULL, NULL, NULL, + NULL); + goto try_cache; + } + + CTRACE("query_addadditional2: db_find"); + + /* + * Since we are looking for authoritative data, we do not set + * the GLUEOK flag. Glue will be looked for later, but not + * necessarily in the same database. + */ + node = NULL; + result = dns_db_find(db, name, version, type, client->query.dboptions, + client->now, &node, fname, NULL, NULL); + if (result == ISC_R_SUCCESS) + goto found; + + /* Cache the negative result */ + (void)dns_rdataset_setadditional(rdataset_base, additionaltype, + type, client->view->acache, zone, db, + version, NULL, fname); + + if (node != NULL) + dns_db_detachnode(db, &node); + version = NULL; + dns_db_detach(&db); + + /* + * No authoritative data was found. The cache is our next best bet. + */ + + try_cache: + additionaltype = dns_rdatasetadditional_fromcache; + result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG); + if (result != ISC_R_SUCCESS) + /* + * Most likely the client isn't allowed to query the cache. + */ + goto try_glue; + + result = dns_db_find(db, name, version, type, + client->query.dboptions | DNS_DBFIND_GLUEOK, + client->now, &node, fname, NULL, NULL); + if (result == ISC_R_SUCCESS) + goto found; + + if (node != NULL) + dns_db_detachnode(db, &node); + dns_db_detach(&db); + + try_glue: + /* + * No cached data was found. Glue is our last chance. + * RFC1035 sayeth: + * + * NS records cause both the usual additional section + * processing to locate a type A record, and, when used + * in a referral, a special search of the zone in which + * they reside for glue information. + * + * This is the "special search". Note that we must search + * the zone where the NS record resides, not the zone it + * points to, and that we only do the search in the delegation + * case (identified by client->query.gluedb being set). + */ + if (client->query.gluedb == NULL) + goto cleanup; + + /* + * Don't poision caches using the bailiwick protection model. + */ + if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb))) + goto cleanup; + + /* Check additional cache */ + additionaltype = dns_rdatasetadditional_fromglue; + result = dns_rdataset_getadditional(rdataset_base, additionaltype, + type, client->view->acache, NULL, + &cdb, &cversion, &cnode, &cfname, + client->message, client->now); + if (result != ISC_R_SUCCESS) + goto findglue; + + result = query_iscachevalid(zone, cdb, client->query.gluedb, cversion); + if (result != ISC_R_SUCCESS) { + CTRACE("query_addadditional2: old glue additional cache"); + query_discardcache(client, rdataset_base, additionaltype, + type, &zone, &cdb, &cversion, &cnode, + &cfname); + goto findglue; + } + + if (cnode == NULL) { + /* We have a negative cache. */ + CTRACE("query_addadditional2: negative glue additional cache"); + dns_db_closeversion(cdb, &cversion, ISC_FALSE); + dns_db_detach(&cdb); + goto cleanup; + } + + /* Cache hit. */ + CTRACE("query_addadditional2: glue additional cache"); + dns_db_closeversion(cdb, &cversion, ISC_FALSE); + db = cdb; + node = cnode; + dns_name_clone(&cfname, fname); + query_keepname(client, fname, dbuf); + goto foundcache; + + findglue: + dns_db_attach(client->query.gluedb, &db); + result = dns_db_find(db, name, version, type, + client->query.dboptions | DNS_DBFIND_GLUEOK, + client->now, &node, fname, NULL, NULL); + if (!(result == ISC_R_SUCCESS || + result == DNS_R_ZONECUT || + result == DNS_R_GLUE)) { + /* cache the negative result */ + (void)dns_rdataset_setadditional(rdataset_base, additionaltype, + type, client->view->acache, + NULL, db, version, NULL, + fname); + goto cleanup; + } + + found: + /* + * We have found a DB node to iterate over from a DB. + * We are going to look for address RRsets (i.e., A and AAAA) in the DB + * node we've just found. We'll then store the complete information + * in the additional data cache. + */ + dns_name_clone(fname, &cfname); + query_keepname(client, fname, dbuf); + needadditionalcache = ISC_TRUE; + + rdataset = query_newrdataset(client); + if (rdataset == NULL) + goto cleanup; + + sigrdataset = query_newrdataset(client); + if (sigrdataset == NULL) + goto cleanup; + + /* + * Find A RRset with sig RRset. Even if we don't find a sig RRset + * for a client using DNSSEC, we'll continue the process to make a + * complete list to be cached. However, we need to cancel the + * caching when something unexpected happens, in order to avoid + * caching incomplete information. + */ + result = dns_db_findrdataset(db, node, version, dns_rdatatype_a, 0, + client->now, rdataset, sigrdataset); + /* + * If we can't promote glue/pending from the cache to secure + * then drop it. + */ + if (result == ISC_R_SUCCESS && + additionaltype == dns_rdatasetadditional_fromcache && + (rdataset->trust == dns_trust_pending || + rdataset->trust == dns_trust_glue) && + !validate(client, db, fname, rdataset, sigrdataset)) { + dns_rdataset_disassociate(rdataset); + if (dns_rdataset_isassociated(sigrdataset)) + dns_rdataset_disassociate(sigrdataset); + result = ISC_R_NOTFOUND; + } + if (result == DNS_R_NCACHENXDOMAIN) + goto setcache; + if (result == DNS_R_NCACHENXRRSET) { + dns_rdataset_disassociate(rdataset); + /* + * Negative cache entries don't have sigrdatasets. + */ + INSIST(! dns_rdataset_isassociated(sigrdataset)); + } + if (result == ISC_R_SUCCESS) { + /* Remember the result as a cache */ + ISC_LIST_APPEND(cfname.list, rdataset, link); + if (dns_rdataset_isassociated(sigrdataset)) { + ISC_LIST_APPEND(cfname.list, sigrdataset, link); + sigrdataset = query_newrdataset(client); + } + rdataset = query_newrdataset(client); + if (sigrdataset == NULL || rdataset == NULL) { + /* do not cache incomplete information */ + goto foundcache; + } + } + + /* Find AAAA RRset with sig RRset */ + result = dns_db_findrdataset(db, node, version, dns_rdatatype_aaaa, + 0, client->now, rdataset, sigrdataset); + /* + * If we can't promote glue/pending from the cache to secure + * then drop it. + */ + if (result == ISC_R_SUCCESS && + additionaltype == dns_rdatasetadditional_fromcache && + (rdataset->trust == dns_trust_pending || + rdataset->trust == dns_trust_glue) && + !validate(client, db, fname, rdataset, sigrdataset)) { + dns_rdataset_disassociate(rdataset); + if (dns_rdataset_isassociated(sigrdataset)) + dns_rdataset_disassociate(sigrdataset); + result = ISC_R_NOTFOUND; + } + if (result == ISC_R_SUCCESS) { + ISC_LIST_APPEND(cfname.list, rdataset, link); + rdataset = NULL; + if (dns_rdataset_isassociated(sigrdataset)) { + ISC_LIST_APPEND(cfname.list, sigrdataset, link); + sigrdataset = NULL; + } + } + + setcache: + /* + * Set the new result in the cache if required. We do not support + * caching additional data from a cache DB. + */ + if (needadditionalcache == ISC_TRUE && + (additionaltype == dns_rdatasetadditional_fromauth || + additionaltype == dns_rdatasetadditional_fromglue)) { + (void)dns_rdataset_setadditional(rdataset_base, additionaltype, + type, client->view->acache, + zone, db, version, node, + &cfname); + } + + foundcache: + need_sigrrset = ISC_FALSE; + mname0 = NULL; + for (crdataset = ISC_LIST_HEAD(cfname.list); + crdataset != NULL; + crdataset = crdataset_next) { + dns_name_t *mname; + + crdataset_next = ISC_LIST_NEXT(crdataset, link); + + mname = NULL; + if (crdataset->type == dns_rdatatype_a || + crdataset->type == dns_rdatatype_aaaa) { + if (!query_isduplicate(client, fname, crdataset->type, + &mname)) { + if (mname != NULL) { + /* + * A different type of this name is + * already stored in the additional + * section. We'll reuse the name. + * Note that this should happen at most + * once. Otherwise, fname->link could + * leak below. + */ + INSIST(mname0 == NULL); + + query_releasename(client, &fname); + fname = mname; + mname0 = mname; + } else + need_addname = ISC_TRUE; + ISC_LIST_UNLINK(cfname.list, crdataset, link); + ISC_LIST_APPEND(fname->list, crdataset, link); + added_something = ISC_TRUE; + need_sigrrset = ISC_TRUE; + } else + need_sigrrset = ISC_FALSE; + } else if (crdataset->type == dns_rdatatype_rrsig && + need_sigrrset && WANTDNSSEC(client)) { + ISC_LIST_UNLINK(cfname.list, crdataset, link); + ISC_LIST_APPEND(fname->list, crdataset, link); + added_something = ISC_TRUE; /* just in case */ + need_sigrrset = ISC_FALSE; + } + } + + CTRACE("query_addadditional2: addname"); + + /* + * If we haven't added anything, then we're done. + */ + if (!added_something) + goto cleanup; + + /* + * We may have added our rdatasets to an existing name, if so, then + * need_addname will be ISC_FALSE. Whether we used an existing name + * or a new one, we must set fname to NULL to prevent cleanup. + */ + if (need_addname) + dns_message_addname(client->message, fname, + DNS_SECTION_ADDITIONAL); + fname = NULL; + + cleanup: + CTRACE("query_addadditional2: cleanup"); + + if (rdataset != NULL) + query_putrdataset(client, &rdataset); + if (sigrdataset != NULL) + query_putrdataset(client, &sigrdataset); + while ((crdataset = ISC_LIST_HEAD(cfname.list)) != NULL) { + ISC_LIST_UNLINK(cfname.list, crdataset, link); + query_putrdataset(client, &crdataset); + } + if (fname != NULL) + query_releasename(client, &fname); + if (node != NULL) + dns_db_detachnode(db, &node); + if (db != NULL) + dns_db_detach(&db); + if (zone != NULL) + dns_zone_detach(&zone); + + CTRACE("query_addadditional2: done"); + return (eresult); +} + +static inline void +query_addrdataset(ns_client_t *client, dns_name_t *fname, + dns_rdataset_t *rdataset) +{ + client_additionalctx_t additionalctx; + + /* + * Add 'rdataset' and any pertinent additional data to + * 'fname', a name in the response message for 'client'. + */ + + CTRACE("query_addrdataset"); + + ISC_LIST_APPEND(fname->list, rdataset, link); + + if (client->view->order != NULL) + rdataset->attributes |= dns_order_find(client->view->order, + fname, rdataset->type, + rdataset->rdclass); + rdataset->attributes |= DNS_RDATASETATTR_LOADORDER; + + if (NOADDITIONAL(client)) + return; + + /* + * Add additional data. + * + * We don't care if dns_rdataset_additionaldata() fails. + */ + additionalctx.client = client; + additionalctx.rdataset = rdataset; + (void)dns_rdataset_additionaldata(rdataset, query_addadditional2, + &additionalctx); + CTRACE("query_addrdataset: done"); +} + +static void +query_addrrset(ns_client_t *client, dns_name_t **namep, + dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp, + isc_buffer_t *dbuf, dns_section_t section) +{ + dns_name_t *name, *mname; + dns_rdataset_t *rdataset, *mrdataset, *sigrdataset; + isc_result_t result; + + /*% + * To the current response for 'client', add the answer RRset + * '*rdatasetp' and an optional signature set '*sigrdatasetp', with + * owner name '*namep', to section 'section', unless they are + * already there. Also add any pertinent additional data. + * + * If 'dbuf' is not NULL, then '*namep' is the name whose data is + * stored in 'dbuf'. In this case, query_addrrset() guarantees that + * when it returns the name will either have been kept or released. + */ + CTRACE("query_addrrset"); + name = *namep; + rdataset = *rdatasetp; + if (sigrdatasetp != NULL) + sigrdataset = *sigrdatasetp; + else + sigrdataset = NULL; + mname = NULL; + mrdataset = NULL; + result = dns_message_findname(client->message, section, + name, rdataset->type, rdataset->covers, + &mname, &mrdataset); + if (result == ISC_R_SUCCESS) { + /* + * We've already got an RRset of the given name and type. + * There's nothing else to do; + */ + CTRACE("query_addrrset: dns_message_findname succeeded: done"); + if (dbuf != NULL) + query_releasename(client, namep); + return; + } else if (result == DNS_R_NXDOMAIN) { + /* + * The name doesn't exist. + */ + if (dbuf != NULL) + query_keepname(client, name, dbuf); + dns_message_addname(client->message, name, section); + *namep = NULL; + mname = name; + } else { + RUNTIME_CHECK(result == DNS_R_NXRRSET); + if (dbuf != NULL) + query_releasename(client, namep); + } + + if (rdataset->trust != dns_trust_secure && + (section == DNS_SECTION_ANSWER || + section == DNS_SECTION_AUTHORITY)) + client->query.attributes &= ~NS_QUERYATTR_SECURE; + /* + * Note: we only add SIGs if we've added the type they cover, so + * we do not need to check if the SIG rdataset is already in the + * response. + */ + query_addrdataset(client, mname, rdataset); + *rdatasetp = NULL; + if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) { + /* + * We have a signature. Add it to the response. + */ + ISC_LIST_APPEND(mname->list, sigrdataset, link); + *sigrdatasetp = NULL; + } + CTRACE("query_addrrset: done"); +} + +static inline isc_result_t +query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version, + isc_boolean_t zero_ttl) +{ + dns_name_t *name; + dns_dbnode_t *node; + isc_result_t result, eresult; + dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; + dns_rdataset_t **sigrdatasetp = NULL; + + CTRACE("query_addsoa"); + /* + * Initialization. + */ + eresult = ISC_R_SUCCESS; + name = NULL; + rdataset = NULL; + node = NULL; + + /* + * Get resources and make 'name' be the database origin. + */ + result = dns_message_gettempname(client->message, &name); + if (result != ISC_R_SUCCESS) + return (result); + dns_name_init(name, NULL); + dns_name_clone(dns_db_origin(db), name); + rdataset = query_newrdataset(client); + if (rdataset == NULL) { + eresult = DNS_R_SERVFAIL; + goto cleanup; + } + if (WANTDNSSEC(client)) { + sigrdataset = query_newrdataset(client); + if (sigrdataset == NULL) { + eresult = DNS_R_SERVFAIL; + goto cleanup; + } + } + + /* + * Find the SOA. + */ + result = dns_db_getoriginnode(db, &node); + if (result == ISC_R_SUCCESS) { + result = dns_db_findrdataset(db, node, version, + dns_rdatatype_soa, + 0, client->now, rdataset, + sigrdataset); + } else { + dns_fixedname_t foundname; + dns_name_t *fname; + + dns_fixedname_init(&foundname); + fname = dns_fixedname_name(&foundname); + + result = dns_db_find(db, name, version, dns_rdatatype_soa, + client->query.dboptions, 0, &node, + fname, rdataset, sigrdataset); + } + if (result != ISC_R_SUCCESS) { + /* + * This is bad. We tried to get the SOA RR at the zone top + * and it didn't work! + */ + eresult = DNS_R_SERVFAIL; + } else { + /* + * Extract the SOA MINIMUM. + */ + dns_rdata_soa_t soa; + dns_rdata_t rdata = DNS_RDATA_INIT; + result = dns_rdataset_first(rdataset); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + dns_rdataset_current(rdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &soa, NULL); + if (result != ISC_R_SUCCESS) + goto cleanup; + + if (zero_ttl) { + rdataset->ttl = 0; + if (sigrdataset != NULL) + sigrdataset->ttl = 0; + } + + /* + * Add the SOA and its SIG to the response, with the + * TTLs adjusted per RFC2308 section 3. + */ + if (rdataset->ttl > soa.minimum) + rdataset->ttl = soa.minimum; + if (sigrdataset != NULL && sigrdataset->ttl > soa.minimum) + sigrdataset->ttl = soa.minimum; + + if (sigrdataset != NULL) + sigrdatasetp = &sigrdataset; + else + sigrdatasetp = NULL; + query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL, + DNS_SECTION_AUTHORITY); + } + + cleanup: + query_putrdataset(client, &rdataset); + if (sigrdataset != NULL) + query_putrdataset(client, &sigrdataset); + if (name != NULL) + query_releasename(client, &name); + if (node != NULL) + dns_db_detachnode(db, &node); + + return (eresult); +} + +static inline isc_result_t +query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) { + dns_name_t *name, *fname; + dns_dbnode_t *node; + isc_result_t result, eresult; + dns_fixedname_t foundname; + dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; + dns_rdataset_t **sigrdatasetp = NULL; + + CTRACE("query_addns"); + /* + * Initialization. + */ + eresult = ISC_R_SUCCESS; + name = NULL; + rdataset = NULL; + node = NULL; + dns_fixedname_init(&foundname); + fname = dns_fixedname_name(&foundname); + + /* + * Get resources and make 'name' be the database origin. + */ + result = dns_message_gettempname(client->message, &name); + if (result != ISC_R_SUCCESS) { + CTRACE("query_addns: dns_message_gettempname failed: done"); + return (result); + } + dns_name_init(name, NULL); + dns_name_clone(dns_db_origin(db), name); + rdataset = query_newrdataset(client); + if (rdataset == NULL) { + CTRACE("query_addns: query_newrdataset failed"); + eresult = DNS_R_SERVFAIL; + goto cleanup; + } + if (WANTDNSSEC(client)) { + sigrdataset = query_newrdataset(client); + if (sigrdataset == NULL) { + CTRACE("query_addns: query_newrdataset failed"); + eresult = DNS_R_SERVFAIL; + goto cleanup; + } + } + + /* + * Find the NS rdataset. + */ + result = dns_db_getoriginnode(db, &node); + if (result == ISC_R_SUCCESS) { + result = dns_db_findrdataset(db, node, version, + dns_rdatatype_ns, + 0, client->now, rdataset, + sigrdataset); + } else { + CTRACE("query_addns: calling dns_db_find"); + result = dns_db_find(db, name, NULL, dns_rdatatype_ns, + client->query.dboptions, 0, &node, + fname, rdataset, sigrdataset); + CTRACE("query_addns: dns_db_find complete"); + } + if (result != ISC_R_SUCCESS) { + CTRACE("query_addns: " + "dns_db_findrdataset or dns_db_find failed"); + /* + * This is bad. We tried to get the NS rdataset at the zone + * top and it didn't work! + */ + eresult = DNS_R_SERVFAIL; + } else { + if (sigrdataset != NULL) + sigrdatasetp = &sigrdataset; + else + sigrdatasetp = NULL; + query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL, + DNS_SECTION_AUTHORITY); + } + + cleanup: + CTRACE("query_addns: cleanup"); + query_putrdataset(client, &rdataset); + if (sigrdataset != NULL) + query_putrdataset(client, &sigrdataset); + if (name != NULL) + query_releasename(client, &name); + if (node != NULL) + dns_db_detachnode(db, &node); + + CTRACE("query_addns: done"); + return (eresult); +} + +static inline isc_result_t +query_addcnamelike(ns_client_t *client, dns_name_t *qname, dns_name_t *tname, + dns_trust_t trust, dns_name_t **anamep, dns_rdatatype_t type) +{ + dns_rdataset_t *rdataset; + dns_rdatalist_t *rdatalist; + dns_rdata_t *rdata; + isc_result_t result; + isc_region_t r; + + /* + * We assume the name data referred to by tname won't go away. + */ + + REQUIRE(anamep != NULL); + + rdatalist = NULL; + result = dns_message_gettemprdatalist(client->message, &rdatalist); + if (result != ISC_R_SUCCESS) + return (result); + rdata = NULL; + result = dns_message_gettemprdata(client->message, &rdata); + if (result != ISC_R_SUCCESS) + return (result); + rdataset = NULL; + result = dns_message_gettemprdataset(client->message, &rdataset); + if (result != ISC_R_SUCCESS) + return (result); + dns_rdataset_init(rdataset); + result = dns_name_dup(qname, client->mctx, *anamep); + if (result != ISC_R_SUCCESS) { + dns_message_puttemprdataset(client->message, &rdataset); + return (result); + } + + rdatalist->type = type; + rdatalist->covers = 0; + rdatalist->rdclass = client->message->rdclass; + rdatalist->ttl = 0; + + dns_name_toregion(tname, &r); + rdata->data = r.base; + rdata->length = r.length; + rdata->rdclass = client->message->rdclass; + rdata->type = type; + + ISC_LIST_INIT(rdatalist->rdata); + ISC_LIST_APPEND(rdatalist->rdata, rdata, link); + RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) + == ISC_R_SUCCESS); + rdataset->trust = trust; + + query_addrrset(client, anamep, &rdataset, NULL, NULL, + DNS_SECTION_ANSWER); + + if (rdataset != NULL) { + if (dns_rdataset_isassociated(rdataset)) + dns_rdataset_disassociate(rdataset); + dns_message_puttemprdataset(client->message, &rdataset); + } + + return (ISC_R_SUCCESS); +} + +/* + * Mark the RRsets as secure. Update the cache (db) to reflect the + * change in trust level. + */ +static void +mark_secure(ns_client_t *client, dns_db_t *db, dns_name_t *name, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) +{ + isc_result_t result; + dns_dbnode_t *node = NULL; + + rdataset->trust = dns_trust_secure; + sigrdataset->trust = dns_trust_secure; + + /* + * Save the updated secure state. Ignore failures. + */ + result = dns_db_findnode(db, name, ISC_TRUE, &node); + if (result != ISC_R_SUCCESS) + return; + (void)dns_db_addrdataset(db, node, NULL, client->now, rdataset, + 0, NULL); + (void)dns_db_addrdataset(db, node, NULL, client->now, sigrdataset, + 0, NULL); + dns_db_detachnode(db, &node); +} + +/* + * Find the secure key that corresponds to rrsig. + * Note: 'keyrdataset' maintains state between sucessive calls, + * there may be multiple keys with the same keyid. + * Return ISC_FALSE if we have exhausted all the possible keys. + */ +static isc_boolean_t +get_key(ns_client_t *client, dns_db_t *db, dns_rdata_rrsig_t *rrsig, + dns_rdataset_t *keyrdataset, dst_key_t **keyp) +{ + isc_result_t result; + dns_dbnode_t *node = NULL; + isc_boolean_t secure = ISC_FALSE; + + if (!dns_rdataset_isassociated(keyrdataset)) { + result = dns_db_findnode(db, &rrsig->signer, ISC_FALSE, &node); + if (result != ISC_R_SUCCESS) + return (ISC_FALSE); + + result = dns_db_findrdataset(db, node, NULL, + dns_rdatatype_dnskey, 0, + client->now, keyrdataset, NULL); + dns_db_detachnode(db, &node); + if (result != ISC_R_SUCCESS) + return (ISC_FALSE); + + if (keyrdataset->trust != dns_trust_secure) + return (ISC_FALSE); + + result = dns_rdataset_first(keyrdataset); + } else + result = dns_rdataset_next(keyrdataset); + + for ( ; result == ISC_R_SUCCESS; + result = dns_rdataset_next(keyrdataset)) { + dns_rdata_t rdata = DNS_RDATA_INIT; + isc_buffer_t b; + + dns_rdataset_current(keyrdataset, &rdata); + isc_buffer_init(&b, rdata.data, rdata.length); + isc_buffer_add(&b, rdata.length); + result = dst_key_fromdns(&rrsig->signer, rdata.rdclass, &b, + client->mctx, keyp); + if (result != ISC_R_SUCCESS) + continue; + if (rrsig->algorithm == (dns_secalg_t)dst_key_alg(*keyp) && + rrsig->keyid == (dns_keytag_t)dst_key_id(*keyp) && + dst_key_iszonekey(*keyp)) { + secure = ISC_TRUE; + break; + } + dst_key_free(keyp); + } + return (secure); +} + +static isc_boolean_t +verify(dst_key_t *key, dns_name_t *name, dns_rdataset_t *rdataset, + dns_rdata_t *rdata, isc_mem_t *mctx, isc_boolean_t acceptexpired) +{ + isc_result_t result; + dns_fixedname_t fixed; + isc_boolean_t ignore = ISC_FALSE; + + dns_fixedname_init(&fixed); + +again: + result = dns_dnssec_verify2(name, rdataset, key, ignore, mctx, + rdata, NULL); + if (result == DNS_R_SIGEXPIRED && acceptexpired) { + ignore = ISC_TRUE; + goto again; + } + if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD) + return (ISC_TRUE); + return (ISC_FALSE); +} + +/* + * Validate the rdataset if possible with available records. + */ +static isc_boolean_t +validate(ns_client_t *client, dns_db_t *db, dns_name_t *name, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) +{ + isc_result_t result; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdata_rrsig_t rrsig; + dst_key_t *key = NULL; + dns_rdataset_t keyrdataset; + + if (sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset)) + return (ISC_FALSE); + + for (result = dns_rdataset_first(sigrdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(sigrdataset)) { + + dns_rdata_reset(&rdata); + dns_rdataset_current(sigrdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &rrsig, NULL); + if (result != ISC_R_SUCCESS) + return (ISC_FALSE); + if (!dns_resolver_algorithm_supported(client->view->resolver, + name, rrsig.algorithm)) + continue; + if (!dns_name_issubdomain(name, &rrsig.signer)) + continue; + dns_rdataset_init(&keyrdataset); + do { + if (!get_key(client, db, &rrsig, &keyrdataset, &key)) + break; + if (verify(key, name, rdataset, &rdata, client->mctx, + client->view->acceptexpired)) { + dst_key_free(&key); + dns_rdataset_disassociate(&keyrdataset); + mark_secure(client, db, name, rdataset, + sigrdataset); + return (ISC_TRUE); + } + dst_key_free(&key); + } while (1); + if (dns_rdataset_isassociated(&keyrdataset)) + dns_rdataset_disassociate(&keyrdataset); + } + return (ISC_FALSE); +} + +static void +query_addbestns(ns_client_t *client) { + dns_db_t *db, *zdb; + dns_dbnode_t *node; + dns_name_t *fname, *zfname; + dns_rdataset_t *rdataset, *sigrdataset, *zrdataset, *zsigrdataset; + isc_boolean_t is_zone, use_zone; + isc_buffer_t *dbuf; + isc_result_t result; + dns_dbversion_t *version; + dns_zone_t *zone; + isc_buffer_t b; + + CTRACE("query_addbestns"); + fname = NULL; + zfname = NULL; + rdataset = NULL; + zrdataset = NULL; + sigrdataset = NULL; + zsigrdataset = NULL; + node = NULL; + db = NULL; + zdb = NULL; + version = NULL; + zone = NULL; + is_zone = ISC_FALSE; + use_zone = ISC_FALSE; + + /* + * Find the right database. + */ + result = query_getdb(client, client->query.qname, dns_rdatatype_ns, 0, + &zone, &db, &version, &is_zone); + if (result != ISC_R_SUCCESS) + goto cleanup; + + db_find: + /* + * We'll need some resources... + */ + dbuf = query_getnamebuf(client); + if (dbuf == NULL) + goto cleanup; + fname = query_newname(client, dbuf, &b); + rdataset = query_newrdataset(client); + if (fname == NULL || rdataset == NULL) + goto cleanup; + /* + * Get the RRSIGs if the client requested them or if we may + * need to validate answers from the cache. + */ + if (WANTDNSSEC(client) || !is_zone) { + sigrdataset = query_newrdataset(client); + if (sigrdataset == NULL) + goto cleanup; + } + + /* + * Now look for the zonecut. + */ + if (is_zone) { + result = dns_db_find(db, client->query.qname, version, + dns_rdatatype_ns, client->query.dboptions, + client->now, &node, fname, + rdataset, sigrdataset); + if (result != DNS_R_DELEGATION) + goto cleanup; + if (USECACHE(client)) { + query_keepname(client, fname, dbuf); + zdb = db; + zfname = fname; + fname = NULL; + zrdataset = rdataset; + rdataset = NULL; + zsigrdataset = sigrdataset; + sigrdataset = NULL; + dns_db_detachnode(db, &node); + version = NULL; + db = NULL; + dns_db_attach(client->view->cachedb, &db); + is_zone = ISC_FALSE; + goto db_find; + } + } else { + result = dns_db_findzonecut(db, client->query.qname, + client->query.dboptions, + client->now, &node, fname, + rdataset, sigrdataset); + if (result == ISC_R_SUCCESS) { + if (zfname != NULL && + !dns_name_issubdomain(fname, zfname)) { + /* + * We found a zonecut in the cache, but our + * zone delegation is better. + */ + use_zone = ISC_TRUE; + } + } else if (result == ISC_R_NOTFOUND && zfname != NULL) { + /* + * We didn't find anything in the cache, but we + * have a zone delegation, so use it. + */ + use_zone = ISC_TRUE; + } else + goto cleanup; + } + + if (use_zone) { + query_releasename(client, &fname); + fname = zfname; + zfname = NULL; + /* + * We've already done query_keepname() on + * zfname, so we must set dbuf to NULL to + * prevent query_addrrset() from trying to + * call query_keepname() again. + */ + dbuf = NULL; + query_putrdataset(client, &rdataset); + if (sigrdataset != NULL) + query_putrdataset(client, &sigrdataset); + rdataset = zrdataset; + zrdataset = NULL; + sigrdataset = zsigrdataset; + zsigrdataset = NULL; + } + + /* + * Attempt to validate RRsets that are pending or that are glue. + */ + if ((rdataset->trust == dns_trust_pending || + (sigrdataset != NULL && sigrdataset->trust == dns_trust_pending)) + && !validate(client, db, fname, rdataset, sigrdataset) && + (client->query.dboptions & DNS_DBFIND_PENDINGOK) == 0) + goto cleanup; + + if ((rdataset->trust == dns_trust_glue || + (sigrdataset != NULL && sigrdataset->trust == dns_trust_glue)) && + !validate(client, db, fname, rdataset, sigrdataset) && + SECURE(client) && WANTDNSSEC(client)) + goto cleanup; + + /* + * If the client doesn't want DNSSEC we can discard the sigrdataset + * now. + */ + if (!WANTDNSSEC(client)) + query_putrdataset(client, &sigrdataset); + query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf, + DNS_SECTION_AUTHORITY); + + cleanup: + if (rdataset != NULL) + query_putrdataset(client, &rdataset); + if (sigrdataset != NULL) + query_putrdataset(client, &sigrdataset); + if (fname != NULL) + query_releasename(client, &fname); + if (node != NULL) + dns_db_detachnode(db, &node); + if (db != NULL) + dns_db_detach(&db); + if (zone != NULL) + dns_zone_detach(&zone); + if (zdb != NULL) { + query_putrdataset(client, &zrdataset); + if (zsigrdataset != NULL) + query_putrdataset(client, &zsigrdataset); + if (zfname != NULL) + query_releasename(client, &zfname); + dns_db_detach(&zdb); + } +} + +static void +query_addds(ns_client_t *client, dns_db_t *db, dns_dbnode_t *node, + dns_dbversion_t *version) +{ + dns_name_t *rname; + dns_rdataset_t *rdataset, *sigrdataset; + isc_result_t result; + + CTRACE("query_addds"); + rname = NULL; + rdataset = NULL; + sigrdataset = NULL; + + /* + * We'll need some resources... + */ + rdataset = query_newrdataset(client); + sigrdataset = query_newrdataset(client); + if (rdataset == NULL || sigrdataset == NULL) + goto cleanup; + + /* + * Look for the DS record, which may or may not be present. + */ + result = dns_db_findrdataset(db, node, version, dns_rdatatype_ds, 0, + client->now, rdataset, sigrdataset); + /* + * If we didn't find it, look for an NSEC. */ + if (result == ISC_R_NOTFOUND) + result = dns_db_findrdataset(db, node, version, + dns_rdatatype_nsec, 0, client->now, + rdataset, sigrdataset); + if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) + goto cleanup; + if (!dns_rdataset_isassociated(rdataset) || + !dns_rdataset_isassociated(sigrdataset)) + goto cleanup; + + /* + * We've already added the NS record, so if the name's not there, + * we have other problems. Use this name rather than calling + * query_addrrset(). + */ + result = dns_message_firstname(client->message, DNS_SECTION_AUTHORITY); + if (result != ISC_R_SUCCESS) + goto cleanup; + + rname = NULL; + dns_message_currentname(client->message, DNS_SECTION_AUTHORITY, + &rname); + result = dns_message_findtype(rname, dns_rdatatype_ns, 0, NULL); + if (result != ISC_R_SUCCESS) + goto cleanup; + + ISC_LIST_APPEND(rname->list, rdataset, link); + ISC_LIST_APPEND(rname->list, sigrdataset, link); + rdataset = NULL; + sigrdataset = NULL; + + cleanup: + if (rdataset != NULL) + query_putrdataset(client, &rdataset); + if (sigrdataset != NULL) + query_putrdataset(client, &sigrdataset); +} + +static void +query_addwildcardproof(ns_client_t *client, dns_db_t *db, + dns_dbversion_t *version, dns_name_t *name, + isc_boolean_t ispositive) +{ + isc_buffer_t *dbuf, b; + dns_name_t *fname; + dns_rdataset_t *rdataset, *sigrdataset; + dns_fixedname_t wfixed; + dns_name_t *wname; + dns_dbnode_t *node; + unsigned int options; + unsigned int olabels, nlabels; + isc_result_t result; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdata_nsec_t nsec; + isc_boolean_t have_wname; + int order; + + CTRACE("query_addwildcardproof"); + fname = NULL; + rdataset = NULL; + sigrdataset = NULL; + node = NULL; + + /* + * Get the NOQNAME proof then if !ispositve + * get the NOWILDCARD proof. + * + * DNS_DBFIND_NOWILD finds the NSEC records that covers the + * name ignoring any wildcard. From the owner and next names + * of this record you can compute which wildcard (if it exists) + * will match by finding the longest common suffix of the + * owner name and next names with the qname and prefixing that + * with the wildcard label. + * + * e.g. + * Given: + * example SOA + * example NSEC b.example + * b.example A + * b.example NSEC a.d.example + * a.d.example A + * a.d.example NSEC g.f.example + * g.f.example A + * g.f.example NSEC z.i.example + * z.i.example A + * z.i.example NSEC example + * + * QNAME: + * a.example -> example NSEC b.example + * owner common example + * next common example + * wild *.example + * d.b.example -> b.example NSEC a.d.example + * owner common b.example + * next common example + * wild *.b.example + * a.f.example -> a.d.example NSEC g.f.example + * owner common example + * next common f.example + * wild *.f.example + * j.example -> z.i.example NSEC example + * owner common example + * next common example + * wild *.f.example + */ + options = client->query.dboptions | DNS_DBFIND_NOWILD; + dns_fixedname_init(&wfixed); + wname = dns_fixedname_name(&wfixed); + again: + have_wname = ISC_FALSE; + /* + * We'll need some resources... + */ + dbuf = query_getnamebuf(client); + if (dbuf == NULL) + goto cleanup; + fname = query_newname(client, dbuf, &b); + rdataset = query_newrdataset(client); + sigrdataset = query_newrdataset(client); + if (fname == NULL || rdataset == NULL || sigrdataset == NULL) + goto cleanup; + + result = dns_db_find(db, name, version, dns_rdatatype_nsec, options, + 0, &node, fname, rdataset, sigrdataset); + if (node != NULL) + dns_db_detachnode(db, &node); + if (result == DNS_R_NXDOMAIN) { + if (!ispositive) + result = dns_rdataset_first(rdataset); + if (result == ISC_R_SUCCESS) { + dns_rdataset_current(rdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &nsec, NULL); + } + if (result == ISC_R_SUCCESS) { + (void)dns_name_fullcompare(name, fname, &order, + &olabels); + (void)dns_name_fullcompare(name, &nsec.next, &order, + &nlabels); + if (olabels > nlabels) + dns_name_split(name, olabels, NULL, wname); + else + dns_name_split(name, nlabels, NULL, wname); + result = dns_name_concatenate(dns_wildcardname, + wname, wname, NULL); + if (result == ISC_R_SUCCESS) + have_wname = ISC_TRUE; + dns_rdata_freestruct(&nsec); + } + query_addrrset(client, &fname, &rdataset, &sigrdataset, + dbuf, DNS_SECTION_AUTHORITY); + } + if (rdataset != NULL) + query_putrdataset(client, &rdataset); + if (sigrdataset != NULL) + query_putrdataset(client, &sigrdataset); + if (fname != NULL) + query_releasename(client, &fname); + if (have_wname) { + ispositive = ISC_TRUE; /* prevent loop */ + if (!dns_name_equal(name, wname)) { + name = wname; + goto again; + } + } + cleanup: + if (rdataset != NULL) + query_putrdataset(client, &rdataset); + if (sigrdataset != NULL) + query_putrdataset(client, &sigrdataset); + if (fname != NULL) + query_releasename(client, &fname); +} + +static void +query_addnxrrsetnsec(ns_client_t *client, dns_db_t *db, + dns_dbversion_t *version, dns_name_t **namep, + dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp) +{ + dns_name_t *name; + dns_rdataset_t *sigrdataset; + dns_rdata_t sigrdata; + dns_rdata_rrsig_t sig; + unsigned int labels; + isc_buffer_t *dbuf, b; + dns_name_t *fname; + isc_result_t result; + + name = *namep; + if ((name->attributes & DNS_NAMEATTR_WILDCARD) == 0) { + query_addrrset(client, namep, rdatasetp, sigrdatasetp, + NULL, DNS_SECTION_AUTHORITY); + return; + } + + if (sigrdatasetp == NULL) + return; + sigrdataset = *sigrdatasetp; + if (sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset)) + return; + result = dns_rdataset_first(sigrdataset); + if (result != ISC_R_SUCCESS) + return; + dns_rdata_init(&sigrdata); + dns_rdataset_current(sigrdataset, &sigrdata); + result = dns_rdata_tostruct(&sigrdata, &sig, NULL); + if (result != ISC_R_SUCCESS) + return; + + labels = dns_name_countlabels(name); + if ((unsigned int)sig.labels + 1 >= labels) + return; + + /* XXX */ + query_addwildcardproof(client, db, version, client->query.qname, + ISC_TRUE); + + /* + * We'll need some resources... + */ + dbuf = query_getnamebuf(client); + if (dbuf == NULL) + return; + fname = query_newname(client, dbuf, &b); + if (fname == NULL) + return; + dns_name_split(name, sig.labels + 1, NULL, fname); + /* This will succeed, since we've stripped labels. */ + RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname, fname, fname, + NULL) == ISC_R_SUCCESS); + query_addrrset(client, &fname, rdatasetp, sigrdatasetp, + dbuf, DNS_SECTION_AUTHORITY); +} + +static void +query_resume(isc_task_t *task, isc_event_t *event) { + dns_fetchevent_t *devent = (dns_fetchevent_t *)event; + ns_client_t *client; + isc_boolean_t fetch_cancelled, client_shuttingdown; + + /* + * Resume a query after recursion. + */ + + UNUSED(task); + + REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); + client = devent->ev_arg; + REQUIRE(NS_CLIENT_VALID(client)); + REQUIRE(task == client->task); + REQUIRE(RECURSING(client)); + + LOCK(&client->query.fetchlock); + if (client->query.fetch != NULL) { + /* + * This is the fetch we've been waiting for. + */ + INSIST(devent->fetch == client->query.fetch); + client->query.fetch = NULL; + fetch_cancelled = ISC_FALSE; + /* + * Update client->now. + */ + isc_stdtime_get(&client->now); + } else { + /* + * This is a fetch completion event for a cancelled fetch. + * Clean up and don't resume the find. + */ + fetch_cancelled = ISC_TRUE; + } + UNLOCK(&client->query.fetchlock); + INSIST(client->query.fetch == NULL); + + client->query.attributes &= ~NS_QUERYATTR_RECURSING; + dns_resolver_destroyfetch(&devent->fetch); + + /* + * If this client is shutting down, or this transaction + * has timed out, do not resume the find. + */ + client_shuttingdown = ns_client_shuttingdown(client); + if (fetch_cancelled || client_shuttingdown) { + if (devent->node != NULL) + dns_db_detachnode(devent->db, &devent->node); + if (devent->db != NULL) + dns_db_detach(&devent->db); + query_putrdataset(client, &devent->rdataset); + if (devent->sigrdataset != NULL) + query_putrdataset(client, &devent->sigrdataset); + isc_event_free(&event); + if (fetch_cancelled) + query_error(client, DNS_R_SERVFAIL); + else + query_next(client, ISC_R_CANCELED); + /* + * This may destroy the client. + */ + ns_client_detach(&client); + } else { + query_find(client, devent, 0); + } +} + +static isc_result_t +query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qdomain, + dns_rdataset_t *nameservers) +{ + isc_result_t result; + dns_rdataset_t *rdataset, *sigrdataset; + isc_sockaddr_t *peeraddr; + + inc_stats(client, dns_statscounter_recursion); + + /* + * We are about to recurse, which means that this client will + * be unavailable for serving new requests for an indeterminate + * amount of time. If this client is currently responsible + * for handling incoming queries, set up a new client + * object to handle them while we are waiting for a + * response. There is no need to replace TCP clients + * because those have already been replaced when the + * connection was accepted (if allowed by the TCP quota). + */ + if (client->recursionquota == NULL) { + result = isc_quota_attach(&ns_g_server->recursionquota, + &client->recursionquota); + if (result == ISC_R_SOFTQUOTA) { + static isc_stdtime_t last = 0; + isc_stdtime_t now; + isc_stdtime_get(&now); + if (now != last) { + last = now; + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_QUERY, + ISC_LOG_WARNING, + "recursive-clients soft limit " + "exceeded, aborting oldest query"); + } + ns_client_killoldestquery(client); + result = ISC_R_SUCCESS; + } else if (result == ISC_R_QUOTA) { + static isc_stdtime_t last = 0; + isc_stdtime_t now; + isc_stdtime_get(&now); + if (now != last) { + last = now; + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_QUERY, + ISC_LOG_WARNING, + "no more recursive clients: %s", + isc_result_totext(result)); + } + ns_client_killoldestquery(client); + } + if (result == ISC_R_SUCCESS && !client->mortal && + (client->attributes & NS_CLIENTATTR_TCP) == 0) { + result = ns_client_replace(client); + if (result != ISC_R_SUCCESS) { + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_QUERY, + ISC_LOG_WARNING, + "ns_client_replace() failed: %s", + isc_result_totext(result)); + isc_quota_detach(&client->recursionquota); + } + } + if (result != ISC_R_SUCCESS) + return (result); + ns_client_recursing(client); + } + + /* + * Invoke the resolver. + */ + REQUIRE(nameservers == NULL || nameservers->type == dns_rdatatype_ns); + REQUIRE(client->query.fetch == NULL); + + rdataset = query_newrdataset(client); + if (rdataset == NULL) + return (ISC_R_NOMEMORY); + if (WANTDNSSEC(client)) { + sigrdataset = query_newrdataset(client); + if (sigrdataset == NULL) { + query_putrdataset(client, &rdataset); + return (ISC_R_NOMEMORY); + } + } else + sigrdataset = NULL; + + if (client->query.timerset == ISC_FALSE) + ns_client_settimeout(client, 60); + if ((client->attributes & NS_CLIENTATTR_TCP) == 0) + peeraddr = &client->peeraddr; + else + peeraddr = NULL; + result = dns_resolver_createfetch2(client->view->resolver, + client->query.qname, + qtype, qdomain, nameservers, + NULL, peeraddr, client->message->id, + client->query.fetchoptions, + client->task, + query_resume, client, + rdataset, sigrdataset, + &client->query.fetch); + + if (result == ISC_R_SUCCESS) { + /* + * Record that we're waiting for an event. A client which + * is shutting down will not be destroyed until all the + * events have been received. + */ + } else { + query_putrdataset(client, &rdataset); + if (sigrdataset != NULL) + query_putrdataset(client, &sigrdataset); + } + + return (result); +} + +#define MAX_RESTARTS 16 + +#define QUERY_ERROR(r) \ +do { \ + eresult = r; \ + want_restart = ISC_FALSE; \ +} while (0) + +/* + * Extract a network address from the RDATA of an A or AAAA + * record. + * + * Returns: + * ISC_R_SUCCESS + * ISC_R_NOTIMPLEMENTED The rdata is not a known address type. + */ +static isc_result_t +rdata_tonetaddr(const dns_rdata_t *rdata, isc_netaddr_t *netaddr) { + struct in_addr ina; + struct in6_addr in6a; + + switch (rdata->type) { + case dns_rdatatype_a: + INSIST(rdata->length == 4); + memcpy(&ina.s_addr, rdata->data, 4); + isc_netaddr_fromin(netaddr, &ina); + return (ISC_R_SUCCESS); + case dns_rdatatype_aaaa: + INSIST(rdata->length == 16); + memcpy(in6a.s6_addr, rdata->data, 16); + isc_netaddr_fromin6(netaddr, &in6a); + return (ISC_R_SUCCESS); + default: + return (ISC_R_NOTIMPLEMENTED); + } +} + +/* + * Find the sort order of 'rdata' in the topology-like + * ACL forming the second element in a 2-element top-level + * sortlist statement. + */ +static int +query_sortlist_order_2element(const dns_rdata_t *rdata, const void *arg) { + isc_netaddr_t netaddr; + + if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS) + return (INT_MAX); + return (ns_sortlist_addrorder2(&netaddr, arg)); +} + +/* + * Find the sort order of 'rdata' in the matching element + * of a 1-element top-level sortlist statement. + */ +static int +query_sortlist_order_1element(const dns_rdata_t *rdata, const void *arg) { + isc_netaddr_t netaddr; + + if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS) + return (INT_MAX); + return (ns_sortlist_addrorder1(&netaddr, arg)); +} + +/* + * Find the sortlist statement that applies to 'client' and set up + * the sortlist info in in client->message appropriately. + */ +static void +setup_query_sortlist(ns_client_t *client) { + isc_netaddr_t netaddr; + dns_rdatasetorderfunc_t order = NULL; + const void *order_arg = NULL; + + isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); + switch (ns_sortlist_setup(client->view->sortlist, + &netaddr, &order_arg)) { + case NS_SORTLISTTYPE_1ELEMENT: + order = query_sortlist_order_1element; + break; + case NS_SORTLISTTYPE_2ELEMENT: + order = query_sortlist_order_2element; + break; + case NS_SORTLISTTYPE_NONE: + order = NULL; + break; + default: + INSIST(0); + break; + } + dns_message_setsortorder(client->message, order, order_arg); +} + +static void +query_addnoqnameproof(ns_client_t *client, dns_rdataset_t *rdataset) { + isc_buffer_t *dbuf, b; + dns_name_t *fname; + dns_rdataset_t *nsec, *nsecsig; + isc_result_t result = ISC_R_NOMEMORY; + + CTRACE("query_addnoqnameproof"); + + fname = NULL; + nsec = NULL; + nsecsig = NULL; + + dbuf = query_getnamebuf(client); + if (dbuf == NULL) + goto cleanup; + fname = query_newname(client, dbuf, &b); + nsec = query_newrdataset(client); + nsecsig = query_newrdataset(client); + if (fname == NULL || nsec == NULL || nsecsig == NULL) + goto cleanup; + + result = dns_rdataset_getnoqname(rdataset, fname, nsec, nsecsig); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + query_addrrset(client, &fname, &nsec, &nsecsig, dbuf, + DNS_SECTION_AUTHORITY); + + cleanup: + if (nsec != NULL) + query_putrdataset(client, &nsec); + if (nsecsig != NULL) + query_putrdataset(client, &nsecsig); + if (fname != NULL) + query_releasename(client, &fname); +} + +static inline void +answer_in_glue(ns_client_t *client, dns_rdatatype_t qtype) { + dns_name_t *name; + dns_message_t *msg; + dns_section_t section = DNS_SECTION_ADDITIONAL; + dns_rdataset_t *rdataset = NULL; + + msg = client->message; + for (name = ISC_LIST_HEAD(msg->sections[section]); + name != NULL; + name = ISC_LIST_NEXT(name, link)) + if (dns_name_equal(name, client->query.qname)) { + for (rdataset = ISC_LIST_HEAD(name->list); + rdataset != NULL; + rdataset = ISC_LIST_NEXT(rdataset, link)) + if (rdataset->type == qtype) + break; + break; + } + if (rdataset != NULL) { + ISC_LIST_UNLINK(msg->sections[section], name, link); + ISC_LIST_PREPEND(msg->sections[section], name, link); + ISC_LIST_UNLINK(name->list, rdataset, link); + ISC_LIST_PREPEND(name->list, rdataset, link); + rdataset->attributes |= DNS_RDATASETATTR_REQUIREDGLUE; + } +} + +#define NS_NAME_INIT(A,B) \ + { \ + DNS_NAME_MAGIC, \ + A, sizeof(A), sizeof(B), \ + DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, \ + B, NULL, { (void *)-1, (void *)-1}, \ + {NULL, NULL} \ + } + +static unsigned char inaddr10_offsets[] = { 0, 3, 11, 16 }; +static unsigned char inaddr172_offsets[] = { 0, 3, 7, 15, 20 }; +static unsigned char inaddr192_offsets[] = { 0, 4, 8, 16, 21 }; + +static unsigned char inaddr10[] = "\00210\007IN-ADDR\004ARPA"; + +static unsigned char inaddr16172[] = "\00216\003172\007IN-ADDR\004ARPA"; +static unsigned char inaddr17172[] = "\00217\003172\007IN-ADDR\004ARPA"; +static unsigned char inaddr18172[] = "\00218\003172\007IN-ADDR\004ARPA"; +static unsigned char inaddr19172[] = "\00219\003172\007IN-ADDR\004ARPA"; +static unsigned char inaddr20172[] = "\00220\003172\007IN-ADDR\004ARPA"; +static unsigned char inaddr21172[] = "\00221\003172\007IN-ADDR\004ARPA"; +static unsigned char inaddr22172[] = "\00222\003172\007IN-ADDR\004ARPA"; +static unsigned char inaddr23172[] = "\00223\003172\007IN-ADDR\004ARPA"; +static unsigned char inaddr24172[] = "\00224\003172\007IN-ADDR\004ARPA"; +static unsigned char inaddr25172[] = "\00225\003172\007IN-ADDR\004ARPA"; +static unsigned char inaddr26172[] = "\00226\003172\007IN-ADDR\004ARPA"; +static unsigned char inaddr27172[] = "\00227\003172\007IN-ADDR\004ARPA"; +static unsigned char inaddr28172[] = "\00228\003172\007IN-ADDR\004ARPA"; +static unsigned char inaddr29172[] = "\00229\003172\007IN-ADDR\004ARPA"; +static unsigned char inaddr30172[] = "\00230\003172\007IN-ADDR\004ARPA"; +static unsigned char inaddr31172[] = "\00231\003172\007IN-ADDR\004ARPA"; + +static unsigned char inaddr168192[] = "\003168\003192\007IN-ADDR\004ARPA"; + +static dns_name_t rfc1918names[] = { + NS_NAME_INIT(inaddr10, inaddr10_offsets), + NS_NAME_INIT(inaddr16172, inaddr172_offsets), + NS_NAME_INIT(inaddr17172, inaddr172_offsets), + NS_NAME_INIT(inaddr18172, inaddr172_offsets), + NS_NAME_INIT(inaddr19172, inaddr172_offsets), + NS_NAME_INIT(inaddr20172, inaddr172_offsets), + NS_NAME_INIT(inaddr21172, inaddr172_offsets), + NS_NAME_INIT(inaddr22172, inaddr172_offsets), + NS_NAME_INIT(inaddr23172, inaddr172_offsets), + NS_NAME_INIT(inaddr24172, inaddr172_offsets), + NS_NAME_INIT(inaddr25172, inaddr172_offsets), + NS_NAME_INIT(inaddr26172, inaddr172_offsets), + NS_NAME_INIT(inaddr27172, inaddr172_offsets), + NS_NAME_INIT(inaddr28172, inaddr172_offsets), + NS_NAME_INIT(inaddr29172, inaddr172_offsets), + NS_NAME_INIT(inaddr30172, inaddr172_offsets), + NS_NAME_INIT(inaddr31172, inaddr172_offsets), + NS_NAME_INIT(inaddr168192, inaddr192_offsets) +}; + + +static unsigned char prisoner_data[] = "\010prisoner\004iana\003org"; +static unsigned char hostmaster_data[] = "\012hostmaster\014root-servers\003org"; + +static unsigned char prisoner_offsets[] = { 0, 9, 14, 18 }; +static unsigned char hostmaster_offsets[] = { 0, 11, 24, 28 }; + +static dns_name_t prisoner = NS_NAME_INIT(prisoner_data, prisoner_offsets); +static dns_name_t hostmaster = NS_NAME_INIT(hostmaster_data, hostmaster_offsets); + +static void +warn_rfc1918(ns_client_t *client, dns_name_t *fname, dns_rdataset_t *rdataset) { + unsigned int i; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdata_soa_t soa; + dns_rdataset_t found; + isc_result_t result; + + for (i = 0; i < (sizeof(rfc1918names)/sizeof(*rfc1918names)); i++) { + if (dns_name_issubdomain(fname, &rfc1918names[i])) { + dns_rdataset_init(&found); + result = dns_ncache_getrdataset(rdataset, + &rfc1918names[i], + dns_rdatatype_soa, + &found); + if (result != ISC_R_SUCCESS) + return; + + result = dns_rdataset_first(&found); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + dns_rdataset_current(&found, &rdata); + result = dns_rdata_tostruct(&rdata, &soa, NULL); + if (result != ISC_R_SUCCESS) + return; + if (dns_name_equal(&soa.origin, &prisoner) && + dns_name_equal(&soa.contact, &hostmaster)) { + char buf[DNS_NAME_FORMATSIZE]; + dns_name_format(fname, buf, sizeof(buf)); + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_QUERY, + ISC_LOG_WARNING, + "RFC 1918 response from " + "Internet for %s", buf); + } + dns_rdataset_disassociate(&found); + return; + } + } +} + +/* + * Do the bulk of query processing for the current query of 'client'. + * If 'event' is non-NULL, we are returning from recursion and 'qtype' + * is ignored. Otherwise, 'qtype' is the query type. + */ +static void +query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) +{ + dns_db_t *db, *zdb; + dns_dbnode_t *node; + dns_rdatatype_t type; + dns_name_t *fname, *zfname, *tname, *prefix; + dns_rdataset_t *rdataset, *trdataset; + dns_rdataset_t *sigrdataset, *zrdataset, *zsigrdataset; + dns_rdataset_t **sigrdatasetp; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdatasetiter_t *rdsiter; + isc_boolean_t want_restart, authoritative, is_zone, need_wildcardproof; + unsigned int n, nlabels; + dns_namereln_t namereln; + int order; + isc_buffer_t *dbuf; + isc_buffer_t b; + isc_result_t result, eresult; + dns_fixedname_t fixed; + dns_fixedname_t wildcardname; + dns_dbversion_t *version; + dns_zone_t *zone; + dns_rdata_cname_t cname; + dns_rdata_dname_t dname; + unsigned int options; + isc_boolean_t empty_wild; + dns_rdataset_t *noqname; + + CTRACE("query_find"); + + /* + * One-time initialization. + * + * It's especially important to initialize anything that the cleanup + * code might cleanup. + */ + + eresult = ISC_R_SUCCESS; + fname = NULL; + zfname = NULL; + rdataset = NULL; + zrdataset = NULL; + sigrdataset = NULL; + zsigrdataset = NULL; + node = NULL; + db = NULL; + zdb = NULL; + version = NULL; + zone = NULL; + need_wildcardproof = ISC_FALSE; + empty_wild = ISC_FALSE; + options = 0; + + if (event != NULL) { + /* + * We're returning from recursion. Restore the query context + * and resume. + */ + + want_restart = ISC_FALSE; + authoritative = ISC_FALSE; + is_zone = ISC_FALSE; + + qtype = event->qtype; + if (qtype == dns_rdatatype_rrsig || qtype == dns_rdatatype_sig) + type = dns_rdatatype_any; + else + type = qtype; + db = event->db; + node = event->node; + rdataset = event->rdataset; + sigrdataset = event->sigrdataset; + + /* + * We'll need some resources... + */ + dbuf = query_getnamebuf(client); + if (dbuf == NULL) { + QUERY_ERROR(DNS_R_SERVFAIL); + goto cleanup; + } + fname = query_newname(client, dbuf, &b); + if (fname == NULL) { + QUERY_ERROR(DNS_R_SERVFAIL); + goto cleanup; + } + tname = dns_fixedname_name(&event->foundname); + result = dns_name_copy(tname, fname, NULL); + if (result != ISC_R_SUCCESS) { + QUERY_ERROR(DNS_R_SERVFAIL); + goto cleanup; + } + + result = event->result; + + goto resume; + } + + /* + * Not returning from recursion. + */ + + /* + * If it's a SIG query, we'll iterate the node. + */ + if (qtype == dns_rdatatype_rrsig || qtype == dns_rdatatype_sig) + type = dns_rdatatype_any; + else + type = qtype; + + restart: + CTRACE("query_find: restart"); + want_restart = ISC_FALSE; + authoritative = ISC_FALSE; + version = NULL; + need_wildcardproof = ISC_FALSE; + + if (client->view->checknames && + !dns_rdata_checkowner(client->query.qname, + client->message->rdclass, + qtype, ISC_FALSE)) { + char namebuf[DNS_NAME_FORMATSIZE]; + char typename[DNS_RDATATYPE_FORMATSIZE]; + char classname[DNS_RDATACLASS_FORMATSIZE]; + + dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); + dns_rdatatype_format(qtype, typename, sizeof(typename)); + dns_rdataclass_format(client->message->rdclass, classname, + sizeof(classname)); + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_QUERY, ISC_LOG_ERROR, + "check-names failure %s/%s/%s", namebuf, + typename, classname); + QUERY_ERROR(DNS_R_REFUSED); + goto cleanup; + } + + /* + * First we must find the right database. + */ + options &= DNS_GETDB_NOLOG; /* Preserve DNS_GETDB_NOLOG. */ + if (dns_rdatatype_atparent(qtype) && + !dns_name_equal(client->query.qname, dns_rootname)) + options |= DNS_GETDB_NOEXACT; + result = query_getdb(client, client->query.qname, qtype, options, + &zone, &db, &version, &is_zone); + if ((result != ISC_R_SUCCESS || !is_zone) && !RECURSIONOK(client) && + (options & DNS_GETDB_NOEXACT) != 0 && qtype == dns_rdatatype_ds) { + /* + * Look to see if we are authoritative for the + * child zone if the query type is DS. + */ + dns_db_t *tdb = NULL; + dns_zone_t *tzone = NULL; + dns_dbversion_t *tversion = NULL; + isc_result_t tresult; + + tresult = query_getzonedb(client, client->query.qname, qtype, + DNS_GETDB_PARTIAL, &tzone, &tdb, + &tversion); + if (tresult == ISC_R_SUCCESS) { + options &= ~DNS_GETDB_NOEXACT; + query_putrdataset(client, &rdataset); + if (db != NULL) + dns_db_detach(&db); + if (zone != NULL) + dns_zone_detach(&zone); + version = tversion; + db = tdb; + zone = tzone; + is_zone = ISC_TRUE; + result = ISC_R_SUCCESS; + } else { + if (tdb != NULL) + dns_db_detach(&tdb); + if (tzone != NULL) + dns_zone_detach(&tzone); + } + } + if (result != ISC_R_SUCCESS) { + if (result == DNS_R_REFUSED) { + if (!PARTIALANSWER(client)) + QUERY_ERROR(DNS_R_REFUSED); + } else + QUERY_ERROR(DNS_R_SERVFAIL); + goto cleanup; + } + + if (is_zone) + authoritative = ISC_TRUE; + + if (event == NULL && client->query.restarts == 0) { + if (is_zone) { +#ifdef DLZ + if (zone != NULL) { + /* + * if is_zone = true, zone = NULL then this is + * a DLZ zone. Don't attempt to attach zone. + */ +#endif + dns_zone_attach(zone, &client->query.authzone); +#ifdef DLZ + } +#endif + dns_db_attach(db, &client->query.authdb); + } + client->query.authdbset = ISC_TRUE; + } + + db_find: + CTRACE("query_find: db_find"); + /* + * We'll need some resources... + */ + dbuf = query_getnamebuf(client); + if (dbuf == NULL) { + QUERY_ERROR(DNS_R_SERVFAIL); + goto cleanup; + } + fname = query_newname(client, dbuf, &b); + rdataset = query_newrdataset(client); + if (fname == NULL || rdataset == NULL) { + QUERY_ERROR(DNS_R_SERVFAIL); + goto cleanup; + } + if (WANTDNSSEC(client)) { + sigrdataset = query_newrdataset(client); + if (sigrdataset == NULL) { + QUERY_ERROR(DNS_R_SERVFAIL); + goto cleanup; + } + } + + /* + * Now look for an answer in the database. + */ + result = dns_db_find(db, client->query.qname, version, type, + client->query.dboptions, client->now, + &node, fname, rdataset, sigrdataset); + + resume: + CTRACE("query_find: resume"); + switch (result) { + case ISC_R_SUCCESS: + /* + * This case is handled in the main line below. + */ + break; + case DNS_R_GLUE: + case DNS_R_ZONECUT: + /* + * These cases are handled in the main line below. + */ + INSIST(is_zone); + authoritative = ISC_FALSE; + break; + case ISC_R_NOTFOUND: + /* + * The cache doesn't even have the root NS. Get them from + * the hints DB. + */ + INSIST(!is_zone); + if (db != NULL) + dns_db_detach(&db); + + if (client->view->hints == NULL) { + /* We have no hints. */ + result = ISC_R_FAILURE; + } else { + dns_db_attach(client->view->hints, &db); + result = dns_db_find(db, dns_rootname, + NULL, dns_rdatatype_ns, + 0, client->now, &node, fname, + rdataset, sigrdataset); + } + if (result != ISC_R_SUCCESS) { + /* + * Nonsensical root hints may require cleanup. + */ + if (dns_rdataset_isassociated(rdataset)) + dns_rdataset_disassociate(rdataset); + if (sigrdataset != NULL && + dns_rdataset_isassociated(sigrdataset)) + dns_rdataset_disassociate(sigrdataset); + if (node != NULL) + dns_db_detachnode(db, &node); + + /* + * We don't have any root server hints, but + * we may have working forwarders, so try to + * recurse anyway. + */ + if (RECURSIONOK(client)) { + result = query_recurse(client, qtype, + NULL, NULL); + if (result == ISC_R_SUCCESS) + client->query.attributes |= + NS_QUERYATTR_RECURSING; + else if (result == DNS_R_DUPLICATE || + result == DNS_R_DROP) { + /* Duplicate query. */ + QUERY_ERROR(result); + } else { + /* Unable to recurse. */ + QUERY_ERROR(DNS_R_SERVFAIL); + } + goto cleanup; + } else { + /* Unable to give root server referral. */ + QUERY_ERROR(DNS_R_SERVFAIL); + goto cleanup; + } + } + /* + * XXXRTH We should trigger root server priming here. + */ + /* FALLTHROUGH */ + case DNS_R_DELEGATION: + authoritative = ISC_FALSE; + if (is_zone) { + /* + * Look to see if we are authoritative for the + * child zone if the query type is DS. + */ + if (!RECURSIONOK(client) && + (options & DNS_GETDB_NOEXACT) != 0 && + qtype == dns_rdatatype_ds) { + dns_db_t *tdb = NULL; + dns_zone_t *tzone = NULL; + dns_dbversion_t *tversion = NULL; + result = query_getzonedb(client, + client->query.qname, + qtype, + DNS_GETDB_PARTIAL, + &tzone, &tdb, + &tversion); + if (result == ISC_R_SUCCESS) { + options &= ~DNS_GETDB_NOEXACT; + query_putrdataset(client, &rdataset); + if (sigrdataset != NULL) + query_putrdataset(client, + &sigrdataset); + if (fname != NULL) + query_releasename(client, + &fname); + if (node != NULL) + dns_db_detachnode(db, &node); + if (db != NULL) + dns_db_detach(&db); + if (zone != NULL) + dns_zone_detach(&zone); + version = tversion; + db = tdb; + zone = tzone; + authoritative = ISC_TRUE; + goto db_find; + } + if (tdb != NULL) + dns_db_detach(&tdb); + if (tzone != NULL) + dns_zone_detach(&tzone); + } + /* + * We're authoritative for an ancestor of QNAME. + */ + if (!USECACHE(client) || !RECURSIONOK(client)) { + /* + * If we don't have a cache, this is the best + * answer. + * + * If the client is making a nonrecursive + * query we always give out the authoritative + * delegation. This way even if we get + * junk in our cache, we won't fail in our + * role as the delegating authority if another + * nameserver asks us about a delegated + * subzone. + * + * We enable the retrieval of glue for this + * database by setting client->query.gluedb. + */ + client->query.gluedb = db; + client->query.isreferral = ISC_TRUE; + /* + * We must ensure NOADDITIONAL is off, + * because the generation of + * additional data is required in + * delegations. + */ + client->query.attributes &= + ~NS_QUERYATTR_NOADDITIONAL; + if (sigrdataset != NULL) + sigrdatasetp = &sigrdataset; + else + sigrdatasetp = NULL; + query_addrrset(client, &fname, + &rdataset, sigrdatasetp, + dbuf, DNS_SECTION_AUTHORITY); + client->query.gluedb = NULL; + if (WANTDNSSEC(client) && dns_db_issecure(db)) + query_addds(client, db, node, version); + } else { + /* + * We might have a better answer or delegation + * in the cache. We'll remember the current + * values of fname, rdataset, and sigrdataset. + * We'll then go looking for QNAME in the + * cache. If we find something better, we'll + * use it instead. + */ + query_keepname(client, fname, dbuf); + zdb = db; + zfname = fname; + fname = NULL; + zrdataset = rdataset; + rdataset = NULL; + zsigrdataset = sigrdataset; + sigrdataset = NULL; + dns_db_detachnode(db, &node); + version = NULL; + db = NULL; + dns_db_attach(client->view->cachedb, &db); + is_zone = ISC_FALSE; + goto db_find; + } + } else { + if (zfname != NULL && + !dns_name_issubdomain(fname, zfname)) { + /* + * We've already got a delegation from + * authoritative data, and it is better + * than what we found in the cache. Use + * it instead of the cache delegation. + */ + query_releasename(client, &fname); + fname = zfname; + zfname = NULL; + /* + * We've already done query_keepname() on + * zfname, so we must set dbuf to NULL to + * prevent query_addrrset() from trying to + * call query_keepname() again. + */ + dbuf = NULL; + query_putrdataset(client, &rdataset); + if (sigrdataset != NULL) + query_putrdataset(client, + &sigrdataset); + rdataset = zrdataset; + zrdataset = NULL; + sigrdataset = zsigrdataset; + zsigrdataset = NULL; + /* + * We don't clean up zdb here because we + * may still need it. It will get cleaned + * up by the main cleanup code. + */ + } + + if (RECURSIONOK(client)) { + /* + * Recurse! + */ + if (dns_rdatatype_atparent(type)) + result = query_recurse(client, qtype, + NULL, NULL); + else + result = query_recurse(client, qtype, + fname, rdataset); + if (result == ISC_R_SUCCESS) + client->query.attributes |= + NS_QUERYATTR_RECURSING; + else if (result == DNS_R_DUPLICATE || + result == DNS_R_DROP) + QUERY_ERROR(result); + else + QUERY_ERROR(DNS_R_SERVFAIL); + } else { + /* + * This is the best answer. + */ + client->query.attributes |= + NS_QUERYATTR_CACHEGLUEOK; + client->query.gluedb = zdb; + client->query.isreferral = ISC_TRUE; + /* + * We must ensure NOADDITIONAL is off, + * because the generation of + * additional data is required in + * delegations. + */ + client->query.attributes &= + ~NS_QUERYATTR_NOADDITIONAL; + if (sigrdataset != NULL) + sigrdatasetp = &sigrdataset; + else + sigrdatasetp = NULL; + query_addrrset(client, &fname, + &rdataset, sigrdatasetp, + dbuf, DNS_SECTION_AUTHORITY); + client->query.gluedb = NULL; + client->query.attributes &= + ~NS_QUERYATTR_CACHEGLUEOK; + if (WANTDNSSEC(client)) + query_addds(client, db, node, version); + } + } + goto cleanup; + case DNS_R_EMPTYNAME: + result = DNS_R_NXRRSET; + /* FALLTHROUGH */ + case DNS_R_NXRRSET: + INSIST(is_zone); + if (dns_rdataset_isassociated(rdataset)) { + /* + * If we've got a NSEC record, we need to save the + * name now because we're going call query_addsoa() + * below, and it needs to use the name buffer. + */ + query_keepname(client, fname, dbuf); + } else { + /* + * We're not going to use fname, and need to release + * our hold on the name buffer so query_addsoa() + * may use it. + */ + query_releasename(client, &fname); + } + /* + * Add SOA. + */ + result = query_addsoa(client, db, version, ISC_FALSE); + if (result != ISC_R_SUCCESS) { + QUERY_ERROR(result); + goto cleanup; + } + /* + * Add NSEC record if we found one. + */ + if (WANTDNSSEC(client)) { + if (dns_rdataset_isassociated(rdataset)) + query_addnxrrsetnsec(client, db, version, + &fname, &rdataset, + &sigrdataset); + } + goto cleanup; + case DNS_R_EMPTYWILD: + empty_wild = ISC_TRUE; + /* FALLTHROUGH */ + case DNS_R_NXDOMAIN: + INSIST(is_zone); + if (dns_rdataset_isassociated(rdataset)) { + /* + * If we've got a NSEC record, we need to save the + * name now because we're going call query_addsoa() + * below, and it needs to use the name buffer. + */ + query_keepname(client, fname, dbuf); + } else { + /* + * We're not going to use fname, and need to release + * our hold on the name buffer so query_addsoa() + * may use it. + */ + query_releasename(client, &fname); + } + /* + * Add SOA. If the query was for a SOA record force the + * ttl to zero so that it is possible for clients to find + * the containing zone of an arbitrary name with a stub + * resolver and not have it cached. + */ + if (qtype == dns_rdatatype_soa && +#ifdef DLZ + zone != NULL && +#endif + dns_zone_getzeronosoattl(zone)) + result = query_addsoa(client, db, version, ISC_TRUE); + else + result = query_addsoa(client, db, version, ISC_FALSE); + if (result != ISC_R_SUCCESS) { + QUERY_ERROR(result); + goto cleanup; + } + /* + * Add NSEC record if we found one. + */ + if (dns_rdataset_isassociated(rdataset)) { + if (WANTDNSSEC(client)) { + query_addrrset(client, &fname, &rdataset, + &sigrdataset, + NULL, DNS_SECTION_AUTHORITY); + query_addwildcardproof(client, db, version, + client->query.qname, + ISC_FALSE); + } + } + /* + * Set message rcode. + */ + if (empty_wild) + client->message->rcode = dns_rcode_noerror; + else + client->message->rcode = dns_rcode_nxdomain; + goto cleanup; + case DNS_R_NCACHENXDOMAIN: + case DNS_R_NCACHENXRRSET: + INSIST(!is_zone); + authoritative = ISC_FALSE; + /* + * Set message rcode, if required. + */ + if (result == DNS_R_NCACHENXDOMAIN) + client->message->rcode = dns_rcode_nxdomain; + /* + * Look for RFC 1918 leakage from Internet. + */ + if (result == DNS_R_NCACHENXDOMAIN && + qtype == dns_rdatatype_ptr && + client->message->rdclass == dns_rdataclass_in && + dns_name_countlabels(fname) == 7) + warn_rfc1918(client, fname, rdataset); + /* + * We don't call query_addrrset() because we don't need any + * of its extra features (and things would probably break!). + */ + query_keepname(client, fname, dbuf); + dns_message_addname(client->message, fname, + DNS_SECTION_AUTHORITY); + ISC_LIST_APPEND(fname->list, rdataset, link); + fname = NULL; + rdataset = NULL; + goto cleanup; + case DNS_R_CNAME: + /* + * Keep a copy of the rdataset. We have to do this because + * query_addrrset may clear 'rdataset' (to prevent the + * cleanup code from cleaning it up). + */ + trdataset = rdataset; + /* + * Add the CNAME to the answer section. + */ + if (sigrdataset != NULL) + sigrdatasetp = &sigrdataset; + else + sigrdatasetp = NULL; + if (WANTDNSSEC(client) && + (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) + { + dns_fixedname_init(&wildcardname); + dns_name_copy(fname, dns_fixedname_name(&wildcardname), + NULL); + need_wildcardproof = ISC_TRUE; + } + if ((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0 && + WANTDNSSEC(client)) + noqname = rdataset; + else + noqname = NULL; + query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf, + DNS_SECTION_ANSWER); + if (noqname != NULL) + query_addnoqnameproof(client, noqname); + /* + * We set the PARTIALANSWER attribute so that if anything goes + * wrong later on, we'll return what we've got so far. + */ + client->query.attributes |= NS_QUERYATTR_PARTIALANSWER; + /* + * Reset qname to be the target name of the CNAME and restart + * the query. + */ + tname = NULL; + result = dns_message_gettempname(client->message, &tname); + if (result != ISC_R_SUCCESS) + goto cleanup; + result = dns_rdataset_first(trdataset); + if (result != ISC_R_SUCCESS) { + dns_message_puttempname(client->message, &tname); + goto cleanup; + } + dns_rdataset_current(trdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &cname, NULL); + dns_rdata_reset(&rdata); + if (result != ISC_R_SUCCESS) { + dns_message_puttempname(client->message, &tname); + goto cleanup; + } + dns_name_init(tname, NULL); + result = dns_name_dup(&cname.cname, client->mctx, tname); + if (result != ISC_R_SUCCESS) { + dns_message_puttempname(client->message, &tname); + dns_rdata_freestruct(&cname); + goto cleanup; + } + dns_rdata_freestruct(&cname); + ns_client_qnamereplace(client, tname); + want_restart = ISC_TRUE; + if (!WANTRECURSION(client)) + options |= DNS_GETDB_NOLOG; + goto addauth; + case DNS_R_DNAME: + /* + * Compare the current qname to the found name. We need + * to know how many labels and bits are in common because + * we're going to have to split qname later on. + */ + namereln = dns_name_fullcompare(client->query.qname, fname, + &order, &nlabels); + INSIST(namereln == dns_namereln_subdomain); + /* + * Keep a copy of the rdataset. We have to do this because + * query_addrrset may clear 'rdataset' (to prevent the + * cleanup code from cleaning it up). + */ + trdataset = rdataset; + /* + * Add the DNAME to the answer section. + */ + if (sigrdataset != NULL) + sigrdatasetp = &sigrdataset; + else + sigrdatasetp = NULL; + if (WANTDNSSEC(client) && + (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) + { + dns_fixedname_init(&wildcardname); + dns_name_copy(fname, dns_fixedname_name(&wildcardname), + NULL); + need_wildcardproof = ISC_TRUE; + } + query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf, + DNS_SECTION_ANSWER); + /* + * We set the PARTIALANSWER attribute so that if anything goes + * wrong later on, we'll return what we've got so far. + */ + client->query.attributes |= NS_QUERYATTR_PARTIALANSWER; + /* + * Get the target name of the DNAME. + */ + tname = NULL; + result = dns_message_gettempname(client->message, &tname); + if (result != ISC_R_SUCCESS) + goto cleanup; + result = dns_rdataset_first(trdataset); + if (result != ISC_R_SUCCESS) { + dns_message_puttempname(client->message, &tname); + goto cleanup; + } + dns_rdataset_current(trdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &dname, NULL); + dns_rdata_reset(&rdata); + if (result != ISC_R_SUCCESS) { + dns_message_puttempname(client->message, &tname); + goto cleanup; + } + dns_name_init(tname, NULL); + dns_name_clone(&dname.dname, tname); + dns_rdata_freestruct(&dname); + /* + * Construct the new qname. + */ + dns_fixedname_init(&fixed); + prefix = dns_fixedname_name(&fixed); + dns_name_split(client->query.qname, nlabels, prefix, NULL); + INSIST(fname == NULL); + dbuf = query_getnamebuf(client); + if (dbuf == NULL) { + dns_message_puttempname(client->message, &tname); + goto cleanup; + } + fname = query_newname(client, dbuf, &b); + if (fname == NULL) { + dns_message_puttempname(client->message, &tname); + goto cleanup; + } + result = dns_name_concatenate(prefix, tname, fname, NULL); + if (result != ISC_R_SUCCESS) { + dns_message_puttempname(client->message, &tname); + if (result == ISC_R_NOSPACE) { + /* + * RFC2672, section 4.1, subsection 3c says + * we should return YXDOMAIN if the constructed + * name would be too long. + */ + client->message->rcode = dns_rcode_yxdomain; + } + goto cleanup; + } + query_keepname(client, fname, dbuf); + /* + * Synthesize a CNAME for this DNAME. + * + * We want to synthesize a CNAME since if we don't + * then older software that doesn't understand DNAME + * will not chain like it should. + * + * We do not try to synthesize a signature because we hope + * that security aware servers will understand DNAME. Also, + * even if we had an online key, making a signature + * on-the-fly is costly, and not really legitimate anyway + * since the synthesized CNAME is NOT in the zone. + */ + dns_name_init(tname, NULL); + (void)query_addcnamelike(client, client->query.qname, fname, + trdataset->trust, &tname, + dns_rdatatype_cname); + if (tname != NULL) + dns_message_puttempname(client->message, &tname); + /* + * Switch to the new qname and restart. + */ + ns_client_qnamereplace(client, fname); + fname = NULL; + want_restart = ISC_TRUE; + if (!WANTRECURSION(client)) + options |= DNS_GETDB_NOLOG; + goto addauth; + default: + /* + * Something has gone wrong. + */ + QUERY_ERROR(DNS_R_SERVFAIL); + goto cleanup; + } + + if (WANTDNSSEC(client) && + (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) + { + dns_fixedname_init(&wildcardname); + dns_name_copy(fname, dns_fixedname_name(&wildcardname), NULL); + need_wildcardproof = ISC_TRUE; + } + + if (type == dns_rdatatype_any) { + /* + * XXXRTH Need to handle zonecuts with special case + * code. + */ + n = 0; + rdsiter = NULL; + result = dns_db_allrdatasets(db, node, version, 0, &rdsiter); + if (result != ISC_R_SUCCESS) { + QUERY_ERROR(DNS_R_SERVFAIL); + goto cleanup; + } + /* + * Calling query_addrrset() with a non-NULL dbuf is going + * to either keep or release the name. We don't want it to + * release fname, since we may have to call query_addrrset() + * more than once. That means we have to call query_keepname() + * now, and pass a NULL dbuf to query_addrrset(). + * + * If we do a query_addrrset() below, we must set fname to + * NULL before leaving this block, otherwise we might try to + * cleanup fname even though we're using it! + */ + query_keepname(client, fname, dbuf); + tname = fname; + result = dns_rdatasetiter_first(rdsiter); + while (result == ISC_R_SUCCESS) { + dns_rdatasetiter_current(rdsiter, rdataset); + if ((qtype == dns_rdatatype_any || + rdataset->type == qtype) && rdataset->type != 0) { + query_addrrset(client, + fname != NULL ? &fname : &tname, + &rdataset, NULL, + NULL, DNS_SECTION_ANSWER); + n++; + INSIST(tname != NULL); + /* + * rdataset is non-NULL only in certain pathological + * cases involving DNAMEs. + */ + if (rdataset != NULL) + query_putrdataset(client, &rdataset); + rdataset = query_newrdataset(client); + if (rdataset == NULL) + break; + } else { + /* + * We're not interested in this rdataset. + */ + dns_rdataset_disassociate(rdataset); + } + result = dns_rdatasetiter_next(rdsiter); + } + + if (fname != NULL) + dns_message_puttempname(client->message, &fname); + + if (n == 0) { + /* + * We didn't match any rdatasets. + */ + if (qtype == dns_rdatatype_rrsig && + result == ISC_R_NOMORE) { + /* + * XXXRTH If this is a secure zone and we + * didn't find any SIGs, we should generate + * an error unless we were searching for + * glue. Ugh. + */ + if (!is_zone) { + authoritative = ISC_FALSE; + dns_rdatasetiter_destroy(&rdsiter); + if (RECURSIONOK(client)) { + result = query_recurse(client, + qtype, + NULL, + NULL); + if (result == ISC_R_SUCCESS) + client->query.attributes |= + NS_QUERYATTR_RECURSING; + else + QUERY_ERROR(DNS_R_SERVFAIL); } + goto addauth; + } + /* + * We were searching for SIG records in + * a nonsecure zone. Send a "no error, + * no data" response. + */ + /* + * Add SOA. + */ + result = query_addsoa(client, db, version, + ISC_FALSE); + if (result == ISC_R_SUCCESS) + result = ISC_R_NOMORE; + } else { + /* + * Something went wrong. + */ + result = DNS_R_SERVFAIL; + } + } + dns_rdatasetiter_destroy(&rdsiter); + if (result != ISC_R_NOMORE) { + QUERY_ERROR(DNS_R_SERVFAIL); + goto cleanup; + } + } else { + /* + * This is the "normal" case -- an ordinary question to which + * we know the answer. + */ + if (sigrdataset != NULL) + sigrdatasetp = &sigrdataset; + else + sigrdatasetp = NULL; + if ((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0 && + WANTDNSSEC(client)) + noqname = rdataset; + else + noqname = NULL; + /* + * BIND 8 priming queries need the additional section. + */ + if (is_zone && qtype == dns_rdatatype_ns && + dns_name_equal(client->query.qname, dns_rootname)) + client->query.attributes &= ~NS_QUERYATTR_NOADDITIONAL; + + query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf, + DNS_SECTION_ANSWER); + if (noqname != NULL) + query_addnoqnameproof(client, noqname); + /* + * We shouldn't ever fail to add 'rdataset' + * because it's already in the answer. + */ + INSIST(rdataset == NULL); + } + + addauth: + CTRACE("query_find: addauth"); + /* + * Add NS records to the authority section (if we haven't already + * added them to the answer section). + */ + if (!want_restart && !NOAUTHORITY(client)) { + if (is_zone) { + if (!((qtype == dns_rdatatype_ns || + qtype == dns_rdatatype_any) && + dns_name_equal(client->query.qname, + dns_db_origin(db)))) + (void)query_addns(client, db, version); + } else if (qtype != dns_rdatatype_ns) { + if (fname != NULL) + query_releasename(client, &fname); + query_addbestns(client); + } + } + + /* + * Add NSEC records to the authority section if they're needed for + * DNSSEC wildcard proofs. + */ + if (need_wildcardproof && dns_db_issecure(db)) + query_addwildcardproof(client, db, version, + dns_fixedname_name(&wildcardname), + ISC_TRUE); + cleanup: + CTRACE("query_find: cleanup"); + /* + * General cleanup. + */ + if (rdataset != NULL) + query_putrdataset(client, &rdataset); + if (sigrdataset != NULL) + query_putrdataset(client, &sigrdataset); + if (fname != NULL) + query_releasename(client, &fname); + if (node != NULL) + dns_db_detachnode(db, &node); + if (db != NULL) + dns_db_detach(&db); + if (zone != NULL) + dns_zone_detach(&zone); + if (zdb != NULL) { + query_putrdataset(client, &zrdataset); + if (zsigrdataset != NULL) + query_putrdataset(client, &zsigrdataset); + if (zfname != NULL) + query_releasename(client, &zfname); + dns_db_detach(&zdb); + } + if (event != NULL) + isc_event_free(ISC_EVENT_PTR(&event)); + + /* + * AA bit. + */ + if (client->query.restarts == 0 && !authoritative) { + /* + * We're not authoritative, so we must ensure the AA bit + * isn't set. + */ + client->message->flags &= ~DNS_MESSAGEFLAG_AA; + } + + /* + * Restart the query? + */ + if (want_restart && client->query.restarts < MAX_RESTARTS) { + client->query.restarts++; + goto restart; + } + + if (eresult != ISC_R_SUCCESS && + (!PARTIALANSWER(client) || WANTRECURSION(client))) { + if (eresult == DNS_R_DUPLICATE || eresult == DNS_R_DROP) { + /* + * This was a duplicate query that we are + * recursing on. Don't send a response now. + * The original query will still cause a response. + */ + query_next(client, eresult); + } else { + /* + * If we don't have any answer to give the client, + * or if the client requested recursion and thus wanted + * the complete answer, send an error response. + */ + query_error(client, eresult); + } + ns_client_detach(&client); + } else if (!RECURSING(client)) { + /* + * We are done. Set up sortlist data for the message + * rendering code, make a final tweak to the AA bit if the + * auth-nxdomain config option says so, then render and + * send the response. + */ + setup_query_sortlist(client); + + /* + * If this is a referral and the answer to the question + * is in the glue sort it to the start of the additional + * section. + */ + if (client->message->counts[DNS_SECTION_ANSWER] == 0 && + client->message->rcode == dns_rcode_noerror && + (qtype == dns_rdatatype_a || qtype == dns_rdatatype_aaaa)) + answer_in_glue(client, qtype); + + if (client->message->rcode == dns_rcode_nxdomain && + client->view->auth_nxdomain == ISC_TRUE) + client->message->flags |= DNS_MESSAGEFLAG_AA; + + query_send(client); + ns_client_detach(&client); + } + CTRACE("query_find: done"); +} + +static inline void +log_query(ns_client_t *client) { + char namebuf[DNS_NAME_FORMATSIZE]; + char typename[DNS_RDATATYPE_FORMATSIZE]; + char classname[DNS_RDATACLASS_FORMATSIZE]; + dns_rdataset_t *rdataset; + int level = ISC_LOG_INFO; + + if (! isc_log_wouldlog(ns_g_lctx, level)) + return; + + rdataset = ISC_LIST_HEAD(client->query.qname->list); + INSIST(rdataset != NULL); + dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); + dns_rdataclass_format(rdataset->rdclass, classname, sizeof(classname)); + dns_rdatatype_format(rdataset->type, typename, sizeof(typename)); + + ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY, + level, "query: %s %s %s %s%s%s", namebuf, classname, + typename, WANTRECURSION(client) ? "+" : "-", + (client->signer != NULL) ? "S": "", + (client->opt != NULL) ? "E" : ""); +} + +void +ns_query_start(ns_client_t *client) { + isc_result_t result; + dns_message_t *message = client->message; + dns_rdataset_t *rdataset; + ns_client_t *qclient; + dns_rdatatype_t qtype; + + CTRACE("ns_query_start"); + + /* + * Ensure that appropriate cleanups occur. + */ + client->next = query_next_callback; + + /* + * Behave as if we don't support DNSSEC if not enabled. + */ + if (!client->view->enablednssec) { + message->flags &= ~DNS_MESSAGEFLAG_CD; + client->extflags &= ~DNS_MESSAGEEXTFLAG_DO; + if (client->opt != NULL) + client->opt->ttl &= ~DNS_MESSAGEEXTFLAG_DO; + } + + if ((message->flags & DNS_MESSAGEFLAG_RD) != 0) + client->query.attributes |= NS_QUERYATTR_WANTRECURSION; + + if ((client->extflags & DNS_MESSAGEEXTFLAG_DO) != 0) + client->attributes |= NS_CLIENTATTR_WANTDNSSEC; + + if (client->view->minimalresponses) + client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | + NS_QUERYATTR_NOADDITIONAL); + + if ((client->view->cachedb == NULL) + || (!client->view->additionalfromcache)) { + /* + * We don't have a cache. Turn off cache support and + * recursion. + */ + client->query.attributes &= + ~(NS_QUERYATTR_RECURSIONOK|NS_QUERYATTR_CACHEOK); + } else if ((client->attributes & NS_CLIENTATTR_RA) == 0 || + (message->flags & DNS_MESSAGEFLAG_RD) == 0) { + /* + * If the client isn't allowed to recurse (due to + * "recursion no", the allow-recursion ACL, or the + * lack of a resolver in this view), or if it + * doesn't want recursion, turn recursion off. + */ + client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK; + } + + /* + * Get the question name. + */ + result = dns_message_firstname(message, DNS_SECTION_QUESTION); + if (result != ISC_R_SUCCESS) { + query_error(client, result); + return; + } + dns_message_currentname(message, DNS_SECTION_QUESTION, + &client->query.qname); + client->query.origqname = client->query.qname; + result = dns_message_nextname(message, DNS_SECTION_QUESTION); + if (result != ISC_R_NOMORE) { + if (result == ISC_R_SUCCESS) { + /* + * There's more than one QNAME in the question + * section. + */ + query_error(client, DNS_R_FORMERR); + } else + query_error(client, result); + return; + } + + if (ns_g_server->log_queries) + log_query(client); + + /* + * Check for multiple question queries, since edns1 is dead. + */ + if (message->counts[DNS_SECTION_QUESTION] > 1) { + query_error(client, DNS_R_FORMERR); + return; + } + + /* + * Check for meta-queries like IXFR and AXFR. + */ + rdataset = ISC_LIST_HEAD(client->query.qname->list); + INSIST(rdataset != NULL); + qtype = rdataset->type; + if (dns_rdatatype_ismeta(qtype)) { + switch (qtype) { + case dns_rdatatype_any: + break; /* Let query_find handle it. */ + case dns_rdatatype_ixfr: + case dns_rdatatype_axfr: + ns_xfr_start(client, rdataset->type); + return; + case dns_rdatatype_maila: + case dns_rdatatype_mailb: + query_error(client, DNS_R_NOTIMP); + return; + case dns_rdatatype_tkey: + result = dns_tkey_processquery(client->message, + ns_g_server->tkeyctx, + client->view->dynamickeys); + if (result == ISC_R_SUCCESS) + query_send(client); + else + query_error(client, result); + return; + default: /* TSIG, etc. */ + query_error(client, DNS_R_FORMERR); + return; + } + } + + /* + * If the client has requested that DNSSEC checking be disabled, + * allow lookups to return pending data and instruct the resolver + * to return data before validation has completed. + * + * We don't need to set DNS_DBFIND_PENDINGOK when validation is + * disabled as there will be no pending data. + */ + if (message->flags & DNS_MESSAGEFLAG_CD || + qtype == dns_rdatatype_rrsig) + { + client->query.dboptions |= DNS_DBFIND_PENDINGOK; + client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE; + } else if (!client->view->enablevalidation) + client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE; + + /* + * Allow glue NS records to be added to the authority section + * if the answer is secure. + */ + if (message->flags & DNS_MESSAGEFLAG_CD) + client->query.attributes &= ~NS_QUERYATTR_SECURE; + + /* + * This is an ordinary query. + */ + result = dns_message_reply(message, ISC_TRUE); + if (result != ISC_R_SUCCESS) { + query_next(client, result); + return; + } + + /* + * Assume authoritative response until it is known to be + * otherwise. + */ + message->flags |= DNS_MESSAGEFLAG_AA; + + /* + * Set AD. We must clear it if we add non-validated data to a + * response. + */ + if (WANTDNSSEC(client)) + message->flags |= DNS_MESSAGEFLAG_AD; + + qclient = NULL; + ns_client_attach(client, &qclient); + query_find(qclient, NULL, qtype); +} diff --git a/bin/named/server.c b/bin/named/server.c new file mode 100644 index 0000000..cd8bff1 --- /dev/null +++ b/bin/named/server.c @@ -0,0 +1,4835 @@ +/* + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-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: server.c,v 1.419.18.57 2007/08/28 07:20:01 tbox Exp $ */ + +/*! \file */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#ifdef DLZ +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LIBSCF +#include +#include +#endif + +/*% + * Check an operation for failure. Assumes that the function + * using it has a 'result' variable and a 'cleanup' label. + */ +#define CHECK(op) \ + do { result = (op); \ + if (result != ISC_R_SUCCESS) goto cleanup; \ + } while (0) + +#define CHECKM(op, msg) \ + do { result = (op); \ + if (result != ISC_R_SUCCESS) { \ + isc_log_write(ns_g_lctx, \ + NS_LOGCATEGORY_GENERAL, \ + NS_LOGMODULE_SERVER, \ + ISC_LOG_ERROR, \ + "%s: %s", msg, \ + isc_result_totext(result)); \ + goto cleanup; \ + } \ + } while (0) \ + +#define CHECKMF(op, msg, file) \ + do { result = (op); \ + if (result != ISC_R_SUCCESS) { \ + isc_log_write(ns_g_lctx, \ + NS_LOGCATEGORY_GENERAL, \ + NS_LOGMODULE_SERVER, \ + ISC_LOG_ERROR, \ + "%s '%s': %s", msg, file, \ + isc_result_totext(result)); \ + goto cleanup; \ + } \ + } while (0) \ + +#define CHECKFATAL(op, msg) \ + do { result = (op); \ + if (result != ISC_R_SUCCESS) \ + fatal(msg, result); \ + } while (0) \ + +struct ns_dispatch { + isc_sockaddr_t addr; + unsigned int dispatchgen; + dns_dispatch_t *dispatch; + ISC_LINK(struct ns_dispatch) link; +}; + +struct dumpcontext { + isc_mem_t *mctx; + isc_boolean_t dumpcache; + isc_boolean_t dumpzones; + FILE *fp; + ISC_LIST(struct viewlistentry) viewlist; + struct viewlistentry *view; + struct zonelistentry *zone; + dns_dumpctx_t *mdctx; + dns_db_t *db; + dns_db_t *cache; + isc_task_t *task; + dns_dbversion_t *version; +}; + +struct viewlistentry { + dns_view_t *view; + ISC_LINK(struct viewlistentry) link; + ISC_LIST(struct zonelistentry) zonelist; +}; + +struct zonelistentry { + dns_zone_t *zone; + ISC_LINK(struct zonelistentry) link; +}; + +/* + * These zones should not leak onto the Internet. + */ +static const struct { + const char *zone; + isc_boolean_t rfc1918; +} empty_zones[] = { +#ifdef notyet + /* RFC 1918 */ + { "10.IN-ADDR.ARPA", ISC_TRUE }, + { "16.172.IN-ADDR.ARPA", ISC_TRUE }, + { "17.172.IN-ADDR.ARPA", ISC_TRUE }, + { "18.172.IN-ADDR.ARPA", ISC_TRUE }, + { "19.172.IN-ADDR.ARPA", ISC_TRUE }, + { "20.172.IN-ADDR.ARPA", ISC_TRUE }, + { "21.172.IN-ADDR.ARPA", ISC_TRUE }, + { "22.172.IN-ADDR.ARPA", ISC_TRUE }, + { "23.172.IN-ADDR.ARPA", ISC_TRUE }, + { "24.172.IN-ADDR.ARPA", ISC_TRUE }, + { "25.172.IN-ADDR.ARPA", ISC_TRUE }, + { "26.172.IN-ADDR.ARPA", ISC_TRUE }, + { "27.172.IN-ADDR.ARPA", ISC_TRUE }, + { "28.172.IN-ADDR.ARPA", ISC_TRUE }, + { "29.172.IN-ADDR.ARPA", ISC_TRUE }, + { "30.172.IN-ADDR.ARPA", ISC_TRUE }, + { "31.172.IN-ADDR.ARPA", ISC_TRUE }, + { "168.192.IN-ADDR.ARPA", ISC_TRUE }, +#endif + + /* RFC 3330 */ + { "127.IN-ADDR.ARPA", ISC_FALSE }, /* LOOPBACK */ + { "254.169.IN-ADDR.ARPA", ISC_FALSE }, /* LINK LOCAL */ + { "2.0.192.IN-ADDR.ARPA", ISC_FALSE }, /* TEST NET */ + { "255.255.255.255.IN-ADDR.ARPA", ISC_FALSE }, /* BROADCAST */ + + /* Local IPv6 Unicast Addresses */ + { "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA", ISC_FALSE }, + { "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA", ISC_FALSE }, + /* LOCALLY ASSIGNED LOCAL ADDRES S SCOPE */ + { "D.F.IP6.ARPA", ISC_FALSE }, + { "8.E.F.IP6.ARPA", ISC_FALSE }, /* LINK LOCAL */ + { "9.E.F.IP6.ARPA", ISC_FALSE }, /* LINK LOCAL */ + { "A.E.F.IP6.ARPA", ISC_FALSE }, /* LINK LOCAL */ + { "B.E.F.IP6.ARPA", ISC_FALSE }, /* LINK LOCAL */ + + { NULL, ISC_FALSE } +}; + +static void +fatal(const char *msg, isc_result_t result); + +static void +ns_server_reload(isc_task_t *task, isc_event_t *event); + +static isc_result_t +ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, + cfg_aclconfctx_t *actx, + isc_mem_t *mctx, ns_listenelt_t **target); +static isc_result_t +ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config, + cfg_aclconfctx_t *actx, + isc_mem_t *mctx, ns_listenlist_t **target); + +static isc_result_t +configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin, + const cfg_obj_t *forwarders, const cfg_obj_t *forwardtype); + +static isc_result_t +configure_alternates(const cfg_obj_t *config, dns_view_t *view, + const cfg_obj_t *alternates); + +static isc_result_t +configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig, + const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view, + cfg_aclconfctx_t *aclconf); + +static void +end_reserved_dispatches(ns_server_t *server, isc_boolean_t all); + +/*% + * Configure a single view ACL at '*aclp'. Get its configuration by + * calling 'getvcacl' (for per-view configuration) and maybe 'getscacl' + * (for a global default). + */ +static isc_result_t +configure_view_acl(const cfg_obj_t *vconfig, const cfg_obj_t *config, + const char *aclname, cfg_aclconfctx_t *actx, + isc_mem_t *mctx, dns_acl_t **aclp) +{ + isc_result_t result; + const cfg_obj_t *maps[3]; + const cfg_obj_t *aclobj = NULL; + int i = 0; + + if (*aclp != NULL) + dns_acl_detach(aclp); + if (vconfig != NULL) + maps[i++] = cfg_tuple_get(vconfig, "options"); + if (config != NULL) { + const cfg_obj_t *options = NULL; + (void)cfg_map_get(config, "options", &options); + if (options != NULL) + maps[i++] = options; + } + maps[i] = NULL; + + (void)ns_config_get(maps, aclname, &aclobj); + if (aclobj == NULL) + /* + * No value available. *aclp == NULL. + */ + return (ISC_R_SUCCESS); + + result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx, + actx, mctx, aclp); + + return (result); +} + +static isc_result_t +configure_view_dnsseckey(const cfg_obj_t *vconfig, const cfg_obj_t *key, + dns_keytable_t *keytable, isc_mem_t *mctx) +{ + dns_rdataclass_t viewclass; + dns_rdata_dnskey_t keystruct; + isc_uint32_t flags, proto, alg; + const char *keystr, *keynamestr; + unsigned char keydata[4096]; + isc_buffer_t keydatabuf; + unsigned char rrdata[4096]; + isc_buffer_t rrdatabuf; + isc_region_t r; + dns_fixedname_t fkeyname; + dns_name_t *keyname; + isc_buffer_t namebuf; + isc_result_t result; + dst_key_t *dstkey = NULL; + + flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags")); + proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol")); + alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm")); + keyname = dns_fixedname_name(&fkeyname); + keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name")); + + if (vconfig == NULL) + viewclass = dns_rdataclass_in; + else { + const cfg_obj_t *classobj = cfg_tuple_get(vconfig, "class"); + CHECK(ns_config_getclass(classobj, dns_rdataclass_in, + &viewclass)); + } + keystruct.common.rdclass = viewclass; + keystruct.common.rdtype = dns_rdatatype_dnskey; + /* + * The key data in keystruct is not dynamically allocated. + */ + keystruct.mctx = NULL; + + ISC_LINK_INIT(&keystruct.common, link); + + if (flags > 0xffff) + CHECKM(ISC_R_RANGE, "key flags"); + if (proto > 0xff) + CHECKM(ISC_R_RANGE, "key protocol"); + if (alg > 0xff) + CHECKM(ISC_R_RANGE, "key algorithm"); + keystruct.flags = (isc_uint16_t)flags; + keystruct.protocol = (isc_uint8_t)proto; + keystruct.algorithm = (isc_uint8_t)alg; + + isc_buffer_init(&keydatabuf, keydata, sizeof(keydata)); + isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata)); + + keystr = cfg_obj_asstring(cfg_tuple_get(key, "key")); + CHECK(isc_base64_decodestring(keystr, &keydatabuf)); + isc_buffer_usedregion(&keydatabuf, &r); + keystruct.datalen = r.length; + keystruct.data = r.base; + + if ((keystruct.algorithm == DST_ALG_RSASHA1 || + keystruct.algorithm == DST_ALG_RSAMD5) && + r.length > 1 && r.base[0] == 1 && r.base[1] == 3) + cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, + "trusted key '%s' has a weak exponent", + keynamestr); + + CHECK(dns_rdata_fromstruct(NULL, + keystruct.common.rdclass, + keystruct.common.rdtype, + &keystruct, &rrdatabuf)); + dns_fixedname_init(&fkeyname); + isc_buffer_init(&namebuf, keynamestr, strlen(keynamestr)); + isc_buffer_add(&namebuf, strlen(keynamestr)); + CHECK(dns_name_fromtext(keyname, &namebuf, + dns_rootname, ISC_FALSE, + NULL)); + CHECK(dst_key_fromdns(keyname, viewclass, &rrdatabuf, + mctx, &dstkey)); + + CHECK(dns_keytable_add(keytable, &dstkey)); + INSIST(dstkey == NULL); + return (ISC_R_SUCCESS); + + cleanup: + if (result == DST_R_NOCRYPTO) { + cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, + "ignoring trusted key for '%s': no crypto support", + keynamestr); + result = ISC_R_SUCCESS; + } else { + cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, + "configuring trusted key for '%s': %s", + keynamestr, isc_result_totext(result)); + result = ISC_R_FAILURE; + } + + if (dstkey != NULL) + dst_key_free(&dstkey); + + return (result); +} + +/*% + * Configure DNSSEC keys for a view. Currently used only for + * the security roots. + * + * The per-view configuration values and the server-global defaults are read + * from 'vconfig' and 'config'. The variable to be configured is '*target'. + */ +static isc_result_t +configure_view_dnsseckeys(const cfg_obj_t *vconfig, const cfg_obj_t *config, + isc_mem_t *mctx, dns_keytable_t **target) +{ + isc_result_t result; + const cfg_obj_t *keys = NULL; + const cfg_obj_t *voptions = NULL; + const cfg_listelt_t *element, *element2; + const cfg_obj_t *keylist; + const cfg_obj_t *key; + dns_keytable_t *keytable = NULL; + + CHECK(dns_keytable_create(mctx, &keytable)); + + if (vconfig != NULL) + voptions = cfg_tuple_get(vconfig, "options"); + + keys = NULL; + if (voptions != NULL) + (void)cfg_map_get(voptions, "trusted-keys", &keys); + if (keys == NULL) + (void)cfg_map_get(config, "trusted-keys", &keys); + + for (element = cfg_list_first(keys); + element != NULL; + element = cfg_list_next(element)) + { + keylist = cfg_listelt_value(element); + for (element2 = cfg_list_first(keylist); + element2 != NULL; + element2 = cfg_list_next(element2)) + { + key = cfg_listelt_value(element2); + CHECK(configure_view_dnsseckey(vconfig, key, + keytable, mctx)); + } + } + + dns_keytable_detach(target); + *target = keytable; /* Transfer ownership. */ + keytable = NULL; + result = ISC_R_SUCCESS; + + cleanup: + return (result); +} + +static isc_result_t +mustbesecure(const cfg_obj_t *mbs, dns_resolver_t *resolver) +{ + const cfg_listelt_t *element; + const cfg_obj_t *obj; + const char *str; + dns_fixedname_t fixed; + dns_name_t *name; + isc_boolean_t value; + isc_result_t result; + isc_buffer_t b; + + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + for (element = cfg_list_first(mbs); + element != NULL; + element = cfg_list_next(element)) + { + obj = cfg_listelt_value(element); + str = cfg_obj_asstring(cfg_tuple_get(obj, "name")); + isc_buffer_init(&b, str, strlen(str)); + isc_buffer_add(&b, strlen(str)); + CHECK(dns_name_fromtext(name, &b, dns_rootname, + ISC_FALSE, NULL)); + value = cfg_obj_asboolean(cfg_tuple_get(obj, "value")); + CHECK(dns_resolver_setmustbesecure(resolver, name, value)); + } + + result = ISC_R_SUCCESS; + + cleanup: + return (result); +} + +/*% + * Get a dispatch appropriate for the resolver of a given view. + */ +static isc_result_t +get_view_querysource_dispatch(const cfg_obj_t **maps, + int af, dns_dispatch_t **dispatchp) +{ + isc_result_t result; + dns_dispatch_t *disp; + isc_sockaddr_t sa; + unsigned int attrs, attrmask; + const cfg_obj_t *obj = NULL; + + /* + * Make compiler happy. + */ + result = ISC_R_FAILURE; + + switch (af) { + case AF_INET: + result = ns_config_get(maps, "query-source", &obj); + INSIST(result == ISC_R_SUCCESS); + break; + case AF_INET6: + result = ns_config_get(maps, "query-source-v6", &obj); + INSIST(result == ISC_R_SUCCESS); + break; + default: + INSIST(0); + } + + sa = *(cfg_obj_assockaddr(obj)); + INSIST(isc_sockaddr_pf(&sa) == af); + + /* + * If we don't support this address family, we're done! + */ + switch (af) { + case AF_INET: + result = isc_net_probeipv4(); + break; + case AF_INET6: + result = isc_net_probeipv6(); + break; + default: + INSIST(0); + } + if (result != ISC_R_SUCCESS) + return (ISC_R_SUCCESS); + + /* + * Try to find a dispatcher that we can share. + */ + attrs = 0; + attrs |= DNS_DISPATCHATTR_UDP; + switch (af) { + case AF_INET: + attrs |= DNS_DISPATCHATTR_IPV4; + break; + case AF_INET6: + attrs |= DNS_DISPATCHATTR_IPV6; + break; + } + attrmask = 0; + attrmask |= DNS_DISPATCHATTR_UDP; + attrmask |= DNS_DISPATCHATTR_TCP; + attrmask |= DNS_DISPATCHATTR_IPV4; + attrmask |= DNS_DISPATCHATTR_IPV6; + + disp = NULL; + result = dns_dispatch_getudp(ns_g_dispatchmgr, ns_g_socketmgr, + ns_g_taskmgr, &sa, 4096, + 1000, 32768, 16411, 16433, + attrs, attrmask, &disp); + if (result != ISC_R_SUCCESS) { + isc_sockaddr_t any; + char buf[ISC_SOCKADDR_FORMATSIZE]; + + switch (af) { + case AF_INET: + isc_sockaddr_any(&any); + break; + case AF_INET6: + isc_sockaddr_any6(&any); + break; + } + if (isc_sockaddr_equal(&sa, &any)) + return (ISC_R_SUCCESS); + isc_sockaddr_format(&sa, buf, sizeof(buf)); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "could not get query source dispatcher (%s)", + buf); + return (result); + } + + *dispatchp = disp; + + return (ISC_R_SUCCESS); +} + +static isc_result_t +configure_order(dns_order_t *order, const cfg_obj_t *ent) { + dns_rdataclass_t rdclass; + dns_rdatatype_t rdtype; + const cfg_obj_t *obj; + dns_fixedname_t fixed; + unsigned int mode = 0; + const char *str; + isc_buffer_t b; + isc_result_t result; + isc_boolean_t addroot; + + result = ns_config_getclass(cfg_tuple_get(ent, "class"), + dns_rdataclass_any, &rdclass); + if (result != ISC_R_SUCCESS) + return (result); + + result = ns_config_gettype(cfg_tuple_get(ent, "type"), + dns_rdatatype_any, &rdtype); + if (result != ISC_R_SUCCESS) + return (result); + + obj = cfg_tuple_get(ent, "name"); + if (cfg_obj_isstring(obj)) + str = cfg_obj_asstring(obj); + else + str = "*"; + addroot = ISC_TF(strcmp(str, "*") == 0); + isc_buffer_init(&b, str, strlen(str)); + isc_buffer_add(&b, strlen(str)); + dns_fixedname_init(&fixed); + result = dns_name_fromtext(dns_fixedname_name(&fixed), &b, + dns_rootname, ISC_FALSE, NULL); + if (result != ISC_R_SUCCESS) + return (result); + + obj = cfg_tuple_get(ent, "ordering"); + INSIST(cfg_obj_isstring(obj)); + str = cfg_obj_asstring(obj); + if (!strcasecmp(str, "fixed")) + mode = DNS_RDATASETATTR_FIXEDORDER; + else if (!strcasecmp(str, "random")) + mode = DNS_RDATASETATTR_RANDOMIZE; + else if (!strcasecmp(str, "cyclic")) + mode = 0; + else + INSIST(0); + + /* + * "*" should match everything including the root (BIND 8 compat). + * As dns_name_matcheswildcard(".", "*.") returns FALSE add a + * explicit entry for "." when the name is "*". + */ + if (addroot) { + result = dns_order_add(order, dns_rootname, + rdtype, rdclass, mode); + if (result != ISC_R_SUCCESS) + return (result); + } + + return (dns_order_add(order, dns_fixedname_name(&fixed), + rdtype, rdclass, mode)); +} + +static isc_result_t +configure_peer(const cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) { + isc_netaddr_t na; + dns_peer_t *peer; + const cfg_obj_t *obj; + const char *str; + isc_result_t result; + unsigned int prefixlen; + + cfg_obj_asnetprefix(cfg_map_getname(cpeer), &na, &prefixlen); + + peer = NULL; + result = dns_peer_new(mctx, &na, &peer); + if (result != ISC_R_SUCCESS) + return (result); + + obj = NULL; + (void)cfg_map_get(cpeer, "bogus", &obj); + if (obj != NULL) + CHECK(dns_peer_setbogus(peer, cfg_obj_asboolean(obj))); + + obj = NULL; + (void)cfg_map_get(cpeer, "provide-ixfr", &obj); + if (obj != NULL) + CHECK(dns_peer_setprovideixfr(peer, cfg_obj_asboolean(obj))); + + obj = NULL; + (void)cfg_map_get(cpeer, "request-ixfr", &obj); + if (obj != NULL) + CHECK(dns_peer_setrequestixfr(peer, cfg_obj_asboolean(obj))); + + obj = NULL; + (void)cfg_map_get(cpeer, "edns", &obj); + if (obj != NULL) + CHECK(dns_peer_setsupportedns(peer, cfg_obj_asboolean(obj))); + + obj = NULL; + (void)cfg_map_get(cpeer, "edns-udp-size", &obj); + if (obj != NULL) { + isc_uint32_t udpsize = cfg_obj_asuint32(obj); + if (udpsize < 512) + udpsize = 512; + if (udpsize > 4096) + udpsize = 4096; + CHECK(dns_peer_setudpsize(peer, (isc_uint16_t)udpsize)); + } + + obj = NULL; + (void)cfg_map_get(cpeer, "max-udp-size", &obj); + if (obj != NULL) { + isc_uint32_t udpsize = cfg_obj_asuint32(obj); + if (udpsize < 512) + udpsize = 512; + if (udpsize > 4096) + udpsize = 4096; + CHECK(dns_peer_setmaxudp(peer, (isc_uint16_t)udpsize)); + } + + obj = NULL; + (void)cfg_map_get(cpeer, "transfers", &obj); + if (obj != NULL) + CHECK(dns_peer_settransfers(peer, cfg_obj_asuint32(obj))); + + obj = NULL; + (void)cfg_map_get(cpeer, "transfer-format", &obj); + if (obj != NULL) { + str = cfg_obj_asstring(obj); + if (strcasecmp(str, "many-answers") == 0) + CHECK(dns_peer_settransferformat(peer, + dns_many_answers)); + else if (strcasecmp(str, "one-answer") == 0) + CHECK(dns_peer_settransferformat(peer, + dns_one_answer)); + else + INSIST(0); + } + + obj = NULL; + (void)cfg_map_get(cpeer, "keys", &obj); + if (obj != NULL) { + result = dns_peer_setkeybycharp(peer, cfg_obj_asstring(obj)); + if (result != ISC_R_SUCCESS) + goto cleanup; + } + + obj = NULL; + if (na.family == AF_INET) + (void)cfg_map_get(cpeer, "transfer-source", &obj); + else + (void)cfg_map_get(cpeer, "transfer-source-v6", &obj); + if (obj != NULL) { + result = dns_peer_settransfersource(peer, + cfg_obj_assockaddr(obj)); + if (result != ISC_R_SUCCESS) + goto cleanup; + ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); + } + + obj = NULL; + if (na.family == AF_INET) + (void)cfg_map_get(cpeer, "notify-source", &obj); + else + (void)cfg_map_get(cpeer, "notify-source-v6", &obj); + if (obj != NULL) { + result = dns_peer_setnotifysource(peer, + cfg_obj_assockaddr(obj)); + if (result != ISC_R_SUCCESS) + goto cleanup; + ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); + } + + obj = NULL; + if (na.family == AF_INET) + (void)cfg_map_get(cpeer, "query-source", &obj); + else + (void)cfg_map_get(cpeer, "query-source-v6", &obj); + if (obj != NULL) { + result = dns_peer_setquerysource(peer, + cfg_obj_assockaddr(obj)); + if (result != ISC_R_SUCCESS) + goto cleanup; + ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); + } + + *peerp = peer; + return (ISC_R_SUCCESS); + + cleanup: + dns_peer_detach(&peer); + return (result); +} + +static isc_result_t +disable_algorithms(const cfg_obj_t *disabled, dns_resolver_t *resolver) { + isc_result_t result; + const cfg_obj_t *algorithms; + const cfg_listelt_t *element; + const char *str; + dns_fixedname_t fixed; + dns_name_t *name; + isc_buffer_t b; + + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + str = cfg_obj_asstring(cfg_tuple_get(disabled, "name")); + isc_buffer_init(&b, str, strlen(str)); + isc_buffer_add(&b, strlen(str)); + CHECK(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL)); + + algorithms = cfg_tuple_get(disabled, "algorithms"); + for (element = cfg_list_first(algorithms); + element != NULL; + element = cfg_list_next(element)) + { + isc_textregion_t r; + dns_secalg_t alg; + + DE_CONST(cfg_obj_asstring(cfg_listelt_value(element)), r.base); + r.length = strlen(r.base); + + result = dns_secalg_fromtext(&alg, &r); + if (result != ISC_R_SUCCESS) { + isc_uint8_t ui; + result = isc_parse_uint8(&ui, r.base, 10); + alg = ui; + } + if (result != ISC_R_SUCCESS) { + cfg_obj_log(cfg_listelt_value(element), + ns_g_lctx, ISC_LOG_ERROR, + "invalid algorithm"); + CHECK(result); + } + CHECK(dns_resolver_disable_algorithm(resolver, name, alg)); + } + cleanup: + return (result); +} + +static isc_boolean_t +on_disable_list(const cfg_obj_t *disablelist, dns_name_t *zonename) { + const cfg_listelt_t *element; + dns_fixedname_t fixed; + dns_name_t *name; + isc_result_t result; + const cfg_obj_t *value; + const char *str; + isc_buffer_t b; + + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + + for (element = cfg_list_first(disablelist); + element != NULL; + element = cfg_list_next(element)) + { + value = cfg_listelt_value(element); + str = cfg_obj_asstring(value); + isc_buffer_init(&b, str, strlen(str)); + isc_buffer_add(&b, strlen(str)); + result = dns_name_fromtext(name, &b, dns_rootname, + ISC_TRUE, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + if (dns_name_equal(name, zonename)) + return (ISC_TRUE); + } + return (ISC_FALSE); +} + +static void +check_dbtype(dns_zone_t **zonep, unsigned int dbtypec, const char **dbargv, + isc_mem_t *mctx) +{ + char **argv = NULL; + unsigned int i; + isc_result_t result; + + result = dns_zone_getdbtype(*zonep, &argv, mctx); + if (result != ISC_R_SUCCESS) { + dns_zone_detach(zonep); + return; + } + + /* + * Check that all the arguments match. + */ + for (i = 0; i < dbtypec; i++) + if (argv[i] == NULL || strcmp(argv[i], dbargv[i]) != 0) { + dns_zone_detach(zonep); + break; + } + + /* + * Check that there are not extra arguments. + */ + if (i == dbtypec && argv[i] != NULL) + dns_zone_detach(zonep); + isc_mem_free(mctx, argv); +} + + +/* + * Configure 'view' according to 'vconfig', taking defaults from 'config' + * where values are missing in 'vconfig'. + * + * When configuring the default view, 'vconfig' will be NULL and the + * global defaults in 'config' used exclusively. + */ +static isc_result_t +configure_view(dns_view_t *view, const cfg_obj_t *config, + const cfg_obj_t *vconfig, isc_mem_t *mctx, + cfg_aclconfctx_t *actx, isc_boolean_t need_hints) +{ + const cfg_obj_t *maps[4]; + const cfg_obj_t *cfgmaps[3]; + const cfg_obj_t *options = NULL; + const cfg_obj_t *voptions = NULL; + const cfg_obj_t *forwardtype; + const cfg_obj_t *forwarders; + const cfg_obj_t *alternates; + const cfg_obj_t *zonelist; +#ifdef DLZ + const cfg_obj_t *dlz; + unsigned int dlzargc; + char **dlzargv; +#endif + const cfg_obj_t *disabled; + const cfg_obj_t *obj; + const cfg_listelt_t *element; + in_port_t port; + dns_cache_t *cache = NULL; + isc_result_t result; + isc_uint32_t max_adb_size; + isc_uint32_t max_cache_size; + isc_uint32_t max_acache_size; + isc_uint32_t lame_ttl; + dns_tsig_keyring_t *ring; + dns_view_t *pview = NULL; /* Production view */ + isc_mem_t *cmctx; + dns_dispatch_t *dispatch4 = NULL; + dns_dispatch_t *dispatch6 = NULL; + isc_boolean_t reused_cache = ISC_FALSE; + int i; + const char *str; + dns_order_t *order = NULL; + isc_uint32_t udpsize; + unsigned int check = 0; + dns_zone_t *zone = NULL; + isc_uint32_t max_clients_per_query; + const char *sep = ": view "; + const char *viewname = view->name; + const char *forview = " for view "; + isc_boolean_t rfc1918; + isc_boolean_t empty_zones_enable; + const cfg_obj_t *disablelist = NULL; + + REQUIRE(DNS_VIEW_VALID(view)); + + cmctx = NULL; + + if (config != NULL) + (void)cfg_map_get(config, "options", &options); + + i = 0; + if (vconfig != NULL) { + voptions = cfg_tuple_get(vconfig, "options"); + maps[i++] = voptions; + } + if (options != NULL) + maps[i++] = options; + maps[i++] = ns_g_defaults; + maps[i] = NULL; + + i = 0; + if (voptions != NULL) + cfgmaps[i++] = voptions; + if (config != NULL) + cfgmaps[i++] = config; + cfgmaps[i] = NULL; + + if (!strcmp(viewname, "_default")) { + sep = ""; + viewname = ""; + forview = ""; + } + + /* + * Set the view's port number for outgoing queries. + */ + CHECKM(ns_config_getport(config, &port), "port"); + dns_view_setdstport(view, port); + + /* + * Create additional cache for this view and zones under the view + * if explicitly enabled. + * XXX950 default to on. + */ + obj = NULL; + (void)ns_config_get(maps, "acache-enable", &obj); + if (obj != NULL && cfg_obj_asboolean(obj)) { + cmctx = NULL; + CHECK(isc_mem_create(0, 0, &cmctx)); + CHECK(dns_acache_create(&view->acache, cmctx, ns_g_taskmgr, + ns_g_timermgr)); + isc_mem_detach(&cmctx); + } + if (view->acache != NULL) { + obj = NULL; + result = ns_config_get(maps, "acache-cleaning-interval", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_acache_setcleaninginterval(view->acache, + cfg_obj_asuint32(obj) * 60); + + obj = NULL; + result = ns_config_get(maps, "max-acache-size", &obj); + INSIST(result == ISC_R_SUCCESS); + if (cfg_obj_isstring(obj)) { + str = cfg_obj_asstring(obj); + INSIST(strcasecmp(str, "unlimited") == 0); + max_acache_size = ISC_UINT32_MAX; + } else { + isc_resourcevalue_t value; + + value = cfg_obj_asuint64(obj); + if (value > ISC_UINT32_MAX) { + cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, + "'max-acache-size " + "%" ISC_PRINT_QUADFORMAT + "d' is too large", + value); + result = ISC_R_RANGE; + goto cleanup; + } + max_acache_size = (isc_uint32_t)value; + } + dns_acache_setcachesize(view->acache, max_acache_size); + } + + /* + * Configure the zones. + */ + zonelist = NULL; + if (voptions != NULL) + (void)cfg_map_get(voptions, "zone", &zonelist); + else + (void)cfg_map_get(config, "zone", &zonelist); + for (element = cfg_list_first(zonelist); + element != NULL; + element = cfg_list_next(element)) + { + const cfg_obj_t *zconfig = cfg_listelt_value(element); + CHECK(configure_zone(config, zconfig, vconfig, mctx, view, + actx)); + } + +#ifdef DLZ + /* + * Create Dynamically Loadable Zone driver. + */ + dlz = NULL; + if (voptions != NULL) + (void)cfg_map_get(voptions, "dlz", &dlz); + else + (void)cfg_map_get(config, "dlz", &dlz); + + obj = NULL; + if (dlz != NULL) { + (void)cfg_map_get(cfg_tuple_get(dlz, "options"), + "database", &obj); + if (obj != NULL) { + char *s = isc_mem_strdup(mctx, cfg_obj_asstring(obj)); + if (s == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + + result = dns_dlzstrtoargv(mctx, s, &dlzargc, &dlzargv); + if (result != ISC_R_SUCCESS) { + isc_mem_free(mctx, s); + goto cleanup; + } + + obj = cfg_tuple_get(dlz, "name"); + result = dns_dlzcreate(mctx, cfg_obj_asstring(obj), + dlzargv[0], dlzargc, dlzargv, + &view->dlzdatabase); + isc_mem_free(mctx, s); + isc_mem_put(mctx, dlzargv, dlzargc * sizeof(*dlzargv)); + if (result != ISC_R_SUCCESS) + goto cleanup; + } + } +#endif + + /* + * Configure the view's cache. Try to reuse an existing + * cache if possible, otherwise create a new cache. + * Note that the ADB is not preserved in either case. + * + * XXX Determining when it is safe to reuse a cache is + * tricky. When the view's configuration changes, the cached + * data may become invalid because it reflects our old + * view of the world. As more view attributes become + * configurable, we will have to add code here to check + * whether they have changed in ways that could + * invalidate the cache. + */ + result = dns_viewlist_find(&ns_g_server->viewlist, + view->name, view->rdclass, + &pview); + if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) + goto cleanup; + if (pview != NULL) { + INSIST(pview->cache != NULL); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(3), + "reusing existing cache"); + reused_cache = ISC_TRUE; + dns_cache_attach(pview->cache, &cache); + dns_view_detach(&pview); + } else { + CHECK(isc_mem_create(0, 0, &cmctx)); + CHECK(dns_cache_create(cmctx, ns_g_taskmgr, ns_g_timermgr, + view->rdclass, "rbt", 0, NULL, &cache)); + } + dns_view_setcache(view, cache); + + /* + * cache-file cannot be inherited if views are present, but this + * should be caught by the configuration checking stage. + */ + obj = NULL; + result = ns_config_get(maps, "cache-file", &obj); + if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") != 0) { + CHECK(dns_cache_setfilename(cache, cfg_obj_asstring(obj))); + if (!reused_cache) + CHECK(dns_cache_load(cache)); + } + + obj = NULL; + result = ns_config_get(maps, "cleaning-interval", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_cache_setcleaninginterval(cache, cfg_obj_asuint32(obj) * 60); + + obj = NULL; + result = ns_config_get(maps, "max-cache-size", &obj); + INSIST(result == ISC_R_SUCCESS); + if (cfg_obj_isstring(obj)) { + str = cfg_obj_asstring(obj); + INSIST(strcasecmp(str, "unlimited") == 0); + max_cache_size = ISC_UINT32_MAX; + } else { + isc_resourcevalue_t value; + value = cfg_obj_asuint64(obj); + if (value > ISC_UINT32_MAX) { + cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, + "'max-cache-size " + "%" ISC_PRINT_QUADFORMAT "d' is too large", + value); + result = ISC_R_RANGE; + goto cleanup; + } + max_cache_size = (isc_uint32_t)value; + } + dns_cache_setcachesize(cache, max_cache_size); + + dns_cache_detach(&cache); + + /* + * Check-names. + */ + obj = NULL; + result = ns_checknames_get(maps, "response", &obj); + INSIST(result == ISC_R_SUCCESS); + + str = cfg_obj_asstring(obj); + if (strcasecmp(str, "fail") == 0) { + check = DNS_RESOLVER_CHECKNAMES | + DNS_RESOLVER_CHECKNAMESFAIL; + view->checknames = ISC_TRUE; + } else if (strcasecmp(str, "warn") == 0) { + check = DNS_RESOLVER_CHECKNAMES; + view->checknames = ISC_FALSE; + } else if (strcasecmp(str, "ignore") == 0) { + check = 0; + view->checknames = ISC_FALSE; + } else + INSIST(0); + + /* + * Resolver. + * + * XXXRTH Hardwired number of tasks. + */ + CHECK(get_view_querysource_dispatch(maps, AF_INET, &dispatch4)); + CHECK(get_view_querysource_dispatch(maps, AF_INET6, &dispatch6)); + if (dispatch4 == NULL && dispatch6 == NULL) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "unable to obtain neither an IPv4 nor" + " an IPv6 dispatch"); + result = ISC_R_UNEXPECTED; + goto cleanup; + } + CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31, + ns_g_socketmgr, ns_g_timermgr, + check, ns_g_dispatchmgr, + dispatch4, dispatch6)); + + /* + * Set the ADB cache size to 1/8th of the max-cache-size. + */ + max_adb_size = 0; + if (max_cache_size != 0) { + max_adb_size = max_cache_size / 8; + if (max_adb_size == 0) + max_adb_size = 1; /* Force minimum. */ + } + dns_adb_setadbsize(view->adb, max_adb_size); + + /* + * Set resolver's lame-ttl. + */ + obj = NULL; + result = ns_config_get(maps, "lame-ttl", &obj); + INSIST(result == ISC_R_SUCCESS); + lame_ttl = cfg_obj_asuint32(obj); + if (lame_ttl > 1800) + lame_ttl = 1800; + dns_resolver_setlamettl(view->resolver, lame_ttl); + + obj = NULL; + result = ns_config_get(maps, "zero-no-soa-ttl-cache", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_resolver_setzeronosoattl(view->resolver, cfg_obj_asboolean(obj)); + + /* + * Set the resolver's EDNS UDP size. + */ + obj = NULL; + result = ns_config_get(maps, "edns-udp-size", &obj); + INSIST(result == ISC_R_SUCCESS); + udpsize = cfg_obj_asuint32(obj); + if (udpsize < 512) + udpsize = 512; + if (udpsize > 4096) + udpsize = 4096; + dns_resolver_setudpsize(view->resolver, (isc_uint16_t)udpsize); + + /* + * Set the maximum UDP response size. + */ + obj = NULL; + result = ns_config_get(maps, "max-udp-size", &obj); + INSIST(result == ISC_R_SUCCESS); + udpsize = cfg_obj_asuint32(obj); + if (udpsize < 512) + udpsize = 512; + if (udpsize > 4096) + udpsize = 4096; + view->maxudp = udpsize; + + /* + * Set supported DNSSEC algorithms. + */ + dns_resolver_reset_algorithms(view->resolver); + disabled = NULL; + (void)ns_config_get(maps, "disable-algorithms", &disabled); + if (disabled != NULL) { + for (element = cfg_list_first(disabled); + element != NULL; + element = cfg_list_next(element)) + CHECK(disable_algorithms(cfg_listelt_value(element), + view->resolver)); + } + + /* + * A global or view "forwarders" option, if present, + * creates an entry for "." in the forwarding table. + */ + forwardtype = NULL; + forwarders = NULL; + (void)ns_config_get(maps, "forward", &forwardtype); + (void)ns_config_get(maps, "forwarders", &forwarders); + if (forwarders != NULL) + CHECK(configure_forward(config, view, dns_rootname, + forwarders, forwardtype)); + + /* + * Dual Stack Servers. + */ + alternates = NULL; + (void)ns_config_get(maps, "dual-stack-servers", &alternates); + if (alternates != NULL) + CHECK(configure_alternates(config, view, alternates)); + + /* + * We have default hints for class IN if we need them. + */ + if (view->rdclass == dns_rdataclass_in && view->hints == NULL) + dns_view_sethints(view, ns_g_server->in_roothints); + + /* + * If we still have no hints, this is a non-IN view with no + * "hints zone" configured. Issue a warning, except if this + * is a root server. Root servers never need to consult + * their hints, so it's no point requiring users to configure + * them. + */ + if (view->hints == NULL) { + dns_zone_t *rootzone = NULL; + (void)dns_view_findzone(view, dns_rootname, &rootzone); + if (rootzone != NULL) { + dns_zone_detach(&rootzone); + need_hints = ISC_FALSE; + } + if (need_hints) + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_WARNING, + "no root hints for view '%s'", + view->name); + } + + /* + * Configure the view's TSIG keys. + */ + ring = NULL; + CHECK(ns_tsigkeyring_fromconfig(config, vconfig, view->mctx, &ring)); + dns_view_setkeyring(view, ring); + + /* + * Configure the view's peer list. + */ + { + const cfg_obj_t *peers = NULL; + const cfg_listelt_t *element; + dns_peerlist_t *newpeers = NULL; + + (void)ns_config_get(cfgmaps, "server", &peers); + CHECK(dns_peerlist_new(mctx, &newpeers)); + for (element = cfg_list_first(peers); + element != NULL; + element = cfg_list_next(element)) + { + const cfg_obj_t *cpeer = cfg_listelt_value(element); + dns_peer_t *peer; + + CHECK(configure_peer(cpeer, mctx, &peer)); + dns_peerlist_addpeer(newpeers, peer); + dns_peer_detach(&peer); + } + dns_peerlist_detach(&view->peers); + view->peers = newpeers; /* Transfer ownership. */ + } + + /* + * Configure the views rrset-order. + */ + { + const cfg_obj_t *rrsetorder = NULL; + const cfg_listelt_t *element; + + (void)ns_config_get(maps, "rrset-order", &rrsetorder); + CHECK(dns_order_create(mctx, &order)); + for (element = cfg_list_first(rrsetorder); + element != NULL; + element = cfg_list_next(element)) + { + const cfg_obj_t *ent = cfg_listelt_value(element); + + CHECK(configure_order(order, ent)); + } + if (view->order != NULL) + dns_order_detach(&view->order); + dns_order_attach(order, &view->order); + dns_order_detach(&order); + } + /* + * Copy the aclenv object. + */ + dns_aclenv_copy(&view->aclenv, &ns_g_server->aclenv); + + /* + * Configure the "match-clients" and "match-destinations" ACL. + */ + CHECK(configure_view_acl(vconfig, config, "match-clients", actx, + ns_g_mctx, &view->matchclients)); + CHECK(configure_view_acl(vconfig, config, "match-destinations", actx, + ns_g_mctx, &view->matchdestinations)); + + /* + * Configure the "match-recursive-only" option. + */ + obj = NULL; + (void)ns_config_get(maps, "match-recursive-only", &obj); + if (obj != NULL && cfg_obj_asboolean(obj)) + view->matchrecursiveonly = ISC_TRUE; + else + view->matchrecursiveonly = ISC_FALSE; + + /* + * Configure other configurable data. + */ + obj = NULL; + result = ns_config_get(maps, "recursion", &obj); + INSIST(result == ISC_R_SUCCESS); + view->recursion = cfg_obj_asboolean(obj); + + obj = NULL; + result = ns_config_get(maps, "auth-nxdomain", &obj); + INSIST(result == ISC_R_SUCCESS); + view->auth_nxdomain = cfg_obj_asboolean(obj); + + obj = NULL; + result = ns_config_get(maps, "minimal-responses", &obj); + INSIST(result == ISC_R_SUCCESS); + view->minimalresponses = cfg_obj_asboolean(obj); + + obj = NULL; + result = ns_config_get(maps, "transfer-format", &obj); + INSIST(result == ISC_R_SUCCESS); + str = cfg_obj_asstring(obj); + if (strcasecmp(str, "many-answers") == 0) + view->transfer_format = dns_many_answers; + else if (strcasecmp(str, "one-answer") == 0) + view->transfer_format = dns_one_answer; + else + INSIST(0); + + /* + * Set sources where additional data and CNAME/DNAME + * targets for authoritative answers may be found. + */ + obj = NULL; + result = ns_config_get(maps, "additional-from-auth", &obj); + INSIST(result == ISC_R_SUCCESS); + view->additionalfromauth = cfg_obj_asboolean(obj); + if (view->recursion && ! view->additionalfromauth) { + cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, + "'additional-from-auth no' is only supported " + "with 'recursion no'"); + view->additionalfromauth = ISC_TRUE; + } + + obj = NULL; + result = ns_config_get(maps, "additional-from-cache", &obj); + INSIST(result == ISC_R_SUCCESS); + view->additionalfromcache = cfg_obj_asboolean(obj); + if (view->recursion && ! view->additionalfromcache) { + cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, + "'additional-from-cache no' is only supported " + "with 'recursion no'"); + view->additionalfromcache = ISC_TRUE; + } + + /* + * Set "allow-query-cache" and "allow-recursion" acls if + * configured in named.conf. + */ + CHECK(configure_view_acl(vconfig, config, "allow-query-cache", + actx, ns_g_mctx, &view->queryacl)); + + if (strcmp(view->name, "_bind") != 0) + CHECK(configure_view_acl(vconfig, config, "allow-recursion", + actx, ns_g_mctx, &view->recursionacl)); + + /* + * Warning if both "recursion no;" and allow-recursion are active + * except for "allow-recursion { none; };". + */ + if (!view->recursion && view->recursionacl != NULL && + (view->recursionacl->length != 1 || + view->recursionacl->elements[0].type != dns_aclelementtype_any || + view->recursionacl->elements[0].negative != ISC_TRUE)) + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_WARNING, + "both \"recursion no;\" and \"allow-recursion\" " + "active%s%s", forview, viewname); + + /* + * "allow-query-cache" inherits from "allow-recursion" if set, + * otherwise from "allow-query" if set. + * "allow-recursion" inherits from "allow-query-cache" if set, + * otherwise from "allow-query" if set. + */ + if (view->queryacl == NULL && view->recursionacl != NULL) + dns_acl_attach(view->recursionacl, &view->queryacl); + if (view->queryacl == NULL) + CHECK(configure_view_acl(vconfig, config, "allow-query", + actx, ns_g_mctx, &view->queryacl)); + if (view->recursionacl == NULL && view->queryacl != NULL) + dns_acl_attach(view->queryacl, &view->recursionacl); + + /* + * Set default "allow-recursion" and "allow-query-cache" acls. + */ + if (view->recursionacl == NULL && view->recursion) + CHECK(configure_view_acl(NULL, ns_g_config, "allow-recursion", + actx, ns_g_mctx, &view->recursionacl)); + if (view->queryacl == NULL) + CHECK(configure_view_acl(NULL, ns_g_config, + "allow-query-cache", actx, + ns_g_mctx, &view->queryacl)); + + CHECK(configure_view_acl(vconfig, config, "sortlist", + actx, ns_g_mctx, &view->sortlist)); + + obj = NULL; + result = ns_config_get(maps, "request-ixfr", &obj); + INSIST(result == ISC_R_SUCCESS); + view->requestixfr = cfg_obj_asboolean(obj); + + obj = NULL; + result = ns_config_get(maps, "provide-ixfr", &obj); + INSIST(result == ISC_R_SUCCESS); + view->provideixfr = cfg_obj_asboolean(obj); + + obj = NULL; + result = ns_config_get(maps, "max-clients-per-query", &obj); + INSIST(result == ISC_R_SUCCESS); + max_clients_per_query = cfg_obj_asuint32(obj); + + obj = NULL; + result = ns_config_get(maps, "clients-per-query", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_resolver_setclientsperquery(view->resolver, + cfg_obj_asuint32(obj), + max_clients_per_query); + + obj = NULL; + result = ns_config_get(maps, "dnssec-enable", &obj); + INSIST(result == ISC_R_SUCCESS); + view->enablednssec = cfg_obj_asboolean(obj); + + obj = NULL; + result = ns_config_get(maps, "dnssec-accept-expired", &obj); + INSIST(result == ISC_R_SUCCESS); + view->acceptexpired = cfg_obj_asboolean(obj); + + obj = NULL; + result = ns_config_get(maps, "dnssec-validation", &obj); + INSIST(result == ISC_R_SUCCESS); + view->enablevalidation = cfg_obj_asboolean(obj); + + obj = NULL; + result = ns_config_get(maps, "dnssec-lookaside", &obj); + if (result == ISC_R_SUCCESS) { + for (element = cfg_list_first(obj); + element != NULL; + element = cfg_list_next(element)) + { + const char *str; + isc_buffer_t b; + dns_name_t *dlv; + + obj = cfg_listelt_value(element); +#if 0 + dns_fixedname_t fixed; + dns_name_t *name; + + /* + * When we support multiple dnssec-lookaside + * entries this is how to find the domain to be + * checked. XXXMPA + */ + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + str = cfg_obj_asstring(cfg_tuple_get(obj, + "domain")); + isc_buffer_init(&b, str, strlen(str)); + isc_buffer_add(&b, strlen(str)); + CHECK(dns_name_fromtext(name, &b, dns_rootname, + ISC_TRUE, NULL)); +#endif + str = cfg_obj_asstring(cfg_tuple_get(obj, + "trust-anchor")); + isc_buffer_init(&b, str, strlen(str)); + isc_buffer_add(&b, strlen(str)); + dlv = dns_fixedname_name(&view->dlv_fixed); + CHECK(dns_name_fromtext(dlv, &b, dns_rootname, + ISC_TRUE, NULL)); + view->dlv = dns_fixedname_name(&view->dlv_fixed); + } + } else + view->dlv = NULL; + + /* + * For now, there is only one kind of trusted keys, the + * "security roots". + */ + CHECK(configure_view_dnsseckeys(vconfig, config, mctx, + &view->secroots)); + dns_resolver_resetmustbesecure(view->resolver); + obj = NULL; + result = ns_config_get(maps, "dnssec-must-be-secure", &obj); + if (result == ISC_R_SUCCESS) + CHECK(mustbesecure(obj, view->resolver)); + + obj = NULL; + result = ns_config_get(maps, "max-cache-ttl", &obj); + INSIST(result == ISC_R_SUCCESS); + view->maxcachettl = cfg_obj_asuint32(obj); + + obj = NULL; + result = ns_config_get(maps, "max-ncache-ttl", &obj); + INSIST(result == ISC_R_SUCCESS); + view->maxncachettl = cfg_obj_asuint32(obj); + if (view->maxncachettl > 7 * 24 * 3600) + view->maxncachettl = 7 * 24 * 3600; + + obj = NULL; + result = ns_config_get(maps, "preferred-glue", &obj); + if (result == ISC_R_SUCCESS) { + str = cfg_obj_asstring(obj); + if (strcasecmp(str, "a") == 0) + view->preferred_glue = dns_rdatatype_a; + else if (strcasecmp(str, "aaaa") == 0) + view->preferred_glue = dns_rdatatype_aaaa; + else + view->preferred_glue = 0; + } else + view->preferred_glue = 0; + + obj = NULL; + result = ns_config_get(maps, "root-delegation-only", &obj); + if (result == ISC_R_SUCCESS) { + dns_view_setrootdelonly(view, ISC_TRUE); + if (!cfg_obj_isvoid(obj)) { + dns_fixedname_t fixed; + dns_name_t *name; + isc_buffer_t b; + const char *str; + const cfg_obj_t *exclude; + + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + for (element = cfg_list_first(obj); + element != NULL; + element = cfg_list_next(element)) { + exclude = cfg_listelt_value(element); + str = cfg_obj_asstring(exclude); + isc_buffer_init(&b, str, strlen(str)); + isc_buffer_add(&b, strlen(str)); + CHECK(dns_name_fromtext(name, &b, dns_rootname, + ISC_FALSE, NULL)); + CHECK(dns_view_excludedelegationonly(view, + name)); + } + } + } else + dns_view_setrootdelonly(view, ISC_FALSE); + + /* + * Setup automatic empty zones. If recursion is off then + * they are disabled by default. + */ + obj = NULL; + (void)ns_config_get(maps, "empty-zones-enable", &obj); + (void)ns_config_get(maps, "disable-empty-zone", &disablelist); + if (obj == NULL && disablelist == NULL && + view->rdclass == dns_rdataclass_in) { + rfc1918 = ISC_FALSE; + empty_zones_enable = view->recursion; + } else if (view->rdclass == dns_rdataclass_in) { + rfc1918 = ISC_TRUE; + if (obj != NULL) + empty_zones_enable = cfg_obj_asboolean(obj); + else + empty_zones_enable = view->recursion; + } else { + rfc1918 = ISC_FALSE; + empty_zones_enable = ISC_FALSE; + } + if (empty_zones_enable) { + const char *empty; + int empty_zone = 0; + dns_fixedname_t fixed; + dns_name_t *name; + isc_buffer_t buffer; + const char *str; + char server[DNS_NAME_FORMATSIZE + 1]; + char contact[DNS_NAME_FORMATSIZE + 1]; + isc_boolean_t logit; + const char *empty_dbtype[4] = + { "_builtin", "empty", NULL, NULL }; + int empty_dbtypec = 4; + + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + + obj = NULL; + result = ns_config_get(maps, "empty-server", &obj); + if (result == ISC_R_SUCCESS) { + str = cfg_obj_asstring(obj); + isc_buffer_init(&buffer, str, strlen(str)); + isc_buffer_add(&buffer, strlen(str)); + CHECK(dns_name_fromtext(name, &buffer, dns_rootname, + ISC_FALSE, NULL)); + isc_buffer_init(&buffer, server, sizeof(server) - 1); + CHECK(dns_name_totext(name, ISC_FALSE, &buffer)); + server[isc_buffer_usedlength(&buffer)] = 0; + empty_dbtype[2] = server; + } else + empty_dbtype[2] = "@"; + + obj = NULL; + result = ns_config_get(maps, "empty-contact", &obj); + if (result == ISC_R_SUCCESS) { + str = cfg_obj_asstring(obj); + isc_buffer_init(&buffer, str, strlen(str)); + isc_buffer_add(&buffer, strlen(str)); + CHECK(dns_name_fromtext(name, &buffer, dns_rootname, + ISC_FALSE, NULL)); + isc_buffer_init(&buffer, contact, sizeof(contact) - 1); + CHECK(dns_name_totext(name, ISC_FALSE, &buffer)); + contact[isc_buffer_usedlength(&buffer)] = 0; + empty_dbtype[3] = contact; + } else + empty_dbtype[3] = "."; + + logit = ISC_TRUE; + for (empty = empty_zones[empty_zone].zone; + empty != NULL; + empty = empty_zones[++empty_zone].zone) + { + dns_forwarders_t *forwarders = NULL; + dns_view_t *pview = NULL; + + isc_buffer_init(&buffer, empty, strlen(empty)); + isc_buffer_add(&buffer, strlen(empty)); + /* + * Look for zone on drop list. + */ + CHECK(dns_name_fromtext(name, &buffer, dns_rootname, + ISC_FALSE, NULL)); + if (disablelist != NULL && + on_disable_list(disablelist, name)) + continue; + + /* + * This zone already exists. + */ + (void)dns_view_findzone(view, name, &zone); + if (zone != NULL) { + dns_zone_detach(&zone); + continue; + } + + /* + * If we would forward this name don't add a + * empty zone for it. + */ + result = dns_fwdtable_find(view->fwdtable, name, + &forwarders); + if (result == ISC_R_SUCCESS && + forwarders->fwdpolicy == dns_fwdpolicy_only) + continue; + + if (!rfc1918 && empty_zones[empty_zone].rfc1918) { + if (logit) { + isc_log_write(ns_g_lctx, + NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, + ISC_LOG_WARNING, + "Warning%s%s: " + "'empty-zones-enable/" + "disable-empty-zone' " + "not set: disabling " + "RFC 1918 empty zones", + sep, viewname); + logit = ISC_FALSE; + } + continue; + } + + /* + * See if we can re-use a existing zone. + */ + result = dns_viewlist_find(&ns_g_server->viewlist, + view->name, view->rdclass, + &pview); + if (result != ISC_R_NOTFOUND && + result != ISC_R_SUCCESS) + goto cleanup; + + if (pview != NULL) { + (void)dns_view_findzone(pview, name, &zone); + dns_view_detach(&pview); + if (zone != NULL) + check_dbtype(&zone, empty_dbtypec, + empty_dbtype, mctx); + if (zone != NULL) { + dns_zone_setview(zone, view); + CHECK(dns_view_addzone(view, zone)); + dns_zone_detach(&zone); + continue; + } + } + + CHECK(dns_zone_create(&zone, mctx)); + CHECK(dns_zone_setorigin(zone, name)); + dns_zone_setview(zone, view); + CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone)); + dns_zone_setclass(zone, view->rdclass); + dns_zone_settype(zone, dns_zone_master); + CHECK(dns_zone_setdbtype(zone, empty_dbtypec, + empty_dbtype)); + if (view->queryacl != NULL) + dns_zone_setqueryacl(zone, view->queryacl); + dns_zone_setdialup(zone, dns_dialuptype_no); + dns_zone_setnotifytype(zone, dns_notifytype_no); + dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, + ISC_TRUE); + CHECK(dns_view_addzone(view, zone)); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_INFO, + "automatic empty zone%s%s: %s", + sep, viewname, empty); + dns_zone_detach(&zone); + } + } + + result = ISC_R_SUCCESS; + + cleanup: + if (zone != NULL) + dns_zone_detach(&zone); + if (dispatch4 != NULL) + dns_dispatch_detach(&dispatch4); + if (dispatch6 != NULL) + dns_dispatch_detach(&dispatch6); + if (order != NULL) + dns_order_detach(&order); + if (cmctx != NULL) + isc_mem_detach(&cmctx); + + if (cache != NULL) + dns_cache_detach(&cache); + + return (result); +} + +static isc_result_t +configure_hints(dns_view_t *view, const char *filename) { + isc_result_t result; + dns_db_t *db; + + db = NULL; + result = dns_rootns_create(view->mctx, view->rdclass, filename, &db); + if (result == ISC_R_SUCCESS) { + dns_view_sethints(view, db); + dns_db_detach(&db); + } + + return (result); +} + +static isc_result_t +configure_alternates(const cfg_obj_t *config, dns_view_t *view, + const cfg_obj_t *alternates) +{ + const cfg_obj_t *portobj; + const cfg_obj_t *addresses; + const cfg_listelt_t *element; + isc_result_t result = ISC_R_SUCCESS; + in_port_t port; + + /* + * Determine which port to send requests to. + */ + if (ns_g_lwresdonly && ns_g_port != 0) + port = ns_g_port; + else + CHECKM(ns_config_getport(config, &port), "port"); + + if (alternates != NULL) { + portobj = cfg_tuple_get(alternates, "port"); + if (cfg_obj_isuint32(portobj)) { + isc_uint32_t val = cfg_obj_asuint32(portobj); + if (val > ISC_UINT16_MAX) { + cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, + "port '%u' out of range", val); + return (ISC_R_RANGE); + } + port = (in_port_t) val; + } + } + + addresses = NULL; + if (alternates != NULL) + addresses = cfg_tuple_get(alternates, "addresses"); + + for (element = cfg_list_first(addresses); + element != NULL; + element = cfg_list_next(element)) + { + const cfg_obj_t *alternate = cfg_listelt_value(element); + isc_sockaddr_t sa; + + if (!cfg_obj_issockaddr(alternate)) { + dns_fixedname_t fixed; + dns_name_t *name; + const char *str = cfg_obj_asstring(cfg_tuple_get( + alternate, "name")); + isc_buffer_t buffer; + in_port_t myport = port; + + isc_buffer_init(&buffer, str, strlen(str)); + isc_buffer_add(&buffer, strlen(str)); + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + CHECK(dns_name_fromtext(name, &buffer, dns_rootname, + ISC_FALSE, NULL)); + + portobj = cfg_tuple_get(alternate, "port"); + if (cfg_obj_isuint32(portobj)) { + isc_uint32_t val = cfg_obj_asuint32(portobj); + if (val > ISC_UINT16_MAX) { + cfg_obj_log(portobj, ns_g_lctx, + ISC_LOG_ERROR, + "port '%u' out of range", + val); + return (ISC_R_RANGE); + } + myport = (in_port_t) val; + } + CHECK(dns_resolver_addalternate(view->resolver, NULL, + name, myport)); + continue; + } + + sa = *cfg_obj_assockaddr(alternate); + if (isc_sockaddr_getport(&sa) == 0) + isc_sockaddr_setport(&sa, port); + CHECK(dns_resolver_addalternate(view->resolver, &sa, + NULL, 0)); + } + + cleanup: + return (result); +} + +static isc_result_t +configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin, + const cfg_obj_t *forwarders, const cfg_obj_t *forwardtype) +{ + const cfg_obj_t *portobj; + const cfg_obj_t *faddresses; + const cfg_listelt_t *element; + dns_fwdpolicy_t fwdpolicy = dns_fwdpolicy_none; + isc_sockaddrlist_t addresses; + isc_sockaddr_t *sa; + isc_result_t result; + in_port_t port; + + /* + * Determine which port to send forwarded requests to. + */ + if (ns_g_lwresdonly && ns_g_port != 0) + port = ns_g_port; + else + CHECKM(ns_config_getport(config, &port), "port"); + + if (forwarders != NULL) { + portobj = cfg_tuple_get(forwarders, "port"); + if (cfg_obj_isuint32(portobj)) { + isc_uint32_t val = cfg_obj_asuint32(portobj); + if (val > ISC_UINT16_MAX) { + cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, + "port '%u' out of range", val); + return (ISC_R_RANGE); + } + port = (in_port_t) val; + } + } + + faddresses = NULL; + if (forwarders != NULL) + faddresses = cfg_tuple_get(forwarders, "addresses"); + + ISC_LIST_INIT(addresses); + + for (element = cfg_list_first(faddresses); + element != NULL; + element = cfg_list_next(element)) + { + const cfg_obj_t *forwarder = cfg_listelt_value(element); + sa = isc_mem_get(view->mctx, sizeof(isc_sockaddr_t)); + if (sa == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + *sa = *cfg_obj_assockaddr(forwarder); + if (isc_sockaddr_getport(sa) == 0) + isc_sockaddr_setport(sa, port); + ISC_LINK_INIT(sa, link); + ISC_LIST_APPEND(addresses, sa, link); + } + + if (ISC_LIST_EMPTY(addresses)) { + if (forwardtype != NULL) + cfg_obj_log(forwarders, ns_g_lctx, ISC_LOG_WARNING, + "no forwarders seen; disabling " + "forwarding"); + fwdpolicy = dns_fwdpolicy_none; + } else { + if (forwardtype == NULL) + fwdpolicy = dns_fwdpolicy_first; + else { + const char *forwardstr = cfg_obj_asstring(forwardtype); + if (strcasecmp(forwardstr, "first") == 0) + fwdpolicy = dns_fwdpolicy_first; + else if (strcasecmp(forwardstr, "only") == 0) + fwdpolicy = dns_fwdpolicy_only; + else + INSIST(0); + } + } + + result = dns_fwdtable_add(view->fwdtable, origin, &addresses, + fwdpolicy); + if (result != ISC_R_SUCCESS) { + char namebuf[DNS_NAME_FORMATSIZE]; + dns_name_format(origin, namebuf, sizeof(namebuf)); + cfg_obj_log(forwarders, ns_g_lctx, ISC_LOG_WARNING, + "could not set up forwarding for domain '%s': %s", + namebuf, isc_result_totext(result)); + goto cleanup; + } + + result = ISC_R_SUCCESS; + + cleanup: + + while (!ISC_LIST_EMPTY(addresses)) { + sa = ISC_LIST_HEAD(addresses); + ISC_LIST_UNLINK(addresses, sa, link); + isc_mem_put(view->mctx, sa, sizeof(isc_sockaddr_t)); + } + + return (result); +} + +/* + * Create a new view and add it to the list. + * + * If 'vconfig' is NULL, create the default view. + * + * The view created is attached to '*viewp'. + */ +static isc_result_t +create_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist, + dns_view_t **viewp) +{ + isc_result_t result; + const char *viewname; + dns_rdataclass_t viewclass; + dns_view_t *view = NULL; + + if (vconfig != NULL) { + const cfg_obj_t *classobj = NULL; + + viewname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name")); + classobj = cfg_tuple_get(vconfig, "class"); + result = ns_config_getclass(classobj, dns_rdataclass_in, + &viewclass); + } else { + viewname = "_default"; + viewclass = dns_rdataclass_in; + } + result = dns_viewlist_find(viewlist, viewname, viewclass, &view); + if (result == ISC_R_SUCCESS) + return (ISC_R_EXISTS); + if (result != ISC_R_NOTFOUND) + return (result); + INSIST(view == NULL); + + result = dns_view_create(ns_g_mctx, viewclass, viewname, &view); + if (result != ISC_R_SUCCESS) + return (result); + + ISC_LIST_APPEND(*viewlist, view, link); + dns_view_attach(view, viewp); + return (ISC_R_SUCCESS); +} + +/* + * Configure or reconfigure a zone. + */ +static isc_result_t +configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig, + const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view, + cfg_aclconfctx_t *aclconf) +{ + dns_view_t *pview = NULL; /* Production view */ + dns_zone_t *zone = NULL; /* New or reused zone */ + dns_zone_t *dupzone = NULL; + const cfg_obj_t *options = NULL; + const cfg_obj_t *zoptions = NULL; + const cfg_obj_t *typeobj = NULL; + const cfg_obj_t *forwarders = NULL; + const cfg_obj_t *forwardtype = NULL; + const cfg_obj_t *only = NULL; + isc_result_t result; + isc_result_t tresult; + isc_buffer_t buffer; + dns_fixedname_t fixorigin; + dns_name_t *origin; + const char *zname; + dns_rdataclass_t zclass; + const char *ztypestr; + + options = NULL; + (void)cfg_map_get(config, "options", &options); + + zoptions = cfg_tuple_get(zconfig, "options"); + + /* + * Get the zone origin as a dns_name_t. + */ + zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); + isc_buffer_init(&buffer, zname, strlen(zname)); + isc_buffer_add(&buffer, strlen(zname)); + dns_fixedname_init(&fixorigin); + CHECK(dns_name_fromtext(dns_fixedname_name(&fixorigin), + &buffer, dns_rootname, ISC_FALSE, NULL)); + origin = dns_fixedname_name(&fixorigin); + + CHECK(ns_config_getclass(cfg_tuple_get(zconfig, "class"), + view->rdclass, &zclass)); + if (zclass != view->rdclass) { + const char *vname = NULL; + if (vconfig != NULL) + vname = cfg_obj_asstring(cfg_tuple_get(vconfig, + "name")); + else + vname = ""; + + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "zone '%s': wrong class for view '%s'", + zname, vname); + result = ISC_R_FAILURE; + goto cleanup; + } + + (void)cfg_map_get(zoptions, "type", &typeobj); + if (typeobj == NULL) { + cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, + "zone '%s' 'type' not specified", zname); + return (ISC_R_FAILURE); + } + ztypestr = cfg_obj_asstring(typeobj); + + /* + * "hints zones" aren't zones. If we've got one, + * configure it and return. + */ + if (strcasecmp(ztypestr, "hint") == 0) { + const cfg_obj_t *fileobj = NULL; + if (cfg_map_get(zoptions, "file", &fileobj) != ISC_R_SUCCESS) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "zone '%s': 'file' not specified", + zname); + result = ISC_R_FAILURE; + goto cleanup; + } + if (dns_name_equal(origin, dns_rootname)) { + const char *hintsfile = cfg_obj_asstring(fileobj); + + result = configure_hints(view, hintsfile); + if (result != ISC_R_SUCCESS) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, + ISC_LOG_ERROR, + "could not configure root hints " + "from '%s': %s", hintsfile, + isc_result_totext(result)); + goto cleanup; + } + /* + * Hint zones may also refer to delegation only points. + */ + only = NULL; + tresult = cfg_map_get(zoptions, "delegation-only", + &only); + if (tresult == ISC_R_SUCCESS && cfg_obj_asboolean(only)) + CHECK(dns_view_adddelegationonly(view, origin)); + } else { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_WARNING, + "ignoring non-root hint zone '%s'", + zname); + result = ISC_R_SUCCESS; + } + /* Skip ordinary zone processing. */ + goto cleanup; + } + + /* + * "forward zones" aren't zones either. Translate this syntax into + * the appropriate selective forwarding configuration and return. + */ + if (strcasecmp(ztypestr, "forward") == 0) { + forwardtype = NULL; + forwarders = NULL; + + (void)cfg_map_get(zoptions, "forward", &forwardtype); + (void)cfg_map_get(zoptions, "forwarders", &forwarders); + result = configure_forward(config, view, origin, forwarders, + forwardtype); + goto cleanup; + } + + /* + * "delegation-only zones" aren't zones either. + */ + if (strcasecmp(ztypestr, "delegation-only") == 0) { + result = dns_view_adddelegationonly(view, origin); + goto cleanup; + } + + /* + * Check for duplicates in the new zone table. + */ + result = dns_view_findzone(view, origin, &dupzone); + if (result == ISC_R_SUCCESS) { + /* + * We already have this zone! + */ + cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, + "zone '%s' already exists", zname); + dns_zone_detach(&dupzone); + result = ISC_R_EXISTS; + goto cleanup; + } + INSIST(dupzone == NULL); + + /* + * See if we can reuse an existing zone. This is + * only possible if all of these are true: + * - The zone's view exists + * - A zone with the right name exists in the view + * - The zone is compatible with the config + * options (e.g., an existing master zone cannot + * be reused if the options specify a slave zone) + */ + result = dns_viewlist_find(&ns_g_server->viewlist, + view->name, view->rdclass, + &pview); + if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) + goto cleanup; + if (pview != NULL) + result = dns_view_findzone(pview, origin, &zone); + if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) + goto cleanup; + if (zone != NULL && !ns_zone_reusable(zone, zconfig)) + dns_zone_detach(&zone); + + if (zone != NULL) { + /* + * We found a reusable zone. Make it use the + * new view. + */ + dns_zone_setview(zone, view); + if (view->acache != NULL) + dns_zone_setacache(zone, view->acache); + } else { + /* + * We cannot reuse an existing zone, we have + * to create a new one. + */ + CHECK(dns_zone_create(&zone, mctx)); + CHECK(dns_zone_setorigin(zone, origin)); + dns_zone_setview(zone, view); + if (view->acache != NULL) + dns_zone_setacache(zone, view->acache); + CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone)); + } + + /* + * If the zone contains a 'forwarders' statement, configure + * selective forwarding. + */ + forwarders = NULL; + if (cfg_map_get(zoptions, "forwarders", &forwarders) == ISC_R_SUCCESS) + { + forwardtype = NULL; + (void)cfg_map_get(zoptions, "forward", &forwardtype); + CHECK(configure_forward(config, view, origin, forwarders, + forwardtype)); + } + + /* + * Stub and forward zones may also refer to delegation only points. + */ + only = NULL; + if (cfg_map_get(zoptions, "delegation-only", &only) == ISC_R_SUCCESS) + { + if (cfg_obj_asboolean(only)) + CHECK(dns_view_adddelegationonly(view, origin)); + } + + /* + * Configure the zone. + */ + CHECK(ns_zone_configure(config, vconfig, zconfig, aclconf, zone)); + + /* + * Add the zone to its view in the new view list. + */ + CHECK(dns_view_addzone(view, zone)); + + cleanup: + if (zone != NULL) + dns_zone_detach(&zone); + if (pview != NULL) + dns_view_detach(&pview); + + return (result); +} + +/* + * Configure a single server quota. + */ +static void +configure_server_quota(const cfg_obj_t **maps, const char *name, + isc_quota_t *quota) +{ + const cfg_obj_t *obj = NULL; + isc_result_t result; + + result = ns_config_get(maps, name, &obj); + INSIST(result == ISC_R_SUCCESS); + isc_quota_max(quota, cfg_obj_asuint32(obj)); +} + +/* + * This function is called as soon as the 'directory' statement has been + * parsed. This can be extended to support other options if necessary. + */ +static isc_result_t +directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) { + isc_result_t result; + const char *directory; + + REQUIRE(strcasecmp("directory", clausename) == 0); + + UNUSED(arg); + UNUSED(clausename); + + /* + * Change directory. + */ + directory = cfg_obj_asstring(obj); + + if (! isc_file_ischdiridempotent(directory)) + cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, + "option 'directory' contains relative path '%s'", + directory); + + result = isc_dir_chdir(directory); + if (result != ISC_R_SUCCESS) { + cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, + "change directory to '%s' failed: %s", + directory, isc_result_totext(result)); + return (result); + } + + return (ISC_R_SUCCESS); +} + +static void +scan_interfaces(ns_server_t *server, isc_boolean_t verbose) { + isc_boolean_t match_mapped = server->aclenv.match_mapped; + + ns_interfacemgr_scan(server->interfacemgr, verbose); + /* + * Update the "localhost" and "localnets" ACLs to match the + * current set of network interfaces. + */ + dns_aclenv_copy(&server->aclenv, + ns_interfacemgr_getaclenv(server->interfacemgr)); + + server->aclenv.match_mapped = match_mapped; +} + +static isc_result_t +add_listenelt(isc_mem_t *mctx, ns_listenlist_t *list, isc_sockaddr_t *addr) { + ns_listenelt_t *lelt = NULL; + dns_acl_t *src_acl = NULL; + dns_aclelement_t aelt; + isc_result_t result; + isc_sockaddr_t any_sa6; + + REQUIRE(isc_sockaddr_pf(addr) == AF_INET6); + + isc_sockaddr_any6(&any_sa6); + if (!isc_sockaddr_equal(&any_sa6, addr)) { + aelt.type = dns_aclelementtype_ipprefix; + aelt.negative = ISC_FALSE; + aelt.u.ip_prefix.prefixlen = 128; + isc_netaddr_fromin6(&aelt.u.ip_prefix.address, + &addr->type.sin6.sin6_addr); + + result = dns_acl_create(mctx, 1, &src_acl); + if (result != ISC_R_SUCCESS) + return (result); + result = dns_acl_appendelement(src_acl, &aelt); + if (result != ISC_R_SUCCESS) + goto clean; + + result = ns_listenelt_create(mctx, isc_sockaddr_getport(addr), + src_acl, &lelt); + if (result != ISC_R_SUCCESS) + goto clean; + ISC_LIST_APPEND(list->elts, lelt, link); + } + + return (ISC_R_SUCCESS); + + clean: + INSIST(lelt == NULL); + dns_acl_detach(&src_acl); + + return (result); +} + +/* + * Make a list of xxx-source addresses and call ns_interfacemgr_adjust() + * to update the listening interfaces accordingly. + * We currently only consider IPv6, because this only affects IPv6 wildcard + * sockets. + */ +static void +adjust_interfaces(ns_server_t *server, isc_mem_t *mctx) { + isc_result_t result; + ns_listenlist_t *list = NULL; + dns_view_t *view; + dns_zone_t *zone, *next; + isc_sockaddr_t addr, *addrp; + + result = ns_listenlist_create(mctx, &list); + if (result != ISC_R_SUCCESS) + return; + + for (view = ISC_LIST_HEAD(server->viewlist); + view != NULL; + view = ISC_LIST_NEXT(view, link)) { + dns_dispatch_t *dispatch6; + + dispatch6 = dns_resolver_dispatchv6(view->resolver); + if (dispatch6 == NULL) + continue; + result = dns_dispatch_getlocaladdress(dispatch6, &addr); + if (result != ISC_R_SUCCESS) + goto fail; + result = add_listenelt(mctx, list, &addr); + if (result != ISC_R_SUCCESS) + goto fail; + } + + zone = NULL; + for (result = dns_zone_first(server->zonemgr, &zone); + result == ISC_R_SUCCESS; + next = NULL, result = dns_zone_next(zone, &next), zone = next) { + dns_view_t *zoneview; + + /* + * At this point the zone list may contain a stale zone + * just removed from the configuration. To see the validity, + * check if the corresponding view is in our current view list. + * There may also be old zones that are still in the process + * of shutting down and have detached from their old view + * (zoneview == NULL). + */ + zoneview = dns_zone_getview(zone); + if (zoneview == NULL) + continue; + for (view = ISC_LIST_HEAD(server->viewlist); + view != NULL && view != zoneview; + view = ISC_LIST_NEXT(view, link)) + ; + if (view == NULL) + continue; + + addrp = dns_zone_getnotifysrc6(zone); + result = add_listenelt(mctx, list, addrp); + if (result != ISC_R_SUCCESS) + goto fail; + + addrp = dns_zone_getxfrsource6(zone); + result = add_listenelt(mctx, list, addrp); + if (result != ISC_R_SUCCESS) + goto fail; + } + + ns_interfacemgr_adjust(server->interfacemgr, list, ISC_TRUE); + + clean: + ns_listenlist_detach(&list); + return; + + fail: + /* + * Even when we failed the procedure, most of other interfaces + * should work correctly. We therefore just warn it. + */ + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_WARNING, + "could not adjust the listen-on list; " + "some interfaces may not work"); + goto clean; +} + +/* + * This event callback is invoked to do periodic network + * interface scanning. + */ +static void +interface_timer_tick(isc_task_t *task, isc_event_t *event) { + isc_result_t result; + ns_server_t *server = (ns_server_t *) event->ev_arg; + INSIST(task == server->task); + UNUSED(task); + isc_event_free(&event); + /* + * XXX should scan interfaces unlocked and get exclusive access + * only to replace ACLs. + */ + result = isc_task_beginexclusive(server->task); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + scan_interfaces(server, ISC_FALSE); + isc_task_endexclusive(server->task); +} + +static void +heartbeat_timer_tick(isc_task_t *task, isc_event_t *event) { + ns_server_t *server = (ns_server_t *) event->ev_arg; + dns_view_t *view; + + UNUSED(task); + isc_event_free(&event); + view = ISC_LIST_HEAD(server->viewlist); + while (view != NULL) { + dns_view_dialup(view); + view = ISC_LIST_NEXT(view, link); + } +} + +static void +pps_timer_tick(isc_task_t *task, isc_event_t *event) { + static unsigned int oldrequests = 0; + unsigned int requests = ns_client_requests; + + UNUSED(task); + isc_event_free(&event); + + /* + * Don't worry about wrapping as the overflow result will be right. + */ + dns_pps = (requests - oldrequests) / 1200; + oldrequests = requests; +} + +/* + * Replace the current value of '*field', a dynamically allocated + * string or NULL, with a dynamically allocated copy of the + * null-terminated string pointed to by 'value', or NULL. + */ +static isc_result_t +setstring(ns_server_t *server, char **field, const char *value) { + char *copy; + + if (value != NULL) { + copy = isc_mem_strdup(server->mctx, value); + if (copy == NULL) + return (ISC_R_NOMEMORY); + } else { + copy = NULL; + } + + if (*field != NULL) + isc_mem_free(server->mctx, *field); + + *field = copy; + return (ISC_R_SUCCESS); +} + +/* + * Replace the current value of '*field', a dynamically allocated + * string or NULL, with another dynamically allocated string + * or NULL if whether 'obj' is a string or void value, respectively. + */ +static isc_result_t +setoptstring(ns_server_t *server, char **field, const cfg_obj_t *obj) { + if (cfg_obj_isvoid(obj)) + return (setstring(server, field, NULL)); + else + return (setstring(server, field, cfg_obj_asstring(obj))); +} + +static void +set_limit(const cfg_obj_t **maps, const char *configname, + const char *description, isc_resource_t resourceid, + isc_resourcevalue_t defaultvalue) +{ + const cfg_obj_t *obj = NULL; + const char *resource; + isc_resourcevalue_t value; + isc_result_t result; + + if (ns_config_get(maps, configname, &obj) != ISC_R_SUCCESS) + return; + + if (cfg_obj_isstring(obj)) { + resource = cfg_obj_asstring(obj); + if (strcasecmp(resource, "unlimited") == 0) + value = ISC_RESOURCE_UNLIMITED; + else { + INSIST(strcasecmp(resource, "default") == 0); + value = defaultvalue; + } + } else + value = cfg_obj_asuint64(obj); + + result = isc_resource_setlimit(resourceid, value); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + result == ISC_R_SUCCESS ? + ISC_LOG_DEBUG(3) : ISC_LOG_WARNING, + "set maximum %s to %" ISC_PRINT_QUADFORMAT "d: %s", + description, value, isc_result_totext(result)); +} + +#define SETLIMIT(cfgvar, resource, description) \ + set_limit(maps, cfgvar, description, isc_resource_ ## resource, \ + ns_g_init ## resource) + +static void +set_limits(const cfg_obj_t **maps) { + SETLIMIT("stacksize", stacksize, "stack size"); + SETLIMIT("datasize", datasize, "data size"); + SETLIMIT("coresize", coresize, "core size"); + SETLIMIT("files", openfiles, "open files"); +} + +static isc_result_t +portlist_fromconf(dns_portlist_t *portlist, unsigned int family, + const cfg_obj_t *ports) +{ + const cfg_listelt_t *element; + isc_result_t result = ISC_R_SUCCESS; + + for (element = cfg_list_first(ports); + element != NULL; + element = cfg_list_next(element)) { + const cfg_obj_t *obj = cfg_listelt_value(element); + in_port_t port = (in_port_t)cfg_obj_asuint32(obj); + + result = dns_portlist_add(portlist, family, port); + if (result != ISC_R_SUCCESS) + break; + } + return (result); +} + +static isc_result_t +removed(dns_zone_t *zone, void *uap) { + const char *type; + + if (dns_zone_getview(zone) != uap) + return (ISC_R_SUCCESS); + + switch (dns_zone_gettype(zone)) { + case dns_zone_master: + type = "master"; + break; + case dns_zone_slave: + type = "slave"; + break; + case dns_zone_stub: + type = "stub"; + break; + default: + type = "other"; + break; + } + dns_zone_log(zone, ISC_LOG_INFO, "(%s) removed", type); + return (ISC_R_SUCCESS); +} + +static isc_result_t +load_configuration(const char *filename, ns_server_t *server, + isc_boolean_t first_time) +{ + isc_result_t result; + isc_interval_t interval; + cfg_parser_t *parser = NULL; + cfg_obj_t *config; + const cfg_obj_t *options; + const cfg_obj_t *views; + const cfg_obj_t *obj; + const cfg_obj_t *v4ports, *v6ports; + const cfg_obj_t *maps[3]; + const cfg_obj_t *builtin_views; + const cfg_listelt_t *element; + dns_view_t *view = NULL; + dns_view_t *view_next; + dns_viewlist_t viewlist; + dns_viewlist_t tmpviewlist; + cfg_aclconfctx_t aclconfctx; + isc_uint32_t interface_interval; + isc_uint32_t heartbeat_interval; + isc_uint32_t udpsize; + in_port_t listen_port; + int i; + + cfg_aclconfctx_init(&aclconfctx); + ISC_LIST_INIT(viewlist); + + /* Ensure exclusive access to configuration data. */ + result = isc_task_beginexclusive(server->task); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + /* + * Parse the global default pseudo-config file. + */ + if (first_time) { + CHECK(ns_config_parsedefaults(ns_g_parser, &ns_g_config)); + RUNTIME_CHECK(cfg_map_get(ns_g_config, "options", + &ns_g_defaults) == + ISC_R_SUCCESS); + } + + /* + * Parse the configuration file using the new config code. + */ + result = ISC_R_FAILURE; + config = NULL; + + /* + * Unless this is lwresd with the -C option, parse the config file. + */ + if (!(ns_g_lwresdonly && lwresd_g_useresolvconf)) { + isc_log_write(ns_g_lctx, + NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_INFO, "loading configuration from '%s'", + filename); + CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &parser)); + cfg_parser_setcallback(parser, directory_callback, NULL); + result = cfg_parse_file(parser, filename, &cfg_type_namedconf, + &config); + } + + /* + * If this is lwresd with the -C option, or lwresd with no -C or -c + * option where the above parsing failed, parse resolv.conf. + */ + if (ns_g_lwresdonly && + (lwresd_g_useresolvconf || + (!ns_g_conffileset && result == ISC_R_FILENOTFOUND))) + { + isc_log_write(ns_g_lctx, + NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_INFO, "loading configuration from '%s'", + lwresd_g_resolvconffile); + if (parser != NULL) + cfg_parser_destroy(&parser); + CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &parser)); + result = ns_lwresd_parseeresolvconf(ns_g_mctx, parser, + &config); + } + CHECK(result); + + /* + * Check the validity of the configuration. + */ + CHECK(bind9_check_namedconf(config, ns_g_lctx, ns_g_mctx)); + + /* + * Fill in the maps array, used for resolving defaults. + */ + i = 0; + options = NULL; + result = cfg_map_get(config, "options", &options); + if (result == ISC_R_SUCCESS) + maps[i++] = options; + maps[i++] = ns_g_defaults; + maps[i++] = NULL; + + /* + * Set process limits, which (usually) needs to be done as root. + */ + set_limits(maps); + + /* + * Configure various server options. + */ + configure_server_quota(maps, "transfers-out", &server->xfroutquota); + configure_server_quota(maps, "tcp-clients", &server->tcpquota); + configure_server_quota(maps, "recursive-clients", + &server->recursionquota); + if (server->recursionquota.max > 1000) + isc_quota_soft(&server->recursionquota, + server->recursionquota.max - 100); + else + isc_quota_soft(&server->recursionquota, 0); + + CHECK(configure_view_acl(NULL, config, "blackhole", &aclconfctx, + ns_g_mctx, &server->blackholeacl)); + if (server->blackholeacl != NULL) + dns_dispatchmgr_setblackhole(ns_g_dispatchmgr, + server->blackholeacl); + + obj = NULL; + result = ns_config_get(maps, "match-mapped-addresses", &obj); + INSIST(result == ISC_R_SUCCESS); + server->aclenv.match_mapped = cfg_obj_asboolean(obj); + + v4ports = NULL; + v6ports = NULL; + (void)ns_config_get(maps, "avoid-v4-udp-ports", &v4ports); + (void)ns_config_get(maps, "avoid-v6-udp-ports", &v6ports); + if (v4ports != NULL || v6ports != NULL) { + dns_portlist_t *portlist = NULL; + result = dns_portlist_create(ns_g_mctx, &portlist); + if (result == ISC_R_SUCCESS && v4ports != NULL) + result = portlist_fromconf(portlist, AF_INET, v4ports); + if (result == ISC_R_SUCCESS && v6ports != NULL) + portlist_fromconf(portlist, AF_INET6, v6ports); + if (result == ISC_R_SUCCESS) + dns_dispatchmgr_setblackportlist(ns_g_dispatchmgr, portlist); + if (portlist != NULL) + dns_portlist_detach(&portlist); + CHECK(result); + } else + dns_dispatchmgr_setblackportlist(ns_g_dispatchmgr, NULL); + + /* + * Set the EDNS UDP size when we don't match a view. + */ + obj = NULL; + result = ns_config_get(maps, "edns-udp-size", &obj); + INSIST(result == ISC_R_SUCCESS); + udpsize = cfg_obj_asuint32(obj); + if (udpsize < 512) + udpsize = 512; + if (udpsize > 4096) + udpsize = 4096; + ns_g_udpsize = (isc_uint16_t)udpsize; + + /* + * Configure the zone manager. + */ + obj = NULL; + result = ns_config_get(maps, "transfers-in", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zonemgr_settransfersin(server->zonemgr, cfg_obj_asuint32(obj)); + + obj = NULL; + result = ns_config_get(maps, "transfers-per-ns", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zonemgr_settransfersperns(server->zonemgr, cfg_obj_asuint32(obj)); + + obj = NULL; + result = ns_config_get(maps, "serial-query-rate", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zonemgr_setserialqueryrate(server->zonemgr, cfg_obj_asuint32(obj)); + + /* + * Determine which port to use for listening for incoming connections. + */ + if (ns_g_port != 0) + listen_port = ns_g_port; + else + CHECKM(ns_config_getport(config, &listen_port), "port"); + + /* + * Find the listen queue depth. + */ + obj = NULL; + result = ns_config_get(maps, "tcp-listen-queue", &obj); + INSIST(result == ISC_R_SUCCESS); + ns_g_listen = cfg_obj_asuint32(obj); + if (ns_g_listen < 3) + ns_g_listen = 3; + + /* + * Configure the interface manager according to the "listen-on" + * statement. + */ + { + const cfg_obj_t *clistenon = NULL; + ns_listenlist_t *listenon = NULL; + + clistenon = NULL; + /* + * Even though listen-on is present in the default + * configuration, we can't use it here, since it isn't + * used if we're in lwresd mode. This way is easier. + */ + if (options != NULL) + (void)cfg_map_get(options, "listen-on", &clistenon); + if (clistenon != NULL) { + result = ns_listenlist_fromconfig(clistenon, + config, + &aclconfctx, + ns_g_mctx, + &listenon); + } else if (!ns_g_lwresdonly) { + /* + * Not specified, use default. + */ + CHECK(ns_listenlist_default(ns_g_mctx, listen_port, + ISC_TRUE, &listenon)); + } + if (listenon != NULL) { + ns_interfacemgr_setlistenon4(server->interfacemgr, + listenon); + ns_listenlist_detach(&listenon); + } + } + /* + * Ditto for IPv6. + */ + { + const cfg_obj_t *clistenon = NULL; + ns_listenlist_t *listenon = NULL; + + if (options != NULL) + (void)cfg_map_get(options, "listen-on-v6", &clistenon); + if (clistenon != NULL) { + result = ns_listenlist_fromconfig(clistenon, + config, + &aclconfctx, + ns_g_mctx, + &listenon); + } else if (!ns_g_lwresdonly) { + /* + * Not specified, use default. + */ + CHECK(ns_listenlist_default(ns_g_mctx, listen_port, + ISC_FALSE, &listenon)); + } + if (listenon != NULL) { + ns_interfacemgr_setlistenon6(server->interfacemgr, + listenon); + ns_listenlist_detach(&listenon); + } + } + + /* + * Rescan the interface list to pick up changes in the + * listen-on option. It's important that we do this before we try + * to configure the query source, since the dispatcher we use might + * be shared with an interface. + */ + scan_interfaces(server, ISC_TRUE); + + /* + * Arrange for further interface scanning to occur periodically + * as specified by the "interface-interval" option. + */ + obj = NULL; + result = ns_config_get(maps, "interface-interval", &obj); + INSIST(result == ISC_R_SUCCESS); + interface_interval = cfg_obj_asuint32(obj) * 60; + if (interface_interval == 0) { + CHECK(isc_timer_reset(server->interface_timer, + isc_timertype_inactive, + NULL, NULL, ISC_TRUE)); + } else if (server->interface_interval != interface_interval) { + isc_interval_set(&interval, interface_interval, 0); + CHECK(isc_timer_reset(server->interface_timer, + isc_timertype_ticker, + NULL, &interval, ISC_FALSE)); + } + server->interface_interval = interface_interval; + + /* + * Configure the dialup heartbeat timer. + */ + obj = NULL; + result = ns_config_get(maps, "heartbeat-interval", &obj); + INSIST(result == ISC_R_SUCCESS); + heartbeat_interval = cfg_obj_asuint32(obj) * 60; + if (heartbeat_interval == 0) { + CHECK(isc_timer_reset(server->heartbeat_timer, + isc_timertype_inactive, + NULL, NULL, ISC_TRUE)); + } else if (server->heartbeat_interval != heartbeat_interval) { + isc_interval_set(&interval, heartbeat_interval, 0); + CHECK(isc_timer_reset(server->heartbeat_timer, + isc_timertype_ticker, + NULL, &interval, ISC_FALSE)); + } + server->heartbeat_interval = heartbeat_interval; + + isc_interval_set(&interval, 1200, 0); + CHECK(isc_timer_reset(server->pps_timer, isc_timertype_ticker, NULL, + &interval, ISC_FALSE)); + + /* + * Configure and freeze all explicit views. Explicit + * views that have zones were already created at parsing + * time, but views with no zones must be created here. + */ + views = NULL; + (void)cfg_map_get(config, "view", &views); + for (element = cfg_list_first(views); + element != NULL; + element = cfg_list_next(element)) + { + const cfg_obj_t *vconfig = cfg_listelt_value(element); + view = NULL; + + CHECK(create_view(vconfig, &viewlist, &view)); + INSIST(view != NULL); + CHECK(configure_view(view, config, vconfig, + ns_g_mctx, &aclconfctx, ISC_TRUE)); + dns_view_freeze(view); + dns_view_detach(&view); + } + + /* + * Make sure we have a default view if and only if there + * were no explicit views. + */ + if (views == NULL) { + /* + * No explicit views; there ought to be a default view. + * There may already be one created as a side effect + * of zone statements, or we may have to create one. + * In either case, we need to configure and freeze it. + */ + CHECK(create_view(NULL, &viewlist, &view)); + CHECK(configure_view(view, config, NULL, ns_g_mctx, + &aclconfctx, ISC_TRUE)); + dns_view_freeze(view); + dns_view_detach(&view); + } + + /* + * Create (or recreate) the built-in views. Currently + * there is only one, the _bind view. + */ + builtin_views = NULL; + RUNTIME_CHECK(cfg_map_get(ns_g_config, "view", + &builtin_views) == ISC_R_SUCCESS); + for (element = cfg_list_first(builtin_views); + element != NULL; + element = cfg_list_next(element)) + { + const cfg_obj_t *vconfig = cfg_listelt_value(element); + CHECK(create_view(vconfig, &viewlist, &view)); + CHECK(configure_view(view, config, vconfig, ns_g_mctx, + &aclconfctx, ISC_FALSE)); + dns_view_freeze(view); + dns_view_detach(&view); + view = NULL; + } + + /* + * Swap our new view list with the production one. + */ + tmpviewlist = server->viewlist; + server->viewlist = viewlist; + viewlist = tmpviewlist; + + /* + * Load the TKEY information from the configuration. + */ + if (options != NULL) { + dns_tkeyctx_t *t = NULL; + CHECKM(ns_tkeyctx_fromconfig(options, ns_g_mctx, ns_g_entropy, + &t), + "configuring TKEY"); + if (server->tkeyctx != NULL) + dns_tkeyctx_destroy(&server->tkeyctx); + server->tkeyctx = t; + } + + /* + * Bind the control port(s). + */ + CHECKM(ns_controls_configure(ns_g_server->controls, config, + &aclconfctx), + "binding control channel(s)"); + + /* + * Bind the lwresd port(s). + */ + CHECKM(ns_lwresd_configure(ns_g_mctx, config), + "binding lightweight resolver ports"); + + /* + * Open the source of entropy. + */ + if (first_time) { + obj = NULL; + result = ns_config_get(maps, "random-device", &obj); + if (result != ISC_R_SUCCESS) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_INFO, + "no source of entropy found"); + } else { + const char *randomdev = cfg_obj_asstring(obj); + result = isc_entropy_createfilesource(ns_g_entropy, + randomdev); + if (result != ISC_R_SUCCESS) + isc_log_write(ns_g_lctx, + NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, + ISC_LOG_INFO, + "could not open entropy source " + "%s: %s", + randomdev, + isc_result_totext(result)); +#ifdef PATH_RANDOMDEV + if (ns_g_fallbackentropy != NULL) { + if (result != ISC_R_SUCCESS) { + isc_log_write(ns_g_lctx, + NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, + ISC_LOG_INFO, + "using pre-chroot entropy source " + "%s", + PATH_RANDOMDEV); + isc_entropy_detach(&ns_g_entropy); + isc_entropy_attach(ns_g_fallbackentropy, + &ns_g_entropy); + } + isc_entropy_detach(&ns_g_fallbackentropy); + } +#endif + } + } + + /* + * Relinquish root privileges. + */ + if (first_time) + ns_os_changeuser(); + + /* + * Configure the logging system. + * + * Do this after changing UID to make sure that any log + * files specified in named.conf get created by the + * unprivileged user, not root. + */ + if (ns_g_logstderr) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_INFO, + "ignoring config file logging " + "statement due to -g option"); + } else { + const cfg_obj_t *logobj = NULL; + isc_logconfig_t *logc = NULL; + + CHECKM(isc_logconfig_create(ns_g_lctx, &logc), + "creating new logging configuration"); + + logobj = NULL; + (void)cfg_map_get(config, "logging", &logobj); + if (logobj != NULL) { + CHECKM(ns_log_configure(logc, logobj), + "configuring logging"); + } else { + CHECKM(ns_log_setdefaultchannels(logc), + "setting up default logging channels"); + CHECKM(ns_log_setunmatchedcategory(logc), + "setting up default 'category unmatched'"); + CHECKM(ns_log_setdefaultcategory(logc), + "setting up default 'category default'"); + } + + result = isc_logconfig_use(ns_g_lctx, logc); + if (result != ISC_R_SUCCESS) { + isc_logconfig_destroy(&logc); + CHECKM(result, "installing logging configuration"); + } + + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1), + "now using logging configuration from " + "config file"); + } + + /* + * Set the default value of the query logging flag depending + * whether a "queries" category has been defined. This is + * a disgusting hack, but we need to do this for BIND 8 + * compatibility. + */ + if (first_time) { + const cfg_obj_t *logobj = NULL; + const cfg_obj_t *categories = NULL; + + obj = NULL; + if (ns_config_get(maps, "querylog", &obj) == ISC_R_SUCCESS) { + server->log_queries = cfg_obj_asboolean(obj); + } else { + + (void)cfg_map_get(config, "logging", &logobj); + if (logobj != NULL) + (void)cfg_map_get(logobj, "category", + &categories); + if (categories != NULL) { + const cfg_listelt_t *element; + for (element = cfg_list_first(categories); + element != NULL; + element = cfg_list_next(element)) + { + const cfg_obj_t *catobj; + const char *str; + + obj = cfg_listelt_value(element); + catobj = cfg_tuple_get(obj, "name"); + str = cfg_obj_asstring(catobj); + if (strcasecmp(str, "queries") == 0) + server->log_queries = ISC_TRUE; + } + } + } + } + + obj = NULL; + if (ns_config_get(maps, "pid-file", &obj) == ISC_R_SUCCESS) + if (cfg_obj_isvoid(obj)) + ns_os_writepidfile(NULL, first_time); + else + ns_os_writepidfile(cfg_obj_asstring(obj), first_time); + else if (ns_g_lwresdonly) + ns_os_writepidfile(lwresd_g_defaultpidfile, first_time); + else + ns_os_writepidfile(ns_g_defaultpidfile, first_time); + + obj = NULL; + if (options != NULL && + cfg_map_get(options, "memstatistics-file", &obj) == ISC_R_SUCCESS) + ns_main_setmemstats(cfg_obj_asstring(obj)); + else + ns_main_setmemstats(NULL); + + obj = NULL; + result = ns_config_get(maps, "statistics-file", &obj); + INSIST(result == ISC_R_SUCCESS); + CHECKM(setstring(server, &server->statsfile, cfg_obj_asstring(obj)), + "strdup"); + + obj = NULL; + result = ns_config_get(maps, "dump-file", &obj); + INSIST(result == ISC_R_SUCCESS); + CHECKM(setstring(server, &server->dumpfile, cfg_obj_asstring(obj)), + "strdup"); + + obj = NULL; + result = ns_config_get(maps, "recursing-file", &obj); + INSIST(result == ISC_R_SUCCESS); + CHECKM(setstring(server, &server->recfile, cfg_obj_asstring(obj)), + "strdup"); + + obj = NULL; + result = ns_config_get(maps, "version", &obj); + if (result == ISC_R_SUCCESS) { + CHECKM(setoptstring(server, &server->version, obj), "strdup"); + server->version_set = ISC_TRUE; + } else { + server->version_set = ISC_FALSE; + } + + obj = NULL; + result = ns_config_get(maps, "hostname", &obj); + if (result == ISC_R_SUCCESS) { + CHECKM(setoptstring(server, &server->hostname, obj), "strdup"); + server->hostname_set = ISC_TRUE; + } else { + server->hostname_set = ISC_FALSE; + } + + obj = NULL; + result = ns_config_get(maps, "server-id", &obj); + server->server_usehostname = ISC_FALSE; + if (result == ISC_R_SUCCESS && cfg_obj_isboolean(obj)) { + server->server_usehostname = ISC_TRUE; + } else if (result == ISC_R_SUCCESS) { + CHECKM(setoptstring(server, &server->server_id, obj), "strdup"); + } else { + result = setstring(server, &server->server_id, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + } + + obj = NULL; + result = ns_config_get(maps, "flush-zones-on-shutdown", &obj); + if (result == ISC_R_SUCCESS) { + server->flushonshutdown = cfg_obj_asboolean(obj); + } else { + server->flushonshutdown = ISC_FALSE; + } + + result = ISC_R_SUCCESS; + + cleanup: + cfg_aclconfctx_destroy(&aclconfctx); + + if (parser != NULL) { + if (config != NULL) + cfg_obj_destroy(parser, &config); + cfg_parser_destroy(&parser); + } + + if (view != NULL) + dns_view_detach(&view); + + /* + * This cleans up either the old production view list + * or our temporary list depending on whether they + * were swapped above or not. + */ + for (view = ISC_LIST_HEAD(viewlist); + view != NULL; + view = view_next) { + view_next = ISC_LIST_NEXT(view, link); + ISC_LIST_UNLINK(viewlist, view, link); + if (result == ISC_R_SUCCESS && + strcmp(view->name, "_bind") != 0) + (void)dns_zt_apply(view->zonetable, ISC_FALSE, + removed, view); + dns_view_detach(&view); + } + + /* + * Adjust the listening interfaces in accordance with the source + * addresses specified in views and zones. + */ + if (isc_net_probeipv6() == ISC_R_SUCCESS) + adjust_interfaces(server, ns_g_mctx); + + /* Relinquish exclusive access to configuration data. */ + isc_task_endexclusive(server->task); + + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_DEBUG(1), "load_configuration: %s", + isc_result_totext(result)); + + return (result); +} + +static isc_result_t +load_zones(ns_server_t *server, isc_boolean_t stop) { + isc_result_t result; + dns_view_t *view; + + result = isc_task_beginexclusive(server->task); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + /* + * Load zone data from disk. + */ + for (view = ISC_LIST_HEAD(server->viewlist); + view != NULL; + view = ISC_LIST_NEXT(view, link)) + { + CHECK(dns_view_load(view, stop)); + } + + /* + * Force zone maintenance. Do this after loading + * so that we know when we need to force AXFR of + * slave zones whose master files are missing. + */ + CHECK(dns_zonemgr_forcemaint(server->zonemgr)); + cleanup: + isc_task_endexclusive(server->task); + return (result); +} + +static isc_result_t +load_new_zones(ns_server_t *server, isc_boolean_t stop) { + isc_result_t result; + dns_view_t *view; + + result = isc_task_beginexclusive(server->task); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + /* + * Load zone data from disk. + */ + for (view = ISC_LIST_HEAD(server->viewlist); + view != NULL; + view = ISC_LIST_NEXT(view, link)) + { + CHECK(dns_view_loadnew(view, stop)); + } + /* + * Force zone maintenance. Do this after loading + * so that we know when we need to force AXFR of + * slave zones whose master files are missing. + */ + dns_zonemgr_resumexfrs(server->zonemgr); + cleanup: + isc_task_endexclusive(server->task); + return (result); +} + +static void +run_server(isc_task_t *task, isc_event_t *event) { + isc_result_t result; + ns_server_t *server = (ns_server_t *)event->ev_arg; + + INSIST(task == server->task); + + isc_event_free(&event); + + CHECKFATAL(dns_dispatchmgr_create(ns_g_mctx, ns_g_entropy, + &ns_g_dispatchmgr), + "creating dispatch manager"); + + CHECKFATAL(ns_interfacemgr_create(ns_g_mctx, ns_g_taskmgr, + ns_g_socketmgr, ns_g_dispatchmgr, + &server->interfacemgr), + "creating interface manager"); + + CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive, + NULL, NULL, server->task, + interface_timer_tick, + server, &server->interface_timer), + "creating interface timer"); + + CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive, + NULL, NULL, server->task, + heartbeat_timer_tick, + server, &server->heartbeat_timer), + "creating heartbeat timer"); + + CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive, + NULL, NULL, server->task, pps_timer_tick, + server, &server->pps_timer), + "creating pps timer"); + + CHECKFATAL(cfg_parser_create(ns_g_mctx, NULL, &ns_g_parser), + "creating default configuration parser"); + + if (ns_g_lwresdonly) + CHECKFATAL(load_configuration(lwresd_g_conffile, server, + ISC_TRUE), + "loading configuration"); + else + CHECKFATAL(load_configuration(ns_g_conffile, server, ISC_TRUE), + "loading configuration"); + + isc_hash_init(); + + CHECKFATAL(load_zones(server, ISC_FALSE), "loading zones"); + + ns_os_started(); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_NOTICE, "running"); +} + +void +ns_server_flushonshutdown(ns_server_t *server, isc_boolean_t flush) { + + REQUIRE(NS_SERVER_VALID(server)); + + server->flushonshutdown = flush; +} + +static void +shutdown_server(isc_task_t *task, isc_event_t *event) { + isc_result_t result; + dns_view_t *view, *view_next; + ns_server_t *server = (ns_server_t *)event->ev_arg; + isc_boolean_t flush = server->flushonshutdown; + + UNUSED(task); + INSIST(task == server->task); + + result = isc_task_beginexclusive(server->task); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_INFO, "shutting down%s", + flush ? ": flushing changes" : ""); + + ns_controls_shutdown(server->controls); + end_reserved_dispatches(server, ISC_TRUE); + + cfg_obj_destroy(ns_g_parser, &ns_g_config); + cfg_parser_destroy(&ns_g_parser); + + for (view = ISC_LIST_HEAD(server->viewlist); + view != NULL; + view = view_next) { + view_next = ISC_LIST_NEXT(view, link); + ISC_LIST_UNLINK(server->viewlist, view, link); + if (flush) + dns_view_flushanddetach(&view); + else + dns_view_detach(&view); + } + + isc_timer_detach(&server->interface_timer); + isc_timer_detach(&server->heartbeat_timer); + isc_timer_detach(&server->pps_timer); + + ns_interfacemgr_shutdown(server->interfacemgr); + ns_interfacemgr_detach(&server->interfacemgr); + + dns_dispatchmgr_destroy(&ns_g_dispatchmgr); + + dns_zonemgr_shutdown(server->zonemgr); + + if (server->blackholeacl != NULL) + dns_acl_detach(&server->blackholeacl); + + dns_db_detach(&server->in_roothints); + + isc_task_endexclusive(server->task); + + isc_task_detach(&server->task); + + isc_event_free(&event); +} + +void +ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) { + isc_result_t result; + + ns_server_t *server = isc_mem_get(mctx, sizeof(*server)); + if (server == NULL) + fatal("allocating server object", ISC_R_NOMEMORY); + + server->mctx = mctx; + server->task = NULL; + + /* Initialize configuration data with default values. */ + + result = isc_quota_init(&server->xfroutquota, 10); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + result = isc_quota_init(&server->tcpquota, 10); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + result = isc_quota_init(&server->recursionquota, 100); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + result = dns_aclenv_init(mctx, &server->aclenv); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + /* Initialize server data structures. */ + server->zonemgr = NULL; + server->interfacemgr = NULL; + ISC_LIST_INIT(server->viewlist); + server->in_roothints = NULL; + server->blackholeacl = NULL; + + CHECKFATAL(dns_rootns_create(mctx, dns_rdataclass_in, NULL, + &server->in_roothints), + "setting up root hints"); + + CHECKFATAL(isc_mutex_init(&server->reload_event_lock), + "initializing reload event lock"); + server->reload_event = + isc_event_allocate(ns_g_mctx, server, + NS_EVENT_RELOAD, + ns_server_reload, + server, + sizeof(isc_event_t)); + CHECKFATAL(server->reload_event == NULL ? + ISC_R_NOMEMORY : ISC_R_SUCCESS, + "allocating reload event"); + + CHECKFATAL(dst_lib_init(ns_g_mctx, ns_g_entropy, ISC_ENTROPY_GOODONLY), + "initializing DST"); + + server->tkeyctx = NULL; + CHECKFATAL(dns_tkeyctx_create(ns_g_mctx, ns_g_entropy, + &server->tkeyctx), + "creating TKEY context"); + + /* + * Setup the server task, which is responsible for coordinating + * startup and shutdown of the server. + */ + CHECKFATAL(isc_task_create(ns_g_taskmgr, 0, &server->task), + "creating server task"); + isc_task_setname(server->task, "server", server); + CHECKFATAL(isc_task_onshutdown(server->task, shutdown_server, server), + "isc_task_onshutdown"); + CHECKFATAL(isc_app_onrun(ns_g_mctx, server->task, run_server, server), + "isc_app_onrun"); + + server->interface_timer = NULL; + server->heartbeat_timer = NULL; + server->pps_timer = NULL; + + server->interface_interval = 0; + server->heartbeat_interval = 0; + + CHECKFATAL(dns_zonemgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr, + ns_g_socketmgr, &server->zonemgr), + "dns_zonemgr_create"); + + server->statsfile = isc_mem_strdup(server->mctx, "named.stats"); + CHECKFATAL(server->statsfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS, + "isc_mem_strdup"); + server->querystats = NULL; + + server->dumpfile = isc_mem_strdup(server->mctx, "named_dump.db"); + CHECKFATAL(server->dumpfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS, + "isc_mem_strdup"); + + server->recfile = isc_mem_strdup(server->mctx, "named.recursing"); + CHECKFATAL(server->recfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS, + "isc_mem_strdup"); + + server->hostname_set = ISC_FALSE; + server->hostname = NULL; + server->version_set = ISC_FALSE; + server->version = NULL; + server->server_usehostname = ISC_FALSE; + server->server_id = NULL; + + CHECKFATAL(dns_stats_alloccounters(ns_g_mctx, &server->querystats), + "dns_stats_alloccounters"); + + server->flushonshutdown = ISC_FALSE; + server->log_queries = ISC_FALSE; + + server->controls = NULL; + CHECKFATAL(ns_controls_create(server, &server->controls), + "ns_controls_create"); + server->dispatchgen = 0; + ISC_LIST_INIT(server->dispatches); + + server->magic = NS_SERVER_MAGIC; + *serverp = server; +} + +void +ns_server_destroy(ns_server_t **serverp) { + ns_server_t *server = *serverp; + REQUIRE(NS_SERVER_VALID(server)); + + ns_controls_destroy(&server->controls); + + dns_stats_freecounters(server->mctx, &server->querystats); + + isc_mem_free(server->mctx, server->statsfile); + isc_mem_free(server->mctx, server->dumpfile); + isc_mem_free(server->mctx, server->recfile); + + if (server->version != NULL) + isc_mem_free(server->mctx, server->version); + if (server->hostname != NULL) + isc_mem_free(server->mctx, server->hostname); + if (server->server_id != NULL) + isc_mem_free(server->mctx, server->server_id); + + dns_zonemgr_detach(&server->zonemgr); + + if (server->tkeyctx != NULL) + dns_tkeyctx_destroy(&server->tkeyctx); + + dst_lib_destroy(); + + isc_event_free(&server->reload_event); + + INSIST(ISC_LIST_EMPTY(server->viewlist)); + + dns_aclenv_destroy(&server->aclenv); + + isc_quota_destroy(&server->recursionquota); + isc_quota_destroy(&server->tcpquota); + isc_quota_destroy(&server->xfroutquota); + + server->magic = 0; + isc_mem_put(server->mctx, server, sizeof(*server)); + *serverp = NULL; +} + +static void +fatal(const char *msg, isc_result_t result) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_CRITICAL, "%s: %s", msg, + isc_result_totext(result)); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_CRITICAL, "exiting (due to fatal error)"); + exit(1); +} + +static void +start_reserved_dispatches(ns_server_t *server) { + + REQUIRE(NS_SERVER_VALID(server)); + + server->dispatchgen++; +} + +static void +end_reserved_dispatches(ns_server_t *server, isc_boolean_t all) { + ns_dispatch_t *dispatch, *nextdispatch; + + REQUIRE(NS_SERVER_VALID(server)); + + for (dispatch = ISC_LIST_HEAD(server->dispatches); + dispatch != NULL; + dispatch = nextdispatch) { + nextdispatch = ISC_LIST_NEXT(dispatch, link); + if (!all && server->dispatchgen == dispatch-> dispatchgen) + continue; + ISC_LIST_UNLINK(server->dispatches, dispatch, link); + dns_dispatch_detach(&dispatch->dispatch); + isc_mem_put(server->mctx, dispatch, sizeof(*dispatch)); + } +} + +void +ns_add_reserved_dispatch(ns_server_t *server, const isc_sockaddr_t *addr) { + ns_dispatch_t *dispatch; + in_port_t port; + char addrbuf[ISC_SOCKADDR_FORMATSIZE]; + isc_result_t result; + unsigned int attrs, attrmask; + + REQUIRE(NS_SERVER_VALID(server)); + + port = isc_sockaddr_getport(addr); + if (port == 0 || port >= 1024) + return; + + for (dispatch = ISC_LIST_HEAD(server->dispatches); + dispatch != NULL; + dispatch = ISC_LIST_NEXT(dispatch, link)) { + if (isc_sockaddr_equal(&dispatch->addr, addr)) + break; + } + if (dispatch != NULL) { + dispatch->dispatchgen = server->dispatchgen; + return; + } + + dispatch = isc_mem_get(server->mctx, sizeof(*dispatch)); + if (dispatch == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + + dispatch->addr = *addr; + dispatch->dispatchgen = server->dispatchgen; + dispatch->dispatch = NULL; + + attrs = 0; + attrs |= DNS_DISPATCHATTR_UDP; + switch (isc_sockaddr_pf(addr)) { + case AF_INET: + attrs |= DNS_DISPATCHATTR_IPV4; + break; + case AF_INET6: + attrs |= DNS_DISPATCHATTR_IPV6; + break; + default: + result = ISC_R_NOTIMPLEMENTED; + goto cleanup; + } + attrmask = 0; + attrmask |= DNS_DISPATCHATTR_UDP; + attrmask |= DNS_DISPATCHATTR_TCP; + attrmask |= DNS_DISPATCHATTR_IPV4; + attrmask |= DNS_DISPATCHATTR_IPV6; + + result = dns_dispatch_getudp(ns_g_dispatchmgr, ns_g_socketmgr, + ns_g_taskmgr, &dispatch->addr, 4096, + 1000, 32768, 16411, 16433, + attrs, attrmask, &dispatch->dispatch); + if (result != ISC_R_SUCCESS) + goto cleanup; + + ISC_LIST_INITANDPREPEND(server->dispatches, dispatch, link); + + return; + + cleanup: + if (dispatch != NULL) + isc_mem_put(server->mctx, dispatch, sizeof(*dispatch)); + isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf)); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_WARNING, + "unable to create dispatch for reserved port %s: %s", + addrbuf, isc_result_totext(result)); +} + + +static isc_result_t +loadconfig(ns_server_t *server) { + isc_result_t result; + start_reserved_dispatches(server); + result = load_configuration(ns_g_lwresdonly ? + lwresd_g_conffile : ns_g_conffile, + server, ISC_FALSE); + if (result == ISC_R_SUCCESS) + end_reserved_dispatches(server, ISC_FALSE); + else + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "reloading configuration failed: %s", + isc_result_totext(result)); + return (result); +} + +static isc_result_t +reload(ns_server_t *server) { + isc_result_t result; + CHECK(loadconfig(server)); + + result = load_zones(server, ISC_FALSE); + if (result != ISC_R_SUCCESS) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "reloading zones failed: %s", + isc_result_totext(result)); + } + cleanup: + return (result); +} + +static void +reconfig(ns_server_t *server) { + isc_result_t result; + CHECK(loadconfig(server)); + + result = load_new_zones(server, ISC_FALSE); + if (result != ISC_R_SUCCESS) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "loading new zones failed: %s", + isc_result_totext(result)); + } + cleanup: ; +} + +/* + * Handle a reload event (from SIGHUP). + */ +static void +ns_server_reload(isc_task_t *task, isc_event_t *event) { + ns_server_t *server = (ns_server_t *)event->ev_arg; + + INSIST(task = server->task); + UNUSED(task); + + (void)reload(server); + + LOCK(&server->reload_event_lock); + INSIST(server->reload_event == NULL); + server->reload_event = event; + UNLOCK(&server->reload_event_lock); +} + +void +ns_server_reloadwanted(ns_server_t *server) { + LOCK(&server->reload_event_lock); + if (server->reload_event != NULL) + isc_task_send(server->task, &server->reload_event); + UNLOCK(&server->reload_event_lock); +} + +static char * +next_token(char **stringp, const char *delim) { + char *res; + + do { + res = strsep(stringp, delim); + if (res == NULL) + break; + } while (*res == '\0'); + return (res); +} + +/* + * Find the zone specified in the control channel command 'args', + * if any. If a zone is specified, point '*zonep' at it, otherwise + * set '*zonep' to NULL. + */ +static isc_result_t +zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep) { + char *input, *ptr; + const char *zonetxt; + char *classtxt; + const char *viewtxt = NULL; + dns_fixedname_t name; + isc_result_t result; + isc_buffer_t buf; + dns_view_t *view = NULL; + dns_rdataclass_t rdclass; + + REQUIRE(zonep != NULL && *zonep == NULL); + + input = args; + + /* Skip the command name. */ + ptr = next_token(&input, " \t"); + if (ptr == NULL) + return (ISC_R_UNEXPECTEDEND); + + /* Look for the zone name. */ + zonetxt = next_token(&input, " \t"); + if (zonetxt == NULL) + return (ISC_R_SUCCESS); + + /* Look for the optional class name. */ + classtxt = next_token(&input, " \t"); + if (classtxt != NULL) { + /* Look for the optional view name. */ + viewtxt = next_token(&input, " \t"); + } + + isc_buffer_init(&buf, zonetxt, strlen(zonetxt)); + isc_buffer_add(&buf, strlen(zonetxt)); + dns_fixedname_init(&name); + result = dns_name_fromtext(dns_fixedname_name(&name), + &buf, dns_rootname, ISC_FALSE, NULL); + if (result != ISC_R_SUCCESS) + goto fail1; + + if (classtxt != NULL) { + isc_textregion_t r; + r.base = classtxt; + r.length = strlen(classtxt); + result = dns_rdataclass_fromtext(&rdclass, &r); + if (result != ISC_R_SUCCESS) + goto fail1; + } else { + rdclass = dns_rdataclass_in; + } + + if (viewtxt == NULL) + viewtxt = "_default"; + result = dns_viewlist_find(&server->viewlist, viewtxt, + rdclass, &view); + if (result != ISC_R_SUCCESS) + goto fail1; + + result = dns_zt_find(view->zonetable, dns_fixedname_name(&name), + 0, NULL, zonep); + /* Partial match? */ + if (result != ISC_R_SUCCESS && *zonep != NULL) + dns_zone_detach(zonep); + dns_view_detach(&view); + fail1: + return (result); +} + +/* + * Act on a "retransfer" command from the command channel. + */ +isc_result_t +ns_server_retransfercommand(ns_server_t *server, char *args) { + isc_result_t result; + dns_zone_t *zone = NULL; + dns_zonetype_t type; + + result = zone_from_args(server, args, &zone); + if (result != ISC_R_SUCCESS) + return (result); + if (zone == NULL) + return (ISC_R_UNEXPECTEDEND); + type = dns_zone_gettype(zone); + if (type == dns_zone_slave || type == dns_zone_stub) + dns_zone_forcereload(zone); + else + result = ISC_R_NOTFOUND; + dns_zone_detach(&zone); + return (result); +} + +/* + * Act on a "reload" command from the command channel. + */ +isc_result_t +ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t *text) { + isc_result_t result; + dns_zone_t *zone = NULL; + dns_zonetype_t type; + const char *msg = NULL; + + result = zone_from_args(server, args, &zone); + if (result != ISC_R_SUCCESS) + return (result); + if (zone == NULL) { + result = reload(server); + if (result == ISC_R_SUCCESS) + msg = "server reload successful"; + } else { + type = dns_zone_gettype(zone); + if (type == dns_zone_slave || type == dns_zone_stub) { + dns_zone_refresh(zone); + dns_zone_detach(&zone); + msg = "zone refresh queued"; + } else { + result = dns_zone_load(zone); + dns_zone_detach(&zone); + switch (result) { + case ISC_R_SUCCESS: + msg = "zone reload successful"; + break; + case DNS_R_CONTINUE: + msg = "zone reload queued"; + result = ISC_R_SUCCESS; + break; + case DNS_R_UPTODATE: + msg = "zone reload up-to-date"; + result = ISC_R_SUCCESS; + break; + default: + /* failure message will be generated by rndc */ + break; + } + } + } + if (msg != NULL && strlen(msg) < isc_buffer_availablelength(text)) + isc_buffer_putmem(text, (const unsigned char *)msg, + strlen(msg) + 1); + return (result); +} + +/* + * Act on a "reconfig" command from the command channel. + */ +isc_result_t +ns_server_reconfigcommand(ns_server_t *server, char *args) { + UNUSED(args); + + reconfig(server); + return (ISC_R_SUCCESS); +} + +/* + * Act on a "notify" command from the command channel. + */ +isc_result_t +ns_server_notifycommand(ns_server_t *server, char *args, isc_buffer_t *text) { + isc_result_t result; + dns_zone_t *zone = NULL; + const unsigned char msg[] = "zone notify queued"; + + result = zone_from_args(server, args, &zone); + if (result != ISC_R_SUCCESS) + return (result); + if (zone == NULL) + return (ISC_R_UNEXPECTEDEND); + + dns_zone_notify(zone); + dns_zone_detach(&zone); + if (sizeof(msg) <= isc_buffer_availablelength(text)) + isc_buffer_putmem(text, msg, sizeof(msg)); + + return (ISC_R_SUCCESS); +} + +/* + * Act on a "refresh" command from the command channel. + */ +isc_result_t +ns_server_refreshcommand(ns_server_t *server, char *args, isc_buffer_t *text) { + isc_result_t result; + dns_zone_t *zone = NULL; + const unsigned char msg1[] = "zone refresh queued"; + const unsigned char msg2[] = "not a slave or stub zone"; + dns_zonetype_t type; + + result = zone_from_args(server, args, &zone); + if (result != ISC_R_SUCCESS) + return (result); + if (zone == NULL) + return (ISC_R_UNEXPECTEDEND); + + type = dns_zone_gettype(zone); + if (type == dns_zone_slave || type == dns_zone_stub) { + dns_zone_refresh(zone); + dns_zone_detach(&zone); + if (sizeof(msg1) <= isc_buffer_availablelength(text)) + isc_buffer_putmem(text, msg1, sizeof(msg1)); + return (ISC_R_SUCCESS); + } + + dns_zone_detach(&zone); + if (sizeof(msg2) <= isc_buffer_availablelength(text)) + isc_buffer_putmem(text, msg2, sizeof(msg2)); + return (ISC_R_FAILURE); +} + +isc_result_t +ns_server_togglequerylog(ns_server_t *server) { + server->log_queries = server->log_queries ? ISC_FALSE : ISC_TRUE; + + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_INFO, + "query logging is now %s", + server->log_queries ? "on" : "off"); + return (ISC_R_SUCCESS); +} + +static isc_result_t +ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config, + cfg_aclconfctx_t *actx, + isc_mem_t *mctx, ns_listenlist_t **target) +{ + isc_result_t result; + const cfg_listelt_t *element; + ns_listenlist_t *dlist = NULL; + + REQUIRE(target != NULL && *target == NULL); + + result = ns_listenlist_create(mctx, &dlist); + if (result != ISC_R_SUCCESS) + return (result); + + for (element = cfg_list_first(listenlist); + element != NULL; + element = cfg_list_next(element)) + { + ns_listenelt_t *delt = NULL; + const cfg_obj_t *listener = cfg_listelt_value(element); + result = ns_listenelt_fromconfig(listener, config, actx, + mctx, &delt); + if (result != ISC_R_SUCCESS) + goto cleanup; + ISC_LIST_APPEND(dlist->elts, delt, link); + } + *target = dlist; + return (ISC_R_SUCCESS); + + cleanup: + ns_listenlist_detach(&dlist); + return (result); +} + +/* + * Create a listen list from the corresponding configuration + * data structure. + */ +static isc_result_t +ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, + cfg_aclconfctx_t *actx, + isc_mem_t *mctx, ns_listenelt_t **target) +{ + isc_result_t result; + const cfg_obj_t *portobj; + in_port_t port; + ns_listenelt_t *delt = NULL; + REQUIRE(target != NULL && *target == NULL); + + portobj = cfg_tuple_get(listener, "port"); + if (!cfg_obj_isuint32(portobj)) { + if (ns_g_port != 0) { + port = ns_g_port; + } else { + result = ns_config_getport(config, &port); + if (result != ISC_R_SUCCESS) + return (result); + } + } else { + if (cfg_obj_asuint32(portobj) >= ISC_UINT16_MAX) { + cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, + "port value '%u' is out of range", + cfg_obj_asuint32(portobj)); + return (ISC_R_RANGE); + } + port = (in_port_t)cfg_obj_asuint32(portobj); + } + + result = ns_listenelt_create(mctx, port, NULL, &delt); + if (result != ISC_R_SUCCESS) + return (result); + + result = cfg_acl_fromconfig(cfg_tuple_get(listener, "acl"), + config, ns_g_lctx, actx, mctx, &delt->acl); + if (result != ISC_R_SUCCESS) { + ns_listenelt_destroy(delt); + return (result); + } + *target = delt; + return (ISC_R_SUCCESS); +} + +isc_result_t +ns_server_dumpstats(ns_server_t *server) { + isc_result_t result; + dns_zone_t *zone, *next; + isc_stdtime_t now; + FILE *fp = NULL; + int i; + int ncounters; + + isc_stdtime_get(&now); + + CHECKMF(isc_stdio_open(server->statsfile, "a", &fp), + "could not open statistics dump file", server->statsfile); + + ncounters = DNS_STATS_NCOUNTERS; + fprintf(fp, "+++ Statistics Dump +++ (%lu)\n", (unsigned long)now); + + for (i = 0; i < ncounters; i++) + fprintf(fp, "%s %" ISC_PRINT_QUADFORMAT "u\n", + dns_statscounter_names[i], + server->querystats[i]); + + zone = NULL; + for (result = dns_zone_first(server->zonemgr, &zone); + result == ISC_R_SUCCESS; + next = NULL, result = dns_zone_next(zone, &next), zone = next) + { + isc_uint64_t *zonestats = dns_zone_getstatscounters(zone); + if (zonestats != NULL) { + char zonename[DNS_NAME_FORMATSIZE]; + dns_view_t *view; + char *viewname; + + dns_name_format(dns_zone_getorigin(zone), + zonename, sizeof(zonename)); + view = dns_zone_getview(zone); + viewname = view->name; + for (i = 0; i < ncounters; i++) { + fprintf(fp, "%s %" ISC_PRINT_QUADFORMAT + "u %s", + dns_statscounter_names[i], + zonestats[i], + zonename); + if (strcmp(viewname, "_default") != 0) + fprintf(fp, " %s", viewname); + fprintf(fp, "\n"); + } + } + } + if (result == ISC_R_NOMORE) + result = ISC_R_SUCCESS; + CHECK(result); + + fprintf(fp, "--- Statistics Dump --- (%lu)\n", (unsigned long)now); + + cleanup: + if (fp != NULL) + (void)isc_stdio_close(fp); + return (result); +} + +static isc_result_t +add_zone_tolist(dns_zone_t *zone, void *uap) { + struct dumpcontext *dctx = uap; + struct zonelistentry *zle; + + zle = isc_mem_get(dctx->mctx, sizeof *zle); + if (zle == NULL) + return (ISC_R_NOMEMORY); + zle->zone = NULL; + dns_zone_attach(zone, &zle->zone); + ISC_LINK_INIT(zle, link); + ISC_LIST_APPEND(ISC_LIST_TAIL(dctx->viewlist)->zonelist, zle, link); + return (ISC_R_SUCCESS); +} + +static isc_result_t +add_view_tolist(struct dumpcontext *dctx, dns_view_t *view) { + struct viewlistentry *vle; + isc_result_t result = ISC_R_SUCCESS; + + /* + * Prevent duplicate views. + */ + for (vle = ISC_LIST_HEAD(dctx->viewlist); + vle != NULL; + vle = ISC_LIST_NEXT(vle, link)) + if (vle->view == view) + return (ISC_R_SUCCESS); + + vle = isc_mem_get(dctx->mctx, sizeof *vle); + if (vle == NULL) + return (ISC_R_NOMEMORY); + vle->view = NULL; + dns_view_attach(view, &vle->view); + ISC_LINK_INIT(vle, link); + ISC_LIST_INIT(vle->zonelist); + ISC_LIST_APPEND(dctx->viewlist, vle, link); + if (dctx->dumpzones) + result = dns_zt_apply(view->zonetable, ISC_TRUE, + add_zone_tolist, dctx); + return (result); +} + +static void +dumpcontext_destroy(struct dumpcontext *dctx) { + struct viewlistentry *vle; + struct zonelistentry *zle; + + vle = ISC_LIST_HEAD(dctx->viewlist); + while (vle != NULL) { + ISC_LIST_UNLINK(dctx->viewlist, vle, link); + zle = ISC_LIST_HEAD(vle->zonelist); + while (zle != NULL) { + ISC_LIST_UNLINK(vle->zonelist, zle, link); + dns_zone_detach(&zle->zone); + isc_mem_put(dctx->mctx, zle, sizeof *zle); + zle = ISC_LIST_HEAD(vle->zonelist); + } + dns_view_detach(&vle->view); + isc_mem_put(dctx->mctx, vle, sizeof *vle); + vle = ISC_LIST_HEAD(dctx->viewlist); + } + if (dctx->version != NULL) + dns_db_closeversion(dctx->db, &dctx->version, ISC_FALSE); + if (dctx->db != NULL) + dns_db_detach(&dctx->db); + if (dctx->cache != NULL) + dns_db_detach(&dctx->cache); + if (dctx->task != NULL) + isc_task_detach(&dctx->task); + if (dctx->fp != NULL) + (void)isc_stdio_close(dctx->fp); + if (dctx->mdctx != NULL) + dns_dumpctx_detach(&dctx->mdctx); + isc_mem_put(dctx->mctx, dctx, sizeof *dctx); +} + +static void +dumpdone(void *arg, isc_result_t result) { + struct dumpcontext *dctx = arg; + char buf[1024+32]; + const dns_master_style_t *style; + + if (result != ISC_R_SUCCESS) + goto cleanup; + if (dctx->mdctx != NULL) + dns_dumpctx_detach(&dctx->mdctx); + if (dctx->view == NULL) { + dctx->view = ISC_LIST_HEAD(dctx->viewlist); + if (dctx->view == NULL) + goto done; + INSIST(dctx->zone == NULL); + } else + goto resume; + nextview: + fprintf(dctx->fp, ";\n; Start view %s\n;\n", dctx->view->view->name); + resume: + if (dctx->zone == NULL && dctx->cache == NULL && dctx->dumpcache) { + style = &dns_master_style_cache; + /* start cache dump */ + if (dctx->view->view->cachedb != NULL) + dns_db_attach(dctx->view->view->cachedb, &dctx->cache); + if (dctx->cache != NULL) { + + fprintf(dctx->fp, ";\n; Cache dump of view '%s'\n;\n", + dctx->view->view->name); + result = dns_master_dumptostreaminc(dctx->mctx, + dctx->cache, NULL, + style, dctx->fp, + dctx->task, + dumpdone, dctx, + &dctx->mdctx); + if (result == DNS_R_CONTINUE) + return; + if (result == ISC_R_NOTIMPLEMENTED) + fprintf(dctx->fp, "; %s\n", + dns_result_totext(result)); + else if (result != ISC_R_SUCCESS) + goto cleanup; + } + } + if (dctx->cache != NULL) { + dns_adb_dump(dctx->view->view->adb, dctx->fp); + dns_db_detach(&dctx->cache); + } + if (dctx->dumpzones) { + style = &dns_master_style_full; + nextzone: + if (dctx->version != NULL) + dns_db_closeversion(dctx->db, &dctx->version, + ISC_FALSE); + if (dctx->db != NULL) + dns_db_detach(&dctx->db); + if (dctx->zone == NULL) + dctx->zone = ISC_LIST_HEAD(dctx->view->zonelist); + else + dctx->zone = ISC_LIST_NEXT(dctx->zone, link); + if (dctx->zone != NULL) { + /* start zone dump */ + dns_zone_name(dctx->zone->zone, buf, sizeof(buf)); + fprintf(dctx->fp, ";\n; Zone dump of '%s'\n;\n", buf); + result = dns_zone_getdb(dctx->zone->zone, &dctx->db); + if (result != ISC_R_SUCCESS) { + fprintf(dctx->fp, "; %s\n", + dns_result_totext(result)); + goto nextzone; + } + dns_db_currentversion(dctx->db, &dctx->version); + result = dns_master_dumptostreaminc(dctx->mctx, + dctx->db, + dctx->version, + style, dctx->fp, + dctx->task, + dumpdone, dctx, + &dctx->mdctx); + if (result == DNS_R_CONTINUE) + return; + if (result == ISC_R_NOTIMPLEMENTED) { + fprintf(dctx->fp, "; %s\n", + dns_result_totext(result)); + result = ISC_R_SUCCESS; + goto nextzone; + } + if (result != ISC_R_SUCCESS) + goto cleanup; + } + } + if (dctx->view != NULL) + dctx->view = ISC_LIST_NEXT(dctx->view, link); + if (dctx->view != NULL) + goto nextview; + done: + fprintf(dctx->fp, "; Dump complete\n"); + result = isc_stdio_flush(dctx->fp); + if (result == ISC_R_SUCCESS) + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_INFO, + "dumpdb complete"); + cleanup: + if (result != ISC_R_SUCCESS) + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_INFO, + "dumpdb failed: %s", dns_result_totext(result)); + dumpcontext_destroy(dctx); +} + +isc_result_t +ns_server_dumpdb(ns_server_t *server, char *args) { + struct dumpcontext *dctx = NULL; + dns_view_t *view; + isc_result_t result; + char *ptr; + const char *sep; + + /* Skip the command name. */ + ptr = next_token(&args, " \t"); + if (ptr == NULL) + return (ISC_R_UNEXPECTEDEND); + + dctx = isc_mem_get(server->mctx, sizeof(*dctx)); + if (dctx == NULL) + return (ISC_R_NOMEMORY); + + dctx->mctx = server->mctx; + dctx->dumpcache = ISC_TRUE; + dctx->dumpzones = ISC_FALSE; + dctx->fp = NULL; + ISC_LIST_INIT(dctx->viewlist); + dctx->view = NULL; + dctx->zone = NULL; + dctx->cache = NULL; + dctx->mdctx = NULL; + dctx->db = NULL; + dctx->cache = NULL; + dctx->task = NULL; + dctx->version = NULL; + isc_task_attach(server->task, &dctx->task); + + CHECKMF(isc_stdio_open(server->dumpfile, "w", &dctx->fp), + "could not open dump file", server->dumpfile); + + sep = (args == NULL) ? "" : ": "; + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_INFO, + "dumpdb started%s%s", sep, (args != NULL) ? args : ""); + + ptr = next_token(&args, " \t"); + if (ptr != NULL && strcmp(ptr, "-all") == 0) { + dctx->dumpzones = ISC_TRUE; + dctx->dumpcache = ISC_TRUE; + ptr = next_token(&args, " \t"); + } else if (ptr != NULL && strcmp(ptr, "-cache") == 0) { + dctx->dumpzones = ISC_FALSE; + dctx->dumpcache = ISC_TRUE; + ptr = next_token(&args, " \t"); + } else if (ptr != NULL && strcmp(ptr, "-zones") == 0) { + dctx->dumpzones = ISC_TRUE; + dctx->dumpcache = ISC_FALSE; + ptr = next_token(&args, " \t"); + } + + nextview: + for (view = ISC_LIST_HEAD(server->viewlist); + view != NULL; + view = ISC_LIST_NEXT(view, link)) + { + if (ptr != NULL && strcmp(view->name, ptr) != 0) + continue; + CHECK(add_view_tolist(dctx, view)); + } + if (ptr != NULL) { + ptr = next_token(&args, " \t"); + if (ptr != NULL) + goto nextview; + } + dumpdone(dctx, ISC_R_SUCCESS); + return (ISC_R_SUCCESS); + + cleanup: + if (dctx != NULL) + dumpcontext_destroy(dctx); + return (result); +} + +isc_result_t +ns_server_dumprecursing(ns_server_t *server) { + FILE *fp = NULL; + isc_result_t result; + + CHECKMF(isc_stdio_open(server->recfile, "w", &fp), + "could not open dump file", server->recfile); + fprintf(fp,";\n; Recursing Queries\n;\n"); + ns_interfacemgr_dumprecursing(fp, server->interfacemgr); + fprintf(fp, "; Dump complete\n"); + + cleanup: + if (fp != NULL) + result = isc_stdio_close(fp); + return (result); +} + +isc_result_t +ns_server_setdebuglevel(ns_server_t *server, char *args) { + char *ptr; + char *levelstr; + char *endp; + long newlevel; + + UNUSED(server); + + /* Skip the command name. */ + ptr = next_token(&args, " \t"); + if (ptr == NULL) + return (ISC_R_UNEXPECTEDEND); + + /* Look for the new level name. */ + levelstr = next_token(&args, " \t"); + if (levelstr == NULL) { + if (ns_g_debuglevel < 99) + ns_g_debuglevel++; + } else { + newlevel = strtol(levelstr, &endp, 10); + if (*endp != '\0' || newlevel < 0 || newlevel > 99) + return (ISC_R_RANGE); + ns_g_debuglevel = (unsigned int)newlevel; + } + isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); + return (ISC_R_SUCCESS); +} + +isc_result_t +ns_server_validation(ns_server_t *server, char *args) { + char *ptr, *viewname; + dns_view_t *view; + isc_boolean_t changed = ISC_FALSE; + isc_result_t result; + isc_boolean_t enable; + + /* Skip the command name. */ + ptr = next_token(&args, " \t"); + if (ptr == NULL) + return (ISC_R_UNEXPECTEDEND); + + /* Find out what we are to do. */ + ptr = next_token(&args, " \t"); + if (ptr == NULL) + return (ISC_R_UNEXPECTEDEND); + + if (!strcasecmp(ptr, "on") || !strcasecmp(ptr, "yes") || + !strcasecmp(ptr, "enable") || !strcasecmp(ptr, "true")) + enable = ISC_TRUE; + else if (!strcasecmp(ptr, "off") || !strcasecmp(ptr, "no") || + !strcasecmp(ptr, "disable") || !strcasecmp(ptr, "false")) + enable = ISC_FALSE; + else + return (DNS_R_SYNTAX); + + /* Look for the view name. */ + viewname = next_token(&args, " \t"); + + result = isc_task_beginexclusive(server->task); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + for (view = ISC_LIST_HEAD(server->viewlist); + view != NULL; + view = ISC_LIST_NEXT(view, link)) + { + if (viewname != NULL && strcasecmp(viewname, view->name) != 0) + continue; + result = dns_view_flushcache(view); + if (result != ISC_R_SUCCESS) + goto out; + view->enablevalidation = enable; + changed = ISC_TRUE; + } + if (changed) + result = ISC_R_SUCCESS; + else + result = ISC_R_FAILURE; + out: + isc_task_endexclusive(server->task); + return (result); +} + +isc_result_t +ns_server_flushcache(ns_server_t *server, char *args) { + char *ptr, *viewname; + dns_view_t *view; + isc_boolean_t flushed; + isc_boolean_t found; + isc_result_t result; + + /* Skip the command name. */ + ptr = next_token(&args, " \t"); + if (ptr == NULL) + return (ISC_R_UNEXPECTEDEND); + + /* Look for the view name. */ + viewname = next_token(&args, " \t"); + + result = isc_task_beginexclusive(server->task); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + flushed = ISC_TRUE; + found = ISC_FALSE; + for (view = ISC_LIST_HEAD(server->viewlist); + view != NULL; + view = ISC_LIST_NEXT(view, link)) + { + if (viewname != NULL && strcasecmp(viewname, view->name) != 0) + continue; + found = ISC_TRUE; + result = dns_view_flushcache(view); + if (result != ISC_R_SUCCESS) + flushed = ISC_FALSE; + } + if (flushed && found) { + result = ISC_R_SUCCESS; + } else { + if (!found) + result = ISC_R_NOTFOUND; + else + result = ISC_R_FAILURE; + } + isc_task_endexclusive(server->task); + return (result); +} + +isc_result_t +ns_server_flushname(ns_server_t *server, char *args) { + char *ptr, *target, *viewname; + dns_view_t *view; + isc_boolean_t flushed; + isc_boolean_t found; + isc_result_t result; + isc_buffer_t b; + dns_fixedname_t fixed; + dns_name_t *name; + + /* Skip the command name. */ + ptr = next_token(&args, " \t"); + if (ptr == NULL) + return (ISC_R_UNEXPECTEDEND); + + /* Find the domain name to flush. */ + target = next_token(&args, " \t"); + if (target == NULL) + return (ISC_R_UNEXPECTEDEND); + + isc_buffer_init(&b, target, strlen(target)); + isc_buffer_add(&b, strlen(target)); + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL); + if (result != ISC_R_SUCCESS) + return (result); + + /* Look for the view name. */ + viewname = next_token(&args, " \t"); + + result = isc_task_beginexclusive(server->task); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + flushed = ISC_TRUE; + found = ISC_FALSE; + for (view = ISC_LIST_HEAD(server->viewlist); + view != NULL; + view = ISC_LIST_NEXT(view, link)) + { + if (viewname != NULL && strcasecmp(viewname, view->name) != 0) + continue; + found = ISC_TRUE; + result = dns_view_flushname(view, name); + if (result != ISC_R_SUCCESS) + flushed = ISC_FALSE; + } + if (flushed && found) + result = ISC_R_SUCCESS; + else if (!found) + result = ISC_R_NOTFOUND; + else + result = ISC_R_FAILURE; + isc_task_endexclusive(server->task); + return (result); +} + +isc_result_t +ns_server_status(ns_server_t *server, isc_buffer_t *text) { + int zonecount, xferrunning, xferdeferred, soaqueries; + unsigned int n; + + zonecount = dns_zonemgr_getcount(server->zonemgr, DNS_ZONESTATE_ANY); + xferrunning = dns_zonemgr_getcount(server->zonemgr, + DNS_ZONESTATE_XFERRUNNING); + xferdeferred = dns_zonemgr_getcount(server->zonemgr, + DNS_ZONESTATE_XFERDEFERRED); + soaqueries = dns_zonemgr_getcount(server->zonemgr, + DNS_ZONESTATE_SOAQUERY); + n = snprintf((char *)isc_buffer_used(text), + isc_buffer_availablelength(text), + "number of zones: %u\n" + "debug level: %d\n" + "xfers running: %u\n" + "xfers deferred: %u\n" + "soa queries in progress: %u\n" + "query logging is %s\n" + "recursive clients: %d/%d/%d\n" + "tcp clients: %d/%d\n" + "server is up and running", + zonecount, ns_g_debuglevel, xferrunning, xferdeferred, + soaqueries, server->log_queries ? "ON" : "OFF", + server->recursionquota.used, server->recursionquota.soft, + server->recursionquota.max, + server->tcpquota.used, server->tcpquota.max); + if (n >= isc_buffer_availablelength(text)) + return (ISC_R_NOSPACE); + isc_buffer_add(text, n); + return (ISC_R_SUCCESS); +} + +/* + * Act on a "freeze" or "thaw" command from the command channel. + */ +isc_result_t +ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args) { + isc_result_t result, tresult; + dns_zone_t *zone = NULL; + dns_zonetype_t type; + char classstr[DNS_RDATACLASS_FORMATSIZE]; + char zonename[DNS_NAME_FORMATSIZE]; + dns_view_t *view; + char *journal; + const char *vname, *sep; + isc_boolean_t frozen; + + result = zone_from_args(server, args, &zone); + if (result != ISC_R_SUCCESS) + return (result); + if (zone == NULL) { + result = isc_task_beginexclusive(server->task); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + tresult = ISC_R_SUCCESS; + for (view = ISC_LIST_HEAD(server->viewlist); + view != NULL; + view = ISC_LIST_NEXT(view, link)) { + result = dns_view_freezezones(view, freeze); + if (result != ISC_R_SUCCESS && + tresult == ISC_R_SUCCESS) + tresult = result; + } + isc_task_endexclusive(server->task); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_INFO, + "%s all zones: %s", + freeze ? "freezing" : "thawing", + isc_result_totext(tresult)); + return (tresult); + } + type = dns_zone_gettype(zone); + if (type != dns_zone_master) { + dns_zone_detach(&zone); + return (ISC_R_NOTFOUND); + } + + frozen = dns_zone_getupdatedisabled(zone); + if (freeze) { + if (frozen) + 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); + if (result == DNS_R_CONTINUE || + result == DNS_R_UPTODATE) + result = ISC_R_SUCCESS; + } + } + if (result == ISC_R_SUCCESS) + dns_zone_setupdatedisabled(zone, freeze); + + view = dns_zone_getview(zone); + if (strcmp(view->name, "_bind") == 0 || + strcmp(view->name, "_default") == 0) + { + vname = ""; + sep = ""; + } else { + vname = view->name; + sep = " "; + } + dns_rdataclass_format(dns_zone_getclass(zone), classstr, + sizeof(classstr)); + dns_name_format(dns_zone_getorigin(zone), + zonename, sizeof(zonename)); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_INFO, + "%s zone '%s/%s'%s%s: %s", + freeze ? "freezing" : "thawing", + zonename, classstr, sep, vname, + isc_result_totext(result)); + dns_zone_detach(&zone); + return (result); +} + +#ifdef HAVE_LIBSCF +/* + * This function adds a message for rndc to echo if named + * is managed by smf and is also running chroot. + */ +isc_result_t +ns_smf_add_message(isc_buffer_t *text) { + unsigned int n; + + n = snprintf((char *)isc_buffer_used(text), + isc_buffer_availablelength(text), + "use svcadm(1M) to manage named"); + if (n >= isc_buffer_availablelength(text)) + return (ISC_R_NOSPACE); + isc_buffer_add(text, n); + return (ISC_R_SUCCESS); +} +#endif /* HAVE_LIBSCF */ diff --git a/bin/named/sortlist.c b/bin/named/sortlist.c new file mode 100644 index 0000000..28f0360 --- /dev/null +++ b/bin/named/sortlist.c @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: sortlist.c,v 1.9.18.4 2006/03/02 00:37:21 marka Exp $ */ + +/*! \file */ + +#include + +#include +#include + +#include +#include + +#include +#include +#include + +ns_sortlisttype_t +ns_sortlist_setup(dns_acl_t *acl, isc_netaddr_t *clientaddr, + const void **argp) +{ + unsigned int i; + + if (acl == NULL) + goto dont_sort; + + for (i = 0; i < acl->length; i++) { + /* + * 'e' refers to the current 'top level statement' + * in the sortlist (see ARM). + */ + dns_aclelement_t *e = &acl->elements[i]; + dns_aclelement_t *try_elt; + dns_aclelement_t *order_elt = NULL; + const dns_aclelement_t *matched_elt = NULL; + + if (e->type == dns_aclelementtype_nestedacl) { + dns_acl_t *inner = e->u.nestedacl; + + if (inner->length < 1 || inner->length > 2) + goto dont_sort; + if (inner->elements[0].negative) + goto dont_sort; + try_elt = &inner->elements[0]; + if (inner->length == 2) + order_elt = &inner->elements[1]; + } else { + /* + * BIND 8 allows bare elements at the top level + * as an undocumented feature. + */ + try_elt = e; + } + + if (dns_aclelement_match(clientaddr, NULL, try_elt, + &ns_g_server->aclenv, + &matched_elt)) { + if (order_elt != NULL) { + if (order_elt->type == + dns_aclelementtype_nestedacl) { + *argp = order_elt->u.nestedacl; + return (NS_SORTLISTTYPE_2ELEMENT); + } else if (order_elt->type == + dns_aclelementtype_localhost && + ns_g_server->aclenv.localhost != NULL) { + *argp = ns_g_server->aclenv.localhost; + return (NS_SORTLISTTYPE_2ELEMENT); + } else if (order_elt->type == + dns_aclelementtype_localnets && + ns_g_server->aclenv.localnets != NULL) { + *argp = ns_g_server->aclenv.localnets; + return (NS_SORTLISTTYPE_2ELEMENT); + } else { + /* + * BIND 8 allows a bare IP prefix as + * the 2nd element of a 2-element + * sortlist statement. + */ + *argp = order_elt; + return (NS_SORTLISTTYPE_1ELEMENT); + } + } else { + INSIST(matched_elt != NULL); + *argp = matched_elt; + return (NS_SORTLISTTYPE_1ELEMENT); + } + } + } + + /* No match; don't sort. */ + dont_sort: + *argp = NULL; + return (NS_SORTLISTTYPE_NONE); +} + +int +ns_sortlist_addrorder2(const isc_netaddr_t *addr, const void *arg) { + const dns_acl_t *sortacl = (const dns_acl_t *) arg; + int match; + + (void)dns_acl_match(addr, NULL, sortacl, + &ns_g_server->aclenv, + &match, NULL); + if (match > 0) + return (match); + else if (match < 0) + return (INT_MAX - (-match)); + else + return (INT_MAX / 2); +} + +int +ns_sortlist_addrorder1(const isc_netaddr_t *addr, const void *arg) { + const dns_aclelement_t *matchelt = (const dns_aclelement_t *) arg; + if (dns_aclelement_match(addr, NULL, matchelt, + &ns_g_server->aclenv, + NULL)) { + return (0); + } else { + return (INT_MAX); + } +} + +void +ns_sortlist_byaddrsetup(dns_acl_t *sortlist_acl, isc_netaddr_t *client_addr, + dns_addressorderfunc_t *orderp, + const void **argp) +{ + ns_sortlisttype_t sortlisttype; + + sortlisttype = ns_sortlist_setup(sortlist_acl, client_addr, argp); + + switch (sortlisttype) { + case NS_SORTLISTTYPE_1ELEMENT: + *orderp = ns_sortlist_addrorder1; + break; + case NS_SORTLISTTYPE_2ELEMENT: + *orderp = ns_sortlist_addrorder2; + break; + case NS_SORTLISTTYPE_NONE: + *orderp = NULL; + break; + default: + UNEXPECTED_ERROR(__FILE__, __LINE__, + "unexpected return from ns_sortlist_setup(): " + "%d", sortlisttype); + break; + } +} + diff --git a/bin/named/tkeyconf.c b/bin/named/tkeyconf.c new file mode 100644 index 0000000..3c843ac --- /dev/null +++ b/bin/named/tkeyconf.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: tkeyconf.c,v 1.20.18.6 2006/03/02 00:37:21 marka Exp $ */ + +/*! \file */ + +#include + +#include +#include /* Required for HP/UX (and others?) */ +#include + +#include + +#include +#include +#include +#include + +#include + +#include + +#define RETERR(x) do { \ + result = (x); \ + if (result != ISC_R_SUCCESS) \ + goto failure; \ + } while (0) + + +isc_result_t +ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx, + isc_entropy_t *ectx, dns_tkeyctx_t **tctxp) +{ + isc_result_t result; + dns_tkeyctx_t *tctx = NULL; + const char *s; + isc_uint32_t n; + dns_fixedname_t fname; + dns_name_t *name; + isc_buffer_t b; + const cfg_obj_t *obj; + int type; + + result = dns_tkeyctx_create(mctx, ectx, &tctx); + if (result != ISC_R_SUCCESS) + return (result); + + obj = NULL; + result = cfg_map_get(options, "tkey-dhkey", &obj); + if (result == ISC_R_SUCCESS) { + s = cfg_obj_asstring(cfg_tuple_get(obj, "name")); + n = cfg_obj_asuint32(cfg_tuple_get(obj, "keyid")); + isc_buffer_init(&b, s, strlen(s)); + isc_buffer_add(&b, strlen(s)); + dns_fixedname_init(&fname); + name = dns_fixedname_name(&fname); + RETERR(dns_name_fromtext(name, &b, dns_rootname, + ISC_FALSE, NULL)); + type = DST_TYPE_PUBLIC|DST_TYPE_PRIVATE|DST_TYPE_KEY; + RETERR(dst_key_fromfile(name, (dns_keytag_t) n, DNS_KEYALG_DH, + type, NULL, mctx, &tctx->dhkey)); + } + + obj = NULL; + result = cfg_map_get(options, "tkey-domain", &obj); + if (result == ISC_R_SUCCESS) { + s = cfg_obj_asstring(obj); + isc_buffer_init(&b, s, strlen(s)); + isc_buffer_add(&b, strlen(s)); + dns_fixedname_init(&fname); + name = dns_fixedname_name(&fname); + RETERR(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, + NULL)); + tctx->domain = isc_mem_get(mctx, sizeof(dns_name_t)); + if (tctx->domain == NULL) { + result = ISC_R_NOMEMORY; + goto failure; + } + dns_name_init(tctx->domain, NULL); + RETERR(dns_name_dup(name, mctx, tctx->domain)); + } + + obj = NULL; + result = cfg_map_get(options, "tkey-gssapi-credential", &obj); + if (result == ISC_R_SUCCESS) { + s = cfg_obj_asstring(obj); + isc_buffer_init(&b, s, strlen(s)); + isc_buffer_add(&b, strlen(s)); + dns_fixedname_init(&fname); + name = dns_fixedname_name(&fname); + RETERR(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, + NULL)); + RETERR(dst_gssapi_acquirecred(name, ISC_FALSE, + &tctx->gsscred)); + } + + *tctxp = tctx; + return (ISC_R_SUCCESS); + + failure: + dns_tkeyctx_destroy(&tctx); + return (result); +} + diff --git a/bin/named/tsigconf.c b/bin/named/tsigconf.c new file mode 100644 index 0000000..7fa7fe5 --- /dev/null +++ b/bin/named/tsigconf.c @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: tsigconf.c,v 1.22.18.6 2006/02/28 03:10:47 marka Exp $ */ + +/*! \file */ + +#include + +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include +#include + +static isc_result_t +add_initial_keys(const cfg_obj_t *list, dns_tsig_keyring_t *ring, + isc_mem_t *mctx) +{ + dns_tsigkey_t *tsigkey = NULL; + const cfg_listelt_t *element; + const cfg_obj_t *key = NULL; + const char *keyid = NULL; + unsigned char *secret = NULL; + int secretalloc = 0; + int secretlen = 0; + isc_result_t ret; + isc_stdtime_t now; + isc_uint16_t bits; + + for (element = cfg_list_first(list); + element != NULL; + element = cfg_list_next(element)) + { + const cfg_obj_t *algobj = NULL; + const cfg_obj_t *secretobj = NULL; + dns_name_t keyname; + dns_name_t *alg; + const char *algstr; + char keynamedata[1024]; + isc_buffer_t keynamesrc, keynamebuf; + const char *secretstr; + isc_buffer_t secretbuf; + + key = cfg_listelt_value(element); + keyid = cfg_obj_asstring(cfg_map_getname(key)); + + algobj = NULL; + secretobj = NULL; + (void)cfg_map_get(key, "algorithm", &algobj); + (void)cfg_map_get(key, "secret", &secretobj); + INSIST(algobj != NULL && secretobj != NULL); + + /* + * Create the key name. + */ + dns_name_init(&keyname, NULL); + isc_buffer_init(&keynamesrc, keyid, strlen(keyid)); + isc_buffer_add(&keynamesrc, strlen(keyid)); + isc_buffer_init(&keynamebuf, keynamedata, sizeof(keynamedata)); + ret = dns_name_fromtext(&keyname, &keynamesrc, dns_rootname, + ISC_TRUE, &keynamebuf); + if (ret != ISC_R_SUCCESS) + goto failure; + + /* + * Create the algorithm. + */ + algstr = cfg_obj_asstring(algobj); + if (ns_config_getkeyalgorithm(algstr, &alg, &bits) + != ISC_R_SUCCESS) { + cfg_obj_log(algobj, ns_g_lctx, ISC_LOG_ERROR, + "key '%s': has a unsupported algorithm '%s'", + keyid, algstr); + ret = DNS_R_BADALG; + goto failure; + } + + secretstr = cfg_obj_asstring(secretobj); + secretalloc = secretlen = strlen(secretstr) * 3 / 4; + secret = isc_mem_get(mctx, secretlen); + if (secret == NULL) { + ret = ISC_R_NOMEMORY; + goto failure; + } + isc_buffer_init(&secretbuf, secret, secretlen); + ret = isc_base64_decodestring(secretstr, &secretbuf); + if (ret != ISC_R_SUCCESS) + goto failure; + secretlen = isc_buffer_usedlength(&secretbuf); + + isc_stdtime_get(&now); + ret = dns_tsigkey_create(&keyname, alg, secret, secretlen, + ISC_FALSE, NULL, now, now, + mctx, ring, &tsigkey); + isc_mem_put(mctx, secret, secretalloc); + secret = NULL; + if (ret != ISC_R_SUCCESS) + goto failure; + /* + * Set digest bits. + */ + dst_key_setbits(tsigkey->key, bits); + dns_tsigkey_detach(&tsigkey); + } + + return (ISC_R_SUCCESS); + + failure: + cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, + "configuring key '%s': %s", keyid, + isc_result_totext(ret)); + + if (secret != NULL) + isc_mem_put(mctx, secret, secretalloc); + return (ret); +} + +isc_result_t +ns_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig, + isc_mem_t *mctx, dns_tsig_keyring_t **ringp) +{ + const cfg_obj_t *maps[3]; + const cfg_obj_t *keylist; + dns_tsig_keyring_t *ring = NULL; + isc_result_t result; + int i; + + i = 0; + if (config != NULL) + maps[i++] = config; + if (vconfig != NULL) + maps[i++] = cfg_tuple_get(vconfig, "options"); + maps[i] = NULL; + + result = dns_tsigkeyring_create(mctx, &ring); + if (result != ISC_R_SUCCESS) + return (result); + + for (i = 0; ; i++) { + if (maps[i] == NULL) + break; + keylist = NULL; + result = cfg_map_get(maps[i], "key", &keylist); + if (result != ISC_R_SUCCESS) + continue; + result = add_initial_keys(keylist, ring, mctx); + if (result != ISC_R_SUCCESS) + goto failure; + } + + *ringp = ring; + return (ISC_R_SUCCESS); + + failure: + dns_tsigkeyring_destroy(&ring); + return (result); +} diff --git a/bin/named/unix/Makefile.in b/bin/named/unix/Makefile.in new file mode 100644 index 0000000..a18351a --- /dev/null +++ b/bin/named/unix/Makefile.in @@ -0,0 +1,36 @@ +# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 1999-2001 Internet Software Consortium. +# +# Permission to use, copy, modify, and 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: Makefile.in,v 1.8 2004/03/05 04:58:01 marka Exp $ + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +@BIND9_MAKE_INCLUDES@ + +CINCLUDES = -I${srcdir}/include -I${srcdir}/../include \ + ${DNS_INCLUDES} ${ISC_INCLUDES} + +CDEFINES = +CWARNINGS = + +OBJS = os.@O@ + +SRCS = os.c + +TARGETS = ${OBJS} + +@BIND9_MAKE_RULES@ diff --git a/bin/named/unix/include/named/os.h b/bin/named/unix/include/named/os.h new file mode 100644 index 0000000..24afdcb --- /dev/null +++ b/bin/named/unix/include/named/os.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2002 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: os.h,v 1.22.18.3 2005/04/29 00:15:39 marka Exp $ */ + +#ifndef NS_OS_H +#define NS_OS_H 1 + +/*! \file */ + +#include + +void +ns_os_init(const char *progname); + +void +ns_os_daemonize(void); + +void +ns_os_opendevnull(void); + +void +ns_os_closedevnull(void); + +void +ns_os_chroot(const char *root); + +void +ns_os_inituserinfo(const char *username); + +void +ns_os_changeuser(void); + +void +ns_os_minprivs(void); + +void +ns_os_writepidfile(const char *filename, isc_boolean_t first_time); + +void +ns_os_shutdown(void); + +isc_result_t +ns_os_gethostname(char *buf, size_t len); + +void +ns_os_shutdownmsg(char *command, isc_buffer_t *text); + +void +ns_os_tzset(void); + +void +ns_os_started(void); + +#endif /* NS_OS_H */ diff --git a/bin/named/unix/os.c b/bin/named/unix/os.c new file mode 100644 index 0000000..3864612 --- /dev/null +++ b/bin/named/unix/os.c @@ -0,0 +1,691 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2002 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: os.c,v 1.66.18.11 2006/02/03 23:51:38 marka Exp $ */ + +/*! \file */ + +#include +#include + +#include /* dev_t FreeBSD 2.1 */ +#include + +#include +#include +#include +#include /* Required for initgroups() on IRIX. */ +#include +#include +#include +#include +#include +#ifdef HAVE_TZSET +#include +#endif +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#ifdef HAVE_LIBSCF +#include +#endif + +static char *pidfile = NULL; +static int devnullfd = -1; + +#ifndef ISC_FACILITY +#define ISC_FACILITY LOG_DAEMON +#endif + +/* + * If there's no , we don't care about + */ +#ifndef HAVE_LINUX_CAPABILITY_H +#undef HAVE_SYS_PRCTL_H +#endif + +/* + * Linux defines: + * (T) HAVE_LINUXTHREADS + * (C) HAVE_LINUX_CAPABILITY_H + * (P) HAVE_SYS_PRCTL_H + * The possible cases are: + * none: setuid() normally + * T: no setuid() + * C: setuid() normally, drop caps (keep CAP_SETUID) + * T+C: no setuid(), drop caps (don't keep CAP_SETUID) + * T+C+P: setuid() early, drop caps (keep CAP_SETUID) + * C+P: setuid() normally, drop caps (keep CAP_SETUID) + * P: not possible + * T+P: not possible + * + * if (C) + * caps = BIND_SERVICE + CHROOT + SETGID + * if ((T && C && P) || !T) + * caps += SETUID + * endif + * capset(caps) + * endif + * if (T && C && P && -u) + * setuid() + * else if (T && -u) + * fail + * --> start threads + * if (!T && -u) + * setuid() + * if (C && (P || !-u)) + * caps = BIND_SERVICE + * capset(caps) + * endif + * + * It will be nice when Linux threads work properly with setuid(). + */ + +#ifdef HAVE_LINUXTHREADS +static pid_t mainpid = 0; +#endif + +static struct passwd *runas_pw = NULL; +static isc_boolean_t done_setuid = ISC_FALSE; +static int dfd[2] = { -1, -1 }; + +#ifdef HAVE_LINUX_CAPABILITY_H + +static isc_boolean_t non_root = ISC_FALSE; +static isc_boolean_t non_root_caps = ISC_FALSE; + +/*% + * We define _LINUX_FS_H to prevent it from being included. We don't need + * anything from it, and the files it includes cause warnings with 2.2 + * kernels, and compilation failures (due to conflicts between + * and ) on 2.3 kernels. + */ +#define _LINUX_FS_H + +#include /* Required for syscall(). */ +#include /* Required for _LINUX_CAPABILITY_VERSION. */ + +#ifdef HAVE_SYS_PRCTL_H +#include /* Required for prctl(). */ + +/* + * If the value of PR_SET_KEEPCAPS is not in , define it + * here. This allows setuid() to work on systems running a new enough + * kernel but with /usr/include/linux pointing to "standard" kernel + * headers. + */ +#ifndef PR_SET_KEEPCAPS +#define PR_SET_KEEPCAPS 8 +#endif + +#endif /* HAVE_SYS_PRCTL_H */ + +#ifndef SYS_capset +#ifndef __NR_capset +#include /* Slackware 4.0 needs this. */ +#endif +#define SYS_capset __NR_capset +#endif + +static void +linux_setcaps(unsigned int caps) { + struct __user_cap_header_struct caphead; + struct __user_cap_data_struct cap; + char strbuf[ISC_STRERRORSIZE]; + + if ((getuid() != 0 && !non_root_caps) || non_root) + return; + + memset(&caphead, 0, sizeof(caphead)); + caphead.version = _LINUX_CAPABILITY_VERSION; + caphead.pid = 0; + memset(&cap, 0, sizeof(cap)); + cap.effective = caps; + cap.permitted = caps; + cap.inheritable = 0; + if (syscall(SYS_capset, &caphead, &cap) < 0) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + ns_main_earlyfatal("capset failed: %s:" + " please ensure that the capset kernel" + " module is loaded. see insmod(8)", + strbuf); + } +} + +static void +linux_initialprivs(void) { + unsigned int caps; + + /*% + * We don't need most privileges, so we drop them right away. + * Later on linux_minprivs() will be called, which will drop our + * capabilities to the minimum needed to run the server. + */ + + caps = 0; + + /* + * We need to be able to bind() to privileged ports, notably port 53! + */ + caps |= (1 << CAP_NET_BIND_SERVICE); + + /* + * We need chroot() initially too. + */ + caps |= (1 << CAP_SYS_CHROOT); + +#if defined(HAVE_SYS_PRCTL_H) || !defined(HAVE_LINUXTHREADS) + /* + * We can setuid() only if either the kernel supports keeping + * capabilities after setuid() (which we don't know until we've + * tried) or we're not using threads. If either of these is + * true, we want the setuid capability. + */ + caps |= (1 << CAP_SETUID); +#endif + + /* + * Since we call initgroups, we need this. + */ + caps |= (1 << CAP_SETGID); + + /* + * Without this, we run into problems reading a configuration file + * owned by a non-root user and non-world-readable on startup. + */ + caps |= (1 << CAP_DAC_READ_SEARCH); + + /* + * XXX We might want to add CAP_SYS_RESOURCE, though it's not + * clear it would work right given the way linuxthreads work. + * XXXDCL But since we need to be able to set the maximum number + * of files, the stack size, data size, and core dump size to + * support named.conf options, this is now being added to test. + */ + caps |= (1 << CAP_SYS_RESOURCE); + + linux_setcaps(caps); +} + +static void +linux_minprivs(void) { + unsigned int caps; + + /*% + * Drop all privileges except the ability to bind() to privileged + * ports. + * + * It's important that we drop CAP_SYS_CHROOT. If we didn't, it + * chroot() could be used to escape from the chrooted area. + */ + + caps = 0; + caps |= (1 << CAP_NET_BIND_SERVICE); + + /* + * XXX We might want to add CAP_SYS_RESOURCE, though it's not + * clear it would work right given the way linuxthreads work. + * XXXDCL But since we need to be able to set the maximum number + * of files, the stack size, data size, and core dump size to + * support named.conf options, this is now being added to test. + */ + caps |= (1 << CAP_SYS_RESOURCE); + + linux_setcaps(caps); +} + +#ifdef HAVE_SYS_PRCTL_H +static void +linux_keepcaps(void) { + char strbuf[ISC_STRERRORSIZE]; + /*% + * Ask the kernel to allow us to keep our capabilities after we + * setuid(). + */ + + if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) { + if (errno != EINVAL) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + ns_main_earlyfatal("prctl() failed: %s", strbuf); + } + } else { + non_root_caps = ISC_TRUE; + if (getuid() != 0) + non_root = ISC_TRUE; + } +} +#endif + +#endif /* HAVE_LINUX_CAPABILITY_H */ + + +static void +setup_syslog(const char *progname) { + int options; + + options = LOG_PID; +#ifdef LOG_NDELAY + options |= LOG_NDELAY; +#endif + openlog(isc_file_basename(progname), options, ISC_FACILITY); +} + +void +ns_os_init(const char *progname) { + setup_syslog(progname); +#ifdef HAVE_LINUX_CAPABILITY_H + linux_initialprivs(); +#endif +#ifdef HAVE_LINUXTHREADS + mainpid = getpid(); +#endif +#ifdef SIGXFSZ + signal(SIGXFSZ, SIG_IGN); +#endif +} + +void +ns_os_daemonize(void) { + pid_t pid; + char strbuf[ISC_STRERRORSIZE]; + + if (pipe(dfd) == -1) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + ns_main_earlyfatal("pipe(): %s", strbuf); + } + + pid = fork(); + if (pid == -1) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + ns_main_earlyfatal("fork(): %s", strbuf); + } + if (pid != 0) { + int n; + /* + * Wait for the child to finish loading for the first time. + * This would be so much simpler if fork() worked once we + * were multi-threaded. + */ + (void)close(dfd[1]); + do { + char buf; + n = read(dfd[0], &buf, 1); + if (n == 1) + _exit(0); + } while (n == -1 && errno == EINTR); + _exit(1); + } + (void)close(dfd[0]); + + /* + * We're the child. + */ + +#ifdef HAVE_LINUXTHREADS + mainpid = getpid(); +#endif + + if (setsid() == -1) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + ns_main_earlyfatal("setsid(): %s", strbuf); + } + + /* + * Try to set stdin, stdout, and stderr to /dev/null, but press + * on even if it fails. + * + * XXXMLG The close() calls here are unneeded on all but NetBSD, but + * are harmless to include everywhere. dup2() is supposed to close + * the FD if it is in use, but unproven-pthreads-0.16 is broken + * and will end up closing the wrong FD. This will be fixed eventually, + * and these calls will be removed. + */ + if (devnullfd != -1) { + if (devnullfd != STDIN_FILENO) { + (void)close(STDIN_FILENO); + (void)dup2(devnullfd, STDIN_FILENO); + } + if (devnullfd != STDOUT_FILENO) { + (void)close(STDOUT_FILENO); + (void)dup2(devnullfd, STDOUT_FILENO); + } + if (devnullfd != STDERR_FILENO) { + (void)close(STDERR_FILENO); + (void)dup2(devnullfd, STDERR_FILENO); + } + } +} + +void +ns_os_started(void) { + char buf = 0; + + /* + * Signal to the parent that we stated successfully. + */ + if (dfd[0] != -1 && dfd[1] != -1) { + write(dfd[1], &buf, 1); + close(dfd[1]); + dfd[0] = dfd[1] = -1; + } +} + +void +ns_os_opendevnull(void) { + devnullfd = open("/dev/null", O_RDWR, 0); +} + +void +ns_os_closedevnull(void) { + if (devnullfd != STDIN_FILENO && + devnullfd != STDOUT_FILENO && + devnullfd != STDERR_FILENO) { + close(devnullfd); + devnullfd = -1; + } +} + +static isc_boolean_t +all_digits(const char *s) { + if (*s == '\0') + return (ISC_FALSE); + while (*s != '\0') { + if (!isdigit((*s)&0xff)) + return (ISC_FALSE); + s++; + } + return (ISC_TRUE); +} + +void +ns_os_chroot(const char *root) { + char strbuf[ISC_STRERRORSIZE]; +#ifdef HAVE_LIBSCF + ns_smf_chroot = 0; +#endif + if (root != NULL) { + if (chroot(root) < 0) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + ns_main_earlyfatal("chroot(): %s", strbuf); + } + if (chdir("/") < 0) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + ns_main_earlyfatal("chdir(/): %s", strbuf); + } +#ifdef HAVE_LIBSCF + /* Set ns_smf_chroot flag on successful chroot. */ + ns_smf_chroot = 1; +#endif + } +} + +void +ns_os_inituserinfo(const char *username) { + char strbuf[ISC_STRERRORSIZE]; + if (username == NULL) + return; + + if (all_digits(username)) + runas_pw = getpwuid((uid_t)atoi(username)); + else + runas_pw = getpwnam(username); + endpwent(); + + if (runas_pw == NULL) + ns_main_earlyfatal("user '%s' unknown", username); + + if (getuid() == 0) { + if (initgroups(runas_pw->pw_name, runas_pw->pw_gid) < 0) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + ns_main_earlyfatal("initgroups(): %s", strbuf); + } + } + +} + +void +ns_os_changeuser(void) { + char strbuf[ISC_STRERRORSIZE]; + if (runas_pw == NULL || done_setuid) + return; + + done_setuid = ISC_TRUE; + +#ifdef HAVE_LINUXTHREADS +#ifdef HAVE_LINUX_CAPABILITY_H + if (!non_root_caps) + ns_main_earlyfatal("-u with Linux threads not supported: " + "requires kernel support for " + "prctl(PR_SET_KEEPCAPS)"); +#else + ns_main_earlyfatal("-u with Linux threads not supported: " + "no capabilities support or capabilities " + "disabled at build time"); +#endif +#endif + + if (setgid(runas_pw->pw_gid) < 0) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + ns_main_earlyfatal("setgid(): %s", strbuf); + } + + if (setuid(runas_pw->pw_uid) < 0) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + ns_main_earlyfatal("setuid(): %s", strbuf); + } + +#if defined(HAVE_LINUX_CAPABILITY_H) && !defined(HAVE_LINUXTHREADS) + linux_minprivs(); +#endif +#if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_DUMPABLE) + /* + * Restore the ability of named to drop core after the setuid() + * call has disabled it. + */ + prctl(PR_SET_DUMPABLE,1,0,0,0); +#endif +} + +void +ns_os_minprivs(void) { +#ifdef HAVE_SYS_PRCTL_H + linux_keepcaps(); +#endif + +#ifdef HAVE_LINUXTHREADS + ns_os_changeuser(); /* Call setuid() before threads are started */ +#endif + +#if defined(HAVE_LINUX_CAPABILITY_H) && defined(HAVE_LINUXTHREADS) + linux_minprivs(); +#endif +} + +static int +safe_open(const char *filename, isc_boolean_t append) { + int fd; + struct stat sb; + + if (stat(filename, &sb) == -1) { + if (errno != ENOENT) + return (-1); + } else if ((sb.st_mode & S_IFREG) == 0) { + errno = EOPNOTSUPP; + return (-1); + } + + if (append) + fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, + S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); + else { + (void)unlink(filename); + fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, + S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); + } + return (fd); +} + +static void +cleanup_pidfile(void) { + if (pidfile != NULL) { + (void)unlink(pidfile); + free(pidfile); + } + pidfile = NULL; +} + +void +ns_os_writepidfile(const char *filename, isc_boolean_t first_time) { + int fd; + FILE *lockfile; + size_t len; + pid_t pid; + char strbuf[ISC_STRERRORSIZE]; + void (*report)(const char *, ...); + + /* + * The caller must ensure any required synchronization. + */ + + report = first_time ? ns_main_earlyfatal : ns_main_earlywarning; + + cleanup_pidfile(); + + if (filename == NULL) + return; + + len = strlen(filename); + pidfile = malloc(len + 1); + if (pidfile == NULL) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + (*report)("couldn't malloc '%s': %s", filename, strbuf); + return; + } + /* This is safe. */ + strcpy(pidfile, filename); + + fd = safe_open(filename, ISC_FALSE); + if (fd < 0) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + (*report)("couldn't open pid file '%s': %s", filename, strbuf); + free(pidfile); + pidfile = NULL; + return; + } + lockfile = fdopen(fd, "w"); + if (lockfile == NULL) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + (*report)("could not fdopen() pid file '%s': %s", + filename, strbuf); + (void)close(fd); + cleanup_pidfile(); + return; + } +#ifdef HAVE_LINUXTHREADS + pid = mainpid; +#else + pid = getpid(); +#endif + if (fprintf(lockfile, "%ld\n", (long)pid) < 0) { + (*report)("fprintf() to pid file '%s' failed", filename); + (void)fclose(lockfile); + cleanup_pidfile(); + return; + } + if (fflush(lockfile) == EOF) { + (*report)("fflush() to pid file '%s' failed", filename); + (void)fclose(lockfile); + cleanup_pidfile(); + return; + } + (void)fclose(lockfile); +} + +void +ns_os_shutdown(void) { + closelog(); + cleanup_pidfile(); +} + +isc_result_t +ns_os_gethostname(char *buf, size_t len) { + int n; + + n = gethostname(buf, len); + return ((n == 0) ? ISC_R_SUCCESS : ISC_R_FAILURE); +} + +static char * +next_token(char **stringp, const char *delim) { + char *res; + + do { + res = strsep(stringp, delim); + if (res == NULL) + break; + } while (*res == '\0'); + return (res); +} + +void +ns_os_shutdownmsg(char *command, isc_buffer_t *text) { + char *input, *ptr; + unsigned int n; + pid_t pid; + + input = command; + + /* Skip the command name. */ + ptr = next_token(&input, " \t"); + if (ptr == NULL) + return; + + ptr = next_token(&input, " \t"); + if (ptr == NULL) + return; + + if (strcmp(ptr, "-p") != 0) + return; + +#ifdef HAVE_LINUXTHREADS + pid = mainpid; +#else + pid = getpid(); +#endif + + n = snprintf((char *)isc_buffer_used(text), + isc_buffer_availablelength(text), + "pid: %ld", (long)pid); + /* Only send a message if it is complete. */ + if (n < isc_buffer_availablelength(text)) + isc_buffer_add(text, n); +} + +void +ns_os_tzset(void) { +#ifdef HAVE_TZSET + tzset(); +#endif +} diff --git a/bin/named/update.c b/bin/named/update.c new file mode 100644 index 0000000..98054f8 --- /dev/null +++ b/bin/named/update.c @@ -0,0 +1,3026 @@ +/* + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-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: update.c,v 1.109.18.23 2007/08/28 07:20:01 tbox Exp $ */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file + * \brief + * This module implements dynamic update as in RFC2136. + */ + +/* + XXX TODO: + - document strict minimality +*/ + +/**************************************************************************/ + +/*% + * Log level for tracing dynamic update protocol requests. + */ +#define LOGLEVEL_PROTOCOL ISC_LOG_INFO + +/*% + * Log level for low-level debug tracing. + */ +#define LOGLEVEL_DEBUG ISC_LOG_DEBUG(8) + +/*% + * Check an operation for failure. These macros all assume that + * the function using them has a 'result' variable and a 'failure' + * label. + */ +#define CHECK(op) \ + do { result = (op); \ + if (result != ISC_R_SUCCESS) goto failure; \ + } while (0) + +/*% + * Fail unconditionally with result 'code', which must not + * be ISC_R_SUCCESS. The reason for failure presumably has + * been logged already. + * + * The test against ISC_R_SUCCESS is there to keep the Solaris compiler + * from complaining about "end-of-loop code not reached". + */ + +#define FAIL(code) \ + do { \ + result = (code); \ + if (result != ISC_R_SUCCESS) goto failure; \ + } while (0) + +/*% + * Fail unconditionally and log as a client error. + * The test against ISC_R_SUCCESS is there to keep the Solaris compiler + * from complaining about "end-of-loop code not reached". + */ +#define FAILC(code, msg) \ + do { \ + const char *_what = "failed"; \ + result = (code); \ + switch (result) { \ + case DNS_R_NXDOMAIN: \ + case DNS_R_YXDOMAIN: \ + case DNS_R_YXRRSET: \ + case DNS_R_NXRRSET: \ + _what = "unsuccessful"; \ + } \ + update_log(client, zone, LOGLEVEL_PROTOCOL, \ + "update %s: %s (%s)", _what, \ + msg, isc_result_totext(result)); \ + if (result != ISC_R_SUCCESS) goto failure; \ + } while (0) + +#define FAILN(code, name, msg) \ + do { \ + const char *_what = "failed"; \ + result = (code); \ + switch (result) { \ + case DNS_R_NXDOMAIN: \ + case DNS_R_YXDOMAIN: \ + case DNS_R_YXRRSET: \ + case DNS_R_NXRRSET: \ + _what = "unsuccessful"; \ + } \ + if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { \ + char _nbuf[DNS_NAME_FORMATSIZE]; \ + dns_name_format(name, _nbuf, sizeof(_nbuf)); \ + update_log(client, zone, LOGLEVEL_PROTOCOL, \ + "update %s: %s: %s (%s)", _what, _nbuf, \ + msg, isc_result_totext(result)); \ + } \ + if (result != ISC_R_SUCCESS) goto failure; \ + } while (0) + +#define FAILNT(code, name, type, msg) \ + do { \ + const char *_what = "failed"; \ + result = (code); \ + switch (result) { \ + case DNS_R_NXDOMAIN: \ + case DNS_R_YXDOMAIN: \ + case DNS_R_YXRRSET: \ + case DNS_R_NXRRSET: \ + _what = "unsuccessful"; \ + } \ + if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { \ + char _nbuf[DNS_NAME_FORMATSIZE]; \ + char _tbuf[DNS_RDATATYPE_FORMATSIZE]; \ + dns_name_format(name, _nbuf, sizeof(_nbuf)); \ + dns_rdatatype_format(type, _tbuf, sizeof(_tbuf)); \ + update_log(client, zone, LOGLEVEL_PROTOCOL, \ + "update %s: %s/%s: %s (%s)", \ + _what, _nbuf, _tbuf, msg, \ + isc_result_totext(result)); \ + } \ + if (result != ISC_R_SUCCESS) goto failure; \ + } while (0) +/*% + * Fail unconditionally and log as a server error. + * The test against ISC_R_SUCCESS is there to keep the Solaris compiler + * from complaining about "end-of-loop code not reached". + */ +#define FAILS(code, msg) \ + do { \ + result = (code); \ + update_log(client, zone, LOGLEVEL_PROTOCOL, \ + "error: %s: %s", \ + msg, isc_result_totext(result)); \ + if (result != ISC_R_SUCCESS) goto failure; \ + } while (0) + +/**************************************************************************/ + +typedef struct rr rr_t; + +struct rr { + /* dns_name_t name; */ + isc_uint32_t ttl; + dns_rdata_t rdata; +}; + +typedef struct update_event update_event_t; + +struct update_event { + ISC_EVENT_COMMON(update_event_t); + dns_zone_t *zone; + isc_result_t result; + dns_message_t *answer; +}; + +/**************************************************************************/ +/* + * Forward declarations. + */ + +static void update_action(isc_task_t *task, isc_event_t *event); +static void updatedone_action(isc_task_t *task, isc_event_t *event); +static isc_result_t send_forward_event(ns_client_t *client, dns_zone_t *zone); +static void forward_done(isc_task_t *task, isc_event_t *event); + +/**************************************************************************/ + +static void +update_log(ns_client_t *client, dns_zone_t *zone, + int level, const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5); + +static void +update_log(ns_client_t *client, dns_zone_t *zone, + int level, const char *fmt, ...) +{ + va_list ap; + char message[4096]; + char namebuf[DNS_NAME_FORMATSIZE]; + char classbuf[DNS_RDATACLASS_FORMATSIZE]; + + if (client == NULL || zone == NULL) + return; + + if (isc_log_wouldlog(ns_g_lctx, level) == ISC_FALSE) + return; + + dns_name_format(dns_zone_getorigin(zone), namebuf, + sizeof(namebuf)); + dns_rdataclass_format(dns_zone_getclass(zone), classbuf, + sizeof(classbuf)); + + va_start(ap, fmt); + vsnprintf(message, sizeof(message), fmt, ap); + va_end(ap); + + ns_client_log(client, NS_LOGCATEGORY_UPDATE, NS_LOGMODULE_UPDATE, + level, "updating zone '%s/%s': %s", + namebuf, classbuf, message); +} + +static isc_result_t +checkupdateacl(ns_client_t *client, dns_acl_t *acl, const char *message, + dns_name_t *zonename, isc_boolean_t slave) +{ + char namebuf[DNS_NAME_FORMATSIZE]; + char classbuf[DNS_RDATACLASS_FORMATSIZE]; + int level = ISC_LOG_ERROR; + const char *msg = "denied"; + isc_result_t result; + + if (slave && acl == NULL) { + result = DNS_R_NOTIMP; + level = ISC_LOG_DEBUG(3); + msg = "disabled"; + } else + result = ns_client_checkaclsilent(client, acl, ISC_FALSE); + + if (result == ISC_R_SUCCESS) { + level = ISC_LOG_DEBUG(3); + msg = "approved"; + } + + dns_name_format(zonename, namebuf, sizeof(namebuf)); + dns_rdataclass_format(client->view->rdclass, classbuf, + sizeof(classbuf)); + + ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY, + NS_LOGMODULE_UPDATE, level, "%s '%s/%s' %s", + message, namebuf, classbuf, msg); + return (result); +} + +/*% + * Update a single RR in version 'ver' of 'db' and log the + * update in 'diff'. + * + * Ensures: + * \li '*tuple' == NULL. Either the tuple is freed, or its + * ownership has been transferred to the diff. + */ +static isc_result_t +do_one_tuple(dns_difftuple_t **tuple, + dns_db_t *db, dns_dbversion_t *ver, + dns_diff_t *diff) +{ + dns_diff_t temp_diff; + isc_result_t result; + + /* + * Create a singleton diff. + */ + dns_diff_init(diff->mctx, &temp_diff); + ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); + + /* + * Apply it to the database. + */ + result = dns_diff_apply(&temp_diff, db, ver); + ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); + if (result != ISC_R_SUCCESS) { + dns_difftuple_free(tuple); + return (result); + } + + /* + * Merge it into the current pending journal entry. + */ + dns_diff_appendminimal(diff, tuple); + + /* + * Do not clear temp_diff. + */ + return (ISC_R_SUCCESS); +} + +/*% + * Perform the updates in 'updates' in version 'ver' of 'db' and log the + * update in 'diff'. + * + * Ensures: + * \li 'updates' is empty. + */ +static isc_result_t +do_diff(dns_diff_t *updates, dns_db_t *db, dns_dbversion_t *ver, + dns_diff_t *diff) +{ + isc_result_t result; + while (! ISC_LIST_EMPTY(updates->tuples)) { + dns_difftuple_t *t = ISC_LIST_HEAD(updates->tuples); + ISC_LIST_UNLINK(updates->tuples, t, link); + CHECK(do_one_tuple(&t, db, ver, diff)); + } + return (ISC_R_SUCCESS); + + failure: + dns_diff_clear(diff); + return (result); +} + +static isc_result_t +update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, + dns_diffop_t op, dns_name_t *name, + dns_ttl_t ttl, dns_rdata_t *rdata) +{ + dns_difftuple_t *tuple = NULL; + isc_result_t result; + result = dns_difftuple_create(diff->mctx, op, + name, ttl, rdata, &tuple); + if (result != ISC_R_SUCCESS) + return (result); + return (do_one_tuple(&tuple, db, ver, diff)); +} + +/**************************************************************************/ +/* + * Callback-style iteration over rdatasets and rdatas. + * + * foreach_rrset() can be used to iterate over the RRsets + * of a name and call a callback function with each + * one. Similarly, foreach_rr() can be used to iterate + * over the individual RRs at name, optionally restricted + * to RRs of a given type. + * + * The callback functions are called "actions" and take + * two arguments: a void pointer for passing arbitrary + * context information, and a pointer to the current RRset + * or RR. By convention, their names end in "_action". + */ + +/* + * XXXRTH We might want to make this public somewhere in libdns. + */ + +/*% + * Function type for foreach_rrset() iterator actions. + */ +typedef isc_result_t rrset_func(void *data, dns_rdataset_t *rrset); + +/*% + * Function type for foreach_rr() iterator actions. + */ +typedef isc_result_t rr_func(void *data, rr_t *rr); + +/*% + * Internal context struct for foreach_node_rr(). + */ +typedef struct { + rr_func * rr_action; + void * rr_action_data; +} foreach_node_rr_ctx_t; + +/*% + * Internal helper function for foreach_node_rr(). + */ +static isc_result_t +foreach_node_rr_action(void *data, dns_rdataset_t *rdataset) { + isc_result_t result; + foreach_node_rr_ctx_t *ctx = data; + for (result = dns_rdataset_first(rdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(rdataset)) + { + rr_t rr = { 0, DNS_RDATA_INIT }; + + dns_rdataset_current(rdataset, &rr.rdata); + rr.ttl = rdataset->ttl; + result = (*ctx->rr_action)(ctx->rr_action_data, &rr); + if (result != ISC_R_SUCCESS) + return (result); + } + if (result != ISC_R_NOMORE) + return (result); + return (ISC_R_SUCCESS); +} + +/*% + * For each rdataset of 'name' in 'ver' of 'db', call 'action' + * with the rdataset and 'action_data' as arguments. If the name + * does not exist, do nothing. + * + * If 'action' returns an error, abort iteration and return the error. + */ +static isc_result_t +foreach_rrset(dns_db_t *db, + dns_dbversion_t *ver, + dns_name_t *name, + rrset_func *action, + void *action_data) +{ + isc_result_t result; + dns_dbnode_t *node; + dns_rdatasetiter_t *iter; + + node = NULL; + result = dns_db_findnode(db, name, ISC_FALSE, &node); + if (result == ISC_R_NOTFOUND) + return (ISC_R_SUCCESS); + if (result != ISC_R_SUCCESS) + return (result); + + iter = NULL; + result = dns_db_allrdatasets(db, node, ver, + (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)) + { + dns_rdataset_t rdataset; + + dns_rdataset_init(&rdataset); + dns_rdatasetiter_current(iter, &rdataset); + + result = (*action)(action_data, &rdataset); + + dns_rdataset_disassociate(&rdataset); + if (result != ISC_R_SUCCESS) + goto cleanup_iterator; + } + if (result == ISC_R_NOMORE) + result = ISC_R_SUCCESS; + + cleanup_iterator: + dns_rdatasetiter_destroy(&iter); + + cleanup_node: + dns_db_detachnode(db, &node); + + return (result); +} + +/*% + * For each RR of 'name' in 'ver' of 'db', call 'action' + * with the RR and 'action_data' as arguments. If the name + * does not exist, do nothing. + * + * If 'action' returns an error, abort iteration + * and return the error. + */ +static isc_result_t +foreach_node_rr(dns_db_t *db, + dns_dbversion_t *ver, + dns_name_t *name, + rr_func *rr_action, + void *rr_action_data) +{ + foreach_node_rr_ctx_t ctx; + ctx.rr_action = rr_action; + ctx.rr_action_data = rr_action_data; + return (foreach_rrset(db, ver, name, + foreach_node_rr_action, &ctx)); +} + + +/*% + * For each of the RRs specified by 'db', 'ver', 'name', 'type', + * (which can be dns_rdatatype_any to match any type), and 'covers', call + * 'action' with the RR and 'action_data' as arguments. If the name + * does not exist, or if no RRset of the given type exists at the name, + * do nothing. + * + * If 'action' returns an error, abort iteration and return the error. + */ +static isc_result_t +foreach_rr(dns_db_t *db, + dns_dbversion_t *ver, + dns_name_t *name, + dns_rdatatype_t type, + dns_rdatatype_t covers, + rr_func *rr_action, + void *rr_action_data) +{ + + isc_result_t result; + dns_dbnode_t *node; + dns_rdataset_t rdataset; + + if (type == dns_rdatatype_any) + return (foreach_node_rr(db, ver, name, + rr_action, rr_action_data)); + + node = NULL; + result = dns_db_findnode(db, name, ISC_FALSE, &node); + if (result == ISC_R_NOTFOUND) + return (ISC_R_SUCCESS); + if (result != ISC_R_SUCCESS) + return (result); + + dns_rdataset_init(&rdataset); + result = dns_db_findrdataset(db, node, ver, type, covers, + (isc_stdtime_t) 0, &rdataset, NULL); + if (result == ISC_R_NOTFOUND) { + result = ISC_R_SUCCESS; + goto cleanup_node; + } + if (result != ISC_R_SUCCESS) + goto cleanup_node; + + for (result = dns_rdataset_first(&rdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(&rdataset)) + { + rr_t rr = { 0, DNS_RDATA_INIT }; + dns_rdataset_current(&rdataset, &rr.rdata); + rr.ttl = rdataset.ttl; + result = (*rr_action)(rr_action_data, &rr); + if (result != ISC_R_SUCCESS) + goto cleanup_rdataset; + } + if (result != ISC_R_NOMORE) + goto cleanup_rdataset; + result = ISC_R_SUCCESS; + + cleanup_rdataset: + dns_rdataset_disassociate(&rdataset); + cleanup_node: + dns_db_detachnode(db, &node); + + return (result); +} + +/**************************************************************************/ +/* + * Various tests on the database contents (for prerequisites, etc). + */ + +/*% + * Function type for predicate functions that compare a database RR 'db_rr' + * against an update RR 'update_rr'. + */ +typedef isc_boolean_t rr_predicate(dns_rdata_t *update_rr, dns_rdata_t *db_rr); + +/*% + * Helper function for rrset_exists(). + */ +static isc_result_t +rrset_exists_action(void *data, rr_t *rr) { + UNUSED(data); + UNUSED(rr); + return (ISC_R_EXISTS); +} + +/*% + * Utility macro for RR existence checking functions. + * + * If the variable 'result' has the value ISC_R_EXISTS or + * ISC_R_SUCCESS, set *exists to ISC_TRUE or ISC_FALSE, + * respectively, and return success. + * + * If 'result' has any other value, there was a failure. + * Return the failure result code and do not set *exists. + * + * This would be more readable as "do { if ... } while(0)", + * but that form generates tons of warnings on Solaris 2.6. + */ +#define RETURN_EXISTENCE_FLAG \ + return ((result == ISC_R_EXISTS) ? \ + (*exists = ISC_TRUE, ISC_R_SUCCESS) : \ + ((result == ISC_R_SUCCESS) ? \ + (*exists = ISC_FALSE, ISC_R_SUCCESS) : \ + result)) + +/*% + * Set '*exists' to true iff an rrset of the given type exists, + * to false otherwise. + */ +static isc_result_t +rrset_exists(dns_db_t *db, dns_dbversion_t *ver, + dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers, + isc_boolean_t *exists) +{ + isc_result_t result; + result = foreach_rr(db, ver, name, type, covers, + rrset_exists_action, NULL); + RETURN_EXISTENCE_FLAG; +} + +/*% + * Helper function for cname_incompatible_rrset_exists. + */ +static isc_result_t +cname_compatibility_action(void *data, dns_rdataset_t *rrset) { + UNUSED(data); + if (rrset->type != dns_rdatatype_cname && + ! dns_rdatatype_isdnssec(rrset->type)) + return (ISC_R_EXISTS); + return (ISC_R_SUCCESS); +} + +/*% + * Check whether there is an rrset incompatible with adding a CNAME RR, + * i.e., anything but another CNAME (which can be replaced) or a + * DNSSEC RR (which can coexist). + * + * If such an incompatible rrset exists, set '*exists' to ISC_TRUE. + * Otherwise, set it to ISC_FALSE. + */ +static isc_result_t +cname_incompatible_rrset_exists(dns_db_t *db, dns_dbversion_t *ver, + dns_name_t *name, isc_boolean_t *exists) { + isc_result_t result; + result = foreach_rrset(db, ver, name, + cname_compatibility_action, NULL); + RETURN_EXISTENCE_FLAG; +} + +/*% + * Helper function for rr_count(). + */ +static isc_result_t +count_rr_action(void *data, rr_t *rr) { + int *countp = data; + UNUSED(rr); + (*countp)++; + return (ISC_R_SUCCESS); +} + +/*% + * Count the number of RRs of 'type' belonging to 'name' in 'ver' of 'db'. + */ +static isc_result_t +rr_count(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, + dns_rdatatype_t type, dns_rdatatype_t covers, int *countp) +{ + *countp = 0; + return (foreach_rr(db, ver, name, type, covers, + count_rr_action, countp)); +} + +/*% + * Context struct and helper function for name_exists(). + */ + +static isc_result_t +name_exists_action(void *data, dns_rdataset_t *rrset) { + UNUSED(data); + UNUSED(rrset); + return (ISC_R_EXISTS); +} + +/*% + * Set '*exists' to true iff the given name exists, to false otherwise. + */ +static isc_result_t +name_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, + isc_boolean_t *exists) +{ + isc_result_t result; + result = foreach_rrset(db, ver, name, + name_exists_action, NULL); + RETURN_EXISTENCE_FLAG; +} + +typedef struct { + dns_name_t *name, *signer; + dns_ssutable_t *table; +} ssu_check_t; + +static isc_result_t +ssu_checkrule(void *data, dns_rdataset_t *rrset) { + ssu_check_t *ssuinfo = data; + isc_boolean_t result; + + /* + * If we're deleting all records, it's ok to delete RRSIG and NSEC even + * if we're normally not allowed to. + */ + if (rrset->type == dns_rdatatype_rrsig || + rrset->type == dns_rdatatype_nsec) + return (ISC_R_SUCCESS); + result = dns_ssutable_checkrules(ssuinfo->table, ssuinfo->signer, + ssuinfo->name, rrset->type); + return (result == ISC_TRUE ? ISC_R_SUCCESS : ISC_R_FAILURE); +} + +static isc_boolean_t +ssu_checkall(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, + dns_ssutable_t *ssutable, dns_name_t *signer) +{ + isc_result_t result; + ssu_check_t ssuinfo; + + ssuinfo.name = name; + ssuinfo.table = ssutable; + ssuinfo.signer = signer; + result = foreach_rrset(db, ver, name, ssu_checkrule, &ssuinfo); + return (ISC_TF(result == ISC_R_SUCCESS)); +} + +/**************************************************************************/ +/* + * Checking of "RRset exists (value dependent)" prerequisites. + * + * In the RFC2136 section 3.2.5, this is the pseudocode involving + * a variable called "temp", a mapping of tuples to rrsets. + * + * Here, we represent the "temp" data structure as (non-minimial) "dns_diff_t" + * where each typle has op==DNS_DIFFOP_EXISTS. + */ + + +/*% + * Append a tuple asserting the existence of the RR with + * 'name' and 'rdata' to 'diff'. + */ +static isc_result_t +temp_append(dns_diff_t *diff, dns_name_t *name, dns_rdata_t *rdata) { + isc_result_t result; + dns_difftuple_t *tuple = NULL; + + REQUIRE(DNS_DIFF_VALID(diff)); + CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_EXISTS, + name, 0, rdata, &tuple)); + ISC_LIST_APPEND(diff->tuples, tuple, link); + failure: + return (result); +} + +/*% + * Compare two rdatasets represented as sorted lists of tuples. + * All list elements must have the same owner name and type. + * Return ISC_R_SUCCESS if the rdatasets are equal, rcode(dns_rcode_nxrrset) + * if not. + */ +static isc_result_t +temp_check_rrset(dns_difftuple_t *a, dns_difftuple_t *b) { + for (;;) { + if (a == NULL || b == NULL) + break; + INSIST(a->op == DNS_DIFFOP_EXISTS && + b->op == DNS_DIFFOP_EXISTS); + INSIST(a->rdata.type == b->rdata.type); + INSIST(dns_name_equal(&a->name, &b->name)); + if (dns_rdata_compare(&a->rdata, &b->rdata) != 0) + return (DNS_R_NXRRSET); + a = ISC_LIST_NEXT(a, link); + b = ISC_LIST_NEXT(b, link); + } + if (a != NULL || b != NULL) + return (DNS_R_NXRRSET); + return (ISC_R_SUCCESS); +} + +/*% + * A comparison function defining the sorting order for the entries + * in the "temp" data structure. The major sort key is the owner name, + * followed by the type and rdata. + */ +static int +temp_order(const void *av, const void *bv) { + dns_difftuple_t const * const *ap = av; + dns_difftuple_t const * const *bp = bv; + dns_difftuple_t const *a = *ap; + dns_difftuple_t const *b = *bp; + int r; + r = dns_name_compare(&a->name, &b->name); + if (r != 0) + return (r); + r = (b->rdata.type - a->rdata.type); + if (r != 0) + return (r); + r = dns_rdata_compare(&a->rdata, &b->rdata); + return (r); +} + +/*% + * Check the "RRset exists (value dependent)" prerequisite information + * in 'temp' against the contents of the database 'db'. + * + * Return ISC_R_SUCCESS if the prerequisites are satisfied, + * rcode(dns_rcode_nxrrset) if not. + * + * 'temp' must be pre-sorted. + */ + +static isc_result_t +temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db, + dns_dbversion_t *ver, dns_name_t *tmpname, dns_rdatatype_t *typep) +{ + isc_result_t result; + dns_name_t *name; + dns_dbnode_t *node; + dns_difftuple_t *t; + dns_diff_t trash; + + dns_diff_init(mctx, &trash); + + /* + * For each name and type in the prerequisites, + * construct a sorted rdata list of the corresponding + * database contents, and compare the lists. + */ + t = ISC_LIST_HEAD(temp->tuples); + while (t != NULL) { + name = &t->name; + (void)dns_name_copy(name, tmpname, NULL); + *typep = t->rdata.type; + + /* A new unique name begins here. */ + node = NULL; + result = dns_db_findnode(db, name, ISC_FALSE, &node); + if (result == ISC_R_NOTFOUND) + return (DNS_R_NXRRSET); + if (result != ISC_R_SUCCESS) + return (result); + + /* A new unique type begins here. */ + while (t != NULL && dns_name_equal(&t->name, name)) { + dns_rdatatype_t type, covers; + dns_rdataset_t rdataset; + dns_diff_t d_rrs; /* Database RRs with + this name and type */ + dns_diff_t u_rrs; /* Update RRs with + this name and type */ + + *typep = type = t->rdata.type; + if (type == dns_rdatatype_rrsig || + type == dns_rdatatype_sig) + covers = dns_rdata_covers(&t->rdata); + else + covers = 0; + + /* + * Collect all database RRs for this name and type + * onto d_rrs and sort them. + */ + dns_rdataset_init(&rdataset); + result = dns_db_findrdataset(db, node, ver, type, + covers, (isc_stdtime_t) 0, + &rdataset, NULL); + if (result != ISC_R_SUCCESS) { + dns_db_detachnode(db, &node); + return (DNS_R_NXRRSET); + } + + dns_diff_init(mctx, &d_rrs); + dns_diff_init(mctx, &u_rrs); + + for (result = dns_rdataset_first(&rdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(&rdataset)) + { + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdataset_current(&rdataset, &rdata); + result = temp_append(&d_rrs, name, &rdata); + if (result != ISC_R_SUCCESS) + goto failure; + } + if (result != ISC_R_NOMORE) + goto failure; + result = dns_diff_sort(&d_rrs, temp_order); + if (result != ISC_R_SUCCESS) + goto failure; + + /* + * Collect all update RRs for this name and type + * onto u_rrs. No need to sort them here - + * they are already sorted. + */ + while (t != NULL && + dns_name_equal(&t->name, name) && + t->rdata.type == type) + { + dns_difftuple_t *next = + ISC_LIST_NEXT(t, link); + ISC_LIST_UNLINK(temp->tuples, t, link); + ISC_LIST_APPEND(u_rrs.tuples, t, link); + t = next; + } + + /* Compare the two sorted lists. */ + result = temp_check_rrset(ISC_LIST_HEAD(u_rrs.tuples), + ISC_LIST_HEAD(d_rrs.tuples)); + if (result != ISC_R_SUCCESS) + goto failure; + + /* + * We are done with the tuples, but we can't free + * them yet because "name" still points into one + * of them. Move them on a temporary list. + */ + ISC_LIST_APPENDLIST(trash.tuples, u_rrs.tuples, link); + ISC_LIST_APPENDLIST(trash.tuples, d_rrs.tuples, link); + dns_rdataset_disassociate(&rdataset); + + continue; + + failure: + dns_diff_clear(&d_rrs); + dns_diff_clear(&u_rrs); + dns_diff_clear(&trash); + dns_rdataset_disassociate(&rdataset); + dns_db_detachnode(db, &node); + return (result); + } + + dns_db_detachnode(db, &node); + } + + dns_diff_clear(&trash); + return (ISC_R_SUCCESS); +} + +/**************************************************************************/ +/* + * Conditional deletion of RRs. + */ + +/*% + * Context structure for delete_if(). + */ + +typedef struct { + rr_predicate *predicate; + dns_db_t *db; + dns_dbversion_t *ver; + dns_diff_t *diff; + dns_name_t *name; + dns_rdata_t *update_rr; +} conditional_delete_ctx_t; + +/*% + * Predicate functions for delete_if(). + */ + +/*% + * Return true iff 'db_rr' is neither a SOA nor an NS RR nor + * an RRSIG nor a NSEC. + */ +static isc_boolean_t +type_not_soa_nor_ns_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { + UNUSED(update_rr); + return ((db_rr->type != dns_rdatatype_soa && + db_rr->type != dns_rdatatype_ns && + db_rr->type != dns_rdatatype_rrsig && + db_rr->type != dns_rdatatype_nsec) ? + ISC_TRUE : ISC_FALSE); +} + +/*% + * Return true iff 'db_rr' is neither a RRSIG nor a NSEC. + */ +static isc_boolean_t +type_not_dnssec(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { + UNUSED(update_rr); + return ((db_rr->type != dns_rdatatype_rrsig && + db_rr->type != dns_rdatatype_nsec) ? + ISC_TRUE : ISC_FALSE); +} + +/*% + * Return true always. + */ +static isc_boolean_t +true_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { + UNUSED(update_rr); + UNUSED(db_rr); + return (ISC_TRUE); +} + +/*% + * Return true iff the two RRs have identical rdata. + */ +static isc_boolean_t +rr_equal_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { + /* + * XXXRTH This is not a problem, but we should consider creating + * dns_rdata_equal() (that used dns_name_equal()), since it + * would be faster. Not a priority. + */ + return (dns_rdata_compare(update_rr, db_rr) == 0 ? + ISC_TRUE : ISC_FALSE); +} + +/*% + * Return true iff 'update_rr' should replace 'db_rr' according + * to the special RFC2136 rules for CNAME, SOA, and WKS records. + * + * RFC2136 does not mention NSEC or DNAME, but multiple NSECs or DNAMEs + * make little sense, so we replace those, too. + */ +static isc_boolean_t +replaces_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { + if (db_rr->type != update_rr->type) + return (ISC_FALSE); + if (db_rr->type == dns_rdatatype_cname) + return (ISC_TRUE); + if (db_rr->type == dns_rdatatype_dname) + return (ISC_TRUE); + if (db_rr->type == dns_rdatatype_soa) + return (ISC_TRUE); + if (db_rr->type == dns_rdatatype_nsec) + return (ISC_TRUE); + if (db_rr->type == dns_rdatatype_wks) { + /* + * Compare the address and protocol fields only. These + * form the first five bytes of the RR data. Do a + * raw binary comparison; unpacking the WKS RRs using + * dns_rdata_tostruct() might be cleaner in some ways, + * but it would require us to pass around an mctx. + */ + INSIST(db_rr->length >= 5 && update_rr->length >= 5); + return (memcmp(db_rr->data, update_rr->data, 5) == 0 ? + ISC_TRUE : ISC_FALSE); + } + return (ISC_FALSE); +} + +/*% + * Internal helper function for delete_if(). + */ +static isc_result_t +delete_if_action(void *data, rr_t *rr) { + conditional_delete_ctx_t *ctx = data; + if ((*ctx->predicate)(ctx->update_rr, &rr->rdata)) { + isc_result_t result; + result = update_one_rr(ctx->db, ctx->ver, ctx->diff, + DNS_DIFFOP_DEL, ctx->name, + rr->ttl, &rr->rdata); + return (result); + } else { + return (ISC_R_SUCCESS); + } +} + +/*% + * Conditionally delete RRs. Apply 'predicate' to the RRs + * specified by 'db', 'ver', 'name', and 'type' (which can + * be dns_rdatatype_any to match any type). Delete those + * RRs for which the predicate returns true, and log the + * deletions in 'diff'. + */ +static isc_result_t +delete_if(rr_predicate *predicate, + dns_db_t *db, + dns_dbversion_t *ver, + dns_name_t *name, + dns_rdatatype_t type, + dns_rdatatype_t covers, + dns_rdata_t *update_rr, + dns_diff_t *diff) +{ + conditional_delete_ctx_t ctx; + ctx.predicate = predicate; + ctx.db = db; + ctx.ver = ver; + ctx.diff = diff; + ctx.name = name; + ctx.update_rr = update_rr; + return (foreach_rr(db, ver, name, type, covers, + delete_if_action, &ctx)); +} + +/**************************************************************************/ +/*% + * Prepare an RR for the addition of the new RR 'ctx->update_rr', + * with TTL 'ctx->update_rr_ttl', to its rdataset, by deleting + * the RRs if it is replaced by the new RR or has a conflicting TTL. + * The necessary changes are appended to ctx->del_diff and ctx->add_diff; + * we need to do all deletions before any additions so that we don't run + * into transient states with conflicting TTLs. + */ + +typedef struct { + dns_db_t *db; + dns_dbversion_t *ver; + dns_diff_t *diff; + dns_name_t *name; + dns_rdata_t *update_rr; + dns_ttl_t update_rr_ttl; + isc_boolean_t ignore_add; + dns_diff_t del_diff; + dns_diff_t add_diff; +} add_rr_prepare_ctx_t; + +static isc_result_t +add_rr_prepare_action(void *data, rr_t *rr) { + isc_result_t result = ISC_R_SUCCESS; + add_rr_prepare_ctx_t *ctx = data; + dns_difftuple_t *tuple = NULL; + isc_boolean_t equal; + + /* + * If the update RR is a "duplicate" of the update RR, + * the update should be silently ignored. + */ + equal = ISC_TF(dns_rdata_compare(&rr->rdata, ctx->update_rr) == 0); + if (equal && rr->ttl == ctx->update_rr_ttl) { + ctx->ignore_add = ISC_TRUE; + return (ISC_R_SUCCESS); + } + + /* + * If this RR is "equal" to the update RR, it should + * be deleted before the update RR is added. + */ + if (replaces_p(ctx->update_rr, &rr->rdata)) { + CHECK(dns_difftuple_create(ctx->del_diff.mctx, + DNS_DIFFOP_DEL, ctx->name, + rr->ttl, + &rr->rdata, + &tuple)); + dns_diff_append(&ctx->del_diff, &tuple); + return (ISC_R_SUCCESS); + } + + /* + * If this RR differs in TTL from the update RR, + * its TTL must be adjusted. + */ + if (rr->ttl != ctx->update_rr_ttl) { + CHECK(dns_difftuple_create(ctx->del_diff.mctx, + DNS_DIFFOP_DEL, ctx->name, + rr->ttl, + &rr->rdata, + &tuple)); + dns_diff_append(&ctx->del_diff, &tuple); + if (!equal) { + CHECK(dns_difftuple_create(ctx->add_diff.mctx, + DNS_DIFFOP_ADD, ctx->name, + ctx->update_rr_ttl, + &rr->rdata, + &tuple)); + dns_diff_append(&ctx->add_diff, &tuple); + } + } + failure: + return (result); +} + +/**************************************************************************/ +/* + * Miscellaneous subroutines. + */ + +/*% + * Extract a single update RR from 'section' of dynamic update message + * 'msg', with consistency checking. + * + * Stores the owner name, rdata, and TTL of the update RR at 'name', + * 'rdata', and 'ttl', respectively. + */ +static void +get_current_rr(dns_message_t *msg, dns_section_t section, + dns_rdataclass_t zoneclass, + dns_name_t **name, dns_rdata_t *rdata, dns_rdatatype_t *covers, + dns_ttl_t *ttl, + dns_rdataclass_t *update_class) +{ + dns_rdataset_t *rdataset; + isc_result_t result; + dns_message_currentname(msg, section, name); + rdataset = ISC_LIST_HEAD((*name)->list); + INSIST(rdataset != NULL); + INSIST(ISC_LIST_NEXT(rdataset, link) == NULL); + *covers = rdataset->covers; + *ttl = rdataset->ttl; + result = dns_rdataset_first(rdataset); + INSIST(result == ISC_R_SUCCESS); + dns_rdataset_current(rdataset, rdata); + INSIST(dns_rdataset_next(rdataset) == ISC_R_NOMORE); + *update_class = rdata->rdclass; + rdata->rdclass = zoneclass; +} + +/*% + * Increment the SOA serial number of database 'db', version 'ver'. + * Replace the SOA record in the database, and log the + * change in 'diff'. + */ + + /* + * XXXRTH Failures in this routine will be worth logging, when + * we have a logging system. Failure to find the zonename + * or the SOA rdataset warrant at least an UNEXPECTED_ERROR(). + */ + +static isc_result_t +increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver, + dns_diff_t *diff, isc_mem_t *mctx) +{ + dns_difftuple_t *deltuple = NULL; + dns_difftuple_t *addtuple = NULL; + isc_uint32_t serial; + isc_result_t result; + + CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple)); + CHECK(dns_difftuple_copy(deltuple, &addtuple)); + addtuple->op = DNS_DIFFOP_ADD; + + serial = dns_soa_getserial(&addtuple->rdata); + + /* RFC1982 */ + serial = (serial + 1) & 0xFFFFFFFF; + if (serial == 0) + serial = 1; + + dns_soa_setserial(serial, &addtuple->rdata); + CHECK(do_one_tuple(&deltuple, db, ver, diff)); + CHECK(do_one_tuple(&addtuple, db, ver, diff)); + result = ISC_R_SUCCESS; + + failure: + if (addtuple != NULL) + dns_difftuple_free(&addtuple); + if (deltuple != NULL) + dns_difftuple_free(&deltuple); + return (result); +} + +/*% + * Check that the new SOA record at 'update_rdata' does not + * illegally cause the SOA serial number to decrease or stay + * unchanged relative to the existing SOA in 'db'. + * + * Sets '*ok' to ISC_TRUE if the update is legal, ISC_FALSE if not. + * + * William King points out that RFC2136 is inconsistent about + * the case where the serial number stays unchanged: + * + * section 3.4.2.2 requires a server to ignore a SOA update request + * if the serial number on the update SOA is less_than_or_equal to + * the zone SOA serial. + * + * section 3.6 requires a server to ignore a SOA update request if + * the serial is less_than the zone SOA serial. + * + * Paul says 3.4.2.2 is correct. + * + */ +static isc_result_t +check_soa_increment(dns_db_t *db, dns_dbversion_t *ver, + dns_rdata_t *update_rdata, + isc_boolean_t *ok) +{ + isc_uint32_t db_serial; + isc_uint32_t update_serial; + isc_result_t result; + + update_serial = dns_soa_getserial(update_rdata); + + result = dns_db_getsoaserial(db, ver, &db_serial); + if (result != ISC_R_SUCCESS) + return (result); + + if (DNS_SERIAL_GE(db_serial, update_serial)) { + *ok = ISC_FALSE; + } else { + *ok = ISC_TRUE; + } + + return (ISC_R_SUCCESS); + +} + +/**************************************************************************/ +/* + * Incremental updating of NSECs and RRSIGs. + */ + +#define MAXZONEKEYS 32 /*%< Maximum number of zone keys supported. */ + +/*% + * We abuse the dns_diff_t type to represent a set of domain names + * affected by the update. + */ +static isc_result_t +namelist_append_name(dns_diff_t *list, dns_name_t *name) { + isc_result_t result; + dns_difftuple_t *tuple = NULL; + static dns_rdata_t dummy_rdata = DNS_RDATA_INIT; + + CHECK(dns_difftuple_create(list->mctx, DNS_DIFFOP_EXISTS, name, 0, + &dummy_rdata, &tuple)); + dns_diff_append(list, &tuple); + failure: + return (result); +} + +static isc_result_t +namelist_append_subdomain(dns_db_t *db, dns_name_t *name, dns_diff_t *affected) +{ + isc_result_t result; + dns_fixedname_t fixedname; + dns_name_t *child; + dns_dbiterator_t *dbit = NULL; + + dns_fixedname_init(&fixedname); + child = dns_fixedname_name(&fixedname); + + CHECK(dns_db_createiterator(db, ISC_FALSE, &dbit)); + + for (result = dns_dbiterator_seek(dbit, name); + result == ISC_R_SUCCESS; + result = dns_dbiterator_next(dbit)) + { + dns_dbnode_t *node = NULL; + CHECK(dns_dbiterator_current(dbit, &node, child)); + dns_db_detachnode(db, &node); + if (! dns_name_issubdomain(child, name)) + break; + CHECK(namelist_append_name(affected, child)); + } + if (result == ISC_R_NOMORE) + result = ISC_R_SUCCESS; + failure: + if (dbit != NULL) + dns_dbiterator_destroy(&dbit); + return (result); +} + + + +/*% + * Helper function for non_nsec_rrset_exists(). + */ +static isc_result_t +is_non_nsec_action(void *data, dns_rdataset_t *rrset) { + UNUSED(data); + if (!(rrset->type == dns_rdatatype_nsec || + (rrset->type == dns_rdatatype_rrsig && + rrset->covers == dns_rdatatype_nsec))) + return (ISC_R_EXISTS); + return (ISC_R_SUCCESS); +} + +/*% + * Check whether there is an rrset other than a NSEC or RRSIG NSEC, + * i.e., anything that justifies the continued existence of a name + * after a secure update. + * + * If such an rrset exists, set '*exists' to ISC_TRUE. + * Otherwise, set it to ISC_FALSE. + */ +static isc_result_t +non_nsec_rrset_exists(dns_db_t *db, dns_dbversion_t *ver, + dns_name_t *name, isc_boolean_t *exists) +{ + isc_result_t result; + result = foreach_rrset(db, ver, name, + is_non_nsec_action, NULL); + RETURN_EXISTENCE_FLAG; +} + +/*% + * A comparison function for sorting dns_diff_t:s by name. + */ +static int +name_order(const void *av, const void *bv) { + dns_difftuple_t const * const *ap = av; + dns_difftuple_t const * const *bp = bv; + dns_difftuple_t const *a = *ap; + dns_difftuple_t const *b = *bp; + return (dns_name_compare(&a->name, &b->name)); +} + +static isc_result_t +uniqify_name_list(dns_diff_t *list) { + isc_result_t result; + dns_difftuple_t *p, *q; + + CHECK(dns_diff_sort(list, name_order)); + + p = ISC_LIST_HEAD(list->tuples); + while (p != NULL) { + do { + q = ISC_LIST_NEXT(p, link); + if (q == NULL || ! dns_name_equal(&p->name, &q->name)) + break; + ISC_LIST_UNLINK(list->tuples, q, link); + dns_difftuple_free(&q); + } while (1); + p = ISC_LIST_NEXT(p, link); + } + failure: + return (result); +} + + +static isc_result_t +is_glue(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, + isc_boolean_t *flag) +{ + isc_result_t result; + dns_fixedname_t foundname; + dns_fixedname_init(&foundname); + result = dns_db_find(db, name, ver, dns_rdatatype_any, + DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD, + (isc_stdtime_t) 0, NULL, + dns_fixedname_name(&foundname), + NULL, NULL); + if (result == ISC_R_SUCCESS) { + *flag = ISC_FALSE; + return (ISC_R_SUCCESS); + } else if (result == DNS_R_ZONECUT) { + /* + * We are at the zonecut. The name will have an NSEC, but + * non-delegation will be omitted from the type bit map. + */ + *flag = ISC_FALSE; + return (ISC_R_SUCCESS); + } else if (result == DNS_R_GLUE || result == DNS_R_DNAME) { + *flag = ISC_TRUE; + return (ISC_R_SUCCESS); + } else { + return (result); + } +} + +/*% + * Find the next/previous name that has a NSEC record. + * In other words, skip empty database nodes and names that + * have had their NSECs removed because they are obscured by + * a zone cut. + */ +static isc_result_t +next_active(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, + dns_dbversion_t *ver, dns_name_t *oldname, dns_name_t *newname, + isc_boolean_t forward) +{ + isc_result_t result; + dns_dbiterator_t *dbit = NULL; + isc_boolean_t has_nsec; + unsigned int wraps = 0; + + CHECK(dns_db_createiterator(db, ISC_FALSE, &dbit)); + + CHECK(dns_dbiterator_seek(dbit, oldname)); + do { + dns_dbnode_t *node = NULL; + + if (forward) + result = dns_dbiterator_next(dbit); + else + result = dns_dbiterator_prev(dbit); + if (result == ISC_R_NOMORE) { + /* + * Wrap around. + */ + if (forward) + CHECK(dns_dbiterator_first(dbit)); + else + CHECK(dns_dbiterator_last(dbit)); + wraps++; + if (wraps == 2) { + update_log(client, zone, ISC_LOG_ERROR, + "secure zone with no NSECs"); + result = DNS_R_BADZONE; + goto failure; + } + } + CHECK(dns_dbiterator_current(dbit, &node, newname)); + dns_db_detachnode(db, &node); + + /* + * The iterator may hold the tree lock, and + * rrset_exists() calls dns_db_findnode() which + * may try to reacquire it. To avoid deadlock + * we must pause the iterator first. + */ + CHECK(dns_dbiterator_pause(dbit)); + CHECK(rrset_exists(db, ver, newname, + dns_rdatatype_nsec, 0, &has_nsec)); + + } while (! has_nsec); + failure: + if (dbit != NULL) + dns_dbiterator_destroy(&dbit); + + return (result); +} + +/*% + * Add a NSEC record for "name", recording the change in "diff". + * The existing NSEC is removed. + */ +static isc_result_t +add_nsec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, + dns_dbversion_t *ver, dns_name_t *name, dns_ttl_t nsecttl, + dns_diff_t *diff) +{ + isc_result_t result; + dns_dbnode_t *node = NULL; + unsigned char buffer[DNS_NSEC_BUFFERSIZE]; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_difftuple_t *tuple = NULL; + dns_fixedname_t fixedname; + dns_name_t *target; + + dns_fixedname_init(&fixedname); + target = dns_fixedname_name(&fixedname); + + /* + * Find the successor name, aka NSEC target. + */ + CHECK(next_active(client, zone, db, ver, name, target, ISC_TRUE)); + + /* + * Create the NSEC RDATA. + */ + CHECK(dns_db_findnode(db, name, ISC_FALSE, &node)); + dns_rdata_init(&rdata); + CHECK(dns_nsec_buildrdata(db, ver, node, target, buffer, &rdata)); + dns_db_detachnode(db, &node); + + /* + * Delete the old NSEC and record the change. + */ + CHECK(delete_if(true_p, db, ver, name, dns_rdatatype_nsec, 0, + NULL, diff)); + /* + * Add the new NSEC and record the change. + */ + CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, + nsecttl, &rdata, &tuple)); + CHECK(do_one_tuple(&tuple, db, ver, diff)); + INSIST(tuple == NULL); + + failure: + if (node != NULL) + dns_db_detachnode(db, &node); + return (result); +} + +/*% + * Add a placeholder NSEC record for "name", recording the change in "diff". + */ +static isc_result_t +add_placeholder_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, + dns_diff_t *diff) { + isc_result_t result; + dns_difftuple_t *tuple = NULL; + isc_region_t r; + unsigned char data[1] = { 0 }; /* The root domain, no bits. */ + dns_rdata_t rdata = DNS_RDATA_INIT; + + r.base = data; + r.length = sizeof(data); + dns_rdata_fromregion(&rdata, dns_db_class(db), dns_rdatatype_nsec, &r); + CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, 0, + &rdata, &tuple)); + CHECK(do_one_tuple(&tuple, db, ver, diff)); + failure: + return (result); +} + +static isc_result_t +find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, + isc_mem_t *mctx, unsigned int maxkeys, + dst_key_t **keys, unsigned int *nkeys) +{ + isc_result_t result; + dns_dbnode_t *node = NULL; + const char *directory = dns_zone_getkeydirectory(zone); + CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node)); + CHECK(dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db), + directory, mctx, maxkeys, keys, nkeys)); + failure: + if (node != NULL) + dns_db_detachnode(db, &node); + return (result); +} + +static isc_boolean_t +ksk_sanity(dns_db_t *db, dns_dbversion_t *ver) { + isc_boolean_t ret = ISC_FALSE; + isc_boolean_t have_ksk = ISC_FALSE, have_nonksk = ISC_FALSE; + isc_result_t result; + dns_dbnode_t *node = NULL; + dns_rdataset_t rdataset; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdata_dnskey_t dnskey; + + dns_rdataset_init(&rdataset); + CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node)); + CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0, + &rdataset, NULL)); + CHECK(dns_rdataset_first(&rdataset)); + while (result == ISC_R_SUCCESS && (!have_ksk || !have_nonksk)) { + dns_rdataset_current(&rdataset, &rdata); + CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL)); + if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH)) + == DNS_KEYOWNER_ZONE) { + if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) + have_ksk = ISC_TRUE; + else + have_nonksk = ISC_TRUE; + } + dns_rdata_reset(&rdata); + result = dns_rdataset_next(&rdataset); + } + if (have_ksk && have_nonksk) + ret = ISC_TRUE; + failure: + if (dns_rdataset_isassociated(&rdataset)) + dns_rdataset_disassociate(&rdataset); + if (node != NULL) + dns_db_detachnode(db, &node); + return (ret); +} + +/*% + * Add RRSIG records for an RRset, recording the change in "diff". + */ +static isc_result_t +add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, + dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, + unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception, + isc_stdtime_t expire, isc_boolean_t check_ksk) +{ + isc_result_t result; + dns_dbnode_t *node = NULL; + dns_rdataset_t rdataset; + dns_rdata_t sig_rdata = DNS_RDATA_INIT; + isc_buffer_t buffer; + unsigned char data[1024]; /* XXX */ + unsigned int i; + + dns_rdataset_init(&rdataset); + isc_buffer_init(&buffer, data, sizeof(data)); + + /* Get the rdataset to sign. */ + CHECK(dns_db_findnode(db, name, ISC_FALSE, &node)); + CHECK(dns_db_findrdataset(db, node, ver, type, 0, + (isc_stdtime_t) 0, + &rdataset, NULL)); + dns_db_detachnode(db, &node); + + for (i = 0; i < nkeys; i++) { + + if (check_ksk && type != dns_rdatatype_dnskey && + (dst_key_flags(keys[i]) & DNS_KEYFLAG_KSK) != 0) + continue; + + if (!dst_key_isprivate(keys[i])) + continue; + + /* Calculate the signature, creating a RRSIG RDATA. */ + CHECK(dns_dnssec_sign(name, &rdataset, keys[i], + &inception, &expire, + mctx, &buffer, &sig_rdata)); + + /* Update the database and journal with the RRSIG. */ + /* XXX inefficient - will cause dataset merging */ + CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, + rdataset.ttl, &sig_rdata)); + dns_rdata_reset(&sig_rdata); + } + + failure: + if (dns_rdataset_isassociated(&rdataset)) + dns_rdataset_disassociate(&rdataset); + if (node != NULL) + dns_db_detachnode(db, &node); + return (result); +} + +/*% + * Update RRSIG and NSEC records affected by an update. The original + * update, including the SOA serial update but exluding the RRSIG & NSEC + * changes, is in "diff" and has already been applied to "newver" of "db". + * The database version prior to the update is "oldver". + * + * The necessary RRSIG and NSEC changes will be applied to "newver" + * and added (as a minimal diff) to "diff". + * + * The RRSIGs generated will be valid for 'sigvalidityinterval' seconds. + */ +static isc_result_t +update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, + dns_dbversion_t *oldver, dns_dbversion_t *newver, + dns_diff_t *diff, isc_uint32_t sigvalidityinterval) +{ + isc_result_t result; + dns_difftuple_t *t; + dns_diff_t diffnames; + dns_diff_t affected; + dns_diff_t sig_diff; + dns_diff_t nsec_diff; + dns_diff_t nsec_mindiff; + isc_boolean_t flag; + dst_key_t *zone_keys[MAXZONEKEYS]; + unsigned int nkeys = 0; + unsigned int i; + isc_stdtime_t now, inception, expire; + dns_ttl_t nsecttl; + dns_rdata_soa_t soa; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdataset_t rdataset; + dns_dbnode_t *node = NULL; + isc_boolean_t check_ksk; + + dns_diff_init(client->mctx, &diffnames); + dns_diff_init(client->mctx, &affected); + + dns_diff_init(client->mctx, &sig_diff); + dns_diff_init(client->mctx, &nsec_diff); + dns_diff_init(client->mctx, &nsec_mindiff); + + result = find_zone_keys(zone, db, newver, client->mctx, + MAXZONEKEYS, zone_keys, &nkeys); + if (result != ISC_R_SUCCESS) { + update_log(client, zone, ISC_LOG_ERROR, + "could not get zone keys for secure dynamic update"); + goto failure; + } + + isc_stdtime_get(&now); + inception = now - 3600; /* Allow for some clock skew. */ + expire = now + sigvalidityinterval; + + /* + * Do we look at the KSK flag on the DNSKEY to determining which + * keys sign which RRsets? First check the zone option then + * check the keys flags to make sure atleast one has a ksk set + * and one doesn't. + */ + check_ksk = ISC_TF((dns_zone_getoptions(zone) & + DNS_ZONEOPT_UPDATECHECKKSK) != 0); + if (check_ksk) + check_ksk = ksk_sanity(db, newver); + + /* + * Get the NSEC's TTL from the SOA MINIMUM field. + */ + CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node)); + dns_rdataset_init(&rdataset); + CHECK(dns_db_findrdataset(db, node, newver, dns_rdatatype_soa, 0, + (isc_stdtime_t) 0, &rdataset, NULL)); + CHECK(dns_rdataset_first(&rdataset)); + dns_rdataset_current(&rdataset, &rdata); + CHECK(dns_rdata_tostruct(&rdata, &soa, NULL)); + nsecttl = soa.minimum; + dns_rdataset_disassociate(&rdataset); + dns_db_detachnode(db, &node); + + /* + * Find all RRsets directly affected by the update, and + * update their RRSIGs. Also build a list of names affected + * by the update in "diffnames". + */ + CHECK(dns_diff_sort(diff, temp_order)); + + t = ISC_LIST_HEAD(diff->tuples); + while (t != NULL) { + dns_name_t *name = &t->name; + /* Now "name" is a new, unique name affected by the update. */ + + CHECK(namelist_append_name(&diffnames, name)); + + while (t != NULL && dns_name_equal(&t->name, name)) { + dns_rdatatype_t type; + type = t->rdata.type; + + /* + * Now "name" and "type" denote a new unique RRset + * affected by the update. + */ + + /* Don't sign RRSIGs. */ + if (type == dns_rdatatype_rrsig) + goto skip; + + /* + * Delete all old RRSIGs covering this type, since they + * are all invalid when the signed RRset has changed. + * We may not be able to recreate all of them - tough. + */ + CHECK(delete_if(true_p, db, newver, name, + dns_rdatatype_rrsig, type, + NULL, &sig_diff)); + + /* + * If this RRset still exists after the update, + * add a new signature for it. + */ + CHECK(rrset_exists(db, newver, name, type, 0, &flag)); + if (flag) { + CHECK(add_sigs(db, newver, name, type, + &sig_diff, zone_keys, nkeys, + client->mctx, inception, + expire, check_ksk)); + } + skip: + /* Skip any other updates to the same RRset. */ + while (t != NULL && + dns_name_equal(&t->name, name) && + t->rdata.type == type) + { + t = ISC_LIST_NEXT(t, link); + } + } + } + + /* Remove orphaned NSECs and RRSIG NSECs. */ + for (t = ISC_LIST_HEAD(diffnames.tuples); + t != NULL; + t = ISC_LIST_NEXT(t, link)) + { + CHECK(non_nsec_rrset_exists(db, newver, &t->name, &flag)); + if (! flag) { + CHECK(delete_if(true_p, db, newver, &t->name, + dns_rdatatype_any, 0, + NULL, &sig_diff)); + } + } + + /* + * When a name is created or deleted, its predecessor needs to + * have its NSEC updated. + */ + for (t = ISC_LIST_HEAD(diffnames.tuples); + t != NULL; + t = ISC_LIST_NEXT(t, link)) + { + isc_boolean_t existed, exists; + dns_fixedname_t fixedname; + dns_name_t *prevname; + + dns_fixedname_init(&fixedname); + prevname = dns_fixedname_name(&fixedname); + + CHECK(name_exists(db, oldver, &t->name, &existed)); + CHECK(name_exists(db, newver, &t->name, &exists)); + if (exists == existed) + continue; + + /* + * Find the predecessor. + * When names become obscured or unobscured in this update + * transaction, we may find the wrong predecessor because + * the NSECs have not yet been updated to reflect the delegation + * change. This should not matter because in this case, + * the correct predecessor is either the delegation node or + * a newly unobscured node, and those nodes are on the + * "affected" list in any case. + */ + CHECK(next_active(client, zone, db, newver, + &t->name, prevname, ISC_FALSE)); + CHECK(namelist_append_name(&affected, prevname)); + } + + /* + * Find names potentially affected by delegation changes + * (obscured by adding an NS or DNAME, or unobscured by + * removing one). + */ + for (t = ISC_LIST_HEAD(diffnames.tuples); + t != NULL; + t = ISC_LIST_NEXT(t, link)) + { + isc_boolean_t ns_existed, dname_existed; + isc_boolean_t ns_exists, dname_exists; + + CHECK(rrset_exists(db, oldver, &t->name, dns_rdatatype_ns, 0, + &ns_existed)); + CHECK(rrset_exists(db, oldver, &t->name, dns_rdatatype_dname, 0, + &dname_existed)); + CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_ns, 0, + &ns_exists)); + CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_dname, 0, + &dname_exists)); + if ((ns_exists || dname_exists) == (ns_existed || dname_existed)) + continue; + /* + * There was a delegation change. Mark all subdomains + * of t->name as potentially needing a NSEC update. + */ + CHECK(namelist_append_subdomain(db, &t->name, &affected)); + } + + ISC_LIST_APPENDLIST(affected.tuples, diffnames.tuples, link); + INSIST(ISC_LIST_EMPTY(diffnames.tuples)); + + CHECK(uniqify_name_list(&affected)); + + /* + * Determine which names should have NSECs, and delete/create + * NSECs to make it so. We don't know the final NSEC targets yet, + * so we just create placeholder NSECs with arbitrary contents + * to indicate that their respective owner names should be part of + * the NSEC chain. + */ + for (t = ISC_LIST_HEAD(affected.tuples); + t != NULL; + t = ISC_LIST_NEXT(t, link)) + { + isc_boolean_t exists; + CHECK(name_exists(db, newver, &t->name, &exists)); + if (! exists) + continue; + CHECK(is_glue(db, newver, &t->name, &flag)); + if (flag) { + /* + * This name is obscured. Delete any + * existing NSEC record. + */ + CHECK(delete_if(true_p, db, newver, &t->name, + dns_rdatatype_nsec, 0, + NULL, &nsec_diff)); + } else { + /* + * This name is not obscured. It should have a NSEC. + */ + CHECK(rrset_exists(db, newver, &t->name, + dns_rdatatype_nsec, 0, &flag)); + if (! flag) + CHECK(add_placeholder_nsec(db, newver, &t->name, + diff)); + } + } + + /* + * Now we know which names are part of the NSEC chain. + * Make them all point at their correct targets. + */ + for (t = ISC_LIST_HEAD(affected.tuples); + t != NULL; + t = ISC_LIST_NEXT(t, link)) + { + CHECK(rrset_exists(db, newver, &t->name, + dns_rdatatype_nsec, 0, &flag)); + if (flag) { + /* + * There is a NSEC, but we don't know if it is correct. + * Delete it and create a correct one to be sure. + * If the update was unnecessary, the diff minimization + * will take care of eliminating it from the journal, + * IXFRs, etc. + * + * The RRSIG bit should always be set in the NSECs + * we generate, because they will all get RRSIG NSECs. + * (XXX what if the zone keys are missing?). + * Because the RRSIG NSECs have not necessarily been + * created yet, the correctness of the bit mask relies + * on the assumption that NSECs are only created if + * there is other data, and if there is other data, + * there are other RRSIGs. + */ + CHECK(add_nsec(client, zone, db, newver, &t->name, + nsecttl, &nsec_diff)); + } + } + + /* + * Minimize the set of NSEC updates so that we don't + * have to regenerate the RRSIG NSECs for NSECs that were + * replaced with identical ones. + */ + while ((t = ISC_LIST_HEAD(nsec_diff.tuples)) != NULL) { + ISC_LIST_UNLINK(nsec_diff.tuples, t, link); + dns_diff_appendminimal(&nsec_mindiff, &t); + } + + /* Update RRSIG NSECs. */ + for (t = ISC_LIST_HEAD(nsec_mindiff.tuples); + t != NULL; + t = ISC_LIST_NEXT(t, link)) + { + if (t->op == DNS_DIFFOP_DEL) { + CHECK(delete_if(true_p, db, newver, &t->name, + dns_rdatatype_rrsig, dns_rdatatype_nsec, + NULL, &sig_diff)); + } else if (t->op == DNS_DIFFOP_ADD) { + CHECK(add_sigs(db, newver, &t->name, dns_rdatatype_nsec, + &sig_diff, zone_keys, nkeys, + client->mctx, inception, expire, + check_ksk)); + } else { + INSIST(0); + } + } + + /* Record our changes for the journal. */ + while ((t = ISC_LIST_HEAD(sig_diff.tuples)) != NULL) { + ISC_LIST_UNLINK(sig_diff.tuples, t, link); + dns_diff_appendminimal(diff, &t); + } + while ((t = ISC_LIST_HEAD(nsec_mindiff.tuples)) != NULL) { + ISC_LIST_UNLINK(nsec_mindiff.tuples, t, link); + dns_diff_appendminimal(diff, &t); + } + + INSIST(ISC_LIST_EMPTY(sig_diff.tuples)); + INSIST(ISC_LIST_EMPTY(nsec_diff.tuples)); + INSIST(ISC_LIST_EMPTY(nsec_mindiff.tuples)); + + failure: + dns_diff_clear(&sig_diff); + dns_diff_clear(&nsec_diff); + dns_diff_clear(&nsec_mindiff); + + dns_diff_clear(&affected); + dns_diff_clear(&diffnames); + + for (i = 0; i < nkeys; i++) + dst_key_free(&zone_keys[i]); + + return (result); +} + + +/**************************************************************************/ +/*% + * The actual update code in all its glory. We try to follow + * the RFC2136 pseudocode as closely as possible. + */ + +static isc_result_t +send_update_event(ns_client_t *client, dns_zone_t *zone) { + isc_result_t result = ISC_R_SUCCESS; + update_event_t *event = NULL; + isc_task_t *zonetask = NULL; + ns_client_t *evclient; + + event = (update_event_t *) + isc_event_allocate(client->mctx, client, DNS_EVENT_UPDATE, + update_action, NULL, sizeof(*event)); + if (event == NULL) + FAIL(ISC_R_NOMEMORY); + event->zone = zone; + event->result = ISC_R_SUCCESS; + + evclient = NULL; + ns_client_attach(client, &evclient); + INSIST(client->nupdates == 0); + client->nupdates++; + event->ev_arg = evclient; + + dns_zone_gettask(zone, &zonetask); + isc_task_send(zonetask, ISC_EVENT_PTR(&event)); + + failure: + if (event != NULL) + isc_event_free(ISC_EVENT_PTR(&event)); + return (result); +} + +static void +respond(ns_client_t *client, isc_result_t result) { + isc_result_t msg_result; + + msg_result = dns_message_reply(client->message, ISC_TRUE); + if (msg_result != ISC_R_SUCCESS) + goto msg_failure; + client->message->rcode = dns_result_torcode(result); + + ns_client_send(client); + return; + + msg_failure: + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_UPDATE, NS_LOGMODULE_UPDATE, + ISC_LOG_ERROR, + "could not create update response message: %s", + isc_result_totext(msg_result)); + ns_client_next(client, msg_result); +} + +void +ns_update_start(ns_client_t *client, isc_result_t sigresult) { + dns_message_t *request = client->message; + isc_result_t result; + dns_name_t *zonename; + dns_rdataset_t *zone_rdataset; + dns_zone_t *zone = NULL; + + /* + * Interpret the zone section. + */ + result = dns_message_firstname(request, DNS_SECTION_ZONE); + if (result != ISC_R_SUCCESS) + FAILC(DNS_R_FORMERR, + "update zone section empty"); + + /* + * The zone section must contain exactly one "question", and + * it must be of type SOA. + */ + zonename = NULL; + dns_message_currentname(request, DNS_SECTION_ZONE, &zonename); + zone_rdataset = ISC_LIST_HEAD(zonename->list); + if (zone_rdataset->type != dns_rdatatype_soa) + FAILC(DNS_R_FORMERR, + "update zone section contains non-SOA"); + if (ISC_LIST_NEXT(zone_rdataset, link) != NULL) + FAILC(DNS_R_FORMERR, + "update zone section contains multiple RRs"); + + /* The zone section must have exactly one name. */ + result = dns_message_nextname(request, DNS_SECTION_ZONE); + if (result != ISC_R_NOMORE) + FAILC(DNS_R_FORMERR, + "update zone section contains multiple RRs"); + + result = dns_zt_find(client->view->zonetable, zonename, 0, NULL, + &zone); + if (result != ISC_R_SUCCESS) + FAILC(DNS_R_NOTAUTH, + "not authoritative for update zone"); + + switch(dns_zone_gettype(zone)) { + case dns_zone_master: + /* + * We can now fail due to a bad signature as we now know + * that we are the master. + */ + if (sigresult != ISC_R_SUCCESS) + FAIL(sigresult); + CHECK(send_update_event(client, zone)); + break; + case dns_zone_slave: + CHECK(checkupdateacl(client, dns_zone_getforwardacl(zone), + "update forwarding", zonename, ISC_TRUE)); + CHECK(send_forward_event(client, zone)); + break; + default: + FAILC(DNS_R_NOTAUTH, + "not authoritative for update zone"); + } + return; + + failure: + /* + * We failed without having sent an update event to the zone. + * We are still in the client task context, so we can + * simply give an error response without switching tasks. + */ + respond(client, result); + if (zone != NULL) + dns_zone_detach(&zone); +} + +/*% + * DS records are not allowed to exist without corresponding NS records, + * draft-ietf-dnsext-delegation-signer-11.txt, 2.2 Protocol Change, + * "DS RRsets MUST NOT appear at non-delegation points or at a zone's apex". + */ + +static isc_result_t +remove_orphaned_ds(dns_db_t *db, dns_dbversion_t *newver, dns_diff_t *diff) { + isc_result_t result; + isc_boolean_t ns_exists, ds_exists; + dns_difftuple_t *t; + + for (t = ISC_LIST_HEAD(diff->tuples); + t != NULL; + t = ISC_LIST_NEXT(t, link)) { + if (t->op != DNS_DIFFOP_ADD || + t->rdata.type != dns_rdatatype_ns) + continue; + CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_ns, 0, + &ns_exists)); + if (ns_exists) + continue; + CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_ds, 0, + &ds_exists)); + if (!ds_exists) + continue; + CHECK(delete_if(true_p, db, newver, &t->name, + dns_rdatatype_ds, 0, NULL, diff)); + } + return (ISC_R_SUCCESS); + + failure: + return (result); +} + +/* + * This implements the post load integrity checks for mx records. + */ +static isc_result_t +check_mx(ns_client_t *client, dns_zone_t *zone, + dns_db_t *db, dns_dbversion_t *newver, dns_diff_t *diff) +{ + char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123.")]; + char ownerbuf[DNS_NAME_FORMATSIZE]; + char namebuf[DNS_NAME_FORMATSIZE]; + char altbuf[DNS_NAME_FORMATSIZE]; + dns_difftuple_t *t; + dns_fixedname_t fixed; + dns_name_t *foundname; + dns_rdata_mx_t mx; + dns_rdata_t rdata; + isc_boolean_t ok = ISC_TRUE; + isc_boolean_t isaddress; + isc_result_t result; + struct in6_addr addr6; + struct in_addr addr; + unsigned int options; + + dns_fixedname_init(&fixed); + foundname = dns_fixedname_name(&fixed); + dns_rdata_init(&rdata); + options = dns_zone_getoptions(zone); + + for (t = ISC_LIST_HEAD(diff->tuples); + t != NULL; + t = ISC_LIST_NEXT(t, link)) { + if (t->op != DNS_DIFFOP_ADD || + t->rdata.type != dns_rdatatype_mx) + continue; + + result = dns_rdata_tostruct(&t->rdata, &mx, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + /* + * Check if we will error out if we attempt to reload the + * zone. + */ + dns_name_format(&mx.mx, namebuf, sizeof(namebuf)); + dns_name_format(&t->name, ownerbuf, sizeof(ownerbuf)); + isaddress = ISC_FALSE; + if ((options & DNS_RDATA_CHECKMX) != 0 && + strlcpy(tmp, namebuf, sizeof(tmp)) < sizeof(tmp)) { + if (tmp[strlen(tmp) - 1] == '.') + tmp[strlen(tmp) - 1] = '\0'; + if (inet_aton(tmp, &addr) == 1 || + inet_pton(AF_INET6, tmp, &addr6) == 1) + isaddress = ISC_TRUE; + } + + if (isaddress && (options & DNS_RDATA_CHECKMXFAIL) != 0) { + update_log(client, zone, ISC_LOG_ERROR, + "%s/MX: '%s': %s", + ownerbuf, namebuf, + dns_result_totext(DNS_R_MXISADDRESS)); + ok = ISC_FALSE; + } else if (isaddress) { + update_log(client, zone, ISC_LOG_WARNING, + "%s/MX: warning: '%s': %s", + ownerbuf, namebuf, + dns_result_totext(DNS_R_MXISADDRESS)); + } + + /* + * Check zone integrity checks. + */ + if ((options & DNS_ZONEOPT_CHECKINTEGRITY) == 0) + continue; + result = dns_db_find(db, &mx.mx, newver, dns_rdatatype_a, + 0, 0, NULL, foundname, NULL, NULL); + if (result == ISC_R_SUCCESS) + continue; + + if (result == DNS_R_NXRRSET) { + result = dns_db_find(db, &mx.mx, newver, + dns_rdatatype_aaaa, + 0, 0, NULL, foundname, + NULL, NULL); + if (result == ISC_R_SUCCESS) + continue; + } + + if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN) { + update_log(client, zone, ISC_LOG_ERROR, + "%s/MX '%s' has no address records " + "(A or AAAA)", ownerbuf, namebuf); + ok = ISC_FALSE; + } else if (result == DNS_R_CNAME) { + update_log(client, zone, ISC_LOG_ERROR, + "%s/MX '%s' is a CNAME (illegal)", + ownerbuf, namebuf); + ok = ISC_FALSE; + } else if (result == DNS_R_DNAME) { + dns_name_format(foundname, altbuf, sizeof altbuf); + update_log(client, zone, ISC_LOG_ERROR, + "%s/MX '%s' is below a DNAME '%s' (illegal)", + ownerbuf, namebuf, altbuf); + ok = ISC_FALSE; + } + } + return (ok ? ISC_R_SUCCESS : DNS_R_REFUSED); +} + +static void +update_action(isc_task_t *task, isc_event_t *event) { + update_event_t *uev = (update_event_t *) event; + dns_zone_t *zone = uev->zone; + ns_client_t *client = (ns_client_t *)event->ev_arg; + + isc_result_t result; + dns_db_t *db = NULL; + dns_dbversion_t *oldver = NULL; + dns_dbversion_t *ver = NULL; + dns_diff_t diff; /* Pending updates. */ + dns_diff_t temp; /* Pending RR existence assertions. */ + isc_boolean_t soa_serial_changed = ISC_FALSE; + isc_mem_t *mctx = client->mctx; + dns_rdatatype_t covers; + dns_message_t *request = client->message; + dns_rdataclass_t zoneclass; + dns_name_t *zonename; + dns_ssutable_t *ssutable = NULL; + dns_fixedname_t tmpnamefixed; + dns_name_t *tmpname = NULL; + unsigned int options; + + INSIST(event->ev_type == DNS_EVENT_UPDATE); + + dns_diff_init(mctx, &diff); + dns_diff_init(mctx, &temp); + + CHECK(dns_zone_getdb(zone, &db)); + zonename = dns_db_origin(db); + zoneclass = dns_db_class(db); + dns_zone_getssutable(zone, &ssutable); + dns_db_currentversion(db, &oldver); + CHECK(dns_db_newversion(db, &ver)); + + /* + * Check prerequisites. + */ + + for (result = dns_message_firstname(request, DNS_SECTION_PREREQUISITE); + result == ISC_R_SUCCESS; + result = dns_message_nextname(request, DNS_SECTION_PREREQUISITE)) + { + dns_name_t *name = NULL; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_ttl_t ttl; + dns_rdataclass_t update_class; + isc_boolean_t flag; + + get_current_rr(request, DNS_SECTION_PREREQUISITE, zoneclass, + &name, &rdata, &covers, &ttl, &update_class); + + if (ttl != 0) + FAILC(DNS_R_FORMERR, "prerequisite TTL is not zero"); + + if (! dns_name_issubdomain(name, zonename)) + FAILN(DNS_R_NOTZONE, name, + "prerequisite name is out of zone"); + + if (update_class == dns_rdataclass_any) { + if (rdata.length != 0) + FAILC(DNS_R_FORMERR, + "class ANY prerequisite " + "RDATA is not empty"); + if (rdata.type == dns_rdatatype_any) { + CHECK(name_exists(db, ver, name, &flag)); + if (! flag) { + FAILN(DNS_R_NXDOMAIN, name, + "'name in use' prerequisite " + "not satisfied"); + } + } else { + CHECK(rrset_exists(db, ver, name, + rdata.type, covers, &flag)); + if (! flag) { + /* RRset does not exist. */ + FAILNT(DNS_R_NXRRSET, name, rdata.type, + "'rrset exists (value independent)' " + "prerequisite not satisfied"); + } + } + } else if (update_class == dns_rdataclass_none) { + if (rdata.length != 0) + FAILC(DNS_R_FORMERR, + "class NONE prerequisite " + "RDATA is not empty"); + if (rdata.type == dns_rdatatype_any) { + CHECK(name_exists(db, ver, name, &flag)); + if (flag) { + FAILN(DNS_R_YXDOMAIN, name, + "'name not in use' prerequisite " + "not satisfied"); + } + } else { + CHECK(rrset_exists(db, ver, name, + rdata.type, covers, &flag)); + if (flag) { + /* RRset exists. */ + FAILNT(DNS_R_YXRRSET, name, rdata.type, + "'rrset does not exist' " + "prerequisite not satisfied"); + } + } + } else if (update_class == zoneclass) { + /* "temp += rr;" */ + result = temp_append(&temp, name, &rdata); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "temp entry creation failed: %s", + dns_result_totext(result)); + FAIL(ISC_R_UNEXPECTED); + } + } else { + FAILC(DNS_R_FORMERR, "malformed prerequisite"); + } + } + if (result != ISC_R_NOMORE) + FAIL(result); + + + /* + * Perform the final check of the "rrset exists (value dependent)" + * prerequisites. + */ + if (ISC_LIST_HEAD(temp.tuples) != NULL) { + dns_rdatatype_t type; + + /* + * Sort the prerequisite records by owner name, + * type, and rdata. + */ + result = dns_diff_sort(&temp, temp_order); + if (result != ISC_R_SUCCESS) + FAILC(result, "'RRset exists (value dependent)' " + "prerequisite not satisfied"); + + dns_fixedname_init(&tmpnamefixed); + tmpname = dns_fixedname_name(&tmpnamefixed); + result = temp_check(mctx, &temp, db, ver, tmpname, &type); + if (result != ISC_R_SUCCESS) + FAILNT(result, tmpname, type, + "'RRset exists (value dependent)' " + "prerequisite not satisfied"); + } + + update_log(client, zone, LOGLEVEL_DEBUG, + "prerequisites are OK"); + + /* + * Check Requestor's Permissions. It seems a bit silly to do this + * only after prerequisite testing, but that is what RFC2136 says. + */ + result = ISC_R_SUCCESS; + if (ssutable == NULL) + CHECK(checkupdateacl(client, dns_zone_getupdateacl(zone), + "update", zonename, ISC_FALSE)); + else if (client->signer == NULL) + CHECK(checkupdateacl(client, NULL, "update", zonename, + ISC_FALSE)); + + if (dns_zone_getupdatedisabled(zone)) + FAILC(DNS_R_REFUSED, "dynamic update temporarily disabled"); + + /* + * Perform the Update Section Prescan. + */ + + for (result = dns_message_firstname(request, DNS_SECTION_UPDATE); + result == ISC_R_SUCCESS; + result = dns_message_nextname(request, DNS_SECTION_UPDATE)) + { + dns_name_t *name = NULL; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_ttl_t ttl; + dns_rdataclass_t update_class; + get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, + &name, &rdata, &covers, &ttl, &update_class); + + if (! dns_name_issubdomain(name, zonename)) + FAILC(DNS_R_NOTZONE, + "update RR is outside zone"); + if (update_class == zoneclass) { + /* + * Check for meta-RRs. The RFC2136 pseudocode says + * check for ANY|AXFR|MAILA|MAILB, but the text adds + * "or any other QUERY metatype" + */ + if (dns_rdatatype_ismeta(rdata.type)) { + FAILC(DNS_R_FORMERR, + "meta-RR in update"); + } + result = dns_zone_checknames(zone, name, &rdata); + if (result != ISC_R_SUCCESS) + FAIL(DNS_R_REFUSED); + } else if (update_class == dns_rdataclass_any) { + if (ttl != 0 || rdata.length != 0 || + (dns_rdatatype_ismeta(rdata.type) && + rdata.type != dns_rdatatype_any)) + FAILC(DNS_R_FORMERR, + "meta-RR in update"); + } else if (update_class == dns_rdataclass_none) { + if (ttl != 0 || + dns_rdatatype_ismeta(rdata.type)) + FAILC(DNS_R_FORMERR, + "meta-RR in update"); + } else { + update_log(client, zone, ISC_LOG_WARNING, + "update RR has incorrect class %d", + update_class); + FAIL(DNS_R_FORMERR); + } + /* + * draft-ietf-dnsind-simple-secure-update-01 says + * "Unlike traditional dynamic update, the client + * is forbidden from updating NSEC records." + */ + if (dns_db_issecure(db)) { + if (rdata.type == dns_rdatatype_nsec) { + FAILC(DNS_R_REFUSED, + "explicit NSEC updates are not allowed " + "in secure zones"); + } + else if (rdata.type == dns_rdatatype_rrsig) { + FAILC(DNS_R_REFUSED, + "explicit RRSIG updates are currently not " + "supported in secure zones"); + } + } + + if (ssutable != NULL && client->signer != NULL) { + if (rdata.type != dns_rdatatype_any) { + if (!dns_ssutable_checkrules(ssutable, + client->signer, + name, rdata.type)) + FAILC(DNS_R_REFUSED, + "rejected by secure update"); + } + else { + if (!ssu_checkall(db, ver, name, ssutable, + client->signer)) + FAILC(DNS_R_REFUSED, + "rejected by secure update"); + } + } + } + if (result != ISC_R_NOMORE) + FAIL(result); + + update_log(client, zone, LOGLEVEL_DEBUG, + "update section prescan OK"); + + /* + * Process the Update Section. + */ + + options = dns_zone_getoptions(zone); + for (result = dns_message_firstname(request, DNS_SECTION_UPDATE); + result == ISC_R_SUCCESS; + result = dns_message_nextname(request, DNS_SECTION_UPDATE)) + { + dns_name_t *name = NULL; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_ttl_t ttl; + dns_rdataclass_t update_class; + isc_boolean_t flag; + + get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, + &name, &rdata, &covers, &ttl, &update_class); + + if (update_class == zoneclass) { + + /* + * RFC1123 doesn't allow MF and MD in master zones. */ + if (rdata.type == dns_rdatatype_md || + rdata.type == dns_rdatatype_mf) { + char typebuf[DNS_RDATATYPE_FORMATSIZE]; + + dns_rdatatype_format(rdata.type, typebuf, + sizeof(typebuf)); + update_log(client, zone, LOGLEVEL_PROTOCOL, + "attempt to add %s ignored", + typebuf); + continue; + } + if (rdata.type == dns_rdatatype_ns && + dns_name_iswildcard(name)) { + update_log(client, zone, + LOGLEVEL_PROTOCOL, + "attempt to add wildcard NS record" + "ignored"); + continue; + } + if (rdata.type == dns_rdatatype_cname) { + CHECK(cname_incompatible_rrset_exists(db, ver, + name, + &flag)); + if (flag) { + update_log(client, zone, + LOGLEVEL_PROTOCOL, + "attempt to add CNAME " + "alongside non-CNAME " + "ignored"); + continue; + } + } else { + CHECK(rrset_exists(db, ver, name, + dns_rdatatype_cname, 0, + &flag)); + if (flag && + ! dns_rdatatype_isdnssec(rdata.type)) + { + update_log(client, zone, + LOGLEVEL_PROTOCOL, + "attempt to add non-CNAME " + "alongside CNAME ignored"); + continue; + } + } + if (rdata.type == dns_rdatatype_soa) { + isc_boolean_t ok; + CHECK(rrset_exists(db, ver, name, + dns_rdatatype_soa, 0, + &flag)); + if (! flag) { + update_log(client, zone, + LOGLEVEL_PROTOCOL, + "attempt to create 2nd " + "SOA ignored"); + continue; + } + CHECK(check_soa_increment(db, ver, &rdata, + &ok)); + if (! ok) { + update_log(client, zone, + LOGLEVEL_PROTOCOL, + "SOA update failed to " + "increment serial, " + "ignoring it"); + continue; + } + soa_serial_changed = ISC_TRUE; + } + if ((options & DNS_ZONEOPT_CHECKWILDCARD) != 0 && + dns_name_internalwildcard(name)) { + char namestr[DNS_NAME_FORMATSIZE]; + dns_name_format(name, namestr, + sizeof(namestr)); + update_log(client, zone, LOGLEVEL_PROTOCOL, + "warning: ownername '%s' contains " + "a non-terminal wildcard", namestr); + } + + if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { + char namestr[DNS_NAME_FORMATSIZE]; + char typestr[DNS_RDATATYPE_FORMATSIZE]; + dns_name_format(name, namestr, + sizeof(namestr)); + dns_rdatatype_format(rdata.type, typestr, + sizeof(typestr)); + update_log(client, zone, + LOGLEVEL_PROTOCOL, + "adding an RR at '%s' %s", + namestr, typestr); + } + + /* Prepare the affected RRset for the addition. */ + { + add_rr_prepare_ctx_t ctx; + ctx.db = db; + ctx.ver = ver; + ctx.diff = &diff; + ctx.name = name; + ctx.update_rr = &rdata; + ctx.update_rr_ttl = ttl; + ctx.ignore_add = ISC_FALSE; + dns_diff_init(mctx, &ctx.del_diff); + dns_diff_init(mctx, &ctx.add_diff); + CHECK(foreach_rr(db, ver, name, rdata.type, + covers, add_rr_prepare_action, + &ctx)); + + if (ctx.ignore_add) { + dns_diff_clear(&ctx.del_diff); + dns_diff_clear(&ctx.add_diff); + } else { + CHECK(do_diff(&ctx.del_diff, db, ver, &diff)); + CHECK(do_diff(&ctx.add_diff, db, ver, &diff)); + CHECK(update_one_rr(db, ver, &diff, + DNS_DIFFOP_ADD, + name, ttl, &rdata)); + } + } + } else if (update_class == dns_rdataclass_any) { + if (rdata.type == dns_rdatatype_any) { + if (isc_log_wouldlog(ns_g_lctx, + LOGLEVEL_PROTOCOL)) + { + char namestr[DNS_NAME_FORMATSIZE]; + dns_name_format(name, namestr, + sizeof(namestr)); + update_log(client, zone, + LOGLEVEL_PROTOCOL, + "delete all rrsets from " + "name '%s'", namestr); + } + if (dns_name_equal(name, zonename)) { + CHECK(delete_if(type_not_soa_nor_ns_p, + db, ver, name, + dns_rdatatype_any, 0, + &rdata, &diff)); + } else { + CHECK(delete_if(type_not_dnssec, + db, ver, name, + dns_rdatatype_any, 0, + &rdata, &diff)); + } + } else if (dns_name_equal(name, zonename) && + (rdata.type == dns_rdatatype_soa || + rdata.type == dns_rdatatype_ns)) { + update_log(client, zone, + LOGLEVEL_PROTOCOL, + "attempt to delete all SOA " + "or NS records ignored"); + continue; + } else { + if (isc_log_wouldlog(ns_g_lctx, + LOGLEVEL_PROTOCOL)) + { + char namestr[DNS_NAME_FORMATSIZE]; + char typestr[DNS_RDATATYPE_FORMATSIZE]; + dns_name_format(name, namestr, + sizeof(namestr)); + dns_rdatatype_format(rdata.type, + typestr, + sizeof(typestr)); + update_log(client, zone, + LOGLEVEL_PROTOCOL, + "deleting rrset at '%s' %s", + namestr, typestr); + } + CHECK(delete_if(true_p, db, ver, name, + rdata.type, covers, &rdata, + &diff)); + } + } else if (update_class == dns_rdataclass_none) { + /* + * The (name == zonename) condition appears in + * RFC2136 3.4.2.4 but is missing from the pseudocode. + */ + if (dns_name_equal(name, zonename)) { + if (rdata.type == dns_rdatatype_soa) { + update_log(client, zone, + LOGLEVEL_PROTOCOL, + "attempt to delete SOA " + "ignored"); + continue; + } + if (rdata.type == dns_rdatatype_ns) { + int count; + CHECK(rr_count(db, ver, name, + dns_rdatatype_ns, + 0, &count)); + if (count == 1) { + update_log(client, zone, + LOGLEVEL_PROTOCOL, + "attempt to " + "delete last " + "NS ignored"); + continue; + } + } + } + update_log(client, zone, + LOGLEVEL_PROTOCOL, + "deleting an RR"); + CHECK(delete_if(rr_equal_p, db, ver, name, + rdata.type, covers, &rdata, &diff)); + } + } + if (result != ISC_R_NOMORE) + FAIL(result); + + /* + * If any changes were made, increment the SOA serial number, + * update RRSIGs and NSECs (if zone is secure), and write the update + * to the journal. + */ + if (! ISC_LIST_EMPTY(diff.tuples)) { + char *journalfile; + dns_journal_t *journal; + + /* + * Increment the SOA serial, but only if it was not + * changed as a result of an update operation. + */ + if (! soa_serial_changed) { + CHECK(increment_soa_serial(db, ver, &diff, mctx)); + } + + CHECK(check_mx(client, zone, db, ver, &diff)); + + CHECK(remove_orphaned_ds(db, ver, &diff)); + + if (dns_db_issecure(db)) { + result = update_signatures(client, zone, db, oldver, + ver, &diff, + dns_zone_getsigvalidityinterval(zone)); + if (result != ISC_R_SUCCESS) { + update_log(client, zone, + ISC_LOG_ERROR, + "RRSIG/NSEC update failed: %s", + isc_result_totext(result)); + goto failure; + } + } + + journalfile = dns_zone_getjournal(zone); + if (journalfile != NULL) { + update_log(client, zone, LOGLEVEL_DEBUG, + "writing journal %s", journalfile); + + journal = NULL; + result = dns_journal_open(mctx, journalfile, + ISC_TRUE, &journal); + if (result != ISC_R_SUCCESS) + FAILS(result, "journal open failed"); + + result = dns_journal_write_transaction(journal, &diff); + if (result != ISC_R_SUCCESS) { + dns_journal_destroy(&journal); + FAILS(result, "journal write failed"); + } + + dns_journal_destroy(&journal); + } + + /* + * XXXRTH Just a note that this committing code will have + * to change to handle databases that need two-phase + * commit, but this isn't a priority. + */ + update_log(client, zone, LOGLEVEL_DEBUG, + "committing update transaction"); + dns_db_closeversion(db, &ver, ISC_TRUE); + + /* + * Mark the zone as dirty so that it will be written to disk. + */ + dns_zone_markdirty(zone); + + /* + * Notify slaves of the change we just made. + */ + dns_zone_notify(zone); + } else { + update_log(client, zone, LOGLEVEL_DEBUG, "redundant request"); + dns_db_closeversion(db, &ver, ISC_TRUE); + } + result = ISC_R_SUCCESS; + goto common; + + failure: + /* + * The reason for failure should have been logged at this point. + */ + if (ver != NULL) { + update_log(client, zone, LOGLEVEL_DEBUG, + "rolling back"); + dns_db_closeversion(db, &ver, ISC_FALSE); + } + + common: + dns_diff_clear(&temp); + dns_diff_clear(&diff); + + if (oldver != NULL) + dns_db_closeversion(db, &oldver, ISC_FALSE); + + if (db != NULL) + dns_db_detach(&db); + + if (ssutable != NULL) + dns_ssutable_detach(&ssutable); + + if (zone != NULL) + dns_zone_detach(&zone); + + isc_task_detach(&task); + uev->result = result; + uev->ev_type = DNS_EVENT_UPDATEDONE; + uev->ev_action = updatedone_action; + isc_task_send(client->task, &event); + INSIST(event == NULL); +} + +static void +updatedone_action(isc_task_t *task, isc_event_t *event) { + update_event_t *uev = (update_event_t *) event; + ns_client_t *client = (ns_client_t *) event->ev_arg; + + UNUSED(task); + + INSIST(event->ev_type == DNS_EVENT_UPDATEDONE); + INSIST(task == client->task); + + INSIST(client->nupdates > 0); + client->nupdates--; + respond(client, uev->result); + isc_event_free(&event); + ns_client_detach(&client); +} + +/*% + * Update forwarding support. + */ + +static void +forward_fail(isc_task_t *task, isc_event_t *event) { + ns_client_t *client = (ns_client_t *)event->ev_arg; + + UNUSED(task); + + INSIST(client->nupdates > 0); + client->nupdates--; + respond(client, DNS_R_SERVFAIL); + isc_event_free(&event); + ns_client_detach(&client); +} + + +static void +forward_callback(void *arg, isc_result_t result, dns_message_t *answer) { + update_event_t *uev = arg; + ns_client_t *client = uev->ev_arg; + + if (result != ISC_R_SUCCESS) { + INSIST(answer == NULL); + uev->ev_type = DNS_EVENT_UPDATEDONE; + uev->ev_action = forward_fail; + } else { + uev->ev_type = DNS_EVENT_UPDATEDONE; + uev->ev_action = forward_done; + uev->answer = answer; + } + isc_task_send(client->task, ISC_EVENT_PTR(&uev)); +} + +static void +forward_done(isc_task_t *task, isc_event_t *event) { + update_event_t *uev = (update_event_t *) event; + ns_client_t *client = (ns_client_t *)event->ev_arg; + + UNUSED(task); + + INSIST(client->nupdates > 0); + client->nupdates--; + ns_client_sendraw(client, uev->answer); + dns_message_destroy(&uev->answer); + isc_event_free(&event); + ns_client_detach(&client); +} + +static void +forward_action(isc_task_t *task, isc_event_t *event) { + update_event_t *uev = (update_event_t *) event; + dns_zone_t *zone = uev->zone; + ns_client_t *client = (ns_client_t *)event->ev_arg; + isc_result_t result; + + result = dns_zone_forwardupdate(zone, client->message, + forward_callback, event); + if (result != ISC_R_SUCCESS) { + uev->ev_type = DNS_EVENT_UPDATEDONE; + uev->ev_action = forward_fail; + isc_task_send(client->task, &event); + } + dns_zone_detach(&zone); + isc_task_detach(&task); +} + +static isc_result_t +send_forward_event(ns_client_t *client, dns_zone_t *zone) { + isc_result_t result = ISC_R_SUCCESS; + update_event_t *event = NULL; + isc_task_t *zonetask = NULL; + ns_client_t *evclient; + + event = (update_event_t *) + isc_event_allocate(client->mctx, client, DNS_EVENT_UPDATE, + forward_action, NULL, sizeof(*event)); + if (event == NULL) + FAIL(ISC_R_NOMEMORY); + event->zone = zone; + event->result = ISC_R_SUCCESS; + + evclient = NULL; + ns_client_attach(client, &evclient); + INSIST(client->nupdates == 0); + client->nupdates++; + event->ev_arg = evclient; + + dns_zone_gettask(zone, &zonetask); + isc_task_send(zonetask, ISC_EVENT_PTR(&event)); + + failure: + if (event != NULL) + isc_event_free(ISC_EVENT_PTR(&event)); + return (result); +} diff --git a/bin/named/xfrout.c b/bin/named/xfrout.c new file mode 100644 index 0000000..9fe90a2 --- /dev/null +++ b/bin/named/xfrout.c @@ -0,0 +1,1810 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: xfrout.c,v 1.115.18.8 2006/03/05 23:58:51 marka Exp $ */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#ifdef DLZ +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/*! \file + * \brief + * Outgoing AXFR and IXFR. + */ + +/* + * TODO: + * - IXFR over UDP + */ + +#define XFROUT_COMMON_LOGARGS \ + ns_g_lctx, DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT + +#define XFROUT_PROTOCOL_LOGARGS \ + XFROUT_COMMON_LOGARGS, ISC_LOG_INFO + +#define XFROUT_DEBUG_LOGARGS(n) \ + XFROUT_COMMON_LOGARGS, ISC_LOG_DEBUG(n) + +#define XFROUT_RR_LOGARGS \ + XFROUT_COMMON_LOGARGS, XFROUT_RR_LOGLEVEL + +#define XFROUT_RR_LOGLEVEL ISC_LOG_DEBUG(8) + +/*% + * Fail unconditionally and log as a client error. + * The test against ISC_R_SUCCESS is there to keep the Solaris compiler + * from complaining about "end-of-loop code not reached". + */ +#define FAILC(code, msg) \ + do { \ + result = (code); \ + ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \ + NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \ + "bad zone transfer request: %s (%s)", \ + msg, isc_result_totext(code)); \ + if (result != ISC_R_SUCCESS) goto failure; \ + } while (0) + +#define FAILQ(code, msg, question, rdclass) \ + do { \ + char _buf1[DNS_NAME_FORMATSIZE]; \ + char _buf2[DNS_RDATACLASS_FORMATSIZE]; \ + result = (code); \ + dns_name_format(question, _buf1, sizeof(_buf1)); \ + dns_rdataclass_format(rdclass, _buf2, sizeof(_buf2)); \ + ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \ + NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \ + "bad zone transfer request: '%s/%s': %s (%s)", \ + _buf1, _buf2, msg, isc_result_totext(code)); \ + if (result != ISC_R_SUCCESS) goto failure; \ + } while (0) + +#define CHECK(op) \ + do { result = (op); \ + if (result != ISC_R_SUCCESS) goto failure; \ + } while (0) + +/**************************************************************************/ +/*% + * A db_rr_iterator_t is an iterator that iterates over an entire database, + * returning one RR at a time, in some arbitrary order. + */ + +typedef struct db_rr_iterator db_rr_iterator_t; + +/*% db_rr_iterator structure */ +struct db_rr_iterator { + isc_result_t result; + dns_db_t *db; + dns_dbiterator_t *dbit; + dns_dbversion_t *ver; + isc_stdtime_t now; + dns_dbnode_t *node; + dns_fixedname_t fixedname; + dns_rdatasetiter_t *rdatasetit; + dns_rdataset_t rdataset; + dns_rdata_t rdata; +}; + +static isc_result_t +db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver, + isc_stdtime_t now); + +static isc_result_t +db_rr_iterator_first(db_rr_iterator_t *it); + +static isc_result_t +db_rr_iterator_next(db_rr_iterator_t *it); + +static void +db_rr_iterator_current(db_rr_iterator_t *it, dns_name_t **name, + isc_uint32_t *ttl, dns_rdata_t **rdata); + +static void +db_rr_iterator_destroy(db_rr_iterator_t *it); + +static isc_result_t +db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver, + isc_stdtime_t now) +{ + isc_result_t result; + it->db = db; + it->dbit = NULL; + it->ver = ver; + it->now = now; + it->node = NULL; + result = dns_db_createiterator(it->db, ISC_FALSE, &it->dbit); + if (result != ISC_R_SUCCESS) + return (result); + it->rdatasetit = NULL; + dns_rdata_init(&it->rdata); + dns_rdataset_init(&it->rdataset); + dns_fixedname_init(&it->fixedname); + INSIST(! dns_rdataset_isassociated(&it->rdataset)); + it->result = ISC_R_SUCCESS; + return (it->result); +} + +static isc_result_t +db_rr_iterator_first(db_rr_iterator_t *it) { + it->result = dns_dbiterator_first(it->dbit); + /* + * The top node may be empty when out of zone glue exists. + * Walk the tree to find the first node with data. + */ + while (it->result == ISC_R_SUCCESS) { + it->result = dns_dbiterator_current(it->dbit, &it->node, + dns_fixedname_name(&it->fixedname)); + if (it->result != ISC_R_SUCCESS) + return (it->result); + + it->result = dns_db_allrdatasets(it->db, it->node, + it->ver, it->now, + &it->rdatasetit); + if (it->result != ISC_R_SUCCESS) + return (it->result); + + it->result = dns_rdatasetiter_first(it->rdatasetit); + if (it->result != ISC_R_SUCCESS) { + /* + * This node is empty. Try next node. + */ + dns_rdatasetiter_destroy(&it->rdatasetit); + dns_db_detachnode(it->db, &it->node); + it->result = dns_dbiterator_next(it->dbit); + continue; + } + dns_rdatasetiter_current(it->rdatasetit, &it->rdataset); + it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER; + it->result = dns_rdataset_first(&it->rdataset); + return (it->result); + } + return (it->result); +} + + +static isc_result_t +db_rr_iterator_next(db_rr_iterator_t *it) { + if (it->result != ISC_R_SUCCESS) + return (it->result); + + INSIST(it->dbit != NULL); + INSIST(it->node != NULL); + INSIST(it->rdatasetit != NULL); + + it->result = dns_rdataset_next(&it->rdataset); + if (it->result == ISC_R_NOMORE) { + dns_rdataset_disassociate(&it->rdataset); + it->result = dns_rdatasetiter_next(it->rdatasetit); + /* + * The while loop body is executed more than once + * only when an empty dbnode needs to be skipped. + */ + while (it->result == ISC_R_NOMORE) { + dns_rdatasetiter_destroy(&it->rdatasetit); + dns_db_detachnode(it->db, &it->node); + it->result = dns_dbiterator_next(it->dbit); + if (it->result == ISC_R_NOMORE) { + /* We are at the end of the entire database. */ + return (it->result); + } + if (it->result != ISC_R_SUCCESS) + return (it->result); + it->result = dns_dbiterator_current(it->dbit, + &it->node, + dns_fixedname_name(&it->fixedname)); + if (it->result != ISC_R_SUCCESS) + return (it->result); + it->result = dns_db_allrdatasets(it->db, it->node, + it->ver, it->now, + &it->rdatasetit); + if (it->result != ISC_R_SUCCESS) + return (it->result); + it->result = dns_rdatasetiter_first(it->rdatasetit); + } + if (it->result != ISC_R_SUCCESS) + return (it->result); + dns_rdatasetiter_current(it->rdatasetit, &it->rdataset); + it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER; + it->result = dns_rdataset_first(&it->rdataset); + if (it->result != ISC_R_SUCCESS) + return (it->result); + } + return (it->result); +} + +static void +db_rr_iterator_pause(db_rr_iterator_t *it) { + RUNTIME_CHECK(dns_dbiterator_pause(it->dbit) == ISC_R_SUCCESS); +} + +static void +db_rr_iterator_destroy(db_rr_iterator_t *it) { + if (dns_rdataset_isassociated(&it->rdataset)) + dns_rdataset_disassociate(&it->rdataset); + if (it->rdatasetit != NULL) + dns_rdatasetiter_destroy(&it->rdatasetit); + if (it->node != NULL) + dns_db_detachnode(it->db, &it->node); + dns_dbiterator_destroy(&it->dbit); +} + +static void +db_rr_iterator_current(db_rr_iterator_t *it, dns_name_t **name, + isc_uint32_t *ttl, dns_rdata_t **rdata) +{ + REQUIRE(name != NULL && *name == NULL); + REQUIRE(it->result == ISC_R_SUCCESS); + *name = dns_fixedname_name(&it->fixedname); + *ttl = it->rdataset.ttl; + dns_rdata_reset(&it->rdata); + dns_rdataset_current(&it->rdataset, &it->rdata); + *rdata = &it->rdata; +} + +/**************************************************************************/ + +/*% Log an RR (for debugging) */ + +static void +log_rr(dns_name_t *name, dns_rdata_t *rdata, isc_uint32_t ttl) { + isc_result_t result; + isc_buffer_t buf; + char mem[2000]; + dns_rdatalist_t rdl; + dns_rdataset_t rds; + dns_rdata_t rd = DNS_RDATA_INIT; + + rdl.type = rdata->type; + rdl.rdclass = rdata->rdclass; + rdl.ttl = ttl; + ISC_LIST_INIT(rdl.rdata); + ISC_LINK_INIT(&rdl, link); + dns_rdataset_init(&rds); + dns_rdata_init(&rd); + dns_rdata_clone(rdata, &rd); + ISC_LIST_APPEND(rdl.rdata, &rd, link); + RUNTIME_CHECK(dns_rdatalist_tordataset(&rdl, &rds) == ISC_R_SUCCESS); + + isc_buffer_init(&buf, mem, sizeof(mem)); + result = dns_rdataset_totext(&rds, name, + ISC_FALSE, ISC_FALSE, &buf); + + /* + * We could use xfrout_log(), but that would produce + * very long lines with a repetitive prefix. + */ + if (result == ISC_R_SUCCESS) { + /* + * Get rid of final newline. + */ + INSIST(buf.used >= 1 && + ((char *) buf.base)[buf.used - 1] == '\n'); + buf.used--; + + isc_log_write(XFROUT_RR_LOGARGS, "%.*s", + (int)isc_buffer_usedlength(&buf), + (char *)isc_buffer_base(&buf)); + } else { + isc_log_write(XFROUT_RR_LOGARGS, ""); + } +} + +/**************************************************************************/ +/* + * An 'rrstream_t' is a polymorphic iterator that returns + * a stream of resource records. There are multiple implementations, + * e.g. for generating AXFR and IXFR records streams. + */ + +typedef struct rrstream_methods rrstream_methods_t; + +typedef struct rrstream { + isc_mem_t *mctx; + rrstream_methods_t *methods; +} rrstream_t; + +struct rrstream_methods { + isc_result_t (*first)(rrstream_t *); + isc_result_t (*next)(rrstream_t *); + void (*current)(rrstream_t *, + dns_name_t **, + isc_uint32_t *, + dns_rdata_t **); + void (*pause)(rrstream_t *); + void (*destroy)(rrstream_t **); +}; + +static void +rrstream_noop_pause(rrstream_t *rs) { + UNUSED(rs); +} + +/**************************************************************************/ +/* + * An 'ixfr_rrstream_t' is an 'rrstream_t' that returns + * an IXFR-like RR stream from a journal file. + * + * The SOA at the beginning of each sequence of additions + * or deletions are included in the stream, but the extra + * SOAs at the beginning and end of the entire transfer are + * not included. + */ + +typedef struct ixfr_rrstream { + rrstream_t common; + dns_journal_t *journal; +} ixfr_rrstream_t; + +/* Forward declarations. */ +static void +ixfr_rrstream_destroy(rrstream_t **sp); + +static rrstream_methods_t ixfr_rrstream_methods; + +/* + * Returns: anything dns_journal_open() or dns_journal_iter_init() + * may return. + */ + +static isc_result_t +ixfr_rrstream_create(isc_mem_t *mctx, + const char *journal_filename, + isc_uint32_t begin_serial, + isc_uint32_t end_serial, + rrstream_t **sp) +{ + ixfr_rrstream_t *s; + isc_result_t result; + + INSIST(sp != NULL && *sp == NULL); + + s = isc_mem_get(mctx, sizeof(*s)); + if (s == NULL) + return (ISC_R_NOMEMORY); + s->common.mctx = mctx; + s->common.methods = &ixfr_rrstream_methods; + s->journal = NULL; + + CHECK(dns_journal_open(mctx, journal_filename, + ISC_FALSE, &s->journal)); + CHECK(dns_journal_iter_init(s->journal, begin_serial, end_serial)); + + *sp = (rrstream_t *) s; + return (ISC_R_SUCCESS); + + failure: + ixfr_rrstream_destroy((rrstream_t **) (void *)&s); + return (result); +} + +static isc_result_t +ixfr_rrstream_first(rrstream_t *rs) { + ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; + return (dns_journal_first_rr(s->journal)); +} + +static isc_result_t +ixfr_rrstream_next(rrstream_t *rs) { + ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; + return (dns_journal_next_rr(s->journal)); +} + +static void +ixfr_rrstream_current(rrstream_t *rs, + dns_name_t **name, isc_uint32_t *ttl, + dns_rdata_t **rdata) +{ + ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; + dns_journal_current_rr(s->journal, name, ttl, rdata); +} + +static void +ixfr_rrstream_destroy(rrstream_t **rsp) { + ixfr_rrstream_t *s = (ixfr_rrstream_t *) *rsp; + if (s->journal != 0) + dns_journal_destroy(&s->journal); + isc_mem_put(s->common.mctx, s, sizeof(*s)); +} + +static rrstream_methods_t ixfr_rrstream_methods = { + ixfr_rrstream_first, + ixfr_rrstream_next, + ixfr_rrstream_current, + rrstream_noop_pause, + ixfr_rrstream_destroy +}; + +/**************************************************************************/ +/* + * An 'axfr_rrstream_t' is an 'rrstream_t' that returns + * an AXFR-like RR stream from a database. + * + * The SOAs at the beginning and end of the transfer are + * not included in the stream. + */ + +typedef struct axfr_rrstream { + rrstream_t common; + db_rr_iterator_t it; + isc_boolean_t it_valid; +} axfr_rrstream_t; + +/* + * Forward declarations. + */ +static void +axfr_rrstream_destroy(rrstream_t **rsp); + +static rrstream_methods_t axfr_rrstream_methods; + +static isc_result_t +axfr_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver, + rrstream_t **sp) +{ + axfr_rrstream_t *s; + isc_result_t result; + + INSIST(sp != NULL && *sp == NULL); + + s = isc_mem_get(mctx, sizeof(*s)); + if (s == NULL) + return (ISC_R_NOMEMORY); + s->common.mctx = mctx; + s->common.methods = &axfr_rrstream_methods; + s->it_valid = ISC_FALSE; + + CHECK(db_rr_iterator_init(&s->it, db, ver, 0)); + s->it_valid = ISC_TRUE; + + *sp = (rrstream_t *) s; + return (ISC_R_SUCCESS); + + failure: + axfr_rrstream_destroy((rrstream_t **) (void *)&s); + return (result); +} + +static isc_result_t +axfr_rrstream_first(rrstream_t *rs) { + axfr_rrstream_t *s = (axfr_rrstream_t *) rs; + isc_result_t result; + result = db_rr_iterator_first(&s->it); + if (result != ISC_R_SUCCESS) + return (result); + /* Skip SOA records. */ + for (;;) { + dns_name_t *name_dummy = NULL; + isc_uint32_t ttl_dummy; + dns_rdata_t *rdata = NULL; + db_rr_iterator_current(&s->it, &name_dummy, + &ttl_dummy, &rdata); + if (rdata->type != dns_rdatatype_soa) + break; + result = db_rr_iterator_next(&s->it); + if (result != ISC_R_SUCCESS) + break; + } + return (result); +} + +static isc_result_t +axfr_rrstream_next(rrstream_t *rs) { + axfr_rrstream_t *s = (axfr_rrstream_t *) rs; + isc_result_t result; + + /* Skip SOA records. */ + for (;;) { + dns_name_t *name_dummy = NULL; + isc_uint32_t ttl_dummy; + dns_rdata_t *rdata = NULL; + result = db_rr_iterator_next(&s->it); + if (result != ISC_R_SUCCESS) + break; + db_rr_iterator_current(&s->it, &name_dummy, + &ttl_dummy, &rdata); + if (rdata->type != dns_rdatatype_soa) + break; + } + return (result); +} + +static void +axfr_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, + dns_rdata_t **rdata) +{ + axfr_rrstream_t *s = (axfr_rrstream_t *) rs; + db_rr_iterator_current(&s->it, name, ttl, rdata); +} + +static void +axfr_rrstream_pause(rrstream_t *rs) { + axfr_rrstream_t *s = (axfr_rrstream_t *) rs; + db_rr_iterator_pause(&s->it); +} + +static void +axfr_rrstream_destroy(rrstream_t **rsp) { + axfr_rrstream_t *s = (axfr_rrstream_t *) *rsp; + if (s->it_valid) + db_rr_iterator_destroy(&s->it); + isc_mem_put(s->common.mctx, s, sizeof(*s)); +} + +static rrstream_methods_t axfr_rrstream_methods = { + axfr_rrstream_first, + axfr_rrstream_next, + axfr_rrstream_current, + axfr_rrstream_pause, + axfr_rrstream_destroy +}; + +/**************************************************************************/ +/* + * An 'soa_rrstream_t' is a degenerate 'rrstream_t' that returns + * a single SOA record. + */ + +typedef struct soa_rrstream { + rrstream_t common; + dns_difftuple_t *soa_tuple; +} soa_rrstream_t; + +/* + * Forward declarations. + */ +static void +soa_rrstream_destroy(rrstream_t **rsp); + +static rrstream_methods_t soa_rrstream_methods; + +static isc_result_t +soa_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver, + rrstream_t **sp) +{ + soa_rrstream_t *s; + isc_result_t result; + + INSIST(sp != NULL && *sp == NULL); + + s = isc_mem_get(mctx, sizeof(*s)); + if (s == NULL) + return (ISC_R_NOMEMORY); + s->common.mctx = mctx; + s->common.methods = &soa_rrstream_methods; + s->soa_tuple = NULL; + + CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, + &s->soa_tuple)); + + *sp = (rrstream_t *) s; + return (ISC_R_SUCCESS); + + failure: + soa_rrstream_destroy((rrstream_t **) (void *)&s); + return (result); +} + +static isc_result_t +soa_rrstream_first(rrstream_t *rs) { + UNUSED(rs); + return (ISC_R_SUCCESS); +} + +static isc_result_t +soa_rrstream_next(rrstream_t *rs) { + UNUSED(rs); + return (ISC_R_NOMORE); +} + +static void +soa_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, + dns_rdata_t **rdata) +{ + soa_rrstream_t *s = (soa_rrstream_t *) rs; + *name = &s->soa_tuple->name; + *ttl = s->soa_tuple->ttl; + *rdata = &s->soa_tuple->rdata; +} + +static void +soa_rrstream_destroy(rrstream_t **rsp) { + soa_rrstream_t *s = (soa_rrstream_t *) *rsp; + if (s->soa_tuple != NULL) + dns_difftuple_free(&s->soa_tuple); + isc_mem_put(s->common.mctx, s, sizeof(*s)); +} + +static rrstream_methods_t soa_rrstream_methods = { + soa_rrstream_first, + soa_rrstream_next, + soa_rrstream_current, + rrstream_noop_pause, + soa_rrstream_destroy +}; + +/**************************************************************************/ +/* + * A 'compound_rrstream_t' objects owns a soa_rrstream + * and another rrstream, the "data stream". It returns + * a concatenated stream consisting of the soa_rrstream, then + * the data stream, then the soa_rrstream again. + * + * The component streams are owned by the compound_rrstream_t + * and are destroyed with it. + */ + +typedef struct compound_rrstream { + rrstream_t common; + rrstream_t *components[3]; + int state; + isc_result_t result; +} compound_rrstream_t; + +/* + * Forward declarations. + */ +static void +compound_rrstream_destroy(rrstream_t **rsp); + +static isc_result_t +compound_rrstream_next(rrstream_t *rs); + +static rrstream_methods_t compound_rrstream_methods; + +/* + * Requires: + * soa_stream != NULL && *soa_stream != NULL + * data_stream != NULL && *data_stream != NULL + * sp != NULL && *sp == NULL + * + * Ensures: + * *soa_stream == NULL + * *data_stream == NULL + * *sp points to a valid compound_rrstream_t + * The soa and data streams will be destroyed + * when the compound_rrstream_t is destroyed. + */ +static isc_result_t +compound_rrstream_create(isc_mem_t *mctx, rrstream_t **soa_stream, + rrstream_t **data_stream, rrstream_t **sp) +{ + compound_rrstream_t *s; + + INSIST(sp != NULL && *sp == NULL); + + s = isc_mem_get(mctx, sizeof(*s)); + if (s == NULL) + return (ISC_R_NOMEMORY); + s->common.mctx = mctx; + s->common.methods = &compound_rrstream_methods; + s->components[0] = *soa_stream; + s->components[1] = *data_stream; + s->components[2] = *soa_stream; + s->state = -1; + s->result = ISC_R_FAILURE; + + *soa_stream = NULL; + *data_stream = NULL; + *sp = (rrstream_t *) s; + return (ISC_R_SUCCESS); +} + +static isc_result_t +compound_rrstream_first(rrstream_t *rs) { + compound_rrstream_t *s = (compound_rrstream_t *) rs; + s->state = 0; + do { + rrstream_t *curstream = s->components[s->state]; + s->result = curstream->methods->first(curstream); + } while (s->result == ISC_R_NOMORE && s->state < 2); + return (s->result); +} + +static isc_result_t +compound_rrstream_next(rrstream_t *rs) { + compound_rrstream_t *s = (compound_rrstream_t *) rs; + rrstream_t *curstream = s->components[s->state]; + s->result = curstream->methods->next(curstream); + while (s->result == ISC_R_NOMORE) { + /* + * Make sure locks held by the current stream + * are released before we switch streams. + */ + curstream->methods->pause(curstream); + if (s->state == 2) + return (ISC_R_NOMORE); + s->state++; + curstream = s->components[s->state]; + s->result = curstream->methods->first(curstream); + } + return (s->result); +} + +static void +compound_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, + dns_rdata_t **rdata) +{ + compound_rrstream_t *s = (compound_rrstream_t *) rs; + rrstream_t *curstream; + INSIST(0 <= s->state && s->state < 3); + INSIST(s->result == ISC_R_SUCCESS); + curstream = s->components[s->state]; + curstream->methods->current(curstream, name, ttl, rdata); +} + +static void +compound_rrstream_pause(rrstream_t *rs) +{ + compound_rrstream_t *s = (compound_rrstream_t *) rs; + rrstream_t *curstream; + INSIST(0 <= s->state && s->state < 3); + curstream = s->components[s->state]; + curstream->methods->pause(curstream); +} + +static void +compound_rrstream_destroy(rrstream_t **rsp) { + compound_rrstream_t *s = (compound_rrstream_t *) *rsp; + s->components[0]->methods->destroy(&s->components[0]); + s->components[1]->methods->destroy(&s->components[1]); + s->components[2] = NULL; /* Copy of components[0]. */ + isc_mem_put(s->common.mctx, s, sizeof(*s)); +} + +static rrstream_methods_t compound_rrstream_methods = { + compound_rrstream_first, + compound_rrstream_next, + compound_rrstream_current, + compound_rrstream_pause, + compound_rrstream_destroy +}; + +/**************************************************************************/ +/* + * An 'xfrout_ctx_t' contains the state of an outgoing AXFR or IXFR + * in progress. + */ + +typedef struct { + isc_mem_t *mctx; + ns_client_t *client; + unsigned int id; /* ID of request */ + dns_name_t *qname; /* Question name of request */ + dns_rdatatype_t qtype; /* dns_rdatatype_{a,i}xfr */ + dns_rdataclass_t qclass; + dns_db_t *db; + dns_dbversion_t *ver; + isc_quota_t *quota; + rrstream_t *stream; /* The XFR RR stream */ + isc_boolean_t end_of_stream; /* EOS has been reached */ + isc_buffer_t buf; /* Buffer for message owner + names and rdatas */ + isc_buffer_t txlenbuf; /* Transmit length buffer */ + isc_buffer_t txbuf; /* Transmit message buffer */ + void *txmem; + unsigned int txmemlen; + unsigned int nmsg; /* Number of messages sent */ + dns_tsigkey_t *tsigkey; /* Key used to create TSIG */ + isc_buffer_t *lasttsig; /* the last TSIG */ + isc_boolean_t many_answers; + int sends; /* Send in progress */ + isc_boolean_t shuttingdown; + const char *mnemonic; /* Style of transfer */ +} xfrout_ctx_t; + +static isc_result_t +xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, + unsigned int id, dns_name_t *qname, dns_rdatatype_t qtype, + dns_rdataclass_t qclass, + dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota, + rrstream_t *stream, dns_tsigkey_t *tsigkey, + isc_buffer_t *lasttsig, + unsigned int maxtime, + unsigned int idletime, + isc_boolean_t many_answers, + xfrout_ctx_t **xfrp); + +static void +sendstream(xfrout_ctx_t *xfr); + +static void +xfrout_senddone(isc_task_t *task, isc_event_t *event); + +static void +xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg); + +static void +xfrout_maybe_destroy(xfrout_ctx_t *xfr); + +static void +xfrout_ctx_destroy(xfrout_ctx_t **xfrp); + +static void +xfrout_client_shutdown(void *arg, isc_result_t result); + +static void +xfrout_log1(ns_client_t *client, dns_name_t *zonename, + dns_rdataclass_t rdclass, int level, + const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); + +static void +xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) + ISC_FORMAT_PRINTF(3, 4); + +/**************************************************************************/ + +void +ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) { + isc_result_t result; + dns_name_t *question_name; + dns_rdataset_t *question_rdataset; + dns_zone_t *zone = NULL; + dns_db_t *db = NULL; + dns_dbversion_t *ver = NULL; + dns_rdataclass_t question_class; + rrstream_t *soa_stream = NULL; + rrstream_t *data_stream = NULL; + rrstream_t *stream = NULL; + dns_difftuple_t *current_soa_tuple = NULL; + dns_name_t *soa_name; + dns_rdataset_t *soa_rdataset; + dns_rdata_t soa_rdata = DNS_RDATA_INIT; + isc_boolean_t have_soa = ISC_FALSE; + const char *mnemonic = NULL; + isc_mem_t *mctx = client->mctx; + dns_message_t *request = client->message; + xfrout_ctx_t *xfr = NULL; + isc_quota_t *quota = NULL; + dns_transfer_format_t format = client->view->transfer_format; + isc_netaddr_t na; + dns_peer_t *peer = NULL; + isc_buffer_t *tsigbuf = NULL; + char *journalfile; + char msg[NS_CLIENT_ACLMSGSIZE("zone transfer")]; + char keyname[DNS_NAME_FORMATSIZE]; + isc_boolean_t is_poll = ISC_FALSE; +#ifdef DLZ + isc_boolean_t is_dlz = ISC_FALSE; +#endif + + switch (reqtype) { + case dns_rdatatype_axfr: + mnemonic = "AXFR"; + break; + case dns_rdatatype_ixfr: + mnemonic = "IXFR"; + break; + default: + INSIST(0); + break; + } + + ns_client_log(client, + DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT, + ISC_LOG_DEBUG(6), "%s request", mnemonic); + /* + * Apply quota. + */ + result = isc_quota_attach(&ns_g_server->xfroutquota, "a); + if (result != ISC_R_SUCCESS) { + isc_log_write(XFROUT_COMMON_LOGARGS, ISC_LOG_WARNING, + "%s request denied: %s", mnemonic, + isc_result_totext(result)); + goto failure; + } + + /* + * Interpret the question section. + */ + result = dns_message_firstname(request, DNS_SECTION_QUESTION); + INSIST(result == ISC_R_SUCCESS); + + /* + * The question section must contain exactly one question, and + * it must be for AXFR/IXFR as appropriate. + */ + question_name = NULL; + dns_message_currentname(request, DNS_SECTION_QUESTION, &question_name); + question_rdataset = ISC_LIST_HEAD(question_name->list); + question_class = question_rdataset->rdclass; + INSIST(question_rdataset->type == reqtype); + if (ISC_LIST_NEXT(question_rdataset, link) != NULL) + FAILC(DNS_R_FORMERR, "multiple questions"); + result = dns_message_nextname(request, DNS_SECTION_QUESTION); + if (result != ISC_R_NOMORE) + FAILC(DNS_R_FORMERR, "multiple questions"); + + result = dns_zt_find(client->view->zonetable, question_name, 0, NULL, + &zone); + + if (result != ISC_R_SUCCESS) +#ifdef DLZ + { + /* + * Normal zone table does not have a match. Try the DLZ database + */ + if (client->view->dlzdatabase != NULL) { + result = dns_dlzallowzonexfr(client->view, + question_name, &client->peeraddr, + &db); + + if (result == ISC_R_NOPERM) { + char _buf1[DNS_NAME_FORMATSIZE]; + char _buf2[DNS_RDATACLASS_FORMATSIZE]; + + result = DNS_R_REFUSED; + dns_name_format(question_name, _buf1, + sizeof(_buf1)); + dns_rdataclass_format(question_class, + _buf2, sizeof(_buf2)); + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_XFER_OUT, + ISC_LOG_ERROR, + "zone transfer '%s/%s' denied", + _buf1, _buf2); + goto failure; + } + if (result != ISC_R_SUCCESS) +#endif + FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", + question_name, question_class); +#ifdef DLZ + is_dlz = ISC_TRUE; + /* + * DLZ only support full zone transfer, not incremental + */ + if (reqtype != dns_rdatatype_axfr) { + mnemonic = "AXFR-style IXFR"; + reqtype = dns_rdatatype_axfr; + } + + } else { + /* + * not DLZ and not in normal zone table, we are + * not authoritative + */ + FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", + question_name, question_class); + } + } else { + /* zone table has a match */ +#endif + switch(dns_zone_gettype(zone)) { + case dns_zone_master: + case dns_zone_slave: + break; /* Master and slave zones are OK for transfer. */ + default: + FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", question_name, question_class); + } + CHECK(dns_zone_getdb(zone, &db)); + dns_db_currentversion(db, &ver); +#ifdef DLZ + } +#endif + + xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), + "%s question section OK", mnemonic); + + /* + * Check the authority section. Look for a SOA record with + * the same name and class as the question. + */ + for (result = dns_message_firstname(request, DNS_SECTION_AUTHORITY); + result == ISC_R_SUCCESS; + result = dns_message_nextname(request, DNS_SECTION_AUTHORITY)) + { + soa_name = NULL; + dns_message_currentname(request, DNS_SECTION_AUTHORITY, + &soa_name); + + /* + * Ignore data whose owner name is not the zone apex. + */ + if (! dns_name_equal(soa_name, question_name)) + continue; + + for (soa_rdataset = ISC_LIST_HEAD(soa_name->list); + soa_rdataset != NULL; + soa_rdataset = ISC_LIST_NEXT(soa_rdataset, link)) + { + /* + * Ignore non-SOA data. + */ + if (soa_rdataset->type != dns_rdatatype_soa) + continue; + if (soa_rdataset->rdclass != question_class) + continue; + + CHECK(dns_rdataset_first(soa_rdataset)); + dns_rdataset_current(soa_rdataset, &soa_rdata); + result = dns_rdataset_next(soa_rdataset); + if (result == ISC_R_SUCCESS) + FAILC(DNS_R_FORMERR, + "IXFR authority section " + "has multiple SOAs"); + have_soa = ISC_TRUE; + goto got_soa; + } + } + got_soa: + if (result != ISC_R_NOMORE) + CHECK(result); + + xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), + "%s authority section OK", mnemonic); + + /* + * Decide whether to allow this transfer. + */ +#ifdef DLZ + /* + * if not a DLZ zone decide whether to allow this transfer. + */ + if (!is_dlz) { +#endif + ns_client_aclmsg("zone transfer", question_name, reqtype, + client->view->rdclass, msg, sizeof(msg)); + CHECK(ns_client_checkacl(client, msg, + dns_zone_getxfracl(zone), ISC_TRUE, + ISC_LOG_ERROR)); +#ifdef DLZ + } +#endif + + /* + * AXFR over UDP is not possible. + */ + if (reqtype == dns_rdatatype_axfr && + (client->attributes & NS_CLIENTATTR_TCP) == 0) + FAILC(DNS_R_FORMERR, "attempted AXFR over UDP"); + + /* + * Look up the requesting server in the peer table. + */ + isc_netaddr_fromsockaddr(&na, &client->peeraddr); + (void)dns_peerlist_peerbyaddr(client->view->peers, &na, &peer); + + /* + * Decide on the transfer format (one-answer or many-answers). + */ + if (peer != NULL) + (void)dns_peer_gettransferformat(peer, &format); + + /* + * Get a dynamically allocated copy of the current SOA. + */ +#ifdef DLZ + if (is_dlz) + dns_db_currentversion(db, &ver); +#endif + CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, + ¤t_soa_tuple)); + + if (reqtype == dns_rdatatype_ixfr) { + isc_uint32_t begin_serial, current_serial; + isc_boolean_t provide_ixfr; + + /* + * Outgoing IXFR may have been disabled for this peer + * or globally. + */ + provide_ixfr = client->view->provideixfr; + if (peer != NULL) + (void) dns_peer_getprovideixfr(peer, &provide_ixfr); + if (provide_ixfr == ISC_FALSE) + goto axfr_fallback; + + if (! have_soa) + FAILC(DNS_R_FORMERR, + "IXFR request missing SOA"); + + begin_serial = dns_soa_getserial(&soa_rdata); + current_serial = dns_soa_getserial(¤t_soa_tuple->rdata); + + /* + * RFC1995 says "If an IXFR query with the same or + * newer version number than that of the server + * is received, it is replied to with a single SOA + * record of the server's current version, just as + * in AXFR". The claim about AXFR is incorrect, + * but other than that, we do as the RFC says. + * + * Sending a single SOA record is also how we refuse + * IXFR over UDP (currently, we always do). + */ + if (DNS_SERIAL_GE(begin_serial, current_serial) || + (client->attributes & NS_CLIENTATTR_TCP) == 0) + { + CHECK(soa_rrstream_create(mctx, db, ver, &stream)); + is_poll = ISC_TRUE; + goto have_stream; + } + journalfile = dns_zone_getjournal(zone); + if (journalfile != NULL) + result = ixfr_rrstream_create(mctx, + journalfile, + begin_serial, + current_serial, + &data_stream); + else + result = ISC_R_NOTFOUND; + if (result == ISC_R_NOTFOUND || + result == ISC_R_RANGE) { + xfrout_log1(client, question_name, question_class, + ISC_LOG_DEBUG(4), + "IXFR version not in journal, " + "falling back to AXFR"); + mnemonic = "AXFR-style IXFR"; + goto axfr_fallback; + } + CHECK(result); + } else { + axfr_fallback: + CHECK(axfr_rrstream_create(mctx, db, ver, + &data_stream)); + } + + /* + * Bracket the the data stream with SOAs. + */ + CHECK(soa_rrstream_create(mctx, db, ver, &soa_stream)); + CHECK(compound_rrstream_create(mctx, &soa_stream, &data_stream, + &stream)); + soa_stream = NULL; + data_stream = NULL; + + have_stream: + CHECK(dns_message_getquerytsig(request, mctx, &tsigbuf)); + /* + * Create the xfrout context object. This transfers the ownership + * of "stream", "db", "ver", and "quota" to the xfrout context object. + */ + + + +#ifdef DLZ + if (is_dlz) + CHECK(xfrout_ctx_create(mctx, client, request->id, question_name, + reqtype, question_class, db, ver, quota, + stream, dns_message_gettsigkey(request), + tsigbuf, + 3600, + 3600, + (format == dns_many_answers) ? + ISC_TRUE : ISC_FALSE, + &xfr)); + else +#endif + CHECK(xfrout_ctx_create(mctx, client, request->id, question_name, + reqtype, question_class, db, ver, quota, + stream, dns_message_gettsigkey(request), + tsigbuf, + dns_zone_getmaxxfrout(zone), + dns_zone_getidleout(zone), + (format == dns_many_answers) ? + ISC_TRUE : ISC_FALSE, + &xfr)); + + xfr->mnemonic = mnemonic; + stream = NULL; + quota = NULL; + + CHECK(xfr->stream->methods->first(xfr->stream)); + + if (xfr->tsigkey != NULL) { + dns_name_format(&xfr->tsigkey->name, keyname, sizeof(keyname)); + } else + keyname[0] = '\0'; + if (is_poll) + xfrout_log1(client, question_name, question_class, + ISC_LOG_DEBUG(1), "IXFR poll up to date%s%s", + (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname); + else + xfrout_log1(client, question_name, question_class, + ISC_LOG_INFO, "%s started%s%s", mnemonic, + (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname); + + /* + * Hand the context over to sendstream(). Set xfr to NULL; + * sendstream() is responsible for either passing the + * context on to a later event handler or destroying it. + */ + sendstream(xfr); + xfr = NULL; + + result = ISC_R_SUCCESS; + + failure: + if (quota != NULL) + isc_quota_detach("a); + if (current_soa_tuple != NULL) + dns_difftuple_free(¤t_soa_tuple); + if (stream != NULL) + stream->methods->destroy(&stream); + if (soa_stream != NULL) + soa_stream->methods->destroy(&soa_stream); + if (data_stream != NULL) + data_stream->methods->destroy(&data_stream); + if (ver != NULL) + dns_db_closeversion(db, &ver, ISC_FALSE); + if (db != NULL) + dns_db_detach(&db); + if (zone != NULL) + dns_zone_detach(&zone); + /* XXX kludge */ + if (xfr != NULL) { + xfrout_fail(xfr, result, "setting up zone transfer"); + } else if (result != ISC_R_SUCCESS) { + ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, + NS_LOGMODULE_XFER_OUT, + ISC_LOG_DEBUG(3), "zone transfer setup failed"); + ns_client_error(client, result); + } +} + +static isc_result_t +xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id, + dns_name_t *qname, dns_rdatatype_t qtype, + dns_rdataclass_t qclass, + dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota, + rrstream_t *stream, dns_tsigkey_t *tsigkey, + isc_buffer_t *lasttsig, unsigned int maxtime, + unsigned int idletime, isc_boolean_t many_answers, + xfrout_ctx_t **xfrp) +{ + xfrout_ctx_t *xfr; + isc_result_t result; + unsigned int len; + void *mem; + + INSIST(xfrp != NULL && *xfrp == NULL); + xfr = isc_mem_get(mctx, sizeof(*xfr)); + if (xfr == NULL) + return (ISC_R_NOMEMORY); + xfr->mctx = mctx; + xfr->client = NULL; + ns_client_attach(client, &xfr->client); + xfr->id = id; + xfr->qname = qname; + xfr->qtype = qtype; + xfr->qclass = qclass; + xfr->db = NULL; + xfr->ver = NULL; + dns_db_attach(db, &xfr->db); + dns_db_attachversion(db, ver, &xfr->ver); + xfr->end_of_stream = ISC_FALSE; + xfr->tsigkey = tsigkey; + xfr->lasttsig = lasttsig; + xfr->txmem = NULL; + xfr->txmemlen = 0; + xfr->nmsg = 0; + xfr->many_answers = many_answers, + xfr->sends = 0; + xfr->shuttingdown = ISC_FALSE; + xfr->mnemonic = NULL; + xfr->buf.base = NULL; + xfr->buf.length = 0; + xfr->txmem = NULL; + xfr->txmemlen = 0; + xfr->stream = NULL; + xfr->quota = NULL; + + /* + * Allocate a temporary buffer for the uncompressed response + * message data. The size should be no more than 65535 bytes + * so that the compressed data will fit in a TCP message, + * and no less than 65535 bytes so that an almost maximum-sized + * RR will fit. Note that although 65535-byte RRs are allowed + * in principle, they cannot be zone-transferred (at least not + * if uncompressible), because the message and RR headers would + * push the size of the TCP message over the 65536 byte limit. + */ + len = 65535; + mem = isc_mem_get(mctx, len); + if (mem == NULL) { + result = ISC_R_NOMEMORY; + goto failure; + } + isc_buffer_init(&xfr->buf, mem, len); + + /* + * Allocate another temporary buffer for the compressed + * response message and its TCP length prefix. + */ + len = 2 + 65535; + mem = isc_mem_get(mctx, len); + if (mem == NULL) { + result = ISC_R_NOMEMORY; + goto failure; + } + isc_buffer_init(&xfr->txlenbuf, mem, 2); + isc_buffer_init(&xfr->txbuf, (char *) mem + 2, len - 2); + xfr->txmem = mem; + xfr->txmemlen = len; + + CHECK(dns_timer_setidle(xfr->client->timer, + maxtime, idletime, ISC_FALSE)); + + /* + * Register a shutdown callback with the client, so that we + * can stop the transfer immediately when the client task + * gets a shutdown event. + */ + xfr->client->shutdown = xfrout_client_shutdown; + xfr->client->shutdown_arg = xfr; + /* + * These MUST be after the last "goto failure;" / CHECK to + * prevent a double free by the caller. + */ + xfr->quota = quota; + xfr->stream = stream; + + *xfrp = xfr; + return (ISC_R_SUCCESS); + +failure: + xfrout_ctx_destroy(&xfr); + return (result); +} + + +/* + * Arrange to send as much as we can of "stream" without blocking. + * + * Requires: + * The stream iterator is initialized and points at an RR, + * or possiby at the end of the stream (that is, the + * _first method of the iterator has been called). + */ +static void +sendstream(xfrout_ctx_t *xfr) { + dns_message_t *tcpmsg = NULL; + dns_message_t *msg = NULL; /* Client message if UDP, tcpmsg if TCP */ + isc_result_t result; + isc_region_t used; + isc_region_t region; + dns_rdataset_t *qrdataset; + dns_name_t *msgname = NULL; + dns_rdata_t *msgrdata = NULL; + dns_rdatalist_t *msgrdl = NULL; + dns_rdataset_t *msgrds = NULL; + dns_compress_t cctx; + isc_boolean_t cleanup_cctx = ISC_FALSE; + + int n_rrs; + + isc_buffer_clear(&xfr->buf); + isc_buffer_clear(&xfr->txlenbuf); + isc_buffer_clear(&xfr->txbuf); + + if ((xfr->client->attributes & NS_CLIENTATTR_TCP) == 0) { + /* + * In the UDP case, we put the response data directly into + * the client message. + */ + msg = xfr->client->message; + CHECK(dns_message_reply(msg, ISC_TRUE)); + } else { + /* + * TCP. Build a response dns_message_t, temporarily storing + * the raw, uncompressed owner names and RR data contiguously + * in xfr->buf. We know that if the uncompressed data fits + * in xfr->buf, the compressed data will surely fit in a TCP + * message. + */ + + CHECK(dns_message_create(xfr->mctx, + DNS_MESSAGE_INTENTRENDER, &tcpmsg)); + msg = tcpmsg; + + msg->id = xfr->id; + msg->rcode = dns_rcode_noerror; + msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA; + if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0) + msg->flags |= DNS_MESSAGEFLAG_RA; + CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); + CHECK(dns_message_setquerytsig(msg, xfr->lasttsig)); + if (xfr->lasttsig != NULL) + isc_buffer_free(&xfr->lasttsig); + + /* + * Include a question section in the first message only. + * BIND 8.2.1 will not recognize an IXFR if it does not + * have a question section. + */ + if (xfr->nmsg == 0) { + dns_name_t *qname = NULL; + isc_region_t r; + + /* + * Reserve space for the 12-byte message header + * and 4 bytes of question. + */ + isc_buffer_add(&xfr->buf, 12 + 4); + + qrdataset = NULL; + result = dns_message_gettemprdataset(msg, &qrdataset); + if (result != ISC_R_SUCCESS) + goto failure; + dns_rdataset_init(qrdataset); + dns_rdataset_makequestion(qrdataset, + xfr->client->message->rdclass, + xfr->qtype); + + result = dns_message_gettempname(msg, &qname); + if (result != ISC_R_SUCCESS) + goto failure; + dns_name_init(qname, NULL); + isc_buffer_availableregion(&xfr->buf, &r); + INSIST(r.length >= xfr->qname->length); + r.length = xfr->qname->length; + isc_buffer_putmem(&xfr->buf, xfr->qname->ndata, + xfr->qname->length); + dns_name_fromregion(qname, &r); + ISC_LIST_INIT(qname->list); + ISC_LIST_APPEND(qname->list, qrdataset, link); + + dns_message_addname(msg, qname, DNS_SECTION_QUESTION); + } + else + msg->tcp_continuation = 1; + } + + /* + * Try to fit in as many RRs as possible, unless "one-answer" + * format has been requested. + */ + for (n_rrs = 0; ; n_rrs++) { + dns_name_t *name = NULL; + isc_uint32_t ttl; + dns_rdata_t *rdata = NULL; + + unsigned int size; + isc_region_t r; + + msgname = NULL; + msgrdata = NULL; + msgrdl = NULL; + msgrds = NULL; + + xfr->stream->methods->current(xfr->stream, + &name, &ttl, &rdata); + size = name->length + 10 + rdata->length; + isc_buffer_availableregion(&xfr->buf, &r); + if (size >= r.length) { + /* + * RR would not fit. If there are other RRs in the + * buffer, send them now and leave this RR to the + * next message. If this RR overflows the buffer + * all by itself, fail. + * + * In theory some RRs might fit in a TCP message + * when compressed even if they do not fit when + * uncompressed, but surely we don't want + * to send such monstrosities to an unsuspecting + * slave. + */ + if (n_rrs == 0) { + xfrout_log(xfr, ISC_LOG_WARNING, + "RR too large for zone transfer " + "(%d bytes)", size); + /* XXX DNS_R_RRTOOLARGE? */ + result = ISC_R_NOSPACE; + goto failure; + } + break; + } + + if (isc_log_wouldlog(ns_g_lctx, XFROUT_RR_LOGLEVEL)) + log_rr(name, rdata, ttl); /* XXX */ + + result = dns_message_gettempname(msg, &msgname); + if (result != ISC_R_SUCCESS) + goto failure; + dns_name_init(msgname, NULL); + isc_buffer_availableregion(&xfr->buf, &r); + INSIST(r.length >= name->length); + r.length = name->length; + isc_buffer_putmem(&xfr->buf, name->ndata, name->length); + dns_name_fromregion(msgname, &r); + + /* Reserve space for RR header. */ + isc_buffer_add(&xfr->buf, 10); + + result = dns_message_gettemprdata(msg, &msgrdata); + if (result != ISC_R_SUCCESS) + goto failure; + isc_buffer_availableregion(&xfr->buf, &r); + r.length = rdata->length; + isc_buffer_putmem(&xfr->buf, rdata->data, rdata->length); + dns_rdata_init(msgrdata); + dns_rdata_fromregion(msgrdata, + rdata->rdclass, rdata->type, &r); + + result = dns_message_gettemprdatalist(msg, &msgrdl); + if (result != ISC_R_SUCCESS) + goto failure; + msgrdl->type = rdata->type; + msgrdl->rdclass = rdata->rdclass; + msgrdl->ttl = ttl; + ISC_LINK_INIT(msgrdl, link); + ISC_LIST_INIT(msgrdl->rdata); + ISC_LIST_APPEND(msgrdl->rdata, msgrdata, link); + + result = dns_message_gettemprdataset(msg, &msgrds); + if (result != ISC_R_SUCCESS) + goto failure; + dns_rdataset_init(msgrds); + result = dns_rdatalist_tordataset(msgrdl, msgrds); + INSIST(result == ISC_R_SUCCESS); + + ISC_LIST_APPEND(msgname->list, msgrds, link); + + dns_message_addname(msg, msgname, DNS_SECTION_ANSWER); + msgname = NULL; + + result = xfr->stream->methods->next(xfr->stream); + if (result == ISC_R_NOMORE) { + xfr->end_of_stream = ISC_TRUE; + break; + } + CHECK(result); + + if (! xfr->many_answers) + break; + } + + if ((xfr->client->attributes & NS_CLIENTATTR_TCP) != 0) { + CHECK(dns_compress_init(&cctx, -1, xfr->mctx)); + dns_compress_setsensitive(&cctx, ISC_TRUE); + cleanup_cctx = ISC_TRUE; + CHECK(dns_message_renderbegin(msg, &cctx, &xfr->txbuf)); + CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0)); + CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0)); + CHECK(dns_message_renderend(msg)); + dns_compress_invalidate(&cctx); + cleanup_cctx = ISC_FALSE; + + isc_buffer_usedregion(&xfr->txbuf, &used); + isc_buffer_putuint16(&xfr->txlenbuf, + (isc_uint16_t)used.length); + region.base = xfr->txlenbuf.base; + region.length = 2 + used.length; + xfrout_log(xfr, ISC_LOG_DEBUG(8), + "sending TCP message of %d bytes", + used.length); + CHECK(isc_socket_send(xfr->client->tcpsocket, /* XXX */ + ®ion, xfr->client->task, + xfrout_senddone, + xfr)); + xfr->sends++; + } else { + xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response"); + ns_client_send(xfr->client); + xfr->stream->methods->pause(xfr->stream); + xfrout_ctx_destroy(&xfr); + return; + } + + /* Advance lasttsig to be the last TSIG generated */ + CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig)); + + xfr->nmsg++; + + failure: + if (msgname != NULL) { + if (msgrds != NULL) { + if (dns_rdataset_isassociated(msgrds)) + dns_rdataset_disassociate(msgrds); + dns_message_puttemprdataset(msg, &msgrds); + } + if (msgrdl != NULL) { + ISC_LIST_UNLINK(msgrdl->rdata, msgrdata, link); + dns_message_puttemprdatalist(msg, &msgrdl); + } + if (msgrdata != NULL) + dns_message_puttemprdata(msg, &msgrdata); + dns_message_puttempname(msg, &msgname); + } + + if (tcpmsg != NULL) + dns_message_destroy(&tcpmsg); + + if (cleanup_cctx) + dns_compress_invalidate(&cctx); + /* + * Make sure to release any locks held by database + * iterators before returning from the event handler. + */ + xfr->stream->methods->pause(xfr->stream); + + if (result == ISC_R_SUCCESS) + return; + + xfrout_fail(xfr, result, "sending zone data"); +} + +static void +xfrout_ctx_destroy(xfrout_ctx_t **xfrp) { + xfrout_ctx_t *xfr = *xfrp; + + INSIST(xfr->sends == 0); + + xfr->client->shutdown = NULL; + xfr->client->shutdown_arg = NULL; + + if (xfr->stream != NULL) + xfr->stream->methods->destroy(&xfr->stream); + if (xfr->buf.base != NULL) + isc_mem_put(xfr->mctx, xfr->buf.base, xfr->buf.length); + if (xfr->txmem != NULL) + isc_mem_put(xfr->mctx, xfr->txmem, xfr->txmemlen); + if (xfr->lasttsig != NULL) + isc_buffer_free(&xfr->lasttsig); + if (xfr->quota != NULL) + isc_quota_detach(&xfr->quota); + if (xfr->ver != NULL) + dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE); + if (xfr->db != NULL) + dns_db_detach(&xfr->db); + + ns_client_detach(&xfr->client); + + isc_mem_put(xfr->mctx, xfr, sizeof(*xfr)); + + *xfrp = NULL; +} + +static void +xfrout_senddone(isc_task_t *task, isc_event_t *event) { + isc_socketevent_t *sev = (isc_socketevent_t *)event; + xfrout_ctx_t *xfr = (xfrout_ctx_t *)event->ev_arg; + isc_result_t evresult = sev->result; + + UNUSED(task); + + INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE); + + isc_event_free(&event); + xfr->sends--; + INSIST(xfr->sends == 0); + + (void)isc_timer_touch(xfr->client->timer); + if (xfr->shuttingdown == ISC_TRUE) { + xfrout_maybe_destroy(xfr); + } else if (evresult != ISC_R_SUCCESS) { + xfrout_fail(xfr, evresult, "send"); + } else if (xfr->end_of_stream == ISC_FALSE) { + sendstream(xfr); + } else { + /* End of zone transfer stream. */ + xfrout_log(xfr, ISC_LOG_INFO, "%s ended", xfr->mnemonic); + ns_client_next(xfr->client, ISC_R_SUCCESS); + xfrout_ctx_destroy(&xfr); + } +} + +static void +xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg) { + xfr->shuttingdown = ISC_TRUE; + xfrout_log(xfr, ISC_LOG_ERROR, "%s: %s", + msg, isc_result_totext(result)); + xfrout_maybe_destroy(xfr); +} + +static void +xfrout_maybe_destroy(xfrout_ctx_t *xfr) { + INSIST(xfr->shuttingdown == ISC_TRUE); + if (xfr->sends > 0) { + /* + * If we are currently sending, cancel it and wait for + * cancel event before destroying the context. + */ + isc_socket_cancel(xfr->client->tcpsocket, xfr->client->task, + ISC_SOCKCANCEL_SEND); + } else { + ns_client_next(xfr->client, ISC_R_CANCELED); + xfrout_ctx_destroy(&xfr); + } +} + +static void +xfrout_client_shutdown(void *arg, isc_result_t result) { + xfrout_ctx_t *xfr = (xfrout_ctx_t *) arg; + xfrout_fail(xfr, result, "aborted"); +} + +/* + * Log outgoing zone transfer messages in a format like + * : transfer of : + */ + +static void +xfrout_logv(ns_client_t *client, dns_name_t *zonename, + dns_rdataclass_t rdclass, int level, const char *fmt, va_list ap) + ISC_FORMAT_PRINTF(5, 0); + +static void +xfrout_logv(ns_client_t *client, dns_name_t *zonename, + dns_rdataclass_t rdclass, int level, const char *fmt, va_list ap) +{ + char msgbuf[2048]; + char namebuf[DNS_NAME_FORMATSIZE]; + char classbuf[DNS_RDATACLASS_FORMATSIZE]; + + dns_name_format(zonename, namebuf, sizeof(namebuf)); + dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf)); + vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); + ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, + NS_LOGMODULE_XFER_OUT, level, + "transfer of '%s/%s': %s", namebuf, classbuf, msgbuf); +} + +/* + * Logging function for use when a xfrout_ctx_t has not yet been created. + */ +static void +xfrout_log1(ns_client_t *client, dns_name_t *zonename, + dns_rdataclass_t rdclass, int level, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + xfrout_logv(client, zonename, rdclass, level, fmt, ap); + va_end(ap); +} + +/* + * Logging function for use when there is a xfrout_ctx_t. + */ +static void +xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + xfrout_logv(xfr->client, xfr->qname, xfr->qclass, level, fmt, ap); + va_end(ap); +} diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c new file mode 100644 index 0000000..a0c1bab --- /dev/null +++ b/bin/named/zoneconf.c @@ -0,0 +1,913 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: zoneconf.c,v 1.110.18.23 2006/05/16 03:39:57 marka Exp $ */ + +/*% */ + +#include + +#include +#include +#include +#include +#include /* Required for HP/UX (and others?) */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/*% + * These are BIND9 server defaults, not necessarily identical to the + * library defaults defined in zone.c. + */ +#define RETERR(x) do { \ + isc_result_t _r = (x); \ + if (_r != ISC_R_SUCCESS) \ + return (_r); \ + } while (0) + +/*% + * Convenience function for configuring a single zone ACL. + */ +static isc_result_t +configure_zone_acl(const cfg_obj_t *zconfig, const cfg_obj_t *vconfig, + const cfg_obj_t *config, const char *aclname, + cfg_aclconfctx_t *actx, dns_zone_t *zone, + void (*setzacl)(dns_zone_t *, dns_acl_t *), + void (*clearzacl)(dns_zone_t *)) +{ + isc_result_t result; + const cfg_obj_t *maps[5]; + const cfg_obj_t *aclobj = NULL; + int i = 0; + dns_acl_t *dacl = NULL; + + if (zconfig != NULL) + maps[i++] = cfg_tuple_get(zconfig, "options"); + if (vconfig != NULL) + maps[i++] = cfg_tuple_get(vconfig, "options"); + if (config != NULL) { + const cfg_obj_t *options = NULL; + (void)cfg_map_get(config, "options", &options); + if (options != NULL) + maps[i++] = options; + } + maps[i++] = ns_g_defaults; + maps[i] = NULL; + + result = ns_config_get(maps, aclname, &aclobj); + if (aclobj == NULL) { + (*clearzacl)(zone); + return (ISC_R_SUCCESS); + } + + result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx, actx, + dns_zone_getmctx(zone), &dacl); + if (result != ISC_R_SUCCESS) + return (result); + (*setzacl)(zone, dacl); + dns_acl_detach(&dacl); + return (ISC_R_SUCCESS); +} + +/*% + * Parse the zone update-policy statement. + */ +static isc_result_t +configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone) { + const cfg_obj_t *updatepolicy = NULL; + const cfg_listelt_t *element, *element2; + dns_ssutable_t *table = NULL; + isc_mem_t *mctx = dns_zone_getmctx(zone); + isc_result_t result; + + (void)cfg_map_get(zconfig, "update-policy", &updatepolicy); + if (updatepolicy == NULL) { + dns_zone_setssutable(zone, NULL); + return (ISC_R_SUCCESS); + } + + result = dns_ssutable_create(mctx, &table); + if (result != ISC_R_SUCCESS) + return (result); + + for (element = cfg_list_first(updatepolicy); + element != NULL; + element = cfg_list_next(element)) + { + const cfg_obj_t *stmt = cfg_listelt_value(element); + const cfg_obj_t *mode = cfg_tuple_get(stmt, "mode"); + const cfg_obj_t *identity = cfg_tuple_get(stmt, "identity"); + const cfg_obj_t *matchtype = cfg_tuple_get(stmt, "matchtype"); + const cfg_obj_t *dname = cfg_tuple_get(stmt, "name"); + const cfg_obj_t *typelist = cfg_tuple_get(stmt, "types"); + const char *str; + isc_boolean_t grant = ISC_FALSE; + unsigned int mtype = DNS_SSUMATCHTYPE_NAME; + dns_fixedname_t fname, fident; + isc_buffer_t b; + dns_rdatatype_t *types; + unsigned int i, n; + + str = cfg_obj_asstring(mode); + if (strcasecmp(str, "grant") == 0) + grant = ISC_TRUE; + else if (strcasecmp(str, "deny") == 0) + grant = ISC_FALSE; + else + INSIST(0); + + str = cfg_obj_asstring(matchtype); + if (strcasecmp(str, "name") == 0) + mtype = DNS_SSUMATCHTYPE_NAME; + else if (strcasecmp(str, "subdomain") == 0) + mtype = DNS_SSUMATCHTYPE_SUBDOMAIN; + else if (strcasecmp(str, "wildcard") == 0) + mtype = DNS_SSUMATCHTYPE_WILDCARD; + else if (strcasecmp(str, "self") == 0) + mtype = DNS_SSUMATCHTYPE_SELF; + else if (strcasecmp(str, "selfsub") == 0) + mtype = DNS_SSUMATCHTYPE_SELFSUB; + else if (strcasecmp(str, "selfwild") == 0) + mtype = DNS_SSUMATCHTYPE_SELFWILD; + else + INSIST(0); + + dns_fixedname_init(&fident); + str = cfg_obj_asstring(identity); + isc_buffer_init(&b, str, strlen(str)); + isc_buffer_add(&b, strlen(str)); + result = dns_name_fromtext(dns_fixedname_name(&fident), &b, + dns_rootname, ISC_FALSE, NULL); + if (result != ISC_R_SUCCESS) { + cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR, + "'%s' is not a valid name", str); + goto cleanup; + } + + dns_fixedname_init(&fname); + str = cfg_obj_asstring(dname); + isc_buffer_init(&b, str, strlen(str)); + isc_buffer_add(&b, strlen(str)); + result = dns_name_fromtext(dns_fixedname_name(&fname), &b, + dns_rootname, ISC_FALSE, NULL); + if (result != ISC_R_SUCCESS) { + cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR, + "'%s' is not a valid name", str); + goto cleanup; + } + + n = ns_config_listcount(typelist); + if (n == 0) + types = NULL; + else { + types = isc_mem_get(mctx, n * sizeof(dns_rdatatype_t)); + if (types == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + } + + i = 0; + for (element2 = cfg_list_first(typelist); + element2 != NULL; + element2 = cfg_list_next(element2)) + { + const cfg_obj_t *typeobj; + isc_textregion_t r; + + INSIST(i < n); + + typeobj = cfg_listelt_value(element2); + str = cfg_obj_asstring(typeobj); + DE_CONST(str, r.base); + r.length = strlen(str); + + result = dns_rdatatype_fromtext(&types[i++], &r); + if (result != ISC_R_SUCCESS) { + cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR, + "'%s' is not a valid type", str); + isc_mem_put(mctx, types, + n * sizeof(dns_rdatatype_t)); + goto cleanup; + } + } + INSIST(i == n); + + result = dns_ssutable_addrule(table, grant, + dns_fixedname_name(&fident), + mtype, + dns_fixedname_name(&fname), + n, types); + if (types != NULL) + isc_mem_put(mctx, types, n * sizeof(dns_rdatatype_t)); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + + } + + result = ISC_R_SUCCESS; + dns_zone_setssutable(zone, table); + + cleanup: + dns_ssutable_detach(&table); + return (result); +} + +/*% + * Convert a config file zone type into a server zone type. + */ +static inline dns_zonetype_t +zonetype_fromconfig(const cfg_obj_t *map) { + const cfg_obj_t *obj = NULL; + isc_result_t result; + + result = cfg_map_get(map, "type", &obj); + INSIST(result == ISC_R_SUCCESS); + return (ns_config_getzonetype(obj)); +} + +/*% + * Helper function for strtoargv(). Pardon the gratuitous recursion. + */ +static isc_result_t +strtoargvsub(isc_mem_t *mctx, char *s, unsigned int *argcp, + char ***argvp, unsigned int n) +{ + isc_result_t result; + + /* Discard leading whitespace. */ + while (*s == ' ' || *s == '\t') + s++; + + if (*s == '\0') { + /* We have reached the end of the string. */ + *argcp = n; + *argvp = isc_mem_get(mctx, n * sizeof(char *)); + if (*argvp == NULL) + return (ISC_R_NOMEMORY); + } else { + char *p = s; + while (*p != ' ' && *p != '\t' && *p != '\0') + p++; + if (*p != '\0') + *p++ = '\0'; + + result = strtoargvsub(mctx, p, argcp, argvp, n + 1); + if (result != ISC_R_SUCCESS) + return (result); + (*argvp)[n] = s; + } + return (ISC_R_SUCCESS); +} + +/*% + * Tokenize the string "s" into whitespace-separated words, + * return the number of words in '*argcp' and an array + * of pointers to the words in '*argvp'. The caller + * must free the array using isc_mem_put(). The string + * is modified in-place. + */ +static isc_result_t +strtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp) { + return (strtoargvsub(mctx, s, argcp, argvp, 0)); +} + +static void +checknames(dns_zonetype_t ztype, const cfg_obj_t **maps, + const cfg_obj_t **objp) +{ + const char *zone = NULL; + isc_result_t result; + + switch (ztype) { + case dns_zone_slave: zone = "slave"; break; + case dns_zone_master: zone = "master"; break; + default: + INSIST(0); + } + result = ns_checknames_get(maps, zone, objp); + INSIST(result == ISC_R_SUCCESS); +} + +isc_result_t +ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, + const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac, + dns_zone_t *zone) +{ + isc_result_t result; + const char *zname; + dns_rdataclass_t zclass; + dns_rdataclass_t vclass; + const cfg_obj_t *maps[5]; + const cfg_obj_t *zoptions = NULL; + const cfg_obj_t *options = NULL; + const cfg_obj_t *obj; + const char *filename = NULL; + dns_notifytype_t notifytype = dns_notifytype_yes; + isc_sockaddr_t *addrs; + dns_name_t **keynames; + isc_uint32_t count; + char *cpval; + unsigned int dbargc; + char **dbargv; + static char default_dbtype[] = "rbt"; + isc_mem_t *mctx = dns_zone_getmctx(zone); + dns_dialuptype_t dialup = dns_dialuptype_no; + dns_zonetype_t ztype; + int i; + isc_int32_t journal_size; + isc_boolean_t multi; + isc_boolean_t alt; + dns_view_t *view; + isc_boolean_t check = ISC_FALSE, fail = ISC_FALSE; + isc_boolean_t warn = ISC_FALSE, ignore = ISC_FALSE; + isc_boolean_t ixfrdiff; + dns_masterformat_t masterformat; + + i = 0; + if (zconfig != NULL) { + zoptions = cfg_tuple_get(zconfig, "options"); + maps[i++] = zoptions; + } + if (vconfig != NULL) + maps[i++] = cfg_tuple_get(vconfig, "options"); + if (config != NULL) { + (void)cfg_map_get(config, "options", &options); + if (options != NULL) + maps[i++] = options; + } + maps[i++] = ns_g_defaults; + maps[i++] = NULL; + + if (vconfig != NULL) + RETERR(ns_config_getclass(cfg_tuple_get(vconfig, "class"), + dns_rdataclass_in, &vclass)); + else + vclass = dns_rdataclass_in; + + /* + * Configure values common to all zone types. + */ + + zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); + + RETERR(ns_config_getclass(cfg_tuple_get(zconfig, "class"), + vclass, &zclass)); + dns_zone_setclass(zone, zclass); + + ztype = zonetype_fromconfig(zoptions); + dns_zone_settype(zone, ztype); + + obj = NULL; + result = cfg_map_get(zoptions, "database", &obj); + if (result == ISC_R_SUCCESS) + cpval = isc_mem_strdup(mctx, cfg_obj_asstring(obj)); + else + cpval = default_dbtype; + + if (cpval == NULL) + return(ISC_R_NOMEMORY); + + result = strtoargv(mctx, cpval, &dbargc, &dbargv); + if (result != ISC_R_SUCCESS && cpval != default_dbtype) { + isc_mem_free(mctx, cpval); + return (result); + } + + /* + * ANSI C is strange here. There is no logical reason why (char **) + * cannot be promoted automatically to (const char * const *) by the + * compiler w/o generating a warning. + */ + result = dns_zone_setdbtype(zone, dbargc, (const char * const *)dbargv); + isc_mem_put(mctx, dbargv, dbargc * sizeof(*dbargv)); + if (cpval != default_dbtype) + isc_mem_free(mctx, cpval); + if (result != ISC_R_SUCCESS) + return (result); + + obj = NULL; + result = cfg_map_get(zoptions, "file", &obj); + if (result == ISC_R_SUCCESS) + filename = cfg_obj_asstring(obj); + + masterformat = dns_masterformat_text; + obj = NULL; + result= ns_config_get(maps, "masterfile-format", &obj); + if (result == ISC_R_SUCCESS) { + const char *masterformatstr = cfg_obj_asstring(obj); + + if (strcasecmp(masterformatstr, "text") == 0) + masterformat = dns_masterformat_text; + else if (strcasecmp(masterformatstr, "raw") == 0) + masterformat = dns_masterformat_raw; + else + INSIST(0); + } + RETERR(dns_zone_setfile2(zone, filename, masterformat)); + + obj = NULL; + result = cfg_map_get(zoptions, "journal", &obj); + if (result == ISC_R_SUCCESS) + RETERR(dns_zone_setjournal(zone, cfg_obj_asstring(obj))); + + if (ztype == dns_zone_slave) + RETERR(configure_zone_acl(zconfig, vconfig, config, + "allow-notify", ac, zone, + dns_zone_setnotifyacl, + dns_zone_clearnotifyacl)); + /* + * XXXAG This probably does not make sense for stubs. + */ + RETERR(configure_zone_acl(zconfig, vconfig, config, + "allow-query", ac, zone, + dns_zone_setqueryacl, + dns_zone_clearqueryacl)); + + obj = NULL; + result = ns_config_get(maps, "dialup", &obj); + INSIST(result == ISC_R_SUCCESS); + if (cfg_obj_isboolean(obj)) { + if (cfg_obj_asboolean(obj)) + dialup = dns_dialuptype_yes; + else + dialup = dns_dialuptype_no; + } else { + const char *dialupstr = cfg_obj_asstring(obj); + if (strcasecmp(dialupstr, "notify") == 0) + dialup = dns_dialuptype_notify; + else if (strcasecmp(dialupstr, "notify-passive") == 0) + dialup = dns_dialuptype_notifypassive; + else if (strcasecmp(dialupstr, "refresh") == 0) + dialup = dns_dialuptype_refresh; + else if (strcasecmp(dialupstr, "passive") == 0) + dialup = dns_dialuptype_passive; + else + INSIST(0); + } + dns_zone_setdialup(zone, dialup); + + obj = NULL; + result = ns_config_get(maps, "zone-statistics", &obj); + INSIST(result == ISC_R_SUCCESS); + RETERR(dns_zone_setstatistics(zone, cfg_obj_asboolean(obj))); + + /* + * Configure master functionality. This applies + * to primary masters (type "master") and slaves + * acting as masters (type "slave"), but not to stubs. + */ + if (ztype != dns_zone_stub) { + obj = NULL; + result = ns_config_get(maps, "notify", &obj); + INSIST(result == ISC_R_SUCCESS); + if (cfg_obj_isboolean(obj)) { + if (cfg_obj_asboolean(obj)) + notifytype = dns_notifytype_yes; + else + notifytype = dns_notifytype_no; + } else { + const char *notifystr = cfg_obj_asstring(obj); + if (strcasecmp(notifystr, "explicit") == 0) + notifytype = dns_notifytype_explicit; + else if (strcasecmp(notifystr, "master-only") == 0) + notifytype = dns_notifytype_masteronly; + else + INSIST(0); + } + dns_zone_setnotifytype(zone, notifytype); + + obj = NULL; + result = ns_config_get(maps, "also-notify", &obj); + if (result == ISC_R_SUCCESS) { + isc_sockaddr_t *addrs = NULL; + isc_uint32_t addrcount; + result = ns_config_getiplist(config, obj, 0, mctx, + &addrs, &addrcount); + if (result != ISC_R_SUCCESS) + return (result); + result = dns_zone_setalsonotify(zone, addrs, + addrcount); + ns_config_putiplist(mctx, &addrs, addrcount); + if (result != ISC_R_SUCCESS) + return (result); + } else + RETERR(dns_zone_setalsonotify(zone, NULL, 0)); + + obj = NULL; + result = ns_config_get(maps, "notify-source", &obj); + INSIST(result == ISC_R_SUCCESS); + RETERR(dns_zone_setnotifysrc4(zone, cfg_obj_assockaddr(obj))); + ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); + + obj = NULL; + result = ns_config_get(maps, "notify-source-v6", &obj); + INSIST(result == ISC_R_SUCCESS); + RETERR(dns_zone_setnotifysrc6(zone, cfg_obj_assockaddr(obj))); + ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); + + dns_zone_setisself(zone, ns_client_isself, NULL); + + RETERR(configure_zone_acl(zconfig, vconfig, config, + "allow-transfer", ac, zone, + dns_zone_setxfracl, + dns_zone_clearxfracl)); + + obj = NULL; + result = ns_config_get(maps, "max-transfer-time-out", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zone_setmaxxfrout(zone, cfg_obj_asuint32(obj) * 60); + + obj = NULL; + result = ns_config_get(maps, "max-transfer-idle-out", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zone_setidleout(zone, cfg_obj_asuint32(obj) * 60); + + obj = NULL; + result = ns_config_get(maps, "max-journal-size", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zone_setjournalsize(zone, -1); + if (cfg_obj_isstring(obj)) { + const char *str = cfg_obj_asstring(obj); + INSIST(strcasecmp(str, "unlimited") == 0); + journal_size = ISC_UINT32_MAX / 2; + } else { + isc_resourcevalue_t value; + value = cfg_obj_asuint64(obj); + if (value > ISC_UINT32_MAX / 2) { + cfg_obj_log(obj, ns_g_lctx, + ISC_LOG_ERROR, + "'max-journal-size " + "%" ISC_PRINT_QUADFORMAT "d' " + "is too large", + value); + RETERR(ISC_R_RANGE); + } + journal_size = (isc_uint32_t)value; + } + dns_zone_setjournalsize(zone, journal_size); + + obj = NULL; + result = ns_config_get(maps, "ixfr-from-differences", &obj); + INSIST(result == ISC_R_SUCCESS); + if (cfg_obj_isboolean(obj)) + ixfrdiff = cfg_obj_asboolean(obj); + else if (strcasecmp(cfg_obj_asstring(obj), "master") && + ztype == dns_zone_master) + ixfrdiff = ISC_TRUE; + else if (strcasecmp(cfg_obj_asstring(obj), "slave") && + ztype == dns_zone_slave) + ixfrdiff = ISC_TRUE; + else + ixfrdiff = ISC_FALSE; + dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS, ixfrdiff); + + checknames(ztype, maps, &obj); + INSIST(obj != NULL); + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + fail = ISC_FALSE; + check = ISC_TRUE; + } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { + fail = check = ISC_TRUE; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + fail = check = ISC_FALSE; + } else + INSIST(0); + dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES, check); + dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL, fail); + + obj = NULL; + result = ns_config_get(maps, "notify-delay", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zone_setnotifydelay(zone, cfg_obj_asuint32(obj)); + + obj = NULL; + result = ns_config_get(maps, "check-sibling", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSIBLING, + cfg_obj_asboolean(obj)); + + obj = NULL; + result = ns_config_get(maps, "zero-no-soa-ttl", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zone_setzeronosoattl(zone, cfg_obj_asboolean(obj)); + } + + /* + * Configure update-related options. These apply to + * primary masters only. + */ + if (ztype == dns_zone_master) { + dns_acl_t *updateacl; + RETERR(configure_zone_acl(zconfig, vconfig, config, + "allow-update", ac, zone, + dns_zone_setupdateacl, + dns_zone_clearupdateacl)); + + updateacl = dns_zone_getupdateacl(zone); + if (updateacl != NULL && dns_acl_isinsecure(updateacl)) + isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_SERVER, ISC_LOG_WARNING, + "zone '%s' allows updates by IP " + "address, which is insecure", + zname); + + RETERR(configure_zone_ssutable(zoptions, zone)); + + obj = NULL; + result = ns_config_get(maps, "sig-validity-interval", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zone_setsigvalidityinterval(zone, + cfg_obj_asuint32(obj) * 86400); + + obj = NULL; + result = ns_config_get(maps, "key-directory", &obj); + if (result == ISC_R_SUCCESS) { + filename = cfg_obj_asstring(obj); + if (!isc_file_isabsolute(filename)) { + cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, + "key-directory '%s' " + "is not absolute", filename); + return (ISC_R_FAILURE); + } + RETERR(dns_zone_setkeydirectory(zone, filename)); + } + + obj = NULL; + result = ns_config_get(maps, "check-wildcard", &obj); + if (result == ISC_R_SUCCESS) + check = cfg_obj_asboolean(obj); + else + check = ISC_FALSE; + dns_zone_setoption(zone, DNS_ZONEOPT_CHECKWILDCARD, check); + + obj = NULL; + result = ns_config_get(maps, "check-mx", &obj); + INSIST(obj != NULL); + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + fail = ISC_FALSE; + check = ISC_TRUE; + } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { + fail = check = ISC_TRUE; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + fail = check = ISC_FALSE; + } else + INSIST(0); + dns_zone_setoption(zone, DNS_ZONEOPT_CHECKMX, check); + dns_zone_setoption(zone, DNS_ZONEOPT_CHECKMXFAIL, fail); + + obj = NULL; + result = ns_config_get(maps, "check-integrity", &obj); + INSIST(obj != NULL); + dns_zone_setoption(zone, DNS_ZONEOPT_CHECKINTEGRITY, + cfg_obj_asboolean(obj)); + + obj = NULL; + result = ns_config_get(maps, "check-mx-cname", &obj); + INSIST(obj != NULL); + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + warn = ISC_TRUE; + ignore = ISC_FALSE; + } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { + warn = ignore = ISC_FALSE; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + warn = ignore = ISC_TRUE; + } else + INSIST(0); + dns_zone_setoption(zone, DNS_ZONEOPT_WARNMXCNAME, warn); + dns_zone_setoption(zone, DNS_ZONEOPT_IGNOREMXCNAME, ignore); + + obj = NULL; + result = ns_config_get(maps, "check-srv-cname", &obj); + INSIST(obj != NULL); + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + warn = ISC_TRUE; + ignore = ISC_FALSE; + } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { + warn = ignore = ISC_FALSE; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + warn = ignore = ISC_TRUE; + } else + INSIST(0); + dns_zone_setoption(zone, DNS_ZONEOPT_WARNSRVCNAME, warn); + dns_zone_setoption(zone, DNS_ZONEOPT_IGNORESRVCNAME, ignore); + + obj = NULL; + result = ns_config_get(maps, "update-check-ksk", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zone_setoption(zone, DNS_ZONEOPT_UPDATECHECKKSK, + cfg_obj_asboolean(obj)); + } + + /* + * Configure update-related options. These apply to + * primary masters only. + */ + if (ztype == dns_zone_master) { + dns_acl_t *updateacl; + RETERR(configure_zone_acl(zconfig, vconfig, config, + "allow-update", ac, zone, + dns_zone_setupdateacl, + dns_zone_clearupdateacl)); + + updateacl = dns_zone_getupdateacl(zone); + if (updateacl != NULL && dns_acl_isinsecure(updateacl)) + isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_SERVER, ISC_LOG_WARNING, + "zone '%s' allows updates by IP " + "address, which is insecure", + zname); + + RETERR(configure_zone_ssutable(zoptions, zone)); + + obj = NULL; + result = ns_config_get(maps, "sig-validity-interval", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zone_setsigvalidityinterval(zone, + cfg_obj_asuint32(obj) * 86400); + + obj = NULL; + result = ns_config_get(maps, "key-directory", &obj); + if (result == ISC_R_SUCCESS) { + filename = cfg_obj_asstring(obj); + if (!isc_file_isabsolute(filename)) { + cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, + "key-directory '%s' " + "is not absolute", filename); + return (ISC_R_FAILURE); + } + RETERR(dns_zone_setkeydirectory(zone, filename)); + } + + } else if (ztype == dns_zone_slave) { + RETERR(configure_zone_acl(zconfig, vconfig, config, + "allow-update-forwarding", ac, zone, + dns_zone_setforwardacl, + dns_zone_clearforwardacl)); + } + + /* + * Configure slave functionality. + */ + switch (ztype) { + case dns_zone_slave: + case dns_zone_stub: + count = 0; + obj = NULL; + result = cfg_map_get(zoptions, "masters", &obj); + if (obj != NULL) { + addrs = NULL; + keynames = NULL; + RETERR(ns_config_getipandkeylist(config, obj, mctx, + &addrs, &keynames, + &count)); + result = dns_zone_setmasterswithkeys(zone, addrs, + keynames, count); + ns_config_putipandkeylist(mctx, &addrs, &keynames, + count); + } else + result = dns_zone_setmasters(zone, NULL, 0); + RETERR(result); + + multi = ISC_FALSE; + if (count > 1) { + obj = NULL; + result = ns_config_get(maps, "multi-master", &obj); + INSIST(result == ISC_R_SUCCESS); + multi = cfg_obj_asboolean(obj); + } + dns_zone_setoption(zone, DNS_ZONEOPT_MULTIMASTER, multi); + + obj = NULL; + result = ns_config_get(maps, "max-transfer-time-in", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zone_setmaxxfrin(zone, cfg_obj_asuint32(obj) * 60); + + obj = NULL; + result = ns_config_get(maps, "max-transfer-idle-in", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zone_setidlein(zone, cfg_obj_asuint32(obj) * 60); + + obj = NULL; + result = ns_config_get(maps, "max-refresh-time", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zone_setmaxrefreshtime(zone, cfg_obj_asuint32(obj)); + + obj = NULL; + result = ns_config_get(maps, "min-refresh-time", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zone_setminrefreshtime(zone, cfg_obj_asuint32(obj)); + + obj = NULL; + result = ns_config_get(maps, "max-retry-time", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zone_setmaxretrytime(zone, cfg_obj_asuint32(obj)); + + obj = NULL; + result = ns_config_get(maps, "min-retry-time", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zone_setminretrytime(zone, cfg_obj_asuint32(obj)); + + obj = NULL; + result = ns_config_get(maps, "transfer-source", &obj); + INSIST(result == ISC_R_SUCCESS); + RETERR(dns_zone_setxfrsource4(zone, cfg_obj_assockaddr(obj))); + ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); + + obj = NULL; + result = ns_config_get(maps, "transfer-source-v6", &obj); + INSIST(result == ISC_R_SUCCESS); + RETERR(dns_zone_setxfrsource6(zone, cfg_obj_assockaddr(obj))); + ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); + + obj = NULL; + result = ns_config_get(maps, "alt-transfer-source", &obj); + INSIST(result == ISC_R_SUCCESS); + RETERR(dns_zone_setaltxfrsource4(zone, cfg_obj_assockaddr(obj))); + + obj = NULL; + result = ns_config_get(maps, "alt-transfer-source-v6", &obj); + INSIST(result == ISC_R_SUCCESS); + RETERR(dns_zone_setaltxfrsource6(zone, cfg_obj_assockaddr(obj))); + + obj = NULL; + (void)ns_config_get(maps, "use-alt-transfer-source", &obj); + if (obj == NULL) { + /* + * Default off when views are in use otherwise + * on for BIND 8 compatibility. + */ + view = dns_zone_getview(zone); + if (view != NULL && strcmp(view->name, "_default") == 0) + alt = ISC_TRUE; + else + alt = ISC_FALSE; + } else + alt = cfg_obj_asboolean(obj); + dns_zone_setoption(zone, DNS_ZONEOPT_USEALTXFRSRC, alt); + + break; + + default: + break; + } + + return (ISC_R_SUCCESS); +} + +isc_boolean_t +ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) { + const cfg_obj_t *zoptions = NULL; + const cfg_obj_t *obj = NULL; + const char *cfilename; + const char *zfilename; + + zoptions = cfg_tuple_get(zconfig, "options"); + + if (zonetype_fromconfig(zoptions) != dns_zone_gettype(zone)) + return (ISC_FALSE); + + obj = NULL; + (void)cfg_map_get(zoptions, "file", &obj); + if (obj != NULL) + cfilename = cfg_obj_asstring(obj); + else + cfilename = NULL; + zfilename = dns_zone_getfile(zone); + if (!((cfilename == NULL && zfilename == NULL) || + (cfilename != NULL && zfilename != NULL && + strcmp(cfilename, zfilename) == 0))) + return (ISC_FALSE); + + return (ISC_TRUE); +} diff --git a/bin/nsupdate/Makefile.in b/bin/nsupdate/Makefile.in new file mode 100644 index 0000000..6bb22f8 --- /dev/null +++ b/bin/nsupdate/Makefile.in @@ -0,0 +1,83 @@ +# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2000-2002 Internet Software Consortium. +# +# Permission to use, copy, modify, and 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: Makefile.in,v 1.22.18.1 2004/07/20 07:03:20 marka Exp $ + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +@BIND9_VERSION@ + +@BIND9_MAKE_INCLUDES@ + +CINCLUDES = ${LWRES_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} \ + ${ISC_INCLUDES} + +CDEFINES = +CWARNINGS = + +LWRESLIBS = ../../lib/lwres/liblwres.@A@ +DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ +BIND9LIBS = ../../lib/bind9/libbind9.@A@ +ISCLIBS = ../../lib/isc/libisc.@A@ +ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ + +LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@ +DNSDEPLIBS = ../../lib/dns/libdns.@A@ +BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ +ISCDEPLIBS = ../../lib/isc/libisc.@A@ +ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ + +DEPLIBS = ${DNSDEPLIBS} ${BIND9DEPLIBS} ${ISCDEPLIBS} ${ISCCFGDEPLIBS} + +LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCLIBS} ${ISCCFGLIBS} @LIBS@ + +SUBDIRS = + +TARGETS = nsupdate@EXEEXT@ + +OBJS = nsupdate.@O@ + +UOBJS = + +SRCS = nsupdate.c + +MANPAGES = nsupdate.8 + +HTMLPAGES = nsupdate.html + +MANOBJS = ${MANPAGES} ${HTMLPAGES} + +@BIND9_MAKE_RULES@ + +nsupdate@EXEEXT@: nsupdate.@O@ ${UOBJS} ${DEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ nsupdate.@O@ ${UOBJS} ${LIBS} + +doc man:: ${MANOBJS} + +docclean manclean maintainer-clean:: + rm -f ${MANOBJS} + +clean distclean:: + rm -f ${TARGETS} + +installdirs: + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${bindir} + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 + +install:: nsupdate@EXEEXT@ installdirs + ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} nsupdate@EXEEXT@ ${DESTDIR}${bindir} + ${INSTALL_DATA} ${srcdir}/nsupdate.8 ${DESTDIR}${mandir}/man8 diff --git a/bin/nsupdate/nsupdate.8 b/bin/nsupdate/nsupdate.8 new file mode 100644 index 0000000..8e3963a --- /dev/null +++ b/bin/nsupdate/nsupdate.8 @@ -0,0 +1,348 @@ +.\" Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2000-2003 Internet Software Consortium. +.\" +.\" Permission to use, copy, modify, and 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: nsupdate.8,v 1.30.18.14 2007/05/09 03:33:13 marka Exp $ +.\" +.hy 0 +.ad l +.\" Title: nsupdate +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.71.1 +.\" Date: Jun 30, 2000 +.\" Manual: BIND9 +.\" Source: BIND9 +.\" +.TH "NSUPDATE" "8" "Jun 30, 2000" "BIND9" "BIND9" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +nsupdate \- Dynamic DNS update utility +.SH "SYNOPSIS" +.HP 9 +\fBnsupdate\fR [\fB\-d\fR] [[\fB\-y\ \fR\fB\fI[hmac:]\fR\fIkeyname:secret\fR\fR] | [\fB\-k\ \fR\fB\fIkeyfile\fR\fR]] [\fB\-t\ \fR\fB\fItimeout\fR\fR] [\fB\-u\ \fR\fB\fIudptimeout\fR\fR] [\fB\-r\ \fR\fB\fIudpretries\fR\fR] [\fB\-v\fR] [filename] +.SH "DESCRIPTION" +.PP +\fBnsupdate\fR +is used to submit Dynamic DNS Update requests as defined in RFC2136 to a name server. This allows resource records to be added or removed from a zone without manually editing the zone file. A single update request can contain requests to add or remove more than one resource record. +.PP +Zones that are under dynamic control via +\fBnsupdate\fR +or a DHCP server should not be edited by hand. Manual edits could conflict with dynamic updates and cause data to be lost. +.PP +The resource records that are dynamically added or removed with +\fBnsupdate\fR +have to be in the same zone. Requests are sent to the zone's master server. This is identified by the MNAME field of the zone's SOA record. +.PP +The +\fB\-d\fR +option makes +\fBnsupdate\fR +operate in debug mode. This provides tracing information about the update requests that are made and the replies received from the name server. +.PP +Transaction signatures can be used to authenticate the Dynamic DNS updates. These use the TSIG resource record type described in RFC2845 or the SIG(0) record described in RFC3535 and RFC2931. TSIG relies on a shared secret that should only be known to +\fBnsupdate\fR +and the name server. Currently, the only supported encryption algorithm for TSIG is HMAC\-MD5, which is defined in RFC 2104. Once other algorithms are defined for TSIG, applications will need to ensure they select the appropriate algorithm as well as the key when authenticating each other. For instance, suitable +\fBkey\fR +and +\fBserver\fR +statements would be added to +\fI/etc/named.conf\fR +so that the name server can associate the appropriate secret key and algorithm with the IP address of the client application that will be using TSIG authentication. SIG(0) uses public key cryptography. To use a SIG(0) key, the public key must be stored in a KEY record in a zone served by the name server. +\fBnsupdate\fR +does not read +\fI/etc/named.conf\fR. +.PP +\fBnsupdate\fR +uses the +\fB\-y\fR +or +\fB\-k\fR +option to provide the shared secret needed to generate a TSIG record for authenticating Dynamic DNS update requests, default type HMAC\-MD5. These options are mutually exclusive. With the +\fB\-k\fR +option, +\fBnsupdate\fR +reads the shared secret from the file +\fIkeyfile\fR, whose name is of the form +\fIK{name}.+157.+{random}.private\fR. For historical reasons, the file +\fIK{name}.+157.+{random}.key\fR +must also be present. When the +\fB\-y\fR +option is used, a signature is generated from +[\fIhmac:\fR]\fIkeyname:secret.\fR +\fIkeyname\fR +is the name of the key, and +\fIsecret\fR +is the base64 encoded shared secret. Use of the +\fB\-y\fR +option is discouraged because the shared secret is supplied as a command line argument in clear text. This may be visible in the output from +\fBps\fR(1) +or in a history file maintained by the user's shell. +.PP +The +\fB\-k\fR +may also be used to specify a SIG(0) key used to authenticate Dynamic DNS update requests. In this case, the key specified is not an HMAC\-MD5 key. +.PP +By default +\fBnsupdate\fR +uses UDP to send update requests to the name server unless they are too large to fit in a UDP request in which case TCP will be used. The +\fB\-v\fR +option makes +\fBnsupdate\fR +use a TCP connection. This may be preferable when a batch of update requests is made. +.PP +The +\fB\-t\fR +option sets the maximum time an update request can take before it is aborted. The default is 300 seconds. Zero can be used to disable the timeout. +.PP +The +\fB\-u\fR +option sets the UDP retry interval. The default is 3 seconds. If zero, the interval will be computed from the timeout interval and number of UDP retries. +.PP +The +\fB\-r\fR +option sets the number of UDP retries. The default is 3. If zero, only one update request will be made. +.SH "INPUT FORMAT" +.PP +\fBnsupdate\fR +reads input from +\fIfilename\fR +or standard input. Each command is supplied on exactly one line of input. Some commands are for administrative purposes. The others are either update instructions or prerequisite checks on the contents of the zone. These checks set conditions that some name or set of resource records (RRset) either exists or is absent from the zone. These conditions must be met if the entire update request is to succeed. Updates will be rejected if the tests for the prerequisite conditions fail. +.PP +Every update request consists of zero or more prerequisites and zero or more updates. This allows a suitably authenticated update request to proceed if some specified resource records are present or missing from the zone. A blank input line (or the +\fBsend\fR +command) causes the accumulated commands to be sent as one Dynamic DNS update request to the name server. +.PP +The command formats and their meaning are as follows: +.PP +\fBserver\fR {servername} [port] +.RS 4 +Sends all dynamic update requests to the name server +\fIservername\fR. When no server statement is provided, +\fBnsupdate\fR +will send updates to the master server of the correct zone. The MNAME field of that zone's SOA record will identify the master server for that zone. +\fIport\fR +is the port number on +\fIservername\fR +where the dynamic update requests get sent. If no port number is specified, the default DNS port number of 53 is used. +.RE +.PP +\fBlocal\fR {address} [port] +.RS 4 +Sends all dynamic update requests using the local +\fIaddress\fR. When no local statement is provided, +\fBnsupdate\fR +will send updates using an address and port chosen by the system. +\fIport\fR +can additionally be used to make requests come from a specific port. If no port number is specified, the system will assign one. +.RE +.PP +\fBzone\fR {zonename} +.RS 4 +Specifies that all updates are to be made to the zone +\fIzonename\fR. If no +\fIzone\fR +statement is provided, +\fBnsupdate\fR +will attempt determine the correct zone to update based on the rest of the input. +.RE +.PP +\fBclass\fR {classname} +.RS 4 +Specify the default class. If no +\fIclass\fR +is specified, the default class is +\fIIN\fR. +.RE +.PP +\fBkey\fR {name} {secret} +.RS 4 +Specifies that all updates are to be TSIG\-signed using the +\fIkeyname\fR +\fIkeysecret\fR +pair. The +\fBkey\fR +command overrides any key specified on the command line via +\fB\-y\fR +or +\fB\-k\fR. +.RE +.PP +\fBprereq nxdomain\fR {domain\-name} +.RS 4 +Requires that no resource record of any type exists with name +\fIdomain\-name\fR. +.RE +.PP +\fBprereq yxdomain\fR {domain\-name} +.RS 4 +Requires that +\fIdomain\-name\fR +exists (has as at least one resource record, of any type). +.RE +.PP +\fBprereq nxrrset\fR {domain\-name} [class] {type} +.RS 4 +Requires that no resource record exists of the specified +\fItype\fR, +\fIclass\fR +and +\fIdomain\-name\fR. If +\fIclass\fR +is omitted, IN (internet) is assumed. +.RE +.PP +\fBprereq yxrrset\fR {domain\-name} [class] {type} +.RS 4 +This requires that a resource record of the specified +\fItype\fR, +\fIclass\fR +and +\fIdomain\-name\fR +must exist. If +\fIclass\fR +is omitted, IN (internet) is assumed. +.RE +.PP +\fBprereq yxrrset\fR {domain\-name} [class] {type} {data...} +.RS 4 +The +\fIdata\fR +from each set of prerequisites of this form sharing a common +\fItype\fR, +\fIclass\fR, and +\fIdomain\-name\fR +are combined to form a set of RRs. This set of RRs must exactly match the set of RRs existing in the zone at the given +\fItype\fR, +\fIclass\fR, and +\fIdomain\-name\fR. The +\fIdata\fR +are written in the standard text representation of the resource record's RDATA. +.RE +.PP +\fBupdate delete\fR {domain\-name} [ttl] [class] [type\ [data...]] +.RS 4 +Deletes any resource records named +\fIdomain\-name\fR. If +\fItype\fR +and +\fIdata\fR +is provided, only matching resource records will be removed. The internet class is assumed if +\fIclass\fR +is not supplied. The +\fIttl\fR +is ignored, and is only allowed for compatibility. +.RE +.PP +\fBupdate add\fR {domain\-name} {ttl} [class] {type} {data...} +.RS 4 +Adds a new resource record with the specified +\fIttl\fR, +\fIclass\fR +and +\fIdata\fR. +.RE +.PP +\fBshow\fR +.RS 4 +Displays the current message, containing all of the prerequisites and updates specified since the last send. +.RE +.PP +\fBsend\fR +.RS 4 +Sends the current message. This is equivalent to entering a blank line. +.RE +.PP +\fBanswer\fR +.RS 4 +Displays the answer. +.RE +.PP +Lines beginning with a semicolon are comments and are ignored. +.SH "EXAMPLES" +.PP +The examples below show how +\fBnsupdate\fR +could be used to insert and delete resource records from the +\fBexample.com\fR +zone. Notice that the input in each example contains a trailing blank line so that a group of commands are sent as one dynamic update request to the master name server for +\fBexample.com\fR. +.sp +.RS 4 +.nf +# nsupdate +> update delete oldhost.example.com A +> update add newhost.example.com 86400 A 172.16.1.1 +> send +.fi +.RE +.sp +.PP +Any A records for +\fBoldhost.example.com\fR +are deleted. And an A record for +\fBnewhost.example.com\fR +with IP address 172.16.1.1 is added. The newly\-added record has a 1 day TTL (86400 seconds). +.sp +.RS 4 +.nf +# nsupdate +> prereq nxdomain nickname.example.com +> update add nickname.example.com 86400 CNAME somehost.example.com +> send +.fi +.RE +.sp +.PP +The prerequisite condition gets the name server to check that there are no resource records of any type for +\fBnickname.example.com\fR. If there are, the update request fails. If this name does not exist, a CNAME for it is added. This ensures that when the CNAME is added, it cannot conflict with the long\-standing rule in RFC1034 that a name must not exist as any other record type if it exists as a CNAME. (The rule has been updated for DNSSEC in RFC2535 to allow CNAMEs to have RRSIG, DNSKEY and NSEC records.) +.SH "FILES" +.PP +\fB/etc/resolv.conf\fR +.RS 4 +used to identify default name server +.RE +.PP +\fBK{name}.+157.+{random}.key\fR +.RS 4 +base\-64 encoding of HMAC\-MD5 key created by +\fBdnssec\-keygen\fR(8). +.RE +.PP +\fBK{name}.+157.+{random}.private\fR +.RS 4 +base\-64 encoding of HMAC\-MD5 key created by +\fBdnssec\-keygen\fR(8). +.RE +.SH "SEE ALSO" +.PP +\fBRFC2136\fR(), +\fBRFC3007\fR(), +\fBRFC2104\fR(), +\fBRFC2845\fR(), +\fBRFC1034\fR(), +\fBRFC2535\fR(), +\fBRFC2931\fR(), +\fBnamed\fR(8), +\fBdnssec\-keygen\fR(8). +.SH "BUGS" +.PP +The TSIG key is redundantly stored in two separate files. This is a consequence of nsupdate using the DST library for its cryptographic operations, and may change in future releases. +.SH "COPYRIGHT" +Copyright \(co 2004\-2007 Internet Systems Consortium, Inc. ("ISC") +.br +Copyright \(co 2000\-2003 Internet Software Consortium. +.br diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c new file mode 100644 index 0000000..7f10174 --- /dev/null +++ b/bin/nsupdate/nsupdate.c @@ -0,0 +1,2176 @@ +/* + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000-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: nsupdate.c,v 1.130.18.19 2007/08/28 07:20:01 tbox Exp $ */ + +/*! \file */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#ifdef HAVE_ADDRINFO +#ifdef HAVE_GETADDRINFO +#ifdef HAVE_GAISTRERROR +#define USE_GETADDRINFO +#endif +#endif +#endif + +#ifndef USE_GETADDRINFO +#ifndef ISC_PLATFORM_NONSTDHERRNO +extern int h_errno; +#endif +#endif + +#define MAXCMD (4 * 1024) +#define MAXWIRE (64 * 1024) +#define PACKETSIZE ((64 * 1024) - 1) +#define INITTEXT (2 * 1024) +#define MAXTEXT (128 * 1024) +#define FIND_TIMEOUT 5 +#define TTL_MAX 2147483647U /* Maximum signed 32 bit integer. */ + +#define DNSDEFAULTPORT 53 + +#ifndef RESOLV_CONF +#define RESOLV_CONF "/etc/resolv.conf" +#endif + +static isc_boolean_t debugging = ISC_FALSE, ddebugging = ISC_FALSE; +static isc_boolean_t memdebugging = ISC_FALSE; +static isc_boolean_t have_ipv4 = ISC_FALSE; +static isc_boolean_t have_ipv6 = ISC_FALSE; +static isc_boolean_t is_dst_up = ISC_FALSE; +static isc_boolean_t usevc = ISC_FALSE; +static isc_taskmgr_t *taskmgr = NULL; +static isc_task_t *global_task = NULL; +static isc_event_t *global_event = NULL; +static isc_mem_t *mctx = NULL; +static dns_dispatchmgr_t *dispatchmgr = NULL; +static dns_requestmgr_t *requestmgr = NULL; +static isc_socketmgr_t *socketmgr = NULL; +static isc_timermgr_t *timermgr = NULL; +static dns_dispatch_t *dispatchv4 = NULL; +static dns_dispatch_t *dispatchv6 = NULL; +static dns_message_t *updatemsg = NULL; +static dns_fixedname_t fuserzone; +static dns_name_t *userzone = NULL; +static dns_tsigkey_t *tsigkey = NULL; +static dst_key_t *sig0key; +static lwres_context_t *lwctx = NULL; +static lwres_conf_t *lwconf; +static isc_sockaddr_t *servers; +static int ns_inuse = 0; +static int ns_total = 0; +static isc_sockaddr_t *userserver = NULL; +static isc_sockaddr_t *localaddr = NULL; +static char *keystr = NULL, *keyfile = NULL; +static isc_entropy_t *entp = NULL; +static isc_boolean_t shuttingdown = ISC_FALSE; +static FILE *input; +static isc_boolean_t interactive = ISC_TRUE; +static isc_boolean_t seenerror = ISC_FALSE; +static const dns_master_style_t *style; +static int requests = 0; +static unsigned int timeout = 300; +static unsigned int udp_timeout = 3; +static unsigned int udp_retries = 3; +static dns_rdataclass_t defaultclass = dns_rdataclass_in; +static dns_rdataclass_t zoneclass = dns_rdataclass_none; +static dns_message_t *answer = NULL; + +typedef struct nsu_requestinfo { + dns_message_t *msg; + isc_sockaddr_t *addr; +} nsu_requestinfo_t; + +static void +sendrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, + dns_message_t *msg, dns_request_t **request); +static void +fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); + +static void +debug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); + +static void +ddebug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); + +static void +error(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); + +#define STATUS_MORE (isc_uint16_t)0 +#define STATUS_SEND (isc_uint16_t)1 +#define STATUS_QUIT (isc_uint16_t)2 +#define STATUS_SYNTAX (isc_uint16_t)3 + +static dns_rdataclass_t +getzoneclass(void) { + if (zoneclass == dns_rdataclass_none) + zoneclass = defaultclass; + return (zoneclass); +} + +static isc_boolean_t +setzoneclass(dns_rdataclass_t rdclass) { + if (zoneclass == dns_rdataclass_none || + rdclass == dns_rdataclass_none) + zoneclass = rdclass; + if (zoneclass != rdclass) + return (ISC_FALSE); + return (ISC_TRUE); +} + +static void +fatal(const char *format, ...) { + va_list args; + + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, "\n"); + exit(1); +} + +static void +error(const char *format, ...) { + va_list args; + + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, "\n"); +} + +static void +debug(const char *format, ...) { + va_list args; + + if (debugging) { + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, "\n"); + } +} + +static void +ddebug(const char *format, ...) { + va_list args; + + if (ddebugging) { + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, "\n"); + } +} + +static inline void +check_result(isc_result_t result, const char *msg) { + if (result != ISC_R_SUCCESS) + fatal("%s: %s", msg, isc_result_totext(result)); +} + +static void * +mem_alloc(void *arg, size_t size) { + return (isc_mem_get(arg, size)); +} + +static void +mem_free(void *arg, void *mem, size_t size) { + isc_mem_put(arg, mem, size); +} + +static char * +nsu_strsep(char **stringp, const char *delim) { + char *string = *stringp; + char *s; + const char *d; + char sc, dc; + + if (string == NULL) + return (NULL); + + for (; *string != '\0'; string++) { + sc = *string; + for (d = delim; (dc = *d) != '\0'; d++) { + if (sc == dc) + break; + } + if (dc == 0) + break; + } + + for (s = string; *s != '\0'; s++) { + sc = *s; + for (d = delim; (dc = *d) != '\0'; d++) { + if (sc == dc) { + *s++ = '\0'; + *stringp = s; + return (string); + } + } + } + *stringp = NULL; + return (string); +} + +static void +reset_system(void) { + isc_result_t result; + + ddebug("reset_system()"); + /* If the update message is still around, destroy it */ + if (updatemsg != NULL) + dns_message_reset(updatemsg, DNS_MESSAGE_INTENTRENDER); + else { + result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, + &updatemsg); + check_result(result, "dns_message_create"); + } + updatemsg->opcode = dns_opcode_update; +} + +static isc_uint16_t +parse_hmac(dns_name_t **hmac, const char *hmacstr, size_t len) { + isc_uint16_t digestbits = 0; + isc_result_t result; + char buf[20]; + + REQUIRE(hmac != NULL && *hmac == NULL); + REQUIRE(hmacstr != NULL); + + if (len >= sizeof(buf)) + fatal("unknown key type '%.*s'", (int)(len), hmacstr); + + strncpy(buf, hmacstr, len); + buf[len] = 0; + + if (strcasecmp(buf, "hmac-md5") == 0) { + *hmac = DNS_TSIG_HMACMD5_NAME; + } else if (strncasecmp(buf, "hmac-md5-", 9) == 0) { + *hmac = DNS_TSIG_HMACMD5_NAME; + result = isc_parse_uint16(&digestbits, &buf[9], 10); + if (result != ISC_R_SUCCESS || digestbits > 128) + fatal("digest-bits out of range [0..128]"); + digestbits = (digestbits +7) & ~0x7U; + } else if (strcasecmp(buf, "hmac-sha1") == 0) { + *hmac = DNS_TSIG_HMACSHA1_NAME; + } else if (strncasecmp(buf, "hmac-sha1-", 10) == 0) { + *hmac = DNS_TSIG_HMACSHA1_NAME; + result = isc_parse_uint16(&digestbits, &buf[10], 10); + if (result != ISC_R_SUCCESS || digestbits > 160) + fatal("digest-bits out of range [0..160]"); + digestbits = (digestbits +7) & ~0x7U; + } else if (strcasecmp(buf, "hmac-sha224") == 0) { + *hmac = DNS_TSIG_HMACSHA224_NAME; + } else if (strncasecmp(buf, "hmac-sha224-", 12) == 0) { + *hmac = DNS_TSIG_HMACSHA224_NAME; + result = isc_parse_uint16(&digestbits, &buf[12], 10); + if (result != ISC_R_SUCCESS || digestbits > 224) + fatal("digest-bits out of range [0..224]"); + digestbits = (digestbits +7) & ~0x7U; + } else if (strcasecmp(buf, "hmac-sha256") == 0) { + *hmac = DNS_TSIG_HMACSHA256_NAME; + } else if (strncasecmp(buf, "hmac-sha256-", 12) == 0) { + *hmac = DNS_TSIG_HMACSHA256_NAME; + result = isc_parse_uint16(&digestbits, &buf[12], 10); + if (result != ISC_R_SUCCESS || digestbits > 256) + fatal("digest-bits out of range [0..256]"); + digestbits = (digestbits +7) & ~0x7U; + } else if (strcasecmp(buf, "hmac-sha384") == 0) { + *hmac = DNS_TSIG_HMACSHA384_NAME; + } else if (strncasecmp(buf, "hmac-sha384-", 12) == 0) { + *hmac = DNS_TSIG_HMACSHA384_NAME; + result = isc_parse_uint16(&digestbits, &buf[12], 10); + if (result != ISC_R_SUCCESS || digestbits > 384) + fatal("digest-bits out of range [0..384]"); + digestbits = (digestbits +7) & ~0x7U; + } else if (strcasecmp(buf, "hmac-sha512") == 0) { + *hmac = DNS_TSIG_HMACSHA512_NAME; + } else if (strncasecmp(buf, "hmac-sha512-", 12) == 0) { + *hmac = DNS_TSIG_HMACSHA512_NAME; + result = isc_parse_uint16(&digestbits, &buf[12], 10); + if (result != ISC_R_SUCCESS || digestbits > 512) + fatal("digest-bits out of range [0..512]"); + digestbits = (digestbits +7) & ~0x7U; + } else + fatal("unknown key type '%s'", buf); + return (digestbits); +} + +static void +setup_keystr(void) { + unsigned char *secret = NULL; + int secretlen; + isc_buffer_t secretbuf; + isc_result_t result; + isc_buffer_t keynamesrc; + char *secretstr; + char *s, *n; + dns_fixedname_t fkeyname; + dns_name_t *keyname; + char *name; + dns_name_t *hmacname = NULL; + isc_uint16_t digestbits = 0; + + dns_fixedname_init(&fkeyname); + keyname = dns_fixedname_name(&fkeyname); + + debug("Creating key..."); + + s = strchr(keystr, ':'); + if (s == NULL || s == keystr || s[1] == 0) + fatal("key option must specify [hmac:]keyname:secret"); + secretstr = s + 1; + n = strchr(secretstr, ':'); + if (n != NULL) { + if (n == secretstr || n[1] == 0) + fatal("key option must specify [hmac:]keyname:secret"); + name = secretstr; + secretstr = n + 1; + digestbits = parse_hmac(&hmacname, keystr, s - keystr); + } else { + hmacname = DNS_TSIG_HMACMD5_NAME; + name = keystr; + n = s; + } + + isc_buffer_init(&keynamesrc, name, n - name); + isc_buffer_add(&keynamesrc, n - name); + + debug("namefromtext"); + result = dns_name_fromtext(keyname, &keynamesrc, dns_rootname, + ISC_FALSE, NULL); + check_result(result, "dns_name_fromtext"); + + secretlen = strlen(secretstr) * 3 / 4; + secret = isc_mem_allocate(mctx, secretlen); + if (secret == NULL) + fatal("out of memory"); + + isc_buffer_init(&secretbuf, secret, secretlen); + result = isc_base64_decodestring(secretstr, &secretbuf); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "could not create key from %s: %s\n", + keystr, isc_result_totext(result)); + goto failure; + } + + secretlen = isc_buffer_usedlength(&secretbuf); + + debug("keycreate"); + result = dns_tsigkey_create(keyname, hmacname, secret, secretlen, + ISC_TRUE, NULL, 0, 0, mctx, NULL, &tsigkey); + if (result != ISC_R_SUCCESS) + fprintf(stderr, "could not create key from %s: %s\n", + keystr, dns_result_totext(result)); + else + dst_key_setbits(tsigkey->key, digestbits); + failure: + if (secret != NULL) + isc_mem_free(mctx, secret); +} + +static void +setup_keyfile(void) { + dst_key_t *dstkey = NULL; + isc_result_t result; + dns_name_t *hmacname = NULL; + + debug("Creating key..."); + + result = dst_key_fromnamedfile(keyfile, + DST_TYPE_PRIVATE | DST_TYPE_KEY, mctx, + &dstkey); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "could not read key from %s: %s\n", + keyfile, isc_result_totext(result)); + return; + } + switch (dst_key_alg(dstkey)) { + case DST_ALG_HMACMD5: + hmacname = DNS_TSIG_HMACMD5_NAME; + break; + case DST_ALG_HMACSHA1: + hmacname = DNS_TSIG_HMACSHA1_NAME; + break; + case DST_ALG_HMACSHA224: + hmacname = DNS_TSIG_HMACSHA224_NAME; + break; + case DST_ALG_HMACSHA256: + hmacname = DNS_TSIG_HMACSHA256_NAME; + break; + case DST_ALG_HMACSHA384: + hmacname = DNS_TSIG_HMACSHA384_NAME; + break; + case DST_ALG_HMACSHA512: + hmacname = DNS_TSIG_HMACSHA512_NAME; + break; + } + if (hmacname != NULL) { + result = dns_tsigkey_createfromkey(dst_key_name(dstkey), + hmacname, dstkey, ISC_FALSE, + NULL, 0, 0, mctx, NULL, + &tsigkey); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "could not create key from %s: %s\n", + keyfile, isc_result_totext(result)); + dst_key_free(&dstkey); + return; + } + } else + sig0key = dstkey; +} + +static void +doshutdown(void) { + isc_task_detach(&global_task); + + if (userserver != NULL) + isc_mem_put(mctx, userserver, sizeof(isc_sockaddr_t)); + + if (localaddr != NULL) + isc_mem_put(mctx, localaddr, sizeof(isc_sockaddr_t)); + + if (tsigkey != NULL) { + ddebug("Freeing TSIG key"); + dns_tsigkey_detach(&tsigkey); + } + + if (sig0key != NULL) { + ddebug("Freeing SIG(0) key"); + dst_key_free(&sig0key); + } + + if (updatemsg != NULL) + dns_message_destroy(&updatemsg); + + if (is_dst_up) { + ddebug("Destroy DST lib"); + dst_lib_destroy(); + is_dst_up = ISC_FALSE; + } + + if (entp != NULL) { + ddebug("Detach from entropy"); + isc_entropy_detach(&entp); + } + + lwres_conf_clear(lwctx); + lwres_context_destroy(&lwctx); + + isc_mem_put(mctx, servers, ns_total * sizeof(isc_sockaddr_t)); + + ddebug("Destroying request manager"); + dns_requestmgr_detach(&requestmgr); + + ddebug("Freeing the dispatchers"); + if (have_ipv4) + dns_dispatch_detach(&dispatchv4); + if (have_ipv6) + dns_dispatch_detach(&dispatchv6); + + ddebug("Shutting down dispatch manager"); + dns_dispatchmgr_destroy(&dispatchmgr); + +} + +static void +maybeshutdown(void) { + ddebug("Shutting down request manager"); + dns_requestmgr_shutdown(requestmgr); + + if (requests != 0) + return; + + doshutdown(); +} + +static void +shutdown_program(isc_task_t *task, isc_event_t *event) { + REQUIRE(task == global_task); + UNUSED(task); + + ddebug("shutdown_program()"); + isc_event_free(&event); + + shuttingdown = ISC_TRUE; + maybeshutdown(); +} + +static void +setup_system(void) { + isc_result_t result; + isc_sockaddr_t bind_any, bind_any6; + lwres_result_t lwresult; + unsigned int attrs, attrmask; + int i; + + ddebug("setup_system()"); + + dns_result_register(); + + result = isc_net_probeipv4(); + if (result == ISC_R_SUCCESS) + have_ipv4 = ISC_TRUE; + + result = isc_net_probeipv6(); + if (result == ISC_R_SUCCESS) + have_ipv6 = ISC_TRUE; + + if (!have_ipv4 && !have_ipv6) + fatal("could not find either IPv4 or IPv6"); + + result = isc_mem_create(0, 0, &mctx); + check_result(result, "isc_mem_create"); + + lwresult = lwres_context_create(&lwctx, mctx, mem_alloc, mem_free, 1); + if (lwresult != LWRES_R_SUCCESS) + fatal("lwres_context_create failed"); + + (void)lwres_conf_parse(lwctx, RESOLV_CONF); + lwconf = lwres_conf_get(lwctx); + + ns_total = lwconf->nsnext; + if (ns_total <= 0) { + /* No name servers in resolv.conf; default to loopback. */ + struct in_addr localhost; + ns_total = 1; + servers = isc_mem_get(mctx, ns_total * sizeof(isc_sockaddr_t)); + if (servers == NULL) + fatal("out of memory"); + localhost.s_addr = htonl(INADDR_LOOPBACK); + isc_sockaddr_fromin(&servers[0], &localhost, DNSDEFAULTPORT); + } else { + servers = isc_mem_get(mctx, ns_total * sizeof(isc_sockaddr_t)); + if (servers == NULL) + fatal("out of memory"); + for (i = 0; i < ns_total; i++) { + if (lwconf->nameservers[i].family == LWRES_ADDRTYPE_V4) { + struct in_addr in4; + memcpy(&in4, lwconf->nameservers[i].address, 4); + isc_sockaddr_fromin(&servers[i], &in4, DNSDEFAULTPORT); + } else { + struct in6_addr in6; + memcpy(&in6, lwconf->nameservers[i].address, 16); + isc_sockaddr_fromin6(&servers[i], &in6, + DNSDEFAULTPORT); + } + } + } + + result = isc_entropy_create(mctx, &entp); + check_result(result, "isc_entropy_create"); + + result = isc_hash_create(mctx, entp, DNS_NAME_MAXWIRE); + check_result(result, "isc_hash_create"); + isc_hash_init(); + + result = dns_dispatchmgr_create(mctx, entp, &dispatchmgr); + check_result(result, "dns_dispatchmgr_create"); + + result = isc_socketmgr_create(mctx, &socketmgr); + check_result(result, "dns_socketmgr_create"); + + result = isc_timermgr_create(mctx, &timermgr); + check_result(result, "dns_timermgr_create"); + + result = isc_taskmgr_create(mctx, 1, 0, &taskmgr); + check_result(result, "isc_taskmgr_create"); + + result = isc_task_create(taskmgr, 0, &global_task); + check_result(result, "isc_task_create"); + + result = isc_task_onshutdown(global_task, shutdown_program, NULL); + check_result(result, "isc_task_onshutdown"); + + result = dst_lib_init(mctx, entp, 0); + check_result(result, "dst_lib_init"); + is_dst_up = ISC_TRUE; + + attrmask = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP; + attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6; + + if (have_ipv6) { + attrs = DNS_DISPATCHATTR_UDP; + attrs |= DNS_DISPATCHATTR_MAKEQUERY; + attrs |= DNS_DISPATCHATTR_IPV6; + isc_sockaddr_any6(&bind_any6); + result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, + &bind_any6, PACKETSIZE, + 4, 2, 3, 5, + attrs, attrmask, &dispatchv6); + check_result(result, "dns_dispatch_getudp (v6)"); + } + + if (have_ipv4) { + attrs = DNS_DISPATCHATTR_UDP; + attrs |= DNS_DISPATCHATTR_MAKEQUERY; + attrs |= DNS_DISPATCHATTR_IPV4; + isc_sockaddr_any(&bind_any); + result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, + &bind_any, PACKETSIZE, + 4, 2, 3, 5, + attrs, attrmask, &dispatchv4); + check_result(result, "dns_dispatch_getudp (v4)"); + } + + result = dns_requestmgr_create(mctx, timermgr, + socketmgr, taskmgr, dispatchmgr, + dispatchv4, dispatchv6, &requestmgr); + check_result(result, "dns_requestmgr_create"); + + if (keystr != NULL) + setup_keystr(); + else if (keyfile != NULL) + setup_keyfile(); +} + +static void +get_address(char *host, in_port_t port, isc_sockaddr_t *sockaddr) { + int count; + isc_result_t result; + + isc_app_block(); + result = bind9_getaddresses(host, port, sockaddr, 1, &count); + isc_app_unblock(); + if (result != ISC_R_SUCCESS) + fatal("couldn't get address for '%s': %s", + host, isc_result_totext(result)); + INSIST(count == 1); +} + +static void +parse_args(int argc, char **argv) { + int ch; + isc_result_t result; + + debug("parse_args"); + while ((ch = isc_commandline_parse(argc, argv, "dDMy:vk:r:t:u:")) != -1) + { + switch (ch) { + case 'd': + debugging = ISC_TRUE; + break; + case 'D': /* was -dd */ + debugging = ISC_TRUE; + ddebugging = ISC_TRUE; + break; + case 'M': /* was -dm */ + debugging = ISC_TRUE; + ddebugging = ISC_TRUE; + memdebugging = ISC_TRUE; + isc_mem_debugging = ISC_MEM_DEBUGTRACE | + ISC_MEM_DEBUGRECORD; + break; + case 'y': + keystr = isc_commandline_argument; + break; + case 'v': + usevc = ISC_TRUE; + break; + case 'k': + keyfile = isc_commandline_argument; + break; + case 't': + result = isc_parse_uint32(&timeout, + isc_commandline_argument, 10); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "bad timeout '%s'\n", isc_commandline_argument); + exit(1); + } + if (timeout == 0) + timeout = UINT_MAX; + break; + case 'u': + result = isc_parse_uint32(&udp_timeout, + isc_commandline_argument, 10); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "bad udp timeout '%s'\n", isc_commandline_argument); + exit(1); + } + if (udp_timeout == 0) + udp_timeout = UINT_MAX; + break; + case 'r': + result = isc_parse_uint32(&udp_retries, + isc_commandline_argument, 10); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "bad udp retries '%s'\n", isc_commandline_argument); + exit(1); + } + break; + default: + fprintf(stderr, "%s: invalid argument -%c\n", + argv[0], ch); + fprintf(stderr, "usage: nsupdate [-d] " + "[-y keyname:secret | -k keyfile] [-v] " + "[filename]\n"); + exit(1); + } + } + if (keyfile != NULL && keystr != NULL) { + fprintf(stderr, "%s: cannot specify both -k and -y\n", + argv[0]); + exit(1); + } + + if (argv[isc_commandline_index] != NULL) { + if (strcmp(argv[isc_commandline_index], "-") == 0) { + input = stdin; + } else { + result = isc_stdio_open(argv[isc_commandline_index], + "r", &input); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "could not open '%s': %s\n", + argv[isc_commandline_index], + isc_result_totext(result)); + exit(1); + } + } + interactive = ISC_FALSE; + } +} + +static isc_uint16_t +parse_name(char **cmdlinep, dns_message_t *msg, dns_name_t **namep) { + isc_result_t result; + char *word; + isc_buffer_t *namebuf = NULL; + isc_buffer_t source; + + word = nsu_strsep(cmdlinep, " \t\r\n"); + if (*word == 0) { + fprintf(stderr, "could not read owner name\n"); + return (STATUS_SYNTAX); + } + + result = dns_message_gettempname(msg, namep); + check_result(result, "dns_message_gettempname"); + result = isc_buffer_allocate(mctx, &namebuf, DNS_NAME_MAXWIRE); + check_result(result, "isc_buffer_allocate"); + dns_name_init(*namep, NULL); + dns_name_setbuffer(*namep, namebuf); + dns_message_takebuffer(msg, &namebuf); + isc_buffer_init(&source, word, strlen(word)); + isc_buffer_add(&source, strlen(word)); + result = dns_name_fromtext(*namep, &source, dns_rootname, + ISC_FALSE, NULL); + check_result(result, "dns_name_fromtext"); + isc_buffer_invalidate(&source); + return (STATUS_MORE); +} + +static isc_uint16_t +parse_rdata(char **cmdlinep, dns_rdataclass_t rdataclass, + dns_rdatatype_t rdatatype, dns_message_t *msg, + dns_rdata_t *rdata) +{ + char *cmdline = *cmdlinep; + isc_buffer_t source, *buf = NULL, *newbuf = NULL; + isc_region_t r; + isc_lex_t *lex = NULL; + dns_rdatacallbacks_t callbacks; + isc_result_t result; + + while (*cmdline != 0 && isspace((unsigned char)*cmdline)) + cmdline++; + + if (*cmdline != 0) { + dns_rdatacallbacks_init(&callbacks); + result = isc_lex_create(mctx, strlen(cmdline), &lex); + check_result(result, "isc_lex_create"); + isc_buffer_init(&source, cmdline, strlen(cmdline)); + isc_buffer_add(&source, strlen(cmdline)); + result = isc_lex_openbuffer(lex, &source); + check_result(result, "isc_lex_openbuffer"); + result = isc_buffer_allocate(mctx, &buf, MAXWIRE); + check_result(result, "isc_buffer_allocate"); + result = dns_rdata_fromtext(rdata, rdataclass, rdatatype, lex, + dns_rootname, 0, mctx, buf, + &callbacks); + isc_lex_destroy(&lex); + if (result == ISC_R_SUCCESS) { + isc_buffer_usedregion(buf, &r); + result = isc_buffer_allocate(mctx, &newbuf, r.length); + check_result(result, "isc_buffer_allocate"); + isc_buffer_putmem(newbuf, r.base, r.length); + isc_buffer_usedregion(newbuf, &r); + dns_rdata_fromregion(rdata, rdataclass, rdatatype, &r); + isc_buffer_free(&buf); + dns_message_takebuffer(msg, &newbuf); + } else { + fprintf(stderr, "invalid rdata format: %s\n", + isc_result_totext(result)); + isc_buffer_free(&buf); + return (STATUS_SYNTAX); + } + } else { + rdata->flags = DNS_RDATA_UPDATE; + } + *cmdlinep = cmdline; + return (STATUS_MORE); +} + +static isc_uint16_t +make_prereq(char *cmdline, isc_boolean_t ispositive, isc_boolean_t isrrset) { + isc_result_t result; + char *word; + dns_name_t *name = NULL; + isc_textregion_t region; + dns_rdataset_t *rdataset = NULL; + dns_rdatalist_t *rdatalist = NULL; + dns_rdataclass_t rdataclass; + dns_rdatatype_t rdatatype; + dns_rdata_t *rdata = NULL; + isc_uint16_t retval; + + ddebug("make_prereq()"); + + /* + * Read the owner name + */ + retval = parse_name(&cmdline, updatemsg, &name); + if (retval != STATUS_MORE) + return (retval); + + /* + * If this is an rrset prereq, read the class or type. + */ + if (isrrset) { + word = nsu_strsep(&cmdline, " \t\r\n"); + if (*word == 0) { + fprintf(stderr, "could not read class or type\n"); + goto failure; + } + region.base = word; + region.length = strlen(word); + result = dns_rdataclass_fromtext(&rdataclass, ®ion); + if (result == ISC_R_SUCCESS) { + if (!setzoneclass(rdataclass)) { + fprintf(stderr, "class mismatch: %s\n", word); + goto failure; + } + /* + * Now read the type. + */ + word = nsu_strsep(&cmdline, " \t\r\n"); + if (*word == 0) { + fprintf(stderr, "could not read type\n"); + goto failure; + } + region.base = word; + region.length = strlen(word); + result = dns_rdatatype_fromtext(&rdatatype, ®ion); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "invalid type: %s\n", word); + goto failure; + } + } else { + rdataclass = getzoneclass(); + result = dns_rdatatype_fromtext(&rdatatype, ®ion); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "invalid type: %s\n", word); + goto failure; + } + } + } else + rdatatype = dns_rdatatype_any; + + result = dns_message_gettemprdata(updatemsg, &rdata); + check_result(result, "dns_message_gettemprdata"); + + rdata->data = NULL; + rdata->length = 0; + + if (isrrset && ispositive) { + retval = parse_rdata(&cmdline, rdataclass, rdatatype, + updatemsg, rdata); + if (retval != STATUS_MORE) + goto failure; + } else + rdata->flags = DNS_RDATA_UPDATE; + + result = dns_message_gettemprdatalist(updatemsg, &rdatalist); + check_result(result, "dns_message_gettemprdatalist"); + result = dns_message_gettemprdataset(updatemsg, &rdataset); + check_result(result, "dns_message_gettemprdataset"); + dns_rdatalist_init(rdatalist); + rdatalist->type = rdatatype; + if (ispositive) { + if (isrrset && rdata->data != NULL) + rdatalist->rdclass = rdataclass; + else + rdatalist->rdclass = dns_rdataclass_any; + } else + rdatalist->rdclass = dns_rdataclass_none; + rdatalist->covers = 0; + rdatalist->ttl = 0; + rdata->rdclass = rdatalist->rdclass; + rdata->type = rdatatype; + ISC_LIST_INIT(rdatalist->rdata); + ISC_LIST_APPEND(rdatalist->rdata, rdata, link); + dns_rdataset_init(rdataset); + dns_rdatalist_tordataset(rdatalist, rdataset); + ISC_LIST_INIT(name->list); + ISC_LIST_APPEND(name->list, rdataset, link); + dns_message_addname(updatemsg, name, DNS_SECTION_PREREQUISITE); + return (STATUS_MORE); + + failure: + if (name != NULL) + dns_message_puttempname(updatemsg, &name); + return (STATUS_SYNTAX); +} + +static isc_uint16_t +evaluate_prereq(char *cmdline) { + char *word; + isc_boolean_t ispositive, isrrset; + + ddebug("evaluate_prereq()"); + word = nsu_strsep(&cmdline, " \t\r\n"); + if (*word == 0) { + fprintf(stderr, "could not read operation code\n"); + return (STATUS_SYNTAX); + } + if (strcasecmp(word, "nxdomain") == 0) { + ispositive = ISC_FALSE; + isrrset = ISC_FALSE; + } else if (strcasecmp(word, "yxdomain") == 0) { + ispositive = ISC_TRUE; + isrrset = ISC_FALSE; + } else if (strcasecmp(word, "nxrrset") == 0) { + ispositive = ISC_FALSE; + isrrset = ISC_TRUE; + } else if (strcasecmp(word, "yxrrset") == 0) { + ispositive = ISC_TRUE; + isrrset = ISC_TRUE; + } else { + fprintf(stderr, "incorrect operation code: %s\n", word); + return (STATUS_SYNTAX); + } + return (make_prereq(cmdline, ispositive, isrrset)); +} + +static isc_uint16_t +evaluate_server(char *cmdline) { + char *word, *server; + long port; + + word = nsu_strsep(&cmdline, " \t\r\n"); + if (*word == 0) { + fprintf(stderr, "could not read server name\n"); + return (STATUS_SYNTAX); + } + server = word; + + word = nsu_strsep(&cmdline, " \t\r\n"); + if (*word == 0) + port = DNSDEFAULTPORT; + else { + char *endp; + port = strtol(word, &endp, 10); + if (*endp != 0) { + fprintf(stderr, "port '%s' is not numeric\n", word); + return (STATUS_SYNTAX); + } else if (port < 1 || port > 65535) { + fprintf(stderr, "port '%s' is out of range " + "(1 to 65535)\n", word); + return (STATUS_SYNTAX); + } + } + + if (userserver == NULL) { + userserver = isc_mem_get(mctx, sizeof(isc_sockaddr_t)); + if (userserver == NULL) + fatal("out of memory"); + } + + get_address(server, (in_port_t)port, userserver); + + return (STATUS_MORE); +} + +static isc_uint16_t +evaluate_local(char *cmdline) { + char *word, *local; + long port; + struct in_addr in4; + struct in6_addr in6; + + word = nsu_strsep(&cmdline, " \t\r\n"); + if (*word == 0) { + fprintf(stderr, "could not read server name\n"); + return (STATUS_SYNTAX); + } + local = word; + + word = nsu_strsep(&cmdline, " \t\r\n"); + if (*word == 0) + port = 0; + else { + char *endp; + port = strtol(word, &endp, 10); + if (*endp != 0) { + fprintf(stderr, "port '%s' is not numeric\n", word); + return (STATUS_SYNTAX); + } else if (port < 1 || port > 65535) { + fprintf(stderr, "port '%s' is out of range " + "(1 to 65535)\n", word); + return (STATUS_SYNTAX); + } + } + + if (localaddr == NULL) { + localaddr = isc_mem_get(mctx, sizeof(isc_sockaddr_t)); + if (localaddr == NULL) + fatal("out of memory"); + } + + if (have_ipv6 && inet_pton(AF_INET6, local, &in6) == 1) + isc_sockaddr_fromin6(localaddr, &in6, (in_port_t)port); + else if (have_ipv4 && inet_pton(AF_INET, local, &in4) == 1) + isc_sockaddr_fromin(localaddr, &in4, (in_port_t)port); + else { + fprintf(stderr, "invalid address %s", local); + return (STATUS_SYNTAX); + } + + return (STATUS_MORE); +} + +static isc_uint16_t +evaluate_key(char *cmdline) { + char *namestr; + char *secretstr; + isc_buffer_t b; + isc_result_t result; + dns_fixedname_t fkeyname; + dns_name_t *keyname; + int secretlen; + unsigned char *secret = NULL; + isc_buffer_t secretbuf; + dns_name_t *hmacname = NULL; + isc_uint16_t digestbits = 0; + char *n; + + namestr = nsu_strsep(&cmdline, " \t\r\n"); + if (*namestr == 0) { + fprintf(stderr, "could not read key name\n"); + return (STATUS_SYNTAX); + } + + dns_fixedname_init(&fkeyname); + keyname = dns_fixedname_name(&fkeyname); + + n = strchr(namestr, ':'); + if (n != NULL) { + digestbits = parse_hmac(&hmacname, namestr, n - namestr); + namestr = n + 1; + } else + hmacname = DNS_TSIG_HMACMD5_NAME; + + isc_buffer_init(&b, namestr, strlen(namestr)); + isc_buffer_add(&b, strlen(namestr)); + result = dns_name_fromtext(keyname, &b, dns_rootname, ISC_FALSE, NULL); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "could not parse key name\n"); + return (STATUS_SYNTAX); + } + + secretstr = nsu_strsep(&cmdline, "\r\n"); + if (*secretstr == 0) { + fprintf(stderr, "could not read key secret\n"); + return (STATUS_SYNTAX); + } + secretlen = strlen(secretstr) * 3 / 4; + secret = isc_mem_allocate(mctx, secretlen); + if (secret == NULL) + fatal("out of memory"); + + isc_buffer_init(&secretbuf, secret, secretlen); + result = isc_base64_decodestring(secretstr, &secretbuf); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "could not create key from %s: %s\n", + secretstr, isc_result_totext(result)); + isc_mem_free(mctx, secret); + return (STATUS_SYNTAX); + } + secretlen = isc_buffer_usedlength(&secretbuf); + + if (tsigkey != NULL) + dns_tsigkey_detach(&tsigkey); + result = dns_tsigkey_create(keyname, hmacname, secret, secretlen, + ISC_TRUE, NULL, 0, 0, mctx, NULL, + &tsigkey); + isc_mem_free(mctx, secret); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "could not create key from %s %s: %s\n", + namestr, secretstr, dns_result_totext(result)); + return (STATUS_SYNTAX); + } + dst_key_setbits(tsigkey->key, digestbits); + return (STATUS_MORE); +} + +static isc_uint16_t +evaluate_zone(char *cmdline) { + char *word; + isc_buffer_t b; + isc_result_t result; + + word = nsu_strsep(&cmdline, " \t\r\n"); + if (*word == 0) { + fprintf(stderr, "could not read zone name\n"); + return (STATUS_SYNTAX); + } + + dns_fixedname_init(&fuserzone); + userzone = dns_fixedname_name(&fuserzone); + isc_buffer_init(&b, word, strlen(word)); + isc_buffer_add(&b, strlen(word)); + result = dns_name_fromtext(userzone, &b, dns_rootname, ISC_FALSE, + NULL); + if (result != ISC_R_SUCCESS) { + userzone = NULL; /* Lest it point to an invalid name */ + fprintf(stderr, "could not parse zone name\n"); + return (STATUS_SYNTAX); + } + + return (STATUS_MORE); +} + +static isc_uint16_t +evaluate_class(char *cmdline) { + char *word; + isc_textregion_t r; + isc_result_t result; + dns_rdataclass_t rdclass; + + word = nsu_strsep(&cmdline, " \t\r\n"); + if (*word == 0) { + fprintf(stderr, "could not read class name\n"); + return (STATUS_SYNTAX); + } + + r.base = word; + r.length = strlen(word); + result = dns_rdataclass_fromtext(&rdclass, &r); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "could not parse class name: %s\n", word); + return (STATUS_SYNTAX); + } + switch (rdclass) { + case dns_rdataclass_none: + case dns_rdataclass_any: + case dns_rdataclass_reserved0: + fprintf(stderr, "bad default class: %s\n", word); + return (STATUS_SYNTAX); + default: + defaultclass = rdclass; + } + + return (STATUS_MORE); +} + +static isc_uint16_t +update_addordelete(char *cmdline, isc_boolean_t isdelete) { + isc_result_t result; + dns_name_t *name = NULL; + isc_uint32_t ttl; + char *word; + dns_rdataclass_t rdataclass; + dns_rdatatype_t rdatatype; + dns_rdata_t *rdata = NULL; + dns_rdatalist_t *rdatalist = NULL; + dns_rdataset_t *rdataset = NULL; + isc_textregion_t region; + isc_uint16_t retval; + + ddebug("update_addordelete()"); + + /* + * Read the owner name. + */ + retval = parse_name(&cmdline, updatemsg, &name); + if (retval != STATUS_MORE) + return (retval); + + result = dns_message_gettemprdata(updatemsg, &rdata); + check_result(result, "dns_message_gettemprdata"); + + rdata->rdclass = 0; + rdata->type = 0; + rdata->data = NULL; + rdata->length = 0; + + /* + * If this is an add, read the TTL and verify that it's in range. + * If it's a delete, ignore a TTL if present (for compatibility). + */ + word = nsu_strsep(&cmdline, " \t\r\n"); + if (*word == 0) { + if (!isdelete) { + fprintf(stderr, "could not read owner ttl\n"); + goto failure; + } + else { + ttl = 0; + rdataclass = dns_rdataclass_any; + rdatatype = dns_rdatatype_any; + rdata->flags = DNS_RDATA_UPDATE; + goto doneparsing; + } + } + result = isc_parse_uint32(&ttl, word, 10); + if (result != ISC_R_SUCCESS) { + if (isdelete) { + ttl = 0; + goto parseclass; + } else { + fprintf(stderr, "ttl '%s': %s\n", word, + isc_result_totext(result)); + goto failure; + } + } + + if (isdelete) + ttl = 0; + else if (ttl > TTL_MAX) { + fprintf(stderr, "ttl '%s' is out of range (0 to %u)\n", + word, TTL_MAX); + goto failure; + } + + /* + * Read the class or type. + */ + word = nsu_strsep(&cmdline, " \t\r\n"); + parseclass: + if (*word == 0) { + if (isdelete) { + rdataclass = dns_rdataclass_any; + rdatatype = dns_rdatatype_any; + rdata->flags = DNS_RDATA_UPDATE; + goto doneparsing; + } else { + fprintf(stderr, "could not read class or type\n"); + goto failure; + } + } + region.base = word; + region.length = strlen(word); + result = dns_rdataclass_fromtext(&rdataclass, ®ion); + if (result == ISC_R_SUCCESS) { + if (!setzoneclass(rdataclass)) { + fprintf(stderr, "class mismatch: %s\n", word); + goto failure; + } + /* + * Now read the type. + */ + word = nsu_strsep(&cmdline, " \t\r\n"); + if (*word == 0) { + if (isdelete) { + rdataclass = dns_rdataclass_any; + rdatatype = dns_rdatatype_any; + rdata->flags = DNS_RDATA_UPDATE; + goto doneparsing; + } else { + fprintf(stderr, "could not read type\n"); + goto failure; + } + } + region.base = word; + region.length = strlen(word); + result = dns_rdatatype_fromtext(&rdatatype, ®ion); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "'%s' is not a valid type: %s\n", + word, isc_result_totext(result)); + goto failure; + } + } else { + rdataclass = getzoneclass(); + result = dns_rdatatype_fromtext(&rdatatype, ®ion); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "'%s' is not a valid class or type: " + "%s\n", word, isc_result_totext(result)); + goto failure; + } + } + + retval = parse_rdata(&cmdline, rdataclass, rdatatype, updatemsg, + rdata); + if (retval != STATUS_MORE) + goto failure; + + if (isdelete) { + if ((rdata->flags & DNS_RDATA_UPDATE) != 0) + rdataclass = dns_rdataclass_any; + else + rdataclass = dns_rdataclass_none; + } else { + if ((rdata->flags & DNS_RDATA_UPDATE) != 0) { + fprintf(stderr, "could not read rdata\n"); + goto failure; + } + } + + doneparsing: + + result = dns_message_gettemprdatalist(updatemsg, &rdatalist); + check_result(result, "dns_message_gettemprdatalist"); + result = dns_message_gettemprdataset(updatemsg, &rdataset); + check_result(result, "dns_message_gettemprdataset"); + dns_rdatalist_init(rdatalist); + rdatalist->type = rdatatype; + rdatalist->rdclass = rdataclass; + rdatalist->covers = rdatatype; + rdatalist->ttl = (dns_ttl_t)ttl; + ISC_LIST_INIT(rdatalist->rdata); + ISC_LIST_APPEND(rdatalist->rdata, rdata, link); + dns_rdataset_init(rdataset); + dns_rdatalist_tordataset(rdatalist, rdataset); + ISC_LIST_INIT(name->list); + ISC_LIST_APPEND(name->list, rdataset, link); + dns_message_addname(updatemsg, name, DNS_SECTION_UPDATE); + return (STATUS_MORE); + + failure: + if (name != NULL) + dns_message_puttempname(updatemsg, &name); + if (rdata != NULL) + dns_message_puttemprdata(updatemsg, &rdata); + return (STATUS_SYNTAX); +} + +static isc_uint16_t +evaluate_update(char *cmdline) { + char *word; + isc_boolean_t isdelete; + + ddebug("evaluate_update()"); + word = nsu_strsep(&cmdline, " \t\r\n"); + if (*word == 0) { + fprintf(stderr, "could not read operation code\n"); + return (STATUS_SYNTAX); + } + if (strcasecmp(word, "delete") == 0) + isdelete = ISC_TRUE; + else if (strcasecmp(word, "add") == 0) + isdelete = ISC_FALSE; + else { + fprintf(stderr, "incorrect operation code: %s\n", word); + return (STATUS_SYNTAX); + } + return (update_addordelete(cmdline, isdelete)); +} + +static void +setzone(dns_name_t *zonename) { + isc_result_t result; + dns_name_t *name = NULL; + dns_rdataset_t *rdataset = NULL; + + result = dns_message_firstname(updatemsg, DNS_SECTION_ZONE); + if (result == ISC_R_SUCCESS) { + dns_message_currentname(updatemsg, DNS_SECTION_ZONE, &name); + dns_message_removename(updatemsg, name, DNS_SECTION_ZONE); + for (rdataset = ISC_LIST_HEAD(name->list); + rdataset != NULL; + rdataset = ISC_LIST_HEAD(name->list)) { + ISC_LIST_UNLINK(name->list, rdataset, link); + dns_rdataset_disassociate(rdataset); + dns_message_puttemprdataset(updatemsg, &rdataset); + } + dns_message_puttempname(updatemsg, &name); + } + + if (zonename != NULL) { + result = dns_message_gettempname(updatemsg, &name); + check_result(result, "dns_message_gettempname"); + dns_name_init(name, NULL); + dns_name_clone(zonename, name); + result = dns_message_gettemprdataset(updatemsg, &rdataset); + check_result(result, "dns_message_gettemprdataset"); + dns_rdataset_makequestion(rdataset, getzoneclass(), + dns_rdatatype_soa); + ISC_LIST_INIT(name->list); + ISC_LIST_APPEND(name->list, rdataset, link); + dns_message_addname(updatemsg, name, DNS_SECTION_ZONE); + } +} + +static void +show_message(dns_message_t *msg) { + isc_result_t result; + isc_buffer_t *buf = NULL; + int bufsz; + + ddebug("show_message()"); + + setzone(userzone); + + bufsz = INITTEXT; + do { + if (bufsz > MAXTEXT) { + fprintf(stderr, "could not allocate large enough " + "buffer to display message\n"); + exit(1); + } + if (buf != NULL) + isc_buffer_free(&buf); + result = isc_buffer_allocate(mctx, &buf, bufsz); + check_result(result, "isc_buffer_allocate"); + result = dns_message_totext(msg, style, 0, buf); + bufsz *= 2; + } while (result == ISC_R_NOSPACE); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "could not convert message to text format.\n"); + isc_buffer_free(&buf); + return; + } + printf("Outgoing update query:\n%.*s", + (int)isc_buffer_usedlength(buf), + (char*)isc_buffer_base(buf)); + isc_buffer_free(&buf); +} + + +static isc_uint16_t +get_next_command(void) { + char cmdlinebuf[MAXCMD]; + char *cmdline; + char *word; + + ddebug("get_next_command()"); + if (interactive) { + fprintf(stdout, "> "); + fflush(stdout); + } + isc_app_block(); + cmdline = fgets(cmdlinebuf, MAXCMD, input); + isc_app_unblock(); + if (cmdline == NULL) + return (STATUS_QUIT); + word = nsu_strsep(&cmdline, " \t\r\n"); + + if (feof(input)) + return (STATUS_QUIT); + if (*word == 0) + return (STATUS_SEND); + if (word[0] == ';') + return (STATUS_MORE); + if (strcasecmp(word, "quit") == 0) + return (STATUS_QUIT); + if (strcasecmp(word, "prereq") == 0) + return (evaluate_prereq(cmdline)); + if (strcasecmp(word, "update") == 0) + return (evaluate_update(cmdline)); + if (strcasecmp(word, "server") == 0) + return (evaluate_server(cmdline)); + if (strcasecmp(word, "local") == 0) + return (evaluate_local(cmdline)); + if (strcasecmp(word, "zone") == 0) + return (evaluate_zone(cmdline)); + if (strcasecmp(word, "class") == 0) + return (evaluate_class(cmdline)); + if (strcasecmp(word, "send") == 0) + return (STATUS_SEND); + if (strcasecmp(word, "show") == 0) { + show_message(updatemsg); + return (STATUS_MORE); + } + if (strcasecmp(word, "answer") == 0) { + if (answer != NULL) + show_message(answer); + return (STATUS_MORE); + } + if (strcasecmp(word, "key") == 0) + return (evaluate_key(cmdline)); + fprintf(stderr, "incorrect section name: %s\n", word); + return (STATUS_SYNTAX); +} + +static isc_boolean_t +user_interaction(void) { + isc_uint16_t result = STATUS_MORE; + + ddebug("user_interaction()"); + while ((result == STATUS_MORE) || (result == STATUS_SYNTAX)) { + result = get_next_command(); + if (!interactive && result == STATUS_SYNTAX) + fatal("syntax error"); + } + if (result == STATUS_SEND) + return (ISC_TRUE); + return (ISC_FALSE); + +} + +static void +done_update(void) { + isc_event_t *event = global_event; + ddebug("done_update()"); + isc_task_send(global_task, &event); +} + +static void +check_tsig_error(dns_rdataset_t *rdataset, isc_buffer_t *b) { + isc_result_t result; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdata_any_tsig_t tsig; + + result = dns_rdataset_first(rdataset); + check_result(result, "dns_rdataset_first"); + dns_rdataset_current(rdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &tsig, NULL); + check_result(result, "dns_rdata_tostruct"); + if (tsig.error != 0) { + if (isc_buffer_remaininglength(b) < 1) + check_result(ISC_R_NOSPACE, "isc_buffer_remaininglength"); + isc__buffer_putstr(b, "(" /*)*/); + result = dns_tsigrcode_totext(tsig.error, b); + check_result(result, "dns_tsigrcode_totext"); + if (isc_buffer_remaininglength(b) < 1) + check_result(ISC_R_NOSPACE, "isc_buffer_remaininglength"); + isc__buffer_putstr(b, /*(*/ ")"); + } +} + +static void +update_completed(isc_task_t *task, isc_event_t *event) { + dns_requestevent_t *reqev = NULL; + isc_result_t result; + dns_request_t *request; + + UNUSED(task); + + ddebug("update_completed()"); + + requests--; + + REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE); + reqev = (dns_requestevent_t *)event; + request = reqev->request; + + if (shuttingdown) { + dns_request_destroy(&request); + isc_event_free(&event); + maybeshutdown(); + return; + } + + if (reqev->result != ISC_R_SUCCESS) { + fprintf(stderr, "; Communication with server failed: %s\n", + isc_result_totext(reqev->result)); + seenerror = ISC_TRUE; + goto done; + } + + result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &answer); + check_result(result, "dns_message_create"); + result = dns_request_getresponse(request, answer, + DNS_MESSAGEPARSE_PRESERVEORDER); + switch (result) { + case ISC_R_SUCCESS: + break; + case DNS_R_CLOCKSKEW: + case DNS_R_EXPECTEDTSIG: + case DNS_R_TSIGERRORSET: + case DNS_R_TSIGVERIFYFAILURE: + case DNS_R_UNEXPECTEDTSIG: + fprintf(stderr, "; TSIG error with server: %s\n", + isc_result_totext(result)); + seenerror = ISC_TRUE; + break; + default: + check_result(result, "dns_request_getresponse"); + } + + if (answer->rcode != dns_rcode_noerror) { + seenerror = ISC_TRUE; + if (!debugging) { + char buf[64]; + isc_buffer_t b; + dns_rdataset_t *rds; + + isc_buffer_init(&b, buf, sizeof(buf) - 1); + result = dns_rcode_totext(answer->rcode, &b); + check_result(result, "dns_rcode_totext"); + rds = dns_message_gettsig(answer, NULL); + if (rds != NULL) + check_tsig_error(rds, &b); + fprintf(stderr, "update failed: %.*s\n", + (int)isc_buffer_usedlength(&b), buf); + } + } + if (debugging) { + isc_buffer_t *buf = NULL; + int bufsz; + + bufsz = INITTEXT; + do { + if (bufsz > MAXTEXT) { + fprintf(stderr, "could not allocate large " + "enough buffer to display message\n"); + exit(1); + } + if (buf != NULL) + isc_buffer_free(&buf); + result = isc_buffer_allocate(mctx, &buf, bufsz); + check_result(result, "isc_buffer_allocate"); + result = dns_message_totext(answer, style, 0, buf); + bufsz *= 2; + } while (result == ISC_R_NOSPACE); + check_result(result, "dns_message_totext"); + fprintf(stderr, "\nReply from update query:\n%.*s\n", + (int)isc_buffer_usedlength(buf), + (char*)isc_buffer_base(buf)); + isc_buffer_free(&buf); + } + done: + dns_request_destroy(&request); + isc_event_free(&event); + done_update(); +} + +static void +send_update(dns_name_t *zonename, isc_sockaddr_t *master, + isc_sockaddr_t *srcaddr) +{ + isc_result_t result; + dns_request_t *request = NULL; + unsigned int options = 0; + + ddebug("send_update()"); + + setzone(zonename); + + if (usevc) + options |= DNS_REQUESTOPT_TCP; + if (tsigkey == NULL && sig0key != NULL) { + result = dns_message_setsig0key(updatemsg, sig0key); + check_result(result, "dns_message_setsig0key"); + } + if (debugging) { + char addrbuf[ISC_SOCKADDR_FORMATSIZE]; + + isc_sockaddr_format(master, addrbuf, sizeof(addrbuf)); + fprintf(stderr, "Sending update to %s\n", addrbuf); + } + result = dns_request_createvia3(requestmgr, updatemsg, srcaddr, + master, options, tsigkey, timeout, + udp_timeout, udp_retries, global_task, + update_completed, NULL, &request); + check_result(result, "dns_request_createvia3"); + + if (debugging) + show_message(updatemsg); + + requests++; +} + +static void +recvsoa(isc_task_t *task, isc_event_t *event) { + dns_requestevent_t *reqev = NULL; + dns_request_t *request = NULL; + isc_result_t result, eresult; + dns_message_t *rcvmsg = NULL; + dns_section_t section; + dns_name_t *name = NULL; + dns_rdataset_t *soaset = NULL; + dns_rdata_soa_t soa; + dns_rdata_t soarr = DNS_RDATA_INIT; + int pass = 0; + dns_name_t master; + isc_sockaddr_t *serveraddr, tempaddr; + dns_name_t *zonename; + nsu_requestinfo_t *reqinfo; + dns_message_t *soaquery = NULL; + isc_sockaddr_t *addr; + isc_boolean_t seencname = ISC_FALSE; + dns_name_t tname; + unsigned int nlabels; + + UNUSED(task); + + ddebug("recvsoa()"); + + requests--; + + REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE); + reqev = (dns_requestevent_t *)event; + request = reqev->request; + eresult = reqev->result; + reqinfo = reqev->ev_arg; + soaquery = reqinfo->msg; + addr = reqinfo->addr; + + if (shuttingdown) { + dns_request_destroy(&request); + dns_message_destroy(&soaquery); + isc_mem_put(mctx, reqinfo, sizeof(nsu_requestinfo_t)); + isc_event_free(&event); + maybeshutdown(); + return; + } + + if (eresult != ISC_R_SUCCESS) { + char addrbuf[ISC_SOCKADDR_FORMATSIZE]; + + isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf)); + fprintf(stderr, "; Communication with %s failed: %s\n", + addrbuf, isc_result_totext(eresult)); + if (userserver != NULL) + fatal("could not talk to specified name server"); + else if (++ns_inuse >= lwconf->nsnext) + fatal("could not talk to any default name server"); + ddebug("Destroying request [%p]", request); + dns_request_destroy(&request); + dns_message_renderreset(soaquery); + dns_message_settsigkey(soaquery, NULL); + sendrequest(localaddr, &servers[ns_inuse], soaquery, &request); + isc_mem_put(mctx, reqinfo, sizeof(nsu_requestinfo_t)); + isc_event_free(&event); + setzoneclass(dns_rdataclass_none); + return; + } + + isc_mem_put(mctx, reqinfo, sizeof(nsu_requestinfo_t)); + reqinfo = NULL; + isc_event_free(&event); + reqev = NULL; + + ddebug("About to create rcvmsg"); + result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg); + check_result(result, "dns_message_create"); + result = dns_request_getresponse(request, rcvmsg, + DNS_MESSAGEPARSE_PRESERVEORDER); + if (result == DNS_R_TSIGERRORSET && userserver != NULL) { + dns_message_destroy(&rcvmsg); + ddebug("Destroying request [%p]", request); + dns_request_destroy(&request); + reqinfo = isc_mem_get(mctx, sizeof(nsu_requestinfo_t)); + if (reqinfo == NULL) + fatal("out of memory"); + reqinfo->msg = soaquery; + reqinfo->addr = addr; + dns_message_renderreset(soaquery); + ddebug("retrying soa request without TSIG"); + result = dns_request_createvia3(requestmgr, soaquery, + localaddr, addr, 0, NULL, + FIND_TIMEOUT * 20, + FIND_TIMEOUT, 3, + global_task, recvsoa, reqinfo, + &request); + check_result(result, "dns_request_createvia"); + requests++; + return; + } + check_result(result, "dns_request_getresponse"); + section = DNS_SECTION_ANSWER; + if (debugging) { + isc_buffer_t *buf = NULL; + int bufsz; + bufsz = INITTEXT; + do { + if (buf != NULL) + isc_buffer_free(&buf); + if (bufsz > MAXTEXT) { + fprintf(stderr, "could not allocate enough " + "space for debugging message\n"); + exit(1); + } + result = isc_buffer_allocate(mctx, &buf, bufsz); + check_result(result, "isc_buffer_allocate"); + result = dns_message_totext(rcvmsg, style, 0, buf); + } while (result == ISC_R_NOSPACE); + check_result(result, "dns_message_totext"); + fprintf(stderr, "Reply from SOA query:\n%.*s\n", + (int)isc_buffer_usedlength(buf), + (char*)isc_buffer_base(buf)); + isc_buffer_free(&buf); + } + + if (rcvmsg->rcode != dns_rcode_noerror && + rcvmsg->rcode != dns_rcode_nxdomain) + fatal("response to SOA query was unsuccessful"); + + if (userzone != NULL && rcvmsg->rcode == dns_rcode_nxdomain) { + char namebuf[DNS_NAME_FORMATSIZE]; + dns_name_format(userzone, namebuf, sizeof(namebuf)); + error("specified zone '%s' does not exist (NXDOMAIN)", + namebuf); + dns_message_destroy(&rcvmsg); + dns_request_destroy(&request); + dns_message_destroy(&soaquery); + ddebug("Out of recvsoa"); + done_update(); + return; + } + + lookforsoa: + if (pass == 0) + section = DNS_SECTION_ANSWER; + else if (pass == 1) + section = DNS_SECTION_AUTHORITY; + else + goto droplabel; + + result = dns_message_firstname(rcvmsg, section); + if (result != ISC_R_SUCCESS) { + pass++; + goto lookforsoa; + } + while (result == ISC_R_SUCCESS) { + name = NULL; + dns_message_currentname(rcvmsg, section, &name); + soaset = NULL; + result = dns_message_findtype(name, dns_rdatatype_soa, 0, + &soaset); + if (result == ISC_R_SUCCESS) + break; + if (section == DNS_SECTION_ANSWER) { + dns_rdataset_t *tset = NULL; + if (dns_message_findtype(name, dns_rdatatype_cname, 0, + &tset) == ISC_R_SUCCESS + || + dns_message_findtype(name, dns_rdatatype_dname, 0, + &tset) == ISC_R_SUCCESS + ) + { + seencname = ISC_TRUE; + break; + } + } + + result = dns_message_nextname(rcvmsg, section); + } + + if (soaset == NULL && !seencname) { + pass++; + goto lookforsoa; + } + + if (seencname) + goto droplabel; + + if (debugging) { + char namestr[DNS_NAME_FORMATSIZE]; + dns_name_format(name, namestr, sizeof(namestr)); + fprintf(stderr, "Found zone name: %s\n", namestr); + } + + result = dns_rdataset_first(soaset); + check_result(result, "dns_rdataset_first"); + + dns_rdata_init(&soarr); + dns_rdataset_current(soaset, &soarr); + result = dns_rdata_tostruct(&soarr, &soa, NULL); + check_result(result, "dns_rdata_tostruct"); + + dns_name_init(&master, NULL); + dns_name_clone(&soa.origin, &master); + + if (userzone != NULL) + zonename = userzone; + else + zonename = name; + + if (debugging) { + char namestr[DNS_NAME_FORMATSIZE]; + dns_name_format(&master, namestr, sizeof(namestr)); + fprintf(stderr, "The master is: %s\n", namestr); + } + + if (userserver != NULL) + serveraddr = userserver; + else { + char serverstr[DNS_NAME_MAXTEXT+1]; + isc_buffer_t buf; + + isc_buffer_init(&buf, serverstr, sizeof(serverstr)); + result = dns_name_totext(&master, ISC_TRUE, &buf); + check_result(result, "dns_name_totext"); + serverstr[isc_buffer_usedlength(&buf)] = 0; + get_address(serverstr, DNSDEFAULTPORT, &tempaddr); + serveraddr = &tempaddr; + } + dns_rdata_freestruct(&soa); + + send_update(zonename, serveraddr, localaddr); + setzoneclass(dns_rdataclass_none); + + dns_message_destroy(&soaquery); + dns_request_destroy(&request); + + out: + dns_message_destroy(&rcvmsg); + ddebug("Out of recvsoa"); + return; + + droplabel: + result = dns_message_firstname(soaquery, DNS_SECTION_QUESTION); + INSIST(result == ISC_R_SUCCESS); + name = NULL; + dns_message_currentname(soaquery, DNS_SECTION_QUESTION, &name); + nlabels = dns_name_countlabels(name); + if (nlabels == 1) + fatal("could not find enclosing zone"); + dns_name_init(&tname, NULL); + dns_name_getlabelsequence(name, 1, nlabels - 1, &tname); + dns_name_clone(&tname, name); + dns_request_destroy(&request); + dns_message_renderreset(soaquery); + dns_message_settsigkey(soaquery, NULL); + if (userserver != NULL) + sendrequest(localaddr, userserver, soaquery, &request); + else + sendrequest(localaddr, &servers[ns_inuse], soaquery, + &request); + goto out; +} + +static void +sendrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, + dns_message_t *msg, dns_request_t **request) +{ + isc_result_t result; + nsu_requestinfo_t *reqinfo; + + reqinfo = isc_mem_get(mctx, sizeof(nsu_requestinfo_t)); + if (reqinfo == NULL) + fatal("out of memory"); + reqinfo->msg = msg; + reqinfo->addr = destaddr; + result = dns_request_createvia3(requestmgr, msg, srcaddr, destaddr, 0, + (userserver != NULL) ? tsigkey : NULL, + FIND_TIMEOUT * 20, FIND_TIMEOUT, 3, + global_task, recvsoa, reqinfo, request); + check_result(result, "dns_request_createvia"); + requests++; +} + +static void +start_update(void) { + isc_result_t result; + dns_rdataset_t *rdataset = NULL; + dns_name_t *name = NULL; + dns_request_t *request = NULL; + dns_message_t *soaquery = NULL; + dns_name_t *firstname; + dns_section_t section = DNS_SECTION_UPDATE; + + ddebug("start_update()"); + + if (answer != NULL) + dns_message_destroy(&answer); + + if (userzone != NULL && userserver != NULL) { + send_update(userzone, userserver, localaddr); + setzoneclass(dns_rdataclass_none); + return; + } + + result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, + &soaquery); + check_result(result, "dns_message_create"); + + if (userserver == NULL) + soaquery->flags |= DNS_MESSAGEFLAG_RD; + + result = dns_message_gettempname(soaquery, &name); + check_result(result, "dns_message_gettempname"); + + result = dns_message_gettemprdataset(soaquery, &rdataset); + check_result(result, "dns_message_gettemprdataset"); + + dns_rdataset_makequestion(rdataset, getzoneclass(), dns_rdatatype_soa); + + if (userzone != NULL) { + dns_name_init(name, NULL); + dns_name_clone(userzone, name); + } else { + result = dns_message_firstname(updatemsg, section); + if (result == ISC_R_NOMORE) { + section = DNS_SECTION_PREREQUISITE; + result = dns_message_firstname(updatemsg, section); + } + if (result != ISC_R_SUCCESS) { + dns_message_puttempname(soaquery, &name); + dns_rdataset_disassociate(rdataset); + dns_message_puttemprdataset(soaquery, &rdataset); + dns_message_destroy(&soaquery); + done_update(); + return; + } + firstname = NULL; + dns_message_currentname(updatemsg, section, &firstname); + dns_name_init(name, NULL); + dns_name_clone(firstname, name); + } + + ISC_LIST_INIT(name->list); + ISC_LIST_APPEND(name->list, rdataset, link); + dns_message_addname(soaquery, name, DNS_SECTION_QUESTION); + + if (userserver != NULL) + sendrequest(localaddr, userserver, soaquery, &request); + else { + ns_inuse = 0; + sendrequest(localaddr, &servers[ns_inuse], soaquery, &request); + } +} + +static void +cleanup(void) { + ddebug("cleanup()"); + + if (answer != NULL) + dns_message_destroy(&answer); + ddebug("Shutting down task manager"); + isc_taskmgr_destroy(&taskmgr); + + ddebug("Destroying event"); + isc_event_free(&global_event); + + ddebug("Shutting down socket manager"); + isc_socketmgr_destroy(&socketmgr); + + ddebug("Shutting down timer manager"); + isc_timermgr_destroy(&timermgr); + + ddebug("Destroying hash context"); + isc_hash_destroy(); + + ddebug("Destroying name state"); + dns_name_destroy(); + + ddebug("Destroying memory context"); + if (memdebugging) + isc_mem_stats(mctx, stderr); + isc_mem_destroy(&mctx); +} + +static void +getinput(isc_task_t *task, isc_event_t *event) { + isc_boolean_t more; + + UNUSED(task); + + if (shuttingdown) { + maybeshutdown(); + return; + } + + if (global_event == NULL) + global_event = event; + + reset_system(); + more = user_interaction(); + if (!more) { + isc_app_shutdown(); + return; + } + start_update(); + return; +} + +int +main(int argc, char **argv) { + isc_result_t result; + style = &dns_master_style_debug; + + input = stdin; + + interactive = ISC_TF(isatty(0)); + + isc_app_start(); + + parse_args(argc, argv); + + setup_system(); + + result = isc_app_onrun(mctx, global_task, getinput, NULL); + check_result(result, "isc_app_onrun"); + + (void)isc_app_run(); + + cleanup(); + + isc_app_finish(); + + if (seenerror) + return (2); + else + return (0); +} diff --git a/bin/nsupdate/nsupdate.docbook b/bin/nsupdate/nsupdate.docbook new file mode 100644 index 0000000..0ea4906 --- /dev/null +++ b/bin/nsupdate/nsupdate.docbook @@ -0,0 +1,657 @@ +]> + + + + + + Jun 30, 2000 + + + nsupdate + 8 + BIND9 + + + nsupdate + Dynamic DNS update utility + + + + + 2004 + 2005 + 2006 + 2007 + Internet Systems Consortium, Inc. ("ISC") + + + 2000 + 2001 + 2002 + 2003 + Internet Software Consortium. + + + + + + nsupdate + + + + + + + + + + filename + + + + + DESCRIPTION + nsupdate + is used to submit Dynamic DNS Update requests as defined in RFC2136 + to a name server. + This allows resource records to be added or removed from a zone + without manually editing the zone file. + A single update request can contain requests to add or remove more than + one + resource record. + + + Zones that are under dynamic control via + nsupdate + or a DHCP server should not be edited by hand. + Manual edits could + conflict with dynamic updates and cause data to be lost. + + + The resource records that are dynamically added or removed with + nsupdate + have to be in the same zone. + Requests are sent to the zone's master server. + This is identified by the MNAME field of the zone's SOA record. + + + The + + option makes + nsupdate + operate in debug mode. + This provides tracing information about the update requests that are + made and the replies received from the name server. + + + Transaction signatures can be used to authenticate the Dynamic DNS + updates. + These use the TSIG resource record type described in RFC2845 or the + SIG(0) record described in RFC3535 and RFC2931. + TSIG relies on a shared secret that should only be known to + nsupdate and the name server. + Currently, the only supported encryption algorithm for TSIG is + HMAC-MD5, which is defined in RFC 2104. + Once other algorithms are defined for TSIG, applications will need to + ensure they select the appropriate algorithm as well as the key when + authenticating each other. + For instance, suitable + key + and + server + statements would be added to + /etc/named.conf + so that the name server can associate the appropriate secret key + and algorithm with the IP address of the + client application that will be using TSIG authentication. + SIG(0) uses public key cryptography. To use a SIG(0) key, the public + key must be stored in a KEY record in a zone served by the name server. + nsupdate + does not read + /etc/named.conf. + + nsupdate + uses the or option + to provide the shared secret needed to generate a TSIG record + for authenticating Dynamic DNS update requests, default type + HMAC-MD5. These options are mutually exclusive. With the + option, nsupdate reads + the shared secret from the file keyfile, + whose name is of the form + K{name}.+157.+{random}.private. For + historical reasons, the file + K{name}.+157.+{random}.key must also be + present. When the option is used, a + signature is generated from + hmac:keyname:secret. + keyname is the name of the key, and + secret is the base64 encoded shared + secret. Use of the option is discouraged + because the shared secret is supplied as a command line + argument in clear text. This may be visible in the output + from + + ps1 + or in a history file maintained by the user's + shell. + + + The may also be used to specify a SIG(0) key used + to authenticate Dynamic DNS update requests. In this case, the key + specified is not an HMAC-MD5 key. + + + By default + nsupdate + uses UDP to send update requests to the name server unless they are too + large to fit in a UDP request in which case TCP will be used. + The + + option makes + nsupdate + use a TCP connection. + This may be preferable when a batch of update requests is made. + + + The option sets the maximum time an update request + can + take before it is aborted. The default is 300 seconds. Zero can be + used + to disable the timeout. + + + The option sets the UDP retry interval. The default + is + 3 seconds. If zero, the interval will be computed from the timeout + interval + and number of UDP retries. + + + The option sets the number of UDP retries. The + default is + 3. If zero, only one update request will be made. + + + + + INPUT FORMAT + nsupdate + reads input from + filename + or standard input. + Each command is supplied on exactly one line of input. + Some commands are for administrative purposes. + The others are either update instructions or prerequisite checks on the + contents of the zone. + These checks set conditions that some name or set of + resource records (RRset) either exists or is absent from the zone. + These conditions must be met if the entire update request is to succeed. + Updates will be rejected if the tests for the prerequisite conditions + fail. + + + Every update request consists of zero or more prerequisites + and zero or more updates. + This allows a suitably authenticated update request to proceed if some + specified resource records are present or missing from the zone. + A blank input line (or the send command) + causes the + accumulated commands to be sent as one Dynamic DNS update request to the + name server. + + + The command formats and their meaning are as follows: + + + + + server + servername + port + + + + Sends all dynamic update requests to the name server + servername. + When no server statement is provided, + nsupdate + will send updates to the master server of the correct zone. + The MNAME field of that zone's SOA record will identify the + master + server for that zone. + port + is the port number on + servername + where the dynamic update requests get sent. + If no port number is specified, the default DNS port number of + 53 is + used. + + + + + + + local + address + port + + + + Sends all dynamic update requests using the local + address. + + When no local statement is provided, + nsupdate + will send updates using an address and port chosen by the + system. + port + can additionally be used to make requests come from a specific + port. + If no port number is specified, the system will assign one. + + + + + + + zone + zonename + + + + Specifies that all updates are to be made to the zone + zonename. + If no + zone + statement is provided, + nsupdate + will attempt determine the correct zone to update based on the + rest of the input. + + + + + + + class + classname + + + + Specify the default class. + If no class is specified, the + default class is + IN. + + + + + + + key + name + secret + + + + Specifies that all updates are to be TSIG-signed using the + keyname keysecret pair. + The key command + overrides any key specified on the command line via + or . + + + + + + + prereq nxdomain + domain-name + + + + Requires that no resource record of any type exists with name + domain-name. + + + + + + + + prereq yxdomain + domain-name + + + + Requires that + domain-name + exists (has as at least one resource record, of any type). + + + + + + + prereq nxrrset + domain-name + class + type + + + + Requires that no resource record exists of the specified + type, + class + and + domain-name. + If + class + is omitted, IN (internet) is assumed. + + + + + + + + prereq yxrrset + domain-name + class + type + + + + This requires that a resource record of the specified + type, + class + and + domain-name + must exist. + If + class + is omitted, IN (internet) is assumed. + + + + + + + prereq yxrrset + domain-name + class + type + data + + + + The + data + from each set of prerequisites of this form + sharing a common + type, + class, + and + domain-name + are combined to form a set of RRs. This set of RRs must + exactly match the set of RRs existing in the zone at the + given + type, + class, + and + domain-name. + The + data + are written in the standard text representation of the resource + record's + RDATA. + + + + + + + update delete + domain-name + ttl + class + type data + + + + Deletes any resource records named + domain-name. + If + type + and + data + is provided, only matching resource records will be removed. + The internet class is assumed if + class + is not supplied. The + ttl + is ignored, and is only allowed for compatibility. + + + + + + + update add + domain-name + ttl + class + type + data + + + + Adds a new resource record with the specified + ttl, + class + and + data. + + + + + + + show + + + + Displays the current message, containing all of the + prerequisites and + updates specified since the last send. + + + + + + + send + + + + Sends the current message. This is equivalent to entering a + blank line. + + + + + + + answer + + + + Displays the answer. + + + + + + + + + Lines beginning with a semicolon are comments and are ignored. + + + + + + EXAMPLES + + The examples below show how + nsupdate + could be used to insert and delete resource records from the + example.com + zone. + Notice that the input in each example contains a trailing blank line so + that + a group of commands are sent as one dynamic update request to the + master name server for + example.com. + + +# nsupdate +> update delete oldhost.example.com A +> update add newhost.example.com 86400 A 172.16.1.1 +> send + + + + Any A records for + oldhost.example.com + are deleted. + And an A record for + newhost.example.com + with IP address 172.16.1.1 is added. + The newly-added record has a 1 day TTL (86400 seconds). + +# nsupdate +> prereq nxdomain nickname.example.com +> update add nickname.example.com 86400 CNAME somehost.example.com +> send + + + + The prerequisite condition gets the name server to check that there + are no resource records of any type for + nickname.example.com. + + If there are, the update request fails. + If this name does not exist, a CNAME for it is added. + This ensures that when the CNAME is added, it cannot conflict with the + long-standing rule in RFC1034 that a name must not exist as any other + record type if it exists as a CNAME. + (The rule has been updated for DNSSEC in RFC2535 to allow CNAMEs to have + RRSIG, DNSKEY and NSEC records.) + + + + + FILES + + + + /etc/resolv.conf + + + used to identify default name server + + + + + + K{name}.+157.+{random}.key + + + base-64 encoding of HMAC-MD5 key created by + + dnssec-keygen8 + . + + + + + + K{name}.+157.+{random}.private + + + base-64 encoding of HMAC-MD5 key created by + + dnssec-keygen8 + . + + + + + + + + + SEE ALSO + + RFC2136 + , + + RFC3007 + , + + RFC2104 + , + + RFC2845 + , + + RFC1034 + , + + RFC2535 + , + + RFC2931 + , + + named8 + , + + dnssec-keygen8 + . + + + + + BUGS + + The TSIG key is redundantly stored in two separate files. + This is a consequence of nsupdate using the DST library + for its cryptographic operations, and may change in future + releases. + + + diff --git a/bin/nsupdate/nsupdate.html b/bin/nsupdate/nsupdate.html new file mode 100644 index 0000000..d11b57e --- /dev/null +++ b/bin/nsupdate/nsupdate.html @@ -0,0 +1,500 @@ + + + + + +nsupdate + + +
+
+
+

Name

+

nsupdate — Dynamic DNS update utility

+
+
+

Synopsis

+

nsupdate [-d] [[-y [hmac:]keyname:secret] | [-k keyfile]] [-t timeout] [-u udptimeout] [-r udpretries] [-v] [filename]

+
+
+

DESCRIPTION

+

nsupdate + is used to submit Dynamic DNS Update requests as defined in RFC2136 + to a name server. + This allows resource records to be added or removed from a zone + without manually editing the zone file. + A single update request can contain requests to add or remove more than + one + resource record. +

+

+ Zones that are under dynamic control via + nsupdate + or a DHCP server should not be edited by hand. + Manual edits could + conflict with dynamic updates and cause data to be lost. +

+

+ The resource records that are dynamically added or removed with + nsupdate + have to be in the same zone. + Requests are sent to the zone's master server. + This is identified by the MNAME field of the zone's SOA record. +

+

+ The + -d + option makes + nsupdate + operate in debug mode. + This provides tracing information about the update requests that are + made and the replies received from the name server. +

+

+ Transaction signatures can be used to authenticate the Dynamic DNS + updates. + These use the TSIG resource record type described in RFC2845 or the + SIG(0) record described in RFC3535 and RFC2931. + TSIG relies on a shared secret that should only be known to + nsupdate and the name server. + Currently, the only supported encryption algorithm for TSIG is + HMAC-MD5, which is defined in RFC 2104. + Once other algorithms are defined for TSIG, applications will need to + ensure they select the appropriate algorithm as well as the key when + authenticating each other. + For instance, suitable + key + and + server + statements would be added to + /etc/named.conf + so that the name server can associate the appropriate secret key + and algorithm with the IP address of the + client application that will be using TSIG authentication. + SIG(0) uses public key cryptography. To use a SIG(0) key, the public + key must be stored in a KEY record in a zone served by the name server. + nsupdate + does not read + /etc/named.conf. +

+

nsupdate + uses the -y or -k option + to provide the shared secret needed to generate a TSIG record + for authenticating Dynamic DNS update requests, default type + HMAC-MD5. These options are mutually exclusive. With the + -k option, nsupdate reads + the shared secret from the file keyfile, + whose name is of the form + K{name}.+157.+{random}.private. For + historical reasons, the file + K{name}.+157.+{random}.key must also be + present. When the -y option is used, a + signature is generated from + [hmac:]keyname:secret. + keyname is the name of the key, and + secret is the base64 encoded shared + secret. Use of the -y option is discouraged + because the shared secret is supplied as a command line + argument in clear text. This may be visible in the output + from + ps(1) or in a history file maintained by the user's + shell. +

+

+ The -k may also be used to specify a SIG(0) key used + to authenticate Dynamic DNS update requests. In this case, the key + specified is not an HMAC-MD5 key. +

+

+ By default + nsupdate + uses UDP to send update requests to the name server unless they are too + large to fit in a UDP request in which case TCP will be used. + The + -v + option makes + nsupdate + use a TCP connection. + This may be preferable when a batch of update requests is made. +

+

+ The -t option sets the maximum time an update request + can + take before it is aborted. The default is 300 seconds. Zero can be + used + to disable the timeout. +

+

+ The -u option sets the UDP retry interval. The default + is + 3 seconds. If zero, the interval will be computed from the timeout + interval + and number of UDP retries. +

+

+ The -r option sets the number of UDP retries. The + default is + 3. If zero, only one update request will be made. +

+
+
+

INPUT FORMAT

+

nsupdate + reads input from + filename + or standard input. + Each command is supplied on exactly one line of input. + Some commands are for administrative purposes. + The others are either update instructions or prerequisite checks on the + contents of the zone. + These checks set conditions that some name or set of + resource records (RRset) either exists or is absent from the zone. + These conditions must be met if the entire update request is to succeed. + Updates will be rejected if the tests for the prerequisite conditions + fail. +

+

+ Every update request consists of zero or more prerequisites + and zero or more updates. + This allows a suitably authenticated update request to proceed if some + specified resource records are present or missing from the zone. + A blank input line (or the send command) + causes the + accumulated commands to be sent as one Dynamic DNS update request to the + name server. +

+

+ The command formats and their meaning are as follows: +

+
+
+ server + {servername} + [port] +
+

+ Sends all dynamic update requests to the name server + servername. + When no server statement is provided, + nsupdate + will send updates to the master server of the correct zone. + The MNAME field of that zone's SOA record will identify the + master + server for that zone. + port + is the port number on + servername + where the dynamic update requests get sent. + If no port number is specified, the default DNS port number of + 53 is + used. +

+
+ local + {address} + [port] +
+

+ Sends all dynamic update requests using the local + address. + + When no local statement is provided, + nsupdate + will send updates using an address and port chosen by the + system. + port + can additionally be used to make requests come from a specific + port. + If no port number is specified, the system will assign one. +

+
+ zone + {zonename} +
+

+ Specifies that all updates are to be made to the zone + zonename. + If no + zone + statement is provided, + nsupdate + will attempt determine the correct zone to update based on the + rest of the input. +

+
+ class + {classname} +
+

+ Specify the default class. + If no class is specified, the + default class is + IN. +

+
+ key + {name} + {secret} +
+

+ Specifies that all updates are to be TSIG-signed using the + keyname keysecret pair. + The key command + overrides any key specified on the command line via + -y or -k. +

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

+ Requires that no resource record of any type exists with name + domain-name. +

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

+ Requires that + domain-name + exists (has as at least one resource record, of any type). +

+
+ prereq nxrrset + {domain-name} + [class] + {type} +
+

+ Requires that no resource record exists of the specified + type, + class + and + domain-name. + If + class + is omitted, IN (internet) is assumed. +

+
+ prereq yxrrset + {domain-name} + [class] + {type} +
+

+ This requires that a resource record of the specified + type, + class + and + domain-name + must exist. + If + class + is omitted, IN (internet) is assumed. +

+
+ prereq yxrrset + {domain-name} + [class] + {type} + {data...} +
+

+ The + data + from each set of prerequisites of this form + sharing a common + type, + class, + and + domain-name + are combined to form a set of RRs. This set of RRs must + exactly match the set of RRs existing in the zone at the + given + type, + class, + and + domain-name. + The + data + are written in the standard text representation of the resource + record's + RDATA. +

+
+ update delete + {domain-name} + [ttl] + [class] + [type [data...]] +
+

+ Deletes any resource records named + domain-name. + If + type + and + data + is provided, only matching resource records will be removed. + The internet class is assumed if + class + is not supplied. The + ttl + is ignored, and is only allowed for compatibility. +

+
+ update add + {domain-name} + {ttl} + [class] + {type} + {data...} +
+

+ Adds a new resource record with the specified + ttl, + class + and + data. +

+
+ show +
+

+ Displays the current message, containing all of the + prerequisites and + updates specified since the last send. +

+
+ send +
+

+ Sends the current message. This is equivalent to entering a + blank line. +

+
+ answer +
+

+ Displays the answer. +

+
+

+

+

+ Lines beginning with a semicolon are comments and are ignored. +

+
+
+

EXAMPLES

+

+ The examples below show how + nsupdate + could be used to insert and delete resource records from the + example.com + zone. + Notice that the input in each example contains a trailing blank line so + that + a group of commands are sent as one dynamic update request to the + master name server for + example.com. + +

+
+# nsupdate
+> update delete oldhost.example.com A
+> update add newhost.example.com 86400 A 172.16.1.1
+> send
+
+

+

+

+ Any A records for + oldhost.example.com + are deleted. + And an A record for + newhost.example.com + with IP address 172.16.1.1 is added. + The newly-added record has a 1 day TTL (86400 seconds). +

+
+# nsupdate
+> prereq nxdomain nickname.example.com
+> update add nickname.example.com 86400 CNAME somehost.example.com
+> send
+
+

+

+

+ The prerequisite condition gets the name server to check that there + are no resource records of any type for + nickname.example.com. + + If there are, the update request fails. + If this name does not exist, a CNAME for it is added. + This ensures that when the CNAME is added, it cannot conflict with the + long-standing rule in RFC1034 that a name must not exist as any other + record type if it exists as a CNAME. + (The rule has been updated for DNSSEC in RFC2535 to allow CNAMEs to have + RRSIG, DNSKEY and NSEC records.) +

+
+
+

FILES

+
+
/etc/resolv.conf
+

+ used to identify default name server +

+
K{name}.+157.+{random}.key
+

+ base-64 encoding of HMAC-MD5 key created by + dnssec-keygen(8). +

+
K{name}.+157.+{random}.private
+

+ base-64 encoding of HMAC-MD5 key created by + dnssec-keygen(8). +

+
+
+
+

SEE ALSO

+

RFC2136, + RFC3007, + RFC2104, + RFC2845, + RFC1034, + RFC2535, + RFC2931, + named(8), + dnssec-keygen(8). +

+
+
+

BUGS

+

+ The TSIG key is redundantly stored in two separate files. + This is a consequence of nsupdate using the DST library + for its cryptographic operations, and may change in future + releases. +

+
+
+ diff --git a/bin/rndc/Makefile.in b/bin/rndc/Makefile.in new file mode 100644 index 0000000..3bc72b1 --- /dev/null +++ b/bin/rndc/Makefile.in @@ -0,0 +1,104 @@ +# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2000-2002 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: Makefile.in,v 1.40.18.4 2007/08/28 07:20:01 tbox Exp $ + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +@BIND9_VERSION@ + +@BIND9_MAKE_INCLUDES@ + +CINCLUDES = -I${srcdir}/include ${ISC_INCLUDES} ${ISCCC_INCLUDES} \ + ${ISCCFG_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} + +CDEFINES = +CWARNINGS = + +ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ +ISCCCLIBS = ../../lib/isccc/libisccc.@A@ +ISCLIBS = ../../lib/isc/libisc.@A@ +DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ +BIND9LIBS = ../../lib/bind9/libbind9.@A@ + +ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ +ISCCCDEPLIBS = ../../lib/isccc/libisccc.@A@ +ISCDEPLIBS = ../../lib/isc/libisc.@A@ +DNSDEPLIBS = ../../lib/dns/libdns.@A@ +BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ + +RNDCLIBS = ${ISCCFGLIBS} ${ISCCCLIBS} ${BIND9LIBS} ${DNSLIBS} ${ISCLIBS} @LIBS@ +RNDCDEPLIBS = ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${BIND9DEPLIBS} ${DNSDEPLIBS} ${ISCDEPLIBS} + +CONFLIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@ +CONFDEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS} + +SRCS= rndc.c rndc-confgen.c + +SUBDIRS = unix + +TARGETS = rndc@EXEEXT@ rndc-confgen@EXEEXT@ + +MANPAGES = rndc.8 rndc-confgen.8 rndc.conf.5 + +HTMLPAGES = rndc.html rndc-confgen.html rndc.conf.html + +MANOBJS = ${MANPAGES} ${HTMLPAGES} + +UOBJS = unix/os.@O@ + +@BIND9_MAKE_RULES@ + +rndc.@O@: rndc.c + ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ + -DVERSION=\"${VERSION}\" \ + -DRNDC_CONFFILE=\"${sysconfdir}/rndc.conf\" \ + -DRNDC_KEYFILE=\"${sysconfdir}/rndc.key\" \ + -c ${srcdir}/rndc.c + +rndc-confgen.@O@: rndc-confgen.c + ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ + -DRNDC_KEYFILE=\"${sysconfdir}/rndc.key\" \ + -c ${srcdir}/rndc-confgen.c + +rndc@EXEEXT@: rndc.@O@ util.@O@ ${RNDCDEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ rndc.@O@ util.@O@ \ + ${RNDCLIBS} + +rndc-confgen@EXEEXT@: rndc-confgen.@O@ util.@O@ ${UOBJS} ${CONFDEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ rndc-confgen.@O@ util.@O@ \ + ${UOBJS} ${CONFLIBS} + +doc man:: ${MANOBJS} + +docclean manclean maintainer-clean:: + rm -f ${MANOBJS} + +installdirs: + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man5 + +install:: rndc@EXEEXT@ rndc-confgen@EXEEXT@ installdirs + ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} rndc@EXEEXT@ ${DESTDIR}${sbindir} + ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} rndc-confgen@EXEEXT@ ${DESTDIR}${sbindir} + ${INSTALL_DATA} ${srcdir}/rndc.8 ${DESTDIR}${mandir}/man8 + ${INSTALL_DATA} ${srcdir}/rndc-confgen.8 ${DESTDIR}${mandir}/man8 + ${INSTALL_DATA} ${srcdir}/rndc.conf.5 ${DESTDIR}${mandir}/man5 + +clean distclean maintainer-clean:: + rm -f ${TARGETS} diff --git a/bin/rndc/include/rndc/os.h b/bin/rndc/include/rndc/os.h new file mode 100644 index 0000000..b5c1d24 --- /dev/null +++ b/bin/rndc/include/rndc/os.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: os.h,v 1.5.18.2 2005/04/29 00:15:41 marka Exp $ */ + +/*! \file */ + +#ifndef RNDC_OS_H +#define RNDC_OS_H 1 + +#include +#include + +ISC_LANG_BEGINDECLS + +FILE *safe_create(const char *filename); +/*%< + * Open 'filename' for writing, truncate if necessary. If the file was + * created ensure that only the owner can read/write it. + */ + +int set_user(FILE *fd, const char *user); +/*%< + * Set the owner of the file refernced by 'fd' to 'user'. + * Returns: + * 0 success + * -1 insufficient permissions, or 'user' does not exist. + */ + +ISC_LANG_ENDDECLS + +#endif diff --git a/bin/rndc/rndc-confgen.8 b/bin/rndc/rndc-confgen.8 new file mode 100644 index 0000000..fe25a7b --- /dev/null +++ b/bin/rndc/rndc-confgen.8 @@ -0,0 +1,211 @@ +.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2001, 2003 Internet Software Consortium. +.\" +.\" Permission to use, copy, modify, and 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: rndc-confgen.8,v 1.9.18.11 2007/01/30 00:23:44 marka Exp $ +.\" +.hy 0 +.ad l +.\" Title: rndc\-confgen +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.71.1 +.\" Date: Aug 27, 2001 +.\" Manual: BIND9 +.\" Source: BIND9 +.\" +.TH "RNDC\-CONFGEN" "8" "Aug 27, 2001" "BIND9" "BIND9" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +rndc\-confgen \- rndc key generation tool +.SH "SYNOPSIS" +.HP 13 +\fBrndc\-confgen\fR [\fB\-a\fR] [\fB\-b\ \fR\fB\fIkeysize\fR\fR] [\fB\-c\ \fR\fB\fIkeyfile\fR\fR] [\fB\-h\fR] [\fB\-k\ \fR\fB\fIkeyname\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-r\ \fR\fB\fIrandomfile\fR\fR] [\fB\-s\ \fR\fB\fIaddress\fR\fR] [\fB\-t\ \fR\fB\fIchrootdir\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] +.SH "DESCRIPTION" +.PP +\fBrndc\-confgen\fR +generates configuration files for +\fBrndc\fR. It can be used as a convenient alternative to writing the +\fIrndc.conf\fR +file and the corresponding +\fBcontrols\fR +and +\fBkey\fR +statements in +\fInamed.conf\fR +by hand. Alternatively, it can be run with the +\fB\-a\fR +option to set up a +\fIrndc.key\fR +file and avoid the need for a +\fIrndc.conf\fR +file and a +\fBcontrols\fR +statement altogether. +.SH "OPTIONS" +.PP +\-a +.RS 4 +Do automatic +\fBrndc\fR +configuration. This creates a file +\fIrndc.key\fR +in +\fI/etc\fR +(or whatever +\fIsysconfdir\fR +was specified as when +BIND +was built) that is read by both +\fBrndc\fR +and +\fBnamed\fR +on startup. The +\fIrndc.key\fR +file defines a default command channel and authentication key allowing +\fBrndc\fR +to communicate with +\fBnamed\fR +on the local host with no further configuration. +.sp +Running +\fBrndc\-confgen \-a\fR +allows BIND 9 and +\fBrndc\fR +to be used as drop\-in replacements for BIND 8 and +\fBndc\fR, with no changes to the existing BIND 8 +\fInamed.conf\fR +file. +.sp +If a more elaborate configuration than that generated by +\fBrndc\-confgen \-a\fR +is required, for example if rndc is to be used remotely, you should run +\fBrndc\-confgen\fR +without the +\fB\-a\fR +option and set up a +\fIrndc.conf\fR +and +\fInamed.conf\fR +as directed. +.RE +.PP +\-b \fIkeysize\fR +.RS 4 +Specifies the size of the authentication key in bits. Must be between 1 and 512 bits; the default is 128. +.RE +.PP +\-c \fIkeyfile\fR +.RS 4 +Used with the +\fB\-a\fR +option to specify an alternate location for +\fIrndc.key\fR. +.RE +.PP +\-h +.RS 4 +Prints a short summary of the options and arguments to +\fBrndc\-confgen\fR. +.RE +.PP +\-k \fIkeyname\fR +.RS 4 +Specifies the key name of the rndc authentication key. This must be a valid domain name. The default is +\fBrndc\-key\fR. +.RE +.PP +\-p \fIport\fR +.RS 4 +Specifies the command channel port where +\fBnamed\fR +listens for connections from +\fBrndc\fR. The default is 953. +.RE +.PP +\-r \fIrandomfile\fR +.RS 4 +Specifies a source of random data for generating the authorization. If the operating system does not provide a +\fI/dev/random\fR +or equivalent device, the default source of randomness is keyboard input. +\fIrandomdev\fR +specifies the name of a character device or file containing random data to be used instead of the default. The special value +\fIkeyboard\fR +indicates that keyboard input should be used. +.RE +.PP +\-s \fIaddress\fR +.RS 4 +Specifies the IP address where +\fBnamed\fR +listens for command channel connections from +\fBrndc\fR. The default is the loopback address 127.0.0.1. +.RE +.PP +\-t \fIchrootdir\fR +.RS 4 +Used with the +\fB\-a\fR +option to specify a directory where +\fBnamed\fR +will run chrooted. An additional copy of the +\fIrndc.key\fR +will be written relative to this directory so that it will be found by the chrooted +\fBnamed\fR. +.RE +.PP +\-u \fIuser\fR +.RS 4 +Used with the +\fB\-a\fR +option to set the owner of the +\fIrndc.key\fR +file generated. If +\fB\-t\fR +is also specified only the file in the chroot area has its owner changed. +.RE +.SH "EXAMPLES" +.PP +To allow +\fBrndc\fR +to be used with no manual configuration, run +.PP +\fBrndc\-confgen \-a\fR +.PP +To print a sample +\fIrndc.conf\fR +file and corresponding +\fBcontrols\fR +and +\fBkey\fR +statements to be manually inserted into +\fInamed.conf\fR, run +.PP +\fBrndc\-confgen\fR +.SH "SEE ALSO" +.PP +\fBrndc\fR(8), +\fBrndc.conf\fR(5), +\fBnamed\fR(8), +BIND 9 Administrator Reference Manual. +.SH "AUTHOR" +.PP +Internet Systems Consortium +.SH "COPYRIGHT" +Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") +.br +Copyright \(co 2001, 2003 Internet Software Consortium. +.br diff --git a/bin/rndc/rndc-confgen.c b/bin/rndc/rndc-confgen.c new file mode 100644 index 0000000..0764104 --- /dev/null +++ b/bin/rndc/rndc-confgen.c @@ -0,0 +1,335 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2001, 2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: rndc-confgen.c,v 1.18.18.3 2005/04/29 00:15:40 marka Exp $ */ + +/*! \file */ + +/** + * rndc-confgen generates configuration files for rndc. It can be used + * as a convenient alternative to writing the rndc.conf file and the + * corresponding controls and key statements in named.conf by hand. + * Alternatively, it can be run with the -a option to set up a + * rndc.key file and avoid the need for a rndc.conf file and a + * controls statement altogether. + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "util.h" + +#define DEFAULT_KEYLENGTH 128 /*% Bits. */ +#define DEFAULT_KEYNAME "rndc-key" +#define DEFAULT_SERVER "127.0.0.1" +#define DEFAULT_PORT 953 + +static char program[256]; +char *progname; + +isc_boolean_t verbose = ISC_FALSE; + +const char *keyfile, *keydef; + +static void +usage(int status) { + + fprintf(stderr, "\ +Usage:\n\ + %s [-a] [-b bits] [-c keyfile] [-k keyname] [-p port] [-r randomfile] \ +[-s addr] [-t chrootdir] [-u user]\n\ + -a: generate just the key clause and write it to keyfile (%s)\n\ + -b bits: from 1 through 512, default %d; total length of the secret\n\ + -c keyfile: specify an alternate key file (requires -a)\n\ + -k keyname: the name as it will be used in named.conf and rndc.conf\n\ + -p port: the port named will listen on and rndc will connect to\n\ + -r randomfile: a file containing random data\n\ + -s addr: the address to which rndc should connect\n\ + -t chrootdir: write a keyfile in chrootdir as well (requires -a)\n\ + -u user: set the keyfile owner to \"user\" (requires -a)\n", + progname, keydef, DEFAULT_KEYLENGTH); + + exit (status); +} + +/*% + * Write an rndc.key file to 'keyfile'. If 'user' is non-NULL, + * make that user the owner of the file. The key will have + * the name 'keyname' and the secret in the buffer 'secret'. + */ +static void +write_key_file(const char *keyfile, const char *user, + const char *keyname, isc_buffer_t *secret ) +{ + FILE *fd; + + fd = safe_create(keyfile); + if (fd == NULL) + fatal( "unable to create \"%s\"\n", keyfile); + if (user != NULL) { + if (set_user(fd, user) == -1) + fatal("unable to set file owner\n"); + } + fprintf(fd, "key \"%s\" {\n\talgorithm hmac-md5;\n" + "\tsecret \"%.*s\";\n};\n", keyname, + (int)isc_buffer_usedlength(secret), + (char *)isc_buffer_base(secret)); + fflush(fd); + if (ferror(fd)) + fatal("write to %s failed\n", keyfile); + if (fclose(fd)) + fatal("fclose(%s) failed\n", keyfile); + fprintf(stderr, "wrote key file \"%s\"\n", keyfile); +} + +int +main(int argc, char **argv) { + isc_boolean_t show_final_mem = ISC_FALSE; + isc_buffer_t key_rawbuffer; + isc_buffer_t key_txtbuffer; + isc_region_t key_rawregion; + isc_mem_t *mctx = NULL; + isc_entropy_t *ectx = NULL; + isc_entropysource_t *entropy_source = NULL; + isc_result_t result = ISC_R_SUCCESS; + dst_key_t *key = NULL; + const char *keyname = NULL; + const char *randomfile = NULL; + const char *serveraddr = NULL; + char key_rawsecret[64]; + char key_txtsecret[256]; + char *p; + int ch; + int port; + int keysize; + int entropy_flags = 0; + int open_keyboard = ISC_ENTROPY_KEYBOARDMAYBE; + struct in_addr addr4_dummy; + struct in6_addr addr6_dummy; + char *chrootdir = NULL; + char *user = NULL; + isc_boolean_t keyonly = ISC_FALSE; + int len; + + keydef = keyfile = RNDC_KEYFILE; + + result = isc_file_progname(*argv, program, sizeof(program)); + if (result != ISC_R_SUCCESS) + memcpy(program, "rndc-confgen", 13); + progname = program; + + keyname = DEFAULT_KEYNAME; + keysize = DEFAULT_KEYLENGTH; + serveraddr = DEFAULT_SERVER; + port = DEFAULT_PORT; + + while ((ch = isc_commandline_parse(argc, argv, + "ab:c:hk:Mmp:r:s:t:u:Vy")) != -1) { + switch (ch) { + case 'a': + keyonly = ISC_TRUE; + break; + case 'b': + keysize = strtol(isc_commandline_argument, &p, 10); + if (*p != '\0' || keysize < 0) + fatal("-b requires a non-negative number"); + if (keysize < 1 || keysize > 512) + fatal("-b must be in the range 1 through 512"); + break; + case 'c': + keyfile = isc_commandline_argument; + break; + case 'h': + usage(0); + case 'k': + case 'y': /* Compatible with rndc -y. */ + keyname = isc_commandline_argument; + break; + case 'M': + isc_mem_debugging = ISC_MEM_DEBUGTRACE; + break; + + case 'm': + show_final_mem = ISC_TRUE; + break; + case 'p': + port = strtol(isc_commandline_argument, &p, 10); + if (*p != '\0' || port < 0 || port > 65535) + fatal("port '%s' out of range", + isc_commandline_argument); + break; + case 'r': + randomfile = isc_commandline_argument; + break; + case 's': + serveraddr = isc_commandline_argument; + if (inet_pton(AF_INET, serveraddr, &addr4_dummy) != 1 && + inet_pton(AF_INET6, serveraddr, &addr6_dummy) != 1) + fatal("-s should be an IPv4 or IPv6 address"); + break; + case 't': + chrootdir = isc_commandline_argument; + break; + case 'u': + user = isc_commandline_argument; + break; + case 'V': + verbose = ISC_TRUE; + break; + case '?': + usage(1); + break; + default: + fatal("unexpected error parsing command arguments: " + "got %c\n", ch); + break; + } + } + + argc -= isc_commandline_index; + argv += isc_commandline_index; + + if (argc > 0) + usage(1); + + DO("create memory context", isc_mem_create(0, 0, &mctx)); + + DO("create entropy context", isc_entropy_create(mctx, &ectx)); + + if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) { + randomfile = NULL; + open_keyboard = ISC_ENTROPY_KEYBOARDYES; + } + DO("start entropy source", isc_entropy_usebestsource(ectx, + &entropy_source, + randomfile, + open_keyboard)); + + entropy_flags = ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY; + + DO("initialize dst library", dst_lib_init(mctx, ectx, entropy_flags)); + + DO("generate key", dst_key_generate(dns_rootname, DST_ALG_HMACMD5, + keysize, 0, 0, + DNS_KEYPROTO_ANY, + dns_rdataclass_in, mctx, &key)); + + isc_buffer_init(&key_rawbuffer, &key_rawsecret, sizeof(key_rawsecret)); + + DO("dump key to buffer", dst_key_tobuffer(key, &key_rawbuffer)); + + isc_buffer_init(&key_txtbuffer, &key_txtsecret, sizeof(key_txtsecret)); + isc_buffer_usedregion(&key_rawbuffer, &key_rawregion); + + DO("bsse64 encode secret", isc_base64_totext(&key_rawregion, -1, "", + &key_txtbuffer)); + + /* + * Shut down the entropy source now so the "stop typing" message + * does not muck with the output. + */ + if (entropy_source != NULL) + isc_entropy_destroysource(&entropy_source); + + if (key != NULL) + dst_key_free(&key); + + isc_entropy_detach(&ectx); + dst_lib_destroy(); + + if (keyonly) { + write_key_file(keyfile, chrootdir == NULL ? user : NULL, + keyname, &key_txtbuffer); + + if (chrootdir != NULL) { + char *buf; + len = strlen(chrootdir) + strlen(keyfile) + 2; + buf = isc_mem_get(mctx, len); + if (buf == NULL) + fatal("isc_mem_get(%d) failed\n", len); + snprintf(buf, len, "%s%s%s", chrootdir, + (*keyfile != '/') ? "/" : "", keyfile); + + write_key_file(buf, user, keyname, &key_txtbuffer); + isc_mem_put(mctx, buf, len); + } + } else { + printf("\ +# Start of rndc.conf\n\ +key \"%s\" {\n\ + algorithm hmac-md5;\n\ + secret \"%.*s\";\n\ +};\n\ +\n\ +options {\n\ + default-key \"%s\";\n\ + default-server %s;\n\ + default-port %d;\n\ +};\n\ +# End of rndc.conf\n\ +\n\ +# Use with the following in named.conf, adjusting the allow list as needed:\n\ +# key \"%s\" {\n\ +# algorithm hmac-md5;\n\ +# secret \"%.*s\";\n\ +# };\n\ +# \n\ +# controls {\n\ +# inet %s port %d\n\ +# allow { %s; } keys { \"%s\"; };\n\ +# };\n\ +# End of named.conf\n", + keyname, + (int)isc_buffer_usedlength(&key_txtbuffer), + (char *)isc_buffer_base(&key_txtbuffer), + keyname, serveraddr, port, + keyname, + (int)isc_buffer_usedlength(&key_txtbuffer), + (char *)isc_buffer_base(&key_txtbuffer), + serveraddr, port, serveraddr, keyname); + } + + if (show_final_mem) + isc_mem_stats(mctx, stderr); + + isc_mem_destroy(&mctx); + + return (0); +} diff --git a/bin/rndc/rndc-confgen.docbook b/bin/rndc/rndc-confgen.docbook new file mode 100644 index 0000000..c694f4b --- /dev/null +++ b/bin/rndc/rndc-confgen.docbook @@ -0,0 +1,286 @@ +]> + + + + + + Aug 27, 2001 + + + + rndc-confgen + 8 + BIND9 + + + + rndc-confgen + rndc key generation tool + + + + + 2004 + 2005 + 2007 + Internet Systems Consortium, Inc. ("ISC") + + + 2001 + 2003 + Internet Software Consortium. + + + + + + rndc-confgen + + + + + + + + + + + + + + + DESCRIPTION + rndc-confgen + generates configuration files + for rndc. It can be used as a + convenient alternative to writing the + rndc.conf file + and the corresponding controls + and key + statements in named.conf by hand. + Alternatively, it can be run with the -a + option to set up a rndc.key file and + avoid the need for a rndc.conf file + and a controls statement altogether. + + + + + + OPTIONS + + + + -a + + + Do automatic rndc configuration. + This creates a file rndc.key + in /etc (or whatever + sysconfdir + was specified as when BIND was + built) + that is read by both rndc + and named on startup. The + rndc.key file defines a default + command channel and authentication key allowing + rndc to communicate with + named on the local host + with no further configuration. + + + Running rndc-confgen -a allows + BIND 9 and rndc to be used as + drop-in + replacements for BIND 8 and ndc, + with no changes to the existing BIND 8 + named.conf file. + + + If a more elaborate configuration than that + generated by rndc-confgen -a + is required, for example if rndc is to be used remotely, + you should run rndc-confgen without + the + -a option and set up a + rndc.conf and + named.conf + as directed. + + + + + + -b keysize + + + Specifies the size of the authentication key in bits. + Must be between 1 and 512 bits; the default is 128. + + + + + + -c keyfile + + + Used with the -a option to specify + an alternate location for rndc.key. + + + + + + -h + + + Prints a short summary of the options and arguments to + rndc-confgen. + + + + + + -k keyname + + + Specifies the key name of the rndc authentication key. + This must be a valid domain name. + The default is rndc-key. + + + + + + -p port + + + Specifies the command channel port where named + listens for connections from rndc. + The default is 953. + + + + + + -r randomfile + + + Specifies a source of random data for generating the + authorization. If the operating + system does not provide a /dev/random + or equivalent device, the default source of randomness + is keyboard input. randomdev + specifies + the name of a character device or file containing random + data to be used instead of the default. The special value + keyboard indicates that keyboard + input should be used. + + + + + + -s address + + + Specifies the IP address where named + listens for command channel connections from + rndc. The default is the loopback + address 127.0.0.1. + + + + + + -t chrootdir + + + Used with the -a option to specify + a directory where named will run + chrooted. An additional copy of the rndc.key + will be written relative to this directory so that + it will be found by the chrooted named. + + + + + + -u user + + + Used with the -a option to set the + owner + of the rndc.key file generated. + If + -t is also specified only the file + in + the chroot area has its owner changed. + + + + + + + + + EXAMPLES + + To allow rndc to be used with + no manual configuration, run + + rndc-confgen -a + + + To print a sample rndc.conf file and + corresponding controls and key + statements to be manually inserted into named.conf, + run + + rndc-confgen + + + + + SEE ALSO + + rndc8 + , + + rndc.conf5 + , + + named8 + , + BIND 9 Administrator Reference Manual. + + + + + AUTHOR + Internet Systems Consortium + + + + diff --git a/bin/rndc/rndc-confgen.html b/bin/rndc/rndc-confgen.html new file mode 100644 index 0000000..fd40a81 --- /dev/null +++ b/bin/rndc/rndc-confgen.html @@ -0,0 +1,188 @@ + + + + + +rndc-confgen + + +
+
+
+

Name

+

rndc-confgen — rndc key generation tool

+
+
+

Synopsis

+

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

+
+
+

DESCRIPTION

+

rndc-confgen + generates configuration files + for rndc. It can be used as a + convenient alternative to writing the + rndc.conf file + and the corresponding controls + and key + statements in named.conf by hand. + Alternatively, it can be run with the -a + option to set up a rndc.key file and + avoid the need for a rndc.conf file + and a controls statement altogether. +

+
+
+

OPTIONS

+
+
-a
+
+

+ Do automatic rndc configuration. + This creates a file rndc.key + in /etc (or whatever + sysconfdir + was specified as when BIND was + built) + that is read by both rndc + and named on startup. The + rndc.key file defines a default + command channel and authentication key allowing + rndc to communicate with + named on the local host + with no further configuration. +

+

+ Running rndc-confgen -a allows + BIND 9 and rndc to be used as + drop-in + replacements for BIND 8 and ndc, + with no changes to the existing BIND 8 + named.conf file. +

+

+ If a more elaborate configuration than that + generated by rndc-confgen -a + is required, for example if rndc is to be used remotely, + you should run rndc-confgen without + the + -a option and set up a + rndc.conf and + named.conf + as directed. +

+
+
-b keysize
+

+ Specifies the size of the authentication key in bits. + Must be between 1 and 512 bits; the default is 128. +

+
-c keyfile
+

+ Used with the -a option to specify + an alternate location for rndc.key. +

+
-h
+

+ Prints a short summary of the options and arguments to + rndc-confgen. +

+
-k keyname
+

+ Specifies the key name of the rndc authentication key. + This must be a valid domain name. + The default is rndc-key. +

+
-p port
+

+ Specifies the command channel port where named + listens for connections from rndc. + The default is 953. +

+
-r randomfile
+

+ Specifies a source of random data for generating the + authorization. If the operating + system does not provide a /dev/random + or equivalent device, the default source of randomness + is keyboard input. randomdev + specifies + the name of a character device or file containing random + data to be used instead of the default. The special value + keyboard indicates that keyboard + input should be used. +

+
-s address
+

+ Specifies the IP address where named + listens for command channel connections from + rndc. The default is the loopback + address 127.0.0.1. +

+
-t chrootdir
+

+ Used with the -a option to specify + a directory where named will run + chrooted. An additional copy of the rndc.key + will be written relative to this directory so that + it will be found by the chrooted named. +

+
-u user
+

+ Used with the -a option to set the + owner + of the rndc.key file generated. + If + -t is also specified only the file + in + the chroot area has its owner changed. +

+
+
+
+

EXAMPLES

+

+ To allow rndc to be used with + no manual configuration, run +

+

rndc-confgen -a +

+

+ To print a sample rndc.conf file and + corresponding controls and key + statements to be manually inserted into named.conf, + run +

+

rndc-confgen +

+
+
+

SEE ALSO

+

rndc(8), + rndc.conf(5), + named(8), + BIND 9 Administrator Reference Manual. +

+
+
+

AUTHOR

+

Internet Systems Consortium +

+
+
+ diff --git a/bin/rndc/rndc.8 b/bin/rndc/rndc.8 new file mode 100644 index 0000000..14a51b3 --- /dev/null +++ b/bin/rndc/rndc.8 @@ -0,0 +1,147 @@ +.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2000, 2001 Internet Software Consortium. +.\" +.\" Permission to use, copy, modify, and 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: rndc.8,v 1.26.18.15 2007/06/20 02:26:58 marka Exp $ +.\" +.hy 0 +.ad l +.\" Title: rndc +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.71.1 +.\" Date: June 30, 2000 +.\" Manual: BIND9 +.\" Source: BIND9 +.\" +.TH "RNDC" "8" "June 30, 2000" "BIND9" "BIND9" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +rndc \- name server control utility +.SH "SYNOPSIS" +.HP 5 +\fBrndc\fR [\fB\-b\ \fR\fB\fIsource\-address\fR\fR] [\fB\-c\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-k\ \fR\fB\fIkey\-file\fR\fR] [\fB\-s\ \fR\fB\fIserver\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-V\fR] [\fB\-y\ \fR\fB\fIkey_id\fR\fR] {command} +.SH "DESCRIPTION" +.PP +\fBrndc\fR +controls the operation of a name server. It supersedes the +\fBndc\fR +utility that was provided in old BIND releases. If +\fBrndc\fR +is invoked with no command line options or arguments, it prints a short summary of the supported commands and the available options and their arguments. +.PP +\fBrndc\fR +communicates with the name server over a TCP connection, sending commands authenticated with digital signatures. In the current versions of +\fBrndc\fR +and +\fBnamed\fR, the only supported authentication algorithm is HMAC\-MD5, which uses a shared secret on each end of the connection. This provides TSIG\-style authentication for the command request and the name server's response. All commands sent over the channel must be signed by a key_id known to the server. +.PP +\fBrndc\fR +reads a configuration file to determine how to contact the name server and decide what algorithm and key it should use. +.SH "OPTIONS" +.PP +\-b \fIsource\-address\fR +.RS 4 +Use +\fIsource\-address\fR +as the source address for the connection to the server. Multiple instances are permitted to allow setting of both the IPv4 and IPv6 source addresses. +.RE +.PP +\-c \fIconfig\-file\fR +.RS 4 +Use +\fIconfig\-file\fR +as the configuration file instead of the default, +\fI/etc/rndc.conf\fR. +.RE +.PP +\-k \fIkey\-file\fR +.RS 4 +Use +\fIkey\-file\fR +as the key file instead of the default, +\fI/etc/rndc.key\fR. The key in +\fI/etc/rndc.key\fR +will be used to authenticate commands sent to the server if the +\fIconfig\-file\fR +does not exist. +.RE +.PP +\-s \fIserver\fR +.RS 4 +\fIserver\fR +is the name or address of the server which matches a server statement in the configuration file for +\fBrndc\fR. If no server is supplied on the command line, the host named by the default\-server clause in the options statement of the +\fBrndc\fR +configuration file will be used. +.RE +.PP +\-p \fIport\fR +.RS 4 +Send commands to TCP port +\fIport\fR +instead of BIND 9's default control channel port, 953. +.RE +.PP +\-V +.RS 4 +Enable verbose logging. +.RE +.PP +\-y \fIkey_id\fR +.RS 4 +Use the key +\fIkey_id\fR +from the configuration file. +\fIkey_id\fR +must be known by named with the same algorithm and secret string in order for control message validation to succeed. If no +\fIkey_id\fR +is specified, +\fBrndc\fR +will first look for a key clause in the server statement of the server being used, or if no server statement is present for that host, then the default\-key clause of the options statement. Note that the configuration file contains shared secrets which are used to send authenticated control commands to name servers. It should therefore not have general read or write access. +.RE +.PP +For the complete set of commands supported by +\fBrndc\fR, see the BIND 9 Administrator Reference Manual or run +\fBrndc\fR +without arguments to see its help message. +.SH "LIMITATIONS" +.PP +\fBrndc\fR +does not yet support all the commands of the BIND 8 +\fBndc\fR +utility. +.PP +There is currently no way to provide the shared secret for a +\fBkey_id\fR +without using the configuration file. +.PP +Several error messages could be clearer. +.SH "SEE ALSO" +.PP +\fBrndc.conf\fR(5), +\fBnamed\fR(8), +\fBnamed.conf\fR(5), +\fBndc\fR(8), +BIND 9 Administrator Reference Manual. +.SH "AUTHOR" +.PP +Internet Systems Consortium +.SH "COPYRIGHT" +Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") +.br +Copyright \(co 2000, 2001 Internet Software Consortium. +.br diff --git a/bin/rndc/rndc.c b/bin/rndc/rndc.c new file mode 100644 index 0000000..8fd0d8e --- /dev/null +++ b/bin/rndc/rndc.c @@ -0,0 +1,852 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: rndc.c,v 1.96.18.17 2006/08/04 03:03:41 marka Exp $ */ + +/*! \file */ + +/* + * Principal Author: DCL + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "util.h" + +#define SERVERADDRS 10 + +char *progname; +isc_boolean_t verbose; + +static const char *admin_conffile; +static const char *admin_keyfile; +static const char *version = VERSION; +static const char *servername = NULL; +static isc_sockaddr_t serveraddrs[SERVERADDRS]; +static isc_sockaddr_t local4, local6; +static isc_boolean_t local4set = ISC_FALSE, local6set = ISC_FALSE; +static int nserveraddrs; +static int currentaddr = 0; +static unsigned int remoteport = 0; +static isc_socketmgr_t *socketmgr = NULL; +static unsigned char databuf[2048]; +static isccc_ccmsg_t ccmsg; +static isccc_region_t secret; +static isc_boolean_t failed = ISC_FALSE; +static isc_mem_t *mctx; +static int sends, recvs, connects; +static char *command; +static char *args; +static char program[256]; +static isc_socket_t *sock = NULL; +static isc_uint32_t serial; + +static void rndc_startconnect(isc_sockaddr_t *addr, isc_task_t *task); + +static void +usage(int status) { + fprintf(stderr, "\ +Usage: %s [-c config] [-s server] [-p port]\n\ + [-k key-file ] [-y key] [-V] command\n\ +\n\ +command is one of the following:\n\ +\n\ + reload Reload configuration file and zones.\n\ + reload zone [class [view]]\n\ + Reload a single zone.\n\ + refresh zone [class [view]]\n\ + Schedule immediate maintenance for a zone.\n\ + retransfer zone [class [view]]\n\ + Retransfer a single zone without checking serial number.\n\ + freeze Suspend updates to all dynamic zones.\n\ + freeze zone [class [view]]\n\ + Suspend updates to a dynamic zone.\n\ + thaw Enable updates to all dynamic zones and reload them.\n\ + thaw zone [class [view]]\n\ + Enable updates to a frozen dynamic zone and reload it.\n\ + notify zone [class [view]]\n\ + Resend NOTIFY messages for the zone.\n\ + reconfig Reload configuration file and new zones only.\n\ + stats Write server statistics to the statistics file.\n\ + querylog Toggle query logging.\n\ + dumpdb [-all|-cache|-zones] [view ...]\n\ + Dump cache(s) to the dump file (named_dump.db).\n\ + stop Save pending updates to master files and stop the server.\n\ + stop -p Save pending updates to master files and stop the server\n\ + reporting process id.\n\ + halt Stop the server without saving pending updates.\n\ + halt -p Stop the server without saving pending updates reporting\n\ + process id.\n\ + trace Increment debugging level by one.\n\ + trace level Change the debugging level.\n\ + notrace Set debugging level to 0.\n\ + flush Flushes all of the server's caches.\n\ + flush [view] Flushes the server's cache for a view.\n\ + flushname name [view]\n\ + Flush the given name from the server's cache(s)\n\ + status Display status of the server.\n\ + recursing Dump the queries that are currently recursing (named.recursing)\n\ + validation newstate [view]\n\ + Enable / disable DNSSEC validation.\n\ + *restart Restart the server.\n\ +\n\ +* == not yet implemented\n\ +Version: %s\n", + progname, version); + + exit(status); +} + +static void +get_addresses(const char *host, in_port_t port) { + isc_result_t result; + int found = 0, count; + + if (*host == '/') { + result = isc_sockaddr_frompath(&serveraddrs[nserveraddrs], + host); + if (result == ISC_R_SUCCESS) + nserveraddrs++; + } else { + count = SERVERADDRS - nserveraddrs; + result = bind9_getaddresses(host, port, + &serveraddrs[nserveraddrs], + count, &found); + nserveraddrs += found; + } + if (result != ISC_R_SUCCESS) + fatal("couldn't get address for '%s': %s", + host, isc_result_totext(result)); + INSIST(nserveraddrs > 0); +} + +static void +rndc_senddone(isc_task_t *task, isc_event_t *event) { + isc_socketevent_t *sevent = (isc_socketevent_t *)event; + + UNUSED(task); + + sends--; + if (sevent->result != ISC_R_SUCCESS) + fatal("send failed: %s", isc_result_totext(sevent->result)); + isc_event_free(&event); + if (sends == 0 && recvs == 0) { + isc_socket_detach(&sock); + isc_task_shutdown(task); + RUNTIME_CHECK(isc_app_shutdown() == ISC_R_SUCCESS); + } +} + +static void +rndc_recvdone(isc_task_t *task, isc_event_t *event) { + isccc_sexpr_t *response = NULL; + isccc_sexpr_t *data; + isccc_region_t source; + char *errormsg = NULL; + char *textmsg = NULL; + isc_result_t result; + + recvs--; + + if (ccmsg.result == ISC_R_EOF) + fatal("connection to remote host closed\n" + "This may indicate that\n" + "* the remote server is using an older version of" + " the command protocol,\n" + "* this host is not authorized to connect,\n" + "* the clocks are not syncronized, or\n" + "* the key is invalid."); + + if (ccmsg.result != ISC_R_SUCCESS) + fatal("recv failed: %s", isc_result_totext(ccmsg.result)); + + source.rstart = isc_buffer_base(&ccmsg.buffer); + source.rend = isc_buffer_used(&ccmsg.buffer); + + DO("parse message", isccc_cc_fromwire(&source, &response, &secret)); + + data = isccc_alist_lookup(response, "_data"); + if (data == NULL) + fatal("no data section in response"); + result = isccc_cc_lookupstring(data, "err", &errormsg); + if (result == ISC_R_SUCCESS) { + failed = ISC_TRUE; + fprintf(stderr, "%s: '%s' failed: %s\n", + progname, command, errormsg); + } + else if (result != ISC_R_NOTFOUND) + fprintf(stderr, "%s: parsing response failed: %s\n", + progname, isc_result_totext(result)); + + result = isccc_cc_lookupstring(data, "text", &textmsg); + if (result == ISC_R_SUCCESS) + printf("%s\n", textmsg); + else if (result != ISC_R_NOTFOUND) + fprintf(stderr, "%s: parsing response failed: %s\n", + progname, isc_result_totext(result)); + + isc_event_free(&event); + isccc_sexpr_free(&response); + if (sends == 0 && recvs == 0) { + isc_socket_detach(&sock); + isc_task_shutdown(task); + RUNTIME_CHECK(isc_app_shutdown() == ISC_R_SUCCESS); + } +} + +static void +rndc_recvnonce(isc_task_t *task, isc_event_t *event) { + isccc_sexpr_t *response = NULL; + isccc_sexpr_t *_ctrl; + isccc_region_t source; + isc_result_t result; + isc_uint32_t nonce; + isccc_sexpr_t *request = NULL; + isccc_time_t now; + isc_region_t r; + isccc_sexpr_t *data; + isccc_region_t message; + isc_uint32_t len; + isc_buffer_t b; + + recvs--; + + if (ccmsg.result == ISC_R_EOF) + fatal("connection to remote host closed\n" + "This may indicate that\n" + "* the remote server is using an older version of" + " the command protocol,\n" + "* this host is not authorized to connect,\n" + "* the clocks are not syncronized, or\n" + "* the key is invalid."); + + if (ccmsg.result != ISC_R_SUCCESS) + fatal("recv failed: %s", isc_result_totext(ccmsg.result)); + + source.rstart = isc_buffer_base(&ccmsg.buffer); + source.rend = isc_buffer_used(&ccmsg.buffer); + + DO("parse message", isccc_cc_fromwire(&source, &response, &secret)); + + _ctrl = isccc_alist_lookup(response, "_ctrl"); + if (_ctrl == NULL) + fatal("_ctrl section missing"); + nonce = 0; + if (isccc_cc_lookupuint32(_ctrl, "_nonce", &nonce) != ISC_R_SUCCESS) + nonce = 0; + + isc_stdtime_get(&now); + + DO("create message", isccc_cc_createmessage(1, NULL, NULL, ++serial, + now, now + 60, &request)); + data = isccc_alist_lookup(request, "_data"); + if (data == NULL) + fatal("_data section missing"); + if (isccc_cc_definestring(data, "type", args) == NULL) + fatal("out of memory"); + if (nonce != 0) { + _ctrl = isccc_alist_lookup(request, "_ctrl"); + if (_ctrl == NULL) + fatal("_ctrl section missing"); + if (isccc_cc_defineuint32(_ctrl, "_nonce", nonce) == NULL) + fatal("out of memory"); + } + message.rstart = databuf + 4; + message.rend = databuf + sizeof(databuf); + DO("render message", isccc_cc_towire(request, &message, &secret)); + len = sizeof(databuf) - REGION_SIZE(message); + isc_buffer_init(&b, databuf, 4); + isc_buffer_putuint32(&b, len - 4); + r.length = len; + r.base = databuf; + + isccc_ccmsg_cancelread(&ccmsg); + DO("schedule recv", isccc_ccmsg_readmessage(&ccmsg, task, + rndc_recvdone, NULL)); + recvs++; + DO("send message", isc_socket_send(sock, &r, task, rndc_senddone, + NULL)); + sends++; + + isc_event_free(&event); + isccc_sexpr_free(&response); + return; +} + +static void +rndc_connected(isc_task_t *task, isc_event_t *event) { + char socktext[ISC_SOCKADDR_FORMATSIZE]; + isc_socketevent_t *sevent = (isc_socketevent_t *)event; + isccc_sexpr_t *request = NULL; + isccc_sexpr_t *data; + isccc_time_t now; + isccc_region_t message; + isc_region_t r; + isc_uint32_t len; + isc_buffer_t b; + isc_result_t result; + + connects--; + + if (sevent->result != ISC_R_SUCCESS) { + isc_sockaddr_format(&serveraddrs[currentaddr], socktext, + sizeof(socktext)); + if (sevent->result != ISC_R_CANCELED && + ++currentaddr < nserveraddrs) + { + notify("connection failed: %s: %s", socktext, + isc_result_totext(sevent->result)); + isc_socket_detach(&sock); + isc_event_free(&event); + rndc_startconnect(&serveraddrs[currentaddr], task); + return; + } else + fatal("connect failed: %s: %s", socktext, + isc_result_totext(sevent->result)); + } + + isc_stdtime_get(&now); + DO("create message", isccc_cc_createmessage(1, NULL, NULL, ++serial, + now, now + 60, &request)); + data = isccc_alist_lookup(request, "_data"); + if (data == NULL) + fatal("_data section missing"); + if (isccc_cc_definestring(data, "type", "null") == NULL) + fatal("out of memory"); + message.rstart = databuf + 4; + message.rend = databuf + sizeof(databuf); + DO("render message", isccc_cc_towire(request, &message, &secret)); + len = sizeof(databuf) - REGION_SIZE(message); + isc_buffer_init(&b, databuf, 4); + isc_buffer_putuint32(&b, len - 4); + r.length = len; + r.base = databuf; + + isccc_ccmsg_init(mctx, sock, &ccmsg); + isccc_ccmsg_setmaxsize(&ccmsg, 1024); + + DO("schedule recv", isccc_ccmsg_readmessage(&ccmsg, task, + rndc_recvnonce, NULL)); + recvs++; + DO("send message", isc_socket_send(sock, &r, task, rndc_senddone, + NULL)); + sends++; + isc_event_free(&event); +} + +static void +rndc_startconnect(isc_sockaddr_t *addr, isc_task_t *task) { + isc_result_t result; + int pf; + isc_sockettype_t type; + + char socktext[ISC_SOCKADDR_FORMATSIZE]; + + isc_sockaddr_format(addr, socktext, sizeof(socktext)); + + notify("using server %s (%s)", servername, socktext); + + pf = isc_sockaddr_pf(addr); + if (pf == AF_INET || pf == AF_INET6) + type = isc_sockettype_tcp; + else + type = isc_sockettype_unix; + DO("create socket", isc_socket_create(socketmgr, pf, type, &sock)); + switch (isc_sockaddr_pf(addr)) { + case AF_INET: + DO("bind socket", isc_socket_bind(sock, &local4)); + break; + case AF_INET6: + DO("bind socket", isc_socket_bind(sock, &local6)); + break; + default: + break; + } + DO("connect", isc_socket_connect(sock, addr, task, rndc_connected, + NULL)); + connects++; +} + +static void +rndc_start(isc_task_t *task, isc_event_t *event) { + isc_event_free(&event); + + currentaddr = 0; + rndc_startconnect(&serveraddrs[currentaddr], task); +} + +static void +parse_config(isc_mem_t *mctx, isc_log_t *log, const char *keyname, + cfg_parser_t **pctxp, cfg_obj_t **configp) +{ + isc_result_t result; + const char *conffile = admin_conffile; + const cfg_obj_t *addresses = NULL; + const cfg_obj_t *defkey = NULL; + const cfg_obj_t *options = NULL; + const cfg_obj_t *servers = NULL; + const cfg_obj_t *server = NULL; + const cfg_obj_t *keys = NULL; + const cfg_obj_t *key = NULL; + const cfg_obj_t *defport = NULL; + const cfg_obj_t *secretobj = NULL; + const cfg_obj_t *algorithmobj = NULL; + cfg_obj_t *config = NULL; + const cfg_obj_t *address = NULL; + const cfg_listelt_t *elt; + const char *secretstr; + const char *algorithm; + static char secretarray[1024]; + const cfg_type_t *conftype = &cfg_type_rndcconf; + isc_boolean_t key_only = ISC_FALSE; + const cfg_listelt_t *element; + + if (! isc_file_exists(conffile)) { + conffile = admin_keyfile; + conftype = &cfg_type_rndckey; + + if (! isc_file_exists(conffile)) + fatal("neither %s nor %s was found", + admin_conffile, admin_keyfile); + key_only = ISC_TRUE; + } + + DO("create parser", cfg_parser_create(mctx, log, pctxp)); + + /* + * The parser will output its own errors, so DO() is not used. + */ + result = cfg_parse_file(*pctxp, conffile, conftype, &config); + if (result != ISC_R_SUCCESS) + fatal("could not load rndc configuration"); + + if (!key_only) + (void)cfg_map_get(config, "options", &options); + + if (key_only && servername == NULL) + servername = "127.0.0.1"; + else if (servername == NULL && options != NULL) { + const cfg_obj_t *defserverobj = NULL; + (void)cfg_map_get(options, "default-server", &defserverobj); + if (defserverobj != NULL) + servername = cfg_obj_asstring(defserverobj); + } + + if (servername == NULL) + fatal("no server specified and no default"); + + if (!key_only) { + (void)cfg_map_get(config, "server", &servers); + if (servers != NULL) { + for (elt = cfg_list_first(servers); + elt != NULL; + elt = cfg_list_next(elt)) + { + const char *name; + server = cfg_listelt_value(elt); + name = cfg_obj_asstring(cfg_map_getname(server)); + if (strcasecmp(name, servername) == 0) + break; + server = NULL; + } + } + } + + /* + * Look for the name of the key to use. + */ + if (keyname != NULL) + ; /* Was set on command line, do nothing. */ + else if (server != NULL) { + DO("get key for server", cfg_map_get(server, "key", &defkey)); + keyname = cfg_obj_asstring(defkey); + } else if (options != NULL) { + DO("get default key", cfg_map_get(options, "default-key", + &defkey)); + keyname = cfg_obj_asstring(defkey); + } else if (!key_only) + fatal("no key for server and no default"); + + /* + * Get the key's definition. + */ + if (key_only) + DO("get key", cfg_map_get(config, "key", &key)); + else { + DO("get config key list", cfg_map_get(config, "key", &keys)); + for (elt = cfg_list_first(keys); + elt != NULL; + elt = cfg_list_next(elt)) + { + key = cfg_listelt_value(elt); + if (strcasecmp(cfg_obj_asstring(cfg_map_getname(key)), + keyname) == 0) + break; + } + if (elt == NULL) + fatal("no key definition for name %s", keyname); + } + (void)cfg_map_get(key, "secret", &secretobj); + (void)cfg_map_get(key, "algorithm", &algorithmobj); + if (secretobj == NULL || algorithmobj == NULL) + fatal("key must have algorithm and secret"); + + secretstr = cfg_obj_asstring(secretobj); + algorithm = cfg_obj_asstring(algorithmobj); + + if (strcasecmp(algorithm, "hmac-md5") != 0) + fatal("unsupported algorithm: %s", algorithm); + + secret.rstart = (unsigned char *)secretarray; + secret.rend = (unsigned char *)secretarray + sizeof(secretarray); + DO("decode base64 secret", isccc_base64_decode(secretstr, &secret)); + secret.rend = secret.rstart; + secret.rstart = (unsigned char *)secretarray; + + /* + * Find the port to connect to. + */ + if (remoteport != 0) + ; /* Was set on command line, do nothing. */ + else { + if (server != NULL) + (void)cfg_map_get(server, "port", &defport); + if (defport == NULL && options != NULL) + (void)cfg_map_get(options, "default-port", &defport); + } + if (defport != NULL) { + remoteport = cfg_obj_asuint32(defport); + if (remoteport > 65535 || remoteport == 0) + fatal("port %u out of range", remoteport); + } else if (remoteport == 0) + remoteport = NS_CONTROL_PORT; + + if (server != NULL) + result = cfg_map_get(server, "addresses", &addresses); + else + result = ISC_R_NOTFOUND; + if (result == ISC_R_SUCCESS) { + for (element = cfg_list_first(addresses); + element != NULL; + element = cfg_list_next(element)) + { + isc_sockaddr_t sa; + + address = cfg_listelt_value(element); + if (!cfg_obj_issockaddr(address)) { + unsigned int myport; + const char *name; + const cfg_obj_t *obj; + + obj = cfg_tuple_get(address, "name"); + name = cfg_obj_asstring(obj); + obj = cfg_tuple_get(address, "port"); + if (cfg_obj_isuint32(obj)) { + myport = cfg_obj_asuint32(obj); + if (myport > ISC_UINT16_MAX || + myport == 0) + fatal("port %u out of range", + myport); + } else + myport = remoteport; + if (nserveraddrs < SERVERADDRS) + get_addresses(name, (in_port_t) myport); + else + fprintf(stderr, "too many address: " + "%s: dropped\n", name); + continue; + } + sa = *cfg_obj_assockaddr(address); + if (isc_sockaddr_getport(&sa) == 0) + isc_sockaddr_setport(&sa, remoteport); + if (nserveraddrs < SERVERADDRS) + serveraddrs[nserveraddrs++] = sa; + else { + char socktext[ISC_SOCKADDR_FORMATSIZE]; + + isc_sockaddr_format(&sa, socktext, + sizeof(socktext)); + fprintf(stderr, + "too many address: %s: dropped\n", + socktext); + } + } + } + + if (!local4set && server != NULL) { + address = NULL; + cfg_map_get(server, "source-address", &address); + if (address != NULL) { + local4 = *cfg_obj_assockaddr(address); + local4set = ISC_TRUE; + } + } + if (!local4set && options != NULL) { + address = NULL; + cfg_map_get(options, "default-source-address", &address); + if (address != NULL) { + local4 = *cfg_obj_assockaddr(address); + local4set = ISC_TRUE; + } + } + + if (!local6set && server != NULL) { + address = NULL; + cfg_map_get(server, "source-address-v6", &address); + if (address != NULL) { + local6 = *cfg_obj_assockaddr(address); + local6set = ISC_TRUE; + } + } + if (!local6set && options != NULL) { + address = NULL; + cfg_map_get(options, "default-source-address-v6", &address); + if (address != NULL) { + local6 = *cfg_obj_assockaddr(address); + local6set = ISC_TRUE; + } + } + + *configp = config; +} + +int +main(int argc, char **argv) { + isc_boolean_t show_final_mem = ISC_FALSE; + isc_result_t result = ISC_R_SUCCESS; + isc_taskmgr_t *taskmgr = NULL; + isc_task_t *task = NULL; + isc_log_t *log = NULL; + isc_logconfig_t *logconfig = NULL; + isc_logdestination_t logdest; + cfg_parser_t *pctx = NULL; + cfg_obj_t *config = NULL; + const char *keyname = NULL; + struct in_addr in; + struct in6_addr in6; + char *p; + size_t argslen; + int ch; + int i; + + result = isc_file_progname(*argv, program, sizeof(program)); + if (result != ISC_R_SUCCESS) + memcpy(program, "rndc", 5); + progname = program; + + admin_conffile = RNDC_CONFFILE; + admin_keyfile = RNDC_KEYFILE; + + isc_sockaddr_any(&local4); + isc_sockaddr_any6(&local6); + + result = isc_app_start(); + if (result != ISC_R_SUCCESS) + fatal("isc_app_start() failed: %s", isc_result_totext(result)); + + while ((ch = isc_commandline_parse(argc, argv, "b:c:k:Mmp:s:Vy:")) + != -1) { + switch (ch) { + case 'b': + if (inet_pton(AF_INET, isc_commandline_argument, + &in) == 1) { + isc_sockaddr_fromin(&local4, &in, 0); + local4set = ISC_TRUE; + } else if (inet_pton(AF_INET6, isc_commandline_argument, + &in6) == 1) { + isc_sockaddr_fromin6(&local6, &in6, 0); + local6set = ISC_TRUE; + } + break; + + case 'c': + admin_conffile = isc_commandline_argument; + break; + + case 'k': + admin_keyfile = isc_commandline_argument; + break; + + case 'M': + isc_mem_debugging = ISC_MEM_DEBUGTRACE; + break; + + case 'm': + show_final_mem = ISC_TRUE; + break; + + case 'p': + remoteport = atoi(isc_commandline_argument); + if (remoteport > 65535 || remoteport == 0) + fatal("port '%s' out of range", + isc_commandline_argument); + break; + + case 's': + servername = isc_commandline_argument; + break; + + case 'V': + verbose = ISC_TRUE; + break; + + case 'y': + keyname = isc_commandline_argument; + break; + + case '?': + usage(0); + break; + + default: + fatal("unexpected error parsing command arguments: " + "got %c\n", ch); + break; + } + } + + argc -= isc_commandline_index; + argv += isc_commandline_index; + + if (argc < 1) + usage(1); + + isc_random_get(&serial); + + DO("create memory context", isc_mem_create(0, 0, &mctx)); + DO("create socket manager", isc_socketmgr_create(mctx, &socketmgr)); + DO("create task manager", isc_taskmgr_create(mctx, 1, 0, &taskmgr)); + DO("create task", isc_task_create(taskmgr, 0, &task)); + + DO("create logging context", isc_log_create(mctx, &log, &logconfig)); + isc_log_setcontext(log); + DO("setting log tag", isc_log_settag(logconfig, progname)); + logdest.file.stream = stderr; + logdest.file.name = NULL; + logdest.file.versions = ISC_LOG_ROLLNEVER; + logdest.file.maximum_size = 0; + DO("creating log channel", + isc_log_createchannel(logconfig, "stderr", + ISC_LOG_TOFILEDESC, ISC_LOG_INFO, &logdest, + ISC_LOG_PRINTTAG|ISC_LOG_PRINTLEVEL)); + DO("enabling log channel", isc_log_usechannel(logconfig, "stderr", + NULL, NULL)); + + parse_config(mctx, log, keyname, &pctx, &config); + + isccc_result_register(); + + command = *argv; + + /* + * Convert argc/argv into a space-delimited command string + * similar to what the user might enter in interactive mode + * (if that were implemented). + */ + argslen = 0; + for (i = 0; i < argc; i++) + argslen += strlen(argv[i]) + 1; + + args = isc_mem_get(mctx, argslen); + if (args == NULL) + DO("isc_mem_get", ISC_R_NOMEMORY); + + p = args; + for (i = 0; i < argc; i++) { + size_t len = strlen(argv[i]); + memcpy(p, argv[i], len); + p += len; + *p++ = ' '; + } + + p--; + *p++ = '\0'; + INSIST(p == args + argslen); + + notify("%s", command); + + if (strcmp(command, "restart") == 0) + fatal("'%s' is not implemented", command); + + if (nserveraddrs == 0) + get_addresses(servername, (in_port_t) remoteport); + + DO("post event", isc_app_onrun(mctx, task, rndc_start, NULL)); + + result = isc_app_run(); + if (result != ISC_R_SUCCESS) + fatal("isc_app_run() failed: %s", isc_result_totext(result)); + + if (connects > 0 || sends > 0 || recvs > 0) + isc_socket_cancel(sock, task, ISC_SOCKCANCEL_ALL); + + isc_task_detach(&task); + isc_taskmgr_destroy(&taskmgr); + isc_socketmgr_destroy(&socketmgr); + isc_log_destroy(&log); + isc_log_setcontext(NULL); + + cfg_obj_destroy(pctx, &config); + cfg_parser_destroy(&pctx); + + isc_mem_put(mctx, args, argslen); + isccc_ccmsg_invalidate(&ccmsg); + + dns_name_destroy(); + + if (show_final_mem) + isc_mem_stats(mctx, stderr); + + isc_mem_destroy(&mctx); + + if (failed) + return (1); + + return (0); +} diff --git a/bin/rndc/rndc.conf b/bin/rndc/rndc.conf new file mode 100644 index 0000000..e303535 --- /dev/null +++ b/bin/rndc/rndc.conf @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: rndc.conf,v 1.8.18.1 2004/06/18 04:39:39 marka Exp $ */ + +/* + * Sample rndc configuration file. + */ + +options { + default-server localhost; + default-key "key"; +}; + +server localhost { + key "key"; +}; + +key "cc64b3d1db63fc88d7cb5d2f9f57d258" { + algorithm hmac-md5; + secret "34f88008d07deabbe65bd01f1d233d47"; +}; + +server "test1" { + key "cc64b3d1db63fc88d7cb5d2f9f57d258"; + port 5353; + addresses { 10.53.0.1; }; +}; + +key "key" { + algorithm hmac-md5; + secret "c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K"; +}; diff --git a/bin/rndc/rndc.conf.5 b/bin/rndc/rndc.conf.5 new file mode 100644 index 0000000..dbeb707 --- /dev/null +++ b/bin/rndc/rndc.conf.5 @@ -0,0 +1,214 @@ +.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2000, 2001 Internet Software Consortium. +.\" +.\" Permission to use, copy, modify, and 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: rndc.conf.5,v 1.23.18.15 2007/05/09 13:35:47 marka Exp $ +.\" +.hy 0 +.ad l +.\" Title: \fIrndc.conf\fR +.\" Author: +.\" Generator: DocBook XSL Stylesheets v1.71.1 +.\" Date: June 30, 2000 +.\" Manual: BIND9 +.\" Source: BIND9 +.\" +.TH "\fIRNDC.CONF\fR" "5" "June 30, 2000" "BIND9" "BIND9" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +rndc.conf \- rndc configuration file +.SH "SYNOPSIS" +.HP 10 +\fBrndc.conf\fR +.SH "DESCRIPTION" +.PP +\fIrndc.conf\fR +is the configuration file for +\fBrndc\fR, the BIND 9 name server control utility. This file has a similar structure and syntax to +\fInamed.conf\fR. Statements are enclosed in braces and terminated with a semi\-colon. Clauses in the statements are also semi\-colon terminated. The usual comment styles are supported: +.PP +C style: /* */ +.PP +C++ style: // to end of line +.PP +Unix style: # to end of line +.PP +\fIrndc.conf\fR +is much simpler than +\fInamed.conf\fR. The file uses three statements: an options statement, a server statement and a key statement. +.PP +The +\fBoptions\fR +statement contains five clauses. The +\fBdefault\-server\fR +clause is followed by the name or address of a name server. This host will be used when no name server is given as an argument to +\fBrndc\fR. The +\fBdefault\-key\fR +clause is followed by the name of a key which is identified by a +\fBkey\fR +statement. If no +\fBkeyid\fR +is provided on the rndc command line, and no +\fBkey\fR +clause is found in a matching +\fBserver\fR +statement, this default key will be used to authenticate the server's commands and responses. The +\fBdefault\-port\fR +clause is followed by the port to connect to on the remote name server. If no +\fBport\fR +option is provided on the rndc command line, and no +\fBport\fR +clause is found in a matching +\fBserver\fR +statement, this default port will be used to connect. The +\fBdefault\-source\-address\fR +and +\fBdefault\-source\-address\-v6\fR +clauses which can be used to set the IPv4 and IPv6 source addresses respectively. +.PP +After the +\fBserver\fR +keyword, the server statement includes a string which is the hostname or address for a name server. The statement has three possible clauses: +\fBkey\fR, +\fBport\fR +and +\fBaddresses\fR. The key name must match the name of a key statement in the file. The port number specifies the port to connect to. If an +\fBaddresses\fR +clause is supplied these addresses will be used instead of the server name. Each address can take an optional port. If an +\fBsource\-address\fR +or +\fBsource\-address\-v6\fR +of supplied then these will be used to specify the IPv4 and IPv6 source addresses respectively. +.PP +The +\fBkey\fR +statement begins with an identifying string, the name of the key. The statement has two clauses. +\fBalgorithm\fR +identifies the encryption algorithm for +\fBrndc\fR +to use; currently only HMAC\-MD5 is supported. This is followed by a secret clause which contains the base\-64 encoding of the algorithm's encryption key. The base\-64 string is enclosed in double quotes. +.PP +There are two common ways to generate the base\-64 string for the secret. The BIND 9 program +\fBrndc\-confgen\fR +can be used to generate a random key, or the +\fBmmencode\fR +program, also known as +\fBmimencode\fR, can be used to generate a base\-64 string from known input. +\fBmmencode\fR +does not ship with BIND 9 but is available on many systems. See the EXAMPLE section for sample command lines for each. +.SH "EXAMPLE" +.PP +.RS 4 +.nf + options { + default\-server localhost; + default\-key samplekey; + }; +.fi +.RE +.sp +.PP +.RS 4 +.nf + server localhost { + key samplekey; + }; +.fi +.RE +.sp +.PP +.RS 4 +.nf + server testserver { + key testkey; + addresses { localhost port 5353; }; + }; +.fi +.RE +.sp +.PP +.RS 4 +.nf + key samplekey { + algorithm hmac\-md5; + secret "6FMfj43Osz4lyb24OIe2iGEz9lf1llJO+lz"; + }; +.fi +.RE +.sp +.PP +.RS 4 +.nf + key testkey { + algorithm hmac\-md5; + secret "R3HI8P6BKw9ZwXwN3VZKuQ=="; + }; +.fi +.RE +.sp +.PP +In the above example, +\fBrndc\fR +will by default use the server at localhost (127.0.0.1) and the key called samplekey. Commands to the localhost server will use the samplekey key, which must also be defined in the server's configuration file with the same name and secret. The key statement indicates that samplekey uses the HMAC\-MD5 algorithm and its secret clause contains the base\-64 encoding of the HMAC\-MD5 secret enclosed in double quotes. +.PP +If +\fBrndc \-s testserver\fR +is used then +\fBrndc\fR +will connect to server on localhost port 5353 using the key testkey. +.PP +To generate a random secret with +\fBrndc\-confgen\fR: +.PP +\fBrndc\-confgen\fR +.PP +A complete +\fIrndc.conf\fR +file, including the randomly generated key, will be written to the standard output. Commented\-out +\fBkey\fR +and +\fBcontrols\fR +statements for +\fInamed.conf\fR +are also printed. +.PP +To generate a base\-64 secret with +\fBmmencode\fR: +.PP +\fBecho "known plaintext for a secret" | mmencode\fR +.SH "NAME SERVER CONFIGURATION" +.PP +The name server must be configured to accept rndc connections and to recognize the key specified in the +\fIrndc.conf\fR +file, using the controls statement in +\fInamed.conf\fR. See the sections on the +\fBcontrols\fR +statement in the BIND 9 Administrator Reference Manual for details. +.SH "SEE ALSO" +.PP +\fBrndc\fR(8), +\fBrndc\-confgen\fR(8), +\fBmmencode\fR(1), +BIND 9 Administrator Reference Manual. +.SH "AUTHOR" +.PP +Internet Systems Consortium +.SH "COPYRIGHT" +Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") +.br +Copyright \(co 2000, 2001 Internet Software Consortium. +.br diff --git a/bin/rndc/rndc.conf.docbook b/bin/rndc/rndc.conf.docbook new file mode 100644 index 0000000..ebea7af --- /dev/null +++ b/bin/rndc/rndc.conf.docbook @@ -0,0 +1,252 @@ +]> + + + + + + June 30, 2000 + + + + rndc.conf + 5 + BIND9 + + + + rndc.conf + rndc configuration file + + + + + 2004 + 2005 + 2007 + Internet Systems Consortium, Inc. ("ISC") + + + 2000 + 2001 + Internet Software Consortium. + + + + + + rndc.conf + + + + + 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 + named.conf. Statements are enclosed + in braces and terminated with a semi-colon. Clauses in + the statements are also semi-colon terminated. The usual + comment styles are supported: + + + C style: /* */ + + + C++ style: // to end of line + + + Unix style: # to end of line + + rndc.conf is much simpler than + named.conf. The file uses three + statements: an options statement, a server statement + and a key statement. + + + The statement contains five clauses. + The clause is followed by the + name or address of a name server. This host will be used when + no name server is given as an argument to + rndc. The + clause is followed by the name of a key which is identified by + a statement. If no + is provided on the rndc command line, + and no clause is found in a matching + statement, this default key will be + used to authenticate the server's commands and responses. The + clause is followed by the port + to connect to on the remote name server. If no + option is provided on the rndc command + line, and no clause is found in a + matching statement, this default port + will be used to connect. + The and + clauses which + can be used to set the IPv4 and IPv6 source addresses + respectively. + + + After the keyword, the server + statement includes a string which is the hostname or address + for a name server. The statement has three possible clauses: + , and + . The key name must match the + name of a key statement in the file. The port number + specifies the port to connect to. If an + clause is supplied these addresses will be used instead of + the server name. Each address can take an optional port. + If an or + of supplied then these will be used to specify the IPv4 and IPv6 + source addresses respectively. + + + The statement begins with an identifying + string, the name of the key. The statement has two clauses. + identifies the encryption algorithm + for rndc to use; currently only HMAC-MD5 + is + supported. This is followed by a secret clause which contains + the base-64 encoding of the algorithm's encryption key. The + base-64 string is enclosed in double quotes. + + + There are two common ways to generate the base-64 string for the + secret. The BIND 9 program rndc-confgen + can + be used to generate a random key, or the + mmencode program, also known as + mimencode, can be used to generate a + base-64 + string from known input. mmencode does + not + ship with BIND 9 but is available on many systems. See the + EXAMPLE section for sample command lines for each. + + + + + EXAMPLE + + + options { + default-server localhost; + default-key samplekey; + }; + + + + server localhost { + key samplekey; + }; + + + + server testserver { + key testkey; + addresses { localhost port 5353; }; + }; + + + + key samplekey { + algorithm hmac-md5; + secret "6FMfj43Osz4lyb24OIe2iGEz9lf1llJO+lz"; + }; + + + + key testkey { + algorithm hmac-md5; + secret "R3HI8P6BKw9ZwXwN3VZKuQ=="; + }; + + + + + In the above example, rndc will by + default use + the server at localhost (127.0.0.1) and the key called samplekey. + Commands to the localhost server will use the samplekey key, which + must also be defined in the server's configuration file with the + same name and secret. The key statement indicates that samplekey + uses the HMAC-MD5 algorithm and its secret clause contains the + base-64 encoding of the HMAC-MD5 secret enclosed in double quotes. + + + If rndc -s testserver is used then rndc will + connect to server on localhost port 5353 using the key testkey. + + + To generate a random secret with rndc-confgen: + + rndc-confgen + + + A complete rndc.conf file, including + the + randomly generated key, will be written to the standard + output. Commented-out and + statements for + named.conf are also printed. + + + To generate a base-64 secret with mmencode: + + echo "known plaintext for a secret" | mmencode + + + + + NAME SERVER CONFIGURATION + + The name server must be configured to accept rndc connections and + to recognize the key specified in the rndc.conf + file, using the controls statement in named.conf. + See the sections on the statement in the + BIND 9 Administrator Reference Manual for details. + + + + + SEE ALSO + + rndc8 + , + + rndc-confgen8 + , + + mmencode1 + , + BIND 9 Administrator Reference Manual. + + + + + AUTHOR + Internet Systems Consortium + + + + diff --git a/bin/rndc/rndc.conf.html b/bin/rndc/rndc.conf.html new file mode 100644 index 0000000..d11f9df --- /dev/null +++ b/bin/rndc/rndc.conf.html @@ -0,0 +1,217 @@ + + + + + +rndc.conf + + +
+
+
+

Name

+

rndc.conf — rndc configuration file

+
+
+

Synopsis

+

rndc.conf

+
+
+

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 + named.conf. Statements are enclosed + in braces and terminated with a semi-colon. Clauses in + the statements are also semi-colon terminated. The usual + comment styles are supported: +

+

+ C style: /* */ +

+

+ C++ style: // to end of line +

+

+ Unix style: # to end of line +

+

rndc.conf is much simpler than + named.conf. The file uses three + statements: an options statement, a server statement + and a key statement. +

+

+ The options statement contains five clauses. + The default-server clause is followed by the + name or address of a name server. This host will be used when + no name server is given as an argument to + rndc. The default-key + clause is followed by the name of a key which is identified by + a key statement. If no + keyid is provided on the rndc command line, + and no key clause is found in a matching + server statement, this default key will be + used to authenticate the server's commands and responses. The + default-port clause is followed by the port + to connect to on the remote name server. If no + port option is provided on the rndc command + line, and no port clause is found in a + matching server statement, this default port + will be used to connect. + The default-source-address and + default-source-address-v6 clauses which + can be used to set the IPv4 and IPv6 source addresses + respectively. +

+

+ After the server keyword, the server + statement includes a string which is the hostname or address + for a name server. The statement has three possible clauses: + key, port and + addresses. The key name must match the + name of a key statement in the file. The port number + specifies the port to connect to. If an addresses + clause is supplied these addresses will be used instead of + the server name. Each address can take an optional port. + If an source-address or source-address-v6 + of supplied then these will be used to specify the IPv4 and IPv6 + source addresses respectively. +

+

+ The key statement begins with an identifying + string, the name of the key. The statement has two clauses. + algorithm identifies the encryption algorithm + for rndc to use; currently only HMAC-MD5 + is + supported. This is followed by a secret clause which contains + the base-64 encoding of the algorithm's encryption key. The + base-64 string is enclosed in double quotes. +

+

+ There are two common ways to generate the base-64 string for the + secret. The BIND 9 program rndc-confgen + can + be used to generate a random key, or the + mmencode program, also known as + mimencode, can be used to generate a + base-64 + string from known input. mmencode does + not + ship with BIND 9 but is available on many systems. See the + EXAMPLE section for sample command lines for each. +

+
+
+

EXAMPLE

+
+      options {
+        default-server  localhost;
+        default-key     samplekey;
+      };
+
+

+

+
+      server localhost {
+        key             samplekey;
+      };
+
+

+

+
+      server testserver {
+        key		testkey;
+        addresses	{ localhost port 5353; };
+      };
+
+

+

+
+      key samplekey {
+        algorithm       hmac-md5;
+        secret          "6FMfj43Osz4lyb24OIe2iGEz9lf1llJO+lz";
+      };
+
+

+

+
+      key testkey {
+        algorithm	hmac-md5;
+        secret		"R3HI8P6BKw9ZwXwN3VZKuQ==";
+      };
+    
+

+

+

+ In the above example, rndc will by + default use + the server at localhost (127.0.0.1) and the key called samplekey. + Commands to the localhost server will use the samplekey key, which + must also be defined in the server's configuration file with the + same name and secret. The key statement indicates that samplekey + uses the HMAC-MD5 algorithm and its secret clause contains the + base-64 encoding of the HMAC-MD5 secret enclosed in double quotes. +

+

+ If rndc -s testserver is used then rndc will + connect to server on localhost port 5353 using the key testkey. +

+

+ To generate a random secret with rndc-confgen: +

+

rndc-confgen +

+

+ A complete rndc.conf file, including + the + randomly generated key, will be written to the standard + output. Commented-out key and + controls statements for + named.conf are also printed. +

+

+ To generate a base-64 secret with mmencode: +

+

echo "known plaintext for a secret" | mmencode +

+
+
+

NAME SERVER CONFIGURATION

+

+ The name server must be configured to accept rndc connections and + to recognize the key specified in the rndc.conf + file, using the controls statement in named.conf. + See the sections on the controls statement in the + BIND 9 Administrator Reference Manual for details. +

+
+
+

SEE ALSO

+

rndc(8), + rndc-confgen(8), + mmencode(1), + BIND 9 Administrator Reference Manual. +

+
+
+

AUTHOR

+

Internet Systems Consortium +

+
+
+ diff --git a/bin/rndc/rndc.docbook b/bin/rndc/rndc.docbook new file mode 100644 index 0000000..0719a74 --- /dev/null +++ b/bin/rndc/rndc.docbook @@ -0,0 +1,250 @@ +]> + + + + + + June 30, 2000 + + + + rndc + 8 + BIND9 + + + + rndc + name server control utility + + + + + 2004 + 2005 + 2007 + Internet Systems Consortium, Inc. ("ISC") + + + 2000 + 2001 + Internet Software Consortium. + + + + + + rndc + + + + + + + + command + + + + + DESCRIPTION + rndc + controls the operation of a name + server. It supersedes the ndc utility + that was provided in old BIND releases. If + rndc is invoked with no command line + options or arguments, it prints a short summary of the + supported commands and the available options and their + arguments. + + rndc + communicates with the name server + over a TCP connection, sending commands authenticated with + digital signatures. In the current versions of + rndc and named, + the only supported authentication algorithm is HMAC-MD5, + which uses a shared secret on each end of the connection. + This provides TSIG-style authentication for the command + request and the name server's response. All commands sent + over the channel must be signed by a key_id known to the + server. + + rndc + reads a configuration file to + determine how to contact the name server and decide what + algorithm and key it should use. + + + + + OPTIONS + + + + -b source-address + + + Use source-address + as the source address for the connection to the server. + Multiple instances are permitted to allow setting of both + the IPv4 and IPv6 source addresses. + + + + + + -c config-file + + + Use config-file + as the configuration file instead of the default, + /etc/rndc.conf. + + + + + + -k key-file + + + Use key-file + as the key file instead of the default, + /etc/rndc.key. The key in + /etc/rndc.key will be used to + authenticate + commands sent to the server if the config-file + does not exist. + + + + + + -s server + + server is + the name or address of the server which matches a + server statement in the configuration file for + rndc. If no server is supplied on the + command line, the host named by the default-server clause + in the options statement of the rndc + configuration file will be used. + + + + + + -p port + + + Send commands to TCP port + port + instead + of BIND 9's default control channel port, 953. + + + + + + -V + + + Enable verbose logging. + + + + + + -y key_id + + + Use the key key_id + from the configuration file. + key_id + must be + known by named with the same algorithm and secret string + in order for control message validation to succeed. + If no key_id + is specified, rndc will first look + for a key clause in the server statement of the server + being used, or if no server statement is present for that + host, then the default-key clause of the options statement. + Note that the configuration file contains shared secrets + which are used to send authenticated control commands + to name servers. It should therefore not have general read + or write access. + + + + + + + + For the complete set of commands supported by rndc, + see the BIND 9 Administrator Reference Manual or run + rndc without arguments to see its help + message. + + + + + + LIMITATIONS + rndc + does not yet support all the commands of + the BIND 8 ndc utility. + + + There is currently no way to provide the shared secret for a + without using the configuration file. + + + Several error messages could be clearer. + + + + + SEE ALSO + + rndc.conf5 + , + + named8 + , + + named.conf5 + , + + ndc8 + , + BIND 9 Administrator Reference Manual. + + + + + AUTHOR + Internet Systems Consortium + + + + diff --git a/bin/rndc/rndc.html b/bin/rndc/rndc.html new file mode 100644 index 0000000..d4d0ebb --- /dev/null +++ b/bin/rndc/rndc.html @@ -0,0 +1,164 @@ + + + + + +rndc + + +
+
+
+

Name

+

rndc — name server control utility

+
+
+

Synopsis

+

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

+
+
+

DESCRIPTION

+

rndc + controls the operation of a name + server. It supersedes the ndc utility + that was provided in old BIND releases. If + rndc is invoked with no command line + options or arguments, it prints a short summary of the + supported commands and the available options and their + arguments. +

+

rndc + communicates with the name server + over a TCP connection, sending commands authenticated with + digital signatures. In the current versions of + rndc and named, + the only supported authentication algorithm is HMAC-MD5, + which uses a shared secret on each end of the connection. + This provides TSIG-style authentication for the command + request and the name server's response. All commands sent + over the channel must be signed by a key_id known to the + server. +

+

rndc + reads a configuration file to + determine how to contact the name server and decide what + algorithm and key it should use. +

+
+
+

OPTIONS

+
+
-b source-address
+

+ Use source-address + as the source address for the connection to the server. + Multiple instances are permitted to allow setting of both + the IPv4 and IPv6 source addresses. +

+
-c config-file
+

+ Use config-file + as the configuration file instead of the default, + /etc/rndc.conf. +

+
-k key-file
+

+ Use key-file + as the key file instead of the default, + /etc/rndc.key. The key in + /etc/rndc.key will be used to + authenticate + commands sent to the server if the config-file + does not exist. +

+
-s server
+

server is + the name or address of the server which matches a + server statement in the configuration file for + rndc. If no server is supplied on the + command line, the host named by the default-server clause + in the options statement of the rndc + configuration file will be used. +

+
-p port
+

+ Send commands to TCP port + port + instead + of BIND 9's default control channel port, 953. +

+
-V
+

+ Enable verbose logging. +

+
-y key_id
+

+ Use the key key_id + from the configuration file. + key_id + must be + known by named with the same algorithm and secret string + in order for control message validation to succeed. + If no key_id + is specified, rndc will first look + for a key clause in the server statement of the server + being used, or if no server statement is present for that + host, then the default-key clause of the options statement. + Note that the configuration file contains shared secrets + which are used to send authenticated control commands + to name servers. It should therefore not have general read + or write access. +

+
+

+ For the complete set of commands supported by rndc, + see the BIND 9 Administrator Reference Manual or run + rndc without arguments to see its help + message. +

+
+
+

LIMITATIONS

+

rndc + does not yet support all the commands of + the BIND 8 ndc utility. +

+

+ There is currently no way to provide the shared secret for a + key_id without using the configuration file. +

+

+ Several error messages could be clearer. +

+
+
+

SEE ALSO

+

rndc.conf(5), + named(8), + named.conf(5), + ndc(8), + BIND 9 Administrator Reference Manual. +

+
+
+

AUTHOR

+

Internet Systems Consortium +

+
+
+ diff --git a/bin/rndc/unix/Makefile.in b/bin/rndc/unix/Makefile.in new file mode 100644 index 0000000..6696c23 --- /dev/null +++ b/bin/rndc/unix/Makefile.in @@ -0,0 +1,36 @@ +# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2001 Internet Software Consortium. +# +# Permission to use, copy, modify, and 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: Makefile.in,v 1.3 2004/03/05 04:58:29 marka Exp $ + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +@BIND9_MAKE_INCLUDES@ + +CINCLUDES = -I${srcdir}/include -I${srcdir}/../include \ + ${DNS_INCLUDES} ${ISC_INCLUDES} + +CDEFINES = +CWARNINGS = + +OBJS = os.@O@ + +SRCS = os.c + +TARGETS = ${OBJS} + +@BIND9_MAKE_RULES@ diff --git a/bin/rndc/unix/os.c b/bin/rndc/unix/os.c new file mode 100644 index 0000000..f5f6a91 --- /dev/null +++ b/bin/rndc/unix/os.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: os.c,v 1.6.18.2 2005/04/29 00:15:41 marka Exp $ */ + +/*! \file */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +int +set_user(FILE *fd, const char *user) { + struct passwd *pw; + + pw = getpwnam(user); + if (pw == NULL) { + errno = EINVAL; + return (-1); + } + return (fchown(fileno(fd), pw->pw_uid, -1)); +} + +FILE * +safe_create(const char *filename) { + int fd; + FILE *f; + struct stat sb; + int flags = O_WRONLY; + + if (stat(filename, &sb) == -1) { + if (errno != ENOENT) + return (NULL); + flags = O_WRONLY | O_CREAT | O_EXCL; + } else if ((sb.st_mode & S_IFREG) == 0) { + errno = EOPNOTSUPP; + return (NULL); + } else + flags = O_WRONLY | O_TRUNC; + + fd = open(filename, flags, S_IRUSR | S_IWUSR); + if (fd == -1) + return (NULL); + f = fdopen(fd, "w"); + if (f == NULL) + close(fd); + return (f); +} diff --git a/bin/rndc/util.c b/bin/rndc/util.c new file mode 100644 index 0000000..c64add72 --- /dev/null +++ b/bin/rndc/util.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: util.c,v 1.3.18.2 2005/04/29 00:15:40 marka Exp $ */ + +/*! \file */ + +#include + +#include +#include +#include + +#include + +#include "util.h" + +extern isc_boolean_t verbose; +extern const char *progname; + +void +notify(const char *fmt, ...) { + va_list ap; + + if (verbose) { + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fputs("\n", stderr); + } +} + +void +fatal(const char *format, ...) { + va_list args; + + fprintf(stderr, "%s: ", progname); + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, "\n"); + exit(1); +} diff --git a/bin/rndc/util.h b/bin/rndc/util.h new file mode 100644 index 0000000..6414861 --- /dev/null +++ b/bin/rndc/util.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: util.h,v 1.6.18.2 2005/04/29 00:15:41 marka Exp $ */ + +#ifndef RNDC_UTIL_H +#define RNDC_UTIL_H 1 + +/*! \file */ + +#include + +#include + +#define NS_CONTROL_PORT 953 + +#undef DO +#define DO(name, function) \ + do { \ + result = function; \ + if (result != ISC_R_SUCCESS) \ + fatal("%s: %s", name, isc_result_totext(result)); \ + else \ + notify("%s", name); \ + } while (0) + +ISC_LANG_BEGINDECLS + +void +notify(const char *fmt, ...) ISC_FORMAT_PRINTF(1, 2); + +void +fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); + +ISC_LANG_ENDDECLS + +#endif /* RNDC_UTIL_H */ diff --git a/config.guess b/config.guess new file mode 100644 index 0000000..7d0185e --- /dev/null +++ b/config.guess @@ -0,0 +1,1447 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + +timestamp='2004-09-07' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amd64:OpenBSD:*:*) + echo x86_64-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + cats:OpenBSD:*:*) + echo arm-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + luna88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips64-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit 0 ;; + macppc:MirBSD:*:*) + echo powerppc-unknown-mirbsd${UNAME_RELEASE} + exit 0 ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit 0 ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit 0 ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit 0 ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + *86) UNAME_PROCESSOR=i686 ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit 0 ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms && exit 0 ;; + I*) echo ia64-dec-vms && exit 0 ;; + V*) echo vax-dec-vms && exit 0 ;; + esac +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.sub b/config.sub new file mode 100644 index 0000000..edb6b66 --- /dev/null +++ b/config.sub @@ -0,0 +1,1555 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + +timestamp='2004-08-29' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ + kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32r | m32rle | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | msp430 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | msp430-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.threads.in b/config.threads.in new file mode 100644 index 0000000..c1c113b --- /dev/null +++ b/config.threads.in @@ -0,0 +1,177 @@ +# +# Begin pthreads checking. +# +# First, decide whether to use multithreading or not. +# +# Enable multithreading by default on systems where it is known +# to work well, and where debugging of multithreaded programs +# is supported. +# + +AC_MSG_CHECKING(whether to build with thread support) + +case $host in +*-dec-osf*) + use_threads=true ;; +[*-solaris2.[0-6]]) + # Thread signals are broken on Solaris 2.6; they are sometimes + # delivered to the wrong thread. + use_threads=false ;; +*-solaris*) + use_threads=true ;; +*-ibm-aix*) + use_threads=true ;; +*-hp-hpux10*) + use_threads=false ;; +*-hp-hpux11*) + use_threads=true ;; +*-sgi-irix*) + use_threads=true ;; +*-sco-sysv*uw*|*-*-sysv*UnixWare*) + # UnixWare + use_threads=false ;; +*-*-sysv*OpenUNIX*) + # UnixWare + use_threads=true ;; +*-netbsd*) + if test -r /usr/lib/libpthread.so ; then + use_threads=true + else + # Socket I/O optimizations introduced in 9.2 expose a + # bug in unproven-pthreads; see PR #12650 + use_threads=false + fi + ;; +*-openbsd*) + # OpenBSD users have reported that named dumps core on + # startup when built with threads. + use_threads=false ;; +*-freebsd*) + use_threads=false ;; +*-bsdi[234]*) + # Thread signals do not work reliably on some versions of BSD/OS. + use_threads=false ;; +*-bsdi5*) + use_threads=true ;; +*-linux*) + # Threads are disabled on Linux by default because most + # Linux kernels produce unusable core dumps from multithreaded + # programs, and because of limitations in setuid(). + use_threads=false ;; +*) + use_threads=false ;; +esac + +AC_ARG_ENABLE(threads, + [ --enable-threads enable multithreading]) +case "$enable_threads" in + yes) + use_threads=true + ;; + no) + use_threads=false + ;; + '') + # Use system-dependent default + ;; + *) + AC_MSG_ERROR([--enable-threads takes yes or no]) + ;; +esac + +if $use_threads +then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +if $use_threads +then + # + # Search for / configure pthreads in a system-dependent fashion. + # + case "$host" in + *-netbsd*) + # NetBSD has multiple pthreads implementations. The + # recommended one to use is "unproven-pthreads". The + # older "mit-pthreads" may also work on some NetBSD + # versions. The PTL2 thread library does not + # currently work with bind9, but can be chosen with + # the --with-ptl2 option for those who wish to + # experiment with it. + CC="gcc" + AC_MSG_CHECKING(which NetBSD thread library to use) + + AC_ARG_WITH(ptl2, +[ --with-ptl2 on NetBSD, use the ptl2 thread library (experimental)], + use_ptl2="$withval", use_ptl2="no") + + : ${LOCALBASE:=/usr/pkg} + + if test "X$use_ptl2" = "Xyes" + then + AC_MSG_RESULT(PTL2) + AC_MSG_WARN( +[linking with PTL2 is highly experimental and not expected to work]) + CC=ptlgcc + else + if test -r /usr/lib/libpthread.so + then + AC_MSG_RESULT(native) + LIBS="-lpthread $LIBS" + else + if test ! -d $LOCALBASE/pthreads + then + AC_MSG_RESULT(none) + AC_MSG_ERROR("could not find thread libraries") + fi + + if $use_threads + then + AC_MSG_RESULT(mit-pthreads/unproven-pthreads) + pkg="$LOCALBASE/pthreads" + lib1="-L$pkg/lib -Wl,-R$pkg/lib" + lib2="-lpthread -lm -lgcc -lpthread" + LIBS="$lib1 $lib2 $LIBS" + CPPFLAGS="$CPPFLAGS -I$pkg/include" + STD_CINCLUDES="$STD_CINCLUDES -I$pkg/include" + fi + fi + fi + ;; + *-freebsd*) + # We don't want to set -lpthread as that break + # the ability to choose threads library at final + # link time and is not valid for all architectures. + + PTHREAD= + if test "X$GCC" = "Xyes"; then + saved_cc="$CC" + CC="$CC -pthread" + AC_MSG_CHECKING(for gcc -pthread support); + AC_TRY_LINK([#include ], + [printf("%x\n", pthread_create);], + PTHREAD="yes" + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + CC="$saved_cc" + fi + if test "X$PTHREAD" != "Xyes"; then + AC_CHECK_LIB(pthread, pthread_create,, + AC_CHECK_LIB(thr, thread_create,, + AC_CHECK_LIB(c_r, pthread_create,, + AC_CHECK_LIB(c, pthread_create,, + AC_MSG_ERROR("could not find thread libraries"))))) + fi + ;; + *) + AC_CHECK_LIB(pthread, pthread_create,, + AC_CHECK_LIB(pthread, __pthread_create,, + AC_CHECK_LIB(pthread, __pthread_create_system,, + AC_CHECK_LIB(c_r, pthread_create,, + AC_CHECK_LIB(c, pthread_create,, + AC_MSG_ERROR("could not find thread libraries")))))) + ;; + esac +fi diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..b9280a3 --- /dev/null +++ b/configure.in @@ -0,0 +1,2546 @@ +# Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 1998-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. + +dnl +AC_DIVERT_PUSH(1)dnl +esyscmd([sed "s/^/# /" COPYRIGHT])dnl +AC_DIVERT_POP()dnl + +AC_REVISION($Revision: 1.355.18.71 $) + +AC_INIT(lib/dns/name.c) +AC_PREREQ(2.59) + +AC_CONFIG_HEADER(config.h) +AC_CONFIG_SUBDIRS(lib/bind) + +AC_CANONICAL_HOST + +AC_PROG_MAKE_SET +AC_PROG_RANLIB +AC_PROG_INSTALL +AC_PROG_LN_S + +AC_SUBST(STD_CINCLUDES) +AC_SUBST(STD_CDEFINES) +AC_SUBST(STD_CWARNINGS) +AC_SUBST(CCOPT) + +# +# Make very sure that these are the first files processed by +# config.status, since we use the processed output as the input for +# AC_SUBST_FILE() subsitutions in other files. +# +AC_CONFIG_FILES([make/rules make/includes]) + +AC_PATH_PROG(AR, ar) +ARFLAGS="cruv" +AC_SUBST(AR) +AC_SUBST(ARFLAGS) + +# The POSIX ln(1) program. Non-POSIX systems may substitute +# "copy" or something. +LN=ln +AC_SUBST(LN) + +case "$AR" in + "") + AC_MSG_ERROR([ +ar program not found. Please fix your PATH to include the directory in +which ar resides, or set AR in the environment with the full path to ar. +]) + + ;; +esac + +# +# Etags. +# +AC_PATH_PROGS(ETAGS, etags emacs-etags) + +# +# Some systems, e.g. RH7, have the Exuberant Ctags etags instead of +# GNU emacs etags, and it requires the -L flag. +# +if test "X$ETAGS" != "X"; then + AC_MSG_CHECKING(for Exuberant Ctags etags) + if $ETAGS --version 2>&1 | grep 'Exuberant Ctags' >/dev/null 2>&1; then + AC_MSG_RESULT(yes) + ETAGS="$ETAGS -L" + else + AC_MSG_RESULT(no) + fi +fi +AC_SUBST(ETAGS) + +# +# Perl is optional; it is used only by some of the system test scripts. +# +AC_PATH_PROGS(PERL, perl5 perl) +AC_SUBST(PERL) + +# +# Special processing of paths depending on whether --prefix, +# --sysconfdir or --localstatedir arguments were given. What's +# desired is some compatibility with the way previous versions +# of BIND built; they defaulted to /usr/local for most parts of +# the installation, but named.boot/named.conf was in /etc +# and named.pid was in /var/run. +# +# So ... if none of --prefix, --sysconfdir or --localstatedir are +# specified, set things up that way. If --prefix is given, use +# it for sysconfdir and localstatedir the way configure normally +# would. To change the prefix for everything but leave named.conf +# in /etc or named.pid in /var/run, then do this the usual configure way: +# ./configure --prefix=/somewhere --sysconfdir=/etc +# ./configure --prefix=/somewhere --localstatedir=/var +# +# To put named.conf and named.pid in /usr/local with everything else, +# set the prefix explicitly to /usr/local even though that's the default: +# ./configure --prefix=/usr/local +# +case "$prefix" in + NONE) + case "$sysconfdir" in + '${prefix}/etc') + sysconfdir=/etc + ;; + esac + case "$localstatedir" in + '${prefix}/var') + localstatedir=/var + ;; + esac + ;; +esac + +# +# Make sure INSTALL uses an absolute path, else it will be wrong in all +# Makefiles, since they use make/rules.in and INSTALL will be adjusted by +# configure based on the location of the file where it is substituted. +# Since in BIND9 INSTALL is only substituted into make/rules.in, an immediate +# subdirectory of install-sh, This relative path will be wrong for all +# directories more than one level down from install-sh. +# +case "$INSTALL" in + /*) + ;; + *) + # + # Not all systems have dirname. + # + changequote({, }) + ac_dir="`echo $INSTALL | sed 's%/[^/]*$%%'`" + changequote([, ]) + + ac_prog="`echo $INSTALL | sed 's%.*/%%'`" + test "$ac_dir" = "$ac_prog" && ac_dir=. + test -d "$ac_dir" && ac_dir="`(cd \"$ac_dir\" && pwd)`" + INSTALL="$ac_dir/$ac_prog" + ;; +esac + +# +# On these hosts, we really want to use cc, not gcc, even if it is +# found. The gcc that these systems have will not correctly handle +# pthreads. +# +# However, if the user sets $CC to be something, let that override +# our change. +# +if test "X$CC" = "X" ; then + case "$host" in + *-dec-osf*) + CC="cc" + ;; + *-solaris*) + # Use Sun's cc if it is available, but watch + # out for /usr/ucb/cc; it will never be the right + # compiler to use. + # + # If setting CC here fails, the AC_PROG_CC done + # below might still find gcc. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + case "$ac_dir" in + /usr/ucb) + # exclude + ;; + *) + if test -f "$ac_dir/cc"; then + CC="$ac_dir/cc" + break + fi + ;; + esac + done + IFS="$ac_save_ifs" + ;; + *-hp-hpux*) + CC="cc" + ;; + mips-sgi-irix*) + CC="cc" + ;; + esac +fi + +AC_PROG_CC + +# +# gcc's optimiser is broken at -02 for ultrasparc +# +if test "$ac_env_CFLAGS_set" != set -a "X$GCC" = "Xyes"; then + case "$host" in + sparc-*) + CCFLAGS="-g -O1" + ;; + esac +fi + +# +# OS dependent CC flags +# +case "$host" in + # OSF 5.0: recv/send are only avaliable with -D_POSIX_PII_SOCKET or + # -D_XOPEN_SOURCE_EXTENDED. + *-dec-osf*) + STD_CDEFINES="$STD_CDEFINES -D_POSIX_PII_SOCKET" + CPPFLAGS="$CPPFLAGS -D_POSIX_PII_SOCKET" + ;; + #HP-UX: need -D_XOPEN_SOURCE_EXTENDED and -lxnet for CMSG macros + *-hp-hpux*) + STD_CDEFINES="$STD_CDEFINES -D_XOPEN_SOURCE_EXTENDED" + CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE_EXTENDED" + LIBS="-lxnet $LIBS" + ;; + # Solaris: need -D_XPG4_2 and -D__EXTENSIONS__ for CMSG macros + *-solaris*) + STD_CDEFINES="$STD_CDEFINES -D_XPG4_2 -D__EXTENSIONS__" + CPPFLAGS="$CPPFLAGS -D_XPG4_2 -D__EXTENSIONS__" + ;; +esac + +AC_HEADER_STDC + +AC_CHECK_HEADERS(fcntl.h sys/time.h unistd.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h,,, +[$ac_includes_default +#ifdef HAVE_SYS_PARAM_H +# include +#endif +]) + +AC_C_CONST +AC_C_INLINE +AC_CHECK_FUNC(sysctlbyname, AC_DEFINE(HAVE_SYSCTLBYNAME)) + +# +# UnixWare 7.1.1 with the feature supplement to the UDK compiler +# is reported to not support "static inline" (RT #1212). +# +AC_MSG_CHECKING(for static inline breakage) +AC_TRY_COMPILE(, [ + foo1(); + } + + static inline int foo1() { + return 0; + } + + static inline int foo2() { + return foo1(); + ], + [AC_MSG_RESULT(no)], + [AC_MSG_RESULT(yes) + AC_DEFINE(inline, )]) + +AC_TYPE_SIZE_T +AC_CHECK_TYPE(ssize_t, int) +AC_CHECK_TYPE(uintptr_t,unsigned long) +AC_CHECK_TYPE(socklen_t, +[AC_DEFINE(ISC_SOCKADDR_LEN_T, socklen_t)], +[ +AC_TRY_COMPILE( +[ +#include +#include +int getsockname(int, struct sockaddr *, size_t *); +],[], +[AC_DEFINE(ISC_SOCKADDR_LEN_T, size_t)], +[AC_DEFINE(ISC_SOCKADDR_LEN_T, int)]) +], +[ +#include +#include +]) +AC_SUBST(ISC_SOCKADDR_LEN_T) +AC_HEADER_TIME +AC_MSG_CHECKING(for long long) +AC_TRY_COMPILE([],[long long i = 0; return (0);], + [AC_MSG_RESULT(yes) + ISC_PLATFORM_HAVELONGLONG="#define ISC_PLATFORM_HAVELONGLONG 1"], + [AC_MSG_RESULT(no) + ISC_PLATFORM_HAVELONGLONG="#undef ISC_PLATFORM_HAVELONGLONG"]) +AC_SUBST(ISC_PLATFORM_HAVELONGLONG) + +# +# check if we have lifconf +# +AC_MSG_CHECKING(for struct lifconf) +AC_TRY_COMPILE([ +#include +#include +#include +], +[ +struct lifconf lifconf; +lifconf.lifc_len = 0; +] +, + [AC_MSG_RESULT(yes) + ISC_PLATFORM_HAVELIFCONF="#define ISC_PLATFORM_HAVELIFCONF 1"], + [AC_MSG_RESULT(no) + ISC_PLATFORM_HAVELIFCONF="#undef ISC_PLATFORM_HAVELIFCONF"]) +AC_SUBST(ISC_PLATFORM_HAVELIFCONF) + + +# +# check if we need to #include sys/select.h explicitly +# +case $ac_cv_header_unistd_h in +yes) +AC_MSG_CHECKING(if unistd.h or sys/types.h defines fd_set) +AC_TRY_COMPILE([ +#include /* Ultrix */ +#include ], +[fd_set read_set; return (0);], + [AC_MSG_RESULT(yes) + ISC_PLATFORM_NEEDSYSSELECTH="#undef ISC_PLATFORM_NEEDSYSSELECTH" + LWRES_PLATFORM_NEEDSYSSELECTH="#undef LWRES_PLATFORM_NEEDSYSSELECTH"], + [AC_MSG_RESULT(no) + case $ac_cv_header_sys_select_h in + yes) + ISC_PLATFORM_NEEDSYSSELECTH="#define ISC_PLATFORM_NEEDSYSSELECTH 1" + LWRES_PLATFORM_NEEDSYSSELECTH="#define LWRES_PLATFORM_NEEDSYSSELECTH 1" + ;; + no) + AC_MSG_ERROR([need either working unistd.h or sys/select.h]) + ;; + esac + ]) + ;; +no) + case $ac_cv_header_sys_select_h in + yes) + ISC_PLATFORM_NEEDSYSSELECTH="#define ISC_PLATFORM_NEEDSYSSELECTH 1" + LWRES_PLATFORM_NEEDSYSSELECTH="#define LWRES_PLATFORM_NEEDSYSSELECTH 1" + ;; + no) + AC_MSG_ERROR([need either unistd.h or sys/select.h]) + ;; + esac + ;; +esac +AC_SUBST(ISC_PLATFORM_NEEDSYSSELECTH) +AC_SUBST(LWRES_PLATFORM_NEEDSYSSELECTH) + +# +# Find the machine's endian flavor. +# +AC_C_BIGENDIAN + + +# +# was --with-openssl specified? +# +OPENSSL_WARNING= +AC_MSG_CHECKING(for OpenSSL library) +AC_ARG_WITH(openssl, +[ --with-openssl[=PATH] Build with OpenSSL [yes|no|path]. + (Required for DNSSEC)], + use_openssl="$withval", use_openssl="auto") + +openssldirs="/usr /usr/local /usr/local/ssl /usr/pkg /usr/sfw" +if test "$use_openssl" = "auto" +then + for d in $openssldirs + do + if test -f $d/include/openssl/opensslv.h + then + use_openssl=$d + break + fi + done +fi +case "$use_openssl" in + no) + AC_MSG_RESULT(no) + DST_OPENSSL_INC="" + USE_OPENSSL="" + ;; + auto) + DST_OPENSSL_INC="" + USE_OPENSSL="" + AC_MSG_RESULT(not found) + ;; + *) + if test "$use_openssl" = "yes" + then + # User did not specify a path - guess it + for d in $openssldirs + do + if test -f $d/include/openssl/opensslv.h + then + use_openssl=$d + break + fi + done + if test "$use_openssl" = "yes" + then + AC_MSG_RESULT(not found) + AC_MSG_ERROR( +[OpenSSL was not found in any of $openssldirs; use --with-openssl=/path]) + fi + fi + USE_OPENSSL='-DOPENSSL' + if test "$use_openssl" = "/usr" + then + DST_OPENSSL_INC="" + DNS_OPENSSL_LIBS="-lcrypto" + else + DST_OPENSSL_INC="-I$use_openssl/include" + case $host in + *-solaris*) + DNS_OPENSSL_LIBS="-L$use_openssl/lib -R$use_openssl/lib -lcrypto" + ;; + *-hp-hpux*) + DNS_OPENSSL_LIBS="-L$use_openssl/lib -Wl,+b: -lcrypto" + ;; + *-apple-darwin*) + # + # Apple's ld seaches for serially for dynamic + # then static libraries. This means you can't + # use -L to override dynamic system libraries + # with static ones when linking. Instead + # we specify a absolute path. + # + if test -f "$use_openssl/lib/libcrypto.dylib" + then + DNS_OPENSSL_LIBS="-L$use_openssl/lib -lcrypto" + else + DNS_OPENSSL_LIBS="$use_openssl/lib/libcrypto.a" + fi + ;; + *) + DNS_OPENSSL_LIBS="-L$use_openssl/lib -lcrypto" + ;; + esac + fi + AC_MSG_RESULT(using openssl from $use_openssl/lib and $use_openssl/include) + + saved_cflags="$CFLAGS" + saved_libs="$LIBS" + CFLAGS="$CFLAGS $DST_OPENSSL_INC" + LIBS="$LIBS $DNS_OPENSSL_LIBS" + AC_MSG_CHECKING(whether linking with OpenSSL works) + AC_TRY_RUN([ +#include +int main() { + ERR_clear_error(); + return (0); +} +], + [AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no) + AC_MSG_ERROR(Could not run test program using OpenSSL from +$use_openssl/lib and $use_openssl/include. +Please check the argument to --with-openssl and your +shared library configuration (e.g., LD_LIBRARY_PATH).)], + [AC_MSG_RESULT(assuming it does work on target platform)]) + + AC_MSG_CHECKING(whether linking with OpenSSL requires -ldl) + AC_TRY_LINK([ +#include ], +[ DSO_METHOD_dlfcn(); ], + [AC_MSG_RESULT(no)], + [LIBS="$LIBS -ldl" + AC_TRY_LINK([ +#include +],[ DSO_METHOD_dlfcn(); ], + [AC_MSG_RESULT(yes) + DNS_OPENSSL_LIBS="$DNS_OPENSSL_LIBS -ldl" + ], + [AC_MSG_RESULT(unknown) + AC_MSG_ERROR(OpenSSL has unsupported dynamic loading)], + [AC_MSG_RESULT(assuming it does work on target platform)]) + ], + [AC_MSG_RESULT(assuming it does work on target platform)] + ) + +AC_ARG_ENABLE(openssl-version-check, +[AC_HELP_STRING([--enable-openssl-version-check], + [Check OpenSSL Version @<:@default=yes@:>@])]) +case "$enable_openssl_version_check" in +yes|'') + AC_MSG_CHECKING(OpenSSL library version) + AC_TRY_RUN([ +#include +#include +int main() { + if ((OPENSSL_VERSION_NUMBER >= 0x009070cfL && + OPENSSL_VERSION_NUMBER < 0x00908000L) || + OPENSSL_VERSION_NUMBER >= 0x0090804fL) + return (0); + printf("\n\nFound OPENSSL_VERSION_NUMBER %#010x\n", + OPENSSL_VERSION_NUMBER); + printf("Require OPENSSL_VERSION_NUMBER 0x009070cf or greater (0.9.7l)\n" + "Require OPENSSL_VERSION_NUMBER 0x0090804f or greater (0.9.8d)\n\n"); + return (1); +} + ], + [AC_MSG_RESULT(ok)], + [AC_MSG_RESULT(not compatible) + OPENSSL_WARNING=yes + ], + [AC_MSG_RESULT(assuming target platform has compatible version)]) +;; +no) + AC_MSG_RESULT(Skipped OpenSSL version check) +;; +esac + + AC_MSG_CHECKING(for OpenSSL DSA support) + if test -f $use_openssl/include/openssl/dsa.h + then + AC_DEFINE(HAVE_OPENSSL_DSA) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + CFLAGS="$saved_cflags" + LIBS="$saved_libs" + ;; +esac + +# +# This would include the system openssl path (and linker options to use +# it as needed) if it is found. +# + +AC_SUBST(USE_OPENSSL) +AC_SUBST(DST_OPENSSL_INC) +DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DNS_OPENSSL_LIBS" + +# +# was --with-gssapi specified? +# +#AC_MSG_CHECKING(for GSSAPI library) +#AC_ARG_WITH(gssapi, +#[ --with-gssapi=PATH Specify path for system-supplied GSSAPI], +# use_gssapi="$withval", use_gssapi="no") +# +#case "$use_gssapi" in +# no) +# USE_GSSAPI='' +# DST_GSSAPI_INC='' +# DNS_GSSAPI_LIBS='' +# AC_MSG_RESULT(not specified) +# ;; +# yes) +# AC_MSG_ERROR([--with-gssapi must specify a path]) +# ;; +# *) +# USE_GSSAPI='-DGSSAPI' +# DST_GSSAPI_INC="-I$use_gssapi/include" +# DNS_GSSAPI_LIBS="-L$use_gssapi/lib -lgssapi_krb5" +# AC_MSG_RESULT(using gssapi from $use_gssapi/lib and $use_gssapi/include) +# ;; +#esac + +USE_GSSAPI='' +DST_GSSAPI_INC='' +DNS_GSSAPI_LIBS='' + +AC_SUBST(USE_GSSAPI) +AC_SUBST(DST_GSSAPI_INC) +DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DNS_GSSAPI_LIBS" + +# +# Applications linking with libdns also need to link with these libraries. +# + +AC_SUBST(DNS_CRYPTO_LIBS) + +# +# was --with-randomdev specified? +# +AC_MSG_CHECKING(for random device) +AC_ARG_WITH(randomdev, +[ --with-randomdev=PATH Specify path for random device], + use_randomdev="$withval", use_randomdev="unspec") + +case "$use_randomdev" in + unspec) + case "$host" in + *-openbsd*) + devrandom=/dev/arandom + ;; + *) + devrandom=/dev/random + ;; + esac + AC_MSG_RESULT($devrandom) + AC_CHECK_FILE($devrandom, + AC_DEFINE_UNQUOTED(PATH_RANDOMDEV, + "$devrandom"),) + ;; + yes) + AC_MSG_ERROR([--with-randomdev must specify a path]) + ;; + no) + AC_MSG_RESULT(disabled) + ;; + *) + AC_DEFINE_UNQUOTED(PATH_RANDOMDEV, "$use_randomdev") + AC_MSG_RESULT(using "$use_randomdev") + ;; +esac + +# +# Do we have arc4random() ? +# +AC_CHECK_FUNC(arc4random, AC_DEFINE(HAVE_ARC4RANDOM)) + +sinclude(config.threads.in)dnl + +if $use_threads +then + if test "X$GCC" = "Xyes"; then + case "$host" in + *-freebsd*) + CC="$CC -pthread" + CCOPT="$CCOPT -pthread" + STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE" + ;; + *-openbsd*) + CC="$CC -pthread" + CCOPT="$CCOPT -pthread" + ;; + *-solaris*) + LIBS="$LIBS -lthread" + ;; + *-ibm-aix*) + STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE" + ;; + esac + else + case $host in + *-dec-osf*) + CC="$CC -pthread" + CCOPT="$CCOPT -pthread" + ;; + *-solaris*) + CC="$CC -mt" + CCOPT="$CCOPT -mt" + ;; + *-ibm-aix*) + STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE" + ;; + *-sco-sysv*uw*|*-*-sysv*UnixWare*) + CC="$CC -Kthread" + CCOPT="$CCOPT -Kthread" + ;; + *-*-sysv*OpenUNIX*) + CC="$CC -Kpthread" + CCOPT="$CCOPT -Kpthread" + ;; + esac + fi + ALWAYS_DEFINES="-D_REENTRANT" + ISC_PLATFORM_USETHREADS="#define ISC_PLATFORM_USETHREADS 1" + thread_dir=pthreads + # + # We'd like to use sigwait() too + # + AC_CHECK_FUNC(sigwait, + AC_DEFINE(HAVE_SIGWAIT), + AC_CHECK_LIB(c, sigwait, + AC_DEFINE(HAVE_SIGWAIT), + AC_CHECK_LIB(pthread, sigwait, + AC_DEFINE(HAVE_SIGWAIT), + AC_CHECK_LIB(pthread, _Psigwait, + AC_DEFINE(HAVE_SIGWAIT),)))) + + AC_CHECK_FUNC(pthread_attr_getstacksize, + AC_DEFINE(HAVE_PTHREAD_ATTR_GETSTACKSIZE),) + + AC_CHECK_FUNC(pthread_attr_setstacksize, + AC_DEFINE(HAVE_PTHREAD_ATTR_SETSTACKSIZE),) + + # + # Additional OS-specific issues related to pthreads and sigwait. + # + case "$host" in + # + # One more place to look for sigwait. + # + *-freebsd*) + AC_CHECK_LIB(c_r, sigwait, AC_DEFINE(HAVE_SIGWAIT),) + case $host in + *-freebsd5.[[012]]|*-freebsd5.[[012]].*);; + *-freebsd5.[[3456789]]|*-freebsd5.[[3456789]].*) + AC_DEFINE(NEED_PTHREAD_SCOPE_SYSTEM) + ;; + *-freebsd6.*) + AC_DEFINE(NEED_PTHREAD_SCOPE_SYSTEM) + ;; + esac + ;; + # + # BSDI 3.0 through 4.0.1 needs pthread_init() to be + # called before certain pthreads calls. This is deprecated + # in BSD/OS 4.1. + # + *-bsdi3.*|*-bsdi4.0*) + AC_DEFINE(NEED_PTHREAD_INIT) + ;; + # + # LinuxThreads requires some changes to the way we + # deal with signals. + # + *-linux*) + AC_DEFINE(HAVE_LINUXTHREADS) + ;; + # + # Ensure the right sigwait() semantics on Solaris and make + # sure we call pthread_setconcurrency. + # + *-solaris*) + AC_DEFINE(_POSIX_PTHREAD_SEMANTICS) + AC_CHECK_FUNC(pthread_setconcurrency, + AC_DEFINE(CALL_PTHREAD_SETCONCURRENCY)) + ;; + # + # UnixWare does things its own way. + # + *-sco-sysv*uw*|*-*-sysv*UnixWare*|*-*-sysv*OpenUNIX*) + AC_DEFINE(HAVE_UNIXWARE_SIGWAIT) + ;; + esac + + # + # Look for sysconf to allow detection of the number of processors. + # + AC_CHECK_FUNC(sysconf, AC_DEFINE(HAVE_SYSCONF),) + +else + ISC_PLATFORM_USETHREADS="#undef ISC_PLATFORM_USETHREADS" + thread_dir=nothreads + ALWAYS_DEFINES="" +fi + +AC_SUBST(ALWAYS_DEFINES) +AC_SUBST(ISC_PLATFORM_USETHREADS) +ISC_THREAD_DIR=$thread_dir +AC_SUBST(ISC_THREAD_DIR) + +# +# In solaris 10, SMF can manage named service +# +AC_CHECK_LIB(scf, smf_enable_instance) + +# +# flockfile is usually provided by pthreads, but we may want to use it +# even if compiled with --disable-threads. getc_unlocked might also not +# be defined. +# +AC_CHECK_FUNC(flockfile, AC_DEFINE(HAVE_FLOCKFILE),) +AC_CHECK_FUNC(getc_unlocked, AC_DEFINE(HAVE_GETCUNLOCKED),) + +# +# Indicate what the final decision was regarding threads. +# +AC_MSG_CHECKING(whether to build with threads) +if $use_threads; then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +# +# End of pthreads stuff. +# + +# +# Large File +# +AC_ARG_ENABLE(largefile, [ --enable-largefile 64-bit file support], + want_largefile="yes", want_largefile="no") +case $want_largefile in + yes) + ALWAYS_DEFINES="$ALWAYS_DEFINES -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" + ;; + *) + ;; +esac + +# +# Additional compiler settings. +# +MKDEPCC="$CC" +MKDEPCFLAGS="-M" +IRIX_DNSSEC_WARNINGS_HACK="" + +if test "X$GCC" = "Xyes"; then + AC_MSG_CHECKING(if "$CC" supports -fno-strict-aliasing) + SAVE_CFLAGS=$CFLAGS + CFLAGS=-fno-strict-aliasing + AC_TRY_COMPILE(,, [FNOSTRICTALIASING=yes],[FNOSTRICTALIASING=no]) + CFLAGS=$SAVE_CFLAGS + if test "$FNOSTRICTALIASING" = "yes"; then + AC_MSG_RESULT(yes) + STD_CWARNINGS="$STD_CWARNINGS -W -Wall -Wmissing-prototypes -Wcast-qual -Wwrite-strings -Wformat -Wpointer-arith -fno-strict-aliasing" + else + AC_MSG_RESULT(no) + STD_CWARNINGS="$STD_CWARNINGS -W -Wall -Wmissing-prototypes -Wcast-qual -Wwrite-strings -Wformat -Wpointer-arith" + fi + case "$host" in + *-hp-hpux*) + LDFLAGS="-Wl,+vnocompatwarnings $LDFLAGS" + ;; + esac +else + case $host in + *-dec-osf*) + CC="$CC -std" + CCOPT="$CCOPT -std" + MKDEPCC="$CC" + ;; + *-hp-hpux*) + CC="$CC -Ae -z" + # The version of the C compiler that constantly warns about + # 'const' as well as alignment issues is unfortunately not + # able to be discerned via the version of the operating + # system, nor does cc have a version flag. + case "`$CC +W 123 2>&1`" in + *Unknown?option*) + STD_CWARNINGS="+w1" + ;; + *) + # Turn off the pointlessly noisy warnings. + STD_CWARNINGS="+w1 +W 474,530,2193,2236" + ;; + esac + CCOPT="$CCOPT -Ae -z" + LDFLAGS="-Wl,+vnocompatwarnings $LDFLAGS" + MKDEPPROG='cc -Ae -E -Wp,-M >/dev/null 2>>$TMP' + ;; + *-sgi-irix*) + STD_CWARNINGS="-fullwarn -woff 1209" + # + # Silence more than 250 instances of + # "prototyped function redeclared without prototype" + # and 11 instances of + # "variable ... was set but never used" + # from lib/dns/sec/openssl. + # + IRIX_DNSSEC_WARNINGS_HACK="-woff 1692,1552" + ;; + *-solaris*) + MKDEPCFLAGS="-xM" + ;; + *-sco-sysv*uw*|*-*-sysv*UnixWare*|*-*-sysv*OpenUNIX*) + # UnixWare + CC="$CC -w" + ;; + esac +fi + +AC_SUBST(MKDEPCC) +AC_SUBST(MKDEPCFLAGS) +AC_SUBST(MKDEPPROG) +AC_SUBST(IRIX_DNSSEC_WARNINGS_HACK) + +# +# NLS +# +AC_CHECK_FUNC(catgets, AC_DEFINE(HAVE_CATGETS),) + +# +# -lxnet buys us one big porting headache... standards, gotta love 'em. +# +# AC_CHECK_LIB(xnet, socket, , +# AC_CHECK_LIB(socket, socket) +# AC_CHECK_LIB(nsl, inet_ntoa) +# ) +# +# Use this for now, instead: +# +case "$host" in + mips-sgi-irix*) + ;; + *) + AC_CHECK_LIB(socket, socket) + AC_CHECK_LIB(nsl, inet_ntoa) + ;; +esac + +# +# Purify support +# +AC_MSG_CHECKING(whether to use purify) +AC_ARG_WITH(purify, + [ --with-purify[=PATH] use Rational purify], + use_purify="$withval", use_purify="no") + +case "$use_purify" in + no) + ;; + yes) + AC_PATH_PROG(purify_path, purify, purify) + ;; + *) + purify_path="$use_purify" + ;; +esac + +case "$use_purify" in + no) + AC_MSG_RESULT(no) + PURIFY="" + ;; + *) + if test -f $purify_path || test $purify_path = purify; then + AC_MSG_RESULT($purify_path) + PURIFYFLAGS="`echo $PURIFYOPTIONS`" + PURIFY="$purify_path $PURIFYFLAGS" + else + AC_MSG_ERROR([$purify_path not found. + +Please choose the proper path with the following command: + + configure --with-purify=PATH +]) + fi + ;; +esac + +AC_SUBST(PURIFY) + +# +# GNU libtool support +# +AC_ARG_WITH(libtool, + [ --with-libtool use GNU libtool (following indented options supported)], + use_libtool="$withval", use_libtool="no") + +case $use_libtool in + yes) + AM_PROG_LIBTOOL + O=lo + A=la + LIBTOOL_MKDEP_SED='s;\.o;\.lo;' + LIBTOOL_MODE_COMPILE='--mode=compile' + LIBTOOL_MODE_INSTALL='--mode=install' + LIBTOOL_MODE_LINK='--mode=link' + case "$host" in + *) LIBTOOL_ALLOW_UNDEFINED= ;; + esac + case "$host" in + *-ibm-aix*) LIBTOOL_IN_MAIN="-Wl,-bI:T_testlist.imp" ;; + *) LIBTOOL_IN_MAIN= ;; + esac; + ;; + *) + O=o + A=a + LIBTOOL= + AC_SUBST(LIBTOOL) + LIBTOOL_MKDEP_SED= + LIBTOOL_MODE_COMPILE= + LIBTOOL_MODE_INSTALL= + LIBTOOL_MODE_LINK= + LIBTOOL_ALLOW_UNDEFINED= + LIBTOOL_IN_MAIN= + ;; +esac + +# +# File name extension for static archive files, for those few places +# where they are treated differently from dynamic ones. +# +SA=a + +AC_SUBST(O) +AC_SUBST(A) +AC_SUBST(SA) +AC_SUBST(LIBTOOL_MKDEP_SED) +AC_SUBST(LIBTOOL_MODE_COMPILE) +AC_SUBST(LIBTOOL_MODE_INSTALL) +AC_SUBST(LIBTOOL_MODE_LINK) +AC_SUBST(LIBTOOL_ALLOW_UNDEFINED) +AC_SUBST(LIBTOOL_IN_MAIN) + +# +# build libbind? +# +AC_ARG_ENABLE(libbind, + [ --enable-libbind build libbind [default=no]]) + +case "$enable_libbind" in + yes) + LIBBIND=lib/bind + AC_SUBST(LIBBIND) + ;; + no|'') + ;; +esac + + +# +# Here begins a very long section to determine the system's networking +# capabilities. The order of the tests is signficant. +# + +# +# IPv6 +# +AC_ARG_ENABLE(ipv6, + [ --enable-ipv6 use IPv6 [default=autodetect]]) + +case "$enable_ipv6" in + yes|''|autodetect) + AC_DEFINE(WANT_IPV6) + ;; + no) + ;; +esac + +# +# We do the IPv6 compilation checking after libtool so that we can put +# the right suffix on the files. +# +AC_MSG_CHECKING(for IPv6 structures) +AC_TRY_COMPILE([ +#include +#include +#include ], +[struct sockaddr_in6 sin6; return (0);], + [AC_MSG_RESULT(yes) + found_ipv6=yes], + [AC_MSG_RESULT(no) + found_ipv6=no]) + +# +# See whether IPv6 support is provided via a Kame add-on. +# This is done before other IPv6 linking tests to LIBS is properly set. +# +AC_MSG_CHECKING(for Kame IPv6 support) +AC_ARG_WITH(kame, + [ --with-kame[=PATH] use Kame IPv6 [default path /usr/local/v6]], + use_kame="$withval", use_kame="no") + +case "$use_kame" in + no) + ;; + yes) + kame_path=/usr/local/v6 + ;; + *) + kame_path="$use_kame" + ;; +esac + +case "$use_kame" in + no) + AC_MSG_RESULT(no) + ;; + *) + if test -f $kame_path/lib/libinet6.a; then + AC_MSG_RESULT($kame_path/lib/libinet6.a) + LIBS="-L$kame_path/lib -linet6 $LIBS" + else + AC_MSG_ERROR([$kame_path/lib/libinet6.a not found. + +Please choose the proper path with the following command: + + configure --with-kame=PATH +]) + fi + ;; +esac + +# +# Whether netinet6/in6.h is needed has to be defined in isc/platform.h. +# Including it on Kame-using platforms is very bad, though, because +# Kame uses #error against direct inclusion. So include it on only +# the platform that is otherwise broken without it -- BSD/OS 4.0 through 4.1. +# This is done before the in6_pktinfo check because that's what +# netinet6/in6.h is needed for. +# +changequote({, }) +case "$host" in +*-bsdi4.[01]*) + ISC_PLATFORM_NEEDNETINET6IN6H="#define ISC_PLATFORM_NEEDNETINET6IN6H 1" + LWRES_PLATFORM_NEEDNETINET6IN6H="#define LWRES_PLATFORM_NEEDNETINET6IN6H 1" + isc_netinet6in6_hack="#include " + ;; +*) + ISC_PLATFORM_NEEDNETINET6IN6H="#undef ISC_PLATFORM_NEEDNETINET6IN6H" + LWRES_PLATFORM_NEEDNETINET6IN6H="#undef LWRES_PLATFORM_NEEDNETINET6IN6H" + isc_netinet6in6_hack="" + ;; +esac +changequote([, ]) + +# +# This is similar to the netinet6/in6.h issue. +# +case "$host" in +*-sco-sysv*uw*|*-*-sysv*UnixWare*|*-*-sysv*OpenUNIX*) + # UnixWare + ISC_PLATFORM_NEEDNETINETIN6H="#define ISC_PLATFORM_NEEDNETINETIN6H 1" + LWRES_PLATFORM_NEEDNETINETIN6H="#define LWRES_PLATFORM_NEEDNETINETIN6H 1" + ISC_PLATFORM_FIXIN6ISADDR="#define ISC_PLATFORM_FIXIN6ISADDR 1" + isc_netinetin6_hack="#include " + ;; +*) + ISC_PLATFORM_NEEDNETINETIN6H="#undef ISC_PLATFORM_NEEDNETINETIN6H" + LWRES_PLATFORM_NEEDNETINETIN6H="#undef LWRES_PLATFORM_NEEDNETINETIN6H" + ISC_PLATFORM_FIXIN6ISADDR="#undef ISC_PLATFORM_FIXIN6ISADDR" + isc_netinetin6_hack="" + ;; +esac + +# +# Now delve deeper into the suitability of the IPv6 support. +# +case "$found_ipv6" in + yes) + ISC_PLATFORM_HAVEIPV6="#define ISC_PLATFORM_HAVEIPV6 1" + LWRES_PLATFORM_HAVEIPV6="#define LWRES_PLATFORM_HAVEIPV6 1" + + AC_MSG_CHECKING(for in6_addr) + AC_TRY_COMPILE([ +#include +#include +#include +$isc_netinetin6_hack +$isc_netinet6in6_hack +], +[struct in6_addr in6; return (0);], + [AC_MSG_RESULT(yes) + ISC_PLATFORM_HAVEINADDR6="#undef ISC_PLATFORM_HAVEINADDR6" + LWRES_PLATFORM_HAVEINADDR6="#undef LWRES_PLATFORM_HAVEINADDR6" + isc_in_addr6_hack=""], + [AC_MSG_RESULT(no) + ISC_PLATFORM_HAVEINADDR6="#define ISC_PLATFORM_HAVEINADDR6 1" + LWRES_PLATFORM_HAVEINADDR6="#define LWRES_PLATFORM_HAVEINADDR6 1" + isc_in_addr6_hack="#define in6_addr in_addr6"]) + + AC_MSG_CHECKING(for in6addr_any) + AC_TRY_LINK([ +#include +#include +#include +$isc_netinetin6_hack +$isc_netinet6in6_hack +$isc_in_addr6_hack +], + [struct in6_addr in6; in6 = in6addr_any; return (in6.s6_addr[0]);], + [AC_MSG_RESULT(yes) + ISC_PLATFORM_NEEDIN6ADDRANY="#undef ISC_PLATFORM_NEEDIN6ADDRANY" + LWRES_PLATFORM_NEEDIN6ADDRANY="#undef LWRES_PLATFORM_NEEDIN6ADDRANY"], + [AC_MSG_RESULT(no) + ISC_PLATFORM_NEEDIN6ADDRANY="#define ISC_PLATFORM_NEEDIN6ADDRANY 1" + LWRES_PLATFORM_NEEDIN6ADDRANY="#define LWRES_PLATFORM_NEEDIN6ADDRANY 1"]) + + AC_MSG_CHECKING(for in6addr_loopback) + AC_TRY_LINK([ +#include +#include +#include +$isc_netinetin6_hack +$isc_netinet6in6_hack +$isc_in_addr6_hack +], + [struct in6_addr in6; in6 = in6addr_loopback; return (in6.s6_addr[0]);], + [AC_MSG_RESULT(yes) + ISC_PLATFORM_NEEDIN6ADDRLOOPBACK="#undef ISC_PLATFORM_NEEDIN6ADDRLOOPBACK" + LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK="#undef LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK"], + [AC_MSG_RESULT(no) + ISC_PLATFORM_NEEDIN6ADDRLOOPBACK="#define ISC_PLATFORM_NEEDIN6ADDRLOOPBACK 1" + LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK="#define LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK 1"]) + + AC_MSG_CHECKING(for sin6_scope_id in struct sockaddr_in6) + AC_TRY_COMPILE([ +#include +#include +#include +$isc_netinetin6_hack +$isc_netinet6in6_hack +], + [struct sockaddr_in6 xyzzy; xyzzy.sin6_scope_id = 0; return (0);], + [AC_MSG_RESULT(yes) + ISC_PLATFORM_HAVESCOPEID="#define ISC_PLATFORM_HAVESCOPEID 1" + result="#define LWRES_HAVE_SIN6_SCOPE_ID 1"], + [AC_MSG_RESULT(no) + ISC_PLATFORM_HAVESCOPEID="#undef ISC_PLATFORM_HAVESCOPEID" + result="#undef LWRES_HAVE_SIN6_SCOPE_ID"]) + LWRES_HAVE_SIN6_SCOPE_ID="$result" + + AC_MSG_CHECKING(for in6_pktinfo) + AC_TRY_COMPILE([ +#include +#include +#include +$isc_netinetin6_hack +$isc_netinet6in6_hack +], + [struct in6_pktinfo xyzzy; return (0);], + [AC_MSG_RESULT(yes) + ISC_PLATFORM_HAVEIN6PKTINFO="#define ISC_PLATFORM_HAVEIN6PKTINFO 1"], + [AC_MSG_RESULT(no -- disabling runtime ipv6 support) + ISC_PLATFORM_HAVEIN6PKTINFO="#undef ISC_PLATFORM_HAVEIN6PKTINFO"]) + ;; + no) + ISC_PLATFORM_HAVEIPV6="#undef ISC_PLATFORM_HAVEIPV6" + LWRES_PLATFORM_HAVEIPV6="#undef LWRES_PLATFORM_HAVEIPV6" + ISC_PLATFORM_NEEDIN6ADDRANY="#undef ISC_PLATFORM_NEEDIN6ADDRANY" + LWRES_PLATFORM_NEEDIN6ADDRANY="#undef LWRES_PLATFORM_NEEDIN6ADDRANY" + ISC_PLATFORM_HAVEIN6PKTINFO="#undef ISC_PLATFORM_HAVEIN6PKTINFO" + LWRES_HAVE_SIN6_SCOPE_ID="#define LWRES_HAVE_SIN6_SCOPE_ID 1" + ISC_PLATFORM_HAVESCOPEID="#define ISC_PLATFORM_HAVESCOPEID 1" + ISC_IPV6_H="ipv6.h" + ISC_IPV6_O="ipv6.$O" + ISC_ISCIPV6_O="unix/ipv6.$O" + ISC_IPV6_C="ipv6.c" + ;; +esac + +AC_SUBST(ISC_PLATFORM_HAVEIPV6) +AC_SUBST(LWRES_PLATFORM_HAVEIPV6) +AC_SUBST(ISC_PLATFORM_NEEDNETINETIN6H) +AC_SUBST(LWRES_PLATFORM_NEEDNETINETIN6H) +AC_SUBST(ISC_PLATFORM_NEEDNETINET6IN6H) +AC_SUBST(LWRES_PLATFORM_NEEDNETINET6IN6H) +AC_SUBST(ISC_PLATFORM_HAVEINADDR6) +AC_SUBST(LWRES_PLATFORM_HAVEINADDR6) +AC_SUBST(ISC_PLATFORM_NEEDIN6ADDRANY) +AC_SUBST(LWRES_PLATFORM_NEEDIN6ADDRANY) +AC_SUBST(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK) +AC_SUBST(LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK) +AC_SUBST(ISC_PLATFORM_HAVEIN6PKTINFO) +AC_SUBST(ISC_PLATFORM_FIXIN6ISADDR) +AC_SUBST(ISC_IPV6_H) +AC_SUBST(ISC_IPV6_O) +AC_SUBST(ISC_ISCIPV6_O) +AC_SUBST(ISC_IPV6_C) +AC_SUBST(LWRES_HAVE_SIN6_SCOPE_ID) +AC_SUBST(ISC_PLATFORM_HAVESCOPEID) + +AC_MSG_CHECKING([for struct if_laddrreq]) +AC_TRY_LINK([ +#include +#include +],[ struct if_laddrreq a; ], + [AC_MSG_RESULT(yes) + ISC_PLATFORM_HAVEIF_LADDRREQ="#define ISC_PLATFORM_HAVEIF_LADDRREQ 1"], + [AC_MSG_RESULT(no) + ISC_PLATFORM_HAVEIF_LADDRREQ="#undef ISC_PLATFORM_HAVEIF_LADDRREQ"]) +AC_SUBST(ISC_PLATFORM_HAVEIF_LADDRREQ) + +AC_MSG_CHECKING([for struct if_laddrconf]) +AC_TRY_LINK([ +#include +#include +],[ struct if_laddrconf a; ], + [AC_MSG_RESULT(yes) + ISC_PLATFORM_HAVEIF_LADDRCONF="#define ISC_PLATFORM_HAVEIF_LADDRCONF 1"], + [AC_MSG_RESULT(no) + ISC_PLATFORM_HAVEIF_LADDRCONF="#undef ISC_PLATFORM_HAVEIF_LADDRCONF"]) +AC_SUBST(ISC_PLATFORM_HAVEIF_LADDRCONF) + +# +# Check for network functions that are often missing. We do this +# after the libtool checking, so we can put the right suffix on +# the files. It also needs to come after checking for a Kame add-on, +# which provides some (all?) of the desired functions. +# + +AC_MSG_CHECKING([for inet_ntop with IPv6 support]) +AC_TRY_RUN([ +#include +#include +#include +#include +main() { +char a[16],b[64]; return(inet_ntop(AF_INET6, a, b, sizeof(b)) == (char*)0);}], + [AC_MSG_RESULT(yes) + ISC_PLATFORM_NEEDNTOP="#undef ISC_PLATFORM_NEEDNTOP"], + + [AC_MSG_RESULT(no) + ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS inet_ntop.$O" + ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS inet_ntop.c" + ISC_PLATFORM_NEEDNTOP="#define ISC_PLATFORM_NEEDNTOP 1"], + [AC_MSG_RESULT(assuming inet_ntop needed) + ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS inet_ntop.$O" + ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS inet_ntop.c" + ISC_PLATFORM_NEEDNTOP="#define ISC_PLATFORM_NEEDNTOP 1"]) + + +# On NetBSD 1.4.2 and maybe others, inet_pton() incorrectly accepts +# addresses with less than four octets, like "1.2.3". Also leading +# zeros should also be rejected. + +AC_MSG_CHECKING([for working inet_pton with IPv6 support]) +AC_TRY_RUN([ +#include +#include +#include +#include +main() { char a[16]; return (inet_pton(AF_INET, "1.2.3", a) == 1 ? 1 : + inet_pton(AF_INET, "1.2.3.04", a) == 1 ? 1 : + (inet_pton(AF_INET6, "::1.2.3.4", a) != 1)); }], + [AC_MSG_RESULT(yes) + ISC_PLATFORM_NEEDPTON="#undef ISC_PLATFORM_NEEDPTON"], + [AC_MSG_RESULT(no) + ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS inet_pton.$O" + ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS inet_pton.c" + ISC_PLATFORM_NEEDPTON="#define ISC_PLATFORM_NEEDPTON 1"], + [AC_MSG_RESULT(assuming target platform has working inet_pton) + ISC_PLATFORM_NEEDPTON="#undef ISC_PLATFORM_NEEDPTON"], + [AC_MSG_RESULT(assuming inet_pton needed) + ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS inet_pton.$O" + ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS inet_pton.c" + ISC_PLATFORM_NEEDPTON="#define ISC_PLATFORM_NEEDPTON 1"], + [AC_MSG_RESULT(assuming target platform has working inet_pton) + ISC_PLATFORM_NEEDPTON="#undef ISC_PLATFORM_NEEDPTON"]) + +AC_MSG_CHECKING([for inet_aton]) +AC_TRY_LINK([ +#include +#include +#include ], + [struct in_addr in; inet_aton(0, &in); return (0);], + [AC_MSG_RESULT(yes) + ISC_PLATFORM_NEEDATON="#undef ISC_PLATFORM_NEEDATON"], + + [AC_MSG_RESULT(no) + ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS inet_aton.$O" + ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS inet_aton.c" + ISC_PLATFORM_NEEDATON="#define ISC_PLATFORM_NEEDATON 1"]) + +AC_SUBST(ISC_PLATFORM_NEEDNTOP) +AC_SUBST(ISC_PLATFORM_NEEDPTON) +AC_SUBST(ISC_PLATFORM_NEEDATON) + +# +# Look for a 4.4BSD-style sa_len member in struct sockaddr. +# +case "$host" in + *-dec-osf*) + # Turn on 4.4BSD style sa_len support. + AC_DEFINE(_SOCKADDR_LEN) + ;; +esac + +AC_MSG_CHECKING(for sa_len in struct sockaddr) +AC_TRY_COMPILE([ +#include +#include ], +[struct sockaddr sa; sa.sa_len = 0; return (0);], + [AC_MSG_RESULT(yes) + ISC_PLATFORM_HAVESALEN="#define ISC_PLATFORM_HAVESALEN 1" + LWRES_PLATFORM_HAVESALEN="#define LWRES_PLATFORM_HAVESALEN 1"], + [AC_MSG_RESULT(no) + ISC_PLATFORM_HAVESALEN="#undef ISC_PLATFORM_HAVESALEN" + LWRES_PLATFORM_HAVESALEN="#undef LWRES_PLATFORM_HAVESALEN"]) +AC_SUBST(ISC_PLATFORM_HAVESALEN) +AC_SUBST(LWRES_PLATFORM_HAVESALEN) + +# +# Look for a 4.4BSD or 4.3BSD struct msghdr +# +AC_MSG_CHECKING(for struct msghdr flavor) +AC_TRY_COMPILE([ +#include +#include ], +[struct msghdr msg; msg.msg_flags = 0; return (0);], + [AC_MSG_RESULT(4.4BSD) + ISC_PLATFORM_MSGHDRFLAVOR="#define ISC_NET_BSD44MSGHDR 1"], + [AC_MSG_RESULT(4.3BSD) + ISC_PLATFORM_MSGHDRFLAVOR="#define ISC_NET_BSD43MSGHDR 1"]) +AC_SUBST(ISC_PLATFORM_MSGHDRFLAVOR) + +# +# Look for in_port_t. +# +AC_MSG_CHECKING(for type in_port_t) +AC_TRY_COMPILE([ +#include +#include ], +[in_port_t port = 25; return (0);], + [AC_MSG_RESULT(yes) + ISC_PLATFORM_NEEDPORTT="#undef ISC_PLATFORM_NEEDPORTT"], + [AC_MSG_RESULT(no) + ISC_PLATFORM_NEEDPORTT="#define ISC_PLATFORM_NEEDPORTT 1"]) +AC_SUBST(ISC_PLATFORM_NEEDPORTT) + +# +# Check for addrinfo +# +AC_MSG_CHECKING(for struct addrinfo) +AC_TRY_COMPILE([ +#include ], +[struct addrinfo a; return (0);], + [AC_MSG_RESULT(yes) + ISC_LWRES_NEEDADDRINFO="#undef ISC_LWRES_NEEDADDRINFO" + AC_DEFINE(HAVE_ADDRINFO)], + [AC_MSG_RESULT(no) + ISC_LWRES_NEEDADDRINFO="#define ISC_LWRES_NEEDADDRINFO 1"]) +AC_SUBST(ISC_LWRES_NEEDADDRINFO) + +# +# Check for rrsetinfo +# +AC_MSG_CHECKING(for struct rrsetinfo) +AC_TRY_COMPILE([ +#include ], +[struct rrsetinfo r; return (0);], + [AC_MSG_RESULT(yes) + ISC_LWRES_NEEDRRSETINFO="#undef ISC_LWRES_NEEDRRSETINFO"], + [AC_MSG_RESULT(no) + ISC_LWRES_NEEDRRSETINFO="#define ISC_LWRES_NEEDRRSETINFO 1"]) +AC_SUBST(ISC_LWRES_NEEDRRSETINFO) + +AC_MSG_CHECKING(for int sethostent) +AC_TRY_COMPILE([ +#include ], +[int i = sethostent(0); return(0);], + [AC_MSG_RESULT(yes) + ISC_LWRES_SETHOSTENTINT="#define ISC_LWRES_SETHOSTENTINT 1"], + [AC_MSG_RESULT(no) + ISC_LWRES_SETHOSTENTINT="#undef ISC_LWRES_SETHOSTENTINT"]) +AC_SUBST(ISC_LWRES_SETHOSTENTINT) + +AC_MSG_CHECKING(for int endhostent) +AC_TRY_COMPILE([ +#include ], +[int i = endhostent(); return(0);], + [AC_MSG_RESULT(yes) + ISC_LWRES_ENDHOSTENTINT="#define ISC_LWRES_ENDHOSTENTINT 1"], + [AC_MSG_RESULT(no) + ISC_LWRES_ENDHOSTENTINT="#undef ISC_LWRES_ENDHOSTENTINT"]) +AC_SUBST(ISC_LWRES_ENDHOSTENTINT) + +AC_MSG_CHECKING(for getnetbyaddr(in_addr_t, ...)) +AC_TRY_COMPILE([ +#include +struct netent *getnetbyaddr(in_addr_t, int);], +[], + [AC_MSG_RESULT(yes) + ISC_LWRES_GETNETBYADDRINADDR="#define ISC_LWRES_GETNETBYADDRINADDR 1"], + [AC_MSG_RESULT(no) + ISC_LWRES_GETNETBYADDRINADDR="#undef ISC_LWRES_GETNETBYADDRINADDR"]) +AC_SUBST(ISC_LWRES_GETNETBYADDRINADDR) + +AC_MSG_CHECKING(for int setnetent) +AC_TRY_COMPILE([ +#include ], +[int i = setnetent(0); return(0);], + [AC_MSG_RESULT(yes) + ISC_LWRES_SETNETENTINT="#define ISC_LWRES_SETNETENTINT 1"], + [AC_MSG_RESULT(no) + ISC_LWRES_SETNETENTINT="#undef ISC_LWRES_SETNETENTINT"]) +AC_SUBST(ISC_LWRES_SETNETENTINT) + +AC_MSG_CHECKING(for int endnetent) +AC_TRY_COMPILE([ +#include ], +[int i = endnetent(); return(0);], + [AC_MSG_RESULT(yes) + ISC_LWRES_ENDNETENTINT="#define ISC_LWRES_ENDNETENTINT 1"], + [AC_MSG_RESULT(no) + ISC_LWRES_ENDNETENTINT="#undef ISC_LWRES_ENDNETENTINT"]) +AC_SUBST(ISC_LWRES_ENDNETENTINT) + +AC_MSG_CHECKING(for gethostbyaddr(const void *, size_t, ...)) +AC_TRY_COMPILE([ +#include +struct hostent *gethostbyaddr(const void *, size_t, int);], +[return(0);], + [AC_MSG_RESULT(yes) + ISC_LWRES_GETHOSTBYADDRVOID="#define ISC_LWRES_GETHOSTBYADDRVOID 1"], + [AC_MSG_RESULT(no) + ISC_LWRES_GETHOSTBYADDRVOID="#undef ISC_LWRES_GETHOSTBYADDRVOID"]) +AC_SUBST(ISC_LWRES_GETHOSTBYADDRVOID) + +AC_MSG_CHECKING(for h_errno in netdb.h) +AC_TRY_COMPILE([ +#include ], +[h_errno = 1; return(0);], + [AC_MSG_RESULT(yes) + ISC_LWRES_NEEDHERRNO="#undef ISC_LWRES_NEEDHERRNO"], + [AC_MSG_RESULT(no) + ISC_LWRES_NEEDHERRNO="#define ISC_LWRES_NEEDHERRNO 1"]) +AC_SUBST(ISC_LWRES_NEEDHERRNO) + +AC_CHECK_FUNC(getipnodebyname, + [ISC_LWRES_GETIPNODEPROTO="#undef ISC_LWRES_GETIPNODEPROTO"], + [ISC_LWRES_GETIPNODEPROTO="#define ISC_LWRES_GETIPNODEPROTO 1"]) +AC_CHECK_FUNC(getnameinfo, + [ISC_LWRES_GETNAMEINFOPROTO="#undef ISC_LWRES_GETNAMEINFOPROTO"], + [ISC_LWRES_GETNAMEINFOPROTO="#define ISC_LWRES_GETNAMEINFOPROTO 1"]) +AC_CHECK_FUNC(getaddrinfo, + [ISC_LWRES_GETADDRINFOPROTO="#undef ISC_LWRES_GETADDRINFOPROTO" + AC_DEFINE(HAVE_GETADDRINFO)], + [ISC_LWRES_GETADDRINFOPROTO="#define ISC_LWRES_GETADDRINFOPROTO 1"]) +AC_CHECK_FUNC(gai_strerror, AC_DEFINE(HAVE_GAISTRERROR)) +AC_SUBST(ISC_LWRES_GETIPNODEPROTO) +AC_SUBST(ISC_LWRES_GETADDRINFOPROTO) +AC_SUBST(ISC_LWRES_GETNAMEINFOPROTO) + +AC_ARG_ENABLE(getifaddrs, +[ --enable-getifaddrs Enable the use of getifaddrs() [[yes|no|glibc]]. + glibc: Use getifaddrs() in glibc if you know it supports IPv6.], + want_getifaddrs="$enableval", want_getifaddrs="yes") + +case $want_getifaddrs in +yes|glibc) +# +# Do we have getifaddrs() ? +# +case $host in +*-linux*) + # Some recent versions of glibc support getifaddrs() which does not + # provide AF_INET6 addresses while the function provided by the USAGI + # project handles the AF_INET6 case correctly. We need to avoid + # using the former but prefer the latter unless overridden by + # --enable-getifaddrs=glibc. + if test $want_getifaddrs = glibc + then + AC_CHECK_FUNC(getifaddrs, AC_DEFINE(HAVE_GETIFADDRS)) + else + save_LIBS="$LIBS" + LIBS="-L/usr/local/v6/lib $LIBS" + AC_CHECK_LIB(inet6, getifaddrs, + LIBS="$LIBS -linet6" + AC_DEFINE(HAVE_GETIFADDRS), + LIBS=${save_LIBS}) + fi + ;; +*) + AC_CHECK_FUNC(getifaddrs, AC_DEFINE(HAVE_GETIFADDRS)) + ;; +esac +;; +no) +;; +esac + +# +# Look for a sysctl call to get the list of network interfaces. +# +case $ac_cv_header_sys_sysctl_h in +yes) +AC_MSG_CHECKING(for interface list sysctl) +AC_EGREP_CPP(found_rt_iflist, [ +#include +#include +#include +#ifdef NET_RT_IFLIST +found_rt_iflist +#endif +], + [AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_IFLIST_SYSCTL)], + [AC_MSG_RESULT(no)]) +;; +esac + +# +# Check for some other useful functions that are not ever-present. +# + +# We test for strsep() using AC_TRY_LINK instead of AC_CHECK_FUNC +# because AIX 4.3.3 with patches for bos.adt.include to version 4.3.3.77 +# reportedly defines strsep() without declaring it in when +# -D_LINUX_SOURCE_COMPAT is not defined [RT #2190], and +# AC_CHECK_FUNC() incorrectly succeeds because it declares +# the function itself. +AC_MSG_CHECKING(for correctly declared strsep()) +AC_TRY_LINK([#include ], [char *sp; char *foo = strsep(&sp, ".");], + [AC_MSG_RESULT(yes); ISC_PLATFORM_NEEDSTRSEP="#undef ISC_PLATFORM_NEEDSTRSEP"], + [AC_MSG_RESULT(no); ISC_PLATFORM_NEEDSTRSEP="#define ISC_PLATFORM_NEEDSTRSEP 1"]) +AC_SUBST(ISC_PLATFORM_NEEDSTRSEP) + +AC_CHECK_FUNC(memmove, + [ISC_PLATFORM_NEEDMEMMOVE="#undef ISC_PLATFORM_NEEDMEMMOVE"], + [ISC_PLATFORM_NEEDMEMMOVE="#define ISC_PLATFORM_NEEDMEMMOVE 1"]) +AC_SUBST(ISC_PLATFORM_NEEDMEMMOVE) + +AC_CHECK_FUNC(strtoul, + [ISC_PLATFORM_NEEDSTRTOUL="#undef ISC_PLATFORM_NEEDSTRTOUL" + LWRES_PLATFORM_NEEDSTRTOUL="#undef LWRES_PLATFORM_NEEDSTRTOUL" + GENRANDOMLIB=""], + [ISC_PLATFORM_NEEDSTRTOUL="#define ISC_PLATFORM_NEEDSTRTOUL 1" + LWRES_PLATFORM_NEEDSTRTOUL="#define LWRES_PLATFORM_NEEDSTRTOUL 1" + GENRANDOMLIB='${ISCLIBS}']) +AC_SUBST(ISC_PLATFORM_NEEDSTRTOUL) +AC_SUBST(LWRES_PLATFORM_NEEDSTRTOUL) +AC_SUBST(GENRANDOMLIB) + +AC_CHECK_FUNC(strlcpy, + [ISC_PLATFORM_NEEDSTRLCPY="#undef ISC_PLATFORM_NEEDSTRLCPY"], + [ISC_PLATFORM_NEEDSTRLCPY="#define ISC_PLATFORM_NEEDSTRLCPY 1"]) +AC_SUBST(ISC_PLATFORM_NEEDSTRLCPY) + +AC_CHECK_FUNC(strlcat, + [ISC_PLATFORM_NEEDSTRLCAT="#undef ISC_PLATFORM_NEEDSTRLCAT"], + [ISC_PLATFORM_NEEDSTRLCAT="#define ISC_PLATFORM_NEEDSTRLCAT 1"]) +AC_SUBST(ISC_PLATFORM_NEEDSTRLCAT) + +ISC_PRINT_OBJS= +ISC_PRINT_SRCS= +AC_MSG_CHECKING(sprintf) +AC_TRY_COMPILE([ +#include +], +[ char buf[2]; return(*sprintf(buf,"x"));], +[ +ISC_PRINT_OBJS="print.$O" +ISC_PRINT_SRCS="print.c" +ISC_PLATFORM_NEEDSPRINTF="#define ISC_PLATFORM_NEEDSPRINTF" +LWRES_PLATFORM_NEEDSPRINTF="#define LWRES_PLATFORM_NEEDSPRINTF" +], +[ISC_PLATFORM_NEEDSPRINTF="#undef ISC_PLATFORM_NEEDSPRINTF" + LWRES_PLATFORM_NEEDSPRINTF="#undef LWRES_PLATFORM_NEEDSPRINTF"] +) +AC_SUBST(ISC_PLATFORM_NEEDSPRINTF) +AC_SUBST(LWRES_PLATFORM_NEEDSPRINTF) + +AC_CHECK_FUNC(vsnprintf, + [ISC_PLATFORM_NEEDVSNPRINTF="#undef ISC_PLATFORM_NEEDVSNPRINTF" + LWRES_PLATFORM_NEEDVSNPRINTF="#undef LWRES_PLATFORM_NEEDVSNPRINTF"], + [ISC_PRINT_OBJS="print.$O" + ISC_PRINT_SRCS="print.c" + ISC_PLATFORM_NEEDVSNPRINTF="#define ISC_PLATFORM_NEEDVSNPRINTF 1" + LWRES_PLATFORM_NEEDVSNPRINTF="#define LWRES_PLATFORM_NEEDVSNPRINTF 1"]) +AC_SUBST(ISC_PLATFORM_NEEDVSNPRINTF) +AC_SUBST(LWRES_PLATFORM_NEEDVSNPRINTF) +ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS $ISC_PRINT_OBJS" +ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS $ISC_PRINT_SRCS" + +AC_CHECK_FUNC(strerror, AC_DEFINE(HAVE_STRERROR)) + +AC_SUBST(ISC_EXTRA_OBJS) +AC_SUBST(ISC_EXTRA_SRCS) + +# Determine the printf format characters to use when printing +# values of type isc_int64_t. This will normally be "ll", but where +# the compiler treats "long long" as a alias for "long" and printf +# doesn't know about "long long" use "l". Hopefully the sprintf +# will produce a inconsistant result in the later case. If the compiler +# fails due to seeing "%lld" we fall back to "l". +# +# Digital Unix 4.0 (gcc?) (long long) is 64 bits as is its long. It uses +# %ld even for (long long)/ +# +# Win32 uses "%I64d", but that's defined elsewhere since we don't use +# configure on Win32. +# +AC_MSG_CHECKING(printf format modifier for 64-bit integers) +AC_TRY_RUN([ +#include +main() { + long long int j = 0; + char buf[100]; + buf[0] = 0; + sprintf(buf, "%lld", j); + exit((sizeof(long long int) != sizeof(long int))? 0 : + (strcmp(buf, "0") != 0)); +} +], + [AC_MSG_RESULT(ll) + ISC_PLATFORM_QUADFORMAT='#define ISC_PLATFORM_QUADFORMAT "ll"' + LWRES_PLATFORM_QUADFORMAT='#define LWRES_PLATFORM_QUADFORMAT "ll"'], + [AC_MSG_RESULT(l) + ISC_PLATFORM_QUADFORMAT='#define ISC_PLATFORM_QUADFORMAT "l"' + LWRES_PLATFORM_QUADFORMAT='#define LWRES_PLATFORM_QUADFORMAT "l"'], + [AC_MSG_RESULT(assuming target platform uses ll) + ISC_PLATFORM_QUADFORMAT='#define ISC_PLATFORM_QUADFORMAT "ll"' + LWRES_PLATFORM_QUADFORMAT='#define LWRES_PLATFORM_QUADFORMAT "ll"']) +AC_SUBST(ISC_PLATFORM_QUADFORMAT) +AC_SUBST(LWRES_PLATFORM_QUADFORMAT) + +# +# Security Stuff +# +AC_CHECK_FUNC(chroot, AC_DEFINE(HAVE_CHROOT)) +AC_ARG_ENABLE(linux-caps, + [ --disable-linux-caps disable linux capabilities]) +case "$enable_linux_caps" in + yes|'') + AC_CHECK_HEADERS(linux/capability.h) + ;; + no) + ;; +esac +AC_CHECK_HEADERS(sys/prctl.h) + +AC_CHECK_HEADERS(sys/un.h, +ISC_PLATFORM_HAVESYSUNH="#define ISC_PLATFORM_HAVESYSUNH 1" +, +ISC_PLATFORM_HAVESYSUNH="#undef ISC_PLATFORM_HAVESYSUNH" +) +AC_SUBST(ISC_PLATFORM_HAVESYSUNH) + +case "$host" in +*-solaris*) + AC_DEFINE(NEED_SECURE_DIRECTORY, 1, + [Define if connect does not honour the permission on the UNIX domain socket.]) + ;; +*-sunos*) + AC_DEFINE(NEED_SECURE_DIRECTORY, 1, + [Define if connect does not honour the permission on the UNIX domain socket.]) + ;; +esac + +# +# Time Zone Stuff +# +AC_CHECK_FUNC(tzset, AC_DEFINE(HAVE_TZSET)) + +AC_MSG_CHECKING(for optarg decarartion) +AC_TRY_COMPILE([ +#include +], +[optarg = 0;], +[AC_MSG_RESULT(yes)], +[AC_MSG_RESULT(no) +GEN_NEED_OPTARG="-DNEED_OPTARG=1" +AC_DEFINE(NEED_OPTARG, 1, [Defined if extern char *optarg is not declared.])]) + +# +# BSD/OS, and perhaps some others, don't define rlim_t. +# +AC_MSG_CHECKING(for type rlim_t) +AC_TRY_COMPILE([ +#include +#include +#include ], +[rlim_t rl = 19671212; return (0);], +[AC_MSG_RESULT(yes) + ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE rlim_t"], +[AC_MSG_RESULT(no) + +AC_MSG_CHECKING(type of rlim_cur) +AC_TRY_RUN([ +#include +#include +#include +main() { struct rlimit r; exit(!(sizeof(r.rlim_cur) == sizeof(int)));}], +[AC_MSG_RESULT(int) +ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE int"], +[ +AC_TRY_RUN([ +#include +#include +#include +main() { struct rlimit r; exit(!(sizeof(r.rlim_cur) == sizeof(long int)));}], +[AC_MSG_RESULT(long int) +ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE long int"], +[ +AC_TRY_RUN([ +#include +#include +#include +main() { struct rlimit r; exit((!sizeof(r.rlim_cur) == sizeof(long long int)));}], +[AC_MSG_RESULT(long long int) +ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE long long int"], +[AC_MSG_ERROR([unable to determine sizeof rlim_cur]) +],[AC_MSG_ERROR(this cannot happen)]) +],[AC_MSG_ERROR(this cannot happen)]) +],[ +ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE long long int" +AC_MSG_RESULT(cannot determine type of rlim_cur when cross compiling - assuming long long int)]) +]) +AC_SUBST(ISC_PLATFORM_RLIMITTYPE) + +# +# Compaq TruCluster requires more code for handling cluster IP aliases +# +case "$host" in + *-dec-osf*) + AC_CHECK_LIB(clua, clua_getaliasaddress, LIBS="-lclua $LIBS") + AC_CHECK_FUNC(clua_getaliasaddress, + AC_DEFINE(HAVE_TRUCLUSTER, 1, + [Define if running under Compaq TruCluster])) + ;; + *) + ;; +esac + +# +# Some hosts need msg_namelen to match the size of the socket structure. +# Some hosts don't set msg_namelen appropriately on return from recvmsg(). +# +case $host in +*os2*|*hp-mpeix*) + AC_DEFINE(BROKEN_RECVMSG, 1, + [Define if recvmsg() does not meet all of the BSD socket API specifications.]) + ;; +esac + +# +# Microsoft has their own way of handling shared libraries that requires +# additional qualifiers on extern variables. Unix systems don't need it. +# +AC_SUBST(ISC_PLATFORM_USEDECLSPEC) +ISC_PLATFORM_USEDECLSPEC="#undef ISC_PLATFORM_USEDECLSPEC" +AC_SUBST(LWRES_PLATFORM_USEDECLSPEC) +LWRES_PLATFORM_USEDECLSPEC="#undef LWRES_PLATFORM_USEDECLSPEC" + +# +# Random remaining OS-specific issues involving compiler warnings. +# XXXDCL print messages to indicate some compensation is being done? +# +AC_SUBST(ISC_PLATFORM_BRACEPTHREADONCEINIT) +ISC_PLATFORM_BRACEPTHREADONCEINIT="#undef ISC_PLATFORM_BRACEPTHREADONCEINIT" + +case "$host" in + *-aix5.[[123]].*) + hack_shutup_pthreadonceinit=yes + ;; + *-bsdi3.1*) + hack_shutup_sputaux=yes + ;; + *-bsdi4.0*) + hack_shutup_sigwait=yes + hack_shutup_sputaux=yes + ;; + [*-bsdi4.[12]*]) + hack_shutup_stdargcast=yes + ;; + [*-solaris2.[89]]) + hack_shutup_pthreadonceinit=yes + ;; + *-solaris2.10) + hack_shutup_pthreadonceinit=yes + ;; +esac + +case "$hack_shutup_pthreadonceinit" in + yes) + # + # Shut up PTHREAD_ONCE_INIT unbraced initializer warnings. + # + ISC_PLATFORM_BRACEPTHREADONCEINIT="#define ISC_PLATFORM_BRACEPTHREADONCEINIT 1" + ;; +esac + +case "$hack_shutup_sigwait" in + yes) + # + # Shut up a -Wmissing-prototypes warning for sigwait(). + # + AC_DEFINE(SHUTUP_SIGWAIT) + ;; +esac + +case "$hack_shutup_sputaux" in + yes) + # + # Shut up a -Wmissing-prototypes warning from . + # + AC_DEFINE(SHUTUP_SPUTAUX) + ;; +esac + +case "$hack_shutup_stdargcast" in + yes) + # + # Shut up a -Wcast-qual warning from va_start(). + # + AC_DEFINE(SHUTUP_STDARG_CAST) + ;; +esac + +AC_CHECK_HEADERS(strings.h, + ISC_PLATFORM_HAVESTRINGSH="#define ISC_PLATFORM_HAVESTRINGSH 1" +, + ISC_PLATFORM_HAVESTRINGSH="#undef ISC_PLATFORM_HAVESTRINGSH" +) +AC_SUBST(ISC_PLATFORM_HAVESTRINGSH) + +# +# Check for if_nametoindex() for IPv6 scoped addresses support +# +AC_CHECK_FUNC(if_nametoindex, ac_cv_have_if_nametoindex=yes, + ac_cv_have_if_nametoindex=no) +case $ac_cv_have_if_nametoindex in +no) + case "$host" in + *-hp-hpux*) + AC_CHECK_LIB(ipv6, if_nametoindex, + ac_cv_have_if_nametoindex=yes + LIBS="-lipv6 $LIBS",) + ;; + esac +esac +case $ac_cv_have_if_nametoindex in +yes) + ISC_PLATFORM_HAVEIFNAMETOINDEX="#define ISC_PLATFORM_HAVEIFNAMETOINDEX 1" + ;; +*) + ISC_PLATFORM_HAVEIFNAMETOINDEX="#undef ISC_PLATFORM_HAVEIFNAMETOINDEX" + ;; +esac +AC_SUBST(ISC_PLATFORM_HAVEIFNAMETOINDEX) + +# +# Machine architecture dependent features +# +AC_ARG_ENABLE(atomic, + [ --enable-atomic enable machine specific atomic operations + [[default=autodetect]]], + enable_atomic="$enableval", + enable_atomic="autodetect") +case "$enable_atomic" in + yes|''|autodetect) + use_atomic=yes + ;; + no) + use_atomic=no + arch=noatomic + ;; +esac + +ISC_PLATFORM_USEOSFASM="#undef ISC_PLATFORM_USEOSFASM" +if test "$use_atomic" = "yes"; then + AC_MSG_CHECKING([architecture type for atomic operations]) + have_atomic=yes # set default + case "$host" in + [i[3456]86-*]) + # XXX: some old x86 architectures actually do not support + # (some of) these operations. Do we need stricter checks? +AC_TRY_RUN([ +main() { + exit((sizeof(void *) == 8) ? 0 : 1); +} +], + [arch=x86_64], + [arch=x86_32], + [arch=x86_32]) + ;; + x86_64-*) + arch=x86_64 + ;; + alpha*-*) + arch=alpha + ;; + powerpc-*) + arch=powerpc + ;; + mips-*|mipsel-*|mips64-*|mips64el-*) + arch=mips + ;; + ia64-*) + arch=ia64 + ;; + *) + have_atomic=no + arch=noatomic + ;; + esac + AC_MSG_RESULT($arch) +fi + +if test "$have_atomic" = "yes"; then + AC_MSG_CHECKING([compiler support for inline assembly code]) + + compiler=generic + # Check whether the compiler supports the assembly syntax we provide. + if test "X$GCC" = "Xyes"; then + # GCC's ASM extension always works + compiler=gcc + if test $arch = "x86_64"; then + # We can share the same code for gcc with x86_32 + arch=x86_32 + fi + if test $arch = "powerpc"; then + # + # The MacOS (and maybe others) uses "r0" for register + # zero. Under linux/ibm it is "0" for register 0. + # Probe to see if we have a MacOS style assembler. + # + AC_MSG_CHECKING([Checking for MacOS style assembler syntax]) + AC_TRY_COMPILE(, [ + __asm__ volatile ("li r0, 0x0\n"::); + ], [ + AC_MSG_RESULT(yes) + compiler="mac" + ISC_PLATFORM_USEMACASM="#define ISC_PLATFORM_USEMACASM 1" + ], [AC_MSG_RESULT(no)]) + fi + else + case "$host" in + alpha*-dec-osf*) + # Tru64 compiler has its own syntax for inline + # assembly. + AC_TRY_COMPILE(, [ +#ifndef __DECC +#error "unexpected compiler" +#endif + return (0);], + [compiler=osf],) + ;; + powerpc-ibm-aix*) + compiler=aix + ;; + esac + fi + case "$compiler" in + gcc) + ISC_PLATFORM_USEGCCASM="#define ISC_PLATFORM_USEGCCASM 1" + ;; + osf) + ISC_PLATFORM_USEOSFASM="#define ISC_PLATFORM_USEOSFASM 1" + ;; + aix) + ;; + mac) + ;; + *) + # See if the generic __asm function works. If not, + # we need to disable the atomic operations. + AC_TRY_LINK(, [ + __asm("nop") + ], + [compiler="standard" + ISC_PLATFORM_USESTDASM="#define ISC_PLATFORM_USESTDASM 1"], + [compiler="not supported (atomic operations disabled)" + have_atomic=no + arch=noatomic ]); + ;; + esac + + AC_MSG_RESULT($compiler) +fi + +if test "$have_atomic" = "yes"; then + ISC_PLATFORM_HAVEXADD="#define ISC_PLATFORM_HAVEXADD 1" + ISC_PLATFORM_HAVECMPXCHG="#define ISC_PLATFORM_HAVECMPXCHG 1" + ISC_PLATFORM_HAVEATOMICSTORE="#define ISC_PLATFORM_HAVEATOMICSTORE 1" +else + ISC_PLATFORM_HAVEXADD="#undef ISC_PLATFORM_HAVEXADD" + ISC_PLATFORM_HAVECMPXCHG="#undef ISC_PLATFORM_HAVECMPXCHG" + ISC_PLATFORM_HAVEATOMICSTORE="#undef ISC_PLATFORM_HAVEATOMICSTORE" +fi + +AC_SUBST(ISC_PLATFORM_HAVEXADD) +AC_SUBST(ISC_PLATFORM_HAVECMPXCHG) +AC_SUBST(ISC_PLATFORM_HAVEATOMICSTORE) + +AC_SUBST(ISC_PLATFORM_USEGCCASM) +AC_SUBST(ISC_PLATFORM_USEOSFASM) +AC_SUBST(ISC_PLATFORM_USESTDASM) +AC_SUBST(ISC_PLATFORM_USEMACASM) + +ISC_ARCH_DIR=$arch +AC_SUBST(ISC_ARCH_DIR) + +# +# The following sets up how non-blocking i/o is established. +# Sunos, cygwin and solaris 2.x (x<5) require special handling. +# +case "$host" in +*-sunos*) AC_DEFINE(PORT_NONBLOCK, O_NDELAY);; +*-cygwin*) AC_DEFINE(PORT_NONBLOCK, O_NDELAY);; +*-solaris2.[[01234]]) + AC_DEFINE(PORT_NONBLOCK, O_NONBLOCK) + AC_DEFINE(USE_FIONBIO_IOCTL, 1, + [Defined if you need to use ioctl(FIONBIO) instead a fcntl call to make non-blocking.]) + ;; +*) AC_DEFINE(PORT_NONBLOCK, O_NONBLOCK, + [Sets which flag to pass to open/fcntl to make non-blocking (O_NDELAY/O_NONBLOCK).]) + ;; +esac +# +# Solaris 2.5.1 and earlier cannot bind() then connect() a TCP socket. +# This prevents the source address being set. +# +case "$host" in +*-solaris2.[[012345]]|*-solaris2.5.1) + AC_DEFINE(BROKEN_TCP_BIND_BEFORE_CONNECT, 1, + [Define if you cannot bind() before connect() for TCP sockets.]) + ;; +esac +# +# The following sections deal with tools used for formatting +# the documentation. They are all optional, unless you are +# a developer editing the documentation source. +# + +# +# Look for TeX. +# + +AC_PATH_PROGS(LATEX, latex, latex) +AC_SUBST(LATEX) + +AC_PATH_PROGS(PDFLATEX, pdflatex, pdflatex) +AC_SUBST(PDFLATEX) + +# +# Look for w3m +# + +AC_PATH_PROGS(W3M, w3m, w3m) +AC_SUBST(W3M) + +# +# Look for xsltproc (libxslt) +# + +AC_PATH_PROG(XSLTPROC, xsltproc, xsltproc) +AC_SUBST(XSLTPROC) + +# +# Look for xmllint (libxml2) +# + +AC_PATH_PROG(XMLLINT, xmllint, xmllint) +AC_SUBST(XMLLINT) + +# +# Subroutine for searching for an ordinary file (e.g., a stylesheet) +# in a number of directories: +# +# NOM_PATH_FILE(VARIABLE, FILENAME, DIRECTORIES) +# +# If the file FILENAME is found in one of the DIRECTORIES, the shell +# variable VARIABLE is defined to its absolute pathname. Otherwise, +# it is set to FILENAME, with no directory prefix (that's not terribly +# useful, but looks less confusing in substitutions than leaving it +# empty). The variable VARIABLE will be substituted into output files. +# + +AC_DEFUN(NOM_PATH_FILE, [ +$1="" +AC_MSG_CHECKING(for $2) +for d in $3 +do + f=$d/$2 + if test -f $f + then + $1=$f + AC_MSG_RESULT($f) + break + fi +done +if test "X[$]$1" = "X" +then + AC_MSG_RESULT("not found"); + $1=$2 +fi +AC_SUBST($1) +]) + +# +# Look for Docbook-XSL stylesheets. Location probably varies by +# system. Guessing where it might be found, based on where SGML stuff +# lives on some systems. FreeBSD is the only one I'm sure of at the +# moment. +# + +docbook_xsl_trees="/usr/pkg/share/xsl /usr/local/share/xsl /usr/share/xsl" + +# +# Look for stylesheets we need. +# + +NOM_PATH_FILE(XSLT_DOCBOOK_STYLE_HTML, docbook/html/docbook.xsl, $docbook_xsl_trees) +NOM_PATH_FILE(XSLT_DOCBOOK_STYLE_XHTML, docbook/xhtml/docbook.xsl, $docbook_xsl_trees) +NOM_PATH_FILE(XSLT_DOCBOOK_STYLE_MAN, docbook/manpages/docbook.xsl, $docbook_xsl_trees) +NOM_PATH_FILE(XSLT_DOCBOOK_CHUNK_HTML, docbook/html/chunk.xsl, $docbook_xsl_trees) +NOM_PATH_FILE(XSLT_DOCBOOK_CHUNK_XHTML, docbook/xhtml/chunk.xsl, $docbook_xsl_trees) +NOM_PATH_FILE(XSLT_DOCBOOK_CHUNKTOC_HTML, docbook/html/chunktoc.xsl, $docbook_xsl_trees) +NOM_PATH_FILE(XSLT_DOCBOOK_CHUNKTOC_XHTML, docbook/xhtml/chunktoc.xsl, $docbook_xsl_trees) +NOM_PATH_FILE(XSLT_DOCBOOK_MAKETOC_HTML, docbook/html/maketoc.xsl, $docbook_xsl_trees) +NOM_PATH_FILE(XSLT_DOCBOOK_MAKETOC_XHTML, docbook/xhtml/maketoc.xsl, $docbook_xsl_trees) + +# +# Same dance for db2latex +# +# No idea where this lives except on FreeBSD. +# + +db2latex_xsl_trees="/usr/local/share" + +# +# Look for stylesheets we need. +# + +NOM_PATH_FILE(XSLT_DB2LATEX_STYLE, db2latex/xsl/docbook.xsl, $db2latex_xsl_trees) + +# +# Look for "admonition" image directory. Can't use NOM_PATH_FILE() +# because it's a directory, so just do the same things, inline. +# + +AC_MSG_CHECKING(for db2latex/xsl/figures) +for d in $db2latex_xsl_trees +do + dd=$d/db2latex/xsl/figures + if test -d $dd + then + XSLT_DB2LATEX_ADMONITIONS=$dd + AC_MSG_RESULT($dd) + break + fi +done +if test "X$XSLT_DB2LATEX_ADMONITIONS" = "X" +then + AC_MSG_RESULT(not found) + XSLT_DB2LATEX_ADMONITIONS=db2latex/xsl/figures +fi +AC_SUBST(XSLT_DB2LATEX_ADMONITIONS) + +# +# IDN support +# +AC_ARG_WITH(idn, + [ --with-idn[=MPREFIX] enable IDN support using idnkit [default PREFIX]], + use_idn="$withval", use_idn="no") +case "$use_idn" in +yes) + if test X$prefix = XNONE ; then + idn_path=/usr/local + else + idn_path=$prefix + fi + ;; +no) + ;; +*) + idn_path="$use_idn" + ;; +esac + +iconvinc= +iconvlib= +AC_ARG_WITH(libiconv, + [ --with-libiconv[=IPREFIX] GNU libiconv are in IPREFIX [default PREFIX]], + use_libiconv="$withval", use_libiconv="no") +case "$use_libiconv" in +yes) + if test X$prefix = XNONE ; then + iconvlib="-L/usr/local/lib -R/usr/local/lib -liconv" + else + iconvlib="-L$prefix/lib -R$prefix/lib -liconv" + fi + ;; +no) + iconvlib= + ;; +*) + iconvlib="-L$use_libiconv/lib -R$use_libiconv/lib -liconv" + ;; +esac + +AC_ARG_WITH(iconv, + [ --with-iconv[=LIBSPEC] specify iconv library [default -liconv]], + iconvlib="$withval") +case "$iconvlib" in +no) + iconvlib= + ;; +yes) + iconvlib=-liconv + ;; +esac + +AC_ARG_WITH(idnlib, + [ --with-idnlib=ARG specify libidnkit], + idnlib="$withval", idnlib="no") +if test "$idnlib" = yes; then + AC_MSG_ERROR([You must specify ARG for --with-idnlib.]) +fi + +IDNLIBS= +if test "$use_idn" != no; then + AC_DEFINE(WITH_IDN, 1, [define if idnkit support is to be included.]) + STD_CINCLUDES="$STD_CINCLUDES -I$idn_path/include" + if test "$idnlib" != no; then + IDNLIBS="$idnlib $iconvlib" + else + IDNLIBS="-L$idn_path/lib -lidnkit $iconvlib" + fi +fi +AC_SUBST(IDNLIBS) + +AC_CHECK_HEADERS(locale.h) +AC_CHECK_FUNCS(setlocale) + +# +# Substitutions +# +AC_SUBST(BIND9_TOP_BUILDDIR) +BIND9_TOP_BUILDDIR=`pwd` + +AC_SUBST(BIND9_ISC_BUILDINCLUDE) +AC_SUBST(BIND9_ISCCC_BUILDINCLUDE) +AC_SUBST(BIND9_ISCCFG_BUILDINCLUDE) +AC_SUBST(BIND9_DNS_BUILDINCLUDE) +AC_SUBST(BIND9_LWRES_BUILDINCLUDE) +AC_SUBST(BIND9_BIND9_BUILDINCLUDE) +if test "X$srcdir" != "X"; then + BIND9_ISC_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/isc/include" + BIND9_ISCCC_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/isccc/include" + BIND9_ISCCFG_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/isccfg/include" + BIND9_DNS_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/dns/include" + BIND9_LWRES_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/lwres/include" + BIND9_BIND9_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/bind9/include" +else + BIND9_ISC_BUILDINCLUDE="" + BIND9_ISCCC_BUILDINCLUDE="" + BIND9_ISCCFG_BUILDINCLUDE="" + BIND9_DNS_BUILDINCLUDE="" + BIND9_LWRES_BUILDINCLUDE="" + BIND9_BIND9_BUILDINCLUDE="" +fi + +AC_SUBST_FILE(BIND9_MAKE_INCLUDES) +BIND9_MAKE_INCLUDES=$BIND9_TOP_BUILDDIR/make/includes + +AC_SUBST_FILE(BIND9_MAKE_RULES) +BIND9_MAKE_RULES=$BIND9_TOP_BUILDDIR/make/rules + +. $srcdir/version +BIND9_VERSION="VERSION=${MAJORVER}.${MINORVER}.${PATCHVER}${RELEASETYPE}${RELEASEVER}" +AC_SUBST(BIND9_VERSION) + +AC_SUBST_FILE(LIBISC_API) +LIBISC_API=$srcdir/lib/isc/api + +AC_SUBST_FILE(LIBISCCC_API) +LIBISCCC_API=$srcdir/lib/isccc/api + +AC_SUBST_FILE(LIBISCCFG_API) +LIBISCCFG_API=$srcdir/lib/isccfg/api + +AC_SUBST_FILE(LIBDNS_API) +LIBDNS_API=$srcdir/lib/dns/api + +AC_SUBST_FILE(LIBBIND9_API) +LIBBIND9_API=$srcdir/lib/bind9/api + +AC_SUBST_FILE(LIBLWRES_API) +LIBLWRES_API=$srcdir/lib/lwres/api + +# +# Configure any DLZ drivers. +# +# If config.dlz.in selects one or more DLZ drivers, it will set +# USE_DLZ to a non-empty value, which will be our clue to +# enable the DLZ core functions. +# +# This section has to come after the libtool stuff because it needs to +# know how to name the driver object files. +# + +USE_DLZ="" +DLZ_DRIVER_INCLUDES="" +DLZ_DRIVER_LIBS="" +DLZ_DRIVER_SRCS="" +DLZ_DRIVER_OBJS="" + +sinclude(contrib/dlz/config.dlz.in) + +AC_MSG_CHECKING(for DLZ) + +if test -n "$USE_DLZ" +then + AC_MSG_RESULT(yes) + USE_DLZ="-DDLZ $USE_DLZ" + DLZ_DRIVER_RULES=contrib/dlz/drivers/rules + AC_CONFIG_FILES([$DLZ_DRIVER_RULES]) +else + AC_MSG_RESULT(no) + DLZ_DRIVER_RULES=/dev/null +fi + +AC_SUBST(USE_DLZ) +AC_SUBST(DLZ_DRIVER_INCLUDES) +AC_SUBST(DLZ_DRIVER_LIBS) +AC_SUBST(DLZ_DRIVER_SRCS) +AC_SUBST(DLZ_DRIVER_OBJS) +AC_SUBST_FILE(DLZ_DRIVER_RULES) + +if test "$cross_compiling" = "yes"; then + if test -z "$BUILD_CC"; then + AC_ERROR([BUILD_CC not set]) + fi + BUILD_CFLAGS="$BUILD_CFLAGS" + BUILD_CPPFLAGS="$BUILD_CPPFLAGS" + BUILD_LDFLAGS="$BUILD_LDFLAGS" + BUILD_LIBS="$BUILD_LIBS" +else + BUILD_CC="$CC" + BUILD_CFLAGS="$CFLAGS" + BUILD_CPPFLAGS="$CPPFLAGS $GEN_NEED_OPTARG" + BUILD_LDFLAGS="$LDFLAGS" + BUILD_LIBS="$LIBS" +fi + +AC_SUBST(BUILD_CC) +AC_SUBST(BUILD_CFLAGS) +AC_SUBST(BUILD_CPPFLAGS) +AC_SUBST(BUILD_LDFLAGS) +AC_SUBST(BUILD_LIBS) + +# +# Commands to run at the end of config.status. +# Don't just put these into configure, it won't work right if somebody +# runs config.status directly (which autoconf allows). +# + +AC_CONFIG_COMMANDS( + [chmod], + [chmod a+x isc-config.sh]) + +# +# Files to configure. These are listed here because we used to +# specify them as arguments to AC_OUTPUT. It's (now) ok to move these +# elsewhere if there's a good reason for doing so. +# + +AC_CONFIG_FILES([ + Makefile + make/Makefile + make/mkdep + lib/Makefile + lib/isc/Makefile + lib/isc/include/Makefile + lib/isc/include/isc/Makefile + lib/isc/include/isc/platform.h + lib/isc/unix/Makefile + lib/isc/unix/include/Makefile + lib/isc/unix/include/isc/Makefile + lib/isc/nls/Makefile + lib/isc/$thread_dir/Makefile + lib/isc/$thread_dir/include/Makefile + lib/isc/$thread_dir/include/isc/Makefile + lib/isc/$arch/Makefile + lib/isc/$arch/include/Makefile + lib/isc/$arch/include/isc/Makefile + lib/isccc/Makefile + lib/isccc/include/Makefile + lib/isccc/include/isccc/Makefile + lib/isccfg/Makefile + lib/isccfg/include/Makefile + lib/isccfg/include/isccfg/Makefile + lib/dns/Makefile + lib/dns/include/Makefile + lib/dns/include/dns/Makefile + lib/dns/include/dst/Makefile + lib/bind9/Makefile + lib/bind9/include/Makefile + lib/bind9/include/bind9/Makefile + lib/lwres/Makefile + lib/lwres/include/Makefile + lib/lwres/include/lwres/Makefile + lib/lwres/include/lwres/netdb.h + lib/lwres/include/lwres/platform.h + lib/lwres/man/Makefile + lib/lwres/unix/Makefile + lib/lwres/unix/include/Makefile + lib/lwres/unix/include/lwres/Makefile + lib/tests/Makefile + lib/tests/include/Makefile + lib/tests/include/tests/Makefile + bin/Makefile + bin/check/Makefile + bin/named/Makefile + bin/named/unix/Makefile + bin/rndc/Makefile + bin/rndc/unix/Makefile + bin/dig/Makefile + bin/nsupdate/Makefile + bin/tests/Makefile + bin/tests/names/Makefile + bin/tests/master/Makefile + bin/tests/rbt/Makefile + bin/tests/db/Makefile + bin/tests/tasks/Makefile + bin/tests/timers/Makefile + bin/tests/dst/Makefile + bin/tests/mem/Makefile + bin/tests/net/Makefile + bin/tests/sockaddr/Makefile + bin/tests/system/Makefile + bin/tests/system/conf.sh + bin/tests/system/lwresd/Makefile + bin/tests/system/tkey/Makefile + bin/tests/headerdep_test.sh + bin/dnssec/Makefile + doc/Makefile + doc/arm/Makefile + doc/misc/Makefile + isc-config.sh + doc/xsl/Makefile + doc/xsl/isc-docbook-chunk.xsl + doc/xsl/isc-docbook-html.xsl + doc/xsl/isc-docbook-latex.xsl + doc/xsl/isc-manpage.xsl +]) + +# +# Do it +# + +AC_OUTPUT + +if test "X$OPENSSL_WARNING" != "X"; then +cat << \EOF +WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +WARNING WARNING +WARNING Your OpenSSL crypto library may be vulnerable to WARNING +WARNING one or more of the the following known security WARNING +WARNING flaws: WARNING +WARNING WARNING +WARNING CAN-2002-0659, CAN-2006-4339, CVE-2006-2937 and WARNING +WARNING CVE-2006-2940. WARNING +WARNING WARNING +WARNING It is recommended that you upgrade to OpenSSL WARNING +WARNING version 0.9.8d/0.9.7l (or greater). WARNING +WARNING WARNING +WARNING You can disable this warning by specifying: WARNING +WARNING WARNING +WARNING --disable-openssl-version-check WARNING +WARNING WARNING +WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +EOF +fi + +# Tell Emacs to edit this file in shell mode. +# Local Variables: +# mode: sh +# End: diff --git a/contrib/bind9/CHANGES b/contrib/bind9/CHANGES deleted file mode 100644 index 06b6052..0000000 --- a/contrib/bind9/CHANGES +++ /dev/null @@ -1,7120 +0,0 @@ - - --- 9.4.2 released --- - --- 9.4.2rc2 released --- - -2259. [bug] Reverse incorrect LIBINTERFACE bump of libisc - in 9.4.2rc1. Applications built against 9.4.2rc1 - will need to be rebuilt. - -2258. [bug] Fallback from IXFR/TSIG to SOA/AXFR/TSIG broken. - [RT #17241] - -2257. [bug] win32: Use the full path to vcredist_x86.exe when - calling it. [RT #17222] - -2256. [bug] win32: Correctly register the installation location of - bindevt.dll. [RT #17159] - -2255. [bug] L.ROOT-SERVERS.NET is now 199.7.83.42. - -2254. [bug] timer.c:dispatch() failed to lock timer->lock - when reading timer->idle allowing it to see - intermediate values as timer->idle was reset by - isc_timer_touch(). [RT #17243] - - --- 9.4.2rc1 released --- - -2251. [doc] Update memstatistics-file documentation to reflect - reality. Note there is behaviour change for BIND 9.5. - [RT #17113] - -2249. [bug] Only set Authentic Data bit if client requested - DNSSEC, per RFC 3655 [RT #17175] - -2248. [cleanup] Fix several errors reported by Coverity. [RT #17160] - -2245. [bug] Validating lack of DS records at trust anchors wasn't - working. [RT #17151] - -2238. [bug] It was possible to trigger a REQUIRE when a - validation was cancelled. [RT #17106] - -2237. [bug] libbind: res_init() was not thread aware. [RT #17123] - -2236. [bug] dnssec-signzone failed to preserve the case of - of wildcard owner names. [RT #17085] - -2235. [bug] was not being installed. [RT #17135] - -2234. [port] Correct some compiler warnings on SCO OSr5 [RT #17134] - -2232. [bug] dns_adb_findaddrinfo() could fail and return - ISC_R_SUCCESS. [RT #17137] - -2231. [bug] Building dlzbdb (contrib/dlz/bin/dlzbdb) was broken. - [RT #17088] - -2230. [bug] We could INSIST reading a corrupted journal. - [RT #17132] - -2228. [contrib] contrib: Change 2188 was incomplete. - -2227. [cleanup] Tidied up the FAQ. [RT #17121] - -2225. [bug] More support for systems with no IPv4 addresses. - [RT #17111] - -2224. [bug] Defer journal compaction if a xfrin is in progress. - [RT #17119] - -2223. [bug] Make a new journal when compacting. [RT #17119] - -2221. [bug] Set the event result code to reflect the actual - record returned to caller when a cache update is - rejected due to a more credible answer existing. - [RT #17017] - -2220. [bug] win32: Address a race condition in final shutdown of - the Windows socket code. [RT #17028] - -2219. [bug] Apply zone consistancy checks to additions, not - removals, when updating. [RT #17049] - -2218. [bug] Remove unnecessary REQUIRE from dns_validator_create(). - [RT #16976] - -2216. [cleanup] Fix a number of errors reported by Coverity. - [RT #17094] - -2215. [bug] Bad REQUIRE check isc_hmacsha1_verify(). [RT #17094] - -2214. [bug] Deregister OpenSSL lock callback when cleaning - up. Reorder OpenSSL cleanup so that RAND_cleanup() - is called before the locks are destroyed. [RT #17098] - -2213. [bug] SIG0 diagnostic failure messages were looking at the - wrong status code. [RT #17101] - -2212. [func] 'host -m' now causes memory statistics and active - memory to be printed at exit. [RT 17028] - -2210. [bug] Deleting class specific records via UPDATE could - fail. [RT #17074] - -2209. [port] osx: linking against user supplied static OpenSSL - libraries failed as the system ones were still being - found. [RT #17078] - -2208. [port] win32: make sure both build methods produce the - same output. [RT #17058] - -2207. [port] Some implementations of getaddrinfo() fail to set - ai_canonname correctly. [RT #17061] - - --- 9.4.2b1 released --- - -2206. [security] "allow-query-cache" and "allow-recursion" now - cross inherit from each other. - - If allow-query-cache is not set in named.conf then - allow-recursion is used if set, otherwise allow-query - is used if set, otherwise the default (localnets; - localhost;) is used. - - If allow-recursion is not set in named.conf then - allow-query-cache is used if set, otherwise allow-query - is used if set, otherwise the default (localnets; - localhost;) is used. - - [RT #16987] - -2205. [bug] libbind: change #2119 broke thread support. [RT #16982] - -2203. [security] Query id generation was cryptographically weak. - [RT # 16915] - -2202. [security] The default acls for allow-query-cache and - allow-recursion were not being applied. [RT #16960] - -2200. [bug] The search for cached NSEC records was stopping to - early leading to excessive DLV queries. [RT #16930] - -2199. [bug] win32: don't call WSAStartup() while loading dlls. - [RT #16911] - -2198. [bug] win32: RegCloseKey() could be called when - RegOpenKeyEx() failed. [RT #16911] - -2197. [bug] Add INSIST to catch negative responses which are - not setting the event result code appropriately. - [RT #16909] - -2196. [port] win32: yield processor while waiting for once to - to complete. [RT #16958] - -2194. [bug] Close journal before calling 'done' in xfrin.c. - -2193. [port] win32: BINDInstall.exe is now linked statically. - [RT #16906] - -2192. [port] win32: use vcredist_x86.exe to install Visual - Studio's redistributable dlls if building with - Visual Stdio 2005 or later. - -2189. [bug] Handle socket() returning EINTR. [RT #15949] - -2188. [contrib] queryperf: autoconf changes to make the search for - libresolv or libbind more robust. [RT #16299] - -2187. [bug] query_addds(), query_addwildcardproof() and - query_addnxrrsetnsec() should take a version - arguement. [RT #16368] - -2186. [port] cygwin: libbind: check for struct sockaddr_storage - independently of IPv6. [RT #16482] - -2185. [port] sunos: libbind: check for ssize_t, memmove() and - memchr(). [RT #16463] - -2183. [bug] dnssec-signzone didn't handle offline private keys - well. [RT #16832] - -2182. [bug] dns_dispatch_createtcp() and dispatch_createudp() - could return ISC_R_SUCCESS when they ran out of - memory. [RT #16365] - -2181. [port] sunos: libbind: add paths.h from BIND 8. [RT #16462] - -2180. [cleanup] Remove bit test from 'compress_test' as they - are no longer needed. [RT #16497] - -2178. [bug] 'rndc reload' of a slave or stub zone resulted in - a reference leak. [RT #16867] - -2177. [bug] Array bounds overrun on read (rcodetext) at - debug level 10+. [RT #16798] - -2176. [contrib] dbus update to handle race condition during - initialisation (Bugzilla 235809). [RT #16842] - -2175. [bug] win32: windows broadcast condition variable support - was broken. [RT #16592] - -2174. [bug] I/O errors should always be fatal when reading - master files. [RT #16825] - -2173. [port] win32: When compiling with MSVS 2005 SP1 we also - need to ship Microsoft.VC80.MFCLOC. - -2171. [bug] Handle breaks in DNSSEC trust chains where the parent - servers are not DS aware (DS queries to the parent - return a referral to the child). - -2170. [func] Add acache processing to test suite. [RT #16711] - -2169. [bug] host, nslookup: when reporting NXDOMAIN report the - given name and not the last name searched for. - [RT #16763] - -2168. [bug] nsupdate: in non-interactive mode treat syntax errors - as fatal errors. [RT #16785] - -2167. [bug] When re-using a automatic zone named failed to - attach it to the new view. [RT #16786] - -2166. [bug] When running in batch mode, dig could misinterpret - a server address as a name to be looked up, causing - unexpected output. [RT #16743] - -2164. [bug] The code to determine how named-checkzone / - named-compilezone was called failed under windows. - [RT #16764] - -2162. [func] Allow "rrset-order fixed" to be disabled at compile - time. [RT #16665] - -2161. [bug] 'rndc flush' could report a false success. [RT #16698] - -2160. [bug] libisc wasn't handling NULL ifa_addr pointers returned - from getifaddrs(). [RT #16708] - -2159. [bug] Array bounds overrun in acache processing. [RT #16710] - -2158. [bug] ns_client_isself() failed to initialise key - leading to a REQUIRE failure. [RT #16688] - -2156. [bug] Fix node reference leaks in lookup.c:lookup_find(), - resolver.c:validated() and resolver.c:cache_name(). - Fix a memory leak in rbtdb.c:free_noqname(). - Make lookup.c:lookup_find() robust against - event leaks. [RT #16685] - -2155. [contrib] SQLite sdb module from jaboydjr@netwalk.com. - [RT #16694] - -2153. [bug] nsupdate could leak memory. [RT #16691] - -2152. [cleanup] Use sizeof(buf) instead of fixed number in - dighost.c:get_trusted_key(). [RT #16678] - -2151. [bug] Missing newline in usage message for journalprint. - [RT #16679] - -2150. [bug] 'rrset-order cyclic' uniformly distribute the - starting point for the first response for a given - RRset. [RT #16655] - -2149. [bug] isc_mem_checkdestroyed() failed to abort on - if there were still active memory contexts. - [RT #16672] - -2147. [bug] libbind: remove potential buffer overflow from - hmac_link.c. [RT #16437] - -2146. [cleanup] Silence Linux's spurious "obsolete setsockopt - SO_BSDCOMPAT" message. [RT #16641] - -2145. [bug] Check DS/DLV digest lengths for known digests. - [RT #16622] - -2144. [cleanup] Suppress logging of SERVFAIL from forwarders. - [RT #16619] - -2143. [bug] We failed to restart the IPv6 client when the - kernel failed to return the destination the - packet was sent to. [RT #16613] - -2142. [bug] Handle master files with a modification time that - matches the epoch. [RT# 16612] - -2141. [bug] dig/host should not be setting IDN_ASCCHECK (IDN - equivalent of LDH checks). [RT #16609] - -2140. [bug] libbind: missing unlock on pthread_key_create() - failures. [RT #16654] - -2139. [bug] dns_view_find() was being called with wrong type - in adb.c. [RT #16670] - -2119. [compat] libbind: allow res_init() to succeed enough to - return the default domain even if it was unable - to allocate memory. - - --- 9.4.1 released --- - -2172. [bug] query_addsoa() was being called with a non zone db. - [RT #16834] - - --- 9.4.0 released --- - -2138. [bug] Lock order reversal in resolver.c. [RT #16653] - -2137. [port] Mips little endian and/or mips 64 bit are now - supported for atomic operations. [RT#16648] - -2136. [bug] nslookup/host looped if there was no search list - and the host didn't exist. [RT #16657] - -2135. [bug] Uninitialised rdataset in sdlz.c. [RT# 16656] - -2133. [port] powerpc: Support both IBM and MacOS Power PC - assembler syntaxes. [RT #16647] - -2132. [bug] Missing unlock on out of memory in - dns_dispatchmgr_setudp(). - -2131. [contrib] dlz/mysql: AXFR was broken. [RT #16630] - -2128. [doc] xsltproc --nonet, update DTD versions. [RT #16635] - - --- 9.4.0rc2 released --- - -2127. [port] Improved OpenSSL 0.9.8 support. [RT #16563] - -2126. [security] Serialise validation of type ANY responses. [RT #16555] - -2125. [bug] dns_zone_getzeronosoattl() REQUIRE failure if DLZ - was defined. [RT #16574] - -2124. [security] It was possible to dereference a freed fetch - context. [RT #16584] - -2120. [doc] Fix markup on nsupdate man page. [RT #16556] - - --- 9.4.0rc1 released --- - -2118. [bug] Handle response with long chains of domain name - compression pointers which point to other compression - pointers. [RT #16427] - -2117. [bug] DNSSEC fixes: named could fail to cache NSEC records - which could lead to validation failures. named didn't - handle negative DS responses that were in the process - of being validated. Check CNAME bit before accepting - NODATA proof. To be able to ignore a child NSEC there - must be SOA (and NS) set in the bitmap. [RT #16399] - -2116. [bug] 'rndc reload' could cause the cache to continually - be cleaned. [RT #16401] - -2115. [bug] 'rndc reconfig' could trigger a INSIST if the - number of masters for a zone was reduced. [RT #16444] - -2114. [bug] dig/host/nslookup: searches for names with multiple - labels were failing. [RT #16447] - -2113. [bug] nsupdate: if a zone is specified it should be used - for server discover. [RT# 16455] - -2112. [security] Warn if weak RSA exponent is used. [RT #16460] - -2111. [bug] Fix a number of errors reported by Coverity. - [RT #16507] - -2110. [bug] "minimal-response yes;" interacted badly with BIND 8 - priming queries. [RT #16491] - -2109. [port] libbind: silence aix 5.3 compiler warnings. [RT #16502] - -2107. [bug] dighost.c: more cleanup of buffers. [RT #16499] - -2104. [port] Fix Solaris SMF error message. - -2103. [port] Add /usr/sfw to list of locations for OpenSSL - under Solaris. - -2102. [port] Silence solaris 10 warnings. - - --- 9.4.0b4 released --- - -2101. [bug] OpenSSL version checks were not quite right. - [RT #16476] - -2100. [port] win32: copy libeay32.dll to Build\Debug. - Copy Debug\named-checkzone to Debug\named-compilezone. - -2099. [port] win32: more manifiest issues. - -2098. [bug] Race in rbtdb.c:no_references(), which occasionally - triggered an INSIST failure about the node lock - reference. [RT #16411] - - --- 9.4.0b3 released --- - -2097. [bug] named could reference a destroyed memory context - after being reloaded / reconfigured. [RT #16428] - -2096. [bug] libbind: handle applications that fail to detect - res_init() failures better. - -2095. [port] libbind: alway prototype inet_cidr_ntop_ipv6() and - net_cidr_ntop_ipv6(). [RT #16388] - -2094. [contrib] Update named-bootconf. [RT# 16404] - -2093. [bug] named-checkzone -s was broken. - -2092. [bug] win32: dig, host, nslookup. Use registry config - if resolv.conf does not exist or no nameservers - listed. [RT #15877] - -2091. [port] dighost.c: race condition on cleanup. [RT #16417] - -2090. [port] win32: Visual C++ 2005 command line manifest support. - [RT #16417] - -2089. [security] Raise the minimum safe OpenSSL versions to - OpenSSL 0.9.7l and OpenSSL 0.9.8d. Versions - prior to these have known security flaws which - are (potentially) exploitable in named. [RT #16391] - -2088. [security] Change the default RSA exponent from 3 to 65537. - [RT #16391] - -2087. [port] libisc failed to compile on OS's w/o a vsnprintf. - [RT #16382] - -2086. [port] libbind: FreeBSD now has get*by*_r() functions. - [RT #16403] - -2085. [doc] win32: added index.html and README to zip. [RT #16201] - -2084. [contrib] dbus update for 9.3.3rc2. - -2083. [port] win32: Visual C++ 2005 support. - -2082. [doc] Document 'cache-file' as a test only option. - - --- 9.4.0b2 released --- - -2081. [port] libbind: minor 64-bit portability fix in memcluster.c. - [RT #16360] - -2080. [port] libbind: res_init.c did not compile on older versions - of Solaris. [RT #16363] - -2079. [bug] The lame cache was not handling multiple types - correctly. [RT #16361] - -2078. [bug] dnssec-checkzone output style "default" was badly - named. It is now called "relative". [RT #16326] - -2077. [bug] 'dnssec-signzone -O raw' wasn't outputing the - complete signed zone. [RT #16326] - -2076. [bug] Several files were missing #include - causing build failures on OSF. [RT #16341] - -2075. [bug] The spillat timer event hander could leak memory. - [RT #16357] - -2074. [bug] dns_request_createvia2(), dns_request_createvia3(), - dns_request_createraw2() and dns_request_createraw3() - failed to send multiple UDP requests. [RT #16349] - -2073. [bug] Incorrect semantics check for update policy "wildcard". - [RT #16353] - -2072. [bug] We were not generating valid HMAC SHA digests. - [RT #16320] - -2071. [port] Test whether gcc accepts -fno-strict-aliasing. - [RT #16324] - -2070. [bug] The remote address was not always displayed when - reporting dispatch failures. [RT #16315] - -2069. [bug] Cross compiling was not working. [RT #16330] - -2068. [cleanup] Lower incremental tuning message to debug 1. - [RT #16319] - -2067. [bug] 'rndc' could close the socket too early triggering - a INSIST under Windows. [RT #16317] - -2066. [security] Handle SIG queries gracefully. [RT #16300] - -2065. [bug] libbind: probe for HPUX prototypes for - endprotoent_r() and endservent_r(). [RT 16313] - -2064. [bug] libbind: silence AIX compiler warnings. [RT #16218] - -2063. [bug] Change #1955 introduced a bug which caused the first - 'rndc flush' call to not free memory. [RT #16244] - -2062. [bug] 'dig +nssearch' was reusing a buffer before it had - been returned by the socket code. [RT #16307] - -2061. [bug] Accept expired wildcard message reversed. [RT #16296] - -2060. [bug] Enabling DLZ support could leave views partially - configured. [RT #16295] - - --- 9.4.0b1 released --- - -2059. [bug] Search into cache rbtdb could trigger an INSIST - failure while cleaning up a stale rdataset. - [RT #16292] - -2058. [bug] Adjust how we calculate rtt estimates in the presence - of authoritative servers that drop EDNS and/or CD - requests. Also fallback to EDNS/512 and plain DNS - faster for zones with less than 3 servers. [RT #16187] - -2057. [bug] Make setting "ra" dependent on both allow-query-cache - and allow-recursion. [RT #16290] - -2056. [bug] dig: ixfr= was not being treated case insensitively - at all times. [RT #15955] - -2055. [bug] Missing goto after dropping multicast query. - [RT #15944] - -2054. [port] freebsd: do not explicitly link against -lpthread. - [RT #16170] - -2053. [port] netbsd:libbind: silence compiler warnings. [RT #16220] - -2052. [bug] 'rndc' improve connect failed message to report - the failing address. [RT #15978] - -2051. [port] More strtol() fixes. [RT #16249] - -2050. [bug] Parsing of NSAP records was not case insensitive. - [RT #16287] - -2049. [bug] Restore SOA before AXFR when falling back from - a attempted IXFR when transfering in a zone. - Allow a initial SOA query before attempting - a AXFR to be requested. [RT #16156] - -2048. [bug] It was possible to loop forever when using - avoid-v4-udp-ports / avoid-v6-udp-ports when - the OS always returned the same local port. - [RT #16182] - -2047. [bug] Failed to initialise the interface flags to zero. - [RT #16245] - -2046. [bug] rbtdb.c:rdataset_setadditional() could cause duplicate - cleanup [RT #16247]. - -2045. [func] Use lock buckets for acache entries to limit memory - consumption. [RT #16183] - -2044. [port] Add support for atomic operations for Itanium. - [RT #16179] - -2043. [port] nsupdate/nslookup: Force the flushing of the prompt - for interactive sessions. [RT#16148] - -2042. [bug] named-checkconf was incorrectly rejecting the - logging category "config". [RT #16117] - -2041. [bug] "configure --with-dlz-bdb=yes" produced a bad - set of libraries to be linked. [RT #16129] - -2040. [bug] rbtdb no_references() could trigger an INSIST - failure with --enable-atomic. [RT #16022] - -2039. [func] Check that all buffers passed to the socket code - have been retrieved when the socket event is freed. - [RT #16122] - -2038. [bug] dig/nslookup/host was unlinking from wrong list - when handling errors. [RT #16122] - -2037. [func] When unlinking the first or last element in a list - check that the list head points to the element to - be unlinked. [RT #15959] - -2036. [bug] 'rndc recursing' could cause trigger a REQUIRE. - [RT #16075] - -2034. [bug] gcc: set -fno-strict-aliasing. [RT #16124] - -2033. [bug] We wern't creating multiple client memory contexts - on demand as expected. [RT #16095] - - --- 9.4.0a6 released --- - -2032. [bug] Remove a INSIST in query_addadditional2(). [RT #16074] - -2031. [bug] Emit a error message when "rndc refresh" is called on - a non slave/stub zone. [RT # 16073] - -2030. [bug] We were being overly conservative when disabling - openssl engine support. [RT #16030] - -2029. [bug] host printed out the server multiple times when - specified on the command line. [RT #15992] - -2028. [port] linux: socket.c compatability for old systems. - [RT #16015] - -2027. [port] libbind: Solaris x86 support. [RT #16020] - -2026. [bug] Rate limit the two recursive client exceeded messages. - [RT #16044] - -2025. [func] Update "zone serial unchanged" message. [RT #16026] - -2024. [bug] named emited spurious "zone serial unchanged" - messages on reload. [RT #16027] - -2023. [bug] "make install" should create ${localstatedir}/run and - ${sysconfdir} if they do not exist. [RT #16033] - -2022. [bug] If dnssec validation is disabled only assert CD if - CD was requested. [RT #16037] - -2021. [bug] dnssec-enable no; triggered a REQUIRE. [RT #16037] - -2020. [bug] rdataset_setadditional() could leak memory. [RT #16034] - -2019. [tuning] Reduce the amount of work performed per quantum - when cleaning the cache. [RT #15986] - -2018. [bug] Checking if the HMAC MD5 private file was broken. - [RT #15960] - -2017. [bug] allow-query default was not correct. [RT #15946] - -2016. [bug] Return a partial answer if recursion is not - allowed but requested and we had the answer - to the original qname. [RT #15945] - - --- 9.4.0a5 released --- - -2015. [cleanup] use-additional-cache is now acache-enable for - consistancy. Default acache-enable off in BIND 9.4 - as it requires memory usage to be configured. - It may be enabled by default in BIND 9.5 once we - have more experience with it. - -2014. [func] Statistics about acache now recorded and sent - to log. [RT #15976] - -2013. [bug] Handle unexpected TSIGs on unsigned AXFR/IXFR - responses more gracefully. [RT #15941] - -2012. [func] Don't insert new acache entries if acache is full. - [RT #15970] - -2011. [func] dnssec-signzone can now update the SOA record of - the signed zone, either as an increment or as the - system time(). [RT #15633] - - --- 9.4.0a4 released --- - -2009. [bug] libbind: coverity fixes. [RT #15808] - -2008. [func] It is now posssible to enable/disable DNSSEC - validation from rndc. This is useful for the - mobile hosts where the current connection point - breaks DNSSEC (firewall/proxy). [RT #15592] - - rndc validation newstate [view] - -2007. [func] It is now possible to explicitly enable DNSSEC - validation. default dnssec-validation no; to - be changed to yes in 9.5.0. [RT #15674] - -2006. [security] Allow-query-cache and allow-recursion now default - to the builtin acls "localnets" and "localhost". - - This is being done to make caching servers less - attractive as reflective amplifying targets for - spoofed traffic. This still leave authoritative - servers exposed. - - The best fix is for full BCP 38 deployment to - remove spoofed traffic. - -2005. [bug] libbind: Retransmission timeouts should be - based on which attempt it is to the nameserver - and not the nameserver itself. [RT #13548] - -2004. [bug] dns_tsig_sign() could pass a NULL pointer to - dst_context_destroy() when cleaning up after a - error. [RT #15835] - -2003. [bug] libbind: The DNS name/address lookup functions could - occasionally follow a random pointer due to - structures not being completely zeroed. [RT #15806] - -2002. [bug] libbind: tighten the constraints on when - struct addrinfo._ai_pad exists. [RT #15783] - -2001. [func] Check the KSK flag when updating a secure dynamic zone. - New zone option "update-check-ksk yes;". [RT #15817] - -2000. [bug] memmove()/strtol() fix was incomplete. [RT #15812] - -1999. [func] Implement "rrset-order fixed". [RT #13662] - -1998. [bug] Restrict handling of fifos as sockets to just SunOS. - This allows named to connect to entropy gathering - daemons that use fifos instead of sockets. [RT #15840] - -1997. [bug] Named was failing to replace negative cache entries - when a positive one for the type was learnt. - [RT #15818] - -1996. [bug] nsupdate: if a zone has been specified it should - appear in the output of 'show'. [RT #15797] - -1995. [bug] 'host' was reporting multiple "is an alias" messages. - [RT #15702] - -1994. [port] OpenSSL 0.9.8 support. [RT #15694] - -1993. [bug] Log messsage, via syslog, were missing the space - after the timestamp if "print-time yes" was specified. - [RT #15844] - -1992. [bug] Not all incoming zone transfer messages included the - view. [RT #15825] - -1991. [cleanup] The configuration data, once read, should be treated - as readonly. Expand the use of const to enforce this - at compile time. [RT #15813] - -1990. [bug] libbind: isc's override of broken gettimeofday() - implementions was not always effective. - [RT #15709] - -1989. [bug] win32: don't check the service password when - re-installing. [RT #15882] - -1988. [bug] Remove a bus error from the SHA256/SHA512 support. - [RT #15878] - -1987. [func] DS/DLV SHA256 digest algorithm support. [RT #15608] - -1986. [func] Report when a zone is removed. [RT #15849] - -1985. [protocol] DLV has now been assigned a official type code of - 32769. [RT #15807] - - Note: care should be taken to ensure you upgrade - both named and dnssec-signzone at the same time for - zones with DLV records where named is the master - server for the zone. Also any zones that contain - DLV records should be removed when upgrading a slave - zone. You do not however have to upgrade all - servers for a zone with DLV records simultaniously. - -1984. [func] dig, nslookup and host now advertise a 4096 byte - EDNS UDP buffer size by default. [RT #15855] - -1983. [func] Two new update policies. "selfsub" and "selfwild". - [RT #12895] - -1982. [bug] DNSKEY was being accepted on the parent side of - a delegation. KEY is still accepted there for - RFC 3007 validated updates. [RT #15620] - -1981. [bug] win32: condition.c:wait() could fail to reattain - the mutex lock. - -1980. [func] dnssec-signzone: output the SOA record as the - first record in the signed zone. [RT #15758] - -1979. [port] linux: allow named to drop core after changing - user ids. [RT #15753] - -1978. [port] Handle systems which have a broken recvmsg(). - [RT #15742] - -1977. [bug] Silence noisy log message. [RT #15704] - -1976. [bug] Handle systems with no IPv4 addresses. [RT #15695] - -1975. [bug] libbind: isc_gethexstring() could misparse multi-line - hex strings with comments. [RT #15814] - -1974. [doc] List each of the zone types and associated zone - options separately in the ARM. - -1973. [func] TSIG HMACSHA1, HMACSHA224, HMACSHA256, HMACSHA384 and - HMACSHA512 support. [RT #13606] - -1972. [contrib] DBUS dynamic forwarders integation from - Jason Vas Dias . - -1971. [port] linux: make detection of missing IF_NAMESIZE more - robust. [RT #15443] - -1970. [bug] nsupdate: adjust UDP timeout when falling back to - unsigned SOA query. [RT #15775] - -1969. [bug] win32: the socket code was freeing the socket - structure too early. [RT #15776] - -1968. [bug] Missing lock in resolver.c:validated(). [RT #15739] - -1967. [func] dig/nslookup/host: warn about missing "QR". [RT #15779] - -1966. [bug] Don't set CD when we have fallen back to plain DNS. - [RT #15727] - -1965. [func] Suppress spurious "recusion requested but not - available" warning with 'dig +qr'. [RT #15780]. - -1964. [func] Separate out MX and SRV to CNAME checks. [RT #15723] - -1963. [port] Tru64 4.0E doesn't support send() and recv(). - [RT #15586] - -1962. [bug] Named failed to clear old update-policy when it - was removed. [RT #15491] - -1961. [bug] Check the port and address of responses forwarded - to dispatch. [RT #15474] - -1960. [bug] Update code should set NSEC ttls from SOA MINIMUM. - [RT #15465] - -1959. [func] Control the zeroing of the negative response TTL to - a soa query. Defaults "zero-no-soa-ttl yes;" and - "zero-no-soa-ttl-cache no;". [RT #15460] - -1958. [bug] Named failed to update the zone's secure state - until the zone was reloaded. [RT #15412] - -1957. [bug] Dig mishandled responses to class ANY queries. - [RT #15402] - -1956. [bug] Improve cross compile support, 'gen' is now built - by native compiler. See README for additional - cross compile support information. [RT #15148] - -1955. [bug] Pre-allocate the cache cleaning interator. [RT #14998] - -1954. [func] Named now falls back to advertising EDNS with a - 512 byte receive buffer if the initial EDNS queries - fail. [RT #14852] - -1953. [func] The maximum EDNS UDP response named will send can - now be set in named.conf (max-udp-size). This is - independent of the advertised receive buffer - (edns-udp-size). [RT #14852] - -1952. [port] hpux: tell the linker to build a runtime link - path "-Wl,+b:". [RT #14816]. - -1951. [security] Drop queries from particular well known ports. - Don't return FORMERR to queries from particular - well known ports. [RT #15636] - -1950. [port] Solaris 2.5.1 and earlier cannot bind() then connect() - a TCP socket. This prevents the source address being - set for TCP connections. [RT #15628] - -1949. [func] Addition memory leakage checks. [RT #15544] - -1948. [bug] If was possible to trigger a REQUIRE failure in - xfrin.c:maybe_free() if named ran out of memory. - [RT #15568] - -1947. [func] It is now possible to configure named to accept - expired RRSIGs. Default "dnssec-accept-expired no;". - Setting "dnssec-accept-expired yes;" leaves named - vulnerable to replay attacks. [RT #14685] - -1946. [bug] resume_dslookup() could trigger a REQUIRE failure - when using forwarders. [RT #15549] - -1945. [cleanup] dnssec-keygen: RSA (RSAMD5) is nolonger recommended. - To generate a RSAMD5 key you must explicitly request - RSAMD5. [RT #13780] - -1944. [cleanup] isc_hash_create() does not need a read/write lock. - [RT #15522] - -1943. [bug] Set the loadtime after rolling forward the journal. - [RT #15647] - -1597. [func] Allow notify-source and query-source to be specified - on a per server basis similar to transfer-source. - [RT #6496] - - --- 9.4.0a3 released --- - -1942. [bug] If the name of a DNSKEY match that of one in - trusted-keys do not attempt to validate the DNSKEY - using the parents DS RRset. [RT #15649] - -1941. [bug] ncache_adderesult() should set eresult even if no - rdataset is passed to it. [RT #15642] - -1940. [bug] Fixed a number of error conditions reported by - Coverity. - -1939. [bug] The resolver could dereference a null pointer after - validation if all the queries have timed out. - [RT #15528] - -1938. [bug] The validator was not correctly handling unsecure - negative responses at or below a SEP. [RT #15528] - -1937. [bug] sdlz doesn't handle RRSIG records. [RT #15564] - -1936. [bug] The validator could leak memory. [RT #15544] - -1935. [bug] 'acache' was DO sensitive. [RT #15430] - -1934. [func] Validate pending NS RRsets, in the authority section, - prior to returning them if it can be done without - requiring DNSKEYs to be fetched. [RT #15430] - -1919. [contrib] queryperf: a set of new features: collecting/printing - response delays, printing intermediate results, and - adjusting query rate for the "target" qps. - - --- 9.4.0a2 released --- - -1933. [bug] dump_rdataset_raw() had a incorrect INSIST. [RT #15534] - -1932. [bug] hpux: LDFLAGS was getting corrupted. [RT #15530] - -1931. [bug] Per-client mctx could require a huge amount of memory, - particularly for a busy caching server. [RT #15519] - -1930. [port] HPUX: ia64 support. [RT #15473] - -1929. [port] FreeBSD: extend use of PTHREAD_SCOPE_SYSTEM. - -1928. [bug] Race in rbtdb.c:currentversion(). [RT #15517] - -1927. [bug] Access to soanode or nsnode in rbtdb violated the - lock order rule and could cause a dead lock. - [RT# 15518] - -1926. [bug] The Windows installer did not check for empty - passwords. BINDinstall was being installed in - the wrong place. [RT #15483] - -1925. [port] All outer level AC_TRY_RUNs need cross compiling - defaults. [RT #15469] - -1924. [port] libbind: hpux ia64 support. [RT #15473] - -1923. [bug] ns_client_detach() called too early. [RT #15499] - -1922. [bug] check-tool.c:setup_logging() missing call to - dns_log_setcontext(). - -1921. [bug] Client memory contexts were not using internal - malloc. [RT# 15434] - -1920. [bug] The cache rbtdb lock array was too small to - have the desired performance characteristics. - [RT #15454] - - --- 9.4.0a1 released --- - -1918. [bug] Memory leak when checking acls. [RT #15391] - -1917. [doc] funcsynopsisinfo wasn't being treated as verbatim - when generating man pages. [RT #15385] - -1916. [func] Integrate contibuted IDN code from JPNIC. [RT #15383] - -1915. [bug] dig +ndots was broken. [RT #15215] - -1914. [protocol] DS is required to accept mnemonic algorithms - (RFC 4034). Still emit numeric algorithms for - compatability with RFC 3658. [RT #15354] - -1913. [func] Integrate contibuted DLZ code into named. [RT #11382] - -1912. [port] aix: atomic locking for powerpc. [RT #15020] - -1911. [bug] Update windows socket code. [RT #14965] - -1910. [bug] dig's +sigchase code overhauled. [RT #14933] - -1909. [bug] The DLV code has been re-worked to make no longer - query order sensitive. [RT #14933] - -1908. [func] dig now warns if 'RA' is not set in the answer when - 'RD' was set in the query. host/nslookup skip servers - that fail to set 'RA' when 'RD' is set unless a server - is explicitly set. [RT #15005] - -1907. [func] host/nslookup now continue (default)/fail on SERVFAIL. - [RT #15006] - -1906. [func] dig now has a '-q queryname' and '+showsearch' options. - [RT #15034] - -1905. [bug] Strings returned from cfg_obj_asstring() should be - treated as read-only. The prototype for - cfg_obj_asstring() has been updated to reflect this. - [RT #15256] - -1904. [func] Automatic empty zone creation for D.F.IP6.ARPA and - friends. Note: RFC 1918 zones are not yet covered by - this but are likely to be in a future release. - - New options: empty-server, empty-contact, - empty-zones-enable and disable-empty-zone. - -1903. [func] ISC string copy API. - -1902. [func] Attempt to make the amount of work performed in a - iteration self tuning. The covers nodes clean from - the cache per iteration, nodes written to disk when - rewriting a master file and nodes destroyed per - iteration when destroying a zone or a cache. - [RT #14996] - -1901. [cleanup] Don't add DNSKEY records to the additional section. - -1900. [bug] ixfr-from-differences failed to ensure that the - serial number increased. [RT #15036] - -1899. [func] named-checkconf now validates update-policy entries. - [RT #14963] - -1898. [bug] Extend ISC_SOCKADDR_FORMATSIZE and - ISC_NETADDR_FORMATSIZE to allow for scope details. - -1897. [func] x86 and x86_64 now have separate atomic locking - implementations. - -1896. [bug] Recursive clients soft quota support wasn't working - as expected. [RT #15103] - -1895. [bug] A escaped character is, potentially, converted to - the output character set too early. [RT #14666] - -1894. [doc] Review ARM for BIND 9.4. - -1893. [port] Use uintptr_t if available. [RT #14606] - -1892. [func] Support for SPF rdata type. [RT #15033] - -1891. [port] freebsd: pthread_mutex_init can fail if it runs out - of memory. [RT #14995] - -1890. [func] Raise the UDP recieve buffer size to 32k if it is - less than 32k. [RT #14953] - -1889. [port] sunos: non blocking i/o support. [RT #14951] - -1888. [func] Support for IPSECKEY rdata type. [RT #14967] - -1887. [bug] The cache could delete expired records too fast for - clients with a virtual time in the past. [RT #14991] - -1886. [bug] fctx_create() could return success even though it - failed. [RT #14993] - -1885. [func] dig: report the number of extra bytes still left in - the packet after processing all the records. - -1884. [cleanup] dighost.c: move external declarations into . - -1883. [bug] dnssec-signzone, dnssec-keygen: handle negative debug - levels. [RT #14962] - -1882. [func] Limit the number of recursive clients that can be - waiting for a single query () to - resolve. New options clients-per-query and - max-clients-per-query. - -1881. [func] Add a system test for named-checkconf. [RT #14931] - -1880. [func] The lame cache is now done on a - basis as some servers only appear to be lame for - certain query types. [RT #14916] - -1879. [func] "USE INTERNAL MALLOC" is now runtime selectable. - [RT #14892] - -1878. [func] Detect duplicates of UDP queries we are recursing on - and drop them. New stats category "duplicate". - [RT #2471] - -1877. [bug] Fix unreasonably low quantum on call to - dns_rbt_destroy2(). Remove unnecessay unhash_node() - call. [RT #14919] - -1876. [func] Additional memory debugging support to track size - and mctx arguments. [RT #14814] - -1875. [bug] process_dhtkey() was using the wrong memory context - to free some memory. [RT #14890] - -1874. [port] sunos: portability fixes. [RT #14814] - -1873. [port] win32: isc__errno2result() now reports its caller. - [RT #13753] - -1872. [port] win32: Handle ERROR_NETNAME_DELETED. [RT #13753] - -1870. [func] Added framework for handling multiple EDNS versions. - [RT #14873] - -1869. [func] dig can now specify the EDNS version when making - a query. [RT #14873] - -1868. [func] edns-udp-size can now be overridden on a per - server basis. [RT #14851] - -1867. [bug] It was possible to trigger a INSIST in - dlv_validatezonekey(). [RT #14846] - -1866. [bug] resolv.conf parse errors were being ignored by - dig/host/nslookup. [RT #14841] - -1865. [bug] Silently ignore nameservers in /etc/resolv.conf with - bad addresses. [RT #14841] - -1864. [bug] Don't try the alternative transfer source if you - got a answer / transfer with the main source - address. [RT #14802] - -1863. [bug] rrset-order "fixed" error messages not complete. - -1862. [func] Add additional zone data constancy checks. - named-checkzone has extended checking of NS, MX and - SRV record and the hosts they reference. - named has extended post zone load checks. - New zone options: check-mx and integrity-check. - [RT #4940] - -1861. [bug] dig could trigger a INSIST on certain malformed - responses. [RT #14801] - -1860. [port] solaris 2.8: hack_shutup_pthreadmutexinit was - incorrectly set. [RT #14775] - -1859. [func] Add support for CH A record. [RT #14695] - -1858. [bug] The flush-zones-on-shutdown option wasn't being - parsed. [RT #14686] - -1857. [bug] named could trigger a INSIST() if reconfigured / - reloaded too fast. [RT #14673] - -1856. [doc] Switch Docbook toolchain from DSSSL to XSL. - [RT #11398] - -1855. [bug] ixfr-from-differences was failing to detect changes - of ttl due to dns_diff_subtract() was ignoring the ttl - of records. [RT #14616] - -1854. [bug] lwres also needs to know the print format for - (long long). [RT #13754] - -1853. [bug] Rework how DLV interacts with proveunsecure(). - [RT #13605] - -1852. [cleanup] Remove last vestiges of dnssec-signkey and - dnssec-makekeyset (removed from Makefile years ago). - -1851. [doc] Doxygen comment markup. [RT #11398] - -1850. [bug] Memory leak in lwres_getipnodebyaddr(). [RT #14591] - -1849. [doc] All forms of the man pages (docbook, man, html) should - have consistant copyright dates. - -1848. [bug] Improve SMF integration. [RT #13238] - -1847. [bug] isc_ondestroy_init() is called too late in - dns_rbtdb_create()/dns_rbtdb64_create(). - [RT #13661] - -1846. [contrib] query-loc-0.3.0 from Stephane Bortzmeyer - . - -1845. [bug] Improve error reporting to distingish between - accept()/fcntl() and socket()/fcntl() errors. - [RT #13745] - -1844. [bug] inet_pton() accepted more that 4 hexadecimal digits - for each 16 bit piece of the IPv6 address. The text - representation of a IPv6 address has been tighted - to disallow this (draft-ietf-ipv6-addr-arch-v4-02.txt). - [RT #5662] - -1843. [cleanup] CINCLUDES takes precedence over CFLAGS. This helps - when CFLAGS contains "-I /usr/local/include" - resulting in old header files being used. - -1842. [port] cmsg_len() could produce incorrect results on - some platform. [RT #13744] - -1841. [bug] "dig +nssearch" now makes a recursive query to - find the list of nameservers to query. [RT #13694] - -1840. [func] dnssec-signzone can now randomize signature end times - (dnssec-signzone -j jitter). [RT #13609] - -1839. [bug] was not being installed. - -1838. [cleanup] Don't allow Linux capabilities to be inherited. - [RT #13707] - -1837. [bug] Compile time option ISC_FACILITY was not effective - for 'named -u '. [RT #13714] - -1836. [cleanup] Silence compiler warnings in hash_test.c. - -1835. [bug] Update dnssec-signzone's usage message. [RT #13657] - -1834. [bug] Bad memset in rdata_test.c. [RT #13658] - -1833. [bug] Race condition in isc_mutex_lock_profile(). [RT #13660] - -1832. [bug] named fails to return BADKEY on unknown TSIG algorithm. - [RT #13620] - -1831. [doc] Update named-checkzone documentation. [RT#13604] - -1830. [bug] adb lame cache has sence of test reversed. [RT #13600] - -1829. [bug] win32: "pid-file none;" broken. [RT #13563] - -1828. [bug] isc_rwlock_init() failed to properly cleanup if it - encountered a error. [RT #13549] - -1827. [bug] host: update usage message for '-a'. [RT #37116] - -1826. [bug] Missing DESTROYLOCK() in isc_mem_createx() on out - of memory error. [RT #13537] - -1825. [bug] Missing UNLOCK() on out of memory error from in - rbtdb.c:subtractrdataset(). [RT #13519] - -1824. [bug] Memory leak on dns_zone_setdbtype() failure. - [RT #13510] - -1823. [bug] Wrong macro used to check for point to point interface. - [RT#13418] - -1822. [bug] check-names test for RT was reversed. [RT #13382] - -1820. [bug] Gracefully handle acl loops. [RT #13659] - -1819. [bug] The validator needed to check both the algorithm and - digest types of the DS to determine if it could be - used to introduce a secure zone. [RT #13593] - -1818. [bug] 'named-checkconf -z' triggered an INSIST. [RT #13599] - -1817. [func] Add support for additional zone file formats for - improving loading performance. The masterfile-format - option in named.conf can be used to specify a - non-default format. A separate command - named-compilezone was provided to generate zone files - in the new format. Additionally, the -I and -O options - for dnssec-signzone specify the input and output - formats. - -1816. [port] UnixWare: failed to compile lib/isc/unix/net.c. - [RT #13597] - -1815. [bug] nsupdate triggered a REQUIRE if the server was set - without also setting the zone and it encountered - a CNAME and was using TSIG. [RT #13086] - -1814. [func] UNIX domain controls are now supported. - -1813. [func] Restructured the data locking framework using - architecture dependent atomic operations (when - available), improving response performance on - multi-processor machines significantly. - x86, x86_64, alpha, powerpc, and mips are currently - supported. - -1812. [port] win32: IN6_IS_ADDR_UNSPECIFIED macro is incorrect. - [RT #13453] - -1811. [func] Preserve the case of domain names in rdata during - zone transfers. [RT #13547] - -1810. [bug] configure, lib/bind/configure make different default - decisions about whether to do a threaded build. - [RT #13212] - -1809. [bug] "make distclean" failed for libbind if the platform - is not supported. - -1808. [bug] zone.c:notify_zone() contained a race condition, - zone->db could change underneath it. [RT #13511] - -1807. [bug] When forwarding (forward only) set the active domain - from the forward zone name. [RT #13526] - -1806. [bug] The resolver returned the wrong result when a CNAME / - DNAME was encountered when fetching glue from a - secure namespace. [RT #13501] - -1805. [bug] Pending status was not being cleared when DLV was - active. [RT #13501] - -1804. [bug] Ensure that if we are queried for glue that it fits - in the additional section or TC is set to tell the - client to retry using TCP. [RT #10114] - -1803. [bug] dnssec-signzone sometimes failed to remove old - RRSIGs. [RT #13483] - -1802. [bug] Handle connection resets better. [RT #11280] - -1801. [func] Report differences between hints and real NS rrset - and associated address records. - -1800. [bug] Changes #1719 allowed a INSIST to be triggered. - [RT #13428] - -1799. [bug] 'rndc flushname' failed to flush negative cache - entries. [RT #13438] - -1798. [func] The server syntax has been extended to support a - range of servers. [RT #11132] - -1797. [func] named-checkconf now check acls to verify that they - only refer to existing acls. [RT #13101] - -1796. [func] "rndc freeze/thaw" now freezes/thaws all zones. - -1795. [bug] "rndc dumpdb" was not fully documented. Minor - formating issues with "rndc dumpdb -all". [RT #13396] - -1794. [func] Named and named-checkzone can now both check for - non-terminal wildcard records. - -1793. [func] Extend adjusting TTL warning messages. [RT #13378] - -1792. [func] New zone option "notify-delay". Specify a minimum - delay between sets of NOTIFY messages. - -1791. [bug] 'host -t a' still printed out AAAA and MX records. - [RT #13230] - -1790. [cleanup] Move lib/dns/sec/dst up into lib/dns. This should - allow parallel make to succeed. - -1789. [bug] Prerequisite test for tkey and dnssec could fail - with "configure --with-libtool". - -1788. [bug] libbind9.la/libbind9.so needs to link against - libisccfg.la/libisccfg.so. - -1787. [port] HPUX: both "cc" and "gcc" need -Wl,+vnocompatwarnings. - -1786. [port] AIX: libt_api needs to be taught to look for - T_testlist in the main executable (--with-libtool). - [RT #13239] - -1785. [bug] libbind9.la/libbind9.so needs to link against - libisc.la/libisc.so. - -1784. [cleanup] "libtool -allow-undefined" is the default. - Leave hooks in configure to allow it to be set - if needed in the future. - -1783. [cleanup] We only need one copy of libtool.m4, ltmain.sh in the - source tree. - -1782. [port] OSX: --with-libtool + --enable-libbind broke on - __evOptMonoTime. [RT #13219] - -1781. [port] FreeBSD 5.3: set PTHREAD_SCOPE_SYSTEM. [RT #12810] - -1780. [bug] Update libtool to 1.5.10. - -1779. [port] OSF 5.1: libtool didn't handle -pthread correctly. - -1778. [port] HUX 11.11: fix broken IN6ADDR_ANY_INIT and - IN6ADDR_LOOPBACK_INIT macros. - -1777. [port] OSF 5.1: fix broken IN6ADDR_ANY_INIT and - IN6ADDR_LOOPBACK_INIT macros. - -1776. [port] Solaris 2.9: fix broken IN6ADDR_ANY_INIT and - IN6ADDR_LOOPBACK_INIT macros. - -1775. [bug] Only compile getnetent_r.c when threaded. [RT #13205] - -1774. [port] Aix: Silence compiler warnings / build failures. - [RT #13154] - -1773. [bug] Fast retry on host / net unreachable. [RT #13153] - -1770. [bug] named-checkconf failed to report missing a missing - file clause for rbt{64} master/hint zones. [RT#13009] - -1769. [port] win32: change compiler flags /MTd ==> /MDd, - /MT ==> /MD. - -1768. [bug] nsecnoexistnodata() could be called with a non-NSEC - rdataset. [RT #12907] - -1767. [port] Builds on IPv6 platforms without IPv6 Advanced API - support for (struct in6_pktinfo) failed. [RT #13077] - -1766. [bug] Update the master file timestamp on successful refresh - as well as the journal's timestamp. [RT# 13062] - -1765. [bug] configure --with-openssl=auto failed. [RT #12937] - -1764. [bug] dns_zone_replacedb failed to emit a error message - if there was no SOA record in the replacment db. - [RT #13016] - -1763. [func] Perform sanity checks on NS records which refer to - 'in zone' names. [RT #13002] - -1762. [bug] isc_interfaceiter_create() could return ISC_R_SUCCESS - even when it failed. [RT #12995] - -1761. [bug] 'rndc dumpdb' didn't report unassociated entries. - [RT #12971] - -1760. [bug] Host / net unreachable was not penalising rtt - estimates. [RT #12970] - -1759. [bug] Named failed to startup if the OS supported IPv6 - but had no IPv6 interfaces configured. [RT #12942] - -1758. [func] Don't send notify messages to self. [RT #12933] - -1757. [func] host now can turn on memory debugging flags with '-m'. - -1756. [func] named-checkconf now checks the logging configuration. - [RT #12352] - -1755. [func] allow-update is now settable at the options / view - level. [RT #6636] - -1754. [bug] We wern't always attempting to query the parent - server for the DS records at the zone cut. - [RT #12774] - -1753. [bug] Don't serve a slave zone which has no NS records. - [RT #12894] - -1752. [port] Move isc_app_start() to after ns_os_daemonise() - as some fork() implementations unblock the signals - that are blocked by isc_app_start(). [RT #12810] - -1751. [bug] --enable-getifaddrs failed under linux. [RT #12867] - -1750. [port] lib/bind/make/rules.in:subdirs was not bash friendly. - [RT #12864] - -1749. [bug] 'check-names response ignore;' failed to ignore. - [RT #12866] - -1748. [func] dig now returns the byte count for axfr/ixfr. - -1747. [bug] BIND 8 compatability: named/named-checkconf failed - to parse "host-statistics-max" in named.conf. - -1746. [func] Make public the function to read a key file, - dst_key_read_public(). [RT #12450] - -1745. [bug] Dig/host/nslookup accept replies from link locals - regardless of scope if no scope was specified when - query was sent. [RT #12745] - -1744. [bug] If tuple2msgname() failed to convert a tuple to - a name a REQUIRE could be triggered. [RT #12796] - -1743. [bug] If isc_taskmgr_create() was not able to create the - requested number of worker threads then destruction - of the manager would trigger an INSIST() failure. - [RT #12790] - -1742. [bug] Deleting all records at a node then adding a - previously existing record, in a single UPDATE - transaction, failed to leave / regenerate the - associated RRSIG records. [RT #12788] - -1741. [bug] Deleting all records at a node in a secure zone - using a update-policy grant failed. [RT #12787] - -1740. [bug] Replace rbt's hash algorithm as it performed badly - with certain zones. [RT #12729] - - NOTE: a hash context now needs to be established - via isc_hash_create() if the application was not - already doing this. - -1739. [bug] dns_rbt_deletetree() could incorrectly return - ISC_R_QUOTA. [RT #12695] - -1738. [bug] Enable overrun checking by default. [RT #12695] - -1737. [bug] named failed if more than 16 masters were specified. - [RT #12627] - -1736. [bug] dst_key_fromnamedfile() could fail to read a - public key. [RT #12687] - -1735. [bug] 'dig +sigtrace' could die with a REQUIRE failure. - [RE #12688] - -1734. [cleanup] 'rndc-confgen -a -t' remove extra '/' in path. - [RT #12588] - -1733. [bug] Return non-zero exit status on initial load failure. - [RT #12658] - -1732. [bug] 'rrset-order name "*"' wasn't being applied to ".". - [RT #12467] - -1731. [port] darwin: relax version test in ifconfig.sh. - [RT #12581] - -1730. [port] Determine the length type used by the socket API. - [RT #12581] - -1729. [func] Improve check-names error messages. - -1728. [doc] Update check-names documentation. - -1727. [bug] named-checkzone: check-names support didn't match - documentation. - -1726. [port] aix5: add support for aix5. - -1725. [port] linux: update error message on interaction of threads, - capabilities and setuid support (named -u). [RT #12541] - -1724. [bug] Look for DNSKEY records with "dig +sigtrace". - [RT #12557] - -1723. [cleanup] Silence compiler warnings from t_tasks.c. [RT #12493] - -1722. [bug] Don't commit the journal on malformed ixfr streams. - [RT #12519] - -1721. [bug] Error message from the journal processing were not - always identifing the relevent journal. [RT #12519] - -1720. [bug] 'dig +chase' did not terminate on a RFC 2308 Type 1 - negative response. [RT #12506] - -1719. [bug] named was not correctly caching a RFC 2308 Type 1 - negative response. [RT #12506] - -1718. [bug] nsupdate was not handling RFC 2308 Type 3 negative - responses when looking for the zone / master server. - [RT #12506] - -1717. [port] solaris: ifconfig.sh did not support Solaris 10. - "ifconfig.sh down" didn't work for Solaris 9. - -1716. [doc] named.conf(5) was being installed in the wrong - location. [RT# 12441] - -1715. [func] 'dig +trace' now randomly selects the next servers - to try. Report if there is a bad delegation. - -1714. [bug] dig/host/nslookup were only trying the first - address when a nameserver was specified by name. - [RT #12286] - -1713. [port] linux: extend capset failure message to say: - please ensure that the capset kernel module is - loaded. see insmod(8) - -1712. [bug] Missing FULLCHECK for "trusted-key" in dig. - -1711. [func] 'rndc unfreeze' has been deprecated by 'rndc thaw'. - -1710. [func] 'rndc notify zone [class [view]]' resend the NOTIFY - messages for the specified zone. [RT #9479] - -1709. [port] solaris: add SMF support from Sun. - -1708. [cleanup] Replaced dns_fullname_hash() with dns_name_fullhash() - for conformance to the name space convention. Binary - backward compatibility to the old function name is - provided. [RT #12376] - -1707. [contrib] sdb/ldap updated to version 1.0-beta. - -1706. [bug] 'rndc stop' failed to cause zones to be flushed - sometimes. [RT #12328] - -1705. [func] Allow the journal's name to be changed via named.conf. - -1704. [port] lwres needed a snprintf() implementation for - platforms without snprintf(). Add missing - "#include ". [RT #12321] - -1703. [bug] named would loop sending NOTIFY messages when it - failed to receive a response. [RT #12322] - -1702. [bug] also-notify should not be applied to builtin zones. - [RT #12323] - -1701. [doc] A minimal named.conf man page. - -1700. [func] nslookup is no longer to be treated as deprecated. - Remove "deprecated" warning message. Add man page. - -1699. [bug] dnssec-signzone can generate "not exact" errors - when resigning. [RT #12281] - -1698. [doc] Use reserved IPv6 documentation prefix. - -1697. [bug] xxx-source{,-v6} was not effective when it - specified one of listening addresses and a - different port than the listening port. [RT #12257] - -1696. [bug] dnssec-signzone failed to clean out nodes that - consisted of only NSEC and RRSIG records. - [RT #12154] - -1695. [bug] DS records when forwarding require special handling. - [RT #12133] - -1694. [bug] Report if the builtin views of "_default" / "_bind" - are defined in named.conf. [RT #12023] - -1693. [bug] max-journal-size was not effective for master zones - with ixfr-from-differences set. [RT# 12024] - -1692. [bug] Don't set -I, -L and -R flags when libcrypto is in - /usr/lib. [RT #11971] - -1691. [bug] sdb's attachversion was not complete. [RT #11990] - -1690. [bug] Delay detaching view from the client until UPDATE - processing completes when shutting down. [RT #11714] - -1689. [bug] DNS_NAME_TOREGION() and DNS_NAME_SPLIT() macros - contained gratuitous semicolons. [RT #11707] - -1688. [bug] LDFLAGS was not supported. - -1687. [bug] Race condition in dispatch. [RT #10272] - -1686. [bug] Named sent a extraneous NOTIFY when it received a - redundant UPDATE request. [RT #11943] - -1685. [bug] Change #1679 loop tests weren't quite right. - -1684. [func] ixfr-from-differences now takes master and slave in - addition to yes and no at the options and view levels. - -1683. [bug] dig +sigchase could leak memory. [RT #11445] - -1682. [port] Update configure test for (long long) printf format. - [RT #5066] - -1681. [bug] Only set SO_REUSEADDR when a port is specified in - isc_socket_bind(). [RT #11742] - -1680. [func] rndc: the source address can now be specified. - -1679. [bug] When there was a single nameserver with multiple - addresses for a zone not all addresses were tried. - [RT #11706] - -1678. [bug] RRSIG should use TYPEXXXXX for unknown types. - -1677. [bug] dig: +aaonly didn't work, +aaflag undocumented. - -1676. [func] New option "allow-query-cache". This lets - allow-query be used to specify the default zone - access level rather than having to have every - zone override the global value. allow-query-cache - can be set at both the options and view levels. - If allow-query-cache is not set allow-query applies. - -1675. [bug] named would sometimes add extra NSEC records to - the authority section. - -1674. [port] linux: increase buffer size used to scan - /proc/net/if_inet6. - -1673. [port] linux: issue a error messages if IPv6 interface - scans fails. - -1672. [cleanup] Tests which only function in a threaded build - now return R:THREADONLY (rather than R:UNTESTED) - in a non-threaded build. - -1671. [contrib] queryperf: add NAPTR to the list of known types. - -1670. [func] Log UPDATE requests to slave zones without an acl as - "disabled" at debug level 3. [RT# 11657] - -1668. [bug] DIG_SIGCHASE was making bin/dig/host dump core. - -1667. [port] linux: not all versions have IF_NAMESIZE. - -1666. [bug] The optional port on hostnames in dual-stack-servers - was being ignored. - -1665. [func] rndc now allows addresses to be set in the - server clauses. - -1664. [bug] nsupdate needed KEY for SIG(0), not DNSKEY. - -1663. [func] Look for OpenSSL by default. - -1662. [bug] Change #1658 failed to change one use of 'type' - to 'keytype'. - -1661. [bug] Restore dns_name_concatenate() call in - adb.c:set_target(). [RT #11582] - -1660. [bug] win32: connection_reset_fix() was being called - unconditionally. [RT #11595] - -1659. [cleanup] Cleanup some messages that were referring to KEY vs - DNSKEY, NXT vs NSEC and SIG vs RRSIG. - -1658. [func] Update dnssec-keygen to default to KEY for HMAC-MD5 - and DH. Tighten which options apply to KEY and - DNSKEY records. - -1657. [doc] ARM: document query log output. - -1656. [doc] Update DNSSEC description in ARM to cover DS, NSEC - DNSKEY and RRSIG. [RT #11542] - -1655. [bug] Logging multiple versions w/o a size was broken. - [RT #11446] - -1654. [bug] isc_result_totext() contained array bounds read - error. - -1653. [func] Add key type checking to dst_key_fromfilename(), - DST_TYPE_KEY should be used to read TSIG, TKEY and - SIG(0) keys. - -1652. [bug] TKEY still uses KEY. - -1651. [bug] dig: process multiple dash options. - -1650. [bug] dig, nslookup: flush standard out after each command. - -1649. [bug] Silence "unexpected non-minimal diff" message. - [RT #11206] - -1648. [func] Update dnssec-lookaside named.conf syntax to support - multiple dnssec-lookaside namespaces (not yet - implemented). - -1647. [bug] It was possible trigger a INSIST when chasing a DS - record that required walking back over a empty node. - [RT #11445] - -1646. [bug] win32: logging file versions didn't work with - non-UNC filenames. [RT#11486] - -1645. [bug] named could trigger a REQUIRE failure if multiple - masters with keys are specified. - -1644. [bug] Update the journal modification time after a - sucessfull refresh query. [RT #11436] - -1643. [bug] dns_db_closeversion() could leak memory / node - references. [RT #11163] - -1642. [port] Support OpenSSL implementations which don't have - DSA support. [RT #11360] - -1641. [bug] Update the check-names description in ARM. [RT #11389] - -1640. [bug] win32: isc_socket_cancel(ISC_SOCKCANCEL_ACCEPT) was - incorrectly closing the socket. [RT #11291] - -1639. [func] Initial dlv system test. - -1638. [bug] "ixfr-from-differences" could generate a REQUIRE - failure if the journal open failed. [RT #11347] - -1637. [bug] Node reference leak on error in addnoqname(). - -1636. [bug] The dump done callback could get ISC_R_SUCCESS even if - a error had occured. The database version no longer - matched the version of the database that was dumped. - -1635. [bug] Memory leak on error in query_addds(). - -1634. [bug] named didn't supply a useful error message when it - detected duplicate views. [RT #11208] - -1633. [bug] named should return NOTIMP to update requests to a - slaves without a allow-update-forwarding acl specified. - [RT #11331] - -1632. [bug] nsupdate failed to send prerequisite only UPDATE - messages. [RT #11288] - -1631. [bug] dns_journal_compact() could sometimes corrupt the - journal. [RT #11124] - -1630. [contrib] queryperf: add support for IPv6 transport. - -1629. [func] dig now supports IPv6 scoped addresses with the - extended format in the local-server part. [RT #8753] - -1628. [bug] Typo in Compaq Trucluster support. [RT# 11264] - -1627. [bug] win32: sockets were not being closed when the - last external reference was removed. [RT# 11179] - -1626. [bug] --enable-getifaddrs was broken. [RT#11259] - -1625. [bug] named failed to load/transfer RFC2535 signed zones - which contained CNAMES. [RT# 11237] - -1624. [bug] zonemgr_putio() call should be locked. [RT# 11163] - -1623. [bug] A serial number of zero was being displayed in the - "sending notifies" log message when also-notify was - used. [RT #11177] - -1622. [func] probe the system to see if IPV6_(RECV)PKTINFO is - available, and suppress wildcard binding if not. - -1621. [bug] match-destinations did not work for IPv6 TCP queries. - [RT# 11156] - -1620. [func] When loading a zone report if it is signed. [RT #11149] - -1619. [bug] Missing ISC_LIST_UNLINK in end_reserved_dispatches(). - [RT# 11118] - -1618. [bug] Fencepost errors in dns_name_ishostname() and - dns_name_ismailbox() could trigger a INSIST(). - -1617. [port] win32: VC++ 6.0 support. - -1616. [compat] Ensure that named's version is visible in the core - dump. [RT #11127] - -1615. [port] Define ISC_SOCKADDR_LEN_T based on _BSD_SOCKLEN_T_ if - it is defined. - -1614. [port] win32: silence resource limit messages. [RT# 11101] - -1613. [bug] Builds would fail on machines w/o a if_nametoindex(). - Missing #ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX/#endif. - [RT #11119] - -1612. [bug] check-names at the option/view level could trigger - an INSIST. [RT# 11116] - -1611. [bug] solaris: IPv6 interface scanning failed to cope with - no active IPv6 interfaces. - -1610. [bug] On dual stack machines "dig -b" failed to set the - address type to be looked up with "@server". - [RT #11069] - -1609. [func] dig now has support to chase DNSSEC signature chains. - Requires -DDIG_SIGCHASE=1 to be set in STD_CDEFINES. - - DNSSEC validation code in dig coded by Olivier Courtay - (olivier.courtay@irisa.fr) for the IDsA project - (http://idsa.irisa.fr). - -1608. [func] dig and host now accept -4/-6 to select IP transport - to use when making queries. - -1607. [bug] dig, host and nslookup were still using random() - to generate query ids. [RT# 11013] - -1606. [bug] DLV insecurity proof was failing. - -1605. [func] New dns_db_find() option DNS_DBFIND_COVERINGNSEC. - -1604. [bug] A xfrout_ctx_create() failure would result in - xfrout_ctx_destroy() being called with a - partially initialized structure. - -1603. [bug] nsupdate: set interactive based on isatty(). - [RT# 10929] - -1602. [bug] Logging to a file failed unless a size was specified. - [RT# 10925] - -1601. [bug] Silence spurious warning 'both "recursion no;" and - "allow-recursion" active' warning from view "_bind". - [RT# 10920] - -1600. [bug] Duplicate zone pre-load checks were not case - insensitive. - -1599. [bug] Fix memory leak on error path when checking named.conf. - -1598. [func] Specify that certain parts of the namespace must - be secure (dnssec-must-be-secure). - -1596. [func] Accept 'notify-source' style syntax for query-source. - -1595. [func] New notify type 'master-only'. Enable notify for - master zones only. - -1594. [bug] 'rndc dumpdb' could prevent named from answering - queries while the dump was in progress. [RT #10565] - -1593. [bug] rndc should return "unknown command" to unknown - commands. [RT# 10642] - -1592. [bug] configure_view() could leak a dispatch. [RT# 10675] - -1591. [bug] libbind: updated to BIND 8.4.5. - -1590. [port] netbsd: update thread support. - -1589. [func] DNSSEC lookaside validation. - -1588. [bug] win32: TCP sockets could become blocked. [RT #10115] - -1587. [bug] dns_message_settsigkey() failed to clear existing key. - [RT #10590] - -1586. [func] "check-names" is now implemented. - -1585. [placeholder] - -1584. [bug] "make test" failed with a read only source tree. - [RT #10461] - -1583. [bug] Records add via UPDATE failed to get the correct trust - level. [RT #10452] - -1582. [bug] rrset-order failed to work on RRsets with more - than 32 elements. [RT #10381] - -1581. [func] Disable DNSSEC support by default. To enable - DNSSEC specify "dnssec-enable yes;" in named.conf. - -1580. [bug] Zone destruction on final detach takes a long time. - [RT #3746] - -1579. [bug] Multiple task managers could not be created. - -1578. [bug] Don't use CLASS E IPv4 addresses when resolving. - [RT #10346] - -1577. [bug] Use isc_uint32_t in ultrasparc optimizer bug - workaround code. [RT #10331] - -1576. [bug] Race condition in dns_dispatch_addresponse(). - [RT# 10272] - -1575. [func] Log TSIG name on TSIG verify failure. [RT #4404] - -1574. [bug] Don't attempt to open the controls socket(s) when - running tests. [RT #9091] - -1573. [port] linux: update to libtool 1.5.2 so that - "make install DESTDIR=/xx" works with - "configure --with-libtool". [RT #9941] - -1572. [bug] nsupdate: sign the soa query to find the enclosing - zone if the server is specified. [RT #10148] - -1571. [bug] rbt:hash_node() could fail leaving the hash table - in an inconsistent state. [RT #10208] - -1570. [bug] nsupdate failed to handle classes other than IN. - New keyword 'class' which sets the default class. - [RT #10202] - -1569. [func] nsupdate new command 'answer' which displays the - complete answer message to the last update. - -1568. [bug] nsupdate now reports that the update failed in - interactive mode. [RT# 10236] - -1567. [bug] B.ROOT-SERVERS.NET is now 192.228.79.201. - -1566. [port] Support for the cmsg framework on Solaris and HP/UX. - This also solved the problem that match-destinations - for IPv6 addresses did not work on these systems. - [RT #10221] - -1565. [bug] CD flag should be copied to outgoing queries unless - the query is under a secure entry point in which case - CD should be set. - -1564. [func] Attempt to provide a fallback entropy source to be - used if named is running chrooted and named is unable - to open entropy source within the chroot area. - [RT #10133] - -1563. [bug] Gracefully fail when unable to obtain neither an IPv4 - nor an IPv6 dispatch. [RT #10230] - -1562. [bug] isc_socket_create() and isc_socket_accept() could - leak memory under error conditions. [RT #10230] - -1561. [bug] It was possible to release the same name twice if - named ran out of memory. [RT #10197] - -1560. [port] FreeBSD: work around FreeBSD 5.2 mapping EAI_NODATA - and EAI_NONAME to the same value. - -1559. [port] named should ignore SIGFSZ. - -1558. [func] New DNSSEC 'disable-algorithms'. Support entry into - child zones for which we don't have a supported - algorithm. Such child zones are treated as unsigned. - -1557. [func] Implement missing DNSSEC tests for - * NOQNAME proof with wildcard answers. - * NOWILDARD proof with NXDOMAIN. - Cache and return NOQNAME with wildcard answers. - -1556. [bug] nsupdate now treats all names as fully qualified. - [RT #6427] - -1555. [func] 'rrset-order cyclic' no longer has a random starting - point per query. [RT #7572] - -1554. [bug] dig, host, nslookup failed when no nameservers - were specified in /etc/resolv.conf. [RT #8232] - -1553. [bug] The windows socket code could stop accepting - connections. [RT#10115] - -1552. [bug] Accept NOTIFY requests from mapped masters if - matched-mapped is set. [RT #10049] - -1551. [port] Open "/dev/null" before calling chroot(). - -1550. [port] Call tzset(), if available, before calling chroot(). - -1549. [func] named-checkzone can now write out the zone contents - in a easily parsable format (-D and -o). - -1548. [bug] When parsing APL records it was possible to silently - accept out of range ADDRESSFAMILY values. [RT# 9979] - -1547. [bug] Named wasted memory recording duplicate lame zone - entries. [RT #9341] - -1546. [bug] We were rejecting valid secure CNAME to negative - answers. - -1545. [bug] It was possible to leak memory if named was unable to - bind to the specified transfer source and TSIG was - being used. [RT #10120] - -1544. [bug] Named would logged a single entry to a file despite it - being over the specified size limit. - -1543. [bug] Logging using "versions unlimited" did not work. - -1542. [placeholder] - -1541. [func] NSEC now uses new bitmap format. - -1540. [bug] "rndc reload " was silently accepted. - [RT #8934] - -1539. [bug] Open UDP sockets for notify-source and transfer-source - that use reserved ports at startup. [RT #9475] - -1538. [placeholder] rt9997 - -1537. [func] New option "querylog". If set specify whether query - logging is to be enabled or disabled at startup. - -1536. [bug] Windows socket code failed to log a error description - when returning ISC_R_UNEXPECTED. [RT #9998] - -1535. [placeholder] - -1534. [bug] Race condition when priming cache. [RT# 9940] - -1533. [func] Warn if both "recursion no;" and "allow-recursion" - are active. [RT# 4389] - -1532. [port] netbsd: the configure test for - requires . - -1531. [port] AIX more libtool fixes. - -1530. [bug] It was possible to trigger a INSIST() failure if a - slave master file was removed at just the correct - moment. [RT #9462] - -1529. [bug] "notify explicit;" failed to log that NOTIFY messages - were being sent for the zone. [RT# 9442] - -1528. [cleanup] Simplify some dns_name_ functions based on the - deprecation of bitstring labels. - -1527. [cleanup] Reduce the number of gettimeofday() calls without - losing necessary timer granularity. - -1526. [func] Implemented "additional section caching (or acache)", - an internal cache framework for additional section - content to improve response performance. Several - configuration options were provided to control the - behavior. - -1525. [bug] dns_cache_create() could trigger a REQUIRE - failure in isc_mem_put() during error cleanup. - [RT# 9360] - -1524. [port] AIX needs to be able to resolve all symbols when - creating shared libraries (--with-libtool). - -1523. [bug] Fix race condition in rbtdb. [RT# 9189] - -1522. [bug] dns_db_findnode() relax the requirements on 'name'. - [RT# 9286] - -1521. [bug] dns_view_createresolver() failed to check the - result from isc_mem_create(). [RT# 9294] - -1520. [protocol] Add SSHFP (SSH Finger Print) type. - -1519. [bug] dnssec-signzone:nsec_setbit() computed the wrong - length of the new bitmap. - -1518. [bug] dns_nsec_buildrdata(), and hence dns_nsec_build(), - contained a off-by-one error when working out the - number of octets in the bitmap. - -1517. [port] Support for IPv6 interface scanning on HP/UX and - TrueUNIX 5.1. - -1516. [func] Roll the DNSSEC types to RRSIG, NSEC and DNSKEY. - -1515. [func] Allow transfer source to be set in a server statement. - [RT #6496] - -1514. [bug] named: isc_hash_destroy() was being called too early. - [RT #9160] - -1513. [doc] Add "US" to root-delegation-only exclude list. - -1512. [bug] Extend the delegation-only logging to return query - type, class and responding nameserver. - -1511. [bug] delegation-only was generating false positives - on negative answers from subzones. - -1510. [func] New view option "root-delegation-only". Apply - delegation-only check to all TLDs and root. - Note there are some TLDs that are NOT delegation - only (e.g. DE, LV, US and MUSEUM) these can be excluded - from the checks by using exclude. - - root-delegation-only exclude { - "DE"; "LV"; "US"; "MUSEUM"; - }; - -1509. [bug] Hint zones should accept delegation-only. Forward - zone should not accept delegation-only. - -1508. [bug] Don't apply delegation-only checks to answers from - forwarders. - -1507. [bug] Handle BIND 8 style returns to NS queries to parents - when making delegation-only checks. - -1506. [bug] Wrong return type for dns_view_isdelegationonly(). - -1505. [bug] Uninitialized rdataset in sdb. [RT #8750] - -1504. [func] New zone type "delegation-only". - -1503. [port] win32: install libeay32.dll outside of system32. - -1502. [bug] nsupdate: adjust timeouts for UPDATE requests over TCP. - -1501. [func] Allow TCP queue length to be specified via - named.conf, tcp-listen-queue. - -1500. [bug] host failed to lookup MX records. Also look up - AAAA records. - -1499. [bug] isc_random need to be seeded better if arc4random() - is not used. - -1498. [port] bsdos: 5.x support. - -1497. [placeholder] - -1496. [port] test for pthread_attr_setstacksize(). - -1495. [cleanup] Replace hash functions with universal hash. - -1494. [security] Turn on RSA BLINDING as a precaution. - -1493. [placeholder] - -1492. [cleanup] Preserve rwlock quota context when upgrading / - downgrading. [RT #5599] - -1491. [bug] dns_master_dump*() would produce extraneous $ORIGIN - lines. [RT #6206] - -1490. [bug] Accept reading state as well as working state in - ns_client_next(). [RT #6813] - -1489. [compat] Treat 'allow-update' on slave zones as a warning. - [RT #3469] - -1488. [bug] Don't override trust levels for glue addresses. - [RT #5764] - -1487. [bug] A REQUIRE() failure could be triggered if a zone was - queued for transfer and the zone was then removed. - [RT #6189] - -1486. [bug] isc_print_snprintf() '%%' consumed one too many format - characters. [RT# 8230] - -1485. [bug] gen failed to handle high type values. [RT #6225] - -1484. [bug] The number of records reported after a AXFR was wrong. - [RT #6229] - -1483. [bug] dig axfr failed if the message id in the answer failed - to match that in the request. Only the id in the first - message is required to match. [RT #8138] - -1482. [bug] named could fail to start if the kernel supports - IPv6 but no interfaces are configured. Similarly - for IPv4. [RT #6229] - -1481. [bug] Refresh and stub queries failed to use masters keys - if specified. [RT #7391] - -1480. [bug] Provide replay protection for rndc commands. Full - replay protection requires both rndc and named to - be updated. Partial replay protection (limited - exposure after restart) is provided if just named - is updated. - -1479. [bug] cfg_create_tuple() failed to handle out of - memory cleanup. parse_list() would leak memory - on syntax errors. - -1478. [port] ifconfig.sh didn't account for other virtual - interfaces. It now takes a optional argument - to specify the first interface number. [RT #3907] - -1477. [bug] memory leak using stub zones and TSIG. - -1476. [placeholder] - -1475. [port] Probe for old sprintf(). - -1474. [port] Provide strtoul() and memmove() for platforms - without them. - -1473. [bug] create_map() and create_string() failed to handle out - of memory cleanup. [RT #6813] - -1472. [contrib] idnkit-1.0 from JPNIC, replaces mdnkit. - -1471. [bug] libbind: updated to BIND 8.4.0. - -1470. [bug] Incorrect length passed to snprintf. [RT #5966] - -1469. [func] Log end of outgoing zone transfer at same level - as the start of transfer is logged. [RT #4441] - -1468. [func] Internal zones are no longer counted for - 'rndc status'. [RT #4706] - -1467. [func] $GENERATES now supports optional class and ttl. - -1466. [bug] lwresd configuration errors resulted in memory - and lock leaks. [RT #5228] - -1465. [bug] isc_base64_decodestring() and isc_base64_tobuffer() - failed to check that trailing bits were zero allowing - some invalid base64 strings to be accepted. [RT #5397] - -1464. [bug] Preserve "out of zone" data for outgoing zone - transfers. [RT #5192] - -1463. [bug] dns_rdata_from{wire,struct}() failed to catch bad - NXT bit maps. [RT #5577] - -1462. [bug] parse_sizeval() failed to check the token type. - [RT #5586] - -1461. [bug] Remove deadlock from rbtdb code. [RT #5599] - -1460. [bug] inet_pton() failed to reject certain malformed - IPv6 literals. - -1459. [placeholder] - -1458. [cleanup] sprintf() -> snprintf(). - -1457. [port] Provide strlcat() and strlcpy() for platforms without - them. - -1456. [contrib] gen-data-queryperf.py from Stephane Bortzmeyer. - -1455. [bug] missing from server grammar in - doc/misc/options. [RT #5616] - -1454. [port] Use getifaddrs() if available for interface scanning. - --disable-getifaddrs to override. Glibc currently - has a getifaddrs() that does not support IPv6. - Use --enable-getifaddrs=glibc to force the use of - this version under linux machines. - -1453. [doc] ARM: $GENERATE example wasn't accurate. [RT #5298] - -1452. [placeholder] - -1451. [bug] rndc-confgen didn't exit with a error code for all - failures. [RT #5209] - -1450. [bug] Fetching expired glue failed under certain - circumstances. [RT #5124] - -1449. [bug] query_addbestns() didn't handle running out of memory - gracefully. - -1448. [bug] Handle empty wildcards labels. - -1447. [bug] We were casting (unsigned int) to and from (void *). - rdataset->private4 is now rdataset->privateuint4 - to reflect a type change. - -1446. [func] Implemented undocumented alternate transfer sources - from BIND 8. See use-alt-transfer-source, - alt-transfer-source and alt-transfer-source-v6. - - SECURITY: use-alt-transfer-source is ENABLED unless - you are using views. This may cause a security risk - resulting in accidental disclosure of wrong zone - content if the master supplying different source - content based on IP address. If you are not certain - ISC recommends setting use-alt-transfer-source no; - -1445. [bug] DNS_ADBFIND_STARTATROOT broke stub zones. This has - been replaced with DNS_ADBFIND_STARTATZONE which - causes the search to start using the closest zone. - -1444. [func] dns_view_findzonecut2() allows you to specify if the - cache should be searched for zone cuts. - -1443. [func] Masters lists can now be specified and referenced - in zone masters clauses and other masters lists. - -1442. [func] New functions for manipulating port lists: - dns_portlist_create(), dns_portlist_add(), - dns_portlist_remove(), dns_portlist_match(), - dns_portlist_attach() and dns_portlist_detach(). - -1441. [func] It is now possible to tell dig to bind to a specific - source port. - -1440. [func] It is now possible to tell named to avoid using - certain source ports (avoid-v4-udp-ports, - avoid-v6-udp-ports). - -1439. [bug] Named could return NOERROR with certain NOTIFY - failures. Return NOTAUTH if the NOTIFY zone is - not being served. - -1438. [func] Log TSIG (if any) when logging NOTIFY requests. - -1437. [bug] Leave space for stdio to work in. [RT #5033] - -1436. [func] dns_zonemgr_resumexfrs() can be used to restart - stalled transfers. - -1435. [bug] zmgr_resume_xfrs() was being called read locked - rather than write locked. zmgr_resume_xfrs() - was not being called if the zone was being - shutdown. - -1434. [bug] "rndc reconfig" failed to initiate the initial - zone transfer of new slave zones. - -1433. [bug] named could trigger a REQUIRE failure if it could - not get a file descriptor when attempting to write - a master file. [RT #4347] - -1432. [func] The advertised EDNS UDP buffer size can now be set - via named.conf (edns-udp-size). - -1431. [bug] isc_print_snprintf() "%s" with precision could walk off - end of argument. [RT #5191] - -1430. [port] linux: IPv6 interface scanning support. - -1429. [bug] Prevent the cache getting locked to old servers. - -1428. [placeholder] - -1427. [bug] Race condition in adb with threaded build. - -1426. [placeholder] - -1425. [port] linux/libbind: define __USE_MISC when testing *_r() - function prototypes in netdb.h. [RT #4921] - -1424. [bug] EDNS version not being correctly printed. - -1423. [contrib] queryperf: added A6 and SRV. - -1422. [func] Log name/type/class when denying a query. [RT #4663] - -1421. [func] Differentiate updates that don't succeed due to - prerequisites (unsuccessful) vs other reasons - (failed). - -1420. [port] solaris: work around gcc optimizer bug. - -1419. [port] openbsd: use /dev/arandom. [RT #4950] - -1418. [bug] 'rndc reconfig' did not cause new slaves to load. - -1417. [func] ID.SERVER/CHAOS is now a built in zone. - See "server-id" for how to configure. - -1416. [bug] Empty node should return NOERROR NODATA, not NXDOMAIN. - [RT #4715] - -1415. [func] DS TTL now derived from NS ttl. NXT TTL now derived - from SOA MINIMUM. - -1414. [func] Support for KSK flag. - -1413. [func] Explicitly request the (re-)generation of DS records - from keysets (dnssec-signzone -g). - -1412. [func] You can now specify servers to be tried if a nameserver - has IPv6 address and you only support IPv4 or the - reverse. See dual-stack-servers. - -1411. [bug] empty nodes should stop wildcard matches. [RT #4802] - -1410. [func] Handle records that live in the parent zone, e.g. DS. - -1409. [bug] DS should have attribute DNS_RDATATYPEATTR_DNSSEC. - -1408. [bug] "make distclean" was not complete. [RT #4700] - -1407. [bug] lfsr incorrectly implements the shift register. - [RT #4617] - -1406. [bug] dispatch initializes one of the LFSR's with a incorrect - polynomial. [RT #4617] - -1405. [func] Use arc4random() if available. - -1404. [bug] libbind: ns_name_ntol() could overwrite a zero length - buffer. - -1403. [func] dnssec-signzone, dnssec-keygen, dnssec-makekeyset - dnssec-signkey now report their version in the - usage message. - -1402. [cleanup] A6 has been moved to experimental and is no longer - fully supported. - -1401. [bug] adb wasn't clearing state when the timer expired. - -1400. [bug] Block the addition of wildcard NS records by IXFR - or UPDATE. [RT #3502] - -1399. [bug] Use serial number arithmetic when testing SIG - timestamps. [RT #4268] - -1398. [doc] ARM: notify-also should have been also-notify. - [RT #4345] - -1397. [bug] J.ROOT-SERVERS.NET is now 192.58.128.30. - -1396. [func] dnssec-signzone: adjust the default signing time by - 1 hour to allow for clock skew. - -1395. [port] OpenSSL 0.9.7 defines CRYPTO_LOCK_ENGINE but doesn't - have a working implementation. [RT #4079] - -1394. [func] It is now possible to check if a particular element is - in a acl. Remove duplicate entries from the localnets - acl. - -1393. [port] Bind to individual IPv6 interfaces if IPV6_IPV6ONLY - is not available in the kernel to prevent accidently - listening on IPv4 interfaces. - -1392. [bug] named-checkzone: update usage. - -1391. [func] Add support for IPv6 scoped addresses in named. - -1390. [func] host now supports ixfr. - -1389. [bug] named could fail to rotate long log files. [RT #3666] - -1388. [port] irix: check for sys/sysctl.h and NET_RT_IFLIST before - defining HAVE_IFLIST_SYSCTL. [RT #3770] - -1387. [bug] named could crash due to an access to invalid memory - space (which caused an assertion failure) in - incremental cleaning. [RT #3588] - -1386. [bug] named-checkzone -z stopped on errors in a zone. - [RT #3653] - -1385. [bug] Setting serial-query-rate to 10 would trigger a - REQUIRE failure. - -1384. [bug] host was incompatible with BIND 8 in its exit code and - in the output with the -l option. [RT #3536] - -1383. [func] Track the serial number in a IXFR response and log if - a mismatch occurs. This is a more specific error than - "not exact". [RT #3445] - -1382. [bug] make install failed with --enable-libbind. [RT #3656] - -1381. [bug] named failed to correctly process answers that - contained DNAME records where the resulting CNAME - resulted in a negative answer. - -1380. [func] 'rndc recursing' dump recursing queries to - 'recursing-file = "named.recursing";'. - -1379. [func] 'rndc status' now reports tcp and recursion quota - states. - -1378. [func] Improved positive feedback for 'rndc {reload|refresh}. - -1377. [func] dns_zone_load{new}() now reports if the zone was - loaded, queued for loading to up to date. - -1376. [func] New function dns_zone_logc() to log to specified - category. - -1375. [func] 'rndc dumpdb' now dumps the adb cache along with the - data cache. - -1374. [func] dns_adb_dump() now logs the lame zones associated - with each server. - -1373. [bug] Recovery from expired glue failed under certain - circumstances. - -1372. [bug] named crashes with an assertion failure on exit when - sharing the same port for listening and querying, and - changing listening addresses several times. [RT# 3509] - -1371. [bug] notify-source-v6, transfer-source-v6 and - query-source-v6 with explicit addresses and using the - same ports as named was listening on could interfere - with named's ability to answer queries sent to those - addresses. - -1370. [bug] dig '+[no]recurse' was incorrectly documented. - -1369. [bug] Adding an NS record as the lexicographically last - record in a secure zone didn't work. - -1368. [func] remove support for bitstring labels. - -1367. [func] Use response times to select forwarders. - -1366. [contrib] queryperf usage was incomplete. Add '-h' for help. - -1365. [func] "localhost" and "localnets" acls now include IPv6 - addresses / prefixes. - -1364. [func] Log file name when unable to open memory statistics - and dump database files. [RT# 3437] - -1363. [func] Listen-on-v6 now supports specific addresses. - -1362. [bug] remove IFF_RUNNING test when scanning interfaces. - -1361. [func] log the reason for rejecting a server when resolving - queries. - -1360. [bug] --enable-libbind would fail when not built in the - source tree for certain OS's. - -1359. [security] Support patches OpenSSL libraries. - http://www.cert.org/advisories/CA-2002-23.html - -1358. [bug] It was possible to trigger a INSIST when debugging - large dynamic updates. [RT #3390] - -1357. [bug] nsupdate was extremely wasteful of memory. - -1356. [tuning] Reduce the number of events / quantum for zone tasks. - -1355. [bug] Fix DNSSEC wildcard proof for CNAME/DNAME. - -1354. [doc] lwres man pages had illegal nroff. - -1353. [contrib] sdb/ldap to version 0.9. - -1352. [bug] dig, host, nslookup when falling back to TCP use the - current search entry (if any). [RT #3374] - -1351. [bug] lwres_getipnodebyname() returned the wrong name - when given a IPv4 literal, af=AF_INET6 and AI_MAPPED - was set. - -1350. [bug] dns_name_fromtext() failed to handle too many labels - gracefully. - -1349. [security] Minimum OpenSSL version now 0.9.6e (was 0.9.5a). - http://www.cert.org/advisories/CA-2002-23.html - -1348. [port] win32: Rewrote code to use I/O Completion Ports - in socket.c and eliminating a host of socket - errors. Performance is enhanced. - -1347. [placeholder] - -1346. [placeholder] - -1345. [port] Use a explicit -Wformat with gcc. Not all versions - include it in -Wall. - -1344. [func] Log if the serial number on the master has gone - backwards. - If you have multiple machines specified in the masters - clause you may want to set 'multi-master yes;' to - suppress this warning. - -1343. [func] Log successful notifies received (info). Adjust log - level for failed notifies to notice. - -1342. [func] Log remote address with TCP dispatch failures. - -1341. [func] Allow a rate limiter to be stalled. - -1340. [bug] Delay and spread out the startup refresh load. - -1339. [func] dig, host and nslookup now use IP6.ARPA for nibble - lookups. Bit string lookups are no longer attempted. - -1338. [placeholder] - -1337. [placeholder] - -1336. [func] Nibble lookups under IP6.ARPA are now supported by - dns_byaddr_create(). dns_byaddr_createptrname() is - deprecated, use dns_byaddr_createptrname2() instead. - -1335. [bug] When performing a nonexistence proof, the validator - should discard parent NXTs from higher in the DNS. - -1334. [bug] When signing/verifying rdatasets, duplicate rdatas - need to be suppressed. - -1333. [contrib] queryperf now reports a summary of returned - rcodes (-c), rcodes are printed in mnemonic form (-v). - -1332. [func] Report the current serial with periodic commits when - rolling forward the journal. - -1331. [func] Generate DNSSEC wildcard proofs. - -1330. [bug] When processing events (non-threaded) only allow - the task one chance to use to use its quantum. - -1329. [func] named-checkzone will now check if nameservers that - appear to be IP addresses. Available modes "fail", - "warn" (default) and "ignore" the results of the - check. - -1328. [bug] The validator could incorrectly verify an invalid - negative proof. - -1327. [bug] The validator would incorrectly mark data as insecure - when seeing a bogus signature before a correct - signature. - -1326. [bug] DNAME/CNAME signatures were not being cached when - validation was not being performed. [RT #3284] - -1325. [bug] If the tcpquota was exhausted it was possible to - to trigger a INSIST() failure. - -1324. [port] darwin: ifconfig.sh now supports darwin. - -1323. [port] linux: Slackware 4.0 needs . [RT #3205] - -1322. [bug] dnssec-signzone usage message was misleading. - -1321. [bug] If the last RRset in a zone is glue, dnssec-signzone - would incorrectly duplicate its output and sign it. - -1320. [doc] query-source-v6 was missing from options section. - [RT #3218] - -1319. [func] libbind: log attempts to exploit #1318. - -1318. [bug] libbind: Remote buffer overrun. - -1317. [port] libbind: TrueUNIX 5.1 does not like __align as a - element name. - -1316. [bug] libbind: gethostans() could get out of sync parsing - the response if there was a very long CNAME chain. - -1315. [bug] Options should apply to the internal _bind view. - -1314. [port] Handle ECONNRESET from sendmsg() [unix]. - -1313. [func] Query log now says if the query was signed (S) or - if EDNS was used (E). - -1312. [func] Log TSIG key used w/ outgoing zone transfers. - -1311. [bug] lwres_getrrsetbyname leaked memory. [RT #3159] - -1310. [bug] 'rndc stop' failed to cause zones to be flushed - sometimes. [RT #3157] - -1309. [func] Log that a zone transfer was covered by a TSIG. - -1308. [func] DS (delegation signer) support. - -1307. [bug] nsupdate: allow white space base64 key data. - -1306. [bug] Badly encoded LOC record when the size, horizontal - precision or vertical precision was 0.1m. - -1305. [bug] Document that internal zones are included in the - rndc status results. - -1304. [func] New function: dns_zone_name(). - -1303. [func] Option 'flush-zones-on-shutdown ;'. - -1302. [func] Extended rndc dumpdb to support dumping of zones and - view selection: 'dumpdb [-all|-zones|-cache] [view]'. - -1301. [func] New category 'update-security'. - -1300. [port] Compaq Trucluster support. - -1299. [bug] Set AI_ADDRCONFIG when looking up addresses - via getaddrinfo() (affects dig, host, nslookup, rndc - and nsupdate). - -1298. [bug] The CINCLUDES macro in lib/dns/sec/dst/Makefile - could be left with a trailing "\" after configure - has been run. - -1297. [port] linux: make handling EINVAL from socket() no longer - conditional on #ifdef LINUX. - -1296. [bug] isc_log_closefilelogs() needed to lock the log - context. - -1295. [bug] isc_log_setdebuglevel() needed to lock the log - context. - -1294. [func] libbind: no longer attempts bit string labels for - IPv6 reverse resolution. Try IP6.ARPA then IP6.INT - for nibble style resolution. - -1293. [func] Entropy can now be retrieved from EGDs. [RT #2438] - -1292. [func] Enable IPv6 support when using ioctl style interface - scanning and OS supports SIOCGLIFADDR using struct - if_laddrreq. - -1291. [func] Enable IPv6 support when using sysctl style interface - scanning. - -1290. [func] "dig axfr" now reports the number of messages - as well as the number of records. - -1289. [port] See if -ldl is required for OpenSSL? [RT #2672] - -1288. [bug] Adjusted REQUIRE's in lib/dns/name.c to better - reflect written requirements. - -1287. [bug] REQUIRE that DNS_DBADD_MERGE only be set when adding - a rdataset to a zone db in the rbtdb implementation of - addrdataset. - -1286. [bug] dns_name_downcase() enforce requirement that - target != NULL or name->buffer != NULL. - -1285. [func] lwres: probe the system to see what address families - are currently in use. - -1284. [bug] The RTT estimate on unused servers was not aged. - [RT #2569] - -1283. [func] Use "dataready" accept filter if available. - -1282. [port] libbind: hpux 11.11 interface scanning. - -1281. [func] Log zone when unable to get private keys to update - zone. Log zone when NXT records are missing from - secure zone. - -1280. [bug] libbind: escape '(' and ')' when converting to - presentation form. - -1279. [port] Darwin uses (unsigned long) for size_t. [RT #2590] - -1278. [func] dig: now supports +[no]cl +[no]ttlid. - -1277. [func] You can now create your own customized printing - styles: dns_master_stylecreate() and - dns_master_styledestroy(). - -1276. [bug] libbind: const pointer conflicts in res_debug.c. - -1275. [port] libbind: hpux: treat all hpux systems as BIG_ENDIAN. - -1274. [bug] Memory leak in lwres_gnbarequest_parse(). - -1273. [port] libbind: solaris: 64 bit binary compatibility. - -1272. [contrib] Berkeley DB 4.0 sdb implementation from - Nuno Miguel Rodrigues . - -1271. [bug] "recursion available: {denied,approved}" was too - confusing. - -1270. [bug] Check that system inet_pton() and inet_ntop() support - AF_INET6. - -1269. [port] Openserver: ifconfig.sh support. - -1268. [port] Openserver: the value FD_SETSIZE depends on whether - is included or not. Be consistent. - -1267. [func] isc_file_openunique() now creates file using mode - 0666 rather than 0600. - -1266. [bug] ISC_LINK_INIT, ISC_LINK_UNLINK, ISC_LIST_DEQUEUE, - __ISC_LINK_UNLINKUNSAFE and __ISC_LIST_DEQUEUEUNSAFE - are not C++ compatible, use *_TYPE versions instead. - -1265. [bug] libbind: LINK_INIT and UNLINK were not compatible with - C++, use LINK_INIT_TYPE and UNLINK_TYPE instead. - -1264. [placeholder] - -1263. [bug] Reference after free error if dns_dispatchmgr_create() - failed. - -1262. [bug] ns_server_destroy() failed to set *serverp to NULL. - -1261. [func] libbind: ns_sign2() and ns_sign_tcp() now provide - support for compressed TSIG owner names. - -1260. [func] libbind: res_update can now update IPv6 servers, - new function res_findzonecut2(). - -1259. [bug] libbind: get_salen() IPv6 support was broken for OSs - w/o sa_len. - -1258. [bug] libbind: res_nametotype() and res_nametoclass() were - broken. - -1257. [bug] Failure to write pid-file should not be fatal on - reload. [RT #2861] - -1256. [contrib] 'queryperf' now has EDNS (-e) + DNSSEC DO (-D) support. - -1255. [bug] When verifying that an NXT proves nonexistence, check - the rcode of the message and only do the matching NXT - check. That is, for NXDOMAIN responses, check that - the name is in the range between the NXT owner and - next name, and for NOERROR NODATA responses, check - that the type is not present in the NXT bitmap. - -1254. [func] preferred-glue option from BIND 8.3. - -1253. [bug] The dnssec system test failed to remove the correct - files. - -1252. [bug] Dig, host and nslookup were not checking the address - the answer was coming from against the address it was - sent to. [RT# 2692] - -1251. [port] win32: a make file contained absolute version specific - references. - -1250. [func] Nsupdate will report the address the update was - sent to. - -1249. [bug] Missing masters clause was not handled gracefully. - [RT #2703] - -1248. [bug] DESTDIR was not being propagated between makes. - -1247. [bug] Don't reset the interface index for link/site local - addresses. [RT #2576] - -1246. [func] New functions isc_sockaddr_issitelocal(), - isc_sockaddr_islinklocal(), isc_netaddr_issitelocal() - and isc_netaddr_islinklocal(). - -1245. [bug] Treat ENOBUFS, ENOMEM and ENFILE as soft errors for - accept(). - -1244. [bug] Receiving a TCP message from a blackhole address would - prevent further messages being received over that - interface. - -1243. [bug] It was possible to trigger a REQUIRE() in - dns_message_findtype(). [RT #2659] - -1242. [bug] named-checkzone failed if a journal existed. [RT #2657] - -1241. [bug] Drop received UDP messages with a zero source port - as these are invariably forged. [RT #2621] - -1240. [bug] It was possible to leak zone references by - specifying an incorrect zone to rndc. - -1239. [bug] Under certain circumstances named could continue to - use a name after it had been freed triggering - INSIST() failures. [RT #2614] - -1238. [bug] It is possible to lockup the server when shutting down - if notifies were being processed. [RT #2591] - -1237. [bug] nslookup: "set q=type" failed. - -1236. [bug] dns_rdata{class,type}_fromtext() didn't handle non - NULL terminated text regions. [RT #2588] - -1235. [func] Report 'out of memory' errors from openssl. - -1234. [bug] contrib/sdb: 'zonetodb' failed to call - dns_result_register(). DNS_R_SEENINCLUDE should not - be fatal. - -1233. [bug] The flags field of a KEY record can be expressed in - hex as well as decimal. - -1232. [bug] unix/errno2result() didn't handle EADDRNOTAVAIL. - -1231. [port] HPUX 11.11 recvmsg() can return spurious EADDRNOTAVAIL. - -1230. [bug] isccc_cc_isreply() and isccc_cc_isack() were broken. - -1229. [bug] named would crash if it received a TSIG signed - query as part of an AXFR response. [RT #2570] - -1228. [bug] 'make install' did not depend on 'make all'. [RT #2559] - -1227. [bug] dns_lex_getmastertoken() now returns ISC_R_BADNUMBER - if a number was expected and some other token was - found. [RT#2532] - -1226. [func] Use EDNS for zone refresh queries. [RT #2551] - -1225. [func] dns_message_setopt() no longer requires that - dns_message_renderbegin() to have been called. - -1224. [bug] 'rrset-order' and 'sortlist' should be additive - not exclusive. - -1223. [func] 'rrset-order' partially works 'cyclic' and 'random' - are supported. - -1222. [bug] Specifying 'port *' did not always result in a system - selected (non-reserved) port being used. [RT #2537] - -1221. [bug] Zone types 'master', 'slave' and 'stub' were not being - compared case insensitively. [RT #2542] - -1220. [func] Support for APL rdata type. - -1219. [func] Named now reports the TSIG extended error code when - signature verification fails. [RT #1651] - -1218. [bug] Named incorrectly returned SERVFAIL rather than - NOTAUTH when there was a TSIG BADTIME error. [RT #2519] - -1217. [func] Report locations of previous key definition when a - duplicate is detected. - -1216. [bug] Multiple server clauses for the same server were not - reported. [RT #2514] - -1215. [port] solaris: add support to ifconfig.sh for x86 2.5.1 - -1214. [bug] Win32: isc_file_renameunique() could leave zero length - files behind. - -1213. [func] Report view associated with client if it is not a - standard view (_default or _bind). - -1212. [port] libbind: 64k answer buffers were causing stack space - to be exceeded for certain OS. Use heap space instead. - -1211. [bug] dns_name_fromtext() incorrectly handled certain - valid octal bitlabels. [RT #2483] - -1210. [bug] libbind: getnameinfo() failed to lookup IPv4 mapped / - compatible addresses. [RT #2461] - -1209. [bug] Dig, host, nslookup were not checking the message ids - on the responses. [RT #2454] - -1208. [bug] dns_master_load*() failed to log a error message if - an error was detected when parsing the ownername of - a record. [RT #2448] - -1207. [bug] libbind: getaddrinfo() could call freeaddrinfo() with - an invalid pointer. - -1206. [bug] SERVFAIL and NOTIMP responses to an EDNS query should - trigger a non-EDNS retry. - -1205. [bug] OPT, TSIG and TKEY cannot be used to set the "class" - of the message. [RT #2449] - -1204. [bug] libbind: res_nupdate() failed to update the name - server addresses before sending the update. - -1203. [func] Report locations of previous acl and zone definitions - when a duplicate is detected. - -1202. [func] New functions: cfg_obj_line() and cfg_obj_file(). - -1201. [bug] Require that if 'callbacks' is passed to - dns_rdata_fromtext(), callbacks->error and - callbacks->warn are initialized. - -1200. [bug] Log 'errno' that we are unable to convert to - isc_result_t. [RT #2404] - -1199. [doc] ARM reference to RFC 2157 should have been RFC 1918. - [RT #2436] - -1198. [bug] OPT printing style was not consistent with the way the - header fields are printed. The DO bit was not reported - if set. Report if any of the MBZ bits are set. - -1197. [bug] Attempts to define the same acl multiple times were not - detected. - -1196. [contrib] update mdnkit to 2.2.3. - -1195. [bug] Attempts to redefine builtin acls should be caught. - [RT #2403] - -1194. [bug] Not all duplicate zone definitions were being detected - at the named.conf checking stage. [RT #2431] - -1193. [bug] dig +besteffort parsing didn't handle packet - truncation. dns_message_parse() has new flag - DNS_MESSAGE_IGNORETRUNCATION. - -1192. [bug] The seconds fields in LOC records were restricted - to three decimal places. More decimal places should - be allowed but warned about. - -1191. [bug] A dynamic update removing the last non-apex name in - a secure zone would fail. [RT #2399] - -1190. [func] Add the "rndc freeze" and "rndc unfreeze" commands. - [RT #2394] - -1189. [bug] On some systems, malloc(0) returns NULL, which - could cause the caller to report an out of memory - error. [RT #2398] - -1188. [bug] Dynamic updates of a signed zone would fail if - some of the zone private keys were unavailable. - -1187. [bug] named was incorrectly returning DNSSEC records - in negative responses when the DO bit was not set. - -1186. [bug] isc_hex_tobuffer(,,length = 0) failed to unget the - EOL token when reading to end of line. - -1185. [bug] libbind: don't assume statp->_u._ext.ext is valid - unless RES_INIT is set when calling res_*init(). - -1184. [bug] libbind: call res_ndestroy() if RES_INIT is set - when res_*init() is called. - -1183. [bug] Handle ENOSR error when writing to the internal - control pipe. [RT #2395] - -1182. [bug] The server could throw an assertion failure when - constructing a negative response packet. - -1181. [func] Add the "key-directory" configuration statement, - which allows the server to look for online signing - keys in alternate directories. - -1180. [func] dnssec-keygen should always generate keys with - protocol 3 (DNSSEC), since it's less confusing - that way. - -1179. [func] Add SIG(0) support to nsupdate. - -1178. [bug] Follow and cache (if appropriate) A6 and other - data chains to completion in the additional section. - -1177. [func] Report view when loading zones if it is not a - standard view (_default or _bind). [RT #2270] - -1176. [doc] Document that allow-v6-synthesis is only performed - for clients that are supplied recursive service. - [RT #2260] - -1175. [bug] named-checkzone and named-checkconf failed to call - dns_result_register() at startup which could - result in runtime exceptions when printing - "out of memory" errors. [RT #2335] - -1174. [bug] Win32: add WSAECONNRESET to the expected errors - from connect(). [RT #2308] - -1173. [bug] Potential memory leaks in isc_log_create() and - isc_log_settag(). [RT #2336] - -1172. [doc] Add CERT, GPOS, KX, NAPTR, NSAP, PX and TXT to - table of RR types in ARM. - -1171. [func] Added function isc_region_compare(), updated files in - lib/dns to use this function instead of local one. - -1170. [bug] Don't attempt to print the token when a I/O error - occurs when parsing named.conf. [RT #2275] - -1169. [func] Identify recursive queries in the query log. - -1168. [bug] Empty also-notify clauses were not handled. [RT #2309] - -1167. [contrib] nslint-2.1a3 (from author). - -1166. [bug] "Not Implemented" should be reported as NOTIMP, - not NOTIMPL. [RT #2281] - -1165. [bug] We were rejecting notify-source{-v6} in zone clauses. - -1164. [bug] Empty masters clauses in slave / stub zones were not - handled gracefully. [RT #2262] - -1163. [func] isc_time_formattimestamp() now includes the year. - -1162. [bug] The allow-notify option was not accepted in slave - zone statements. - -1161. [bug] named-checkzone looped on unbalanced brackets. - [RT #2248] - -1160. [bug] Generating Diffie-Hellman keys longer than 1024 - bits could fail. [RT #2241] - -1159. [bug] MD and MF are not permitted to be loaded by RFC1123. - -1158. [func] Report the client's address when logging notify - messages. - -1157. [func] match-clients and match-destinations now accept - keys. [RT #2045] - -1156. [port] The configure test for strsep() incorrectly - succeeded on certain patched versions of - AIX 4.3.3. [RT #2190] - -1155. [func] Recover from master files being removed from under - us. - -1154. [bug] Don't attempt to obtain the netmask of a interface - if there is no address configured. [RT #2176] - -1153. [func] 'rndc {stop|halt} -p' now reports the process id - of the instance of named being shutdown. - -1152. [bug] libbind: read buffer overflows. - -1151. [bug] nslookup failed to check that the arguments to - the port, timeout, and retry options were - valid integers and in range. [RT #2099] - -1150. [bug] named incorrectly accepted TTL values - containing plus or minus signs, such as - 1d+1h-1s. - -1149. [func] New function isc_parse_uint32(). - -1148. [func] 'rndc-confgen -a' now provides positive feedback. - -1147. [func] Set IPV6_V6ONLY on IPv6 sockets if supported by - the OS. listen-on-v6 { any; }; should no longer - result in IPv4 queries be accepted. Similarly - control { inet :: ... }; should no longer result - in IPv4 connections being accepted. This can be - overridden at compile time by defining - ISC_ALLOW_MAPPED=1. - -1146. [func] Allow IPV6_IPV6ONLY to be set/cleared on a socket if - supported by the OS by a new function - isc_socket_ipv6only(). - -1145. [func] "host" no longer reports a NOERROR/NODATA response - by printing nothing. [RT #2065] - -1144. [bug] rndc-confgen would crash if both the -a and -t - options were specified. [RT #2159] - -1143. [bug] When a trusted-keys statement was present and named - was built without crypto support, it would leak memory. - -1142. [bug] dnssec-signzone would fail to delete temporary files - in some failure cases. [RT #2144] - -1141. [bug] When named rejected a control message, it would - leak a file descriptor and memory. It would also - fail to respond, causing rndc to hang. - [RT #2139, #2164] - -1140. [bug] rndc-confgen did not accept IPv6 addresses as arguments - to the -s option. [RT #2138] - -1139. [func] It is now possible to flush a given name from the - cache(s) via 'rndc flushname name [view]'. [RT #2051] - -1138. [func] It is now possible to flush a given name from the - cache by calling the new function - dns_cache_flushname(). - -1137. [func] It is now possible to flush a given name from the - ADB by calling the new function dns_adb_flushname(). - -1136. [bug] CNAME records synthesized from DNAMEs did not - have a TTL of zero as required by RFC2672. - [RT #2129] - -1135. [func] You can now override the default syslog() facility for - named/lwresd at compile time. [RT #1982] - -1134. [bug] Multi-threaded servers could deadlock in ferror() - when reloading zone files. [RT #1951, #1998] - -1133. [bug] IN6_IS_ADDR_LOOPBACK was not portably defined on - platforms without IN6_IS_ADDR_LOOPBACK. [RT #2106] - -1132. [func] Improve UPDATE prerequisite failure diagnostic messages. - -1131. [bug] The match-destinations view option did not work with - IPv6 destinations. [RT #2073, #2074] - -1130. [bug] Log messages reporting an out-of-range serial number - did not include the out-of-range number but the - following token. [RT #2076] - -1129. [bug] Multi-threaded servers could crash under heavy - resolution load due to a race condition. [RT #2018] - -1128. [func] sdb drivers can now provide RR data in either text - or wire format, the latter using the new functions - dns_sdb_putrdata() and dns_sdb_putnamedrdata(). - -1127. [func] rndc: If the server to contact has multiple addresses, - try all of them. - -1126. [bug] The server could access a freed event if shut - down while a client start event was pending - delivery. [RT #2061] - -1125. [bug] rndc: -k option was missing from usage message. - [RT #2057] - -1124. [doc] dig: +[no]dnssec, +[no]besteffort and +[no]fail - are now documented. [RT #2052] - -1123. [bug] dig +[no]fail did not match description. [RT #2052] - -1122. [tuning] Resolution timeout reduced from 90 to 30 seconds. - [RT #2046] - -1121. [bug] The server could attempt to access a NULL zone - table if shut down while resolving. - [RT #1587, #2054] - -1120. [bug] Errors in options were not fatal. [RT #2002] - -1119. [func] Added support in Win32 for NTFS file/directory ACL's - for access control. - -1118. [bug] On multi-threaded servers, a race condition - could cause an assertion failure in resolver.c - during resolver shutdown. [RT #2029] - -1117. [port] The configure check for in6addr_loopback incorrectly - succeeded on AIX 4.3 when compiling with -O2 - because the test code was optimized away. - [RT #2016] - -1116. [bug] Setting transfers in a server clause, transfers-in, - or transfers-per-ns to a value greater than - 2147483647 disabled transfers. [RT #2002] - -1115. [func] Set maximum values for cleaning-interval, - heartbeat-interval, interface-interval, - max-transfer-idle-in, max-transfer-idle-out, - max-transfer-time-in, max-transfer-time-out, - statistics-interval of 28 days and - sig-validity-interval of 3660 days. [RT #2002] - -1114. [port] Ignore more accept() errors. [RT #2021] - -1113. [bug] The allow-update-forwarding option was ignored - when specified in a view. [RT #2014] - -1112. [placeholder] - -1111. [bug] Multi-threaded servers could deadlock processing - recursive queries due to a locking hierarchy - violation in adb.c. [RT #2017] - -1110. [bug] dig should only accept valid abbreviations of +options. - [RT #2003] - -1109. [bug] nsupdate accepted illegal ttl values. - -1108. [bug] On Win32, rndc was hanging when named was not running - due to failure to select for exceptional conditions - in select(). [RT #1870] - -1107. [bug] nsupdate could catch an assertion failure if an - invalid domain name was given as the argument to - the "zone" command. - -1106. [bug] After seeing an out of range TTL, nsupdate would - treat all TTLs as out of range. [RT #2001] - -1105. [port] OpenUNIX 8 enable threads by default. [RT #1970] - -1104. [bug] Invalid arguments to the transfer-format option - could cause an assertion failure. [RT #1995] - -1103. [port] OpenUNIX 8 support (ifconfig.sh). [RT #1970] - -1102. [doc] Note that query logging is enabled by directing the - queries category to a channel. - -1101. [bug] Array bounds read error in lwres_gai_strerror. - -1100. [bug] libbind: DNSSEC key ids were computed incorrectly. - -1099. [cleanup] libbind: defining REPORT_ERRORS in lib/bind/dst caused - compile time errors. - -1098. [bug] libbind: HMAC-MD5 key files are now mode 0600. - -1097. [func] libbind: RES_PRF_TRUNC for dig. - -1096. [func] libbind: "DNSSEC OK" (DO) support. - -1095. [func] libbind: resolver option: no-tld-query. disables - trying unqualified as a tld. no_tld_query is also - supported for FreeBSD compatibility. - -1094. [func] libbind: add support gcc's format string checking. - -1093. [doc] libbind: miscellaneous nroff fixes. - -1092. [bug] libbind: get*by*() failed to check if res_init() had - been called. - -1091. [bug] libbind: misplaced va_end(). - -1090. [bug] libbind: dns_ho.c:add_hostent() was not returning - the amount of memory consumed resulting in garbage - address being returned. Alignment calculations were - wasting space. We weren't suppressing duplicate - addresses. - -1089. [func] libbind: inet_{cidr,net}_{pton,ntop}() now have IPv6 - support. - -1088. [port] libbind: MPE/iX C.70 (incomplete) - -1087. [bug] libbind: struct __res_state too large on 64 bit arch. - -1086. [port] libbind: sunos: old sprintf. - -1085. [port] libbind: solaris: sys_nerr and sys_errlist do not - exist when compiling in 64 bit mode. - -1084. [cleanup] libbind: gai_strerror() rewritten. - -1083. [bug] The default control channel listened on the - wildcard address, not the loopback as documented. - [RT #1975] - -1082. [bug] The -g option to named incorrectly caused logging - to be sent to syslog in addition to stderr. - [RT #1974] - -1081. [bug] Multicast queries were incorrectly identified - based on the source address, not the destination - address. - -1080. [bug] BIND 8 compatibility: accept bare IP prefixes - as the second element of a two-element top level - sort list statement. [RT #1964] - -1079. [bug] BIND 8 compatibility: accept bare elements at top - level of sort list treating them as if they were - a single element list. [RT #1963] - -1078. [bug] We failed to correct bad tv_usec values in one case. - [RT #1966] - -1077. [func] Do not accept further recursive clients when - the total number of recursive lookups being - processed exceeds max-recursive-clients, even - if some of the lookups are internally generated. - [RT #1915, #1938] - -1076. [bug] A badly defined global key could trigger an assertion - on load/reload if views were used. [RT #1947] - -1075. [bug] Out-of-range network prefix lengths were not - reported. [RT #1954] - -1074. [bug] Running out of memory in dump_rdataset() could - cause an assertion failure. [RT #1946] - -1073. [bug] The ADB cache cleaning should also be space driven. - [RT #1915, #1938] - -1072. [bug] The TCP client quota could be exceeded when - recursion occurred. [RT #1937] - -1071. [bug] Sockets listening for TCP DNS connections - specified an excessive listen backlog. [RT #1937] - -1070. [bug] Copy DNSSEC OK (DO) to response as specified by - draft-ietf-dnsext-dnssec-okbit-03.txt. - -1069. [placeholder] - -1068. [bug] errno could be overwritten by catgets(). [RT #1921] - -1067. [func] Allow quotas to be soft, isc_quota_soft(). - -1066. [bug] Provide a thread safe wrapper for strerror(). - [RT #1689] - -1065. [func] Runtime support to select new / old style interface - scanning using ioctls. - -1064. [bug] Do not shut down active network interfaces if we - are unable to scan the interface list. [RT #1921] - -1063. [bug] libbind: "make install" was failing on IRIX. - [RT #1919] - -1062. [bug] If the control channel listener socket was shut - down before server exit, the listener object could - be freed twice. [RT #1916] - -1061. [bug] If periodic cache cleaning happened to start - while cleaning due to reaching the configured - maximum cache size was in progress, the server - could catch an assertion failure. [RT #1912] - -1060. [func] Move refresh, stub and notify UDP retry processing - into dns_request. - -1059. [func] dns_request now support will now retry UDP queries, - dns_request_createvia2() and dns_request_createraw2(). - -1058. [func] Limited lifetime ticker timers are now available, - isc_timertype_limited. - -1057. [bug] Reloading the server after adding a "file" clause - to a zone statement could cause the server to - crash due to a typo in change 1016. - -1056. [bug] Rndc could catch an assertion failure on SIGINT due - to an uninitialized variable. [RT #1908] - -1055. [func] Version and hostname queries can now be disabled - using "version none;" and "hostname none;", - respectively. - -1054. [bug] On Win32, cfg_categories and cfg_modules need to be - exported from the libisccfg DLL. - -1053. [bug] Dig did not increase its timeout when receiving - AXFRs unless the +time option was used. [RT #1904] - -1052. [bug] Journals were not being created in binary mode - resulting in "journal format not recognized" error - under Win32. [RT #1889] - -1051. [bug] Do not ignore a network interface completely just - because it has a noncontiguous netmask. Instead, - omit it from the localnets ACL and issue a warning. - [RT #1891] - -1050. [bug] Log messages reporting malformed IP addresses in - address lists such as that of the forwarders option - failed to include the correct error code, file - name, and line number. [RT #1890] - -1049. [func] "pid-file none;" will disable writing a pid file. - [RT #1848] - -1048. [bug] Servers built with -DISC_MEM_USE_INTERNAL_MALLOC=1 - didn't work. - -1047. [bug] named was incorrectly refusing all requests signed - with a TSIG key derived from an unsigned TKEY - negotiation with a NOERROR response. [RT #1886] - -1046. [bug] The help message for the --with-openssl configure - option was inaccurate. [RT #1880] - -1045. [bug] It was possible to skip saving glue for a nameserver - for a stub zone. - -1044. [bug] Specifying allow-transfer, notify-source, or - notify-source-v6 in a stub zone was not treated - as an error. - -1043. [bug] Specifying a transfer-source or transfer-source-v6 - option in the zone statement for a master zone was - not treated as an error. [RT #1876] - -1042. [bug] The "config" logging category did not work properly. - [RT #1873] - -1041. [bug] Dig/host/nslookup could catch an assertion failure - on SIGINT due to an uninitialized variable. [RT #1867] - -1040. [bug] Multiple listen-on-v6 options with different ports - were not accepted. [RT #1875] - -1039. [bug] Negative responses with CNAMEs in the answer section - were cached incorrectly. [RT #1862] - -1038. [bug] In servers configured with a tkey-domain option, - TKEY queries with an owner name other than the root - could cause an assertion failure. [RT #1866, #1869] - -1037. [bug] Negative responses whose authority section contain - SOA or NS records whose owner names are not equal - equal to or parents of the query name should be - rejected. [RT #1862] - -1036. [func] Silently drop requests received via multicast as - long as there is no final multicast DNS standard. - -1035. [bug] If we respond to multicast queries (which we - currently do not), respond from a unicast address - as specified in RFC 1123. [RT #137] - -1034. [bug] Ignore the RD bit on multicast queries as specified - in RFC 1123. [RT #137] - -1033. [bug] Always respond to requests with an unsupported opcode - with NOTIMP, even if we don't have a matching view - or cannot determine the class. - -1032. [func] hostname.bind/txt/chaos now returns the name of - the machine hosting the nameserver. This is useful - in diagnosing problems with anycast servers. - -1031. [bug] libbind.a: isc__gettimeofday() infinite recursion. - [RT #1858] - -1030. [bug] On systems with no resolv.conf file, nsupdate - exited with an error rather than defaulting - to using the loopback address. [RT #1836] - -1029. [bug] Some named.conf errors did not cause the loading - of the configuration file to return a failure - status even though they were logged. [RT #1847] - -1028. [bug] On Win32, dig/host/nslookup looked for resolv.conf - in the wrong directory. [RT #1833] - -1027. [bug] RRs having the reserved type 0 should be rejected. - [RT #1471] - -1026. [placeholder] - -1025. [bug] Don't use multicast addresses to resolve iterative - queries. [RT #101] - -1024. [port] Compilation failed on HP-UX 11.11 due to - incompatible use of the SIOCGLIFCONF macro - name. [RT #1831] - -1023. [func] Accept hints without TTLs. - -1022. [bug] Don't report empty root hints as "extra data". - [RT #1802] - -1021. [bug] On Win32, log message timestamps were one month - later than they should have been, and the server - would exhibit unspecified behavior in December. - -1020. [bug] IXFR log messages did not distinguish between - true IXFRs, AXFR-style IXFRs, and mere version - polls. [RT #1811] - -1019. [bug] The value of the lame-ttl option was limited to 18000 - seconds, not 1800 seconds as documented. [RT #1803] - -1018. [bug] The default log channel was not always initialized - correctly. [RT #1813] - -1017. [bug] When specifying TSIG keys to dig and nsupdate using - the -k option, they must be HMAC-MD5 keys. [RT #1810] - -1016. [bug] Slave zones with no backup file were re-transferred - on every server reload. - -1015. [bug] Log channels that had a "versions" option but no - "size" option failed to create numbered log - files. [RT #1783] - -1014. [bug] Some queries would cause statistics counters to - increment more than once or not at all. [RT #1321] - -1013. [bug] It was possible to cancel a query twice when marking - a server as bogus or by having a blackhole acl. - [RT #1776] - -1012. [bug] The -p option to named did not behave as documented. - -1011. [cleanup] Removed isc_dir_current(). - -1010. [bug] The server could attempt to execute a command channel - command after initiating server shutdown, causing - an assertion failure. [RT #1766] - -1009. [port] OpenUNIX 8 support. [RT #1728] - -1008. [port] libtool.m4, ltmain.sh from libtool-1.4.2. - -1007. [port] config.guess, config.sub from autoconf-2.52. - -1006. [bug] If a KEY RR was found missing during DNSSEC validation, - an assertion failure could subsequently be triggered - in the resolver. [RT #1763] - -1005. [bug] Don't copy nonzero RCODEs from request to response. - [RT #1765] - -1004. [port] Deal with recvfrom() returning EHOSTDOWN. [RT #1770] - -1003. [func] Add the +retry option to dig. - -1002. [bug] When reporting an unknown class name in named.conf, - including the file name and line number. [RT #1759] - -1001. [bug] win32 socket code doio_recv was not catching a - WSACONNRESET error when a client was timing out - the request and closing its socket. [RT #1745] - -1000. [bug] BIND 8 compatibility: accept "HESIOD" as an alias - for class "HS". [RT #1759] - - 999. [func] "rndc retransfer zone [class [view]]" added. - [RT #1752] - - 998. [func] named-checkzone now has arguments to specify the - chroot directory (-t) and working directory (-w). - [RT #1755] - - 997. [func] Add support for RSA-SHA1 keys (RFC3110). - - 996. [func] Issue warning if the configuration filename contains - the chroot path. - - 995. [bug] dig, host, nslookup: using a raw IPv6 address as a - target address should be fatal on a IPv4 only system. - - 994. [func] Treat non-authoritative responses to queries for type - NS as referrals even if the NS records are in the - answer section, because BIND 8 servers incorrectly - send them that way. This is necessary for DNSSEC - validation of the NS records of a secure zone to - succeed when the parent is a BIND 8 server. [RT #1706] - - 993. [func] dig: -v now reports the version. - - 992. [doc] dig: ~/.digrc is now documented. - - 991. [func] Lower UDP refresh timeout messages to level - debug 1. - - 990. [bug] The rndc-confgen man page was not installed. - - 989. [bug] Report filename if $INCLUDE fails for file related - errors. [RT #1736] - - 988. [bug] 'additional-from-auth no;' did not work reliably - in the case of queries answered from the cache. - [RT #1436] - - 987. [bug] "dig -help" didn't show "+[no]stats". - - 986. [bug] "dig +noall" failed to clear stats and command - printing. - - 985. [func] Consider network interfaces to be up iff they have - a nonzero IP address rather than based on the - IFF_UP flag. [RT #1160] - - 984. [bug] Multi-threading should be enabled by default on - Solaris 2.7 and newer, but it wasn't. - - 983. [func] The server now supports generating IXFR difference - sequences for non-dynamic zones by comparing zone - versions, when enabled using the new config - option "ixfr-from-differences". [RT #1727] - - 982. [func] If "memstatistics-file" is set in options the memory - statistics will be written to it. - - 981. [func] The dnssec tools can now take multiple '-r randomfile' - arguments. - - 980. [bug] Incoming zone transfers restarting after an error - could trigger an assertion failure. [RT #1692] - - 979. [func] Incremental master file dumping. dns_master_dumpinc(), - dns_master_dumptostreaminc(), dns_dumpctx_attach(), - dns_dumpctx_detach(), dns_dumpctx_cancel(), - dns_dumpctx_db() and dns_dumpctx_version(). - - 978. [bug] dns_db_attachversion() had an invalid REQUIRE() - condition. - - 977. [bug] Improve "not at top of zone" error message. - - 976. [func] named-checkconf can now test load master zones - (named-checkconf -z). [RT #1468] - - 975. [bug] "max-cache-size default;" as a view option - caused an assertion failure. - - 974. [bug] "max-cache-size unlimited;" as a global option - was not accepted. - - 973. [bug] Failed to log the question name when logging: - "bad zone transfer request: non-authoritative zone - (NOTAUTH)". - - 972. [bug] The file modification time code in zone.c was using the - wrong epoch. [RT #1667] - - 971. [placeholder] - - 970. [func] 'max-journal-size' can now be used to set a target - size for a journal. - - 969. [func] dig now supports the undocumented dig 8 feature - of allowing arbitrary labels, not just dotted - decimal quads, with the -x option. This can be - used to conveniently look up RFC2317 names as in - "dig -x 10.0.0.0-127". [RT #827, #1576, #1598] - - 968. [bug] On win32, the isc_time_now() function was unnecessarily - calling strtime(). [RT #1671] - - 967. [bug] On win32, the link for bindevt was not including the - required resource file to enable the event viewer - to interpret the error messages in the event log, - [RT #1668] - - 966. [placeholder] - - 965. [bug] Including data other than root server NS and A - records in the root hint file could cause a rbtdb - node reference leak. [RT #1581, #1618] - - 964. [func] Warn if data other than root server NS and A records - are found in the root hint file. [RT #1581, #1618] - - 963. [bug] Bad ISC_LANG_ENDDECLS. [RT #1645] - - 962. [bug] libbind: bad "#undef", don't attempt to install - non-existant nlist.h. [RT #1640] - - 961. [bug] Tried to use a IPV6 feature when ISC_PLATFORM_HAVEIPV6 - was not defined. [RT #1482] - - 960. [port] liblwres failed to build on systems with support for - getrrsetbyname() in the OS. [RT #1592] - - 959. [port] On FreeBSD, determine the number of CPUs by calling - sysctlbyname(). [RT #1584] - - 958. [port] ssize_t is not available on all platforms. [RT #1607] - - 957. [bug] sys/select.h inclusion was broken on older platforms. - [RT #1607] - - 956. [bug] ns_g_autorndcfile changed to ns_g_keyfile - in named/win32/os.c due to code changes in - change #953. win32 .make file for rndc-confgen - updated to add include path for os.h header. - - --- 9.2.0rc1 released --- - - 955. [bug] When using views, the zone's class was not being - inherited from the view's class. [RT #1583] - - 954. [bug] When requesting AXFRs or IXFRs using dig, host, or - nslookup, the RD bit should not be set as zone - transfers are inherently nonrecursive. [RT #1575] - - 953. [func] The /var/run/named.key file from change #843 - has been replaced by /etc/rndc.key. Both - named and rndc will look for this file and use - it to configure a default control channel key - if not already configured using a different - method (rndc.conf / controls). Unlike - named.key, rndc.key is not created automatically; - it must be created by manually running - "rndc-confgen -a". - - 952. [bug] The server required manual intervention to serve the - affected zones if it died between creating a journal - and committing the first change to it. - - 951. [bug] CFLAGS was not passed to the linker when - linking some of the test programs under - bin/tests. [RT #1555]. - - 950. [bug] Explicit TTLs did not properly override $TTL - due to a bug in change 834. [RT #1558] - - 949. [bug] host was unable to print records larger than 512 - bytes. [RT #1557] - - --- 9.2.0b2 released --- - - 948. [port] Integrated support for building on Windows NT / - Windows 2000. - - 947. [bug] dns_rdata_soa_t had a badly named element "mname" which - was really the RNAME field from RFC1035. To avoid - confusion and silent errors that would occur it the - "origin" and "mname" elements were given their correct - names "mname" and "rname" respectively, the "mname" - element is renamed to "contact". - - 946. [cleanup] doc/misc/options is now machine-generated from the - configuration parser syntax tables, and therefore - more likely to be correct. - - 945. [func] Add the new view-specific options - "match-destinations" and "match-recursive-only". - - 944. [func] Check for expired signatures on load. - - 943. [bug] The server could crash when receiving a command - via rndc if the configuration file listed only - nonexistent keys in the controls statement. [RT #1530] - - 942. [port] libbind: GETNETBYADDR_ADDR_T was not correctly - defined on some platforms. - - 941. [bug] The configuration checker crashed if a slave - zone didn't contain a masters statement. [RT #1514] - - 940. [bug] Double zone locking failure on error path. [RT #1510] - - --- 9.2.0b1 released --- - - 939. [port] Add the --disable-linux-caps option to configure for - systems that manage capabilities outside of named. - [RT #1503] - - 938. [placeholder] - - 937. [bug] A race when shutting down a zone could trigger a - INSIST() failure. [RT #1034] - - 936. [func] Warn about IPv4 addresses that are not complete - dotted quads. [RT #1084] - - 935. [bug] inet_pton failed to reject leading zeros. - - 934. [port] Deal with systems where accept() spuriously returns - ECONNRESET. - - 933. [bug] configure failed doing libbind on platforms not - supported by BIND 8. [RT #1496] - - --- 9.2.0a3 released --- - - 932. [bug] Use INSTALL_SCRIPT, not INSTALL_PROGRAM, - when installing isc-config.sh. - [RT #198, #1466] - - 931. [bug] The controls statement only attempted to verify - messages using the first key in the key list. - (9.2.0a1/a2 only). - - 930. [func] Query performance testing tool added as - contrib/queryperf. - - 929. [placeholder] - - 928. [bug] nsupdate would send empty update packets if the - send (or empty line) command was run after - another send but before any new updates or - prerequisites were specified. It should simply - ignore this command. - - 927. [bug] Don't hold the zone lock for the entire dump to disk. - [RT #1423] - - 926. [bug] The resolver could deadlock with the ADB when - shutting down (multi-threaded builds only). - [RT #1324] - - 925. [cleanup] Remove openssl from the distribution; require that - --with-openssl be specified if DNSSEC is needed. - - 924. [port] Extend support for pre-RFC2133 IPv6 implementation. - [RT #987] - - 923. [bug] Multiline TSIG secrets (and other multiline strings) - were not accepted in named.conf. [RT #1469] - - 922. [func] Added two new lwres_getrrsetbyname() result codes, - ERR_NONAME and ERR_NODATA. - - 921. [bug] lwres returned an incorrect error code if it received - a truncated message. - - 920. [func] Increase the lwres receive buffer size to 16K. - [RT #1451] - - 919. [placeholder] - - 918. [func] In nsupdate, TSIG errors are no longer treated as - fatal errors. - - 917. [func] New nsupdate command 'key', allowing TSIG keys to - be specified in the nsupdate command stream rather - than the command line. - - 916. [bug] Specifying type ixfr to dig without specifying - a serial number failed in unexpected ways. - - 915. [func] The named-checkconf and named-checkzone programs - now have a '-v' option for printing their version. - [RT #1151] - - 914. [bug] Global 'server' statements were rejected when - using views, even though they were accepted - in 9.1. [RT #1368] - - 913. [bug] Cache cleaning was not sufficiently aggressive. - [RT #1441, #1444] - - 912. [bug] Attempts to set the 'additional-from-cache' or - 'additional-from-auth' option to 'no' in a - server with recursion enabled will now - be ignored and cause a warning message. - [RT #1145] - - 911. [placeholder] - - 910. [port] Some pre-RFC2133 IPv6 implementations do not define - IN6ADDR_ANY_INIT. [RT #1416] - - 909. [placeholder] - - 908. [func] New program, rndc-confgen, to simplify setting up rndc. - - 907. [func] The ability to get entropy from either the - random device, a user-provided file or from - the keyboard was migrated from the DNSSEC tools - to libisc as isc_entropy_usebestsource(). - - 906. [port] Separated the system independent portion of - lib/isc/unix/entropy.c into lib/isc/entropy.c - and added lib/isc/win32/entropy.c. - - 905. [bug] Configuring a forward "zone" for the root domain - did not work. [RT #1418] - - 904. [bug] The server would leak memory if attempting to use - an expired TSIG key. [RT #1406] - - 903. [bug] dig should not crash when receiving a TCP packet - of length 0. - - 902. [bug] The -d option was ignored if both -t and -g were also - specified. - - 901. [placeholder] - - 900. [bug] A config.guess update changed the system identification - string of FreeBSD systems; configure and - bin/tests/system/ifconfig.sh now recognize the new - string. - - --- 9.2.0a2 released --- - - 899. [bug] lib/dns/soa.c failed to compile on many platforms - due to inappropriate use of a void value. - [RT #1372, #1373, #1386, #1387, #1395] - - 898. [bug] "dig" failed to set a nonzero exit status - on UDP query timeout. [RT #1323] - - 897. [bug] A config.guess update changed the system identification - string of UnixWare systems; configure now recognizes - the new string. - - 896. [bug] If a configuration file is set on named's command line - and it has a relative pathname, the current directory - (after any possible jailing resulting from named -t) - will be prepended to it so that reloading works - properly even when a directory option is present. - - 895. [func] New function, isc_dir_current(), akin to POSIX's - getcwd(). - - 894. [bug] When using the DNSSEC tools, a message intended to warn - when the keyboard was being used because of the lack - of a suitable random device was not being printed. - - 893. [func] Removed isc_file_test() and added isc_file_exists() - for the basic functionality that was being added - with isc_file_test(). - - 892. [placeholder] - - 891. [bug] Return an error when a SIG(0) signed response to - an unsigned query is seen. This should actually - do the verification, but it's not currently - possible. [RT #1391] - - 890. [cleanup] The man pages no longer require the mandoc macros - and should now format cleanly using most versions of - nroff, and HTML versions of the man pages have been - added. Both are generated from DocBook source. - - 889. [port] Eliminated blank lines before .TH in nroff man - pages since they cause problems with some versions - of nroff. [RT #1390] - - 888. [bug] Don't die when using TKEY to delete a nonexistent - TSIG key. [RT #1392] - - 887. [port] Detect broken compilers that can't call static - functions from inline functions. [RT #1212] - - 886. [placeholder] - - 885. [placeholder] - - 884. [placeholder] - - 883. [placeholder] - - 882. [placeholder] - - 881. [placeholder] - - 880. [placeholder] - - 879. [placeholder] - - 878. [placeholder] - - 877. [placeholder] - - 876. [placeholder] - - 875. [placeholder] - - 874. [placeholder] - - 873. [placeholder] - - 872. [placeholder] - - 871. [placeholder] - - 870. [placeholder] - - 869. [placeholder] - - 868. [placeholder] - - 867. [placeholder] - - 866. [func] Close debug only file channels when debug is set to - zero. [RT #1246] - - 865. [bug] The new configuration parser did not allow - the optional debug level in a "severity debug" - clause of a logging channel to be omitted. - This is now allowed and treated as "severity - debug 1;" like it does in BIND 8.2.4, not as - "severity debug 0;" like it did in BIND 9.1. - [RT #1367] - - 864. [cleanup] Multi-threading is now enabled by default on - OSF1, Solaris 2.7 and newer, AIX, IRIX, and HP-UX. - - 863. [bug] If an error occurred while an outgoing zone transfer - was starting up, the server could access a domain - name that had already been freed when logging a - message saying that the transfer was starting. - [RT #1383] - - 862. [bug] Use after realloc(), non portable pointer arithmetic in - grmerge(). - - 861. [port] Add support for Mac OS X, by making it equivalent - to Darwin. This was derived from the config.guess - file shipped with Mac OS X. [RT #1355] - - 860. [func] Drop cross class glue in zone transfers. - - 859. [bug] Cache cleaning now won't swamp the CPU if there - is a persistent overlimit condition. - - 858. [func] isc_mem_setwater() no longer requires that when the - callback function is non-NULL then its hi_water - argument must be greater than its lo_water argument - (they can now be equal) or that they be non-zero. - - 857. [cleanup] Use ISC_MAGIC() to define all magic numbers for - structs, for our friends in EBCDIC-land. - - 856. [func] Allow partial rdatasets to be returned in answer and - authority sections to help non-TCP capable clients - recover from truncation. [RT #1301] - - 855. [bug] Stop spurious "using RFC 1035 TTL semantics" warnings. - - 854. [bug] The config parser didn't properly handle config - options that were specified in units of time other - than seconds. [RT #1372] - - 853. [bug] configure_view_acl() failed to detach existing acls. - [RT #1374] - - 852. [bug] Handle responses from servers which do not know - about IXFR. - - 851. [cleanup] The obsolete support-ixfr option was not properly - ignored. - - --- 9.2.0a1 released --- - - 850. [bug] dns_rbt_findnode() would not find nodes that were - split on a bitstring label somewhere other than in - the last label of the node. [RT #1351] - - 849. [func] will ensure INADDR_LOOPBACK is defined. - - 848. [func] A minimum max-cache-size of two megabytes is enforced - by the cache cleaner. - - 847. [func] Added isc_file_test(), which currently only has - some very basic functionality to test for the - existence of a file, whether a pathname is absolute, - or whether a pathname is the fundamental representation - of the current directory. It is intended that this - function can be expanded to test other things a - programmer might want to know about a file. - - 846. [func] A non-zero 'param' to dst_key_generate() when making an - hmac-md5 key means that good entropy is not required. - - 845. [bug] The access rights on the public file of a symmetric - key are now restricted as soon as the file is opened, - rather than after it has been written and closed. - - 844. [func] will ensure INADDR_LOOPBACK is defined, - just as does. - - 843. [func] If no controls statement is present in named.conf, - or if any inet phrase of a controls statement is - lacking a keys clause, then a key will be automatically - generated by named and an rndc.conf-style file - named named.key will be written that uses it. rndc - will use this file only if its normal configuration - file, or one provided on the command line, does not - exist. - - 842. [func] 'rndc flush' now takes an optional view. - - 841. [bug] When sdb modules were not declared threadsafe, their - create and destroy functions were not serialized. - - 840. [bug] The config file parser could print the wrong file - name if an error was detected after an included file - was parsed. [RT #1353] - - 839. [func] Dump packets for which there was no view or that the - class could not be determined to category "unmatched". - - 838. [port] UnixWare 7.x.x is now suported by - bin/tests/system/ifconfig.sh. - - 837. [cleanup] Multi-threading is now enabled by default only on - OSF1, Solaris 2.7 and newer, and AIX. - - 836. [func] Upgraded libtool to 1.4. - - 835. [bug] The dispatcher could enter a busy loop if - it got an I/O error receiving on a UDP socket. - [RT #1293] - - 834. [func] Accept (but warn about) master files beginning with - an SOA record without an explicit TTL field and - lacking a $TTL directive, by using the SOA MINTTL - as a default TTL. This is for backwards compatibility - with old versions of BIND 8, which accepted such - files without warning although they are illegal - according to RFC1035. - - 833. [cleanup] Moved dns_soa_*() from to - , and extended them to support - all the integer-valued fields of the SOA RR. - - 832. [bug] The default location for named.conf in named-checkconf - should depend on --sysconfdir like it does in named. - [RT #1258] - - 831. [placeholder] - - 830. [func] Implement 'rndc status'. - - 829. [bug] The DNS_R_ZONECUT result code should only be returned - when an ANY query is made with DNS_DBFIND_GLUEOK set. - In all other ANY query cases, returning the delegation - is better. - - 828. [bug] The errno value from recvfrom() could be overwritten - by logging code. [RT #1293] - - 827. [bug] When an IXFR protocol error occurs, the slave - should retry with AXFR. - - 826. [bug] Some IXFR protocol errors were not detected. - - 825. [bug] zone.c:ns_query() detached from the wrong zone - reference. [RT #1264] - - 824. [bug] Correct line numbers reported by dns_master_load(). - [RT #1263] - - 823. [func] The output of "dig -h" now goes to stdout so that it - can easily be piped through "more". [RT #1254] - - 822. [bug] Sending nxrrset prerequisites would crash nsupdate. - [RT #1248] - - 821. [bug] The program name used when logging to syslog should - be stripped of leading path components. - [RT #1178, #1232] - - 820. [bug] Name server address lookups failed to follow - A6 chains into the glue of local authoritative - zones. - - 819. [bug] In certain cases, the resolver's attempts to - restart an address lookup at the root could cause - the fetch to deadlock (with itself) instead of - restarting. [RT #1225] - - 818. [bug] Certain pathological responses to ANY queries could - cause an assertion failure. [RT #1218] - - 817. [func] Adjust timeouts for dialup zone queries. - - 816. [bug] Report potential problems with log file accessibility - at configuration time, since such problems can't - reliably be reported at the time they actually occur. - - 815. [bug] If a log file was specified with a path separator - character (i.e. "/") in its name and the directory - did not exist, the log file's name was treated as - though it were the directory name. [RT #1189] - - 814. [bug] Socket objects left over from accept() failures - were incorrectly destroyed, causing corruption - of socket manager data structures. - - 813. [bug] File descriptors exceeding FD_SETSIZE were handled - badly. [RT #1192] - - 812. [bug] dig sometimes printed incomplete IXFR responses - due to an uninitialized variable. [RT #1188] - - 811. [bug] Parentheses were not quoted in zone dumps. [RT #1194] - - 810. [bug] The signer name in SIG records was not properly - downcased when signing/verifying records. [RT #1186] - - 809. [bug] Configuring a non-local address as a transfer-source - could cause an assertion failure during load. - - 808. [func] Add 'rndc flush' to flush the server's cache. - - 807. [bug] When setting up TCP connections for incoming zone - transfers, the transfer-source port was not - ignored like it should be. - - 806. [bug] DNS_R_SEENINCLUDE was failing to propagate back up - the calling stack to the zone maintence level, causing - zones to not reload when an included file was touched - but the top-level zone file was not. - - 805. [bug] When using "forward only", missing root hints should - not cause queries to fail. [RT #1143] - - 804. [bug] Attempting to obtain entropy could fail in some - situations. This would be most common on systems - with user-space threads. [RT #1131] - - 803. [bug] Treat all SIG queries as if they have the CD bit set, - otherwise no data will be returned [RT #749] - - 802. [bug] DNSSEC key tags were computed incorrectly in almost - all cases. [RT #1146] - - 801. [bug] nsupdate should treat lines beginning with ';' as - comments. [RT #1139] - - 800. [bug] dnssec-signzone produced incorrect statistics for - large zones. [RT #1133] - - 799. [bug] The ADB didn't find AAAA glue in a zone unless A6 - glue was also present. - - 798. [bug] nsupdate should be able to reject bad input lines - and continue. [RT #1130] - - 797. [func] Issue a warning if the 'directory' option contains - a relative path. [RT #269] - - 796. [func] When a size limit is associated with a log file, - only roll it when the size is reached, not every - time the log file is opened. [RT #1096] - - 795. [func] Add the +multiline option to dig. [RT #1095] - - 794. [func] Implement the "port" and "default-port" statements - in rndc.conf. - - 793. [cleanup] The DNSSEC tools could create filenames that were - illegal or contained shell metacharacters. They - now use a different text encoding of names that - doesn't have these problems. [RT #1101] - - 792. [cleanup] Replace the OMAPI command channel protocol with a - simpler one. - - 791. [bug] The command channel now works over IPv6. - - 790. [bug] Wildcards created using dynamic update or IXFR - could fail to match. [RT #1111] - - 789. [bug] The "localhost" and "localnets" ACLs did not match - when used as the second element of a two-element - sortlist item. - - 788. [func] Add the "match-mapped-addresses" option, which - causes IPv6 v4mapped addresses to be treated as - IPv4 addresses for the purpose of acl matching. - - 787. [bug] The DNSSEC tools failed to downcase domain - names when mapping them into file names. - - 786. [bug] When DNSSEC signing/verifying data, owner names were - not properly downcased. - - 785. [bug] A race condition in the resolver could cause - an assertion failure. [RT #673, #872, #1048] - - 784. [bug] nsupdate and other programs would not quit properly - if some signals were blocked by the caller. [RT #1081] - - 783. [bug] Following CNAMEs could cause an assertion failure - when either using an sdb database or under very - rare conditions. - - 782. [func] Implement the "serial-query-rate" option. - - 781. [func] Avoid error packet loops by dropping duplicate FORMERR - responses. [RT #1006] - - 780. [bug] Error handling code dealing with out of memory or - other rare errors could lead to assertion failures - by calling functions on unitialized names. [RT #1065] - - 779. [func] Added the "minimal-responses" option. - - 778. [bug] When starting cache cleaning, cleaning_timer_action() - returned without first pausing the iterator, which - could cause deadlock. [RT #998] - - 777. [bug] An empty forwarders list in a zone failed to override - global forwarders. [RT #995] - - 776. [func] Improved error reporting in denied messages. [RT #252] - - 775. [placeholder] - - 774. [func] max-cache-size is implemented. - - 773. [func] Added isc_rwlock_trylock() to attempt to lock without - blocking. - - 772. [bug] Owner names could be incorrectly omitted from cache - dumps in the presence of negative caching entries. - [RT #991] - - 771. [cleanup] TSIG errors related to unsynchronized clocks - are logged better. [RT #919] - - 770. [func] Add the "edns yes_or_no" statement to the server - clause. [RT #524] - - 769. [func] Improved error reporting when parsing rdata. [RT #740] - - 768. [bug] The server did not emit an SOA when a CNAME - or DNAME chain ended in NXDOMAIN in an - authoritative zone. - - 767. [placeholder] - - 766. [bug] A few cases in query_find() could leak fname. - This would trigger the mpctx->allocated == 0 - assertion when the server exited. - [RT #739, #776, #798, #812, #818, #821, #845, - #892, #935, #966] - - 765. [func] ACL names are once again case insensitive, like - in BIND 8. [RT #252] - - 764. [func] Configuration files now allow "include" directives - in more places, such as inside the "view" statement. - [RT #377, #728, #860] - - 763. [func] Configuration files no longer have reserved words. - [RT #731, #753] - - 762. [cleanup] The named.conf and rndc.conf file parsers have - been completely rewritten. - - 761. [bug] _REENTRANT was still defined when building with - --disable-threads. - - 760. [contrib] Significant enhancements to the pgsql sdb driver. - - 759. [bug] The resolver didn't turn off "avoid fetches" mode - when restarting, possibly causing resolution - to fail when it should not. This bug only affected - platforms which support both IPv4 and IPv6. [RT #927] - - 758. [bug] The "avoid fetches" code did not treat negative - cache entries correctly, causing fetches that would - be useful to be avoided. This bug only affected - platforms which support both IPv4 and IPv6. [RT #927] - - 757. [func] Log zone transfers. - - 756. [bug] dns_zone_load() could "return" success when no master - file was configured. - - 755. [bug] Fix incorrectly formatted log messages in zone.c. - - 754. [bug] Certain failure conditions sending UDP packets - could cause the server to retry the transmission - indefinitely. [RT #902] - - 753. [bug] dig, host, and nslookup would fail to contact a - remote server if getaddrinfo() returned an IPv6 - address on a system that doesn't support IPv6. - [RT #917] - - 752. [func] Correct bad tv_usec elements returned by - gettimeofday(). - - 751. [func] Log successful zone loads / transfers. [RT #898] - - 750. [bug] A query should not match a DNAME whose trust level - is pending. [RT #916] - - 749. [bug] When a query matched a DNAME in a secure zone, the - server did not return the signature of the DNAME. - [RT #915] - - 748. [doc] List supported RFCs in doc/misc/rfc-compliance. - [RT #781] - - 747. [bug] The code to determine whether an IXFR was possible - did not properly check for a database that could - not have a journal. [RT #865, #908] - - 746. [bug] The sdb didn't clone rdatasets properly, causing - a crash when the server followed delegations. [RT #905] - - 745. [func] Report the owner name of records that fail - semantic checks while loading. - - 744. [bug] When returning DNS_R_CNAME or DNS_R_DNAME as the - result of an ANY or SIG query, the resolver failed - to setup the return event's rdatasets, causing an - assertion failure in the query code. [RT #881] - - 743. [bug] Receiving a large number of certain malformed - answers could cause named to stop responding. - [RT #861] - - 742. [placeholder] - - 741. [port] Support openssl-engine. [RT #709] - - 740. [port] Handle openssl library mismatches slightly better. - - 739. [port] Look for /dev/random in configure, rather than - assuming it will be there for only a predefined - set of OSes. - - 738. [bug] If a non-threadsafe sdb driver supported AXFR and - received an AXFR request, it would deadlock or die - with an assertion failure. [RT #852] - - 737. [port] stdtime.c failed to compile on certain platforms. - - 736. [func] New functions isc_task_{begin,end}exclusive(). - - 735. [doc] Add BIND 4 migration notes. - - 734. [bug] An attempt to re-lock the zone lock could occur if - the server was shutdown during a zone tranfer. - [RT #830] - - 733. [bug] Reference counts of dns_acl_t objects need to be - locked but were not. [RT #801, #821] - - 732. [bug] Glue with 0 TTL could also cause SERVFAIL. [RT #828] - - 731. [bug] Certain zone errors could cause named-checkzone to - fail ungracefully. [RT #819] - - 730. [bug] lwres_getaddrinfo() returns the correct result when - it fails to contact a server. [RT #768] - - 729. [port] pthread_setconcurrency() needs to be called on Solaris. - - 728. [bug] Fix comment processing on master file directives. - [RT# 757] - - 727. [port] Work around OS bug where accept() succeeds but - fails to fill in the peer address of the accepted - connection, by treating it as an error rather than - an assertion failure. [RT #809] - - 726. [func] Implement the "trace" and "notrace" commands in rndc. - - 725. [bug] Installing man pages could fail. - - 724. [func] New libisc functions isc_netaddr_any(), - isc_netaddr_any6(). - - 723. [bug] Referrals whose NS RRs had a 0 TTL caused the resolver - to return DNS_R_SERVFAIL. [RT #783] - - 722. [func] Allow incremental loads to be canceled. - - 721. [cleanup] Load manager and dns_master_loadfilequota() are no - more. - - 720. [bug] Server could enter infinite loop in - dispatch.c:do_cancel(). [RT #733] - - 719. [bug] Rapid reloads could trigger an assertion failure. - [RT #743, #763] - - 718. [cleanup] "internal" is no longer a reserved word in named.conf. - [RT #753, #731] - - 717. [bug] Certain TKEY processing failure modes could - reference an uninitialized variable, causing the - server to crash. [RT #750] - - 716. [bug] The first line of a $INCLUDE master file was lost if - an origin was specified. [RT #744] - - 715. [bug] Resolving some A6 chains could cause an assertion - failure in adb.c. [RT #738] - - 714. [bug] Preserve interval timers across reloads unless changed. - [RT# 729] - - 713. [func] named-checkconf takes '-t directory' similar to named. - [RT #726] - - 712. [bug] Sending a large signed update message caused an - assertion failure. [RT #718] - - 711. [bug] The libisc and liblwres implementations of - inet_ntop contained an off by one error. - - 710. [func] The forwarders statement now takes an optional - port. [RT #418] - - 709. [bug] ANY or SIG queries for data with a TTL of 0 - would return SERVFAIL. [RT #620] - - 708. [bug] When building with --with-openssl, the openssl headers - included with BIND 9 should not be used. [RT #702] - - 707. [func] The "filename" argument to named-checkzone is no - longer optional, to reduce confusion. [RT #612] - - 706. [bug] Zones with an explicit "allow-update { none; };" - were considered dynamic and therefore not reloaded - on SIGHUP or "rndc reload". - - 705. [port] Work out resource limit type for use where rlim_t is - not available. [RT #695] - - 704. [port] RLIMIT_NOFILE is not available on all platforms. - [RT #695] - - 703. [port] sys/select.h is needed on older platforms. [RT #695] - - 702. [func] If the address 0.0.0.0 is seen in resolv.conf, - use 127.0.0.1 instead. [RT #693] - - 701. [func] Root hints are now fully optional. Class IN - views use compiled-in hints by default, as - before. Non-IN views with no root hints now - provide authoritative service but not recursion. - A warning is logged if a view has neither root - hints nor authoritative data for the root. [RT #696] - - 700. [bug] $GENERATE range check was wrong. [RT #688] - - 699. [bug] The lexer mishandled empty quoted strings. [RT #694] - - 698. [bug] Aborting nsupdate with ^C would lead to several - race conditions. - - 697. [bug] nsupdate was not compatible with the undocumented - BIND 8 behavior of ignoring TTLs in "update delete" - commands. [RT #693] - - 696. [bug] lwresd would die with an assertion failure when passed - a zero-length name. [RT #692] - - 695. [bug] If the resolver attempted to query a blackholed or - bogus server, the resolution would fail immediately. - - 694. [bug] $GENERATE did not produce the last entry. - [RT #682, #683] - - 693. [bug] An empty lwres statement in named.conf caused - the server to crash while loading. - - 692. [bug] Deal with systems that have getaddrinfo() but not - gai_strerror(). [RT #679] - - 691. [bug] Configuring per-view forwarders caused an assertion - failure. [RT #675, #734] - - 690. [func] $GENERATE now supports DNAME. [RT #654] - - 689. [doc] man pages are now installed. [RT #210] - - 688. [func] "make tags" now works on systems with the - "Exuberant Ctags" etags. - - 687. [bug] Only say we have IPv6, with sufficent functionality, - if it has actually been tested. [RT #586] - - 686. [bug] dig and nslookup can now be properly aborted during - blocking operations. [RT #568] - - 685. [bug] nslookup should use the search list/domain options - from resolv.conf by default. [RT #405, #630] - - 684. [bug] Memory leak with view forwarders. [RT #656] - - 683. [bug] File descriptor leak in isc_lex_openfile(). - - 682. [bug] nslookup displayed SOA records incorrectly. [RT #665] - - 681. [bug] $GENERATE specifying output format was broken. [RT #653] - - 680. [bug] dns_rdata_fromstruct() mishandled options bigger - than 255 octets. - - 679. [bug] $INCLUDE could leak memory and file descriptors on - reload. [RT #639] - - 678. [bug] "transfer-format one-answer;" could trigger an assertion - failure. [RT #646] - - 677. [bug] dnssec-signzone would occasionally use the wrong ttl - for database operations and fail. [RT #643] - - 676. [bug] Log messages about lame servers to category - 'lame-servers' rather than 'resolver', so as not - to be gratuitously incompatible with BIND 8. - - 675. [bug] TKEY queries could cause the server to leak - memory. - - 674. [func] Allow messages to be TSIG signed / verified using - a offset from the current time. - - 673. [func] The server can now convert RFC1886-style recursive - lookup requests into RFC2874-style lookups, when - enabled using the new option "allow-v6-synthesis". - - 672. [bug] The wrong time was in the "time signed" field when - replying with BADTIME error. - - 671. [bug] The message code was failing to parse a message with - no question section and a TSIG record. [RT #628] - - 670. [bug] The lwres replacements for getaddrinfo and - getipnodebyname didn't properly check for the - existence of the sockaddr sa_len field. - - 669. [bug] dnssec-keygen now makes the public key file - non-world-readable for symmetric keys. [RT #403] - - 668. [func] named-checkzone now reports multiple errors in master - files. - - 667. [bug] On Linux, running named with the -u option and a - non-world-readable configuration file didn't work. - [RT #626] - - 666. [bug] If a request sent by dig is longer than 512 bytes, - use TCP. - - 665. [bug] Signed responses were not sent when the size of the - TSIG + question exceeded the maximum message size. - [RT #628] - - 664. [bug] The t_tasks and t_timers module tests are now skipped - when building without threads, since they require - threads. - - 663. [func] Accept a size_spec, not just an integer, in the - (unimplemented and ignored) max-ixfr-log-size option - for compatibility with recent versions of BIND 8. - [RT #613] - - 662. [bug] dns_rdata_fromtext() failed to log certain errors. - - 661. [bug] Certain UDP IXFR requests caused an assertion failure - (mpctx->allocated == 0). [RT #355, #394, #623] - - 660. [port] Detect multiple CPUs on HP-UX and IRIX. - - 659. [performance] Rewrite the name compression code to be much faster. - - 658. [cleanup] Remove all vestiges of 16 bit global compression. - - 657. [bug] When a listen-on statement in an lwres block does not - specify a port, use 921, not 53. Also update the - listen-on documentation. [RT #616] - - 656. [func] Treat an unescaped newline in a quoted string as - an error. This means that TXT records with missing - close quotes should have meaningful errors printed. - - 655. [bug] Improve error reporting on unexpected eof when loading - zones. [RT #611] - - 654. [bug] Origin was being forgotten in TCP retries in dig. - [RT #574] - - 653. [bug] +defname option in dig was reversed in sense. - [RT #549] - - 652. [bug] zone_saveunique() did not report the new name. - - 651. [func] The AD bit in responses now has the meaning - specified in . - - 650. [bug] SIG(0) records were being generated and verified - incorrectly. [RT #606] - - 649. [bug] It was possible to join to an already running fctx - after it had "cloned" its events, but before it sent - them. In this case, the event of the newly joined - fetch would not contain the answer, and would - trigger the INSIST() in fctx_sendevents(). In - BIND 9.0, this bug did not trigger an INSIST(), but - caused the fetch to fail with a SERVFAIL result. - [RT #588, #597, #605, #607] - - 648. [port] Add support for pre-RFC2133 IPv6 implementations. - - 647. [bug] Resolver queries sent after following multiple - referrals had excessively long retransmission - timeouts due to incorrectly counting the referrals - as "restarts". - - 646. [bug] The UnixWare ISC_PLATFORM_FIXIN6INADDR fix in isc/net.h - didn't _cleanly_ fix the problem it was trying to fix. - - 645. [port] BSD/OS 3.0 needs pthread_init(). [RT #603] - - 644. [bug] #622 needed more work. [RT #562] - - 643. [bug] xfrin error messages made more verbose, added class - of the zone. [RT# 599] - - 642. [bug] Break the exit_check() race in the zone module. - [RT #598] - - --- 9.1.0b2 released --- - - 641. [bug] $GENERATE caused a uninitialized link to be used. - [RT #595] - - 640. [bug] Memory leak in error path could cause - "mpctx->allocated == 0" failure. [RT #584] - - 639. [bug] Reading entropy from the keyboard would sometimes fail. - [RT #591] - - 638. [port] lib/isc/random.c needed to explicitly include time.h - to get a prototype for time() when pthreads was not - being used. [RT #592] - - 637. [port] Use isc_u?int64_t instead of (unsigned) long long in - lib/isc/print.c. Also allow lib/isc/print.c to - be compiled even if the platform does not need it. - [RT #592] - - 636. [port] Shut up MSVC++ about a possible loss of precision - in the ISC__BUFFER_PUTUINT*() macros. [RT #592] - - 635. [bug] Reloading a server with a configured blackhole list - would cause an assertion. [RT #590] - - 634. [bug] A log file will completely stop being written when - it reaches the maximum size in all cases, not just - when versioning is also enabled. [RT #570] - - 633. [port] Cope with rlim_t missing on BSD/OS systems. [RT #575] - - 632. [bug] The index array of the journal file was - corrupted as it was written to disk. - - 631. [port] Build without thread support on systems without - pthreads. - - 630. [bug] Locking failure in zone code. [RT #582] - - 629. [bug] 9.1.0b1 dereferenced a null pointer and crashed - when responding to a UDP IXFR request. - - 628. [bug] If the root hints contained only AAAA addresses, - named would be unable to perform resolution. - - 627. [bug] The EDNS0 blackhole detection code of change 324 - waited for three retransmissions to each server, - which takes much too long when a domain has many - name servers and all of them drop EDNS0 queries. - Now we retry without EDNS0 after three consecutive - timeouts, even if they are all from different - servers. [RT #143] - - 626. [bug] The lightweight resolver daemon no longer crashes - when asked for a SIG rrset. [RT #558] - - 625. [func] Zones now inherit their class from the enclosing view. - - 624. [bug] The zone object could get timer events after it had - been destroyed, causing a server crash. [RT #571] - - 623. [func] Added "named-checkconf" and "named-checkzone" program - for syntax checking named.conf files and zone files, - respectively. - - 622. [bug] A canceled request could be destroyed before - dns_request_destroy() was called. [RT #562] - - 621. [port] Disable IPv6 at runtime if IPv6 sockets are unusable. - This mostly affects Red Hat Linux 7.0, which has - conflicts between libc and the kernel. - - 620. [bug] dns_master_load*inc() now require 'task' and 'load' - to be non-null. Also 'done' will not be called if - dns_master_load*inc() fails immediately. [RT #565] - - 619. [placeholder] - - 618. [bug] Queries to a signed zone could sometimes cause - an assertion failure. - - 617. [bug] When using dynamic update to add a new RR to an - existing RRset with a different TTL, the journal - entries generated from the update did not include - explicit deletions and re-additions of the existing - RRs to update their TTL to the new value. - - 616. [func] dnssec-signzone -t output now includes performance - statistics. - - 615. [bug] dnssec-signzone did not like child keysets signed - by multiple keys. - - 614. [bug] Checks for uninitialized link fields were prone - to false positives, causing assertion failures. - The checks are now disabled by default and may - be re-enabled by defining ISC_LIST_CHECKINIT. - - 613. [bug] "rndc reload zone" now reloads primary zones. - It previously only updated slave and stub zones, - if an SOA query indicated an out of date serial. - - 612. [cleanup] Shutup a ridiculously noisy HP-UX compiler that - complains relentlessly about how its treatment - of 'const' has changed as well as how casting - sometimes tightens alignment constraints. - - 611. [func] allow-notify can be used to permit processing of - notify messages from hosts other than a slave's - masters. - - 610. [func] rndc dumpdb is now supported. - - 609. [bug] getrrsetbyname() would crash lwresd if the server - found more SIGs than answers. [RT #554] - - 608. [func] dnssec-signzone now adds a comment to the zone - with the time the file was signed. - - 607. [bug] nsupdate would fail if it encountered a CNAME or - DNAME in a response to an SOA query. [RT #515] - - 606. [bug] Compiling with --disable-threads failed due - to isc_thread_self() being incorrectly defined - as an integer rather than a function. - - 605. [func] New function isc_lex_getlasttokentext(). - - 604. [bug] The named.conf parser could print incorrect line - numbers when long comments were present. - - 603. [bug] Make dig handle multiple types or classes on the same - query more correctly. - - 602. [func] Cope automatically with UnixWare's broken - IN6_IS_ADDR_* macros. [RT #539] - - 601. [func] Return a non-zero exit code if an update fails - in nsupdate. - - 600. [bug] Reverse lookups sometimes failed in dig, etc... - - 599. [func] Added four new functions to the libisc log API to - support i18n messages. isc_log_iwrite(), - isc_log_ivwrite(), isc_log_iwrite1() and - isc_log_ivwrite1() were added. - - 598. [bug] An update-policy statement would cause the server - to assert while loading. [RT #536] - - 597. [func] dnssec-signzone is now multi-threaded. - - 596. [bug] DNS_RDATASLAB_FORCE and DNS_RDATASLAB_EXACT are - not mutually exclusive. - - 595. [port] On Linux 2.2, socket() returns EINVAL when it - should return EAFNOSUPPORT. Work around this. - [RT #531] - - 594. [func] sdb drivers are now assumed to not be thread-safe - unless the DNS_SDBFLAG_THREADSAFE flag is supplied. - - 593. [bug] If a secure zone was missing all its NXTs and - a dynamic update was attempted, the server entered - an infinite loop. - - 592. [bug] The sig-validity-interval option now specifies a - number of days, not seconds. This matches the - documentation. [RT #529] - - --- 9.1.0b1 released --- - - 591. [bug] Work around non-reentrancy in openssl by disabling - precomputation in keys. - - 590. [doc] There are now man pages for the lwres library in - doc/man/lwres. - - 589. [bug] The server could deadlock if a zone was updated - while being transferred out. - - 588. [bug] ctx->in_use was not being correctly initialized when - when pushing a file for $INCLUDE. [RT #523] - - 587. [func] A warning is now printed if the "allow-update" - option allows updates based on the source IP - address, to alert users to the fact that this - is insecure and becoming increasingly so as - servers capable of update forwarding are being - deployed. - - 586. [bug] multiple views with the same name were fatal. [RT #516] - - 585. [func] dns_db_addrdataset() and and dns_rdataslab_merge() - now support 'exact' additions in a similar manner to - dns_db_subtractrdataset() and dns_rdataslab_subtract(). - - 584. [func] You can now say 'notify explicit'; to suppress - notification of the servers listed in NS records - and notify only those servers listed in the - 'also-notify' option. - - 583. [func] "rndc querylog" will now toggle logging of - queries, like "ndc querylog" in BIND 8. - - 582. [bug] dns_zone_idetach() failed to lock the zone. - [RT #199, #463] - - 581. [bug] log severity was not being correctly processed. - [RT #485] - - 580. [func] Ignore trailing garbage on incoming DNS packets, - for interoperability with broken server - implementations. [RT #491] - - 579. [bug] nsupdate did not take a filename to read update from. - [RT #492] - - 578. [func] New config option "notify-source", to specify the - source address for notify messages. - - 577. [func] Log illegal RDATA combinations. e.g. multiple - singlton types, cname and other data. - - 576. [doc] isc_log_create() description did not match reality. - - 575. [bug] isc_log_create() was not setting internal state - correctly to reflect the default channels created. - - 574. [bug] TSIG signed queries sent by the resolver would fail to - have their responses validated and would leak memory. - - 573. [bug] The journal files of IXFRed slave zones were - inadvertantly discarded on server reload, causing - "journal out of sync with zone" errors on subsequent - reloads. [RT #482] - - 572. [bug] Quoted strings were not accepted as key names in - address match lists. - - 571. [bug] It was possible to create an rdataset of singleton - type which had more than one rdata. [RT #154] - [RT #279] - - 570. [bug] rbtdb.c allowed zones containing nodes which had - both a CNAME and "other data". [RT #154] - - 569. [func] The DNSSEC AD bit will not be set on queries which - have not requested a DNSSEC response. - - 568. [func] Add sample simple database drivers in contrib/sdb. - - 567. [bug] Setting the zone transfer timeout to zero caused an - assertion failure. [RT #302] - - 566. [func] New public function dns_timer_setidle(). - - 565. [func] Log queries more like BIND 8: query logging is now - done to category "queries", level "info". [RT #169] - - 564. [func] Add sortlist support to lwresd. - - 563. [func] New public functions dns_rdatatype_format() and - dns_rdataclass_format(), for convenient formatting - of rdata type/class mnemonics in log messages. - - 562. [cleanup] Moved lib/dns/*conf.c to bin/named where they belong. - - 561. [func] The 'datasize', 'stacksize', 'coresize' and 'files' - clauses of the options{} statement are now implemented. - - 560. [bug] dns_name_split did not properly the resulting prefix - when a maximal length bitstring label was split which - was preceded by another bitstring label. [RT #429] - - 559. [bug] dns_name_split did not properly create the suffix - when splitting within a maximal length bitstring label. - - 558. [func] New functions, isc_resource_getlimit and - isc_resource_setlimit. - - 557. [func] Symbolic constants for libisc integral types. - - 556. [func] The DNSSEC OK bit in the EDNS extended flags - is now implemented. Responses to queries without - this bit set will not contain any DNSSEC records. - - 555. [bug] A slave server attempting a zone transfer could - crash with an assertion failure on certain - malformed responses from the master. [RT #457] - - 554. [bug] In some cases, not all of the dnssec tools were - properly installed. - - 553. [bug] Incoming zone transfers deferred due to quota - were not started when quota was increased but - only when a transfer in progress finished. [RT #456] - - 552. [bug] We were not correctly detecting the end of all c-style - comments. [RT #455] - - 551. [func] Implemented the 'sortlist' option. - - 550. [func] Support unknown rdata types and classes. - - 549. [bug] "make" did not immediately abort the build when a - subdirectory make failed [RT #450]. - - 548. [func] The lexer now ungets tokens more correctly. - - 547. [placeholder] - - 546. [func] Option 'lame-ttl' is now implemented. - - 545. [func] Name limit and counting options removed from dig; - they didn't work properly, and cannot be correctly - implemented without significant changes. - - 544. [func] Add statistics option, enable statistics-file option, - add RNDC option "dump-statistics" to write out a - query statistics file. - - 543. [doc] The 'port' option is now documented. - - 542. [func] Add support for update forwarding as required for - full compliance with RFC2136. It is turned off - by default and can be enabled using the - 'allow-update-forwarding' option. - - 541. [func] Add bogus server support. - - 540. [func] Add dialup support. - - 539. [func] Support the blackhole option. - - 538. [bug] fix buffer overruns by 1 in lwres_getnameinfo(). - - 537. [placeholder] - - 536. [func] Use transfer-source{-v6} when sending refresh queries. - Transfer-source{-v6} now take a optional port - parameter for setting the UDP source port. The port - parameter is ignored for TCP. - - 535. [func] Use transfer-source{-v6} when forwarding update - requests. - - 534. [func] Ancestors have been removed from RBT chains. Ancestor - information can be discerned via node parent pointers. - - 533. [func] Incorporated name hashing into the RBT database to - improve search speed. - - 532. [func] Implement DNS UPDATE pseudo records using - DNS_RDATA_UPDATE flag. - - 531. [func] Rdata really should be initialized before being assigned - to (dns_rdata_fromwire(), dns_rdata_fromtext(), - dns_rdata_clone(), dns_rdata_fromregion()), - check that it is. - - 530. [func] New function dns_rdata_invalidate(). - - 529. [bug] 521 contained a bug which caused zones to always - reload. [RT #410] - - 528. [func] The ISC_LIST_XXXX macros now perform sanity checks - on their arguments. ISC_LIST_XXXXUNSAFE can be use - to skip the checks however use with caution. - - 527. [func] New function dns_rdata_clone(). - - 526. [bug] nsupdate incorrectly refused to add RRs with a TTL - of 0. - - 525. [func] New arguments 'options' for dns_db_subtractrdataset(), - and 'flags' for dns_rdataslab_subtract() allowing you - to request that the RR's must exist prior to deletion. - DNS_R_NOTEXACT is returned if the condition is not met. - - 524. [func] The 'forward' and 'forwarders' statement in - non-forward zones should work now. - - 523. [doc] The source to the Administrator Reference Manual is - now an XML file using the DocBook DTD, and is included - in the distribution. The plain text version of the - ARM is temporarily unavailable while we figure out - how to generate readable plain text from the XML. - - 522. [func] The lightweight resolver daemon can now use - a real configuration file, and its functionality - can be provided by a name server. Also, the -p and -P - options to lwresd have been reversed. - - 521. [bug] Detect master files which contain $INCLUDE and always - reload. [RT #196] - - 520. [bug] Upgraded libtool to 1.3.5, which makes shared - library builds almost work on AIX (and possibly - others). - - 519. [bug] dns_name_split() would improperly split some bitstring - labels, zeroing a few of the least signficant bits in - the prefix part. When such an improperly created - prefix was returned to the RBT database, the bogus - label was dutifully stored, corrupting the tree. - [RT #369] - - 518. [bug] The resolver did not realize that a DNAME which was - "the answer" to the client's query was "the answer", - and such queries would fail. [RT #399] - - 517. [bug] The resolver's DNAME code would trigger an assertion - if there was more than one DNAME in the chain. - [RT #399] - - 516. [bug] Cache lookups which had a NULL node pointer, e.g. - those by dns_view_find(), and which would match a - DNAME, would trigger an INSIST(!search.need_cleanup) - assertion. [RT #399] - - 515. [bug] The ssu table was not being attached / detached - by dns_zone_[sg]etssutable. [RT#397] - - 514. [func] Retry refresh and notify queries if they timeout. - [RT #388] - - 513. [func] New functionality added to rdnc and server to allow - individual zones to be refreshed or reloaded. - - 512. [bug] The zone transfer code could throw an execption with - an invalid IXFR stream. - - 511. [bug] The message code could throw an assertion on an - out of memory failure. [RT #392] - - 510. [bug] Remove spurious view notify warning. [RT #376] - - 509. [func] Add support for write of zone files on shutdown. - - 508. [func] dns_message_parse() can now do a best-effort - attempt, which should allow dig to print more invalid - messages. - - 507. [func] New functions dns_zone_flush(), dns_zt_flushanddetach() - and dns_view_flushanddetach(). - - 506. [func] Do not fail to start on errors in zone files. - - 505. [bug] nsupdate was printing "unknown result code". [RT #373] - - 504. [bug] The zone was not being marked as dirty when updated via - IXFR. - - 503. [bug] dumptime was not being set along with - DNS_ZONEFLG_NEEDDUMP. - - 502. [func] On a SERVFAIL reply, DiG will now try the next server - in the list, unless the +fail option is specified. - - 501. [bug] Incorrect port numbers were being displayed by - nslookup. [RT #352] - - 500. [func] Nearly useless +details option removed from DiG. - - 499. [func] In DiG, specifying a class with -c or type with -t - changes command-line parsing so that classes and - types are only recognized if following -c or -t. - This allows hosts with the same name as a class or - type to be looked up. - - 498. [doc] There is now a man page for "dig" - in doc/man/bin/dig.1. - - 497. [bug] The error messages printed when an IP match list - contained a network address with a nonzero host - part where not sufficiently detailed. [RT #365] - - 496. [bug] named didn't sanity check numeric parameters. [RT #361] - - 495. [bug] nsupdate was unable to handle large records. [RT #368] - - 494. [func] Do not cache NXDOMAIN responses for SOA queries. - - 493. [func] Return non-cachable (ttl = 0) NXDOMAIN responses - for SOA queries. This makes it easier to locate - the containing zone without polluting intermediate - caches. - - 492. [bug] attempting to reload a zone caused the server fail - to shutdown cleanly. [RT #360] - - 491. [bug] nsupdate would segfault when sending certain - prerequisites with empty RDATA. [RT #356] - - 490. [func] When a slave/stub zone has not yet successfully - obtained an SOA containing the zone's configured - retry time, perform the SOA query retries using - exponential backoff. [RT #337] - - 489. [func] The zone manager now has a "i/o" queue. - - 488. [bug] Locks weren't properly destroyed in some cases. - - 487. [port] flockfile() is not defined on all systems. - - 486. [bug] nslookup: "set all" and "server" commands showed - the incorrect port number if a port other than 53 - was specified. [RT #352] - - 485. [func] When dig had more than one server to query, it would - send all of the messages at the same time. Add - rate limiting of the transmitted messages. - - 484. [bug] When the server was reloaded after removing addresses - from the named.conf "listen-on" statement, sockets - were still listening on the removed addresses due - to reference count loops. [RT #325] - - 483. [bug] nslookup: "set all" showed a "search" option but it - was not settable. - - 482. [bug] nslookup: a plain "server" or "lserver" should be - treated as a lookup. - - 481. [bug] nslookup:get_next_command() stack size could exceed - per thread limit. - - 480. [bug] strtok() is not thread safe. [RT #349] - - 479. [func] The test suite can now be run by typing "make check" - or "make test" at the top level. - - 478. [bug] "make install" failed if the directory specified with - --prefix did not already exist. - - 477. [bug] The the isc-config.sh script could be installed before - its directory was created. [RT #324] - - 476. [bug] A zone could expire while a zone transfer was in - progress triggering a INSIST failure. [RT #329] - - 475. [bug] query_getzonedb() sometimes returned a non-null version - on failure. This caused assertion failures when - generating query responses where names subject to - additional section processing pointed to a zone - to which access had been denied by means of the - allow-query option. [RT #336] - - 474. [bug] The mnemonic of the CHAOS class is CH according to - RFC1035, but it was printed and read only as CHAOS. - We now accept both forms as input, and print it - as CH. [RT #305] - - 473. [bug] nsupdate overran the end of the list of name servers - when no servers could be reached, typically causing - it to print the error message "dns_request_create: - not implemented". - - 472. [bug] Off-by-one error caused isc_time_add() to sometimes - produce invalid time values. - - 471. [bug] nsupdate didn't compile on HP/UX 10.20 - - 470. [func] $GENERATE is now supported. See also - doc/misc/migration. - - 469. [bug] "query-source address * port 53;" now works. - - 468. [bug] dns_master_load*() failed to report file and line - number in certain error conditions. - - 467. [bug] dns_master_load*() failed to log an error if - pushfile() failed. - - 466. [bug] dns_master_load*() could return success when it failed. - - 465. [cleanup] Allow 0 to be set as an omapi_value_t value by - omapi_value_storeint(). - - 464. [cleanup] Build with openssl's RSA code instead of dnssafe. - - 463. [bug] nsupdate sent malformed SOA queries to the second - and subsequent name servers in resolv.conf if the - query sent to the first one failed. - - 462. [bug] --disable-ipv6 should work now. - - 461. [bug] Specifying an unknown key in the "keys" clause of the - "controls" statement caused a NULL pointer dereference. - [RT #316] - - 460. [bug] Much of the DNSSEC code only worked with class IN. - - 459. [bug] Nslookup processed the "set" command incorrectly. - - 458. [bug] Nslookup didn't properly check class and type values. - [RT #305] - - 457. [bug] Dig/host/hslookup didn't properly handle connect - timeouts in certain situations, causing an - unnecessary warning message to be printed. - - 456. [bug] Stub zones were not resetting the refresh and expire - counters, loadtime or clearing the DNS_ZONE_REFRESH - (refresh in progress) flag upon successful update. - This disabled further refreshing of the stub zone, - causing it to eventually expire. [RT #300] - - 455. [doc] Document IPv4 prefix notation does not require a - dotted decimal quad but may be just dotted decimal. - - 454. [bug] Enforce dotted decimal and dotted decimal quad where - documented as such in named.conf. [RT #304, RT #311] - - 453. [bug] Warn if the obsolete option "maintain-ixfr-base" - is specified in named.conf. [RT #306] - - 452. [bug] Warn if the unimplemented option "statistics-file" - is specified in named.conf. [RT #301] - - 451. [func] Update forwarding implememted. - - 450. [func] New function ns_client_sendraw(). - - 449. [bug] isc_bitstring_copy() only works correctly if the - two bitstrings have the same lsb0 value, but this - requirement was not documented, nor was there a - REQUIRE for it. - - 448. [bug] Host output formatting change, to match v8. [RT #255] - - 447. [bug] Dig didn't properly retry in TCP mode after - a truncated reply. [RT #277] - - 446. [bug] Confusing notify log message. [RT #298] - - 445. [bug] Doing a 0 bit isc_bitstring_copy() of an lsb0 - bitstring triggered a REQUIRE statement. The REQUIRE - statement was incorrect. [RT #297] - - 444. [func] "recursion denied" messages are always logged at - debug level 1, now, rather than sometimes at ERROR. - This silences these warnings in the usual case, where - some clients set the RD bit in all queries. - - 443. [bug] When loading a master file failed because of an - unrecognized RR type name, the error message - did not include the file name and line number. - [RT #285] - - 442. [bug] TSIG signed messages that did not match any view - crashed the server. [RT #290] - - 441. [bug] Nodes obscured by a DNAME were inaccessible even - when DNS_DBFIND_GLUEOK was set. - - 440. [func] New function dns_zone_forwardupdate(). - - 439. [func] New function dns_request_createraw(). - - 438. [func] New function dns_message_getrawmessage(). - - 437. [func] Log NOTIFY activity to the notify channel. - - 436. [bug] If recvmsg() returned EHOSTUNREACH or ENETUNREACH, - which sometimes happens on Linux, named would enter - a busy loop. Also, unexpected socket errors were - not logged at a high enough logging level to be - useful in diagnosing this situation. [RT #275] - - 435. [bug] dns_zone_dump() overwrote existing zone files - rather than writing to a temporary file and - renaming. This could lead to empty or partial - zone files being left around in certain error - conditions involving the initial transfer of a - slave zone, interfering with subsequent server - startup. [RT #282] - - 434. [func] New function isc_file_isabsolute(). - - 433. [func] isc_base64_decodestring() now accepts newlines - within the base64 data. This makes it possible - to break up the key data in a "trusted-keys" - statement into multiple lines. [RT #284] - - 432. [func] Added refresh/retry jitter. The actual refresh/ - retry time is now a random value between 75% and - 100% of the configured value. - - 431. [func] Log at ISC_LOG_INFO when a zone is successfully - loaded. - - 430. [bug] Rewrote the lightweight resolver client management - code to handle shutdown correctly and general - cleanup. - - 429. [bug] The space reserved for a TSIG record in a response - was 2 bytes too short, leading to message - generation failures. - - 428. [bug] rbtdb.c:find_closest_nxt() erroneously returned - DNS_R_BADDB for nodes which had neither NXT nor SIG NXT - (e.g. glue). This could cause SERVFAILs when - generating negative responses in a secure zone. - - 427. [bug] Avoid going into an infinite loop when the validator - gets a negative response to a key query where the - records are signed by the missing key. - - 426. [bug] Attempting to generate an oversized RSA key could - cause dnssec-keygen to dump core. - - 425. [bug] Warn about the auth-nxdomain default value change - if there is no auth-nxdomain statement in the - config file. [RT #287] - - 424. [bug] notify_createmessage() could trigger an assertion - failure when creating the notify message failed, - e.g. due to corrupt zones with multiple SOA records. - [RT #279] - - 423. [bug] When responding to a recusive query, errors that occur - after following a CNAME should cause the query to fail. - [RT #274] - - 422. [func] get rid of isc_random_t, and make isc_random_get() - and isc_random_jitter() use rand() internally - instead of local state. Note that isc_random_*() - functions are only for weak, non-critical "randomness" - such as timing jitter and such. - - 421. [bug] nslookup would exit when given a blank line as input. - - 420. [bug] nslookup failed to implement the "exit" command. - - 419. [bug] The certificate type PKIX was misspelled as SKIX. - - 418. [bug] At debug levels >= 10, getting an unexpected - socket receive error would crash the server - while trying to log the error message. - - 417. [func] Add isc_app_block() and isc_app_unblock(), which - allow an application to handle signals while - blocking. - - 416. [bug] Slave zones with no master file tried to use a - NULL pointer for a journal file name when they - received an IXFR. [RT #273] - - 415. [bug] The logging code leaked file descriptors. - - 414. [bug] Server did not shut down until all incoming zone - transfers were finished. - - 413. [bug] Notify could attempt to use the zone database after - it had been unloaded. [RT#267] - - 412. [bug] named -v didn't print the version. - - 411. [bug] A typo in the HS A code caused an assertion failure. - - 410. [bug] lwres_gethostbyname() and company set lwres_h_errno - to a random value on success. - - 409. [bug] If named was shut down early in the startup - process, ns_omapi_shutdown() would attempt to lock - an unintialized mutex. [RT #262] - - 408. [bug] stub zones could leak memory and reference counts if - all the masters were unreachable. - - 407. [bug] isc_rwlock_lock() would needlessly block - readers when it reached the read quota even - if no writers were waiting. - - 406. [bug] Log messages were occasionally lost or corrupted - due to a race condition in isc_log_doit(). - - 405. [func] Add support for selective forwarding (forward zones) - - 404. [bug] The request library didn't completely work with IPv6. - - 403. [bug] "host" did not use the search list. - - 402. [bug] Treat undefined acls as errors, rather than - warning and then later throwing an assertion. - [RT #252] - - 401. [func] Added simple database API. - - 400. [bug] SIG(0) signing and verifying was done incorrectly. - [RT #249] - - 399. [bug] When reloading the server with a config file - containing a syntax error, it could catch an - assertion failure trying to perform zone - maintenance on, or sending notifies from, - tentatively created zones whose views were - never fully configured and lacked an address - database and request manager. - - 398. [bug] "dig" sometimes caught an assertion failure when - using TSIG, depending on the key length. - - 397. [func] Added utility functions dns_view_gettsig() and - dns_view_getpeertsig(). - - 396. [doc] There is now a man page for "nsupdate" - in doc/man/bin/nsupdate.8. - - 395. [bug] nslookup printed incorrect RR type mnemonics - for RRs of type >= 21 [RT #237]. - - 394. [bug] Current name was not propagated via $INCLUDE. - - 393. [func] Initial answer while loading (awl) support. - Entry points: dns_master_loadfileinc(), - dns_master_loadstreaminc(), dns_master_loadbufferinc(). - Note: calls to dns_master_load*inc() should be rate - be rate limited so as to not use up all file - descriptors. - - 392. [func] Add ISC_R_FAMILYNOSUPPORT. Returned when OS does - not support the given address family requested. - - 391. [clarity] ISC_R_FAMILY -> ISC_R_FAMILYMISMATCH. - - 390. [func] The function dns_zone_setdbtype() now takes - an argc/argv style vector of words and sets - both the zone database type and its arguments, - making the functions dns_zone_adddbarg() - and dns_zone_cleardbargs() unnecessary. - - 389. [bug] Attempting to send a reqeust over IPv6 using - dns_request_create() on a system without IPv6 - support caused an assertion failure [RT #235]. - - 388. [func] dig and host can now do reverse ipv6 lookups. - - 387. [func] Add dns_byaddr_createptrname(), which converts - an address into the name used by a PTR query. - - 386. [bug] Missing strdup() of ACL name caused random - ACL matching failures [RT #228]. - - 385. [cleanup] Removed functions dns_zone_equal(), dns_zone_print(), - and dns_zt_print(). - - 384. [bug] nsupdate was incorrectly limiting TTLs to 65535 instead - of 2147483647. - - 383. [func] When writing a master file, print the SOA and NS - records (and their SIGs) before other records. - - 382. [bug] named -u failed on many Linux systems where the - libc provided kernel headers do not match - the current kernel. - - 381. [bug] Check for IPV6_RECVPKTINFO and use it instead of - IPV6_PKTINFO if found. [RT #229] - - 380. [bug] nsupdate didn't work with IPv6. - - 379. [func] New library function isc_sockaddr_anyofpf(). - - 378. [func] named and lwresd will log the command line arguments - they were started with in the "starting ..." message. - - 377. [bug] When additional data lookups were refused due to - "allow-query", the databases were still being - attached causing reference leaks. - - 376. [bug] The server should always use good entropy when - performing cryptographic functions needing entropy. - - 375. [bug] Per-zone "allow-query" did not properly override the - view/global one for CNAME targets and additional - data [RT #220]. - - 374. [bug] SOA in authoritative negative responses had wrong TTL. - - 373. [func] nslookup is now installed by "make install". - - 372. [bug] Deal with Microsoft DNS servers appending two bytes of - garbage to zone transfer requests. - - 371. [bug] At high debug levels, doing an outgoing zone transfer - of a very large RRset could cause an assertion failure - during logging. - - 370. [bug] The error messages for rollforward failures were - overly terse. - - 369. [func] Support new named.conf options, view and zone - statements: - - max-retry-time, min-retry-time, - max-refresh-time, min-refresh-time. - - 368. [func] Restructure the internal ".bind" view so that more - zones can be added to it. - - 367. [bug] Allow proper selection of server on nslookup command - line. - - 366. [func] Allow use of '-' batch file in dig for stdin. - - 365. [bug] nsupdate -k leaked memory. - - 364. [func] Added additional-from-{cache,auth} - - 363. [placeholder] - - 362. [bug] rndc no longer aborts if the configuration file is - missing an options statement. [RT #209] - - 361. [func] When the RBT find or chain functions set the name and - origin for a node that stores the root label - the name is now set to an empty name, instead of ".", - to simplify later use of the name and origin by - dns_name_concatenate(), dns_name_totext() or - dns_name_format(). - - 360. [func] dns_name_totext() and dns_name_format() now allow - an empty name to be passed, which is formatted as "@". - - 359. [bug] dnssec-signzone occasionally signed glue records. - - 358. [cleanup] Rename the intermediate files used by the dnssec - programs. - - 357. [bug] The zone file parser crashed if the argument - to $INCLUDE was a quoted string. - - 356. [cleanup] isc_task_send no longer requires event->sender to - be non-null. - - 355. [func] Added isc_dir_createunique(), similar to mkdtemp(). - - 354. [doc] Man pages for the dnssec tools are now included in - the distribution, in doc/man/dnssec. - - 353. [bug] double increment in lwres/gethost.c:copytobuf(). - [RT# 187] - - 352. [bug] Race condition in dns_client_t startup could cause - an assertion failure. - - 351. [bug] Constructing a response with rcode SERVFAIL to a TSIG - signed query could crash the server. - - 350. [bug] Also-notify lists specified in the global options - block were not correctly reference counted, causing - a memory leak. - - 349. [bug] Processing a query with the CD bit set now works - as expected. - - 348. [func] New boolean named.conf options 'additional-from-auth' - and 'additional-from-cache' now supported in view and - global options statement. - - 347. [bug] Don't crash if an argument is left off options in dig. - - 346. [placeholder] - - 345. [bug] Large-scale changes/cleanups to dig: - * Significantly improve structure handling - * Don't pre-load entire batch files - * Add name/rr counting/limiting - * Fix SIGINT handling - * Shorten timeouts to match v8's behavior - - 344. [bug] When shutting down, lwresd sometimes tried - to shut down its client tasks twice, - triggering an assertion. - - 343. [bug] Although zone maintenance SOA queries and - notify requests were signed with TSIG keys - when configured for the server in case, - the TSIG was not verified on the response. - - 342. [bug] The wrong name was being passed to - dns_name_dup() when generating a TSIG - key using TKEY. - - 341. [func] Support 'key' clause in named.conf zone masters - statement to allow authentication via TSIG keys: - - masters { - 10.0.0.1 port 5353 key "foo"; - 10.0.0.2 ; - }; - - 340. [bug] The top-level COPYRIGHT file was missing from - the distribution. - - 339. [bug] DNSSEC validation of the response to an ANY - query at a name with a CNAME RR in a secure - zone triggered an assertion failure. - - 338. [bug] lwresd logged to syslog as named, not lwresd. - - 337. [bug] "dig" did not recognize "nsap-ptr" as an RR type - on the command line. - - 336. [bug] "dig -f" used 64 k of memory for each line in - the file. It now uses much less, though still - proportionally to the file size. - - 335. [bug] named would occasionally attempt recursion when - it was disallowed or undesired. - - 334. [func] Added hmac-md5 to libisc. - - 333. [bug] The resolver incorrectly accepted referrals to - domains that were not parents of the query name, - causing assertion failures. - - 332. [func] New function dns_name_reset(). - - 331. [bug] Only log "recursion denied" if RD is set. [RT #178] - - 330. [bug] Many debugging messages were partially formatted - even when debugging was turned off, causing a - significant decrease in query performance. - - 329. [func] omapi_auth_register() now takes a size_t argument for - the length of a key's secret data. Previously - OMAPI only stored secrets up to the first NUL byte. - - 328. [func] Added isc_base64_decodestring(). - - 327. [bug] rndc.conf parser wasn't correctly recognising an IP - address where a host specification was required. - - 326. [func] 'keys' in an 'inet' control statement is now - required and must have at least one item in it. - A "not supported" warning is now issued if a 'unix' - control channel is defined. - - 325. [bug] isc_lex_gettoken was processing octal strings when - ISC_LEXOPT_CNUMBER was not set. - - 324. [func] In the resolver, turn EDNS0 off if there is no - response after a number of retransmissions. - This is to allow queries some chance of succeeding - even if all the authoritative servers of a zone - silently discard EDNS0 requests instead of - sending an error response like they ought to. - - 323. [bug] dns_rbt_findname() did not ignore empty rbt nodes. - Because of this, servers authoritative for a parent - and grandchild zone but not authoritative for the - intervening child zone did not correctly issue - referrals to the servers of the child zone. - - 322. [bug] Queries for KEY RRs are now sent to the parent - server before the authoritative one, making - DNSSEC insecurity proofs work in many cases - where they previously didn't. - - 321. [bug] When synthesizing a CNAME RR for a DNAME - response, query_addcname() failed to intitialize - the type and class of the CNAME dns_rdata_t, - causing random failures. - - 320. [func] Multiple rndc changes: parses an rndc.conf file, - uses authentication to talk to named, command - line syntax changed. This will all be described - in the ARM. - - 319. [func] The named.conf "controls" statement is now used - to configure the OMAPI command channel. - - 318. [func] dns_c_ndcctx_destroy() could never return anything - except ISC_R_SUCCESS; made it have void return instead. - - 317. [func] Use callbacks from libomapi to determine if a - new connection is valid, and if a key requested - to be used with that connection is valid. - - 316. [bug] Generate a warning if we detect an unexpected - but treat as . - - 315. [bug] Handle non-empty blanks lines. [RT #163] - - 314. [func] The named.conf controls statement can now have - more than one key specified for the inet clause. - - 313. [bug] When parsing resolv.conf, don't terminate on an - error. Instead, parse as much as possible, but - still return an error if one was found. - - 312. [bug] Increase the number of allowed elements in the - resolv.conf search path from 6 to 8. If there - are more than this, ignore the remainder rather - than returning a failure in lwres_conf_parse. - - 311. [bug] lwres_conf_parse failed when the first line of - resolv.conf was empty or a comment. - - 310. [func] Changes to named.conf "controls" statement (inet - subtype only) - - - support "keys" clause - - controls { - inet * port 1024 - allow { any; } keys { "foo"; } - } - - - allow "port xxx" to be left out of statement, - in which case it defaults to omapi's default port - of 953. - - 309. [bug] When sending a referral, the server did not look - for name server addresses as glue in the zone - holding the NS RRset in the case where this zone - was not the same as the one where it looked for - name server addresses as authoritative data. - - 308. [bug] Treat a SOA record not at top of zone as an error - when loading a zone. [RT #154] - - 307. [bug] When canceling a query, the resolver didn't check for - isc_socket_sendto() calls that did not yet have their - completion events posted, so it could (rarely) end up - destroying the query context and then want to use - it again when the send event posted, triggering an - assertion as it tried to cancel an already-canceled - query. [RT #77] - - 306. [bug] Reading HMAC-MD5 private key files didn't work. - - 305. [bug] When reloading the server with a config file - containing a syntax error, it could catch an - assertion failure trying to perform zone - maintenance on tentatively created zones whose - views were never fully configured and lacked - an address database. - - 304. [bug] If more than LWRES_CONFMAXNAMESERVERS servers - are listed in resolv.conf, silently ignore them - instead of returning failure. - - 303. [bug] Add additional sanity checks to differentiate a AXFR - response vs a IXFR response. [RT #157] - - 302. [bug] In dig, host, and nslookup, MXNAME should be large - enough to hold any legal domain name in presentation - format + terminating NULL. - - 301. [bug] Uninitialized pointer in host:printmessage(). [RT #159] - - 300. [bug] Using both and didn't work - on platforms lacking IPv6 because each included their - own ipv6 header file for the missing definitions. Now - each library's ipv6.h defines the wrapper symbol of - the other (ISC_IPV6_H and LWRES_IPV6_H). - - 299. [cleanup] Get the user and group information before changing the - root directory, so the administrator does not need to - keep a copy of the user and group databases in the - chroot'ed environment. Suggested by Hakan Olsson. - - 298. [bug] A mutex deadlock occurred during shutdown of the - interface manager under certain conditions. - Digital Unix systems were the most affected. - - 297. [bug] Specifying a key name that wasn't fully qualified - in certain parts of the config file could cause - an assertion failure. - - 296. [bug] "make install" from a separate build directory - failed unless configure had been run in the source - directory, too. - - 295. [bug] When invoked with type==CNAME and a message - not constructed by dns_message_parse(), - dns_message_findname() failed to find anything - due to checking for attribute bits that are set - only in dns_message_parse(). This caused an - infinite loop when constructing the response to - an ANY query at a CNAME in a secure zone. - - 294. [bug] If we run out of space in while processing glue - when reading a master file and commit "current name" - reverts to "name_current" instead of staying as - "name_glue". - - 293. [port] Add support for FreeBSD 4.0 system tests. - - 292. [bug] Due to problems with the way some operating systems - handle simultaneous listening on IPv4 and IPv6 - addresses, the server no longer listens on IPv6 - addresses by default. To revert to the previous - behavior, specify "listen-on-v6 { any; };" in - the config file. - - 291. [func] Caching servers no longer send outgoing queries - over TCP just because the incoming recursive query - was a TCP one. - - 290. [cleanup] +twiddle option to dig (for testing only) removed. - - 289. [cleanup] dig is now installed in $bindir instead of $sbindir. - host is now installed in $bindir. (Be sure to remove - any $sbindir/dig from a previous release.) - - 288. [func] rndc is now installed by "make install" into $sbindir. - - 287. [bug] rndc now works again as "rndc 127.1 reload" (for - only that task). Parsing its configuration file and - using digital signatures for authentication has been - disabled until named supports the "controls" statement, - post-9.0.0. - - 286. [bug] On Solaris 2, when named inherited a signal state - where SIGHUP had the SIG_IGN action, SIGHUP would - be ignored rather than causing the server to reload - its configuration. - - 285. [bug] A change made to the dst API for beta4 inadvertently - broke OMAPI's creation of a dst key from an incoming - message, causing an assertion to be triggered. Fixed. - - 284. [func] The DNSSEC key generation and signing tools now - generate randomness from keyboard input on systems - that lack /dev/random. - - 283. [cleanup] The 'lwresd' program is now a link to 'named'. - - 282. [bug] The lexer now returns ISC_R_RANGE if parsed integer is - too big for an unsigned long. - - 281. [bug] Fixed list of recognized config file category names. - - 280. [func] Add isc-config.sh, which can be used to more - easily build applications that link with - our libraries. - - 279. [bug] Private omapi function symbols shared between - two or more files in libomapi.a were not namespace - protected using the ISC convention of starting with - the library name and two underscores ("omapi__"...) - - 278. [bug] bin/named/logconf.c:category_fromconf() didn't take - note of when isc_log_categorybyname() wasn't able - to find the category name and would then apply the - channel list of the unknown category to all categories. - - 277. [bug] isc_log_categorybyname() and isc_log_modulebyname() - would fail to find the first member of any category - or module array apart from the internal defaults. - Thus, for example, the "notify" category was improperly - configured by named. - - 276. [bug] dig now supports maximum sized TCP messages. - - 275. [bug] The definition of lwres_gai_strerror() was missing - the lwres_ prefix. - - 274. [bug] TSIG AXFR verify failed when talking to a BIND 8 - server. - - 273. [func] The default for the 'transfer-format' option is - now 'many-answers'. This will break zone transfers - to BIND 4.9.5 and older unless there is an explicit - 'one-answer' configuration. - - 272. [bug] The sending of large TCP responses was canceled - in mid-transmission due to a race condition - caused by the failure to set the client object's - "newstate" variable correctly when transitioning - to the "working" state. - - 271. [func] Attempt to probe the number of cpus in named - if unspecified rather than defaulting to 1. - - 270. [func] Allow maximum sized TCP answers. - - 269. [bug] Failed DNSSEC validations could cause an assertion - failure by causing clone_results() to be called with - with hevent->node == NULL. - - 268. [doc] A plain text version of the Administrator - Reference Manual is now included in the distribution, - as doc/arm/Bv9ARM.txt. - - 267. [func] Nsupdate is now provided in the distribution. - - 266. [bug] zone.c:save_nsrrset() node was not initialized. - - 265. [bug] dns_request_create() now works for TCP. - - 264. [func] Dispatch can not take TCP sockets in connecting - state. Set DNS_DISPATCHATTR_CONNECTED when calling - dns_dispatch_createtcp() for connected TCP sockets - or call dns_dispatch_starttcp() when the socket is - connected. - - 263. [func] New logging channel type 'stderr' - - channel some-name { - stderr; - severity error; - } - - 262. [bug] 'master' was not initialized in zone.c:stub_callback(). - - 261. [func] Add dns_zone_markdirty(). - - 260. [bug] Running named as a non-root user failed on Linux - kernels new enough to support retaining capabilities - after setuid(). - - 259. [func] New random-device and random-seed-file statements - for global options block of named.conf. Both accept - a single string argument. - - 258. [bug] Fixed printing of lwres_addr_t.address field. - - 257. [bug] The server detached the last zone manager reference - too early, while it could still be in use by queries. - This manifested itself as assertion failures during the - shutdown process for busy name servers. [RT #133] - - 256. [func] isc_ratelimiter_t now has attach/detach semantics, and - isc_ratelimiter_shutdown guarantees that the rate - limiter is detached from its task. - - 255. [func] New function dns_zonemgr_attach(). - - 254. [bug] Suppress "query denied" messages on additional data - lookups. - - --- 9.0.0b4 released --- - - 253. [func] resolv.conf parser now recognises ';' and '#' as - comments (anywhere in line, not just as the beginning). - - 252. [bug] resolv.conf parser mishandled masks on sortlists. - It also aborted when an unrecognized keyword was seen, - now it silently ignores the entire line. - - 251. [bug] lwresd caught an assertion failure on startup. - - 250. [bug] fixed handling of size+unit when value would be too - large for internal representation. - - 249. [cleanup] max-cache-size config option now takes a size-spec - like 'datasize', except 'default' is not allowed. - - 248. [bug] global lame-ttl option was not being printed when - config structures were written out. - - 247. [cleanup] Rename cache-size config option to max-cache-size. - - 246. [func] Rename global option cachesize to cache-size and - add corresponding option to view statement. - - 245. [bug] If an uncompressed name will take more than 255 - bytes and the buffer is sufficiently long, - dns_name_fromwire should return DNS_R_FORMERR, - not ISC_R_NOSPACE. This bug caused cause the - server to catch an assertion failure when it - received a query for a name longer than 255 - bytes. - - 244. [bug] empty named.conf file and empty options statement are - now parsed properly. - - 243. [func] new cachesize option for named.conf - - 242. [cleanup] fixed incorrect warning about auth-nxdomain usage. - - 241. [cleanup] nscount and soacount have been removed from the - dns_master_*() argument lists. - - 240. [func] databases now come in three flavours: zone, cache - and stub. - - 239. [func] If ISC_MEM_DEBUG is enabled, the variable - isc_mem_debugging controls whether messages - are printed or not. - - 238. [cleanup] A few more compilation warnings have been quieted: - + missing sigwait prototype on BSD/OS 4.0/4.0.1. - + PTHREAD_ONCE_INIT unbraced initializer warnings on - Solaris 2.8. - + IN6ADDR_ANY_INIT unbraced initializer warnings on - BSD/OS 4.*, Linux and Solaris 2.8. - - 237. [bug] If connect() returned ENOBUFS when the resolver was - initiating a TCP query, the socket didn't get - destroyed, and the server did not shut down cleanly. - - 236. [func] Added new listen-on-v6 config file statement. - - 235. [func] Consider it a config file error if a listen-on - statement has an IPv6 address in it, or a - listen-on-v6 statement has an IPv4 address in it. - - 234. [bug] Allow a trusted-key's first field (domain-name) be - either a quoted or an unquoted string, instead of - requiring a quoted string. - - 233. [cleanup] Convert all config structure integer values to unsigned - integer (isc_uint32_t) to match grammer. - - 232. [bug] Allow slave zones to not have a file. - - 231. [func] Support new 'port' clause in config file options - section. Causes 'listen-on', 'masters' and - 'also-notify' statements to use its value instead of - default (53). - - 230. [func] Replace the dst sign/verify API with a cleaner one. - - 229. [func] Support config file sig-validity-interval statement - in options, views and zone statements (master - zones only). - - 228. [cleanup] Logging messages in config module stripped of - trailing period. - - 227. [cleanup] The enumerated identifiers dns_rdataclass_*, - dns_rcode_*, dns_opcode_*, and dns_trust_* are - also now cast to their appropriate types, as with - dns_rdatatype_* in item number 225 below. - - 226. [func] dns_name_totext() now always prints the root name as - '.', even when omit_final_dot is true. - - 225. [cleanup] The enumerated dns_rdatatype_* identifiers are now - cast to dns_rdatatype_t via macros of their same name - so that they are of the proper integral type wherever - a dns_rdatatype_t is needed. - - 224. [cleanup] The entire project builds cleanly with gcc's - -Wcast-qual and -Wwrite-strings warnings enabled, - which is now the default when using gcc. (Warnings - from confparser.c, because of yacc's code, are - unfortunately to be expected.) - - 223. [func] Several functions were reprototyped to qualify one - or more of their arguments with "const". Similarly, - several functions that return pointers now have - those pointers qualified with const. - - 222. [bug] The global 'also-notify' option was ignored. - - 221. [bug] An uninitialized variable was sometimes passed to - dns_rdata_freestruct() when loading a zone, causing - an assertion failure. - - 220. [cleanup] Set the default outgoing port in the view, and - set it in sockaddrs returned from the ADB. - [31-May-2000 explorer] - - 219. [bug] Signed truncated messages more correctly follow - the respective specs. - - 218. [func] When an rdataset is signed, its ttl is normalized - based on the signature validity period. - - 217. [func] Also-notify and trusted-keys can now be used in - the 'view' statement. - - 216. [func] The 'max-cache-ttl' and 'max-ncache-ttl' options - now work. - - 215. [bug] Failures at certain points in request processing - could cause the assertion INSIST(client->lockview - == NULL) to be triggered. - - 214. [func] New public function isc_netaddr_format(), for - formatting network addresses in log messages. - - 213. [bug] Don't leak memory when reloading the zone if - an update-policy clause was present in the old zone. - - 212. [func] Added dns_message_get/settsigkey, to make TSIG - key management reasonable. - - 211. [func] The 'key' and 'server' statements can now occur - inside 'view' statements. - - 210. [bug] The 'allow-transfer' option was ignored for slave - zones, and the 'transfers-per-ns' option was - was ignored for all zones. - - 209. [cleanup] Upgraded openssl files to new version 0.9.5a - - 208. [func] Added ISC_OFFSET_MAXIMUM for the maximum value - of an isc_offset_t. - - 207. [func] The dnssec tools properly use the logging subsystem. - - 206. [cleanup] dst now stores the key name as a dns_name_t, not - a char *. - - 205. [cleanup] On IRIX, turn off the mostly harmless warnings 1692 - ("prototyped function redeclared without prototype") - and 1552 ("variable ... set but not used") when - compiling in the lib/dns/sec/{dnssafe,openssl} - directories, which contain code imported from outside - sources. - - 204. [cleanup] On HP/UX, pass +vnocompatwarnings to the linker - to quiet the warnings that "The linked output may not - run on a PA 1.x system." - - 203. [func] notify and zone soa queries are now tsig signed when - appropriate. - - 202. [func] isc_lex_getsourceline() changed from returning int - to returning unsigned long, the type of its underlying - counter. - - 201. [cleanup] Removed the test/sdig program, it has been - replaced by bin/dig/dig. - - --- 9.0.0b3 released --- - - 200. [bug] Failures in sending query responses to clients - (e.g., running out of network buffers) were - not logged. - - 199. [bug] isc_heap_delete() sometimes violated the heap - invariant, causing timer events not to be posted - when due. - - 198. [func] Dispatch managers hold memory pools which - any managed dispatcher may use. This allows - us to avoid dipping into the memory context for - most allocations. [19-May-2000 explorer] - - 197. [bug] When an incoming AXFR or IXFR completes, the - zone's internal state is refreshed from the - SOA data. [19-May-2000 explorer] - - 196. [func] Dispatchers can be shared easily between views - and/or interfaces. [19-May-2000 explorer] - - 195. [bug] Including the NXT record of the root domain - in a negative response caused an assertion - failure. - - 194. [doc] The PDF version of the Administrator's Reference - Manual is no longer included in the ISC BIND9 - distribution. - - 193. [func] changed dst_key_free() prototype. - - 192. [bug] Zone configuration validation is now done at end - of config file parsing, and before loading - callbacks. - - 191. [func] Patched to compile on UnixWare 7.x. This platform - is not directly supported by the ISC. - - 190. [cleanup] The DNSSEC tools have been moved to a separate - directory dnssec/ and given the following new, - more descriptive names: - - dnssec-keygen - dnssec-signzone - dnssec-signkey - dnssec-makekeyset - - Their command line arguments have also been changed to - be more consistent. dnssec-keygen now prints the - name of the generated key files (sans extension) - on standard output to simplify its use in automated - scripts. - - 189. [func] isc_time_secondsastimet(), a new function, will ensure - that the number of seconds in an isc_time_t does not - exceed the range of a time_t, or return ISC_R_RANGE. - Similarly, isc_time_now(), isc_time_nowplusinterval(), - isc_time_add() and isc_time_subtract() now check the - range for overflow/underflow. In the case of - isc_time_subtract, this changed a calling requirement - (ie, something that could generate an assertion) - into merely a condition that returns an error result. - isc_time_add() and isc_time_subtract() were void- - valued before but now return isc_result_t. - - 188. [func] Log a warning message when an incoming zone transfer - contains out-of-zone data. - - 187. [func] isc_ratelimter_enqueue() has an additional argument - 'task'. - - 186. [func] dns_request_getresponse() has an additional argument - 'preserve_order'. - - 185. [bug] Fixed up handling of ISC_MEMCLUSTER_LEGACY. Several - public functions did not have an isc__ prefix, and - referred to functions that had previously been - renamed. - - 184. [cleanup] Variables/functions which began with two leading - underscores were made to conform to the ANSI/ISO - standard, which says that such names are reserved. - - 183. [func] ISC_LOG_PRINTTAG option for log channels. Useful - for logging the program name or other identifier. - - 182. [cleanup] New commandline parameters for dnssec tools - - 181. [func] Added dst_key_buildfilename and dst_key_parsefilename - - 180. [func] New isc_result_t ISC_R_RANGE. Supersedes DNS_R_RANGE. - - 179. [func] options named.conf statement *must* now come - before any zone or view statements. - - 178. [func] Post-load of named.conf check verifies a slave zone - has non-empty list of masters defined. - - 177. [func] New per-zone boolean: - - enable-zone yes | no ; - - intended to let a zone be disabled without having - to comment out the entire zone statement. - - 176. [func] New global and per-view option: - - max-cache-ttl number - - 175. [func] New global and per-view option: - - additional-data internal | minimal | maximal; - - 174. [func] New public function isc_sockaddr_format(), for - formatting socket addresses in log messages. - - 173. [func] Keep a queue of zones waiting for zone transfer - quota so that a new transfer can be dispatched - immediately whenever quota becomes available. - - 172. [bug] $TTL directive was sometimes missing from dumped - master files because totext_ctx_init() failed to - initialize ctx->current_ttl_valid. - - 171. [cleanup] On NetBSD systems, the mit-pthreads or - unproven-pthreads library is now always used - unless --with-ptl2 is explicitly specified on - the configure command line. The - --with-mit-pthreads option is no longer needed - and has been removed. - - 170. [cleanup] Remove inter server consistancy checks from zone, - these should return as a separate module in 9.1. - dns_zone_checkservers(), dns_zone_checkparents(), - dns_zone_checkchildren(), dns_zone_checkglue(). - - Remove dns_zone_setadb(), dns_zone_setresolver(), - dns_zone_setrequestmgr() these should now be found - via the view. - - 169. [func] ratelimiter can now process N events per interval. - - 168. [bug] include statements in named.conf caused syntax errors - due to not consuming the semicolon ending the include - statement before switching input streams. - - 167. [bug] Make lack of masters for a slave zone a soft error. - - 166. [bug] Keygen was overwriting existing keys if key_id - conflicted, now it will retry, and non-null keys - with key_id == 0 are not generated anymore. Key - was not able to generate NOAUTHCONF DSA key, - increased RSA key size to 2048 bits. - - 165. [cleanup] Silence "end-of-loop condition not reached" warnings - from Solaris compiler. - - 164. [func] Added functions isc_stdio_open(), isc_stdio_close(), - isc_stdio_seek(), isc_stdio_read(), isc_stdio_write(), - isc_stdio_flush(), isc_stdio_sync(), isc_file_remove() - to encapsulate nonportable usage of errno and sync. - - 163. [func] Added result codes ISC_R_FILENOTFOUND and - ISC_R_FILEEXISTS. - - 162. [bug] Ensure proper range for arguments to ctype.h functions. - - 161. [cleanup] error in yyparse prototype that only HPUX caught. - - 160. [cleanup] getnet*() are not going to be implemented at this - stage. - - 159. [func] Redefinition of config file elements is now an - error (instead of a warning). - - 158. [bug] Log channel and category list copy routines - weren't assigning properly to output parameter. - - 157. [port] Fix missing prototype for getopt(). - - 156. [func] Support new 'database' statement in zone. - - database "quoted-string"; - - 155. [bug] ns_notify_start() was not detaching the found zone. - - 154. [func] The signer now logs libdns warnings to stderr even when - not verbose, and in a nicer format. - - 153. [func] dns_rdata_tostruct() 'mctx' is now optional. If 'mctx' - is NULL then you need to preserve the 'rdata' until - you have finished using the structure as there may be - references to the associated memory. If 'mctx' is - non-NULL it is guaranteed that there are no references - to memory associated with 'rdata'. - - dns_rdata_freestruct() must be called if 'mctx' was - non-NULL and may safely be called if 'mctx' was NULL. - - 152. [bug] keygen dumped core if domain name argument was omitted - from command line. - - 151. [func] Support 'disabled' statement in zone config (causes - zone to be parsed and then ignored). Currently must - come after the 'type' clause. - - 150. [func] Support optional ports in masters and also-notify - statements: - - masters [ port xxx ] { y.y.y.y [ port zzz ] ; } - - 149. [cleanup] Removed usused argument 'olist' from - dns_c_view_unsetordering(). - - 148. [cleanup] Stop issuing some warnings about some configuration - file statements that were not implemented, but now are. - - 147. [bug] Changed yacc union size to be smaller for yaccs that - put yacc-stack on the real stack. - - 146. [cleanup] More general redundant header file cleanup. Rather - than continuing to itemize every header which changed, - this changelog entry just notes that if a header file - did not need another header file that it was including - in order to provide its advertized functionality, the - inclusion of the other header file was removed. See - util/check-includes for how this was tested. - - 145. [cleanup] Added and ISC_LANG_BEGINDECLS/ - ISC_LANG_ENDDECLS to header files that had function - prototypes, and removed it from those that did not. - - 144. [cleanup] libdns header files too numerous to name were made - to conform to the same style for multiple inclusion - protection. - - 143. [func] Added function dns_rdatatype_isknown(). - - 142. [cleanup] does not need or - . - - 141. [bug] Corrupt requests with multiple questions could - cause an assertion failure. - - 140. [cleanup] does not need or . - - 139. [cleanup] now includes instead of - and . - - 138. [cleanup] isc_strtouq moved from str.[ch] to string.[ch] and - renamed isc_string_touint64. isc_strsep moved from - strsep.c to string.c and renamed isc_string_separate. - - 137. [cleanup] , , - , and - made to conform to the same style for multiple - inclusion protection. - - 136. [cleanup] , , - and Win32's needed - ISC_LANG_BEGINDECLS/ISC_LANG_ENDDECLS. - - 135. [cleanup] Win32's did not need - or , now uses in place - of , and needed ISC_LANG_BEGINDECLS - and ISC_LANG_ENDDECLS. - - 134. [cleanup] does not need . - - 133. [cleanup] needs . - - 132. [cleanup] does not need , but does - need . - - 131. [cleanup] and need - for ISC_R_* codes used in macros. - - 130. [cleanup] does not need or - , and now includes - instead of . - - 129. [bug] The 'default_debug' log channel was not set up when - 'category default' was present in the config file - - 128. [cleanup] had ISC_LANG_BEGINDECLS instead of - ISC_LANG_ENDDECLS at end of header. - - 127. [cleanup] The contracts for the comparision routines - dns_name_fullcompare(), dns_name_compare(), - dns_name_rdatacompare(), and dns_rdata_compare() now - specify that the order value returned is < 0, 0, or > 0 - instead of -1, 0, or 1. - - 126. [cleanup] and need . - - 125. [cleanup] , , , - , , , and - do not need . - - 124. [func] signer now imports parent's zone key signature - and creates null keys/sets zone status bit for - children when necessary - - 123. [cleanup] does not need . - - 122. [cleanup] does not need or - . - - 121. [cleanup] does not need or - . Multiple inclusion protection - symbol fixed from ISC_SYMBOL_H to ISC_SYMTAB_H. - isc_symtab_t moved to . - - 120. [cleanup] does not need , - , , or - . - - 119. [cleanup] structure definitions for generic rdata structures do - not have _generic_ in their names. - - 118. [cleanup] libdns.a is now namespace-clean, on NetBSD, excepting - YACC crust (yyparse, etc) [2000-apr-27 explorer] - - 117. [cleanup] libdns.a changes: - dns_zone_clearnotify() and dns_zone_addnotify() - are replaced by dns_zone_setnotifyalso(). - dns_zone_clearmasters() and dns_zone_addmaster() - are replaced by dns_zone_setmasters(). - - 116. [func] Added for isc_offset_t (aka off_t - on Unix systems). - - 115. [port] Shut up the -Wmissing-declarations warning about - 's __sputaux on BSD/OS pre-4.1. - - 114. [cleanup] does not need or - . - - 113. [func] Utility programs dig and host added. - - 112. [cleanup] does not need . - - 111. [cleanup] does not need or - . - - 110. [cleanup] does not need or - . - - 109. [bug] "make depend" did nothing for - bin/tests/{db,mem,sockaddr,tasks,timers}/. - - 108. [cleanup] DNS_SETBIT/DNS_GETBIT/DNS_CLEARBIT moved from - to and renamed to - DNS_BIT_SET/DNS_BIT_GET/DNS_BIT_CLEAR. - - 107. [func] Add keysigner and keysettool. - - 106. [func] Allow dnssec verifications to ignore the validity - period. Used by several of the dnssec tools. - - 105. [doc] doc/dev/coding.html expanded with other - implicit conventions the developers have used. - - 104. [bug] Made compress_add and compress_find static to - lib/dns/compress.c. - - 103. [func] libisc buffer API changes for : - Added: - isc_buffer_base(b) (pointer) - isc_buffer_current(b) (pointer) - isc_buffer_active(b) (pointer) - isc_buffer_used(b) (pointer) - isc_buffer_length(b) (int) - isc_buffer_usedlength(b) (int) - isc_buffer_consumedlength(b) (int) - isc_buffer_remaininglength(b) (int) - isc_buffer_activelength(b) (int) - isc_buffer_availablelength(b) (int) - Removed: - ISC_BUFFER_USEDCOUNT(b) - ISC_BUFFER_AVAILABLECOUNT(b) - isc_buffer_type(b) - Changed names: - isc_buffer_used(b, r) -> - isc_buffer_usedregion(b, r) - isc_buffer_available(b, r) -> - isc_buffer_available_region(b, r) - isc_buffer_consumed(b, r) -> - isc_buffer_consumedregion(b, r) - isc_buffer_active(b, r) -> - isc_buffer_activeregion(b, r) - isc_buffer_remaining(b, r) -> - isc_buffer_remainingregion(b, r) - - Buffer types were removed, so the ISC_BUFFERTYPE_* - macros are no more, and the type argument to - isc_buffer_init and isc_buffer_allocate were removed. - isc_buffer_putstr is now void (instead of isc_result_t) - and requires that the caller ensure that there - is enough available buffer space for the string. - - 102. [port] Correctly detect inet_aton, inet_pton and inet_ptop - on BSD/OS 4.1. - - 101. [cleanup] Quieted EGCS warnings from lib/isc/print.c. - - 100. [cleanup] does not need or - . isc_random_t moved to . - - 99. [cleanup] Rate limiter now has separate shutdown() and - destroy() functions, and it guarantees that all - queued events are delivered even in the shutdown case. - - 98. [cleanup] does not need or - unless ISC_PLATFORM_NEEDVSNPRINTF is defined. - - 97. [cleanup] does not need or - . - - 96. [cleanup] does not need . - - 95. [cleanup] does not need . - - 94. [cleanup] Some installed header files did not compile as C++. - - 93. [cleanup] does not need . - - 92. [cleanup] does not need , , - or . - - 91. [cleanup] does not need or - . - - 90. [cleanup] Removed unneeded ISC_LANG_BEGINDECLS/ISC_LANG_ENDDECLS - from . - - 89. [cleanup] does not need . - - 88. [cleanup] does not need or - . isc_interface_t and isc_interfaceiter_t - moved to . - - 87. [cleanup] does not need , - or . - - 86. [cleanup] isc_bufferlist_t moved from to - . - - 85. [cleanup] does not need , - , , or - . - - 84. [func] allow-query ACL checks now apply to all data - added to a response. - - 83. [func] If the server is authoritative for both a - delegating zone and its (nonsecure) delegatee, and - a query is made for a KEY RR at the top of the - delegatee, then the server will look for a KEY - in the delegator if it is not found in the delegatee. - - 82. [cleanup] does not need . - - 81. [cleanup] and do not need - . - - 80. [cleanup] does not need or . - - 79. [cleanup] does not need . - - 78. [cleanup] lwres_conftest renamed to lwresconf_test for - consistency with other *_test programs. - - 77. [cleanup] typedef of isc_time_t and isc_interval_t moved from - to . - - 76. [cleanup] Rewrote keygen. - - 75. [func] Don't load a zone if its database file is older - than the last time the zone was loaded. - - 74. [cleanup] Removed mktemplate.o and ufile.o from libisc.a, - subsumed by file.o. - - 73. [func] New "file" API in libisc, including new function - isc_file_getmodtime, isc_mktemplate renamed to - isc_file_mktemplate and isc_ufile renamed to - isc_file_openunique. By no means an exhaustive API, - it is just what's needed for now. - - 72. [func] DNS_RBTFIND_NOPREDECESSOR and DNS_RBTFIND_NOOPTIONS - added for dns_rbt_findnode, the former to disable the - setting of the chain to the predecessor, and the - latter to make clear when no options are set. - - 71. [cleanup] Made explicit the implicit REQUIREs of - isc_time_seconds, isc_time_nanoseconds, and - isc_time_subtract. - - 70. [func] isc_time_set() added. - - 69. [bug] The zone object's master and also-notify lists grew - longer with each server reload. - - 68. [func] Partial support for SIG(0) on incoming messages. - - 67. [performance] Allow use of alternate (compile-time supplied) - OpenSSL libraries/headers. - - 66. [func] Data in authoritative zones should have a trust level - beyond secure. - - 65. [cleanup] Removed obsolete typedef of dns_zone_callbackarg_t - from . - - 64. [func] The RBT, DB, and zone table APIs now allow the - caller find the most-enclosing superdomain of - a name. - - 63. [func] Generate NOTIFY messages. - - 62. [func] Add UDP refresh support. - - 61. [cleanup] Use single quotes consistently in log messages. - - 60. [func] Catch and disallow singleton types on message - parse. - - 59. [bug] Cause net/host unreachable to be a hard error - when sending and receiving. - - 58. [bug] bin/named/query.c could sometimes trigger the - (client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) - == 0 assertion in query_newname(). - - 57. [func] Added dns_nxt_typepresent() - - 56. [bug] SIG records were not properly returned in cached - negative answers. - - 55. [bug] Responses containing multiple names in the authority - section were not negatively cached. - - 54. [bug] If a fetch with sigrdataset==NULL joined one with - sigrdataset!=NULL or vice versa, the resolver - could catch an assertion or lose signature data, - respectively. - - 53. [port] freebsd 4.0: lib/isc/unix/socket.c requires - . - - 52. [bug] rndc: taskmgr and socketmgr were not initialized - to NULL. - - 51. [cleanup] dns/compress.h and dns/zt.h did not need to include - dns/rbt.h; it was needed only by compress.c and zt.c. - - 50. [func] RBT deletion no longer requires a valid chain to work, - and dns_rbt_deletenode was added. - - 49. [func] Each cache now has its own mctx. - - 48. [func] isc_task_create() no longer takes an mctx. - isc_task_mem() has been eliminated. - - 47. [func] A number of modules now use memory context reference - counting. - - 46. [func] Memory contexts are now reference counted. - Added isc_mem_inuse() and isc_mem_preallocate(). - Renamed isc_mem_destroy_check() to - isc_mem_setdestroycheck(). - - 45. [bug] The trusted-key statement incorrectly loaded keys. - - 44. [bug] Don't include authority data if it would force us - to unset the AD bit in the message. - - 43. [bug] DNSSEC verification of cached rdatasets was failing. - - 42. [cleanup] Simplified logging of messages with embedded domain - names by introducing a new convenience function - dns_name_format(). - - 41. [func] Use PR_SET_KEEPCAPS on Linux 2.3.99-pre3 and later - to allow 'named' to run as a non-root user while - retaining the ability to bind() to privileged - ports. - - 40. [func] Introduced new logging category "dnssec" and - logging module "dns/validator". - - 39. [cleanup] Moved the typedefs for isc_region_t, isc_textregion_t, - and isc_lex_t to . - - 38. [bug] TSIG signed incoming zone transfers work now. - - 37. [bug] If the first RR in an incoming zone transfer was - not an SOA, the server died with an assertion failure - instead of just reporting an error. - - 36. [cleanup] Change DNS_R_SUCCESS (and others) to ISC_R_SUCCESS - - 35. [performance] Log messages which are of a level too high to be - logged by any channel in the logging configuration - will not cause the log mutex to be locked. - - 34. [bug] Recursion was allowed even with 'recursion no'. - - 33. [func] The RBT now maintains a parent pointer at each node. - - 32. [cleanup] bin/lwresd/client.c needs for memset() - prototype. - - 31. [bug] Use ${LIBTOOL} to compile bin/named/main.@O@. - - 30. [func] config file grammer change to support optional - class type for a view. - - 29. [func] support new config file view options: - - auth-nxdomain recursion query-source - query-source-v6 transfer-source - transfer-source-v6 max-transfer-time-out - max-transfer-idle-out transfer-format - request-ixfr provide-ixfr cleaning-interval - fetch-glue notify rfc2308-type1 lame-ttl - max-ncache-ttl min-roots - - 28. [func] support lame-ttl, min-roots and serial-queries - config global options. - - 27. [bug] Only include on BSD/OS 4.[01]*. - Including it on other platforms (eg, NetBSD) can - cause a forced #error from the C preprocessor. - - 26. [func] new match-clients statement in config file view. - - 25. [bug] make install failed to install and - . - - 24. [cleanup] Eliminate some unnecessary #includes of header - files from header files. - - 23. [cleanup] Provide more context in log messages about client - requests, using a new function ns_client_log(). - - 22. [bug] SIGs weren't returned in the answer section when - the query resulted in a fetch. - - 21. [port] Look at STD_CINCLUDES after CINCLUDES during - compilation, so additional system include directories - can be searched but header files in the bind9 source - tree with conflicting names take precedence. This - avoids issues with installed versions of dnssafe and - openssl. - - 20. [func] Configuration file post-load validation of zones - failed if there were no zones. - - 19. [bug] dns_zone_notifyreceive() failed to unlock the zone - lock in certain error cases. - - 18. [bug] Use AC_TRY_LINK rather than AC_TRY_COMPILE in - configure.in to check for presence of in6addr_any. - - 17. [func] Do configuration file post-load validation of zones. - - 16. [bug] put quotes around key names on config file - output to avoid possible keyword clashes. - - 15. [func] Add dns_name_dupwithoffsets(). This function is - improves comparison performance for duped names. - - 14. [bug] free_rbtdb() could have 'put' unallocated memory in - an unlikely error path. - - 13. [bug] lib/dns/master.c and lib/dns/xfrin.c didn't ignore - out-of-zone data. - - 12. [bug] Fixed possible unitialized variable error. - - 11. [bug] axfr_rrstream_first() didn't check the result code of - db_rr_iterator_first(), possibly causing an assertion - to be triggered later. - - 10. [bug] A bug in the code which makes EDNS0 OPT records in - bin/named/client.c and lib/dns/resolver.c could - trigger an assertion. - - 9. [cleanup] replaced bit-setting code in confctx.c and replaced - repeated code with macro calls. - - 8. [bug] Shutdown of incoming zone transfer accessed - freed memory. - - 7. [cleanup] removed 'listen-on' from view statement. - - 6. [bug] quote RR names when generating config file to - prevent possible clash with config file keywords - (such as 'key'). - - 5. [func] syntax change to named.conf file: new ssu grant/deny - statements must now be enclosed by an 'update-policy' - block. - - 4. [port] bin/named/unix/os.c didn't compile on systems with - linux 2.3 kernel includes due to conflicts between - C library includes and the kernel includes. We now - get only what we need from , and - avoid pulling in other linux kernel .h files. - - 3. [bug] TKEYs go in the answer section of responses, not - the additional section. - - 2. [bug] Generating cryptographic randomness failed on - systems without /dev/random. - - 1. [bug] The installdirs rule in - lib/isc/unix/include/isc/Makefile.in had a typo which - prevented the isc directory from being created if it - didn't exist. - - --- 9.0.0b2 released --- - -# This tells Emacs to use hard tabs in this file. -# Local Variables: -# indent-tabs-mode: t -# End: diff --git a/contrib/bind9/COPYRIGHT b/contrib/bind9/COPYRIGHT deleted file mode 100644 index 48141e7..0000000 --- a/contrib/bind9/COPYRIGHT +++ /dev/null @@ -1,30 +0,0 @@ -Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") -Copyright (C) 1996-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: COPYRIGHT,v 1.9.18.4 2007/08/28 07:19:54 tbox Exp $ - -Portions Copyright (C) 1996-2001 Nominum, Inc. - -Permission to use, copy, modify, and 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 NOMINUM DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM 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. diff --git a/contrib/bind9/FAQ b/contrib/bind9/FAQ deleted file mode 100644 index 90b3ca0..0000000 --- a/contrib/bind9/FAQ +++ /dev/null @@ -1,781 +0,0 @@ -Frequently Asked Questions about BIND 9 - -Copyright © 2004-2007 Internet Systems Consortium, Inc. ("ISC") - -Copyright © 2000-2003 Internet Software Consortium. - ------------------------------------------------------------------------ - -1. Compilation and Installation Questions - -Q: I'm trying to compile BIND 9, and "make" is failing due to files not - being found. Why? - -A: Using a parallel or distributed "make" to build BIND 9 is not - supported, and doesn't work. If you are using one of these, use normal - make or gmake instead. - -Q: Isn't "make install" supposed to generate a default named.conf? - -A: Short Answer: No. - - Long Answer: There really isn't a default configuration which fits any - site perfectly. There are lots of decisions that need to be made and - there is no consensus on what the defaults should be. For example - FreeBSD uses /etc/namedb as the location where the configuration files - for named are stored. Others use /var/named. - - What addresses to listen on? For a laptop on the move a lot you may - only want to listen on the loop back interfaces. - - Who do you offer recursive service to? Is there are firewall to - consider? If so is it stateless or stateful. Are you directly on the - Internet? Are you on a private network? Are you on a NAT'd network? The - answers to all these questions change how you configure even a caching - name server. - -2. Configuration and Setup Questions - -Q: Why does named log the warning message "no TTL specified - using SOA - MINTTL instead"? - -A: Your zone file is illegal according to RFC1035. It must either have a - line like: - - $TTL 86400 - - at the beginning, or the first record in it must have a TTL field, like - the "84600" in this example: - - example.com. 86400 IN SOA ns hostmaster ( 1 3600 1800 1814400 3600 ) - -Q: Why do I get errors like "dns_zone_load: zone foo/IN: loading master - file bar: ran out of space"? - -A: This is often caused by TXT records with missing close quotes. Check - that all TXT records containing quoted strings have both open and close - quotes. - -Q: How do I restrict people from looking up the server version? - -A: Put a "version" option containing something other than the real version - in the "options" section of named.conf. Note doing this will not - prevent attacks and may impede people trying to diagnose problems with - your server. Also it is possible to "fingerprint" nameservers to - determine their version. - -Q: How do I restrict only remote users from looking up the server version? - -A: The following view statement will intercept lookups as the internal - view that holds the version information will be matched last. The - caveats of the previous answer still apply, of course. - - view "chaos" chaos { - match-clients { ; }; - allow-query { none; }; - zone "." { - type hint; - file "/dev/null"; // or any empty file - }; - }; - -Q: What do "no source of entropy found" or "could not open entropy source - foo" mean? - -A: The server requires a source of entropy to perform certain operations, - mostly DNSSEC related. These messages indicate that you have no source - of entropy. On systems with /dev/random or an equivalent, it is used by - default. A source of entropy can also be defined using the - random-device option in named.conf. - -Q: I'm trying to use TSIG to authenticate dynamic updates or zone - transfers. I'm sure I have the keys set up correctly, but the server is - rejecting the TSIG. Why? - -A: This may be a clock skew problem. Check that the the clocks on the - client and server are properly synchronised (e.g., using ntp). - -Q: I see a log message like the following. Why? - - couldn't open pid file '/var/run/named.pid': Permission denied - -A: You are most likely running named as a non-root user, and that user - does not have permission to write in /var/run. The common ways of - fixing this are to create a /var/run/named directory owned by the named - user and set pid-file to "/var/run/named/named.pid", or set pid-file to - "named.pid", which will put the file in the directory specified by the - directory option (which, in this case, must be writable by the named - user). - -Q: I can query the nameserver from the nameserver but not from other - machines. Why? - -A: This is usually the result of the firewall configuration stopping the - queries and / or the replies. - -Q: How can I make a server a slave for both an internal and an external - view at the same time? When I tried, both views on the slave were - transferred from the same view on the master. - -A: You will need to give the master and slave multiple IP addresses and - use those to make sure you reach the correct view on the other machine. - - Master: 10.0.1.1 (internal), 10.0.1.2 (external, IP alias) - internal: - match-clients { !10.0.1.2; !10.0.1.4; 10.0.1/24; }; - notify-source 10.0.1.1; - transfer-source 10.0.1.1; - query-source address 10.0.1.1; - external: - match-clients { any; }; - recursion no; // don't offer recursion to the world - notify-source 10.0.1.2; - transfer-source 10.0.1.2; - query-source address 10.0.1.2; - - Slave: 10.0.1.3 (internal), 10.0.1.4 (external, IP alias) - internal: - match-clients { !10.0.1.2; !10.0.1.4; 10.0.1/24; }; - notify-source 10.0.1.3; - transfer-source 10.0.1.3; - query-source address 10.0.1.3; - external: - match-clients { any; }; - recursion no; // don't offer recursion to the world - notify-source 10.0.1.4; - transfer-source 10.0.1.4; - query-source address 10.0.1.4; - - You put the external address on the alias so that all the other dns - clients on these boxes see the internal view by default. - -A: BIND 9.3 and later: Use TSIG to select the appropriate view. - - Master 10.0.1.1: - key "external" { - algorithm hmac-md5; - secret "xxxxxxxx"; - }; - view "internal" { - match-clients { !key external; 10.0.1/24; }; - ... - }; - view "external" { - match-clients { key external; any; }; - server 10.0.1.2 { keys external; }; - recursion no; - ... - }; - - Slave 10.0.1.2: - key "external" { - algorithm hmac-md5; - secret "xxxxxxxx"; - }; - view "internal" { - match-clients { !key external; 10.0.1/24; }; - ... - }; - view "external" { - match-clients { key external; any; }; - server 10.0.1.1 { keys external; }; - recursion no; - ... - }; - -Q: I get error messages like "multiple RRs of singleton type" and "CNAME - and other data" when transferring a zone. What does this mean? - -A: These indicate a malformed master zone. You can identify the exact - records involved by transferring the zone using dig then running - named-checkzone on it. - - dig axfr example.com @master-server > tmp - named-checkzone example.com tmp - - A CNAME record cannot exist with the same name as another record except - for the DNSSEC records which prove its existence (NSEC). - - RFC 1034, Section 3.6.2: "If a CNAME RR is present at a node, no other - data should be present; this ensures that the data for a canonical name - and its aliases cannot be different. This rule also insures that a - cached CNAME can be used without checking with an authoritative server - for other RR types." - -Q: I get error messages like "named.conf:99: unexpected end of input" - where 99 is the last line of named.conf. - -A: Some text editors (notepad and wordpad) fail to put a line title - indication (e.g. CR/LF) on the last line of a text file. This can be - fixed by "adding" a blank line to the end of the file. Named expects to - see EOF immediately after EOL and treats text files where this is not - met as truncated. - -Q: How do I share a dynamic zone between multiple views? - -A: You choose one view to be master and the second a slave and transfer - the zone between views. - - Master 10.0.1.1: - key "external" { - algorithm hmac-md5; - secret "xxxxxxxx"; - }; - - key "mykey" { - algorithm hmac-md5; - secret "yyyyyyyy"; - }; - - view "internal" { - match-clients { !key external; 10.0.1/24; }; - server 10.0.1.1 { - /* Deliver notify messages to external view. */ - keys { external; }; - }; - zone "example.com" { - type master; - file "internal/example.db"; - allow-update { key mykey; }; - notify-also { 10.0.1.1; }; - }; - }; - - view "external" { - match-clients { key external; any; }; - zone "example.com" { - type slave; - file "external/example.db"; - masters { 10.0.1.1; }; - transfer-source { 10.0.1.1; }; - // allow-update-forwarding { any; }; - // allow-notify { ... }; - }; - }; - -Q: I get a error message like "zone wireless.ietf56.ietf.org/IN: loading - master file primaries/wireless.ietf56.ietf.org: no owner". - -A: This error is produced when a line in the master file contains leading - white space (tab/space) but the is no current record owner name to - inherit the name from. Usually this is the result of putting white - space before a comment, forgetting the "@" for the SOA record, or - indenting the master file. - -Q: Why are my logs in GMT (UTC). - -A: You are running chrooted (-t) and have not supplied local timezone - information in the chroot area. - - FreeBSD: /etc/localtime - Solaris: /etc/TIMEZONE and /usr/share/lib/zoneinfo - OSF: /etc/zoneinfo/localtime - - See also tzset(3) and zic(8). - -Q: I get "rndc: connect failed: connection refused" when I try to run - rndc. - -A: This is usually a configuration error. - - First ensure that named is running and no errors are being reported at - startup (/var/log/messages or equivalent). Running "named -g " from a title can help at this point. - - Secondly ensure that named is configured to use rndc either by - "rndc-confgen -a", rndc-confgen or manually. The Administrators - Reference manual has details on how to do this. - - Old versions of rndc-confgen used localhost rather than 127.0.0.1 in / - etc/rndc.conf for the default server. Update /etc/rndc.conf if - necessary so that the default server listed in /etc/rndc.conf matches - the addresses used in named.conf. "localhost" has two address - (127.0.0.1 and ::1). - - If you use "rndc-confgen -a" and named is running with -t or -u ensure - that /etc/rndc.conf has the correct ownership and that a copy is in the - chroot area. You can do this by re-running "rndc-confgen -a" with - appropriate -t and -u arguments. - -Q: I get "transfer of 'example.net/IN' from 192.168.4.12#53: failed while - receiving responses: permission denied" error messages. - -A: These indicate a filesystem permission error preventing named creating - / renaming the temporary file. These will usually also have other - associated error messages like - - "dumping master file: sl/tmp-XXXX5il3sQ: open: permission denied" - - Named needs write permission on the directory containing the file. - Named writes the new cache file to a temporary file then renames it to - the name specified in named.conf to ensure that the contents are always - complete. This is to prevent named loading a partial zone in the event - of power failure or similar interrupting the write of the master file. - - Note file names are relative to the directory specified in options and - any chroot directory ([/][]). - - If named is invoked as "named -t /chroot/DNS" with the following - named.conf then "/chroot/DNS/var/named/sl" needs to be writable by the - user named is running as. - - options { - directory "/var/named"; - }; - - zone "example.net" { - type slave; - file "sl/example.net"; - masters { 192.168.4.12; }; - }; - -Q: I want to forward all DNS queries from my caching nameserver to another - server. But there are some domains which have to be served locally, via - rbldnsd. - - How do I achieve this ? - -A: options { - forward only; - forwarders { ; }; - }; - - zone "sbl-xbl.spamhaus.org" { - type forward; forward only; - forwarders { port 530; }; - }; - - zone "list.dsbl.org" { - type forward; forward only; - forwarders { port 530; }; - }; - - -Q: Can you help me understand how BIND 9 uses memory to store DNS zones? - - Some times it seems to take several times the amount of memory it needs - to store the zone. - -A: When reloading a zone named my have multiple copies of the zone in - memory at one time. The zone it is serving and the one it is loading. - If reloads are ultra fast it can have more still. - - e.g. Ones that are transferring out, the one that it is serving and the - one that is loading. - - BIND 8 destroyed the zone before loading and also killed off outgoing - transfers of the zone. - - The new strategy allows slaves to get copies of the new zone regardless - of how often the master is loaded compared to the transfer time. The - slave might skip some intermediate versions but the transfers will - complete and it will keep reasonably in sync with the master. - - The new strategy also allows the master to recover from syntax and - other errors in the master file as it still has an in-core copy of the - old contents. - -3. General Questions - -Q: I keep getting log messages like the following. Why? - - Dec 4 23:47:59 client 10.0.0.1#1355: updating zone 'example.com/IN': - update failed: 'RRset exists (value dependent)' prerequisite not - satisfied (NXRRSET) - -A: DNS updates allow the update request to test to see if certain - conditions are met prior to proceeding with the update. The message - above is saying that conditions were not met and the update is not - proceeding. See doc/rfc/rfc2136.txt for more details on prerequisites. - -Q: I keep getting log messages like the following. Why? - - Jun 21 12:00:00.000 client 10.0.0.1#1234: update denied - -A: Someone is trying to update your DNS data using the RFC2136 Dynamic - Update protocol. Windows 2000 machines have a habit of sending dynamic - update requests to DNS servers without being specifically configured to - do so. If the update requests are coming from a Windows 2000 machine, - see http://support.microsoft.com/support/kb/articles/q246/8/04.asp for - information about how to turn them off. - -Q: When I do a "dig . ns", many of the A records for the root servers are - missing. Why? - -A: This is normal and harmless. It is a somewhat confusing side effect of - the way BIND 9 does RFC2181 trust ranking and of the efforts BIND 9 - makes to avoid promoting glue into answers. - - When BIND 9 first starts up and primes its cache, it receives the root - server addresses as additional data in an authoritative response from a - root server, and these records are eligible for inclusion as additional - data in responses. Subsequently it receives a subset of the root server - addresses as additional data in a non-authoritative (referral) response - from a root server. This causes the addresses to now be considered - non-authoritative (glue) data, which is not eligible for inclusion in - responses. - - The server does have a complete set of root server addresses cached at - all times, it just may not include all of them as additional data, - depending on whether they were last received as answers or as glue. You - can always look up the addresses with explicit queries like "dig - a.root-servers.net A". - -Q: Why don't my zones reload when I do an "rndc reload" or SIGHUP? - -A: A zone can be updated either by editing zone files and reloading the - server or by dynamic update, but not both. If you have enabled dynamic - update for a zone using the "allow-update" option, you are not supposed - to edit the zone file by hand, and the server will not attempt to - reload it. - -Q: Why is named listening on UDP port other than 53? - -A: Named uses a system selected port to make queries of other nameservers. - This behaviour can be overridden by using query-source to lock down the - port and/or address. See also notify-source and transfer-source. - -Q: I get warning messages like "zone example.com/IN: refresh: failure - trying master 1.2.3.4#53: timed out". - -A: Check that you can make UDP queries from the slave to the master - - dig +norec example.com soa @1.2.3.4 - - You could be generating queries faster than the slave can cope with. - Lower the serial query rate. - - serial-query-rate 5; // default 20 - -Q: I don't get RRSIG's returned when I use "dig +dnssec". - -A: You need to ensure DNSSEC is enabled (dnssec-enable yes;). - -Q: Can a NS record refer to a CNAME. - -A: No. The rules for glue (copies of the *address* records in the parent - zones) and additional section processing do not allow it to work. - - You would have to add both the CNAME and address records (A/AAAA) as - glue to the parent zone and have CNAMEs be followed when doing - additional section processing to make it work. No nameserver - implementation supports either of these requirements. - -Q: What does "RFC 1918 response from Internet for 0.0.0.10.IN-ADDR.ARPA" - mean? - -A: If the IN-ADDR.ARPA name covered refers to a internal address space you - are using then you have failed to follow RFC 1918 usage rules and are - leaking queries to the Internet. You should establish your own zones - for these addresses to prevent you querying the Internet's name servers - for these addresses. Please see http://as112.net/ for details of the - problems you are causing and the counter measures that have had to be - deployed. - - If you are not using these private addresses then a client has queried - for them. You can just ignore the messages, get the offending client to - stop sending you these messages as they are most probably leaking them - or setup your own zones empty zones to serve answers to these queries. - - zone "10.IN-ADDR.ARPA" { - type master; - file "empty"; - }; - - zone "16.172.IN-ADDR.ARPA" { - type master; - file "empty"; - }; - - ... - - zone "31.172.IN-ADDR.ARPA" { - type master; - file "empty"; - }; - - zone "168.192.IN-ADDR.ARPA" { - type master; - file "empty"; - }; - - empty: - @ 10800 IN SOA . . ( - 1 3600 1200 604800 10800 ) - @ 10800 IN NS . - - Note - - Future versions of named are likely to do this automatically. - -Q: Will named be affected by the 2007 changes to daylight savings rules in - the US. - -A: No, so long as the machines internal clock (as reported by "date -u") - remains at UTC. The only visible change if you fail to upgrade your OS, - if you are in a affected area, will be that log messages will be a hour - out during the period where the old rules do not match the new rules. - - For most OS's this change just means that you need to update the - conversion rules from UTC to local time. Normally this involves - updating a file in /etc (which sets the default timezone for the - machine) and possibly a directory which has all the conversion rules - for the world (e.g. /usr/share/zoneinfo). When updating the OS do not - forget to update any chroot areas as well. See your OS's documentation - for more details. - - The local timezone conversion rules can also be done on a individual - basis by setting the TZ environment variable appropriately. See your - OS's documentation for more details. - -Q: Is there a bugzilla (or other tool) database that mere mortals can have - (read-only) access to for bind? - -A: No. The BIND 9 bug database is kept closed for a number of reasons. - These include, but are not limited to, that the database contains - proprietory information from people reporting bugs. The database has in - the past and may in future contain unfixed bugs which are capable of - bringing down most of the Internet's DNS infrastructure. - - The release pages for each version contain up to date lists of bugs - that have been fixed post release. That is as close as we can get to - providing a bug database. - -4. Operating-System Specific Questions - -4.1. HPUX - -Q: I get the following error trying to configure BIND: - - checking if unistd.h or sys/types.h defines fd_set... no - configure: error: need either working unistd.h or sys/select.h - -A: You have attempted to configure BIND with the bundled C compiler. This - compiler does not meet the minimum compiler requirements to for - building BIND. You need to install a ANSI C compiler and / or teach - configure how to find the ANSI C compiler. The later can be done by - adjusting the PATH environment variable and / or specifying the - compiler via CC. - - ./configure CC= ... - -4.2. Linux - -Q: Why do I get the following errors: - - general: errno2result.c:109: unexpected error: - general: unable to convert errno to isc_result: 14: Bad address - client: UDP client handler shutting down due to fatal receive error: unexpected error - -A: This is the result of a Linux kernel bug. - - See: http://marc.theaimsgroup.com/?l=linux-netdev&m=113081708031466&w=2 - -Q: Why do I see 5 (or more) copies of named on Linux? - -A: Linux threads each show up as a process under ps. The approximate - number of threads running is n+4, where n is the number of CPUs. Note - that the amount of memory used is not cumulative; if each process is - using 10M of memory, only a total of 10M is used. - - Newer versions of Linux's ps command hide the individual threads and - require -L to display them. - -Q: Why does BIND 9 log "permission denied" errors accessing its - configuration files or zones on my Linux system even though it is - running as root? - -A: On Linux, BIND 9 drops most of its root privileges on startup. This - including the privilege to open files owned by other users. Therefore, - if the server is running as root, the configuration files and zone - files should also be owned by root. - -Q: I get the error message "named: capset failed: Operation not permitted" - when starting named. - -A: The capability module, part of "Linux Security Modules/LSM", has not - been loaded into the kernel. See insmod(8). - -Q: I'm running BIND on Red Hat Enterprise Linux or Fedora Core - - - Why can't named update slave zone database files? - - Why can't named create DDNS journal files or update the master zones - from journals? - - Why can't named create custom log files? - -A: Red Hat Security Enhanced Linux (SELinux) policy security protections : - - Red Hat have adopted the National Security Agency's SELinux security - policy ( see http://www.nsa.gov/selinux ) and recommendations for BIND - security , which are more secure than running named in a chroot and - make use of the bind-chroot environment unnecessary . - - By default, named is not allowed by the SELinux policy to write, create - or delete any files EXCEPT in these directories: - - $ROOTDIR/var/named/slaves - $ROOTDIR/var/named/data - $ROOTDIR/var/tmp - - - where $ROOTDIR may be set in /etc/sysconfig/named if bind-chroot is - installed. - - The SELinux policy particularly does NOT allow named to modify the - $ROOTDIR/var/named directory, the default location for master zone - database files. - - SELinux policy overrules file access permissions - so even if all the - files under /var/named have ownership named:named and mode rw-rw-r--, - named will still not be able to write or create files except in the - directories above, with SELinux in Enforcing mode. - - So, to allow named to update slave or DDNS zone files, it is best to - locate them in $ROOTDIR/var/named/slaves, with named.conf zone - statements such as: - - zone "slave.zone." IN { - type slave; - file "slaves/slave.zone.db"; - ... - }; - zone "ddns.zone." IN { - type master; - allow-updates {...}; - file "slaves/ddns.zone.db"; - }; - - - To allow named to create its cache dump and statistics files, for - example, you could use named.conf options statements such as: - - options { - ... - dump-file "/var/named/data/cache_dump.db"; - statistics-file "/var/named/data/named_stats.txt"; - ... - }; - - - You can also tell SELinux to allow named to update any zone database - files, by setting the SELinux tunable boolean parameter - 'named_write_master_zones=1', using the system-config-securitylevel - GUI, using the 'setsebool' command, or in /etc/selinux/targeted/ - booleans. - - You can disable SELinux protection for named entirely by setting the - 'named_disable_trans=1' SELinux tunable boolean parameter. - - The SELinux named policy defines these SELinux contexts for named: - - named_zone_t : for zone database files - $ROOTDIR/var/named/* - named_conf_t : for named configuration files - $ROOTDIR/etc/{named,rndc}.* - named_cache_t: for files modifiable by named - $ROOTDIR/var/{tmp,named/{slaves,data}} - - - If you want to retain use of the SELinux policy for named, and put - named files in different locations, you can do so by changing the - context of the custom file locations . - - To create a custom configuration file location, e.g. '/root/ - named.conf', to use with the 'named -c' option, do: - - # chcon system_u:object_r:named_conf_t /root/named.conf - - - To create a custom modifiable named data location, e.g. '/var/log/ - named' for a log file, do: - - # chcon system_u:object_r:named_cache_t /var/log/named - - - To create a custom zone file location, e.g. /root/zones/, do: - - # chcon system_u:object_r:named_zone_t /root/zones/{.,*} - - - See these man-pages for more information : selinux(8), named_selinux - (8), chcon(1), setsebool(8) - -4.3. Windows - -Q: Zone transfers from my BIND 9 master to my Windows 2000 slave fail. - Why? - -A: This may be caused by a bug in the Windows 2000 DNS server where DNS - messages larger than 16K are not handled properly. This can be worked - around by setting the option "transfer-format one-answer;". Also check - whether your zone contains domain names with embedded spaces or other - special characters, like "John\032Doe\213s\032Computer", since such - names have been known to cause Windows 2000 slaves to incorrectly - reject the zone. - -Q: I get "Error 1067" when starting named under Windows. - -A: This is the service manager saying that named exited. You need to - examine the Application log in the EventViewer to find out why. - - Common causes are that you failed to create "named.conf" (usually "C:\ - windows\dns\etc\named.conf") or failed to specify the directory in - named.conf. - - options { - Directory "C:\windows\dns\etc"; - }; - -4.4. FreeBSD - -Q: I have FreeBSD 4.x and "rndc-confgen -a" just sits there. - -A: /dev/random is not configured. Use rndcontrol(8) to tell the kernel to - use certain interrupts as a source of random events. You can make this - permanent by setting rand_irqs in /etc/rc.conf. - - /etc/rc.conf - rand_irqs="3 14 15" - - See also http://people.freebsd.org/~dougb/randomness.html - -4.5. Solaris - -Q: How do I integrate BIND 9 and Solaris SMF - -A: Sun has a blog entry describing how to do this. - - http://blogs.sun.com/roller/page/anay/Weblog?catname=%2FSolaris - -4.6. Apple Mac OS X - -Q: How do I run BIND 9 on Apple Mac OS X? - -A: If you run Tiger(Mac OS 10.4) or later then this is all you need to do: - - % sudo rndc-confgen > /etc/rndc.conf - - Copy the key statement from /etc/rndc.conf into /etc/rndc.key, e.g.: - - key "rndc-key" { - algorithm hmac-md5; - secret "uvceheVuqf17ZwIcTydddw=="; - }; - - Then start the relevant service: - - % sudo service org.isc.named start - - This is persistent upon a reboot, so you will have to do it only once. - -A: Alternatively you can just generate /etc/rndc.key by running: - - % sudo rndc-confgen -a - - Then start the relevant service: - - % sudo service org.isc.named start - - Named will look for /etc/rndc.key when it starts if it doesn't have a - controls section or the existing controls are missing keys sub-clauses. - This is persistent upon a reboot, so you will have to do it only once. - diff --git a/contrib/bind9/FAQ.xml b/contrib/bind9/FAQ.xml deleted file mode 100644 index 0f864ef..0000000 --- a/contrib/bind9/FAQ.xml +++ /dev/null @@ -1,1347 +0,0 @@ - - - - - -
- Frequently Asked Questions about BIND 9 - - - 2004 - 2005 - 2006 - 2007 - Internet Systems Consortium, Inc. ("ISC") - - - 2000 - 2001 - 2002 - 2003 - Internet Software Consortium. - - - - - Compilation and Installation Questions - - - - - I'm trying to compile BIND 9, and "make" is failing due to - files not being found. Why? - - - - - Using a parallel or distributed "make" to build BIND 9 is - not supported, and doesn't work. If you are using one of - these, use normal make or gmake instead. - - - - - - - - Isn't "make install" supposed to generate a default named.conf? - - - - - Short Answer: No. - - - Long Answer: There really isn't a default configuration which fits - any site perfectly. There are lots of decisions that need to - be made and there is no consensus on what the defaults should be. - For example FreeBSD uses /etc/namedb as the location where the - configuration files for named are stored. Others use /var/named. - - - What addresses to listen on? For a laptop on the move a lot - you may only want to listen on the loop back interfaces. - - - Who do you offer recursive service to? Is there are firewall - to consider? If so is it stateless or stateful. Are you - directly on the Internet? Are you on a private network? Are - you on a NAT'd network? The answers - to all these questions change how you configure even a - caching name server. - - - - - - - Configuration and Setup Questions - - - - - - Why does named log the warning message no TTL specified - - using SOA MINTTL instead? - - - - - Your zone file is illegal according to RFC1035. It must either - have a line like: - - - -$TTL 86400 - - - at the beginning, or the first record in it must have a TTL field, - like the "84600" in this example: - - - -example.com. 86400 IN SOA ns hostmaster ( 1 3600 1800 1814400 3600 ) - - - - - - - - - Why do I get errors like dns_zone_load: zone foo/IN: loading - master file bar: ran out of space? - - - - - This is often caused by TXT records with missing close - quotes. Check that all TXT records containing quoted strings - have both open and close quotes. - - - - - - - - - How do I restrict people from looking up the server version? - - - - - Put a "version" option containing something other than the - real version in the "options" section of named.conf. Note - doing this will not prevent attacks and may impede people - trying to diagnose problems with your server. Also it is - possible to "fingerprint" nameservers to determine their - version. - - - - - - - - - How do I restrict only remote users from looking up the - server version? - - - - - The following view statement will intercept lookups as the - internal view that holds the version information will be - matched last. The caveats of the previous answer still - apply, of course. - - - -view "chaos" chaos { - match-clients { <those to be refused>; }; - allow-query { none; }; - zone "." { - type hint; - file "/dev/null"; // or any empty file - }; -}; - - - - - - - - - What do no source of entropy found or could not - open entropy source foo mean? - - - - - The server requires a source of entropy to perform certain - operations, mostly DNSSEC related. These messages indicate - that you have no source of entropy. On systems with - /dev/random or an equivalent, it is used by default. A - source of entropy can also be defined using the random-device - option in named.conf. - - - - - - - - - I'm trying to use TSIG to authenticate dynamic updates or - zone transfers. I'm sure I have the keys set up correctly, - but the server is rejecting the TSIG. Why? - - - - - This may be a clock skew problem. Check that the the clocks - on the client and server are properly synchronised (e.g., - using ntp). - - - - - - - - I see a log message like the following. Why? - - - couldn't open pid file '/var/run/named.pid': Permission denied - - - - - You are most likely running named as a non-root user, and - that user does not have permission to write in /var/run. - The common ways of fixing this are to create a /var/run/named - directory owned by the named user and set pid-file to - "/var/run/named/named.pid", or set pid-file to "named.pid", - which will put the file in the directory specified by the - directory option (which, in this case, must be writable by - the named user). - - - - - - - - I can query the nameserver from the nameserver but not from other - machines. Why? - - - - - This is usually the result of the firewall configuration stopping - the queries and / or the replies. - - - - - - - - How can I make a server a slave for both an internal and - an external view at the same time? When I tried, both views - on the slave were transferred from the same view on the master. - - - - - You will need to give the master and slave multiple IP - addresses and use those to make sure you reach the correct - view on the other machine. - - - -Master: 10.0.1.1 (internal), 10.0.1.2 (external, IP alias) - internal: - match-clients { !10.0.1.2; !10.0.1.4; 10.0.1/24; }; - notify-source 10.0.1.1; - transfer-source 10.0.1.1; - query-source address 10.0.1.1; - external: - match-clients { any; }; - recursion no; // don't offer recursion to the world - notify-source 10.0.1.2; - transfer-source 10.0.1.2; - query-source address 10.0.1.2; - -Slave: 10.0.1.3 (internal), 10.0.1.4 (external, IP alias) - internal: - match-clients { !10.0.1.2; !10.0.1.4; 10.0.1/24; }; - notify-source 10.0.1.3; - transfer-source 10.0.1.3; - query-source address 10.0.1.3; - external: - match-clients { any; }; - recursion no; // don't offer recursion to the world - notify-source 10.0.1.4; - transfer-source 10.0.1.4; - query-source address 10.0.1.4; - - - You put the external address on the alias so that all the other - dns clients on these boxes see the internal view by default. - - - - - BIND 9.3 and later: Use TSIG to select the appropriate view. - - - -Master 10.0.1.1: - key "external" { - algorithm hmac-md5; - secret "xxxxxxxx"; - }; - view "internal" { - match-clients { !key external; 10.0.1/24; }; - ... - }; - view "external" { - match-clients { key external; any; }; - server 10.0.1.2 { keys external; }; - recursion no; - ... - }; - -Slave 10.0.1.2: - key "external" { - algorithm hmac-md5; - secret "xxxxxxxx"; - }; - view "internal" { - match-clients { !key external; 10.0.1/24; }; - ... - }; - view "external" { - match-clients { key external; any; }; - server 10.0.1.1 { keys external; }; - recursion no; - ... - }; - - - - - - - - I get error messages like multiple RRs of singleton type - and CNAME and other data when transferring a zone. What - does this mean? - - - - - These indicate a malformed master zone. You can identify - the exact records involved by transferring the zone using - dig then running named-checkzone on it. - - - -dig axfr example.com @master-server > tmp -named-checkzone example.com tmp - - - A CNAME record cannot exist with the same name as another record - except for the DNSSEC records which prove its existence (NSEC). - - - RFC 1034, Section 3.6.2: If a CNAME RR is present at a node, - no other data should be present; this ensures that the data for a - canonical name and its aliases cannot be different. This rule also - insures that a cached CNAME can be used without checking with an - authoritative server for other RR types. - - - - - - - - I get error messages like named.conf:99: unexpected end - of input where 99 is the last line of named.conf. - - - - - Some text editors (notepad and wordpad) fail to put a line - title indication (e.g. CR/LF) on the last line of a - text file. This can be fixed by "adding" a blank line to - the end of the file. Named expects to see EOF immediately - after EOL and treats text files where this is not met as - truncated. - - - - - - - - How do I share a dynamic zone between multiple views? - - - - - You choose one view to be master and the second a slave and - transfer the zone between views. - - - -Master 10.0.1.1: - key "external" { - algorithm hmac-md5; - secret "xxxxxxxx"; - }; - - key "mykey" { - algorithm hmac-md5; - secret "yyyyyyyy"; - }; - - view "internal" { - match-clients { !key external; 10.0.1/24; }; - server 10.0.1.1 { - /* Deliver notify messages to external view. */ - keys { external; }; - }; - zone "example.com" { - type master; - file "internal/example.db"; - allow-update { key mykey; }; - notify-also { 10.0.1.1; }; - }; - }; - - view "external" { - match-clients { key external; any; }; - zone "example.com" { - type slave; - file "external/example.db"; - masters { 10.0.1.1; }; - transfer-source { 10.0.1.1; }; - // allow-update-forwarding { any; }; - // allow-notify { ... }; - }; - }; - - - - - - - - I get a error message like zone wireless.ietf56.ietf.org/IN: - loading master file primaries/wireless.ietf56.ietf.org: no - owner. - - - - - This error is produced when a line in the master file - contains leading white space (tab/space) but the is no - current record owner name to inherit the name from. Usually - this is the result of putting white space before a comment, - forgetting the "@" for the SOA record, or indenting the master - file. - - - - - - - - Why are my logs in GMT (UTC). - - - - - You are running chrooted (-t) and have not supplied local timezone - information in the chroot area. - - - FreeBSD: /etc/localtime - Solaris: /etc/TIMEZONE and /usr/share/lib/zoneinfo - OSF: /etc/zoneinfo/localtime - - - See also tzset(3) and zic(8). - - - - - - - - I get rndc: connect failed: connection refused when - I try to run rndc. - - - - - This is usually a configuration error. - - - First ensure that named is running and no errors are being - reported at startup (/var/log/messages or equivalent). - Running "named -g <usual arguments>" from a title - can help at this point. - - - Secondly ensure that named is configured to use rndc either - by "rndc-confgen -a", rndc-confgen or manually. The - Administrators Reference manual has details on how to do - this. - - - Old versions of rndc-confgen used localhost rather than - 127.0.0.1 in /etc/rndc.conf for the default server. Update - /etc/rndc.conf if necessary so that the default server - listed in /etc/rndc.conf matches the addresses used in - named.conf. "localhost" has two address (127.0.0.1 and - ::1). - - - If you use "rndc-confgen -a" and named is running with -t or -u - ensure that /etc/rndc.conf has the correct ownership and that - a copy is in the chroot area. You can do this by re-running - "rndc-confgen -a" with appropriate -t and -u arguments. - - - - - - - - I get transfer of 'example.net/IN' from 192.168.4.12#53: - failed while receiving responses: permission denied error - messages. - - - - - These indicate a filesystem permission error preventing - named creating / renaming the temporary file. These will - usually also have other associated error messages like - - - -"dumping master file: sl/tmp-XXXX5il3sQ: open: permission denied" - - - Named needs write permission on the directory containing - the file. Named writes the new cache file to a temporary - file then renames it to the name specified in named.conf - to ensure that the contents are always complete. This is - to prevent named loading a partial zone in the event of - power failure or similar interrupting the write of the - master file. - - - Note file names are relative to the directory specified in - options and any chroot directory ([<chroot - dir>/][<options dir>]). - - - - If named is invoked as "named -t /chroot/DNS" with - the following named.conf then "/chroot/DNS/var/named/sl" - needs to be writable by the user named is running as. - - -options { - directory "/var/named"; -}; - -zone "example.net" { - type slave; - file "sl/example.net"; - masters { 192.168.4.12; }; -}; - - - - - - - - I want to forward all DNS queries from my caching nameserver to - another server. But there are some domains which have to be - served locally, via rbldnsd. - - - How do I achieve this ? - - - - -options { - forward only; - forwarders { <ip.of.primary.nameserver>; }; -}; - -zone "sbl-xbl.spamhaus.org" { - type forward; forward only; - forwarders { <ip.of.rbldns.server> port 530; }; -}; - -zone "list.dsbl.org" { - type forward; forward only; - forwarders { <ip.of.rbldns.server> port 530; }; -}; - - - - - - - - Can you help me understand how BIND 9 uses memory to store - DNS zones? - - - Some times it seems to take several times the amount of - memory it needs to store the zone. - - - - - When reloading a zone named my have multiple copies of - the zone in memory at one time. The zone it is serving - and the one it is loading. If reloads are ultra fast it - can have more still. - - - e.g. Ones that are transferring out, the one that it is - serving and the one that is loading. - - - BIND 8 destroyed the zone before loading and also killed - off outgoing transfers of the zone. - - - The new strategy allows slaves to get copies of the new - zone regardless of how often the master is loaded compared - to the transfer time. The slave might skip some intermediate - versions but the transfers will complete and it will keep - reasonably in sync with the master. - - - The new strategy also allows the master to recover from - syntax and other errors in the master file as it still - has an in-core copy of the old contents. - - - - - - - General Questions - - - - - I keep getting log messages like the following. Why? - - - Dec 4 23:47:59 client 10.0.0.1#1355: updating zone - 'example.com/IN': update failed: 'RRset exists (value - dependent)' prerequisite not satisfied (NXRRSET) - - - - - DNS updates allow the update request to test to see if - certain conditions are met prior to proceeding with the - update. The message above is saying that conditions were - not met and the update is not proceeding. See doc/rfc/rfc2136.txt - for more details on prerequisites. - - - - - - - - I keep getting log messages like the following. Why? - - - Jun 21 12:00:00.000 client 10.0.0.1#1234: update denied - - - - - Someone is trying to update your DNS data using the RFC2136 - Dynamic Update protocol. Windows 2000 machines have a habit - of sending dynamic update requests to DNS servers without - being specifically configured to do so. If the update - requests are coming from a Windows 2000 machine, see - - http://support.microsoft.com/support/kb/articles/q246/8/04.asp - - for information about how to turn them off. - - - - - - - - When I do a "dig . ns", many of the A records for the root - servers are missing. Why? - - - - - This is normal and harmless. It is a somewhat confusing - side effect of the way BIND 9 does RFC2181 trust ranking - and of the efforts BIND 9 makes to avoid promoting glue - into answers. - - - When BIND 9 first starts up and primes its cache, it receives - the root server addresses as additional data in an authoritative - response from a root server, and these records are eligible - for inclusion as additional data in responses. Subsequently - it receives a subset of the root server addresses as - additional data in a non-authoritative (referral) response - from a root server. This causes the addresses to now be - considered non-authoritative (glue) data, which is not - eligible for inclusion in responses. - - - The server does have a complete set of root server addresses - cached at all times, it just may not include all of them - as additional data, depending on whether they were last - received as answers or as glue. You can always look up the - addresses with explicit queries like "dig a.root-servers.net A". - - - - - - - - Why don't my zones reload when I do an "rndc reload" or SIGHUP? - - - - - A zone can be updated either by editing zone files and - reloading the server or by dynamic update, but not both. - If you have enabled dynamic update for a zone using the - "allow-update" option, you are not supposed to edit the - zone file by hand, and the server will not attempt to reload - it. - - - - - - - - Why is named listening on UDP port other than 53? - - - - - Named uses a system selected port to make queries of other - nameservers. This behaviour can be overridden by using - query-source to lock down the port and/or address. See - also notify-source and transfer-source. - - - - - - - - I get warning messages like zone example.com/IN: refresh: - failure trying master 1.2.3.4#53: timed out. - - - - - Check that you can make UDP queries from the slave to the master - - - -dig +norec example.com soa @1.2.3.4 - - - You could be generating queries faster than the slave can - cope with. Lower the serial query rate. - - - -serial-query-rate 5; // default 20 - - - - - - - - I don't get RRSIG's returned when I use "dig +dnssec". - - - - - You need to ensure DNSSEC is enabled (dnssec-enable yes;). - - - - - - - - Can a NS record refer to a CNAME. - - - - - No. The rules for glue (copies of the *address* records - in the parent zones) and additional section processing do - not allow it to work. - - - You would have to add both the CNAME and address records - (A/AAAA) as glue to the parent zone and have CNAMEs be - followed when doing additional section processing to make - it work. No nameserver implementation supports either of - these requirements. - - - - - - - - What does RFC 1918 response from Internet for - 0.0.0.10.IN-ADDR.ARPA mean? - - - - - If the IN-ADDR.ARPA name covered refers to a internal address - space you are using then you have failed to follow RFC 1918 - usage rules and are leaking queries to the Internet. You - should establish your own zones for these addresses to prevent - you querying the Internet's name servers for these addresses. - Please see http://as112.net/ - for details of the problems you are causing and the counter - measures that have had to be deployed. - - - If you are not using these private addresses then a client - has queried for them. You can just ignore the messages, - get the offending client to stop sending you these messages - as they are most probably leaking them or setup your own zones - empty zones to serve answers to these queries. - - - -zone "10.IN-ADDR.ARPA" { - type master; - file "empty"; -}; - -zone "16.172.IN-ADDR.ARPA" { - type master; - file "empty"; -}; - -... - -zone "31.172.IN-ADDR.ARPA" { - type master; - file "empty"; -}; - -zone "168.192.IN-ADDR.ARPA" { - type master; - file "empty"; -}; - -empty: -@ 10800 IN SOA <name-of-server>. <contact-email>. ( - 1 3600 1200 604800 10800 ) -@ 10800 IN NS <name-of-server>. - - - - Future versions of named are likely to do this automatically. - - - - - - - - - Will named be affected by the 2007 changes to daylight savings - rules in the US. - - - - - No, so long as the machines internal clock (as reported - by "date -u") remains at UTC. The only visible change - if you fail to upgrade your OS, if you are in a affected - area, will be that log messages will be a hour out during - the period where the old rules do not match the new rules. - - - For most OS's this change just means that you need to - update the conversion rules from UTC to local time. - Normally this involves updating a file in /etc (which - sets the default timezone for the machine) and possibly - a directory which has all the conversion rules for the - world (e.g. /usr/share/zoneinfo). When updating the OS - do not forget to update any chroot areas as well. - See your OS's documentation for more details. - - - The local timezone conversion rules can also be done on - a individual basis by setting the TZ environment variable - appropriately. See your OS's documentation for more - details. - - - - - - - - Is there a bugzilla (or other tool) database that mere - mortals can have (read-only) access to for bind? - - - - - No. The BIND 9 bug database is kept closed for a number - of reasons. These include, but are not limited to, that - the database contains proprietory information from people - reporting bugs. The database has in the past and may in - future contain unfixed bugs which are capable of bringing - down most of the Internet's DNS infrastructure. - - - The release pages for each version contain up to date - lists of bugs that have been fixed post release. That - is as close as we can get to providing a bug database. - - - - - - - Operating-System Specific Questions - - HPUX - - - - I get the following error trying to configure BIND: -checking if unistd.h or sys/types.h defines fd_set... no -configure: error: need either working unistd.h or sys/select.h - - - - - You have attempted to configure BIND with the bundled C compiler. - This compiler does not meet the minimum compiler requirements to - for building BIND. You need to install a ANSI C compiler and / or - teach configure how to find the ANSI C compiler. The later can - be done by adjusting the PATH environment variable and / or - specifying the compiler via CC. - - - ./configure CC=<compiler> ... - - - - - - - Linux - - - - - Why do I get the following errors: -general: errno2result.c:109: unexpected error: -general: unable to convert errno to isc_result: 14: Bad address -client: UDP client handler shutting down due to fatal receive error: unexpected error - - - - - This is the result of a Linux kernel bug. - - - See: - http://marc.theaimsgroup.com/?l=linux-netdev&m=113081708031466&w=2 - - - - - - - - Why do I see 5 (or more) copies of named on Linux? - - - - - Linux threads each show up as a process under ps. The - approximate number of threads running is n+4, where n is - the number of CPUs. Note that the amount of memory used - is not cumulative; if each process is using 10M of memory, - only a total of 10M is used. - - - Newer versions of Linux's ps command hide the individual threads - and require -L to display them. - - - - - - - - Why does BIND 9 log permission denied errors accessing - its configuration files or zones on my Linux system even - though it is running as root? - - - - - On Linux, BIND 9 drops most of its root privileges on - startup. This including the privilege to open files owned - by other users. Therefore, if the server is running as - root, the configuration files and zone files should also - be owned by root. - - - - - - - - I get the error message named: capset failed: Operation - not permitted when starting named. - - - - - The capability module, part of "Linux Security Modules/LSM", - has not been loaded into the kernel. See insmod(8). - - - - - - - - I'm running BIND on Red Hat Enterprise Linux or Fedora Core - - - - Why can't named update slave zone database files? - - - Why can't named create DDNS journal files or update - the master zones from journals? - - - Why can't named create custom log files? - - - - - - Red Hat Security Enhanced Linux (SELinux) policy security - protections : - - - - Red Hat have adopted the National Security Agency's - SELinux security policy ( see http://www.nsa.gov/selinux - ) and recommendations for BIND security , which are more - secure than running named in a chroot and make use of - the bind-chroot environment unnecessary . - - - - By default, named is not allowed by the SELinux policy - to write, create or delete any files EXCEPT in these - directories: - - -$ROOTDIR/var/named/slaves -$ROOTDIR/var/named/data -$ROOTDIR/var/tmp - - - where $ROOTDIR may be set in /etc/sysconfig/named if - bind-chroot is installed. - - - - The SELinux policy particularly does NOT allow named to modify - the $ROOTDIR/var/named directory, the default location for master - zone database files. - - - - SELinux policy overrules file access permissions - so - even if all the files under /var/named have ownership - named:named and mode rw-rw-r--, named will still not be - able to write or create files except in the directories - above, with SELinux in Enforcing mode. - - - - So, to allow named to update slave or DDNS zone files, - it is best to locate them in $ROOTDIR/var/named/slaves, - with named.conf zone statements such as: - - -zone "slave.zone." IN { - type slave; - file "slaves/slave.zone.db"; - ... -}; -zone "ddns.zone." IN { - type master; - allow-updates {...}; - file "slaves/ddns.zone.db"; -}; - - - - - - To allow named to create its cache dump and statistics - files, for example, you could use named.conf options - statements such as: - - -options { - ... - dump-file "/var/named/data/cache_dump.db"; - statistics-file "/var/named/data/named_stats.txt"; - ... -}; - - - - - - You can also tell SELinux to allow named to update any - zone database files, by setting the SELinux tunable boolean - parameter 'named_write_master_zones=1', using the - system-config-securitylevel GUI, using the 'setsebool' - command, or in /etc/selinux/targeted/booleans. - - - - You can disable SELinux protection for named entirely by - setting the 'named_disable_trans=1' SELinux tunable boolean - parameter. - - - - The SELinux named policy defines these SELinux contexts for named: - - -named_zone_t : for zone database files - $ROOTDIR/var/named/* -named_conf_t : for named configuration files - $ROOTDIR/etc/{named,rndc}.* -named_cache_t: for files modifiable by named - $ROOTDIR/var/{tmp,named/{slaves,data}} - - - - - - If you want to retain use of the SELinux policy for named, - and put named files in different locations, you can do - so by changing the context of the custom file locations - . - - - - To create a custom configuration file location, e.g. - '/root/named.conf', to use with the 'named -c' option, - do: - - -# chcon system_u:object_r:named_conf_t /root/named.conf - - - - - - To create a custom modifiable named data location, e.g. - '/var/log/named' for a log file, do: - - -# chcon system_u:object_r:named_cache_t /var/log/named - - - - - - To create a custom zone file location, e.g. /root/zones/, do: - - -# chcon system_u:object_r:named_zone_t /root/zones/{.,*} - - - - - - See these man-pages for more information : selinux(8), - named_selinux(8), chcon(1), setsebool(8) - - - - - - - Windows - - - - - Zone transfers from my BIND 9 master to my Windows 2000 - slave fail. Why? - - - - - This may be caused by a bug in the Windows 2000 DNS server - where DNS messages larger than 16K are not handled properly. - This can be worked around by setting the option "transfer-format - one-answer;". Also check whether your zone contains domain - names with embedded spaces or other special characters, - like "John\032Doe\213s\032Computer", since such names have - been known to cause Windows 2000 slaves to incorrectly - reject the zone. - - - - - - - - I get Error 1067 when starting named under Windows. - - - - - This is the service manager saying that named exited. You - need to examine the Application log in the EventViewer to - find out why. - - - Common causes are that you failed to create "named.conf" - (usually "C:\windows\dns\etc\named.conf") or failed to - specify the directory in named.conf. - - - -options { - Directory "C:\windows\dns\etc"; -}; - - - - - - - FreeBSD - - - - - I have FreeBSD 4.x and "rndc-confgen -a" just sits there. - - - - - /dev/random is not configured. Use rndcontrol(8) to tell - the kernel to use certain interrupts as a source of random - events. You can make this permanent by setting rand_irqs - in /etc/rc.conf. - - - -/etc/rc.conf -rand_irqs="3 14 15" - - - See also - - http://people.freebsd.org/~dougb/randomness.html - - - - - - - - Solaris - - - - - How do I integrate BIND 9 and Solaris SMF - - - - - Sun has a blog entry describing how to do this. - - - - http://blogs.sun.com/roller/page/anay/Weblog?catname=%2FSolaris - - - - - - - - - - -
diff --git a/contrib/bind9/Makefile.in b/contrib/bind9/Makefile.in deleted file mode 100644 index 9ff0f64..0000000 --- a/contrib/bind9/Makefile.in +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 1998-2002 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: Makefile.in,v 1.43.18.6 2007/09/03 23:46:21 tbox Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -@BIND9_VERSION@ - -SUBDIRS = make lib bin doc @LIBBIND@ -TARGETS = - -@BIND9_MAKE_RULES@ - -distclean:: - @if [ "X@LIBBIND@" = "X" ] ; then \ - i=lib/bind; \ - echo "making $@ in `pwd`/$$i"; \ - (cd $$i; ${MAKE} ${MAKEDEFS} $@) || exit 1; \ - fi - -distclean:: - rm -f config.cache config.h config.log config.status TAGS - rm -f libtool isc-config.sh configure.lineno - rm -f util/conf.sh docutil/docbook2man-wrapper.sh - -# XXX we should clean libtool stuff too. Only do this after we add rules -# to make it. -maintainer-clean:: - rm -f configure - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${bindir} \ - ${DESTDIR}${localstatedir}/run ${DESTDIR}${sysconfdir} - -install:: isc-config.sh installdirs - ${INSTALL_SCRIPT} isc-config.sh ${DESTDIR}${bindir} - -tags: - rm -f TAGS - find lib bin -name "*.[ch]" -print | @ETAGS@ - - -check: test - -test: - (cd bin/tests && ${MAKE} ${MAKEDEFS} test) - -FAQ: FAQ.xml - ${XSLTPROC} doc/xsl/isc-docbook-text.xsl FAQ.xml | \ - LC_ALL=C ${W3M} -T text/html -dump -cols 72 >$@.tmp - mv $@.tmp $@ - -clean:: - rm -f FAQ.tmp diff --git a/contrib/bind9/README b/contrib/bind9/README deleted file mode 100644 index 20fd84a..0000000 --- a/contrib/bind9/README +++ /dev/null @@ -1,601 +0,0 @@ -BIND 9 - - BIND version 9 is a major rewrite of nearly all aspects of the - underlying BIND architecture. Some of the important features of - BIND 9 are: - - - DNS Security - DNSSEC (signed zones) - TSIG (signed DNS requests) - - - IP version 6 - Answers DNS queries on IPv6 sockets - IPv6 resource records (AAAA) - Experimental IPv6 Resolver Library - - - DNS Protocol Enhancements - IXFR, DDNS, Notify, EDNS0 - Improved standards conformance - - - Views - One server process can provide multiple "views" of - the DNS namespace, e.g. an "inside" view to certain - clients, and an "outside" view to others. - - - Multiprocessor Support - - - Improved Portability Architecture - - - BIND version 9 development has been underwritten by the following - organizations: - - Sun Microsystems, Inc. - Hewlett Packard - Compaq Computer Corporation - IBM - Process Software Corporation - Silicon Graphics, Inc. - Network Associates, Inc. - U.S. Defense Information Systems Agency - USENIX Association - Stichting NLnet - NLnet Foundation - Nominum, Inc. - - -BIND 9.4.2 - - BIND 9.4.2 is a maintenance release, containing fixes for - a number of bugs in 9.4.1. - - Warning: If you installed BIND 9.4.2rc1 then any applications - linked against this release candidate will need to be rebuilt. - -BIND 9.4.1 - - BIND 9.4.1 is a security release, containing a fix for - a security bugs in 9.4.0. - -BIND 9.4.0 - - BIND 9.4.0 has a number of new features over 9.3, - including: - - Implemented "additional section caching" (or "acache"), an - internal cache framework for additional section content to - improve response performance. Several configuration options - were provided to control the behavior. - - New notify type 'master-only'. Enable notify for master - zones only. - - Accept 'notify-source' style syntax for query-source. - - rndc now allows addresses to be set in the server clauses. - - New option "allow-query-cache". This lets allow-query be - used to specify the default zone access level rather than - having to have every zone override the global value. - allow-query-cache can be set at both the options and view - levels. If allow-query-cache is not set then allow-recursion - is used if set, otherwise allow-query is used if set, otherwise - the default (localhost; localnets;) is used. - - rndc: the source address can now be specified. - - ixfr-from-differences now takes master and slave in addition - to yes and no at the options and view levels. - - Allow the journal's name to be changed via named.conf. - - 'rndc notify zone [class [view]]' resend the NOTIFY messages - for the specified zone. - - 'dig +trace' now randomly selects the next servers to try. - Report if there is a bad delegation. - - Improve check-names error messages. - - Make public the function to read a key file, dst_key_read_public(). - - dig now returns the byte count for axfr/ixfr. - - allow-update is now settable at the options / view level. - - named-checkconf now checks the logging configuration. - - host now can turn on memory debugging flags with '-m'. - - Don't send notify messages to self. - - Perform sanity checks on NS records which refer to 'in zone' names. - - New zone option "notify-delay". Specify a minimum delay - between sets of NOTIFY messages. - - Extend adjusting TTL warning messages. - - Named and named-checkzone can now both check for non-terminal - wildcard records. - - "rndc freeze/thaw" now freezes/thaws all zones. - - named-checkconf now check acls to verify that they only - refer to existing acls. - - The server syntax has been extended to support a range of - servers. - - Report differences between hints and real NS rrset and - associated address records. - - Preserve the case of domain names in rdata during zone - transfers. - - Restructured the data locking framework using architecture - dependent atomic operations (when available), improving - response performance on multi-processor machines significantly. - x86, x86_64, alpha, powerpc, and mips are currently supported. - - UNIX domain controls are now supported. - - Add support for additional zone file formats for improving - loading performance. The masterfile-format option in - named.conf can be used to specify a non-default format. A - separate command named-compilezone was provided to generate - zone files in the new format. Additionally, the -I and -O - options for dnssec-signzone specify the input and output - formats. - - dnssec-signzone can now randomize signature end times - (dnssec-signzone -j jitter). - - Add support for CH A record. - - Add additional zone data consistancy checks. named-checkzone - has extended checking of NS, MX and SRV record and the hosts - they reference. named has extended post zone load checks. - New zone options: check-mx and integrity-check. - - edns-udp-size can now be overridden on a per server basis. - - dig can now specify the EDNS version when making a query. - - Added framework for handling multiple EDNS versions. - - Additional memory debugging support to track size and mctx - arguments. - - Detect duplicates of UDP queries we are recursing on and - drop them. New stats category "duplicates". - - Memory management. "USE INTERNAL MALLOC" is now runtime selectable. - - The lame cache is now done on a basis - as some servers only appear to be lame for certain query - types. - - Limit the number of recursive clients that can be waiting - for a single query () to resolve. New - options clients-per-query and max-clients-per-query. - - dig: report the number of extra bytes still left in the - packet after processing all the records. - - Support for IPSECKEY rdata type. - - Raise the UDP receive buffer size to 32k if it is less than 32k. - - x86 and x86_64 now have separate atomic locking implementations. - - named-checkconf now validates update-policy entries. - - Attempt to make the amount of work performed in a iteration - self tuning. The covers nodes clean from the cache per - iteration, nodes written to disk when rewriting a master - file and nodes destroyed per iteration when destroying a - zone or a cache. - - ISC string copy API. - - Automatic empty zone creation for D.F.IP6.ARPA and friends. - Note: RFC 1918 zones are not yet covered by this but are - likely to be in a future release. - - New options: empty-server, empty-contact, empty-zones-enable - and disable-empty-zone. - - dig now has a '-q queryname' and '+showsearch' options. - - host/nslookup now continue (default)/fail on SERVFAIL. - - dig now warns if 'RA' is not set in the answer when 'RD' - was set in the query. host/nslookup skip servers that fail - to set 'RA' when 'RD' is set unless a server is explicitly - set. - - Integrate contributed DLZ code into named. - - Integrate contributed IDN code from JPNIC. - - Validate pending NS RRsets, in the authority section, prior - to returning them if it can be done without requiring DNSKEYs - to be fetched. - - It is now possible to configure named to accept expired - RRSIGs. Default "dnssec-accept-expired no;". Setting - "dnssec-accept-expired yes;" leaves named vulnerable to - replay attacks. - - Additional memory leakage checks. - - The maximum EDNS UDP response named will send can now be - set in named.conf (max-udp-size). This is independent of - the advertised receive buffer (edns-udp-size). - - Named now falls back to advertising EDNS with a 512 byte - receive buffer if the initial EDNS queries fail. - - Control the zeroing of the negative response TTL to a soa - query. Defaults "zero-no-soa-ttl yes;" and - "zero-no-soa-ttl-cache no;". - - Separate out MX and SRV to CNAME checks. - - dig/nslookup/host: warn about missing "QR". - - TSIG HMACSHA1, HMACSHA224, HMACSHA256, HMACSHA384 and - HMACSHA512 support. - - dnssec-signzone: output the SOA record as the first record - in the signed zone. - - Two new update policies. "selfsub" and "selfwild". - - dig, nslookup and host now advertise a 4096 byte EDNS UDP - buffer size by default. - - Report when a zone is removed. - - DS/DLV SHA256 digest algorithm support. - - Implement "rrset-order fixed". - - Check the KSK flag when updating a secure dynamic zone. - New zone option "update-check-ksk yes;". - - It is now possible to explicitly enable DNSSEC validation. - default dnssec-validation no; to be changed to yes in 9.5.0. - - It is now possible to enable/disable DNSSEC validation - from rndc. This is useful for the mobile hosts where the - current connection point breaks DNSSEC (firewall/proxy). - - rndc validation newstate [view] - - dnssec-signzone can now update the SOA record of the signed - zone, either as an increment or as the system time(). - - Statistics about acache now recorded and sent to log. - - libbind: corresponds to that from BIND 8.4.7. - -BIND 9.3.0 - - BIND 9.3.0 has a number of new features over 9.2, - including: - - DNSSEC is now DS based (RFC 3658). - See also RFC 3845, doc/draft/draft-ietf-dnsext-dnssec-*. - - DNSSEC lookaside validation. - - check-names is now implemented. - rrset-order in more complete. - - IPv4/IPv6 transition support, dual-stack-servers. - - IXFR deltas can now be generated when loading master files, - ixfr-from-differences. - - It is now possible to specify the size of a journal, max-journal-size. - - It is now possible to define a named set of master servers to be - used in masters clause, masters. - - The advertised EDNS UDP size can now be set, edns-udp-size. - - allow-v6-synthesis has been obsoleted. - - NOTE: - * Zones containing MD and MF will now be rejected. - * dig, nslookup name. now report "Not Implemented" as - NOTIMP rather than NOTIMPL. This will have impact on scripts - that are looking for NOTIMPL. - - libbind: corresponds to that from BIND 8.4.5. - -BIND 9.2.0 - - BIND 9.2.0 has a number of new features over 9.1, - including: - - - The size of the cache can now be limited using the - "max-cache-size" option. - - - The server can now automatically convert RFC1886-style - recursive lookup requests into RFC2874-style lookups, - when enabled using the new option "allow-v6-synthesis". - This allows stub resolvers that support AAAA records - but not A6 record chains or binary labels to perform - lookups in domains that make use of these IPv6 DNS - features. - - - Performance has been improved. - - - The man pages now use the more portable "man" macros - rather than the "mandoc" macros, and are installed - by "make install". - - - The named.conf parser has been completely rewritten. - It now supports "include" directives in more - places such as inside "view" statements, and it no - longer has any reserved words. - - - The "rndc status" command is now implemented. - - - rndc can now be configured automatically. - - - A BIND 8 compatible stub resolver library is now - included in lib/bind. - - - OpenSSL has been removed from the distribution. This - means that to use DNSSEC, OpenSSL must be installed and - the --with-openssl option must be supplied to configure. - This does not apply to the use of TSIG, which does not - require OpenSSL. - - - The source distribution now builds on Windows NT/2000. - See win32utils/readme1.txt and win32utils/win32-build.txt - for details. - - This distribution also includes a new lightweight stub - resolver library and associated resolver daemon that fully - support forward and reverse lookups of both IPv4 and IPv6 - addresses. This library is considered experimental and - is not a complete replacement for the BIND 8 resolver library. - Applications that use the BIND 8 res_* functions to perform - DNS lookups or dynamic updates still need to be linked against - the BIND 8 libraries. For DNS lookups, they can also use the - new "getrrsetbyname()" API. - - BIND 9.2 is capable of acting as an authoritative server - for DNSSEC secured zones. This functionality is believed to - be stable and complete except for lacking support for - verifications involving wildcard records in secure zones. - - When acting as a caching server, BIND 9.2 can be configured - to perform DNSSEC secure resolution on behalf of its clients. - This part of the DNSSEC implementation is still considered - experimental. For detailed information about the state of the - DNSSEC implementation, see the file doc/misc/dnssec. - - There are a few known bugs: - - On some systems, IPv6 and IPv4 sockets interact in - unexpected ways. For details, see doc/misc/ipv6. - To reduce the impact of these problems, the server - no longer listens for requests on IPv6 addresses - by default. If you need to accept DNS queries over - IPv6, you must specify "listen-on-v6 { any; };" - in the named.conf options statement. - - FreeBSD prior to 4.2 (and 4.2 if running as non-root) - and OpenBSD prior to 2.8 log messages like - "fcntl(8, F_SETFL, 4): Inappropriate ioctl for device". - This is due to a bug in "/dev/random" and impacts the - server's DNSSEC support. - - OS X 10.1.4 (Darwin 5.4), OS X 10.1.5 (Darwin 5.5) and - OS X 10.2 (Darwin 6.0) reports errors like - "fcntl(3, F_SETFL, 4): Operation not supported by device". - This is due to a bug in "/dev/random" and impacts the - server's DNSSEC support. - - --with-libtool does not work on AIX. - - --with-libtool does not work on SunOS 4. configure - requires "printf" which is not available. - - A bug in the Windows 2000 DNS server can cause zone transfers - from a BIND 9 server to a W2K server to fail. For details, - see the "Zone Transfers" section in doc/misc/migration. - - For a detailed list of user-visible changes from - previous releases, see the CHANGES file. - - -Building - - BIND 9 currently requires a UNIX system with an ANSI C compiler, - basic POSIX support, and a 64 bit integer type. - - We've had successful builds and tests on the following systems: - - COMPAQ Tru64 UNIX 5.1B - FreeBSD 4.10, 5.2.1, 6.2 - HP-UX 11.11 - NetBSD 1.5 - Slackware Linux 8.1 - Solaris 8, 9, 9 (x86) - Windows NT/2000/XP/2003 - - Additionally, we have unverified reports of success building - previous versions of BIND 9 from users of the following systems: - - AIX 5L - SuSE Linux 7.0 - Slackware Linux 7.x, 8.0 - Red Hat Linux 7.1 - Debian GNU/Linux 2.2 and 3.0 - Mandrake 8.1 - OpenBSD 2.6, 2.8, 2.9, 3.1, 3.6, 3.8 - UnixWare 7.1.1 - HP-UX 10.20 - BSD/OS 4.2 - Mac OS X 10.1, 10.3.8 - - To build, just - - ./configure - make - - Do not use a parallel "make". - - Several environment variables that can be set before running - configure will affect compilation: - - CC - The C compiler to use. configure tries to figure - out the right one for supported systems. - - CFLAGS - C compiler flags. Defaults to include -g and/or -O2 - as supported by the compiler. - - STD_CINCLUDES - System header file directories. Can be used to specify - where add-on thread or IPv6 support is, for example. - Defaults to empty string. - - STD_CDEFINES - Any additional preprocessor symbols you want defined. - Defaults to empty string. - - Possible settings: - Change the default syslog facility of named/lwresd. - -DISC_FACILITY=LOG_LOCAL0 - Enable DNSSEC signature chasing support in dig. - -DDIG_SIGCHASE=1 (sets -DDIG_SIGCHASE_TD=1 and - -DDIG_SIGCHASE_BU=1) - Disable dropping queries from particular well known ports. - -DNS_CLIENT_DROPPORT=0 - Disable support for "rrset-order fixed". - -DDNS_RDATASET_FIXED=0 - - LDFLAGS - Linker flags. Defaults to empty string. - - The following need to be set when cross compiling. - - BUILD_CC - The native C compiler. - BUILD_CFLAGS (optional) - BUILD_CPPFLAGS (optional) - Possible Settings: - -DNEED_OPTARG=1 (optarg is not declared in ) - BUILD_LDFLAGS (optional) - BUILD_LIBS (optional) - - To build shared libraries, specify "--with-libtool" on the - configure command line. - - For the server to support DNSSEC, you need to build it - with crypto support. You must have OpenSSL 0.9.5a - or newer installed and specify "--with-openssl" on the - configure command line. If OpenSSL is installed under - a nonstandard prefix, you can tell configure where to - look for it using "--with-openssl=/prefix". - - To build libbind (the BIND 8 resolver library), specify - "--enable-libbind" on the configure command line. - - On some platforms, BIND 9 can be built with multithreading - support, allowing it to take advantage of multiple CPUs. - You can specify whether to build a multithreaded BIND 9 - by specifying "--enable-threads" or "--disable-threads" - on the configure command line. The default is operating - system dependent. - - If your operating system has integrated support for IPv6, it - will be used automatically. If you have installed KAME IPv6 - separately, use "--with-kame[=PATH]" to specify its location. - - "make install" will install "named" and the various BIND 9 libraries. - By default, installation is into /usr/local, but this can be changed - with the "--prefix" option when running "configure". - - You may specify the option "--sysconfdir" to set the directory - where configuration files like "named.conf" go by default, - and "--localstatedir" to set the default parent directory - of "run/named.pid". For backwards compatibility with BIND 8, - --sysconfdir defaults to "/etc" and --localstatedir defaults to - "/var" if no --prefix option is given. If there is a --prefix - option, sysconfdir defaults to "$prefix/etc" and localstatedir - defaults to "$prefix/var". - - To see additional configure options, run "configure --help". - Note that the help message does not reflect the BIND 8 - compatibility defaults for sysconfdir and localstatedir. - - If you're planning on making changes to the BIND 9 source, you - should also "make depend". If you're using Emacs, you might find - "make tags" helpful. - - If you need to re-run configure please run "make distclean" first. - This will ensure that all the option changes take. - - Building with gcc is not supported, unless gcc is the vendor's usual - compiler (e.g. the various BSD systems, Linux). - - Known compiler issues: - * gcc-3.2.1 and gcc-3.1.1 is known to cause problems with solaris-x86. - * gcc prior to gcc-3.2.3 ultrasparc generates incorrect code at -02. - * gcc-3.3.5 powerpc generates incorrect code at -02. - * Irix, MipsPRO 7.4.1m is known to cause problems. - - A limited test suite can be run with "make test". Many of - the tests require you to configure a set of virtual IP addresses - on your system, and some require Perl; see bin/tests/system/README - for details. - - -Documentation - - The BIND 9 Administrator Reference Manual is included with the - source distribution in DocBook XML and HTML format, in the - doc/arm directory. - - Some of the programs in the BIND 9 distribution have man pages - in their directories. In particular, the command line - options of "named" are documented in /bin/named/named.8. - There is now also a set of man pages for the lwres library. - - If you are upgrading from BIND 8, please read the migration - notes in doc/misc/migration. If you are upgrading from - BIND 4, read doc/misc/migration-4to9. - - Frequently asked questions and their answers can be found in - FAQ. - - -Bug Reports and Mailing Lists - - Bugs reports should be sent to - - bind9-bugs@isc.org - - To join the BIND Users mailing list, send mail to - - bind-users-request@isc.org - - archives of which can be found via - - http://www.isc.org/ops/lists/ - - If you're planning on making changes to the BIND 9 source - code, you might want to join the BIND Forum as a Worker. - This gives you access to the bind-workers@isc.org mailing - list and pre-release access to the code. - - http://www.isc.org/sw/guild/bf/ diff --git a/contrib/bind9/README.idnkit b/contrib/bind9/README.idnkit deleted file mode 100644 index 316f879..0000000 --- a/contrib/bind9/README.idnkit +++ /dev/null @@ -1,112 +0,0 @@ - - BIND-9 IDN patch - - Japan Network Information Center (JPNIC) - - -* What is this patch for? - -This patch adds internationalized domain name (IDN) support to BIND-9. -You'll get internationalized version of dig/host/nslookup commands. - - + internationalized dig/host/nslookup - dig/host/nslookup accepts non-ASCII domain names in the local - codeset (such as Shift JIS, Big5 or ISO8859-1) determined by - the locale information. The domain names are normalized and - converted to the encoding on the DNS protocol, and sent to DNS - servers. The replies are converted back to the local codeset - and displayed. - - -* Compilation & installation - -0. Prerequisite - -You have to build and install idnkit before building this patched version -of bind-9. - -1. Running configure script - -Run `configure' in the top directory. See `README' for the -configuration options. - -This patch adds the following 4 options to `configure'. You should -at least specify `--with-idn' option to enable IDN support. - - --with-idn[=IDN_PREFIX] - To enable IDN support, you have to specify `--with-idn' option. - The argument IDN_PREFIX is the install prefix of idnkit. If - IDN_PREFIX is omitted, PREFIX (derived from `--prefix=PREFIX') - is assumed. - - --with-libiconv[=LIBICONV_PREFIX] - Specify this option if idnkit you have installed links GNU - libiconv. The argument LIBICONV_PREFIX is install prefix of - GNU libiconv. If the argument is omitted, PREFIX (derived - from `--prefix=PREFIX') is assumed. - - `--with-libiconv' is shorthand option for GNU libiconv. - - --with-libiconv=/usr/local - - This is equivalent to: - - --with-iconv='-L/usr/local/lib -R/usr/local/lib -liconv' - - `--with-libiconv' assumes that your C compiler has `-R' - option, and that the option adds the specified run-time path - to an exacutable binary. If `-R' option of your compiler has - different meaning, or your compiler lacks the option, you - should use `--with-iconv' option instead. Binary command - without run-time path information might be unexecutable. - In that case, you would see an error message like: - - error in loading shared libraries: libiconv.so.2: cannot - open shared object file - - If both `--with-libiconv' and `--with-iconv' options are - specified, `--with-iconv' is prior to `--with-libiconv'. - - --with-iconv=ICONV_LIBSPEC - If your libc doens't provide iconv(), you need to specify the - library containing iconv() with this option. `ICONV_LIBSPEC' - is the argument(s) to `cc' or `ld' to link the library, for - example, `--with-iconv="-L/usr/local/lib -liconv"'. - You don't need to specify the header file directory for "iconv.h" - to the compiler, as it isn't included directly by bind-9 with - this patch. - - --with-idnlib=IDN_LIBSPEC - With this option, you can explicitly specify the argument(s) - to `cc' or `ld' to link the idnkit's library, `libidnkit'. If - this option is not specified, `-L${PREFIX}/lib -lidnkit' is - assumed, where ${PREFIX} is the installation prefix specified - with `--with-idn' option above. You may need to use this - option to specify extra argments, for example, - `--with-idnlib="-L/usr/local/lib -R/usr/local/lib -lidnkit"'. - -Please consult `README' for other configuration options. - -Note that if you want to specify some extra header file directories, -you should use the environment variable STD_CINCLUDES instead of -CFLAGS, as described in README. - -2. Compilation and installation - -After running "configure", just do - - make - make install - -for compiling and installing. - - -* Contact information - -Please see http//www.nic.ad.jp/en/idn/ for the latest news -about idnkit and this patch. - -Bug reports and comments on this kit should be sent to -mdnkit-bugs@nic.ad.jp and idn-cmt@nic.ad.jp, respectively. - -; $Id: README.idnkit,v 1.2.2.2 2005/09/12 02:12:08 marka Exp $ diff --git a/contrib/bind9/acconfig.h b/contrib/bind9/acconfig.h deleted file mode 100644 index e8f7d52..0000000 --- a/contrib/bind9/acconfig.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: acconfig.h,v 1.44.18.5 2005/04/29 00:15:20 marka Exp $ */ - -/*! \file */ - -/*** - *** This file is not to be included by any public header files, because - *** it does not get installed. - ***/ -@TOP@ - -/** define to `int' if doesn't define. */ -#undef ssize_t - -/** define on DEC OSF to enable 4.4BSD style sa_len support */ -#undef _SOCKADDR_LEN - -/** define if your system needs pthread_init() before using pthreads */ -#undef NEED_PTHREAD_INIT - -/** define if your system has sigwait() */ -#undef HAVE_SIGWAIT - -/** define if sigwait() is the UnixWare flavor */ -#undef HAVE_UNIXWARE_SIGWAIT - -/** define on Solaris to get sigwait() to work using pthreads semantics */ -#undef _POSIX_PTHREAD_SEMANTICS - -/** define if LinuxThreads is in use */ -#undef HAVE_LINUXTHREADS - -/** define if sysconf() is available */ -#undef HAVE_SYSCONF - -/** define if sysctlbyname() is available */ -#undef HAVE_SYSCTLBYNAME - -/** define if catgets() is available */ -#undef HAVE_CATGETS - -/** define if getifaddrs() exists */ -#undef HAVE_GETIFADDRS - -/** define if you have the NET_RT_IFLIST sysctl variable and sys/sysctl.h */ -#undef HAVE_IFLIST_SYSCTL - -/** define if chroot() is available */ -#undef HAVE_CHROOT - -/** define if tzset() is available */ -#undef HAVE_TZSET - -/** define if struct addrinfo exists */ -#undef HAVE_ADDRINFO - -/** define if getaddrinfo() exists */ -#undef HAVE_GETADDRINFO - -/** define if gai_strerror() exists */ -#undef HAVE_GAISTRERROR - -/** define if arc4random() exists */ -#undef HAVE_ARC4RANDOM - -/** - * define if pthread_setconcurrency() should be called to tell the - * OS how many threads we might want to run. - */ -#undef CALL_PTHREAD_SETCONCURRENCY - -/** define if IPv6 is not disabled */ -#undef WANT_IPV6 - -/** define if flockfile() is available */ -#undef HAVE_FLOCKFILE - -/** define if getc_unlocked() is available */ -#undef HAVE_GETCUNLOCKED - -/** Shut up warnings about sputaux in stdio.h on BSD/OS pre-4.1 */ -#undef SHUTUP_SPUTAUX -#ifdef SHUTUP_SPUTAUX -struct __sFILE; -extern __inline int __sputaux(int _c, struct __sFILE *_p); -#endif - -/** Shut up warnings about missing sigwait prototype on BSD/OS 4.0* */ -#undef SHUTUP_SIGWAIT -#ifdef SHUTUP_SIGWAIT -int sigwait(const unsigned int *set, int *sig); -#endif - -/** Shut up warnings from gcc -Wcast-qual on BSD/OS 4.1. */ -#undef SHUTUP_STDARG_CAST -#if defined(SHUTUP_STDARG_CAST) && defined(__GNUC__) -#include /** Grr. Must be included *every time*. */ -/** - * The silly continuation line is to keep configure from - * commenting out the #undef. - */ - -#undef \ - va_start -#define va_start(ap, last) \ - do { \ - union { const void *konst; long *var; } _u; \ - _u.konst = &(last); \ - ap = (va_list)(_u.var + __va_words(__typeof(last))); \ - } while (0) -#endif /** SHUTUP_STDARG_CAST && __GNUC__ */ - -/** define if the system has a random number generating device */ -#undef PATH_RANDOMDEV - -/** define if pthread_attr_getstacksize() is available */ -#undef HAVE_PTHREAD_ATTR_GETSTACKSIZE - -/** define if pthread_attr_setstacksize() is available */ -#undef HAVE_PTHREAD_ATTR_SETSTACKSIZE - -/** define if you have strerror in the C library. */ -#undef HAVE_STRERROR - -/** Define if you are running under Compaq TruCluster. */ -#undef HAVE_TRUCLUSTER - -/* Define if OpenSSL includes DSA support */ -#undef HAVE_OPENSSL_DSA - -/* Define to the length type used by the socket API (socklen_t, size_t, int). */ -#undef ISC_SOCKADDR_LEN_T - -/* Define if threads need PTHREAD_SCOPE_SYSTEM */ -#undef NEED_PTHREAD_SCOPE_SYSTEM diff --git a/contrib/bind9/bin/Makefile.in b/contrib/bind9/bin/Makefile.in deleted file mode 100644 index 2e29f94..0000000 --- a/contrib/bind9/bin/Makefile.in +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 1998-2001 Internet Software Consortium. -# -# Permission to use, copy, modify, and 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: Makefile.in,v 1.23 2004/03/05 04:57:10 marka Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -SUBDIRS = named rndc dig dnssec tests nsupdate check -TARGETS = - -@BIND9_MAKE_RULES@ diff --git a/contrib/bind9/bin/check/Makefile.in b/contrib/bind9/bin/check/Makefile.in deleted file mode 100644 index cd9ecf6..0000000 --- a/contrib/bind9/bin/check/Makefile.in +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 2000-2003 Internet Software Consortium. -# -# Permission to use, copy, modify, and 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: Makefile.in,v 1.24.18.6 2006/06/09 00:54:08 marka Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -@BIND9_VERSION@ - -@BIND9_MAKE_INCLUDES@ - -CINCLUDES = ${BIND9_INCLUDES} ${DNS_INCLUDES} ${ISCCFG_INCLUDES} \ - ${ISC_INCLUDES} - -CDEFINES = -DNAMED_CONFFILE=\"${sysconfdir}/named.conf\" -CWARNINGS = - -DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ -ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ -ISCLIBS = ../../lib/isc/libisc.@A@ -BIND9LIBS = ../../lib/bind9/libbind9.@A@ - -DNSDEPLIBS = ../../lib/dns/libdns.@A@ -ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ -ISCDEPLIBS = ../../lib/isc/libisc.@A@ -BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ - -LIBS = @LIBS@ - -SUBDIRS = - -# Alphabetically -TARGETS = named-checkconf@EXEEXT@ named-checkzone@EXEEXT@ - -# Alphabetically -SRCS = named-checkconf.c named-checkzone.c check-tool.c - -MANPAGES = named-checkconf.8 named-checkzone.8 - -HTMLPAGES = named-checkconf.html named-checkzone.html - -MANOBJS = ${MANPAGES} ${HTMLPAGES} - -@BIND9_MAKE_RULES@ - -named-checkconf.@O@: named-checkconf.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ - -DVERSION=\"${VERSION}\" \ - -c ${srcdir}/named-checkconf.c - -named-checkzone.@O@: named-checkzone.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ - -DVERSION=\"${VERSION}\" \ - -c ${srcdir}/named-checkzone.c - -named-checkconf@EXEEXT@: named-checkconf.@O@ check-tool.@O@ ${ISCDEPLIBS} \ - ${ISCCFGDEPLIBS} ${BIND9DEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ - named-checkconf.@O@ check-tool.@O@ ${BIND9LIBS} ${ISCCFGLIBS} \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} - -named-checkzone@EXEEXT@: named-checkzone.@O@ check-tool.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ - named-checkzone.@O@ check-tool.@O@ ${ISCCFGLIBS} ${DNSLIBS} \ - ${ISCLIBS} ${LIBS} - -doc man:: ${MANOBJS} - -docclean manclean maintainer-clean:: - rm -f ${MANOBJS} - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 - -install:: named-checkconf@EXEEXT@ named-checkzone@EXEEXT@ installdirs - ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named-checkconf@EXEEXT@ ${DESTDIR}${sbindir} - ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named-checkzone@EXEEXT@ ${DESTDIR}${sbindir} - (cd ${DESTDIR}${sbindir}; rm -f named-compilezone@EXEEXT@; ${LINK_PROGRAM} named-checkzone@EXEEXT@ named-compilezone@EXEEXT@) - for m in ${MANPAGES}; do ${INSTALL_DATA} ${srcdir}/$$m ${DESTDIR}${mandir}/man8; done - (cd ${DESTDIR}${mandir}/man8; rm -f named-compilezone.8; ${LINK_PROGRAM} named-checkzone.8 named-compilezone.8) - -clean distclean:: - rm -f ${TARGETS} r1.htm diff --git a/contrib/bind9/bin/check/check-tool.c b/contrib/bind9/bin/check/check-tool.c deleted file mode 100644 index 1f5f1cd..0000000 --- a/contrib/bind9/bin/check/check-tool.c +++ /dev/null @@ -1,543 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-2002 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: check-tool.c,v 1.10.18.18 2007/09/13 05:04:01 each Exp $ */ - -/*! \file */ - -#include - -#include - -#include "check-tool.h" -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef HAVE_ADDRINFO -#ifdef HAVE_GETADDRINFO -#ifdef HAVE_GAISTRERROR -#define USE_GETADDRINFO -#endif -#endif -#endif - -#define CHECK(r) \ - do { \ - result = (r); \ - if (result != ISC_R_SUCCESS) \ - goto cleanup; \ - } while (0) - -static const char *dbtype[] = { "rbt" }; - -int debug = 0; -isc_boolean_t nomerge = ISC_TRUE; -isc_boolean_t docheckmx = ISC_TRUE; -isc_boolean_t dochecksrv = ISC_TRUE; -isc_boolean_t docheckns = ISC_TRUE; -unsigned int zone_options = DNS_ZONEOPT_CHECKNS | - DNS_ZONEOPT_CHECKMX | - DNS_ZONEOPT_MANYERRORS | - DNS_ZONEOPT_CHECKNAMES | - DNS_ZONEOPT_CHECKINTEGRITY | - DNS_ZONEOPT_CHECKWILDCARD | - DNS_ZONEOPT_WARNMXCNAME | - DNS_ZONEOPT_WARNSRVCNAME; - -/* - * This needs to match the list in bin/named/log.c. - */ -static isc_logcategory_t categories[] = { - { "", 0 }, - { "client", 0 }, - { "network", 0 }, - { "update", 0 }, - { "queries", 0 }, - { "unmatched", 0 }, - { "update-security", 0 }, - { NULL, 0 } -}; - -static isc_boolean_t -checkns(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner, - dns_rdataset_t *a, dns_rdataset_t *aaaa) -{ -#ifdef USE_GETADDRINFO - dns_rdataset_t *rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - struct addrinfo hints, *ai, *cur; - char namebuf[DNS_NAME_FORMATSIZE + 1]; - char ownerbuf[DNS_NAME_FORMATSIZE]; - char addrbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123")]; - isc_boolean_t answer = ISC_TRUE; - isc_boolean_t match; - const char *type; - void *ptr = NULL; - int result; - - REQUIRE(a == NULL || !dns_rdataset_isassociated(a) || - a->type == dns_rdatatype_a); - REQUIRE(aaaa == NULL || !dns_rdataset_isassociated(aaaa) || - aaaa->type == dns_rdatatype_aaaa); - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_CANONNAME; - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - dns_name_format(name, namebuf, sizeof(namebuf) - 1); - /* - * Turn off search. - */ - if (dns_name_countlabels(name) > 1U) - strcat(namebuf, "."); - dns_name_format(owner, ownerbuf, sizeof(ownerbuf)); - - result = getaddrinfo(namebuf, NULL, &hints, &ai); - dns_name_format(name, namebuf, sizeof(namebuf) - 1); - switch (result) { - case 0: - /* - * Work around broken getaddrinfo() implementations that - * fail to set ai_canonname on first entry. - */ - cur = ai; - while (cur != NULL && cur->ai_canonname == NULL && - cur->ai_next != NULL) - cur = cur->ai_next; - if (cur != NULL && cur->ai_canonname != NULL && - strcasecmp(ai->ai_canonname, namebuf) != 0) { - dns_zone_log(zone, ISC_LOG_ERROR, - "%s/NS '%s' (out of zone) " - "is a CNAME (illegal)", - ownerbuf, namebuf); - /* XXX950 make fatal for 9.5.0 */ - /* answer = ISC_FALSE; */ - } - break; - case EAI_NONAME: -#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) - case EAI_NODATA: -#endif - dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' (out of zone) " - "has no addresses records (A or AAAA)", - ownerbuf, namebuf); - /* XXX950 make fatal for 9.5.0 */ - return (ISC_TRUE); - - default: - dns_zone_log(zone, ISC_LOG_WARNING, - "getaddrinfo(%s) failed: %s", - namebuf, gai_strerror(result)); - return (ISC_TRUE); - } - if (a == NULL || aaaa == NULL) - return (answer); - /* - * Check that all glue records really exist. - */ - if (!dns_rdataset_isassociated(a)) - goto checkaaaa; - result = dns_rdataset_first(a); - while (result == ISC_R_SUCCESS) { - dns_rdataset_current(a, &rdata); - match = ISC_FALSE; - for (cur = ai; cur != NULL; cur = cur->ai_next) { - if (cur->ai_family != AF_INET) - continue; - ptr = &((struct sockaddr_in *)(cur->ai_addr))->sin_addr; - if (memcmp(ptr, rdata.data, rdata.length) == 0) { - match = ISC_TRUE; - break; - } - } - if (!match) { - dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' " - "extra GLUE A record (%s)", - ownerbuf, namebuf, - inet_ntop(AF_INET, rdata.data, - addrbuf, sizeof(addrbuf))); - /* XXX950 make fatal for 9.5.0 */ - /* answer = ISC_FALSE; */ - } - dns_rdata_reset(&rdata); - result = dns_rdataset_next(a); - } - - checkaaaa: - if (!dns_rdataset_isassociated(aaaa)) - goto checkmissing; - result = dns_rdataset_first(aaaa); - while (result == ISC_R_SUCCESS) { - dns_rdataset_current(aaaa, &rdata); - match = ISC_FALSE; - for (cur = ai; cur != NULL; cur = cur->ai_next) { - if (cur->ai_family != AF_INET6) - continue; - ptr = &((struct sockaddr_in6 *)(cur->ai_addr))->sin6_addr; - if (memcmp(ptr, rdata.data, rdata.length) == 0) { - match = ISC_TRUE; - break; - } - } - if (!match) { - dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' " - "extra GLUE AAAA record (%s)", - ownerbuf, namebuf, - inet_ntop(AF_INET6, rdata.data, - addrbuf, sizeof(addrbuf))); - /* XXX950 make fatal for 9.5.0. */ - /* answer = ISC_FALSE; */ - } - dns_rdata_reset(&rdata); - result = dns_rdataset_next(aaaa); - } - - checkmissing: - /* - * Check that all addresses appear in the glue. - */ - for (cur = ai; cur != NULL; cur = cur->ai_next) { - switch (cur->ai_family) { - case AF_INET: - rdataset = a; - ptr = &((struct sockaddr_in *)(cur->ai_addr))->sin_addr; - type = "A"; - break; - case AF_INET6: - rdataset = aaaa; - ptr = &((struct sockaddr_in6 *)(cur->ai_addr))->sin6_addr; - type = "AAAA"; - break; - default: - continue; - } - match = ISC_FALSE; - if (dns_rdataset_isassociated(rdataset)) - result = dns_rdataset_first(rdataset); - else - result = ISC_R_FAILURE; - while (result == ISC_R_SUCCESS && !match) { - dns_rdataset_current(rdataset, &rdata); - if (memcmp(ptr, rdata.data, rdata.length) == 0) - match = ISC_TRUE; - dns_rdata_reset(&rdata); - result = dns_rdataset_next(rdataset); - } - if (!match) { - dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' " - "missing GLUE %s record (%s)", - ownerbuf, namebuf, type, - inet_ntop(cur->ai_family, ptr, - addrbuf, sizeof(addrbuf))); - /* XXX950 make fatal for 9.5.0. */ - /* answer = ISC_FALSE; */ - } - } - freeaddrinfo(ai); - return (answer); -#else - return (ISC_TRUE); -#endif -} - -static isc_boolean_t -checkmx(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) { -#ifdef USE_GETADDRINFO - struct addrinfo hints, *ai, *cur; - char namebuf[DNS_NAME_FORMATSIZE + 1]; - char ownerbuf[DNS_NAME_FORMATSIZE]; - int result; - int level = ISC_LOG_ERROR; - isc_boolean_t answer = ISC_TRUE; - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_CANONNAME; - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - dns_name_format(name, namebuf, sizeof(namebuf) - 1); - /* - * Turn off search. - */ - if (dns_name_countlabels(name) > 1U) - strcat(namebuf, "."); - dns_name_format(owner, ownerbuf, sizeof(ownerbuf)); - - result = getaddrinfo(namebuf, NULL, &hints, &ai); - dns_name_format(name, namebuf, sizeof(namebuf) - 1); - switch (result) { - case 0: - /* - * Work around broken getaddrinfo() implementations that - * fail to set ai_canonname on first entry. - */ - cur = ai; - while (cur != NULL && cur->ai_canonname == NULL && - cur->ai_next != NULL) - cur = cur->ai_next; - if (cur != NULL && cur->ai_canonname != NULL && - strcasecmp(cur->ai_canonname, namebuf) != 0) { - if ((zone_options & DNS_ZONEOPT_WARNMXCNAME) != 0) - level = ISC_LOG_WARNING; - if ((zone_options & DNS_ZONEOPT_IGNOREMXCNAME) == 0) { - dns_zone_log(zone, ISC_LOG_WARNING, - "%s/MX '%s' (out of zone) " - "is a CNAME (illegal)", - ownerbuf, namebuf); - if (level == ISC_LOG_ERROR) - answer = ISC_FALSE; - } - } - freeaddrinfo(ai); - return (answer); - - case EAI_NONAME: -#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) - case EAI_NODATA: -#endif - dns_zone_log(zone, ISC_LOG_ERROR, "%s/MX '%s' (out of zone) " - "has no addresses records (A or AAAA)", - ownerbuf, namebuf); - /* XXX950 make fatal for 9.5.0. */ - return (ISC_TRUE); - - default: - dns_zone_log(zone, ISC_LOG_WARNING, - "getaddrinfo(%s) failed: %s", - namebuf, gai_strerror(result)); - return (ISC_TRUE); - } -#else - return (ISC_TRUE); -#endif -} - -static isc_boolean_t -checksrv(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) { -#ifdef USE_GETADDRINFO - struct addrinfo hints, *ai, *cur; - char namebuf[DNS_NAME_FORMATSIZE + 1]; - char ownerbuf[DNS_NAME_FORMATSIZE]; - int result; - int level = ISC_LOG_ERROR; - isc_boolean_t answer = ISC_TRUE; - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_CANONNAME; - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - dns_name_format(name, namebuf, sizeof(namebuf) - 1); - /* - * Turn off search. - */ - if (dns_name_countlabels(name) > 1U) - strcat(namebuf, "."); - dns_name_format(owner, ownerbuf, sizeof(ownerbuf)); - - result = getaddrinfo(namebuf, NULL, &hints, &ai); - dns_name_format(name, namebuf, sizeof(namebuf) - 1); - switch (result) { - case 0: - /* - * Work around broken getaddrinfo() implementations that - * fail to set ai_canonname on first entry. - */ - cur = ai; - while (cur != NULL && cur->ai_canonname == NULL && - cur->ai_next != NULL) - cur = cur->ai_next; - if (cur != NULL && cur->ai_canonname != NULL && - strcasecmp(cur->ai_canonname, namebuf) != 0) { - if ((zone_options & DNS_ZONEOPT_WARNSRVCNAME) != 0) - level = ISC_LOG_WARNING; - if ((zone_options & DNS_ZONEOPT_IGNORESRVCNAME) == 0) { - dns_zone_log(zone, level, - "%s/SRV '%s' (out of zone) " - "is a CNAME (illegal)", - ownerbuf, namebuf); - if (level == ISC_LOG_ERROR) - answer = ISC_FALSE; - } - } - freeaddrinfo(ai); - return (answer); - - case EAI_NONAME: -#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) - case EAI_NODATA: -#endif - dns_zone_log(zone, ISC_LOG_ERROR, "%s/SRV '%s' (out of zone) " - "has no addresses records (A or AAAA)", - ownerbuf, namebuf); - /* XXX950 make fatal for 9.5.0. */ - return (ISC_TRUE); - - default: - dns_zone_log(zone, ISC_LOG_WARNING, - "getaddrinfo(%s) failed: %s", - namebuf, gai_strerror(result)); - return (ISC_TRUE); - } -#else - return (ISC_TRUE); -#endif -} - -isc_result_t -setup_logging(isc_mem_t *mctx, isc_log_t **logp) { - isc_logdestination_t destination; - isc_logconfig_t *logconfig = NULL; - isc_log_t *log = NULL; - - RUNTIME_CHECK(isc_log_create(mctx, &log, &logconfig) == ISC_R_SUCCESS); - isc_log_registercategories(log, categories); - isc_log_setcontext(log); - dns_log_init(log); - dns_log_setcontext(log); - cfg_log_init(log); - - destination.file.stream = stdout; - destination.file.name = NULL; - destination.file.versions = ISC_LOG_ROLLNEVER; - destination.file.maximum_size = 0; - RUNTIME_CHECK(isc_log_createchannel(logconfig, "stderr", - ISC_LOG_TOFILEDESC, - ISC_LOG_DYNAMIC, - &destination, 0) == ISC_R_SUCCESS); - RUNTIME_CHECK(isc_log_usechannel(logconfig, "stderr", - NULL, NULL) == ISC_R_SUCCESS); - - *logp = log; - return (ISC_R_SUCCESS); -} - -/*% load the zone */ -isc_result_t -load_zone(isc_mem_t *mctx, const char *zonename, const char *filename, - dns_masterformat_t fileformat, const char *classname, - dns_zone_t **zonep) -{ - isc_result_t result; - dns_rdataclass_t rdclass; - isc_textregion_t region; - isc_buffer_t buffer; - dns_fixedname_t fixorigin; - dns_name_t *origin; - dns_zone_t *zone = NULL; - - REQUIRE(zonep == NULL || *zonep == NULL); - - if (debug) - fprintf(stderr, "loading \"%s\" from \"%s\" class \"%s\"\n", - zonename, filename, classname); - - CHECK(dns_zone_create(&zone, mctx)); - - dns_zone_settype(zone, dns_zone_master); - - isc_buffer_init(&buffer, zonename, strlen(zonename)); - isc_buffer_add(&buffer, strlen(zonename)); - dns_fixedname_init(&fixorigin); - origin = dns_fixedname_name(&fixorigin); - CHECK(dns_name_fromtext(origin, &buffer, dns_rootname, - ISC_FALSE, NULL)); - CHECK(dns_zone_setorigin(zone, origin)); - CHECK(dns_zone_setdbtype(zone, 1, (const char * const *) dbtype)); - CHECK(dns_zone_setfile2(zone, filename, fileformat)); - - DE_CONST(classname, region.base); - region.length = strlen(classname); - CHECK(dns_rdataclass_fromtext(&rdclass, ®ion)); - - dns_zone_setclass(zone, rdclass); - dns_zone_setoption(zone, zone_options, ISC_TRUE); - dns_zone_setoption(zone, DNS_ZONEOPT_NOMERGE, nomerge); - if (docheckmx) - dns_zone_setcheckmx(zone, checkmx); - if (docheckns) - dns_zone_setcheckns(zone, checkns); - if (dochecksrv) - dns_zone_setchecksrv(zone, checksrv); - - CHECK(dns_zone_load(zone)); - if (zonep != NULL) { - *zonep = zone; - zone = NULL; - } - - cleanup: - if (zone != NULL) - dns_zone_detach(&zone); - return (result); -} - -/*% 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) -{ - isc_result_t result; - FILE *output = stdout; - - if (debug) { - if (filename != NULL) - fprintf(stderr, "dumping \"%s\" to \"%s\"\n", - zonename, filename); - else - fprintf(stderr, "dumping \"%s\"\n", zonename); - } - - if (filename != NULL) { - result = isc_stdio_open(filename, "w+", &output); - - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "could not open output " - "file \"%s\" for writing\n", filename); - return (ISC_R_FAILURE); - } - } - - result = dns_zone_dumptostream2(zone, output, fileformat, style); - - if (filename != NULL) - (void)isc_stdio_close(output); - - return (result); -} diff --git a/contrib/bind9/bin/check/check-tool.h b/contrib/bind9/bin/check/check-tool.h deleted file mode 100644 index ef9017f..0000000 --- a/contrib/bind9/bin/check/check-tool.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-2002 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: check-tool.h,v 1.7.18.4 2005/06/20 01:19:25 marka Exp $ */ - -#ifndef CHECK_TOOL_H -#define CHECK_TOOL_H - -/*! \file */ - -#include -#include - -#include -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -setup_logging(isc_mem_t *mctx, isc_log_t **logp); - -isc_result_t -load_zone(isc_mem_t *mctx, const char *zonename, const char *filename, - dns_masterformat_t fileformat, const char *classname, - dns_zone_t **zonep); - -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); - -extern int debug; -extern isc_boolean_t nomerge; -extern isc_boolean_t docheckmx; -extern isc_boolean_t docheckns; -extern isc_boolean_t dochecksrv; -extern unsigned int zone_options; - -ISC_LANG_ENDDECLS - -#endif diff --git a/contrib/bind9/bin/check/named-checkconf.8 b/contrib/bind9/bin/check/named-checkconf.8 deleted file mode 100644 index 364e6b9..0000000 --- a/contrib/bind9/bin/check/named-checkconf.8 +++ /dev/null @@ -1,89 +0,0 @@ -.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") -.\" Copyright (C) 2000-2002 Internet Software Consortium. -.\" -.\" Permission to use, copy, modify, and 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: named-checkconf.8,v 1.16.18.13 2007/06/20 02:26:58 marka Exp $ -.\" -.hy 0 -.ad l -.\" Title: named\-checkconf -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.71.1 -.\" Date: June 14, 2000 -.\" Manual: BIND9 -.\" Source: BIND9 -.\" -.TH "NAMED\-CHECKCONF" "8" "June 14, 2000" "BIND9" "BIND9" -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.SH "NAME" -named\-checkconf \- named configuration file syntax checking tool -.SH "SYNOPSIS" -.HP 16 -\fBnamed\-checkconf\fR [\fB\-v\fR] [\fB\-j\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] {filename} [\fB\-z\fR] -.SH "DESCRIPTION" -.PP -\fBnamed\-checkconf\fR -checks the syntax, but not the semantics, of a named configuration file. -.SH "OPTIONS" -.PP -\-t \fIdirectory\fR -.RS 4 -Chroot to -\fIdirectory\fR -so that include directives in the configuration file are processed as if run by a similarly chrooted named. -.RE -.PP -\-v -.RS 4 -Print the version of the -\fBnamed\-checkconf\fR -program and exit. -.RE -.PP -\-z -.RS 4 -Perform a test load of all master zones found in -\fInamed.conf\fR. -.RE -.PP -\-j -.RS 4 -When loading a zonefile read the journal if it exists. -.RE -.PP -filename -.RS 4 -The name of the configuration file to be checked. If not specified, it defaults to -\fI/etc/named.conf\fR. -.RE -.SH "RETURN VALUES" -.PP -\fBnamed\-checkconf\fR -returns an exit status of 1 if errors were detected and 0 otherwise. -.SH "SEE ALSO" -.PP -\fBnamed\fR(8), -\fBnamed\-checkzone\fR(8), -BIND 9 Administrator Reference Manual. -.SH "AUTHOR" -.PP -Internet Systems Consortium -.SH "COPYRIGHT" -Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") -.br -Copyright \(co 2000\-2002 Internet Software Consortium. -.br diff --git a/contrib/bind9/bin/check/named-checkconf.c b/contrib/bind9/bin/check/named-checkconf.c deleted file mode 100644 index cc63153..0000000 --- a/contrib/bind9/bin/check/named-checkconf.c +++ /dev/null @@ -1,488 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: named-checkconf.c,v 1.28.18.14 2006/02/28 03:10:47 marka Exp $ */ - -/*! \file */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include - -#include "check-tool.h" - -isc_log_t *logc = NULL; - -#define CHECK(r)\ - do { \ - result = (r); \ - if (result != ISC_R_SUCCESS) \ - goto cleanup; \ - } while (0) - -/*% usage */ -static void -usage(void) { - fprintf(stderr, "usage: named-checkconf [-j] [-v] [-z] [-t directory] " - "[named.conf]\n"); - exit(1); -} - -/*% directory callback */ -static isc_result_t -directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) { - isc_result_t result; - const char *directory; - - REQUIRE(strcasecmp("directory", clausename) == 0); - - UNUSED(arg); - UNUSED(clausename); - - /* - * Change directory. - */ - directory = cfg_obj_asstring(obj); - result = isc_dir_chdir(directory); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(obj, logc, ISC_LOG_ERROR, - "change directory to '%s' failed: %s\n", - directory, isc_result_totext(result)); - return (result); - } - - return (ISC_R_SUCCESS); -} - -static isc_boolean_t -get_maps(const cfg_obj_t **maps, const char *name, const cfg_obj_t **obj) { - int i; - for (i = 0;; i++) { - if (maps[i] == NULL) - return (ISC_FALSE); - if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS) - return (ISC_TRUE); - } -} - -static isc_boolean_t -get_checknames(const cfg_obj_t **maps, const cfg_obj_t **obj) { - const cfg_listelt_t *element; - const cfg_obj_t *checknames; - const cfg_obj_t *type; - const cfg_obj_t *value; - isc_result_t result; - int i; - - for (i = 0;; i++) { - if (maps[i] == NULL) - return (ISC_FALSE); - checknames = NULL; - result = cfg_map_get(maps[i], "check-names", &checknames); - if (result != ISC_R_SUCCESS) - continue; - if (checknames != NULL && !cfg_obj_islist(checknames)) { - *obj = checknames; - return (ISC_TRUE); - } - for (element = cfg_list_first(checknames); - element != NULL; - element = cfg_list_next(element)) { - value = cfg_listelt_value(element); - type = cfg_tuple_get(value, "type"); - if (strcasecmp(cfg_obj_asstring(type), "master") != 0) - continue; - *obj = cfg_tuple_get(value, "mode"); - return (ISC_TRUE); - } - } -} - -static isc_result_t -config_get(const cfg_obj_t **maps, const char *name, const cfg_obj_t **obj) { - int i; - - for (i = 0;; i++) { - if (maps[i] == NULL) - return (ISC_R_NOTFOUND); - if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - } -} - -/*% configure the zone */ -static isc_result_t -configure_zone(const char *vclass, const char *view, - const cfg_obj_t *zconfig, const cfg_obj_t *vconfig, - const cfg_obj_t *config, isc_mem_t *mctx) -{ - int i = 0; - isc_result_t result; - const char *zclass; - const char *zname; - const char *zfile; - const cfg_obj_t *maps[4]; - const cfg_obj_t *zoptions = NULL; - const cfg_obj_t *classobj = NULL; - const cfg_obj_t *typeobj = NULL; - const cfg_obj_t *fileobj = NULL; - const cfg_obj_t *dbobj = NULL; - const cfg_obj_t *obj = NULL; - const cfg_obj_t *fmtobj = NULL; - dns_masterformat_t masterformat; - - zone_options = DNS_ZONEOPT_CHECKNS | DNS_ZONEOPT_MANYERRORS; - - zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); - classobj = cfg_tuple_get(zconfig, "class"); - if (!cfg_obj_isstring(classobj)) - zclass = vclass; - else - zclass = cfg_obj_asstring(classobj); - - zoptions = cfg_tuple_get(zconfig, "options"); - maps[i++] = zoptions; - if (vconfig != NULL) - maps[i++] = cfg_tuple_get(vconfig, "options"); - if (config != NULL) { - cfg_map_get(config, "options", &obj); - if (obj != NULL) - maps[i++] = obj; - } - maps[i++] = NULL; - - cfg_map_get(zoptions, "type", &typeobj); - if (typeobj == NULL) - return (ISC_R_FAILURE); - if (strcasecmp(cfg_obj_asstring(typeobj), "master") != 0) - return (ISC_R_SUCCESS); - cfg_map_get(zoptions, "database", &dbobj); - if (dbobj != NULL) - return (ISC_R_SUCCESS); - cfg_map_get(zoptions, "file", &fileobj); - if (fileobj == NULL) - return (ISC_R_FAILURE); - zfile = cfg_obj_asstring(fileobj); - - obj = NULL; - if (get_maps(maps, "check-mx", &obj)) { - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - zone_options |= DNS_ZONEOPT_CHECKMX; - zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; - } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { - zone_options |= DNS_ZONEOPT_CHECKMX; - zone_options |= DNS_ZONEOPT_CHECKMXFAIL; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - zone_options &= ~DNS_ZONEOPT_CHECKMX; - zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; - } else - INSIST(0); - } else { - zone_options |= DNS_ZONEOPT_CHECKMX; - zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; - } - - obj = NULL; - if (get_maps(maps, "check-integrity", &obj)) { - if (cfg_obj_asboolean(obj)) - zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; - else - zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY; - } - - obj = NULL; - if (get_maps(maps, "check-mx-cname", &obj)) { - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - zone_options |= DNS_ZONEOPT_WARNMXCNAME; - zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; - } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { - zone_options &= ~DNS_ZONEOPT_WARNMXCNAME; - zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - zone_options |= DNS_ZONEOPT_WARNMXCNAME; - zone_options |= DNS_ZONEOPT_IGNOREMXCNAME; - } else - INSIST(0); - } else { - zone_options |= DNS_ZONEOPT_WARNMXCNAME; - zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; - } - - obj = NULL; - if (get_maps(maps, "check-srv-cname", &obj)) { - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - zone_options |= DNS_ZONEOPT_WARNSRVCNAME; - zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; - } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { - zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME; - zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - zone_options |= DNS_ZONEOPT_WARNSRVCNAME; - zone_options |= DNS_ZONEOPT_IGNORESRVCNAME; - } else - INSIST(0); - } else { - zone_options |= DNS_ZONEOPT_WARNSRVCNAME; - zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; - } - - obj = NULL; - if (get_maps(maps, "check-sibling", &obj)) { - if (cfg_obj_asboolean(obj)) - zone_options |= DNS_ZONEOPT_CHECKSIBLING; - else - zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; - } - - obj = NULL; - if (get_checknames(maps, &obj)) { - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - zone_options |= DNS_ZONEOPT_CHECKNAMES; - zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; - } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { - zone_options |= DNS_ZONEOPT_CHECKNAMES; - zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - zone_options &= ~DNS_ZONEOPT_CHECKNAMES; - zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; - } else - INSIST(0); - } else { - zone_options |= DNS_ZONEOPT_CHECKNAMES; - zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL; - } - - masterformat = dns_masterformat_text; - fmtobj = NULL; - result = config_get(maps, "masterfile-format", &fmtobj); - if (result == ISC_R_SUCCESS) { - const char *masterformatstr = cfg_obj_asstring(fmtobj); - if (strcasecmp(masterformatstr, "text") == 0) - masterformat = dns_masterformat_text; - else if (strcasecmp(masterformatstr, "raw") == 0) - masterformat = dns_masterformat_raw; - else - INSIST(0); - } - - result = load_zone(mctx, zname, zfile, masterformat, zclass, NULL); - if (result != ISC_R_SUCCESS) - fprintf(stderr, "%s/%s/%s: %s\n", view, zname, zclass, - dns_result_totext(result)); - return(result); -} - -/*% configure a view */ -static isc_result_t -configure_view(const char *vclass, const char *view, const cfg_obj_t *config, - const cfg_obj_t *vconfig, isc_mem_t *mctx) -{ - const cfg_listelt_t *element; - const cfg_obj_t *voptions; - const cfg_obj_t *zonelist; - isc_result_t result = ISC_R_SUCCESS; - isc_result_t tresult; - - voptions = NULL; - if (vconfig != NULL) - voptions = cfg_tuple_get(vconfig, "options"); - - zonelist = NULL; - if (voptions != NULL) - (void)cfg_map_get(voptions, "zone", &zonelist); - else - (void)cfg_map_get(config, "zone", &zonelist); - - for (element = cfg_list_first(zonelist); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *zconfig = cfg_listelt_value(element); - tresult = configure_zone(vclass, view, zconfig, vconfig, - config, mctx); - if (tresult != ISC_R_SUCCESS) - result = tresult; - } - return (result); -} - - -/*% load zones from the configuration */ -static isc_result_t -load_zones_fromconfig(const cfg_obj_t *config, isc_mem_t *mctx) { - const cfg_listelt_t *element; - const cfg_obj_t *classobj; - const cfg_obj_t *views; - const cfg_obj_t *vconfig; - const char *vclass; - isc_result_t result = ISC_R_SUCCESS; - isc_result_t tresult; - - views = NULL; - - (void)cfg_map_get(config, "view", &views); - for (element = cfg_list_first(views); - element != NULL; - element = cfg_list_next(element)) - { - const char *vname; - - vclass = "IN"; - vconfig = cfg_listelt_value(element); - if (vconfig != NULL) { - classobj = cfg_tuple_get(vconfig, "class"); - if (cfg_obj_isstring(classobj)) - vclass = cfg_obj_asstring(classobj); - } - vname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name")); - tresult = configure_view(vclass, vname, config, vconfig, mctx); - if (tresult != ISC_R_SUCCESS) - result = tresult; - } - - if (views == NULL) { - tresult = configure_view("IN", "_default", config, NULL, mctx); - if (tresult != ISC_R_SUCCESS) - result = tresult; - } - return (result); -} - -/*% The main processing routine */ -int -main(int argc, char **argv) { - int c; - cfg_parser_t *parser = NULL; - cfg_obj_t *config = NULL; - const char *conffile = NULL; - isc_mem_t *mctx = NULL; - isc_result_t result; - int exit_status = 0; - isc_entropy_t *ectx = NULL; - isc_boolean_t load_zones = ISC_FALSE; - - while ((c = isc_commandline_parse(argc, argv, "djt:vz")) != EOF) { - switch (c) { - case 'd': - debug++; - break; - - case 'j': - nomerge = ISC_FALSE; - break; - - case 't': - result = isc_dir_chroot(isc_commandline_argument); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "isc_dir_chroot: %s\n", - isc_result_totext(result)); - exit(1); - } - result = isc_dir_chdir("/"); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "isc_dir_chdir: %s\n", - isc_result_totext(result)); - exit(1); - } - break; - - case 'v': - printf(VERSION "\n"); - exit(0); - - case 'z': - load_zones = ISC_TRUE; - docheckmx = ISC_FALSE; - docheckns = ISC_FALSE; - dochecksrv = ISC_FALSE; - break; - - default: - usage(); - } - } - - if (argv[isc_commandline_index] != NULL) - conffile = argv[isc_commandline_index]; - if (conffile == NULL || conffile[0] == '\0') - conffile = NAMED_CONFFILE; - - RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); - - RUNTIME_CHECK(setup_logging(mctx, &logc) == ISC_R_SUCCESS); - - RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS); - RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE) - == ISC_R_SUCCESS); - - dns_result_register(); - - RUNTIME_CHECK(cfg_parser_create(mctx, logc, &parser) == ISC_R_SUCCESS); - - cfg_parser_setcallback(parser, directory_callback, NULL); - - if (cfg_parse_file(parser, conffile, &cfg_type_namedconf, &config) != - ISC_R_SUCCESS) - exit(1); - - result = bind9_check_namedconf(config, logc, mctx); - if (result != ISC_R_SUCCESS) - exit_status = 1; - - if (result == ISC_R_SUCCESS && load_zones) { - result = load_zones_fromconfig(config, mctx); - if (result != ISC_R_SUCCESS) - exit_status = 1; - } - - cfg_obj_destroy(parser, &config); - - cfg_parser_destroy(&parser); - - dns_name_destroy(); - - isc_log_destroy(&logc); - - isc_hash_destroy(); - isc_entropy_detach(&ectx); - - isc_mem_destroy(&mctx); - - return (exit_status); -} diff --git a/contrib/bind9/bin/check/named-checkconf.docbook b/contrib/bind9/bin/check/named-checkconf.docbook deleted file mode 100644 index af7a73d..0000000 --- a/contrib/bind9/bin/check/named-checkconf.docbook +++ /dev/null @@ -1,161 +0,0 @@ -]> - - - - - - June 14, 2000 - - - - named-checkconf - 8 - BIND9 - - - - - 2004 - 2005 - 2007 - Internet Systems Consortium, Inc. ("ISC") - - - 2000 - 2001 - 2002 - Internet Software Consortium. - - - - - named-checkconf - named configuration file syntax checking tool - - - - - named-checkconf - - - - filename - - - - - - DESCRIPTION - named-checkconf - checks the syntax, but not the semantics, of a named - configuration file. - - - - - OPTIONS - - - - -t directory - - - Chroot to directory so that - include - directives in the configuration file are processed as if - run by a similarly chrooted named. - - - - - - -v - - - Print the version of the named-checkconf - program and exit. - - - - - - -z - - - Perform a test load of all master zones found in - named.conf. - - - - - - -j - - - When loading a zonefile read the journal if it exists. - - - - - - filename - - - The name of the configuration file to be checked. If not - specified, it defaults to /etc/named.conf. - - - - - - - - - - RETURN VALUES - named-checkconf - returns an exit status of 1 if - errors were detected and 0 otherwise. - - - - - SEE ALSO - - named8 - , - - named-checkzone8 - , - BIND 9 Administrator Reference Manual. - - - - - AUTHOR - Internet Systems Consortium - - - - diff --git a/contrib/bind9/bin/check/named-checkconf.html b/contrib/bind9/bin/check/named-checkconf.html deleted file mode 100644 index 910df0d..0000000 --- a/contrib/bind9/bin/check/named-checkconf.html +++ /dev/null @@ -1,92 +0,0 @@ - - - - - -named-checkconf - - -
-
-
-

Name

-

named-checkconf — named configuration file syntax checking tool

-
-
-

Synopsis

-

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

-
-
-

DESCRIPTION

-

named-checkconf - checks the syntax, but not the semantics, of a named - configuration file. -

-
-
-

OPTIONS

-
-
-t directory
-

- Chroot to directory so that - include - directives in the configuration file are processed as if - run by a similarly chrooted named. -

-
-v
-

- Print the version of the named-checkconf - program and exit. -

-
-z
-

- Perform a test load of all master zones found in - named.conf. -

-
-j
-

- When loading a zonefile read the journal if it exists. -

-
filename
-

- The name of the configuration file to be checked. If not - specified, it defaults to /etc/named.conf. -

-
-
-
-

RETURN VALUES

-

named-checkconf - returns an exit status of 1 if - errors were detected and 0 otherwise. -

-
-
-

SEE ALSO

-

named(8), - named-checkzone(8), - BIND 9 Administrator Reference Manual. -

-
-
-

AUTHOR

-

Internet Systems Consortium -

-
-
- diff --git a/contrib/bind9/bin/check/named-checkzone.8 b/contrib/bind9/bin/check/named-checkzone.8 deleted file mode 100644 index bd538ac..0000000 --- a/contrib/bind9/bin/check/named-checkzone.8 +++ /dev/null @@ -1,269 +0,0 @@ -.\" Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") -.\" Copyright (C) 2000-2002 Internet Software Consortium. -.\" -.\" Permission to use, copy, modify, and 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: named-checkzone.8,v 1.18.18.23 2007/06/20 02:26:58 marka Exp $ -.\" -.hy 0 -.ad l -.\" Title: named\-checkzone -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.71.1 -.\" Date: June 13, 2000 -.\" Manual: BIND9 -.\" Source: BIND9 -.\" -.TH "NAMED\-CHECKZONE" "8" "June 13, 2000" "BIND9" "BIND9" -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.SH "NAME" -named\-checkzone, named\-compilezone \- zone file validity checking or converting tool -.SH "SYNOPSIS" -.HP 16 -\fBnamed\-checkzone\fR [\fB\-d\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\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-S\ \fR\fB\fImode\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\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\-o\ \fR\fB\fIfilename\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {zonename} {filename} -.SH "DESCRIPTION" -.PP -\fBnamed\-checkzone\fR -checks the syntax and integrity of a zone file. It performs the same checks as -\fBnamed\fR -does when loading a zone. This makes -\fBnamed\-checkzone\fR -useful for checking zone files before configuring them into a name server. -.PP -\fBnamed\-compilezone\fR -is similar to -\fBnamed\-checkzone\fR, but it always dumps the zone contents to a specified file in a specified format. Additionally, it applies stricter check levels by default, since the dump output will be used as an actual zone file loaded by -\fBnamed\fR. When manually specified otherwise, the check levels must at least be as strict as those specified in the -\fBnamed\fR -configuration file. -.SH "OPTIONS" -.PP -\-d -.RS 4 -Enable debugging. -.RE -.PP -\-q -.RS 4 -Quiet mode \- exit code only. -.RE -.PP -\-v -.RS 4 -Print the version of the -\fBnamed\-checkzone\fR -program and exit. -.RE -.PP -\-j -.RS 4 -When loading the zone file read the journal if it exists. -.RE -.PP -\-c \fIclass\fR -.RS 4 -Specify the class of the zone. If not specified "IN" is assumed. -.RE -.PP -\-i \fImode\fR -.RS 4 -Perform post\-load zone integrity checks. Possible modes are -\fB"full"\fR -(default), -\fB"full\-sibling"\fR, -\fB"local"\fR, -\fB"local\-sibling"\fR -and -\fB"none"\fR. -.sp -Mode -\fB"full"\fR -checks that MX records refer to A or AAAA record (both in\-zone and out\-of\-zone hostnames). Mode -\fB"local"\fR -only checks MX records which refer to in\-zone hostnames. -.sp -Mode -\fB"full"\fR -checks that SRV records refer to A or AAAA record (both in\-zone and out\-of\-zone hostnames). Mode -\fB"local"\fR -only checks SRV records which refer to in\-zone hostnames. -.sp -Mode -\fB"full"\fR -checks that delegation NS records refer to A or AAAA record (both in\-zone and out\-of\-zone hostnames). It also checks that glue address records in the zone match those advertised by the child. Mode -\fB"local"\fR -only checks NS records which refer to in\-zone hostnames or that some required glue exists, that is when the nameserver is in a child zone. -.sp -Mode -\fB"full\-sibling"\fR -and -\fB"local\-sibling"\fR -disable sibling glue checks but are otherwise the same as -\fB"full"\fR -and -\fB"local"\fR -respectively. -.sp -Mode -\fB"none"\fR -disables the checks. -.RE -.PP -\-f \fIformat\fR -.RS 4 -Specify the format of the zone file. Possible formats are -\fB"text"\fR -(default) and -\fB"raw"\fR. -.RE -.PP -\-F \fIformat\fR -.RS 4 -Specify the format of the output file specified. 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. -.RE -.PP -\-k \fImode\fR -.RS 4 -Perform -\fB"check\-names"\fR -checks with the specified failure mode. Possible modes are -\fB"fail"\fR -(default for -\fBnamed\-compilezone\fR), -\fB"warn"\fR -(default for -\fBnamed\-checkzone\fR) and -\fB"ignore"\fR. -.RE -.PP -\-m \fImode\fR -.RS 4 -Specify whether MX records should be checked to see if they are addresses. Possible modes are -\fB"fail"\fR, -\fB"warn"\fR -(default) and -\fB"ignore"\fR. -.RE -.PP -\-M \fImode\fR -.RS 4 -Check if a MX record refers to a CNAME. Possible modes are -\fB"fail"\fR, -\fB"warn"\fR -(default) and -\fB"ignore"\fR. -.RE -.PP -\-n \fImode\fR -.RS 4 -Specify whether NS records should be checked to see if they are addresses. Possible modes are -\fB"fail"\fR -(default for -\fBnamed\-compilezone\fR), -\fB"warn"\fR -(default for -\fBnamed\-checkzone\fR) and -\fB"ignore"\fR. -.RE -.PP -\-o \fIfilename\fR -.RS 4 -Write zone output to -\fIfilename\fR. This is mandatory for -\fBnamed\-compilezone\fR. -.RE -.PP -\-s \fIstyle\fR -.RS 4 -Specify the style of the dumped zone file. Possible styles are -\fB"full"\fR -(default) and -\fB"relative"\fR. The full format is most suitable for processing automatically by a separate script. On the other hand, the relative format is more human\-readable and is thus suitable for editing by hand. For -\fBnamed\-checkzone\fR -this does not cause any effects unless it dumps the zone contents. It also does not have any meaning if the output format is not text. -.RE -.PP -\-S \fImode\fR -.RS 4 -Check if a SRV record refers to a CNAME. Possible modes are -\fB"fail"\fR, -\fB"warn"\fR -(default) and -\fB"ignore"\fR. -.RE -.PP -\-t \fIdirectory\fR -.RS 4 -Chroot to -\fIdirectory\fR -so that include directives in the configuration file are processed as if run by a similarly chrooted named. -.RE -.PP -\-w \fIdirectory\fR -.RS 4 -chdir to -\fIdirectory\fR -so that relative filenames in master file $INCLUDE directives work. This is similar to the directory clause in -\fInamed.conf\fR. -.RE -.PP -\-D -.RS 4 -Dump zone file in canonical format. This is always enabled for -\fBnamed\-compilezone\fR. -.RE -.PP -\-W \fImode\fR -.RS 4 -Specify whether to check for non\-terminal wildcards. Non\-terminal wildcards are almost always the result of a failure to understand the wildcard matching algorithm (RFC 1034). Possible modes are -\fB"warn"\fR -(default) and -\fB"ignore"\fR. -.RE -.PP -zonename -.RS 4 -The domain name of the zone being checked. -.RE -.PP -filename -.RS 4 -The name of the zone file. -.RE -.SH "RETURN VALUES" -.PP -\fBnamed\-checkzone\fR -returns an exit status of 1 if errors were detected and 0 otherwise. -.SH "SEE ALSO" -.PP -\fBnamed\fR(8), -\fBnamed\-checkconf\fR(8), -RFC 1035, -BIND 9 Administrator Reference Manual. -.SH "AUTHOR" -.PP -Internet Systems Consortium -.SH "COPYRIGHT" -Copyright \(co 2004\-2007 Internet Systems Consortium, Inc. ("ISC") -.br -Copyright \(co 2000\-2002 Internet Software Consortium. -.br diff --git a/contrib/bind9/bin/check/named-checkzone.c b/contrib/bind9/bin/check/named-checkzone.c deleted file mode 100644 index 08e958e..0000000 --- a/contrib/bind9/bin/check/named-checkzone.c +++ /dev/null @@ -1,429 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-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: named-checkzone.c,v 1.29.18.19 2007/08/28 07:19:55 tbox Exp $ */ - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "check-tool.h" - -static int quiet = 0; -static isc_mem_t *mctx = NULL; -static isc_entropy_t *ectx = NULL; -dns_zone_t *zone = NULL; -dns_zonetype_t zonetype = dns_zone_master; -static int dumpzone = 0; -static const char *output_filename; -static char *prog_name = NULL; -static const dns_master_style_t *outputstyle = NULL; -static enum { progmode_check, progmode_compile } progmode; - -#define ERRRET(result, function) \ - do { \ - if (result != ISC_R_SUCCESS) { \ - if (!quiet) \ - fprintf(stderr, "%s() returned %s\n", \ - function, dns_result_totext(result)); \ - return (result); \ - } \ - } while (0) - -static void -usage(void) { - fprintf(stderr, - "usage: %s [-djqvD] [-c class] [-o output] " - "[-f inputformat] [-F outputformat] " - "[-t directory] [-w directory] [-k (ignore|warn|fail)] " - "[-n (ignore|warn|fail)] [-m (ignore|warn|fail)] " - "[-i (full|local|none)] [-M (ignore|warn|fail)] " - "[-S (ignore|warn|fail)] [-W (ignore|warn)] " - "zonename filename\n", prog_name); - exit(1); -} - -static void -destroy(void) { - if (zone != NULL) - dns_zone_detach(&zone); - dns_name_destroy(); -} - -/*% main processing routine */ -int -main(int argc, char **argv) { - int c; - char *origin = NULL; - char *filename = NULL; - isc_log_t *lctx = NULL; - isc_result_t result; - char classname_in[] = "IN"; - char *classname = classname_in; - const char *workdir = NULL; - const char *inputformatstr = NULL; - const char *outputformatstr = NULL; - dns_masterformat_t inputformat = dns_masterformat_text; - dns_masterformat_t outputformat = dns_masterformat_text; - - outputstyle = &dns_master_style_full; - - prog_name = strrchr(argv[0], '/'); - if (prog_name == NULL) - prog_name = strrchr(argv[0], '\\'); - if (prog_name != NULL) - prog_name++; - else - prog_name = argv[0]; - /* - * Libtool doesn't preserve the program name prior to final - * installation. Remove the libtool prefix ("lt-"). - */ - if (strncmp(prog_name, "lt-", 3) == 0) - prog_name += 3; - if (strcmp(prog_name, "named-checkzone") == 0) - progmode = progmode_check; - else if (strcmp(prog_name, "named-compilezone") == 0) - progmode = progmode_compile; - else - INSIST(0); - - /* Compilation specific defaults */ - if (progmode == progmode_compile) { - zone_options |= (DNS_ZONEOPT_CHECKNS | - DNS_ZONEOPT_FATALNS | - DNS_ZONEOPT_CHECKNAMES | - DNS_ZONEOPT_CHECKNAMESFAIL | - DNS_ZONEOPT_CHECKWILDCARD); - } - -#define ARGCMP(X) (strcmp(isc_commandline_argument, X) == 0) - - while ((c = isc_commandline_parse(argc, argv, - "c:df:i:jk:m:n:qs:t:o:vw:DF:M:S:W:")) - != EOF) { - switch (c) { - case 'c': - classname = isc_commandline_argument; - break; - - case 'd': - debug++; - break; - - case 'i': - if (ARGCMP("full")) { - zone_options |= DNS_ZONEOPT_CHECKINTEGRITY | - DNS_ZONEOPT_CHECKSIBLING; - docheckmx = ISC_TRUE; - docheckns = ISC_TRUE; - dochecksrv = ISC_TRUE; - } else if (ARGCMP("full-sibling")) { - zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; - zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; - docheckmx = ISC_TRUE; - docheckns = ISC_TRUE; - dochecksrv = ISC_TRUE; - } else if (ARGCMP("local")) { - zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; - zone_options |= DNS_ZONEOPT_CHECKSIBLING; - docheckmx = ISC_FALSE; - docheckns = ISC_FALSE; - dochecksrv = ISC_FALSE; - } else if (ARGCMP("local-sibling")) { - zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; - zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; - docheckmx = ISC_FALSE; - docheckns = ISC_FALSE; - dochecksrv = ISC_FALSE; - } else if (ARGCMP("none")) { - zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY; - zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; - docheckmx = ISC_FALSE; - docheckns = ISC_FALSE; - dochecksrv = ISC_FALSE; - } else { - fprintf(stderr, "invalid argument to -i: %s\n", - isc_commandline_argument); - exit(1); - } - break; - - case 'f': - inputformatstr = isc_commandline_argument; - break; - - case 'F': - outputformatstr = isc_commandline_argument; - break; - - case 'j': - nomerge = ISC_FALSE; - break; - - case 'k': - if (ARGCMP("warn")) { - zone_options |= DNS_ZONEOPT_CHECKNAMES; - zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; - } else if (ARGCMP("fail")) { - zone_options |= DNS_ZONEOPT_CHECKNAMES | - DNS_ZONEOPT_CHECKNAMESFAIL; - } else if (ARGCMP("ignore")) { - zone_options &= ~(DNS_ZONEOPT_CHECKNAMES | - DNS_ZONEOPT_CHECKNAMESFAIL); - } else { - fprintf(stderr, "invalid argument to -k: %s\n", - isc_commandline_argument); - exit(1); - } - break; - - case 'n': - if (ARGCMP("ignore")) { - zone_options &= ~(DNS_ZONEOPT_CHECKNS| - DNS_ZONEOPT_FATALNS); - } else if (ARGCMP("warn")) { - zone_options |= DNS_ZONEOPT_CHECKNS; - zone_options &= ~DNS_ZONEOPT_FATALNS; - } else if (ARGCMP("fail")) { - zone_options |= DNS_ZONEOPT_CHECKNS| - DNS_ZONEOPT_FATALNS; - } else { - fprintf(stderr, "invalid argument to -n: %s\n", - isc_commandline_argument); - exit(1); - } - break; - - case 'm': - if (ARGCMP("warn")) { - zone_options |= DNS_ZONEOPT_CHECKMX; - zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; - } else if (ARGCMP("fail")) { - zone_options |= DNS_ZONEOPT_CHECKMX | - DNS_ZONEOPT_CHECKMXFAIL; - } else if (ARGCMP("ignore")) { - zone_options &= ~(DNS_ZONEOPT_CHECKMX | - DNS_ZONEOPT_CHECKMXFAIL); - } else { - fprintf(stderr, "invalid argument to -m: %s\n", - isc_commandline_argument); - exit(1); - } - break; - - case 'q': - quiet++; - break; - - case 't': - result = isc_dir_chroot(isc_commandline_argument); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "isc_dir_chroot: %s: %s\n", - isc_commandline_argument, - isc_result_totext(result)); - exit(1); - } - result = isc_dir_chdir("/"); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "isc_dir_chdir: %s\n", - isc_result_totext(result)); - exit(1); - } - break; - - case 's': - if (ARGCMP("full")) - outputstyle = &dns_master_style_full; - else if (ARGCMP("relative")) { - outputstyle = &dns_master_style_default; - } else { - fprintf(stderr, - "unknown or unsupported style: %s\n", - isc_commandline_argument); - exit(1); - } - break; - - case 'o': - output_filename = isc_commandline_argument; - break; - - case 'v': - printf(VERSION "\n"); - exit(0); - - case 'w': - workdir = isc_commandline_argument; - break; - - case 'D': - dumpzone++; - break; - - case 'M': - if (ARGCMP("fail")) { - zone_options &= ~DNS_ZONEOPT_WARNMXCNAME; - zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; - } else if (ARGCMP("warn")) { - zone_options |= DNS_ZONEOPT_WARNMXCNAME; - zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; - } else if (ARGCMP("ignore")) { - zone_options |= DNS_ZONEOPT_WARNMXCNAME; - zone_options |= DNS_ZONEOPT_IGNOREMXCNAME; - } else { - fprintf(stderr, "invalid argument to -M: %s\n", - isc_commandline_argument); - exit(1); - } - break; - - case 'S': - if (ARGCMP("fail")) { - zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME; - zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; - } else if (ARGCMP("warn")) { - zone_options |= DNS_ZONEOPT_WARNSRVCNAME; - zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; - } else if (ARGCMP("ignore")) { - zone_options |= DNS_ZONEOPT_WARNSRVCNAME; - zone_options |= DNS_ZONEOPT_IGNORESRVCNAME; - } else { - fprintf(stderr, "invalid argument to -S: %s\n", - isc_commandline_argument); - exit(1); - } - break; - - case 'W': - if (ARGCMP("warn")) - zone_options |= DNS_ZONEOPT_CHECKWILDCARD; - else if (ARGCMP("ignore")) - zone_options &= ~DNS_ZONEOPT_CHECKWILDCARD; - break; - - default: - usage(); - } - } - - if (progmode == progmode_compile) { - dumpzone = 1; /* always dump */ - if (output_filename == NULL) { - fprintf(stderr, - "output file required, but not specified\n"); - usage(); - } - } - - if (workdir != NULL) { - result = isc_dir_chdir(workdir); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "isc_dir_chdir: %s: %s\n", - workdir, isc_result_totext(result)); - exit(1); - } - } - - if (inputformatstr != NULL) { - if (strcasecmp(inputformatstr, "text") == 0) - inputformat = dns_masterformat_text; - else if (strcasecmp(inputformatstr, "raw") == 0) - inputformat = dns_masterformat_raw; - else { - fprintf(stderr, "unknown file format: %s\n", - inputformatstr); - exit(1); - } - } - - if (outputformatstr != NULL) { - if (strcasecmp(outputformatstr, "text") == 0) - outputformat = dns_masterformat_text; - else if (strcasecmp(outputformatstr, "raw") == 0) - outputformat = dns_masterformat_raw; - else { - fprintf(stderr, "unknown file format: %s\n", - outputformatstr); - exit(1); - } - } - - if (isc_commandline_index + 2 > argc) - usage(); - - RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); - if (!quiet) - RUNTIME_CHECK(setup_logging(mctx, &lctx) == ISC_R_SUCCESS); - RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS); - RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE) - == ISC_R_SUCCESS); - - dns_result_register(); - - origin = argv[isc_commandline_index++]; - filename = argv[isc_commandline_index++]; - result = load_zone(mctx, origin, filename, inputformat, classname, - &zone); - - if (result == ISC_R_SUCCESS && dumpzone) { - if (!quiet && progmode == progmode_compile) { - fprintf(stdout, "dump zone to %s...", output_filename); - fflush(stdout); - } - result = dump_zone(origin, zone, output_filename, - outputformat, outputstyle); - if (!quiet && progmode == progmode_compile) - fprintf(stdout, "done\n"); - } - - if (!quiet && result == ISC_R_SUCCESS) - fprintf(stdout, "OK\n"); - destroy(); - if (lctx != NULL) - isc_log_destroy(&lctx); - isc_hash_destroy(); - isc_entropy_detach(&ectx); - isc_mem_destroy(&mctx); - return ((result == ISC_R_SUCCESS) ? 0 : 1); -} diff --git a/contrib/bind9/bin/check/named-checkzone.docbook b/contrib/bind9/bin/check/named-checkzone.docbook deleted file mode 100644 index 11b85ef..0000000 --- a/contrib/bind9/bin/check/named-checkzone.docbook +++ /dev/null @@ -1,443 +0,0 @@ -]> - - - - - - June 13, 2000 - - - - named-checkzone - 8 - BIND9 - - - - - 2004 - 2005 - 2006 - 2007 - Internet Systems Consortium, Inc. ("ISC") - - - 2000 - 2001 - 2002 - Internet Software Consortium. - - - - - named-checkzone - named-compilezone - zone file validity checking or converting tool - - - - - named-checkzone - - - - - - - - - - - - - - - - - - - - zonename - filename - - - named-compilezone - - - - - - - - - - - - - - - - - - - zonename - filename - - - - - DESCRIPTION - named-checkzone - checks the syntax and integrity of a zone file. It performs the - same checks as named does when loading a - zone. This makes named-checkzone useful for - checking zone files before configuring them into a name server. - - - named-compilezone is similar to - named-checkzone, but it always dumps the - zone contents to a specified file in a specified format. - Additionally, it applies stricter check levels by default, - since the dump output will be used as an actual zone file - loaded by named. - When manually specified otherwise, the check levels must at - least be as strict as those specified in the - named configuration file. - - - - - OPTIONS - - - - -d - - - Enable debugging. - - - - - - -q - - - Quiet mode - exit code only. - - - - - - -v - - - Print the version of the named-checkzone - program and exit. - - - - - - -j - - - When loading the zone file read the journal if it exists. - - - - - - -c class - - - Specify the class of the zone. If not specified "IN" is assumed. - - - - - - -i mode - - - Perform post-load zone integrity checks. Possible modes are - "full" (default), - "full-sibling", - "local", - "local-sibling" and - "none". - - - Mode "full" checks that MX records - refer to A or AAAA record (both in-zone and out-of-zone - hostnames). Mode "local" only - checks MX records which refer to in-zone hostnames. - - - Mode "full" checks that SRV records - refer to A or AAAA record (both in-zone and out-of-zone - hostnames). Mode "local" only - checks SRV records which refer to in-zone hostnames. - - - Mode "full" checks that delegation NS - records refer to A or AAAA record (both in-zone and out-of-zone - hostnames). It also checks that glue address records - in the zone match those advertised by the child. - Mode "local" only checks NS records which - refer to in-zone hostnames or that some required glue exists, - that is when the nameserver is in a child zone. - - - Mode "full-sibling" and - "local-sibling" disable sibling glue - checks but are otherwise the same as "full" - and "local" respectively. - - - Mode "none" disables the checks. - - - - - - -f format - - - Specify the format of the zone file. - Possible formats are "text" (default) - 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. - - - - - - -k mode - - - Perform "check-names" checks with the - specified failure mode. - Possible modes are "fail" - (default for named-compilezone), - "warn" - (default for named-checkzone) and - "ignore". - - - - - - -m mode - - - Specify whether MX records should be checked to see if they - are addresses. Possible modes are "fail", - "warn" (default) and - "ignore". - - - - - - -M mode - - - Check if a MX record refers to a CNAME. - Possible modes are "fail", - "warn" (default) and - "ignore". - - - - - - -n mode - - - Specify whether NS records should be checked to see if they - are addresses. - Possible modes are "fail" - (default for named-compilezone), - "warn" - (default for named-checkzone) and - "ignore". - - - - - - -o filename - - - Write zone output to filename. - This is mandatory for named-compilezone. - - - - - - -s style - - - Specify the style of the dumped zone file. - Possible styles are "full" (default) - and "relative". - The full format is most suitable for processing - automatically by a separate script. - On the other hand, the relative format is more - human-readable and is thus suitable for editing by hand. - For named-checkzone - this does not cause any effects unless it dumps the zone - contents. - It also does not have any meaning if the output format - is not text. - - - - - - -S mode - - - Check if a SRV record refers to a CNAME. - Possible modes are "fail", - "warn" (default) and - "ignore". - - - - - - -t directory - - - Chroot to directory so that - include - directives in the configuration file are processed as if - run by a similarly chrooted named. - - - - - - -w directory - - - chdir to directory so that - relative - filenames in master file $INCLUDE directives work. This - is similar to the directory clause in - named.conf. - - - - - - -D - - - Dump zone file in canonical format. - This is always enabled for named-compilezone. - - - - - - -W mode - - - Specify whether to check for non-terminal wildcards. - Non-terminal wildcards are almost always the result of a - failure to understand the wildcard matching algorithm (RFC 1034). - Possible modes are "warn" (default) - and - "ignore". - - - - - - zonename - - - The domain name of the zone being checked. - - - - - - filename - - - The name of the zone file. - - - - - - - - - - RETURN VALUES - named-checkzone - returns an exit status of 1 if - errors were detected and 0 otherwise. - - - - - SEE ALSO - - named8 - , - - named-checkconf8 - , - RFC 1035, - BIND 9 Administrator Reference Manual. - - - - - AUTHOR - Internet Systems Consortium - - - - diff --git a/contrib/bind9/bin/check/named-checkzone.html b/contrib/bind9/bin/check/named-checkzone.html deleted file mode 100644 index 0e1015d..0000000 --- a/contrib/bind9/bin/check/named-checkzone.html +++ /dev/null @@ -1,256 +0,0 @@ - - - - - -named-checkzone - - -
-
-
-

Name

-

named-checkzone, named-compilezone — zone file validity checking or converting tool

-
-
-

Synopsis

-

named-checkzone [-d] [-j] [-q] [-v] [-c class] [-f format] [-F format] [-i mode] [-k mode] [-m mode] [-M mode] [-n mode] [-o filename] [-s style] [-S mode] [-t directory] [-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] [-o filename] [-s style] [-t directory] [-w directory] [-D] [-W mode] {zonename} {filename}

-
-
-

DESCRIPTION

-

named-checkzone - checks the syntax and integrity of a zone file. It performs the - same checks as named does when loading a - zone. This makes named-checkzone useful for - checking zone files before configuring them into a name server. -

-

- named-compilezone is similar to - named-checkzone, but it always dumps the - zone contents to a specified file in a specified format. - Additionally, it applies stricter check levels by default, - since the dump output will be used as an actual zone file - loaded by named. - When manually specified otherwise, the check levels must at - least be as strict as those specified in the - named configuration file. -

-
-
-

OPTIONS

-
-
-d
-

- Enable debugging. -

-
-q
-

- Quiet mode - exit code only. -

-
-v
-

- Print the version of the named-checkzone - program and exit. -

-
-j
-

- When loading the zone file read the journal if it exists. -

-
-c class
-

- Specify the class of the zone. If not specified "IN" is assumed. -

-
-i mode
-
-

- Perform post-load zone integrity checks. Possible modes are - "full" (default), - "full-sibling", - "local", - "local-sibling" and - "none". -

-

- Mode "full" checks that MX records - refer to A or AAAA record (both in-zone and out-of-zone - hostnames). Mode "local" only - checks MX records which refer to in-zone hostnames. -

-

- Mode "full" checks that SRV records - refer to A or AAAA record (both in-zone and out-of-zone - hostnames). Mode "local" only - checks SRV records which refer to in-zone hostnames. -

-

- Mode "full" checks that delegation NS - records refer to A or AAAA record (both in-zone and out-of-zone - hostnames). It also checks that glue address records - in the zone match those advertised by the child. - Mode "local" only checks NS records which - refer to in-zone hostnames or that some required glue exists, - that is when the nameserver is in a child zone. -

-

- Mode "full-sibling" and - "local-sibling" disable sibling glue - checks but are otherwise the same as "full" - and "local" respectively. -

-

- Mode "none" disables the checks. -

-
-
-f format
-

- Specify the format of the zone file. - Possible formats are "text" (default) - 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. -

-
-k mode
-

- Perform "check-names" checks with the - specified failure mode. - Possible modes are "fail" - (default for named-compilezone), - "warn" - (default for named-checkzone) and - "ignore". -

-
-m mode
-

- Specify whether MX records should be checked to see if they - are addresses. Possible modes are "fail", - "warn" (default) and - "ignore". -

-
-M mode
-

- Check if a MX record refers to a CNAME. - Possible modes are "fail", - "warn" (default) and - "ignore". -

-
-n mode
-

- Specify whether NS records should be checked to see if they - are addresses. - Possible modes are "fail" - (default for named-compilezone), - "warn" - (default for named-checkzone) and - "ignore". -

-
-o filename
-

- Write zone output to filename. - This is mandatory for named-compilezone. -

-
-s style
-

- Specify the style of the dumped zone file. - Possible styles are "full" (default) - and "relative". - The full format is most suitable for processing - automatically by a separate script. - On the other hand, the relative format is more - human-readable and is thus suitable for editing by hand. - For named-checkzone - this does not cause any effects unless it dumps the zone - contents. - It also does not have any meaning if the output format - is not text. -

-
-S mode
-

- Check if a SRV record refers to a CNAME. - Possible modes are "fail", - "warn" (default) and - "ignore". -

-
-t directory
-

- Chroot to directory so that - include - directives in the configuration file are processed as if - run by a similarly chrooted named. -

-
-w directory
-

- chdir to directory so that - relative - filenames in master file $INCLUDE directives work. This - is similar to the directory clause in - named.conf. -

-
-D
-

- Dump zone file in canonical format. - This is always enabled for named-compilezone. -

-
-W mode
-

- Specify whether to check for non-terminal wildcards. - Non-terminal wildcards are almost always the result of a - failure to understand the wildcard matching algorithm (RFC 1034). - Possible modes are "warn" (default) - and - "ignore". -

-
zonename
-

- The domain name of the zone being checked. -

-
filename
-

- The name of the zone file. -

-
-
-
-

RETURN VALUES

-

named-checkzone - returns an exit status of 1 if - errors were detected and 0 otherwise. -

-
-
-

SEE ALSO

-

named(8), - named-checkconf(8), - RFC 1035, - BIND 9 Administrator Reference Manual. -

-
-
-

AUTHOR

-

Internet Systems Consortium -

-
-
- diff --git a/contrib/bind9/bin/dig/Makefile.in b/contrib/bind9/bin/dig/Makefile.in deleted file mode 100644 index 836b7f2..0000000 --- a/contrib/bind9/bin/dig/Makefile.in +++ /dev/null @@ -1,101 +0,0 @@ -# Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 2000-2002 Internet Software Consortium. -# -# Permission to use, copy, modify, and 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: Makefile.in,v 1.33.18.6 2005/09/09 14:11:04 marka Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -@BIND9_VERSION@ - -@BIND9_MAKE_INCLUDES@ - -CINCLUDES = -I${srcdir}/include ${DNS_INCLUDES} ${BIND9_INCLUDES} \ - ${ISC_INCLUDES} ${LWRES_INCLUDES} - -CDEFINES = -DVERSION=\"${VERSION}\" -CWARNINGS = - -ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ -DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ -BIND9LIBS = ../../lib/bind9/libbind9.@A@ -ISCLIBS = ../../lib/isc/libisc.@A@ -LWRESLIBS = ../../lib/lwres/liblwres.@A@ - -ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ -DNSDEPLIBS = ../../lib/dns/libdns.@A@ -BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ -ISCDEPLIBS = ../../lib/isc/libisc.@A@ -LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@ - -DEPLIBS = ${DNSDEPLIBS} ${BIND9DEPLIBS} ${ISCDEPLIBS} ${ISCCFGDEPLIBS} \ - ${LWRESDEPLIBS} - -LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCLIBS} \ - ${ISCCFGLIBS} @IDNLIBS@ @LIBS@ - -SUBDIRS = - -TARGETS = dig@EXEEXT@ host@EXEEXT@ nslookup@EXEEXT@ - -OBJS = dig.@O@ dighost.@O@ host.@O@ nslookup.@O@ - -UOBJS = - -SRCS = dig.c dighost.c host.c nslookup.c - -MANPAGES = dig.1 host.1 nslookup.1 - -HTMLPAGES = dig.html host.html nslookup.html - -MANOBJS = ${MANPAGES} ${HTMLPAGES} - -@BIND9_MAKE_RULES@ - -dig@EXEEXT@: dig.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ - dig.@O@ dighost.@O@ ${UOBJS} ${LIBS} - -host@EXEEXT@: host.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ - host.@O@ dighost.@O@ ${UOBJS} ${LIBS} - -nslookup@EXEEXT@: nslookup.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ - nslookup.@O@ dighost.@O@ ${UOBJS} ${LIBS} - -doc man:: ${MANOBJS} - -docclean manclean maintainer-clean:: - rm -f ${MANOBJS} - -clean distclean maintainer-clean:: - rm -f ${TARGETS} - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${bindir} - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man1 - -install:: dig@EXEEXT@ host@EXEEXT@ nslookup@EXEEXT@ installdirs - ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} \ - dig@EXEEXT@ ${DESTDIR}${bindir} - ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} \ - host@EXEEXT@ ${DESTDIR}${bindir} - ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} \ - nslookup@EXEEXT@ ${DESTDIR}${bindir} - for m in ${MANPAGES}; do \ - ${INSTALL_DATA} ${srcdir}/$$m ${DESTDIR}${mandir}/man1; \ - done diff --git a/contrib/bind9/bin/dig/dig.1 b/contrib/bind9/bin/dig/dig.1 deleted file mode 100644 index bf53280..0000000 --- a/contrib/bind9/bin/dig/dig.1 +++ /dev/null @@ -1,557 +0,0 @@ -.\" Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") -.\" Copyright (C) 2000-2003 Internet Software Consortium. -.\" -.\" Permission to use, copy, modify, and 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: dig.1,v 1.23.18.22 2007/05/16 06:11:27 marka Exp $ -.\" -.hy 0 -.ad l -.\" Title: dig -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.71.1 -.\" Date: Jun 30, 2000 -.\" Manual: BIND9 -.\" Source: BIND9 -.\" -.TH "DIG" "1" "Jun 30, 2000" "BIND9" "BIND9" -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.SH "NAME" -dig \- DNS lookup utility -.SH "SYNOPSIS" -.HP 4 -\fBdig\fR [@server] [\fB\-b\ \fR\fB\fIaddress\fR\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIfilename\fR\fR] [\fB\-k\ \fR\fB\fIfilename\fR\fR] [\fB\-p\ \fR\fB\fIport#\fR\fR] [\fB\-q\ \fR\fB\fIname\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-x\ \fR\fB\fIaddr\fR\fR] [\fB\-y\ \fR\fB\fI[hmac:]\fR\fIname:key\fR\fR] [\fB\-4\fR] [\fB\-6\fR] [name] [type] [class] [queryopt...] -.HP 4 -\fBdig\fR [\fB\-h\fR] -.HP 4 -\fBdig\fR [global\-queryopt...] [query...] -.SH "DESCRIPTION" -.PP -\fBdig\fR -(domain information groper) is a flexible tool for interrogating DNS name servers. It performs DNS lookups and displays the answers that are returned from the name server(s) that were queried. Most DNS administrators use -\fBdig\fR -to troubleshoot DNS problems because of its flexibility, ease of use and clarity of output. Other lookup tools tend to have less functionality than -\fBdig\fR. -.PP -Although -\fBdig\fR -is normally used with command\-line arguments, it also has a batch mode of operation for reading lookup requests from a file. A brief summary of its command\-line arguments and options is printed when the -\fB\-h\fR -option is given. Unlike earlier versions, the BIND 9 implementation of -\fBdig\fR -allows multiple lookups to be issued from the command line. -.PP -Unless it is told to query a specific name server, -\fBdig\fR -will try each of the servers listed in -\fI/etc/resolv.conf\fR. -.PP -When no command line arguments or options are given, will perform an NS query for "." (the root). -.PP -It is possible to set per\-user defaults for -\fBdig\fR -via -\fI${HOME}/.digrc\fR. This file is read and any options in it are applied before the command line arguments. -.PP -The IN and CH class names overlap with the IN and CH top level domains names. Either use the -\fB\-t\fR -and -\fB\-c\fR -options to specify the type and class or use the -\fB\-q\fR -the specify the domain name or use "IN." and "CH." when looking up these top level domains. -.SH "SIMPLE USAGE" -.PP -A typical invocation of -\fBdig\fR -looks like: -.sp -.RS 4 -.nf - dig @server name type -.fi -.RE -.sp -where: -.PP -\fBserver\fR -.RS 4 -is the name or IP address of the name server to query. This can be an IPv4 address in dotted\-decimal notation or an IPv6 address in colon\-delimited notation. When the supplied -\fIserver\fR -argument is a hostname, -\fBdig\fR -resolves that name before querying that name server. If no -\fIserver\fR -argument is provided, -\fBdig\fR -consults -\fI/etc/resolv.conf\fR -and queries the name servers listed there. The reply from the name server that responds is displayed. -.RE -.PP -\fBname\fR -.RS 4 -is the name of the resource record that is to be looked up. -.RE -.PP -\fBtype\fR -.RS 4 -indicates what type of query is required \(em ANY, A, MX, SIG, etc. -\fItype\fR -can be any valid query type. If no -\fItype\fR -argument is supplied, -\fBdig\fR -will perform a lookup for an A record. -.RE -.SH "OPTIONS" -.PP -The -\fB\-b\fR -option sets the source IP address of the query to -\fIaddress\fR. This must be a valid address on one of the host's network interfaces or "0.0.0.0" or "::". An optional port may be specified by appending "#" -.PP -The default query class (IN for internet) is overridden by the -\fB\-c\fR -option. -\fIclass\fR -is any valid class, such as HS for Hesiod records or CH for Chaosnet records. -.PP -The -\fB\-f\fR -option makes -\fBdig \fR -operate in batch mode by reading a list of lookup requests to process from the file -\fIfilename\fR. The file contains a number of queries, one per line. Each entry in the file should be organized in the same way they would be presented as queries to -\fBdig\fR -using the command\-line interface. -.PP -If a non\-standard port number is to be queried, the -\fB\-p\fR -option is used. -\fIport#\fR -is the port number that -\fBdig\fR -will send its queries instead of the standard DNS port number 53. This option would be used to test a name server that has been configured to listen for queries on a non\-standard port number. -.PP -The -\fB\-4\fR -option forces -\fBdig\fR -to only use IPv4 query transport. The -\fB\-6\fR -option forces -\fBdig\fR -to only use IPv6 query transport. -.PP -The -\fB\-t\fR -option sets the query type to -\fItype\fR. It can be any valid query type which is supported in BIND 9. The default query type is "A", unless the -\fB\-x\fR -option is supplied to indicate a reverse lookup. A zone transfer can be requested by specifying a type of AXFR. When an incremental zone transfer (IXFR) is required, -\fItype\fR -is set to -ixfr=N. The incremental zone transfer will contain the changes made to the zone since the serial number in the zone's SOA record was -\fIN\fR. -.PP -The -\fB\-q\fR -option sets the query name to -\fIname\fR. This useful do distinguish the -\fIname\fR -from other arguments. -.PP -Reverse lookups \(em mapping addresses to names \(em are simplified by the -\fB\-x\fR -option. -\fIaddr\fR -is an IPv4 address in dotted\-decimal notation, or a colon\-delimited IPv6 address. When this option is used, there is no need to provide the -\fIname\fR, -\fIclass\fR -and -\fItype\fR -arguments. -\fBdig\fR -automatically performs a lookup for a name like -11.12.13.10.in\-addr.arpa -and sets the query type and class to PTR and IN respectively. By default, IPv6 addresses are looked up using nibble format under the IP6.ARPA domain. To use the older RFC1886 method using the IP6.INT domain specify the -\fB\-i\fR -option. Bit string labels (RFC2874) are now experimental and are not attempted. -.PP -To sign the DNS queries sent by -\fBdig\fR -and their responses using transaction signatures (TSIG), specify a TSIG key file using the -\fB\-k\fR -option. You can also specify the TSIG key itself on the command line using the -\fB\-y\fR -option; -\fIhmac\fR -is the type of the TSIG, default HMAC\-MD5, -\fIname\fR -is the name of the TSIG key and -\fIkey\fR -is the actual key. The key is a base\-64 encoded string, typically generated by -\fBdnssec\-keygen\fR(8). Caution should be taken when using the -\fB\-y\fR -option on multi\-user systems as the key can be visible in the output from -\fBps\fR(1) -or in the shell's history file. When using TSIG authentication with -\fBdig\fR, the name server that is queried needs to know the key and algorithm that is being used. In BIND, this is done by providing appropriate -\fBkey\fR -and -\fBserver\fR -statements in -\fInamed.conf\fR. -.SH "QUERY OPTIONS" -.PP -\fBdig\fR -provides a number of query options which affect the way in which lookups are made and the results displayed. Some of these set or reset flag bits in the query header, some determine which sections of the answer get printed, and others determine the timeout and retry strategies. -.PP -Each query option is identified by a keyword preceded by a plus sign (+). Some keywords set or reset an option. These may be preceded by the string -no -to negate the meaning of that keyword. Other keywords assign values to options like the timeout interval. They have the form -\fB+keyword=value\fR. The query options are: -.PP -\fB+[no]tcp\fR -.RS 4 -Use [do not use] TCP when querying name servers. The default behavior is to use UDP unless an AXFR or IXFR query is requested, in which case a TCP connection is used. -.RE -.PP -\fB+[no]vc\fR -.RS 4 -Use [do not use] TCP when querying name servers. This alternate syntax to -\fI+[no]tcp\fR -is provided for backwards compatibility. The "vc" stands for "virtual circuit". -.RE -.PP -\fB+[no]ignore\fR -.RS 4 -Ignore truncation in UDP responses instead of retrying with TCP. By default, TCP retries are performed. -.RE -.PP -\fB+domain=somename\fR -.RS 4 -Set the search list to contain the single domain -\fIsomename\fR, as if specified in a -\fBdomain\fR -directive in -\fI/etc/resolv.conf\fR, and enable search list processing as if the -\fI+search\fR -option were given. -.RE -.PP -\fB+[no]search\fR -.RS 4 -Use [do not use] the search list defined by the searchlist or domain directive in -\fIresolv.conf\fR -(if any). The search list is not used by default. -.RE -.PP -\fB+[no]showsearch\fR -.RS 4 -Perform [do not perform] a search showing intermediate results. -.RE -.PP -\fB+[no]defname\fR -.RS 4 -Deprecated, treated as a synonym for -\fI+[no]search\fR -.RE -.PP -\fB+[no]aaonly\fR -.RS 4 -Sets the "aa" flag in the query. -.RE -.PP -\fB+[no]aaflag\fR -.RS 4 -A synonym for -\fI+[no]aaonly\fR. -.RE -.PP -\fB+[no]adflag\fR -.RS 4 -Set [do not set] the AD (authentic data) bit in the query. The AD bit currently has a standard meaning only in responses, not in queries, but the ability to set the bit in the query is provided for completeness. -.RE -.PP -\fB+[no]cdflag\fR -.RS 4 -Set [do not set] the CD (checking disabled) bit in the query. This requests the server to not perform DNSSEC validation of responses. -.RE -.PP -\fB+[no]cl\fR -.RS 4 -Display [do not display] the CLASS when printing the record. -.RE -.PP -\fB+[no]ttlid\fR -.RS 4 -Display [do not display] the TTL when printing the record. -.RE -.PP -\fB+[no]recurse\fR -.RS 4 -Toggle the setting of the RD (recursion desired) bit in the query. This bit is set by default, which means -\fBdig\fR -normally sends recursive queries. Recursion is automatically disabled when the -\fI+nssearch\fR -or -\fI+trace\fR -query options are used. -.RE -.PP -\fB+[no]nssearch\fR -.RS 4 -When this option is set, -\fBdig\fR -attempts to find the authoritative name servers for the zone containing the name being looked up and display the SOA record that each name server has for the zone. -.RE -.PP -\fB+[no]trace\fR -.RS 4 -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, -\fBdig\fR -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. -.RE -.PP -\fB+[no]cmd\fR -.RS 4 -Toggles the printing of the initial comment in the output identifying the version of -\fBdig\fR -and the query options that have been applied. This comment is printed by default. -.RE -.PP -\fB+[no]short\fR -.RS 4 -Provide a terse answer. The default is to print the answer in a verbose form. -.RE -.PP -\fB+[no]identify\fR -.RS 4 -Show [or do not show] the IP address and port number that supplied the answer when the -\fI+short\fR -option is enabled. If short form answers are requested, the default is not to show the source address and port number of the server that provided the answer. -.RE -.PP -\fB+[no]comments\fR -.RS 4 -Toggle the display of comment lines in the output. The default is to print comments. -.RE -.PP -\fB+[no]stats\fR -.RS 4 -This query option toggles the printing of statistics: when the query was made, the size of the reply and so on. The default behavior is to print the query statistics. -.RE -.PP -\fB+[no]qr\fR -.RS 4 -Print [do not print] the query as it is sent. By default, the query is not printed. -.RE -.PP -\fB+[no]question\fR -.RS 4 -Print [do not print] the question section of a query when an answer is returned. The default is to print the question section as a comment. -.RE -.PP -\fB+[no]answer\fR -.RS 4 -Display [do not display] the answer section of a reply. The default is to display it. -.RE -.PP -\fB+[no]authority\fR -.RS 4 -Display [do not display] the authority section of a reply. The default is to display it. -.RE -.PP -\fB+[no]additional\fR -.RS 4 -Display [do not display] the additional section of a reply. The default is to display it. -.RE -.PP -\fB+[no]all\fR -.RS 4 -Set or clear all display flags. -.RE -.PP -\fB+time=T\fR -.RS 4 -Sets the timeout for a query to -\fIT\fR -seconds. The default timeout is 5 seconds. An attempt to set -\fIT\fR -to less than 1 will result in a query timeout of 1 second being applied. -.RE -.PP -\fB+tries=T\fR -.RS 4 -Sets the number of times to try UDP queries to server to -\fIT\fR -instead of the default, 3. If -\fIT\fR -is less than or equal to zero, the number of tries is silently rounded up to 1. -.RE -.PP -\fB+retry=T\fR -.RS 4 -Sets the number of times to retry UDP queries to server to -\fIT\fR -instead of the default, 2. Unlike -\fI+tries\fR, this does not include the initial query. -.RE -.PP -\fB+ndots=D\fR -.RS 4 -Set the number of dots that have to appear in -\fIname\fR -to -\fID\fR -for it to be considered absolute. The default value is that defined using the ndots statement in -\fI/etc/resolv.conf\fR, or 1 if no ndots statement is present. Names with fewer dots are interpreted as relative names and will be searched for in the domains listed in the -\fBsearch\fR -or -\fBdomain\fR -directive in -\fI/etc/resolv.conf\fR. -.RE -.PP -\fB+bufsize=B\fR -.RS 4 -Set the UDP message buffer size advertised using EDNS0 to -\fIB\fR -bytes. The maximum and minimum sizes of this buffer are 65535 and 0 respectively. Values outside this range are rounded up or down appropriately. Values other than zero will cause a EDNS query to be sent. -.RE -.PP -\fB+edns=#\fR -.RS 4 -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. -\fB+noedns\fR -clears the remembered EDNS version. -.RE -.PP -\fB+[no]multiline\fR -.RS 4 -Print records like the SOA records in a verbose multi\-line format with human\-readable comments. The default is to print each record on a single line, to facilitate machine parsing of the -\fBdig\fR -output. -.RE -.PP -\fB+[no]fail\fR -.RS 4 -Do not try the next server if you receive a SERVFAIL. The default is to not try the next server which is the reverse of normal stub resolver behavior. -.RE -.PP -\fB+[no]besteffort\fR -.RS 4 -Attempt to display the contents of messages which are malformed. The default is to not display malformed answers. -.RE -.PP -\fB+[no]dnssec\fR -.RS 4 -Requests DNSSEC records be sent by setting the DNSSEC OK bit (DO) in the OPT record in the additional section of the query. -.RE -.PP -\fB+[no]sigchase\fR -.RS 4 -Chase DNSSEC signature chains. Requires dig be compiled with \-DDIG_SIGCHASE. -.RE -.PP -\fB+trusted\-key=####\fR -.RS 4 -Specifies a file containing trusted keys to be used with -\fB+sigchase\fR. Each DNSKEY record must be on its own line. -.sp -If not specified -\fBdig\fR -will look for -\fI/etc/trusted\-key.key\fR -then -\fItrusted\-key.key\fR -in the current directory. -.sp -Requires dig be compiled with \-DDIG_SIGCHASE. -.RE -.PP -\fB+[no]topdown\fR -.RS 4 -When chasing DNSSEC signature chains perform a top\-down validation. Requires dig be compiled with \-DDIG_SIGCHASE. -.RE -.SH "MULTIPLE QUERIES" -.PP -The BIND 9 implementation of -\fBdig \fR -supports specifying multiple queries on the command line (in addition to supporting the -\fB\-f\fR -batch file option). Each of those queries can be supplied with its own set of flags, options and query options. -.PP -In this case, each -\fIquery\fR -argument represent an individual query in the command\-line syntax described above. Each consists of any of the standard options and flags, the name to be looked up, an optional query type and class and any query options that should be applied to that query. -.PP -A global set of query options, which should be applied to all queries, can also be supplied. These global query options must precede the first tuple of name, class, type, options, flags, and query options supplied on the command line. Any global query options (except the -\fB+[no]cmd\fR -option) can be overridden by a query\-specific set of query options. For example: -.sp -.RS 4 -.nf -dig +qr www.isc.org any \-x 127.0.0.1 isc.org ns +noqr -.fi -.RE -.sp -shows how -\fBdig\fR -could be used from the command line to make three lookups: an ANY query for -www.isc.org, a reverse lookup of 127.0.0.1 and a query for the NS records of -isc.org. A global query option of -\fI+qr\fR -is applied, so that -\fBdig\fR -shows the initial query it made for each lookup. The final query has a local query option of -\fI+noqr\fR -which means that -\fBdig\fR -will not print the initial query when it looks up the NS records for -isc.org. -.SH "IDN SUPPORT" -.PP -If -\fBdig\fR -has been built with IDN (internationalized domain name) support, it can accept and display non\-ASCII domain names. -\fBdig\fR -appropriately converts character encoding of domain name before sending a request to DNS server or displaying a reply from the server. If you'd like to turn off the IDN support for some reason, defines the -\fBIDN_DISABLE\fR -environment variable. The IDN support is disabled if the variable is set when -\fBdig\fR -runs. -.SH "FILES" -.PP -\fI/etc/resolv.conf\fR -.PP -\fI${HOME}/.digrc\fR -.SH "SEE ALSO" -.PP -\fBhost\fR(1), -\fBnamed\fR(8), -\fBdnssec\-keygen\fR(8), -RFC1035. -.SH "BUGS" -.PP -There are probably too many query options. -.SH "COPYRIGHT" -Copyright \(co 2004\-2007 Internet Systems Consortium, Inc. ("ISC") -.br -Copyright \(co 2000\-2003 Internet Software Consortium. -.br diff --git a/contrib/bind9/bin/dig/dig.c b/contrib/bind9/bin/dig/dig.c deleted file mode 100644 index ba5d87b..0000000 --- a/contrib/bind9/bin/dig/dig.c +++ /dev/null @@ -1,1797 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-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: dig.c,v 1.186.18.29 2007/08/28 07:19:55 tbox Exp $ */ - -/*! \file */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#define ADD_STRING(b, s) { \ - if (strlen(s) >= isc_buffer_availablelength(b)) \ - return (ISC_R_NOSPACE); \ - else \ - isc_buffer_putstr(b, s); \ -} - -#define DIG_MAX_ADDRESSES 20 - -dig_lookup_t *default_lookup = NULL; - -static char *batchname = NULL; -static FILE *batchfp = NULL; -static char *argv0; -static int addresscount = 0; - -static char domainopt[DNS_NAME_MAXTEXT]; - -static isc_boolean_t short_form = ISC_FALSE, printcmd = ISC_TRUE, - ip6_int = ISC_FALSE, plusquest = ISC_FALSE, pluscomm = ISC_FALSE, - multiline = ISC_FALSE, nottl = ISC_FALSE, noclass = ISC_FALSE; - -/*% opcode text */ -static const char *opcodetext[] = { - "QUERY", - "IQUERY", - "STATUS", - "RESERVED3", - "NOTIFY", - "UPDATE", - "RESERVED6", - "RESERVED7", - "RESERVED8", - "RESERVED9", - "RESERVED10", - "RESERVED11", - "RESERVED12", - "RESERVED13", - "RESERVED14", - "RESERVED15" -}; - -/*% return code text */ -static const char *rcodetext[] = { - "NOERROR", - "FORMERR", - "SERVFAIL", - "NXDOMAIN", - "NOTIMP", - "REFUSED", - "YXDOMAIN", - "YXRRSET", - "NXRRSET", - "NOTAUTH", - "NOTZONE", - "RESERVED11", - "RESERVED12", - "RESERVED13", - "RESERVED14", - "RESERVED15", - "BADVERS" -}; - -/*% print usage */ -static void -print_usage(FILE *fp) { - fputs( -"Usage: dig [@global-server] [domain] [q-type] [q-class] {q-opt}\n" -" {global-d-opt} host [@local-server] {local-d-opt}\n" -" [ host [@local-server] {local-d-opt} [...]]\n", fp); -} - -static void -usage(void) { - print_usage(stderr); - fputs("\nUse \"dig -h\" (or \"dig -h | more\") " - "for complete list of options\n", stderr); - exit(1); -} - -/*% version */ -static void -version(void) { - fputs("DiG " VERSION "\n", stderr); -} - -/*% help */ -static void -help(void) { - print_usage(stdout); - fputs( -"Where: domain is in the Domain Name System\n" -" q-class is one of (in,hs,ch,...) [default: in]\n" -" q-type is one of (a,any,mx,ns,soa,hinfo,axfr,txt,...) [default:a]\n" -" (Use ixfr=version for type ixfr)\n" -" q-opt is one of:\n" -" -x dot-notation (shortcut for in-addr lookups)\n" -" -i (IP6.INT reverse IPv6 lookups)\n" -" -f filename (batch mode)\n" -" -b address[#port] (bind to source address/port)\n" -" -p port (specify port number)\n" -" -q name (specify query name)\n" -" -t type (specify query type)\n" -" -c class (specify query class)\n" -" -k keyfile (specify tsig key file)\n" -" -y [hmac:]name:key (specify named base64 tsig key)\n" -" -4 (use IPv4 query transport only)\n" -" -6 (use IPv6 query transport only)\n" -" d-opt is of the form +keyword[=value], where keyword is:\n" -" +[no]vc (TCP mode)\n" -" +[no]tcp (TCP mode, alternate syntax)\n" -" +time=### (Set query timeout) [5]\n" -" +tries=### (Set number of UDP attempts) [3]\n" -" +retry=### (Set number of UDP retries) [2]\n" -" +domain=### (Set default domainname)\n" -" +bufsize=### (Set EDNS0 Max UDP packet size)\n" -" +ndots=### (Set NDOTS value)\n" -" +edns=### (Set EDNS version)\n" -" +[no]search (Set whether to use searchlist)\n" -" +[no]showsearch (Search with intermediate results)\n" -" +[no]defname (Ditto)\n" -" +[no]recurse (Recursive mode)\n" -" +[no]ignore (Don't revert to TCP for TC responses.)" -"\n" -" +[no]fail (Don't try next server on SERVFAIL)\n" -" +[no]besteffort (Try to parse even illegal messages)\n" -" +[no]aaonly (Set AA flag in query (+[no]aaflag))\n" -" +[no]adflag (Set AD flag in query)\n" -" +[no]cdflag (Set CD flag in query)\n" -" +[no]cl (Control display of class in records)\n" -" +[no]cmd (Control display of command line)\n" -" +[no]comments (Control display of comment lines)\n" -" +[no]question (Control display of question)\n" -" +[no]answer (Control display of answer)\n" -" +[no]authority (Control display of authority)\n" -" +[no]additional (Control display of additional)\n" -" +[no]stats (Control display of statistics)\n" -" +[no]short (Disable everything except short\n" -" form of answer)\n" -" +[no]ttlid (Control display of ttls in records)\n" -" +[no]all (Set or clear all display flags)\n" -" +[no]qr (Print question before sending)\n" -" +[no]nssearch (Search all authoritative nameservers)\n" -" +[no]identify (ID responders in short answers)\n" -" +[no]trace (Trace delegation down from root)\n" -" +[no]dnssec (Request DNSSEC records)\n" -#ifdef DIG_SIGCHASE -" +[no]sigchase (Chase DNSSEC signatures)\n" -" +trusted-key=#### (Trusted Key when chasing DNSSEC sigs)\n" -#if DIG_SIGCHASE_TD -" +[no]topdown (Do DNSSEC validation top down mode)\n" -#endif -#endif -" +[no]multiline (Print records in an expanded format)\n" -" global d-opts and servers (before host name) affect all queries.\n" -" local d-opts and servers (after host name) affect only that lookup.\n" -" -h (print help and exit)\n" -" -v (print version and exit)\n", - stdout); -} - -/*% - * Callback from dighost.c to print the received message. - */ -void -received(int bytes, isc_sockaddr_t *from, dig_query_t *query) { - isc_uint64_t diff; - isc_time_t now; - time_t tnow; - char fromtext[ISC_SOCKADDR_FORMATSIZE]; - - isc_sockaddr_format(from, fromtext, sizeof(fromtext)); - - TIME_NOW(&now); - - if (query->lookup->stats && !short_form) { - diff = isc_time_microdiff(&now, &query->time_sent); - printf(";; Query time: %ld msec\n", (long int)diff/1000); - printf(";; SERVER: %s(%s)\n", fromtext, query->servname); - time(&tnow); - printf(";; WHEN: %s", ctime(&tnow)); - if (query->lookup->doing_xfr) { - printf(";; XFR size: %u records (messages %u, " - "bytes %" ISC_PRINT_QUADFORMAT "u)\n", - query->rr_count, query->msg_count, - query->byte_count); - } else { - printf(";; MSG SIZE rcvd: %u\n", bytes); - - } - if (key != NULL) { - if (!validated) - puts(";; WARNING -- Some TSIG could not " - "be validated"); - } - if ((key == NULL) && (keysecret[0] != 0)) { - puts(";; WARNING -- TSIG key was not used."); - } - puts(""); - } else if (query->lookup->identify && !short_form) { - diff = isc_time_microdiff(&now, &query->time_sent); - printf(";; Received %" ISC_PRINT_QUADFORMAT "u bytes " - "from %s(%s) in %d ms\n\n", - query->lookup->doing_xfr ? - query->byte_count : (isc_uint64_t)bytes, - fromtext, query->servname, - (int)diff/1000); - } -} - -/* - * Callback from dighost.c to print that it is trying a server. - * Not used in dig. - * XXX print_trying - */ -void -trying(char *frm, dig_lookup_t *lookup) { - UNUSED(frm); - UNUSED(lookup); -} - -/*% - * Internal print routine used to print short form replies. - */ -static isc_result_t -say_message(dns_rdata_t *rdata, dig_query_t *query, isc_buffer_t *buf) { - isc_result_t result; - isc_uint64_t diff; - isc_time_t now; - char store[sizeof("12345678901234567890")]; - - if (query->lookup->trace || query->lookup->ns_search_only) { - result = dns_rdatatype_totext(rdata->type, buf); - if (result != ISC_R_SUCCESS) - return (result); - ADD_STRING(buf, " "); - } - result = dns_rdata_totext(rdata, NULL, buf); - check_result(result, "dns_rdata_totext"); - if (query->lookup->identify) { - TIME_NOW(&now); - diff = isc_time_microdiff(&now, &query->time_sent); - ADD_STRING(buf, " from server "); - ADD_STRING(buf, query->servname); - snprintf(store, 19, " in %d ms.", (int)diff/1000); - ADD_STRING(buf, store); - } - ADD_STRING(buf, "\n"); - return (ISC_R_SUCCESS); -} - -/*% - * short_form message print handler. Calls above say_message() - */ -static isc_result_t -short_answer(dns_message_t *msg, dns_messagetextflag_t flags, - isc_buffer_t *buf, dig_query_t *query) -{ - dns_name_t *name; - dns_rdataset_t *rdataset; - isc_buffer_t target; - isc_result_t result, loopresult; - dns_name_t empty_name; - char t[4096]; - dns_rdata_t rdata = DNS_RDATA_INIT; - - UNUSED(flags); - - dns_name_init(&empty_name, NULL); - result = dns_message_firstname(msg, DNS_SECTION_ANSWER); - if (result == ISC_R_NOMORE) - return (ISC_R_SUCCESS); - else if (result != ISC_R_SUCCESS) - return (result); - - for (;;) { - name = NULL; - dns_message_currentname(msg, DNS_SECTION_ANSWER, &name); - - isc_buffer_init(&target, t, sizeof(t)); - - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - loopresult = dns_rdataset_first(rdataset); - while (loopresult == ISC_R_SUCCESS) { - dns_rdataset_current(rdataset, &rdata); - result = say_message(&rdata, query, - buf); - check_result(result, "say_message"); - loopresult = dns_rdataset_next(rdataset); - dns_rdata_reset(&rdata); - } - } - result = dns_message_nextname(msg, DNS_SECTION_ANSWER); - if (result == ISC_R_NOMORE) - break; - else if (result != ISC_R_SUCCESS) - return (result); - } - - return (ISC_R_SUCCESS); -} -#ifdef DIG_SIGCHASE -isc_result_t -printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset, - isc_buffer_t *target) -{ - isc_result_t result; - dns_master_style_t *style = NULL; - unsigned int styleflags = 0; - - if (rdataset == NULL || owner_name == NULL || target == NULL) - return(ISC_FALSE); - - styleflags |= DNS_STYLEFLAG_REL_OWNER; - if (nottl) - styleflags |= DNS_STYLEFLAG_NO_TTL; - if (noclass) - styleflags |= DNS_STYLEFLAG_NO_CLASS; - if (multiline) { - styleflags |= DNS_STYLEFLAG_OMIT_OWNER; - styleflags |= DNS_STYLEFLAG_OMIT_CLASS; - styleflags |= DNS_STYLEFLAG_REL_DATA; - styleflags |= DNS_STYLEFLAG_OMIT_TTL; - styleflags |= DNS_STYLEFLAG_TTL; - styleflags |= DNS_STYLEFLAG_MULTILINE; - styleflags |= DNS_STYLEFLAG_COMMENT; - } - if (multiline || (nottl && noclass)) - result = dns_master_stylecreate(&style, styleflags, - 24, 24, 24, 32, 80, 8, mctx); - else if (nottl || noclass) - result = dns_master_stylecreate(&style, styleflags, - 24, 24, 32, 40, 80, 8, mctx); - else - result = dns_master_stylecreate(&style, styleflags, - 24, 32, 40, 48, 80, 8, mctx); - check_result(result, "dns_master_stylecreate"); - - result = dns_master_rdatasettotext(owner_name, rdataset, style, target); - - if (style != NULL) - dns_master_styledestroy(&style, mctx); - - return(result); -} -#endif - -/* - * Callback from dighost.c to print the reply from a server - */ -isc_result_t -printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) { - isc_result_t result; - dns_messagetextflag_t flags; - isc_buffer_t *buf = NULL; - unsigned int len = OUTPUTBUF; - dns_master_style_t *style = NULL; - unsigned int styleflags = 0; - - styleflags |= DNS_STYLEFLAG_REL_OWNER; - if (nottl) - styleflags |= DNS_STYLEFLAG_NO_TTL; - if (noclass) - styleflags |= DNS_STYLEFLAG_NO_CLASS; - if (multiline) { - styleflags |= DNS_STYLEFLAG_OMIT_OWNER; - styleflags |= DNS_STYLEFLAG_OMIT_CLASS; - styleflags |= DNS_STYLEFLAG_REL_DATA; - styleflags |= DNS_STYLEFLAG_OMIT_TTL; - styleflags |= DNS_STYLEFLAG_TTL; - styleflags |= DNS_STYLEFLAG_MULTILINE; - styleflags |= DNS_STYLEFLAG_COMMENT; - } - if (multiline || (nottl && noclass)) - result = dns_master_stylecreate(&style, styleflags, - 24, 24, 24, 32, 80, 8, mctx); - else if (nottl || noclass) - result = dns_master_stylecreate(&style, styleflags, - 24, 24, 32, 40, 80, 8, mctx); - else - result = dns_master_stylecreate(&style, styleflags, - 24, 32, 40, 48, 80, 8, mctx); - check_result(result, "dns_master_stylecreate"); - - if (query->lookup->cmdline[0] != 0) { - if (!short_form) - fputs(query->lookup->cmdline, stdout); - query->lookup->cmdline[0]=0; - } - debug("printmessage(%s %s %s)", headers ? "headers" : "noheaders", - query->lookup->comments ? "comments" : "nocomments", - short_form ? "short_form" : "long_form"); - - flags = 0; - if (!headers) { - flags |= DNS_MESSAGETEXTFLAG_NOHEADERS; - flags |= DNS_MESSAGETEXTFLAG_NOCOMMENTS; - } - if (!query->lookup->comments) - flags |= DNS_MESSAGETEXTFLAG_NOCOMMENTS; - - result = ISC_R_SUCCESS; - - result = isc_buffer_allocate(mctx, &buf, len); - check_result(result, "isc_buffer_allocate"); - - if (query->lookup->comments && !short_form) { - if (query->lookup->cmdline[0] != 0) - printf("; %s\n", query->lookup->cmdline); - if (msg == query->lookup->sendmsg) - printf(";; Sending:\n"); - else - printf(";; Got answer:\n"); - - if (headers) { - printf(";; ->>HEADER<<- opcode: %s, status: %s, " - "id: %u\n", - opcodetext[msg->opcode], rcodetext[msg->rcode], - msg->id); - printf(";; flags:"); - if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) - printf(" qr"); - if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) - printf(" aa"); - if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) - printf(" tc"); - if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) - printf(" rd"); - if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) - printf(" ra"); - if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0) - printf(" ad"); - if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0) - printf(" cd"); - - printf("; QUERY: %u, ANSWER: %u, " - "AUTHORITY: %u, ADDITIONAL: %u\n", - msg->counts[DNS_SECTION_QUESTION], - msg->counts[DNS_SECTION_ANSWER], - msg->counts[DNS_SECTION_AUTHORITY], - msg->counts[DNS_SECTION_ADDITIONAL]); - - if (msg != query->lookup->sendmsg && - (msg->flags & DNS_MESSAGEFLAG_RD) != 0 && - (msg->flags & DNS_MESSAGEFLAG_RA) == 0) - printf(";; WARNING: recursion requested " - "but not available\n"); - } - if (msg != query->lookup->sendmsg && extrabytes != 0U) - printf(";; WARNING: Messages has %u extra byte%s at " - "end\n", extrabytes, extrabytes != 0 ? "s" : ""); - } - -repopulate_buffer: - - if (query->lookup->comments && headers && !short_form) { - result = dns_message_pseudosectiontotext(msg, - DNS_PSEUDOSECTION_OPT, - style, flags, buf); - if (result == ISC_R_NOSPACE) { -buftoosmall: - len += OUTPUTBUF; - isc_buffer_free(&buf); - result = isc_buffer_allocate(mctx, &buf, len); - if (result == ISC_R_SUCCESS) - goto repopulate_buffer; - else - goto cleanup; - } - check_result(result, - "dns_message_pseudosectiontotext"); - } - - if (query->lookup->section_question && headers) { - if (!short_form) { - result = dns_message_sectiontotext(msg, - DNS_SECTION_QUESTION, - style, flags, buf); - if (result == ISC_R_NOSPACE) - goto buftoosmall; - check_result(result, "dns_message_sectiontotext"); - } - } - if (query->lookup->section_answer) { - if (!short_form) { - result = dns_message_sectiontotext(msg, - DNS_SECTION_ANSWER, - style, flags, buf); - if (result == ISC_R_NOSPACE) - goto buftoosmall; - check_result(result, "dns_message_sectiontotext"); - } else { - result = short_answer(msg, flags, buf, query); - if (result == ISC_R_NOSPACE) - goto buftoosmall; - check_result(result, "short_answer"); - } - } - if (query->lookup->section_authority) { - if (!short_form) { - result = dns_message_sectiontotext(msg, - DNS_SECTION_AUTHORITY, - style, flags, buf); - if (result == ISC_R_NOSPACE) - goto buftoosmall; - check_result(result, "dns_message_sectiontotext"); - } - } - if (query->lookup->section_additional) { - if (!short_form) { - result = dns_message_sectiontotext(msg, - DNS_SECTION_ADDITIONAL, - style, flags, buf); - if (result == ISC_R_NOSPACE) - goto buftoosmall; - check_result(result, "dns_message_sectiontotext"); - /* - * Only print the signature on the first record. - */ - if (headers) { - result = dns_message_pseudosectiontotext( - msg, - DNS_PSEUDOSECTION_TSIG, - style, flags, buf); - if (result == ISC_R_NOSPACE) - goto buftoosmall; - check_result(result, - "dns_message_pseudosectiontotext"); - result = dns_message_pseudosectiontotext( - msg, - DNS_PSEUDOSECTION_SIG0, - style, flags, buf); - if (result == ISC_R_NOSPACE) - goto buftoosmall; - check_result(result, - "dns_message_pseudosectiontotext"); - } - } - } - - if (headers && query->lookup->comments && !short_form) - printf("\n"); - - printf("%.*s", (int)isc_buffer_usedlength(buf), - (char *)isc_buffer_base(buf)); - isc_buffer_free(&buf); - -cleanup: - if (style != NULL) - dns_master_styledestroy(&style, mctx); - return (result); -} - -/*% - * print the greeting message when the program first starts up. - */ -static void -printgreeting(int argc, char **argv, dig_lookup_t *lookup) { - int i; - int remaining; - static isc_boolean_t first = ISC_TRUE; - char append[MXNAME]; - - if (printcmd) { - lookup->cmdline[sizeof(lookup->cmdline) - 1] = 0; - snprintf(lookup->cmdline, sizeof(lookup->cmdline), - "%s; <<>> DiG " VERSION " <<>>", - first?"\n":""); - i = 1; - while (i < argc) { - snprintf(append, sizeof(append), " %s", argv[i++]); - remaining = sizeof(lookup->cmdline) - - strlen(lookup->cmdline) - 1; - strncat(lookup->cmdline, append, remaining); - } - remaining = sizeof(lookup->cmdline) - - strlen(lookup->cmdline) - 1; - strncat(lookup->cmdline, "\n", remaining); - if (first && addresscount != 0) { - snprintf(append, sizeof(append), - "; (%d server%s found)\n", - addresscount, - addresscount > 1 ? "s" : ""); - remaining = sizeof(lookup->cmdline) - - strlen(lookup->cmdline) - 1; - strncat(lookup->cmdline, append, remaining); - } - if (first) { - snprintf(append, sizeof(append), - ";; global options: %s %s\n", - short_form ? "short_form" : "", - printcmd ? "printcmd" : ""); - first = ISC_FALSE; - remaining = sizeof(lookup->cmdline) - - strlen(lookup->cmdline) - 1; - strncat(lookup->cmdline, append, remaining); - } - } -} - -static isc_uint32_t -parse_uint(char *arg, const char *desc, isc_uint32_t max) { - isc_result_t result; - isc_uint32_t tmp; - - result = isc_parse_uint32(&tmp, arg, 10); - if (result == ISC_R_SUCCESS && tmp > max) - result = ISC_R_RANGE; - if (result != ISC_R_SUCCESS) - fatal("%s '%s': %s", desc, arg, isc_result_totext(result)); - return (tmp); -} - -/*% - * We're not using isc_commandline_parse() here since the command line - * syntax of dig is quite a bit different from that which can be described - * by that routine. - * XXX doc options - */ - -static void -plus_option(char *option, isc_boolean_t is_batchfile, - dig_lookup_t *lookup) -{ - char option_store[256]; - char *cmd, *value, *ptr; - isc_boolean_t state = ISC_TRUE; -#ifdef DIG_SIGCHASE - size_t n; -#endif - - strncpy(option_store, option, sizeof(option_store)); - option_store[sizeof(option_store)-1]=0; - ptr = option_store; - cmd = next_token(&ptr,"="); - if (cmd == NULL) { - printf(";; Invalid option %s\n", option_store); - return; - } - value = ptr; - if (strncasecmp(cmd, "no", 2)==0) { - cmd += 2; - state = ISC_FALSE; - } - -#define FULLCHECK(A) \ - do { \ - size_t _l = strlen(cmd); \ - if (_l >= sizeof(A) || strncasecmp(cmd, A, _l) != 0) \ - goto invalid_option; \ - } while (0) -#define FULLCHECK2(A, B) \ - do { \ - size_t _l = strlen(cmd); \ - if ((_l >= sizeof(A) || strncasecmp(cmd, A, _l) != 0) && \ - (_l >= sizeof(B) || strncasecmp(cmd, B, _l) != 0)) \ - goto invalid_option; \ - } while (0) - - switch (cmd[0]) { - case 'a': - switch (cmd[1]) { - case 'a': /* aaonly / aaflag */ - FULLCHECK2("aaonly", "aaflag"); - lookup->aaonly = state; - break; - case 'd': - switch (cmd[2]) { - case 'd': /* additional */ - FULLCHECK("additional"); - lookup->section_additional = state; - break; - case 'f': /* adflag */ - FULLCHECK("adflag"); - lookup->adflag = state; - break; - default: - goto invalid_option; - } - break; - case 'l': /* all */ - FULLCHECK("all"); - lookup->section_question = state; - lookup->section_authority = state; - lookup->section_answer = state; - lookup->section_additional = state; - lookup->comments = state; - lookup->stats = state; - printcmd = state; - break; - case 'n': /* answer */ - FULLCHECK("answer"); - lookup->section_answer = state; - break; - case 'u': /* authority */ - FULLCHECK("authority"); - lookup->section_authority = state; - break; - default: - goto invalid_option; - } - break; - case 'b': - switch (cmd[1]) { - case 'e':/* besteffort */ - FULLCHECK("besteffort"); - lookup->besteffort = state; - break; - case 'u':/* bufsize */ - FULLCHECK("bufsize"); - if (value == NULL) - goto need_value; - if (!state) - goto invalid_option; - lookup->udpsize = (isc_uint16_t) parse_uint(value, - "buffer size", COMMSIZE); - break; - default: - goto invalid_option; - } - break; - case 'c': - switch (cmd[1]) { - case 'd':/* cdflag */ - FULLCHECK("cdflag"); - lookup->cdflag = state; - break; - case 'l': /* cl */ - FULLCHECK("cl"); - noclass = ISC_TF(!state); - break; - case 'm': /* cmd */ - FULLCHECK("cmd"); - printcmd = state; - break; - case 'o': /* comments */ - FULLCHECK("comments"); - lookup->comments = state; - if (lookup == default_lookup) - pluscomm = state; - break; - default: - goto invalid_option; - } - break; - case 'd': - switch (cmd[1]) { - case 'e': /* defname */ - FULLCHECK("defname"); - usesearch = state; - break; - case 'n': /* dnssec */ - FULLCHECK("dnssec"); - if (state && lookup->edns == -1) - lookup->edns = 0; - lookup->dnssec = state; - break; - case 'o': /* domain */ - FULLCHECK("domain"); - if (value == NULL) - goto need_value; - if (!state) - goto invalid_option; - strncpy(domainopt, value, sizeof(domainopt)); - domainopt[sizeof(domainopt)-1] = '\0'; - break; - default: - goto invalid_option; - } - break; - case 'e': - FULLCHECK("edns"); - if (!state) { - lookup->edns = -1; - break; - } - if (value == NULL) - goto need_value; - lookup->edns = (isc_int16_t) parse_uint(value, "edns", 255); - break; - case 'f': /* fail */ - FULLCHECK("fail"); - lookup->servfail_stops = state; - break; - case 'i': - switch (cmd[1]) { - case 'd': /* identify */ - FULLCHECK("identify"); - lookup->identify = state; - break; - case 'g': /* ignore */ - default: /* Inherets default for compatibility */ - FULLCHECK("ignore"); - lookup->ignore = ISC_TRUE; - } - break; - case 'm': /* multiline */ - FULLCHECK("multiline"); - multiline = state; - break; - case 'n': - switch (cmd[1]) { - case 'd': /* ndots */ - FULLCHECK("ndots"); - if (value == NULL) - goto need_value; - if (!state) - goto invalid_option; - ndots = parse_uint(value, "ndots", MAXNDOTS); - break; - case 's': /* nssearch */ - FULLCHECK("nssearch"); - lookup->ns_search_only = state; - if (state) { - lookup->trace_root = ISC_TRUE; - lookup->recurse = ISC_TRUE; - lookup->identify = ISC_TRUE; - lookup->stats = ISC_FALSE; - lookup->comments = ISC_FALSE; - lookup->section_additional = ISC_FALSE; - lookup->section_authority = ISC_FALSE; - lookup->section_question = ISC_FALSE; - lookup->rdtype = dns_rdatatype_ns; - lookup->rdtypeset = ISC_TRUE; - short_form = ISC_TRUE; - } - break; - default: - goto invalid_option; - } - break; - case 'q': - switch (cmd[1]) { - case 'r': /* qr */ - FULLCHECK("qr"); - qr = state; - break; - case 'u': /* question */ - FULLCHECK("question"); - lookup->section_question = state; - if (lookup == default_lookup) - plusquest = state; - break; - default: - goto invalid_option; - } - break; - case 'r': - switch (cmd[1]) { - case 'e': - switch (cmd[2]) { - case 'c': /* recurse */ - FULLCHECK("recurse"); - lookup->recurse = state; - break; - case 't': /* retry / retries */ - FULLCHECK2("retry", "retries"); - if (value == NULL) - goto need_value; - if (!state) - goto invalid_option; - lookup->retries = parse_uint(value, "retries", - MAXTRIES - 1); - lookup->retries++; - break; - default: - goto invalid_option; - } - break; - default: - goto invalid_option; - } - break; - case 's': - switch (cmd[1]) { - case 'e': /* search */ - FULLCHECK("search"); - usesearch = state; - break; - case 'h': - if (cmd[2] != 'o') - goto invalid_option; - switch (cmd[3]) { - case 'r': /* short */ - FULLCHECK("short"); - short_form = state; - if (state) { - printcmd = ISC_FALSE; - lookup->section_additional = ISC_FALSE; - lookup->section_answer = ISC_TRUE; - lookup->section_authority = ISC_FALSE; - lookup->section_question = ISC_FALSE; - lookup->comments = ISC_FALSE; - lookup->stats = ISC_FALSE; - } - break; - case 'w': /* showsearch */ - FULLCHECK("showsearch"); - showsearch = state; - usesearch = state; - break; - default: - goto invalid_option; - } - break; -#ifdef DIG_SIGCHASE - case 'i': /* sigchase */ - FULLCHECK("sigchase"); - lookup->sigchase = state; - if (lookup->sigchase) - lookup->dnssec = ISC_TRUE; - break; -#endif - case 't': /* stats */ - FULLCHECK("stats"); - lookup->stats = state; - break; - default: - goto invalid_option; - } - break; - case 't': - switch (cmd[1]) { - case 'c': /* tcp */ - FULLCHECK("tcp"); - if (!is_batchfile) - lookup->tcp_mode = state; - break; - case 'i': /* timeout */ - FULLCHECK("timeout"); - if (value == NULL) - goto need_value; - if (!state) - goto invalid_option; - timeout = parse_uint(value, "timeout", MAXTIMEOUT); - if (timeout == 0) - timeout = 1; - break; -#if DIG_SIGCHASE_TD - case 'o': /* topdown */ - FULLCHECK("topdown"); - lookup->do_topdown = state; - break; -#endif - case 'r': - switch (cmd[2]) { - case 'a': /* trace */ - FULLCHECK("trace"); - lookup->trace = state; - lookup->trace_root = state; - if (state) { - lookup->recurse = ISC_FALSE; - lookup->identify = ISC_TRUE; - lookup->comments = ISC_FALSE; - lookup->stats = ISC_FALSE; - lookup->section_additional = ISC_FALSE; - lookup->section_authority = ISC_TRUE; - lookup->section_question = ISC_FALSE; - } - break; - case 'i': /* tries */ - FULLCHECK("tries"); - if (value == NULL) - goto need_value; - if (!state) - goto invalid_option; - lookup->retries = parse_uint(value, "tries", - MAXTRIES); - if (lookup->retries == 0) - lookup->retries = 1; - break; -#ifdef DIG_SIGCHASE - case 'u': /* trusted-key */ - FULLCHECK("trusted-key"); - if (value == NULL) - goto need_value; - if (!state) - goto invalid_option; - n = strlcpy(trustedkey, ptr, - sizeof(trustedkey)); - if (n >= sizeof(trustedkey)) - fatal("trusted key too large"); - break; -#endif - default: - goto invalid_option; - } - break; - case 't': /* ttlid */ - FULLCHECK("ttlid"); - nottl = ISC_TF(!state); - break; - default: - goto invalid_option; - } - break; - case 'v': - FULLCHECK("vc"); - if (!is_batchfile) - lookup->tcp_mode = state; - break; - default: - invalid_option: - need_value: - fprintf(stderr, "Invalid option: +%s\n", - option); - usage(); - } - return; -} - -/*% - * #ISC_TRUE returned if value was used - */ -static const char *single_dash_opts = "46dhimnv"; -static const char *dash_opts = "46bcdfhikmnptvyx"; -static isc_boolean_t -dash_option(char *option, char *next, dig_lookup_t **lookup, - isc_boolean_t *open_type_class, isc_boolean_t *need_clone, - isc_boolean_t config_only, int argc, char **argv, - isc_boolean_t *firstarg) -{ - char opt, *value, *ptr, *ptr2, *ptr3; - isc_result_t result; - isc_boolean_t value_from_next; - isc_textregion_t tr; - dns_rdatatype_t rdtype; - dns_rdataclass_t rdclass; - char textname[MXNAME]; - struct in_addr in4; - struct in6_addr in6; - in_port_t srcport; - char *hash, *cmd; - - while (strpbrk(option, single_dash_opts) == &option[0]) { - /* - * Since the -[46dhimnv] options do not take an argument, - * account for them (in any number and/or combination) - * if they appear as the first character(s) of a q-opt. - */ - opt = option[0]; - switch (opt) { - case '4': - if (have_ipv4) { - isc_net_disableipv6(); - have_ipv6 = ISC_FALSE; - } else { - fatal("can't find IPv4 networking"); - return (ISC_FALSE); - } - break; - case '6': - if (have_ipv6) { - isc_net_disableipv4(); - have_ipv4 = ISC_FALSE; - } else { - fatal("can't find IPv6 networking"); - return (ISC_FALSE); - } - break; - case 'd': - ptr = strpbrk(&option[1], dash_opts); - if (ptr != &option[1]) { - cmd = option; - FULLCHECK("debug"); - debugging = ISC_TRUE; - return (ISC_FALSE); - } else - debugging = ISC_TRUE; - break; - case 'h': - help(); - exit(0); - break; - case 'i': - ip6_int = ISC_TRUE; - break; - case 'm': /* memdebug */ - /* memdebug is handled in preparse_args() */ - break; - case 'n': - /* deprecated */ - break; - case 'v': - version(); - exit(0); - break; - } - if (strlen(option) > 1U) - option = &option[1]; - else - return (ISC_FALSE); - } - opt = option[0]; - if (strlen(option) > 1U) { - value_from_next = ISC_FALSE; - value = &option[1]; - } else { - value_from_next = ISC_TRUE; - value = next; - } - if (value == NULL) - goto invalid_option; - switch (opt) { - case 'b': - hash = strchr(value, '#'); - if (hash != NULL) { - srcport = (in_port_t) - parse_uint(hash + 1, - "port number", MAXPORT); - *hash = '\0'; - } else - srcport = 0; - if (have_ipv6 && inet_pton(AF_INET6, value, &in6) == 1) { - isc_sockaddr_fromin6(&bind_address, &in6, srcport); - isc_net_disableipv4(); - } else if (have_ipv4 && inet_pton(AF_INET, value, &in4) == 1) { - isc_sockaddr_fromin(&bind_address, &in4, srcport); - isc_net_disableipv6(); - } else { - if (hash != NULL) - *hash = '#'; - fatal("invalid address %s", value); - } - if (hash != NULL) - *hash = '#'; - specified_source = ISC_TRUE; - return (value_from_next); - case 'c': - if ((*lookup)->rdclassset) { - fprintf(stderr, ";; Warning, extra class option\n"); - } - *open_type_class = ISC_FALSE; - tr.base = value; - tr.length = strlen(value); - result = dns_rdataclass_fromtext(&rdclass, - (isc_textregion_t *)&tr); - if (result == ISC_R_SUCCESS) { - (*lookup)->rdclass = rdclass; - (*lookup)->rdclassset = ISC_TRUE; - } else - fprintf(stderr, ";; Warning, ignoring " - "invalid class %s\n", - value); - return (value_from_next); - case 'f': - batchname = value; - return (value_from_next); - case 'k': - strncpy(keyfile, value, sizeof(keyfile)); - keyfile[sizeof(keyfile)-1]=0; - return (value_from_next); - case 'p': - port = (in_port_t) parse_uint(value, "port number", MAXPORT); - return (value_from_next); - case 'q': - if (!config_only) { - if (*need_clone) - (*lookup) = clone_lookup(default_lookup, - ISC_TRUE); - *need_clone = ISC_TRUE; - strncpy((*lookup)->textname, value, - sizeof((*lookup)->textname)); - (*lookup)->textname[sizeof((*lookup)->textname)-1]=0; - (*lookup)->trace_root = ISC_TF((*lookup)->trace || - (*lookup)->ns_search_only); - (*lookup)->new_search = ISC_TRUE; - if (*firstarg) { - printgreeting(argc, argv, *lookup); - *firstarg = ISC_FALSE; - } - ISC_LIST_APPEND(lookup_list, (*lookup), link); - debug("looking up %s", (*lookup)->textname); - } - return (value_from_next); - case 't': - *open_type_class = ISC_FALSE; - if (strncasecmp(value, "ixfr=", 5) == 0) { - rdtype = dns_rdatatype_ixfr; - result = ISC_R_SUCCESS; - } else { - tr.base = value; - tr.length = strlen(value); - result = dns_rdatatype_fromtext(&rdtype, - (isc_textregion_t *)&tr); - if (result == ISC_R_SUCCESS && - rdtype == dns_rdatatype_ixfr) { - result = DNS_R_UNKNOWN; - } - } - if (result == ISC_R_SUCCESS) { - if ((*lookup)->rdtypeset) { - fprintf(stderr, ";; Warning, " - "extra type option\n"); - } - if (rdtype == dns_rdatatype_ixfr) { - (*lookup)->rdtype = dns_rdatatype_ixfr; - (*lookup)->rdtypeset = ISC_TRUE; - (*lookup)->ixfr_serial = - parse_uint(&value[5], "serial number", - MAXSERIAL); - (*lookup)->section_question = plusquest; - (*lookup)->comments = pluscomm; - } else { - (*lookup)->rdtype = rdtype; - (*lookup)->rdtypeset = ISC_TRUE; - if (rdtype == dns_rdatatype_axfr) { - (*lookup)->section_question = plusquest; - (*lookup)->comments = pluscomm; - } - (*lookup)->ixfr_serial = ISC_FALSE; - } - } else - fprintf(stderr, ";; Warning, ignoring " - "invalid type %s\n", - value); - return (value_from_next); - case 'y': - ptr = next_token(&value,":"); /* hmac type or name */ - if (ptr == NULL) { - usage(); - } - ptr2 = next_token(&value, ":"); /* name or secret */ - if (ptr2 == NULL) - usage(); - ptr3 = next_token(&value,":"); /* secret or NULL */ - if (ptr3 != NULL) { - if (strcasecmp(ptr, "hmac-md5") == 0) { - hmacname = DNS_TSIG_HMACMD5_NAME; - digestbits = 0; - } else if (strncasecmp(ptr, "hmac-md5-", 9) == 0) { - hmacname = DNS_TSIG_HMACMD5_NAME; - digestbits = parse_uint(&ptr[9], - "digest-bits [0..128]", - 128); - digestbits = (digestbits + 7) & ~0x7U; - } else if (strcasecmp(ptr, "hmac-sha1") == 0) { - hmacname = DNS_TSIG_HMACSHA1_NAME; - digestbits = 0; - } else if (strncasecmp(ptr, "hmac-sha1-", 10) == 0) { - hmacname = DNS_TSIG_HMACSHA1_NAME; - digestbits = parse_uint(&ptr[10], - "digest-bits [0..160]", - 160); - digestbits = (digestbits + 7) & ~0x7U; - } else if (strcasecmp(ptr, "hmac-sha224") == 0) { - hmacname = DNS_TSIG_HMACSHA224_NAME; - digestbits = 0; - } else if (strncasecmp(ptr, "hmac-sha224-", 12) == 0) { - hmacname = DNS_TSIG_HMACSHA224_NAME; - digestbits = parse_uint(&ptr[12], - "digest-bits [0..224]", - 224); - digestbits = (digestbits + 7) & ~0x7U; - } else if (strcasecmp(ptr, "hmac-sha256") == 0) { - hmacname = DNS_TSIG_HMACSHA256_NAME; - digestbits = 0; - } else if (strncasecmp(ptr, "hmac-sha256-", 12) == 0) { - hmacname = DNS_TSIG_HMACSHA256_NAME; - digestbits = parse_uint(&ptr[12], - "digest-bits [0..256]", - 256); - digestbits = (digestbits + 7) & ~0x7U; - } else if (strcasecmp(ptr, "hmac-sha384") == 0) { - hmacname = DNS_TSIG_HMACSHA384_NAME; - digestbits = 0; - } else if (strncasecmp(ptr, "hmac-sha384-", 12) == 0) { - hmacname = DNS_TSIG_HMACSHA384_NAME; - digestbits = parse_uint(&ptr[12], - "digest-bits [0..384]", - 384); - digestbits = (digestbits + 7) & ~0x7U; - } else if (strcasecmp(ptr, "hmac-sha512") == 0) { - hmacname = DNS_TSIG_HMACSHA512_NAME; - digestbits = 0; - } else if (strncasecmp(ptr, "hmac-sha512-", 12) == 0) { - hmacname = DNS_TSIG_HMACSHA512_NAME; - digestbits = parse_uint(&ptr[12], - "digest-bits [0..512]", - 512); - digestbits = (digestbits + 7) & ~0x7U; - } else { - fprintf(stderr, ";; Warning, ignoring " - "invalid TSIG algorithm %s\n", ptr); - return (value_from_next); - } - ptr = ptr2; - ptr2 = ptr3; - } else { - hmacname = DNS_TSIG_HMACMD5_NAME; - digestbits = 0; - } - strncpy(keynametext, ptr, sizeof(keynametext)); - keynametext[sizeof(keynametext)-1]=0; - strncpy(keysecret, ptr2, sizeof(keysecret)); - keysecret[sizeof(keysecret)-1]=0; - return (value_from_next); - case 'x': - if (*need_clone) - *lookup = clone_lookup(default_lookup, ISC_TRUE); - *need_clone = ISC_TRUE; - if (get_reverse(textname, sizeof(textname), value, - ip6_int, ISC_FALSE) == ISC_R_SUCCESS) { - strncpy((*lookup)->textname, textname, - sizeof((*lookup)->textname)); - debug("looking up %s", (*lookup)->textname); - (*lookup)->trace_root = ISC_TF((*lookup)->trace || - (*lookup)->ns_search_only); - (*lookup)->ip6_int = ip6_int; - if (!(*lookup)->rdtypeset) - (*lookup)->rdtype = dns_rdatatype_ptr; - if (!(*lookup)->rdclassset) - (*lookup)->rdclass = dns_rdataclass_in; - (*lookup)->new_search = ISC_TRUE; - if (*firstarg) { - printgreeting(argc, argv, *lookup); - *firstarg = ISC_FALSE; - } - ISC_LIST_APPEND(lookup_list, *lookup, link); - } else { - fprintf(stderr, "Invalid IP address %s\n", value); - exit(1); - } - return (value_from_next); - invalid_option: - default: - fprintf(stderr, "Invalid option: -%s\n", option); - usage(); - } - return (ISC_FALSE); -} - -/*% - * Because we may be trying to do memory allocation recording, we're going - * to need to parse the arguments for the -m *before* we start the main - * argument parsing routine. - * - * I'd prefer not to have to do this, but I am not quite sure how else to - * fix the problem. Argument parsing in dig involves memory allocation - * by its nature, so it can't be done in the main argument parser. - */ -static void -preparse_args(int argc, char **argv) { - int rc; - char **rv; - char *option; - - rc = argc; - rv = argv; - for (rc--, rv++; rc > 0; rc--, rv++) { - if (rv[0][0] != '-') - continue; - option = &rv[0][1]; - while (strpbrk(option, single_dash_opts) == &option[0]) { - if (option[0] == 'm') { - memdebugging = ISC_TRUE; - isc_mem_debugging = ISC_MEM_DEBUGTRACE | - ISC_MEM_DEBUGRECORD; - return; - } - option = &option[1]; - } - } -} - -static void -getaddresses(dig_lookup_t *lookup, const char *host) { - isc_result_t result; - isc_sockaddr_t sockaddrs[DIG_MAX_ADDRESSES]; - isc_netaddr_t netaddr; - int count, i; - dig_server_t *srv; - char tmp[ISC_NETADDR_FORMATSIZE]; - - result = bind9_getaddresses(host, 0, sockaddrs, - DIG_MAX_ADDRESSES, &count); - if (result != ISC_R_SUCCESS) - fatal("couldn't get address for '%s': %s", - host, isc_result_totext(result)); - - for (i = 0; i < count; i++) { - isc_netaddr_fromsockaddr(&netaddr, &sockaddrs[i]); - isc_netaddr_format(&netaddr, tmp, sizeof(tmp)); - srv = make_server(tmp, host); - ISC_LIST_APPEND(lookup->my_server_list, srv, link); - } - addresscount = count; -} - -static void -parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, - int argc, char **argv) { - isc_result_t result; - isc_textregion_t tr; - isc_boolean_t firstarg = ISC_TRUE; - dig_lookup_t *lookup = NULL; - dns_rdatatype_t rdtype; - dns_rdataclass_t rdclass; - isc_boolean_t open_type_class = ISC_TRUE; - char batchline[MXNAME]; - int bargc; - char *bargv[64]; - int rc; - char **rv; -#ifndef NOPOSIX - char *homedir; - char rcfile[256]; -#endif - char *input; - int i; - isc_boolean_t need_clone = ISC_TRUE; - - /* - * The semantics for parsing the args is a bit complex; if - * we don't have a host yet, make the arg apply globally, - * otherwise make it apply to the latest host. This is - * a bit different than the previous versions, but should - * form a consistent user interface. - * - * First, create a "default lookup" which won't actually be used - * anywhere, except for cloning into new lookups - */ - - debug("parse_args()"); - if (!is_batchfile) { - debug("making new lookup"); - default_lookup = make_empty_lookup(); - -#ifndef NOPOSIX - /* - * Treat ${HOME}/.digrc as a special batchfile - */ - INSIST(batchfp == NULL); - homedir = getenv("HOME"); - if (homedir != NULL) { - unsigned int n; - n = snprintf(rcfile, sizeof(rcfile), "%s/.digrc", - homedir); - if (n < sizeof(rcfile)) - batchfp = fopen(rcfile, "r"); - } - if (batchfp != NULL) { - while (fgets(batchline, sizeof(batchline), - batchfp) != 0) { - debug("config line %s", batchline); - bargc = 1; - input = batchline; - bargv[bargc] = next_token(&input, " \t\r\n"); - while ((bargv[bargc] != NULL) && - (bargc < 62)) { - bargc++; - bargv[bargc] = - next_token(&input, " \t\r\n"); - } - - bargv[0] = argv[0]; - argv0 = argv[0]; - - for(i = 0; i < bargc; i++) - debug(".digrc argv %d: %s", - i, bargv[i]); - parse_args(ISC_TRUE, ISC_TRUE, bargc, - (char **)bargv); - } - fclose(batchfp); - } -#endif - } - - if (is_batchfile && !config_only) { - /* Processing '-f batchfile'. */ - lookup = clone_lookup(default_lookup, ISC_TRUE); - need_clone = ISC_FALSE; - } else - lookup = default_lookup; - - rc = argc; - rv = argv; - for (rc--, rv++; rc > 0; rc--, rv++) { - debug("main parsing %s", rv[0]); - if (strncmp(rv[0], "%", 1) == 0) - break; - if (strncmp(rv[0], "@", 1) == 0) { - getaddresses(lookup, &rv[0][1]); - } else if (rv[0][0] == '+') { - plus_option(&rv[0][1], is_batchfile, - lookup); - } else if (rv[0][0] == '-') { - if (rc <= 1) { - if (dash_option(&rv[0][1], NULL, - &lookup, &open_type_class, - &need_clone, config_only, - argc, argv, &firstarg)) { - rc--; - rv++; - } - } else { - if (dash_option(&rv[0][1], rv[1], - &lookup, &open_type_class, - &need_clone, config_only, - argc, argv, &firstarg)) { - rc--; - rv++; - } - } - } else { - /* - * Anything which isn't an option - */ - if (open_type_class) { - if (strncasecmp(rv[0], "ixfr=", 5) == 0) { - rdtype = dns_rdatatype_ixfr; - result = ISC_R_SUCCESS; - } else { - tr.base = rv[0]; - tr.length = strlen(rv[0]); - result = dns_rdatatype_fromtext(&rdtype, - (isc_textregion_t *)&tr); - if (result == ISC_R_SUCCESS && - rdtype == dns_rdatatype_ixfr) { - result = DNS_R_UNKNOWN; - fprintf(stderr, ";; Warning, " - "ixfr requires a " - "serial number\n"); - continue; - } - } - if (result == ISC_R_SUCCESS) { - if (lookup->rdtypeset) { - fprintf(stderr, ";; Warning, " - "extra type option\n"); - } - if (rdtype == dns_rdatatype_ixfr) { - lookup->rdtype = - dns_rdatatype_ixfr; - lookup->rdtypeset = ISC_TRUE; - lookup->ixfr_serial = - parse_uint(&rv[0][5], - "serial number", - MAXSERIAL); - lookup->section_question = - plusquest; - lookup->comments = pluscomm; - } else { - lookup->rdtype = rdtype; - lookup->rdtypeset = ISC_TRUE; - if (rdtype == - dns_rdatatype_axfr) { - lookup->section_question = - plusquest; - lookup->comments = pluscomm; - } - lookup->ixfr_serial = ISC_FALSE; - } - continue; - } - result = dns_rdataclass_fromtext(&rdclass, - (isc_textregion_t *)&tr); - if (result == ISC_R_SUCCESS) { - if (lookup->rdclassset) { - fprintf(stderr, ";; Warning, " - "extra class option\n"); - } - lookup->rdclass = rdclass; - lookup->rdclassset = ISC_TRUE; - continue; - } - } - - if (!config_only) { - if (need_clone) - lookup = clone_lookup(default_lookup, - ISC_TRUE); - need_clone = ISC_TRUE; - strncpy(lookup->textname, rv[0], - sizeof(lookup->textname)); - lookup->textname[sizeof(lookup->textname)-1]=0; - lookup->trace_root = ISC_TF(lookup->trace || - lookup->ns_search_only); - lookup->new_search = ISC_TRUE; - if (firstarg) { - printgreeting(argc, argv, lookup); - firstarg = ISC_FALSE; - } - ISC_LIST_APPEND(lookup_list, lookup, link); - debug("looking up %s", lookup->textname); - } - /* XXX Error message */ - } - } - - /* - * If we have a batchfile, seed the lookup list with the - * first entry, then trust the callback in dighost_shutdown - * to get the rest - */ - if ((batchname != NULL) && !(is_batchfile)) { - if (strcmp(batchname, "-") == 0) - batchfp = stdin; - else - batchfp = fopen(batchname, "r"); - if (batchfp == NULL) { - perror(batchname); - if (exitcode < 8) - exitcode = 8; - fatal("couldn't open specified batch file"); - } - /* XXX Remove code dup from shutdown code */ - next_line: - if (fgets(batchline, sizeof(batchline), batchfp) != 0) { - bargc = 1; - debug("batch line %s", batchline); - if (batchline[0] == '\r' || batchline[0] == '\n' - || batchline[0] == '#' || batchline[0] == ';') - goto next_line; - input = batchline; - bargv[bargc] = next_token(&input, " \t\r\n"); - while ((bargv[bargc] != NULL) && (bargc < 14)) { - bargc++; - bargv[bargc] = next_token(&input, " \t\r\n"); - } - - bargv[0] = argv[0]; - argv0 = argv[0]; - - for(i = 0; i < bargc; i++) - debug("batch argv %d: %s", i, bargv[i]); - parse_args(ISC_TRUE, ISC_FALSE, bargc, (char **)bargv); - return; - } - return; - } - /* - * If no lookup specified, search for root - */ - if ((lookup_list.head == NULL) && !config_only) { - if (need_clone) - lookup = clone_lookup(default_lookup, ISC_TRUE); - need_clone = ISC_TRUE; - lookup->trace_root = ISC_TF(lookup->trace || - lookup->ns_search_only); - lookup->new_search = ISC_TRUE; - strcpy(lookup->textname, "."); - lookup->rdtype = dns_rdatatype_ns; - lookup->rdtypeset = ISC_TRUE; - if (firstarg) { - printgreeting(argc, argv, lookup); - firstarg = ISC_FALSE; - } - ISC_LIST_APPEND(lookup_list, lookup, link); - } - if (!need_clone) - destroy_lookup(lookup); -} - -/* - * Callback from dighost.c to allow program-specific shutdown code. - * Here, we're possibly reading from a batch file, then shutting down - * for real if there's nothing in the batch file to read. - */ -void -dighost_shutdown(void) { - char batchline[MXNAME]; - int bargc; - char *bargv[16]; - char *input; - int i; - - if (batchname == NULL) { - isc_app_shutdown(); - return; - } - - fflush(stdout); - if (feof(batchfp)) { - batchname = NULL; - isc_app_shutdown(); - if (batchfp != stdin) - fclose(batchfp); - return; - } - - if (fgets(batchline, sizeof(batchline), batchfp) != 0) { - debug("batch line %s", batchline); - bargc = 1; - input = batchline; - bargv[bargc] = next_token(&input, " \t\r\n"); - while ((bargv[bargc] != NULL) && (bargc < 14)) { - bargc++; - bargv[bargc] = next_token(&input, " \t\r\n"); - } - - bargv[0] = argv0; - - for(i = 0; i < bargc; i++) - debug("batch argv %d: %s", i, bargv[i]); - parse_args(ISC_TRUE, ISC_FALSE, bargc, (char **)bargv); - start_lookup(); - } else { - batchname = NULL; - if (batchfp != stdin) - fclose(batchfp); - isc_app_shutdown(); - return; - } -} - -/*% Main processing routine for dig */ -int -main(int argc, char **argv) { - isc_result_t result; - - ISC_LIST_INIT(lookup_list); - ISC_LIST_INIT(server_list); - ISC_LIST_INIT(search_list); - - debug("main()"); - preparse_args(argc, argv); - progname = argv[0]; - result = isc_app_start(); - check_result(result, "isc_app_start"); - setup_libs(); - parse_args(ISC_FALSE, ISC_FALSE, argc, argv); - setup_system(); - if (domainopt[0] != '\0') { - set_search_domain(domainopt); - usesearch = ISC_TRUE; - } - result = isc_app_onrun(mctx, global_task, onrun_callback, NULL); - check_result(result, "isc_app_onrun"); - isc_app_run(); - destroy_lookup(default_lookup); - if (batchname != NULL) { - if (batchfp != stdin) - fclose(batchfp); - batchname = NULL; - } -#ifdef DIG_SIGCHASE - clean_trustedkey(); -#endif - cancel_all(); - destroy_libs(); - isc_app_finish(); - return (exitcode); -} diff --git a/contrib/bind9/bin/dig/dig.docbook b/contrib/bind9/bin/dig/dig.docbook deleted file mode 100644 index 6a28b88..0000000 --- a/contrib/bind9/bin/dig/dig.docbook +++ /dev/null @@ -1,936 +0,0 @@ -]> - - - - - - - Jun 30, 2000 - - - - dig - 1 - BIND9 - - - - dig - DNS lookup utility - - - - - 2004 - 2005 - 2006 - 2007 - Internet Systems Consortium, Inc. ("ISC") - - - 2000 - 2001 - 2002 - 2003 - Internet Software Consortium. - - - - - - dig - @server - - - - - - - - - - - - name - type - class - queryopt - - - - dig - - - - - dig - global-queryopt - query - - - - - DESCRIPTION - dig - (domain information groper) is a flexible tool - for interrogating DNS name servers. It performs DNS lookups and - displays the answers that are returned from the name server(s) that - were queried. Most DNS administrators use dig to - troubleshoot DNS problems because of its flexibility, ease of use and - clarity of output. Other lookup tools tend to have less functionality - than dig. - - - - Although dig is normally used with - command-line - arguments, it also has a batch mode of operation for reading lookup - requests from a file. A brief summary of its command-line arguments - and options is printed when the option is given. - Unlike earlier versions, the BIND 9 implementation of - dig allows multiple lookups to be issued - from the - command line. - - - - Unless it is told to query a specific name server, - dig will try each of the servers listed - in - /etc/resolv.conf. - - - - When no command line arguments or options are given, will perform an - NS query for "." (the root). - - - - It is possible to set per-user defaults for dig via - ${HOME}/.digrc. This file is read and - any options in it - are applied before the command line arguments. - - - - The IN and CH class names overlap with the IN and CH top level - domains names. Either use the and - options to specify the type and class or - use the the specify the domain name or - use "IN." and "CH." when looking up these top level domains. - - - - - - SIMPLE USAGE - - - A typical invocation of dig looks like: - dig @server name type - where: - - - - - server - - - is the name or IP address of the name server to query. This can - be an IPv4 - address in dotted-decimal notation or an IPv6 - address in colon-delimited notation. When the supplied - server argument is a - hostname, - dig resolves that name before - querying that name - server. If no server - argument is provided, - dig consults /etc/resolv.conf - and queries the name servers listed there. The reply from the - name - server that responds is displayed. - - - - - - name - - - is the name of the resource record that is to be looked up. - - - - - - type - - - indicates what type of query is required — - ANY, A, MX, SIG, etc. - type can be any valid query - type. If no - type argument is supplied, - dig will perform a lookup for an - A record. - - - - - - - - - - - OPTIONS - - - The option sets the source IP address of the query - to address. This must be a valid - address on - one of the host's network interfaces or "0.0.0.0" or "::". An optional - port - may be specified by appending "#<port>" - - - - The default query class (IN for internet) is overridden by the - option. class is - any valid - class, such as HS for Hesiod records or CH for Chaosnet records. - - - - The option makes dig - operate - in batch mode by reading a list of lookup requests to process from the - file filename. The file contains a - number of - queries, one per line. Each entry in the file should be organized in - the same way they would be presented as queries to - dig using the command-line interface. - - - - If a non-standard port number is to be queried, the - option is used. port# is - the port number that dig will send its - queries - instead of the standard DNS port number 53. This option would be used - to test a name server that has been configured to listen for queries - on a non-standard port number. - - - - The option forces dig - to only - use IPv4 query transport. The option forces - dig to only use IPv6 query transport. - - - - The option sets the query type to - type. It can be any valid query type - which is - supported in BIND 9. The default query type is "A", unless the - option is supplied to indicate a reverse lookup. - A zone transfer can be requested by specifying a type of AXFR. When - an incremental zone transfer (IXFR) is required, - type is set to ixfr=N. - The incremental zone transfer will contain the changes made to the zone - since the serial number in the zone's SOA record was - N. - - - - The option sets the query name to - name. This useful do distinguish the - name from other arguments. - - - - Reverse lookups — mapping addresses to names — are simplified by the - option. addr is - an IPv4 - address in dotted-decimal notation, or a colon-delimited IPv6 address. - When this option is used, there is no need to provide the - name, class and - type arguments. dig - automatically performs a lookup for a name like - 11.12.13.10.in-addr.arpa and sets the - query type and - class to PTR and IN respectively. By default, IPv6 addresses are - looked up using nibble format under the IP6.ARPA domain. - To use the older RFC1886 method using the IP6.INT domain - specify the option. Bit string labels (RFC2874) - are now experimental and are not attempted. - - - - To sign the DNS queries sent by dig and - their - responses using transaction signatures (TSIG), specify a TSIG key file - using the option. You can also specify the TSIG - key itself on the command line using the option; - hmac is the type of the TSIG, default HMAC-MD5, - name is the name of the TSIG key and - key is the actual key. The key is a - base-64 - encoded string, typically generated by - - dnssec-keygen8 - . - - Caution should be taken when using the option on - multi-user systems as the key can be visible in the output from - - ps1 - - or in the shell's history file. When - using TSIG authentication with dig, the name - server that is queried needs to know the key and algorithm that is - being used. In BIND, this is done by providing appropriate - key and server statements in - named.conf. - - - - - - QUERY OPTIONS - - dig - provides a number of query options which affect - the way in which lookups are made and the results displayed. Some of - these set or reset flag bits in the query header, some determine which - sections of the answer get printed, and others determine the timeout - and retry strategies. - - - - Each query option is identified by a keyword preceded by a plus sign - (+). Some keywords set or reset an - option. These may be preceded - by the string no to negate the meaning of - that keyword. Other - keywords assign values to options like the timeout interval. They - have the form . - The query options are: - - - - - - - - Use [do not use] TCP when querying name servers. The default - behavior is to use UDP unless an AXFR or IXFR query is - requested, in - which case a TCP connection is used. - - - - - - - - - Use [do not use] TCP when querying name servers. This alternate - syntax to +[no]tcp is - provided for backwards - compatibility. The "vc" stands for "virtual circuit". - - - - - - - - - Ignore truncation in UDP responses instead of retrying with TCP. - By - default, TCP retries are performed. - - - - - - - - - Set the search list to contain the single domain - somename, as if specified in - a - domain directive in - /etc/resolv.conf, and enable - search list - processing as if the +search - option were given. - - - - - - - - - Use [do not use] the search list defined by the searchlist or - domain - directive in resolv.conf (if - any). - The search list is not used by default. - - - - - - - - - Perform [do not perform] a search showing intermediate - results. - - - - - - - - - Deprecated, treated as a synonym for +[no]search - - - - - - - - - Sets the "aa" flag in the query. - - - - - - - - - A synonym for +[no]aaonly. - - - - - - - - - Set [do not set] the AD (authentic data) bit in the query. The - AD bit - currently has a standard meaning only in responses, not in - queries, - but the ability to set the bit in the query is provided for - completeness. - - - - - - - - - Set [do not set] the CD (checking disabled) bit in the query. - This - requests the server to not perform DNSSEC validation of - responses. - - - - - - - - - Display [do not display] the CLASS when printing the record. - - - - - - - - - Display [do not display] the TTL when printing the record. - - - - - - - - - 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. - - - - - - - - - When this option is set, dig - attempts to find the - authoritative name servers for the zone containing the name - being - looked up and display the SOA record that each name server has - for the - zone. - - - - - - - - - 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. - - - - - - - - - Toggles the printing of the initial comment in the output - identifying - the version of dig and the query - options that have - been applied. This comment is printed by default. - - - - - - - - - Provide a terse answer. The default is to print the answer in a - verbose form. - - - - - - - - - Show [or do not show] the IP address and port number that - supplied the - answer when the +short option - is enabled. If - short form answers are requested, the default is not to show the - source address and port number of the server that provided the - answer. - - - - - - - - - Toggle the display of comment lines in the output. The default - is to - print comments. - - - - - - - - - This query option toggles the printing of statistics: when the - query - was made, the size of the reply and so on. The default - behavior is - to print the query statistics. - - - - - - - - - Print [do not print] the query as it is sent. - By default, the query is not printed. - - - - - - - - - Print [do not print] the question section of a query when an - answer is - returned. The default is to print the question section as a - comment. - - - - - - - - - Display [do not display] the answer section of a reply. The - default - is to display it. - - - - - - - - - Display [do not display] the authority section of a reply. The - default is to display it. - - - - - - - - - Display [do not display] the additional section of a reply. - The default is to display it. - - - - - - - - - Set or clear all display flags. - - - - - - - - - - Sets the timeout for a query to - T seconds. The default - timeout is 5 seconds. - An attempt to set T to less - than 1 will result - in a query timeout of 1 second being applied. - - - - - - - - - Sets the number of times to try UDP queries to server to - T instead of the default, 3. - If - T is less than or equal to - zero, the number of - tries is silently rounded up to 1. - - - - - - - - - Sets the number of times to retry UDP queries to server to - T instead of the default, 2. - Unlike - +tries, this does not include - the initial - query. - - - - - - - - - Set the number of dots that have to appear in - name to D for it to be - considered absolute. The default value is that defined using - the - ndots statement in /etc/resolv.conf, or 1 if no - ndots statement is present. Names with fewer dots are - interpreted as - relative names and will be searched for in the domains listed in - the - or directive in - /etc/resolv.conf. - - - - - - - - - Set the UDP message buffer size advertised using EDNS0 to - B bytes. The maximum and minimum sizes - of this buffer are 65535 and 0 respectively. Values outside - this range are rounded up or down appropriately. - Values other than zero will cause a EDNS query to be sent. - - - - - - - - - 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. - - - - - - - - - Print records like the SOA records in a verbose multi-line - format with human-readable comments. The default is to print - each record on a single line, to facilitate machine parsing - of the dig output. - - - - - - - - - Do not try the next server if you receive a SERVFAIL. The - default is - to not try the next server which is the reverse of normal stub - resolver - behavior. - - - - - - - - - Attempt to display the contents of messages which are malformed. - The default is to not display malformed answers. - - - - - - - - - Requests DNSSEC records be sent by setting the DNSSEC OK bit - (DO) - in the OPT record in the additional section of the query. - - - - - - - - - Chase DNSSEC signature chains. Requires dig be compiled with - -DDIG_SIGCHASE. - - - - - - - - - Specifies a file containing trusted keys to be used with - . Each DNSKEY record must be - on its own line. - - - If not specified dig will look for - /etc/trusted-key.key then - trusted-key.key in the current directory. - - - Requires dig be compiled with -DDIG_SIGCHASE. - - - - - - - - - When chasing DNSSEC signature chains perform a top-down - validation. - Requires dig be compiled with -DDIG_SIGCHASE. - - - - - - - - - - - - - MULTIPLE QUERIES - - - The BIND 9 implementation of dig - supports - specifying multiple queries on the command line (in addition to - supporting the batch file option). Each of those - queries can be supplied with its own set of flags, options and query - options. - - - - In this case, each query argument - represent an - individual query in the command-line syntax described above. Each - consists of any of the standard options and flags, the name to be - looked up, an optional query type and class and any query options that - should be applied to that query. - - - - A global set of query options, which should be applied to all queries, - can also be supplied. These global query options must precede the - first tuple of name, class, type, options, flags, and query options - supplied on the command line. Any global query options (except - the option) can be - overridden by a query-specific set of query options. For example: - -dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr - - shows how dig could be used from the - command line - to make three lookups: an ANY query for www.isc.org, a - reverse lookup of 127.0.0.1 and a query for the NS records of - isc.org. - - A global query option of +qr is - applied, so - that dig shows the initial query it made - for each - lookup. The final query has a local query option of - +noqr which means that dig - will not print the initial query when it looks up the NS records for - isc.org. - - - - - - IDN SUPPORT - - If dig has been built with IDN (internationalized - domain name) support, it can accept and display non-ASCII domain names. - dig appropriately converts character encoding of - domain name before sending a request to DNS server or displaying a - reply from the server. - If you'd like to turn off the IDN support for some reason, defines - the IDN_DISABLE environment variable. - The IDN support is disabled if the variable is set when - dig runs. - - - - - FILES - /etc/resolv.conf - - ${HOME}/.digrc - - - - - SEE ALSO - - host1 - , - - named8 - , - - dnssec-keygen8 - , - RFC1035. - - - - - BUGS - - There are probably too many query options. - - - diff --git a/contrib/bind9/bin/dig/dig.html b/contrib/bind9/bin/dig/dig.html deleted file mode 100644 index afdaa4f..0000000 --- a/contrib/bind9/bin/dig/dig.html +++ /dev/null @@ -1,629 +0,0 @@ - - - - - -dig - - -
-
-
-

Name

-

dig — DNS lookup utility

-
-
-

Synopsis

-

dig [@server] [-b address] [-c class] [-f filename] [-k filename] [-p port#] [-q name] [-t type] [-x addr] [-y [hmac:]name:key] [-4] [-6] [name] [type] [class] [queryopt...]

-

dig [-h]

-

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

-
-
-

DESCRIPTION

-

dig - (domain information groper) is a flexible tool - for interrogating DNS name servers. It performs DNS lookups and - displays the answers that are returned from the name server(s) that - were queried. Most DNS administrators use dig to - troubleshoot DNS problems because of its flexibility, ease of use and - clarity of output. Other lookup tools tend to have less functionality - than dig. -

-

- Although dig is normally used with - command-line - arguments, it also has a batch mode of operation for reading lookup - requests from a file. A brief summary of its command-line arguments - and options is printed when the -h option is given. - Unlike earlier versions, the BIND 9 implementation of - dig allows multiple lookups to be issued - from the - command line. -

-

- Unless it is told to query a specific name server, - dig will try each of the servers listed - in - /etc/resolv.conf. -

-

- When no command line arguments or options are given, will perform an - NS query for "." (the root). -

-

- It is possible to set per-user defaults for dig via - ${HOME}/.digrc. This file is read and - any options in it - are applied before the command line arguments. -

-

- The IN and CH class names overlap with the IN and CH top level - domains names. Either use the -t and - -c options to specify the type and class or - use the -q the specify the domain name or - use "IN." and "CH." when looking up these top level domains. -

-
-
-

SIMPLE USAGE

-

- A typical invocation of dig looks like: -

-
 dig @server name type 
-

- where: - -

-
-
server
-

- is the name or IP address of the name server to query. This can - be an IPv4 - address in dotted-decimal notation or an IPv6 - address in colon-delimited notation. When the supplied - server argument is a - hostname, - dig resolves that name before - querying that name - server. If no server - argument is provided, - dig consults /etc/resolv.conf - and queries the name servers listed there. The reply from the - name - server that responds is displayed. -

-
name
-

- is the name of the resource record that is to be looked up. -

-
type
-

- indicates what type of query is required — - ANY, A, MX, SIG, etc. - type can be any valid query - type. If no - type argument is supplied, - dig will perform a lookup for an - A record. -

-
-

-

-
-
-

OPTIONS

-

- The -b option sets the source IP address of the query - to address. This must be a valid - address on - one of the host's network interfaces or "0.0.0.0" or "::". An optional - port - may be specified by appending "#<port>" -

-

- The default query class (IN for internet) is overridden by the - -c option. class is - any valid - class, such as HS for Hesiod records or CH for Chaosnet records. -

-

- The -f option makes dig - operate - in batch mode by reading a list of lookup requests to process from the - file filename. The file contains a - number of - queries, one per line. Each entry in the file should be organized in - the same way they would be presented as queries to - dig using the command-line interface. -

-

- If a non-standard port number is to be queried, the - -p option is used. port# is - the port number that dig will send its - queries - instead of the standard DNS port number 53. This option would be used - to test a name server that has been configured to listen for queries - on a non-standard port number. -

-

- The -4 option forces dig - to only - use IPv4 query transport. The -6 option forces - dig to only use IPv6 query transport. -

-

- The -t option sets the query type to - type. It can be any valid query type - which is - supported in BIND 9. The default query type is "A", unless the - -x option is supplied to indicate a reverse lookup. - A zone transfer can be requested by specifying a type of AXFR. When - an incremental zone transfer (IXFR) is required, - type is set to ixfr=N. - The incremental zone transfer will contain the changes made to the zone - since the serial number in the zone's SOA record was - N. -

-

- The -q option sets the query name to - name. This useful do distinguish the - name from other arguments. -

-

- Reverse lookups — mapping addresses to names — are simplified by the - -x option. addr is - an IPv4 - address in dotted-decimal notation, or a colon-delimited IPv6 address. - When this option is used, there is no need to provide the - name, class and - type arguments. dig - automatically performs a lookup for a name like - 11.12.13.10.in-addr.arpa and sets the - query type and - class to PTR and IN respectively. By default, IPv6 addresses are - looked up using nibble format under the IP6.ARPA domain. - To use the older RFC1886 method using the IP6.INT domain - specify the -i option. Bit string labels (RFC2874) - are now experimental and are not attempted. -

-

- To sign the DNS queries sent by dig and - their - responses using transaction signatures (TSIG), specify a TSIG key file - using the -k option. You can also specify the TSIG - key itself on the command line using the -y option; - hmac is the type of the TSIG, default HMAC-MD5, - name is the name of the TSIG key and - key is the actual key. The key is a - base-64 - encoded string, typically generated by - dnssec-keygen(8). - - Caution should be taken when using the -y option on - multi-user systems as the key can be visible in the output from - ps(1) - or in the shell's history file. When - using TSIG authentication with dig, the name - server that is queried needs to know the key and algorithm that is - being used. In BIND, this is done by providing appropriate - key and server statements in - named.conf. -

-
-
-

QUERY OPTIONS

-

dig - provides a number of query options which affect - the way in which lookups are made and the results displayed. Some of - these set or reset flag bits in the query header, some determine which - sections of the answer get printed, and others determine the timeout - and retry strategies. -

-

- Each query option is identified by a keyword preceded by a plus sign - (+). Some keywords set or reset an - option. These may be preceded - by the string no to negate the meaning of - that keyword. Other - keywords assign values to options like the timeout interval. They - have the form +keyword=value. - The query options are: - -

-
-
+[no]tcp
-

- Use [do not use] TCP when querying name servers. The default - behavior is to use UDP unless an AXFR or IXFR query is - requested, in - which case a TCP connection is used. -

-
+[no]vc
-

- Use [do not use] TCP when querying name servers. This alternate - syntax to +[no]tcp is - provided for backwards - compatibility. The "vc" stands for "virtual circuit". -

-
+[no]ignore
-

- Ignore truncation in UDP responses instead of retrying with TCP. - By - default, TCP retries are performed. -

-
+domain=somename
-

- Set the search list to contain the single domain - somename, as if specified in - a - domain directive in - /etc/resolv.conf, and enable - search list - processing as if the +search - option were given. -

-
+[no]search
-

- Use [do not use] the search list defined by the searchlist or - domain - directive in resolv.conf (if - any). - The search list is not used by default. -

-
+[no]showsearch
-

- Perform [do not perform] a search showing intermediate - results. -

-
+[no]defname
-

- Deprecated, treated as a synonym for +[no]search -

-
+[no]aaonly
-

- Sets the "aa" flag in the query. -

-
+[no]aaflag
-

- A synonym for +[no]aaonly. -

-
+[no]adflag
-

- Set [do not set] the AD (authentic data) bit in the query. The - AD bit - currently has a standard meaning only in responses, not in - queries, - but the ability to set the bit in the query is provided for - completeness. -

-
+[no]cdflag
-

- Set [do not set] the CD (checking disabled) bit in the query. - This - requests the server to not perform DNSSEC validation of - responses. -

-
+[no]cl
-

- Display [do not display] the CLASS when printing the record. -

-
+[no]ttlid
-

- Display [do not display] the TTL when printing the record. -

-
+[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. -

-
+[no]nssearch
-

- When this option is set, dig - attempts to find the - authoritative name servers for the zone containing the name - being - looked up and display the SOA record that each name server has - for the - 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. -

-
+[no]cmd
-

- Toggles the printing of the initial comment in the output - identifying - the version of dig and the query - options that have - been applied. This comment is printed by default. -

-
+[no]short
-

- Provide a terse answer. The default is to print the answer in a - verbose form. -

-
+[no]identify
-

- Show [or do not show] the IP address and port number that - supplied the - answer when the +short option - is enabled. If - short form answers are requested, the default is not to show the - source address and port number of the server that provided the - answer. -

-
+[no]comments
-

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

-
+[no]stats
-

- This query option toggles the printing of statistics: when the - query - was made, the size of the reply and so on. The default - behavior is - to print the query statistics. -

-
+[no]qr
-

- Print [do not print] the query as it is sent. - By default, the query is not printed. -

-
+[no]question
-

- Print [do not print] the question section of a query when an - answer is - returned. The default is to print the question section as a - comment. -

-
+[no]answer
-

- Display [do not display] the answer section of a reply. The - default - is to display it. -

-
+[no]authority
-

- Display [do not display] the authority section of a reply. The - default is to display it. -

-
+[no]additional
-

- Display [do not display] the additional section of a reply. - The default is to display it. -

-
+[no]all
-

- Set or clear all display flags. -

-
+time=T
-

- - Sets the timeout for a query to - T seconds. The default - timeout is 5 seconds. - An attempt to set T to less - than 1 will result - in a query timeout of 1 second being applied. -

-
+tries=T
-

- Sets the number of times to try UDP queries to server to - T instead of the default, 3. - If - T is less than or equal to - zero, the number of - tries is silently rounded up to 1. -

-
+retry=T
-

- Sets the number of times to retry UDP queries to server to - T instead of the default, 2. - Unlike - +tries, this does not include - the initial - query. -

-
+ndots=D
-

- Set the number of dots that have to appear in - name to D for it to be - considered absolute. The default value is that defined using - the - ndots statement in /etc/resolv.conf, or 1 if no - ndots statement is present. Names with fewer dots are - interpreted as - relative names and will be searched for in the domains listed in - the - search or domain directive in - /etc/resolv.conf. -

-
+bufsize=B
-

- Set the UDP message buffer size advertised using EDNS0 to - B bytes. The maximum and minimum sizes - of this buffer are 65535 and 0 respectively. Values outside - this range are rounded up or down appropriately. - Values other than zero will cause a EDNS query to be sent. -

-
+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. -

-
+[no]multiline
-

- Print records like the SOA records in a verbose multi-line - format with human-readable comments. The default is to print - each record on a single line, to facilitate machine parsing - of the dig output. -

-
+[no]fail
-

- Do not try the next server if you receive a SERVFAIL. The - default is - to not try the next server which is the reverse of normal stub - resolver - behavior. -

-
+[no]besteffort
-

- Attempt to display the contents of messages which are malformed. - The default is to not display malformed answers. -

-
+[no]dnssec
-

- Requests DNSSEC records be sent by setting the DNSSEC OK bit - (DO) - in the OPT record in the additional section of the query. -

-
+[no]sigchase
-

- Chase DNSSEC signature chains. Requires dig be compiled with - -DDIG_SIGCHASE. -

-
+trusted-key=####
-
-

- Specifies a file containing trusted keys to be used with - +sigchase. Each DNSKEY record must be - on its own line. -

-

- If not specified dig will look for - /etc/trusted-key.key then - trusted-key.key in the current directory. -

-

- Requires dig be compiled with -DDIG_SIGCHASE. -

-
-
+[no]topdown
-

- When chasing DNSSEC signature chains perform a top-down - validation. - Requires dig be compiled with -DDIG_SIGCHASE. -

-
-

- -

-
-
-

MULTIPLE QUERIES

-

- The BIND 9 implementation of dig - supports - specifying multiple queries on the command line (in addition to - supporting the -f batch file option). Each of those - queries can be supplied with its own set of flags, options and query - options. -

-

- In this case, each query argument - represent an - individual query in the command-line syntax described above. Each - consists of any of the standard options and flags, the name to be - looked up, an optional query type and class and any query options that - should be applied to that query. -

-

- A global set of query options, which should be applied to all queries, - can also be supplied. These global query options must precede the - first tuple of name, class, type, options, flags, and query options - supplied on the command line. Any global query options (except - the +[no]cmd option) can be - overridden by a query-specific set of query options. For example: -

-
-dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
-
-

- shows how dig could be used from the - command line - to make three lookups: an ANY query for www.isc.org, a - reverse lookup of 127.0.0.1 and a query for the NS records of - isc.org. - - A global query option of +qr is - applied, so - that dig shows the initial query it made - for each - lookup. The final query has a local query option of - +noqr which means that dig - will not print the initial query when it looks up the NS records for - isc.org. -

-
-
-

IDN SUPPORT

-

- If dig has been built with IDN (internationalized - domain name) support, it can accept and display non-ASCII domain names. - dig appropriately converts character encoding of - domain name before sending a request to DNS server or displaying a - reply from the server. - If you'd like to turn off the IDN support for some reason, defines - the IDN_DISABLE environment variable. - The IDN support is disabled if the variable is set when - dig runs. -

-
-
-

FILES

-

/etc/resolv.conf -

-

${HOME}/.digrc -

-
-
-

SEE ALSO

-

host(1), - named(8), - dnssec-keygen(8), - RFC1035. -

-
-
-

BUGS

-

- There are probably too many query options. -

-
-
- diff --git a/contrib/bind9/bin/dig/dighost.c b/contrib/bind9/bin/dig/dighost.c deleted file mode 100644 index 6e7c16b..0000000 --- a/contrib/bind9/bin/dig/dighost.c +++ /dev/null @@ -1,5399 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-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: dighost.c,v 1.259.18.43 2007/08/28 07:19:55 tbox Exp $ */ - -/*! \file - * \note - * Notice to programmers: Do not use this code as an example of how to - * use the ISC library to perform DNS lookups. Dig and Host both operate - * on the request level, since they allow fine-tuning of output and are - * intended as debugging tools. As a result, they perform many of the - * functions which could be better handled using the dns_resolver - * functions in most applications. - */ - -#include -#include -#include -#include -#include - -#ifdef HAVE_LOCALE_H -#include -#endif - -#ifdef WITH_IDN -#include -#include -#include -#include -#endif - -#include -#ifdef DIG_SIGCHASE -#include -#include -#include -#include -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#ifdef DIG_SIGCHASE -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include - -#if ! defined(NS_INADDRSZ) -#define NS_INADDRSZ 4 -#endif - -#if ! defined(NS_IN6ADDRSZ) -#define NS_IN6ADDRSZ 16 -#endif - -static lwres_context_t *lwctx = NULL; -static lwres_conf_t *lwconf; - -dig_lookuplist_t lookup_list; -dig_serverlist_t server_list; -dig_searchlistlist_t search_list; - -isc_boolean_t - check_ra = ISC_FALSE, - have_ipv4 = ISC_FALSE, - have_ipv6 = ISC_FALSE, - specified_source = ISC_FALSE, - free_now = ISC_FALSE, - cancel_now = ISC_FALSE, - usesearch = ISC_FALSE, - showsearch = ISC_FALSE, - qr = ISC_FALSE, - is_dst_up = ISC_FALSE; -in_port_t port = 53; -unsigned int timeout = 0; -unsigned int extrabytes; -isc_mem_t *mctx = NULL; -isc_taskmgr_t *taskmgr = NULL; -isc_task_t *global_task = NULL; -isc_timermgr_t *timermgr = NULL; -isc_socketmgr_t *socketmgr = NULL; -isc_sockaddr_t bind_address; -isc_sockaddr_t bind_any; -int sendcount = 0; -int recvcount = 0; -int sockcount = 0; -int ndots = -1; -int tries = 3; -int lookup_counter = 0; - -#ifdef WITH_IDN -static void initialize_idn(void); -static isc_result_t output_filter(isc_buffer_t *buffer, - unsigned int used_org, - isc_boolean_t absolute); -static idn_result_t append_textname(char *name, const char *origin, - size_t namesize); -static void idn_check_result(idn_result_t r, const char *msg); - -#define MAXDLEN 256 -int idnoptions = 0; -#endif - -/*% - * Exit Codes: - * - *\li 0 Everything went well, including things like NXDOMAIN - *\li 1 Usage error - *\li 7 Got too many RR's or Names - *\li 8 Couldn't open batch file - *\li 9 No reply from server - *\li 10 Internal error - */ -int exitcode = 0; -int fatalexit = 0; -char keynametext[MXNAME]; -char keyfile[MXNAME] = ""; -char keysecret[MXNAME] = ""; -dns_name_t *hmacname = NULL; -unsigned int digestbits = 0; -isc_buffer_t *namebuf = NULL; -dns_tsigkey_t *key = NULL; -isc_boolean_t validated = ISC_TRUE; -isc_entropy_t *entp = NULL; -isc_mempool_t *commctx = NULL; -isc_boolean_t debugging = ISC_FALSE; -isc_boolean_t memdebugging = ISC_FALSE; -char *progname = NULL; -isc_mutex_t lookup_lock; -dig_lookup_t *current_lookup = NULL; - -#ifdef DIG_SIGCHASE - -isc_result_t get_trusted_key(isc_mem_t *mctx); -dns_rdataset_t * sigchase_scanname(dns_rdatatype_t type, - dns_rdatatype_t covers, - isc_boolean_t *lookedup, - dns_name_t *rdata_name); -dns_rdataset_t * chase_scanname_section(dns_message_t *msg, - dns_name_t *name, - dns_rdatatype_t type, - dns_rdatatype_t covers, - int section); -isc_result_t advanced_rrsearch(dns_rdataset_t **rdataset, - dns_name_t *name, - dns_rdatatype_t type, - dns_rdatatype_t covers, - isc_boolean_t *lookedup); -isc_result_t sigchase_verify_sig_key(dns_name_t *name, - dns_rdataset_t *rdataset, - dst_key_t* dnsseckey, - dns_rdataset_t *sigrdataset, - isc_mem_t *mctx); -isc_result_t sigchase_verify_sig(dns_name_t *name, - dns_rdataset_t *rdataset, - dns_rdataset_t *keyrdataset, - dns_rdataset_t *sigrdataset, - isc_mem_t *mctx); -isc_result_t sigchase_verify_ds(dns_name_t *name, - dns_rdataset_t *keyrdataset, - dns_rdataset_t *dsrdataset, - isc_mem_t *mctx); -void sigchase(dns_message_t *msg); -void print_rdata(dns_rdata_t *rdata, isc_mem_t *mctx); -void print_rdataset(dns_name_t *name, - dns_rdataset_t *rdataset, isc_mem_t *mctx); -void dup_name(dns_name_t *source, dns_name_t* target, - isc_mem_t *mctx); -void free_name(dns_name_t *name, isc_mem_t *mctx); -void dump_database(void); -void dump_database_section(dns_message_t *msg, int section); -dns_rdataset_t * search_type(dns_name_t *name, dns_rdatatype_t type, - dns_rdatatype_t covers); -isc_result_t contains_trusted_key(dns_name_t *name, - dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset, - isc_mem_t *mctx); -void print_type(dns_rdatatype_t type); -isc_result_t prove_nx_domain(dns_message_t * msg, - dns_name_t * name, - dns_name_t * rdata_name, - dns_rdataset_t ** rdataset, - dns_rdataset_t ** sigrdataset); -isc_result_t prove_nx_type(dns_message_t * msg, dns_name_t *name, - dns_rdataset_t *nsec, - dns_rdataclass_t class, - dns_rdatatype_t type, - dns_name_t * rdata_name, - dns_rdataset_t ** rdataset, - dns_rdataset_t ** sigrdataset); -isc_result_t prove_nx(dns_message_t * msg, dns_name_t * name, - dns_rdataclass_t class, - dns_rdatatype_t type, - dns_name_t * rdata_name, - dns_rdataset_t ** rdataset, - dns_rdataset_t ** sigrdataset); -static void nameFromString(const char *str, dns_name_t *p_ret); -int inf_name(dns_name_t * name1, dns_name_t * name2); -isc_result_t opentmpkey(isc_mem_t *mctx, const char *file, - char **tempp, FILE **fp); -isc_result_t removetmpkey(isc_mem_t *mctx, const char *file); -void clean_trustedkey(void); -void insert_trustedkey(dst_key_t * key); -#if DIG_SIGCHASE_BU -isc_result_t getneededrr(dns_message_t *msg); -void sigchase_bottom_up(dns_message_t *msg); -void sigchase_bu(dns_message_t *msg); -#endif -#if DIG_SIGCHASE_TD -isc_result_t initialization(dns_name_t *name); -isc_result_t prepare_lookup(dns_name_t *name); -isc_result_t grandfather_pb_test(dns_name_t * zone_name, - dns_rdataset_t *sigrdataset); -isc_result_t child_of_zone(dns_name_t *name, - dns_name_t *zone_name, - dns_name_t *child_name); -void sigchase_td(dns_message_t *msg); -#endif -char trustedkey[MXNAME] = ""; - -dns_rdataset_t *chase_rdataset = NULL; -dns_rdataset_t *chase_sigrdataset = NULL; -dns_rdataset_t *chase_dsrdataset = NULL; -dns_rdataset_t *chase_sigdsrdataset = NULL; -dns_rdataset_t *chase_keyrdataset = NULL; -dns_rdataset_t *chase_sigkeyrdataset = NULL; -dns_rdataset_t *chase_nsrdataset = NULL; - -dns_name_t chase_name; /* the query name */ -#if DIG_SIGCHASE_TD -/* - * the current name is the parent name when we follow delegation - */ -dns_name_t chase_current_name; -/* - * the child name is used for delegation (NS DS responses in AUTHORITY section) - */ -dns_name_t chase_authority_name; -#endif -#if DIG_SIGCHASE_BU -dns_name_t chase_signame; -#endif - - -isc_boolean_t chase_siglookedup = ISC_FALSE; -isc_boolean_t chase_keylookedup = ISC_FALSE; -isc_boolean_t chase_sigkeylookedup = ISC_FALSE; -isc_boolean_t chase_dslookedup = ISC_FALSE; -isc_boolean_t chase_sigdslookedup = ISC_FALSE; -#if DIG_SIGCHASE_TD -isc_boolean_t chase_nslookedup = ISC_FALSE; -isc_boolean_t chase_lookedup = ISC_FALSE; - - -isc_boolean_t delegation_follow = ISC_FALSE; -isc_boolean_t grandfather_pb = ISC_FALSE; -isc_boolean_t have_response = ISC_FALSE; -isc_boolean_t have_delegation_ns = ISC_FALSE; -dns_message_t * error_message = NULL; -#endif - -isc_boolean_t dsvalidating = ISC_FALSE; -isc_boolean_t chase_name_dup = ISC_FALSE; - -ISC_LIST(dig_message_t) chase_message_list; -ISC_LIST(dig_message_t) chase_message_list2; - - -#define MAX_TRUSTED_KEY 5 -typedef struct struct_trusted_key_list { - dst_key_t * key[MAX_TRUSTED_KEY]; - int nb_tk; -} struct_tk_list; - -struct_tk_list tk_list = { {NULL, NULL, NULL, NULL, NULL}, 0}; - -#endif - -#define DIG_MAX_ADDRESSES 20 - -/*% - * Apply and clear locks at the event level in global task. - * Can I get rid of these using shutdown events? XXX - */ -#define LOCK_LOOKUP {\ - debug("lock_lookup %s:%d", __FILE__, __LINE__);\ - check_result(isc_mutex_lock((&lookup_lock)), "isc_mutex_lock");\ - debug("success");\ -} -#define UNLOCK_LOOKUP {\ - debug("unlock_lookup %s:%d", __FILE__, __LINE__);\ - check_result(isc_mutex_unlock((&lookup_lock)),\ - "isc_mutex_unlock");\ -} - -static void -cancel_lookup(dig_lookup_t *lookup); - -static void -recv_done(isc_task_t *task, isc_event_t *event); - -static void -send_udp(dig_query_t *query); - -static void -connect_timeout(isc_task_t *task, isc_event_t *event); - -static void -launch_next_query(dig_query_t *query, isc_boolean_t include_question); - - -static void * -mem_alloc(void *arg, size_t size) { - return (isc_mem_get(arg, size)); -} - -static void -mem_free(void *arg, void *mem, size_t size) { - isc_mem_put(arg, mem, size); -} - -char * -next_token(char **stringp, const char *delim) { - char *res; - - do { - res = strsep(stringp, delim); - if (res == NULL) - break; - } while (*res == '\0'); - return (res); -} - -static int -count_dots(char *string) { - char *s; - int i = 0; - - s = string; - while (*s != '\0') { - if (*s == '.') - i++; - s++; - } - return (i); -} - -static void -hex_dump(isc_buffer_t *b) { - unsigned int len; - isc_region_t r; - - isc_buffer_usedregion(b, &r); - - printf("%d bytes\n", r.length); - for (len = 0; len < r.length; len++) { - printf("%02x ", r.base[len]); - if (len % 16 == 15) - printf("\n"); - } - if (len % 16 != 0) - printf("\n"); -} - -/*% - * Append 'len' bytes of 'text' at '*p', failing with - * ISC_R_NOSPACE if that would advance p past 'end'. - */ -static isc_result_t -append(const char *text, int len, char **p, char *end) { - if (len > end - *p) - return (ISC_R_NOSPACE); - memcpy(*p, text, len); - *p += len; - return (ISC_R_SUCCESS); -} - -static isc_result_t -reverse_octets(const char *in, char **p, char *end) { - char *dot = strchr(in, '.'); - int len; - if (dot != NULL) { - isc_result_t result; - result = reverse_octets(dot + 1, p, end); - if (result != ISC_R_SUCCESS) - return (result); - result = append(".", 1, p, end); - if (result != ISC_R_SUCCESS) - return (result); - len = dot - in; - } else { - len = strlen(in); - } - return (append(in, len, p, end)); -} - -isc_result_t -get_reverse(char *reverse, size_t len, char *value, isc_boolean_t ip6_int, - isc_boolean_t strict) -{ - int r; - isc_result_t result; - isc_netaddr_t addr; - - addr.family = AF_INET6; - r = inet_pton(AF_INET6, value, &addr.type.in6); - if (r > 0) { - /* This is a valid IPv6 address. */ - dns_fixedname_t fname; - dns_name_t *name; - unsigned int options = 0; - - if (ip6_int) - options |= DNS_BYADDROPT_IPV6INT; - dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); - result = dns_byaddr_createptrname2(&addr, options, name); - if (result != ISC_R_SUCCESS) - return (result); - dns_name_format(name, reverse, len); - return (ISC_R_SUCCESS); - } else { - /* - * Not a valid IPv6 address. Assume IPv4. - * If 'strict' is not set, construct the - * in-addr.arpa name by blindly reversing - * octets whether or not they look like integers, - * so that this can be used for RFC2317 names - * and such. - */ - char *p = reverse; - char *end = reverse + len; - if (strict && inet_pton(AF_INET, value, &addr.type.in) != 1) - return (DNS_R_BADDOTTEDQUAD); - result = reverse_octets(value, &p, end); - if (result != ISC_R_SUCCESS) - return (result); - /* Append .in-addr.arpa. and a terminating NUL. */ - result = append(".in-addr.arpa.", 15, &p, end); - if (result != ISC_R_SUCCESS) - return (result); - return (ISC_R_SUCCESS); - } -} - -void -fatal(const char *format, ...) { - va_list args; - - fprintf(stderr, "%s: ", progname); - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); - fprintf(stderr, "\n"); - if (exitcode < 10) - exitcode = 10; - if (fatalexit != 0) - exitcode = fatalexit; - exit(exitcode); -} - -void -debug(const char *format, ...) { - va_list args; - - if (debugging) { - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); - fprintf(stderr, "\n"); - } -} - -void -check_result(isc_result_t result, const char *msg) { - if (result != ISC_R_SUCCESS) { - fatal("%s: %s", msg, isc_result_totext(result)); - } -} - -/*% - * Create a server structure, which is part of the lookup structure. - * This is little more than a linked list of servers to query in hopes - * of finding the answer the user is looking for - */ -dig_server_t * -make_server(const char *servname, const char *userarg) { - dig_server_t *srv; - - REQUIRE(servname != NULL); - - debug("make_server(%s)", servname); - srv = isc_mem_allocate(mctx, sizeof(struct dig_server)); - if (srv == NULL) - fatal("memory allocation failure in %s:%d", - __FILE__, __LINE__); - strncpy(srv->servername, servname, MXNAME); - strncpy(srv->userarg, userarg, MXNAME); - srv->servername[MXNAME-1] = 0; - srv->userarg[MXNAME-1] = 0; - ISC_LINK_INIT(srv, link); - return (srv); -} - -static int -addr2af(int lwresaddrtype) -{ - int af = 0; - - switch (lwresaddrtype) { - case LWRES_ADDRTYPE_V4: - af = AF_INET; - break; - - case LWRES_ADDRTYPE_V6: - af = AF_INET6; - break; - } - - return (af); -} - -/*% - * Create a copy of the server list from the lwres configuration structure. - * The dest list must have already had ISC_LIST_INIT applied. - */ -static void -copy_server_list(lwres_conf_t *confdata, dig_serverlist_t *dest) { - dig_server_t *newsrv; - char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; - int af; - int i; - - debug("copy_server_list()"); - for (i = 0; i < confdata->nsnext; i++) { - af = addr2af(confdata->nameservers[i].family); - - lwres_net_ntop(af, confdata->nameservers[i].address, - tmp, sizeof(tmp)); - newsrv = make_server(tmp, tmp); - ISC_LINK_INIT(newsrv, link); - ISC_LIST_ENQUEUE(*dest, newsrv, link); - } -} - -void -flush_server_list(void) { - dig_server_t *s, *ps; - - debug("flush_server_list()"); - s = ISC_LIST_HEAD(server_list); - while (s != NULL) { - ps = s; - s = ISC_LIST_NEXT(s, link); - ISC_LIST_DEQUEUE(server_list, ps, link); - isc_mem_free(mctx, ps); - } -} - -void -set_nameserver(char *opt) { - isc_result_t result; - isc_sockaddr_t sockaddrs[DIG_MAX_ADDRESSES]; - isc_netaddr_t netaddr; - int count, i; - dig_server_t *srv; - char tmp[ISC_NETADDR_FORMATSIZE]; - - if (opt == NULL) - return; - - result = bind9_getaddresses(opt, 0, sockaddrs, - DIG_MAX_ADDRESSES, &count); - if (result != ISC_R_SUCCESS) - fatal("couldn't get address for '%s': %s", - opt, isc_result_totext(result)); - - flush_server_list(); - - for (i = 0; i < count; i++) { - isc_netaddr_fromsockaddr(&netaddr, &sockaddrs[i]); - isc_netaddr_format(&netaddr, tmp, sizeof(tmp)); - srv = make_server(tmp, opt); - if (srv == NULL) - fatal("memory allocation failure"); - ISC_LIST_APPEND(server_list, srv, link); - } -} - -static isc_result_t -add_nameserver(lwres_conf_t *confdata, const char *addr, int af) { - - int i = confdata->nsnext; - - if (confdata->nsnext >= LWRES_CONFMAXNAMESERVERS) - return (ISC_R_FAILURE); - - switch (af) { - case AF_INET: - confdata->nameservers[i].family = LWRES_ADDRTYPE_V4; - confdata->nameservers[i].length = NS_INADDRSZ; - break; - case AF_INET6: - confdata->nameservers[i].family = LWRES_ADDRTYPE_V6; - confdata->nameservers[i].length = NS_IN6ADDRSZ; - break; - default: - return (ISC_R_FAILURE); - } - - if (lwres_net_pton(af, addr, &confdata->nameservers[i].address) == 1) { - confdata->nsnext++; - return (ISC_R_SUCCESS); - } - return (ISC_R_FAILURE); -} - -/*% - * Produce a cloned server list. The dest list must have already had - * ISC_LIST_INIT applied. - */ -void -clone_server_list(dig_serverlist_t src, dig_serverlist_t *dest) { - dig_server_t *srv, *newsrv; - - debug("clone_server_list()"); - srv = ISC_LIST_HEAD(src); - while (srv != NULL) { - newsrv = make_server(srv->servername, srv->userarg); - ISC_LINK_INIT(newsrv, link); - ISC_LIST_ENQUEUE(*dest, newsrv, link); - srv = ISC_LIST_NEXT(srv, link); - } -} - -/*% - * Create an empty lookup structure, which holds all the information needed - * to get an answer to a user's question. This structure contains two - * linked lists: the server list (servers to query) and the query list - * (outstanding queries which have been made to the listed servers). - */ -dig_lookup_t * -make_empty_lookup(void) { - dig_lookup_t *looknew; - - debug("make_empty_lookup()"); - - INSIST(!free_now); - - looknew = isc_mem_allocate(mctx, sizeof(struct dig_lookup)); - if (looknew == NULL) - fatal("memory allocation failure in %s:%d", - __FILE__, __LINE__); - looknew->pending = ISC_TRUE; - looknew->textname[0] = 0; - looknew->cmdline[0] = 0; - looknew->rdtype = dns_rdatatype_a; - looknew->qrdtype = dns_rdatatype_a; - looknew->rdclass = dns_rdataclass_in; - looknew->rdtypeset = ISC_FALSE; - looknew->rdclassset = ISC_FALSE; - looknew->sendspace = NULL; - looknew->sendmsg = NULL; - looknew->name = NULL; - looknew->oname = NULL; - looknew->timer = NULL; - looknew->xfr_q = NULL; - looknew->current_query = NULL; - looknew->doing_xfr = ISC_FALSE; - looknew->ixfr_serial = ISC_FALSE; - looknew->trace = ISC_FALSE; - looknew->trace_root = ISC_FALSE; - looknew->identify = ISC_FALSE; - looknew->identify_previous_line = ISC_FALSE; - looknew->ignore = ISC_FALSE; - looknew->servfail_stops = ISC_TRUE; - looknew->besteffort = ISC_TRUE; - looknew->dnssec = ISC_FALSE; -#ifdef DIG_SIGCHASE - looknew->sigchase = ISC_FALSE; -#if DIG_SIGCHASE_TD - looknew->do_topdown = ISC_FALSE; - looknew->trace_root_sigchase = ISC_FALSE; - looknew->rdtype_sigchaseset = ISC_FALSE; - looknew->rdtype_sigchase = dns_rdatatype_any; - looknew->qrdtype_sigchase = dns_rdatatype_any; - looknew->rdclass_sigchase = dns_rdataclass_in; - looknew->rdclass_sigchaseset = ISC_FALSE; -#endif -#endif - looknew->udpsize = 0; - looknew->edns = -1; - looknew->recurse = ISC_TRUE; - looknew->aaonly = ISC_FALSE; - looknew->adflag = ISC_FALSE; - looknew->cdflag = ISC_FALSE; - looknew->ns_search_only = ISC_FALSE; - looknew->origin = NULL; - looknew->tsigctx = NULL; - looknew->querysig = NULL; - looknew->retries = tries; - looknew->nsfound = 0; - looknew->tcp_mode = ISC_FALSE; - looknew->ip6_int = ISC_FALSE; - looknew->comments = ISC_TRUE; - looknew->stats = ISC_TRUE; - looknew->section_question = ISC_TRUE; - looknew->section_answer = ISC_TRUE; - looknew->section_authority = ISC_TRUE; - looknew->section_additional = ISC_TRUE; - looknew->new_search = ISC_FALSE; - looknew->done_as_is = ISC_FALSE; - looknew->need_search = ISC_FALSE; - ISC_LINK_INIT(looknew, link); - ISC_LIST_INIT(looknew->q); - ISC_LIST_INIT(looknew->my_server_list); - return (looknew); -} - -/*% - * Clone a lookup, perhaps copying the server list. This does not clone - * the query list, since it will be regenerated by the setup_lookup() - * function, nor does it queue up the new lookup for processing. - * Caution: If you don't clone the servers, you MUST clone the server - * list seperately from somewhere else, or construct it by hand. - */ -dig_lookup_t * -clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) { - dig_lookup_t *looknew; - - debug("clone_lookup()"); - - INSIST(!free_now); - - looknew = make_empty_lookup(); - INSIST(looknew != NULL); - strncpy(looknew->textname, lookold->textname, MXNAME); -#if DIG_SIGCHASE_TD - strncpy(looknew->textnamesigchase, lookold->textnamesigchase, MXNAME); -#endif - strncpy(looknew->cmdline, lookold->cmdline, MXNAME); - looknew->textname[MXNAME-1] = 0; - looknew->rdtype = lookold->rdtype; - looknew->qrdtype = lookold->qrdtype; - looknew->rdclass = lookold->rdclass; - looknew->rdtypeset = lookold->rdtypeset; - looknew->rdclassset = lookold->rdclassset; - looknew->doing_xfr = lookold->doing_xfr; - looknew->ixfr_serial = lookold->ixfr_serial; - looknew->trace = lookold->trace; - looknew->trace_root = lookold->trace_root; - looknew->identify = lookold->identify; - looknew->identify_previous_line = lookold->identify_previous_line; - looknew->ignore = lookold->ignore; - looknew->servfail_stops = lookold->servfail_stops; - looknew->besteffort = lookold->besteffort; - looknew->dnssec = lookold->dnssec; -#ifdef DIG_SIGCHASE - looknew->sigchase = lookold->sigchase; -#if DIG_SIGCHASE_TD - looknew->do_topdown = lookold->do_topdown; - looknew->trace_root_sigchase = lookold->trace_root_sigchase; - looknew->rdtype_sigchaseset = lookold->rdtype_sigchaseset; - looknew->rdtype_sigchase = lookold->rdtype_sigchase; - looknew->qrdtype_sigchase = lookold->qrdtype_sigchase; - looknew->rdclass_sigchase = lookold->rdclass_sigchase; - looknew->rdclass_sigchaseset = lookold->rdclass_sigchaseset; -#endif -#endif - looknew->udpsize = lookold->udpsize; - looknew->edns = lookold->edns; - looknew->recurse = lookold->recurse; - looknew->aaonly = lookold->aaonly; - looknew->adflag = lookold->adflag; - looknew->cdflag = lookold->cdflag; - looknew->ns_search_only = lookold->ns_search_only; - looknew->tcp_mode = lookold->tcp_mode; - looknew->comments = lookold->comments; - looknew->stats = lookold->stats; - looknew->section_question = lookold->section_question; - looknew->section_answer = lookold->section_answer; - looknew->section_authority = lookold->section_authority; - looknew->section_additional = lookold->section_additional; - looknew->retries = lookold->retries; - looknew->tsigctx = NULL; - looknew->need_search = lookold->need_search; - looknew->done_as_is = lookold->done_as_is; - - if (servers) - clone_server_list(lookold->my_server_list, - &looknew->my_server_list); - return (looknew); -} - -/*% - * Requeue a lookup for further processing, perhaps copying the server - * list. The new lookup structure is returned to the caller, and is - * queued for processing. If servers are not cloned in the requeue, they - * must be added before allowing the current event to complete, since the - * completion of the event may result in the next entry on the lookup - * queue getting run. - */ -dig_lookup_t * -requeue_lookup(dig_lookup_t *lookold, isc_boolean_t servers) { - dig_lookup_t *looknew; - - debug("requeue_lookup()"); - - lookup_counter++; - if (lookup_counter > LOOKUP_LIMIT) - fatal("too many lookups"); - - looknew = clone_lookup(lookold, servers); - INSIST(looknew != NULL); - - debug("before insertion, init@%p -> %p, new@%p -> %p", - lookold, lookold->link.next, looknew, looknew->link.next); - ISC_LIST_PREPEND(lookup_list, looknew, link); - debug("after insertion, init -> %p, new = %p, new -> %p", - lookold, looknew, looknew->link.next); - return (looknew); -} - - -static void -setup_text_key(void) { - isc_result_t result; - dns_name_t keyname; - isc_buffer_t secretbuf; - int secretsize; - unsigned char *secretstore; - - debug("setup_text_key()"); - result = isc_buffer_allocate(mctx, &namebuf, MXNAME); - check_result(result, "isc_buffer_allocate"); - dns_name_init(&keyname, NULL); - check_result(result, "dns_name_init"); - isc_buffer_putstr(namebuf, keynametext); - secretsize = strlen(keysecret) * 3 / 4; - secretstore = isc_mem_allocate(mctx, secretsize); - if (secretstore == NULL) - fatal("memory allocation failure in %s:%d", - __FILE__, __LINE__); - isc_buffer_init(&secretbuf, secretstore, secretsize); - result = isc_base64_decodestring(keysecret, &secretbuf); - if (result != ISC_R_SUCCESS) - goto failure; - - secretsize = isc_buffer_usedlength(&secretbuf); - - result = dns_name_fromtext(&keyname, namebuf, - dns_rootname, ISC_FALSE, - namebuf); - if (result != ISC_R_SUCCESS) - goto failure; - - result = dns_tsigkey_create(&keyname, hmacname, secretstore, - secretsize, ISC_FALSE, NULL, 0, 0, mctx, - NULL, &key); - failure: - if (result != ISC_R_SUCCESS) - printf(";; Couldn't create key %s: %s\n", - keynametext, isc_result_totext(result)); - else - dst_key_setbits(key->key, digestbits); - - isc_mem_free(mctx, secretstore); - dns_name_invalidate(&keyname); - isc_buffer_free(&namebuf); -} - -static void -setup_file_key(void) { - isc_result_t result; - dst_key_t *dstkey = NULL; - - debug("setup_file_key()"); - result = dst_key_fromnamedfile(keyfile, DST_TYPE_PRIVATE | DST_TYPE_KEY, - mctx, &dstkey); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "Couldn't read key from %s: %s\n", - keyfile, isc_result_totext(result)); - goto failure; - } - - switch (dst_key_alg(dstkey)) { - case DST_ALG_HMACMD5: - hmacname = DNS_TSIG_HMACMD5_NAME; - break; - case DST_ALG_HMACSHA1: - hmacname = DNS_TSIG_HMACSHA1_NAME; - break; - case DST_ALG_HMACSHA224: - hmacname = DNS_TSIG_HMACSHA224_NAME; - break; - case DST_ALG_HMACSHA256: - hmacname = DNS_TSIG_HMACSHA256_NAME; - break; - case DST_ALG_HMACSHA384: - hmacname = DNS_TSIG_HMACSHA384_NAME; - break; - case DST_ALG_HMACSHA512: - hmacname = DNS_TSIG_HMACSHA512_NAME; - break; - default: - printf(";; Couldn't create key %s: bad algorithm\n", - keynametext); - goto failure; - } - result = dns_tsigkey_createfromkey(dst_key_name(dstkey), hmacname, - dstkey, ISC_FALSE, NULL, 0, 0, - mctx, NULL, &key); - if (result != ISC_R_SUCCESS) { - printf(";; Couldn't create key %s: %s\n", - keynametext, isc_result_totext(result)); - goto failure; - } - dstkey = NULL; - failure: - if (dstkey != NULL) - dst_key_free(&dstkey); -} - -static dig_searchlist_t * -make_searchlist_entry(char *domain) { - dig_searchlist_t *search; - search = isc_mem_allocate(mctx, sizeof(*search)); - if (search == NULL) - fatal("memory allocation failure in %s:%d", - __FILE__, __LINE__); - strncpy(search->origin, domain, MXNAME); - search->origin[MXNAME-1] = 0; - ISC_LINK_INIT(search, link); - return (search); -} - -static void -create_search_list(lwres_conf_t *confdata) { - int i; - dig_searchlist_t *search; - - debug("create_search_list()"); - ISC_LIST_INIT(search_list); - - for (i = 0; i < confdata->searchnxt; i++) { - search = make_searchlist_entry(confdata->search[i]); - ISC_LIST_APPEND(search_list, search, link); - } -} - -/*% - * Setup the system as a whole, reading key information and resolv.conf - * settings. - */ -void -setup_system(void) { - dig_searchlist_t *domain = NULL; - lwres_result_t lwresult; - - debug("setup_system()"); - - lwresult = lwres_context_create(&lwctx, mctx, mem_alloc, mem_free, 1); - if (lwresult != LWRES_R_SUCCESS) - fatal("lwres_context_create failed"); - - lwresult = lwres_conf_parse(lwctx, RESOLV_CONF); - if (lwresult != LWRES_R_SUCCESS && lwresult != LWRES_R_NOTFOUND) - fatal("parse of %s failed", RESOLV_CONF); - - lwconf = lwres_conf_get(lwctx); - - /* Make the search list */ - if (lwconf->searchnxt > 0) - create_search_list(lwconf); - else { /* No search list. Use the domain name if any */ - if (lwconf->domainname != NULL) { - domain = make_searchlist_entry(lwconf->domainname); - ISC_LIST_INITANDAPPEND(search_list, domain, link); - domain = NULL; - } - } - - if (ndots == -1) { - ndots = lwconf->ndots; - debug("ndots is %d.", ndots); - } - - /* If we don't find a nameserver fall back to localhost */ - if (lwconf->nsnext == 0) { - if (have_ipv4) { - lwresult = add_nameserver(lwconf, "127.0.0.1", AF_INET); - if (lwresult != ISC_R_SUCCESS) - fatal("add_nameserver failed"); - } - if (have_ipv6) { - lwresult = add_nameserver(lwconf, "::1", AF_INET6); - if (lwresult != ISC_R_SUCCESS) - fatal("add_nameserver failed"); - } - } - - if (ISC_LIST_EMPTY(server_list)) - copy_server_list(lwconf, &server_list); - -#ifdef WITH_IDN - initialize_idn(); -#endif - - if (keyfile[0] != 0) - setup_file_key(); - else if (keysecret[0] != 0) - setup_text_key(); -#ifdef DIG_SIGCHASE - /* Setup the list of messages for +sigchase */ - ISC_LIST_INIT(chase_message_list); - ISC_LIST_INIT(chase_message_list2); - dns_name_init(&chase_name, NULL); -#if DIG_SIGCHASE_TD - dns_name_init(&chase_current_name, NULL); - dns_name_init(&chase_authority_name, NULL); -#endif -#if DIG_SIGCHASE_BU - dns_name_init(&chase_signame, NULL); -#endif - -#endif - -} - -static void -clear_searchlist(void) { - dig_searchlist_t *search; - while ((search = ISC_LIST_HEAD(search_list)) != NULL) { - ISC_LIST_UNLINK(search_list, search, link); - isc_mem_free(mctx, search); - } -} - -/*% - * Override the search list derived from resolv.conf by 'domain'. - */ -void -set_search_domain(char *domain) { - dig_searchlist_t *search; - - clear_searchlist(); - search = make_searchlist_entry(domain); - ISC_LIST_APPEND(search_list, search, link); -} - -/*% - * Setup the ISC and DNS libraries for use by the system. - */ -void -setup_libs(void) { - isc_result_t result; - - debug("setup_libs()"); - - result = isc_net_probeipv4(); - if (result == ISC_R_SUCCESS) - have_ipv4 = ISC_TRUE; - - result = isc_net_probeipv6(); - if (result == ISC_R_SUCCESS) - have_ipv6 = ISC_TRUE; - if (!have_ipv6 && !have_ipv4) - fatal("can't find either v4 or v6 networking"); - - result = isc_mem_create(0, 0, &mctx); - check_result(result, "isc_mem_create"); - - result = isc_taskmgr_create(mctx, 1, 0, &taskmgr); - check_result(result, "isc_taskmgr_create"); - - result = isc_task_create(taskmgr, 0, &global_task); - check_result(result, "isc_task_create"); - - result = isc_timermgr_create(mctx, &timermgr); - check_result(result, "isc_timermgr_create"); - - result = isc_socketmgr_create(mctx, &socketmgr); - check_result(result, "isc_socketmgr_create"); - - result = isc_entropy_create(mctx, &entp); - check_result(result, "isc_entropy_create"); - - result = dst_lib_init(mctx, entp, 0); - check_result(result, "dst_lib_init"); - is_dst_up = ISC_TRUE; - - result = isc_mempool_create(mctx, COMMSIZE, &commctx); - check_result(result, "isc_mempool_create"); - isc_mempool_setname(commctx, "COMMPOOL"); - /* - * 6 and 2 set as reasonable parameters for 3 or 4 nameserver - * systems. - */ - isc_mempool_setfreemax(commctx, 6); - isc_mempool_setfillcount(commctx, 2); - - result = isc_mutex_init(&lookup_lock); - check_result(result, "isc_mutex_init"); - - dns_result_register(); -} - -/*% - * Add EDNS0 option record to a message. Currently, the only supported - * options are UDP buffer size and the DO bit. - */ -static void -add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_uint16_t edns, - isc_boolean_t dnssec) -{ - dns_rdataset_t *rdataset = NULL; - dns_rdatalist_t *rdatalist = NULL; - dns_rdata_t *rdata = NULL; - isc_result_t result; - - debug("add_opt()"); - result = dns_message_gettemprdataset(msg, &rdataset); - check_result(result, "dns_message_gettemprdataset"); - dns_rdataset_init(rdataset); - result = dns_message_gettemprdatalist(msg, &rdatalist); - check_result(result, "dns_message_gettemprdatalist"); - result = dns_message_gettemprdata(msg, &rdata); - check_result(result, "dns_message_gettemprdata"); - - debug("setting udp size of %d", udpsize); - rdatalist->type = dns_rdatatype_opt; - rdatalist->covers = 0; - rdatalist->rdclass = udpsize; - rdatalist->ttl = edns << 16; - if (dnssec) - rdatalist->ttl |= DNS_MESSAGEEXTFLAG_DO; - rdata->data = NULL; - rdata->length = 0; - ISC_LIST_INIT(rdatalist->rdata); - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - dns_rdatalist_tordataset(rdatalist, rdataset); - result = dns_message_setopt(msg, rdataset); - check_result(result, "dns_message_setopt"); -} - -/*% - * Add a question section to a message, asking for the specified name, - * type, and class. - */ -static void -add_question(dns_message_t *message, dns_name_t *name, - dns_rdataclass_t rdclass, dns_rdatatype_t rdtype) -{ - dns_rdataset_t *rdataset; - isc_result_t result; - - debug("add_question()"); - rdataset = NULL; - result = dns_message_gettemprdataset(message, &rdataset); - check_result(result, "dns_message_gettemprdataset()"); - dns_rdataset_init(rdataset); - dns_rdataset_makequestion(rdataset, rdclass, rdtype); - ISC_LIST_APPEND(name->list, rdataset, link); -} - -/*% - * Check if we're done with all the queued lookups, which is true iff - * all sockets, sends, and recvs are accounted for (counters == 0), - * and the lookup list is empty. - * If we are done, pass control back out to dighost_shutdown() (which is - * part of dig.c, host.c, or nslookup.c) to either shutdown the system as - * a whole or reseed the lookup list. - */ -static void -check_if_done(void) { - debug("check_if_done()"); - debug("list %s", ISC_LIST_EMPTY(lookup_list) ? "empty" : "full"); - if (ISC_LIST_EMPTY(lookup_list) && current_lookup == NULL && - sendcount == 0) { - INSIST(sockcount == 0); - INSIST(recvcount == 0); - debug("shutting down"); - dighost_shutdown(); - } -} - -/*% - * Clear out a query when we're done with it. WARNING: This routine - * WILL invalidate the query pointer. - */ -static void -clear_query(dig_query_t *query) { - dig_lookup_t *lookup; - - REQUIRE(query != NULL); - - debug("clear_query(%p)", query); - - lookup = query->lookup; - - if (lookup->current_query == query) - lookup->current_query = NULL; - - ISC_LIST_UNLINK(lookup->q, query, link); - if (ISC_LINK_LINKED(&query->recvbuf, link)) - ISC_LIST_DEQUEUE(query->recvlist, &query->recvbuf, - link); - if (ISC_LINK_LINKED(&query->lengthbuf, link)) - ISC_LIST_DEQUEUE(query->lengthlist, &query->lengthbuf, - link); - INSIST(query->recvspace != NULL); - if (query->sock != NULL) { - isc_socket_detach(&query->sock); - sockcount--; - debug("sockcount=%d", sockcount); - } - isc_mempool_put(commctx, query->recvspace); - isc_buffer_invalidate(&query->recvbuf); - isc_buffer_invalidate(&query->lengthbuf); - if (query->waiting_senddone) - query->pending_free = ISC_TRUE; - else - isc_mem_free(mctx, query); -} - -/*% - * Try and clear out a lookup if we're done with it. Return ISC_TRUE if - * the lookup was successfully cleared. If ISC_TRUE is returned, the - * lookup pointer has been invalidated. - */ -static isc_boolean_t -try_clear_lookup(dig_lookup_t *lookup) { - dig_query_t *q; - - REQUIRE(lookup != NULL); - - debug("try_clear_lookup(%p)", lookup); - - if (ISC_LIST_HEAD(lookup->q) != NULL) { - if (debugging) { - q = ISC_LIST_HEAD(lookup->q); - while (q != NULL) { - debug("query to %s still pending", q->servname); - q = ISC_LIST_NEXT(q, link); - } - } - return (ISC_FALSE); - } - - /* - * At this point, we know there are no queries on the lookup, - * so can make it go away also. - */ - destroy_lookup(lookup); - return (ISC_TRUE); -} - -void -destroy_lookup(dig_lookup_t *lookup) { - dig_server_t *s; - void *ptr; - - debug("destroy"); - s = ISC_LIST_HEAD(lookup->my_server_list); - while (s != NULL) { - debug("freeing server %p belonging to %p", s, lookup); - ptr = s; - s = ISC_LIST_NEXT(s, link); - ISC_LIST_DEQUEUE(lookup->my_server_list, - (dig_server_t *)ptr, link); - isc_mem_free(mctx, ptr); - } - if (lookup->sendmsg != NULL) - dns_message_destroy(&lookup->sendmsg); - if (lookup->querysig != NULL) { - debug("freeing buffer %p", lookup->querysig); - isc_buffer_free(&lookup->querysig); - } - if (lookup->timer != NULL) - isc_timer_detach(&lookup->timer); - if (lookup->sendspace != NULL) - isc_mempool_put(commctx, lookup->sendspace); - - if (lookup->tsigctx != NULL) - dst_context_destroy(&lookup->tsigctx); - - isc_mem_free(mctx, lookup); -} - -/*% - * If we can, start the next lookup in the queue running. - * This assumes that the lookup on the head of the queue hasn't been - * started yet. It also removes the lookup from the head of the queue, - * setting the current_lookup pointer pointing to it. - */ -void -start_lookup(void) { - debug("start_lookup()"); - if (cancel_now) - return; - - /* - * If there's a current lookup running, we really shouldn't get - * here. - */ - INSIST(current_lookup == NULL); - - current_lookup = ISC_LIST_HEAD(lookup_list); - /* - * Put the current lookup somewhere so cancel_all can find it - */ - if (current_lookup != NULL) { - ISC_LIST_DEQUEUE(lookup_list, current_lookup, link); -#if DIG_SIGCHASE_TD - if (current_lookup->do_topdown && - !current_lookup->rdtype_sigchaseset) { - dst_key_t *trustedkey = NULL; - isc_buffer_t *b = NULL; - isc_region_t r; - isc_result_t result; - dns_name_t query_name; - dns_name_t *key_name; - int i; - - result = get_trusted_key(mctx); - if (result != ISC_R_SUCCESS) { - printf("\n;; No trusted key, " - "+sigchase option is disabled\n"); - current_lookup->sigchase = ISC_FALSE; - goto novalidation; - } - dns_name_init(&query_name, NULL); - nameFromString(current_lookup->textname, &query_name); - - for (i = 0; i < tk_list.nb_tk; i++) { - key_name = dst_key_name(tk_list.key[i]); - - if (dns_name_issubdomain(&query_name, - key_name) == ISC_TRUE) - trustedkey = tk_list.key[i]; - /* - * Verifier que la temp est bien la plus basse - * WARNING - */ - } - if (trustedkey == NULL) { - printf("\n;; The queried zone: "); - dns_name_print(&query_name, stdout); - printf(" isn't a subdomain of any Trusted Keys" - ": +sigchase option is disable\n"); - current_lookup->sigchase = ISC_FALSE; - free_name(&query_name, mctx); - goto novalidation; - } - free_name(&query_name, mctx); - - current_lookup->rdtype_sigchase - = current_lookup->rdtype; - current_lookup->rdtype_sigchaseset - = current_lookup->rdtypeset; - current_lookup->rdtype = dns_rdatatype_ns; - - current_lookup->qrdtype_sigchase - = current_lookup->qrdtype; - current_lookup->qrdtype = dns_rdatatype_ns; - - current_lookup->rdclass_sigchase - = current_lookup->rdclass; - current_lookup->rdclass_sigchaseset - = current_lookup->rdclassset; - current_lookup->rdclass = dns_rdataclass_in; - - strncpy(current_lookup->textnamesigchase, - current_lookup->textname, MXNAME); - - current_lookup->trace_root_sigchase = ISC_TRUE; - - result = isc_buffer_allocate(mctx, &b, BUFSIZE); - check_result(result, "isc_buffer_allocate"); - result = dns_name_totext(dst_key_name(trustedkey), - ISC_FALSE, b); - check_result(result, "dns_name_totext"); - isc_buffer_usedregion(b, &r); - r.base[r.length] = '\0'; - strncpy(current_lookup->textname, (char*)r.base, - MXNAME); - isc_buffer_free(&b); - - nameFromString(current_lookup->textnamesigchase, - &chase_name); - - dns_name_init(&chase_authority_name, NULL); - } - novalidation: -#endif - setup_lookup(current_lookup); - do_lookup(current_lookup); - } else { - check_if_done(); - } -} - -/*% - * If we can, clear the current lookup and start the next one running. - * This calls try_clear_lookup, so may invalidate the lookup pointer. - */ -static void -check_next_lookup(dig_lookup_t *lookup) { - - INSIST(!free_now); - - debug("check_next_lookup(%p)", lookup); - - if (ISC_LIST_HEAD(lookup->q) != NULL) { - debug("still have a worker"); - return; - } - if (try_clear_lookup(lookup)) { - current_lookup = NULL; - start_lookup(); - } -} - -/*% - * Create and queue a new lookup as a followup to the current lookup, - * based on the supplied message and section. This is used in trace and - * name server search modes to start a new lookup using servers from - * NS records in a reply. Returns the number of followup lookups made. - */ -static int -followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section) -{ - dig_lookup_t *lookup = NULL; - dig_server_t *srv = NULL; - dns_rdataset_t *rdataset = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_name_t *name = NULL; - isc_result_t result; - isc_boolean_t success = ISC_FALSE; - int numLookups = 0; - dns_name_t *domain; - isc_boolean_t horizontal = ISC_FALSE, bad = ISC_FALSE; - - INSIST(!free_now); - - debug("following up %s", query->lookup->textname); - - for (result = dns_message_firstname(msg, section); - result == ISC_R_SUCCESS; - result = dns_message_nextname(msg, section)) { - name = NULL; - dns_message_currentname(msg, section, &name); - - if (section == DNS_SECTION_AUTHORITY) { - rdataset = NULL; - result = dns_message_findtype(name, dns_rdatatype_soa, - 0, &rdataset); - if (result == ISC_R_SUCCESS) - return (0); - } - rdataset = NULL; - result = dns_message_findtype(name, dns_rdatatype_ns, 0, - &rdataset); - if (result != ISC_R_SUCCESS) - continue; - - debug("found NS set"); - - if (query->lookup->trace && !query->lookup->trace_root) { - dns_namereln_t namereln; - unsigned int nlabels; - int order; - - domain = dns_fixedname_name(&query->lookup->fdomain); - namereln = dns_name_fullcompare(name, domain, - &order, &nlabels); - if (namereln == dns_namereln_equal) { - if (!horizontal) - printf(";; BAD (HORIZONTAL) REFERRAL\n"); - horizontal = ISC_TRUE; - } else if (namereln != dns_namereln_subdomain) { - if (!bad) - printf(";; BAD REFERRAL\n"); - bad = ISC_TRUE; - continue; - } - } - - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - char namestr[DNS_NAME_FORMATSIZE]; - dns_rdata_ns_t ns; - - if (query->lookup->trace_root && - query->lookup->nsfound >= MXSERV) - break; - - dns_rdataset_current(rdataset, &rdata); - - query->lookup->nsfound++; - (void)dns_rdata_tostruct(&rdata, &ns, NULL); - dns_name_format(&ns.name, namestr, sizeof(namestr)); - dns_rdata_freestruct(&ns); - - /* Initialize lookup if we've not yet */ - debug("found NS %d %s", numLookups, namestr); - numLookups++; - if (!success) { - success = ISC_TRUE; - lookup_counter++; - lookup = requeue_lookup(query->lookup, - ISC_FALSE); - cancel_lookup(query->lookup); - lookup->doing_xfr = ISC_FALSE; - if (!lookup->trace_root && - section == DNS_SECTION_ANSWER) - lookup->trace = ISC_FALSE; - else - lookup->trace = query->lookup->trace; - lookup->ns_search_only = - query->lookup->ns_search_only; - lookup->trace_root = ISC_FALSE; - if (lookup->ns_search_only) - lookup->recurse = ISC_FALSE; - dns_fixedname_init(&lookup->fdomain); - domain = dns_fixedname_name(&lookup->fdomain); - dns_name_copy(name, domain, NULL); - } - srv = make_server(namestr, namestr); - debug("adding server %s", srv->servername); - ISC_LIST_APPEND(lookup->my_server_list, srv, link); - dns_rdata_reset(&rdata); - } - } - - if (lookup == NULL && - section == DNS_SECTION_ANSWER && - (query->lookup->trace || query->lookup->ns_search_only)) - return (followup_lookup(msg, query, DNS_SECTION_AUTHORITY)); - - /* - * Randomize the order the nameserver will be tried. - */ - if (numLookups > 1) { - isc_uint32_t i, j; - dig_serverlist_t my_server_list; - - ISC_LIST_INIT(my_server_list); - - for (i = numLookups; i > 0; i--) { - isc_random_get(&j); - j %= i; - srv = ISC_LIST_HEAD(lookup->my_server_list); - while (j-- > 0) - srv = ISC_LIST_NEXT(srv, link); - ISC_LIST_DEQUEUE(lookup->my_server_list, srv, link); - ISC_LIST_APPEND(my_server_list, srv, link); - } - ISC_LIST_APPENDLIST(lookup->my_server_list, - my_server_list, link); - } - - return (numLookups); -} - -/*% - * Create and queue a new lookup using the next origin from the search - * list, read in setup_system(). - * - * Return ISC_TRUE iff there was another searchlist entry. - */ -static isc_boolean_t -next_origin(dns_message_t *msg, dig_query_t *query) { - dig_lookup_t *lookup; - dig_searchlist_t *search; - - UNUSED(msg); - - INSIST(!free_now); - - debug("next_origin()"); - debug("following up %s", query->lookup->textname); - - if (!usesearch) - /* - * We're not using a search list, so don't even think - * about finding the next entry. - */ - return (ISC_FALSE); - if (query->lookup->origin == NULL && !query->lookup->need_search) - /* - * Then we just did rootorg; there's nothing left. - */ - return (ISC_FALSE); - if (query->lookup->origin == NULL && query->lookup->need_search) { - lookup = requeue_lookup(query->lookup, ISC_TRUE); - lookup->origin = ISC_LIST_HEAD(search_list); - lookup->need_search = ISC_FALSE; - } else { - search = ISC_LIST_NEXT(query->lookup->origin, link); - if (search == NULL && query->lookup->done_as_is) - return (ISC_FALSE); - lookup = requeue_lookup(query->lookup, ISC_TRUE); - lookup->origin = search; - } - cancel_lookup(query->lookup); - return (ISC_TRUE); -} - -/*% - * Insert an SOA record into the sendmessage in a lookup. Used for - * creating IXFR queries. - */ -static void -insert_soa(dig_lookup_t *lookup) { - isc_result_t result; - dns_rdata_soa_t soa; - dns_rdata_t *rdata = NULL; - dns_rdatalist_t *rdatalist = NULL; - dns_rdataset_t *rdataset = NULL; - dns_name_t *soaname = NULL; - - debug("insert_soa()"); - soa.mctx = mctx; - soa.serial = lookup->ixfr_serial; - soa.refresh = 0; - soa.retry = 0; - soa.expire = 0; - soa.minimum = 0; - soa.common.rdclass = lookup->rdclass; - soa.common.rdtype = dns_rdatatype_soa; - - dns_name_init(&soa.origin, NULL); - dns_name_init(&soa.contact, NULL); - - dns_name_clone(dns_rootname, &soa.origin); - dns_name_clone(dns_rootname, &soa.contact); - - isc_buffer_init(&lookup->rdatabuf, lookup->rdatastore, - sizeof(lookup->rdatastore)); - - result = dns_message_gettemprdata(lookup->sendmsg, &rdata); - check_result(result, "dns_message_gettemprdata"); - - result = dns_rdata_fromstruct(rdata, lookup->rdclass, - dns_rdatatype_soa, &soa, - &lookup->rdatabuf); - check_result(result, "isc_rdata_fromstruct"); - - result = dns_message_gettemprdatalist(lookup->sendmsg, &rdatalist); - check_result(result, "dns_message_gettemprdatalist"); - - result = dns_message_gettemprdataset(lookup->sendmsg, &rdataset); - check_result(result, "dns_message_gettemprdataset"); - - dns_rdatalist_init(rdatalist); - rdatalist->type = dns_rdatatype_soa; - rdatalist->rdclass = lookup->rdclass; - rdatalist->covers = 0; - rdatalist->ttl = 0; - ISC_LIST_INIT(rdatalist->rdata); - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - - dns_rdataset_init(rdataset); - dns_rdatalist_tordataset(rdatalist, rdataset); - - result = dns_message_gettempname(lookup->sendmsg, &soaname); - check_result(result, "dns_message_gettempname"); - dns_name_init(soaname, NULL); - dns_name_clone(lookup->name, soaname); - ISC_LIST_INIT(soaname->list); - ISC_LIST_APPEND(soaname->list, rdataset, link); - dns_message_addname(lookup->sendmsg, soaname, DNS_SECTION_AUTHORITY); -} - -/*% - * Setup the supplied lookup structure, making it ready to start sending - * queries to servers. Create and initialize the message to be sent as - * well as the query structures and buffer space for the replies. If the - * server list is empty, clone it from the system default list. - */ -void -setup_lookup(dig_lookup_t *lookup) { - isc_result_t result; - isc_uint32_t id; - int len; - dig_server_t *serv; - dig_query_t *query; - isc_buffer_t b; - dns_compress_t cctx; - char store[MXNAME]; -#ifdef WITH_IDN - idn_result_t mr; - char utf8_textname[MXNAME], utf8_origin[MXNAME], idn_textname[MXNAME]; -#endif - -#ifdef WITH_IDN - result = dns_name_settotextfilter(output_filter); - check_result(result, "dns_name_settotextfilter"); -#endif - - REQUIRE(lookup != NULL); - INSIST(!free_now); - - debug("setup_lookup(%p)", lookup); - - result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, - &lookup->sendmsg); - check_result(result, "dns_message_create"); - - if (lookup->new_search) { - debug("resetting lookup counter."); - lookup_counter = 0; - } - - if (ISC_LIST_EMPTY(lookup->my_server_list)) { - debug("cloning server list"); - clone_server_list(server_list, &lookup->my_server_list); - } - result = dns_message_gettempname(lookup->sendmsg, &lookup->name); - check_result(result, "dns_message_gettempname"); - dns_name_init(lookup->name, NULL); - - isc_buffer_init(&lookup->namebuf, lookup->namespace, - sizeof(lookup->namespace)); - isc_buffer_init(&lookup->onamebuf, lookup->onamespace, - sizeof(lookup->onamespace)); - -#ifdef WITH_IDN - /* - * We cannot convert `textname' and `origin' separately. - * `textname' doesn't contain TLD, but local mapping needs - * TLD. - */ - mr = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, lookup->textname, - utf8_textname, sizeof(utf8_textname)); - idn_check_result(mr, "convert textname to UTF-8"); -#endif - - /* - * If the name has too many dots, force the origin to be NULL - * (which produces an absolute lookup). Otherwise, take the origin - * we have if there's one in the struct already. If it's NULL, - * take the first entry in the searchlist iff either usesearch - * is TRUE or we got a domain line in the resolv.conf file. - */ - if (lookup->new_search) { -#ifdef WITH_IDN - if ((count_dots(utf8_textname) >= ndots) || !usesearch) { - lookup->origin = NULL; /* Force abs lookup */ - lookup->done_as_is = ISC_TRUE; - lookup->need_search = usesearch; - } else if (lookup->origin == NULL && usesearch) { - lookup->origin = ISC_LIST_HEAD(search_list); - lookup->need_search = ISC_FALSE; - } -#else - if ((count_dots(lookup->textname) >= ndots) || !usesearch) { - lookup->origin = NULL; /* Force abs lookup */ - lookup->done_as_is = ISC_TRUE; - lookup->need_search = usesearch; - } else if (lookup->origin == NULL && usesearch) { - lookup->origin = ISC_LIST_HEAD(search_list); - lookup->need_search = ISC_FALSE; - } -#endif - } - -#ifdef WITH_IDN - if (lookup->origin != NULL) { - mr = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, - lookup->origin->origin, utf8_origin, - sizeof(utf8_origin)); - idn_check_result(mr, "convert origin to UTF-8"); - mr = append_textname(utf8_textname, utf8_origin, - sizeof(utf8_textname)); - idn_check_result(mr, "append origin to textname"); - } - mr = idn_encodename(idnoptions | IDN_LOCALMAP | IDN_NAMEPREP | - IDN_IDNCONV | IDN_LENCHECK, utf8_textname, - idn_textname, sizeof(idn_textname)); - idn_check_result(mr, "convert UTF-8 textname to IDN encoding"); -#else - if (lookup->origin != NULL) { - debug("trying origin %s", lookup->origin->origin); - result = dns_message_gettempname(lookup->sendmsg, - &lookup->oname); - check_result(result, "dns_message_gettempname"); - dns_name_init(lookup->oname, NULL); - /* XXX Helper funct to conv char* to name? */ - len = strlen(lookup->origin->origin); - isc_buffer_init(&b, lookup->origin->origin, len); - isc_buffer_add(&b, len); - result = dns_name_fromtext(lookup->oname, &b, dns_rootname, - ISC_FALSE, &lookup->onamebuf); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(lookup->sendmsg, - &lookup->name); - dns_message_puttempname(lookup->sendmsg, - &lookup->oname); - fatal("'%s' is not in legal name syntax (%s)", - lookup->origin->origin, - isc_result_totext(result)); - } - if (lookup->trace && lookup->trace_root) { - dns_name_clone(dns_rootname, lookup->name); - } else { - len = strlen(lookup->textname); - isc_buffer_init(&b, lookup->textname, len); - isc_buffer_add(&b, len); - result = dns_name_fromtext(lookup->name, &b, - lookup->oname, ISC_FALSE, - &lookup->namebuf); - } - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(lookup->sendmsg, - &lookup->name); - dns_message_puttempname(lookup->sendmsg, - &lookup->oname); - fatal("'%s' is not in legal name syntax (%s)", - lookup->textname, isc_result_totext(result)); - } - dns_message_puttempname(lookup->sendmsg, &lookup->oname); - } else -#endif - { - debug("using root origin"); - if (lookup->trace && lookup->trace_root) - dns_name_clone(dns_rootname, lookup->name); - else { -#ifdef WITH_IDN - len = strlen(idn_textname); - isc_buffer_init(&b, idn_textname, len); - isc_buffer_add(&b, len); - result = dns_name_fromtext(lookup->name, &b, - dns_rootname, - ISC_FALSE, - &lookup->namebuf); -#else - len = strlen(lookup->textname); - isc_buffer_init(&b, lookup->textname, len); - isc_buffer_add(&b, len); - result = dns_name_fromtext(lookup->name, &b, - dns_rootname, - ISC_FALSE, - &lookup->namebuf); -#endif - } - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(lookup->sendmsg, - &lookup->name); - isc_buffer_init(&b, store, MXNAME); - fatal("'%s' is not a legal name " - "(%s)", lookup->textname, - isc_result_totext(result)); - } - } - dns_name_format(lookup->name, store, sizeof(store)); - trying(store, lookup); - INSIST(dns_name_isabsolute(lookup->name)); - - isc_random_get(&id); - lookup->sendmsg->id = (unsigned short)id & 0xFFFF; - lookup->sendmsg->opcode = dns_opcode_query; - lookup->msgcounter = 0; - /* - * If this is a trace request, completely disallow recursion, since - * it's meaningless for traces. - */ - if (lookup->trace || (lookup->ns_search_only && !lookup->trace_root)) - lookup->recurse = ISC_FALSE; - - if (lookup->recurse && - lookup->rdtype != dns_rdatatype_axfr && - lookup->rdtype != dns_rdatatype_ixfr) { - debug("recursive query"); - lookup->sendmsg->flags |= DNS_MESSAGEFLAG_RD; - } - - /* XXX aaflag */ - if (lookup->aaonly) { - debug("AA query"); - lookup->sendmsg->flags |= DNS_MESSAGEFLAG_AA; - } - - if (lookup->adflag) { - debug("AD query"); - lookup->sendmsg->flags |= DNS_MESSAGEFLAG_AD; - } - - if (lookup->cdflag) { - debug("CD query"); - lookup->sendmsg->flags |= DNS_MESSAGEFLAG_CD; - } - - dns_message_addname(lookup->sendmsg, lookup->name, - DNS_SECTION_QUESTION); - - if (lookup->trace && lookup->trace_root) { - lookup->qrdtype = lookup->rdtype; - lookup->rdtype = dns_rdatatype_ns; - } - - if ((lookup->rdtype == dns_rdatatype_axfr) || - (lookup->rdtype == dns_rdatatype_ixfr)) { - lookup->doing_xfr = ISC_TRUE; - /* - * Force TCP mode if we're doing an xfr. - * XXX UDP ixfr's would be useful - */ - lookup->tcp_mode = ISC_TRUE; - } - - add_question(lookup->sendmsg, lookup->name, lookup->rdclass, - lookup->rdtype); - - /* add_soa */ - if (lookup->rdtype == dns_rdatatype_ixfr) - insert_soa(lookup); - - /* XXX Insist this? */ - lookup->tsigctx = NULL; - lookup->querysig = NULL; - if (key != NULL) { - debug("initializing keys"); - result = dns_message_settsigkey(lookup->sendmsg, key); - check_result(result, "dns_message_settsigkey"); - } - - lookup->sendspace = isc_mempool_get(commctx); - if (lookup->sendspace == NULL) - fatal("memory allocation failure"); - - result = dns_compress_init(&cctx, -1, mctx); - check_result(result, "dns_compress_init"); - - debug("starting to render the message"); - isc_buffer_init(&lookup->renderbuf, lookup->sendspace, COMMSIZE); - result = dns_message_renderbegin(lookup->sendmsg, &cctx, - &lookup->renderbuf); - check_result(result, "dns_message_renderbegin"); - if (lookup->udpsize > 0 || lookup->dnssec || lookup->edns > -1) { - if (lookup->udpsize == 0) - lookup->udpsize = 4096; - if (lookup->edns < 0) - lookup->edns = 0; - add_opt(lookup->sendmsg, lookup->udpsize, - lookup->edns, lookup->dnssec); - } - - result = dns_message_rendersection(lookup->sendmsg, - DNS_SECTION_QUESTION, 0); - check_result(result, "dns_message_rendersection"); - result = dns_message_rendersection(lookup->sendmsg, - DNS_SECTION_AUTHORITY, 0); - check_result(result, "dns_message_rendersection"); - result = dns_message_renderend(lookup->sendmsg); - check_result(result, "dns_message_renderend"); - debug("done rendering"); - - dns_compress_invalidate(&cctx); - - /* - * Force TCP mode if the request is larger than 512 bytes. - */ - if (isc_buffer_usedlength(&lookup->renderbuf) > 512) - lookup->tcp_mode = ISC_TRUE; - - lookup->pending = ISC_FALSE; - - for (serv = ISC_LIST_HEAD(lookup->my_server_list); - serv != NULL; - serv = ISC_LIST_NEXT(serv, link)) { - query = isc_mem_allocate(mctx, sizeof(dig_query_t)); - if (query == NULL) - fatal("memory allocation failure in %s:%d", - __FILE__, __LINE__); - debug("create query %p linked to lookup %p", - query, lookup); - query->lookup = lookup; - query->waiting_connect = ISC_FALSE; - query->waiting_senddone = ISC_FALSE; - query->pending_free = ISC_FALSE; - query->recv_made = ISC_FALSE; - query->first_pass = ISC_TRUE; - query->first_soa_rcvd = ISC_FALSE; - query->second_rr_rcvd = ISC_FALSE; - query->first_repeat_rcvd = ISC_FALSE; - query->warn_id = ISC_TRUE; - query->first_rr_serial = 0; - query->second_rr_serial = 0; - query->servname = serv->servername; - query->userarg = serv->userarg; - query->rr_count = 0; - query->msg_count = 0; - query->byte_count = 0; - ISC_LINK_INIT(query, link); - ISC_LIST_INIT(query->recvlist); - ISC_LIST_INIT(query->lengthlist); - query->sock = NULL; - query->recvspace = isc_mempool_get(commctx); - if (query->recvspace == NULL) - fatal("memory allocation failure"); - - isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE); - isc_buffer_init(&query->lengthbuf, query->lengthspace, 2); - isc_buffer_init(&query->slbuf, query->slspace, 2); - query->sendbuf = lookup->renderbuf; - - ISC_LINK_INIT(query, link); - ISC_LIST_ENQUEUE(lookup->q, query, link); - } - /* XXX qrflag, print_query, etc... */ - if (!ISC_LIST_EMPTY(lookup->q) && qr) { - extrabytes = 0; - printmessage(ISC_LIST_HEAD(lookup->q), lookup->sendmsg, - ISC_TRUE); - } -} - -/*% - * Event handler for send completion. Track send counter, and clear out - * the query if the send was canceled. - */ -static void -send_done(isc_task_t *_task, isc_event_t *event) { - isc_socketevent_t *sevent = (isc_socketevent_t *)event; - isc_buffer_t *b = NULL; - dig_query_t *query, *next; - dig_lookup_t *l; - - REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE); - - UNUSED(_task); - - LOCK_LOOKUP; - - debug("send_done()"); - sendcount--; - debug("sendcount=%d", sendcount); - INSIST(sendcount >= 0); - - for (b = ISC_LIST_HEAD(sevent->bufferlist); - b != NULL; - b = ISC_LIST_HEAD(sevent->bufferlist)) - ISC_LIST_DEQUEUE(sevent->bufferlist, b, link); - - query = event->ev_arg; - query->waiting_senddone = ISC_FALSE; - l = query->lookup; - - if (l->ns_search_only && !l->trace_root) { - debug("sending next, since searching"); - next = ISC_LIST_NEXT(query, link); - if (next != NULL) - send_udp(next); - } - - isc_event_free(&event); - - if (query->pending_free) - isc_mem_free(mctx, query); - - check_if_done(); - UNLOCK_LOOKUP; -} - -/*% - * Cancel a lookup, sending isc_socket_cancel() requests to all outstanding - * IO sockets. The cancel handlers should take care of cleaning up the - * query and lookup structures - */ -static void -cancel_lookup(dig_lookup_t *lookup) { - dig_query_t *query, *next; - - debug("cancel_lookup()"); - query = ISC_LIST_HEAD(lookup->q); - while (query != NULL) { - next = ISC_LIST_NEXT(query, link); - if (query->sock != NULL) { - isc_socket_cancel(query->sock, global_task, - ISC_SOCKCANCEL_ALL); - check_if_done(); - } else { - clear_query(query); - } - query = next; - } - if (lookup->timer != NULL) - isc_timer_detach(&lookup->timer); - lookup->pending = ISC_FALSE; - lookup->retries = 0; -} - -static void -bringup_timer(dig_query_t *query, unsigned int default_timeout) { - dig_lookup_t *l; - unsigned int local_timeout; - isc_result_t result; - - debug("bringup_timer()"); - /* - * If the timer already exists, that means we're calling this - * a second time (for a retry). Don't need to recreate it, - * just reset it. - */ - l = query->lookup; - if (ISC_LIST_NEXT(query, link) != NULL) - local_timeout = SERVER_TIMEOUT; - else { - if (timeout == 0) - local_timeout = default_timeout; - else - local_timeout = timeout; - } - debug("have local timeout of %d", local_timeout); - isc_interval_set(&l->interval, local_timeout, 0); - if (l->timer != NULL) - isc_timer_detach(&l->timer); - result = isc_timer_create(timermgr, isc_timertype_once, NULL, - &l->interval, global_task, connect_timeout, - l, &l->timer); - check_result(result, "isc_timer_create"); -} - -static void -connect_done(isc_task_t *task, isc_event_t *event); - -/*% - * Unlike send_udp, this can't be called multiple times with the same - * query. When we retry TCP, we requeue the whole lookup, which should - * start anew. - */ -static void -send_tcp_connect(dig_query_t *query) { - isc_result_t result; - dig_query_t *next; - dig_lookup_t *l; - - debug("send_tcp_connect(%p)", query); - - l = query->lookup; - query->waiting_connect = ISC_TRUE; - query->lookup->current_query = query; - get_address(query->servname, port, &query->sockaddr); - - if (specified_source && - (isc_sockaddr_pf(&query->sockaddr) != - isc_sockaddr_pf(&bind_address))) { - printf(";; Skipping server %s, incompatible " - "address family\n", query->servname); - query->waiting_connect = ISC_FALSE; - next = ISC_LIST_NEXT(query, link); - l = query->lookup; - clear_query(query); - if (next == NULL) { - printf(";; No acceptable nameservers\n"); - check_next_lookup(l); - return; - } - send_tcp_connect(next); - return; - } - INSIST(query->sock == NULL); - result = isc_socket_create(socketmgr, - isc_sockaddr_pf(&query->sockaddr), - isc_sockettype_tcp, &query->sock); - check_result(result, "isc_socket_create"); - sockcount++; - debug("sockcount=%d", sockcount); - if (specified_source) - result = isc_socket_bind(query->sock, &bind_address); - else { - if ((isc_sockaddr_pf(&query->sockaddr) == AF_INET) && - have_ipv4) - isc_sockaddr_any(&bind_any); - else - isc_sockaddr_any6(&bind_any); - result = isc_socket_bind(query->sock, &bind_any); - } - check_result(result, "isc_socket_bind"); - bringup_timer(query, TCP_TIMEOUT); - result = isc_socket_connect(query->sock, &query->sockaddr, - global_task, connect_done, query); - check_result(result, "isc_socket_connect"); - /* - * If we're at the endgame of a nameserver search, we need to - * immediately bring up all the queries. Do it here. - */ - if (l->ns_search_only && !l->trace_root) { - debug("sending next, since searching"); - next = ISC_LIST_NEXT(query, link); - if (next != NULL) - send_tcp_connect(next); - } -} - -/*% - * Send a UDP packet to the remote nameserver, possible starting the - * recv action as well. Also make sure that the timer is running and - * is properly reset. - */ -static void -send_udp(dig_query_t *query) { - dig_lookup_t *l = NULL; - isc_result_t result; - - debug("send_udp(%p)", query); - - l = query->lookup; - bringup_timer(query, UDP_TIMEOUT); - l->current_query = query; - debug("working on lookup %p, query %p", query->lookup, query); - if (!query->recv_made) { - /* XXX Check the sense of this, need assertion? */ - query->waiting_connect = ISC_FALSE; - get_address(query->servname, port, &query->sockaddr); - - result = isc_socket_create(socketmgr, - isc_sockaddr_pf(&query->sockaddr), - isc_sockettype_udp, &query->sock); - check_result(result, "isc_socket_create"); - sockcount++; - debug("sockcount=%d", sockcount); - if (specified_source) { - result = isc_socket_bind(query->sock, &bind_address); - } else { - isc_sockaddr_anyofpf(&bind_any, - isc_sockaddr_pf(&query->sockaddr)); - result = isc_socket_bind(query->sock, &bind_any); - } - check_result(result, "isc_socket_bind"); - - query->recv_made = ISC_TRUE; - ISC_LINK_INIT(&query->recvbuf, link); - ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, - link); - debug("recving with lookup=%p, query=%p, sock=%p", - query->lookup, query, query->sock); - result = isc_socket_recvv(query->sock, &query->recvlist, 1, - global_task, recv_done, query); - check_result(result, "isc_socket_recvv"); - recvcount++; - debug("recvcount=%d", recvcount); - } - ISC_LIST_INIT(query->sendlist); - ISC_LIST_ENQUEUE(query->sendlist, &query->sendbuf, link); - debug("sending a request"); - TIME_NOW(&query->time_sent); - INSIST(query->sock != NULL); - query->waiting_senddone = ISC_TRUE; - result = isc_socket_sendtov(query->sock, &query->sendlist, - global_task, send_done, query, - &query->sockaddr, NULL); - check_result(result, "isc_socket_sendtov"); - sendcount++; -} - -/*% - * IO timeout handler, used for both connect and recv timeouts. If - * retries are still allowed, either resend the UDP packet or queue a - * new TCP lookup. Otherwise, cancel the lookup. - */ -static void -connect_timeout(isc_task_t *task, isc_event_t *event) { - dig_lookup_t *l = NULL; - dig_query_t *query = NULL, *cq; - - UNUSED(task); - REQUIRE(event->ev_type == ISC_TIMEREVENT_IDLE); - - debug("connect_timeout()"); - - LOCK_LOOKUP; - l = event->ev_arg; - query = l->current_query; - isc_event_free(&event); - - INSIST(!free_now); - - if ((query != NULL) && (query->lookup->current_query != NULL) && - (ISC_LIST_NEXT(query->lookup->current_query, link) != NULL)) { - debug("trying next server..."); - cq = query->lookup->current_query; - if (!l->tcp_mode) - send_udp(ISC_LIST_NEXT(cq, link)); - else - send_tcp_connect(ISC_LIST_NEXT(cq, link)); - UNLOCK_LOOKUP; - return; - } - - if (l->retries > 1) { - if (!l->tcp_mode) { - l->retries--; - debug("resending UDP request to first server"); - send_udp(ISC_LIST_HEAD(l->q)); - } else { - debug("making new TCP request, %d tries left", - l->retries); - l->retries--; - requeue_lookup(l, ISC_TRUE); - cancel_lookup(l); - check_next_lookup(l); - } - } else { - fputs(l->cmdline, stdout); - printf(";; connection timed out; no servers could be " - "reached\n"); - cancel_lookup(l); - check_next_lookup(l); - if (exitcode < 9) - exitcode = 9; - } - UNLOCK_LOOKUP; -} - -/*% - * Event handler for the TCP recv which gets the length header of TCP - * packets. Start the next recv of length bytes. - */ -static void -tcp_length_done(isc_task_t *task, isc_event_t *event) { - isc_socketevent_t *sevent; - isc_buffer_t *b = NULL; - isc_result_t result; - dig_query_t *query = NULL; - dig_lookup_t *l; - isc_uint16_t length; - - REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE); - INSIST(!free_now); - - UNUSED(task); - - debug("tcp_length_done()"); - - LOCK_LOOKUP; - sevent = (isc_socketevent_t *)event; - query = event->ev_arg; - - recvcount--; - INSIST(recvcount >= 0); - - b = ISC_LIST_HEAD(sevent->bufferlist); - INSIST(b == &query->lengthbuf); - ISC_LIST_DEQUEUE(sevent->bufferlist, b, link); - - if (sevent->result == ISC_R_CANCELED) { - isc_event_free(&event); - l = query->lookup; - clear_query(query); - check_next_lookup(l); - UNLOCK_LOOKUP; - return; - } - if (sevent->result != ISC_R_SUCCESS) { - char sockstr[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&query->sockaddr, sockstr, - sizeof(sockstr)); - printf(";; communications error to %s: %s\n", - sockstr, isc_result_totext(sevent->result)); - l = query->lookup; - isc_socket_detach(&query->sock); - sockcount--; - debug("sockcount=%d", sockcount); - INSIST(sockcount >= 0); - isc_event_free(&event); - clear_query(query); - check_next_lookup(l); - UNLOCK_LOOKUP; - return; - } - length = isc_buffer_getuint16(b); - if (length == 0) { - isc_event_free(&event); - launch_next_query(query, ISC_FALSE); - UNLOCK_LOOKUP; - return; - } - - /* - * Even though the buffer was already init'ed, we need - * to redo it now, to force the length we want. - */ - isc_buffer_invalidate(&query->recvbuf); - isc_buffer_init(&query->recvbuf, query->recvspace, length); - ENSURE(ISC_LIST_EMPTY(query->recvlist)); - ISC_LINK_INIT(&query->recvbuf, link); - ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, link); - debug("recving with lookup=%p, query=%p", query->lookup, query); - result = isc_socket_recvv(query->sock, &query->recvlist, length, task, - recv_done, query); - check_result(result, "isc_socket_recvv"); - recvcount++; - debug("resubmitted recv request with length %d, recvcount=%d", - length, recvcount); - isc_event_free(&event); - UNLOCK_LOOKUP; -} - -/*% - * For transfers that involve multiple recvs (XFR's in particular), - * launch the next recv. - */ -static void -launch_next_query(dig_query_t *query, isc_boolean_t include_question) { - isc_result_t result; - dig_lookup_t *l; - - INSIST(!free_now); - - debug("launch_next_query()"); - - if (!query->lookup->pending) { - debug("ignoring launch_next_query because !pending"); - isc_socket_detach(&query->sock); - sockcount--; - debug("sockcount=%d", sockcount); - INSIST(sockcount >= 0); - query->waiting_connect = ISC_FALSE; - l = query->lookup; - clear_query(query); - check_next_lookup(l); - return; - } - - isc_buffer_clear(&query->slbuf); - isc_buffer_clear(&query->lengthbuf); - isc_buffer_putuint16(&query->slbuf, (isc_uint16_t) query->sendbuf.used); - ISC_LIST_INIT(query->sendlist); - ISC_LINK_INIT(&query->slbuf, link); - ISC_LIST_ENQUEUE(query->sendlist, &query->slbuf, link); - if (include_question) - ISC_LIST_ENQUEUE(query->sendlist, &query->sendbuf, link); - ISC_LINK_INIT(&query->lengthbuf, link); - ISC_LIST_ENQUEUE(query->lengthlist, &query->lengthbuf, link); - - result = isc_socket_recvv(query->sock, &query->lengthlist, 0, - global_task, tcp_length_done, query); - check_result(result, "isc_socket_recvv"); - recvcount++; - debug("recvcount=%d", recvcount); - if (!query->first_soa_rcvd) { - debug("sending a request in launch_next_query"); - TIME_NOW(&query->time_sent); - query->waiting_senddone = ISC_TRUE; - result = isc_socket_sendv(query->sock, &query->sendlist, - global_task, send_done, query); - check_result(result, "isc_socket_sendv"); - sendcount++; - debug("sendcount=%d", sendcount); - } - query->waiting_connect = ISC_FALSE; -#if 0 - check_next_lookup(query->lookup); -#endif - return; -} - -/*% - * Event handler for TCP connect complete. Make sure the connection was - * successful, then pass into launch_next_query to actually send the - * question. - */ -static void -connect_done(isc_task_t *task, isc_event_t *event) { - isc_socketevent_t *sevent = NULL; - dig_query_t *query = NULL, *next; - dig_lookup_t *l; - - UNUSED(task); - - REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT); - INSIST(!free_now); - - debug("connect_done()"); - - LOCK_LOOKUP; - sevent = (isc_socketevent_t *)event; - query = sevent->ev_arg; - - INSIST(query->waiting_connect); - - query->waiting_connect = ISC_FALSE; - - if (sevent->result == ISC_R_CANCELED) { - debug("in cancel handler"); - isc_socket_detach(&query->sock); - sockcount--; - INSIST(sockcount >= 0); - debug("sockcount=%d", sockcount); - query->waiting_connect = ISC_FALSE; - isc_event_free(&event); - l = query->lookup; - clear_query(query); - check_next_lookup(l); - UNLOCK_LOOKUP; - return; - } - if (sevent->result != ISC_R_SUCCESS) { - char sockstr[ISC_SOCKADDR_FORMATSIZE]; - - debug("unsuccessful connection: %s", - isc_result_totext(sevent->result)); - isc_sockaddr_format(&query->sockaddr, sockstr, sizeof(sockstr)); - if (sevent->result != ISC_R_CANCELED) - printf(";; Connection to %s(%s) for %s failed: " - "%s.\n", sockstr, - query->servname, query->lookup->textname, - isc_result_totext(sevent->result)); - isc_socket_detach(&query->sock); - sockcount--; - INSIST(sockcount >= 0); - /* XXX Clean up exitcodes */ - if (exitcode < 9) - exitcode = 9; - debug("sockcount=%d", sockcount); - query->waiting_connect = ISC_FALSE; - isc_event_free(&event); - l = query->lookup; - if (l->current_query != NULL) - next = ISC_LIST_NEXT(l->current_query, link); - else - next = NULL; - clear_query(query); - if (next != NULL) { - bringup_timer(next, TCP_TIMEOUT); - send_tcp_connect(next); - } else { - check_next_lookup(l); - } - UNLOCK_LOOKUP; - return; - } - launch_next_query(query, ISC_TRUE); - isc_event_free(&event); - UNLOCK_LOOKUP; -} - -/*% - * Check if the ongoing XFR needs more data before it's complete, using - * the semantics of IXFR and AXFR protocols. Much of the complexity of - * this routine comes from determining when an IXFR is complete. - * ISC_FALSE means more data is on the way, and the recv has been issued. - */ -static isc_boolean_t -check_for_more_data(dig_query_t *query, dns_message_t *msg, - isc_socketevent_t *sevent) -{ - dns_rdataset_t *rdataset = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_soa_t soa; - isc_uint32_t serial; - isc_result_t result; - - debug("check_for_more_data()"); - - /* - * By the time we're in this routine, we know we're doing - * either an AXFR or IXFR. If there's no second_rr_type, - * then we don't yet know which kind of answer we got back - * from the server. Here, we're going to walk through the - * rr's in the message, acting as necessary whenever we hit - * an SOA rr. - */ - - query->msg_count++; - query->byte_count += sevent->n; - result = dns_message_firstname(msg, DNS_SECTION_ANSWER); - if (result != ISC_R_SUCCESS) { - puts("; Transfer failed."); - return (ISC_TRUE); - } - do { - dns_name_t *name; - name = NULL; - dns_message_currentname(msg, DNS_SECTION_ANSWER, - &name); - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - result = dns_rdataset_first(rdataset); - if (result != ISC_R_SUCCESS) - continue; - do { - query->rr_count++; - dns_rdata_reset(&rdata); - dns_rdataset_current(rdataset, &rdata); - /* - * If this is the first rr, make sure - * it's an SOA - */ - if ((!query->first_soa_rcvd) && - (rdata.type != dns_rdatatype_soa)) { - puts("; Transfer failed. " - "Didn't start with SOA answer."); - return (ISC_TRUE); - } - if ((!query->second_rr_rcvd) && - (rdata.type != dns_rdatatype_soa)) { - query->second_rr_rcvd = ISC_TRUE; - query->second_rr_serial = 0; - debug("got the second rr as nonsoa"); - goto next_rdata; - } - - /* - * If the record is anything except an SOA - * now, just continue on... - */ - if (rdata.type != dns_rdatatype_soa) - goto next_rdata; - /* Now we have an SOA. Work with it. */ - debug("got an SOA"); - (void)dns_rdata_tostruct(&rdata, &soa, NULL); - serial = soa.serial; - dns_rdata_freestruct(&soa); - if (!query->first_soa_rcvd) { - query->first_soa_rcvd = ISC_TRUE; - query->first_rr_serial = serial; - debug("this is the first %d", - query->lookup->ixfr_serial); - if (query->lookup->ixfr_serial >= - serial) - goto doexit; - goto next_rdata; - } - if (query->lookup->rdtype == - dns_rdatatype_axfr) { - debug("doing axfr, got second SOA"); - goto doexit; - } - if (!query->second_rr_rcvd) { - if (query->first_rr_serial == serial) { - debug("doing ixfr, got " - "empty zone"); - goto doexit; - } - debug("this is the second %d", - query->lookup->ixfr_serial); - query->second_rr_rcvd = ISC_TRUE; - query->second_rr_serial = serial; - goto next_rdata; - } - if (query->second_rr_serial == 0) { - /* - * If the second RR was a non-SOA - * record, and we're getting any - * other SOA, then this is an - * AXFR, and we're done. - */ - debug("done, since axfr"); - goto doexit; - } - /* - * If we get to this point, we're doing an - * IXFR and have to start really looking - * at serial numbers. - */ - if (query->first_rr_serial == serial) { - debug("got a match for ixfr"); - if (!query->first_repeat_rcvd) { - query->first_repeat_rcvd = - ISC_TRUE; - goto next_rdata; - } - debug("done with ixfr"); - goto doexit; - } - debug("meaningless soa %d", serial); - next_rdata: - result = dns_rdataset_next(rdataset); - } while (result == ISC_R_SUCCESS); - } - result = dns_message_nextname(msg, DNS_SECTION_ANSWER); - } while (result == ISC_R_SUCCESS); - launch_next_query(query, ISC_FALSE); - return (ISC_FALSE); - doexit: - received(sevent->n, &sevent->address, query); - return (ISC_TRUE); -} - -/*% - * Event handler for recv complete. Perform whatever actions are necessary, - * based on the specifics of the user's request. - */ -static void -recv_done(isc_task_t *task, isc_event_t *event) { - isc_socketevent_t *sevent = NULL; - dig_query_t *query = NULL; - isc_buffer_t *b = NULL; - dns_message_t *msg = NULL; -#ifdef DIG_SIGCHASE - dig_message_t *chase_msg = NULL; - dig_message_t *chase_msg2 = NULL; -#endif - isc_result_t result; - dig_lookup_t *n, *l; - isc_boolean_t docancel = ISC_FALSE; - isc_boolean_t match = ISC_TRUE; - unsigned int parseflags; - dns_messageid_t id; - unsigned int msgflags; -#ifdef DIG_SIGCHASE - isc_result_t do_sigchase = ISC_FALSE; - - dns_message_t *msg_temp = NULL; - isc_region_t r; - isc_buffer_t *buf = NULL; -#endif - - UNUSED(task); - INSIST(!free_now); - - debug("recv_done()"); - - LOCK_LOOKUP; - recvcount--; - debug("recvcount=%d", recvcount); - INSIST(recvcount >= 0); - - query = event->ev_arg; - debug("lookup=%p, query=%p", query->lookup, query); - - l = query->lookup; - - REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE); - sevent = (isc_socketevent_t *)event; - - b = ISC_LIST_HEAD(sevent->bufferlist); - INSIST(b == &query->recvbuf); - ISC_LIST_DEQUEUE(sevent->bufferlist, &query->recvbuf, link); - - if ((l->tcp_mode) && (l->timer != NULL)) - isc_timer_touch(l->timer); - if ((!l->pending && !l->ns_search_only) || cancel_now) { - debug("no longer pending. Got %s", - isc_result_totext(sevent->result)); - query->waiting_connect = ISC_FALSE; - - isc_event_free(&event); - clear_query(query); - check_next_lookup(l); - UNLOCK_LOOKUP; - return; - } - - if (sevent->result != ISC_R_SUCCESS) { - if (sevent->result == ISC_R_CANCELED) { - debug("in recv cancel handler"); - query->waiting_connect = ISC_FALSE; - } else { - printf(";; communications error: %s\n", - isc_result_totext(sevent->result)); - isc_socket_detach(&query->sock); - sockcount--; - debug("sockcount=%d", sockcount); - INSIST(sockcount >= 0); - } - isc_event_free(&event); - clear_query(query); - check_next_lookup(l); - UNLOCK_LOOKUP; - return; - } - - if (!l->tcp_mode && - !isc_sockaddr_compare(&sevent->address, &query->sockaddr, - ISC_SOCKADDR_CMPADDR| - ISC_SOCKADDR_CMPPORT| - ISC_SOCKADDR_CMPSCOPE| - ISC_SOCKADDR_CMPSCOPEZERO)) { - char buf1[ISC_SOCKADDR_FORMATSIZE]; - char buf2[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_t any; - - if (isc_sockaddr_pf(&query->sockaddr) == AF_INET) - isc_sockaddr_any(&any); - else - isc_sockaddr_any6(&any); - - /* - * We don't expect a match when the packet is - * sent to 0.0.0.0, :: or to a multicast addresses. - * XXXMPA broadcast needs to be handled here as well. - */ - if ((!isc_sockaddr_eqaddr(&query->sockaddr, &any) && - !isc_sockaddr_ismulticast(&query->sockaddr)) || - isc_sockaddr_getport(&query->sockaddr) != - isc_sockaddr_getport(&sevent->address)) { - isc_sockaddr_format(&sevent->address, buf1, - sizeof(buf1)); - isc_sockaddr_format(&query->sockaddr, buf2, - sizeof(buf2)); - printf(";; reply from unexpected source: %s," - " expected %s\n", buf1, buf2); - match = ISC_FALSE; - } - } - - result = dns_message_peekheader(b, &id, &msgflags); - if (result != ISC_R_SUCCESS || l->sendmsg->id != id) { - match = ISC_FALSE; - if (l->tcp_mode) { - isc_boolean_t fail = ISC_TRUE; - if (result == ISC_R_SUCCESS) { - if (!query->first_soa_rcvd || - query->warn_id) - printf(";; %s: ID mismatch: " - "expected ID %u, got %u\n", - query->first_soa_rcvd ? - "WARNING" : "ERROR", - l->sendmsg->id, id); - if (query->first_soa_rcvd) - fail = ISC_FALSE; - query->warn_id = ISC_FALSE; - } else - printf(";; ERROR: short " - "(< header size) message\n"); - if (fail) { - isc_event_free(&event); - clear_query(query); - check_next_lookup(l); - UNLOCK_LOOKUP; - return; - } - match = ISC_TRUE; - } else if (result == ISC_R_SUCCESS) - printf(";; Warning: ID mismatch: " - "expected ID %u, got %u\n", l->sendmsg->id, id); - else - printf(";; Warning: short " - "(< header size) message received\n"); - } - - if (result == ISC_R_SUCCESS && (msgflags & DNS_MESSAGEFLAG_QR) == 0) - printf(";; Warning: query response not set\n"); - - if (!match) { - isc_buffer_invalidate(&query->recvbuf); - isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE); - ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, link); - result = isc_socket_recvv(query->sock, &query->recvlist, 1, - global_task, recv_done, query); - check_result(result, "isc_socket_recvv"); - recvcount++; - isc_event_free(&event); - UNLOCK_LOOKUP; - return; - } - - result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg); - check_result(result, "dns_message_create"); - - if (key != NULL) { - if (l->querysig == NULL) { - debug("getting initial querysig"); - result = dns_message_getquerytsig(l->sendmsg, mctx, - &l->querysig); - check_result(result, "dns_message_getquerytsig"); - } - result = dns_message_setquerytsig(msg, l->querysig); - check_result(result, "dns_message_setquerytsig"); - result = dns_message_settsigkey(msg, key); - check_result(result, "dns_message_settsigkey"); - msg->tsigctx = l->tsigctx; - l->tsigctx = NULL; - if (l->msgcounter != 0) - msg->tcp_continuation = 1; - l->msgcounter++; - } - - debug("before parse starts"); - parseflags = DNS_MESSAGEPARSE_PRESERVEORDER; -#ifdef DIG_SIGCHASE - if (!l->sigchase) { - do_sigchase = ISC_FALSE; - } else { - parseflags = 0; - do_sigchase = ISC_TRUE; - } -#endif - if (l->besteffort) { - parseflags |= DNS_MESSAGEPARSE_BESTEFFORT; - parseflags |= DNS_MESSAGEPARSE_IGNORETRUNCATION; - } - result = dns_message_parse(msg, b, parseflags); - if (result == DNS_R_RECOVERABLE) { - printf(";; Warning: Message parser reports malformed " - "message packet.\n"); - result = ISC_R_SUCCESS; - } - if (result != ISC_R_SUCCESS) { - printf(";; Got bad packet: %s\n", isc_result_totext(result)); - hex_dump(b); - query->waiting_connect = ISC_FALSE; - dns_message_destroy(&msg); - isc_event_free(&event); - clear_query(query); - cancel_lookup(l); - check_next_lookup(l); - UNLOCK_LOOKUP; - return; - } - if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0 && - !l->ignore && !l->tcp_mode) { - printf(";; Truncated, retrying in TCP mode.\n"); - n = requeue_lookup(l, ISC_TRUE); - n->tcp_mode = ISC_TRUE; - n->origin = query->lookup->origin; - dns_message_destroy(&msg); - isc_event_free(&event); - clear_query(query); - cancel_lookup(l); - check_next_lookup(l); - UNLOCK_LOOKUP; - return; - } - if ((msg->rcode == dns_rcode_servfail && !l->servfail_stops) || - (check_ra && (msg->flags & DNS_MESSAGEFLAG_RA) == 0 && l->recurse)) - { - dig_query_t *next = ISC_LIST_NEXT(query, link); - if (l->current_query == query) - l->current_query = NULL; - if (next != NULL) { - debug("sending query %p\n", next); - if (l->tcp_mode) - send_tcp_connect(next); - else - send_udp(next); - } - /* - * If our query is at the head of the list and there - * is no next, we're the only one left, so fall - * through to print the message. - */ - if ((ISC_LIST_HEAD(l->q) != query) || - (ISC_LIST_NEXT(query, link) != NULL)) { - if( l->comments == ISC_TRUE ) - printf(";; Got %s from %s, " - "trying next server\n", - msg->rcode == dns_rcode_servfail ? - "SERVFAIL reply" : - "recursion not available", - query->servname); - clear_query(query); - check_next_lookup(l); - dns_message_destroy(&msg); - isc_event_free(&event); - UNLOCK_LOOKUP; - return; - } - } - - if (key != NULL) { - result = dns_tsig_verify(&query->recvbuf, msg, NULL, NULL); - if (result != ISC_R_SUCCESS) { - printf(";; Couldn't verify signature: %s\n", - isc_result_totext(result)); - validated = ISC_FALSE; - } - l->tsigctx = msg->tsigctx; - msg->tsigctx = NULL; - if (l->querysig != NULL) { - debug("freeing querysig buffer %p", l->querysig); - isc_buffer_free(&l->querysig); - } - result = dns_message_getquerytsig(msg, mctx, &l->querysig); - check_result(result,"dns_message_getquerytsig"); - } - - extrabytes = isc_buffer_remaininglength(b); - - debug("after parse"); - if (l->doing_xfr && l->xfr_q == NULL) { - l->xfr_q = query; - /* - * Once we are in the XFR message, increase - * the timeout to much longer, so brief network - * outages won't cause the XFR to abort - */ - if (timeout != INT_MAX && l->timer != NULL) { - unsigned int local_timeout; - - if (timeout == 0) { - if (l->tcp_mode) - local_timeout = TCP_TIMEOUT * 4; - else - local_timeout = UDP_TIMEOUT * 4; - } else { - if (timeout < (INT_MAX / 4)) - local_timeout = timeout * 4; - else - local_timeout = INT_MAX; - } - debug("have local timeout of %d", local_timeout); - isc_interval_set(&l->interval, local_timeout, 0); - result = isc_timer_reset(l->timer, - isc_timertype_once, - NULL, - &l->interval, - ISC_FALSE); - check_result(result, "isc_timer_reset"); - } - } - - if (!l->doing_xfr || l->xfr_q == query) { - if (msg->rcode != dns_rcode_noerror && - (l->origin != NULL || l->need_search)) { - if (!next_origin(msg, query) || showsearch) { - printmessage(query, msg, ISC_TRUE); - received(b->used, &sevent->address, query); - } - } else if (!l->trace && !l->ns_search_only) { -#ifdef DIG_SIGCHASE - if (!do_sigchase) -#endif - printmessage(query, msg, ISC_TRUE); - } else if (l->trace) { - int n = 0; - int count = msg->counts[DNS_SECTION_ANSWER]; - - debug("in TRACE code"); - if (!l->ns_search_only) - printmessage(query, msg, ISC_TRUE); - - l->rdtype = l->qrdtype; - if (l->trace_root || (l->ns_search_only && count > 0)) { - if (!l->trace_root) - l->rdtype = dns_rdatatype_soa; - n = followup_lookup(msg, query, - DNS_SECTION_ANSWER); - l->trace_root = ISC_FALSE; - } else if (count == 0) - n = followup_lookup(msg, query, - DNS_SECTION_AUTHORITY); - if (n == 0) - docancel = ISC_TRUE; - } else { - debug("in NSSEARCH code"); - - if (l->trace_root) { - /* - * This is the initial NS query. - */ - int n; - - l->rdtype = dns_rdatatype_soa; - n = followup_lookup(msg, query, - DNS_SECTION_ANSWER); - if (n == 0) - docancel = ISC_TRUE; - l->trace_root = ISC_FALSE; - } else -#ifdef DIG_SIGCHASE - if (!do_sigchase) -#endif - printmessage(query, msg, ISC_TRUE); - } -#ifdef DIG_SIGCHASE - if (do_sigchase) { - chase_msg = isc_mem_allocate(mctx, - sizeof(dig_message_t)); - if (chase_msg == NULL) { - fatal("Memory allocation failure in %s:%d", - __FILE__, __LINE__); - } - ISC_LIST_INITANDAPPEND(chase_message_list, chase_msg, - link); - if (dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, - &msg_temp) != ISC_R_SUCCESS) { - fatal("dns_message_create in %s:%d", - __FILE__, __LINE__); - } - - isc_buffer_usedregion(b, &r); - result = isc_buffer_allocate(mctx, &buf, r.length); - - check_result(result, "isc_buffer_allocate"); - result = isc_buffer_copyregion(buf, &r); - check_result(result, "isc_buffer_copyregion"); - - result = dns_message_parse(msg_temp, buf, 0); - - isc_buffer_free(&buf); - chase_msg->msg = msg_temp; - - chase_msg2 = isc_mem_allocate(mctx, - sizeof(dig_message_t)); - if (chase_msg2 == NULL) { - fatal("Memory allocation failure in %s:%d", - __FILE__, __LINE__); - } - ISC_LIST_INITANDAPPEND(chase_message_list2, chase_msg2, - link); - chase_msg2->msg = msg; - } -#endif - } - -#ifdef DIG_SIGCHASE - if (l->sigchase && ISC_LIST_EMPTY(lookup_list)) { - sigchase(msg_temp); - } -#endif - - if (l->pending) - debug("still pending."); - if (l->doing_xfr) { - if (query != l->xfr_q) { - dns_message_destroy(&msg); - isc_event_free(&event); - query->waiting_connect = ISC_FALSE; - UNLOCK_LOOKUP; - return; - } - if (!docancel) - docancel = check_for_more_data(query, msg, sevent); - if (docancel) { - dns_message_destroy(&msg); - clear_query(query); - cancel_lookup(l); - check_next_lookup(l); - } - } else { - - if (msg->rcode == dns_rcode_noerror || l->origin == NULL) { - -#ifdef DIG_SIGCHASE - if (!l->sigchase) -#endif - received(b->used, &sevent->address, query); - } - - if (!query->lookup->ns_search_only) - query->lookup->pending = ISC_FALSE; - if (!query->lookup->ns_search_only || - query->lookup->trace_root || docancel) { -#ifdef DIG_SIGCHASE - if (!do_sigchase) -#endif - dns_message_destroy(&msg); - - cancel_lookup(l); - } - clear_query(query); - check_next_lookup(l); - } - if (msg != NULL) { -#ifdef DIG_SIGCHASE - if (do_sigchase) - msg = NULL; - else -#endif - dns_message_destroy(&msg); - } - isc_event_free(&event); - UNLOCK_LOOKUP; -} - -/*% - * Turn a name into an address, using system-supplied routines. This is - * used in looking up server names, etc... and needs to use system-supplied - * routines, since they may be using a non-DNS system for these lookups. - */ -void -get_address(char *host, in_port_t port, isc_sockaddr_t *sockaddr) { - int count; - isc_result_t result; - - isc_app_block(); - result = bind9_getaddresses(host, port, sockaddr, 1, &count); - isc_app_unblock(); - if (result != ISC_R_SUCCESS) - fatal("couldn't get address for '%s': %s", - host, isc_result_totext(result)); - INSIST(count == 1); -} - -/*% - * Initiate either a TCP or UDP lookup - */ -void -do_lookup(dig_lookup_t *lookup) { - - REQUIRE(lookup != NULL); - - debug("do_lookup()"); - lookup->pending = ISC_TRUE; - if (lookup->tcp_mode) - send_tcp_connect(ISC_LIST_HEAD(lookup->q)); - else - send_udp(ISC_LIST_HEAD(lookup->q)); -} - -/*% - * Start everything in action upon task startup. - */ -void -onrun_callback(isc_task_t *task, isc_event_t *event) { - UNUSED(task); - - isc_event_free(&event); - LOCK_LOOKUP; - start_lookup(); - UNLOCK_LOOKUP; -} - -/*% - * Make everything on the lookup queue go away. Mainly used by the - * SIGINT handler. - */ -void -cancel_all(void) { - dig_lookup_t *l, *n; - dig_query_t *q, *nq; - - debug("cancel_all()"); - - LOCK_LOOKUP; - if (free_now) { - UNLOCK_LOOKUP; - return; - } - cancel_now = ISC_TRUE; - if (current_lookup != NULL) { - if (current_lookup->timer != NULL) - isc_timer_detach(¤t_lookup->timer); - q = ISC_LIST_HEAD(current_lookup->q); - while (q != NULL) { - debug("cancelling query %p, belonging to %p", - q, current_lookup); - nq = ISC_LIST_NEXT(q, link); - if (q->sock != NULL) { - isc_socket_cancel(q->sock, NULL, - ISC_SOCKCANCEL_ALL); - } else { - clear_query(q); - } - q = nq; - } - } - l = ISC_LIST_HEAD(lookup_list); - while (l != NULL) { - n = ISC_LIST_NEXT(l, link); - ISC_LIST_DEQUEUE(lookup_list, l, link); - try_clear_lookup(l); - l = n; - } - UNLOCK_LOOKUP; -} - -/*% - * Destroy all of the libs we are using, and get everything ready for a - * clean shutdown. - */ -void -destroy_libs(void) { -#ifdef DIG_SIGCHASE - void * ptr; - dig_message_t *chase_msg; -#endif -#ifdef WITH_IDN - isc_result_t result; -#endif - - debug("destroy_libs()"); - if (global_task != NULL) { - debug("freeing task"); - isc_task_detach(&global_task); - } - /* - * The taskmgr_destroy() call blocks until all events are cleared - * from the task. - */ - if (taskmgr != NULL) { - debug("freeing taskmgr"); - isc_taskmgr_destroy(&taskmgr); - } - LOCK_LOOKUP; - REQUIRE(sockcount == 0); - REQUIRE(recvcount == 0); - REQUIRE(sendcount == 0); - - INSIST(ISC_LIST_HEAD(lookup_list) == NULL); - INSIST(current_lookup == NULL); - INSIST(!free_now); - - free_now = ISC_TRUE; - - lwres_conf_clear(lwctx); - lwres_context_destroy(&lwctx); - - flush_server_list(); - - clear_searchlist(); - -#ifdef WITH_IDN - result = dns_name_settotextfilter(NULL); - check_result(result, "dns_name_settotextfilter"); -#endif - dns_name_destroy(); - - if (commctx != NULL) { - debug("freeing commctx"); - isc_mempool_destroy(&commctx); - } - if (socketmgr != NULL) { - debug("freeing socketmgr"); - isc_socketmgr_destroy(&socketmgr); - } - if (timermgr != NULL) { - debug("freeing timermgr"); - isc_timermgr_destroy(&timermgr); - } - if (key != NULL) { - debug("freeing key %p", key); - dns_tsigkey_detach(&key); - } - if (namebuf != NULL) - isc_buffer_free(&namebuf); - - if (is_dst_up) { - debug("destroy DST lib"); - dst_lib_destroy(); - is_dst_up = ISC_FALSE; - } - if (entp != NULL) { - debug("detach from entropy"); - isc_entropy_detach(&entp); - } - - UNLOCK_LOOKUP; - DESTROYLOCK(&lookup_lock); -#ifdef DIG_SIGCHASE - - debug("Destroy the messages kept for sigchase"); - /* Destroy the messages kept for sigchase */ - chase_msg = ISC_LIST_HEAD(chase_message_list); - - while (chase_msg != NULL) { - INSIST(chase_msg->msg != NULL); - dns_message_destroy(&(chase_msg->msg)); - ptr = chase_msg; - chase_msg = ISC_LIST_NEXT(chase_msg, link); - isc_mem_free(mctx, ptr); - } - - chase_msg = ISC_LIST_HEAD(chase_message_list2); - - while (chase_msg != NULL) { - INSIST(chase_msg->msg != NULL); - dns_message_destroy(&(chase_msg->msg)); - ptr = chase_msg; - chase_msg = ISC_LIST_NEXT(chase_msg, link); - isc_mem_free(mctx, ptr); - } - if (dns_name_dynamic(&chase_name)) - free_name(&chase_name, mctx); -#if DIG_SIGCHASE_TD - if (dns_name_dynamic(&chase_current_name)) - free_name(&chase_current_name, mctx); - if (dns_name_dynamic(&chase_authority_name)) - free_name(&chase_authority_name, mctx); -#endif -#if DIG_SIGCHASE_BU - if (dns_name_dynamic(&chase_signame)) - free_name(&chase_signame, mctx); -#endif - - debug("Destroy memory"); - -#endif - if (memdebugging != 0) - isc_mem_stats(mctx, stderr); - if (mctx != NULL) - isc_mem_destroy(&mctx); -} - -#ifdef WITH_IDN -static void -initialize_idn(void) { - idn_result_t r; - isc_result_t result; - -#ifdef HAVE_SETLOCALE - /* Set locale */ - (void)setlocale(LC_ALL, ""); -#endif - /* Create configuration context. */ - r = idn_nameinit(1); - if (r != idn_success) - fatal("idn api initialization failed: %s", - idn_result_tostring(r)); - - /* Set domain name -> text post-conversion filter. */ - result = dns_name_settotextfilter(output_filter); - check_result(result, "dns_name_settotextfilter"); -} - -static isc_result_t -output_filter(isc_buffer_t *buffer, unsigned int used_org, - isc_boolean_t absolute) -{ - char tmp1[MAXDLEN], tmp2[MAXDLEN]; - size_t fromlen, tolen; - isc_boolean_t end_with_dot; - - /* - * Copy contents of 'buffer' to 'tmp1', supply trailing dot - * if 'absolute' is true, and terminate with NUL. - */ - fromlen = isc_buffer_usedlength(buffer) - used_org; - if (fromlen >= MAXDLEN) - return (ISC_R_SUCCESS); - memcpy(tmp1, (char *)isc_buffer_base(buffer) + used_org, fromlen); - end_with_dot = (tmp1[fromlen - 1] == '.') ? ISC_TRUE : ISC_FALSE; - if (absolute && !end_with_dot) { - fromlen++; - if (fromlen >= MAXDLEN) - return (ISC_R_SUCCESS); - tmp1[fromlen - 1] = '.'; - } - tmp1[fromlen] = '\0'; - - /* - * Convert contents of 'tmp1' to local encoding. - */ - if (idn_decodename(IDN_DECODE_APP, tmp1, tmp2, MAXDLEN) != idn_success) - return (ISC_R_SUCCESS); - strcpy(tmp1, tmp2); - - /* - * Copy the converted contents in 'tmp1' back to 'buffer'. - * If we have appended trailing dot, remove it. - */ - tolen = strlen(tmp1); - if (absolute && !end_with_dot && tmp1[tolen - 1] == '.') - tolen--; - - if (isc_buffer_length(buffer) < used_org + tolen) - return (ISC_R_NOSPACE); - - isc_buffer_subtract(buffer, isc_buffer_usedlength(buffer) - used_org); - memcpy(isc_buffer_used(buffer), tmp1, tolen); - isc_buffer_add(buffer, tolen); - - return (ISC_R_SUCCESS); -} - -static idn_result_t -append_textname(char *name, const char *origin, size_t namesize) { - size_t namelen = strlen(name); - size_t originlen = strlen(origin); - - /* Already absolute? */ - if (namelen > 0 && name[namelen - 1] == '.') - return idn_success; - - /* Append dot and origin */ - - if (namelen + 1 + originlen >= namesize) - return idn_buffer_overflow; - - name[namelen++] = '.'; - (void)strcpy(name + namelen, origin); - return idn_success; -} - -static void -idn_check_result(idn_result_t r, const char *msg) { - if (r != idn_success) { - exitcode = 1; - fatal("%s: %s", msg, idn_result_tostring(r)); - } -} -#endif /* WITH_IDN */ - -#ifdef DIG_SIGCHASE -void -print_type(dns_rdatatype_t type) -{ - isc_buffer_t * b = NULL; - isc_result_t result; - isc_region_t r; - - result = isc_buffer_allocate(mctx, &b, 4000); - check_result(result, "isc_buffer_allocate"); - - result = dns_rdatatype_totext(type, b); - check_result(result, "print_type"); - - isc_buffer_usedregion(b, &r); - r.base[r.length] = '\0'; - - printf("%s", r.base); - - isc_buffer_free(&b); -} - -void -dump_database_section(dns_message_t *msg, int section) -{ - dns_name_t *msg_name=NULL; - - dns_rdataset_t *rdataset; - - do { - dns_message_currentname(msg, section, &msg_name); - - for (rdataset = ISC_LIST_HEAD(msg_name->list); rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - dns_name_print(msg_name, stdout); - printf("\n"); - print_rdataset(msg_name, rdataset, mctx); - printf("end\n"); - } - msg_name = NULL; - } while (dns_message_nextname(msg, section) == ISC_R_SUCCESS); -} - -void -dump_database(void) { - dig_message_t * msg; - - for (msg = ISC_LIST_HEAD(chase_message_list); msg != NULL; - msg = ISC_LIST_NEXT(msg, link)) { - if (dns_message_firstname(msg->msg, DNS_SECTION_ANSWER) - == ISC_R_SUCCESS) - dump_database_section(msg->msg, DNS_SECTION_ANSWER); - - if (dns_message_firstname(msg->msg, DNS_SECTION_AUTHORITY) - == ISC_R_SUCCESS) - dump_database_section(msg->msg, DNS_SECTION_AUTHORITY); - - if (dns_message_firstname(msg->msg, DNS_SECTION_ADDITIONAL) - == ISC_R_SUCCESS) - dump_database_section(msg->msg, DNS_SECTION_ADDITIONAL); - } -} - - -dns_rdataset_t * -search_type(dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers) { - dns_rdataset_t *rdataset; - dns_rdata_sig_t siginfo; - dns_rdata_t sigrdata; - isc_result_t result; - - for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - if (type == dns_rdatatype_any) { - if (rdataset->type != dns_rdatatype_rrsig) - return (rdataset); - } else if ((type == dns_rdatatype_rrsig) && - (rdataset->type == dns_rdatatype_rrsig)) { - dns_rdata_init(&sigrdata); - result = dns_rdataset_first(rdataset); - check_result(result, "empty rdataset"); - dns_rdataset_current(rdataset, &sigrdata); - result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL); - check_result(result, "sigrdata tostruct siginfo"); - - if ((siginfo.covered == covers) || - (covers == dns_rdatatype_any)) { - dns_rdata_reset(&sigrdata); - dns_rdata_freestruct(&siginfo); - return (rdataset); - } - dns_rdata_reset(&sigrdata); - dns_rdata_freestruct(&siginfo); - } else if (rdataset->type == type) - return (rdataset); - } - return (NULL); -} - -dns_rdataset_t * -chase_scanname_section(dns_message_t *msg, dns_name_t *name, - dns_rdatatype_t type, dns_rdatatype_t covers, - int section) -{ - dns_rdataset_t *rdataset; - dns_name_t *msg_name = NULL; - - do { - dns_message_currentname(msg, section, &msg_name); - if (dns_name_compare(msg_name, name) == 0) { - rdataset = search_type(msg_name, type, covers); - if (rdataset != NULL) - return (rdataset); - } - msg_name = NULL; - } while (dns_message_nextname(msg, section) == ISC_R_SUCCESS); - - return (NULL); -} - - -dns_rdataset_t * -chase_scanname(dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers) -{ - dns_rdataset_t *rdataset = NULL; - dig_message_t * msg; - - for (msg = ISC_LIST_HEAD(chase_message_list2); msg != NULL; - msg = ISC_LIST_NEXT(msg, link)) { - if (dns_message_firstname(msg->msg, DNS_SECTION_ANSWER) - == ISC_R_SUCCESS) - rdataset = chase_scanname_section(msg->msg, name, - type, covers, - DNS_SECTION_ANSWER); - if (rdataset != NULL) - return (rdataset); - if (dns_message_firstname(msg->msg, DNS_SECTION_AUTHORITY) - == ISC_R_SUCCESS) - rdataset = - chase_scanname_section(msg->msg, name, - type, covers, - DNS_SECTION_AUTHORITY); - if (rdataset != NULL) - return (rdataset); - if (dns_message_firstname(msg->msg, DNS_SECTION_ADDITIONAL) - == ISC_R_SUCCESS) - rdataset = - chase_scanname_section(msg->msg, name, type, - covers, - DNS_SECTION_ADDITIONAL); - if (rdataset != NULL) - return (rdataset); - } - - return (NULL); -} - -dns_rdataset_t * -sigchase_scanname(dns_rdatatype_t type, dns_rdatatype_t covers, - isc_boolean_t * lookedup, dns_name_t *rdata_name) -{ - dig_lookup_t *lookup; - isc_buffer_t *b = NULL; - isc_region_t r; - isc_result_t result; - dns_rdataset_t * temp; - dns_rdatatype_t querytype; - - temp = chase_scanname(rdata_name, type, covers); - if (temp != NULL) - return (temp); - - if (*lookedup == ISC_TRUE) - return (NULL); - - lookup = clone_lookup(current_lookup, ISC_TRUE); - lookup->trace_root = ISC_FALSE; - lookup->new_search = ISC_TRUE; - - result = isc_buffer_allocate(mctx, &b, BUFSIZE); - check_result(result, "isc_buffer_allocate"); - result = dns_name_totext(rdata_name, ISC_FALSE, b); - check_result(result, "dns_name_totext"); - isc_buffer_usedregion(b, &r); - r.base[r.length] = '\0'; - strcpy(lookup->textname, (char*)r.base); - isc_buffer_free(&b); - - if (type == dns_rdatatype_rrsig) - querytype = covers; - else - querytype = type; - - if (querytype == 0 || querytype == 255) { - printf("Error in the queried type: %d\n", querytype); - return (NULL); - } - - lookup->rdtype = querytype; - lookup->rdtypeset = ISC_TRUE; - lookup->qrdtype = querytype; - *lookedup = ISC_TRUE; - - ISC_LIST_APPEND(lookup_list, lookup, link); - printf("\n\nLaunch a query to find a RRset of type "); - print_type(type); - printf(" for zone: %s\n", lookup->textname); - return (NULL); -} - -void -insert_trustedkey(dst_key_t * key) -{ - if (key == NULL) - return; - if (tk_list.nb_tk >= MAX_TRUSTED_KEY) - return; - - tk_list.key[tk_list.nb_tk++] = key; - return; -} - -void -clean_trustedkey() -{ - int i = 0; - - for (i= 0; i < MAX_TRUSTED_KEY; i++) { - if (tk_list.key[i] != NULL) { - dst_key_free(&tk_list.key[i]); - tk_list.key[i] = NULL; - } else - break; - } - tk_list.nb_tk = 0; - return; -} - -char alphnum[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - -isc_result_t -removetmpkey(isc_mem_t *mctx, const char *file) -{ - char *tempnamekey = NULL; - int tempnamekeylen; - isc_result_t result; - - tempnamekeylen = strlen(file)+10; - - tempnamekey = isc_mem_allocate(mctx, tempnamekeylen); - if (tempnamekey == NULL) - return (ISC_R_NOMEMORY); - - memset(tempnamekey, 0, tempnamekeylen); - - strcat(tempnamekey, file); - strcat(tempnamekey,".key"); - isc_file_remove(tempnamekey); - - result = isc_file_remove(tempnamekey); - isc_mem_free(mctx, tempnamekey); - return (result); -} - -isc_result_t -opentmpkey(isc_mem_t *mctx, const char *file, char **tempp, FILE **fp) { - FILE *f = NULL; - isc_result_t result; - char *tempname = NULL; - char *tempnamekey = NULL; - int tempnamelen; - int tempnamekeylen; - char *x; - char *cp; - isc_uint32_t which; - - while (1) { - tempnamelen = strlen(file) + 20; - tempname = isc_mem_allocate(mctx, tempnamelen); - if (tempname == NULL) - return (ISC_R_NOMEMORY); - memset(tempname, 0, tempnamelen); - - result = isc_file_mktemplate(file, tempname, tempnamelen); - if (result != ISC_R_SUCCESS) - goto cleanup; - - cp = tempname; - while (*cp != '\0') - cp++; - if (cp == tempname) { - isc_mem_free(mctx, tempname); - return (ISC_R_FAILURE); - } - - x = cp--; - while (cp >= tempname && *cp == 'X') { - isc_random_get(&which); - *cp = alphnum[which % (sizeof(alphnum) - 1)]; - x = cp--; - } - - tempnamekeylen = tempnamelen+5; - tempnamekey = isc_mem_allocate(mctx, tempnamekeylen); - if (tempnamekey == NULL) - return (ISC_R_NOMEMORY); - - memset(tempnamekey, 0, tempnamekeylen); - strncpy(tempnamekey, tempname, tempnamelen); - strcat(tempnamekey ,".key"); - - - if (isc_file_exists(tempnamekey)) { - isc_mem_free(mctx, tempnamekey); - isc_mem_free(mctx, tempname); - continue; - } - - if ((f = fopen(tempnamekey, "w")) == NULL) { - printf("get_trusted_key(): trusted key not found %s\n", - tempnamekey); - return (ISC_R_FAILURE); - } - break; - } - isc_mem_free(mctx, tempnamekey); - *tempp = tempname; - *fp = f; - return (ISC_R_SUCCESS); - - cleanup: - isc_mem_free(mctx, tempname); - - return (result); -} - - -isc_result_t -get_trusted_key(isc_mem_t *mctx) -{ - isc_result_t result; - const char *filename = NULL; - char *filetemp = NULL; - char buf[1500]; - FILE *fp, *fptemp; - dst_key_t *key = NULL; - - result = isc_file_exists(trustedkey); - if (result != ISC_TRUE) { - result = isc_file_exists("/etc/trusted-key.key"); - if (result != ISC_TRUE) { - result = isc_file_exists("./trusted-key.key"); - if (result != ISC_TRUE) - return (ISC_R_FAILURE); - else - filename = "./trusted-key.key"; - } else - filename = "/etc/trusted-key.key"; - } else - filename = trustedkey; - - if (filename == NULL) { - printf("No trusted key\n"); - return (ISC_R_FAILURE); - } - - if ((fp = fopen(filename, "r")) == NULL) { - printf("get_trusted_key(): trusted key not found %s\n", - filename); - return (ISC_R_FAILURE); - } - while (fgets(buf, sizeof(buf), fp) != NULL) { - result = opentmpkey(mctx,"tmp_file", &filetemp, &fptemp); - if (result != ISC_R_SUCCESS) { - fclose(fp); - return (ISC_R_FAILURE); - } - if (fputs(buf, fptemp) < 0) { - fclose(fp); - fclose(fptemp); - return (ISC_R_FAILURE); - } - fclose(fptemp); - result = dst_key_fromnamedfile(filetemp, DST_TYPE_PUBLIC, - mctx, &key); - removetmpkey(mctx, filetemp); - isc_mem_free(mctx, filetemp); - if (result != ISC_R_SUCCESS) { - fclose(fp); - return (ISC_R_FAILURE); - } - insert_trustedkey(key); -#if 0 - dst_key_tofile(key, DST_TYPE_PUBLIC,"/tmp"); -#endif - key = NULL; - } - return (ISC_R_SUCCESS); -} - - -static void -nameFromString(const char *str, dns_name_t *p_ret) { - size_t len = strlen(str); - isc_result_t result; - isc_buffer_t buffer; - dns_fixedname_t fixedname; - - REQUIRE(p_ret != NULL); - REQUIRE(str != NULL); - - isc_buffer_init(&buffer, str, len); - isc_buffer_add(&buffer, len); - - dns_fixedname_init(&fixedname); - result = dns_name_fromtext(dns_fixedname_name(&fixedname), &buffer, - dns_rootname, ISC_TRUE, NULL); - check_result(result, "nameFromString"); - - if (dns_name_dynamic(p_ret)) - free_name(p_ret, mctx); - - result = dns_name_dup(dns_fixedname_name(&fixedname), mctx, p_ret); - check_result(result, "nameFromString"); -} - - -#if DIG_SIGCHASE_TD -isc_result_t -prepare_lookup(dns_name_t *name) -{ - isc_result_t result; - dig_lookup_t *lookup = NULL; - dig_server_t *s; - void *ptr; - - lookup = clone_lookup(current_lookup, ISC_TRUE); - lookup->trace_root = ISC_FALSE; - lookup->new_search = ISC_TRUE; - lookup->trace_root_sigchase = ISC_FALSE; - - strncpy(lookup->textname, lookup->textnamesigchase, MXNAME); - - lookup->rdtype = lookup->rdtype_sigchase; - lookup->rdtypeset = ISC_TRUE; - lookup->qrdtype = lookup->qrdtype_sigchase; - - s = ISC_LIST_HEAD(lookup->my_server_list); - while (s != NULL) { - debug("freeing server %p belonging to %p", - s, lookup); - ptr = s; - s = ISC_LIST_NEXT(s, link); - ISC_LIST_DEQUEUE(lookup->my_server_list, - (dig_server_t *)ptr, link); - isc_mem_free(mctx, ptr); - } - - - for (result = dns_rdataset_first(chase_nsrdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(chase_nsrdataset)) { - char namestr[DNS_NAME_FORMATSIZE]; - dns_rdata_ns_t ns; - dns_rdata_t rdata = DNS_RDATA_INIT; - dig_server_t * srv = NULL; -#define __FOLLOW_GLUE__ -#ifdef __FOLLOW_GLUE__ - isc_buffer_t *b = NULL; - isc_result_t result; - isc_region_t r; - dns_rdataset_t *rdataset = NULL; - isc_boolean_t true = ISC_TRUE; -#endif - - memset(namestr, 0, DNS_NAME_FORMATSIZE); - - dns_rdataset_current(chase_nsrdataset, &rdata); - - (void)dns_rdata_tostruct(&rdata, &ns, NULL); - - - -#ifdef __FOLLOW_GLUE__ - - result = advanced_rrsearch(&rdataset, &ns.name, - dns_rdatatype_aaaa, - dns_rdatatype_any, &true); - if (result == ISC_R_SUCCESS) { - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - dns_rdata_t aaaa = DNS_RDATA_INIT; - dns_rdataset_current(rdataset, &aaaa); - - result = isc_buffer_allocate(mctx, &b, 80); - check_result(result, "isc_buffer_allocate"); - - dns_rdata_totext(&aaaa, &ns.name, b); - isc_buffer_usedregion(b, &r); - r.base[r.length] = '\0'; - strncpy(namestr, (char*)r.base, - DNS_NAME_FORMATSIZE); - isc_buffer_free(&b); - dns_rdata_reset(&aaaa); - - - srv = make_server(namestr, namestr); - - ISC_LIST_APPEND(lookup->my_server_list, - srv, link); - } - } - - rdataset = NULL; - result = advanced_rrsearch(&rdataset, &ns.name, dns_rdatatype_a, - dns_rdatatype_any, &true); - if (result == ISC_R_SUCCESS) { - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) { - dns_rdata_t a = DNS_RDATA_INIT; - dns_rdataset_current(rdataset, &a); - - result = isc_buffer_allocate(mctx, &b, 80); - check_result(result, "isc_buffer_allocate"); - - dns_rdata_totext(&a, &ns.name, b); - isc_buffer_usedregion(b, &r); - r.base[r.length] = '\0'; - strncpy(namestr, (char*)r.base, - DNS_NAME_FORMATSIZE); - isc_buffer_free(&b); - dns_rdata_reset(&a); - printf("ns name: %s\n", namestr); - - - srv = make_server(namestr, namestr); - - ISC_LIST_APPEND(lookup->my_server_list, - srv, link); - } - } -#else - - dns_name_format(&ns.name, namestr, sizeof(namestr)); - printf("ns name: "); - dns_name_print(&ns.name, stdout); - printf("\n"); - srv = make_server(namestr, namestr); - - ISC_LIST_APPEND(lookup->my_server_list, srv, link); - -#endif - dns_rdata_freestruct(&ns); - dns_rdata_reset(&rdata); - - } - - ISC_LIST_APPEND(lookup_list, lookup, link); - printf("\nLaunch a query to find a RRset of type "); - print_type(lookup->rdtype); - printf(" for zone: %s", lookup->textname); - printf(" with nameservers:"); - printf("\n"); - print_rdataset(name, chase_nsrdataset, mctx); - return (ISC_R_SUCCESS); -} - - -isc_result_t -child_of_zone(dns_name_t * name, dns_name_t * zone_name, - dns_name_t * child_name) -{ - dns_namereln_t name_reln; - int orderp; - unsigned int nlabelsp; - - name_reln = dns_name_fullcompare(name, zone_name, &orderp, &nlabelsp); - if (name_reln != dns_namereln_subdomain || - dns_name_countlabels(name) <= dns_name_countlabels(zone_name) + 1) { - printf("\n;; ERROR : "); - dns_name_print(name, stdout); - printf(" is not a subdomain of: "); - dns_name_print(zone_name, stdout); - printf(" FAILED\n\n"); - return (ISC_R_FAILURE); - } - - dns_name_getlabelsequence(name, - dns_name_countlabels(name) - - dns_name_countlabels(zone_name) -1, - dns_name_countlabels(zone_name) +1, - child_name); - return (ISC_R_SUCCESS); -} - -isc_result_t -grandfather_pb_test(dns_name_t *zone_name, dns_rdataset_t *sigrdataset) -{ - isc_result_t result; - dns_rdata_t sigrdata; - dns_rdata_sig_t siginfo; - - result = dns_rdataset_first(sigrdataset); - check_result(result, "empty RRSIG dataset"); - dns_rdata_init(&sigrdata); - - do { - dns_rdataset_current(sigrdataset, &sigrdata); - - result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL); - check_result(result, "sigrdata tostruct siginfo"); - - if (dns_name_compare(&siginfo.signer, zone_name) == 0) { - dns_rdata_freestruct(&siginfo); - dns_rdata_reset(&sigrdata); - return (ISC_R_SUCCESS); - } - - dns_rdata_freestruct(&siginfo); - - } while (dns_rdataset_next(chase_sigkeyrdataset) == ISC_R_SUCCESS); - - dns_rdata_reset(&sigrdata); - - return (ISC_R_FAILURE); -} - - -isc_result_t -initialization(dns_name_t *name) -{ - isc_result_t result; - isc_boolean_t true = ISC_TRUE; - - chase_nsrdataset = NULL; - result = advanced_rrsearch(&chase_nsrdataset, name, dns_rdatatype_ns, - dns_rdatatype_any, &true); - if (result != ISC_R_SUCCESS) { - printf("\n;; NS RRset is missing to continue validation:" - " FAILED\n\n"); - return (ISC_R_FAILURE); - } - INSIST(chase_nsrdataset != NULL); - prepare_lookup(name); - - dup_name(name, &chase_current_name, mctx); - - return (ISC_R_SUCCESS); -} -#endif - -void -print_rdataset(dns_name_t *name, dns_rdataset_t *rdataset, isc_mem_t *mctx) -{ - isc_buffer_t *b = NULL; - isc_result_t result; - isc_region_t r; - - result = isc_buffer_allocate(mctx, &b, 9000); - check_result(result, "isc_buffer_allocate"); - - printrdataset(name, rdataset, b); - - isc_buffer_usedregion(b, &r); - r.base[r.length] = '\0'; - - - printf("%s\n", r.base); - - isc_buffer_free(&b); -} - - -void -dup_name(dns_name_t *source, dns_name_t *target, isc_mem_t *mctx) { - isc_result_t result; - - if (dns_name_dynamic(target)) - free_name(target, mctx); - result = dns_name_dup(source, mctx, target); - check_result(result, "dns_name_dup"); -} - -void -free_name(dns_name_t *name, isc_mem_t *mctx) { - dns_name_free(name, mctx); - dns_name_init(name, NULL); -} - -/* - * - * take a DNSKEY RRset and the RRSIG RRset corresponding in parameter - * return ISC_R_SUCCESS if the DNSKEY RRset contains a trusted_key - * and the RRset is valid - * return ISC_R_NOTFOUND if not contains trusted key - or if the RRset isn't valid - * return ISC_R_FAILURE if problem - * - */ -isc_result_t -contains_trusted_key(dns_name_t *name, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset, - isc_mem_t *mctx) -{ - isc_result_t result; - dns_rdata_t rdata; - dst_key_t *trustedKey = NULL; - dst_key_t *dnsseckey = NULL; - int i; - - if (name == NULL || rdataset == NULL) - return (ISC_R_FAILURE); - - result = dns_rdataset_first(rdataset); - check_result(result, "empty rdataset"); - dns_rdata_init(&rdata); - - do { - dns_rdataset_current(rdataset, &rdata); - INSIST(rdata.type == dns_rdatatype_dnskey); - - result = dns_dnssec_keyfromrdata(name, &rdata, - mctx, &dnsseckey); - check_result(result, "dns_dnssec_keyfromrdata"); - - - for (i = 0; i < tk_list.nb_tk; i++) { - if (dst_key_compare(tk_list.key[i], dnsseckey) - == ISC_TRUE) { - dns_rdata_reset(&rdata); - - printf(";; Ok, find a Trusted Key in the " - "DNSKEY RRset: %d\n", - dst_key_id(dnsseckey)); - if (sigchase_verify_sig_key(name, rdataset, - dnsseckey, - sigrdataset, - mctx) - == ISC_R_SUCCESS) { - dst_key_free(&dnsseckey); - dnsseckey = NULL; - return (ISC_R_SUCCESS); - } - } - } - - dns_rdata_reset(&rdata); - if (dnsseckey != NULL) - dst_key_free(&dnsseckey); - } while (dns_rdataset_next(rdataset) == ISC_R_SUCCESS); - - if (trustedKey != NULL) - dst_key_free(&trustedKey); - trustedKey = NULL; - - return (ISC_R_NOTFOUND); -} - -isc_result_t -sigchase_verify_sig(dns_name_t *name, dns_rdataset_t *rdataset, - dns_rdataset_t *keyrdataset, - dns_rdataset_t *sigrdataset, - isc_mem_t *mctx) -{ - isc_result_t result; - dns_rdata_t keyrdata; - dst_key_t *dnsseckey = NULL; - - result = dns_rdataset_first(keyrdataset); - check_result(result, "empty DNSKEY dataset"); - dns_rdata_init(&keyrdata); - - do { - dns_rdataset_current(keyrdataset, &keyrdata); - INSIST(keyrdata.type == dns_rdatatype_dnskey); - - result = dns_dnssec_keyfromrdata(name, &keyrdata, - mctx, &dnsseckey); - check_result(result, "dns_dnssec_keyfromrdata"); - - result = sigchase_verify_sig_key(name, rdataset, dnsseckey, - sigrdataset, mctx); - if (result == ISC_R_SUCCESS) { - dns_rdata_reset(&keyrdata); - dst_key_free(&dnsseckey); - return (ISC_R_SUCCESS); - } - dst_key_free(&dnsseckey); - } while (dns_rdataset_next(chase_keyrdataset) == ISC_R_SUCCESS); - - dns_rdata_reset(&keyrdata); - - return (ISC_R_NOTFOUND); -} - -isc_result_t -sigchase_verify_sig_key(dns_name_t *name, dns_rdataset_t *rdataset, - dst_key_t *dnsseckey, dns_rdataset_t *sigrdataset, - isc_mem_t *mctx) -{ - isc_result_t result; - dns_rdata_t sigrdata; - dns_rdata_sig_t siginfo; - - result = dns_rdataset_first(sigrdataset); - check_result(result, "empty RRSIG dataset"); - dns_rdata_init(&sigrdata); - - do { - dns_rdataset_current(sigrdataset, &sigrdata); - - result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL); - check_result(result, "sigrdata tostruct siginfo"); - - /* - * Test if the id of the DNSKEY is - * the id of the DNSKEY signer's - */ - if (siginfo.keyid == dst_key_id(dnsseckey)) { - - result = dns_rdataset_first(rdataset); - check_result(result, "empty DS dataset"); - - result = dns_dnssec_verify(name, rdataset, dnsseckey, - ISC_FALSE, mctx, &sigrdata); - - printf(";; VERIFYING "); - print_type(rdataset->type); - printf(" RRset for "); - dns_name_print(name, stdout); - printf(" with DNSKEY:%d: %s\n", dst_key_id(dnsseckey), - isc_result_totext(result)); - - if (result == ISC_R_SUCCESS) { - dns_rdata_reset(&sigrdata); - return (result); - } - } - dns_rdata_freestruct(&siginfo); - - } while (dns_rdataset_next(chase_sigkeyrdataset) == ISC_R_SUCCESS); - - dns_rdata_reset(&sigrdata); - - return (ISC_R_NOTFOUND); -} - - -isc_result_t -sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset, - dns_rdataset_t *dsrdataset, isc_mem_t *mctx) -{ - isc_result_t result; - dns_rdata_t keyrdata; - dns_rdata_t newdsrdata; - dns_rdata_t dsrdata; - dns_rdata_ds_t dsinfo; - dst_key_t *dnsseckey = NULL; - unsigned char dsbuf[DNS_DS_BUFFERSIZE]; - - result = dns_rdataset_first(dsrdataset); - check_result(result, "empty DSset dataset"); - dns_rdata_init(&dsrdata); - do { - dns_rdataset_current(dsrdataset, &dsrdata); - - result = dns_rdata_tostruct(&dsrdata, &dsinfo, NULL); - check_result(result, "dns_rdata_tostruct for DS"); - - result = dns_rdataset_first(keyrdataset); - check_result(result, "empty KEY dataset"); - dns_rdata_init(&keyrdata); - - do { - dns_rdataset_current(keyrdataset, &keyrdata); - INSIST(keyrdata.type == dns_rdatatype_dnskey); - - result = dns_dnssec_keyfromrdata(name, &keyrdata, - mctx, &dnsseckey); - check_result(result, "dns_dnssec_keyfromrdata"); - - /* - * Test if the id of the DNSKEY is the - * id of DNSKEY referenced by the DS - */ - if (dsinfo.key_tag == dst_key_id(dnsseckey)) { - dns_rdata_init(&newdsrdata); - - result = dns_ds_buildrdata(name, &keyrdata, - dsinfo.digest_type, - dsbuf, &newdsrdata); - dns_rdata_freestruct(&dsinfo); - - if (result != ISC_R_SUCCESS) { - dns_rdata_reset(&keyrdata); - dns_rdata_reset(&newdsrdata); - dns_rdata_reset(&dsrdata); - dst_key_free(&dnsseckey); - dns_rdata_freestruct(&dsinfo); - printf("Oops: impossible to build" - " new DS rdata\n"); - return (result); - } - - - if (dns_rdata_compare(&dsrdata, - &newdsrdata) == 0) { - printf(";; OK a DS valids a DNSKEY" - " in the RRset\n"); - printf(";; Now verify that this" - " DNSKEY validates the " - "DNSKEY RRset\n"); - - result = sigchase_verify_sig_key(name, - keyrdataset, - dnsseckey, - chase_sigkeyrdataset, - mctx); - if (result == ISC_R_SUCCESS) { - dns_rdata_reset(&keyrdata); - dns_rdata_reset(&newdsrdata); - dns_rdata_reset(&dsrdata); - dst_key_free(&dnsseckey); - - return (result); - } - } else { - printf(";; This DS is NOT the DS for" - " the chasing KEY: FAILED\n"); - } - - dns_rdata_reset(&newdsrdata); - } - dst_key_free(&dnsseckey); - dnsseckey = NULL; - } while (dns_rdataset_next(chase_keyrdataset) == ISC_R_SUCCESS); - dns_rdata_reset(&keyrdata); - - } while (dns_rdataset_next(chase_dsrdataset) == ISC_R_SUCCESS); -#if 0 - dns_rdata_reset(&dsrdata); WARNING -#endif - - return (ISC_R_NOTFOUND); -} - -/* - * - * take a pointer on a rdataset in parameter and try to resolv it. - * the searched rrset is a rrset on 'name' with type 'type' - * (and if the type is a rrsig the signature cover 'covers'). - * the lookedup is to known if you have already done the query on the net. - * ISC_R_SUCCESS: if we found the rrset - * ISC_R_NOTFOUND: we do not found the rrset in cache - * and we do a query on the net - * ISC_R_FAILURE: rrset not found - */ -isc_result_t -advanced_rrsearch(dns_rdataset_t **rdataset, dns_name_t *name, - dns_rdatatype_t type, dns_rdatatype_t covers, - isc_boolean_t *lookedup) -{ - isc_boolean_t tmplookedup; - - INSIST(rdataset != NULL); - - if (*rdataset != NULL) - return (ISC_R_SUCCESS); - - tmplookedup = *lookedup; - if ((*rdataset = sigchase_scanname(type, covers, - lookedup, name)) == NULL) { - if (tmplookedup) - return (ISC_R_FAILURE); - return (ISC_R_NOTFOUND); - } - *lookedup = ISC_FALSE; - return (ISC_R_SUCCESS); -} - - - -#if DIG_SIGCHASE_TD -void -sigchase_td(dns_message_t *msg) -{ - isc_result_t result; - dns_name_t *name = NULL; - isc_boolean_t have_answer = ISC_FALSE; - isc_boolean_t true = ISC_TRUE; - - if ((result = dns_message_firstname(msg, DNS_SECTION_ANSWER)) - == ISC_R_SUCCESS) { - dns_message_currentname(msg, DNS_SECTION_ANSWER, &name); - if (current_lookup->trace_root_sigchase) { - initialization(name); - return; - } - have_answer = true; - } else { - if (!current_lookup->trace_root_sigchase) { - result = dns_message_firstname(msg, - DNS_SECTION_AUTHORITY); - if (result == ISC_R_SUCCESS) - dns_message_currentname(msg, - DNS_SECTION_AUTHORITY, - &name); - chase_nsrdataset - = chase_scanname_section(msg, name, - dns_rdatatype_ns, - dns_rdatatype_any, - DNS_SECTION_AUTHORITY); - dup_name(name, &chase_authority_name, mctx); - if (chase_nsrdataset != NULL) { - have_delegation_ns = ISC_TRUE; - printf("no response but there is a delegation" - " in authority section:"); - dns_name_print(name, stdout); - printf("\n"); - } else { - printf("no response and no delegation in " - "authority section but a reference" - " to: "); - dns_name_print(name, stdout); - printf("\n"); - error_message = msg; - } - } else { - printf(";; NO ANSWERS: %s\n", - isc_result_totext(result)); - free_name(&chase_name, mctx); - clean_trustedkey(); - return; - } - } - - - if (have_answer) { - chase_rdataset - = chase_scanname_section(msg, &chase_name, - current_lookup - ->rdtype_sigchase, - dns_rdatatype_any, - DNS_SECTION_ANSWER); - if (chase_rdataset != NULL) - have_response = ISC_TRUE; - } - - result = advanced_rrsearch(&chase_keyrdataset, - &chase_current_name, - dns_rdatatype_dnskey, - dns_rdatatype_any, - &chase_keylookedup); - if (result == ISC_R_FAILURE) { - printf("\n;; DNSKEY is missing to continue validation:" - " FAILED\n\n"); - goto cleanandgo; - } - if (result == ISC_R_NOTFOUND) - return; - INSIST(chase_keyrdataset != NULL); - printf("\n;; DNSKEYset:\n"); - print_rdataset(&chase_current_name , chase_keyrdataset, mctx); - - - result = advanced_rrsearch(&chase_sigkeyrdataset, - &chase_current_name, - dns_rdatatype_rrsig, - dns_rdatatype_dnskey, - &chase_sigkeylookedup); - if (result == ISC_R_FAILURE) { - printf("\n;; RRSIG of DNSKEY is missing to continue validation:" - " FAILED\n\n"); - goto cleanandgo; - } - if (result == ISC_R_NOTFOUND) - return; - INSIST(chase_sigkeyrdataset != NULL); - printf("\n;; RRSIG of the DNSKEYset:\n"); - print_rdataset(&chase_current_name , chase_sigkeyrdataset, mctx); - - - if (!chase_dslookedup && !chase_nslookedup) { - if (!delegation_follow) { - result = contains_trusted_key(&chase_current_name, - chase_keyrdataset, - chase_sigkeyrdataset, - mctx); - } else { - INSIST(chase_dsrdataset != NULL); - INSIST(chase_sigdsrdataset != NULL); - result = sigchase_verify_ds(&chase_current_name, - chase_keyrdataset, - chase_dsrdataset, - mctx); - } - - if (result != ISC_R_SUCCESS) { - printf("\n;; chain of trust can't be validated:" - " FAILED\n\n"); - goto cleanandgo; - } else { - chase_dsrdataset = NULL; - chase_sigdsrdataset = NULL; - } - } - - if (have_response || (!have_delegation_ns && !have_response)) { - /* test if it's a grand father case */ - - if (have_response) { - result = advanced_rrsearch(&chase_sigrdataset, - &chase_name, - dns_rdatatype_rrsig, - current_lookup - ->rdtype_sigchase, - &true); - if (result == ISC_R_FAILURE) { - printf("\n;; RRset is missing to continue" - " validation SHOULD NOT APPEND:" - " FAILED\n\n"); - goto cleanandgo; - } - - } else { - result = advanced_rrsearch(&chase_sigrdataset, - &chase_authority_name, - dns_rdatatype_rrsig, - dns_rdatatype_any, - &true); - if (result == ISC_R_FAILURE) { - printf("\n;; RRSIG is missing to continue" - " validation SHOULD NOT APPEND:" - " FAILED\n\n"); - goto cleanandgo; - } - } - result = grandfather_pb_test(&chase_current_name, - chase_sigrdataset); - if (result != ISC_R_SUCCESS) { - dns_name_t tmp_name; - - printf("\n;; We are in a Grand Father Problem:" - " See 2.2.1 in RFC 3568\n"); - chase_rdataset = NULL; - chase_sigrdataset = NULL; - have_response = ISC_FALSE; - have_delegation_ns = ISC_FALSE; - - dns_name_init(&tmp_name, NULL); - result = child_of_zone(&chase_name, &chase_current_name, - &tmp_name); - if (dns_name_dynamic(&chase_authority_name)) - free_name(&chase_authority_name, mctx); - dup_name(&tmp_name, &chase_authority_name, mctx); - printf(";; and we try to continue chain of trust" - " validation of the zone: "); - dns_name_print(&chase_authority_name, stdout); - printf("\n"); - have_delegation_ns = ISC_TRUE; - } else { - if (have_response) - goto finalstep; - else - chase_sigrdataset = NULL; - } - } - - if (have_delegation_ns) { - chase_nsrdataset = NULL; - result = advanced_rrsearch(&chase_nsrdataset, - &chase_authority_name, - dns_rdatatype_ns, - dns_rdatatype_any, - &chase_nslookedup); - if (result == ISC_R_FAILURE) { - printf("\n;;NSset is missing to continue validation:" - " FAILED\n\n"); - goto cleanandgo; - } - if (result == ISC_R_NOTFOUND) { - return; - } - INSIST(chase_nsrdataset != NULL); - - result = advanced_rrsearch(&chase_dsrdataset, - &chase_authority_name, - dns_rdatatype_ds, - dns_rdatatype_any, - &chase_dslookedup); - if (result == ISC_R_FAILURE) { - printf("\n;; DSset is missing to continue validation:" - " FAILED\n\n"); - goto cleanandgo; - } - if (result == ISC_R_NOTFOUND) - return; - INSIST(chase_dsrdataset != NULL); - printf("\n;; DSset:\n"); - print_rdataset(&chase_authority_name , chase_dsrdataset, mctx); - - result = advanced_rrsearch(&chase_sigdsrdataset, - &chase_authority_name, - dns_rdatatype_rrsig, - dns_rdatatype_ds, - &true); - if (result != ISC_R_SUCCESS) { - printf("\n;; DSset is missing to continue validation:" - " FAILED\n\n"); - goto cleanandgo; - } - printf("\n;; RRSIGset of DSset\n"); - print_rdataset(&chase_authority_name, - chase_sigdsrdataset, mctx); - INSIST(chase_sigdsrdataset != NULL); - - result = sigchase_verify_sig(&chase_authority_name, - chase_dsrdataset, - chase_keyrdataset, - chase_sigdsrdataset, mctx); - if (result != ISC_R_SUCCESS) { - printf("\n;; Impossible to verify the DSset:" - " FAILED\n\n"); - goto cleanandgo; - } - chase_keyrdataset = NULL; - chase_sigkeyrdataset = NULL; - - - prepare_lookup(&chase_authority_name); - - have_response = ISC_FALSE; - have_delegation_ns = ISC_FALSE; - delegation_follow = ISC_TRUE; - error_message = NULL; - dup_name(&chase_authority_name, &chase_current_name, mctx); - free_name(&chase_authority_name, mctx); - return; - } - - - if (error_message != NULL) { - dns_rdataset_t *rdataset; - dns_rdataset_t *sigrdataset; - dns_name_t rdata_name; - isc_result_t ret = ISC_R_FAILURE; - - dns_name_init(&rdata_name, NULL); - result = prove_nx(error_message, &chase_name, - current_lookup->rdclass_sigchase, - current_lookup->rdtype_sigchase, &rdata_name, - &rdataset, &sigrdataset); - if (rdataset == NULL || sigrdataset == NULL || - dns_name_countlabels(&rdata_name) == 0) { - printf("\n;; Impossible to verify the non-existence," - " the NSEC RRset can't be validated:" - " FAILED\n\n"); - goto cleanandgo; - } - ret = sigchase_verify_sig(&rdata_name, rdataset, - chase_keyrdataset, - sigrdataset, mctx); - if (ret != ISC_R_SUCCESS) { - free_name(&rdata_name, mctx); - printf("\n;; Impossible to verify the NSEC RR to prove" - " the non-existence : FAILED\n\n"); - goto cleanandgo; - } - free_name(&rdata_name, mctx); - if (result != ISC_R_SUCCESS) { - printf("\n;; Impossible to verify the non-existence:" - " FAILED\n\n"); - goto cleanandgo; - } else { - printf("\n;; OK the query doesn't have response but" - " we have validate this fact : SUCCESS\n\n"); - goto cleanandgo; - } - } - - cleanandgo: - printf(";; cleanandgo \n"); - if (dns_name_dynamic(&chase_current_name)) - free_name(&chase_current_name, mctx); - if (dns_name_dynamic(&chase_authority_name)) - free_name(&chase_authority_name, mctx); - clean_trustedkey(); - return; - - finalstep : - result = advanced_rrsearch(&chase_rdataset, &chase_name, - current_lookup->rdtype_sigchase, - dns_rdatatype_any , - &true); - if (result == ISC_R_FAILURE) { - printf("\n;; RRsig of RRset is missing to continue validation" - " SHOULD NOT APPEND: FAILED\n\n"); - goto cleanandgo; - } - result = sigchase_verify_sig(&chase_name, chase_rdataset, - chase_keyrdataset, - chase_sigrdataset, mctx); - if (result != ISC_R_SUCCESS) { - printf("\n;; Impossible to verify the RRset : FAILED\n\n"); - /* - printf("RRset:\n"); - print_rdataset(&chase_name , chase_rdataset, mctx); - printf("DNSKEYset:\n"); - print_rdataset(&chase_name , chase_keyrdataset, mctx); - printf("RRSIG of RRset:\n"); - print_rdataset(&chase_name , chase_sigrdataset, mctx); - printf("\n"); - */ - goto cleanandgo; - } else { - printf("\n;; The Answer:\n"); - print_rdataset(&chase_name , chase_rdataset, mctx); - - printf("\n;; FINISH : we have validate the DNSSEC chain" - " of trust: SUCCESS\n\n"); - goto cleanandgo; - } -} - -#endif - - -#if DIG_SIGCHASE_BU - -isc_result_t -getneededrr(dns_message_t *msg) -{ - isc_result_t result; - dns_name_t *name = NULL; - dns_rdata_t sigrdata; - dns_rdata_sig_t siginfo; - isc_boolean_t true = ISC_TRUE; - - if ((result = dns_message_firstname(msg, DNS_SECTION_ANSWER)) - != ISC_R_SUCCESS) { - printf(";; NO ANSWERS: %s\n", isc_result_totext(result)); - - if (chase_name.ndata == NULL) - return (ISC_R_ADDRNOTAVAIL); - } else { - dns_message_currentname(msg, DNS_SECTION_ANSWER, &name); - } - - /* What do we chase? */ - if (chase_rdataset == NULL) { - result = advanced_rrsearch(&chase_rdataset, name, - dns_rdatatype_any, - dns_rdatatype_any, &true); - if (result != ISC_R_SUCCESS) { - printf("\n;; No Answers: Validation FAILED\n\n"); - return (ISC_R_NOTFOUND); - } - dup_name(name, &chase_name, mctx); - printf(";; RRset to chase:\n"); - print_rdataset(&chase_name, chase_rdataset, mctx); - } - INSIST(chase_rdataset != NULL); - - - if (chase_sigrdataset == NULL) { - result = advanced_rrsearch(&chase_sigrdataset, name, - dns_rdatatype_rrsig, - chase_rdataset->type, - &chase_siglookedup); - if (result == ISC_R_FAILURE) { - printf("\n;; RRSIG is missing for continue validation:" - " FAILED\n\n"); - if (dns_name_dynamic(&chase_name)) - free_name(&chase_name, mctx); - return (ISC_R_NOTFOUND); - } - if (result == ISC_R_NOTFOUND) { - return (ISC_R_NOTFOUND); - } - printf("\n;; RRSIG of the RRset to chase:\n"); - print_rdataset(&chase_name, chase_sigrdataset, mctx); - } - INSIST(chase_sigrdataset != NULL); - - - /* first find the DNSKEY name */ - result = dns_rdataset_first(chase_sigrdataset); - check_result(result, "empty RRSIG dataset"); - dns_rdata_init(&sigrdata); - dns_rdataset_current(chase_sigrdataset, &sigrdata); - result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL); - check_result(result, "sigrdata tostruct siginfo"); - dup_name(&siginfo.signer, &chase_signame, mctx); - dns_rdata_freestruct(&siginfo); - dns_rdata_reset(&sigrdata); - - /* Do we have a key? */ - if (chase_keyrdataset == NULL) { - result = advanced_rrsearch(&chase_keyrdataset, - &chase_signame, - dns_rdatatype_dnskey, - dns_rdatatype_any, - &chase_keylookedup); - if (result == ISC_R_FAILURE) { - printf("\n;; DNSKEY is missing to continue validation:" - " FAILED\n\n"); - free_name(&chase_signame, mctx); - if (dns_name_dynamic(&chase_name)) - free_name(&chase_name, mctx); - return (ISC_R_NOTFOUND); - } - if (result == ISC_R_NOTFOUND) { - free_name(&chase_signame, mctx); - return (ISC_R_NOTFOUND); - } - printf("\n;; DNSKEYset that signs the RRset to chase:\n"); - print_rdataset(&chase_signame, chase_keyrdataset, mctx); - } - INSIST(chase_keyrdataset != NULL); - - if (chase_sigkeyrdataset == NULL) { - result = advanced_rrsearch(&chase_sigkeyrdataset, - &chase_signame, - dns_rdatatype_rrsig, - dns_rdatatype_dnskey, - &chase_sigkeylookedup); - if (result == ISC_R_FAILURE) { - printf("\n;; RRSIG for DNSKEY is missing to continue" - " validation : FAILED\n\n"); - free_name(&chase_signame, mctx); - if (dns_name_dynamic(&chase_name)) - free_name(&chase_name, mctx); - return (ISC_R_NOTFOUND); - } - if (result == ISC_R_NOTFOUND) { - free_name(&chase_signame, mctx); - return (ISC_R_NOTFOUND); - } - printf("\n;; RRSIG of the DNSKEYset that signs the " - "RRset to chase:\n"); - print_rdataset(&chase_signame, chase_sigkeyrdataset, mctx); - } - INSIST(chase_sigkeyrdataset != NULL); - - - if (chase_dsrdataset == NULL) { - result = advanced_rrsearch(&chase_dsrdataset, &chase_signame, - dns_rdatatype_ds, - dns_rdatatype_any, - &chase_dslookedup); - if (result == ISC_R_FAILURE) { - printf("\n;; WARNING There is no DS for the zone: "); - dns_name_print(&chase_signame, stdout); - printf("\n"); - } - if (result == ISC_R_NOTFOUND) { - free_name(&chase_signame, mctx); - return (ISC_R_NOTFOUND); - } - if (chase_dsrdataset != NULL) { - printf("\n;; DSset of the DNSKEYset\n"); - print_rdataset(&chase_signame, chase_dsrdataset, mctx); - } - } - - if (chase_dsrdataset != NULL) { - /* - * if there is no RRSIG of DS, - * we don't want to search on the network - */ - result = advanced_rrsearch(&chase_sigdsrdataset, - &chase_signame, - dns_rdatatype_rrsig, - dns_rdatatype_ds, &true); - if (result == ISC_R_FAILURE) { - printf(";; WARNING : NO RRSIG DS : RRSIG DS" - " should come with DS\n"); - /* - * We continue even the DS couldn't be validated, - * because the DNSKEY could be a Trusted Key. - */ - chase_dsrdataset = NULL; - } else { - printf("\n;; RRSIG of the DSset of the DNSKEYset\n"); - print_rdataset(&chase_signame, chase_sigdsrdataset, - mctx); - } - } - return (1); -} - - - -void -sigchase_bu(dns_message_t *msg) -{ - isc_result_t result; - int ret; - - if (tk_list.nb_tk == 0) { - result = get_trusted_key(mctx); - if (result != ISC_R_SUCCESS) { - printf("No trusted keys present\n"); - return; - } - } - - - ret = getneededrr(msg); - if (ret == ISC_R_NOTFOUND) - return; - - if (ret == ISC_R_ADDRNOTAVAIL) { - /* We have no response */ - dns_rdataset_t *rdataset; - dns_rdataset_t *sigrdataset; - dns_name_t rdata_name; - dns_name_t query_name; - - - dns_name_init(&query_name, NULL); - dns_name_init(&rdata_name, NULL); - nameFromString(current_lookup->textname, &query_name); - - result = prove_nx(msg, &query_name, current_lookup->rdclass, - current_lookup->rdtype, &rdata_name, - &rdataset, &sigrdataset); - free_name(&query_name, mctx); - if (rdataset == NULL || sigrdataset == NULL || - dns_name_countlabels(&rdata_name) == 0) { - printf("\n;; Impossible to verify the Non-existence," - " the NSEC RRset can't be validated: " - "FAILED\n\n"); - clean_trustedkey(); - return; - } - - if (result != ISC_R_SUCCESS) { - printf("\n No Answers and impossible to prove the" - " unsecurity : Validation FAILED\n\n"); - clean_trustedkey(); - return; - } - printf(";; An NSEC prove the non-existence of a answers," - " Now we want validate this NSEC\n"); - - dup_name(&rdata_name, &chase_name, mctx); - free_name(&rdata_name, mctx); - chase_rdataset = rdataset; - chase_sigrdataset = sigrdataset; - chase_keyrdataset = NULL; - chase_sigkeyrdataset = NULL; - chase_dsrdataset = NULL; - chase_sigdsrdataset = NULL; - chase_siglookedup = ISC_FALSE; - chase_keylookedup = ISC_FALSE; - chase_dslookedup = ISC_FALSE; - chase_sigdslookedup = ISC_FALSE; - sigchase(msg); - clean_trustedkey(); - return; - } - - - printf("\n\n\n;; WE HAVE MATERIAL, WE NOW DO VALIDATION\n"); - - result = sigchase_verify_sig(&chase_name, chase_rdataset, - chase_keyrdataset, - chase_sigrdataset, mctx); - if (result != ISC_R_SUCCESS) { - free_name(&chase_name, mctx); - free_name(&chase_signame, mctx); - printf(";; No DNSKEY is valid to check the RRSIG" - " of the RRset: FAILED\n"); - clean_trustedkey(); - return; - } - printf(";; OK We found DNSKEY (or more) to validate the RRset\n"); - - result = contains_trusted_key(&chase_signame, chase_keyrdataset, - chase_sigkeyrdataset, mctx); - if (result == ISC_R_SUCCESS) { - free_name(&chase_name, mctx); - free_name(&chase_signame, mctx); - printf("\n;; Ok this DNSKEY is a Trusted Key," - " DNSSEC validation is ok: SUCCESS\n\n"); - clean_trustedkey(); - return; - } - - printf(";; Now, we are going to validate this DNSKEY by the DS\n"); - - if (chase_dsrdataset == NULL) { - free_name(&chase_name, mctx); - free_name(&chase_signame, mctx); - printf(";; the DNSKEY isn't trusted-key and there isn't" - " DS to validate the DNSKEY: FAILED\n"); - clean_trustedkey(); - return; - } - - result = sigchase_verify_ds(&chase_signame, chase_keyrdataset, - chase_dsrdataset, mctx); - if (result != ISC_R_SUCCESS) { - free_name(&chase_signame, mctx); - free_name(&chase_name, mctx); - printf(";; ERROR no DS validates a DNSKEY in the" - " DNSKEY RRset: FAILED\n"); - clean_trustedkey(); - return; - } else - printf(";; OK this DNSKEY (validated by the DS) validates" - " the RRset of the DNSKEYs, thus the DNSKEY validates" - " the RRset\n"); - INSIST(chase_sigdsrdataset != NULL); - - dup_name(&chase_signame, &chase_name, mctx); - free_name(&chase_signame, mctx); - chase_rdataset = chase_dsrdataset; - chase_sigrdataset = chase_sigdsrdataset; - chase_keyrdataset = NULL; - chase_sigkeyrdataset = NULL; - chase_dsrdataset = NULL; - chase_sigdsrdataset = NULL; - chase_siglookedup = chase_keylookedup = ISC_FALSE; - chase_dslookedup = chase_sigdslookedup = ISC_FALSE; - - printf(";; Now, we want to validate the DS : recursive call\n"); - sigchase(msg); - return; -} -#endif - -void -sigchase(dns_message_t *msg) { -#if DIG_SIGCHASE_TD - if (current_lookup->do_topdown) { - sigchase_td(msg); - return; - } -#endif -#if DIG_SIGCHASE_BU - sigchase_bu(msg); - return; -#endif -} - - -/* - * return 1 if name1 < name2 - * 0 if name1 == name2 - * -1 if name1 > name2 - * and -2 if problem - */ -int -inf_name(dns_name_t *name1, dns_name_t *name2) -{ - dns_label_t label1; - dns_label_t label2; - unsigned int nblabel1; - unsigned int nblabel2; - int min_lum_label; - int i; - int ret = -2; - - nblabel1 = dns_name_countlabels(name1); - nblabel2 = dns_name_countlabels(name2); - - if (nblabel1 >= nblabel2) - min_lum_label = nblabel2; - else - min_lum_label = nblabel1; - - - for (i=1 ; i < min_lum_label; i++) { - dns_name_getlabel(name1, nblabel1 -1 - i, &label1); - dns_name_getlabel(name2, nblabel2 -1 - i, &label2); - if ((ret = isc_region_compare(&label1, &label2)) != 0) { - if (ret < 0) - return (-1); - else if (ret > 0) - return (1); - } - } - if (nblabel1 == nblabel2) - return (0); - - if (nblabel1 < nblabel2) - return (-1); - else - return (1); -} - -/** - * - * - * - */ -isc_result_t -prove_nx_domain(dns_message_t *msg, - dns_name_t *name, - dns_name_t *rdata_name, - dns_rdataset_t **rdataset, - dns_rdataset_t **sigrdataset) -{ - isc_result_t ret = ISC_R_FAILURE; - isc_result_t result = ISC_R_NOTFOUND; - dns_rdataset_t *nsecset = NULL; - dns_rdataset_t *signsecset = NULL ; - dns_rdata_t nsec = DNS_RDATA_INIT; - dns_name_t *nsecname; - dns_rdata_nsec_t nsecstruct; - - if ((result = dns_message_firstname(msg, DNS_SECTION_AUTHORITY)) - != ISC_R_SUCCESS) { - printf(";; nothing in authority section : impossible to" - " validate the non-existence : FAILED\n"); - return (ISC_R_FAILURE); - } - - do { - nsecname = NULL; - dns_message_currentname(msg, DNS_SECTION_AUTHORITY, &nsecname); - nsecset = search_type(nsecname, dns_rdatatype_nsec, - dns_rdatatype_any); - if (nsecset == NULL) - continue; - - printf("There is a NSEC for this zone in the" - " AUTHORITY section:\n"); - print_rdataset(nsecname, nsecset, mctx); - - for (result = dns_rdataset_first(nsecset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(nsecset)) { - dns_rdataset_current(nsecset, &nsec); - - - signsecset - = chase_scanname_section(msg, nsecname, - dns_rdatatype_rrsig, - dns_rdatatype_nsec, - DNS_SECTION_AUTHORITY); - if (signsecset == NULL) { - printf(";; no RRSIG NSEC in authority section:" - " impossible to validate the " - "non-existence: FAILED\n"); - return (ISC_R_FAILURE); - } - - ret = dns_rdata_tostruct(&nsec, &nsecstruct, NULL); - check_result(ret,"dns_rdata_tostruct"); - - if ((inf_name(nsecname, &nsecstruct.next) == 1 && - inf_name(name, &nsecstruct.next) == 1) || - (inf_name(name, nsecname) == 1 && - inf_name(&nsecstruct.next, name) == 1)) { - dns_rdata_freestruct(&nsecstruct); - *rdataset = nsecset; - *sigrdataset = signsecset; - dup_name(nsecname, rdata_name, mctx); - - return (ISC_R_SUCCESS); - } - - dns_rdata_freestruct(&nsecstruct); - } - } while (dns_message_nextname(msg, DNS_SECTION_AUTHORITY) - == ISC_R_SUCCESS); - - *rdataset = NULL; - *sigrdataset = NULL; - rdata_name = NULL; - return (ISC_R_FAILURE); -} - -/** - * - * - * - * - * - */ -isc_result_t -prove_nx_type(dns_message_t *msg, dns_name_t *name, dns_rdataset_t *nsecset, - dns_rdataclass_t class, dns_rdatatype_t type, - dns_name_t *rdata_name, dns_rdataset_t **rdataset, - dns_rdataset_t **sigrdataset) -{ - isc_result_t ret; - dns_rdataset_t *signsecset; - dns_rdata_t nsec = DNS_RDATA_INIT; - - UNUSED(class); - - ret = dns_rdataset_first(nsecset); - check_result(ret,"dns_rdataset_first"); - - dns_rdataset_current(nsecset, &nsec); - - ret = dns_nsec_typepresent(&nsec, type); - if (ret == ISC_R_SUCCESS) - printf("OK the NSEC said that the type doesn't exist \n"); - - signsecset = chase_scanname_section(msg, name, - dns_rdatatype_rrsig, - dns_rdatatype_nsec, - DNS_SECTION_AUTHORITY); - if (signsecset == NULL) { - printf("There isn't RRSIG NSEC for the zone \n"); - return (ISC_R_FAILURE); - } - dup_name(name, rdata_name, mctx); - *rdataset = nsecset; - *sigrdataset = signsecset; - - return (ret); -} - -/** - * - * - * - * - */ -isc_result_t -prove_nx(dns_message_t *msg, dns_name_t *name, dns_rdataclass_t class, - dns_rdatatype_t type, dns_name_t *rdata_name, - dns_rdataset_t **rdataset, dns_rdataset_t **sigrdataset) -{ - isc_result_t ret; - dns_rdataset_t *nsecset = NULL; - - printf("We want to prove the non-existance of a type of rdata %d" - " or of the zone: \n", type); - - if ((ret = dns_message_firstname(msg, DNS_SECTION_AUTHORITY)) - != ISC_R_SUCCESS) { - printf(";; nothing in authority section : impossible to" - " validate the non-existence : FAILED\n"); - return (ISC_R_FAILURE); - } - - nsecset = chase_scanname_section(msg, name, dns_rdatatype_nsec, - dns_rdatatype_any, - DNS_SECTION_AUTHORITY); - if (nsecset != NULL) { - printf("We have a NSEC for this zone :OK\n"); - ret = prove_nx_type(msg, name, nsecset, class, - type, rdata_name, rdataset, - sigrdataset); - if (ret != ISC_R_SUCCESS) { - printf("prove_nx: ERROR type exist\n"); - return (ret); - } else { - printf("prove_nx: OK type does not exist\n"); - return (ISC_R_SUCCESS); - } - } else { - printf("there is no NSEC for this zone: validating " - "that the zone doesn't exist\n"); - ret = prove_nx_domain(msg, name, rdata_name, - rdataset, sigrdataset); - return (ret); - } - /* Never get here */ -} -#endif diff --git a/contrib/bind9/bin/dig/host.1 b/contrib/bind9/bin/dig/host.1 deleted file mode 100644 index ee537bd..0000000 --- a/contrib/bind9/bin/dig/host.1 +++ /dev/null @@ -1,219 +0,0 @@ -.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") -.\" Copyright (C) 2000-2002 Internet Software Consortium. -.\" -.\" Permission to use, copy, modify, and 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: host.1,v 1.14.18.14 2007/05/09 03:33:12 marka Exp $ -.\" -.hy 0 -.ad l -.\" Title: host -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.71.1 -.\" Date: Jun 30, 2000 -.\" Manual: BIND9 -.\" Source: BIND9 -.\" -.TH "HOST" "1" "Jun 30, 2000" "BIND9" "BIND9" -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.SH "NAME" -host \- DNS lookup utility -.SH "SYNOPSIS" -.HP 5 -\fBhost\fR [\fB\-aCdlnrsTwv\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-N\ \fR\fB\fIndots\fR\fR] [\fB\-R\ \fR\fB\fInumber\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-W\ \fR\fB\fIwait\fR\fR] [\fB\-m\ \fR\fB\fIflag\fR\fR] [\fB\-4\fR] [\fB\-6\fR] {name} [server] -.SH "DESCRIPTION" -.PP -\fBhost\fR -is a simple utility for performing DNS lookups. It is normally used to convert names to IP addresses and vice versa. When no arguments or options are given, -\fBhost\fR -prints a short summary of its command line arguments and options. -.PP -\fIname\fR -is the domain name that is to be looked up. It can also be a dotted\-decimal IPv4 address or a colon\-delimited IPv6 address, in which case -\fBhost\fR -will by default perform a reverse lookup for that address. -\fIserver\fR -is an optional argument which is either the name or IP address of the name server that -\fBhost\fR -should query instead of the server or servers listed in -\fI/etc/resolv.conf\fR. -.PP -The -\fB\-a\fR -(all) option is equivalent to setting the -\fB\-v\fR -option and asking -\fBhost\fR -to make a query of type ANY. -.PP -When the -\fB\-C\fR -option is used, -\fBhost\fR -will attempt to display the SOA records for zone -\fIname\fR -from all the listed authoritative name servers for that zone. The list of name servers is defined by the NS records that are found for the zone. -.PP -The -\fB\-c\fR -option instructs to make a DNS query of class -\fIclass\fR. This can be used to lookup Hesiod or Chaosnet class resource records. The default class is IN (Internet). -.PP -Verbose output is generated by -\fBhost\fR -when the -\fB\-d\fR -or -\fB\-v\fR -option is used. The two options are equivalent. They have been provided for backwards compatibility. In previous versions, the -\fB\-d\fR -option switched on debugging traces and -\fB\-v\fR -enabled verbose output. -.PP -List mode is selected by the -\fB\-l\fR -option. This makes -\fBhost\fR -perform a zone transfer for zone -\fIname\fR. Transfer the zone printing out the NS, PTR and address records (A/AAAA). If combined with -\fB\-a\fR -all records will be printed. -.PP -The -\fB\-i\fR -option specifies that reverse lookups of IPv6 addresses should use the IP6.INT domain as defined in RFC1886. The default is to use IP6.ARPA. -.PP -The -\fB\-N\fR -option sets the number of dots that have to be in -\fIname\fR -for it to be considered absolute. The default value is that defined using the ndots statement in -\fI/etc/resolv.conf\fR, or 1 if no ndots statement is present. Names with fewer dots are interpreted as relative names and will be searched for in the domains listed in the -\fBsearch\fR -or -\fBdomain\fR -directive in -\fI/etc/resolv.conf\fR. -.PP -The number of UDP retries for a lookup can be changed with the -\fB\-R\fR -option. -\fInumber\fR -indicates how many times -\fBhost\fR -will repeat a query that does not get answered. The default number of retries is 1. If -\fInumber\fR -is negative or zero, the number of retries will default to 1. -.PP -Non\-recursive queries can be made via the -\fB\-r\fR -option. Setting this option clears the -\fBRD\fR -\(em recursion desired \(em bit in the query which -\fBhost\fR -makes. This should mean that the name server receiving the query will not attempt to resolve -\fIname\fR. The -\fB\-r\fR -option enables -\fBhost\fR -to mimic the behavior of a name server by making non\-recursive queries and expecting to receive answers to those queries that are usually referrals to other name servers. -.PP -By default -\fBhost\fR -uses UDP when making queries. The -\fB\-T\fR -option makes it use a TCP connection when querying the name server. TCP will be automatically selected for queries that require it, such as zone transfer (AXFR) requests. -.PP -The -\fB\-4\fR -option forces -\fBhost\fR -to only use IPv4 query transport. The -\fB\-6\fR -option forces -\fBhost\fR -to only use IPv6 query transport. -.PP -The -\fB\-t\fR -option is used to select the query type. -\fItype\fR -can be any recognized query type: CNAME, NS, SOA, SIG, KEY, AXFR, etc. When no query type is specified, -\fBhost\fR -automatically selects an appropriate query type. By default it looks for A records, but if the -\fB\-C\fR -option was given, queries will be made for SOA records, and if -\fIname\fR -is a dotted\-decimal IPv4 address or colon\-delimited IPv6 address, -\fBhost\fR -will query for PTR records. If a query type of IXFR is chosen the starting serial number can be specified by appending an equal followed by the starting serial number (e.g. \-t IXFR=12345678). -.PP -The time to wait for a reply can be controlled through the -\fB\-W\fR -and -\fB\-w\fR -options. The -\fB\-W\fR -option makes -\fBhost\fR -wait for -\fIwait\fR -seconds. If -\fIwait\fR -is less than one, the wait interval is set to one second. When the -\fB\-w\fR -option is used, -\fBhost\fR -will effectively wait forever for a reply. The time to wait for a response will be set to the number of seconds given by the hardware's maximum value for an integer quantity. -.PP -The -\fB\-s\fR -option tells -\fBhost\fR -\fInot\fR -to send the query to the next nameserver if any server responds with a SERVFAIL response, which is the reverse of normal stub resolver behavior. -.PP -The -\fB\-m\fR -can be used to set the memory usage debugging flags -\fIrecord\fR, -\fIusage\fR -and -\fItrace\fR. -.SH "IDN SUPPORT" -.PP -If -\fBhost\fR -has been built with IDN (internationalized domain name) support, it can accept and display non\-ASCII domain names. -\fBhost\fR -appropriately converts character encoding of domain name before sending a request to DNS server or displaying a reply from the server. If you'd like to turn off the IDN support for some reason, defines the -\fBIDN_DISABLE\fR -environment variable. The IDN support is disabled if the variable is set when -\fBhost\fR -runs. -.SH "FILES" -.PP -\fI/etc/resolv.conf\fR -.SH "SEE ALSO" -.PP -\fBdig\fR(1), -\fBnamed\fR(8). -.SH "COPYRIGHT" -Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") -.br -Copyright \(co 2000\-2002 Internet Software Consortium. -.br diff --git a/contrib/bind9/bin/dig/host.c b/contrib/bind9/bin/dig/host.c deleted file mode 100644 index 33025d5..0000000 --- a/contrib/bind9/bin/dig/host.c +++ /dev/null @@ -1,861 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-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: host.c,v 1.94.18.19 2007/08/28 07:19:55 tbox Exp $ */ - -/*! \file */ - -#include -#include -#include - -#ifdef HAVE_LOCALE_H -#include -#endif - -#ifdef WITH_IDN -#include -#include -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static isc_boolean_t short_form = ISC_TRUE, listed_server = ISC_FALSE; -static isc_boolean_t default_lookups = ISC_TRUE; -static int seen_error = -1; -static isc_boolean_t list_addresses = ISC_TRUE; -static dns_rdatatype_t list_type = dns_rdatatype_a; -static isc_boolean_t printed_server = ISC_FALSE; - -static const char *opcodetext[] = { - "QUERY", - "IQUERY", - "STATUS", - "RESERVED3", - "NOTIFY", - "UPDATE", - "RESERVED6", - "RESERVED7", - "RESERVED8", - "RESERVED9", - "RESERVED10", - "RESERVED11", - "RESERVED12", - "RESERVED13", - "RESERVED14", - "RESERVED15" -}; - -static const char *rcodetext[] = { - "NOERROR", - "FORMERR", - "SERVFAIL", - "NXDOMAIN", - "NOTIMP", - "REFUSED", - "YXDOMAIN", - "YXRRSET", - "NXRRSET", - "NOTAUTH", - "NOTZONE", - "RESERVED11", - "RESERVED12", - "RESERVED13", - "RESERVED14", - "RESERVED15", - "BADVERS" -}; - -struct rtype { - unsigned int type; - const char *text; -}; - -struct rtype rtypes[] = { - { 1, "has address" }, - { 2, "name server" }, - { 5, "is an alias for" }, - { 11, "has well known services" }, - { 12, "domain name pointer" }, - { 13, "host information" }, - { 15, "mail is handled by" }, - { 16, "descriptive text" }, - { 19, "x25 address" }, - { 20, "ISDN address" }, - { 24, "has signature" }, - { 25, "has key" }, - { 28, "has IPv6 address" }, - { 29, "location" }, - { 0, NULL } -}; - -static void -show_usage(void) { - fputs( -"Usage: host [-aCdlriTwv] [-c class] [-N ndots] [-t type] [-W time]\n" -" [-R number] [-m flag] hostname [server]\n" -" -a is equivalent to -v -t ANY\n" -" -c specifies query class for non-IN data\n" -" -C compares SOA records on authoritative nameservers\n" -" -d is equivalent to -v\n" -" -l lists all hosts in a domain, using AXFR\n" -" -i IP6.INT reverse lookups\n" -" -N changes the number of dots allowed before root lookup is done\n" -" -r disables recursive processing\n" -" -R specifies number of retries for UDP packets\n" -" -s a SERVFAIL response should stop query\n" -" -t specifies the query type\n" -" -T enables TCP/IP mode\n" -" -v enables verbose output\n" -" -w specifies to wait forever for a reply\n" -" -W specifies how long to wait for a reply\n" -" -4 use IPv4 query transport only\n" -" -6 use IPv6 query transport only\n" -" -m set memory debugging flag (trace|record|usage)\n", stderr); - exit(1); -} - -void -dighost_shutdown(void) { - isc_app_shutdown(); -} - -void -received(int bytes, isc_sockaddr_t *from, dig_query_t *query) { - isc_time_t now; - int diff; - - if (!short_form) { - char fromtext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(from, fromtext, sizeof(fromtext)); - TIME_NOW(&now); - diff = (int) isc_time_microdiff(&now, &query->time_sent); - printf("Received %u bytes from %s in %d ms\n", - bytes, fromtext, diff/1000); - } -} - -void -trying(char *frm, dig_lookup_t *lookup) { - UNUSED(lookup); - - if (!short_form) - printf("Trying \"%s\"\n", frm); -} - -static void -say_message(dns_name_t *name, const char *msg, dns_rdata_t *rdata, - dig_query_t *query) -{ - isc_buffer_t *b = NULL; - char namestr[DNS_NAME_FORMATSIZE]; - isc_region_t r; - isc_result_t result; - unsigned int bufsize = BUFSIZ; - - dns_name_format(name, namestr, sizeof(namestr)); - retry: - result = isc_buffer_allocate(mctx, &b, bufsize); - check_result(result, "isc_buffer_allocate"); - result = dns_rdata_totext(rdata, NULL, b); - if (result == ISC_R_NOSPACE) { - isc_buffer_free(&b); - bufsize *= 2; - goto retry; - } - check_result(result, "dns_rdata_totext"); - isc_buffer_usedregion(b, &r); - if (query->lookup->identify_previous_line) { - printf("Nameserver %s:\n\t", - query->servname); - } - printf("%s %s %.*s", namestr, - msg, (int)r.length, (char *)r.base); - if (query->lookup->identify) { - printf(" on server %s", query->servname); - } - printf("\n"); - isc_buffer_free(&b); -} -#ifdef DIG_SIGCHASE -/* Just for compatibility : not use in host program */ -isc_result_t -printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset, - isc_buffer_t *target) -{ - UNUSED(owner_name); - UNUSED(rdataset); - UNUSED(target); - return(ISC_FALSE); -} -#endif -static isc_result_t -printsection(dns_message_t *msg, dns_section_t sectionid, - const char *section_name, isc_boolean_t headers, - dig_query_t *query) -{ - dns_name_t *name, *print_name; - dns_rdataset_t *rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_buffer_t target; - isc_result_t result, loopresult; - isc_region_t r; - dns_name_t empty_name; - char t[4096]; - isc_boolean_t first; - isc_boolean_t no_rdata; - - if (sectionid == DNS_SECTION_QUESTION) - no_rdata = ISC_TRUE; - else - no_rdata = ISC_FALSE; - - if (headers) - printf(";; %s SECTION:\n", section_name); - - dns_name_init(&empty_name, NULL); - - result = dns_message_firstname(msg, sectionid); - if (result == ISC_R_NOMORE) - return (ISC_R_SUCCESS); - else if (result != ISC_R_SUCCESS) - return (result); - - for (;;) { - name = NULL; - dns_message_currentname(msg, sectionid, &name); - - isc_buffer_init(&target, t, sizeof(t)); - first = ISC_TRUE; - print_name = name; - - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - if (query->lookup->rdtype == dns_rdatatype_axfr && - !((!list_addresses && - (list_type == dns_rdatatype_any || - rdataset->type == list_type)) || - (list_addresses && - (rdataset->type == dns_rdatatype_a || - rdataset->type == dns_rdatatype_aaaa || - rdataset->type == dns_rdatatype_ns || - rdataset->type == dns_rdatatype_ptr)))) - continue; - if (!short_form) { - result = dns_rdataset_totext(rdataset, - print_name, - ISC_FALSE, - no_rdata, - &target); - if (result != ISC_R_SUCCESS) - return (result); -#ifdef USEINITALWS - if (first) { - print_name = &empty_name; - first = ISC_FALSE; - } -#else - UNUSED(first); /* Shut up compiler. */ -#endif - } else { - loopresult = dns_rdataset_first(rdataset); - while (loopresult == ISC_R_SUCCESS) { - struct rtype *t; - const char *rtt; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char typebuf2[DNS_RDATATYPE_FORMATSIZE - + 20]; - dns_rdataset_current(rdataset, &rdata); - - for (t = rtypes; t->text != NULL; t++) { - if (t->type == rdata.type) { - rtt = t->text; - goto found; - } - } - - dns_rdatatype_format(rdata.type, - typebuf, - sizeof(typebuf)); - snprintf(typebuf2, sizeof(typebuf2), - "has %s record", typebuf); - rtt = typebuf2; - found: - say_message(print_name, rtt, - &rdata, query); - dns_rdata_reset(&rdata); - loopresult = - dns_rdataset_next(rdataset); - } - } - } - if (!short_form) { - isc_buffer_usedregion(&target, &r); - if (no_rdata) - printf(";%.*s", (int)r.length, - (char *)r.base); - else - printf("%.*s", (int)r.length, (char *)r.base); - } - - result = dns_message_nextname(msg, sectionid); - if (result == ISC_R_NOMORE) - break; - else if (result != ISC_R_SUCCESS) - return (result); - } - - return (ISC_R_SUCCESS); -} - -static isc_result_t -printrdata(dns_message_t *msg, dns_rdataset_t *rdataset, dns_name_t *owner, - const char *set_name, isc_boolean_t headers) -{ - isc_buffer_t target; - isc_result_t result; - isc_region_t r; - char t[4096]; - - UNUSED(msg); - if (headers) - printf(";; %s SECTION:\n", set_name); - - isc_buffer_init(&target, t, sizeof(t)); - - result = dns_rdataset_totext(rdataset, owner, ISC_FALSE, ISC_FALSE, - &target); - if (result != ISC_R_SUCCESS) - return (result); - isc_buffer_usedregion(&target, &r); - printf("%.*s", (int)r.length, (char *)r.base); - - return (ISC_R_SUCCESS); -} - -static void -chase_cnamechain(dns_message_t *msg, dns_name_t *qname) { - isc_result_t result; - dns_rdataset_t *rdataset; - dns_rdata_cname_t cname; - dns_rdata_t rdata = DNS_RDATA_INIT; - unsigned int i = msg->counts[DNS_SECTION_ANSWER]; - - while (i-- > 0) { - rdataset = NULL; - result = dns_message_findname(msg, DNS_SECTION_ANSWER, qname, - dns_rdatatype_cname, 0, NULL, - &rdataset); - if (result != ISC_R_SUCCESS) - return; - result = dns_rdataset_first(rdataset); - check_result(result, "dns_rdataset_first"); - dns_rdata_reset(&rdata); - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &cname, NULL); - check_result(result, "dns_rdata_tostruct"); - dns_name_copy(&cname.cname, qname, NULL); - dns_rdata_freestruct(&cname); - } -} - -isc_result_t -printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) { - isc_boolean_t did_flag = ISC_FALSE; - dns_rdataset_t *opt, *tsig = NULL; - dns_name_t *tsigname; - isc_result_t result = ISC_R_SUCCESS; - int force_error; - - UNUSED(headers); - - /* - * We get called multiple times. - * Preserve any existing error status. - */ - force_error = (seen_error == 1) ? 1 : 0; - seen_error = 1; - if (listed_server && !printed_server) { - char sockstr[ISC_SOCKADDR_FORMATSIZE]; - - printf("Using domain server:\n"); - printf("Name: %s\n", query->userarg); - isc_sockaddr_format(&query->sockaddr, sockstr, - sizeof(sockstr)); - printf("Address: %s\n", sockstr); - printf("Aliases: \n\n"); - printed_server = ISC_TRUE; - } - - if (msg->rcode != 0) { - char namestr[DNS_NAME_FORMATSIZE]; - dns_name_format(query->lookup->name, namestr, sizeof(namestr)); - printf("Host %s not found: %d(%s)\n", - (msg->rcode != dns_rcode_nxdomain) ? namestr : - query->lookup->textname, msg->rcode, - rcodetext[msg->rcode]); - return (ISC_R_SUCCESS); - } - - if (default_lookups && query->lookup->rdtype == dns_rdatatype_a) { - char namestr[DNS_NAME_FORMATSIZE]; - dig_lookup_t *lookup; - dns_fixedname_t fixed; - dns_name_t *name; - - /* Add AAAA and MX lookups. */ - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - dns_name_copy(query->lookup->name, name, NULL); - chase_cnamechain(msg, name); - dns_name_format(name, namestr, sizeof(namestr)); - lookup = clone_lookup(query->lookup, ISC_FALSE); - if (lookup != NULL) { - strncpy(lookup->textname, namestr, - sizeof(lookup->textname)); - lookup->textname[sizeof(lookup->textname)-1] = 0; - lookup->rdtype = dns_rdatatype_aaaa; - lookup->rdtypeset = ISC_TRUE; - lookup->origin = NULL; - lookup->retries = tries; - ISC_LIST_APPEND(lookup_list, lookup, link); - } - lookup = clone_lookup(query->lookup, ISC_FALSE); - if (lookup != NULL) { - strncpy(lookup->textname, namestr, - sizeof(lookup->textname)); - lookup->textname[sizeof(lookup->textname)-1] = 0; - lookup->rdtype = dns_rdatatype_mx; - lookup->rdtypeset = ISC_TRUE; - lookup->origin = NULL; - lookup->retries = tries; - ISC_LIST_APPEND(lookup_list, lookup, link); - } - } - - if (!short_form) { - printf(";; ->>HEADER<<- opcode: %s, status: %s, id: %u\n", - opcodetext[msg->opcode], rcodetext[msg->rcode], - msg->id); - printf(";; flags: "); - if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) { - printf("qr"); - did_flag = ISC_TRUE; - } - if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) { - printf("%saa", did_flag ? " " : ""); - did_flag = ISC_TRUE; - } - if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { - printf("%stc", did_flag ? " " : ""); - did_flag = ISC_TRUE; - } - if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) { - printf("%srd", did_flag ? " " : ""); - did_flag = ISC_TRUE; - } - if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) { - printf("%sra", did_flag ? " " : ""); - did_flag = ISC_TRUE; - } - if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0) { - printf("%sad", did_flag ? " " : ""); - did_flag = ISC_TRUE; - } - if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0) { - printf("%scd", did_flag ? " " : ""); - did_flag = ISC_TRUE; - } - printf("; QUERY: %u, ANSWER: %u, " - "AUTHORITY: %u, ADDITIONAL: %u\n", - msg->counts[DNS_SECTION_QUESTION], - msg->counts[DNS_SECTION_ANSWER], - msg->counts[DNS_SECTION_AUTHORITY], - msg->counts[DNS_SECTION_ADDITIONAL]); - opt = dns_message_getopt(msg); - if (opt != NULL) - printf(";; EDNS: version: %u, udp=%u\n", - (unsigned int)((opt->ttl & 0x00ff0000) >> 16), - (unsigned int)opt->rdclass); - tsigname = NULL; - tsig = dns_message_gettsig(msg, &tsigname); - if (tsig != NULL) - printf(";; PSEUDOSECTIONS: TSIG\n"); - } - if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_QUESTION]) && - !short_form) { - printf("\n"); - result = printsection(msg, DNS_SECTION_QUESTION, "QUESTION", - ISC_TRUE, query); - if (result != ISC_R_SUCCESS) - return (result); - } - if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER])) { - if (!short_form) - printf("\n"); - result = printsection(msg, DNS_SECTION_ANSWER, "ANSWER", - ISC_TF(!short_form), query); - if (result != ISC_R_SUCCESS) - return (result); - } - - if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_AUTHORITY]) && - !short_form) { - printf("\n"); - result = printsection(msg, DNS_SECTION_AUTHORITY, "AUTHORITY", - ISC_TRUE, query); - if (result != ISC_R_SUCCESS) - return (result); - } - if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ADDITIONAL]) && - !short_form) { - printf("\n"); - result = printsection(msg, DNS_SECTION_ADDITIONAL, - "ADDITIONAL", ISC_TRUE, query); - if (result != ISC_R_SUCCESS) - return (result); - } - if ((tsig != NULL) && !short_form) { - printf("\n"); - result = printrdata(msg, tsig, tsigname, - "PSEUDOSECTION TSIG", ISC_TRUE); - if (result != ISC_R_SUCCESS) - return (result); - } - if (!short_form) - printf("\n"); - - if (short_form && !default_lookups && - ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER])) { - char namestr[DNS_NAME_FORMATSIZE]; - char typestr[DNS_RDATATYPE_FORMATSIZE]; - dns_name_format(query->lookup->name, namestr, sizeof(namestr)); - dns_rdatatype_format(query->lookup->rdtype, typestr, - sizeof(typestr)); - printf("%s has no %s record\n", namestr, typestr); - } - seen_error = force_error; - return (result); -} - -static const char * optstring = "46ac:dilnm:rst:vwCDN:R:TW:"; - -static void -pre_parse_args(int argc, char **argv) { - int c; - - while ((c = isc_commandline_parse(argc, argv, optstring)) != -1) { - switch (c) { - case 'm': - memdebugging = ISC_TRUE; - if (strcasecmp("trace", isc_commandline_argument) == 0) - isc_mem_debugging |= ISC_MEM_DEBUGTRACE; - else if (!strcasecmp("record", - isc_commandline_argument) == 0) - isc_mem_debugging |= ISC_MEM_DEBUGRECORD; - else if (strcasecmp("usage", - isc_commandline_argument) == 0) - isc_mem_debugging |= ISC_MEM_DEBUGUSAGE; - break; - - case '4': break; - case '6': break; - case 'a': break; - case 'c': break; - case 'd': break; - case 'i': break; - case 'l': break; - case 'n': break; - case 'r': break; - case 's': break; - case 't': break; - case 'v': break; - case 'w': break; - case 'C': break; - case 'D': break; - case 'N': break; - case 'R': break; - case 'T': break; - case 'W': break; - default: - show_usage(); - } - } - isc_commandline_reset = ISC_TRUE; - isc_commandline_index = 1; -} - -static void -parse_args(isc_boolean_t is_batchfile, int argc, char **argv) { - char hostname[MXNAME]; - dig_lookup_t *lookup; - int c; - char store[MXNAME]; - isc_textregion_t tr; - isc_result_t result = ISC_R_SUCCESS; - dns_rdatatype_t rdtype; - dns_rdataclass_t rdclass; - isc_uint32_t serial = 0; - - UNUSED(is_batchfile); - - lookup = make_empty_lookup(); - - lookup->servfail_stops = ISC_FALSE; - lookup->comments = ISC_FALSE; - - while ((c = isc_commandline_parse(argc, argv, optstring)) != -1) { - switch (c) { - case 'l': - lookup->tcp_mode = ISC_TRUE; - lookup->rdtype = dns_rdatatype_axfr; - lookup->rdtypeset = ISC_TRUE; - fatalexit = 3; - break; - case 'v': - case 'd': - short_form = ISC_FALSE; - break; - case 'r': - lookup->recurse = ISC_FALSE; - break; - case 't': - if (strncasecmp(isc_commandline_argument, - "ixfr=", 5) == 0) { - rdtype = dns_rdatatype_ixfr; - /* XXXMPA add error checking */ - serial = strtoul(isc_commandline_argument + 5, - NULL, 10); - result = ISC_R_SUCCESS; - } else { - tr.base = isc_commandline_argument; - tr.length = strlen(isc_commandline_argument); - result = dns_rdatatype_fromtext(&rdtype, - (isc_textregion_t *)&tr); - } - - if (result != ISC_R_SUCCESS) { - fatalexit = 2; - fatal("invalid type: %s\n", - isc_commandline_argument); - } - if (!lookup->rdtypeset || - lookup->rdtype != dns_rdatatype_axfr) - lookup->rdtype = rdtype; - lookup->rdtypeset = ISC_TRUE; -#ifdef WITH_IDN - idnoptions = 0; -#endif - if (rdtype == dns_rdatatype_axfr) { - /* -l -t any -v */ - list_type = dns_rdatatype_any; - short_form = ISC_FALSE; - lookup->tcp_mode = ISC_TRUE; - } else if (rdtype == dns_rdatatype_ixfr) { - lookup->ixfr_serial = serial; - list_type = rdtype; -#ifdef WITH_IDN - } else if (rdtype == dns_rdatatype_a || - rdtype == dns_rdatatype_aaaa || - rdtype == dns_rdatatype_mx) { - idnoptions = IDN_ASCCHECK; - list_type = rdtype; -#endif - } else - list_type = rdtype; - list_addresses = ISC_FALSE; - default_lookups = ISC_FALSE; - break; - case 'c': - tr.base = isc_commandline_argument; - tr.length = strlen(isc_commandline_argument); - result = dns_rdataclass_fromtext(&rdclass, - (isc_textregion_t *)&tr); - - if (result != ISC_R_SUCCESS) { - fatalexit = 2; - fatal("invalid class: %s\n", - isc_commandline_argument); - } else { - lookup->rdclass = rdclass; - lookup->rdclassset = ISC_TRUE; - } - default_lookups = ISC_FALSE; - break; - case 'a': - if (!lookup->rdtypeset || - lookup->rdtype != dns_rdatatype_axfr) - lookup->rdtype = dns_rdatatype_any; - list_type = dns_rdatatype_any; - list_addresses = ISC_FALSE; - lookup->rdtypeset = ISC_TRUE; - short_form = ISC_FALSE; - default_lookups = ISC_FALSE; - break; - case 'i': - lookup->ip6_int = ISC_TRUE; - break; - case 'n': - /* deprecated */ - break; - case 'm': - /* Handled by pre_parse_args(). */ - break; - case 'w': - /* - * The timer routines are coded such that - * timeout==MAXINT doesn't enable the timer - */ - timeout = INT_MAX; - break; - case 'W': - timeout = atoi(isc_commandline_argument); - if (timeout < 1) - timeout = 1; - break; - case 'R': - tries = atoi(isc_commandline_argument) + 1; - if (tries < 2) - tries = 2; - break; - case 'T': - lookup->tcp_mode = ISC_TRUE; - break; - case 'C': - debug("showing all SOAs"); - lookup->rdtype = dns_rdatatype_ns; - lookup->rdtypeset = ISC_TRUE; - lookup->rdclass = dns_rdataclass_in; - lookup->rdclassset = ISC_TRUE; - lookup->ns_search_only = ISC_TRUE; - lookup->trace_root = ISC_TRUE; - lookup->identify_previous_line = ISC_TRUE; - default_lookups = ISC_FALSE; - break; - case 'N': - debug("setting NDOTS to %s", - isc_commandline_argument); - ndots = atoi(isc_commandline_argument); - break; - case 'D': - debugging = ISC_TRUE; - break; - case '4': - if (have_ipv4) { - isc_net_disableipv6(); - have_ipv6 = ISC_FALSE; - } else - fatal("can't find IPv4 networking"); - break; - case '6': - if (have_ipv6) { - isc_net_disableipv4(); - have_ipv4 = ISC_FALSE; - } else - fatal("can't find IPv6 networking"); - break; - case 's': - lookup->servfail_stops = ISC_TRUE; - break; - } - } - - lookup->retries = tries; - - if (isc_commandline_index >= argc) - show_usage(); - - strncpy(hostname, argv[isc_commandline_index], sizeof(hostname)); - hostname[sizeof(hostname)-1]=0; - if (argc > isc_commandline_index + 1) { - set_nameserver(argv[isc_commandline_index+1]); - debug("server is %s", argv[isc_commandline_index+1]); - listed_server = ISC_TRUE; - } else - check_ra = ISC_TRUE; - - lookup->pending = ISC_FALSE; - if (get_reverse(store, sizeof(store), hostname, - lookup->ip6_int, ISC_TRUE) == ISC_R_SUCCESS) { - strncpy(lookup->textname, store, sizeof(lookup->textname)); - lookup->textname[sizeof(lookup->textname)-1] = 0; - lookup->rdtype = dns_rdatatype_ptr; - lookup->rdtypeset = ISC_TRUE; - default_lookups = ISC_FALSE; - } else { - strncpy(lookup->textname, hostname, sizeof(lookup->textname)); - lookup->textname[sizeof(lookup->textname)-1]=0; - } - lookup->new_search = ISC_TRUE; - ISC_LIST_APPEND(lookup_list, lookup, link); - - usesearch = ISC_TRUE; -} - -int -main(int argc, char **argv) { - isc_result_t result; - - tries = 2; - - ISC_LIST_INIT(lookup_list); - ISC_LIST_INIT(server_list); - ISC_LIST_INIT(search_list); - - fatalexit = 1; -#ifdef WITH_IDN - idnoptions = IDN_ASCCHECK; -#endif - - debug("main()"); - progname = argv[0]; - pre_parse_args(argc, argv); - result = isc_app_start(); - check_result(result, "isc_app_start"); - setup_libs(); - parse_args(ISC_FALSE, argc, argv); - setup_system(); - result = isc_app_onrun(mctx, global_task, onrun_callback, NULL); - check_result(result, "isc_app_onrun"); - isc_app_run(); - cancel_all(); - destroy_libs(); - isc_app_finish(); - return ((seen_error == 0) ? 0 : 1); -} diff --git a/contrib/bind9/bin/dig/host.docbook b/contrib/bind9/bin/dig/host.docbook deleted file mode 100644 index 8ab7679..0000000 --- a/contrib/bind9/bin/dig/host.docbook +++ /dev/null @@ -1,277 +0,0 @@ -]> - - - - - - - Jun 30, 2000 - - - - host - 1 - BIND9 - - - - host - DNS lookup utility - - - - - 2004 - 2005 - 2007 - Internet Systems Consortium, Inc. ("ISC") - - - 2000 - 2001 - 2002 - Internet Software Consortium. - - - - - - host - - - - - - - - - - name - server - - - - - DESCRIPTION - - host - is a simple utility for performing DNS lookups. - It is normally used to convert names to IP addresses and vice versa. - When no arguments or options are given, - host - prints a short summary of its command line arguments and options. - - - name is the domain name that is to be - looked - up. It can also be a dotted-decimal IPv4 address or a colon-delimited - IPv6 address, in which case host will by - default - perform a reverse lookup for that address. - server is an optional argument which - is either - the name or IP address of the name server that host - should query instead of the server or servers listed in - /etc/resolv.conf. - - - - The (all) option is equivalent to setting the - option and asking host to make - a query of type ANY. - - - - When the option is used, host - will attempt to display the SOA records for zone - name from all the listed - authoritative name - servers for that zone. The list of name servers is defined by the NS - records that are found for the zone. - - - - The option instructs to make a DNS query of class - class. This can be used to lookup - Hesiod or - Chaosnet class resource records. The default class is IN (Internet). - - - - Verbose output is generated by host when - the - or option is used. The two - options are equivalent. They have been provided for backwards - compatibility. In previous versions, the option - switched on debugging traces and enabled verbose - output. - - - - List mode is selected by the option. This makes - host perform a zone transfer for zone - name. Transfer the zone printing out - the NS, PTR - and address records (A/AAAA). If combined with - all records will be printed. - - - - The - option specifies that reverse lookups of IPv6 addresses should - use the IP6.INT domain as defined in RFC1886. - The default is to use IP6.ARPA. - - - - The option sets the number of dots that have to be - in name for it to be considered - absolute. The - default value is that defined using the ndots statement in - /etc/resolv.conf, or 1 if no ndots - statement is - present. Names with fewer dots are interpreted as relative names and - will be searched for in the domains listed in the search - or domain directive in - /etc/resolv.conf. - - - - The number of UDP retries for a lookup can be changed with the - option. number - indicates - how many times host will repeat a query - that does - not get answered. The default number of retries is 1. If - number is negative or zero, the - number of - retries will default to 1. - - - - Non-recursive queries can be made via the option. - Setting this option clears the RD — recursion - desired — bit in the query which host makes. - This should mean that the name server receiving the query will not - attempt to resolve name. The - option enables host - to mimic - the behavior of a name server by making non-recursive queries and - expecting to receive answers to those queries that are usually - referrals to other name servers. - - - - By default host uses UDP when making - queries. The - option makes it use a TCP connection when querying - the name server. TCP will be automatically selected for queries that - require it, such as zone transfer (AXFR) requests. - - - - The option forces host to only - use IPv4 query transport. The option forces - host to only use IPv6 query transport. - - - - The option is used to select the query type. - type can be any recognized query - type: CNAME, - NS, SOA, SIG, KEY, AXFR, etc. When no query type is specified, - host automatically selects an appropriate - query - type. By default it looks for A records, but if the - option was given, queries will be made for SOA - records, and if name is a - dotted-decimal IPv4 - address or colon-delimited IPv6 address, host will - query for PTR records. If a query type of IXFR is chosen the starting - serial number can be specified by appending an equal followed by the - starting serial number (e.g. -t IXFR=12345678). - - - - The time to wait for a reply can be controlled through the - and options. The - option makes host - wait for - wait seconds. If wait - is less than one, the wait interval is set to one second. When the - option is used, host - will - effectively wait forever for a reply. The time to wait for a response - will be set to the number of seconds given by the hardware's maximum - value for an integer quantity. - - - - The option tells host - not to send the query to the next nameserver - if any server responds with a SERVFAIL response, which is the - reverse of normal stub resolver behavior. - - - - The can be used to set the memory usage debugging - flags - record, usage and - trace. - - - - - IDN SUPPORT - - If host has been built with IDN (internationalized - domain name) support, it can accept and display non-ASCII domain names. - host appropriately converts character encoding of - domain name before sending a request to DNS server or displaying a - reply from the server. - If you'd like to turn off the IDN support for some reason, defines - the IDN_DISABLE environment variable. - The IDN support is disabled if the variable is set when - host runs. - - - - - FILES - /etc/resolv.conf - - - - - SEE ALSO - - dig1 - , - - named8 - . - - - - diff --git a/contrib/bind9/bin/dig/host.html b/contrib/bind9/bin/dig/host.html deleted file mode 100644 index adc9883..0000000 --- a/contrib/bind9/bin/dig/host.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - -host - - -
-
-
-

Name

-

host — DNS lookup utility

-
-
-

Synopsis

-

host [-aCdlnrsTwv] [-c class] [-N ndots] [-R number] [-t type] [-W wait] [-m flag] [-4] [-6] {name} [server]

-
-
-

DESCRIPTION

-

host - is a simple utility for performing DNS lookups. - It is normally used to convert names to IP addresses and vice versa. - When no arguments or options are given, - host - prints a short summary of its command line arguments and options. -

-

name is the domain name that is to be - looked - up. It can also be a dotted-decimal IPv4 address or a colon-delimited - IPv6 address, in which case host will by - default - perform a reverse lookup for that address. - server is an optional argument which - is either - the name or IP address of the name server that host - should query instead of the server or servers listed in - /etc/resolv.conf. -

-

- The -a (all) option is equivalent to setting the - -v option and asking host to make - a query of type ANY. -

-

- When the -C option is used, host - will attempt to display the SOA records for zone - name from all the listed - authoritative name - servers for that zone. The list of name servers is defined by the NS - records that are found for the zone. -

-

- The -c option instructs to make a DNS query of class - class. This can be used to lookup - Hesiod or - Chaosnet class resource records. The default class is IN (Internet). -

-

- Verbose output is generated by host when - the - -d or -v option is used. The two - options are equivalent. They have been provided for backwards - compatibility. In previous versions, the -d option - switched on debugging traces and -v enabled verbose - output. -

-

- List mode is selected by the -l option. This makes - host perform a zone transfer for zone - name. Transfer the zone printing out - the NS, PTR - and address records (A/AAAA). If combined with -a - all records will be printed. -

-

- The -i - option specifies that reverse lookups of IPv6 addresses should - use the IP6.INT domain as defined in RFC1886. - The default is to use IP6.ARPA. -

-

- The -N option sets the number of dots that have to be - in name for it to be considered - absolute. The - default value is that defined using the ndots statement in - /etc/resolv.conf, or 1 if no ndots - statement is - present. Names with fewer dots are interpreted as relative names and - will be searched for in the domains listed in the search - or domain directive in - /etc/resolv.conf. -

-

- The number of UDP retries for a lookup can be changed with the - -R option. number - indicates - how many times host will repeat a query - that does - not get answered. The default number of retries is 1. If - number is negative or zero, the - number of - retries will default to 1. -

-

- Non-recursive queries can be made via the -r option. - Setting this option clears the RD — recursion - desired — bit in the query which host makes. - This should mean that the name server receiving the query will not - attempt to resolve name. The - -r option enables host - to mimic - the behavior of a name server by making non-recursive queries and - expecting to receive answers to those queries that are usually - referrals to other name servers. -

-

- By default host uses UDP when making - queries. The - -T option makes it use a TCP connection when querying - the name server. TCP will be automatically selected for queries that - require it, such as zone transfer (AXFR) requests. -

-

- The -4 option forces host to only - use IPv4 query transport. The -6 option forces - host to only use IPv6 query transport. -

-

- The -t option is used to select the query type. - type can be any recognized query - type: CNAME, - NS, SOA, SIG, KEY, AXFR, etc. When no query type is specified, - host automatically selects an appropriate - query - type. By default it looks for A records, but if the - -C option was given, queries will be made for SOA - records, and if name is a - dotted-decimal IPv4 - address or colon-delimited IPv6 address, host will - query for PTR records. If a query type of IXFR is chosen the starting - serial number can be specified by appending an equal followed by the - starting serial number (e.g. -t IXFR=12345678). -

-

- The time to wait for a reply can be controlled through the - -W and -w options. The - -W option makes host - wait for - wait seconds. If wait - is less than one, the wait interval is set to one second. When the - -w option is used, host - will - effectively wait forever for a reply. The time to wait for a response - will be set to the number of seconds given by the hardware's maximum - value for an integer quantity. -

-

- The -s option tells host - not to send the query to the next nameserver - if any server responds with a SERVFAIL response, which is the - reverse of normal stub resolver behavior. -

-

- The -m can be used to set the memory usage debugging - flags - record, usage and - trace. -

-
-
-

IDN SUPPORT

-

- If host has been built with IDN (internationalized - domain name) support, it can accept and display non-ASCII domain names. - host appropriately converts character encoding of - domain name before sending a request to DNS server or displaying a - reply from the server. - If you'd like to turn off the IDN support for some reason, defines - the IDN_DISABLE environment variable. - The IDN support is disabled if the variable is set when - host runs. -

-
-
-

FILES

-

/etc/resolv.conf -

-
-
-

SEE ALSO

-

dig(1), - named(8). -

-
-
- diff --git a/contrib/bind9/bin/dig/include/dig/dig.h b/contrib/bind9/bin/dig/include/dig/dig.h deleted file mode 100644 index 02ae4d2..0000000 --- a/contrib/bind9/bin/dig/include/dig/dig.h +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-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: dig.h,v 1.82.18.23 2007/08/28 07:19:55 tbox Exp $ */ - -#ifndef DIG_H -#define DIG_H - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MXSERV 20 -#define MXNAME (DNS_NAME_MAXTEXT+1) -#define MXRD 32 -/*% Buffer Size */ -#define BUFSIZE 512 -#define COMMSIZE 0xffff -#ifndef RESOLV_CONF -/*% location of resolve.conf */ -#define RESOLV_CONF "/etc/resolv.conf" -#endif -/*% output buffer */ -#define OUTPUTBUF 32767 -/*% Max RR Limit */ -#define MAXRRLIMIT 0xffffffff -#define MAXTIMEOUT 0xffff -/*% Max number of tries */ -#define MAXTRIES 0xffffffff -/*% Max number of dots */ -#define MAXNDOTS 0xffff -/*% Max number of ports */ -#define MAXPORT 0xffff -/*% Max serial number */ -#define MAXSERIAL 0xffffffff - -/*% Default TCP Timeout */ -#define TCP_TIMEOUT 10 -/*% Default UDP Timeout */ -#define UDP_TIMEOUT 5 - -#define SERVER_TIMEOUT 1 - -#define LOOKUP_LIMIT 64 -/*% - * Lookup_limit is just a limiter, keeping too many lookups from being - * created. It's job is mainly to prevent the program from running away - * in a tight loop of constant lookups. It's value is arbitrary. - */ - -/* - * Defaults for the sigchase suboptions. Consolidated here because - * these control the layout of dig_lookup_t (among other things). - */ -#ifdef DIG_SIGCHASE -#ifndef DIG_SIGCHASE_BU -#define DIG_SIGCHASE_BU 1 -#endif -#ifndef DIG_SIGCHASE_TD -#define DIG_SIGCHASE_TD 1 -#endif -#endif - -ISC_LANG_BEGINDECLS - -typedef struct dig_lookup dig_lookup_t; -typedef struct dig_query dig_query_t; -typedef struct dig_server dig_server_t; -#ifdef DIG_SIGCHASE -typedef struct dig_message dig_message_t; -#endif -typedef ISC_LIST(dig_server_t) dig_serverlist_t; -typedef struct dig_searchlist dig_searchlist_t; - -/*% The dig_lookup structure */ -struct dig_lookup { - isc_boolean_t - pending, /*%< Pending a successful answer */ - waiting_connect, - doing_xfr, - ns_search_only, /*%< dig +nssearch, host -C */ - identify, /*%< Append an "on server " message */ - identify_previous_line, /*% Prepend a "Nameserver :" - message, with newline and tab */ - ignore, - recurse, - aaonly, - adflag, - cdflag, - trace, /*% dig +trace */ - trace_root, /*% initial query for either +trace or +nssearch */ - tcp_mode, - ip6_int, - comments, - stats, - section_question, - section_answer, - section_authority, - section_additional, - servfail_stops, - new_search, - need_search, - done_as_is, - besteffort, - dnssec; -#ifdef DIG_SIGCHASE -isc_boolean_t sigchase; -#if DIG_SIGCHASE_TD - isc_boolean_t do_topdown, - trace_root_sigchase, - rdtype_sigchaseset, - rdclass_sigchaseset; - /* Name we are going to validate RRset */ - char textnamesigchase[MXNAME]; -#endif -#endif - - char textname[MXNAME]; /*% Name we're going to be looking up */ - char cmdline[MXNAME]; - dns_rdatatype_t rdtype; - dns_rdatatype_t qrdtype; -#if DIG_SIGCHASE_TD - dns_rdatatype_t rdtype_sigchase; - dns_rdatatype_t qrdtype_sigchase; - dns_rdataclass_t rdclass_sigchase; -#endif - dns_rdataclass_t rdclass; - isc_boolean_t rdtypeset; - isc_boolean_t rdclassset; - char namespace[BUFSIZE]; - char onamespace[BUFSIZE]; - isc_buffer_t namebuf; - isc_buffer_t onamebuf; - isc_buffer_t renderbuf; - char *sendspace; - dns_name_t *name; - isc_timer_t *timer; - isc_interval_t interval; - dns_message_t *sendmsg; - dns_name_t *oname; - ISC_LINK(dig_lookup_t) link; - ISC_LIST(dig_query_t) q; - dig_query_t *current_query; - dig_serverlist_t my_server_list; - dig_searchlist_t *origin; - dig_query_t *xfr_q; - isc_uint32_t retries; - int nsfound; - isc_uint16_t udpsize; - isc_int16_t edns; - isc_uint32_t ixfr_serial; - isc_buffer_t rdatabuf; - char rdatastore[MXNAME]; - dst_context_t *tsigctx; - isc_buffer_t *querysig; - isc_uint32_t msgcounter; - dns_fixedname_t fdomain; -}; - -/*% The dig_query structure */ -struct dig_query { - dig_lookup_t *lookup; - isc_boolean_t waiting_connect, - pending_free, - waiting_senddone, - first_pass, - first_soa_rcvd, - second_rr_rcvd, - first_repeat_rcvd, - recv_made, - warn_id; - isc_uint32_t first_rr_serial; - isc_uint32_t second_rr_serial; - isc_uint32_t msg_count; - isc_uint32_t rr_count; - char *servname; - char *userarg; - isc_bufferlist_t sendlist, - recvlist, - lengthlist; - isc_buffer_t recvbuf, - lengthbuf, - slbuf; - char *recvspace, - lengthspace[4], - slspace[4]; - isc_socket_t *sock; - ISC_LINK(dig_query_t) link; - isc_sockaddr_t sockaddr; - isc_time_t time_sent; - isc_uint64_t byte_count; - isc_buffer_t sendbuf; -}; - -struct dig_server { - char servername[MXNAME]; - char userarg[MXNAME]; - ISC_LINK(dig_server_t) link; -}; - -struct dig_searchlist { - char origin[MXNAME]; - ISC_LINK(dig_searchlist_t) link; -}; -#ifdef DIG_SIGCHASE -struct dig_message { - dns_message_t *msg; - ISC_LINK(dig_message_t) link; -}; -#endif - -typedef ISC_LIST(dig_searchlist_t) dig_searchlistlist_t; -typedef ISC_LIST(dig_lookup_t) dig_lookuplist_t; - -/* - * Externals from dighost.c - */ - -extern dig_lookuplist_t lookup_list; -extern dig_serverlist_t server_list; -extern dig_searchlistlist_t search_list; -extern unsigned int extrabytes; - -extern isc_boolean_t check_ra, have_ipv4, have_ipv6, specified_source, - usesearch, showsearch, qr; -extern in_port_t port; -extern unsigned int timeout; -extern isc_mem_t *mctx; -extern dns_messageid_t id; -extern int sendcount; -extern int ndots; -extern int lookup_counter; -extern int exitcode; -extern isc_sockaddr_t bind_address; -extern char keynametext[MXNAME]; -extern char keyfile[MXNAME]; -extern char keysecret[MXNAME]; -extern dns_name_t *hmacname; -extern unsigned int digestbits; -#ifdef DIG_SIGCHASE -extern char trustedkey[MXNAME]; -#endif -extern dns_tsigkey_t *key; -extern isc_boolean_t validated; -extern isc_taskmgr_t *taskmgr; -extern isc_task_t *global_task; -extern isc_boolean_t free_now; -extern isc_boolean_t debugging, memdebugging; - -extern char *progname; -extern int tries; -extern int fatalexit; -#ifdef WITH_IDN -extern int idnoptions; -#endif - -/* - * Routines in dighost.c. - */ -void -get_address(char *host, in_port_t port, isc_sockaddr_t *sockaddr); - -isc_result_t -get_reverse(char *reverse, size_t len, char *value, isc_boolean_t ip6_int, - isc_boolean_t strict); - -void -fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); - -void -debug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); - -void -check_result(isc_result_t result, const char *msg); - -void -setup_lookup(dig_lookup_t *lookup); - -void -destroy_lookup(dig_lookup_t *lookup); - -void -do_lookup(dig_lookup_t *lookup); - -void -start_lookup(void); - -void -onrun_callback(isc_task_t *task, isc_event_t *event); - -int -dhmain(int argc, char **argv); - -void -setup_libs(void); - -void -setup_system(void); - -dig_lookup_t * -requeue_lookup(dig_lookup_t *lookold, isc_boolean_t servers); - -dig_lookup_t * -make_empty_lookup(void); - -dig_lookup_t * -clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers); - -dig_server_t * -make_server(const char *servname, const char *userarg); - -void -flush_server_list(void); - -void -set_nameserver(char *opt); - -void -clone_server_list(dig_serverlist_t src, - dig_serverlist_t *dest); - -void -cancel_all(void); - -void -destroy_libs(void); - -void -set_search_domain(char *domain); - -#ifdef DIG_SIGCHASE -void -clean_trustedkey(void); -#endif - -/* - * Routines to be defined in dig.c, host.c, and nslookup.c. - */ -#ifdef DIG_SIGCHASE -isc_result_t -printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset, - isc_buffer_t *target); -#endif - -isc_result_t -printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers); -/*%< - * Print the final result of the lookup. - */ - -void -received(int bytes, isc_sockaddr_t *from, dig_query_t *query); -/*%< - * Print a message about where and when the response - * was received from, like the final comment in the - * output of "dig". - */ - -void -trying(char *frm, dig_lookup_t *lookup); - -void -dighost_shutdown(void); - -char * -next_token(char **stringp, const char *delim); - -#ifdef DIG_SIGCHASE -/* Chasing functions */ -dns_rdataset_t * -chase_scanname(dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers); -void -chase_sig(dns_message_t *msg); -#endif - -ISC_LANG_ENDDECLS - -#endif diff --git a/contrib/bind9/bin/dig/nslookup.1 b/contrib/bind9/bin/dig/nslookup.1 deleted file mode 100644 index a453c2f..0000000 --- a/contrib/bind9/bin/dig/nslookup.1 +++ /dev/null @@ -1,252 +0,0 @@ -.\" Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") -.\" -.\" Permission to use, copy, modify, and 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: nslookup.1,v 1.1.10.14 2007/05/16 06:11:27 marka Exp $ -.\" -.hy 0 -.ad l -.\" Title: nslookup -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.71.1 -.\" Date: Jun 30, 2000 -.\" Manual: BIND9 -.\" Source: BIND9 -.\" -.TH "NSLOOKUP" "1" "Jun 30, 2000" "BIND9" "BIND9" -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.SH "NAME" -nslookup \- query Internet name servers interactively -.SH "SYNOPSIS" -.HP 9 -\fBnslookup\fR [\fB\-option\fR] [name\ |\ \-] [server] -.SH "DESCRIPTION" -.PP -\fBNslookup\fR -is a program to query Internet domain name servers. -\fBNslookup\fR -has two modes: interactive and non\-interactive. Interactive mode allows the user to query name servers for information about various hosts and domains or to print a list of hosts in a domain. Non\-interactive mode is used to print just the name and requested information for a host or domain. -.SH "ARGUMENTS" -.PP -Interactive mode is entered in the following cases: -.TP 4 -1. -when no arguments are given (the default name server will be used) -.TP 4 -2. -when the first argument is a hyphen (\-) and the second argument is the host name or Internet address of a name server. -.sp -.RE -.PP -Non\-interactive mode is used when the name or Internet address of the host to be looked up is given as the first argument. The optional second argument specifies the host name or address of a name server. -.PP -Options can also be specified on the command line if they precede the arguments and are prefixed with a hyphen. For example, to change the default query type to host information, and the initial timeout to 10 seconds, type: -.sp .RS 4 .nf nslookup \-query=hinfo \-timeout=10 .fi .RE -.SH "INTERACTIVE COMMANDS" -.PP -\fBhost\fR [server] -.RS 4 -Look up information for host using the current default server or using server, if specified. If host is an Internet address and the query type is A or PTR, the name of the host is returned. If host is a name and does not have a trailing period, the search list is used to qualify the name. -.sp -To look up a host not in the current domain, append a period to the name. -.RE -.PP -\fBserver\fR \fIdomain\fR -.RS 4 -.RE -.PP -\fBlserver\fR \fIdomain\fR -.RS 4 -Change the default server to -\fIdomain\fR; -\fBlserver\fR -uses the initial server to look up information about -\fIdomain\fR, while -\fBserver\fR -uses the current default server. If an authoritative answer can't be found, the names of servers that might have the answer are returned. -.RE -.PP -\fBroot\fR -.RS 4 -not implemented -.RE -.PP -\fBfinger\fR -.RS 4 -not implemented -.RE -.PP -\fBls\fR -.RS 4 -not implemented -.RE -.PP -\fBview\fR -.RS 4 -not implemented -.RE -.PP -\fBhelp\fR -.RS 4 -not implemented -.RE -.PP -\fB?\fR -.RS 4 -not implemented -.RE -.PP -\fBexit\fR -.RS 4 -Exits the program. -.RE -.PP -\fBset\fR \fIkeyword\fR\fI[=value]\fR -.RS 4 -This command is used to change state information that affects the lookups. Valid keywords are: -.RS 4 -.PP -\fBall\fR -.RS 4 -Prints the current values of the frequently used options to -\fBset\fR. Information about the current default server and host is also printed. -.RE -.PP -\fBclass=\fR\fIvalue\fR -.RS 4 -Change the query class to one of: -.RS 4 -.PP -\fBIN\fR -.RS 4 -the Internet class -.RE -.PP -\fBCH\fR -.RS 4 -the Chaos class -.RE -.PP -\fBHS\fR -.RS 4 -the Hesiod class -.RE -.PP -\fBANY\fR -.RS 4 -wildcard -.RE -.RE -.IP "" 4 -The class specifies the protocol group of the information. -.sp -(Default = IN; abbreviation = cl) -.RE -.PP -\fB \fR\fB\fI[no]\fR\fR\fBdebug\fR -.RS 4 -Turn on or off the display of the full response packet and any intermediate response packets when searching. -.sp -(Default = nodebug; abbreviation = -[no]deb) -.RE -.PP -\fB \fR\fB\fI[no]\fR\fR\fBd2\fR -.RS 4 -Turn debugging mode on or off. This displays more about what nslookup is doing. -.sp -(Default = nod2) -.RE -.PP -\fBdomain=\fR\fIname\fR -.RS 4 -Sets the search list to -\fIname\fR. -.RE -.PP -\fB \fR\fB\fI[no]\fR\fR\fBsearch\fR -.RS 4 -If the lookup request contains at least one period but doesn't end with a trailing period, append the domain names in the domain search list to the request until an answer is received. -.sp -(Default = search) -.RE -.PP -\fBport=\fR\fIvalue\fR -.RS 4 -Change the default TCP/UDP name server port to -\fIvalue\fR. -.sp -(Default = 53; abbreviation = po) -.RE -.PP -\fBquerytype=\fR\fIvalue\fR -.RS 4 -.RE -.PP -\fBtype=\fR\fIvalue\fR -.RS 4 -Change the type of the information query. -.sp -(Default = A; abbreviations = q, ty) -.RE -.PP -\fB \fR\fB\fI[no]\fR\fR\fBrecurse\fR -.RS 4 -Tell the name server to query other servers if it does not have the information. -.sp -(Default = recurse; abbreviation = [no]rec) -.RE -.PP -\fBretry=\fR\fInumber\fR -.RS 4 -Set the number of retries to number. -.RE -.PP -\fBtimeout=\fR\fInumber\fR -.RS 4 -Change the initial timeout interval for waiting for a reply to number seconds. -.RE -.PP -\fB \fR\fB\fI[no]\fR\fR\fBvc\fR -.RS 4 -Always use a virtual circuit when sending requests to the server. -.sp -(Default = novc) -.RE -.PP -\fB \fR\fB\fI[no]\fR\fR\fBfail\fR -.RS 4 -Try the next nameserver if a nameserver responds with SERVFAIL or a referral (nofail) or terminate query (fail) on such a response. -.sp -(Default = nofail) -.RE -.RE -.IP "" 4 -.RE -.SH "FILES" -.PP -\fI/etc/resolv.conf\fR -.SH "SEE ALSO" -.PP -\fBdig\fR(1), -\fBhost\fR(1), -\fBnamed\fR(8). -.SH "AUTHOR" -.PP -Andrew Cherenson -.SH "COPYRIGHT" -Copyright \(co 2004\-2007 Internet Systems Consortium, Inc. ("ISC") -.br diff --git a/contrib/bind9/bin/dig/nslookup.c b/contrib/bind9/bin/dig/nslookup.c deleted file mode 100644 index 3327c6e..0000000 --- a/contrib/bind9/bin/dig/nslookup.c +++ /dev/null @@ -1,891 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-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: nslookup.c,v 1.101.18.15 2007/08/28 07:19:55 tbox Exp $ */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static isc_boolean_t short_form = ISC_TRUE, - tcpmode = ISC_FALSE, - identify = ISC_FALSE, stats = ISC_TRUE, - comments = ISC_TRUE, section_question = ISC_TRUE, - section_answer = ISC_TRUE, section_authority = ISC_TRUE, - section_additional = ISC_TRUE, recurse = ISC_TRUE, - aaonly = ISC_FALSE, nofail = ISC_TRUE; - -static isc_boolean_t in_use = ISC_FALSE; -static char defclass[MXRD] = "IN"; -static char deftype[MXRD] = "A"; -static isc_event_t *global_event = NULL; - -static char domainopt[DNS_NAME_MAXTEXT]; - -static const char *rcodetext[] = { - "NOERROR", - "FORMERR", - "SERVFAIL", - "NXDOMAIN", - "NOTIMP", - "REFUSED", - "YXDOMAIN", - "YXRRSET", - "NXRRSET", - "NOTAUTH", - "NOTZONE", - "RESERVED11", - "RESERVED12", - "RESERVED13", - "RESERVED14", - "RESERVED15", - "BADVERS" -}; - -static const char *rtypetext[] = { - "rtype_0 = ", /* 0 */ - "internet address = ", /* 1 */ - "nameserver = ", /* 2 */ - "md = ", /* 3 */ - "mf = ", /* 4 */ - "canonical name = ", /* 5 */ - "soa = ", /* 6 */ - "mb = ", /* 7 */ - "mg = ", /* 8 */ - "mr = ", /* 9 */ - "rtype_10 = ", /* 10 */ - "protocol = ", /* 11 */ - "name = ", /* 12 */ - "hinfo = ", /* 13 */ - "minfo = ", /* 14 */ - "mail exchanger = ", /* 15 */ - "text = ", /* 16 */ - "rp = ", /* 17 */ - "afsdb = ", /* 18 */ - "x25 address = ", /* 19 */ - "isdn address = ", /* 20 */ - "rt = ", /* 21 */ - "nsap = ", /* 22 */ - "nsap_ptr = ", /* 23 */ - "signature = ", /* 24 */ - "key = ", /* 25 */ - "px = ", /* 26 */ - "gpos = ", /* 27 */ - "has AAAA address ", /* 28 */ - "loc = ", /* 29 */ - "next = ", /* 30 */ - "rtype_31 = ", /* 31 */ - "rtype_32 = ", /* 32 */ - "service = ", /* 33 */ - "rtype_34 = ", /* 34 */ - "naptr = ", /* 35 */ - "kx = ", /* 36 */ - "cert = ", /* 37 */ - "v6 address = ", /* 38 */ - "dname = ", /* 39 */ - "rtype_40 = ", /* 40 */ - "optional = " /* 41 */ -}; - -#define N_KNOWN_RRTYPES (sizeof(rtypetext) / sizeof(rtypetext[0])) - -static void flush_lookup_list(void); -static void getinput(isc_task_t *task, isc_event_t *event); - -void -dighost_shutdown(void) { - isc_event_t *event = global_event; - - flush_lookup_list(); - debug("dighost_shutdown()"); - - if (!in_use) { - isc_app_shutdown(); - return; - } - - isc_task_send(global_task, &event); -} - -static void -printsoa(dns_rdata_t *rdata) { - dns_rdata_soa_t soa; - isc_result_t result; - char namebuf[DNS_NAME_FORMATSIZE]; - - result = dns_rdata_tostruct(rdata, &soa, NULL); - check_result(result, "dns_rdata_tostruct"); - - dns_name_format(&soa.origin, namebuf, sizeof(namebuf)); - printf("\torigin = %s\n", namebuf); - dns_name_format(&soa.contact, namebuf, sizeof(namebuf)); - printf("\tmail addr = %s\n", namebuf); - printf("\tserial = %u\n", soa.serial); - printf("\trefresh = %u\n", soa.refresh); - printf("\tretry = %u\n", soa.retry); - printf("\texpire = %u\n", soa.expire); - printf("\tminimum = %u\n", soa.minimum); - dns_rdata_freestruct(&soa); -} - -static void -printa(dns_rdata_t *rdata) { - isc_result_t result; - char text[sizeof("255.255.255.255")]; - isc_buffer_t b; - - isc_buffer_init(&b, text, sizeof(text)); - result = dns_rdata_totext(rdata, NULL, &b); - check_result(result, "dns_rdata_totext"); - printf("Address: %.*s\n", (int)isc_buffer_usedlength(&b), - (char *)isc_buffer_base(&b)); -} -#ifdef DIG_SIGCHASE -/* Just for compatibility : not use in host program */ -isc_result_t -printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset, - isc_buffer_t *target) -{ - UNUSED(owner_name); - UNUSED(rdataset); - UNUSED(target); - return(ISC_FALSE); -} -#endif -static void -printrdata(dns_rdata_t *rdata) { - isc_result_t result; - isc_buffer_t *b = NULL; - unsigned int size = 1024; - isc_boolean_t done = ISC_FALSE; - - if (rdata->type < N_KNOWN_RRTYPES) - printf("%s", rtypetext[rdata->type]); - else - printf("rdata_%d = ", rdata->type); - - while (!done) { - result = isc_buffer_allocate(mctx, &b, size); - if (result != ISC_R_SUCCESS) - check_result(result, "isc_buffer_allocate"); - result = dns_rdata_totext(rdata, NULL, b); - if (result == ISC_R_SUCCESS) { - printf("%.*s\n", (int)isc_buffer_usedlength(b), - (char *)isc_buffer_base(b)); - done = ISC_TRUE; - } else if (result != ISC_R_NOSPACE) - check_result(result, "dns_rdata_totext"); - isc_buffer_free(&b); - size *= 2; - } -} - -static isc_result_t -printsection(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers, - dns_section_t section) { - isc_result_t result, loopresult; - dns_name_t *name; - dns_rdataset_t *rdataset = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - char namebuf[DNS_NAME_FORMATSIZE]; - - UNUSED(query); - UNUSED(headers); - - debug("printsection()"); - - result = dns_message_firstname(msg, section); - if (result == ISC_R_NOMORE) - return (ISC_R_SUCCESS); - else if (result != ISC_R_SUCCESS) - return (result); - for (;;) { - name = NULL; - dns_message_currentname(msg, section, - &name); - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - loopresult = dns_rdataset_first(rdataset); - while (loopresult == ISC_R_SUCCESS) { - dns_rdataset_current(rdataset, &rdata); - switch (rdata.type) { - case dns_rdatatype_a: - if (section != DNS_SECTION_ANSWER) - goto def_short_section; - dns_name_format(name, namebuf, - sizeof(namebuf)); - printf("Name:\t%s\n", namebuf); - printa(&rdata); - break; - case dns_rdatatype_soa: - dns_name_format(name, namebuf, - sizeof(namebuf)); - printf("%s\n", namebuf); - printsoa(&rdata); - break; - default: - def_short_section: - dns_name_format(name, namebuf, - sizeof(namebuf)); - printf("%s\t", namebuf); - printrdata(&rdata); - break; - } - dns_rdata_reset(&rdata); - loopresult = dns_rdataset_next(rdataset); - } - } - result = dns_message_nextname(msg, section); - if (result == ISC_R_NOMORE) - break; - else if (result != ISC_R_SUCCESS) { - return (result); - } - } - return (ISC_R_SUCCESS); -} - -static isc_result_t -detailsection(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers, - dns_section_t section) { - isc_result_t result, loopresult; - dns_name_t *name; - dns_rdataset_t *rdataset = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - char namebuf[DNS_NAME_FORMATSIZE]; - - UNUSED(query); - - debug("detailsection()"); - - if (headers) { - switch (section) { - case DNS_SECTION_QUESTION: - puts(" QUESTIONS:"); - break; - case DNS_SECTION_ANSWER: - puts(" ANSWERS:"); - break; - case DNS_SECTION_AUTHORITY: - puts(" AUTHORITY RECORDS:"); - break; - case DNS_SECTION_ADDITIONAL: - puts(" ADDITIONAL RECORDS:"); - break; - } - } - - result = dns_message_firstname(msg, section); - if (result == ISC_R_NOMORE) - return (ISC_R_SUCCESS); - else if (result != ISC_R_SUCCESS) - return (result); - for (;;) { - name = NULL; - dns_message_currentname(msg, section, - &name); - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - if (section == DNS_SECTION_QUESTION) { - dns_name_format(name, namebuf, - sizeof(namebuf)); - printf("\t%s, ", namebuf); - dns_rdatatype_format(rdataset->type, - namebuf, - sizeof(namebuf)); - printf("type = %s, ", namebuf); - dns_rdataclass_format(rdataset->rdclass, - namebuf, - sizeof(namebuf)); - printf("class = %s\n", namebuf); - } - loopresult = dns_rdataset_first(rdataset); - while (loopresult == ISC_R_SUCCESS) { - dns_rdataset_current(rdataset, &rdata); - - dns_name_format(name, namebuf, - sizeof(namebuf)); - printf(" -> %s\n", namebuf); - - switch (rdata.type) { - case dns_rdatatype_soa: - printsoa(&rdata); - break; - default: - printf("\t"); - printrdata(&rdata); - } - dns_rdata_reset(&rdata); - loopresult = dns_rdataset_next(rdataset); - } - } - result = dns_message_nextname(msg, section); - if (result == ISC_R_NOMORE) - break; - else if (result != ISC_R_SUCCESS) { - return (result); - } - } - return (ISC_R_SUCCESS); -} - -void -received(int bytes, isc_sockaddr_t *from, dig_query_t *query) -{ - UNUSED(bytes); - UNUSED(from); - UNUSED(query); -} - -void -trying(char *frm, dig_lookup_t *lookup) { - UNUSED(frm); - UNUSED(lookup); - -} - -isc_result_t -printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) { - char servtext[ISC_SOCKADDR_FORMATSIZE]; - - debug("printmessage()"); - - isc_sockaddr_format(&query->sockaddr, servtext, sizeof(servtext)); - printf("Server:\t\t%s\n", query->userarg); - printf("Address:\t%s\n", servtext); - - puts(""); - - if (!short_form) { - isc_boolean_t headers = ISC_TRUE; - puts("------------"); - /* detailheader(query, msg);*/ - detailsection(query, msg, headers, DNS_SECTION_QUESTION); - detailsection(query, msg, headers, DNS_SECTION_ANSWER); - detailsection(query, msg, headers, DNS_SECTION_AUTHORITY); - detailsection(query, msg, headers, DNS_SECTION_ADDITIONAL); - puts("------------"); - } - - if (msg->rcode != 0) { - char nametext[DNS_NAME_FORMATSIZE]; - dns_name_format(query->lookup->name, - nametext, sizeof(nametext)); - printf("** server can't find %s: %s\n", - (msg->rcode != dns_rcode_nxdomain) ? nametext : - query->lookup->textname, rcodetext[msg->rcode]); - debug("returning with rcode == 0"); - return (ISC_R_SUCCESS); - } - - if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) - puts("Non-authoritative answer:"); - if (!ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER])) - printsection(query, msg, headers, DNS_SECTION_ANSWER); - else - printf("*** Can't find %s: No answer\n", - query->lookup->textname); - - if (((msg->flags & DNS_MESSAGEFLAG_AA) == 0) && - (query->lookup->rdtype != dns_rdatatype_a)) { - puts("\nAuthoritative answers can be found from:"); - printsection(query, msg, headers, - DNS_SECTION_AUTHORITY); - printsection(query, msg, headers, - DNS_SECTION_ADDITIONAL); - } - return (ISC_R_SUCCESS); -} - -static void -show_settings(isc_boolean_t full, isc_boolean_t serv_only) { - dig_server_t *srv; - isc_sockaddr_t sockaddr; - dig_searchlist_t *listent; - - srv = ISC_LIST_HEAD(server_list); - - while (srv != NULL) { - char sockstr[ISC_SOCKADDR_FORMATSIZE]; - - get_address(srv->servername, port, &sockaddr); - isc_sockaddr_format(&sockaddr, sockstr, sizeof(sockstr)); - printf("Default server: %s\nAddress: %s\n", - srv->userarg, sockstr); - if (!full) - return; - srv = ISC_LIST_NEXT(srv, link); - } - if (serv_only) - return; - printf("\nSet options:\n"); - printf(" %s\t\t\t%s\t\t%s\n", - tcpmode ? "vc" : "novc", - short_form ? "nodebug" : "debug", - debugging ? "d2" : "nod2"); - printf(" %s\t\t%s\n", - usesearch ? "search" : "nosearch", - recurse ? "recurse" : "norecurse"); - printf(" timeout = %d\t\tretry = %d\tport = %d\n", - timeout, tries, port); - printf(" querytype = %-8s\tclass = %s\n", deftype, defclass); - printf(" srchlist = "); - for (listent = ISC_LIST_HEAD(search_list); - listent != NULL; - listent = ISC_LIST_NEXT(listent, link)) { - printf("%s", listent->origin); - if (ISC_LIST_NEXT(listent, link) != NULL) - printf("/"); - } - printf("\n"); -} - -static isc_boolean_t -testtype(char *typetext) { - isc_result_t result; - isc_textregion_t tr; - dns_rdatatype_t rdtype; - - tr.base = typetext; - tr.length = strlen(typetext); - result = dns_rdatatype_fromtext(&rdtype, &tr); - if (result == ISC_R_SUCCESS) - return (ISC_TRUE); - else { - printf("unknown query type: %s\n", typetext); - return (ISC_FALSE); - } -} - -static isc_boolean_t -testclass(char *typetext) { - isc_result_t result; - isc_textregion_t tr; - dns_rdataclass_t rdclass; - - tr.base = typetext; - tr.length = strlen(typetext); - result = dns_rdataclass_fromtext(&rdclass, &tr); - if (result == ISC_R_SUCCESS) - return (ISC_TRUE); - else { - printf("unknown query class: %s\n", typetext); - return (ISC_FALSE); - } -} - -static void -safecpy(char *dest, char *src, int size) { - strncpy(dest, src, size); - dest[size-1] = 0; -} - -static isc_result_t -parse_uint(isc_uint32_t *uip, const char *value, isc_uint32_t max, - const char *desc) { - isc_uint32_t n; - isc_result_t result = isc_parse_uint32(&n, value, 10); - if (result == ISC_R_SUCCESS && n > max) - result = ISC_R_RANGE; - if (result != ISC_R_SUCCESS) { - printf("invalid %s '%s': %s\n", desc, - value, isc_result_totext(result)); - return result; - } - *uip = n; - return (ISC_R_SUCCESS); -} - -static void -set_port(const char *value) { - isc_uint32_t n; - isc_result_t result = parse_uint(&n, value, 65535, "port"); - if (result == ISC_R_SUCCESS) - port = (isc_uint16_t) n; -} - -static void -set_timeout(const char *value) { - isc_uint32_t n; - isc_result_t result = parse_uint(&n, value, UINT_MAX, "timeout"); - if (result == ISC_R_SUCCESS) - timeout = n; -} - -static void -set_tries(const char *value) { - isc_uint32_t n; - isc_result_t result = parse_uint(&n, value, INT_MAX, "tries"); - if (result == ISC_R_SUCCESS) - tries = n; -} - -static void -setoption(char *opt) { - if (strncasecmp(opt, "all", 4) == 0) { - show_settings(ISC_TRUE, ISC_FALSE); - } else if (strncasecmp(opt, "class=", 6) == 0) { - if (testclass(&opt[6])) - safecpy(defclass, &opt[6], sizeof(defclass)); - } else if (strncasecmp(opt, "cl=", 3) == 0) { - if (testclass(&opt[3])) - safecpy(defclass, &opt[3], sizeof(defclass)); - } else if (strncasecmp(opt, "type=", 5) == 0) { - if (testtype(&opt[5])) - safecpy(deftype, &opt[5], sizeof(deftype)); - } else if (strncasecmp(opt, "ty=", 3) == 0) { - if (testtype(&opt[3])) - safecpy(deftype, &opt[3], sizeof(deftype)); - } else if (strncasecmp(opt, "querytype=", 10) == 0) { - if (testtype(&opt[10])) - safecpy(deftype, &opt[10], sizeof(deftype)); - } else if (strncasecmp(opt, "query=", 6) == 0) { - if (testtype(&opt[6])) - safecpy(deftype, &opt[6], sizeof(deftype)); - } else if (strncasecmp(opt, "qu=", 3) == 0) { - if (testtype(&opt[3])) - safecpy(deftype, &opt[3], sizeof(deftype)); - } else if (strncasecmp(opt, "q=", 2) == 0) { - if (testtype(&opt[2])) - safecpy(deftype, &opt[2], sizeof(deftype)); - } else if (strncasecmp(opt, "domain=", 7) == 0) { - safecpy(domainopt, &opt[7], sizeof(domainopt)); - set_search_domain(domainopt); - usesearch = ISC_TRUE; - } else if (strncasecmp(opt, "do=", 3) == 0) { - safecpy(domainopt, &opt[3], sizeof(domainopt)); - set_search_domain(domainopt); - usesearch = ISC_TRUE; - } else if (strncasecmp(opt, "port=", 5) == 0) { - set_port(&opt[5]); - } else if (strncasecmp(opt, "po=", 3) == 0) { - set_port(&opt[3]); - } else if (strncasecmp(opt, "timeout=", 8) == 0) { - set_timeout(&opt[8]); - } else if (strncasecmp(opt, "t=", 2) == 0) { - set_timeout(&opt[2]); - } else if (strncasecmp(opt, "rec", 3) == 0) { - recurse = ISC_TRUE; - } else if (strncasecmp(opt, "norec", 5) == 0) { - recurse = ISC_FALSE; - } else if (strncasecmp(opt, "retry=", 6) == 0) { - set_tries(&opt[6]); - } else if (strncasecmp(opt, "ret=", 4) == 0) { - set_tries(&opt[4]); - } else if (strncasecmp(opt, "def", 3) == 0) { - usesearch = ISC_TRUE; - } else if (strncasecmp(opt, "nodef", 5) == 0) { - usesearch = ISC_FALSE; - } else if (strncasecmp(opt, "vc", 3) == 0) { - tcpmode = ISC_TRUE; - } else if (strncasecmp(opt, "novc", 5) == 0) { - tcpmode = ISC_FALSE; - } else if (strncasecmp(opt, "deb", 3) == 0) { - short_form = ISC_FALSE; - showsearch = ISC_TRUE; - } else if (strncasecmp(opt, "nodeb", 5) == 0) { - short_form = ISC_TRUE; - showsearch = ISC_FALSE; - } else if (strncasecmp(opt, "d2", 2) == 0) { - debugging = ISC_TRUE; - } else if (strncasecmp(opt, "nod2", 4) == 0) { - debugging = ISC_FALSE; - } else if (strncasecmp(opt, "search", 3) == 0) { - usesearch = ISC_TRUE; - } else if (strncasecmp(opt, "nosearch", 5) == 0) { - usesearch = ISC_FALSE; - } else if (strncasecmp(opt, "sil", 3) == 0) { - /* deprecation_msg = ISC_FALSE; */ - } else if (strncasecmp(opt, "fail", 3) == 0) { - nofail=ISC_FALSE; - } else if (strncasecmp(opt, "nofail", 3) == 0) { - nofail=ISC_TRUE; - } else { - printf("*** Invalid option: %s\n", opt); - } -} - -static void -addlookup(char *opt) { - dig_lookup_t *lookup; - isc_result_t result; - isc_textregion_t tr; - dns_rdatatype_t rdtype; - dns_rdataclass_t rdclass; - char store[MXNAME]; - - debug("addlookup()"); - tr.base = deftype; - tr.length = strlen(deftype); - result = dns_rdatatype_fromtext(&rdtype, &tr); - if (result != ISC_R_SUCCESS) { - printf("unknown query type: %s\n", deftype); - rdclass = dns_rdatatype_a; - } - tr.base = defclass; - tr.length = strlen(defclass); - result = dns_rdataclass_fromtext(&rdclass, &tr); - if (result != ISC_R_SUCCESS) { - printf("unknown query class: %s\n", defclass); - rdclass = dns_rdataclass_in; - } - lookup = make_empty_lookup(); - if (get_reverse(store, sizeof(store), opt, lookup->ip6_int, ISC_TRUE) - == ISC_R_SUCCESS) { - safecpy(lookup->textname, store, sizeof(lookup->textname)); - lookup->rdtype = dns_rdatatype_ptr; - lookup->rdtypeset = ISC_TRUE; - } else { - safecpy(lookup->textname, opt, sizeof(lookup->textname)); - lookup->rdtype = rdtype; - lookup->rdtypeset = ISC_TRUE; - } - lookup->rdclass = rdclass; - lookup->rdclassset = ISC_TRUE; - lookup->trace = ISC_FALSE; - lookup->trace_root = lookup->trace; - lookup->ns_search_only = ISC_FALSE; - lookup->identify = identify; - lookup->recurse = recurse; - lookup->aaonly = aaonly; - lookup->retries = tries; - lookup->udpsize = 0; - lookup->comments = comments; - lookup->tcp_mode = tcpmode; - lookup->stats = stats; - lookup->section_question = section_question; - lookup->section_answer = section_answer; - lookup->section_authority = section_authority; - lookup->section_additional = section_additional; - lookup->new_search = ISC_TRUE; - if (nofail) - lookup->servfail_stops = ISC_FALSE; - ISC_LIST_INIT(lookup->q); - ISC_LINK_INIT(lookup, link); - ISC_LIST_APPEND(lookup_list, lookup, link); - lookup->origin = NULL; - ISC_LIST_INIT(lookup->my_server_list); - debug("looking up %s", lookup->textname); -} - -static void -get_next_command(void) { - char *buf; - char *ptr, *arg; - char *input; - - fflush(stdout); - buf = isc_mem_allocate(mctx, COMMSIZE); - if (buf == NULL) - fatal("memory allocation failure"); - fputs("> ", stderr); - fflush(stderr); - isc_app_block(); - ptr = fgets(buf, COMMSIZE, stdin); - isc_app_unblock(); - if (ptr == NULL) { - in_use = ISC_FALSE; - goto cleanup; - } - input = buf; - ptr = next_token(&input, " \t\r\n"); - if (ptr == NULL) - goto cleanup; - arg = next_token(&input, " \t\r\n"); - if ((strcasecmp(ptr, "set") == 0) && - (arg != NULL)) - setoption(arg); - else if ((strcasecmp(ptr, "server") == 0) || - (strcasecmp(ptr, "lserver") == 0)) { - isc_app_block(); - set_nameserver(arg); - check_ra = ISC_FALSE; - isc_app_unblock(); - show_settings(ISC_TRUE, ISC_TRUE); - } else if (strcasecmp(ptr, "exit") == 0) { - in_use = ISC_FALSE; - goto cleanup; - } else if (strcasecmp(ptr, "help") == 0 || - strcasecmp(ptr, "?") == 0) { - printf("The '%s' command is not yet implemented.\n", ptr); - goto cleanup; - } else if (strcasecmp(ptr, "finger") == 0 || - strcasecmp(ptr, "root") == 0 || - strcasecmp(ptr, "ls") == 0 || - strcasecmp(ptr, "view") == 0) { - printf("The '%s' command is not implemented.\n", ptr); - goto cleanup; - } else - addlookup(ptr); - cleanup: - isc_mem_free(mctx, buf); -} - -static void -parse_args(int argc, char **argv) { - isc_boolean_t have_lookup = ISC_FALSE; - - usesearch = ISC_TRUE; - for (argc--, argv++; argc > 0; argc--, argv++) { - debug("main parsing %s", argv[0]); - if (argv[0][0] == '-') { - if (argv[0][1] != 0) - setoption(&argv[0][1]); - else - have_lookup = ISC_TRUE; - } else { - if (!have_lookup) { - have_lookup = ISC_TRUE; - in_use = ISC_TRUE; - addlookup(argv[0]); - } else { - set_nameserver(argv[0]); - check_ra = ISC_FALSE; - } - } - } -} - -static void -flush_lookup_list(void) { - dig_lookup_t *l, *lp; - dig_query_t *q, *qp; - dig_server_t *s, *sp; - - lookup_counter = 0; - l = ISC_LIST_HEAD(lookup_list); - while (l != NULL) { - q = ISC_LIST_HEAD(l->q); - while (q != NULL) { - if (q->sock != NULL) { - isc_socket_cancel(q->sock, NULL, - ISC_SOCKCANCEL_ALL); - isc_socket_detach(&q->sock); - } - if (ISC_LINK_LINKED(&q->recvbuf, link)) - ISC_LIST_DEQUEUE(q->recvlist, &q->recvbuf, - link); - if (ISC_LINK_LINKED(&q->lengthbuf, link)) - ISC_LIST_DEQUEUE(q->lengthlist, &q->lengthbuf, - link); - isc_buffer_invalidate(&q->recvbuf); - isc_buffer_invalidate(&q->lengthbuf); - qp = q; - q = ISC_LIST_NEXT(q, link); - ISC_LIST_DEQUEUE(l->q, qp, link); - isc_mem_free(mctx, qp); - } - s = ISC_LIST_HEAD(l->my_server_list); - while (s != NULL) { - sp = s; - s = ISC_LIST_NEXT(s, link); - ISC_LIST_DEQUEUE(l->my_server_list, sp, link); - isc_mem_free(mctx, sp); - - } - if (l->sendmsg != NULL) - dns_message_destroy(&l->sendmsg); - if (l->timer != NULL) - isc_timer_detach(&l->timer); - lp = l; - l = ISC_LIST_NEXT(l, link); - ISC_LIST_DEQUEUE(lookup_list, lp, link); - isc_mem_free(mctx, lp); - } -} - -static void -getinput(isc_task_t *task, isc_event_t *event) { - UNUSED(task); - if (global_event == NULL) - global_event = event; - while (in_use) { - get_next_command(); - if (ISC_LIST_HEAD(lookup_list) != NULL) { - start_lookup(); - return; - } - } - isc_app_shutdown(); -} - -int -main(int argc, char **argv) { - isc_result_t result; - - ISC_LIST_INIT(lookup_list); - ISC_LIST_INIT(server_list); - ISC_LIST_INIT(search_list); - - check_ra = ISC_TRUE; - - result = isc_app_start(); - check_result(result, "isc_app_start"); - - setup_libs(); - progname = argv[0]; - - parse_args(argc, argv); - - setup_system(); - if (domainopt[0] != '\0') - set_search_domain(domainopt); - if (in_use) - result = isc_app_onrun(mctx, global_task, onrun_callback, - NULL); - else - result = isc_app_onrun(mctx, global_task, getinput, NULL); - check_result(result, "isc_app_onrun"); - in_use = ISC_TF(!in_use); - - (void)isc_app_run(); - - puts(""); - debug("done, and starting to shut down"); - if (global_event != NULL) - isc_event_free(&global_event); - cancel_all(); - destroy_libs(); - isc_app_finish(); - - return (0); -} diff --git a/contrib/bind9/bin/dig/nslookup.docbook b/contrib/bind9/bin/dig/nslookup.docbook deleted file mode 100644 index dff5fa3..0000000 --- a/contrib/bind9/bin/dig/nslookup.docbook +++ /dev/null @@ -1,496 +0,0 @@ -]> - - - - - - - - Jun 30, 2000 - - - - nslookup - 1 - BIND9 - - - - nslookup - query Internet name servers interactively - - - - - 2004 - 2005 - 2006 - 2007 - Internet Systems Consortium, Inc. ("ISC") - - - - - - nslookup - - name | - - server - - - - - DESCRIPTION - Nslookup - is a program to query Internet domain name servers. Nslookup - has two modes: interactive and non-interactive. Interactive mode allows - the user to query name servers for information about various hosts and - domains or to print a list of hosts in a domain. Non-interactive mode - is - used to print just the name and requested information for a host or - domain. - - - - - ARGUMENTS - - Interactive mode is entered in the following cases: - - - - when no arguments are given (the default name server will be used) - - - - - when the first argument is a hyphen (-) and the second argument is - the host name or Internet address of a name server. - - - - - - - Non-interactive mode is used when the name or Internet address of the - host to be looked up is given as the first argument. The optional second - argument specifies the host name or address of a name server. - - - - Options can also be specified on the command line if they precede the - arguments and are prefixed with a hyphen. For example, to - change the default query type to host information, and the initial - timeout to 10 seconds, type: - - -nslookup -query=hinfo -timeout=10 - - - - - - - - INTERACTIVE COMMANDS - - - host server - - - Look up information for host using the current default server or - using server, if specified. If host is an Internet address and - the query type is A or PTR, the name of the host is returned. - If host is a name and does not have a trailing period, the - search list is used to qualify the name. - - - - To look up a host not in the current domain, append a period to - the name. - - - - - - server domain - - - - - - lserver domain - - - Change the default server to domain; lserver uses the initial - server to look up information about domain, while server uses - the current default server. If an authoritative answer can't be - found, the names of servers that might have the answer are - returned. - - - - - - root - - - not implemented - - - - - - finger - - - not implemented - - - - - - ls - - - not implemented - - - - - - view - - - not implemented - - - - - - help - - - not implemented - - - - - - ? - - - not implemented - - - - - - exit - - - Exits the program. - - - - - - set - keyword=value - - - This command is used to change state information that affects - the lookups. Valid keywords are: - - - all - - - Prints the current values of the frequently used - options to set. - Information about the current default - server and host is also printed. - - - - - - class=value - - - Change the query class to one of: - - - IN - - - the Internet class - - - - - CH - - - the Chaos class - - - - - HS - - - the Hesiod class - - - - - ANY - - - wildcard - - - - - The class specifies the protocol group of the information. - - - - (Default = IN; abbreviation = cl) - - - - - - - nodebug - - - Turn on or off the display of the full response packet and - any intermediate response packets when searching. - - - (Default = nodebug; abbreviation = nodeb) - - - - - - - nod2 - - - Turn debugging mode on or off. This displays more about - what nslookup is doing. - - - (Default = nod2) - - - - - - domain=name - - - Sets the search list to name. - - - - - - - nosearch - - - If the lookup request contains at least one period but - doesn't end with a trailing period, append the domain - names in the domain search list to the request until an - answer is received. - - - (Default = search) - - - - - - port=value - - - Change the default TCP/UDP name server port to value. - - - (Default = 53; abbreviation = po) - - - - - - querytype=value - - - - - - - type=value - - - Change the type of the information query. - - - (Default = A; abbreviations = q, ty) - - - - - - - norecurse - - - Tell the name server to query other servers if it does not - have the - information. - - - (Default = recurse; abbreviation = [no]rec) - - - - - - retry=number - - - Set the number of retries to number. - - - - - - timeout=number - - - Change the initial timeout interval for waiting for a - reply to number seconds. - - - - - - - novc - - - Always use a virtual circuit when sending requests to the - server. - - - (Default = novc) - - - - - - - nofail - - - Try the next nameserver if a nameserver responds with - SERVFAIL or a referral (nofail) or terminate query - (fail) on such a response. - - - (Default = nofail) - - - - - - - - - - - - - FILES - /etc/resolv.conf - - - - - SEE ALSO - - dig1 - , - - host1 - , - - named8 - . - - - - - Author - - Andrew Cherenson - - - diff --git a/contrib/bind9/bin/dig/nslookup.html b/contrib/bind9/bin/dig/nslookup.html deleted file mode 100644 index 46ae43c..0000000 --- a/contrib/bind9/bin/dig/nslookup.html +++ /dev/null @@ -1,307 +0,0 @@ - - - - - -nslookup - - -
-
-
-

Name

-

nslookup — query Internet name servers interactively

-
-
-

Synopsis

-

nslookup [-option] [name | -] [server]

-
-
-

DESCRIPTION

-

Nslookup - is a program to query Internet domain name servers. Nslookup - has two modes: interactive and non-interactive. Interactive mode allows - the user to query name servers for information about various hosts and - domains or to print a list of hosts in a domain. Non-interactive mode - is - used to print just the name and requested information for a host or - domain. -

-
-
-

ARGUMENTS

-

- Interactive mode is entered in the following cases: -

-
    -
  1. - when no arguments are given (the default name server will be used) -

  2. -
  3. - when the first argument is a hyphen (-) and the second argument is - the host name or Internet address of a name server. -

  4. -
-

-

-

- Non-interactive mode is used when the name or Internet address of the - host to be looked up is given as the first argument. The optional second - argument specifies the host name or address of a name server. -

-

- Options can also be specified on the command line if they precede the - arguments and are prefixed with a hyphen. For example, to - change the default query type to host information, and the initial - timeout to 10 seconds, type: -

-
-nslookup -query=hinfo  -timeout=10
-
-

-

-
-
-

INTERACTIVE COMMANDS

-
-
host [server]
-
-

- Look up information for host using the current default server or - using server, if specified. If host is an Internet address and - the query type is A or PTR, the name of the host is returned. - If host is a name and does not have a trailing period, the - search list is used to qualify the name. -

-

- To look up a host not in the current domain, append a period to - the name. -

-
-
server domain
-

-
lserver domain
-

- Change the default server to domain; lserver uses the initial - server to look up information about domain, while server uses - the current default server. If an authoritative answer can't be - found, the names of servers that might have the answer are - returned. -

-
root
-

- not implemented -

-
finger
-

- not implemented -

-
ls
-

- not implemented -

-
view
-

- not implemented -

-
help
-

- not implemented -

-
?
-

- not implemented -

-
exit
-

- Exits the program. -

-
set - keyword[=value]
-
-

- This command is used to change state information that affects - the lookups. Valid keywords are: -

-
-
all
-

- Prints the current values of the frequently used - options to set. - Information about the current default - server and host is also printed. -

-
class=value
-
-

- Change the query class to one of: -

-
-
IN
-

- the Internet class -

-
CH
-

- the Chaos class -

-
HS
-

- the Hesiod class -

-
ANY
-

- wildcard -

-
-

- The class specifies the protocol group of the information. - -

-

- (Default = IN; abbreviation = cl) -

-
-
- [no]debug
-
-

- Turn on or off the display of the full response packet and - any intermediate response packets when searching. -

-

- (Default = nodebug; abbreviation = [no]deb) -

-
-
- [no]d2
-
-

- Turn debugging mode on or off. This displays more about - what nslookup is doing. -

-

- (Default = nod2) -

-
-
domain=name
-

- Sets the search list to name. -

-
- [no]search
-
-

- If the lookup request contains at least one period but - doesn't end with a trailing period, append the domain - names in the domain search list to the request until an - answer is received. -

-

- (Default = search) -

-
-
port=value
-
-

- Change the default TCP/UDP name server port to value. -

-

- (Default = 53; abbreviation = po) -

-
-
querytype=value
-

-
type=value
-
-

- Change the type of the information query. -

-

- (Default = A; abbreviations = q, ty) -

-
-
- [no]recurse
-
-

- Tell the name server to query other servers if it does not - have the - information. -

-

- (Default = recurse; abbreviation = [no]rec) -

-
-
retry=number
-

- Set the number of retries to number. -

-
timeout=number
-

- Change the initial timeout interval for waiting for a - reply to number seconds. -

-
- [no]vc
-
-

- Always use a virtual circuit when sending requests to the - server. -

-

- (Default = novc) -

-
-
- [no]fail
-
-

- Try the next nameserver if a nameserver responds with - SERVFAIL or a referral (nofail) or terminate query - (fail) on such a response. -

-

- (Default = nofail) -

-
-
-

-

-
-
-
-
-

FILES

-

/etc/resolv.conf -

-
-
-

SEE ALSO

-

dig(1), - host(1), - named(8). -

-
-
-

Author

-

- Andrew Cherenson -

-
-
- diff --git a/contrib/bind9/bin/dnssec/Makefile.in b/contrib/bind9/bin/dnssec/Makefile.in deleted file mode 100644 index b94dca7..0000000 --- a/contrib/bind9/bin/dnssec/Makefile.in +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 2000-2002 Internet Software Consortium. -# -# Permission to use, copy, modify, and 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: Makefile.in,v 1.26.18.4 2005/05/02 00:26:11 marka Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -@BIND9_VERSION@ - -@BIND9_MAKE_INCLUDES@ - -CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} - -CDEFINES = -DVERSION=\"${VERSION}\" -CWARNINGS = - -DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ -ISCLIBS = ../../lib/isc/libisc.@A@ - -DNSDEPLIBS = ../../lib/dns/libdns.@A@ -ISCDEPLIBS = ../../lib/isc/libisc.@A@ - -DEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS} - -LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@ - -# Alphabetically -TARGETS = dnssec-keygen@EXEEXT@ dnssec-signzone@EXEEXT@ - -OBJS = dnssectool.@O@ - -SRCS = dnssec-keygen.c dnssec-signzone.c dnssectool.c - -MANPAGES = dnssec-keygen.8 dnssec-signzone.8 - -HTMLPAGES = dnssec-keygen.html dnssec-signzone.html - -MANOBJS = ${MANPAGES} ${HTMLPAGES} - -@BIND9_MAKE_RULES@ - -dnssec-keygen@EXEEXT@: dnssec-keygen.@O@ ${OBJS} ${DEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ - dnssec-keygen.@O@ ${OBJS} ${LIBS} - -dnssec-signzone.@O@: dnssec-signzone.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -DVERSION=\"${VERSION}\" \ - -c ${srcdir}/dnssec-signzone.c - -dnssec-signzone@EXEEXT@: dnssec-signzone.@O@ ${OBJS} ${DEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ - dnssec-signzone.@O@ ${OBJS} ${LIBS} - -doc man:: ${MANOBJS} - -docclean manclean maintainer-clean:: - rm -f ${MANOBJS} - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 - -install:: ${TARGETS} installdirs - for t in ${TARGETS}; do ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} $$t ${DESTDIR}${sbindir}; done - for m in ${MANPAGES}; do ${INSTALL_DATA} ${srcdir}/$$m ${DESTDIR}${mandir}/man8; done - -clean distclean:: - rm -f ${TARGETS} - diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.8 b/contrib/bind9/bin/dnssec/dnssec-keygen.8 deleted file mode 100644 index 542190b..0000000 --- a/contrib/bind9/bin/dnssec/dnssec-keygen.8 +++ /dev/null @@ -1,200 +0,0 @@ -.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") -.\" Copyright (C) 2000-2003 Internet Software Consortium. -.\" -.\" Permission to use, copy, modify, and 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: dnssec-keygen.8,v 1.23.18.14 2007/05/09 03:33:12 marka Exp $ -.\" -.hy 0 -.ad l -.\" Title: dnssec\-keygen -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.71.1 -.\" Date: June 30, 2000 -.\" Manual: BIND9 -.\" Source: BIND9 -.\" -.TH "DNSSEC\-KEYGEN" "8" "June 30, 2000" "BIND9" "BIND9" -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.SH "NAME" -dnssec\-keygen \- DNSSEC key generation tool -.SH "SYNOPSIS" -.HP 14 -\fBdnssec\-keygen\fR {\-a\ \fIalgorithm\fR} {\-b\ \fIkeysize\fR} {\-n\ \fInametype\fR} [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-e\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-g\ \fR\fB\fIgenerator\fR\fR] [\fB\-h\fR] [\fB\-k\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-s\ \fR\fB\fIstrength\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] {name} -.SH "DESCRIPTION" -.PP -\fBdnssec\-keygen\fR -generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures), as defined in RFC 2845. -.SH "OPTIONS" -.PP -\-a \fIalgorithm\fR -.RS 4 -Selects the cryptographic algorithm. The value of -\fBalgorithm\fR -must be one of RSAMD5 (RSA) or RSASHA1, DSA, DH (Diffie Hellman), or HMAC\-MD5. These values are case insensitive. -.sp -Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. For TSIG, HMAC\-MD5 is mandatory. -.sp -Note 2: HMAC\-MD5 and DH automatically set the \-k flag. -.RE -.PP -\-b \fIkeysize\fR -.RS 4 -Specifies the number of bits in the key. The choice of key size depends on the algorithm used. RSAMD5 / RSASHA1 keys must be between 512 and 2048 bits. Diffie Hellman keys must be between 128 and 4096 bits. DSA keys must be between 512 and 1024 bits and an exact multiple of 64. HMAC\-MD5 keys must be between 1 and 512 bits. -.RE -.PP -\-n \fInametype\fR -.RS 4 -Specifies the owner type of the key. The value of -\fBnametype\fR -must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive. -.RE -.PP -\-c \fIclass\fR -.RS 4 -Indicates that the DNS record containing the key should have the specified class. If not specified, class IN is used. -.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 flag is KSK (Key Signing Key) DNSKEY. -.RE -.PP -\-g \fIgenerator\fR -.RS 4 -If generating a Diffie Hellman key, use this generator. Allowed values are 2 and 5. If no generator is specified, a known prime from RFC 2539 will be used if possible; otherwise the default is 2. -.RE -.PP -\-h -.RS 4 -Prints a short summary of the options and arguments to -\fBdnssec\-keygen\fR. -.RE -.PP -\-k -.RS 4 -Generate KEY records rather than DNSKEY records. -.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. -.RE -.PP -\-r \fIrandomdev\fR -.RS 4 -Specifies the source of randomness. If the operating system does not provide a -\fI/dev/random\fR -or equivalent device, the default source of randomness is keyboard input. -\fIrandomdev\fR -specifies the name of a character device or file containing random data to be used instead of the default. The special value -\fIkeyboard\fR -indicates that keyboard input should be used. -.RE -.PP -\-s \fIstrength\fR -.RS 4 -Specifies the strength value of the key. The strength is a number between 0 and 15, and currently has no defined purpose in DNSSEC. -.RE -.PP -\-t \fItype\fR -.RS 4 -Indicates the use of the key. -\fBtype\fR -must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF. AUTH refers to the ability to authenticate data, and CONF the ability to encrypt data. -.RE -.PP -\-v \fIlevel\fR -.RS 4 -Sets the debugging level. -.RE -.SH "GENERATED KEYS" -.PP -When -\fBdnssec\-keygen\fR -completes successfully, it prints a string of the form -\fIKnnnn.+aaa+iiiii\fR -to the standard output. This is an identification string for the key it has generated. -.TP 4 -\(bu -\fInnnn\fR -is the key name. -.TP 4 -\(bu -\fIaaa\fR -is the numeric representation of the algorithm. -.TP 4 -\(bu -\fIiiiii\fR -is the key identifier (or footprint). -.PP -\fBdnssec\-keygen\fR -creates two files, with names based on the printed string. -\fIKnnnn.+aaa+iiiii.key\fR -contains the public key, and -\fIKnnnn.+aaa+iiiii.private\fR -contains the private key. -.PP -The -\fI.key\fR -file contains a DNS KEY record that can be inserted into a zone file (directly or with a $INCLUDE statement). -.PP -The -\fI.private\fR -file contains algorithm\-specific fields. For obvious security reasons, this file does not have general read permission. -.PP -Both -\fI.key\fR -and -\fI.private\fR -files are generated for symmetric encryption algorithms such as HMAC\-MD5, even though the public and private key are equivalent. -.SH "EXAMPLE" -.PP -To generate a 768\-bit DSA key for the domain -\fBexample.com\fR, the following command would be issued: -.PP -\fBdnssec\-keygen \-a DSA \-b 768 \-n ZONE example.com\fR -.PP -The command would print a string of the form: -.PP -\fBKexample.com.+003+26160\fR -.PP -In this example, -\fBdnssec\-keygen\fR -creates the files -\fIKexample.com.+003+26160.key\fR -and -\fIKexample.com.+003+26160.private\fR. -.SH "SEE ALSO" -.PP -\fBdnssec\-signzone\fR(8), -BIND 9 Administrator Reference Manual, -RFC 2535, -RFC 2845, -RFC 2539. -.SH "AUTHOR" -.PP -Internet Systems Consortium -.SH "COPYRIGHT" -Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") -.br -Copyright \(co 2000\-2003 Internet Software Consortium. -.br diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.c b/contrib/bind9/bin/dnssec/dnssec-keygen.c deleted file mode 100644 index 0b57f6d..0000000 --- a/contrib/bind9/bin/dnssec/dnssec-keygen.c +++ /dev/null @@ -1,512 +0,0 @@ -/* - * Portions Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Portions Copyright (C) 1999-2003 Internet Software Consortium. - * Portions Copyright (C) 1995-2000 by Network Associates, Inc. - * - * 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 AND NETWORK ASSOCIATES 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: dnssec-keygen.c,v 1.66.18.10 2007/08/28 07:19:55 tbox Exp $ */ - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "dnssectool.h" - -#define MAX_RSA 4096 /* should be long enough... */ - -const char *program = "dnssec-keygen"; -int verbose; - -static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 | HMAC-MD5 |" - " HMAC-SHA1 | HMAC-SHA224 | HMAC-SHA256 | " - " HMAC-SHA384 | HMAC-SHA512"; - -static isc_boolean_t -dsa_size_ok(int size) { - return (ISC_TF(size >= 512 && size <= 1024 && size % 64 == 0)); -} - -static void -usage(void) { - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s -a alg -b bits -n type [options] name\n\n", - program); - fprintf(stderr, "Version: %s\n", VERSION); - fprintf(stderr, "Required options:\n"); - fprintf(stderr, " -a algorithm: %s\n", algs); - fprintf(stderr, " -b key size, in bits:\n"); - fprintf(stderr, " RSAMD5:\t\t[512..%d]\n", MAX_RSA); - fprintf(stderr, " RSASHA1:\t\t[512..%d]\n", MAX_RSA); - fprintf(stderr, " DH:\t\t[128..4096]\n"); - fprintf(stderr, " DSA:\t\t[512..1024] and divisible by 64\n"); - fprintf(stderr, " HMAC-MD5:\t[1..512]\n"); - fprintf(stderr, " HMAC-SHA1:\t[1..160]\n"); - fprintf(stderr, " HMAC-SHA224:\t[1..224]\n"); - fprintf(stderr, " HMAC-SHA256:\t[1..256]\n"); - fprintf(stderr, " HMAC-SHA384:\t[1..384]\n"); - fprintf(stderr, " HMAC-SHA512:\t[1..512]\n"); - fprintf(stderr, " -n nametype: ZONE | HOST | ENTITY | USER | OTHER\n"); - fprintf(stderr, " name: owner of the key\n"); - fprintf(stderr, "Other options:\n"); - fprintf(stderr, " -c (default: IN)\n"); - fprintf(stderr, " -d (0 => max, default)\n"); - fprintf(stderr, " -e use large exponent (RSAMD5/RSASHA1 only)\n"); - fprintf(stderr, " -f keyflag: KSK\n"); - fprintf(stderr, " -g use specified generator " - "(DH only)\n"); - fprintf(stderr, " -t : " - "AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF " - "(default: AUTHCONF)\n"); - fprintf(stderr, " -p : " - "default: 3 [dnssec]\n"); - fprintf(stderr, " -s strength value this key signs DNS " - "records with (default: 0)\n"); - fprintf(stderr, " -r : a file containing random data\n"); - fprintf(stderr, " -v \n"); - fprintf(stderr, " -k : generate a TYPE=KEY key\n"); - fprintf(stderr, "Output:\n"); - fprintf(stderr, " K++.key, " - "K++.private\n"); - - exit (-1); -} - -int -main(int argc, char **argv) { - char *algname = NULL, *nametype = NULL, *type = NULL; - char *classname = NULL; - char *endp; - dst_key_t *key = NULL, *oldkey; - dns_fixedname_t fname; - dns_name_t *name; - isc_uint16_t flags = 0, ksk = 0; - dns_secalg_t alg; - isc_boolean_t conflict = ISC_FALSE, null_key = ISC_FALSE; - isc_mem_t *mctx = NULL; - int ch, rsa_exp = 0, generator = 0, param = 0; - int protocol = -1, size = -1, signatory = 0; - isc_result_t ret; - isc_textregion_t r; - char filename[255]; - isc_buffer_t buf; - isc_log_t *log = NULL; - isc_entropy_t *ectx = NULL; - dns_rdataclass_t rdclass; - int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC; - int dbits = 0; - - if (argc == 1) - usage(); - - RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); - - dns_result_register(); - - while ((ch = isc_commandline_parse(argc, argv, - "a:b:c:d:ef:g:kn:t:p:s:r:v:h")) != -1) - { - switch (ch) { - case 'a': - algname = isc_commandline_argument; - break; - case 'b': - size = strtol(isc_commandline_argument, &endp, 10); - if (*endp != '\0' || size < 0) - fatal("-b requires a non-negative number"); - break; - case 'c': - classname = isc_commandline_argument; - break; - case 'd': - dbits = strtol(isc_commandline_argument, &endp, 10); - if (*endp != '\0' || dbits < 0) - fatal("-d requires a non-negative number"); - break; - case 'e': - rsa_exp = 1; - break; - case 'f': - if (strcasecmp(isc_commandline_argument, "KSK") == 0) - ksk = DNS_KEYFLAG_KSK; - else - fatal("unknown flag '%s'", - isc_commandline_argument); - break; - case 'g': - generator = strtol(isc_commandline_argument, - &endp, 10); - if (*endp != '\0' || generator <= 0) - fatal("-g requires a positive number"); - break; - case 'k': - options |= DST_TYPE_KEY; - break; - case 'n': - nametype = isc_commandline_argument; - break; - case 't': - type = isc_commandline_argument; - break; - case 'p': - protocol = strtol(isc_commandline_argument, &endp, 10); - if (*endp != '\0' || protocol < 0 || protocol > 255) - fatal("-p must be followed by a number " - "[0..255]"); - break; - case 's': - signatory = strtol(isc_commandline_argument, - &endp, 10); - if (*endp != '\0' || signatory < 0 || signatory > 15) - fatal("-s must be followed by a number " - "[0..15]"); - break; - case 'r': - setup_entropy(mctx, isc_commandline_argument, &ectx); - break; - case 'v': - endp = NULL; - verbose = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0') - fatal("-v must be followed by a number"); - break; - - case 'h': - usage(); - default: - fprintf(stderr, "%s: invalid argument -%c\n", - program, ch); - usage(); - } - } - - if (ectx == NULL) - setup_entropy(mctx, NULL, &ectx); - ret = dst_lib_init(mctx, ectx, - ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); - if (ret != ISC_R_SUCCESS) - fatal("could not initialize dst"); - - setup_logging(verbose, mctx, &log); - - if (argc < isc_commandline_index + 1) - fatal("the key name was not specified"); - if (argc > isc_commandline_index + 1) - fatal("extraneous arguments"); - - if (algname == NULL) - fatal("no algorithm was specified"); - if (strcasecmp(algname, "RSA") == 0) { - fprintf(stderr, "The use of RSA (RSAMD5) is not recommended.\n" - "If you still wish to use RSA (RSAMD5) please " - "specify \"-a RSAMD5\"\n"); - return (1); - } else if (strcasecmp(algname, "HMAC-MD5") == 0) { - options |= DST_TYPE_KEY; - alg = DST_ALG_HMACMD5; - } else if (strcasecmp(algname, "HMAC-SHA1") == 0) { - options |= DST_TYPE_KEY; - alg = DST_ALG_HMACSHA1; - } else if (strcasecmp(algname, "HMAC-SHA224") == 0) { - options |= DST_TYPE_KEY; - alg = DST_ALG_HMACSHA224; - } else if (strcasecmp(algname, "HMAC-SHA256") == 0) { - options |= DST_TYPE_KEY; - alg = DST_ALG_HMACSHA256; - } else if (strcasecmp(algname, "HMAC-SHA384") == 0) { - options |= DST_TYPE_KEY; - alg = DST_ALG_HMACSHA384; - } else if (strcasecmp(algname, "HMAC-SHA512") == 0) { - options |= DST_TYPE_KEY; - alg = DST_ALG_HMACSHA512; - } else { - r.base = algname; - r.length = strlen(algname); - ret = dns_secalg_fromtext(&alg, &r); - if (ret != ISC_R_SUCCESS) - fatal("unknown algorithm %s", algname); - if (alg == DST_ALG_DH) - options |= DST_TYPE_KEY; - } - - if (type != NULL && (options & DST_TYPE_KEY) != 0) { - if (strcasecmp(type, "NOAUTH") == 0) - flags |= DNS_KEYTYPE_NOAUTH; - else if (strcasecmp(type, "NOCONF") == 0) - flags |= DNS_KEYTYPE_NOCONF; - else if (strcasecmp(type, "NOAUTHCONF") == 0) { - flags |= (DNS_KEYTYPE_NOAUTH | DNS_KEYTYPE_NOCONF); - if (size < 0) - size = 0; - } - else if (strcasecmp(type, "AUTHCONF") == 0) - /* nothing */; - else - fatal("invalid type %s", type); - } - - if (size < 0) - fatal("key size not specified (-b option)"); - - switch (alg) { - case DNS_KEYALG_RSAMD5: - case DNS_KEYALG_RSASHA1: - if (size != 0 && (size < 512 || size > MAX_RSA)) - fatal("RSA key size %d out of range", size); - break; - case DNS_KEYALG_DH: - if (size != 0 && (size < 128 || size > 4096)) - fatal("DH key size %d out of range", size); - break; - case DNS_KEYALG_DSA: - if (size != 0 && !dsa_size_ok(size)) - fatal("invalid DSS key size: %d", size); - break; - case DST_ALG_HMACMD5: - if (size < 1 || size > 512) - fatal("HMAC-MD5 key size %d out of range", size); - if (dbits != 0 && (dbits < 80 || dbits > 128)) - fatal("HMAC-MD5 digest bits %d out of range", dbits); - if ((dbits % 8) != 0) - fatal("HMAC-MD5 digest bits %d not divisible by 8", - dbits); - break; - case DST_ALG_HMACSHA1: - if (size < 1 || size > 160) - fatal("HMAC-SHA1 key size %d out of range", size); - if (dbits != 0 && (dbits < 80 || dbits > 160)) - fatal("HMAC-SHA1 digest bits %d out of range", dbits); - if ((dbits % 8) != 0) - fatal("HMAC-SHA1 digest bits %d not divisible by 8", - dbits); - break; - case DST_ALG_HMACSHA224: - if (size < 1 || size > 224) - fatal("HMAC-SHA224 key size %d out of range", size); - if (dbits != 0 && (dbits < 112 || dbits > 224)) - fatal("HMAC-SHA224 digest bits %d out of range", dbits); - if ((dbits % 8) != 0) - fatal("HMAC-SHA224 digest bits %d not divisible by 8", - dbits); - break; - case DST_ALG_HMACSHA256: - if (size < 1 || size > 256) - fatal("HMAC-SHA256 key size %d out of range", size); - if (dbits != 0 && (dbits < 128 || dbits > 256)) - fatal("HMAC-SHA256 digest bits %d out of range", dbits); - if ((dbits % 8) != 0) - fatal("HMAC-SHA256 digest bits %d not divisible by 8", - dbits); - break; - case DST_ALG_HMACSHA384: - if (size < 1 || size > 384) - fatal("HMAC-384 key size %d out of range", size); - if (dbits != 0 && (dbits < 192 || dbits > 384)) - fatal("HMAC-SHA384 digest bits %d out of range", dbits); - if ((dbits % 8) != 0) - fatal("HMAC-SHA384 digest bits %d not divisible by 8", - dbits); - break; - case DST_ALG_HMACSHA512: - if (size < 1 || size > 512) - fatal("HMAC-SHA512 key size %d out of range", size); - if (dbits != 0 && (dbits < 256 || dbits > 512)) - fatal("HMAC-SHA512 digest bits %d out of range", dbits); - if ((dbits % 8) != 0) - fatal("HMAC-SHA512 digest bits %d not divisible by 8", - dbits); - break; - } - - if (!(alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_RSASHA1) && - 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"); - - if (nametype == NULL) - fatal("no nametype specified"); - if (strcasecmp(nametype, "zone") == 0) - flags |= DNS_KEYOWNER_ZONE; - else if ((options & DST_TYPE_KEY) != 0) { /* KEY */ - if (strcasecmp(nametype, "host") == 0 || - strcasecmp(nametype, "entity") == 0) - flags |= DNS_KEYOWNER_ENTITY; - else if (strcasecmp(nametype, "user") == 0) - flags |= DNS_KEYOWNER_USER; - else - fatal("invalid KEY nametype %s", nametype); - } else if (strcasecmp(nametype, "other") != 0) /* DNSKEY */ - fatal("invalid DNSKEY nametype %s", nametype); - - rdclass = strtoclass(classname); - - if ((options & DST_TYPE_KEY) != 0) /* KEY */ - flags |= signatory; - else if ((flags & DNS_KEYOWNER_ZONE) != 0) /* DNSKEY */ - flags |= ksk; - - if (protocol == -1) - protocol = DNS_KEYPROTO_DNSSEC; - else if ((options & DST_TYPE_KEY) == 0 && - protocol != DNS_KEYPROTO_DNSSEC) - fatal("invalid DNSKEY protocol: %d", protocol); - - if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) { - if (size > 0) - fatal("specified null key with non-zero size"); - if ((flags & DNS_KEYFLAG_SIGNATORYMASK) != 0) - fatal("specified null key with signing authority"); - } - - if ((flags & DNS_KEYFLAG_OWNERMASK) == DNS_KEYOWNER_ZONE && - (alg == DNS_KEYALG_DH || alg == DST_ALG_HMACMD5 || - alg == DST_ALG_HMACSHA1 || alg == DST_ALG_HMACSHA224 || - alg == DST_ALG_HMACSHA256 || alg == DST_ALG_HMACSHA384 || - alg == DST_ALG_HMACSHA512)) - fatal("a key with algorithm '%s' cannot be a zone key", - algname); - - dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); - isc_buffer_init(&buf, argv[isc_commandline_index], - strlen(argv[isc_commandline_index])); - isc_buffer_add(&buf, strlen(argv[isc_commandline_index])); - ret = dns_name_fromtext(name, &buf, dns_rootname, ISC_FALSE, NULL); - if (ret != ISC_R_SUCCESS) - fatal("invalid key name %s: %s", argv[isc_commandline_index], - isc_result_totext(ret)); - - switch(alg) { - case DNS_KEYALG_RSAMD5: - case DNS_KEYALG_RSASHA1: - param = rsa_exp; - break; - case DNS_KEYALG_DH: - param = generator; - break; - case DNS_KEYALG_DSA: - case DST_ALG_HMACMD5: - case DST_ALG_HMACSHA1: - case DST_ALG_HMACSHA224: - case DST_ALG_HMACSHA256: - case DST_ALG_HMACSHA384: - case DST_ALG_HMACSHA512: - param = 0; - break; - } - - if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) - null_key = ISC_TRUE; - - isc_buffer_init(&buf, filename, sizeof(filename) - 1); - - do { - conflict = ISC_FALSE; - oldkey = NULL; - - /* generate the key */ - ret = dst_key_generate(name, alg, size, param, flags, protocol, - rdclass, mctx, &key); - isc_entropy_stopcallbacksources(ectx); - - if (ret != ISC_R_SUCCESS) { - char namestr[DNS_NAME_FORMATSIZE]; - char algstr[ALG_FORMATSIZE]; - dns_name_format(name, namestr, sizeof(namestr)); - alg_format(alg, algstr, sizeof(algstr)); - fatal("failed to generate key %s/%s: %s\n", - namestr, algstr, isc_result_totext(ret)); - exit(-1); - } - - dst_key_setbits(key, dbits); - - /* - * Try to read a key with the same name, alg and id from disk. - * If there is one we must continue generating a new one - * unless we were asked to generate a null key, in which - * case we return failure. - */ - ret = dst_key_fromfile(name, dst_key_id(key), alg, - DST_TYPE_PRIVATE, NULL, mctx, &oldkey); - /* do not overwrite an existing key */ - if (ret == ISC_R_SUCCESS) { - dst_key_free(&oldkey); - conflict = ISC_TRUE; - if (null_key) - break; - } - if (conflict == ISC_TRUE) { - if (verbose > 0) { - isc_buffer_clear(&buf); - ret = dst_key_buildfilename(key, 0, NULL, &buf); - fprintf(stderr, - "%s: %s already exists, " - "generating a new key\n", - program, filename); - } - dst_key_free(&key); - } - - } while (conflict == ISC_TRUE); - - if (conflict) - fatal("cannot generate a null key when a key with id 0 " - "already exists"); - - ret = dst_key_tofile(key, options, NULL); - if (ret != ISC_R_SUCCESS) { - char keystr[KEY_FORMATSIZE]; - key_format(key, keystr, sizeof(keystr)); - fatal("failed to write key %s: %s\n", keystr, - isc_result_totext(ret)); - } - - isc_buffer_clear(&buf); - ret = dst_key_buildfilename(key, 0, NULL, &buf); - printf("%s\n", filename); - dst_key_free(&key); - - cleanup_logging(&log); - cleanup_entropy(&ectx); - dst_lib_destroy(); - dns_name_destroy(); - if (verbose > 10) - isc_mem_stats(mctx, stdout); - isc_mem_destroy(&mctx); - - return (0); -} diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.docbook b/contrib/bind9/bin/dnssec/dnssec-keygen.docbook deleted file mode 100644 index 8e81cb4..0000000 --- a/contrib/bind9/bin/dnssec/dnssec-keygen.docbook +++ /dev/null @@ -1,359 +0,0 @@ -]> - - - - - - June 30, 2000 - - - - dnssec-keygen - 8 - BIND9 - - - - dnssec-keygen - DNSSEC key generation tool - - - - - 2004 - 2005 - 2007 - Internet Systems Consortium, Inc. ("ISC") - - - 2000 - 2001 - 2002 - 2003 - Internet Software Consortium. - - - - - - dnssec-keygen - -a algorithm - -b keysize - -n nametype - - - - - - - - - - - - name - - - - - 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 - TSIG (Transaction Signatures), as defined in RFC 2845. - - - - - OPTIONS - - - - -a algorithm - - - Selects the cryptographic algorithm. The value of - must be one of RSAMD5 (RSA) or RSASHA1, - DSA, DH (Diffie Hellman), or HMAC-MD5. These values - are case insensitive. - - - Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement - algorithm, - and DSA is recommended. For TSIG, HMAC-MD5 is mandatory. - - - Note 2: HMAC-MD5 and DH automatically set the -k flag. - - - - - - -b keysize - - - Specifies the number of bits in the key. The choice of key - size depends on the algorithm used. RSAMD5 / RSASHA1 keys must be - between - 512 and 2048 bits. Diffie Hellman keys must be between - 128 and 4096 bits. DSA keys must be between 512 and 1024 - bits and an exact multiple of 64. HMAC-MD5 keys must be - between 1 and 512 bits. - - - - - - -n nametype - - - Specifies the owner type of the key. The value of - must either be ZONE (for a DNSSEC - zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with - a host (KEY)), - USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). - These values are - case insensitive. - - - - - - -c class - - - Indicates that the DNS record containing the key should have - the specified class. If not specified, class IN is used. - - - - - - -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. - The only recognized flag is KSK (Key Signing Key) DNSKEY. - - - - - - -g generator - - - If generating a Diffie Hellman key, use this generator. - Allowed values are 2 and 5. If no generator - is specified, a known prime from RFC 2539 will be used - if possible; otherwise the default is 2. - - - - - - -h - - - Prints a short summary of the options and arguments to - dnssec-keygen. - - - - - - -k - - - Generate KEY records rather than DNSKEY records. - - - - - - -p protocol - - - 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. - - - - - - -r randomdev - - - Specifies the source of randomness. If the operating - system does not provide a /dev/random - or equivalent device, the default source of randomness - is keyboard input. randomdev - specifies - the name of a character device or file containing random - data to be used instead of the default. The special value - keyboard indicates that keyboard - input should be used. - - - - - - -s strength - - - Specifies the strength value of the key. The strength is - a number between 0 and 15, and currently has no defined - purpose in DNSSEC. - - - - - - -t type - - - Indicates the use of the key. must be - one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default - is AUTHCONF. AUTH refers to the ability to authenticate - data, and CONF the ability to encrypt data. - - - - - - -v level - - - Sets the debugging level. - - - - - - - - - GENERATED KEYS - - When dnssec-keygen completes - successfully, - it prints a string of the form Knnnn.+aaa+iiiii - to the standard output. This is an identification string for - the key it has generated. - - - - nnnn is the key name. - - - - aaa is the numeric representation - of the - algorithm. - - - - iiiii is the key identifier (or - footprint). - - - - dnssec-keygen - creates two files, with names based - on the printed string. Knnnn.+aaa+iiiii.key - contains the public key, and - Knnnn.+aaa+iiiii.private contains the - private - key. - - - The .key file contains a DNS KEY record - that - can be inserted into a zone file (directly or with a $INCLUDE - statement). - - - The .private file contains - algorithm-specific - fields. For obvious security reasons, this file does not have - general read permission. - - - Both .key and .private - files are generated for symmetric encryption algorithms such as - HMAC-MD5, even though the public and private key are equivalent. - - - - - EXAMPLE - - To generate a 768-bit DSA key for the domain - example.com, the following command would be - issued: - - dnssec-keygen -a DSA -b 768 -n ZONE example.com - - - The command would print a string of the form: - - Kexample.com.+003+26160 - - - In this example, dnssec-keygen creates - the files Kexample.com.+003+26160.key - and - Kexample.com.+003+26160.private. - - - - - SEE ALSO - - dnssec-signzone8 - , - BIND 9 Administrator Reference Manual, - RFC 2535, - RFC 2845, - RFC 2539. - - - - - AUTHOR - Internet Systems Consortium - - - - diff --git a/contrib/bind9/bin/dnssec/dnssec-keygen.html b/contrib/bind9/bin/dnssec/dnssec-keygen.html deleted file mode 100644 index 7ad747f..0000000 --- a/contrib/bind9/bin/dnssec/dnssec-keygen.html +++ /dev/null @@ -1,232 +0,0 @@ - - - - - -dnssec-keygen - - -
-
-
-

Name

-

dnssec-keygen — DNSSEC key generation tool

-
-
-

Synopsis

-

dnssec-keygen {-a algorithm} {-b keysize} {-n nametype} [-c class] [-e] [-f flag] [-g generator] [-h] [-k] [-p protocol] [-r randomdev] [-s strength] [-t type] [-v level] {name}

-
-
-

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 - TSIG (Transaction Signatures), as defined in RFC 2845. -

-
-
-

OPTIONS

-
-
-a algorithm
-
-

- Selects the cryptographic algorithm. The value of - algorithm must be one of RSAMD5 (RSA) or RSASHA1, - DSA, DH (Diffie Hellman), or HMAC-MD5. These values - are case insensitive. -

-

- Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement - algorithm, - and DSA is recommended. For TSIG, HMAC-MD5 is mandatory. -

-

- Note 2: HMAC-MD5 and DH automatically set the -k flag. -

-
-
-b keysize
-

- Specifies the number of bits in the key. The choice of key - size depends on the algorithm used. RSAMD5 / RSASHA1 keys must be - between - 512 and 2048 bits. Diffie Hellman keys must be between - 128 and 4096 bits. DSA keys must be between 512 and 1024 - bits and an exact multiple of 64. HMAC-MD5 keys must be - between 1 and 512 bits. -

-
-n nametype
-

- Specifies the owner type of the key. The value of - nametype must either be ZONE (for a DNSSEC - zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with - a host (KEY)), - USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). - These values are - case insensitive. -

-
-c class
-

- Indicates that the DNS record containing the key should have - the specified class. If not specified, class IN is used. -

-
-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. - The only recognized flag is KSK (Key Signing Key) DNSKEY. -

-
-g generator
-

- If generating a Diffie Hellman key, use this generator. - Allowed values are 2 and 5. If no generator - is specified, a known prime from RFC 2539 will be used - if possible; otherwise the default is 2. -

-
-h
-

- Prints a short summary of the options and arguments to - dnssec-keygen. -

-
-k
-

- Generate KEY records rather than DNSKEY records. -

-
-p protocol
-

- 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. -

-
-r randomdev
-

- Specifies the source of randomness. If the operating - system does not provide a /dev/random - or equivalent device, the default source of randomness - is keyboard input. randomdev - specifies - the name of a character device or file containing random - data to be used instead of the default. The special value - keyboard indicates that keyboard - input should be used. -

-
-s strength
-

- Specifies the strength value of the key. The strength is - a number between 0 and 15, and currently has no defined - purpose in DNSSEC. -

-
-t type
-

- Indicates the use of the key. type must be - one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default - is AUTHCONF. AUTH refers to the ability to authenticate - data, and CONF the ability to encrypt data. -

-
-v level
-

- Sets the debugging level. -

-
-
-
-

GENERATED KEYS

-

- When dnssec-keygen completes - successfully, - it prints a string of the form Knnnn.+aaa+iiiii - to the standard output. This is an identification string for - the key it has generated. -

-
    -
  • nnnn is the key name. -

  • -
  • aaa is the numeric representation - of the - algorithm. -

  • -
  • iiiii is the key identifier (or - footprint). -

  • -
-

dnssec-keygen - creates two files, with names based - on the printed string. Knnnn.+aaa+iiiii.key - contains the public key, and - Knnnn.+aaa+iiiii.private contains the - private - key. -

-

- The .key file contains a DNS KEY record - that - can be inserted into a zone file (directly or with a $INCLUDE - statement). -

-

- The .private file contains - algorithm-specific - fields. For obvious security reasons, this file does not have - general read permission. -

-

- Both .key and .private - files are generated for symmetric encryption algorithms such as - HMAC-MD5, even though the public and private key are equivalent. -

-
-
-

EXAMPLE

-

- To generate a 768-bit DSA key for the domain - example.com, the following command would be - issued: -

-

dnssec-keygen -a DSA -b 768 -n ZONE example.com -

-

- The command would print a string of the form: -

-

Kexample.com.+003+26160 -

-

- In this example, dnssec-keygen creates - the files Kexample.com.+003+26160.key - and - Kexample.com.+003+26160.private. -

-
-
-

SEE ALSO

-

dnssec-signzone(8), - BIND 9 Administrator Reference Manual, - RFC 2535, - RFC 2845, - RFC 2539. -

-
-
-

AUTHOR

-

Internet Systems Consortium -

-
-
- diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.8 b/contrib/bind9/bin/dnssec/dnssec-signzone.8 deleted file mode 100644 index d150c3f..0000000 --- a/contrib/bind9/bin/dnssec/dnssec-signzone.8 +++ /dev/null @@ -1,272 +0,0 @@ -.\" Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") -.\" Copyright (C) 2000-2003 Internet Software Consortium. -.\" -.\" Permission to use, copy, modify, and 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: dnssec-signzone.8,v 1.28.18.17 2007/05/09 03:33:12 marka Exp $ -.\" -.hy 0 -.ad l -.\" Title: dnssec\-signzone -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.71.1 -.\" Date: June 30, 2000 -.\" Manual: BIND9 -.\" Source: BIND9 -.\" -.TH "DNSSEC\-SIGNZONE" "8" "June 30, 2000" "BIND9" "BIND9" -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.SH "NAME" -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\fIend\-time\fR\fR] [\fB\-f\ \fR\fB\fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\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\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-t\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-z\fR] {zonefile} [key...] -.SH "DESCRIPTION" -.PP -\fBdnssec\-signzone\fR -signs a zone. It generates NSEC and RRSIG records and produces a signed version of the zone. The security status of delegations from the signed zone (that is, whether the child zones are secure or not) is determined by the presence or absence of a -\fIkeyset\fR -file for each child zone. -.SH "OPTIONS" -.PP -\-a -.RS 4 -Verify all generated signatures. -.RE -.PP -\-c \fIclass\fR -.RS 4 -Specifies the DNS class of the zone. -.RE -.PP -\-k \fIkey\fR -.RS 4 -Treat specified key as a key signing key ignoring any key flags. This option may be specified multiple times. -.RE -.PP -\-l \fIdomain\fR -.RS 4 -Generate a DLV set in addition to the key (DNSKEY) and DS sets. The domain is appended to the name of the records. -.RE -.PP -\-d \fIdirectory\fR -.RS 4 -Look for -\fIkeyset\fR -files in -\fBdirectory\fR -as the directory -.RE -.PP -\-g -.RS 4 -Generate DS records for child zones from keyset files. Existing DS records will be removed. -.RE -.PP -\-s \fIstart\-time\fR -.RS 4 -Specify the date and time when the generated RRSIG records become valid. This can be either an absolute or relative time. An absolute start time is indicated by a number in YYYYMMDDHHMMSS notation; 20000530144500 denotes 14:45:00 UTC on May 30th, 2000. A relative start time is indicated by +N, which is N seconds from the current time. If no -\fBstart\-time\fR -is specified, the current time minus 1 hour (to allow for clock skew) is used. -.RE -.PP -\-e \fIend\-time\fR -.RS 4 -Specify the date and time when the generated RRSIG records expire. 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 -\fBend\-time\fR -is specified, 30 days from the start time is used as a default. -.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. -.RE -.PP -\-h -.RS 4 -Prints a short summary of the options and arguments to -\fBdnssec\-signzone\fR. -.RE -.PP -\-i \fIinterval\fR -.RS 4 -When a previously\-signed zone is passed as input, records may be resigned. The -\fBinterval\fR -option specifies the cycle interval as an offset from the current time (in seconds). If a RRSIG record expires after the cycle interval, it is retained. Otherwise, it is considered to be expiring soon, and it will be replaced. -.sp -The default cycle interval is one quarter of the difference between the signature end and start times. So if neither -\fBend\-time\fR -or -\fBstart\-time\fR -are specified, -\fBdnssec\-signzone\fR -generates signatures that are valid for 30 days, with a cycle interval of 7.5 days. Therefore, if any existing RRSIG records are due to expire in less than 7.5 days, they would be replaced. -.RE -.PP -\-I \fIinput\-format\fR -.RS 4 -The format of the input zone file. Possible formats are -\fB"text"\fR -(default) and -\fB"raw"\fR. This option is primarily intended to be used for dynamic signed zones so that the dumped zone file in a non\-text format containing updates can be signed directly. The use of this option does not make much sense for non\-dynamic zones. -.RE -.PP -\-j \fIjitter\fR -.RS 4 -When signing a zone with a fixed signature lifetime, all RRSIG records issued at the time of signing expires simultaneously. If the zone is incrementally signed, i.e. a previously\-signed zone is passed as input to the signer, all expired signatures have to be regenerated at about the same time. The -\fBjitter\fR -option specifies a jitter window that will be used to randomize the signature expire time, thus spreading incremental signature regeneration over time. -.sp -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 -\-n \fIncpus\fR -.RS 4 -Specifies the number of threads to use. By default, one thread is started for each detected CPU. -.RE -.PP -\-N \fIsoa\-serial\-format\fR -.RS 4 -The SOA serial number format of the signed zone. Possible formats are -\fB"keep"\fR -(default), -\fB"increment"\fR -and -\fB"unixtime"\fR. -.RS 4 -.PP -\fB"keep"\fR -.RS 4 -Do not modify the SOA serial number. -.RE -.PP -\fB"increment"\fR -.RS 4 -Increment the SOA serial number using RFC 1982 arithmetics. -.RE -.PP -\fB"unixtime"\fR -.RS 4 -Set the SOA serial number to the number of seconds since epoch. -.RE -.RE -.RE -.PP -\-o \fIorigin\fR -.RS 4 -The zone origin. If not specified, the name of the zone file is assumed to be the origin. -.RE -.PP -\-O \fIoutput\-format\fR -.RS 4 -The format of the output file containing the signed zone. Possible formats are -\fB"text"\fR -(default) and -\fB"raw"\fR. -.RE -.PP -\-p -.RS 4 -Use pseudo\-random data when signing the zone. This is faster, but less secure, than using real random data. This option may be useful when signing large zones or when the entropy source is limited. -.RE -.PP -\-r \fIrandomdev\fR -.RS 4 -Specifies the source of randomness. If the operating system does not provide a -\fI/dev/random\fR -or equivalent device, the default source of randomness is keyboard input. -\fIrandomdev\fR -specifies the name of a character device or file containing random data to be used instead of the default. The special value -\fIkeyboard\fR -indicates that keyboard input should be used. -.RE -.PP -\-t -.RS 4 -Print statistics at completion. -.RE -.PP -\-v \fIlevel\fR -.RS 4 -Sets the debugging level. -.RE -.PP -\-z -.RS 4 -Ignore KSK flag on key when determining what to sign. -.RE -.PP -zonefile -.RS 4 -The file containing the zone to be signed. -.RE -.PP -key -.RS 4 -Specify which keys should be used to sign the zone. If no keys are specified, then the zone will be examined for DNSKEY records at the zone apex. If these are found and there are matching private keys, in the current directory, then these will be used for signing. -.RE -.SH "EXAMPLE" -.PP -The following command signs the -\fBexample.com\fR -zone with the DSA key generated by -\fBdnssec\-keygen\fR -(Kexample.com.+003+17247). The zone's keys must be in the master file (\fIdb.example.com\fR). This invocation looks for -\fIkeyset\fR -files, in the current directory, so that DS records can be generated from them (\fB\-g\fR). -.sp -.RS 4 -.nf -% dnssec\-signzone \-g \-o example.com db.example.com \\ -Kexample.com.+003+17247 -db.example.com.signed -% -.fi -.RE -.PP -In the above example, -\fBdnssec\-signzone\fR -creates the file -\fIdb.example.com.signed\fR. This file should be referenced in a zone statement in a -\fInamed.conf\fR -file. -.PP -This example re\-signs a previously signed zone with default parameters. The private keys are assumed to be in the current directory. -.sp -.RS 4 -.nf -% cp db.example.com.signed db.example.com -% dnssec\-signzone \-o example.com db.example.com -db.example.com.signed -% -.fi -.RE -.SH "SEE ALSO" -.PP -\fBdnssec\-keygen\fR(8), -BIND 9 Administrator Reference Manual, -RFC 2535. -.SH "AUTHOR" -.PP -Internet Systems Consortium -.SH "COPYRIGHT" -Copyright \(co 2004\-2007 Internet Systems Consortium, Inc. ("ISC") -.br -Copyright \(co 2000\-2003 Internet Software Consortium. -.br diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.c b/contrib/bind9/bin/dnssec/dnssec-signzone.c deleted file mode 100644 index 46cd4a7..0000000 --- a/contrib/bind9/bin/dnssec/dnssec-signzone.c +++ /dev/null @@ -1,2333 +0,0 @@ -/* - * Portions Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Portions Copyright (C) 1999-2003 Internet Software Consortium. - * Portions Copyright (C) 1995-2000 by Network Associates, Inc. - * - * 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 AND NETWORK ASSOCIATES 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: dnssec-signzone.c,v 1.177.18.24 2007/08/28 07:20:00 tbox Exp $ */ - -/*! \file */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "dnssectool.h" - -const char *program = "dnssec-signzone"; -int verbose; - -#define BUFSIZE 2048 -#define MAXDSKEYS 8 - -typedef struct signer_key_struct signer_key_t; - -struct signer_key_struct { - dst_key_t *key; - isc_boolean_t issigningkey; - isc_boolean_t isdsk; - isc_boolean_t isksk; - unsigned int position; - ISC_LINK(signer_key_t) link; -}; - -#define SIGNER_EVENTCLASS ISC_EVENTCLASS(0x4453) -#define SIGNER_EVENT_WRITE (SIGNER_EVENTCLASS + 0) -#define SIGNER_EVENT_WORK (SIGNER_EVENTCLASS + 1) - -#define SOA_SERIAL_KEEP 0 -#define SOA_SERIAL_INCREMENT 1 -#define SOA_SERIAL_UNIXTIME 2 - -typedef struct signer_event sevent_t; -struct signer_event { - ISC_EVENT_COMMON(sevent_t); - dns_fixedname_t *fname; - dns_dbnode_t *node; -}; - -static ISC_LIST(signer_key_t) keylist; -static unsigned int keycount = 0; -static isc_stdtime_t starttime = 0, endtime = 0, now; -static int cycle = -1; -static int jitter = 0; -static isc_boolean_t tryverify = ISC_FALSE; -static isc_boolean_t printstats = ISC_FALSE; -static isc_mem_t *mctx = NULL; -static isc_entropy_t *ectx = NULL; -static dns_ttl_t zonettl; -static FILE *fp; -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 unsigned int nsigned = 0, nretained = 0, ndropped = 0; -static unsigned int nverified = 0, nverifyfailed = 0; -static const char *directory; -static isc_mutex_t namelock, statslock; -static isc_taskmgr_t *taskmgr = NULL; -static dns_db_t *gdb; /* The database */ -static dns_dbversion_t *gversion; /* The database version */ -static dns_dbiterator_t *gdbiter; /* The database iterator */ -static dns_rdataclass_t gclass; /* The class */ -static dns_name_t *gorigin; /* The database origin */ -static isc_task_t *master = NULL; -static unsigned int ntasks = 0; -static isc_boolean_t shuttingdown = ISC_FALSE, finished = ISC_FALSE; -static unsigned int assigned = 0, completed = 0; -static isc_boolean_t nokeys = ISC_FALSE; -static isc_boolean_t removefile = ISC_FALSE; -static isc_boolean_t generateds = ISC_FALSE; -static isc_boolean_t ignoreksk = ISC_FALSE; -static dns_name_t *dlv = NULL; -static dns_fixedname_t dlv_fixed; -static dns_master_style_t *dsstyle = NULL; -static unsigned int serialformat = SOA_SERIAL_KEEP; - -#define INCSTAT(counter) \ - if (printstats) { \ - LOCK(&statslock); \ - counter++; \ - UNLOCK(&statslock); \ - } - -static void -sign(isc_task_t *task, isc_event_t *event); - - -static inline 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 void -dumpnode(dns_name_t *name, dns_dbnode_t *node) { - isc_result_t result; - - if (outputformat != dns_masterformat_text) - return; - result = dns_master_dumpnodetostream(mctx, gdb, gversion, node, name, - masterstyle, fp); - check_result(result, "dns_master_dumpnodetostream"); -} - -static signer_key_t * -newkeystruct(dst_key_t *dstkey, isc_boolean_t signwithkey) { - signer_key_t *key; - - key = isc_mem_get(mctx, sizeof(signer_key_t)); - if (key == NULL) - fatal("out of memory"); - key->key = dstkey; - if ((dst_key_flags(dstkey) & DNS_KEYFLAG_KSK) != 0) { - key->issigningkey = signwithkey; - key->isksk = ISC_TRUE; - key->isdsk = ISC_FALSE; - } else { - key->issigningkey = signwithkey; - key->isksk = ISC_FALSE; - key->isdsk = ISC_TRUE; - } - key->position = keycount++; - ISC_LINK_INIT(key, link); - return (key); -} - -static void -signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdata_t *rdata, - dst_key_t *key, isc_buffer_t *b) -{ - isc_result_t result; - isc_stdtime_t jendtime; - - jendtime = (jitter != 0) ? isc_random_jitter(endtime, jitter) : endtime; - result = dns_dnssec_sign(name, rdataset, key, &starttime, &jendtime, - mctx, b, rdata); - isc_entropy_stopcallbacksources(ectx); - if (result != ISC_R_SUCCESS) { - char keystr[KEY_FORMATSIZE]; - key_format(key, keystr, sizeof(keystr)); - fatal("dnskey '%s' failed to sign data: %s", - keystr, isc_result_totext(result)); - } - INCSTAT(nsigned); - - if (tryverify) { - result = dns_dnssec_verify(name, rdataset, key, - ISC_TRUE, mctx, rdata); - if (result == ISC_R_SUCCESS) { - vbprintf(3, "\tsignature verified\n"); - INCSTAT(nverified); - } else { - vbprintf(3, "\tsignature failed to verify\n"); - INCSTAT(nverifyfailed); - } - } -} - -static inline isc_boolean_t -issigningkey(signer_key_t *key) { - return (key->issigningkey); -} - -static inline isc_boolean_t -iszonekey(signer_key_t *key) { - return (ISC_TF(dns_name_equal(dst_key_name(key->key), gorigin) && - dst_key_iszonekey(key->key))); -} - -/*% - * Finds the key that generated a RRSIG, if possible. First look at the keys - * that we've loaded already, and then see if there's a key on disk. - */ -static signer_key_t * -keythatsigned(dns_rdata_rrsig_t *rrsig) { - isc_result_t result; - dst_key_t *pubkey = NULL, *privkey = NULL; - signer_key_t *key; - - key = ISC_LIST_HEAD(keylist); - while (key != NULL) { - if (rrsig->keyid == dst_key_id(key->key) && - rrsig->algorithm == dst_key_alg(key->key) && - dns_name_equal(&rrsig->signer, dst_key_name(key->key))) - return key; - key = ISC_LIST_NEXT(key, link); - } - - result = dst_key_fromfile(&rrsig->signer, rrsig->keyid, - rrsig->algorithm, DST_TYPE_PUBLIC, - NULL, mctx, &pubkey); - if (result != ISC_R_SUCCESS) - return (NULL); - - result = dst_key_fromfile(&rrsig->signer, rrsig->keyid, - rrsig->algorithm, - DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, - NULL, mctx, &privkey); - if (result == ISC_R_SUCCESS) { - dst_key_free(&pubkey); - key = newkeystruct(privkey, ISC_FALSE); - } else - key = newkeystruct(pubkey, ISC_FALSE); - ISC_LIST_APPEND(keylist, key, link); - return (key); -} - -/*% - * Check to see if we expect to find a key at this name. If we see a RRSIG - * and can't find the signing key that we expect to find, we drop the rrsig. - * I'm not sure if this is completely correct, but it seems to work. - */ -static isc_boolean_t -expecttofindkey(dns_name_t *name) { - unsigned int options = DNS_DBFIND_NOWILD; - dns_fixedname_t fname; - isc_result_t result; - char namestr[DNS_NAME_FORMATSIZE]; - - dns_fixedname_init(&fname); - result = dns_db_find(gdb, name, gversion, dns_rdatatype_dnskey, options, - 0, NULL, dns_fixedname_name(&fname), NULL, NULL); - switch (result) { - case ISC_R_SUCCESS: - case DNS_R_NXDOMAIN: - case DNS_R_NXRRSET: - return (ISC_TRUE); - case DNS_R_DELEGATION: - case DNS_R_CNAME: - case DNS_R_DNAME: - return (ISC_FALSE); - } - dns_name_format(name, namestr, sizeof(namestr)); - fatal("failure looking for '%s DNSKEY' in database: %s", - namestr, isc_result_totext(result)); - return (ISC_FALSE); /* removes a warning */ -} - -static inline isc_boolean_t -setverifies(dns_name_t *name, dns_rdataset_t *set, signer_key_t *key, - dns_rdata_t *rrsig) -{ - isc_result_t result; - result = dns_dnssec_verify(name, set, key->key, ISC_FALSE, mctx, rrsig); - if (result == ISC_R_SUCCESS) { - INCSTAT(nverified); - return (ISC_TRUE); - } else { - INCSTAT(nverifyfailed); - return (ISC_FALSE); - } -} - -/*% - * Signs a set. Goes through contortions to decide if each RRSIG should - * be dropped or retained, and then determines if any new SIGs need to - * be generated. - */ -static void -signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name, - dns_rdataset_t *set) -{ - dns_rdataset_t sigset; - dns_rdata_t sigrdata = DNS_RDATA_INIT; - dns_rdata_rrsig_t rrsig; - signer_key_t *key; - isc_result_t result; - isc_boolean_t nosigs = ISC_FALSE; - isc_boolean_t *wassignedby, *nowsignedby; - int arraysize; - dns_difftuple_t *tuple; - dns_ttl_t ttl; - int i; - char namestr[DNS_NAME_FORMATSIZE]; - char typestr[TYPE_FORMATSIZE]; - char sigstr[SIG_FORMATSIZE]; - - dns_name_format(name, namestr, sizeof(namestr)); - type_format(set->type, typestr, sizeof(typestr)); - - ttl = ISC_MIN(set->ttl, endtime - starttime); - - dns_rdataset_init(&sigset); - result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_rrsig, - set->type, 0, &sigset, NULL); - if (result == ISC_R_NOTFOUND) { - result = ISC_R_SUCCESS; - nosigs = ISC_TRUE; - } - if (result != ISC_R_SUCCESS) - fatal("failed while looking for '%s RRSIG %s': %s", - namestr, typestr, isc_result_totext(result)); - - vbprintf(1, "%s/%s:\n", namestr, typestr); - - arraysize = keycount; - if (!nosigs) - arraysize += dns_rdataset_count(&sigset); - wassignedby = isc_mem_get(mctx, arraysize * sizeof(isc_boolean_t)); - nowsignedby = isc_mem_get(mctx, arraysize * sizeof(isc_boolean_t)); - if (wassignedby == NULL || nowsignedby == NULL) - fatal("out of memory"); - - for (i = 0; i < arraysize; i++) - wassignedby[i] = nowsignedby[i] = ISC_FALSE; - - if (nosigs) - result = ISC_R_NOMORE; - else - result = dns_rdataset_first(&sigset); - - while (result == ISC_R_SUCCESS) { - isc_boolean_t expired, future; - isc_boolean_t keep = ISC_FALSE, resign = ISC_FALSE; - - dns_rdataset_current(&sigset, &sigrdata); - - result = dns_rdata_tostruct(&sigrdata, &rrsig, NULL); - check_result(result, "dns_rdata_tostruct"); - - future = isc_serial_lt(now, rrsig.timesigned); - - key = keythatsigned(&rrsig); - sig_format(&rrsig, sigstr, sizeof(sigstr)); - if (key != NULL && issigningkey(key)) - expired = isc_serial_gt(now + cycle, rrsig.timeexpire); - else - expired = isc_serial_gt(now, rrsig.timeexpire); - - if (isc_serial_gt(rrsig.timesigned, rrsig.timeexpire)) { - /* rrsig is dropped and not replaced */ - vbprintf(2, "\trrsig by %s dropped - " - "invalid validity period\n", - sigstr); - } else if (key == NULL && !future && - expecttofindkey(&rrsig.signer)) - { - /* rrsig is dropped and not replaced */ - vbprintf(2, "\trrsig by %s dropped - " - "private dnskey not found\n", - sigstr); - } else if (key == NULL || future) { - vbprintf(2, "\trrsig by %s %s - dnskey not found\n", - expired ? "retained" : "dropped", sigstr); - if (!expired) - keep = ISC_TRUE; - } else if (issigningkey(key)) { - if (!expired && setverifies(name, set, key, &sigrdata)) - { - vbprintf(2, "\trrsig by %s retained\n", sigstr); - keep = ISC_TRUE; - wassignedby[key->position] = ISC_TRUE; - nowsignedby[key->position] = ISC_TRUE; - } else { - vbprintf(2, "\trrsig by %s dropped - %s\n", - sigstr, - expired ? "expired" : - "failed to verify"); - wassignedby[key->position] = ISC_TRUE; - resign = ISC_TRUE; - } - } else if (iszonekey(key)) { - if (!expired && setverifies(name, set, key, &sigrdata)) - { - vbprintf(2, "\trrsig by %s retained\n", sigstr); - keep = ISC_TRUE; - wassignedby[key->position] = ISC_TRUE; - nowsignedby[key->position] = ISC_TRUE; - } else { - vbprintf(2, "\trrsig by %s dropped - %s\n", - sigstr, - expired ? "expired" : - "failed to verify"); - wassignedby[key->position] = ISC_TRUE; - } - } else if (!expired) { - vbprintf(2, "\trrsig by %s retained\n", sigstr); - keep = ISC_TRUE; - } else { - vbprintf(2, "\trrsig by %s expired\n", sigstr); - } - - if (keep) { - nowsignedby[key->position] = ISC_TRUE; - INCSTAT(nretained); - if (sigset.ttl != ttl) { - vbprintf(2, "\tfixing ttl %s\n", sigstr); - tuple = NULL; - result = dns_difftuple_create(mctx, - DNS_DIFFOP_DEL, - name, sigset.ttl, - &sigrdata, - &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(del, &tuple); - result = dns_difftuple_create(mctx, - DNS_DIFFOP_ADD, - name, ttl, - &sigrdata, - &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(add, &tuple); - } - } else { - tuple = NULL; - result = dns_difftuple_create(mctx, DNS_DIFFOP_DEL, - name, sigset.ttl, - &sigrdata, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(del, &tuple); - INCSTAT(ndropped); - } - - if (resign) { - isc_buffer_t b; - dns_rdata_t trdata = DNS_RDATA_INIT; - unsigned char array[BUFSIZE]; - char keystr[KEY_FORMATSIZE]; - - INSIST(!keep); - - key_format(key->key, keystr, sizeof(keystr)); - vbprintf(1, "\tresigning with dnskey %s\n", keystr); - isc_buffer_init(&b, array, sizeof(array)); - signwithkey(name, set, &trdata, key->key, &b); - nowsignedby[key->position] = ISC_TRUE; - tuple = NULL; - result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, - name, ttl, &trdata, - &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(add, &tuple); - } - - dns_rdata_reset(&sigrdata); - dns_rdata_freestruct(&rrsig); - result = dns_rdataset_next(&sigset); - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - check_result(result, "dns_rdataset_first/next"); - if (dns_rdataset_isassociated(&sigset)) - dns_rdataset_disassociate(&sigset); - - for (key = ISC_LIST_HEAD(keylist); - key != NULL; - key = ISC_LIST_NEXT(key, link)) - { - isc_buffer_t b; - dns_rdata_t trdata; - unsigned char array[BUFSIZE]; - char keystr[KEY_FORMATSIZE]; - - if (nowsignedby[key->position]) - continue; - - if (!key->issigningkey) - continue; - if (!(ignoreksk || key->isdsk || - (key->isksk && - set->type == dns_rdatatype_dnskey && - dns_name_equal(name, gorigin)))) - continue; - - key_format(key->key, keystr, sizeof(keystr)); - vbprintf(1, "\tsigning with dnskey %s\n", keystr); - dns_rdata_init(&trdata); - isc_buffer_init(&b, array, sizeof(array)); - signwithkey(name, set, &trdata, key->key, &b); - tuple = NULL; - result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, - ttl, &trdata, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(add, &tuple); - } - - isc_mem_put(mctx, wassignedby, arraysize * sizeof(isc_boolean_t)); - isc_mem_put(mctx, nowsignedby, arraysize * sizeof(isc_boolean_t)); -} - -static void -opendb(const char *prefix, dns_name_t *name, dns_rdataclass_t rdclass, - dns_db_t **dbp) -{ - char filename[256]; - isc_buffer_t b; - isc_result_t result; - - isc_buffer_init(&b, filename, sizeof(filename)); - if (directory != NULL) { - isc_buffer_putstr(&b, directory); - if (directory[strlen(directory) - 1] != '/') - isc_buffer_putstr(&b, "/"); - } - isc_buffer_putstr(&b, prefix); - result = dns_name_tofilenametext(name, ISC_FALSE, &b); - check_result(result, "dns_name_tofilenametext()"); - if (isc_buffer_availablelength(&b) == 0) { - char namestr[DNS_NAME_FORMATSIZE]; - dns_name_format(name, namestr, sizeof(namestr)); - fatal("name '%s' is too long", namestr); - } - isc_buffer_putuint8(&b, 0); - - result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, - rdclass, 0, NULL, dbp); - check_result(result, "dns_db_create()"); - - result = dns_db_load(*dbp, filename); - if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) - dns_db_detach(dbp); -} - -/*% - * Loads the key set for a child zone, if there is one, and builds DS records. - */ -static isc_result_t -loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) { - dns_db_t *db = NULL; - dns_dbversion_t *ver = NULL; - dns_dbnode_t *node = NULL; - isc_result_t result; - dns_rdataset_t keyset; - dns_rdata_t key, ds; - unsigned char dsbuf[DNS_DS_BUFFERSIZE]; - dns_diff_t diff; - dns_difftuple_t *tuple = NULL; - - opendb("keyset-", name, gclass, &db); - if (db == NULL) - return (ISC_R_NOTFOUND); - - result = dns_db_findnode(db, name, ISC_FALSE, &node); - if (result != ISC_R_SUCCESS) { - dns_db_detach(&db); - return (DNS_R_BADDB); - } - dns_rdataset_init(&keyset); - result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, 0, - &keyset, NULL); - if (result != ISC_R_SUCCESS) { - dns_db_detachnode(db, &node); - dns_db_detach(&db); - return (result); - } - - vbprintf(2, "found DNSKEY records\n"); - - result = dns_db_newversion(db, &ver); - check_result(result, "dns_db_newversion"); - - dns_diff_init(mctx, &diff); - - for (result = dns_rdataset_first(&keyset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&keyset)) - { - dns_rdata_init(&key); - dns_rdata_init(&ds); - dns_rdataset_current(&keyset, &key); - result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA1, - dsbuf, &ds); - check_result(result, "dns_ds_buildrdata"); - - result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, - ttl, &ds, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(&diff, &tuple); - - dns_rdata_reset(&ds); - result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA256, - dsbuf, &ds); - check_result(result, "dns_ds_buildrdata"); - - result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, - ttl, &ds, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(&diff, &tuple); - } - result = dns_diff_apply(&diff, db, ver); - check_result(result, "dns_diff_apply"); - dns_diff_clear(&diff); - - dns_db_closeversion(db, &ver, ISC_TRUE); - - result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ds, 0, 0, - dsset, NULL); - check_result(result, "dns_db_findrdataset"); - - dns_rdataset_disassociate(&keyset); - dns_db_detachnode(db, &node); - dns_db_detach(&db); - return (result); -} - -static isc_boolean_t -nsec_setbit(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdatatype_t type, - unsigned int val) -{ - isc_result_t result; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_nsec_t nsec; - unsigned int newlen; - unsigned char bitmap[8192 + 512]; - unsigned char nsecdata[8192 + 512 + DNS_NAME_MAXWIRE]; - isc_boolean_t answer = ISC_FALSE; - unsigned int i, len, window; - int octet; - - result = dns_rdataset_first(rdataset); - check_result(result, "dns_rdataset_first()"); - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &nsec, NULL); - check_result(result, "dns_rdata_tostruct"); - - INSIST(nsec.len <= sizeof(bitmap)); - - newlen = 0; - - memset(bitmap, 0, sizeof(bitmap)); - for (i = 0; i < nsec.len; i += len) { - INSIST(i + 2 <= nsec.len); - window = nsec.typebits[i]; - len = nsec.typebits[i+1]; - i += 2; - INSIST(len > 0 && len <= 32); - INSIST(i + len <= nsec.len); - memmove(&bitmap[window * 32 + 512], &nsec.typebits[i], len); - } - set_bit(bitmap + 512, type, val); - for (window = 0; window < 256; window++) { - for (octet = 31; octet >= 0; octet--) - if (bitmap[window * 32 + 512 + octet] != 0) - break; - if (octet < 0) - continue; - bitmap[newlen] = window; - bitmap[newlen + 1] = octet + 1; - newlen += 2; - /* - * Overlapping move. - */ - memmove(&bitmap[newlen], &bitmap[window * 32 + 512], octet + 1); - newlen += octet + 1; - } - if (newlen != nsec.len || - memcmp(nsec.typebits, bitmap, newlen) != 0) { - dns_rdata_t newrdata = DNS_RDATA_INIT; - isc_buffer_t b; - dns_diff_t diff; - dns_difftuple_t *tuple = NULL; - - dns_diff_init(mctx, &diff); - result = dns_difftuple_create(mctx, DNS_DIFFOP_DEL, name, - rdataset->ttl, &rdata, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(&diff, &tuple); - - nsec.typebits = bitmap; - nsec.len = newlen; - isc_buffer_init(&b, nsecdata, sizeof(nsecdata)); - result = dns_rdata_fromstruct(&newrdata, rdata.rdclass, - dns_rdatatype_nsec, &nsec, - &b); - check_result(result, "dns_rdata_fromstruct"); - - result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, - name, rdataset->ttl, - &newrdata, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(&diff, &tuple); - result = dns_diff_apply(&diff, gdb, gversion); - check_result(result, "dns_difftuple_apply"); - dns_diff_clear(&diff); - answer = ISC_TRUE; - } - dns_rdata_freestruct(&nsec); - return (answer); -} - -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)); -} - -/*% - * Signs all records at a name. This mostly just signs each set individually, - * but also adds the RRSIG bit to any NSECs generated earlier, deals with - * parent/child KEY signatures, and handles other exceptional cases. - */ -static void -signname(dns_dbnode_t *node, dns_name_t *name) { - isc_result_t result; - dns_rdataset_t rdataset; - dns_rdatasetiter_t *rdsiter; - isc_boolean_t isdelegation = ISC_FALSE; - isc_boolean_t hasds = ISC_FALSE; - isc_boolean_t changed = ISC_FALSE; - dns_diff_t del, add; - char namestr[DNS_NAME_FORMATSIZE]; - isc_uint32_t nsttl = 0; - - dns_name_format(name, namestr, sizeof(namestr)); - - /* - * Determine if this is a delegation point. - */ - if (delegation(name, node, &nsttl)) - isdelegation = ISC_TRUE; - - /* - * If this is a delegation point, look for a DS set. - */ - if (isdelegation) { - dns_rdataset_t dsset; - dns_rdataset_t sigdsset; - - dns_rdataset_init(&dsset); - dns_rdataset_init(&sigdsset); - result = dns_db_findrdataset(gdb, node, gversion, - dns_rdatatype_ds, - 0, 0, &dsset, &sigdsset); - if (result == ISC_R_SUCCESS) { - dns_rdataset_disassociate(&dsset); - if (generateds) { - result = dns_db_deleterdataset(gdb, node, - gversion, - dns_rdatatype_ds, - 0); - check_result(result, "dns_db_deleterdataset"); - } else - hasds = ISC_TRUE; - } - if (generateds) { - result = loadds(name, nsttl, &dsset); - if (result == ISC_R_SUCCESS) { - result = dns_db_addrdataset(gdb, node, - gversion, 0, - &dsset, 0, NULL); - check_result(result, "dns_db_addrdataset"); - hasds = ISC_TRUE; - dns_rdataset_disassociate(&dsset); - if (dns_rdataset_isassociated(&sigdsset)) - dns_rdataset_disassociate(&sigdsset); - } else if (dns_rdataset_isassociated(&sigdsset)) { - result = dns_db_deleterdataset(gdb, node, - gversion, - dns_rdatatype_rrsig, - dns_rdatatype_ds); - check_result(result, "dns_db_deleterdataset"); - dns_rdataset_disassociate(&sigdsset); - } - } else if (dns_rdataset_isassociated(&sigdsset)) - dns_rdataset_disassociate(&sigdsset); - } - - /* - * Make sure that NSEC bits are appropriately set. - */ - dns_rdataset_init(&rdataset); - RUNTIME_CHECK(dns_db_findrdataset(gdb, node, gversion, - dns_rdatatype_nsec, 0, 0, &rdataset, - NULL) == ISC_R_SUCCESS); - if (!nokeys) - changed = nsec_setbit(name, &rdataset, dns_rdatatype_rrsig, 1); - if (changed) { - dns_rdataset_disassociate(&rdataset); - RUNTIME_CHECK(dns_db_findrdataset(gdb, node, gversion, - dns_rdatatype_nsec, 0, 0, - &rdataset, - NULL) == ISC_R_SUCCESS); - } - if (hasds) - (void)nsec_setbit(name, &rdataset, dns_rdatatype_ds, 1); - else - (void)nsec_setbit(name, &rdataset, dns_rdatatype_ds, 0); - dns_rdataset_disassociate(&rdataset); - - /* - * Now iterate through the rdatasets. - */ - dns_diff_init(mctx, &del); - dns_diff_init(mctx, &add); - rdsiter = NULL; - result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets()"); - result = dns_rdatasetiter_first(rdsiter); - while (result == ISC_R_SUCCESS) { - dns_rdatasetiter_current(rdsiter, &rdataset); - - /* If this is a RRSIG set, skip it. */ - if (rdataset.type == dns_rdatatype_rrsig) - goto skip; - - /* - * If this name is a delegation point, skip all records - * except NSEC and DS sets. Otherwise check that there - * isn't a DS record. - */ - if (isdelegation) { - if (rdataset.type != dns_rdatatype_nsec && - rdataset.type != dns_rdatatype_ds) - goto skip; - } else if (rdataset.type == dns_rdatatype_ds) { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(name, namebuf, sizeof(namebuf)); - fatal("'%s': found DS RRset without NS RRset\n", - namebuf); - } - - signset(&del, &add, node, name, &rdataset); - - skip: - dns_rdataset_disassociate(&rdataset); - result = dns_rdatasetiter_next(rdsiter); - } - if (result != ISC_R_NOMORE) - fatal("rdataset iteration for name '%s' failed: %s", - namestr, isc_result_totext(result)); - - dns_rdatasetiter_destroy(&rdsiter); - - result = dns_diff_applysilently(&del, gdb, gversion); - if (result != ISC_R_SUCCESS) - fatal("failed to delete SIGs at node '%s': %s", - namestr, isc_result_totext(result)); - - result = dns_diff_applysilently(&add, gdb, gversion); - if (result != ISC_R_SUCCESS) - fatal("failed to add SIGs at node '%s': %s", - namestr, isc_result_totext(result)); - - dns_diff_clear(&del); - dns_diff_clear(&add); -} - -static inline isc_boolean_t -active_node(dns_dbnode_t *node) { - dns_rdatasetiter_t *rdsiter = NULL; - dns_rdatasetiter_t *rdsiter2 = NULL; - isc_boolean_t active = ISC_FALSE; - isc_result_t result; - dns_rdataset_t rdataset; - dns_rdatatype_t type; - dns_rdatatype_t covers; - isc_boolean_t found; - - dns_rdataset_init(&rdataset); - result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets()"); - result = dns_rdatasetiter_first(rdsiter); - while (result == ISC_R_SUCCESS) { - dns_rdatasetiter_current(rdsiter, &rdataset); - if (rdataset.type != dns_rdatatype_nsec && - rdataset.type != dns_rdatatype_rrsig) - active = ISC_TRUE; - dns_rdataset_disassociate(&rdataset); - if (!active) - result = dns_rdatasetiter_next(rdsiter); - else - result = ISC_R_NOMORE; - } - if (result != ISC_R_NOMORE) - fatal("rdataset iteration failed: %s", - isc_result_totext(result)); - - if (!active) { - /*% - * The node is empty of everything but NSEC / RRSIG records. - */ - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - dns_rdatasetiter_current(rdsiter, &rdataset); - result = dns_db_deleterdataset(gdb, node, gversion, - rdataset.type, - rdataset.covers); - check_result(result, "dns_db_deleterdataset()"); - dns_rdataset_disassociate(&rdataset); - } - if (result != ISC_R_NOMORE) - fatal("rdataset iteration failed: %s", - isc_result_totext(result)); - } else { - /* - * Delete RRSIGs for types that no longer exist. - */ - result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter2); - 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, &rdataset); - type = rdataset.type; - covers = rdataset.covers; - dns_rdataset_disassociate(&rdataset); - if (type != dns_rdatatype_rrsig) - continue; - found = ISC_FALSE; - for (result = dns_rdatasetiter_first(rdsiter2); - !found && result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter2)) { - dns_rdatasetiter_current(rdsiter2, &rdataset); - if (rdataset.type == covers) - found = ISC_TRUE; - dns_rdataset_disassociate(&rdataset); - } - if (!found) { - if (result != ISC_R_NOMORE) - fatal("rdataset iteration failed: %s", - isc_result_totext(result)); - result = dns_db_deleterdataset(gdb, node, - gversion, type, - covers); - check_result(result, - "dns_db_deleterdataset(rrsig)"); - } else if (result != ISC_R_NOMORE && - result != ISC_R_SUCCESS) - fatal("rdataset iteration failed: %s", - isc_result_totext(result)); - } - if (result != ISC_R_NOMORE) - fatal("rdataset iteration failed: %s", - isc_result_totext(result)); - dns_rdatasetiter_destroy(&rdsiter2); - } - dns_rdatasetiter_destroy(&rdsiter); - - return (active); -} - -/*% - * Extracts the TTL from the SOA. - */ -static dns_ttl_t -soattl(void) { - dns_rdataset_t soaset; - dns_fixedname_t fname; - dns_name_t *name; - isc_result_t result; - dns_ttl_t ttl; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_soa_t soa; - - dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); - dns_rdataset_init(&soaset); - result = dns_db_find(gdb, gorigin, gversion, dns_rdatatype_soa, - 0, 0, NULL, name, &soaset, NULL); - if (result != ISC_R_SUCCESS) - fatal("failed to find an SOA at the zone apex: %s", - isc_result_totext(result)); - - result = dns_rdataset_first(&soaset); - check_result(result, "dns_rdataset_first"); - dns_rdataset_current(&soaset, &rdata); - result = dns_rdata_tostruct(&rdata, &soa, NULL); - check_result(result, "dns_rdata_tostruct"); - ttl = soa.minimum; - dns_rdataset_disassociate(&soaset); - return (ttl); -} - -/*% - * Increment (or set if nonzero) the SOA serial - */ -static isc_result_t -setsoaserial(isc_uint32_t serial) { - isc_result_t result; - dns_dbnode_t *node = NULL; - dns_rdataset_t rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_uint32_t old_serial, new_serial; - - result = dns_db_getoriginnode(gdb, &node); - if (result != ISC_R_SUCCESS) - return result; - - dns_rdataset_init(&rdataset); - - result = dns_db_findrdataset(gdb, node, gversion, - dns_rdatatype_soa, 0, - 0, &rdataset, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_rdataset_first(&rdataset); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - dns_rdataset_current(&rdataset, &rdata); - - old_serial = dns_soa_getserial(&rdata); - - if (serial) { - /* Set SOA serial to the value provided. */ - new_serial = serial; - } else { - /* Increment SOA serial using RFC 1982 arithmetics */ - new_serial = (old_serial + 1) & 0xFFFFFFFF; - if (new_serial == 0) - new_serial = 1; - } - - /* If the new serial is not likely to cause a zone transfer - * (a/ixfr) from servers having the old serial, warn the user. - * - * RFC1982 section 7 defines the maximum increment to be - * (2^(32-1))-1. Using u_int32_t arithmetic, we can do a single - * comparison. (5 - 6 == (2^32)-1, not negative-one) - */ - if (new_serial == old_serial || - (new_serial - old_serial) > 0x7fffffffU) - fprintf(stderr, "%s: warning: Serial number not advanced, " - "zone may not transfer\n", program); - - dns_soa_setserial(new_serial, &rdata); - - result = dns_db_deleterdataset(gdb, node, gversion, - dns_rdatatype_soa, 0); - check_result(result, "dns_db_deleterdataset"); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = dns_db_addrdataset(gdb, node, gversion, - 0, &rdataset, 0, NULL); - check_result(result, "dns_db_addrdataset"); - if (result != ISC_R_SUCCESS) - goto cleanup; - -cleanup: - dns_rdataset_disassociate(&rdataset); - if (node != NULL) - dns_db_detachnode(gdb, &node); - dns_rdata_reset(&rdata); - - return (result); -} - -/*% - * Delete any RRSIG records at a node. - */ -static void -cleannode(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node) { - dns_rdatasetiter_t *rdsiter = NULL; - dns_rdataset_t set; - isc_result_t result, dresult; - - if (outputformat != dns_masterformat_text) - return; - - dns_rdataset_init(&set); - result = dns_db_allrdatasets(db, node, version, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets"); - result = dns_rdatasetiter_first(rdsiter); - while (result == ISC_R_SUCCESS) { - isc_boolean_t destroy = ISC_FALSE; - dns_rdatatype_t covers = 0; - dns_rdatasetiter_current(rdsiter, &set); - if (set.type == dns_rdatatype_rrsig) { - covers = set.covers; - destroy = ISC_TRUE; - } - dns_rdataset_disassociate(&set); - result = dns_rdatasetiter_next(rdsiter); - if (destroy) { - dresult = dns_db_deleterdataset(db, node, version, - dns_rdatatype_rrsig, - covers); - check_result(dresult, "dns_db_deleterdataset"); - } - } - if (result != ISC_R_NOMORE) - fatal("rdataset iteration failed: %s", - isc_result_totext(result)); - dns_rdatasetiter_destroy(&rdsiter); -} - -/*% - * Set up the iterator and global state before starting the tasks. - */ -static void -presign(void) { - isc_result_t result; - - gdbiter = NULL; - result = dns_db_createiterator(gdb, ISC_FALSE, &gdbiter); - check_result(result, "dns_db_createiterator()"); - - result = dns_dbiterator_first(gdbiter); - check_result(result, "dns_dbiterator_first()"); -} - -/*% - * Clean up the iterator and global state after the tasks complete. - */ -static void -postsign(void) { - dns_dbiterator_destroy(&gdbiter); -} - -/*% - * Sign the apex of the zone. - */ -static void -signapex(void) { - dns_dbnode_t *node = NULL; - dns_fixedname_t fixed; - dns_name_t *name; - isc_result_t result; - - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - result = dns_dbiterator_current(gdbiter, &node, name); - check_result(result, "dns_dbiterator_current()"); - signname(node, name); - dumpnode(name, node); - cleannode(gdb, gversion, node); - dns_db_detachnode(gdb, &node); - result = dns_dbiterator_next(gdbiter); - if (result == ISC_R_NOMORE) - finished = ISC_TRUE; - else if (result != ISC_R_SUCCESS) - fatal("failure iterating database: %s", - isc_result_totext(result)); -} - -/*% - * Assigns a node to a worker thread. This is protected by the master task's - * lock. - */ -static void -assignwork(isc_task_t *task, isc_task_t *worker) { - dns_fixedname_t *fname; - dns_name_t *name; - dns_dbnode_t *node; - sevent_t *sevent; - dns_rdataset_t nsec; - isc_boolean_t found; - isc_result_t result; - - if (shuttingdown) - return; - - if (finished) { - if (assigned == completed) { - isc_task_detach(&task); - isc_app_shutdown(); - } - return; - } - - fname = isc_mem_get(mctx, sizeof(dns_fixedname_t)); - if (fname == NULL) - fatal("out of memory"); - dns_fixedname_init(fname); - name = dns_fixedname_name(fname); - node = NULL; - found = ISC_FALSE; - LOCK(&namelock); - while (!found) { - result = dns_dbiterator_current(gdbiter, &node, name); - if (result != ISC_R_SUCCESS) - fatal("failure iterating database: %s", - isc_result_totext(result)); - dns_rdataset_init(&nsec); - result = dns_db_findrdataset(gdb, node, gversion, - dns_rdatatype_nsec, 0, 0, - &nsec, NULL); - if (result == ISC_R_SUCCESS) - found = ISC_TRUE; - else - dumpnode(name, node); - if (dns_rdataset_isassociated(&nsec)) - dns_rdataset_disassociate(&nsec); - if (!found) - dns_db_detachnode(gdb, &node); - - result = dns_dbiterator_next(gdbiter); - if (result == ISC_R_NOMORE) { - finished = ISC_TRUE; - break; - } else if (result != ISC_R_SUCCESS) - fatal("failure iterating database: %s", - isc_result_totext(result)); - } - UNLOCK(&namelock); - if (!found) { - if (assigned == completed) { - isc_task_detach(&task); - isc_app_shutdown(); - } - isc_mem_put(mctx, fname, sizeof(dns_fixedname_t)); - return; - } - sevent = (sevent_t *) - isc_event_allocate(mctx, task, SIGNER_EVENT_WORK, - sign, NULL, sizeof(sevent_t)); - if (sevent == NULL) - fatal("failed to allocate event\n"); - - sevent->node = node; - sevent->fname = fname; - isc_task_send(worker, ISC_EVENT_PTR(&sevent)); - assigned++; -} - -/*% - * Start a worker task - */ -static void -startworker(isc_task_t *task, isc_event_t *event) { - isc_task_t *worker; - - worker = (isc_task_t *)event->ev_arg; - assignwork(task, worker); - isc_event_free(&event); -} - -/*% - * Write a node to the output file, and restart the worker task. - */ -static void -writenode(isc_task_t *task, isc_event_t *event) { - isc_task_t *worker; - sevent_t *sevent = (sevent_t *)event; - - completed++; - worker = (isc_task_t *)event->ev_sender; - dumpnode(dns_fixedname_name(sevent->fname), sevent->node); - cleannode(gdb, gversion, sevent->node); - dns_db_detachnode(gdb, &sevent->node); - isc_mem_put(mctx, sevent->fname, sizeof(dns_fixedname_t)); - assignwork(task, worker); - isc_event_free(&event); -} - -/*% - * Sign a database node. - */ -static void -sign(isc_task_t *task, isc_event_t *event) { - dns_fixedname_t *fname; - dns_dbnode_t *node; - sevent_t *sevent, *wevent; - - sevent = (sevent_t *)event; - node = sevent->node; - fname = sevent->fname; - isc_event_free(&event); - - signname(node, dns_fixedname_name(fname)); - wevent = (sevent_t *) - isc_event_allocate(mctx, task, SIGNER_EVENT_WRITE, - writenode, NULL, sizeof(sevent_t)); - if (wevent == NULL) - fatal("failed to allocate event\n"); - wevent->node = node; - wevent->fname = fname; - isc_task_send(master, ISC_EVENT_PTR(&wevent)); -} - -/*% - * Generate NSEC records for the zone. - */ -static void -nsecify(void) { - dns_dbiterator_t *dbiter = NULL; - dns_dbnode_t *node = NULL, *nextnode = NULL; - dns_fixedname_t fname, fnextname, fzonecut; - dns_name_t *name, *nextname, *zonecut; - isc_boolean_t done = ISC_FALSE; - isc_result_t result; - - 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, ISC_FALSE, &dbiter); - check_result(result, "dns_db_createiterator()"); - - result = dns_dbiterator_first(dbiter); - check_result(result, "dns_dbiterator_first()"); - - while (!done) { - dns_dbiterator_current(dbiter, &node, name); - if (delegation(name, node, NULL)) { - zonecut = dns_fixedname_name(&fzonecut); - dns_name_copy(name, zonecut, NULL); - } - result = dns_dbiterator_next(dbiter); - nextnode = NULL; - while (result == ISC_R_SUCCESS) { - isc_boolean_t active = ISC_FALSE; - result = dns_dbiterator_current(dbiter, &nextnode, - nextname); - if (result != ISC_R_SUCCESS) - break; - active = active_node(nextnode); - if (!active) { - dns_db_detachnode(gdb, &nextnode); - result = dns_dbiterator_next(dbiter); - continue; - } - 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) { - dns_name_clone(gorigin, nextname); - done = ISC_TRUE; - } else if (result != ISC_R_SUCCESS) - fatal("iterating through the database failed: %s", - isc_result_totext(result)); - result = dns_nsec_build(gdb, gversion, node, nextname, - zonettl); - check_result(result, "dns_nsec_build()"); - dns_db_detachnode(gdb, &node); - } - - dns_dbiterator_destroy(&dbiter); -} - -/*% - * Load the zone file from disk - */ -static void -loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) { - isc_buffer_t b; - int len; - dns_fixedname_t fname; - dns_name_t *name; - isc_result_t result; - - len = strlen(origin); - isc_buffer_init(&b, origin, len); - isc_buffer_add(&b, len); - - dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); - result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) - fatal("failed converting name '%s' to dns format: %s", - origin, isc_result_totext(result)); - - result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone, - rdclass, 0, NULL, db); - check_result(result, "dns_db_create()"); - - result = dns_db_load2(*db, file, inputformat); - if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) - fatal("failed loading zone from '%s': %s", - file, isc_result_totext(result)); -} - -/*% - * Finds all public zone keys in the zone, and attempts to load the - * private keys from disk. - */ -static void -loadzonekeys(dns_db_t *db) { - dns_dbnode_t *node; - dns_dbversion_t *currentversion; - isc_result_t result; - dst_key_t *keys[20]; - unsigned int nkeys, i; - - currentversion = NULL; - dns_db_currentversion(db, ¤tversion); - - node = NULL; - result = dns_db_findnode(db, gorigin, ISC_FALSE, &node); - if (result != ISC_R_SUCCESS) - fatal("failed to find the zone's origin: %s", - isc_result_totext(result)); - - result = dns_dnssec_findzonekeys(db, currentversion, node, gorigin, - mctx, 20, keys, &nkeys); - if (result == ISC_R_NOTFOUND) - result = ISC_R_SUCCESS; - if (result != ISC_R_SUCCESS) - fatal("failed to find the zone keys: %s", - isc_result_totext(result)); - - for (i = 0; i < nkeys; i++) { - signer_key_t *key; - - key = newkeystruct(keys[i], dst_key_isprivate(keys[i])); - ISC_LIST_APPEND(keylist, key, link); - } - dns_db_detachnode(db, &node); - dns_db_closeversion(db, ¤tversion, ISC_FALSE); -} - -/*% - * Finds all public zone keys in the zone. - */ -static void -loadzonepubkeys(dns_db_t *db) { - dns_dbversion_t *currentversion = NULL; - dns_dbnode_t *node = NULL; - dns_rdataset_t rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - dst_key_t *pubkey; - signer_key_t *key; - isc_result_t result; - - dns_db_currentversion(db, ¤tversion); - - result = dns_db_findnode(db, 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(&rdataset); - result = dns_db_findrdataset(db, node, currentversion, - dns_rdatatype_dnskey, 0, 0, &rdataset, NULL); - if (result != ISC_R_SUCCESS) - fatal("failed to find keys at the zone apex: %s", - isc_result_totext(result)); - result = dns_rdataset_first(&rdataset); - check_result(result, "dns_rdataset_first"); - while (result == ISC_R_SUCCESS) { - pubkey = NULL; - dns_rdata_reset(&rdata); - dns_rdataset_current(&rdataset, &rdata); - result = dns_dnssec_keyfromrdata(gorigin, &rdata, mctx, - &pubkey); - if (result != ISC_R_SUCCESS) - goto next; - if (!dst_key_iszonekey(pubkey)) { - dst_key_free(&pubkey); - goto next; - } - - key = newkeystruct(pubkey, ISC_FALSE); - ISC_LIST_APPEND(keylist, key, link); - next: - result = dns_rdataset_next(&rdataset); - } - dns_rdataset_disassociate(&rdataset); - dns_db_detachnode(db, &node); - dns_db_closeversion(db, ¤tversion, ISC_FALSE); -} - -static void -warnifallksk(dns_db_t *db) { - dns_dbversion_t *currentversion = NULL; - dns_dbnode_t *node = NULL; - dns_rdataset_t rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_result_t result; - dns_rdata_key_t key; - isc_boolean_t have_non_ksk = ISC_FALSE; - - dns_db_currentversion(db, ¤tversion); - - result = dns_db_findnode(db, 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(&rdataset); - result = dns_db_findrdataset(db, node, currentversion, - dns_rdatatype_dnskey, 0, 0, &rdataset, NULL); - if (result != ISC_R_SUCCESS) - fatal("failed to find keys at the zone apex: %s", - isc_result_totext(result)); - result = dns_rdataset_first(&rdataset); - check_result(result, "dns_rdataset_first"); - while (result == ISC_R_SUCCESS) { - dns_rdata_reset(&rdata); - dns_rdataset_current(&rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &key, NULL); - check_result(result, "dns_rdata_tostruct"); - if ((key.flags & DNS_KEYFLAG_KSK) == 0) { - have_non_ksk = ISC_TRUE; - result = ISC_R_NOMORE; - } else - result = dns_rdataset_next(&rdataset); - } - dns_rdataset_disassociate(&rdataset); - dns_db_detachnode(db, &node); - dns_db_closeversion(db, ¤tversion, ISC_FALSE); - if (!have_non_ksk && !ignoreksk) - fprintf(stderr, "%s: warning: No non-KSK dnskey found. " - "Supply non-KSK dnskey or use '-z'.\n", - program); -} - -static void -writeset(const char *prefix, dns_rdatatype_t type) { - char *filename; - char namestr[DNS_NAME_FORMATSIZE]; - dns_db_t *db = NULL; - dns_dbversion_t *version = NULL; - dns_diff_t diff; - dns_difftuple_t *tuple = NULL; - dns_fixedname_t fixed; - dns_name_t *name; - dns_rdata_t rdata, ds; - isc_boolean_t have_ksk = ISC_FALSE; - isc_boolean_t have_non_ksk = ISC_FALSE; - isc_buffer_t b; - isc_buffer_t namebuf; - isc_region_t r; - isc_result_t result; - signer_key_t *key; - unsigned char dsbuf[DNS_DS_BUFFERSIZE]; - unsigned char keybuf[DST_KEY_MAXSIZE]; - unsigned int filenamelen; - const dns_master_style_t *style = - (type == dns_rdatatype_dnskey) ? masterstyle : dsstyle; - - isc_buffer_init(&namebuf, namestr, sizeof(namestr)); - result = dns_name_tofilenametext(gorigin, ISC_FALSE, &namebuf); - check_result(result, "dns_name_tofilenametext"); - isc_buffer_putuint8(&namebuf, 0); - filenamelen = strlen(prefix) + strlen(namestr); - if (directory != NULL) - filenamelen += strlen(directory) + 1; - filename = isc_mem_get(mctx, filenamelen + 1); - if (filename == NULL) - fatal("out of memory"); - if (directory != NULL) - sprintf(filename, "%s/", directory); - else - filename[0] = 0; - strcat(filename, prefix); - strcat(filename, namestr); - - dns_diff_init(mctx, &diff); - - for (key = ISC_LIST_HEAD(keylist); - key != NULL; - key = ISC_LIST_NEXT(key, link)) - if (!key->isksk) { - have_non_ksk = ISC_TRUE; - break; - } - - for (key = ISC_LIST_HEAD(keylist); - key != NULL; - key = ISC_LIST_NEXT(key, link)) - if (key->isksk) { - have_ksk = ISC_TRUE; - break; - } - - if (type == dns_rdatatype_dlv) { - dns_name_t tname; - unsigned int labels; - - dns_name_init(&tname, NULL); - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - labels = dns_name_countlabels(gorigin); - dns_name_getlabelsequence(gorigin, 0, labels - 1, &tname); - result = dns_name_concatenate(&tname, dlv, name, NULL); - check_result(result, "dns_name_concatenate"); - } else - name = gorigin; - - for (key = ISC_LIST_HEAD(keylist); - key != NULL; - key = ISC_LIST_NEXT(key, link)) - { - if (have_ksk && have_non_ksk && !key->isksk) - continue; - dns_rdata_init(&rdata); - dns_rdata_init(&ds); - isc_buffer_init(&b, keybuf, sizeof(keybuf)); - result = dst_key_todns(key->key, &b); - check_result(result, "dst_key_todns"); - isc_buffer_usedregion(&b, &r); - dns_rdata_fromregion(&rdata, gclass, dns_rdatatype_dnskey, &r); - if (type != dns_rdatatype_dnskey) { - result = dns_ds_buildrdata(gorigin, &rdata, - DNS_DSDIGEST_SHA1, - dsbuf, &ds); - check_result(result, "dns_ds_buildrdata"); - if (type == dns_rdatatype_dlv) - ds.type = dns_rdatatype_dlv; - result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, - name, 0, &ds, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(&diff, &tuple); - - dns_rdata_reset(&ds); - result = dns_ds_buildrdata(gorigin, &rdata, - DNS_DSDIGEST_SHA256, - dsbuf, &ds); - check_result(result, "dns_ds_buildrdata"); - if (type == dns_rdatatype_dlv) - ds.type = dns_rdatatype_dlv; - result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, - name, 0, &ds, &tuple); - - } else - result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, - gorigin, zonettl, - &rdata, &tuple); - check_result(result, "dns_difftuple_create"); - dns_diff_append(&diff, &tuple); - } - - result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, - gclass, 0, NULL, &db); - check_result(result, "dns_db_create"); - - result = dns_db_newversion(db, &version); - check_result(result, "dns_db_newversion"); - - result = dns_diff_apply(&diff, db, version); - check_result(result, "dns_diff_apply"); - dns_diff_clear(&diff); - - result = dns_master_dump(mctx, db, version, style, filename); - check_result(result, "dns_master_dump"); - - isc_mem_put(mctx, filename, filenamelen + 1); - - dns_db_closeversion(db, &version, ISC_FALSE); - dns_db_detach(&db); -} - -static void -print_time(FILE *fp) { - time_t currenttime; - - if (outputformat != dns_masterformat_text) - return; - - currenttime = time(NULL); - fprintf(fp, "; File written on %s", ctime(¤ttime)); -} - -static void -print_version(FILE *fp) { - if (outputformat != dns_masterformat_text) - return; - - fprintf(fp, "; dnssec_signzone version " VERSION "\n"); -} - -static void -usage(void) { - fprintf(stderr, "Usage:\n"); - fprintf(stderr, "\t%s [options] zonefile [keys]\n", program); - - fprintf(stderr, "\n"); - - fprintf(stderr, "Version: %s\n", VERSION); - - fprintf(stderr, "Options: (default value in parenthesis) \n"); - fprintf(stderr, "\t-c class (IN)\n"); - fprintf(stderr, "\t-d directory\n"); - fprintf(stderr, "\t\tdirectory to find keyset files (.)\n"); - fprintf(stderr, "\t-g:\t"); - fprintf(stderr, "generate DS records from keyset files\n"); - fprintf(stderr, "\t-s [YYYYMMDDHHMMSS|+offset]:\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 " - "(now + 30 days)\n"); - fprintf(stderr, "\t-i interval:\n"); - fprintf(stderr, "\t\tcycle interval - resign " - "if < interval from end ( (end-start)/4 )\n"); - fprintf(stderr, "\t-j jitter:\n"); - fprintf(stderr, "\t\trandomize signature end time up to jitter seconds\n"); - fprintf(stderr, "\t-v debuglevel (0)\n"); - fprintf(stderr, "\t-o origin:\n"); - fprintf(stderr, "\t\tzone origin (name of zonefile)\n"); - fprintf(stderr, "\t-f outfile:\n"); - fprintf(stderr, "\t\tfile the signed zone is written in " - "(zonefile + .signed)\n"); - fprintf(stderr, "\t-I format:\n"); - fprintf(stderr, "\t\tfile format of input zonefile (text)\n"); - fprintf(stderr, "\t-O format:\n"); - 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-r randomdev:\n"); - fprintf(stderr, "\t\ta file containing random data\n"); - fprintf(stderr, "\t-a:\t"); - fprintf(stderr, "verify generated signatures\n"); - fprintf(stderr, "\t-p:\t"); - fprintf(stderr, "use pseudorandom data (faster but less secure)\n"); - fprintf(stderr, "\t-t:\t"); - fprintf(stderr, "print statistics\n"); - fprintf(stderr, "\t-n ncpus (number of cpus present)\n"); - fprintf(stderr, "\t-k key_signing_key\n"); - fprintf(stderr, "\t-l lookasidezone\n"); - fprintf(stderr, "\t-z:\t"); - fprintf(stderr, "ignore KSK flag in DNSKEYs"); - - fprintf(stderr, "\n"); - - fprintf(stderr, "Signing Keys: "); - fprintf(stderr, "(default: all zone keys that have private keys)\n"); - fprintf(stderr, "\tkeyfile (Kname+alg+tag)\n"); - exit(0); -} - -static void -removetempfile(void) { - if (removefile) - isc_file_remove(tempfile); -} - -static void -print_stats(isc_time_t *timer_start, isc_time_t *timer_finish) { - isc_uint64_t runtime_us; /* Runtime in microseconds */ - isc_uint64_t runtime_ms; /* Runtime in milliseconds */ - isc_uint64_t sig_ms; /* Signatures per millisecond */ - - runtime_us = isc_time_microdiff(timer_finish, timer_start); - - 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); - runtime_ms = runtime_us / 1000; - printf("Runtime in seconds: %7u.%03u\n", - (unsigned int) (runtime_ms / 1000), - (unsigned int) (runtime_ms % 1000)); - if (runtime_us > 0) { - sig_ms = ((isc_uint64_t)nsigned * 1000000000) / runtime_us; - printf("Signatures per second: %7u.%03u\n", - (unsigned int) sig_ms / 1000, - (unsigned int) sig_ms % 1000); - } -} - -int -main(int argc, char *argv[]) { - int i, ch; - char *startstr = NULL, *endstr = NULL, *classname = NULL; - char *origin = NULL, *file = NULL, *output = NULL; - char *inputformatstr = NULL, *outputformatstr = NULL; - char *serialformatstr = NULL; - char *dskeyfile[MAXDSKEYS]; - int ndskeys = 0; - char *endp; - isc_time_t timer_start, timer_finish; - signer_key_t *key; - isc_result_t result; - isc_log_t *log = NULL; - isc_boolean_t pseudorandom = ISC_FALSE; - unsigned int eflags; - isc_boolean_t free_output = ISC_FALSE; - int tempfilelen; - dns_rdataclass_t rdclass; - isc_task_t **tasks = NULL; - isc_buffer_t b; - int len; - - masterstyle = &dns_master_style_explicitttl; - - check_result(isc_app_start(), "isc_app_start"); - - result = isc_mem_create(0, 0, &mctx); - if (result != ISC_R_SUCCESS) - fatal("out of memory"); - - dns_result_register(); - - while ((ch = isc_commandline_parse(argc, argv, - "ac:d:e:f:ghi:I:j:k:l:n:N:o:O:pr:s:Stv:z")) - != -1) { - switch (ch) { - case 'a': - tryverify = ISC_TRUE; - break; - - case 'c': - classname = isc_commandline_argument; - break; - - case 'd': - directory = isc_commandline_argument; - break; - - case 'e': - endstr = isc_commandline_argument; - break; - - case 'f': - output = isc_commandline_argument; - break; - - case 'g': - generateds = ISC_TRUE; - break; - - case 'h': - default: - usage(); - break; - - case 'i': - endp = NULL; - cycle = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0' || cycle < 0) - fatal("cycle period must be numeric and " - "positive"); - break; - - case 'I': - inputformatstr = isc_commandline_argument; - break; - - case 'j': - endp = NULL; - jitter = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0' || jitter < 0) - fatal("jitter must be numeric and positive"); - break; - - case 'l': - dns_fixedname_init(&dlv_fixed); - len = strlen(isc_commandline_argument); - isc_buffer_init(&b, isc_commandline_argument, len); - isc_buffer_add(&b, len); - - dns_fixedname_init(&dlv_fixed); - dlv = dns_fixedname_name(&dlv_fixed); - result = dns_name_fromtext(dlv, &b, dns_rootname, - ISC_FALSE, NULL); - check_result(result, "dns_name_fromtext(dlv)"); - break; - - case 'k': - if (ndskeys == MAXDSKEYS) - fatal("too many key-signing keys specified"); - dskeyfile[ndskeys++] = isc_commandline_argument; - break; - - case 'n': - endp = NULL; - ntasks = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0' || ntasks > ISC_INT32_MAX) - fatal("number of cpus must be numeric"); - break; - - case 'N': - serialformatstr = isc_commandline_argument; - break; - - case 'o': - origin = isc_commandline_argument; - break; - - case 'O': - outputformatstr = isc_commandline_argument; - break; - - case 'p': - pseudorandom = ISC_TRUE; - break; - - case 'r': - setup_entropy(mctx, isc_commandline_argument, &ectx); - break; - - case 's': - startstr = isc_commandline_argument; - break; - - case 'S': - /* This is intentionally undocumented */ - /* -S: simple output style */ - masterstyle = &dns_master_style_simple; - break; - - case 't': - printstats = ISC_TRUE; - break; - - case 'v': - endp = NULL; - verbose = strtol(isc_commandline_argument, &endp, 0); - if (*endp != '\0') - fatal("verbose level must be numeric"); - break; - - case 'z': - ignoreksk = ISC_TRUE; - break; - } - } - - if (ectx == NULL) - setup_entropy(mctx, NULL, &ectx); - eflags = ISC_ENTROPY_BLOCKING; - if (!pseudorandom) - eflags |= ISC_ENTROPY_GOODONLY; - - result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) - fatal("could not create hash context"); - - result = dst_lib_init(mctx, ectx, eflags); - if (result != ISC_R_SUCCESS) - fatal("could not initialize dst"); - - isc_stdtime_get(&now); - - if (startstr != NULL) - starttime = strtotime(startstr, now, now); - else - starttime = now - 3600; /* Allow for some clock skew. */ - - if (endstr != NULL) - endtime = strtotime(endstr, now, starttime); - else - endtime = starttime + (30 * 24 * 60 * 60); - - if (cycle == -1) - cycle = (endtime - starttime) / 4; - - if (ntasks == 0) - ntasks = isc_os_ncpus(); - vbprintf(4, "using %d cpus\n", ntasks); - - rdclass = strtoclass(classname); - - setup_logging(verbose, mctx, &log); - - argc -= isc_commandline_index; - argv += isc_commandline_index; - - if (argc < 1) - usage(); - - file = argv[0]; - - argc -= 1; - argv += 1; - - if (origin == NULL) - origin = file; - - if (output == NULL) { - free_output = ISC_TRUE; - output = isc_mem_allocate(mctx, - strlen(file) + strlen(".signed") + 1); - if (output == NULL) - fatal("out of memory"); - sprintf(output, "%s.signed", file); - } - - if (inputformatstr != NULL) { - if (strcasecmp(inputformatstr, "text") == 0) - inputformat = dns_masterformat_text; - else if (strcasecmp(inputformatstr, "raw") == 0) - inputformat = dns_masterformat_raw; - else - fatal("unknown file format: %s\n", inputformatstr); - } - - if (outputformatstr != NULL) { - if (strcasecmp(outputformatstr, "text") == 0) - outputformat = dns_masterformat_text; - else if (strcasecmp(outputformatstr, "raw") == 0) - outputformat = dns_masterformat_raw; - else - fatal("unknown file format: %s\n", outputformatstr); - } - - if (serialformatstr != NULL) { - if (strcasecmp(serialformatstr, "keep") == 0) - serialformat = SOA_SERIAL_KEEP; - else if (strcasecmp(serialformatstr, "increment") == 0 || - strcasecmp(serialformatstr, "incr") == 0) - serialformat = SOA_SERIAL_INCREMENT; - else if (strcasecmp(serialformatstr, "unixtime") == 0) - serialformat = SOA_SERIAL_UNIXTIME; - else - fatal("unknown soa serial format: %s\n", serialformatstr); - } - - result = dns_master_stylecreate(&dsstyle, DNS_STYLEFLAG_NO_TTL, - 0, 24, 0, 0, 0, 8, mctx); - check_result(result, "dns_master_stylecreate"); - - - gdb = NULL; - TIME_NOW(&timer_start); - loadzone(file, origin, rdclass, &gdb); - gorigin = dns_db_origin(gdb); - gclass = dns_db_class(gdb); - zonettl = soattl(); - - ISC_LIST_INIT(keylist); - - if (argc == 0) { - loadzonekeys(gdb); - } else { - for (i = 0; i < argc; i++) { - dst_key_t *newkey = NULL; - - result = dst_key_fromnamedfile(argv[i], - DST_TYPE_PUBLIC | - DST_TYPE_PRIVATE, - mctx, &newkey); - if (result != ISC_R_SUCCESS) - fatal("cannot load dnskey %s: %s", argv[i], - isc_result_totext(result)); - - key = ISC_LIST_HEAD(keylist); - while (key != NULL) { - dst_key_t *dkey = key->key; - if (dst_key_id(dkey) == dst_key_id(newkey) && - dst_key_alg(dkey) == dst_key_alg(newkey) && - dns_name_equal(dst_key_name(dkey), - dst_key_name(newkey))) - { - if (!dst_key_isprivate(dkey)) - fatal("cannot sign zone with " - "non-private dnskey %s", - argv[i]); - break; - } - key = ISC_LIST_NEXT(key, link); - } - if (key == NULL) { - key = newkeystruct(newkey, ISC_TRUE); - ISC_LIST_APPEND(keylist, key, link); - } else - dst_key_free(&newkey); - } - - loadzonepubkeys(gdb); - } - - for (i = 0; i < ndskeys; i++) { - dst_key_t *newkey = NULL; - - result = dst_key_fromnamedfile(dskeyfile[i], - DST_TYPE_PUBLIC | - DST_TYPE_PRIVATE, - mctx, &newkey); - if (result != ISC_R_SUCCESS) - fatal("cannot load dnskey %s: %s", dskeyfile[i], - isc_result_totext(result)); - - key = ISC_LIST_HEAD(keylist); - while (key != NULL) { - dst_key_t *dkey = key->key; - if (dst_key_id(dkey) == dst_key_id(newkey) && - dst_key_alg(dkey) == dst_key_alg(newkey) && - dns_name_equal(dst_key_name(dkey), - dst_key_name(newkey))) - { - /* Override key flags. */ - key->issigningkey = ISC_TRUE; - key->isksk = ISC_TRUE; - key->isdsk = ISC_FALSE; - dst_key_free(&dkey); - key->key = newkey; - break; - } - key = ISC_LIST_NEXT(key, link); - } - if (key == NULL) { - /* Override dnskey flags. */ - key = newkeystruct(newkey, ISC_TRUE); - key->isksk = ISC_TRUE; - key->isdsk = ISC_FALSE; - ISC_LIST_APPEND(keylist, key, link); - } - } - - if (ISC_LIST_EMPTY(keylist)) { - fprintf(stderr, "%s: warning: No keys specified or found\n", - program); - nokeys = ISC_TRUE; - } - - warnifallksk(gdb); - - gversion = NULL; - result = dns_db_newversion(gdb, &gversion); - check_result(result, "dns_db_newversion()"); - - switch (serialformat) { - case SOA_SERIAL_INCREMENT: - setsoaserial(0); - break; - case SOA_SERIAL_UNIXTIME: - setsoaserial(now); - break; - case SOA_SERIAL_KEEP: - default: - /* do nothing */ - break; - } - - nsecify(); - - if (!nokeys) { - writeset("keyset-", dns_rdatatype_dnskey); - writeset("dsset-", dns_rdatatype_ds); - if (dlv != NULL) { - writeset("dlvset-", dns_rdatatype_dlv); - } - } - - 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"); - - fp = NULL; - result = isc_file_openunique(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); - - result = isc_taskmgr_create(mctx, ntasks, 0, &taskmgr); - if (result != ISC_R_SUCCESS) - fatal("failed to create task manager: %s", - isc_result_totext(result)); - - master = NULL; - result = isc_task_create(taskmgr, 0, &master); - if (result != ISC_R_SUCCESS) - fatal("failed to create task: %s", isc_result_totext(result)); - - tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *)); - if (tasks == NULL) - fatal("out of memory"); - for (i = 0; i < (int)ntasks; i++) { - tasks[i] = NULL; - result = isc_task_create(taskmgr, 0, &tasks[i]); - if (result != ISC_R_SUCCESS) - fatal("failed to create task: %s", - isc_result_totext(result)); - } - - RUNTIME_CHECK(isc_mutex_init(&namelock) == ISC_R_SUCCESS); - if (printstats) - RUNTIME_CHECK(isc_mutex_init(&statslock) == ISC_R_SUCCESS); - - presign(); - signapex(); - if (!finished) { - /* - * There is more work to do. Spread it out over multiple - * processors if possible. - */ - for (i = 0; i < (int)ntasks; i++) { - result = isc_app_onrun(mctx, master, startworker, - tasks[i]); - if (result != ISC_R_SUCCESS) - fatal("failed to start task: %s", - isc_result_totext(result)); - } - (void)isc_app_run(); - if (!finished) - fatal("process aborted by user"); - } else - isc_task_detach(&master); - shuttingdown = ISC_TRUE; - for (i = 0; i < (int)ntasks; i++) - isc_task_detach(&tasks[i]); - isc_taskmgr_destroy(&taskmgr); - isc_mem_put(mctx, tasks, ntasks * sizeof(isc_task_t *)); - postsign(); - - if (outputformat != dns_masterformat_text) { - result = dns_master_dumptostream2(mctx, gdb, gversion, - masterstyle, outputformat, - fp); - check_result(result, "dns_master_dumptostream2"); - } - - 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); - - dns_db_closeversion(gdb, &gversion, ISC_FALSE); - dns_db_detach(&gdb); - - while (!ISC_LIST_EMPTY(keylist)) { - key = ISC_LIST_HEAD(keylist); - ISC_LIST_UNLINK(keylist, key, link); - dst_key_free(&key->key); - isc_mem_put(mctx, key, sizeof(signer_key_t)); - } - - isc_mem_put(mctx, tempfile, tempfilelen); - - if (free_output) - isc_mem_free(mctx, output); - - dns_master_styledestroy(&dsstyle, mctx); - - cleanup_logging(&log); - dst_lib_destroy(); - isc_hash_destroy(); - cleanup_entropy(&ectx); - dns_name_destroy(); - if (verbose > 10) - isc_mem_stats(mctx, stdout); - isc_mem_destroy(&mctx); - - (void) isc_app_finish(); - - if (printstats) { - TIME_NOW(&timer_finish); - print_stats(&timer_start, &timer_finish); - } - - return (0); -} diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.docbook b/contrib/bind9/bin/dnssec/dnssec-signzone.docbook deleted file mode 100644 index 8d92831..0000000 --- a/contrib/bind9/bin/dnssec/dnssec-signzone.docbook +++ /dev/null @@ -1,476 +0,0 @@ -]> - - - - - - June 30, 2000 - - - - dnssec-signzone - 8 - BIND9 - - - - dnssec-signzone - DNSSEC zone signing tool - - - - - 2004 - 2005 - 2006 - 2007 - Internet Systems Consortium, Inc. ("ISC") - - - 2000 - 2001 - 2002 - 2003 - Internet Software Consortium. - - - - - - dnssec-signzone - - - - - - - - - - - - - - - - - - - - - - zonefile - key - - - - - DESCRIPTION - dnssec-signzone - signs a zone. It generates - NSEC and RRSIG records and produces a signed version of the - zone. The security status of delegations from the signed zone - (that is, whether the child zones are secure or not) is - determined by the presence or absence of a - keyset file for each child zone. - - - - - OPTIONS - - - - -a - - - Verify all generated signatures. - - - - - - -c class - - - Specifies the DNS class of the zone. - - - - - - -k key - - - Treat specified key as a key signing key ignoring any - key flags. This option may be specified multiple times. - - - - - - -l domain - - - Generate a DLV set in addition to the key (DNSKEY) and DS sets. - The domain is appended to the name of the records. - - - - - - -d directory - - - Look for keyset files in - as the directory - - - - - - -g - - - Generate DS records for child zones from keyset files. - Existing DS records will be removed. - - - - - - -s start-time - - - Specify the date and time when the generated RRSIG records - become valid. This can be either an absolute or relative - time. An absolute start time is indicated by a number - in YYYYMMDDHHMMSS notation; 20000530144500 denotes - 14:45:00 UTC on May 30th, 2000. A relative start time is - indicated by +N, which is N seconds from the current time. - If no is specified, the current - time minus 1 hour (to allow for clock skew) is used. - - - - - - -e end-time - - - Specify the date and time when the generated RRSIG records - expire. 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, 30 days from the start time is used as a default. - - - - - - -f output-file - - - The name of the output file containing the signed zone. The - default is to append .signed to - the - input filename. - - - - - - -h - - - Prints a short summary of the options and arguments to - dnssec-signzone. - - - - - - -i interval - - - When a previously-signed zone is passed as input, records - may be resigned. The option - specifies the cycle interval as an offset from the current - time (in seconds). If a RRSIG record expires after the - cycle interval, it is retained. Otherwise, it is considered - to be expiring soon, and it will be replaced. - - - The default cycle interval is one quarter of the difference - between the signature end and start times. So if neither - or - are specified, dnssec-signzone - generates - signatures that are valid for 30 days, with a cycle - interval of 7.5 days. Therefore, if any existing RRSIG records - are due to expire in less than 7.5 days, they would be - replaced. - - - - - - -I input-format - - - The format of the input zone file. - Possible formats are "text" (default) - and "raw". - This option is primarily intended to be used for dynamic - signed zones so that the dumped zone file in a non-text - format containing updates can be signed directly. - The use of this option does not make much sense for - non-dynamic zones. - - - - - - -j jitter - - - When signing a zone with a fixed signature lifetime, all - RRSIG records issued at the time of signing expires - simultaneously. If the zone is incrementally signed, i.e. - a previously-signed zone is passed as input to the signer, - all expired signatures have to be regenerated at about the - same time. The option specifies a - jitter window that will be used to randomize the signature - expire time, thus spreading incremental signature - regeneration over time. - - - 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. - - - - - - -n ncpus - - - Specifies the number of threads to use. By default, one - thread is started for each detected CPU. - - - - - - -N soa-serial-format - - - The SOA serial number format of the signed zone. - Possible formats are "keep" (default), - "increment" and - "unixtime". - - - - - "keep" - - Do not modify the SOA serial number. - - - - - "increment" - - Increment the SOA serial number using RFC 1982 - arithmetics. - - - - - "unixtime" - - Set the SOA serial number to the number of seconds - since epoch. - - - - - - - - - -o origin - - - The zone origin. If not specified, the name of the zone file - is assumed to be the origin. - - - - - - -O output-format - - - The format of the output file containing the signed zone. - Possible formats are "text" (default) - and "raw". - - - - - - -p - - - Use pseudo-random data when signing the zone. This is faster, - but less secure, than using real random data. This option - may be useful when signing large zones or when the entropy - source is limited. - - - - - - -r randomdev - - - Specifies the source of randomness. If the operating - system does not provide a /dev/random - or equivalent device, the default source of randomness - is keyboard input. randomdev - specifies - the name of a character device or file containing random - data to be used instead of the default. The special value - keyboard indicates that keyboard - input should be used. - - - - - - -t - - - Print statistics at completion. - - - - - - -v level - - - Sets the debugging level. - - - - - - -z - - - Ignore KSK flag on key when determining what to sign. - - - - - - zonefile - - - The file containing the zone to be signed. - - - - - - key - - - Specify which keys should be used to sign the zone. If - no keys are specified, then the zone will be examined - for DNSKEY records at the zone apex. If these are found and - there are matching private keys, in the current directory, - then these will be used for signing. - - - - - - - - - EXAMPLE - - The following command signs the example.com - zone with the DSA key generated by dnssec-keygen - (Kexample.com.+003+17247). The zone's keys must be in the master - file (db.example.com). This invocation looks - for keyset files, in the current directory, - so that DS records can be generated from them (-g). - -% dnssec-signzone -g -o example.com db.example.com \ -Kexample.com.+003+17247 -db.example.com.signed -% - - In the above example, dnssec-signzone creates - the file db.example.com.signed. This - file should be referenced in a zone statement in a - named.conf file. - - - This example re-signs a previously signed zone with default parameters. - The private keys are assumed to be in the current directory. - -% cp db.example.com.signed db.example.com -% dnssec-signzone -o example.com db.example.com -db.example.com.signed -% - - - - SEE ALSO - - dnssec-keygen8 - , - BIND 9 Administrator Reference Manual, - RFC 2535. - - - - - AUTHOR - Internet Systems Consortium - - - - diff --git a/contrib/bind9/bin/dnssec/dnssec-signzone.html b/contrib/bind9/bin/dnssec/dnssec-signzone.html deleted file mode 100644 index e794d4c..0000000 --- a/contrib/bind9/bin/dnssec/dnssec-signzone.html +++ /dev/null @@ -1,285 +0,0 @@ - - - - - -dnssec-signzone - - -
-
-
-

Name

-

dnssec-signzone — DNSSEC zone signing tool

-
-
-

Synopsis

-

dnssec-signzone [-a] [-c class] [-d directory] [-e end-time] [-f output-file] [-g] [-h] [-k key] [-l domain] [-i interval] [-I input-format] [-j jitter] [-N soa-serial-format] [-o origin] [-O output-format] [-p] [-r randomdev] [-s start-time] [-t] [-v level] [-z] {zonefile} [key...]

-
-
-

DESCRIPTION

-

dnssec-signzone - signs a zone. It generates - NSEC and RRSIG records and produces a signed version of the - zone. The security status of delegations from the signed zone - (that is, whether the child zones are secure or not) is - determined by the presence or absence of a - keyset file for each child zone. -

-
-
-

OPTIONS

-
-
-a
-

- Verify all generated signatures. -

-
-c class
-

- Specifies the DNS class of the zone. -

-
-k key
-

- Treat specified key as a key signing key ignoring any - key flags. This option may be specified multiple times. -

-
-l domain
-

- Generate a DLV set in addition to the key (DNSKEY) and DS sets. - The domain is appended to the name of the records. -

-
-d directory
-

- Look for keyset files in - directory as the directory -

-
-g
-

- Generate DS records for child zones from keyset files. - Existing DS records will be removed. -

-
-s start-time
-

- Specify the date and time when the generated RRSIG records - become valid. This can be either an absolute or relative - time. An absolute start time is indicated by a number - in YYYYMMDDHHMMSS notation; 20000530144500 denotes - 14:45:00 UTC on May 30th, 2000. A relative start time is - indicated by +N, which is N seconds from the current time. - If no start-time is specified, the current - time minus 1 hour (to allow for clock skew) is used. -

-
-e end-time
-

- Specify the date and time when the generated RRSIG records - expire. 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 end-time is - specified, 30 days from the start time is used as a default. -

-
-f output-file
-

- The name of the output file containing the signed zone. The - default is to append .signed to - the - input filename. -

-
-h
-

- Prints a short summary of the options and arguments to - dnssec-signzone. -

-
-i interval
-
-

- When a previously-signed zone is passed as input, records - may be resigned. The interval option - specifies the cycle interval as an offset from the current - time (in seconds). If a RRSIG record expires after the - cycle interval, it is retained. Otherwise, it is considered - to be expiring soon, and it will be replaced. -

-

- The default cycle interval is one quarter of the difference - between the signature end and start times. So if neither - end-time or start-time - are specified, dnssec-signzone - generates - signatures that are valid for 30 days, with a cycle - interval of 7.5 days. Therefore, if any existing RRSIG records - are due to expire in less than 7.5 days, they would be - replaced. -

-
-
-I input-format
-

- The format of the input zone file. - Possible formats are "text" (default) - and "raw". - This option is primarily intended to be used for dynamic - signed zones so that the dumped zone file in a non-text - format containing updates can be signed directly. - The use of this option does not make much sense for - non-dynamic zones. -

-
-j jitter
-
-

- When signing a zone with a fixed signature lifetime, all - RRSIG records issued at the time of signing expires - simultaneously. If the zone is incrementally signed, i.e. - a previously-signed zone is passed as input to the signer, - all expired signatures have to be regenerated at about the - same time. The jitter option specifies a - jitter window that will be used to randomize the signature - expire time, thus spreading incremental signature - regeneration over time. -

-

- 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. -

-
-
-n ncpus
-

- Specifies the number of threads to use. By default, one - thread is started for each detected CPU. -

-
-N soa-serial-format
-
-

- The SOA serial number format of the signed zone. - Possible formats are "keep" (default), - "increment" and - "unixtime". -

-
-
"keep"
-

Do not modify the SOA serial number.

-
"increment"
-

Increment the SOA serial number using RFC 1982 - arithmetics.

-
"unixtime"
-

Set the SOA serial number to the number of seconds - since epoch.

-
-
-
-o origin
-

- The zone origin. If not specified, the name of the zone file - is assumed to be the origin. -

-
-O output-format
-

- The format of the output file containing the signed zone. - Possible formats are "text" (default) - and "raw". -

-
-p
-

- Use pseudo-random data when signing the zone. This is faster, - but less secure, than using real random data. This option - may be useful when signing large zones or when the entropy - source is limited. -

-
-r randomdev
-

- Specifies the source of randomness. If the operating - system does not provide a /dev/random - or equivalent device, the default source of randomness - is keyboard input. randomdev - specifies - the name of a character device or file containing random - data to be used instead of the default. The special value - keyboard indicates that keyboard - input should be used. -

-
-t
-

- Print statistics at completion. -

-
-v level
-

- Sets the debugging level. -

-
-z
-

- Ignore KSK flag on key when determining what to sign. -

-
zonefile
-

- The file containing the zone to be signed. -

-
key
-

- Specify which keys should be used to sign the zone. If - no keys are specified, then the zone will be examined - for DNSKEY records at the zone apex. If these are found and - there are matching private keys, in the current directory, - then these will be used for signing. -

-
-
-
-

EXAMPLE

-

- The following command signs the example.com - zone with the DSA key generated by dnssec-keygen - (Kexample.com.+003+17247). The zone's keys must be in the master - file (db.example.com). This invocation looks - for keyset files, in the current directory, - so that DS records can be generated from them (-g). -

-
% dnssec-signzone -g -o example.com db.example.com \
-Kexample.com.+003+17247
-db.example.com.signed
-%
-

- In the above example, dnssec-signzone creates - the file db.example.com.signed. This - file should be referenced in a zone statement in a - named.conf file. -

-

- This example re-signs a previously signed zone with default parameters. - The private keys are assumed to be in the current directory. -

-
% cp db.example.com.signed db.example.com
-% dnssec-signzone -o example.com db.example.com
-db.example.com.signed
-%
-
-
-

SEE ALSO

-

dnssec-keygen(8), - BIND 9 Administrator Reference Manual, - RFC 2535. -

-
-
-

AUTHOR

-

Internet Systems Consortium -

-
-
- diff --git a/contrib/bind9/bin/dnssec/dnssectool.c b/contrib/bind9/bin/dnssec/dnssectool.c deleted file mode 100644 index 4f95540..0000000 --- a/contrib/bind9/bin/dnssec/dnssectool.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: dnssectool.c,v 1.40.18.3 2005/07/01 03:55:28 marka Exp $ */ - -/*! \file */ - -/*% - * DNSSEC Support Routines. - */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dnssectool.h" - -extern int verbose; -extern const char *program; - -typedef struct entropysource entropysource_t; - -struct entropysource { - isc_entropysource_t *source; - isc_mem_t *mctx; - ISC_LINK(entropysource_t) link; -}; - -static ISC_LIST(entropysource_t) sources; -static fatalcallback_t *fatalcallback = NULL; - -void -fatal(const char *format, ...) { - va_list args; - - fprintf(stderr, "%s: ", program); - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); - fprintf(stderr, "\n"); - if (fatalcallback != NULL) - (*fatalcallback)(); - exit(1); -} - -void -setfatalcallback(fatalcallback_t *callback) { - fatalcallback = callback; -} - -void -check_result(isc_result_t result, const char *message) { - if (result != ISC_R_SUCCESS) - fatal("%s: %s", message, isc_result_totext(result)); -} - -void -vbprintf(int level, const char *fmt, ...) { - va_list ap; - if (level > verbose) - return; - va_start(ap, fmt); - fprintf(stderr, "%s: ", program); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -void -type_format(const dns_rdatatype_t type, char *cp, unsigned int size) { - isc_buffer_t b; - isc_region_t r; - isc_result_t result; - - isc_buffer_init(&b, cp, size - 1); - result = dns_rdatatype_totext(type, &b); - check_result(result, "dns_rdatatype_totext()"); - isc_buffer_usedregion(&b, &r); - r.base[r.length] = 0; -} - -void -alg_format(const dns_secalg_t alg, char *cp, unsigned int size) { - isc_buffer_t b; - isc_region_t r; - isc_result_t result; - - isc_buffer_init(&b, cp, size - 1); - result = dns_secalg_totext(alg, &b); - check_result(result, "dns_secalg_totext()"); - isc_buffer_usedregion(&b, &r); - r.base[r.length] = 0; -} - -void -sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size) { - char namestr[DNS_NAME_FORMATSIZE]; - char algstr[DNS_NAME_FORMATSIZE]; - - dns_name_format(&sig->signer, namestr, sizeof(namestr)); - alg_format(sig->algorithm, algstr, sizeof(algstr)); - snprintf(cp, size, "%s/%s/%d", namestr, algstr, sig->keyid); -} - -void -key_format(const dst_key_t *key, char *cp, unsigned int size) { - char namestr[DNS_NAME_FORMATSIZE]; - char algstr[DNS_NAME_FORMATSIZE]; - - dns_name_format(dst_key_name(key), namestr, sizeof(namestr)); - alg_format((dns_secalg_t) dst_key_alg(key), algstr, sizeof(algstr)); - snprintf(cp, size, "%s/%s/%d", namestr, algstr, dst_key_id(key)); -} - -void -setup_logging(int verbose, isc_mem_t *mctx, isc_log_t **logp) { - isc_result_t result; - isc_logdestination_t destination; - isc_logconfig_t *logconfig = NULL; - isc_log_t *log = NULL; - int level; - - if (verbose < 0) - verbose = 0; - switch (verbose) { - case 0: - /* - * We want to see warnings about things like out-of-zone - * data in the master file even when not verbose. - */ - level = ISC_LOG_WARNING; - break; - case 1: - level = ISC_LOG_INFO; - break; - default: - level = ISC_LOG_DEBUG(verbose - 2 + 1); - break; - } - - RUNTIME_CHECK(isc_log_create(mctx, &log, &logconfig) == ISC_R_SUCCESS); - isc_log_setcontext(log); - dns_log_init(log); - dns_log_setcontext(log); - - RUNTIME_CHECK(isc_log_settag(logconfig, program) == ISC_R_SUCCESS); - - /* - * Set up a channel similar to default_stderr except: - * - the logging level is passed in - * - the program name and logging level are printed - * - no time stamp is printed - */ - destination.file.stream = stderr; - destination.file.name = NULL; - destination.file.versions = ISC_LOG_ROLLNEVER; - destination.file.maximum_size = 0; - result = isc_log_createchannel(logconfig, "stderr", - ISC_LOG_TOFILEDESC, - level, - &destination, - ISC_LOG_PRINTTAG|ISC_LOG_PRINTLEVEL); - check_result(result, "isc_log_createchannel()"); - - RUNTIME_CHECK(isc_log_usechannel(logconfig, "stderr", - NULL, NULL) == ISC_R_SUCCESS); - - *logp = log; -} - -void -cleanup_logging(isc_log_t **logp) { - isc_log_t *log; - - REQUIRE(logp != NULL); - - log = *logp; - if (log == NULL) - return; - isc_log_destroy(&log); - isc_log_setcontext(NULL); - dns_log_setcontext(NULL); - logp = NULL; -} - -void -setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) { - isc_result_t result; - isc_entropysource_t *source = NULL; - entropysource_t *elt; - int usekeyboard = ISC_ENTROPY_KEYBOARDMAYBE; - - REQUIRE(ectx != NULL); - - if (*ectx == NULL) { - result = isc_entropy_create(mctx, ectx); - if (result != ISC_R_SUCCESS) - fatal("could not create entropy object"); - ISC_LIST_INIT(sources); - } - - if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) { - usekeyboard = ISC_ENTROPY_KEYBOARDYES; - randomfile = NULL; - } - - result = isc_entropy_usebestsource(*ectx, &source, randomfile, - usekeyboard); - - if (result != ISC_R_SUCCESS) - fatal("could not initialize entropy source: %s", - isc_result_totext(result)); - - if (source != NULL) { - elt = isc_mem_get(mctx, sizeof(*elt)); - if (elt == NULL) - fatal("out of memory"); - elt->source = source; - elt->mctx = mctx; - ISC_LINK_INIT(elt, link); - ISC_LIST_APPEND(sources, elt, link); - } -} - -void -cleanup_entropy(isc_entropy_t **ectx) { - entropysource_t *source; - while (!ISC_LIST_EMPTY(sources)) { - source = ISC_LIST_HEAD(sources); - ISC_LIST_UNLINK(sources, source, link); - isc_entropy_destroysource(&source->source); - isc_mem_put(source->mctx, source, sizeof(*source)); - } - isc_entropy_detach(ectx); -} - -isc_stdtime_t -strtotime(const char *str, isc_int64_t now, isc_int64_t base) { - isc_int64_t val, offset; - isc_result_t result; - char *endp; - - if (str[0] == '+') { - offset = strtol(str + 1, &endp, 0); - if (*endp != '\0') - fatal("time value %s is invalid", str); - val = base + offset; - } else if (strncmp(str, "now+", 4) == 0) { - offset = strtol(str + 4, &endp, 0); - if (*endp != '\0') - fatal("time value %s is invalid", str); - val = now + offset; - } else if (strlen(str) == 8U) { - char timestr[15]; - sprintf(timestr, "%s000000", str); - result = dns_time64_fromtext(timestr, &val); - if (result != ISC_R_SUCCESS) - fatal("time value %s is invalid", str); - } else { - result = dns_time64_fromtext(str, &val); - if (result != ISC_R_SUCCESS) - fatal("time value %s is invalid", str); - } - - return ((isc_stdtime_t) val); -} - -dns_rdataclass_t -strtoclass(const char *str) { - isc_textregion_t r; - dns_rdataclass_t rdclass; - isc_result_t ret; - - if (str == NULL) - return dns_rdataclass_in; - DE_CONST(str, r.base); - r.length = strlen(str); - ret = dns_rdataclass_fromtext(&rdclass, &r); - if (ret != ISC_R_SUCCESS) - fatal("unknown class %s", str); - return (rdclass); -} diff --git a/contrib/bind9/bin/dnssec/dnssectool.h b/contrib/bind9/bin/dnssec/dnssectool.h deleted file mode 100644 index c5f3648..0000000 --- a/contrib/bind9/bin/dnssec/dnssectool.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: dnssectool.h,v 1.18 2004/03/05 04:57:41 marka Exp $ */ - -#ifndef DNSSECTOOL_H -#define DNSSECTOOL_H 1 - -#include -#include -#include -#include - -typedef void (fatalcallback_t)(void); - -void -fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); - -void -setfatalcallback(fatalcallback_t *callback); - -void -check_result(isc_result_t result, const char *message); - -void -vbprintf(int level, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3); - -void -type_format(const dns_rdatatype_t type, char *cp, unsigned int size); -#define TYPE_FORMATSIZE 10 - -void -alg_format(const dns_secalg_t alg, char *cp, unsigned int size); -#define ALG_FORMATSIZE 10 - -void -sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size); -#define SIG_FORMATSIZE (DNS_NAME_FORMATSIZE + ALG_FORMATSIZE + sizeof("65535")) - -void -key_format(const dst_key_t *key, char *cp, unsigned int size); -#define KEY_FORMATSIZE (DNS_NAME_FORMATSIZE + ALG_FORMATSIZE + sizeof("65535")) - -void -setup_logging(int verbose, isc_mem_t *mctx, isc_log_t **logp); - -void -cleanup_logging(isc_log_t **logp); - -void -setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx); - -void -cleanup_entropy(isc_entropy_t **ectx); - -isc_stdtime_t -strtotime(const char *str, isc_int64_t now, isc_int64_t base); - -dns_rdataclass_t -strtoclass(const char *str); - -#endif /* DNSSEC_DNSSECTOOL_H */ diff --git a/contrib/bind9/bin/named/Makefile.in b/contrib/bind9/bin/named/Makefile.in deleted file mode 100644 index a809e59c..0000000 --- a/contrib/bind9/bin/named/Makefile.in +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 1998-2002 Internet Software Consortium. -# -# Permission to use, copy, modify, and 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: Makefile.in,v 1.80.18.7 2005/09/05 00:18:10 marka Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -@BIND9_VERSION@ - -@BIND9_MAKE_INCLUDES@ - -# -# Add database drivers here. -# -DBDRIVER_OBJS = -DBDRIVER_SRCS = -DBDRIVER_INCLUDES = -DBDRIVER_LIBS = - -DLZ_DRIVER_DIR = ${top_srcdir}/contrib/dlz/drivers - -DLZDRIVER_OBJS = @DLZ_DRIVER_OBJS@ -DLZDRIVER_SRCS = @DLZ_DRIVER_SRCS@ -DLZDRIVER_INCLUDES = @DLZ_DRIVER_INCLUDES@ -DLZDRIVER_LIBS = @DLZ_DRIVER_LIBS@ - -CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include \ - ${LWRES_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} \ - ${ISCCFG_INCLUDES} ${ISCCC_INCLUDES} ${ISC_INCLUDES} \ - ${DLZDRIVER_INCLUDES} ${DBDRIVER_INCLUDES} - -CDEFINES = @USE_DLZ@ - -CWARNINGS = - -DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ -ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ -ISCCCLIBS = ../../lib/isccc/libisccc.@A@ -ISCLIBS = ../../lib/isc/libisc.@A@ -LWRESLIBS = ../../lib/lwres/liblwres.@A@ -BIND9LIBS = ../../lib/bind9/libbind9.@A@ - -DNSDEPLIBS = ../../lib/dns/libdns.@A@ -ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ -ISCCCDEPLIBS = ../../lib/isccc/libisccc.@A@ -ISCDEPLIBS = ../../lib/isc/libisc.@A@ -LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@ -BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ - -DEPLIBS = ${LWRESDEPLIBS} ${DNSDEPLIBS} ${BIND9DEPLIBS} \ - ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${ISCDEPLIBS} - -LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \ - ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCLIBS} \ - ${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBS@ - -SUBDIRS = unix - -TARGETS = named@EXEEXT@ lwresd@EXEEXT@ - -OBJS = builtin.@O@ client.@O@ config.@O@ control.@O@ \ - controlconf.@O@ interfacemgr.@O@ \ - listenlist.@O@ log.@O@ logconf.@O@ main.@O@ notify.@O@ \ - query.@O@ server.@O@ sortlist.@O@ \ - tkeyconf.@O@ tsigconf.@O@ update.@O@ xfrout.@O@ \ - zoneconf.@O@ \ - lwaddr.@O@ lwresd.@O@ lwdclient.@O@ lwderror.@O@ lwdgabn.@O@ \ - lwdgnba.@O@ lwdgrbn.@O@ lwdnoop.@O@ lwsearch.@O@ \ - ${DLZDRIVER_OBJS} ${DBDRIVER_OBJS} - -UOBJS = unix/os.@O@ - -SRCS = builtin.c client.c config.c control.c \ - controlconf.c interfacemgr.c \ - listenlist.c log.c logconf.c main.c notify.c \ - query.c server.c sortlist.c \ - tkeyconf.c tsigconf.c update.c xfrout.c \ - zoneconf.c \ - lwaddr.c lwresd.c lwdclient.c lwderror.c lwdgabn.c \ - lwdgnba.c lwdgrbn.c lwdnoop.c lwsearch.c \ - ${DLZDRIVER_SRCS} ${DBDRIVER_SRCS} - -MANPAGES = named.8 lwresd.8 named.conf.5 - -HTMLPAGES = named.html lwresd.html named.conf.html - -MANOBJS = ${MANPAGES} ${HTMLPAGES} - -@BIND9_MAKE_RULES@ - -main.@O@: main.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ - -DVERSION=\"${VERSION}\" \ - -DNS_LOCALSTATEDIR=\"${localstatedir}\" \ - -DNS_SYSCONFDIR=\"${sysconfdir}\" -c ${srcdir}/main.c - -config.@O@: config.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ - -DVERSION=\"${VERSION}\" \ - -DNS_LOCALSTATEDIR=\"${localstatedir}\" \ - -c ${srcdir}/config.c - -named@EXEEXT@: ${OBJS} ${UOBJS} ${DEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ - ${OBJS} ${UOBJS} ${LIBS} - -lwresd@EXEEXT@: named@EXEEXT@ - rm -f lwresd@EXEEXT@ - @LN@ named@EXEEXT@ lwresd@EXEEXT@ - -doc man:: ${MANOBJS} - -docclean manclean maintainer-clean:: - rm -f ${MANOBJS} - -clean distclean maintainer-clean:: - rm -f ${TARGETS} ${OBJS} - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man5 - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 - -install:: named@EXEEXT@ lwresd@EXEEXT@ installdirs - ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named@EXEEXT@ ${DESTDIR}${sbindir} - (cd ${DESTDIR}${sbindir}; rm -f lwresd@EXEEXT@; @LN@ named@EXEEXT@ lwresd@EXEEXT@) - ${INSTALL_DATA} ${srcdir}/named.8 ${DESTDIR}${mandir}/man8 - ${INSTALL_DATA} ${srcdir}/lwresd.8 ${DESTDIR}${mandir}/man8 - ${INSTALL_DATA} ${srcdir}/named.conf.5 ${DESTDIR}${mandir}/man5 - -@DLZ_DRIVER_RULES@ diff --git a/contrib/bind9/bin/named/builtin.c b/contrib/bind9/bin/named/builtin.c deleted file mode 100644 index 06cbd4a..0000000 --- a/contrib/bind9/bin/named/builtin.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: builtin.c,v 1.5.18.5 2005/08/23 04:12:38 marka Exp $ */ - -/*! \file - * \brief - * The built-in "version", "hostname", "id", "authors" and "empty" databases. - */ - -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -typedef struct builtin builtin_t; - -static isc_result_t do_version_lookup(dns_sdblookup_t *lookup); -static isc_result_t do_hostname_lookup(dns_sdblookup_t *lookup); -static isc_result_t do_authors_lookup(dns_sdblookup_t *lookup); -static isc_result_t do_id_lookup(dns_sdblookup_t *lookup); -static isc_result_t do_empty_lookup(dns_sdblookup_t *lookup); - -/* - * We can't use function pointers as the db_data directly - * because ANSI C does not guarantee that function pointers - * can safely be cast to void pointers and back. - */ - -struct builtin { - isc_result_t (*do_lookup)(dns_sdblookup_t *lookup); - char *server; - char *contact; -}; - -static builtin_t version_builtin = { do_version_lookup, NULL, NULL }; -static builtin_t hostname_builtin = { do_hostname_lookup, NULL, NULL }; -static builtin_t authors_builtin = { do_authors_lookup, NULL, NULL }; -static builtin_t id_builtin = { do_id_lookup, NULL, NULL }; -static builtin_t empty_builtin = { do_empty_lookup, NULL, NULL }; - -static dns_sdbimplementation_t *builtin_impl; - -static isc_result_t -builtin_lookup(const char *zone, const char *name, void *dbdata, - dns_sdblookup_t *lookup) -{ - builtin_t *b = (builtin_t *) dbdata; - - UNUSED(zone); - - if (strcmp(name, "@") == 0) - return (b->do_lookup(lookup)); - else - return (ISC_R_NOTFOUND); -} - -static isc_result_t -put_txt(dns_sdblookup_t *lookup, const char *text) { - unsigned char buf[256]; - unsigned int len = strlen(text); - if (len > 255) - len = 255; /* Silently truncate */ - buf[0] = len; - memcpy(&buf[1], text, len); - return (dns_sdb_putrdata(lookup, dns_rdatatype_txt, 0, buf, len + 1)); -} - -static isc_result_t -do_version_lookup(dns_sdblookup_t *lookup) { - if (ns_g_server->version_set) { - if (ns_g_server->version == NULL) - return (ISC_R_SUCCESS); - else - return (put_txt(lookup, ns_g_server->version)); - } else { - return (put_txt(lookup, ns_g_version)); - } -} - -static isc_result_t -do_hostname_lookup(dns_sdblookup_t *lookup) { - if (ns_g_server->hostname_set) { - if (ns_g_server->hostname == NULL) - return (ISC_R_SUCCESS); - else - return (put_txt(lookup, ns_g_server->hostname)); - } else { - char buf[256]; - isc_result_t result = ns_os_gethostname(buf, sizeof(buf)); - if (result != ISC_R_SUCCESS) - return (result); - return (put_txt(lookup, buf)); - } -} - -static isc_result_t -do_authors_lookup(dns_sdblookup_t *lookup) { - isc_result_t result; - const char **p; - static const char *authors[] = { - "Mark Andrews", - "James Brister", - "Ben Cottrell", - "Michael Graff", - "Andreas Gustafsson", - "Bob Halley", - "David Lawrence", - "Danny Mayer", - "Damien Neil", - "Matt Nelson", - "Michael Sawyer", - "Brian Wellington", - NULL - }; - - /* - * If a version string is specified, disable the authors.bind zone. - */ - if (ns_g_server->version_set) - return (ISC_R_SUCCESS); - - for (p = authors; *p != NULL; p++) { - result = put_txt(lookup, *p); - if (result != ISC_R_SUCCESS) - return (result); - } - return (ISC_R_SUCCESS); -} - -static isc_result_t -do_id_lookup(dns_sdblookup_t *lookup) { - - if (ns_g_server->server_usehostname) { - char buf[256]; - isc_result_t result = ns_os_gethostname(buf, sizeof(buf)); - if (result != ISC_R_SUCCESS) - return (result); - return (put_txt(lookup, buf)); - } - - if (ns_g_server->server_id == NULL) - return (ISC_R_SUCCESS); - else - return (put_txt(lookup, ns_g_server->server_id)); -} - -static isc_result_t -do_empty_lookup(dns_sdblookup_t *lookup) { - - UNUSED(lookup); - return (ISC_R_SUCCESS); -} - -static isc_result_t -builtin_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) { - isc_result_t result; - const char *contact = "hostmaster"; - const char *server = "@"; - builtin_t *b = (builtin_t *) dbdata; - - UNUSED(zone); - UNUSED(dbdata); - - if (b == &empty_builtin) { - server = "."; - contact = "."; - } else { - if (b->server != NULL) - server = b->server; - if (b->contact != NULL) - contact = b->contact; - } - - result = dns_sdb_putsoa(lookup, server, contact, 0); - if (result != ISC_R_SUCCESS) - return (ISC_R_FAILURE); - - result = dns_sdb_putrr(lookup, "ns", 0, server); - if (result != ISC_R_SUCCESS) - return (ISC_R_FAILURE); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -builtin_create(const char *zone, int argc, char **argv, - void *driverdata, void **dbdata) -{ - REQUIRE(argc >= 1); - - UNUSED(zone); - UNUSED(driverdata); - - if (strcmp(argv[0], "empty") == 0) { - if (argc != 3) - return (DNS_R_SYNTAX); - } else if (argc != 1) - return (DNS_R_SYNTAX); - - if (strcmp(argv[0], "version") == 0) - *dbdata = &version_builtin; - else if (strcmp(argv[0], "hostname") == 0) - *dbdata = &hostname_builtin; - else if (strcmp(argv[0], "authors") == 0) - *dbdata = &authors_builtin; - else if (strcmp(argv[0], "id") == 0) - *dbdata = &id_builtin; - else if (strcmp(argv[0], "empty") == 0) { - builtin_t *empty; - char *server; - char *contact; - /* - * We don't want built-in zones to fail. Fallback to - * the static configuration if memory allocation fails. - */ - empty = isc_mem_get(ns_g_mctx, sizeof(*empty)); - server = isc_mem_strdup(ns_g_mctx, argv[1]); - contact = isc_mem_strdup(ns_g_mctx, argv[2]); - if (empty == NULL || server == NULL || contact == NULL) { - *dbdata = &empty_builtin; - if (server != NULL) - isc_mem_free(ns_g_mctx, server); - if (contact != NULL) - isc_mem_free(ns_g_mctx, contact); - if (empty != NULL) - isc_mem_put(ns_g_mctx, empty, sizeof (*empty)); - } else { - memcpy(empty, &empty_builtin, sizeof (empty_builtin)); - empty->server = server; - empty->contact = contact; - *dbdata = empty; - } - } else - return (ISC_R_NOTIMPLEMENTED); - return (ISC_R_SUCCESS); -} - -static void -builtin_destroy(const char *zone, void *driverdata, void **dbdata) { - builtin_t *b = (builtin_t *) *dbdata; - - UNUSED(zone); - UNUSED(driverdata); - - /* - * Don't free the static versions. - */ - if (*dbdata == &version_builtin || *dbdata == &hostname_builtin || - *dbdata == &authors_builtin || *dbdata == &id_builtin || - *dbdata == &empty_builtin) - return; - - isc_mem_free(ns_g_mctx, b->server); - isc_mem_free(ns_g_mctx, b->contact); - isc_mem_put(ns_g_mctx, b, sizeof (*b)); -} - -static dns_sdbmethods_t builtin_methods = { - builtin_lookup, - builtin_authority, - NULL, /* allnodes */ - builtin_create, - builtin_destroy -}; - -isc_result_t -ns_builtin_init(void) { - RUNTIME_CHECK(dns_sdb_register("_builtin", &builtin_methods, NULL, - DNS_SDBFLAG_RELATIVEOWNER | - DNS_SDBFLAG_RELATIVERDATA, - ns_g_mctx, &builtin_impl) - == ISC_R_SUCCESS); - return (ISC_R_SUCCESS); -} - -void -ns_builtin_deinit(void) { - dns_sdb_unregister(&builtin_impl); -} diff --git a/contrib/bind9/bin/named/client.c b/contrib/bind9/bin/named/client.c deleted file mode 100644 index b0e9cdd..0000000 --- a/contrib/bind9/bin/named/client.c +++ /dev/null @@ -1,2643 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-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: client.c,v 1.219.18.28 2007/08/28 07:20:00 tbox Exp $ */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/*** - *** Client - ***/ - -/*! \file - * Client Routines - * - * Important note! - * - * All client state changes, other than that from idle to listening, occur - * as a result of events. This guarantees serialization and avoids the - * need for locking. - * - * If a routine is ever created that allows someone other than the client's - * task to change the client, then the client will have to be locked. - */ - -#define NS_CLIENT_TRACE -#ifdef NS_CLIENT_TRACE -#define CTRACE(m) ns_client_log(client, \ - NS_LOGCATEGORY_CLIENT, \ - NS_LOGMODULE_CLIENT, \ - ISC_LOG_DEBUG(3), \ - "%s", (m)) -#define MTRACE(m) isc_log_write(ns_g_lctx, \ - NS_LOGCATEGORY_GENERAL, \ - NS_LOGMODULE_CLIENT, \ - ISC_LOG_DEBUG(3), \ - "clientmgr @%p: %s", manager, (m)) -#else -#define CTRACE(m) ((void)(m)) -#define MTRACE(m) ((void)(m)) -#endif - -#define TCP_CLIENT(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0) - -#define TCP_BUFFER_SIZE (65535 + 2) -#define SEND_BUFFER_SIZE 4096 -#define RECV_BUFFER_SIZE 4096 - -#ifdef ISC_PLATFORM_USETHREADS -#define NMCTXS 100 -/*%< - * Number of 'mctx pools' for clients. (Should this be configurable?) - * When enabling threads, we use a pool of memory contexts shared by - * client objects, since concurrent access to a shared context would cause - * heavy contentions. The above constant is expected to be enough for - * completely avoiding contentions among threads for an authoritative-only - * server. - */ -#else -#define NMCTXS 0 -/*%< - * If named with built without thread, simply share manager's context. Using - * a separate context in this case would simply waste memory. - */ -#endif - -/*% nameserver client manager structure */ -struct ns_clientmgr { - /* Unlocked. */ - unsigned int magic; - isc_mem_t * mctx; - isc_taskmgr_t * taskmgr; - isc_timermgr_t * timermgr; - isc_mutex_t lock; - /* Locked by lock. */ - isc_boolean_t exiting; - client_list_t active; /*%< Active clients */ - client_list_t recursing; /*%< Recursing clients */ - client_list_t inactive; /*%< To be recycled */ -#if NMCTXS > 0 - /*%< mctx pool for clients. */ - unsigned int nextmctx; - isc_mem_t * mctxpool[NMCTXS]; -#endif -}; - -#define MANAGER_MAGIC ISC_MAGIC('N', 'S', 'C', 'm') -#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, MANAGER_MAGIC) - -/*! - * Client object states. Ordering is significant: higher-numbered - * states are generally "more active", meaning that the client can - * have more dynamically allocated data, outstanding events, etc. - * In the list below, any such properties listed for state N - * also apply to any state > N. - * - * To force the client into a less active state, set client->newstate - * to that state and call exit_check(). This will cause any - * activities defined for higher-numbered states to be aborted. - */ - -#define NS_CLIENTSTATE_FREED 0 -/*%< - * The client object no longer exists. - */ - -#define NS_CLIENTSTATE_INACTIVE 1 -/*%< - * The client object exists and has a task and timer. - * Its "query" struct and sendbuf are initialized. - * It is on the client manager's list of inactive clients. - * It has a message and OPT, both in the reset state. - */ - -#define NS_CLIENTSTATE_READY 2 -/*%< - * The client object is either a TCP or a UDP one, and - * it is associated with a network interface. It is on the - * client manager's list of active clients. - * - * If it is a TCP client object, it has a TCP listener socket - * and an outstanding TCP listen request. - * - * If it is a UDP client object, it has a UDP listener socket - * and an outstanding UDP receive request. - */ - -#define NS_CLIENTSTATE_READING 3 -/*%< - * The client object is a TCP client object that has received - * a connection. It has a tcpsocket, tcpmsg, TCP quota, and an - * outstanding TCP read request. This state is not used for - * UDP client objects. - */ - -#define NS_CLIENTSTATE_WORKING 4 -/*%< - * The client object has received a request and is working - * on it. It has a view, and it may have any of a non-reset OPT, - * recursion quota, and an outstanding write request. - */ - -#define NS_CLIENTSTATE_MAX 9 -/*%< - * Sentinel value used to indicate "no state". When client->newstate - * has this value, we are not attempting to exit the current state. - * Must be greater than any valid state. - */ - -/* - * Enable ns_client_dropport() by default. - */ -#ifndef NS_CLIENT_DROPPORT -#define NS_CLIENT_DROPPORT 1 -#endif - -unsigned int ns_client_requests; - -static void client_read(ns_client_t *client); -static void client_accept(ns_client_t *client); -static void client_udprecv(ns_client_t *client); -static void clientmgr_destroy(ns_clientmgr_t *manager); -static isc_boolean_t exit_check(ns_client_t *client); -static void ns_client_endrequest(ns_client_t *client); -static void ns_client_checkactive(ns_client_t *client); -static void client_start(isc_task_t *task, isc_event_t *event); -static void client_request(isc_task_t *task, isc_event_t *event); -static void ns_client_dumpmessage(ns_client_t *client, const char *reason); - -void -ns_client_recursing(ns_client_t *client) { - REQUIRE(NS_CLIENT_VALID(client)); - - LOCK(&client->manager->lock); - ISC_LIST_UNLINK(*client->list, client, link); - ISC_LIST_APPEND(client->manager->recursing, client, link); - client->list = &client->manager->recursing; - UNLOCK(&client->manager->lock); -} - -void -ns_client_killoldestquery(ns_client_t *client) { - ns_client_t *oldest; - REQUIRE(NS_CLIENT_VALID(client)); - - LOCK(&client->manager->lock); - oldest = ISC_LIST_HEAD(client->manager->recursing); - if (oldest != NULL) { - ns_query_cancel(oldest); - ISC_LIST_UNLINK(*oldest->list, oldest, link); - ISC_LIST_APPEND(client->manager->active, oldest, link); - oldest->list = &client->manager->active; - } - UNLOCK(&client->manager->lock); -} - -void -ns_client_settimeout(ns_client_t *client, unsigned int seconds) { - isc_result_t result; - isc_interval_t interval; - - isc_interval_set(&interval, seconds, 0); - result = isc_timer_reset(client->timer, isc_timertype_once, NULL, - &interval, ISC_FALSE); - client->timerset = ISC_TRUE; - if (result != ISC_R_SUCCESS) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_ERROR, - "setting timeout: %s", - isc_result_totext(result)); - /* Continue anyway. */ - } -} - -/*% - * Check for a deactivation or shutdown request and take appropriate - * action. Returns ISC_TRUE if either is in progress; in this case - * the caller must no longer use the client object as it may have been - * freed. - */ -static isc_boolean_t -exit_check(ns_client_t *client) { - ns_clientmgr_t *locked_manager = NULL; - ns_clientmgr_t *destroy_manager = NULL; - - REQUIRE(NS_CLIENT_VALID(client)); - - if (client->state <= client->newstate) - return (ISC_FALSE); /* Business as usual. */ - - INSIST(client->newstate < NS_CLIENTSTATE_WORKING); - - /* - * We need to detach from the view early when shutting down - * the server to break the following vicious circle: - * - * - The resolver will not shut down until the view refcount is zero - * - The view refcount does not go to zero until all clients detach - * - The client does not detach from the view until references is zero - * - references does not go to zero until the resolver has shut down - * - * Keep the view attached until any outstanding updates complete. - */ - if (client->nupdates == 0 && - client->newstate == NS_CLIENTSTATE_FREED && client->view != NULL) - dns_view_detach(&client->view); - - if (client->state == NS_CLIENTSTATE_WORKING) { - INSIST(client->newstate <= NS_CLIENTSTATE_READING); - /* - * Let the update processing complete. - */ - if (client->nupdates > 0) - return (ISC_TRUE); - /* - * We are trying to abort request processing. - */ - if (client->nsends > 0) { - isc_socket_t *socket; - if (TCP_CLIENT(client)) - socket = client->tcpsocket; - else - socket = client->udpsocket; - isc_socket_cancel(socket, client->task, - ISC_SOCKCANCEL_SEND); - } - - if (! (client->nsends == 0 && client->nrecvs == 0 && - client->references == 0)) - { - /* - * Still waiting for I/O cancel completion. - * or lingering references. - */ - return (ISC_TRUE); - } - /* - * I/O cancel is complete. Burn down all state - * related to the current request. Ensure that - * the client is on the active list and not the - * recursing list. - */ - LOCK(&client->manager->lock); - if (client->list == &client->manager->recursing) { - ISC_LIST_UNLINK(*client->list, client, link); - ISC_LIST_APPEND(client->manager->active, client, link); - client->list = &client->manager->active; - } - UNLOCK(&client->manager->lock); - ns_client_endrequest(client); - - client->state = NS_CLIENTSTATE_READING; - INSIST(client->recursionquota == NULL); - if (NS_CLIENTSTATE_READING == client->newstate) { - client_read(client); - client->newstate = NS_CLIENTSTATE_MAX; - return (ISC_TRUE); /* We're done. */ - } - } - - if (client->state == NS_CLIENTSTATE_READING) { - /* - * We are trying to abort the current TCP connection, - * if any. - */ - INSIST(client->recursionquota == NULL); - INSIST(client->newstate <= NS_CLIENTSTATE_READY); - if (client->nreads > 0) - dns_tcpmsg_cancelread(&client->tcpmsg); - if (! client->nreads == 0) { - /* Still waiting for read cancel completion. */ - return (ISC_TRUE); - } - - if (client->tcpmsg_valid) { - dns_tcpmsg_invalidate(&client->tcpmsg); - client->tcpmsg_valid = ISC_FALSE; - } - if (client->tcpsocket != NULL) { - CTRACE("closetcp"); - isc_socket_detach(&client->tcpsocket); - } - - if (client->tcpquota != NULL) - isc_quota_detach(&client->tcpquota); - - if (client->timerset) { - (void)isc_timer_reset(client->timer, - isc_timertype_inactive, - NULL, NULL, ISC_TRUE); - client->timerset = ISC_FALSE; - } - - client->peeraddr_valid = ISC_FALSE; - - client->state = NS_CLIENTSTATE_READY; - INSIST(client->recursionquota == NULL); - - /* - * Now the client is ready to accept a new TCP connection - * or UDP request, but we may have enough clients doing - * that already. Check whether this client needs to remain - * active and force it to go inactive if not. - */ - ns_client_checkactive(client); - - if (NS_CLIENTSTATE_READY == client->newstate) { - if (TCP_CLIENT(client)) { - client_accept(client); - } else - client_udprecv(client); - client->newstate = NS_CLIENTSTATE_MAX; - return (ISC_TRUE); - } - } - - if (client->state == NS_CLIENTSTATE_READY) { - INSIST(client->newstate <= NS_CLIENTSTATE_INACTIVE); - /* - * We are trying to enter the inactive state. - */ - if (client->naccepts > 0) - isc_socket_cancel(client->tcplistener, client->task, - ISC_SOCKCANCEL_ACCEPT); - - if (! (client->naccepts == 0)) { - /* Still waiting for accept cancel completion. */ - return (ISC_TRUE); - } - /* Accept cancel is complete. */ - - if (client->nrecvs > 0) - isc_socket_cancel(client->udpsocket, client->task, - ISC_SOCKCANCEL_RECV); - if (! (client->nrecvs == 0)) { - /* Still waiting for recv cancel completion. */ - return (ISC_TRUE); - } - /* Recv cancel is complete. */ - - if (client->nctls > 0) { - /* Still waiting for control event to be delivered */ - return (ISC_TRUE); - } - - /* Deactivate the client. */ - if (client->interface) - ns_interface_detach(&client->interface); - - INSIST(client->naccepts == 0); - INSIST(client->recursionquota == NULL); - if (client->tcplistener != NULL) - isc_socket_detach(&client->tcplistener); - - if (client->udpsocket != NULL) - isc_socket_detach(&client->udpsocket); - - if (client->dispatch != NULL) - dns_dispatch_detach(&client->dispatch); - - client->attributes = 0; - client->mortal = ISC_FALSE; - - LOCK(&client->manager->lock); - /* - * Put the client on the inactive list. If we are aiming for - * the "freed" state, it will be removed from the inactive - * list shortly, and we need to keep the manager locked until - * that has been done, lest the manager decide to reactivate - * the dying client inbetween. - */ - locked_manager = client->manager; - ISC_LIST_UNLINK(*client->list, client, link); - ISC_LIST_APPEND(client->manager->inactive, client, link); - client->list = &client->manager->inactive; - client->state = NS_CLIENTSTATE_INACTIVE; - INSIST(client->recursionquota == NULL); - - if (client->state == client->newstate) { - client->newstate = NS_CLIENTSTATE_MAX; - goto unlock; - } - } - - if (client->state == NS_CLIENTSTATE_INACTIVE) { - INSIST(client->newstate == NS_CLIENTSTATE_FREED); - /* - * We are trying to free the client. - * - * When "shuttingdown" is true, either the task has received - * its shutdown event or no shutdown event has ever been - * set up. Thus, we have no outstanding shutdown - * event at this point. - */ - REQUIRE(client->state == NS_CLIENTSTATE_INACTIVE); - - INSIST(client->recursionquota == NULL); - - ns_query_free(client); - isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE); - isc_event_free((isc_event_t **)&client->sendevent); - isc_event_free((isc_event_t **)&client->recvevent); - isc_timer_detach(&client->timer); - - if (client->tcpbuf != NULL) - isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); - if (client->opt != NULL) { - INSIST(dns_rdataset_isassociated(client->opt)); - dns_rdataset_disassociate(client->opt); - dns_message_puttemprdataset(client->message, &client->opt); - } - dns_message_destroy(&client->message); - if (client->manager != NULL) { - ns_clientmgr_t *manager = client->manager; - if (locked_manager == NULL) { - LOCK(&manager->lock); - locked_manager = manager; - } - ISC_LIST_UNLINK(*client->list, client, link); - client->list = NULL; - if (manager->exiting && - ISC_LIST_EMPTY(manager->active) && - ISC_LIST_EMPTY(manager->inactive) && - ISC_LIST_EMPTY(manager->recursing)) - destroy_manager = manager; - } - /* - * Detaching the task must be done after unlinking from - * the manager's lists because the manager accesses - * client->task. - */ - if (client->task != NULL) - isc_task_detach(&client->task); - - CTRACE("free"); - client->magic = 0; - isc_mem_putanddetach(&client->mctx, client, sizeof(*client)); - - goto unlock; - } - - unlock: - if (locked_manager != NULL) { - UNLOCK(&locked_manager->lock); - locked_manager = NULL; - } - - /* - * Only now is it safe to destroy the client manager (if needed), - * because we have accessed its lock for the last time. - */ - if (destroy_manager != NULL) - clientmgr_destroy(destroy_manager); - - return (ISC_TRUE); -} - -/*% - * The client's task has received the client's control event - * as part of the startup process. - */ -static void -client_start(isc_task_t *task, isc_event_t *event) { - ns_client_t *client = (ns_client_t *) event->ev_arg; - - INSIST(task == client->task); - - UNUSED(task); - - INSIST(client->nctls == 1); - client->nctls--; - - if (exit_check(client)) - return; - - if (TCP_CLIENT(client)) { - client_accept(client); - } else { - client_udprecv(client); - } -} - - -/*% - * The client's task has received a shutdown event. - */ -static void -client_shutdown(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - - REQUIRE(event != NULL); - REQUIRE(event->ev_type == ISC_TASKEVENT_SHUTDOWN); - client = event->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - - UNUSED(task); - - CTRACE("shutdown"); - - isc_event_free(&event); - - if (client->shutdown != NULL) { - (client->shutdown)(client->shutdown_arg, ISC_R_SHUTTINGDOWN); - client->shutdown = NULL; - client->shutdown_arg = NULL; - } - - client->newstate = NS_CLIENTSTATE_FREED; - (void)exit_check(client); -} - -static void -ns_client_endrequest(ns_client_t *client) { - INSIST(client->naccepts == 0); - INSIST(client->nreads == 0); - INSIST(client->nsends == 0); - INSIST(client->nrecvs == 0); - INSIST(client->nupdates == 0); - INSIST(client->state == NS_CLIENTSTATE_WORKING); - - CTRACE("endrequest"); - - if (client->next != NULL) { - (client->next)(client); - client->next = NULL; - } - - if (client->view != NULL) - dns_view_detach(&client->view); - if (client->opt != NULL) { - INSIST(dns_rdataset_isassociated(client->opt)); - dns_rdataset_disassociate(client->opt); - dns_message_puttemprdataset(client->message, &client->opt); - } - - client->udpsize = 512; - client->extflags = 0; - client->ednsversion = -1; - dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE); - - if (client->recursionquota != NULL) - isc_quota_detach(&client->recursionquota); - - /* - * Clear all client attributes that are specific to - * the request; that's all except the TCP flag. - */ - client->attributes &= NS_CLIENTATTR_TCP; -} - -static void -ns_client_checkactive(ns_client_t *client) { - if (client->mortal) { - /* - * This client object should normally go inactive - * at this point, but if we have fewer active client - * objects than desired due to earlier quota exhaustion, - * keep it active to make up for the shortage. - */ - isc_boolean_t need_another_client = ISC_FALSE; - if (TCP_CLIENT(client)) { - LOCK(&client->interface->lock); - if (client->interface->ntcpcurrent < - client->interface->ntcptarget) - need_another_client = ISC_TRUE; - UNLOCK(&client->interface->lock); - } else { - /* - * The UDP client quota is enforced by making - * requests fail rather than by not listening - * for new ones. Therefore, there is always a - * full set of UDP clients listening. - */ - } - if (! need_another_client) { - /* - * We don't need this client object. Recycle it. - */ - if (client->newstate >= NS_CLIENTSTATE_INACTIVE) - client->newstate = NS_CLIENTSTATE_INACTIVE; - } - } -} - -void -ns_client_next(ns_client_t *client, isc_result_t result) { - int newstate; - - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(client->state == NS_CLIENTSTATE_WORKING || - client->state == NS_CLIENTSTATE_READING); - - CTRACE("next"); - - if (result != ISC_R_SUCCESS) - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "request failed: %s", isc_result_totext(result)); - - /* - * An error processing a TCP request may have left - * the connection out of sync. To be safe, we always - * sever the connection when result != ISC_R_SUCCESS. - */ - if (result == ISC_R_SUCCESS && TCP_CLIENT(client)) - newstate = NS_CLIENTSTATE_READING; - else - newstate = NS_CLIENTSTATE_READY; - - if (client->newstate > newstate) - client->newstate = newstate; - (void)exit_check(client); -} - - -static void -client_senddone(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - isc_socketevent_t *sevent = (isc_socketevent_t *) event; - - REQUIRE(sevent != NULL); - REQUIRE(sevent->ev_type == ISC_SOCKEVENT_SENDDONE); - client = sevent->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - REQUIRE(sevent == client->sendevent); - - UNUSED(task); - - CTRACE("senddone"); - - if (sevent->result != ISC_R_SUCCESS) - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_WARNING, - "error sending response: %s", - isc_result_totext(sevent->result)); - - INSIST(client->nsends > 0); - client->nsends--; - - if (client->tcpbuf != NULL) { - INSIST(TCP_CLIENT(client)); - isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); - client->tcpbuf = NULL; - } - - if (exit_check(client)) - return; - - ns_client_next(client, ISC_R_SUCCESS); -} - -/*% - * We only want to fail with ISC_R_NOSPACE when called from - * ns_client_sendraw() and not when called from ns_client_send(), - * tcpbuffer is NULL when called from ns_client_sendraw() and - * length != 0. tcpbuffer != NULL when called from ns_client_send() - * and length == 0. - */ - -static isc_result_t -client_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer, - isc_buffer_t *tcpbuffer, isc_uint32_t length, - unsigned char *sendbuf, unsigned char **datap) -{ - unsigned char *data; - isc_uint32_t bufsize; - isc_result_t result; - - INSIST(datap != NULL); - INSIST((tcpbuffer == NULL && length != 0) || - (tcpbuffer != NULL && length == 0)); - - if (TCP_CLIENT(client)) { - INSIST(client->tcpbuf == NULL); - if (length + 2 > TCP_BUFFER_SIZE) { - result = ISC_R_NOSPACE; - goto done; - } - client->tcpbuf = isc_mem_get(client->mctx, TCP_BUFFER_SIZE); - if (client->tcpbuf == NULL) { - result = ISC_R_NOMEMORY; - goto done; - } - data = client->tcpbuf; - if (tcpbuffer != NULL) { - isc_buffer_init(tcpbuffer, data, TCP_BUFFER_SIZE); - isc_buffer_init(buffer, data + 2, TCP_BUFFER_SIZE - 2); - } else { - isc_buffer_init(buffer, data, TCP_BUFFER_SIZE); - INSIST(length <= 0xffff); - isc_buffer_putuint16(buffer, (isc_uint16_t)length); - } - } else { - data = sendbuf; - if (client->udpsize < SEND_BUFFER_SIZE) - bufsize = client->udpsize; - else - bufsize = SEND_BUFFER_SIZE; - if (length > bufsize) { - result = ISC_R_NOSPACE; - goto done; - } - isc_buffer_init(buffer, data, bufsize); - } - *datap = data; - result = ISC_R_SUCCESS; - - done: - return (result); -} - -static isc_result_t -client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) { - struct in6_pktinfo *pktinfo; - isc_result_t result; - isc_region_t r; - isc_sockaddr_t *address; - isc_socket_t *socket; - isc_netaddr_t netaddr; - int match; - unsigned int sockflags = ISC_SOCKFLAG_IMMEDIATE; - - if (TCP_CLIENT(client)) { - socket = client->tcpsocket; - address = NULL; - } else { - socket = client->udpsocket; - address = &client->peeraddr; - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - if (ns_g_server->blackholeacl != NULL && - dns_acl_match(&netaddr, NULL, - ns_g_server->blackholeacl, - &ns_g_server->aclenv, - &match, NULL) == ISC_R_SUCCESS && - match > 0) - return (DNS_R_BLACKHOLED); - sockflags |= ISC_SOCKFLAG_NORETRY; - } - - if ((client->attributes & NS_CLIENTATTR_PKTINFO) != 0 && - (client->attributes & NS_CLIENTATTR_MULTICAST) == 0) - pktinfo = &client->pktinfo; - else - pktinfo = NULL; - - isc_buffer_usedregion(buffer, &r); - - CTRACE("sendto"); - - result = isc_socket_sendto2(socket, &r, client->task, - address, pktinfo, - client->sendevent, sockflags); - if (result == ISC_R_SUCCESS || result == ISC_R_INPROGRESS) { - client->nsends++; - if (result == ISC_R_SUCCESS) - client_senddone(client->task, - (isc_event_t *)client->sendevent); - result = ISC_R_SUCCESS; - } - return (result); -} - -void -ns_client_sendraw(ns_client_t *client, dns_message_t *message) { - isc_result_t result; - unsigned char *data; - isc_buffer_t buffer; - isc_region_t r; - isc_region_t *mr; - unsigned char sendbuf[SEND_BUFFER_SIZE]; - - REQUIRE(NS_CLIENT_VALID(client)); - - CTRACE("sendraw"); - - mr = dns_message_getrawmessage(message); - if (mr == NULL) { - result = ISC_R_UNEXPECTEDEND; - goto done; - } - - result = client_allocsendbuf(client, &buffer, NULL, mr->length, - sendbuf, &data); - if (result != ISC_R_SUCCESS) - goto done; - - /* - * Copy message to buffer and fixup id. - */ - isc_buffer_availableregion(&buffer, &r); - result = isc_buffer_copyregion(&buffer, mr); - if (result != ISC_R_SUCCESS) - goto done; - r.base[0] = (client->message->id >> 8) & 0xff; - r.base[1] = client->message->id & 0xff; - - result = client_sendpkg(client, &buffer); - if (result == ISC_R_SUCCESS) - return; - - done: - if (client->tcpbuf != NULL) { - isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); - client->tcpbuf = NULL; - } - ns_client_next(client, result); -} - -void -ns_client_send(ns_client_t *client) { - isc_result_t result; - unsigned char *data; - isc_buffer_t buffer; - isc_buffer_t tcpbuffer; - isc_region_t r; - dns_compress_t cctx; - isc_boolean_t cleanup_cctx = ISC_FALSE; - unsigned char sendbuf[SEND_BUFFER_SIZE]; - unsigned int dnssec_opts; - unsigned int preferred_glue; - - REQUIRE(NS_CLIENT_VALID(client)); - - CTRACE("send"); - - if ((client->attributes & NS_CLIENTATTR_RA) != 0) - client->message->flags |= DNS_MESSAGEFLAG_RA; - - if ((client->attributes & NS_CLIENTATTR_WANTDNSSEC) != 0) - dnssec_opts = 0; - else - dnssec_opts = DNS_MESSAGERENDER_OMITDNSSEC; - - preferred_glue = 0; - if (client->view != NULL) { - if (client->view->preferred_glue == dns_rdatatype_a) - preferred_glue = DNS_MESSAGERENDER_PREFER_A; - else if (client->view->preferred_glue == dns_rdatatype_aaaa) - preferred_glue = DNS_MESSAGERENDER_PREFER_AAAA; - } - - /* - * XXXRTH The following doesn't deal with TCP buffer resizing. - */ - result = client_allocsendbuf(client, &buffer, &tcpbuffer, 0, - sendbuf, &data); - if (result != ISC_R_SUCCESS) - goto done; - - result = dns_compress_init(&cctx, -1, client->mctx); - if (result != ISC_R_SUCCESS) - goto done; - cleanup_cctx = ISC_TRUE; - - result = dns_message_renderbegin(client->message, &cctx, &buffer); - if (result != ISC_R_SUCCESS) - goto done; - if (client->opt != NULL) { - result = dns_message_setopt(client->message, client->opt); - /* - * XXXRTH dns_message_setopt() should probably do this... - */ - client->opt = NULL; - if (result != ISC_R_SUCCESS) - goto done; - } - result = dns_message_rendersection(client->message, - DNS_SECTION_QUESTION, 0); - if (result == ISC_R_NOSPACE) { - client->message->flags |= DNS_MESSAGEFLAG_TC; - goto renderend; - } - if (result != ISC_R_SUCCESS) - goto done; - result = dns_message_rendersection(client->message, - DNS_SECTION_ANSWER, - DNS_MESSAGERENDER_PARTIAL | - dnssec_opts); - if (result == ISC_R_NOSPACE) { - client->message->flags |= DNS_MESSAGEFLAG_TC; - goto renderend; - } - if (result != ISC_R_SUCCESS) - goto done; - result = dns_message_rendersection(client->message, - DNS_SECTION_AUTHORITY, - DNS_MESSAGERENDER_PARTIAL | - dnssec_opts); - if (result == ISC_R_NOSPACE) { - client->message->flags |= DNS_MESSAGEFLAG_TC; - goto renderend; - } - if (result != ISC_R_SUCCESS) - goto done; - result = dns_message_rendersection(client->message, - DNS_SECTION_ADDITIONAL, - preferred_glue | dnssec_opts); - if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE) - goto done; - renderend: - result = dns_message_renderend(client->message); - - if (result != ISC_R_SUCCESS) - goto done; - - if (cleanup_cctx) { - dns_compress_invalidate(&cctx); - cleanup_cctx = ISC_FALSE; - } - - if (TCP_CLIENT(client)) { - isc_buffer_usedregion(&buffer, &r); - isc_buffer_putuint16(&tcpbuffer, (isc_uint16_t) r.length); - isc_buffer_add(&tcpbuffer, r.length); - result = client_sendpkg(client, &tcpbuffer); - } else - result = client_sendpkg(client, &buffer); - if (result == ISC_R_SUCCESS) - return; - - done: - if (client->tcpbuf != NULL) { - isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); - client->tcpbuf = NULL; - } - - if (cleanup_cctx) - dns_compress_invalidate(&cctx); - - ns_client_next(client, result); -} - -#if NS_CLIENT_DROPPORT -#define DROPPORT_NO 0 -#define DROPPORT_REQUEST 1 -#define DROPPORT_RESPONSE 2 -/*% - * ns_client_dropport determines if certain requests / responses - * should be dropped based on the port number. - * - * Returns: - * \li 0: Don't drop. - * \li 1: Drop request. - * \li 2: Drop (error) response. - */ -static int -ns_client_dropport(in_port_t port) { - switch (port) { - case 7: /* echo */ - case 13: /* daytime */ - case 19: /* chargen */ - case 37: /* time */ - return (DROPPORT_REQUEST); - case 464: /* kpasswd */ - return (DROPPORT_RESPONSE); - } - return (DROPPORT_NO); -} -#endif - -void -ns_client_error(ns_client_t *client, isc_result_t result) { - dns_rcode_t rcode; - dns_message_t *message; - - REQUIRE(NS_CLIENT_VALID(client)); - - CTRACE("error"); - - message = client->message; - rcode = dns_result_torcode(result); - -#if NS_CLIENT_DROPPORT - /* - * Don't send FORMERR to ports on the drop port list. - */ - if (rcode == dns_rcode_formerr && - ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) != - DROPPORT_NO) { - char buf[64]; - isc_buffer_t b; - - isc_buffer_init(&b, buf, sizeof(buf) - 1); - if (dns_rcode_totext(rcode, &b) != ISC_R_SUCCESS) - isc_buffer_putstr(&b, "UNKNOWN RCODE"); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "dropped error (%.*s) response: suspicious port", - (int)isc_buffer_usedlength(&b), buf); - ns_client_next(client, ISC_R_SUCCESS); - return; - } -#endif - - /* - * Message may be an in-progress reply that we had trouble - * with, in which case QR will be set. We need to clear QR before - * calling dns_message_reply() to avoid triggering an assertion. - */ - message->flags &= ~DNS_MESSAGEFLAG_QR; - /* - * AA and AD shouldn't be set. - */ - message->flags &= ~(DNS_MESSAGEFLAG_AA | DNS_MESSAGEFLAG_AD); - result = dns_message_reply(message, ISC_TRUE); - if (result != ISC_R_SUCCESS) { - /* - * It could be that we've got a query with a good header, - * but a bad question section, so we try again with - * want_question_section set to ISC_FALSE. - */ - result = dns_message_reply(message, ISC_FALSE); - if (result != ISC_R_SUCCESS) { - ns_client_next(client, result); - return; - } - } - message->rcode = rcode; - - /* - * FORMERR loop avoidance: If we sent a FORMERR message - * with the same ID to the same client less than two - * seconds ago, assume that we are in an infinite error - * packet dialog with a server for some protocol whose - * error responses look enough like DNS queries to - * elicit a FORMERR response. Drop a packet to break - * the loop. - */ - if (rcode == dns_rcode_formerr) { - if (isc_sockaddr_equal(&client->peeraddr, - &client->formerrcache.addr) && - message->id == client->formerrcache.id && - client->requesttime - client->formerrcache.time < 2) { - /* Drop packet. */ - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "possible error packet loop, " - "FORMERR dropped"); - ns_client_next(client, result); - return; - } - client->formerrcache.addr = client->peeraddr; - client->formerrcache.time = client->requesttime; - client->formerrcache.id = message->id; - } - ns_client_send(client); -} - -static inline isc_result_t -client_addopt(ns_client_t *client) { - dns_rdataset_t *rdataset; - dns_rdatalist_t *rdatalist; - dns_rdata_t *rdata; - isc_result_t result; - dns_view_t *view; - dns_resolver_t *resolver; - isc_uint16_t udpsize; - - REQUIRE(client->opt == NULL); /* XXXRTH free old. */ - - rdatalist = NULL; - result = dns_message_gettemprdatalist(client->message, &rdatalist); - if (result != ISC_R_SUCCESS) - return (result); - rdata = NULL; - result = dns_message_gettemprdata(client->message, &rdata); - if (result != ISC_R_SUCCESS) - return (result); - rdataset = NULL; - result = dns_message_gettemprdataset(client->message, &rdataset); - if (result != ISC_R_SUCCESS) - return (result); - dns_rdataset_init(rdataset); - - rdatalist->type = dns_rdatatype_opt; - rdatalist->covers = 0; - - /* - * Set the maximum UDP buffer size. - */ - view = client->view; - resolver = (view != NULL) ? view->resolver : NULL; - if (resolver != NULL) - udpsize = dns_resolver_getudpsize(resolver); - else - udpsize = ns_g_udpsize; - rdatalist->rdclass = udpsize; - - /* - * Set EXTENDED-RCODE, VERSION and Z to 0. - */ - rdatalist->ttl = (client->extflags & DNS_MESSAGEEXTFLAG_REPLYPRESERVE); - - /* - * No EDNS options in the default case. - */ - rdata->data = NULL; - rdata->length = 0; - rdata->rdclass = rdatalist->rdclass; - rdata->type = rdatalist->type; - rdata->flags = 0; - - ISC_LIST_INIT(rdatalist->rdata); - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) - == ISC_R_SUCCESS); - - client->opt = rdataset; - - return (ISC_R_SUCCESS); -} - -static inline isc_boolean_t -allowed(isc_netaddr_t *addr, dns_name_t *signer, dns_acl_t *acl) { - int match; - isc_result_t result; - - if (acl == NULL) - return (ISC_TRUE); - result = dns_acl_match(addr, signer, acl, &ns_g_server->aclenv, - &match, NULL); - if (result == ISC_R_SUCCESS && match > 0) - return (ISC_TRUE); - return (ISC_FALSE); -} - -/* - * Callback to see if a non-recursive query coming from 'srcaddr' to - * 'destaddr', with optional key 'mykey' for class 'rdclass' would be - * delivered to 'myview'. - * - * We run this unlocked as both the view list and the interface list - * are updated when the approprite task has exclusivity. - */ -isc_boolean_t -ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *dstaddr, - dns_rdataclass_t rdclass, void *arg) -{ - dns_view_t *view; - dns_tsigkey_t *key = NULL; - dns_name_t *tsig = NULL; - isc_netaddr_t netsrc; - isc_netaddr_t netdst; - - UNUSED(arg); - - if (!ns_interfacemgr_listeningon(ns_g_server->interfacemgr, dstaddr)) - return (ISC_FALSE); - - isc_netaddr_fromsockaddr(&netsrc, srcaddr); - isc_netaddr_fromsockaddr(&netdst, dstaddr); - - for (view = ISC_LIST_HEAD(ns_g_server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - - if (view->matchrecursiveonly) - continue; - - if (rdclass != view->rdclass) - continue; - - if (mykey != NULL) { - isc_boolean_t match; - isc_result_t result; - - tsig = &mykey->name; - result = dns_view_gettsig(view, tsig, &key); - if (result != ISC_R_SUCCESS) - continue; - match = dst_key_compare(mykey->key, key->key); - dns_tsigkey_detach(&key); - if (!match) - continue; - } - - if (allowed(&netsrc, tsig, view->matchclients) && - allowed(&netdst, tsig, view->matchdestinations)) - break; - } - return (ISC_TF(view == myview)); -} - -/* - * Handle an incoming request event from the socket (UDP case) - * or tcpmsg (TCP case). - */ -static void -client_request(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - isc_socketevent_t *sevent; - isc_result_t result; - isc_result_t sigresult = ISC_R_SUCCESS; - isc_buffer_t *buffer; - isc_buffer_t tbuffer; - dns_view_t *view; - dns_rdataset_t *opt; - isc_boolean_t ra; /* Recursion available. */ - isc_netaddr_t netaddr; - isc_netaddr_t destaddr; - int match; - dns_messageid_t id; - unsigned int flags; - isc_boolean_t notimp; - - REQUIRE(event != NULL); - client = event->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - - INSIST(client->recursionquota == NULL); - - INSIST(client->state == - TCP_CLIENT(client) ? - NS_CLIENTSTATE_READING : - NS_CLIENTSTATE_READY); - - ns_client_requests++; - - if (event->ev_type == ISC_SOCKEVENT_RECVDONE) { - INSIST(!TCP_CLIENT(client)); - sevent = (isc_socketevent_t *)event; - REQUIRE(sevent == client->recvevent); - isc_buffer_init(&tbuffer, sevent->region.base, sevent->n); - isc_buffer_add(&tbuffer, sevent->n); - buffer = &tbuffer; - result = sevent->result; - if (result == ISC_R_SUCCESS) { - client->peeraddr = sevent->address; - client->peeraddr_valid = ISC_TRUE; - } - if ((sevent->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) { - client->attributes |= NS_CLIENTATTR_PKTINFO; - client->pktinfo = sevent->pktinfo; - } - if ((sevent->attributes & ISC_SOCKEVENTATTR_MULTICAST) != 0) - client->attributes |= NS_CLIENTATTR_MULTICAST; - client->nrecvs--; - } else { - INSIST(TCP_CLIENT(client)); - REQUIRE(event->ev_type == DNS_EVENT_TCPMSG); - REQUIRE(event->ev_sender == &client->tcpmsg); - buffer = &client->tcpmsg.buffer; - result = client->tcpmsg.result; - INSIST(client->nreads == 1); - /* - * client->peeraddr was set when the connection was accepted. - */ - client->nreads--; - } - - if (exit_check(client)) - goto cleanup; - client->state = client->newstate = NS_CLIENTSTATE_WORKING; - - isc_task_getcurrenttime(task, &client->requesttime); - client->now = client->requesttime; - - if (result != ISC_R_SUCCESS) { - if (TCP_CLIENT(client)) { - ns_client_next(client, result); - } else { - if (result != ISC_R_CANCELED) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, - ISC_LOG_ERROR, - "UDP client handler shutting " - "down due to fatal receive " - "error: %s", - isc_result_totext(result)); - isc_task_shutdown(client->task); - } - goto cleanup; - } - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - -#if NS_CLIENT_DROPPORT - if (ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) == - DROPPORT_REQUEST) { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "dropped request: suspicious port"); - ns_client_next(client, ISC_R_SUCCESS); - goto cleanup; - } -#endif - - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "%s request", - TCP_CLIENT(client) ? "TCP" : "UDP"); - - /* - * Check the blackhole ACL for UDP only, since TCP is done in - * client_newconn. - */ - if (!TCP_CLIENT(client)) { - - if (ns_g_server->blackholeacl != NULL && - dns_acl_match(&netaddr, NULL, ns_g_server->blackholeacl, - &ns_g_server->aclenv, - &match, NULL) == ISC_R_SUCCESS && - match > 0) - { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "blackholed UDP datagram"); - ns_client_next(client, ISC_R_SUCCESS); - goto cleanup; - } - } - - /* - * Silently drop multicast requests for the present. - * XXXMPA look at when/if mDNS spec stabilizes. - */ - if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "dropping multicast request"); - ns_client_next(client, DNS_R_REFUSED); - goto cleanup; - } - - result = dns_message_peekheader(buffer, &id, &flags); - if (result != ISC_R_SUCCESS) { - /* - * There isn't enough header to determine whether - * this was a request or a response. Drop it. - */ - ns_client_next(client, result); - goto cleanup; - } - - /* - * The client object handles requests, not responses. - * If this is a UDP response, forward it to the dispatcher. - * If it's a TCP response, discard it here. - */ - if ((flags & DNS_MESSAGEFLAG_QR) != 0) { - if (TCP_CLIENT(client)) { - CTRACE("unexpected response"); - ns_client_next(client, DNS_R_FORMERR); - goto cleanup; - } else { - dns_dispatch_importrecv(client->dispatch, event); - ns_client_next(client, ISC_R_SUCCESS); - goto cleanup; - } - } - - /* - * Hash the incoming request here as it is after - * dns_dispatch_importrecv(). - */ - dns_dispatch_hash(&client->now, sizeof(client->now)); - dns_dispatch_hash(isc_buffer_base(buffer), - isc_buffer_usedlength(buffer)); - - /* - * It's a request. Parse it. - */ - result = dns_message_parse(client->message, buffer, 0); - if (result != ISC_R_SUCCESS) { - /* - * Parsing the request failed. Send a response - * (typically FORMERR or SERVFAIL). - */ - ns_client_error(client, result); - goto cleanup; - } - - switch (client->message->opcode) { - case dns_opcode_query: - case dns_opcode_update: - case dns_opcode_notify: - notimp = ISC_FALSE; - break; - case dns_opcode_iquery: - default: - notimp = ISC_TRUE; - break; - } - - client->message->rcode = dns_rcode_noerror; - - /* RFC1123 section 6.1.3.2 */ - if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) - client->message->flags &= ~DNS_MESSAGEFLAG_RD; - - /* - * Deal with EDNS. - */ - opt = dns_message_getopt(client->message); - if (opt != NULL) { - /* - * Set the client's UDP buffer size. - */ - client->udpsize = opt->rdclass; - - /* - * If the requested UDP buffer size is less than 512, - * ignore it and use 512. - */ - if (client->udpsize < 512) - client->udpsize = 512; - - /* - * Get the flags out of the OPT record. - */ - client->extflags = (isc_uint16_t)(opt->ttl & 0xFFFF); - - /* - * Do we understand this version of EDNS? - * - * XXXRTH need library support for this! - */ - client->ednsversion = (opt->ttl & 0x00FF0000) >> 16; - if (client->ednsversion > 0) { - result = client_addopt(client); - if (result == ISC_R_SUCCESS) - result = DNS_R_BADVERS; - ns_client_error(client, result); - goto cleanup; - } - /* - * Create an OPT for our reply. - */ - result = client_addopt(client); - if (result != ISC_R_SUCCESS) { - ns_client_error(client, result); - goto cleanup; - } - } - - if (client->message->rdclass == 0) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "message class could not be determined"); - ns_client_dumpmessage(client, - "message class could not be determined"); - ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_FORMERR); - goto cleanup; - } - - /* - * Determine the destination address. If the receiving interface is - * bound to a specific address, we simply use it regardless of the - * address family. All IPv4 queries should fall into this case. - * Otherwise, if this is a TCP query, get the address from the - * receiving socket (this needs a system call and can be heavy). - * For IPv6 UDP queries, we get this from the pktinfo structure (if - * supported). - * If all the attempts fail (this can happen due to memory shortage, - * etc), we regard this as an error for safety. - */ - if ((client->interface->flags & NS_INTERFACEFLAG_ANYADDR) == 0) - isc_netaddr_fromsockaddr(&destaddr, &client->interface->addr); - else { - result = ISC_R_FAILURE; - - if (TCP_CLIENT(client)) { - isc_sockaddr_t destsockaddr; - - result = isc_socket_getsockname(client->tcpsocket, - &destsockaddr); - if (result == ISC_R_SUCCESS) - isc_netaddr_fromsockaddr(&destaddr, - &destsockaddr); - } - if (result != ISC_R_SUCCESS && - client->interface->addr.type.sa.sa_family == AF_INET6 && - (client->attributes & NS_CLIENTATTR_PKTINFO) != 0) { - isc_uint32_t zone = 0; - - /* - * XXXJT technically, we should convert the receiving - * interface ID to a proper scope zone ID. However, - * due to the fact there is no standard API for this, - * we only handle link-local addresses and use the - * interface index as link ID. Despite the assumption, - * it should cover most typical cases. - */ - if (IN6_IS_ADDR_LINKLOCAL(&client->pktinfo.ipi6_addr)) - zone = (isc_uint32_t)client->pktinfo.ipi6_ifindex; - - isc_netaddr_fromin6(&destaddr, - &client->pktinfo.ipi6_addr); - isc_netaddr_setzone(&destaddr, zone); - result = ISC_R_SUCCESS; - } - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "failed to get request's " - "destination: %s", - isc_result_totext(result)); - ns_client_next(client, ISC_R_SUCCESS); - goto cleanup; - } - } - - /* - * Find a view that matches the client's source address. - */ - for (view = ISC_LIST_HEAD(ns_g_server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - if (client->message->rdclass == view->rdclass || - client->message->rdclass == dns_rdataclass_any) - { - dns_name_t *tsig = NULL; - sigresult = dns_message_rechecksig(client->message, - view); - if (sigresult == ISC_R_SUCCESS) - tsig = client->message->tsigname; - - if (allowed(&netaddr, tsig, view->matchclients) && - allowed(&destaddr, tsig, view->matchdestinations) && - !((client->message->flags & DNS_MESSAGEFLAG_RD) - == 0 && view->matchrecursiveonly)) - { - dns_view_attach(view, &client->view); - break; - } - } - } - - if (view == NULL) { - char classname[DNS_RDATACLASS_FORMATSIZE]; - - /* - * Do a dummy TSIG verification attempt so that the - * response will have a TSIG if the query did, as - * required by RFC2845. - */ - isc_buffer_t b; - isc_region_t *r; - - dns_message_resetsig(client->message); - - r = dns_message_getrawmessage(client->message); - isc_buffer_init(&b, r->base, r->length); - isc_buffer_add(&b, r->length); - (void)dns_tsig_verify(&b, client->message, NULL, NULL); - - dns_rdataclass_format(client->message->rdclass, classname, - sizeof(classname)); - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "no matching view in class '%s'", classname); - ns_client_dumpmessage(client, "no matching view in class"); - ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_REFUSED); - goto cleanup; - } - - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(5), - "using view '%s'", view->name); - - /* - * Check for a signature. We log bad signatures regardless of - * whether they ultimately cause the request to be rejected or - * not. We do not log the lack of a signature unless we are - * debugging. - */ - client->signer = NULL; - dns_name_init(&client->signername, NULL); - result = dns_message_signer(client->message, &client->signername); - if (result == ISC_R_SUCCESS) { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "request has valid signature"); - client->signer = &client->signername; - } else if (result == ISC_R_NOTFOUND) { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "request is not signed"); - } else if (result == DNS_R_NOIDENTITY) { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "request is signed by a nonauthoritative key"); - } else { - char tsigrcode[64]; - isc_buffer_t b; - dns_name_t *name = NULL; - dns_rcode_t status; - isc_result_t tresult; - - /* There is a signature, but it is bad. */ - if (dns_message_gettsig(client->message, &name) != NULL) { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(name, namebuf, sizeof(namebuf)); - status = client->message->tsigstatus; - isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1); - tresult = dns_tsigrcode_totext(status, &b); - INSIST(tresult == ISC_R_SUCCESS); - tsigrcode[isc_buffer_usedlength(&b)] = '\0'; - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_ERROR, - "request has invalid signature: " - "TSIG %s: %s (%s)", namebuf, - isc_result_totext(result), tsigrcode); - } else { - status = client->message->sig0status; - isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1); - tresult = dns_tsigrcode_totext(status, &b); - INSIST(tresult == ISC_R_SUCCESS); - tsigrcode[isc_buffer_usedlength(&b)] = '\0'; - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_ERROR, - "request has invalid signature: %s (%s)", - isc_result_totext(result), tsigrcode); - } - /* - * Accept update messages signed by unknown keys so that - * update forwarding works transparently through slaves - * that don't have all the same keys as the master. - */ - if (!(client->message->tsigstatus == dns_tsigerror_badkey && - client->message->opcode == dns_opcode_update)) { - ns_client_error(client, sigresult); - goto cleanup; - } - } - - /* - * Decide whether recursive service is available to this client. - * We do this here rather than in the query code so that we can - * set the RA bit correctly on all kinds of responses, not just - * responses to ordinary queries. Note if you can't query the - * cache there is no point in setting RA. - */ - ra = ISC_FALSE; - if (client->view->resolver != NULL && - client->view->recursion == ISC_TRUE && - ns_client_checkaclsilent(client, client->view->recursionacl, - ISC_TRUE) == ISC_R_SUCCESS && - ns_client_checkaclsilent(client, client->view->queryacl, - ISC_TRUE) == ISC_R_SUCCESS) - ra = ISC_TRUE; - - if (ra == ISC_TRUE) - client->attributes |= NS_CLIENTATTR_RA; - - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_CLIENT, - ISC_LOG_DEBUG(3), ra ? "recursion available" : - "recursion not available"); - - /* - * Adjust maximum UDP response size for this client. - */ - if (client->udpsize > 512) { - dns_peer_t *peer = NULL; - isc_uint16_t udpsize = view->maxudp; - (void) dns_peerlist_peerbyaddr(view->peers, &netaddr, &peer); - if (peer != NULL) - dns_peer_getmaxudp(peer, &udpsize); - if (client->udpsize > udpsize) - client->udpsize = udpsize; - } - - /* - * Dispatch the request. - */ - switch (client->message->opcode) { - case dns_opcode_query: - CTRACE("query"); - ns_query_start(client); - break; - case dns_opcode_update: - CTRACE("update"); - ns_client_settimeout(client, 60); - ns_update_start(client, sigresult); - break; - case dns_opcode_notify: - CTRACE("notify"); - ns_client_settimeout(client, 60); - ns_notify_start(client); - break; - case dns_opcode_iquery: - CTRACE("iquery"); - ns_client_error(client, DNS_R_NOTIMP); - break; - default: - CTRACE("unknown opcode"); - ns_client_error(client, DNS_R_NOTIMP); - } - - cleanup: - return; -} - -static void -client_timeout(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - - REQUIRE(event != NULL); - REQUIRE(event->ev_type == ISC_TIMEREVENT_LIFE || - event->ev_type == ISC_TIMEREVENT_IDLE); - client = event->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - REQUIRE(client->timer != NULL); - - UNUSED(task); - - CTRACE("timeout"); - - isc_event_free(&event); - - if (client->shutdown != NULL) { - (client->shutdown)(client->shutdown_arg, ISC_R_TIMEDOUT); - client->shutdown = NULL; - client->shutdown_arg = NULL; - } - - if (client->newstate > NS_CLIENTSTATE_READY) - client->newstate = NS_CLIENTSTATE_READY; - (void)exit_check(client); -} - -static isc_result_t -get_clientmctx(ns_clientmgr_t *manager, isc_mem_t **mctxp) { - isc_mem_t *clientmctx; -#if NMCTXS > 0 - isc_result_t result; -#endif - - /* - * Caller must be holding the manager lock. - */ -#if NMCTXS > 0 - INSIST(manager->nextmctx < NMCTXS); - clientmctx = manager->mctxpool[manager->nextmctx]; - if (clientmctx == NULL) { - result = isc_mem_create(0, 0, &clientmctx); - if (result != ISC_R_SUCCESS) - return (result); - - manager->mctxpool[manager->nextmctx] = clientmctx; - manager->nextmctx++; - if (manager->nextmctx == NMCTXS) - manager->nextmctx = 0; - } -#else - clientmctx = manager->mctx; -#endif - - isc_mem_attach(clientmctx, mctxp); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -client_create(ns_clientmgr_t *manager, ns_client_t **clientp) { - ns_client_t *client; - isc_result_t result; - isc_mem_t *mctx = NULL; - - /* - * Caller must be holding the manager lock. - * - * Note: creating a client does not add the client to the - * manager's client list or set the client's manager pointer. - * The caller is responsible for that. - */ - - REQUIRE(clientp != NULL && *clientp == NULL); - - result = get_clientmctx(manager, &mctx); - if (result != ISC_R_SUCCESS) - return (result); - - client = isc_mem_get(mctx, sizeof(*client)); - if (client == NULL) { - isc_mem_detach(&mctx); - return (ISC_R_NOMEMORY); - } - client->mctx = mctx; - - client->task = NULL; - result = isc_task_create(manager->taskmgr, 0, &client->task); - if (result != ISC_R_SUCCESS) - goto cleanup_client; - isc_task_setname(client->task, "client", client); - - client->timer = NULL; - result = isc_timer_create(manager->timermgr, isc_timertype_inactive, - NULL, NULL, client->task, client_timeout, - client, &client->timer); - if (result != ISC_R_SUCCESS) - goto cleanup_task; - client->timerset = ISC_FALSE; - - client->message = NULL; - result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTPARSE, - &client->message); - if (result != ISC_R_SUCCESS) - goto cleanup_timer; - - /* XXXRTH Hardwired constants */ - - client->sendevent = (isc_socketevent_t *) - isc_event_allocate(client->mctx, client, - ISC_SOCKEVENT_SENDDONE, - client_senddone, client, - sizeof(isc_socketevent_t)); - if (client->sendevent == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_message; - } - - client->recvbuf = isc_mem_get(client->mctx, RECV_BUFFER_SIZE); - if (client->recvbuf == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_sendevent; - } - - client->recvevent = (isc_socketevent_t *) - isc_event_allocate(client->mctx, client, - ISC_SOCKEVENT_RECVDONE, - client_request, client, - sizeof(isc_socketevent_t)); - if (client->recvevent == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_recvbuf; - } - - client->magic = NS_CLIENT_MAGIC; - client->manager = NULL; - client->state = NS_CLIENTSTATE_INACTIVE; - client->newstate = NS_CLIENTSTATE_MAX; - client->naccepts = 0; - client->nreads = 0; - client->nsends = 0; - client->nrecvs = 0; - client->nupdates = 0; - client->nctls = 0; - client->references = 0; - client->attributes = 0; - client->view = NULL; - client->dispatch = NULL; - client->udpsocket = NULL; - client->tcplistener = NULL; - client->tcpsocket = NULL; - client->tcpmsg_valid = ISC_FALSE; - client->tcpbuf = NULL; - client->opt = NULL; - client->udpsize = 512; - client->extflags = 0; - client->ednsversion = -1; - client->next = NULL; - client->shutdown = NULL; - client->shutdown_arg = NULL; - dns_name_init(&client->signername, NULL); - client->mortal = ISC_FALSE; - client->tcpquota = NULL; - client->recursionquota = NULL; - client->interface = NULL; - client->peeraddr_valid = ISC_FALSE; - ISC_EVENT_INIT(&client->ctlevent, sizeof(client->ctlevent), 0, NULL, - NS_EVENT_CLIENTCONTROL, client_start, client, client, - NULL, NULL); - /* - * Initialize FORMERR cache to sentinel value that will not match - * any actual FORMERR response. - */ - isc_sockaddr_any(&client->formerrcache.addr); - client->formerrcache.time = 0; - client->formerrcache.id = 0; - ISC_LINK_INIT(client, link); - client->list = NULL; - - /* - * We call the init routines for the various kinds of client here, - * after we have created an otherwise valid client, because some - * of them call routines that REQUIRE(NS_CLIENT_VALID(client)). - */ - result = ns_query_init(client); - if (result != ISC_R_SUCCESS) - goto cleanup_recvevent; - - result = isc_task_onshutdown(client->task, client_shutdown, client); - if (result != ISC_R_SUCCESS) - goto cleanup_query; - - CTRACE("create"); - - *clientp = client; - - return (ISC_R_SUCCESS); - - cleanup_query: - ns_query_free(client); - - cleanup_recvevent: - isc_event_free((isc_event_t **)&client->recvevent); - - cleanup_recvbuf: - isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE); - - cleanup_sendevent: - isc_event_free((isc_event_t **)&client->sendevent); - - client->magic = 0; - - cleanup_message: - dns_message_destroy(&client->message); - - cleanup_timer: - isc_timer_detach(&client->timer); - - cleanup_task: - isc_task_detach(&client->task); - - cleanup_client: - isc_mem_putanddetach(&client->mctx, client, sizeof(*client)); - - return (result); -} - -static void -client_read(ns_client_t *client) { - isc_result_t result; - - CTRACE("read"); - - result = dns_tcpmsg_readmessage(&client->tcpmsg, client->task, - client_request, client); - if (result != ISC_R_SUCCESS) - goto fail; - - /* - * Set a timeout to limit the amount of time we will wait - * for a request on this TCP connection. - */ - ns_client_settimeout(client, 30); - - client->state = client->newstate = NS_CLIENTSTATE_READING; - INSIST(client->nreads == 0); - INSIST(client->recursionquota == NULL); - client->nreads++; - - return; - fail: - ns_client_next(client, result); -} - -static void -client_newconn(isc_task_t *task, isc_event_t *event) { - ns_client_t *client = event->ev_arg; - isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event; - isc_result_t result; - - REQUIRE(event->ev_type == ISC_SOCKEVENT_NEWCONN); - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(client->task == task); - - UNUSED(task); - - INSIST(client->state == NS_CLIENTSTATE_READY); - - INSIST(client->naccepts == 1); - client->naccepts--; - - LOCK(&client->interface->lock); - INSIST(client->interface->ntcpcurrent > 0); - client->interface->ntcpcurrent--; - UNLOCK(&client->interface->lock); - - /* - * We must take ownership of the new socket before the exit - * check to make sure it gets destroyed if we decide to exit. - */ - if (nevent->result == ISC_R_SUCCESS) { - client->tcpsocket = nevent->newsocket; - client->state = NS_CLIENTSTATE_READING; - INSIST(client->recursionquota == NULL); - - (void)isc_socket_getpeername(client->tcpsocket, - &client->peeraddr); - client->peeraddr_valid = ISC_TRUE; - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "new TCP connection"); - } else { - /* - * XXXRTH What should we do? We're trying to accept but - * it didn't work. If we just give up, then TCP - * service may eventually stop. - * - * For now, we just go idle. - * - * Going idle is probably the right thing if the - * I/O was canceled. - */ - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "accept failed: %s", - isc_result_totext(nevent->result)); - } - - if (exit_check(client)) - goto freeevent; - - if (nevent->result == ISC_R_SUCCESS) { - int match; - isc_netaddr_t netaddr; - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - - if (ns_g_server->blackholeacl != NULL && - dns_acl_match(&netaddr, NULL, - ns_g_server->blackholeacl, - &ns_g_server->aclenv, - &match, NULL) == ISC_R_SUCCESS && - match > 0) - { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "blackholed connection attempt"); - client->newstate = NS_CLIENTSTATE_READY; - (void)exit_check(client); - goto freeevent; - } - - INSIST(client->tcpmsg_valid == ISC_FALSE); - dns_tcpmsg_init(client->mctx, client->tcpsocket, - &client->tcpmsg); - client->tcpmsg_valid = ISC_TRUE; - - /* - * Let a new client take our place immediately, before - * we wait for a request packet. If we don't, - * telnetting to port 53 (once per CPU) will - * deny service to legititmate TCP clients. - */ - result = isc_quota_attach(&ns_g_server->tcpquota, - &client->tcpquota); - if (result == ISC_R_SUCCESS) - result = ns_client_replace(client); - if (result != ISC_R_SUCCESS) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_WARNING, - "no more TCP clients: %s", - isc_result_totext(result)); - } - - client_read(client); - } - - freeevent: - isc_event_free(&event); -} - -static void -client_accept(ns_client_t *client) { - isc_result_t result; - - CTRACE("accept"); - - result = isc_socket_accept(client->tcplistener, client->task, - client_newconn, client); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socket_accept() failed: %s", - isc_result_totext(result)); - /* - * XXXRTH What should we do? We're trying to accept but - * it didn't work. If we just give up, then TCP - * service may eventually stop. - * - * For now, we just go idle. - */ - return; - } - INSIST(client->naccepts == 0); - client->naccepts++; - LOCK(&client->interface->lock); - client->interface->ntcpcurrent++; - UNLOCK(&client->interface->lock); -} - -static void -client_udprecv(ns_client_t *client) { - isc_result_t result; - isc_region_t r; - - CTRACE("udprecv"); - - r.base = client->recvbuf; - r.length = RECV_BUFFER_SIZE; - result = isc_socket_recv2(client->udpsocket, &r, 1, - client->task, client->recvevent, 0); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socket_recv2() failed: %s", - isc_result_totext(result)); - /* - * This cannot happen in the current implementation, since - * isc_socket_recv2() cannot fail if flags == 0. - * - * If this does fail, we just go idle. - */ - return; - } - INSIST(client->nrecvs == 0); - client->nrecvs++; -} - -void -ns_client_attach(ns_client_t *source, ns_client_t **targetp) { - REQUIRE(NS_CLIENT_VALID(source)); - REQUIRE(targetp != NULL && *targetp == NULL); - - source->references++; - ns_client_log(source, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "ns_client_attach: ref = %d", source->references); - *targetp = source; -} - -void -ns_client_detach(ns_client_t **clientp) { - ns_client_t *client = *clientp; - - client->references--; - INSIST(client->references >= 0); - *clientp = NULL; - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "ns_client_detach: ref = %d", client->references); - (void)exit_check(client); -} - -isc_boolean_t -ns_client_shuttingdown(ns_client_t *client) { - return (ISC_TF(client->newstate == NS_CLIENTSTATE_FREED)); -} - -isc_result_t -ns_client_replace(ns_client_t *client) { - isc_result_t result; - - CTRACE("replace"); - - result = ns_clientmgr_createclients(client->manager, - 1, client->interface, - (TCP_CLIENT(client) ? - ISC_TRUE : ISC_FALSE)); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * The responsibility for listening for new requests is hereby - * transferred to the new client. Therefore, the old client - * should refrain from listening for any more requests. - */ - client->mortal = ISC_TRUE; - - return (ISC_R_SUCCESS); -} - -/*** - *** Client Manager - ***/ - -static void -clientmgr_destroy(ns_clientmgr_t *manager) { -#if NMCTXS > 0 - int i; -#endif - - REQUIRE(ISC_LIST_EMPTY(manager->active)); - REQUIRE(ISC_LIST_EMPTY(manager->inactive)); - REQUIRE(ISC_LIST_EMPTY(manager->recursing)); - - MTRACE("clientmgr_destroy"); - -#if NMCTXS > 0 - for (i = 0; i < NMCTXS; i++) { - if (manager->mctxpool[i] != NULL) - isc_mem_detach(&manager->mctxpool[i]); - } -#endif - - DESTROYLOCK(&manager->lock); - manager->magic = 0; - isc_mem_put(manager->mctx, manager, sizeof(*manager)); -} - -isc_result_t -ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, ns_clientmgr_t **managerp) -{ - ns_clientmgr_t *manager; - isc_result_t result; -#if NMCTXS > 0 - int i; -#endif - - manager = isc_mem_get(mctx, sizeof(*manager)); - if (manager == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&manager->lock); - if (result != ISC_R_SUCCESS) - goto cleanup_manager; - - manager->mctx = mctx; - manager->taskmgr = taskmgr; - manager->timermgr = timermgr; - manager->exiting = ISC_FALSE; - ISC_LIST_INIT(manager->active); - ISC_LIST_INIT(manager->inactive); - ISC_LIST_INIT(manager->recursing); -#if NMCTXS > 0 - manager->nextmctx = 0; - for (i = 0; i < NMCTXS; i++) - manager->mctxpool[i] = NULL; /* will be created on-demand */ -#endif - manager->magic = MANAGER_MAGIC; - - MTRACE("create"); - - *managerp = manager; - - return (ISC_R_SUCCESS); - - cleanup_manager: - isc_mem_put(manager->mctx, manager, sizeof(*manager)); - - return (result); -} - -void -ns_clientmgr_destroy(ns_clientmgr_t **managerp) { - ns_clientmgr_t *manager; - ns_client_t *client; - isc_boolean_t need_destroy = ISC_FALSE; - - REQUIRE(managerp != NULL); - manager = *managerp; - REQUIRE(VALID_MANAGER(manager)); - - MTRACE("destroy"); - - LOCK(&manager->lock); - - manager->exiting = ISC_TRUE; - - for (client = ISC_LIST_HEAD(manager->recursing); - client != NULL; - client = ISC_LIST_NEXT(client, link)) - isc_task_shutdown(client->task); - - for (client = ISC_LIST_HEAD(manager->active); - client != NULL; - client = ISC_LIST_NEXT(client, link)) - isc_task_shutdown(client->task); - - for (client = ISC_LIST_HEAD(manager->inactive); - client != NULL; - client = ISC_LIST_NEXT(client, link)) - isc_task_shutdown(client->task); - - if (ISC_LIST_EMPTY(manager->active) && - ISC_LIST_EMPTY(manager->inactive) && - ISC_LIST_EMPTY(manager->recursing)) - need_destroy = ISC_TRUE; - - UNLOCK(&manager->lock); - - if (need_destroy) - clientmgr_destroy(manager); - - *managerp = NULL; -} - -isc_result_t -ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, - ns_interface_t *ifp, isc_boolean_t tcp) -{ - isc_result_t result = ISC_R_SUCCESS; - unsigned int i; - ns_client_t *client; - - REQUIRE(VALID_MANAGER(manager)); - REQUIRE(n > 0); - - MTRACE("createclients"); - - /* - * We MUST lock the manager lock for the entire client creation - * process. If we didn't do this, then a client could get a - * shutdown event and disappear out from under us. - */ - - LOCK(&manager->lock); - - for (i = 0; i < n; i++) { - isc_event_t *ev; - /* - * Allocate a client. First try to get a recycled one; - * if that fails, make a new one. - */ - client = ISC_LIST_HEAD(manager->inactive); - if (client != NULL) { - MTRACE("recycle"); - ISC_LIST_UNLINK(manager->inactive, client, link); - client->list = NULL; - } else { - MTRACE("create new"); - result = client_create(manager, &client); - if (result != ISC_R_SUCCESS) - break; - } - - ns_interface_attach(ifp, &client->interface); - client->state = NS_CLIENTSTATE_READY; - INSIST(client->recursionquota == NULL); - - if (tcp) { - client->attributes |= NS_CLIENTATTR_TCP; - isc_socket_attach(ifp->tcpsocket, - &client->tcplistener); - } else { - isc_socket_t *sock; - - dns_dispatch_attach(ifp->udpdispatch, - &client->dispatch); - sock = dns_dispatch_getsocket(client->dispatch); - isc_socket_attach(sock, &client->udpsocket); - } - client->manager = manager; - ISC_LIST_APPEND(manager->active, client, link); - client->list = &manager->active; - - INSIST(client->nctls == 0); - client->nctls++; - ev = &client->ctlevent; - isc_task_send(client->task, &ev); - } - if (i != 0) { - /* - * We managed to create at least one client, so we - * declare victory. - */ - result = ISC_R_SUCCESS; - } - - UNLOCK(&manager->lock); - - return (result); -} - -isc_sockaddr_t * -ns_client_getsockaddr(ns_client_t *client) { - return (&client->peeraddr); -} - -isc_result_t -ns_client_checkaclsilent(ns_client_t *client, dns_acl_t *acl, - isc_boolean_t default_allow) -{ - isc_result_t result; - int match; - isc_netaddr_t netaddr; - - if (acl == NULL) { - if (default_allow) - goto allow; - else - goto deny; - } - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - - result = dns_acl_match(&netaddr, client->signer, acl, - &ns_g_server->aclenv, - &match, NULL); - if (result != ISC_R_SUCCESS) - goto deny; /* Internal error, already logged. */ - if (match > 0) - goto allow; - goto deny; /* Negative match or no match. */ - - allow: - return (ISC_R_SUCCESS); - - deny: - return (DNS_R_REFUSED); -} - -isc_result_t -ns_client_checkacl(ns_client_t *client, - const char *opname, dns_acl_t *acl, - isc_boolean_t default_allow, int log_level) -{ - isc_result_t result = - ns_client_checkaclsilent(client, acl, default_allow); - - if (result == ISC_R_SUCCESS) - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "%s approved", opname); - else - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, - log_level, "%s denied", opname); - return (result); -} - -static void -ns_client_name(ns_client_t *client, char *peerbuf, size_t len) { - if (client->peeraddr_valid) - isc_sockaddr_format(&client->peeraddr, peerbuf, len); - else - snprintf(peerbuf, len, "@%p", client); -} - -void -ns_client_logv(ns_client_t *client, isc_logcategory_t *category, - isc_logmodule_t *module, int level, const char *fmt, va_list ap) -{ - char msgbuf[2048]; - char peerbuf[ISC_SOCKADDR_FORMATSIZE]; - const char *name = ""; - const char *sep = ""; - - vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); - ns_client_name(client, peerbuf, sizeof(peerbuf)); - if (client->view != NULL && strcmp(client->view->name, "_bind") != 0 && - strcmp(client->view->name, "_default") != 0) { - name = client->view->name; - sep = ": view "; - } - - isc_log_write(ns_g_lctx, category, module, level, - "client %s%s%s: %s", peerbuf, sep, name, msgbuf); -} - -void -ns_client_log(ns_client_t *client, isc_logcategory_t *category, - isc_logmodule_t *module, int level, const char *fmt, ...) -{ - va_list ap; - - if (! isc_log_wouldlog(ns_g_lctx, level)) - return; - - va_start(ap, fmt); - ns_client_logv(client, category, module, level, fmt, ap); - va_end(ap); -} - -void -ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type, - dns_rdataclass_t rdclass, char *buf, size_t len) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - - dns_name_format(name, namebuf, sizeof(namebuf)); - dns_rdatatype_format(type, typebuf, sizeof(typebuf)); - dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf)); - (void)snprintf(buf, len, "%s '%s/%s/%s'", msg, namebuf, typebuf, - classbuf); -} - -static void -ns_client_dumpmessage(ns_client_t *client, const char *reason) { - isc_buffer_t buffer; - char *buf = NULL; - int len = 1024; - isc_result_t result; - - /* - * Note that these are multiline debug messages. We want a newline - * to appear in the log after each message. - */ - - do { - buf = isc_mem_get(client->mctx, len); - if (buf == NULL) - break; - isc_buffer_init(&buffer, buf, len); - result = dns_message_totext(client->message, - &dns_master_style_debug, - 0, &buffer); - if (result == ISC_R_NOSPACE) { - isc_mem_put(client->mctx, buf, len); - len += 1024; - } else if (result == ISC_R_SUCCESS) - ns_client_log(client, NS_LOGCATEGORY_UNMATCHED, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "%s\n%.*s", reason, - (int)isc_buffer_usedlength(&buffer), - buf); - } while (result == ISC_R_NOSPACE); - - if (buf != NULL) - isc_mem_put(client->mctx, buf, len); -} - -void -ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) { - ns_client_t *client; - char namebuf[DNS_NAME_FORMATSIZE]; - char peerbuf[ISC_SOCKADDR_FORMATSIZE]; - const char *name; - const char *sep; - - REQUIRE(VALID_MANAGER(manager)); - - LOCK(&manager->lock); - client = ISC_LIST_HEAD(manager->recursing); - while (client != NULL) { - ns_client_name(client, peerbuf, sizeof(peerbuf)); - if (client->view != NULL && - strcmp(client->view->name, "_bind") != 0 && - strcmp(client->view->name, "_default") != 0) { - name = client->view->name; - sep = ": view "; - } else { - name = ""; - sep = ""; - } - dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); - fprintf(f, "; client %s%s%s: '%s' requesttime %d\n", - peerbuf, sep, name, namebuf, client->requesttime); - client = ISC_LIST_NEXT(client, link); - } - UNLOCK(&manager->lock); -} - -void -ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) { - - if (client->manager != NULL) - LOCK(&client->manager->lock); - if (client->query.restarts > 0) { - /* - * client->query.qname was dynamically allocated. - */ - dns_message_puttempname(client->message, - &client->query.qname); - } - client->query.qname = name; - if (client->manager != NULL) - UNLOCK(&client->manager->lock); -} diff --git a/contrib/bind9/bin/named/config.c b/contrib/bind9/bin/named/config.c deleted file mode 100644 index e2dc833..0000000 --- a/contrib/bind9/bin/named/config.c +++ /dev/null @@ -1,796 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 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: config.c,v 1.47.18.32 2007/09/13 05:04:01 each Exp $ */ - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -/*% default configuration */ -static char defaultconf[] = "\ -options {\n\ -# blackhole {none;};\n" -#ifndef WIN32 -" coresize default;\n\ - datasize default;\n\ - files default;\n\ - stacksize default;\n" -#endif -" deallocate-on-exit true;\n\ -# directory \n\ - dump-file \"named_dump.db\";\n\ - fake-iquery no;\n\ - has-old-clients false;\n\ - heartbeat-interval 60;\n\ - host-statistics no;\n\ - interface-interval 60;\n\ - listen-on {any;};\n\ - listen-on-v6 {none;};\n\ - match-mapped-addresses no;\n\ - memstatistics-file \"named.memstats\";\n\ - multiple-cnames no;\n\ -# named-xfer ;\n\ -# pid-file \"" NS_LOCALSTATEDIR "/named.pid\"; /* or /lwresd.pid */\n\ - port 53;\n\ - recursing-file \"named.recursing\";\n\ -" -#ifdef PATH_RANDOMDEV -"\ - random-device \"" PATH_RANDOMDEV "\";\n\ -" -#endif -"\ - recursive-clients 1000;\n\ - rrset-order {type NS order random; order cyclic; };\n\ - serial-queries 20;\n\ - serial-query-rate 20;\n\ - server-id none;\n\ - statistics-file \"named.stats\";\n\ - statistics-interval 60;\n\ - tcp-clients 100;\n\ - tcp-listen-queue 3;\n\ -# tkey-dhkey \n\ -# tkey-gssapi-credential \n\ -# tkey-domain \n\ - transfers-per-ns 2;\n\ - transfers-in 10;\n\ - transfers-out 10;\n\ - treat-cr-as-space true;\n\ - use-id-pool true;\n\ - use-ixfr true;\n\ - edns-udp-size 4096;\n\ - max-udp-size 4096;\n\ -\n\ - /* view */\n\ - allow-notify {none;};\n\ - allow-update-forwarding {none;};\n\ - allow-query-cache { localnets; localhost; };\n\ - allow-recursion { localnets; localhost; };\n\ -# allow-v6-synthesis ;\n\ -# sortlist \n\ -# topology \n\ - auth-nxdomain false;\n\ - minimal-responses false;\n\ - recursion true;\n\ - provide-ixfr true;\n\ - request-ixfr true;\n\ - fetch-glue no;\n\ - rfc2308-type1 no;\n\ - additional-from-auth true;\n\ - additional-from-cache true;\n\ - query-source address *;\n\ - query-source-v6 address *;\n\ - notify-source *;\n\ - notify-source-v6 *;\n\ - cleaning-interval 60;\n\ - min-roots 2;\n\ - lame-ttl 600;\n\ - max-ncache-ttl 10800; /* 3 hours */\n\ - max-cache-ttl 604800; /* 1 week */\n\ - transfer-format many-answers;\n\ - max-cache-size 0;\n\ - check-names master fail;\n\ - check-names slave warn;\n\ - check-names response ignore;\n\ - check-mx warn;\n\ - acache-enable no;\n\ - acache-cleaning-interval 60;\n\ - max-acache-size 0;\n\ - dnssec-enable yes;\n\ - dnssec-validation no; /* Make yes for 9.5. */ \n\ - dnssec-accept-expired no;\n\ - clients-per-query 10;\n\ - max-clients-per-query 100;\n\ - zero-no-soa-ttl-cache no;\n\ -" - -" /* zone */\n\ - allow-query {any;};\n\ - allow-transfer {any;};\n\ - notify yes;\n\ -# also-notify \n\ - notify-delay 5;\n\ - dialup no;\n\ -# forward \n\ -# forwarders \n\ - maintain-ixfr-base no;\n\ -# max-ixfr-log-size \n\ - transfer-source *;\n\ - transfer-source-v6 *;\n\ - alt-transfer-source *;\n\ - alt-transfer-source-v6 *;\n\ - max-transfer-time-in 120;\n\ - max-transfer-time-out 120;\n\ - max-transfer-idle-in 60;\n\ - max-transfer-idle-out 60;\n\ - max-retry-time 1209600; /* 2 weeks */\n\ - min-retry-time 500;\n\ - max-refresh-time 2419200; /* 4 weeks */\n\ - min-refresh-time 300;\n\ - multi-master no;\n\ - sig-validity-interval 30; /* days */\n\ - zone-statistics false;\n\ - max-journal-size unlimited;\n\ - ixfr-from-differences false;\n\ - check-wildcard yes;\n\ - check-sibling yes;\n\ - check-integrity yes;\n\ - check-mx-cname warn;\n\ - check-srv-cname warn;\n\ - zero-no-soa-ttl yes;\n\ - update-check-ksk yes;\n\ -};\n\ -" - -"#\n\ -# Zones in the \"_bind\" view are NOT counted in the count of zones.\n\ -#\n\ -view \"_bind\" chaos {\n\ - recursion no;\n\ - notify no;\n\ -\n\ - zone \"version.bind\" chaos {\n\ - type master;\n\ - database \"_builtin version\";\n\ - };\n\ -\n\ - zone \"hostname.bind\" chaos {\n\ - type master;\n\ - database \"_builtin hostname\";\n\ - };\n\ -\n\ - zone \"authors.bind\" chaos {\n\ - type master;\n\ - database \"_builtin authors\";\n\ - };\n\ - zone \"id.server\" chaos {\n\ - type master;\n\ - database \"_builtin id\";\n\ - };\n\ -};\n\ -"; - -isc_result_t -ns_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf) { - isc_buffer_t b; - - isc_buffer_init(&b, defaultconf, sizeof(defaultconf) - 1); - isc_buffer_add(&b, sizeof(defaultconf) - 1); - return (cfg_parse_buffer(parser, &b, &cfg_type_namedconf, conf)); -} - -isc_result_t -ns_config_get(const cfg_obj_t **maps, const char *name, const cfg_obj_t **obj) { - int i; - - for (i = 0;; i++) { - if (maps[i] == NULL) - return (ISC_R_NOTFOUND); - if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - } -} - -isc_result_t -ns_checknames_get(const cfg_obj_t **maps, const char *which, - const cfg_obj_t **obj) -{ - const cfg_listelt_t *element; - const cfg_obj_t *checknames; - const cfg_obj_t *type; - const cfg_obj_t *value; - int i; - - for (i = 0;; i++) { - if (maps[i] == NULL) - return (ISC_R_NOTFOUND); - checknames = NULL; - if (cfg_map_get(maps[i], "check-names", &checknames) == ISC_R_SUCCESS) { - /* - * Zone map entry is not a list. - */ - if (checknames != NULL && !cfg_obj_islist(checknames)) { - *obj = checknames; - return (ISC_R_SUCCESS); - } - for (element = cfg_list_first(checknames); - element != NULL; - element = cfg_list_next(element)) { - value = cfg_listelt_value(element); - type = cfg_tuple_get(value, "type"); - if (strcasecmp(cfg_obj_asstring(type), which) == 0) { - *obj = cfg_tuple_get(value, "mode"); - return (ISC_R_SUCCESS); - } - } - - } - } -} - -int -ns_config_listcount(const cfg_obj_t *list) { - const cfg_listelt_t *e; - int i = 0; - - for (e = cfg_list_first(list); e != NULL; e = cfg_list_next(e)) - i++; - - return (i); -} - -isc_result_t -ns_config_getclass(const cfg_obj_t *classobj, dns_rdataclass_t defclass, - dns_rdataclass_t *classp) { - isc_textregion_t r; - isc_result_t result; - - if (!cfg_obj_isstring(classobj)) { - *classp = defclass; - return (ISC_R_SUCCESS); - } - DE_CONST(cfg_obj_asstring(classobj), r.base); - r.length = strlen(r.base); - result = dns_rdataclass_fromtext(classp, &r); - if (result != ISC_R_SUCCESS) - cfg_obj_log(classobj, ns_g_lctx, ISC_LOG_ERROR, - "unknown class '%s'", r.base); - return (result); -} - -isc_result_t -ns_config_gettype(const cfg_obj_t *typeobj, dns_rdatatype_t deftype, - dns_rdatatype_t *typep) { - isc_textregion_t r; - isc_result_t result; - - if (!cfg_obj_isstring(typeobj)) { - *typep = deftype; - return (ISC_R_SUCCESS); - } - DE_CONST(cfg_obj_asstring(typeobj), r.base); - r.length = strlen(r.base); - result = dns_rdatatype_fromtext(typep, &r); - if (result != ISC_R_SUCCESS) - cfg_obj_log(typeobj, ns_g_lctx, ISC_LOG_ERROR, - "unknown type '%s'", r.base); - return (result); -} - -dns_zonetype_t -ns_config_getzonetype(const cfg_obj_t *zonetypeobj) { - dns_zonetype_t ztype = dns_zone_none; - const char *str; - - str = cfg_obj_asstring(zonetypeobj); - if (strcasecmp(str, "master") == 0) - ztype = dns_zone_master; - else if (strcasecmp(str, "slave") == 0) - ztype = dns_zone_slave; - else if (strcasecmp(str, "stub") == 0) - ztype = dns_zone_stub; - else - INSIST(0); - return (ztype); -} - -isc_result_t -ns_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list, - in_port_t defport, isc_mem_t *mctx, - isc_sockaddr_t **addrsp, isc_uint32_t *countp) -{ - int count, i = 0; - const cfg_obj_t *addrlist; - const cfg_obj_t *portobj; - const cfg_listelt_t *element; - isc_sockaddr_t *addrs; - in_port_t port; - isc_result_t result; - - INSIST(addrsp != NULL && *addrsp == NULL); - INSIST(countp != NULL); - - addrlist = cfg_tuple_get(list, "addresses"); - count = ns_config_listcount(addrlist); - - portobj = cfg_tuple_get(list, "port"); - if (cfg_obj_isuint32(portobj)) { - isc_uint32_t val = cfg_obj_asuint32(portobj); - if (val > ISC_UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", val); - return (ISC_R_RANGE); - } - port = (in_port_t) val; - } else if (defport != 0) - port = defport; - else { - result = ns_config_getport(config, &port); - if (result != ISC_R_SUCCESS) - return (result); - } - - addrs = isc_mem_get(mctx, count * sizeof(isc_sockaddr_t)); - if (addrs == NULL) - return (ISC_R_NOMEMORY); - - for (element = cfg_list_first(addrlist); - element != NULL; - element = cfg_list_next(element), i++) - { - INSIST(i < count); - addrs[i] = *cfg_obj_assockaddr(cfg_listelt_value(element)); - if (isc_sockaddr_getport(&addrs[i]) == 0) - isc_sockaddr_setport(&addrs[i], port); - } - INSIST(i == count); - - *addrsp = addrs; - *countp = count; - - return (ISC_R_SUCCESS); -} - -void -ns_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp, - isc_uint32_t count) -{ - INSIST(addrsp != NULL && *addrsp != NULL); - - isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t)); - *addrsp = NULL; -} - -static isc_result_t -get_masters_def(const cfg_obj_t *cctx, const char *name, - const cfg_obj_t **ret) -{ - isc_result_t result; - const cfg_obj_t *masters = NULL; - const cfg_listelt_t *elt; - - result = cfg_map_get(cctx, "masters", &masters); - if (result != ISC_R_SUCCESS) - return (result); - for (elt = cfg_list_first(masters); - elt != NULL; - elt = cfg_list_next(elt)) { - const cfg_obj_t *list; - const char *listname; - - list = cfg_listelt_value(elt); - listname = cfg_obj_asstring(cfg_tuple_get(list, "name")); - - if (strcasecmp(listname, name) == 0) { - *ret = list; - return (ISC_R_SUCCESS); - } - } - return (ISC_R_NOTFOUND); -} - -isc_result_t -ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list, - isc_mem_t *mctx, isc_sockaddr_t **addrsp, - dns_name_t ***keysp, isc_uint32_t *countp) -{ - isc_uint32_t addrcount = 0, keycount = 0, i = 0; - isc_uint32_t listcount = 0, l = 0, j; - isc_uint32_t stackcount = 0, pushed = 0; - isc_result_t result; - const cfg_listelt_t *element; - const cfg_obj_t *addrlist; - const cfg_obj_t *portobj; - in_port_t port; - dns_fixedname_t fname; - isc_sockaddr_t *addrs = NULL; - dns_name_t **keys = NULL; - struct { const char *name; } *lists = NULL; - struct { - const cfg_listelt_t *element; - in_port_t port; - } *stack = NULL; - - REQUIRE(addrsp != NULL && *addrsp == NULL); - REQUIRE(keysp != NULL && *keysp == NULL); - REQUIRE(countp != NULL); - - newlist: - addrlist = cfg_tuple_get(list, "addresses"); - portobj = cfg_tuple_get(list, "port"); - if (cfg_obj_isuint32(portobj)) { - isc_uint32_t val = cfg_obj_asuint32(portobj); - if (val > ISC_UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", val); - result = ISC_R_RANGE; - goto cleanup; - } - port = (in_port_t) val; - } else { - result = ns_config_getport(config, &port); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - result = ISC_R_NOMEMORY; - - element = cfg_list_first(addrlist); - resume: - for ( ; - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *addr; - const cfg_obj_t *key; - const char *keystr; - isc_buffer_t b; - - addr = cfg_tuple_get(cfg_listelt_value(element), - "masterselement"); - key = cfg_tuple_get(cfg_listelt_value(element), "key"); - - if (!cfg_obj_issockaddr(addr)) { - const char *listname = cfg_obj_asstring(addr); - isc_result_t tresult; - - /* Grow lists? */ - if (listcount == l) { - void * new; - isc_uint32_t newlen = listcount + 16; - size_t newsize, oldsize; - - newsize = newlen * sizeof(*lists); - oldsize = listcount * sizeof(*lists); - new = isc_mem_get(mctx, newsize); - if (new == NULL) - goto cleanup; - if (listcount != 0) { - memcpy(new, lists, oldsize); - isc_mem_put(mctx, lists, oldsize); - } - lists = new; - listcount = newlen; - } - /* Seen? */ - for (j = 0; j < l; j++) - if (strcasecmp(lists[j].name, listname) == 0) - break; - if (j < l) - continue; - tresult = get_masters_def(config, listname, &list); - if (tresult == ISC_R_NOTFOUND) { - cfg_obj_log(addr, ns_g_lctx, ISC_LOG_ERROR, - "masters \"%s\" not found", listname); - - result = tresult; - goto cleanup; - } - if (tresult != ISC_R_SUCCESS) - goto cleanup; - lists[l++].name = listname; - /* Grow stack? */ - if (stackcount == pushed) { - void * new; - isc_uint32_t newlen = stackcount + 16; - size_t newsize, oldsize; - - newsize = newlen * sizeof(*stack); - oldsize = stackcount * sizeof(*stack); - new = isc_mem_get(mctx, newsize); - if (new == NULL) - goto cleanup; - if (stackcount != 0) { - memcpy(new, stack, oldsize); - isc_mem_put(mctx, stack, oldsize); - } - stack = new; - stackcount = newlen; - } - /* - * We want to resume processing this list on the - * next element. - */ - stack[pushed].element = cfg_list_next(element); - stack[pushed].port = port; - pushed++; - goto newlist; - } - - if (i == addrcount) { - void * new; - isc_uint32_t newlen = addrcount + 16; - size_t newsize, oldsize; - - newsize = newlen * sizeof(isc_sockaddr_t); - oldsize = addrcount * sizeof(isc_sockaddr_t); - new = isc_mem_get(mctx, newsize); - if (new == NULL) - goto cleanup; - if (addrcount != 0) { - memcpy(new, addrs, oldsize); - isc_mem_put(mctx, addrs, oldsize); - } - addrs = new; - addrcount = newlen; - - newsize = newlen * sizeof(dns_name_t *); - oldsize = keycount * sizeof(dns_name_t *); - new = isc_mem_get(mctx, newsize); - if (new == NULL) - goto cleanup; - if (keycount != 0) { - memcpy(new, keys, oldsize); - isc_mem_put(mctx, keys, oldsize); - } - keys = new; - keycount = newlen; - } - - addrs[i] = *cfg_obj_assockaddr(addr); - if (isc_sockaddr_getport(&addrs[i]) == 0) - isc_sockaddr_setport(&addrs[i], port); - keys[i] = NULL; - if (!cfg_obj_isstring(key)) { - i++; - continue; - } - keys[i] = isc_mem_get(mctx, sizeof(dns_name_t)); - if (keys[i] == NULL) - goto cleanup; - dns_name_init(keys[i], NULL); - - keystr = cfg_obj_asstring(key); - isc_buffer_init(&b, keystr, strlen(keystr)); - isc_buffer_add(&b, strlen(keystr)); - dns_fixedname_init(&fname); - result = dns_name_fromtext(dns_fixedname_name(&fname), &b, - dns_rootname, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_name_dup(dns_fixedname_name(&fname), mctx, - keys[i]); - if (result != ISC_R_SUCCESS) - goto cleanup; - i++; - } - if (pushed != 0) { - pushed--; - element = stack[pushed].element; - port = stack[pushed].port; - goto resume; - } - if (i < addrcount) { - void * new; - size_t newsize, oldsize; - - newsize = i * sizeof(isc_sockaddr_t); - oldsize = addrcount * sizeof(isc_sockaddr_t); - if (i != 0) { - new = isc_mem_get(mctx, newsize); - if (new == NULL) - goto cleanup; - memcpy(new, addrs, newsize); - } else - new = NULL; - isc_mem_put(mctx, addrs, oldsize); - addrs = new; - addrcount = i; - - newsize = i * sizeof(dns_name_t *); - oldsize = keycount * sizeof(dns_name_t *); - if (i != 0) { - new = isc_mem_get(mctx, newsize); - if (new == NULL) - goto cleanup; - memcpy(new, keys, newsize); - } else - new = NULL; - isc_mem_put(mctx, keys, oldsize); - keys = new; - keycount = i; - } - - if (lists != NULL) - isc_mem_put(mctx, lists, listcount * sizeof(*lists)); - if (stack != NULL) - isc_mem_put(mctx, stack, stackcount * sizeof(*stack)); - - INSIST(keycount == addrcount); - - *addrsp = addrs; - *keysp = keys; - *countp = addrcount; - - return (ISC_R_SUCCESS); - - cleanup: - if (addrs != NULL) - isc_mem_put(mctx, addrs, addrcount * sizeof(isc_sockaddr_t)); - if (keys != NULL) { - for (j = 0; j <= i; j++) { - if (keys[j] == NULL) - continue; - if (dns_name_dynamic(keys[j])) - dns_name_free(keys[j], mctx); - isc_mem_put(mctx, keys[j], sizeof(dns_name_t)); - } - isc_mem_put(mctx, keys, keycount * sizeof(dns_name_t *)); - } - if (lists != NULL) - isc_mem_put(mctx, lists, listcount * sizeof(*lists)); - if (stack != NULL) - isc_mem_put(mctx, stack, stackcount * sizeof(*stack)); - return (result); -} - -void -ns_config_putipandkeylist(isc_mem_t *mctx, isc_sockaddr_t **addrsp, - dns_name_t ***keysp, isc_uint32_t count) -{ - unsigned int i; - dns_name_t **keys = *keysp; - - INSIST(addrsp != NULL && *addrsp != NULL); - - isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t)); - for (i = 0; i < count; i++) { - if (keys[i] == NULL) - continue; - if (dns_name_dynamic(keys[i])) - dns_name_free(keys[i], mctx); - isc_mem_put(mctx, keys[i], sizeof(dns_name_t)); - } - isc_mem_put(mctx, *keysp, count * sizeof(dns_name_t *)); - *addrsp = NULL; - *keysp = NULL; -} - -isc_result_t -ns_config_getport(const cfg_obj_t *config, in_port_t *portp) { - const cfg_obj_t *maps[3]; - const cfg_obj_t *options = NULL; - const cfg_obj_t *portobj = NULL; - isc_result_t result; - int i; - - (void)cfg_map_get(config, "options", &options); - i = 0; - if (options != NULL) - maps[i++] = options; - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - result = ns_config_get(maps, "port", &portobj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_asuint32(portobj) >= ISC_UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", - cfg_obj_asuint32(portobj)); - return (ISC_R_RANGE); - } - *portp = (in_port_t)cfg_obj_asuint32(portobj); - return (ISC_R_SUCCESS); -} - -struct keyalgorithms { - const char *str; - enum { hmacnone, hmacmd5, hmacsha1, hmacsha224, - hmacsha256, hmacsha384, hmacsha512 } hmac; - isc_uint16_t size; -} algorithms[] = { - { "hmac-md5", hmacmd5, 128 }, - { "hmac-md5.sig-alg.reg.int", hmacmd5, 0 }, - { "hmac-md5.sig-alg.reg.int.", hmacmd5, 0 }, - { "hmac-sha1", hmacsha1, 160 }, - { "hmac-sha224", hmacsha224, 224 }, - { "hmac-sha256", hmacsha256, 256 }, - { "hmac-sha384", hmacsha384, 384 }, - { "hmac-sha512", hmacsha512, 512 }, - { NULL, hmacnone, 0 } -}; - -isc_result_t -ns_config_getkeyalgorithm(const char *str, dns_name_t **name, - isc_uint16_t *digestbits) -{ - int i; - size_t len = 0; - isc_uint16_t bits; - isc_result_t result; - - for (i = 0; algorithms[i].str != NULL; i++) { - len = strlen(algorithms[i].str); - if (strncasecmp(algorithms[i].str, str, len) == 0 && - (str[len] == '\0' || - (algorithms[i].size != 0 && str[len] == '-'))) - break; - } - if (algorithms[i].str == NULL) - return (ISC_R_NOTFOUND); - if (str[len] == '-') { - result = isc_parse_uint16(&bits, str + len + 1, 10); - if (result != ISC_R_SUCCESS) - return (result); - if (bits > algorithms[i].size) - return (ISC_R_RANGE); - } else if (algorithms[i].size == 0) - bits = 128; - else - bits = algorithms[i].size; - - if (name != NULL) { - switch (algorithms[i].hmac) { - case hmacmd5: *name = dns_tsig_hmacmd5_name; break; - case hmacsha1: *name = dns_tsig_hmacsha1_name; break; - case hmacsha224: *name = dns_tsig_hmacsha224_name; break; - case hmacsha256: *name = dns_tsig_hmacsha256_name; break; - case hmacsha384: *name = dns_tsig_hmacsha384_name; break; - case hmacsha512: *name = dns_tsig_hmacsha512_name; break; - default: - INSIST(0); - } - } - if (digestbits != NULL) - *digestbits = bits; - return (ISC_R_SUCCESS); -} diff --git a/contrib/bind9/bin/named/control.c b/contrib/bind9/bin/named/control.c deleted file mode 100644 index 3f2d52e..0000000 --- a/contrib/bind9/bin/named/control.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 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: control.c,v 1.20.10.10 2007/09/13 23:46:26 tbox Exp $ */ - -/*! \file */ - -#include - - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include -#ifdef HAVE_LIBSCF -#include -#endif - -static isc_boolean_t -command_compare(const char *text, const char *command) { - unsigned int commandlen = strlen(command); - if (strncasecmp(text, command, commandlen) == 0 && - (text[commandlen] == '\0' || - text[commandlen] == ' ' || - text[commandlen] == '\t')) - return (ISC_TRUE); - return (ISC_FALSE); -} - -/*% - * This function is called to process the incoming command - * when a control channel message is received. - */ -isc_result_t -ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) { - isccc_sexpr_t *data; - char *command; - isc_result_t result; -#ifdef HAVE_LIBSCF - ns_smf_want_disable = 0; -#endif - - data = isccc_alist_lookup(message, "_data"); - if (data == NULL) { - /* - * No data section. - */ - return (ISC_R_FAILURE); - } - - result = isccc_cc_lookupstring(data, "type", &command); - if (result != ISC_R_SUCCESS) { - /* - * We have no idea what this is. - */ - return (result); - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_DEBUG(1), - "received control channel command '%s'", - command); - - /* - * Compare the 'command' parameter against all known control commands. - */ - if (command_compare(command, NS_COMMAND_RELOAD)) { - result = ns_server_reloadcommand(ns_g_server, command, text); - } else if (command_compare(command, NS_COMMAND_RECONFIG)) { - result = ns_server_reconfigcommand(ns_g_server, command); - } else if (command_compare(command, NS_COMMAND_REFRESH)) { - result = ns_server_refreshcommand(ns_g_server, command, text); - } else if (command_compare(command, NS_COMMAND_RETRANSFER)) { - result = ns_server_retransfercommand(ns_g_server, command); - } else if (command_compare(command, NS_COMMAND_HALT)) { -#ifdef HAVE_LIBSCF - /* - * If we are managed by smf(5), AND in chroot, then - * we cannot connect to the smf repository, so just - * return with an appropriate message back to rndc. - */ - if (ns_smf_got_instance == 1 && ns_smf_chroot == 1) { - result = ns_smf_add_message(text); - return (result); - } - /* - * If we are managed by smf(5) but not in chroot, - * try to disable ourselves the smf way. - */ - if (ns_smf_got_instance == 1 && ns_smf_chroot == 0) - ns_smf_want_disable = 1; - /* - * If ns_smf_got_instance = 0, ns_smf_chroot - * is not relevant and we fall through to - * isc_app_shutdown below. - */ -#endif - ns_server_flushonshutdown(ns_g_server, ISC_FALSE); - ns_os_shutdownmsg(command, text); - isc_app_shutdown(); - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_STOP)) { -#ifdef HAVE_LIBSCF - if (ns_smf_got_instance == 1 && ns_smf_chroot == 1) { - result = ns_smf_add_message(text); - return (result); - } - if (ns_smf_got_instance == 1 && ns_smf_chroot == 0) - ns_smf_want_disable = 1; -#endif - ns_server_flushonshutdown(ns_g_server, ISC_TRUE); - ns_os_shutdownmsg(command, text); - isc_app_shutdown(); - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_DUMPSTATS)) { - result = ns_server_dumpstats(ns_g_server); - } else if (command_compare(command, NS_COMMAND_QUERYLOG)) { - result = ns_server_togglequerylog(ns_g_server); - } else if (command_compare(command, NS_COMMAND_DUMPDB)) { - ns_server_dumpdb(ns_g_server, command); - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_TRACE)) { - result = ns_server_setdebuglevel(ns_g_server, command); - } else if (command_compare(command, NS_COMMAND_NOTRACE)) { - ns_g_debuglevel = 0; - isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_FLUSH)) { - result = ns_server_flushcache(ns_g_server, command); - } else if (command_compare(command, NS_COMMAND_FLUSHNAME)) { - result = ns_server_flushname(ns_g_server, command); - } else if (command_compare(command, NS_COMMAND_STATUS)) { - result = ns_server_status(ns_g_server, text); - } else if (command_compare(command, NS_COMMAND_FREEZE)) { - result = ns_server_freeze(ns_g_server, ISC_TRUE, command); - } else if (command_compare(command, NS_COMMAND_UNFREEZE) || - command_compare(command, NS_COMMAND_THAW)) { - result = ns_server_freeze(ns_g_server, ISC_FALSE, command); - } else if (command_compare(command, NS_COMMAND_RECURSING)) { - result = ns_server_dumprecursing(ns_g_server); - } else if (command_compare(command, NS_COMMAND_TIMERPOKE)) { - result = ISC_R_SUCCESS; - isc_timermgr_poke(ns_g_timermgr); - } else if (command_compare(command, NS_COMMAND_NULL)) { - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_NOTIFY)) { - result = ns_server_notifycommand(ns_g_server, command, text); - } else if (command_compare(command, NS_COMMAND_VALIDATION)) { - result = ns_server_validation(ns_g_server, command); - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "unknown control channel command '%s'", - command); - result = DNS_R_UNKNOWNCOMMAND; - } - - return (result); -} diff --git a/contrib/bind9/bin/named/controlconf.c b/contrib/bind9/bin/named/controlconf.c deleted file mode 100644 index 3e36446..0000000 --- a/contrib/bind9/bin/named/controlconf.c +++ /dev/null @@ -1,1461 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: controlconf.c,v 1.40.18.10 2006/12/07 04:53:02 marka Exp $ */ - -/*! \file */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -/* - * Note: Listeners and connections are not locked. All event handlers are - * executed by the server task, and all callers of exported routines must - * be running under the server task. - */ - -typedef struct controlkey controlkey_t; -typedef ISC_LIST(controlkey_t) controlkeylist_t; - -typedef struct controlconnection controlconnection_t; -typedef ISC_LIST(controlconnection_t) controlconnectionlist_t; - -typedef struct controllistener controllistener_t; -typedef ISC_LIST(controllistener_t) controllistenerlist_t; - -struct controlkey { - char * keyname; - isc_region_t secret; - ISC_LINK(controlkey_t) link; -}; - -struct controlconnection { - isc_socket_t * sock; - isccc_ccmsg_t ccmsg; - isc_boolean_t ccmsg_valid; - isc_boolean_t sending; - isc_timer_t * timer; - unsigned char buffer[2048]; - controllistener_t * listener; - isc_uint32_t nonce; - ISC_LINK(controlconnection_t) link; -}; - -struct controllistener { - ns_controls_t * controls; - isc_mem_t * mctx; - isc_task_t * task; - isc_sockaddr_t address; - isc_socket_t * sock; - dns_acl_t * acl; - isc_boolean_t listening; - isc_boolean_t exiting; - controlkeylist_t keys; - controlconnectionlist_t connections; - isc_sockettype_t type; - isc_uint32_t perm; - isc_uint32_t owner; - isc_uint32_t group; - ISC_LINK(controllistener_t) link; -}; - -struct ns_controls { - ns_server_t *server; - controllistenerlist_t listeners; - isc_boolean_t shuttingdown; - isccc_symtab_t *symtab; -}; - -static void control_newconn(isc_task_t *task, isc_event_t *event); -static void control_recvmessage(isc_task_t *task, isc_event_t *event); - -#define CLOCKSKEW 300 - -static void -free_controlkey(controlkey_t *key, isc_mem_t *mctx) { - if (key->keyname != NULL) - isc_mem_free(mctx, key->keyname); - if (key->secret.base != NULL) - isc_mem_put(mctx, key->secret.base, key->secret.length); - isc_mem_put(mctx, key, sizeof(*key)); -} - -static void -free_controlkeylist(controlkeylist_t *keylist, isc_mem_t *mctx) { - while (!ISC_LIST_EMPTY(*keylist)) { - controlkey_t *key = ISC_LIST_HEAD(*keylist); - ISC_LIST_UNLINK(*keylist, key, link); - free_controlkey(key, mctx); - } -} - -static void -free_listener(controllistener_t *listener) { - INSIST(listener->exiting); - INSIST(!listener->listening); - INSIST(ISC_LIST_EMPTY(listener->connections)); - - if (listener->sock != NULL) - isc_socket_detach(&listener->sock); - - free_controlkeylist(&listener->keys, listener->mctx); - - if (listener->acl != NULL) - dns_acl_detach(&listener->acl); - - isc_mem_put(listener->mctx, listener, sizeof(*listener)); -} - -static void -maybe_free_listener(controllistener_t *listener) { - if (listener->exiting && - !listener->listening && - ISC_LIST_EMPTY(listener->connections)) - free_listener(listener); -} - -static void -maybe_free_connection(controlconnection_t *conn) { - controllistener_t *listener = conn->listener; - - if (conn->timer != NULL) - isc_timer_detach(&conn->timer); - - if (conn->ccmsg_valid) { - isccc_ccmsg_cancelread(&conn->ccmsg); - return; - } - - if (conn->sending) { - isc_socket_cancel(conn->sock, listener->task, - ISC_SOCKCANCEL_SEND); - return; - } - - ISC_LIST_UNLINK(listener->connections, conn, link); - isc_mem_put(listener->mctx, conn, sizeof(*conn)); -} - -static void -shutdown_listener(controllistener_t *listener) { - controlconnection_t *conn; - controlconnection_t *next; - - if (!listener->exiting) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - - ISC_LIST_UNLINK(listener->controls->listeners, listener, link); - - isc_sockaddr_format(&listener->address, socktext, - sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, - "stopping command channel on %s", socktext); - if (listener->type == isc_sockettype_unix) - isc_socket_cleanunix(&listener->address, ISC_TRUE); - listener->exiting = ISC_TRUE; - } - - for (conn = ISC_LIST_HEAD(listener->connections); - conn != NULL; - conn = next) - { - next = ISC_LIST_NEXT(conn, link); - maybe_free_connection(conn); - } - - if (listener->listening) - isc_socket_cancel(listener->sock, listener->task, - ISC_SOCKCANCEL_ACCEPT); - - maybe_free_listener(listener); -} - -static isc_boolean_t -address_ok(isc_sockaddr_t *sockaddr, dns_acl_t *acl) { - isc_netaddr_t netaddr; - isc_result_t result; - int match; - - isc_netaddr_fromsockaddr(&netaddr, sockaddr); - - result = dns_acl_match(&netaddr, NULL, acl, - &ns_g_server->aclenv, &match, NULL); - - if (result != ISC_R_SUCCESS || match <= 0) - return (ISC_FALSE); - else - return (ISC_TRUE); -} - -static isc_result_t -control_accept(controllistener_t *listener) { - isc_result_t result; - result = isc_socket_accept(listener->sock, - listener->task, - control_newconn, listener); - if (result != ISC_R_SUCCESS) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socket_accept() failed: %s", - isc_result_totext(result)); - else - listener->listening = ISC_TRUE; - return (result); -} - -static isc_result_t -control_listen(controllistener_t *listener) { - isc_result_t result; - - result = isc_socket_listen(listener->sock, 0); - if (result != ISC_R_SUCCESS) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socket_listen() failed: %s", - isc_result_totext(result)); - return (result); -} - -static void -control_next(controllistener_t *listener) { - (void)control_accept(listener); -} - -static void -control_senddone(isc_task_t *task, isc_event_t *event) { - isc_socketevent_t *sevent = (isc_socketevent_t *) event; - controlconnection_t *conn = event->ev_arg; - controllistener_t *listener = conn->listener; - isc_socket_t *sock = (isc_socket_t *)sevent->ev_sender; - isc_result_t result; - - REQUIRE(conn->sending); - - UNUSED(task); - - conn->sending = ISC_FALSE; - - if (sevent->result != ISC_R_SUCCESS && - sevent->result != ISC_R_CANCELED) - { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_t peeraddr; - - (void)isc_socket_getpeername(sock, &peeraddr); - isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "error sending command response to %s: %s", - socktext, isc_result_totext(sevent->result)); - } - isc_event_free(&event); - - result = isccc_ccmsg_readmessage(&conn->ccmsg, listener->task, - control_recvmessage, conn); - if (result != ISC_R_SUCCESS) { - isc_socket_detach(&conn->sock); - maybe_free_connection(conn); - maybe_free_listener(listener); - } -} - -static inline void -log_invalid(isccc_ccmsg_t *ccmsg, isc_result_t result) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_t peeraddr; - - (void)isc_socket_getpeername(ccmsg->sock, &peeraddr); - isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_ERROR, - "invalid command from %s: %s", - socktext, isc_result_totext(result)); -} - -static void -control_recvmessage(isc_task_t *task, isc_event_t *event) { - controlconnection_t *conn; - controllistener_t *listener; - controlkey_t *key; - isccc_sexpr_t *request = NULL; - isccc_sexpr_t *response = NULL; - isccc_region_t ccregion; - isccc_region_t secret; - isc_stdtime_t now; - isc_buffer_t b; - isc_region_t r; - isc_uint32_t len; - isc_buffer_t text; - char textarray[1024]; - isc_result_t result; - isc_result_t eresult; - isccc_sexpr_t *_ctrl; - isccc_time_t sent; - isccc_time_t exp; - isc_uint32_t nonce; - - REQUIRE(event->ev_type == ISCCC_EVENT_CCMSG); - - conn = event->ev_arg; - listener = conn->listener; - secret.rstart = NULL; - - /* Is the server shutting down? */ - if (listener->controls->shuttingdown) - goto cleanup; - - if (conn->ccmsg.result != ISC_R_SUCCESS) { - if (conn->ccmsg.result != ISC_R_CANCELED && - conn->ccmsg.result != ISC_R_EOF) - log_invalid(&conn->ccmsg, conn->ccmsg.result); - goto cleanup; - } - - request = NULL; - - for (key = ISC_LIST_HEAD(listener->keys); - key != NULL; - key = ISC_LIST_NEXT(key, link)) - { - ccregion.rstart = isc_buffer_base(&conn->ccmsg.buffer); - ccregion.rend = isc_buffer_used(&conn->ccmsg.buffer); - if (secret.rstart != NULL) - isc_mem_put(listener->mctx, secret.rstart, - REGION_SIZE(secret)); - secret.rstart = isc_mem_get(listener->mctx, key->secret.length); - if (secret.rstart == NULL) - goto cleanup; - memcpy(secret.rstart, key->secret.base, key->secret.length); - secret.rend = secret.rstart + key->secret.length; - result = isccc_cc_fromwire(&ccregion, &request, &secret); - if (result == ISC_R_SUCCESS) - break; - else if (result == ISCCC_R_BADAUTH) { - /* - * For some reason, request is non-NULL when - * isccc_cc_fromwire returns ISCCC_R_BADAUTH. - */ - if (request != NULL) - isccc_sexpr_free(&request); - } else { - log_invalid(&conn->ccmsg, result); - goto cleanup; - } - } - - if (key == NULL) { - log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH); - goto cleanup; - } - - /* We shouldn't be getting a reply. */ - if (isccc_cc_isreply(request)) { - log_invalid(&conn->ccmsg, ISC_R_FAILURE); - goto cleanup; - } - - isc_stdtime_get(&now); - - /* - * Limit exposure to replay attacks. - */ - _ctrl = isccc_alist_lookup(request, "_ctrl"); - if (_ctrl == NULL) { - log_invalid(&conn->ccmsg, ISC_R_FAILURE); - goto cleanup; - } - - if (isccc_cc_lookupuint32(_ctrl, "_tim", &sent) == ISC_R_SUCCESS) { - if ((sent + CLOCKSKEW) < now || (sent - CLOCKSKEW) > now) { - log_invalid(&conn->ccmsg, ISCCC_R_CLOCKSKEW); - goto cleanup; - } - } else { - log_invalid(&conn->ccmsg, ISC_R_FAILURE); - goto cleanup; - } - - /* - * Expire messages that are too old. - */ - if (isccc_cc_lookupuint32(_ctrl, "_exp", &exp) == ISC_R_SUCCESS && - now > exp) { - log_invalid(&conn->ccmsg, ISCCC_R_EXPIRED); - goto cleanup; - } - - /* - * Duplicate suppression (required for UDP). - */ - isccc_cc_cleansymtab(listener->controls->symtab, now); - result = isccc_cc_checkdup(listener->controls->symtab, request, now); - if (result != ISC_R_SUCCESS) { - if (result == ISC_R_EXISTS) - result = ISCCC_R_DUPLICATE; - log_invalid(&conn->ccmsg, result); - goto cleanup; - } - - if (conn->nonce != 0 && - (isccc_cc_lookupuint32(_ctrl, "_nonce", &nonce) != ISC_R_SUCCESS || - conn->nonce != nonce)) { - log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH); - goto cleanup; - } - - /* - * Establish nonce. - */ - while (conn->nonce == 0) - isc_random_get(&conn->nonce); - - isc_buffer_init(&text, textarray, sizeof(textarray)); - eresult = ns_control_docommand(request, &text); - - result = isccc_cc_createresponse(request, now, now + 60, &response); - if (result != ISC_R_SUCCESS) - goto cleanup; - if (eresult != ISC_R_SUCCESS) { - isccc_sexpr_t *data; - - data = isccc_alist_lookup(response, "_data"); - if (data != NULL) { - const char *estr = isc_result_totext(eresult); - if (isccc_cc_definestring(data, "err", estr) == NULL) - goto cleanup; - } - } - - if (isc_buffer_usedlength(&text) > 0) { - isccc_sexpr_t *data; - - data = isccc_alist_lookup(response, "_data"); - if (data != NULL) { - char *str = (char *)isc_buffer_base(&text); - if (isccc_cc_definestring(data, "text", str) == NULL) - goto cleanup; - } - } - - _ctrl = isccc_alist_lookup(response, "_ctrl"); - if (_ctrl == NULL || - isccc_cc_defineuint32(_ctrl, "_nonce", conn->nonce) == NULL) - goto cleanup; - - ccregion.rstart = conn->buffer + 4; - ccregion.rend = conn->buffer + sizeof(conn->buffer); - result = isccc_cc_towire(response, &ccregion, &secret); - if (result != ISC_R_SUCCESS) - goto cleanup; - isc_buffer_init(&b, conn->buffer, 4); - len = sizeof(conn->buffer) - REGION_SIZE(ccregion); - isc_buffer_putuint32(&b, len - 4); - r.base = conn->buffer; - r.length = len; - - result = isc_socket_send(conn->sock, &r, task, control_senddone, conn); - if (result != ISC_R_SUCCESS) - goto cleanup; - conn->sending = ISC_TRUE; - - if (secret.rstart != NULL) - isc_mem_put(listener->mctx, secret.rstart, - REGION_SIZE(secret)); - if (request != NULL) - isccc_sexpr_free(&request); - if (response != NULL) - isccc_sexpr_free(&response); - return; - - cleanup: - if (secret.rstart != NULL) - isc_mem_put(listener->mctx, secret.rstart, - REGION_SIZE(secret)); - isc_socket_detach(&conn->sock); - isccc_ccmsg_invalidate(&conn->ccmsg); - conn->ccmsg_valid = ISC_FALSE; - maybe_free_connection(conn); - maybe_free_listener(listener); - if (request != NULL) - isccc_sexpr_free(&request); - if (response != NULL) - isccc_sexpr_free(&response); -} - -static void -control_timeout(isc_task_t *task, isc_event_t *event) { - controlconnection_t *conn = event->ev_arg; - - UNUSED(task); - - isc_timer_detach(&conn->timer); - maybe_free_connection(conn); - - isc_event_free(&event); -} - -static isc_result_t -newconnection(controllistener_t *listener, isc_socket_t *sock) { - controlconnection_t *conn; - isc_interval_t interval; - isc_result_t result; - - conn = isc_mem_get(listener->mctx, sizeof(*conn)); - if (conn == NULL) - return (ISC_R_NOMEMORY); - - conn->sock = sock; - isccc_ccmsg_init(listener->mctx, sock, &conn->ccmsg); - conn->ccmsg_valid = ISC_TRUE; - conn->sending = ISC_FALSE; - conn->timer = NULL; - isc_interval_set(&interval, 60, 0); - result = isc_timer_create(ns_g_timermgr, isc_timertype_once, - NULL, &interval, listener->task, - control_timeout, conn, &conn->timer); - if (result != ISC_R_SUCCESS) - goto cleanup; - - conn->listener = listener; - conn->nonce = 0; - ISC_LINK_INIT(conn, link); - - result = isccc_ccmsg_readmessage(&conn->ccmsg, listener->task, - control_recvmessage, conn); - if (result != ISC_R_SUCCESS) - goto cleanup; - isccc_ccmsg_setmaxsize(&conn->ccmsg, 2048); - - ISC_LIST_APPEND(listener->connections, conn, link); - return (ISC_R_SUCCESS); - - cleanup: - isccc_ccmsg_invalidate(&conn->ccmsg); - if (conn->timer != NULL) - isc_timer_detach(&conn->timer); - isc_mem_put(listener->mctx, conn, sizeof(*conn)); - return (result); -} - -static void -control_newconn(isc_task_t *task, isc_event_t *event) { - isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event; - controllistener_t *listener = event->ev_arg; - isc_socket_t *sock; - isc_sockaddr_t peeraddr; - isc_result_t result; - - UNUSED(task); - - listener->listening = ISC_FALSE; - - if (nevent->result != ISC_R_SUCCESS) { - if (nevent->result == ISC_R_CANCELED) { - shutdown_listener(listener); - goto cleanup; - } - goto restart; - } - - sock = nevent->newsocket; - (void)isc_socket_getpeername(sock, &peeraddr); - if (listener->type == isc_sockettype_tcp && - !address_ok(&peeraddr, listener->acl)) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "rejected command channel message from %s", - socktext); - isc_socket_detach(&sock); - goto restart; - } - - result = newconnection(listener, sock); - if (result != ISC_R_SUCCESS) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "dropped command channel from %s: %s", - socktext, isc_result_totext(result)); - isc_socket_detach(&sock); - goto restart; - } - - restart: - control_next(listener); - cleanup: - isc_event_free(&event); -} - -static void -controls_shutdown(ns_controls_t *controls) { - controllistener_t *listener; - controllistener_t *next; - - for (listener = ISC_LIST_HEAD(controls->listeners); - listener != NULL; - listener = next) - { - /* - * This is asynchronous. As listeners shut down, they will - * call their callbacks. - */ - next = ISC_LIST_NEXT(listener, link); - shutdown_listener(listener); - } -} - -void -ns_controls_shutdown(ns_controls_t *controls) { - controls_shutdown(controls); - controls->shuttingdown = ISC_TRUE; -} - -static isc_result_t -cfgkeylist_find(const cfg_obj_t *keylist, const char *keyname, - const cfg_obj_t **objp) -{ - const cfg_listelt_t *element; - const char *str; - const cfg_obj_t *obj; - - for (element = cfg_list_first(keylist); - element != NULL; - element = cfg_list_next(element)) - { - obj = cfg_listelt_value(element); - str = cfg_obj_asstring(cfg_map_getname(obj)); - if (strcasecmp(str, keyname) == 0) - break; - } - if (element == NULL) - return (ISC_R_NOTFOUND); - obj = cfg_listelt_value(element); - *objp = obj; - return (ISC_R_SUCCESS); -} - -static isc_result_t -controlkeylist_fromcfg(const cfg_obj_t *keylist, isc_mem_t *mctx, - controlkeylist_t *keyids) -{ - const cfg_listelt_t *element; - char *newstr = NULL; - const char *str; - const cfg_obj_t *obj; - controlkey_t *key; - - for (element = cfg_list_first(keylist); - element != NULL; - element = cfg_list_next(element)) - { - obj = cfg_listelt_value(element); - str = cfg_obj_asstring(obj); - newstr = isc_mem_strdup(mctx, str); - if (newstr == NULL) - goto cleanup; - key = isc_mem_get(mctx, sizeof(*key)); - if (key == NULL) - goto cleanup; - key->keyname = newstr; - key->secret.base = NULL; - key->secret.length = 0; - ISC_LINK_INIT(key, link); - ISC_LIST_APPEND(*keyids, key, link); - newstr = NULL; - } - return (ISC_R_SUCCESS); - - cleanup: - if (newstr != NULL) - isc_mem_free(mctx, newstr); - free_controlkeylist(keyids, mctx); - return (ISC_R_NOMEMORY); -} - -static void -register_keys(const cfg_obj_t *control, const cfg_obj_t *keylist, - controlkeylist_t *keyids, isc_mem_t *mctx, const char *socktext) -{ - controlkey_t *keyid, *next; - const cfg_obj_t *keydef; - char secret[1024]; - isc_buffer_t b; - isc_result_t result; - - /* - * Find the keys corresponding to the keyids used by this listener. - */ - for (keyid = ISC_LIST_HEAD(*keyids); keyid != NULL; keyid = next) { - next = ISC_LIST_NEXT(keyid, link); - - result = cfgkeylist_find(keylist, keyid->keyname, &keydef); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't find key '%s' for use with " - "command channel %s", - keyid->keyname, socktext); - ISC_LIST_UNLINK(*keyids, keyid, link); - free_controlkey(keyid, mctx); - } else { - const cfg_obj_t *algobj = NULL; - const cfg_obj_t *secretobj = NULL; - const char *algstr = NULL; - const char *secretstr = NULL; - - (void)cfg_map_get(keydef, "algorithm", &algobj); - (void)cfg_map_get(keydef, "secret", &secretobj); - INSIST(algobj != NULL && secretobj != NULL); - - algstr = cfg_obj_asstring(algobj); - secretstr = cfg_obj_asstring(secretobj); - - if (ns_config_getkeyalgorithm(algstr, NULL, NULL) != - ISC_R_SUCCESS) - { - cfg_obj_log(control, ns_g_lctx, - ISC_LOG_WARNING, - "unsupported algorithm '%s' in " - "key '%s' for use with command " - "channel %s", - algstr, keyid->keyname, socktext); - ISC_LIST_UNLINK(*keyids, keyid, link); - free_controlkey(keyid, mctx); - continue; - } - - isc_buffer_init(&b, secret, sizeof(secret)); - result = isc_base64_decodestring(secretstr, &b); - - if (result != ISC_R_SUCCESS) { - cfg_obj_log(keydef, ns_g_lctx, ISC_LOG_WARNING, - "secret for key '%s' on " - "command channel %s: %s", - keyid->keyname, socktext, - isc_result_totext(result)); - ISC_LIST_UNLINK(*keyids, keyid, link); - free_controlkey(keyid, mctx); - continue; - } - - keyid->secret.length = isc_buffer_usedlength(&b); - keyid->secret.base = isc_mem_get(mctx, - keyid->secret.length); - if (keyid->secret.base == NULL) { - cfg_obj_log(keydef, ns_g_lctx, ISC_LOG_WARNING, - "couldn't register key '%s': " - "out of memory", keyid->keyname); - ISC_LIST_UNLINK(*keyids, keyid, link); - free_controlkey(keyid, mctx); - break; - } - memcpy(keyid->secret.base, isc_buffer_base(&b), - keyid->secret.length); - } - } -} - -#define CHECK(x) \ - do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto cleanup; \ - } while (0) - -static isc_result_t -get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) { - isc_result_t result; - cfg_parser_t *pctx = NULL; - cfg_obj_t *config = NULL; - const cfg_obj_t *key = NULL; - const cfg_obj_t *algobj = NULL; - const cfg_obj_t *secretobj = NULL; - const char *algstr = NULL; - const char *secretstr = NULL; - controlkey_t *keyid = NULL; - char secret[1024]; - isc_buffer_t b; - - CHECK(cfg_parser_create(mctx, ns_g_lctx, &pctx)); - CHECK(cfg_parse_file(pctx, ns_g_keyfile, &cfg_type_rndckey, &config)); - CHECK(cfg_map_get(config, "key", &key)); - - keyid = isc_mem_get(mctx, sizeof(*keyid)); - if (keyid == NULL) - CHECK(ISC_R_NOMEMORY); - keyid->keyname = isc_mem_strdup(mctx, - cfg_obj_asstring(cfg_map_getname(key))); - keyid->secret.base = NULL; - keyid->secret.length = 0; - ISC_LINK_INIT(keyid, link); - if (keyid->keyname == NULL) - CHECK(ISC_R_NOMEMORY); - - CHECK(bind9_check_key(key, ns_g_lctx)); - - (void)cfg_map_get(key, "algorithm", &algobj); - (void)cfg_map_get(key, "secret", &secretobj); - INSIST(algobj != NULL && secretobj != NULL); - - algstr = cfg_obj_asstring(algobj); - secretstr = cfg_obj_asstring(secretobj); - - if (ns_config_getkeyalgorithm(algstr, NULL, NULL) != ISC_R_SUCCESS) { - cfg_obj_log(key, ns_g_lctx, - ISC_LOG_WARNING, - "unsupported algorithm '%s' in " - "key '%s' for use with command " - "channel", - algstr, keyid->keyname); - goto cleanup; - } - - isc_buffer_init(&b, secret, sizeof(secret)); - result = isc_base64_decodestring(secretstr, &b); - - if (result != ISC_R_SUCCESS) { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, - "secret for key '%s' on command channel: %s", - keyid->keyname, isc_result_totext(result)); - CHECK(result); - } - - keyid->secret.length = isc_buffer_usedlength(&b); - keyid->secret.base = isc_mem_get(mctx, - keyid->secret.length); - if (keyid->secret.base == NULL) { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, - "couldn't register key '%s': " - "out of memory", keyid->keyname); - CHECK(ISC_R_NOMEMORY); - } - memcpy(keyid->secret.base, isc_buffer_base(&b), - keyid->secret.length); - ISC_LIST_APPEND(*keyids, keyid, link); - keyid = NULL; - result = ISC_R_SUCCESS; - - cleanup: - if (keyid != NULL) - free_controlkey(keyid, mctx); - if (config != NULL) - cfg_obj_destroy(pctx, &config); - if (pctx != NULL) - cfg_parser_destroy(&pctx); - return (result); -} - -/* - * Ensures that both '*global_keylistp' and '*control_keylistp' are - * valid or both are NULL. - */ -static void -get_key_info(const cfg_obj_t *config, const cfg_obj_t *control, - const cfg_obj_t **global_keylistp, - const cfg_obj_t **control_keylistp) -{ - isc_result_t result; - const cfg_obj_t *control_keylist = NULL; - const cfg_obj_t *global_keylist = NULL; - - REQUIRE(global_keylistp != NULL && *global_keylistp == NULL); - REQUIRE(control_keylistp != NULL && *control_keylistp == NULL); - - control_keylist = cfg_tuple_get(control, "keys"); - - if (!cfg_obj_isvoid(control_keylist) && - cfg_list_first(control_keylist) != NULL) { - result = cfg_map_get(config, "key", &global_keylist); - - if (result == ISC_R_SUCCESS) { - *global_keylistp = global_keylist; - *control_keylistp = control_keylist; - } - } -} - -static void -update_listener(ns_controls_t *cp, controllistener_t **listenerp, - const cfg_obj_t *control, const cfg_obj_t *config, - isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx, - const char *socktext, isc_sockettype_t type) -{ - controllistener_t *listener; - const cfg_obj_t *allow; - const cfg_obj_t *global_keylist = NULL; - const cfg_obj_t *control_keylist = NULL; - dns_acl_t *new_acl = NULL; - controlkeylist_t keys; - isc_result_t result = ISC_R_SUCCESS; - - for (listener = ISC_LIST_HEAD(cp->listeners); - listener != NULL; - listener = ISC_LIST_NEXT(listener, link)) - if (isc_sockaddr_equal(addr, &listener->address)) - break; - - if (listener == NULL) { - *listenerp = NULL; - return; - } - - /* - * There is already a listener for this sockaddr. - * Update the access list and key information. - * - * First try to deal with the key situation. There are a few - * possibilities: - * (a) It had an explicit keylist and still has an explicit keylist. - * (b) It had an automagic key and now has an explicit keylist. - * (c) It had an explicit keylist and now needs an automagic key. - * (d) It has an automagic key and still needs the automagic key. - * - * (c) and (d) are the annoying ones. The caller needs to know - * that it should use the automagic configuration for key information - * in place of the named.conf configuration. - * - * XXXDCL There is one other hazard that has not been dealt with, - * the problem that if a key change is being caused by a control - * channel reload, then the response will be with the new key - * and not able to be decrypted by the client. - */ - if (control != NULL) - get_key_info(config, control, &global_keylist, - &control_keylist); - - if (control_keylist != NULL) { - INSIST(global_keylist != NULL); - - ISC_LIST_INIT(keys); - result = controlkeylist_fromcfg(control_keylist, - listener->mctx, &keys); - if (result == ISC_R_SUCCESS) { - free_controlkeylist(&listener->keys, listener->mctx); - listener->keys = keys; - register_keys(control, global_keylist, &listener->keys, - listener->mctx, socktext); - } - } else { - free_controlkeylist(&listener->keys, listener->mctx); - result = get_rndckey(listener->mctx, &listener->keys); - } - - if (result != ISC_R_SUCCESS && global_keylist != NULL) { - /* - * This message might be a little misleading since the - * "new keys" might in fact be identical to the old ones, - * but tracking whether they are identical just for the - * sake of avoiding this message would be too much trouble. - */ - if (control != NULL) - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't install new keys for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "couldn't install new keys for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - } - - /* - * Now, keep the old access list unless a new one can be made. - */ - if (control != NULL && type == isc_sockettype_tcp) { - allow = cfg_tuple_get(control, "allow"); - result = cfg_acl_fromconfig(allow, config, ns_g_lctx, - aclconfctx, listener->mctx, - &new_acl); - } else { - result = dns_acl_any(listener->mctx, &new_acl); - } - - if (result == ISC_R_SUCCESS) { - dns_acl_detach(&listener->acl); - dns_acl_attach(new_acl, &listener->acl); - dns_acl_detach(&new_acl); - /* XXXDCL say the old acl is still used? */ - } else if (control != NULL) - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't install new acl for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "couldn't install new acl for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - - if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) { - isc_uint32_t perm, owner, group; - perm = cfg_obj_asuint32(cfg_tuple_get(control, "perm")); - owner = cfg_obj_asuint32(cfg_tuple_get(control, "owner")); - group = cfg_obj_asuint32(cfg_tuple_get(control, "group")); - result = ISC_R_SUCCESS; - if (listener->perm != perm || listener->owner != owner || - listener->group != group) - result = isc_socket_permunix(&listener->address, perm, - owner, group); - if (result == ISC_R_SUCCESS) { - listener->perm = perm; - listener->owner = owner; - listener->group = group; - } else if (control != NULL) - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't update ownership/permission for " - "command channel %s", socktext); - } - - *listenerp = listener; -} - -static void -add_listener(ns_controls_t *cp, controllistener_t **listenerp, - const cfg_obj_t *control, const cfg_obj_t *config, - isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx, - const char *socktext, isc_sockettype_t type) -{ - isc_mem_t *mctx = cp->server->mctx; - controllistener_t *listener; - const cfg_obj_t *allow; - const cfg_obj_t *global_keylist = NULL; - const cfg_obj_t *control_keylist = NULL; - dns_acl_t *new_acl = NULL; - isc_result_t result = ISC_R_SUCCESS; - - listener = isc_mem_get(mctx, sizeof(*listener)); - if (listener == NULL) - result = ISC_R_NOMEMORY; - - if (result == ISC_R_SUCCESS) { - listener->controls = cp; - listener->mctx = mctx; - listener->task = cp->server->task; - listener->address = *addr; - listener->sock = NULL; - listener->listening = ISC_FALSE; - listener->exiting = ISC_FALSE; - listener->acl = NULL; - listener->type = type; - listener->perm = 0; - listener->owner = 0; - listener->group = 0; - ISC_LINK_INIT(listener, link); - ISC_LIST_INIT(listener->keys); - ISC_LIST_INIT(listener->connections); - - /* - * Make the acl. - */ - if (control != NULL && type == isc_sockettype_tcp) { - allow = cfg_tuple_get(control, "allow"); - result = cfg_acl_fromconfig(allow, config, ns_g_lctx, - aclconfctx, mctx, &new_acl); - } else { - result = dns_acl_any(mctx, &new_acl); - } - } - - if (result == ISC_R_SUCCESS) { - dns_acl_attach(new_acl, &listener->acl); - dns_acl_detach(&new_acl); - - if (config != NULL) - get_key_info(config, control, &global_keylist, - &control_keylist); - - if (control_keylist != NULL) { - result = controlkeylist_fromcfg(control_keylist, - listener->mctx, - &listener->keys); - if (result == ISC_R_SUCCESS) - register_keys(control, global_keylist, - &listener->keys, - listener->mctx, socktext); - } else - result = get_rndckey(mctx, &listener->keys); - - if (result != ISC_R_SUCCESS && control != NULL) - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't install keys for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - } - - if (result == ISC_R_SUCCESS) { - int pf = isc_sockaddr_pf(&listener->address); - if ((pf == AF_INET && isc_net_probeipv4() != ISC_R_SUCCESS) || -#ifdef ISC_PLATFORM_HAVESYSUNH - (pf == AF_UNIX && isc_net_probeunix() != ISC_R_SUCCESS) || -#endif - (pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS)) - result = ISC_R_FAMILYNOSUPPORT; - } - - if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) - isc_socket_cleanunix(&listener->address, ISC_FALSE); - - if (result == ISC_R_SUCCESS) - result = isc_socket_create(ns_g_socketmgr, - isc_sockaddr_pf(&listener->address), - type, &listener->sock); - - if (result == ISC_R_SUCCESS) - result = isc_socket_bind(listener->sock, - &listener->address); - - if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) { - listener->perm = cfg_obj_asuint32(cfg_tuple_get(control, - "perm")); - listener->owner = cfg_obj_asuint32(cfg_tuple_get(control, - "owner")); - listener->group = cfg_obj_asuint32(cfg_tuple_get(control, - "group")); - result = isc_socket_permunix(&listener->address, listener->perm, - listener->owner, listener->group); - } - if (result == ISC_R_SUCCESS) - result = control_listen(listener); - - if (result == ISC_R_SUCCESS) - result = control_accept(listener); - - if (result == ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, - "command channel listening on %s", socktext); - *listenerp = listener; - - } else { - if (listener != NULL) { - listener->exiting = ISC_TRUE; - free_listener(listener); - } - - if (control != NULL) - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't add command channel %s: %s", - socktext, isc_result_totext(result)); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, - "couldn't add command channel %s: %s", - socktext, isc_result_totext(result)); - - *listenerp = NULL; - } - - /* XXXDCL return error results? fail hard? */ -} - -isc_result_t -ns_controls_configure(ns_controls_t *cp, const cfg_obj_t *config, - cfg_aclconfctx_t *aclconfctx) -{ - controllistener_t *listener; - controllistenerlist_t new_listeners; - const cfg_obj_t *controlslist = NULL; - const cfg_listelt_t *element, *element2; - char socktext[ISC_SOCKADDR_FORMATSIZE]; - - ISC_LIST_INIT(new_listeners); - - /* - * Get the list of named.conf 'controls' statements. - */ - (void)cfg_map_get(config, "controls", &controlslist); - - /* - * Run through the new control channel list, noting sockets that - * are already being listened on and moving them to the new list. - * - * Identifying duplicate addr/port combinations is left to either - * the underlying config code, or to the bind attempt getting an - * address-in-use error. - */ - if (controlslist != NULL) { - for (element = cfg_list_first(controlslist); - element != NULL; - element = cfg_list_next(element)) { - const cfg_obj_t *controls; - const cfg_obj_t *inetcontrols = NULL; - - controls = cfg_listelt_value(element); - (void)cfg_map_get(controls, "inet", &inetcontrols); - if (inetcontrols == NULL) - continue; - - for (element2 = cfg_list_first(inetcontrols); - element2 != NULL; - element2 = cfg_list_next(element2)) { - const cfg_obj_t *control; - const cfg_obj_t *obj; - isc_sockaddr_t addr; - - /* - * The parser handles BIND 8 configuration file - * syntax, so it allows unix phrases as well - * inet phrases with no keys{} clause. - */ - control = cfg_listelt_value(element2); - - obj = cfg_tuple_get(control, "address"); - addr = *cfg_obj_assockaddr(obj); - if (isc_sockaddr_getport(&addr) == 0) - isc_sockaddr_setport(&addr, - NS_CONTROL_PORT); - - isc_sockaddr_format(&addr, socktext, - sizeof(socktext)); - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, - ISC_LOG_DEBUG(9), - "processing control channel %s", - socktext); - - update_listener(cp, &listener, control, config, - &addr, aclconfctx, socktext, - isc_sockettype_tcp); - - if (listener != NULL) - /* - * Remove the listener from the old - * list, so it won't be shut down. - */ - ISC_LIST_UNLINK(cp->listeners, - listener, link); - else - /* - * This is a new listener. - */ - add_listener(cp, &listener, control, - config, &addr, aclconfctx, - socktext, - isc_sockettype_tcp); - - if (listener != NULL) - ISC_LIST_APPEND(new_listeners, - listener, link); - } - } - for (element = cfg_list_first(controlslist); - element != NULL; - element = cfg_list_next(element)) { - const cfg_obj_t *controls; - const cfg_obj_t *unixcontrols = NULL; - - controls = cfg_listelt_value(element); - (void)cfg_map_get(controls, "unix", &unixcontrols); - if (unixcontrols == NULL) - continue; - - for (element2 = cfg_list_first(unixcontrols); - element2 != NULL; - element2 = cfg_list_next(element2)) { - const cfg_obj_t *control; - const cfg_obj_t *path; - isc_sockaddr_t addr; - isc_result_t result; - - /* - * The parser handles BIND 8 configuration file - * syntax, so it allows unix phrases as well - * inet phrases with no keys{} clause. - */ - control = cfg_listelt_value(element2); - - path = cfg_tuple_get(control, "path"); - result = isc_sockaddr_frompath(&addr, - cfg_obj_asstring(path)); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, - ISC_LOG_DEBUG(9), - "control channel '%s': %s", - cfg_obj_asstring(path), - isc_result_totext(result)); - continue; - } - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, - ISC_LOG_DEBUG(9), - "processing control channel '%s'", - cfg_obj_asstring(path)); - - update_listener(cp, &listener, control, config, - &addr, aclconfctx, - cfg_obj_asstring(path), - isc_sockettype_unix); - - if (listener != NULL) - /* - * Remove the listener from the old - * list, so it won't be shut down. - */ - ISC_LIST_UNLINK(cp->listeners, - listener, link); - else - /* - * This is a new listener. - */ - add_listener(cp, &listener, control, - config, &addr, aclconfctx, - cfg_obj_asstring(path), - isc_sockettype_unix); - - if (listener != NULL) - ISC_LIST_APPEND(new_listeners, - listener, link); - } - } - } else { - int i; - - for (i = 0; i < 2; i++) { - isc_sockaddr_t addr; - - if (i == 0) { - struct in_addr localhost; - - if (isc_net_probeipv4() != ISC_R_SUCCESS) - continue; - localhost.s_addr = htonl(INADDR_LOOPBACK); - isc_sockaddr_fromin(&addr, &localhost, 0); - } else { - if (isc_net_probeipv6() != ISC_R_SUCCESS) - continue; - isc_sockaddr_fromin6(&addr, - &in6addr_loopback, 0); - } - isc_sockaddr_setport(&addr, NS_CONTROL_PORT); - - isc_sockaddr_format(&addr, socktext, sizeof(socktext)); - - update_listener(cp, &listener, NULL, NULL, - &addr, NULL, socktext, - isc_sockettype_tcp); - - if (listener != NULL) - /* - * Remove the listener from the old - * list, so it won't be shut down. - */ - ISC_LIST_UNLINK(cp->listeners, - listener, link); - else - /* - * This is a new listener. - */ - add_listener(cp, &listener, NULL, NULL, - &addr, NULL, socktext, - isc_sockettype_tcp); - - if (listener != NULL) - ISC_LIST_APPEND(new_listeners, - listener, link); - } - } - - /* - * ns_control_shutdown() will stop whatever is on the global - * listeners list, which currently only has whatever sockaddrs - * were in the previous configuration (if any) that do not - * remain in the current configuration. - */ - controls_shutdown(cp); - - /* - * Put all of the valid listeners on the listeners list. - * Anything already on listeners in the process of shutting - * down will be taken care of by listen_done(). - */ - ISC_LIST_APPENDLIST(cp->listeners, new_listeners, link); - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp) { - isc_mem_t *mctx = server->mctx; - isc_result_t result; - ns_controls_t *controls = isc_mem_get(mctx, sizeof(*controls)); - - if (controls == NULL) - return (ISC_R_NOMEMORY); - controls->server = server; - ISC_LIST_INIT(controls->listeners); - controls->shuttingdown = ISC_FALSE; - controls->symtab = NULL; - result = isccc_cc_createsymtab(&controls->symtab); - if (result != ISC_R_SUCCESS) { - isc_mem_put(server->mctx, controls, sizeof(*controls)); - return (result); - } - *ctrlsp = controls; - return (ISC_R_SUCCESS); -} - -void -ns_controls_destroy(ns_controls_t **ctrlsp) { - ns_controls_t *controls = *ctrlsp; - - REQUIRE(ISC_LIST_EMPTY(controls->listeners)); - - isccc_symtab_destroy(&controls->symtab); - isc_mem_put(controls->server->mctx, controls, sizeof(*controls)); - *ctrlsp = NULL; -} diff --git a/contrib/bind9/bin/named/include/named/builtin.h b/contrib/bind9/bin/named/include/named/builtin.h deleted file mode 100644 index 37a3e76..0000000 --- a/contrib/bind9/bin/named/include/named/builtin.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: builtin.h,v 1.2.18.2 2005/04/29 00:15:34 marka Exp $ */ - -#ifndef NAMED_BUILTIN_H -#define NAMED_BUILTIN_H 1 - -/*! \file */ - -#include - -isc_result_t ns_builtin_init(void); - -void ns_builtin_deinit(void); - -#endif /* NAMED_BUILTIN_H */ diff --git a/contrib/bind9/bin/named/include/named/client.h b/contrib/bind9/bin/named/include/named/client.h deleted file mode 100644 index 0cf7985..0000000 --- a/contrib/bind9/bin/named/include/named/client.h +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: client.h,v 1.69.18.9 2006/06/06 00:11:41 marka Exp $ */ - -#ifndef NAMED_CLIENT_H -#define NAMED_CLIENT_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * This module defines two objects, ns_client_t and ns_clientmgr_t. - * - * An ns_client_t object handles incoming DNS requests from clients - * on a given network interface. - * - * Each ns_client_t object can handle only one TCP connection or UDP - * request at a time. Therefore, several ns_client_t objects are - * typically created to serve each network interface, e.g., one - * for handling TCP requests and a few (one per CPU) for handling - * UDP requests. - * - * Incoming requests are classified as queries, zone transfer - * requests, update requests, notify requests, etc, and handed off - * to the appropriate request handler. When the request has been - * fully handled (which can be much later), the ns_client_t must be - * notified of this by calling one of the following functions - * exactly once in the context of its task: - * \code - * ns_client_send() (sending a non-error response) - * ns_client_sendraw() (sending a raw response) - * ns_client_error() (sending an error response) - * ns_client_next() (sending no response) - *\endcode - * This will release any resources used by the request and - * and allow the ns_client_t to listen for the next request. - * - * A ns_clientmgr_t manages a number of ns_client_t objects. - * New ns_client_t objects are created by calling - * ns_clientmgr_createclients(). They are destroyed by - * destroying their manager. - */ - -/*** - *** Imports - ***/ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -/*** - *** Types - ***/ - -typedef ISC_LIST(ns_client_t) client_list_t; - -/*% nameserver client structure */ -struct ns_client { - unsigned int magic; - isc_mem_t * mctx; - ns_clientmgr_t * manager; - int state; - int newstate; - int naccepts; - int nreads; - int nsends; - int nrecvs; - int nupdates; - int nctls; - int references; - unsigned int attributes; - isc_task_t * task; - dns_view_t * view; - dns_dispatch_t * dispatch; - isc_socket_t * udpsocket; - isc_socket_t * tcplistener; - isc_socket_t * tcpsocket; - unsigned char * tcpbuf; - dns_tcpmsg_t tcpmsg; - isc_boolean_t tcpmsg_valid; - isc_timer_t * timer; - isc_boolean_t timerset; - dns_message_t * message; - isc_socketevent_t * sendevent; - isc_socketevent_t * recvevent; - unsigned char * recvbuf; - dns_rdataset_t * opt; - isc_uint16_t udpsize; - isc_uint16_t extflags; - isc_int16_t ednsversion; /* -1 noedns */ - void (*next)(ns_client_t *); - void (*shutdown)(void *arg, isc_result_t result); - void *shutdown_arg; - ns_query_t query; - isc_stdtime_t requesttime; - isc_stdtime_t now; - dns_name_t signername; /*%< [T]SIG key name */ - dns_name_t * signer; /*%< NULL if not valid sig */ - isc_boolean_t mortal; /*%< Die after handling request */ - isc_quota_t *tcpquota; - isc_quota_t *recursionquota; - ns_interface_t *interface; - isc_sockaddr_t peeraddr; - isc_boolean_t peeraddr_valid; - struct in6_pktinfo pktinfo; - isc_event_t ctlevent; - /*% - * Information about recent FORMERR response(s), for - * FORMERR loop avoidance. This is separate for each - * client object rather than global only to avoid - * the need for locking. - */ - struct { - isc_sockaddr_t addr; - isc_stdtime_t time; - dns_messageid_t id; - } formerrcache; - ISC_LINK(ns_client_t) link; - /*% - * The list 'link' is part of, or NULL if not on any list. - */ - client_list_t *list; -}; - -#define NS_CLIENT_MAGIC ISC_MAGIC('N','S','C','c') -#define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC) - -#define NS_CLIENTATTR_TCP 0x01 -#define NS_CLIENTATTR_RA 0x02 /*%< Client gets recusive service */ -#define NS_CLIENTATTR_PKTINFO 0x04 /*%< pktinfo is valid */ -#define NS_CLIENTATTR_MULTICAST 0x08 /*%< recv'd from multicast */ -#define NS_CLIENTATTR_WANTDNSSEC 0x10 /*%< include dnssec records */ - -extern unsigned int ns_client_requests; - -/*** - *** Functions - ***/ - -/*% - * Note! These ns_client_ routines MUST be called ONLY from the client's - * task in order to ensure synchronization. - */ - -void -ns_client_send(ns_client_t *client); -/*% - * Finish processing the current client request and - * send client->message as a response. - * \brief - * Note! These ns_client_ routines MUST be called ONLY from the client's - * task in order to ensure synchronization. - */ - -void -ns_client_sendraw(ns_client_t *client, dns_message_t *msg); -/*% - * Finish processing the current client request and - * send msg as a response using client->message->id for the id. - */ - -void -ns_client_error(ns_client_t *client, isc_result_t result); -/*% - * Finish processing the current client request and return - * an error response to the client. The error response - * will have an RCODE determined by 'result'. - */ - -void -ns_client_next(ns_client_t *client, isc_result_t result); -/*% - * Finish processing the current client request, - * return no response to the client. - */ - -isc_boolean_t -ns_client_shuttingdown(ns_client_t *client); -/*% - * Return ISC_TRUE iff the client is currently shutting down. - */ - -void -ns_client_attach(ns_client_t *source, ns_client_t **target); -/*% - * Attach '*targetp' to 'source'. - */ - -void -ns_client_detach(ns_client_t **clientp); -/*% - * Detach '*clientp' from its client. - */ - -isc_result_t -ns_client_replace(ns_client_t *client); -/*% - * Try to replace the current client with a new one, so that the - * current one can go off and do some lengthy work without - * leaving the dispatch/socket without service. - */ - -void -ns_client_settimeout(ns_client_t *client, unsigned int seconds); -/*% - * Set a timer in the client to go off in the specified amount of time. - */ - -isc_result_t -ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, ns_clientmgr_t **managerp); -/*% - * Create a client manager. - */ - -void -ns_clientmgr_destroy(ns_clientmgr_t **managerp); -/*% - * Destroy a client manager and all ns_client_t objects - * managed by it. - */ - -isc_result_t -ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, - ns_interface_t *ifp, isc_boolean_t tcp); -/*% - * Create up to 'n' clients listening on interface 'ifp'. - * If 'tcp' is ISC_TRUE, the clients will listen for TCP connections, - * otherwise for UDP requests. - */ - -isc_sockaddr_t * -ns_client_getsockaddr(ns_client_t *client); -/*% - * Get the socket address of the client whose request is - * currently being processed. - */ - -isc_result_t -ns_client_checkaclsilent(ns_client_t *client,dns_acl_t *acl, - isc_boolean_t default_allow); - -/*% - * Convenience function for client request ACL checking. - * - * Check the current client request against 'acl'. If 'acl' - * is NULL, allow the request iff 'default_allow' is ISC_TRUE. - * - * Notes: - *\li This is appropriate for checking allow-update, - * allow-query, allow-transfer, etc. It is not appropriate - * for checking the blackhole list because we treat positive - * matches as "allow" and negative matches as "deny"; in - * the case of the blackhole list this would be backwards. - * - * Requires: - *\li 'client' points to a valid client. - *\li 'acl' points to a valid ACL, or is NULL. - * - * Returns: - *\li ISC_R_SUCCESS if the request should be allowed - * \li ISC_R_REFUSED if the request should be denied - *\li No other return values are possible. - */ - -isc_result_t -ns_client_checkacl(ns_client_t *client, - const char *opname, dns_acl_t *acl, - isc_boolean_t default_allow, - int log_level); -/*% - * Like ns_client_checkacl, but also logs the outcome of the - * check at log level 'log_level' if denied, and at debug 3 - * if approved. Log messages will refer to the request as - * an 'opname' request. - * - * Requires: - *\li Those of ns_client_checkaclsilent(), and: - * - *\li 'opname' points to a null-terminated string. - */ - -void -ns_client_log(ns_client_t *client, isc_logcategory_t *category, - isc_logmodule_t *module, int level, - const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); - -void -ns_client_logv(ns_client_t *client, isc_logcategory_t *category, - isc_logmodule_t *module, int level, const char *fmt, va_list ap) ISC_FORMAT_PRINTF(5, 0); - -void -ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type, - dns_rdataclass_t rdclass, char *buf, size_t len); - -#define NS_CLIENT_ACLMSGSIZE(x) \ - (DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + \ - DNS_RDATACLASS_FORMATSIZE + sizeof(x) + sizeof("'/'")) - -void -ns_client_recursing(ns_client_t *client); -/*% - * Add client to end of th recursing list. - */ - -void -ns_client_killoldestquery(ns_client_t *client); -/*% - * Kill the oldest recursive query (recursing list head). - */ - -void -ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager); -/*% - * Dump the outstanding recursive queries to 'f'. - */ - -void -ns_client_qnamereplace(ns_client_t *client, dns_name_t *name); -/*% - * Replace the qname. - */ - -isc_boolean_t -ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey, - isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - dns_rdataclass_t rdclass, void *arg); -/*% - * Isself callback. - */ - -#endif /* NAMED_CLIENT_H */ diff --git a/contrib/bind9/bin/named/include/named/config.h b/contrib/bind9/bin/named/include/named/config.h deleted file mode 100644 index e8e6038..0000000 --- a/contrib/bind9/bin/named/include/named/config.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001, 2002 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: config.h,v 1.6.18.6 2006/02/28 03:10:47 marka Exp $ */ - -#ifndef NAMED_CONFIG_H -#define NAMED_CONFIG_H 1 - -/*! \file */ - -#include - -#include -#include - -isc_result_t -ns_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf); - -isc_result_t -ns_config_get(const cfg_obj_t **maps, const char* name, const cfg_obj_t **obj); - -isc_result_t -ns_checknames_get(const cfg_obj_t **maps, const char* name, - const cfg_obj_t **obj); - -int -ns_config_listcount(const cfg_obj_t *list); - -isc_result_t -ns_config_getclass(const cfg_obj_t *classobj, dns_rdataclass_t defclass, - dns_rdataclass_t *classp); - -isc_result_t -ns_config_gettype(const cfg_obj_t *typeobj, dns_rdatatype_t deftype, - dns_rdatatype_t *typep); - -dns_zonetype_t -ns_config_getzonetype(const cfg_obj_t *zonetypeobj); - -isc_result_t -ns_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list, - in_port_t defport, isc_mem_t *mctx, - isc_sockaddr_t **addrsp, isc_uint32_t *countp); - -void -ns_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp, - isc_uint32_t count); - -isc_result_t -ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list, - isc_mem_t *mctx, isc_sockaddr_t **addrsp, - dns_name_t ***keys, isc_uint32_t *countp); - -void -ns_config_putipandkeylist(isc_mem_t *mctx, isc_sockaddr_t **addrsp, - dns_name_t ***keys, isc_uint32_t count); - -isc_result_t -ns_config_getport(const cfg_obj_t *config, in_port_t *portp); - -isc_result_t -ns_config_getkeyalgorithm(const char *str, dns_name_t **name, - isc_uint16_t *digestbits); - -#endif /* NAMED_CONFIG_H */ diff --git a/contrib/bind9/bin/named/include/named/control.h b/contrib/bind9/bin/named/include/named/control.h deleted file mode 100644 index 5b7e5f4..0000000 --- a/contrib/bind9/bin/named/include/named/control.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: control.h,v 1.14.18.8 2006/03/09 23:46:20 marka Exp $ */ - -#ifndef NAMED_CONTROL_H -#define NAMED_CONTROL_H 1 - -/*! \file - * \brief - * The name server command channel. - */ - -#include - -#include - -#include - -#define NS_CONTROL_PORT 953 - -#define NS_COMMAND_STOP "stop" -#define NS_COMMAND_HALT "halt" -#define NS_COMMAND_RELOAD "reload" -#define NS_COMMAND_RECONFIG "reconfig" -#define NS_COMMAND_REFRESH "refresh" -#define NS_COMMAND_RETRANSFER "retransfer" -#define NS_COMMAND_DUMPSTATS "stats" -#define NS_COMMAND_QUERYLOG "querylog" -#define NS_COMMAND_DUMPDB "dumpdb" -#define NS_COMMAND_TRACE "trace" -#define NS_COMMAND_NOTRACE "notrace" -#define NS_COMMAND_FLUSH "flush" -#define NS_COMMAND_FLUSHNAME "flushname" -#define NS_COMMAND_STATUS "status" -#define NS_COMMAND_FREEZE "freeze" -#define NS_COMMAND_UNFREEZE "unfreeze" -#define NS_COMMAND_THAW "thaw" -#define NS_COMMAND_TIMERPOKE "timerpoke" -#define NS_COMMAND_RECURSING "recursing" -#define NS_COMMAND_NULL "null" -#define NS_COMMAND_NOTIFY "notify" -#define NS_COMMAND_VALIDATION "validation" - -isc_result_t -ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp); -/*%< - * Create an initial, empty set of command channels for 'server'. - */ - -void -ns_controls_destroy(ns_controls_t **ctrlsp); -/*%< - * Destroy a set of command channels. - * - * Requires: - * Shutdown of the channels has completed. - */ - -isc_result_t -ns_controls_configure(ns_controls_t *controls, const cfg_obj_t *config, - cfg_aclconfctx_t *aclconfctx); -/*%< - * Configure zero or more command channels into 'controls' - * as defined in the configuration parse tree 'config'. - * The channels will evaluate ACLs in the context of - * 'aclconfctx'. - */ - -void -ns_controls_shutdown(ns_controls_t *controls); -/*%< - * Initiate shutdown of all the command channels in 'controls'. - */ - -isc_result_t -ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text); - -#endif /* NAMED_CONTROL_H */ diff --git a/contrib/bind9/bin/named/include/named/globals.h b/contrib/bind9/bin/named/include/named/globals.h deleted file mode 100644 index 11f3989..0000000 --- a/contrib/bind9/bin/named/include/named/globals.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: globals.h,v 1.64.18.4 2006/03/02 00:37:21 marka Exp $ */ - -#ifndef NAMED_GLOBALS_H -#define NAMED_GLOBALS_H 1 - -/*! \file */ - -#include -#include -#include - -#include - -#include - -#include - -#undef EXTERN -#undef INIT -#ifdef NS_MAIN -#define EXTERN -#define INIT(v) = (v) -#else -#define EXTERN extern -#define INIT(v) -#endif - -EXTERN isc_mem_t * ns_g_mctx INIT(NULL); -EXTERN unsigned int ns_g_cpus INIT(0); -EXTERN isc_taskmgr_t * ns_g_taskmgr INIT(NULL); -EXTERN dns_dispatchmgr_t * ns_g_dispatchmgr INIT(NULL); -EXTERN isc_entropy_t * ns_g_entropy INIT(NULL); -EXTERN isc_entropy_t * ns_g_fallbackentropy INIT(NULL); - -/* - * XXXRTH We're going to want multiple timer managers eventually. One - * for really short timers, another for client timers, and one - * for zone timers. - */ -EXTERN isc_timermgr_t * ns_g_timermgr INIT(NULL); -EXTERN isc_socketmgr_t * ns_g_socketmgr INIT(NULL); -EXTERN cfg_parser_t * ns_g_parser INIT(NULL); -EXTERN const char * ns_g_version INIT(VERSION); -EXTERN in_port_t ns_g_port INIT(0); -EXTERN in_port_t lwresd_g_listenport INIT(0); - -EXTERN ns_server_t * ns_g_server INIT(NULL); - -EXTERN isc_boolean_t ns_g_lwresdonly INIT(ISC_FALSE); - -/* - * Logging. - */ -EXTERN isc_log_t * ns_g_lctx INIT(NULL); -EXTERN isc_logcategory_t * ns_g_categories INIT(NULL); -EXTERN isc_logmodule_t * ns_g_modules INIT(NULL); -EXTERN unsigned int ns_g_debuglevel INIT(0); - -/* - * Current configuration information. - */ -EXTERN cfg_obj_t * ns_g_config INIT(NULL); -EXTERN const cfg_obj_t * ns_g_defaults INIT(NULL); -EXTERN const char * ns_g_conffile INIT(NS_SYSCONFDIR - "/named.conf"); -EXTERN const char * ns_g_keyfile INIT(NS_SYSCONFDIR - "/rndc.key"); -EXTERN const char * lwresd_g_conffile INIT(NS_SYSCONFDIR - "/lwresd.conf"); -EXTERN const char * lwresd_g_resolvconffile INIT("/etc" - "/resolv.conf"); -EXTERN isc_boolean_t ns_g_conffileset INIT(ISC_FALSE); -EXTERN isc_boolean_t lwresd_g_useresolvconf INIT(ISC_FALSE); -EXTERN isc_uint16_t ns_g_udpsize INIT(4096); - -/* - * Initial resource limits. - */ -EXTERN isc_resourcevalue_t ns_g_initstacksize INIT(0); -EXTERN isc_resourcevalue_t ns_g_initdatasize INIT(0); -EXTERN isc_resourcevalue_t ns_g_initcoresize INIT(0); -EXTERN isc_resourcevalue_t ns_g_initopenfiles INIT(0); - -/* - * Misc. - */ -EXTERN isc_boolean_t ns_g_coreok INIT(ISC_TRUE); -EXTERN const char * ns_g_chrootdir INIT(NULL); -EXTERN isc_boolean_t ns_g_foreground INIT(ISC_FALSE); -EXTERN isc_boolean_t ns_g_logstderr INIT(ISC_FALSE); - -EXTERN const char * ns_g_defaultpidfile INIT(NS_LOCALSTATEDIR - "/run/named.pid"); -EXTERN const char * lwresd_g_defaultpidfile INIT(NS_LOCALSTATEDIR - "/run/lwresd.pid"); -EXTERN const char * ns_g_username INIT(NULL); - -EXTERN int ns_g_listen INIT(3); - -#undef EXTERN -#undef INIT - -#endif /* NAMED_GLOBALS_H */ diff --git a/contrib/bind9/bin/named/include/named/interfacemgr.h b/contrib/bind9/bin/named/include/named/interfacemgr.h deleted file mode 100644 index 42279ff..0000000 --- a/contrib/bind9/bin/named/include/named/interfacemgr.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: interfacemgr.h,v 1.26.18.4 2005/04/27 05:00:35 sra Exp $ */ - -#ifndef NAMED_INTERFACEMGR_H -#define NAMED_INTERFACEMGR_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * The interface manager monitors the operating system's list - * of network interfaces, creating and destroying listeners - * as needed. - * - * Reliability: - *\li No impact expected. - * - * Resources: - * - * Security: - * \li The server will only be able to bind to the DNS port on - * newly discovered interfaces if it is running as root. - * - * Standards: - *\li The API for scanning varies greatly among operating systems. - * This module attempts to hide the differences. - */ - -/*** - *** Imports - ***/ - -#include -#include -#include - -#include - -#include -#include - -/*** - *** Types - ***/ - -#define IFACE_MAGIC ISC_MAGIC('I',':','-',')') -#define NS_INTERFACE_VALID(t) ISC_MAGIC_VALID(t, IFACE_MAGIC) - -#define NS_INTERFACEFLAG_ANYADDR 0x01U /*%< bound to "any" address */ - -/*% The nameserver interface structure */ -struct ns_interface { - unsigned int magic; /*%< Magic number. */ - ns_interfacemgr_t * mgr; /*%< Interface manager. */ - isc_mutex_t lock; - int references; /*%< Locked */ - unsigned int generation; /*%< Generation number. */ - isc_sockaddr_t addr; /*%< Address and port. */ - unsigned int flags; /*%< Interface characteristics */ - char name[32]; /*%< Null terminated. */ - dns_dispatch_t * udpdispatch; /*%< UDP dispatcher. */ - isc_socket_t * tcpsocket; /*%< TCP socket. */ - int ntcptarget; /*%< Desired number of concurrent - TCP accepts */ - int ntcpcurrent; /*%< Current ditto, locked */ - ns_clientmgr_t * clientmgr; /*%< Client manager. */ - ISC_LINK(ns_interface_t) link; -}; - -/*** - *** Functions - ***/ - -isc_result_t -ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_socketmgr_t *socketmgr, - dns_dispatchmgr_t *dispatchmgr, - ns_interfacemgr_t **mgrp); -/*% - * Create a new interface manager. - * - * Initially, the new manager will not listen on any interfaces. - * Call ns_interfacemgr_setlistenon() and/or ns_interfacemgr_setlistenon6() - * to set nonempty listen-on lists. - */ - -void -ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target); - -void -ns_interfacemgr_detach(ns_interfacemgr_t **targetp); - -void -ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr); - -void -ns_interfacemgr_scan(ns_interfacemgr_t *mgr, isc_boolean_t verbose); -/*% - * Scan the operatings system's list of network interfaces - * and create listeners when new interfaces are discovered. - * Shut down the sockets for interfaces that go away. - * - * This should be called once on server startup and then - * periodically according to the 'interface-interval' option - * in named.conf. - */ - -void -ns_interfacemgr_adjust(ns_interfacemgr_t *mgr, ns_listenlist_t *list, - isc_boolean_t verbose); -/*% - * Similar to ns_interfacemgr_scan(), but this function also tries to see the - * need for an explicit listen-on when a list element in 'list' is going to - * override an already-listening a wildcard interface. - * - * This function does not update localhost and localnets ACLs. - * - * This should be called once on server startup, after configuring views and - * zones. - */ - -void -ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value); -/*% - * Set the IPv4 "listen-on" list of 'mgr' to 'value'. - * The previous IPv4 listen-on list is freed. - */ - -void -ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value); -/*% - * Set the IPv6 "listen-on" list of 'mgr' to 'value'. - * The previous IPv6 listen-on list is freed. - */ - -dns_aclenv_t * -ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr); - -void -ns_interface_attach(ns_interface_t *source, ns_interface_t **target); - -void -ns_interface_detach(ns_interface_t **targetp); - -void -ns_interface_shutdown(ns_interface_t *ifp); -/*% - * Stop listening for queries on interface 'ifp'. - * May safely be called multiple times. - */ - -void -ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr); - -isc_boolean_t -ns_interfacemgr_listeningon(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr); - -#endif /* NAMED_INTERFACEMGR_H */ diff --git a/contrib/bind9/bin/named/include/named/listenlist.h b/contrib/bind9/bin/named/include/named/listenlist.h deleted file mode 100644 index cdca026..0000000 --- a/contrib/bind9/bin/named/include/named/listenlist.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: listenlist.h,v 1.11.18.2 2005/04/29 00:15:34 marka Exp $ */ - -#ifndef NAMED_LISTENLIST_H -#define NAMED_LISTENLIST_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * "Listen lists", as in the "listen-on" configuration statement. - */ - -/*** - *** Imports - ***/ -#include - -#include - -/*** - *** Types - ***/ - -typedef struct ns_listenelt ns_listenelt_t; -typedef struct ns_listenlist ns_listenlist_t; - -struct ns_listenelt { - isc_mem_t * mctx; - in_port_t port; - dns_acl_t * acl; - ISC_LINK(ns_listenelt_t) link; -}; - -struct ns_listenlist { - isc_mem_t * mctx; - int refcount; - ISC_LIST(ns_listenelt_t) elts; -}; - -/*** - *** Functions - ***/ - -isc_result_t -ns_listenelt_create(isc_mem_t *mctx, in_port_t port, - dns_acl_t *acl, ns_listenelt_t **target); -/*% - * Create a listen-on list element. - */ - -void -ns_listenelt_destroy(ns_listenelt_t *elt); -/*% - * Destroy a listen-on list element. - */ - -isc_result_t -ns_listenlist_create(isc_mem_t *mctx, ns_listenlist_t **target); -/*% - * Create a new, empty listen-on list. - */ - -void -ns_listenlist_attach(ns_listenlist_t *source, ns_listenlist_t **target); -/*% - * Attach '*target' to '*source'. - */ - -void -ns_listenlist_detach(ns_listenlist_t **listp); -/*% - * Detach 'listp'. - */ - -isc_result_t -ns_listenlist_default(isc_mem_t *mctx, in_port_t port, - isc_boolean_t enabled, ns_listenlist_t **target); -/*% - * Create a listen-on list with default contents, matching - * all addresses with port 'port' (if 'enabled' is ISC_TRUE), - * or no addresses (if 'enabled' is ISC_FALSE). - */ - -#endif /* NAMED_LISTENLIST_H */ - - diff --git a/contrib/bind9/bin/named/include/named/log.h b/contrib/bind9/bin/named/include/named/log.h deleted file mode 100644 index 6d6e648..0000000 --- a/contrib/bind9/bin/named/include/named/log.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: log.h,v 1.21.18.2 2005/04/29 00:15:35 marka Exp $ */ - -#ifndef NAMED_LOG_H -#define NAMED_LOG_H 1 - -/*! \file */ - -#include -#include - -#include - -#include /* Required for ns_g_(categories|modules). */ - -/* Unused slot 0. */ -#define NS_LOGCATEGORY_CLIENT (&ns_g_categories[1]) -#define NS_LOGCATEGORY_NETWORK (&ns_g_categories[2]) -#define NS_LOGCATEGORY_UPDATE (&ns_g_categories[3]) -#define NS_LOGCATEGORY_QUERIES (&ns_g_categories[4]) -#define NS_LOGCATEGORY_UNMATCHED (&ns_g_categories[5]) -#define NS_LOGCATEGORY_UPDATE_SECURITY (&ns_g_categories[6]) - -/* - * Backwards compatibility. - */ -#define NS_LOGCATEGORY_GENERAL ISC_LOGCATEGORY_GENERAL - -#define NS_LOGMODULE_MAIN (&ns_g_modules[0]) -#define NS_LOGMODULE_CLIENT (&ns_g_modules[1]) -#define NS_LOGMODULE_SERVER (&ns_g_modules[2]) -#define NS_LOGMODULE_QUERY (&ns_g_modules[3]) -#define NS_LOGMODULE_INTERFACEMGR (&ns_g_modules[4]) -#define NS_LOGMODULE_UPDATE (&ns_g_modules[5]) -#define NS_LOGMODULE_XFER_IN (&ns_g_modules[6]) -#define NS_LOGMODULE_XFER_OUT (&ns_g_modules[7]) -#define NS_LOGMODULE_NOTIFY (&ns_g_modules[8]) -#define NS_LOGMODULE_CONTROL (&ns_g_modules[9]) -#define NS_LOGMODULE_LWRESD (&ns_g_modules[10]) - -isc_result_t -ns_log_init(isc_boolean_t safe); -/*% - * Initialize the logging system and set up an initial default - * logging default configuration that will be used until the - * config file has been read. - * - * If 'safe' is true, use a default configuration that refrains - * from opening files. This is to avoid creating log files - * as root. - */ - -isc_result_t -ns_log_setdefaultchannels(isc_logconfig_t *lcfg); -/*% - * Set up logging channels according to the named defaults, which - * may differ from the logging library defaults. Currently, - * this just means setting up default_debug. - */ - -isc_result_t -ns_log_setsafechannels(isc_logconfig_t *lcfg); -/*% - * Like ns_log_setdefaultchannels(), but omits any logging to files. - */ - -isc_result_t -ns_log_setdefaultcategory(isc_logconfig_t *lcfg); -/*% - * Set up "category default" to go to the right places. - */ - -isc_result_t -ns_log_setunmatchedcategory(isc_logconfig_t *lcfg); -/*% - * Set up "category unmatched" to go to the right places. - */ - -void -ns_log_shutdown(void); - -#endif /* NAMED_LOG_H */ diff --git a/contrib/bind9/bin/named/include/named/logconf.h b/contrib/bind9/bin/named/include/named/logconf.h deleted file mode 100644 index 79df5c6..0000000 --- a/contrib/bind9/bin/named/include/named/logconf.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: logconf.h,v 1.11.18.4 2006/03/02 00:37:21 marka Exp $ */ - -#ifndef NAMED_LOGCONF_H -#define NAMED_LOGCONF_H 1 - -/*! \file */ - -#include - -isc_result_t -ns_log_configure(isc_logconfig_t *logconf, const cfg_obj_t *logstmt); -/*%< - * Set up the logging configuration in '*logconf' according to - * the named.conf data in 'logstmt'. - */ - -#endif /* NAMED_LOGCONF_H */ diff --git a/contrib/bind9/bin/named/include/named/lwaddr.h b/contrib/bind9/bin/named/include/named/lwaddr.h deleted file mode 100644 index 552d1d4..0000000 --- a/contrib/bind9/bin/named/include/named/lwaddr.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: lwaddr.h,v 1.4.18.2 2005/04/29 00:15:35 marka Exp $ */ - -/*! \file */ - -#include -#include - -isc_result_t -lwaddr_netaddr_fromlwresaddr(isc_netaddr_t *na, lwres_addr_t *la); - -isc_result_t -lwaddr_sockaddr_fromlwresaddr(isc_sockaddr_t *sa, lwres_addr_t *la, - in_port_t port); - -isc_result_t -lwaddr_lwresaddr_fromnetaddr(lwres_addr_t *la, isc_netaddr_t *na); - -isc_result_t -lwaddr_lwresaddr_fromsockaddr(lwres_addr_t *la, isc_sockaddr_t *sa); diff --git a/contrib/bind9/bin/named/include/named/lwdclient.h b/contrib/bind9/bin/named/include/named/lwdclient.h deleted file mode 100644 index 591b86c..0000000 --- a/contrib/bind9/bin/named/include/named/lwdclient.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: lwdclient.h,v 1.14.18.2 2005/04/29 00:15:36 marka Exp $ */ - -#ifndef NAMED_LWDCLIENT_H -#define NAMED_LWDCLIENT_H 1 - -/*! \file */ - -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include - -#define LWRD_EVENTCLASS ISC_EVENTCLASS(4242) - -#define LWRD_SHUTDOWN (LWRD_EVENTCLASS + 0x0001) - -/*% Lighweight Resolver Daemon Client */ -struct ns_lwdclient { - isc_sockaddr_t address; /*%< where to reply */ - struct in6_pktinfo pktinfo; - isc_boolean_t pktinfo_valid; - ns_lwdclientmgr_t *clientmgr; /*%< our parent */ - ISC_LINK(ns_lwdclient_t) link; - unsigned int state; - void *arg; /*%< packet processing state */ - - /* - * Received data info. - */ - unsigned char buffer[LWRES_RECVLENGTH]; /*%< receive buffer */ - isc_uint32_t recvlength; /*%< length recv'd */ - lwres_lwpacket_t pkt; - - /*% - * Send data state. If sendbuf != buffer (that is, the send buffer - * isn't our receive buffer) it will be freed to the lwres_context_t. - */ - unsigned char *sendbuf; - isc_uint32_t sendlength; - isc_buffer_t recv_buffer; - - /*% - * gabn (get address by name) state info. - */ - dns_adbfind_t *find; - dns_adbfind_t *v4find; - dns_adbfind_t *v6find; - unsigned int find_wanted; /*%< Addresses we want */ - dns_fixedname_t query_name; - dns_fixedname_t target_name; - ns_lwsearchctx_t searchctx; - lwres_gabnresponse_t gabn; - - /*% - * gnba (get name by address) state info. - */ - lwres_gnbaresponse_t gnba; - dns_byaddr_t *byaddr; - unsigned int options; - isc_netaddr_t na; - - /*% - * grbn (get rrset by name) state info. - * - * Note: this also uses target_name and searchctx. - */ - lwres_grbnresponse_t grbn; - dns_lookup_t *lookup; - dns_rdatatype_t rdtype; - - /*% - * Alias and address info. This is copied up to the gabn/gnba - * structures eventually. - * - * XXXMLG We can keep all of this in a client since we only service - * three packet types right now. If we started handling more, - * we'd need to use "arg" above and allocate/destroy things. - */ - char *aliases[LWRES_MAX_ALIASES]; - isc_uint16_t aliaslen[LWRES_MAX_ALIASES]; - lwres_addr_t addrs[LWRES_MAX_ADDRS]; -}; - -/*% - * Client states. - * - * _IDLE The client is not doing anything at all. - * - * _RECV The client is waiting for data after issuing a socket recv(). - * - * _RECVDONE Data has been received, and is being processed. - * - * _FINDWAIT An adb (or other) request was made that cannot be satisfied - * immediately. An event will wake the client up. - * - * _SEND All data for a response has completed, and a reply was - * sent via a socket send() call. - * - * Badly formatted state table: - * - * IDLE -> RECV when client has a recv() queued. - * - * RECV -> RECVDONE when recvdone event received. - * - * RECVDONE -> SEND if the data for a reply is at hand. - * RECVDONE -> FINDWAIT if more searching is needed, and events will - * eventually wake us up again. - * - * FINDWAIT -> SEND when enough data was received to reply. - * - * SEND -> IDLE when a senddone event was received. - * - * At any time -> IDLE on error. Sometimes this will be -> SEND - * instead, if enough data is on hand to reply with a meaningful - * error. - * - * Packets which are badly formatted may or may not get error returns. - */ -#define NS_LWDCLIENT_STATEIDLE 1 -#define NS_LWDCLIENT_STATERECV 2 -#define NS_LWDCLIENT_STATERECVDONE 3 -#define NS_LWDCLIENT_STATEFINDWAIT 4 -#define NS_LWDCLIENT_STATESEND 5 -#define NS_LWDCLIENT_STATESENDDONE 6 - -#define NS_LWDCLIENT_ISIDLE(c) \ - ((c)->state == NS_LWDCLIENT_STATEIDLE) -#define NS_LWDCLIENT_ISRECV(c) \ - ((c)->state == NS_LWDCLIENT_STATERECV) -#define NS_LWDCLIENT_ISRECVDONE(c) \ - ((c)->state == NS_LWDCLIENT_STATERECVDONE) -#define NS_LWDCLIENT_ISFINDWAIT(c) \ - ((c)->state == NS_LWDCLIENT_STATEFINDWAIT) -#define NS_LWDCLIENT_ISSEND(c) \ - ((c)->state == NS_LWDCLIENT_STATESEND) - -/*% - * Overall magic test that means we're not idle. - */ -#define NS_LWDCLIENT_ISRUNNING(c) (!NS_LWDCLIENT_ISIDLE(c)) - -#define NS_LWDCLIENT_SETIDLE(c) \ - ((c)->state = NS_LWDCLIENT_STATEIDLE) -#define NS_LWDCLIENT_SETRECV(c) \ - ((c)->state = NS_LWDCLIENT_STATERECV) -#define NS_LWDCLIENT_SETRECVDONE(c) \ - ((c)->state = NS_LWDCLIENT_STATERECVDONE) -#define NS_LWDCLIENT_SETFINDWAIT(c) \ - ((c)->state = NS_LWDCLIENT_STATEFINDWAIT) -#define NS_LWDCLIENT_SETSEND(c) \ - ((c)->state = NS_LWDCLIENT_STATESEND) -#define NS_LWDCLIENT_SETSENDDONE(c) \ - ((c)->state = NS_LWDCLIENT_STATESENDDONE) - -/*% lightweight daemon client manager */ -struct ns_lwdclientmgr { - ns_lwreslistener_t *listener; - isc_mem_t *mctx; - isc_socket_t *sock; /*%< socket to use */ - dns_view_t *view; - lwres_context_t *lwctx; /*%< lightweight proto context */ - isc_task_t *task; /*%< owning task */ - unsigned int flags; - ISC_LINK(ns_lwdclientmgr_t) link; - ISC_LIST(ns_lwdclient_t) idle; /*%< idle client slots */ - ISC_LIST(ns_lwdclient_t) running; /*%< running clients */ -}; - -#define NS_LWDCLIENTMGR_FLAGRECVPENDING 0x00000001 -#define NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN 0x00000002 - -isc_result_t -ns_lwdclientmgr_create(ns_lwreslistener_t *, unsigned int, isc_taskmgr_t *); - -void -ns_lwdclient_initialize(ns_lwdclient_t *, ns_lwdclientmgr_t *); - -isc_result_t -ns_lwdclient_startrecv(ns_lwdclientmgr_t *); - -void -ns_lwdclient_stateidle(ns_lwdclient_t *); - -void -ns_lwdclient_recv(isc_task_t *, isc_event_t *); - -void -ns_lwdclient_shutdown(isc_task_t *, isc_event_t *); - -void -ns_lwdclient_send(isc_task_t *, isc_event_t *); - -isc_result_t -ns_lwdclient_sendreply(ns_lwdclient_t *client, isc_region_t *r); - -/* - * Processing functions of various types. - */ -void ns_lwdclient_processgabn(ns_lwdclient_t *, lwres_buffer_t *); -void ns_lwdclient_processgnba(ns_lwdclient_t *, lwres_buffer_t *); -void ns_lwdclient_processgrbn(ns_lwdclient_t *, lwres_buffer_t *); -void ns_lwdclient_processnoop(ns_lwdclient_t *, lwres_buffer_t *); - -void ns_lwdclient_errorpktsend(ns_lwdclient_t *, isc_uint32_t); - -void ns_lwdclient_log(int level, const char *format, ...) - ISC_FORMAT_PRINTF(2, 3); - -#endif /* NAMED_LWDCLIENT_H */ diff --git a/contrib/bind9/bin/named/include/named/lwresd.h b/contrib/bind9/bin/named/include/named/lwresd.h deleted file mode 100644 index ef93fcd..0000000 --- a/contrib/bind9/bin/named/include/named/lwresd.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: lwresd.h,v 1.13.18.4 2006/03/02 00:37:21 marka Exp $ */ - -#ifndef NAMED_LWRESD_H -#define NAMED_LWRESD_H 1 - -/*! \file */ - -#include -#include - -#include - -#include - -struct ns_lwresd { - unsigned int magic; - - isc_mutex_t lock; - dns_view_t *view; - ns_lwsearchlist_t *search; - unsigned int ndots; - isc_mem_t *mctx; - isc_boolean_t shutting_down; - unsigned int refs; -}; - -struct ns_lwreslistener { - unsigned int magic; - - isc_mutex_t lock; - isc_mem_t *mctx; - isc_sockaddr_t address; - ns_lwresd_t *manager; - isc_socket_t *sock; - unsigned int refs; - ISC_LIST(ns_lwdclientmgr_t) cmgrs; - ISC_LINK(ns_lwreslistener_t) link; -}; - -/*% - * Configure lwresd. - */ -isc_result_t -ns_lwresd_configure(isc_mem_t *mctx, const cfg_obj_t *config); - -isc_result_t -ns_lwresd_parseeresolvconf(isc_mem_t *mctx, cfg_parser_t *pctx, - cfg_obj_t **configp); - -/*% - * Trigger shutdown. - */ -void -ns_lwresd_shutdown(void); - -/* - * Manager functions - */ -/*% create manager */ -isc_result_t -ns_lwdmanager_create(isc_mem_t *mctx, const cfg_obj_t *lwres, - ns_lwresd_t **lwresdp); - -/*% attach to manager */ -void -ns_lwdmanager_attach(ns_lwresd_t *source, ns_lwresd_t **targetp); - -/*% detach from manager */ -void -ns_lwdmanager_detach(ns_lwresd_t **lwresdp); - -/* - * Listener functions - */ -/*% attach to listener */ -void -ns_lwreslistener_attach(ns_lwreslistener_t *source, - ns_lwreslistener_t **targetp); - -/*% detach from lister */ -void -ns_lwreslistener_detach(ns_lwreslistener_t **listenerp); - -/*% link client manager */ -void -ns_lwreslistener_unlinkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm); - -/*% unlink client manager */ -void -ns_lwreslistener_linkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm); - - - - -/* - * INTERNAL FUNCTIONS. - */ -void * -ns__lwresd_memalloc(void *arg, size_t size); - -void -ns__lwresd_memfree(void *arg, void *mem, size_t size); - -#endif /* NAMED_LWRESD_H */ diff --git a/contrib/bind9/bin/named/include/named/lwsearch.h b/contrib/bind9/bin/named/include/named/lwsearch.h deleted file mode 100644 index b85e401..0000000 --- a/contrib/bind9/bin/named/include/named/lwsearch.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: lwsearch.h,v 1.5.18.2 2005/04/29 00:15:36 marka Exp $ */ - -#ifndef NAMED_LWSEARCH_H -#define NAMED_LWSEARCH_H 1 - -#include -#include -#include - -#include - -#include - -/*! \file - * \brief - * Lightweight resolver search list types and routines. - * - * An ns_lwsearchlist_t holds a list of search path elements. - * - * An ns_lwsearchctx stores the state of search list during a lookup - * operation. - */ - -/*% An ns_lwsearchlist_t holds a list of search path elements. */ -struct ns_lwsearchlist { - unsigned int magic; - - isc_mutex_t lock; - isc_mem_t *mctx; - unsigned int refs; - dns_namelist_t names; -}; -/*% An ns_lwsearchctx stores the state of search list during a lookup operation. */ -struct ns_lwsearchctx { - dns_name_t *relname; - dns_name_t *searchname; - unsigned int ndots; - ns_lwsearchlist_t *list; - isc_boolean_t doneexact; - isc_boolean_t exactfirst; -}; - -isc_result_t -ns_lwsearchlist_create(isc_mem_t *mctx, ns_lwsearchlist_t **listp); -/*%< - * Create an empty search list object. - */ - -void -ns_lwsearchlist_attach(ns_lwsearchlist_t *source, ns_lwsearchlist_t **target); -/*%< - * Attach to a search list object. - */ - -void -ns_lwsearchlist_detach(ns_lwsearchlist_t **listp); -/*%< - * Detach from a search list object. - */ - -isc_result_t -ns_lwsearchlist_append(ns_lwsearchlist_t *list, dns_name_t *name); -/*%< - * Append an element to a search list. This creates a copy of the name. - */ - -void -ns_lwsearchctx_init(ns_lwsearchctx_t *sctx, ns_lwsearchlist_t *list, - dns_name_t *name, unsigned int ndots); -/*%< - * Creates a search list context structure. - */ - -void -ns_lwsearchctx_first(ns_lwsearchctx_t *sctx); -/*%< - * Moves the search list context iterator to the first element, which - * is usually the exact name. - */ - -isc_result_t -ns_lwsearchctx_next(ns_lwsearchctx_t *sctx); -/*%< - * Moves the search list context iterator to the next element. - */ - -isc_result_t -ns_lwsearchctx_current(ns_lwsearchctx_t *sctx, dns_name_t *absname); -/*%< - * Obtains the current name to be looked up. This involves either - * concatenating the name with a search path element, making an - * exact name absolute, or doing nothing. - */ - -#endif /* NAMED_LWSEARCH_H */ diff --git a/contrib/bind9/bin/named/include/named/main.h b/contrib/bind9/bin/named/include/named/main.h deleted file mode 100644 index dd4fe8c..0000000 --- a/contrib/bind9/bin/named/include/named/main.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: main.h,v 1.11.18.2 2005/04/29 00:15:37 marka Exp $ */ - -#ifndef NAMED_MAIN_H -#define NAMED_MAIN_H 1 - -/*! \file */ - -void -ns_main_earlyfatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); - -void -ns_main_earlywarning(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); - -void -ns_main_setmemstats(const char *); - -#endif /* NAMED_MAIN_H */ diff --git a/contrib/bind9/bin/named/include/named/notify.h b/contrib/bind9/bin/named/include/named/notify.h deleted file mode 100644 index 106d70c..0000000 --- a/contrib/bind9/bin/named/include/named/notify.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: notify.h,v 1.10.18.2 2005/04/29 00:15:37 marka Exp $ */ - -#ifndef NAMED_NOTIFY_H -#define NAMED_NOTIFY_H 1 - -#include -#include - -/*** - *** Module Info - ***/ - -/*! \file - * \brief - * RFC1996 - * A Mechanism for Prompt Notification of Zone Changes (DNS NOTIFY) - */ - -/*** - *** Functions. - ***/ - -void -ns_notify_start(ns_client_t *client); - -/*%< - * Examines the incoming message to determine apporiate zone. - * Returns FORMERR if there is not exactly one question. - * Returns REFUSED if we do not serve the listed zone. - * Pass the message to the zone module for processing - * and returns the return status. - * - * Requires - *\li client to be valid. - */ - -#endif /* NAMED_NOTIFY_H */ - diff --git a/contrib/bind9/bin/named/include/named/ns_smf_globals.h b/contrib/bind9/bin/named/include/named/ns_smf_globals.h deleted file mode 100644 index 06df2ba..0000000 --- a/contrib/bind9/bin/named/include/named/ns_smf_globals.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") - * - * Permission to use, copy, modify, and 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: ns_smf_globals.h,v 1.2.2.4 2005/05/13 01:32:46 marka Exp $ */ - -#ifndef NS_SMF_GLOBALS_H -#define NS_SMF_GLOBALS_H 1 - -#include - -#undef EXTERN -#undef INIT -#ifdef NS_MAIN -#define EXTERN -#define INIT(v) = (v) -#else -#define EXTERN extern -#define INIT(v) -#endif - -EXTERN unsigned int ns_smf_got_instance INIT(0); -EXTERN unsigned int ns_smf_chroot INIT(0); -EXTERN unsigned int ns_smf_want_disable INIT(0); - -isc_result_t ns_smf_add_message(isc_buffer_t *text); -isc_result_t ns_smf_get_instance(char **name, int debug, isc_mem_t *mctx); - -#undef EXTERN -#undef INIT - -#endif /* NS_SMF_GLOBALS_H */ diff --git a/contrib/bind9/bin/named/include/named/query.h b/contrib/bind9/bin/named/include/named/query.h deleted file mode 100644 index 741212f..0000000 --- a/contrib/bind9/bin/named/include/named/query.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: query.h,v 1.36.18.2 2005/04/29 00:15:37 marka Exp $ */ - -#ifndef NAMED_QUERY_H -#define NAMED_QUERY_H 1 - -/*! \file */ - -#include -#include -#include - -#include - -#include - -/*% nameserver database version structure */ -typedef struct ns_dbversion { - dns_db_t *db; - dns_dbversion_t *version; - isc_boolean_t queryok; - ISC_LINK(struct ns_dbversion) link; -} ns_dbversion_t; - -/*% nameserver query structure */ -struct ns_query { - unsigned int attributes; - unsigned int restarts; - isc_boolean_t timerset; - dns_name_t * qname; - dns_name_t * origqname; - unsigned int dboptions; - unsigned int fetchoptions; - dns_db_t * gluedb; - dns_db_t * authdb; - dns_zone_t * authzone; - isc_boolean_t authdbset; - isc_boolean_t isreferral; - isc_mutex_t fetchlock; - dns_fetch_t * fetch; - isc_bufferlist_t namebufs; - ISC_LIST(ns_dbversion_t) activeversions; - ISC_LIST(ns_dbversion_t) freeversions; -}; - -#define NS_QUERYATTR_RECURSIONOK 0x0001 -#define NS_QUERYATTR_CACHEOK 0x0002 -#define NS_QUERYATTR_PARTIALANSWER 0x0004 -#define NS_QUERYATTR_NAMEBUFUSED 0x0008 -#define NS_QUERYATTR_RECURSING 0x0010 -#define NS_QUERYATTR_CACHEGLUEOK 0x0020 -#define NS_QUERYATTR_QUERYOKVALID 0x0040 -#define NS_QUERYATTR_QUERYOK 0x0080 -#define NS_QUERYATTR_WANTRECURSION 0x0100 -#define NS_QUERYATTR_SECURE 0x0200 -#define NS_QUERYATTR_NOAUTHORITY 0x0400 -#define NS_QUERYATTR_NOADDITIONAL 0x0800 - -isc_result_t -ns_query_init(ns_client_t *client); - -void -ns_query_free(ns_client_t *client); - -void -ns_query_start(ns_client_t *client); - -void -ns_query_cancel(ns_client_t *client); - -#endif /* NAMED_QUERY_H */ diff --git a/contrib/bind9/bin/named/include/named/server.h b/contrib/bind9/bin/named/include/named/server.h deleted file mode 100644 index 54d1dae..0000000 --- a/contrib/bind9/bin/named/include/named/server.h +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: server.h,v 1.73.18.8 2006/03/09 23:46:20 marka Exp $ */ - -#ifndef NAMED_SERVER_H -#define NAMED_SERVER_H 1 - -/*! \file */ - -#include -#include -#include -#include -#include - -#include -#include - -#include - -#define NS_EVENTCLASS ISC_EVENTCLASS(0x4E43) -#define NS_EVENT_RELOAD (NS_EVENTCLASS + 0) -#define NS_EVENT_CLIENTCONTROL (NS_EVENTCLASS + 1) - -/*% - * Name server state. Better here than in lots of separate global variables. - */ -struct ns_server { - unsigned int magic; - isc_mem_t * mctx; - - isc_task_t * task; - - /* Configurable data. */ - isc_quota_t xfroutquota; - isc_quota_t tcpquota; - isc_quota_t recursionquota; - dns_acl_t *blackholeacl; - char * statsfile; /*%< Statistics file name */ - char * dumpfile; /*%< Dump file name */ - char * recfile; /*%< Recursive file name */ - isc_boolean_t version_set; /*%< User has set version */ - char * version; /*%< User-specified version */ - isc_boolean_t hostname_set; /*%< User has set hostname */ - char * hostname; /*%< User-specified hostname */ - /*% Use hostname for server id */ - isc_boolean_t server_usehostname; - char * server_id; /*%< User-specified server id */ - - /*% - * Current ACL environment. This defines the - * current values of the localhost and localnets - * ACLs. - */ - dns_aclenv_t aclenv; - - /* Server data structures. */ - dns_loadmgr_t * loadmgr; - dns_zonemgr_t * zonemgr; - dns_viewlist_t viewlist; - ns_interfacemgr_t * interfacemgr; - dns_db_t * in_roothints; - dns_tkeyctx_t * tkeyctx; - - isc_timer_t * interface_timer; - isc_timer_t * heartbeat_timer; - isc_timer_t * pps_timer; - - isc_uint32_t interface_interval; - isc_uint32_t heartbeat_interval; - - isc_mutex_t reload_event_lock; - isc_event_t * reload_event; - - isc_boolean_t flushonshutdown; - isc_boolean_t log_queries; /*%< For BIND 8 compatibility */ - - isc_uint64_t * querystats; /*%< Query statistics counters */ - - ns_controls_t * controls; /*%< Control channels */ - unsigned int dispatchgen; - ns_dispatchlist_t dispatches; - - dns_acache_t *acache; -}; - -#define NS_SERVER_MAGIC ISC_MAGIC('S','V','E','R') -#define NS_SERVER_VALID(s) ISC_MAGIC_VALID(s, NS_SERVER_MAGIC) - -void -ns_server_create(isc_mem_t *mctx, ns_server_t **serverp); -/*%< - * Create a server object with default settings. - * This function either succeeds or causes the program to exit - * with a fatal error. - */ - -void -ns_server_destroy(ns_server_t **serverp); -/*%< - * Destroy a server object, freeing its memory. - */ - -void -ns_server_reloadwanted(ns_server_t *server); -/*%< - * Inform a server that a reload is wanted. This function - * may be called asynchronously, from outside the server's task. - * If a reload is already scheduled or in progress, the call - * is ignored. - */ - -void -ns_server_flushonshutdown(ns_server_t *server, isc_boolean_t flush); -/*%< - * Inform the server that the zones should be flushed to disk on shutdown. - */ - -isc_result_t -ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t *text); -/*%< - * Act on a "reload" command from the command channel. - */ - -isc_result_t -ns_server_reconfigcommand(ns_server_t *server, char *args); -/*%< - * Act on a "reconfig" command from the command channel. - */ - -isc_result_t -ns_server_notifycommand(ns_server_t *server, char *args, isc_buffer_t *text); -/*%< - * Act on a "notify" command from the command channel. - */ - -isc_result_t -ns_server_refreshcommand(ns_server_t *server, char *args, isc_buffer_t *text); -/*%< - * Act on a "refresh" command from the command channel. - */ - -isc_result_t -ns_server_retransfercommand(ns_server_t *server, char *args); -/*%< - * Act on a "retransfer" command from the command channel. - */ - -isc_result_t -ns_server_togglequerylog(ns_server_t *server); -/*%< - * Toggle logging of queries, as in BIND 8. - */ - -/*% - * Dump the current statistics to the statistics file. - */ -isc_result_t -ns_server_dumpstats(ns_server_t *server); - -/*% - * Dump the current cache to the dump file. - */ -isc_result_t -ns_server_dumpdb(ns_server_t *server, char *args); - -/*% - * Change or increment the server debug level. - */ -isc_result_t -ns_server_setdebuglevel(ns_server_t *server, char *args); - -/*% - * Flush the server's cache(s) - */ -isc_result_t -ns_server_flushcache(ns_server_t *server, char *args); - -/*% - * Flush a particular name from the server's cache(s) - */ -isc_result_t -ns_server_flushname(ns_server_t *server, char *args); - -/*% - * Report the server's status. - */ -isc_result_t -ns_server_status(ns_server_t *server, isc_buffer_t *text); - -/*% - * Enable or disable updates for a zone. - */ -isc_result_t -ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args); - -/*% - * Dump the current recursive queries. - */ -isc_result_t -ns_server_dumprecursing(ns_server_t *server); - -/*% - * Maintain a list of dispatches that require reserved ports. - */ -void -ns_add_reserved_dispatch(ns_server_t *server, const isc_sockaddr_t *addr); - -/*% - * Enable or disable dnssec validation. - */ -isc_result_t -ns_server_validation(ns_server_t *server, char *args); - -#endif /* NAMED_SERVER_H */ diff --git a/contrib/bind9/bin/named/include/named/sortlist.h b/contrib/bind9/bin/named/include/named/sortlist.h deleted file mode 100644 index f849be2..0000000 --- a/contrib/bind9/bin/named/include/named/sortlist.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: sortlist.h,v 1.5.18.4 2006/03/02 00:37:21 marka Exp $ */ - -#ifndef NAMED_SORTLIST_H -#define NAMED_SORTLIST_H 1 - -/*! \file */ - -#include - -#include - -/*% - * Type for callback functions that rank addresses. - */ -typedef int -(*dns_addressorderfunc_t)(const isc_netaddr_t *address, const void *arg); - -/*% - * Return value type for setup_sortlist. - */ -typedef enum { - NS_SORTLISTTYPE_NONE, - NS_SORTLISTTYPE_1ELEMENT, - NS_SORTLISTTYPE_2ELEMENT -} ns_sortlisttype_t; - -ns_sortlisttype_t -ns_sortlist_setup(dns_acl_t *acl, isc_netaddr_t *clientaddr, - const void **argp); -/*%< - * Find the sortlist statement in 'acl' that applies to 'clientaddr', if any. - * - * If a 1-element sortlist item applies, return NS_SORTLISTTYPE_1ELEMENT and - * make '*argp' point to the matching subelement. - * - * If a 2-element sortlist item applies, return NS_SORTLISTTYPE_2ELEMENT and - * make '*argp' point to ACL that forms the second element. - * - * If no sortlist item applies, return NS_SORTLISTTYPE_NONE and set '*argp' - * to NULL. - */ - -int -ns_sortlist_addrorder1(const isc_netaddr_t *addr, const void *arg); -/*%< - * Find the sort order of 'addr' in 'arg', the matching element - * of a 1-element top-level sortlist statement. - */ - -int -ns_sortlist_addrorder2(const isc_netaddr_t *addr, const void *arg); -/*%< - * Find the sort order of 'addr' in 'arg', a topology-like - * ACL forming the second element in a 2-element top-level - * sortlist statement. - */ - -void -ns_sortlist_byaddrsetup(dns_acl_t *sortlist_acl, isc_netaddr_t *client_addr, - dns_addressorderfunc_t *orderp, - const void **argp); -/*%< - * Find the sortlist statement in 'acl' that applies to 'clientaddr', if any. - * If a sortlist statement applies, return in '*orderp' a pointer to a function - * for ranking network addresses based on that sortlist statement, and in - * '*argp' an argument to pass to said function. If no sortlist statement - * applies, set '*orderp' and '*argp' to NULL. - */ - -#endif /* NAMED_SORTLIST_H */ diff --git a/contrib/bind9/bin/named/include/named/tkeyconf.h b/contrib/bind9/bin/named/include/named/tkeyconf.h deleted file mode 100644 index 946944d..0000000 --- a/contrib/bind9/bin/named/include/named/tkeyconf.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: tkeyconf.h,v 1.10.18.4 2006/03/02 00:37:21 marka Exp $ */ - -#ifndef NS_TKEYCONF_H -#define NS_TKEYCONF_H 1 - -/*! \file */ - -#include -#include - -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx, - isc_entropy_t *ectx, dns_tkeyctx_t **tctxp); -/*%< - * Create a TKEY context and configure it, including the default DH key - * and default domain, according to 'options'. - * - * Requires: - *\li 'cfg' is a valid configuration options object. - *\li 'mctx' is not NULL - *\li 'ectx' is not NULL - *\li 'tctx' is not NULL - *\li '*tctx' is NULL - * - * Returns: - *\li ISC_R_SUCCESS - *\li ISC_R_NOMEMORY - */ - -ISC_LANG_ENDDECLS - -#endif /* NS_TKEYCONF_H */ diff --git a/contrib/bind9/bin/named/include/named/tsigconf.h b/contrib/bind9/bin/named/include/named/tsigconf.h deleted file mode 100644 index a18eede..0000000 --- a/contrib/bind9/bin/named/include/named/tsigconf.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: tsigconf.h,v 1.10.18.4 2006/03/02 00:37:21 marka Exp $ */ - -#ifndef NS_TSIGCONF_H -#define NS_TSIGCONF_H 1 - -/*! \file */ - -#include -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -ns_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig, - isc_mem_t *mctx, dns_tsig_keyring_t **ringp); -/*%< - * Create a TSIG key ring and configure it according to the 'key' - * statements in the global and view configuration objects. - * - * Requires: - * \li 'config' is not NULL. - * \li 'mctx' is not NULL - * \li 'ring' is not NULL, and '*ring' is NULL - * - * Returns: - * \li ISC_R_SUCCESS - * \li ISC_R_NOMEMORY - */ - -ISC_LANG_ENDDECLS - -#endif /* NS_TSIGCONF_H */ diff --git a/contrib/bind9/bin/named/include/named/types.h b/contrib/bind9/bin/named/include/named/types.h deleted file mode 100644 index abc25d5..0000000 --- a/contrib/bind9/bin/named/include/named/types.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: types.h,v 1.21.18.2 2005/04/29 00:15:38 marka Exp $ */ - -#ifndef NAMED_TYPES_H -#define NAMED_TYPES_H 1 - -/*! \file */ - -#include - -typedef struct ns_client ns_client_t; -typedef struct ns_clientmgr ns_clientmgr_t; -typedef struct ns_query ns_query_t; -typedef struct ns_server ns_server_t; -typedef struct ns_interface ns_interface_t; -typedef struct ns_interfacemgr ns_interfacemgr_t; -typedef struct ns_lwresd ns_lwresd_t; -typedef struct ns_lwreslistener ns_lwreslistener_t; -typedef struct ns_lwdclient ns_lwdclient_t; -typedef struct ns_lwdclientmgr ns_lwdclientmgr_t; -typedef struct ns_lwsearchlist ns_lwsearchlist_t; -typedef struct ns_lwsearchctx ns_lwsearchctx_t; -typedef struct ns_controls ns_controls_t; -typedef struct ns_dispatch ns_dispatch_t; -typedef ISC_LIST(ns_dispatch_t) ns_dispatchlist_t; - -#endif /* NAMED_TYPES_H */ diff --git a/contrib/bind9/bin/named/include/named/update.h b/contrib/bind9/bin/named/include/named/update.h deleted file mode 100644 index 37daa95..0000000 --- a/contrib/bind9/bin/named/include/named/update.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: update.h,v 1.9.18.2 2005/04/29 00:15:39 marka Exp $ */ - -#ifndef NAMED_UPDATE_H -#define NAMED_UPDATE_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * RFC2136 Dynamic Update - */ - -/*** - *** Imports - ***/ - -#include -#include - -/*** - *** Types. - ***/ - -/*** - *** Functions - ***/ - -void -ns_update_start(ns_client_t *client, isc_result_t sigresult); - -#endif /* NAMED_UPDATE_H */ diff --git a/contrib/bind9/bin/named/include/named/xfrout.h b/contrib/bind9/bin/named/include/named/xfrout.h deleted file mode 100644 index 82e0e66..0000000 --- a/contrib/bind9/bin/named/include/named/xfrout.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: xfrout.h,v 1.8.18.2 2005/04/29 00:15:39 marka Exp $ */ - -#ifndef NAMED_XFROUT_H -#define NAMED_XFROUT_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * Outgoing zone transfers (AXFR + IXFR). - */ - -/*** - *** Functions - ***/ - -void -ns_xfr_start(ns_client_t *client, dns_rdatatype_t xfrtype); - -#endif /* NAMED_XFROUT_H */ diff --git a/contrib/bind9/bin/named/include/named/zoneconf.h b/contrib/bind9/bin/named/include/named/zoneconf.h deleted file mode 100644 index 61737a2..0000000 --- a/contrib/bind9/bin/named/include/named/zoneconf.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: zoneconf.h,v 1.19.18.5 2006/03/02 00:37:21 marka Exp $ */ - -#ifndef NS_ZONECONF_H -#define NS_ZONECONF_H 1 - -/*! \file */ - -#include -#include - -#include -#include - -ISC_LANG_BEGINDECLS - -isc_result_t -ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, - const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac, - dns_zone_t *zone); -/*%< - * Configure or reconfigure a zone according to the named.conf - * data in 'cctx' and 'czone'. - * - * The zone origin is not configured, it is assumed to have been set - * at zone creation time. - * - * Require: - * \li 'lctx' to be initialized or NULL. - * \li 'cctx' to be initialized or NULL. - * \li 'ac' to point to an initialized ns_aclconfctx_t. - * \li 'czone' to be initialized. - * \li 'zone' to be initialized. - */ - -isc_boolean_t -ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig); -/*%< - * If 'zone' can be safely reconfigured according to the configuration - * data in 'zconfig', return ISC_TRUE. If the configuration data is so - * different from the current zone state that the zone needs to be destroyed - * and recreated, return ISC_FALSE. - */ - -ISC_LANG_ENDDECLS - -#endif /* NS_ZONECONF_H */ diff --git a/contrib/bind9/bin/named/interfacemgr.c b/contrib/bind9/bin/named/interfacemgr.c deleted file mode 100644 index db41031..0000000 --- a/contrib/bind9/bin/named/interfacemgr.c +++ /dev/null @@ -1,978 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: interfacemgr.c,v 1.76.18.8 2006/07/20 01:10:30 marka Exp $ */ - -/*! \file */ - -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#define IFMGR_MAGIC ISC_MAGIC('I', 'F', 'M', 'G') -#define NS_INTERFACEMGR_VALID(t) ISC_MAGIC_VALID(t, IFMGR_MAGIC) - -#define IFMGR_COMMON_LOGARGS \ - ns_g_lctx, NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR - -/*% nameserver interface manager structure */ -struct ns_interfacemgr { - unsigned int magic; /*%< Magic number. */ - int references; - isc_mutex_t lock; - isc_mem_t * mctx; /*%< Memory context. */ - isc_taskmgr_t * taskmgr; /*%< Task manager. */ - isc_socketmgr_t * socketmgr; /*%< Socket manager. */ - dns_dispatchmgr_t * dispatchmgr; - unsigned int generation; /*%< Current generation no. */ - ns_listenlist_t * listenon4; - ns_listenlist_t * listenon6; - dns_aclenv_t aclenv; /*%< Localhost/localnets ACLs */ - ISC_LIST(ns_interface_t) interfaces; /*%< List of interfaces. */ - ISC_LIST(isc_sockaddr_t) listenon; -}; - -static void -purge_old_interfaces(ns_interfacemgr_t *mgr); - -static void -clearlistenon(ns_interfacemgr_t *mgr); - -isc_result_t -ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_socketmgr_t *socketmgr, - dns_dispatchmgr_t *dispatchmgr, - ns_interfacemgr_t **mgrp) -{ - isc_result_t result; - ns_interfacemgr_t *mgr; - - REQUIRE(mctx != NULL); - REQUIRE(mgrp != NULL); - REQUIRE(*mgrp == NULL); - - mgr = isc_mem_get(mctx, sizeof(*mgr)); - if (mgr == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&mgr->lock); - if (result != ISC_R_SUCCESS) - goto cleanup_mem; - - mgr->mctx = mctx; - mgr->taskmgr = taskmgr; - mgr->socketmgr = socketmgr; - mgr->dispatchmgr = dispatchmgr; - mgr->generation = 1; - mgr->listenon4 = NULL; - mgr->listenon6 = NULL; - - ISC_LIST_INIT(mgr->interfaces); - ISC_LIST_INIT(mgr->listenon); - - /* - * The listen-on lists are initially empty. - */ - result = ns_listenlist_create(mctx, &mgr->listenon4); - if (result != ISC_R_SUCCESS) - goto cleanup_mem; - ns_listenlist_attach(mgr->listenon4, &mgr->listenon6); - - result = dns_aclenv_init(mctx, &mgr->aclenv); - if (result != ISC_R_SUCCESS) - goto cleanup_listenon; - - mgr->references = 1; - mgr->magic = IFMGR_MAGIC; - *mgrp = mgr; - return (ISC_R_SUCCESS); - - cleanup_listenon: - ns_listenlist_detach(&mgr->listenon4); - ns_listenlist_detach(&mgr->listenon6); - cleanup_mem: - isc_mem_put(mctx, mgr, sizeof(*mgr)); - return (result); -} - -static void -ns_interfacemgr_destroy(ns_interfacemgr_t *mgr) { - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - dns_aclenv_destroy(&mgr->aclenv); - ns_listenlist_detach(&mgr->listenon4); - ns_listenlist_detach(&mgr->listenon6); - clearlistenon(mgr); - DESTROYLOCK(&mgr->lock); - mgr->magic = 0; - isc_mem_put(mgr->mctx, mgr, sizeof(*mgr)); -} - -dns_aclenv_t * -ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr) { - return (&mgr->aclenv); -} - -void -ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target) { - REQUIRE(NS_INTERFACEMGR_VALID(source)); - LOCK(&source->lock); - INSIST(source->references > 0); - source->references++; - UNLOCK(&source->lock); - *target = source; -} - -void -ns_interfacemgr_detach(ns_interfacemgr_t **targetp) { - isc_result_t need_destroy = ISC_FALSE; - ns_interfacemgr_t *target = *targetp; - REQUIRE(target != NULL); - REQUIRE(NS_INTERFACEMGR_VALID(target)); - LOCK(&target->lock); - REQUIRE(target->references > 0); - target->references--; - if (target->references == 0) - need_destroy = ISC_TRUE; - UNLOCK(&target->lock); - if (need_destroy) - ns_interfacemgr_destroy(target); - *targetp = NULL; -} - -void -ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr) { - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - - /*% - * Shut down and detach all interfaces. - * By incrementing the generation count, we make purge_old_interfaces() - * consider all interfaces "old". - */ - mgr->generation++; - purge_old_interfaces(mgr); -} - - -static isc_result_t -ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, - const char *name, ns_interface_t **ifpret) -{ - ns_interface_t *ifp; - isc_result_t result; - - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - ifp = isc_mem_get(mgr->mctx, sizeof(*ifp)); - if (ifp == NULL) - return (ISC_R_NOMEMORY); - ifp->mgr = NULL; - ifp->generation = mgr->generation; - ifp->addr = *addr; - ifp->flags = 0; - strncpy(ifp->name, name, sizeof(ifp->name)); - ifp->name[sizeof(ifp->name)-1] = '\0'; - ifp->clientmgr = NULL; - - result = isc_mutex_init(&ifp->lock); - if (result != ISC_R_SUCCESS) - goto lock_create_failure; - - result = ns_clientmgr_create(mgr->mctx, mgr->taskmgr, - ns_g_timermgr, - &ifp->clientmgr); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "ns_clientmgr_create() failed: %s", - isc_result_totext(result)); - goto clientmgr_create_failure; - } - - ifp->udpdispatch = NULL; - - ifp->tcpsocket = NULL; - /* - * Create a single TCP client object. It will replace itself - * with a new one as soon as it gets a connection, so the actual - * connections will be handled in parallel even though there is - * only one client initially. - */ - ifp->ntcptarget = 1; - ifp->ntcpcurrent = 0; - - ISC_LINK_INIT(ifp, link); - - ns_interfacemgr_attach(mgr, &ifp->mgr); - ISC_LIST_APPEND(mgr->interfaces, ifp, link); - - ifp->references = 1; - ifp->magic = IFACE_MAGIC; - *ifpret = ifp; - - return (ISC_R_SUCCESS); - - clientmgr_create_failure: - DESTROYLOCK(&ifp->lock); - lock_create_failure: - ifp->magic = 0; - isc_mem_put(mgr->mctx, ifp, sizeof(*ifp)); - - return (ISC_R_UNEXPECTED); -} - -static isc_result_t -ns_interface_listenudp(ns_interface_t *ifp) { - isc_result_t result; - unsigned int attrs; - unsigned int attrmask; - - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; - if (isc_sockaddr_pf(&ifp->addr) == AF_INET) - attrs |= DNS_DISPATCHATTR_IPV4; - else - attrs |= DNS_DISPATCHATTR_IPV6; - attrs |= DNS_DISPATCHATTR_NOLISTEN; - attrmask = 0; - attrmask |= DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP; - attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6; - result = dns_dispatch_getudp(ifp->mgr->dispatchmgr, ns_g_socketmgr, - ns_g_taskmgr, &ifp->addr, - 4096, 1000, 32768, 8219, 8237, - attrs, attrmask, &ifp->udpdispatch); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "could not listen on UDP socket: %s", - isc_result_totext(result)); - goto udp_dispatch_failure; - } - - result = ns_clientmgr_createclients(ifp->clientmgr, ns_g_cpus, - ifp, ISC_FALSE); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "UDP ns_clientmgr_createclients(): %s", - isc_result_totext(result)); - goto addtodispatch_failure; - } - return (ISC_R_SUCCESS); - - addtodispatch_failure: - dns_dispatch_changeattributes(ifp->udpdispatch, 0, - DNS_DISPATCHATTR_NOLISTEN); - dns_dispatch_detach(&ifp->udpdispatch); - udp_dispatch_failure: - return (result); -} - -static isc_result_t -ns_interface_accepttcp(ns_interface_t *ifp) { - isc_result_t result; - - /* - * Open a TCP socket. - */ - result = isc_socket_create(ifp->mgr->socketmgr, - isc_sockaddr_pf(&ifp->addr), - isc_sockettype_tcp, - &ifp->tcpsocket); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "creating TCP socket: %s", - isc_result_totext(result)); - goto tcp_socket_failure; - } -#ifndef ISC_ALLOW_MAPPED - isc_socket_ipv6only(ifp->tcpsocket, ISC_TRUE); -#endif - result = isc_socket_bind(ifp->tcpsocket, &ifp->addr); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "binding TCP socket: %s", - isc_result_totext(result)); - goto tcp_bind_failure; - } - result = isc_socket_listen(ifp->tcpsocket, ns_g_listen); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "listening on TCP socket: %s", - isc_result_totext(result)); - goto tcp_listen_failure; - } - - /* - * If/when there a multiple filters listen to the - * result. - */ - (void)isc_socket_filter(ifp->tcpsocket, "dataready"); - - result = ns_clientmgr_createclients(ifp->clientmgr, - ifp->ntcptarget, ifp, - ISC_TRUE); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "TCP ns_clientmgr_createclients(): %s", - isc_result_totext(result)); - goto accepttcp_failure; - } - return (ISC_R_SUCCESS); - - accepttcp_failure: - tcp_listen_failure: - tcp_bind_failure: - isc_socket_detach(&ifp->tcpsocket); - tcp_socket_failure: - return (ISC_R_SUCCESS); -} - -static isc_result_t -ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, - const char *name, ns_interface_t **ifpret, - isc_boolean_t accept_tcp) -{ - isc_result_t result; - ns_interface_t *ifp = NULL; - REQUIRE(ifpret != NULL && *ifpret == NULL); - - result = ns_interface_create(mgr, addr, name, &ifp); - if (result != ISC_R_SUCCESS) - return (result); - - result = ns_interface_listenudp(ifp); - if (result != ISC_R_SUCCESS) - goto cleanup_interface; - - if (accept_tcp == ISC_TRUE) { - result = ns_interface_accepttcp(ifp); - if (result != ISC_R_SUCCESS) { - /* - * XXXRTH We don't currently have a way to easily stop - * dispatch service, so we currently return - * ISC_R_SUCCESS (the UDP stuff will work even if TCP - * creation failed). This will be fixed later. - */ - result = ISC_R_SUCCESS; - } - } - *ifpret = ifp; - return (ISC_R_SUCCESS); - - cleanup_interface: - ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link); - ns_interface_detach(&ifp); - return (result); -} - -void -ns_interface_shutdown(ns_interface_t *ifp) { - if (ifp->clientmgr != NULL) - ns_clientmgr_destroy(&ifp->clientmgr); -} - -static void -ns_interface_destroy(ns_interface_t *ifp) { - isc_mem_t *mctx = ifp->mgr->mctx; - REQUIRE(NS_INTERFACE_VALID(ifp)); - - ns_interface_shutdown(ifp); - - if (ifp->udpdispatch != NULL) { - dns_dispatch_changeattributes(ifp->udpdispatch, 0, - DNS_DISPATCHATTR_NOLISTEN); - dns_dispatch_detach(&ifp->udpdispatch); - } - if (ifp->tcpsocket != NULL) - isc_socket_detach(&ifp->tcpsocket); - - DESTROYLOCK(&ifp->lock); - - ns_interfacemgr_detach(&ifp->mgr); - - ifp->magic = 0; - isc_mem_put(mctx, ifp, sizeof(*ifp)); -} - -void -ns_interface_attach(ns_interface_t *source, ns_interface_t **target) { - REQUIRE(NS_INTERFACE_VALID(source)); - LOCK(&source->lock); - INSIST(source->references > 0); - source->references++; - UNLOCK(&source->lock); - *target = source; -} - -void -ns_interface_detach(ns_interface_t **targetp) { - isc_result_t need_destroy = ISC_FALSE; - ns_interface_t *target = *targetp; - REQUIRE(target != NULL); - REQUIRE(NS_INTERFACE_VALID(target)); - LOCK(&target->lock); - REQUIRE(target->references > 0); - target->references--; - if (target->references == 0) - need_destroy = ISC_TRUE; - UNLOCK(&target->lock); - if (need_destroy) - ns_interface_destroy(target); - *targetp = NULL; -} - -/*% - * Search the interface list for an interface whose address and port - * both match those of 'addr'. Return a pointer to it, or NULL if not found. - */ -static ns_interface_t * -find_matching_interface(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) { - ns_interface_t *ifp; - for (ifp = ISC_LIST_HEAD(mgr->interfaces); ifp != NULL; - ifp = ISC_LIST_NEXT(ifp, link)) { - if (isc_sockaddr_equal(&ifp->addr, addr)) - break; - } - return (ifp); -} - -/*% - * Remove any interfaces whose generation number is not the current one. - */ -static void -purge_old_interfaces(ns_interfacemgr_t *mgr) { - ns_interface_t *ifp, *next; - for (ifp = ISC_LIST_HEAD(mgr->interfaces); ifp != NULL; ifp = next) { - INSIST(NS_INTERFACE_VALID(ifp)); - next = ISC_LIST_NEXT(ifp, link); - if (ifp->generation != mgr->generation) { - char sabuf[256]; - ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link); - isc_sockaddr_format(&ifp->addr, sabuf, sizeof(sabuf)); - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_INFO, - "no longer listening on %s", sabuf); - ns_interface_shutdown(ifp); - ns_interface_detach(&ifp); - } - } -} - -static isc_result_t -clearacl(isc_mem_t *mctx, dns_acl_t **aclp) { - dns_acl_t *newacl = NULL; - isc_result_t result; - result = dns_acl_create(mctx, 10, &newacl); - if (result != ISC_R_SUCCESS) - return (result); - dns_acl_detach(aclp); - dns_acl_attach(newacl, aclp); - dns_acl_detach(&newacl); - return (ISC_R_SUCCESS); -} - -static isc_boolean_t -listenon_is_ip6_any(ns_listenelt_t *elt) { - if (elt->acl->length != 1) - return (ISC_FALSE); - if (elt->acl->elements[0].negative == ISC_FALSE && - elt->acl->elements[0].type == dns_aclelementtype_any) - return (ISC_TRUE); /* listen-on-v6 { any; } */ - return (ISC_FALSE); /* All others */ -} - -static isc_result_t -setup_locals(ns_interfacemgr_t *mgr, isc_interface_t *interface) { - isc_result_t result; - dns_aclelement_t elt; - unsigned int family; - unsigned int prefixlen; - - family = interface->address.family; - - elt.type = dns_aclelementtype_ipprefix; - elt.negative = ISC_FALSE; - elt.u.ip_prefix.address = interface->address; - elt.u.ip_prefix.prefixlen = (family == AF_INET) ? 32 : 128; - result = dns_acl_appendelement(mgr->aclenv.localhost, &elt); - if (result != ISC_R_SUCCESS) - return (result); - - result = isc_netaddr_masktoprefixlen(&interface->netmask, - &prefixlen); - - /* Non contigious netmasks not allowed by IPv6 arch. */ - if (result != ISC_R_SUCCESS && family == AF_INET6) - return (result); - - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_WARNING, - "omitting IPv4 interface %s from " - "localnets ACL: %s", - interface->name, - isc_result_totext(result)); - } else { - elt.u.ip_prefix.prefixlen = prefixlen; - if (dns_acl_elementmatch(mgr->aclenv.localnets, &elt, - NULL) == ISC_R_NOTFOUND) { - result = dns_acl_appendelement(mgr->aclenv.localnets, - &elt); - if (result != ISC_R_SUCCESS) - return (result); - } - } - - return (ISC_R_SUCCESS); -} - -static void -setup_listenon(ns_interfacemgr_t *mgr, isc_interface_t *interface, - in_port_t port) -{ - isc_sockaddr_t *addr; - isc_sockaddr_t *old; - - addr = isc_mem_get(mgr->mctx, sizeof(*addr)); - if (addr == NULL) - return; - - isc_sockaddr_fromnetaddr(addr, &interface->address, port); - - for (old = ISC_LIST_HEAD(mgr->listenon); - old != NULL; - old = ISC_LIST_NEXT(old, link)) - if (isc_sockaddr_equal(addr, old)) - break; - - if (old != NULL) - isc_mem_put(mgr->mctx, addr, sizeof(*addr)); - else - ISC_LIST_APPEND(mgr->listenon, addr, link); -} - -static void -clearlistenon(ns_interfacemgr_t *mgr) { - isc_sockaddr_t *old; - - old = ISC_LIST_HEAD(mgr->listenon); - while (old != NULL) { - ISC_LIST_UNLINK(mgr->listenon, old, link); - isc_mem_put(mgr->mctx, old, sizeof(*old)); - old = ISC_LIST_HEAD(mgr->listenon); - } -} - -static isc_result_t -do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, - isc_boolean_t verbose) -{ - isc_interfaceiter_t *iter = NULL; - isc_boolean_t scan_ipv4 = ISC_FALSE; - isc_boolean_t scan_ipv6 = ISC_FALSE; - isc_boolean_t adjusting = ISC_FALSE; - isc_boolean_t ipv6only = ISC_TRUE; - isc_boolean_t ipv6pktinfo = ISC_TRUE; - isc_result_t result; - isc_netaddr_t zero_address, zero_address6; - ns_listenelt_t *le; - isc_sockaddr_t listen_addr; - ns_interface_t *ifp; - isc_boolean_t log_explicit = ISC_FALSE; - isc_boolean_t dolistenon; - - if (ext_listen != NULL) - adjusting = ISC_TRUE; - - if (isc_net_probeipv6() == ISC_R_SUCCESS) - scan_ipv6 = ISC_TRUE; -#ifdef WANT_IPV6 - else - isc_log_write(IFMGR_COMMON_LOGARGS, - verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1), - "no IPv6 interfaces found"); -#endif - - if (isc_net_probeipv4() == ISC_R_SUCCESS) - scan_ipv4 = ISC_TRUE; - else - isc_log_write(IFMGR_COMMON_LOGARGS, - verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1), - "no IPv4 interfaces found"); - - /* - * A special, but typical case; listen-on-v6 { any; }. - * When we can make the socket IPv6-only, open a single wildcard - * socket for IPv6 communication. Otherwise, make separate socket - * for each IPv6 address in order to avoid accepting IPv4 packets - * as the form of mapped addresses unintentionally unless explicitly - * allowed. - */ -#ifndef ISC_ALLOW_MAPPED - if (scan_ipv6 == ISC_TRUE && - isc_net_probe_ipv6only() != ISC_R_SUCCESS) { - ipv6only = ISC_FALSE; - log_explicit = ISC_TRUE; - } -#endif - if (scan_ipv6 == ISC_TRUE && - isc_net_probe_ipv6pktinfo() != ISC_R_SUCCESS) { - ipv6pktinfo = ISC_FALSE; - log_explicit = ISC_TRUE; - } - if (scan_ipv6 == ISC_TRUE && ipv6only && ipv6pktinfo) { - for (le = ISC_LIST_HEAD(mgr->listenon6->elts); - le != NULL; - le = ISC_LIST_NEXT(le, link)) { - struct in6_addr in6a; - - if (!listenon_is_ip6_any(le)) - continue; - - in6a = in6addr_any; - isc_sockaddr_fromin6(&listen_addr, &in6a, le->port); - - ifp = find_matching_interface(mgr, &listen_addr); - if (ifp != NULL) { - ifp->generation = mgr->generation; - } else { - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_INFO, - "listening on IPv6 " - "interfaces, port %u", - le->port); - result = ns_interface_setup(mgr, &listen_addr, - "", &ifp, - ISC_TRUE); - if (result == ISC_R_SUCCESS) - ifp->flags |= NS_INTERFACEFLAG_ANYADDR; - else - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_ERROR, - "listening on all IPv6 " - "interfaces failed"); - /* Continue. */ - } - } - } - - isc_netaddr_any(&zero_address); - isc_netaddr_any6(&zero_address6); - - result = isc_interfaceiter_create(mgr->mctx, &iter); - if (result != ISC_R_SUCCESS) - return (result); - - if (adjusting == ISC_FALSE) { - result = clearacl(mgr->mctx, &mgr->aclenv.localhost); - if (result != ISC_R_SUCCESS) - goto cleanup_iter; - result = clearacl(mgr->mctx, &mgr->aclenv.localnets); - if (result != ISC_R_SUCCESS) - goto cleanup_iter; - clearlistenon(mgr); - } - - for (result = isc_interfaceiter_first(iter); - result == ISC_R_SUCCESS; - result = isc_interfaceiter_next(iter)) - { - isc_interface_t interface; - ns_listenlist_t *ll; - unsigned int family; - - result = isc_interfaceiter_current(iter, &interface); - if (result != ISC_R_SUCCESS) - break; - - family = interface.address.family; - if (family != AF_INET && family != AF_INET6) - continue; - if (scan_ipv4 == ISC_FALSE && family == AF_INET) - continue; - if (scan_ipv6 == ISC_FALSE && family == AF_INET6) - continue; - - /* - * Test for the address being nonzero rather than testing - * INTERFACE_F_UP, because on some systems the latter - * follows the media state and we could end up ignoring - * the interface for an entire rescan interval due to - * a temporary media glitch at rescan time. - */ - if (family == AF_INET && - isc_netaddr_equal(&interface.address, &zero_address)) { - continue; - } - if (family == AF_INET6 && - isc_netaddr_equal(&interface.address, &zero_address6)) { - continue; - } - - if (adjusting == ISC_FALSE) { - result = setup_locals(mgr, &interface); - if (result != ISC_R_SUCCESS) - goto ignore_interface; - } - - ll = (family == AF_INET) ? mgr->listenon4 : mgr->listenon6; - dolistenon = ISC_TRUE; - for (le = ISC_LIST_HEAD(ll->elts); - le != NULL; - le = ISC_LIST_NEXT(le, link)) - { - int match; - isc_boolean_t ipv6_wildcard = ISC_FALSE; - isc_netaddr_t listen_netaddr; - isc_sockaddr_t listen_sockaddr; - - /* - * Construct a socket address for this IP/port - * combination. - */ - if (family == AF_INET) { - isc_netaddr_fromin(&listen_netaddr, - &interface.address.type.in); - } else { - isc_netaddr_fromin6(&listen_netaddr, - &interface.address.type.in6); - isc_netaddr_setzone(&listen_netaddr, - interface.address.zone); - } - isc_sockaddr_fromnetaddr(&listen_sockaddr, - &listen_netaddr, - le->port); - - /* - * See if the address matches the listen-on statement; - * if not, ignore the interface. - */ - (void)dns_acl_match(&listen_netaddr, NULL, le->acl, - &mgr->aclenv, &match, NULL); - if (match <= 0) - continue; - - if (adjusting == ISC_FALSE && dolistenon == ISC_TRUE) { - setup_listenon(mgr, &interface, le->port); - dolistenon = ISC_FALSE; - } - - /* - * The case of "any" IPv6 address will require - * special considerations later, so remember it. - */ - if (family == AF_INET6 && ipv6only && ipv6pktinfo && - listenon_is_ip6_any(le)) - ipv6_wildcard = ISC_TRUE; - - /* - * When adjusting interfaces with extra a listening - * list, see if the address matches the extra list. - * If it does, and is also covered by a wildcard - * interface, we need to listen on the address - * explicitly. - */ - if (adjusting == ISC_TRUE) { - ns_listenelt_t *ele; - - match = 0; - for (ele = ISC_LIST_HEAD(ext_listen->elts); - ele != NULL; - ele = ISC_LIST_NEXT(ele, link)) { - (void)dns_acl_match(&listen_netaddr, - NULL, ele->acl, - NULL, &match, NULL); - if (match > 0 && ele->port == le->port) - break; - else - match = 0; - } - if (ipv6_wildcard == ISC_TRUE && match == 0) - continue; - } - - ifp = find_matching_interface(mgr, &listen_sockaddr); - if (ifp != NULL) { - ifp->generation = mgr->generation; - } else { - char sabuf[ISC_SOCKADDR_FORMATSIZE]; - - if (adjusting == ISC_FALSE && - ipv6_wildcard == ISC_TRUE) - continue; - - if (log_explicit && family == AF_INET6 && - !adjusting && listenon_is_ip6_any(le)) { - isc_log_write(IFMGR_COMMON_LOGARGS, - verbose ? ISC_LOG_INFO : - ISC_LOG_DEBUG(1), - "IPv6 socket API is " - "incomplete; explicitly " - "binding to each IPv6 " - "address separately"); - log_explicit = ISC_FALSE; - } - isc_sockaddr_format(&listen_sockaddr, - sabuf, sizeof(sabuf)); - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_INFO, - "%s" - "listening on %s interface " - "%s, %s", - (adjusting == ISC_TRUE) ? - "additionally " : "", - (family == AF_INET) ? - "IPv4" : "IPv6", - interface.name, sabuf); - - result = ns_interface_setup(mgr, - &listen_sockaddr, - interface.name, - &ifp, - (adjusting == ISC_TRUE) ? - ISC_FALSE : - ISC_TRUE); - - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_ERROR, - "creating %s interface " - "%s failed; interface " - "ignored", - (family == AF_INET) ? - "IPv4" : "IPv6", - interface.name); - } - /* Continue. */ - } - - } - continue; - - ignore_interface: - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_ERROR, - "ignoring %s interface %s: %s", - (family == AF_INET) ? "IPv4" : "IPv6", - interface.name, isc_result_totext(result)); - continue; - } - if (result != ISC_R_NOMORE) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "interface iteration failed: %s", - isc_result_totext(result)); - else - result = ISC_R_SUCCESS; - cleanup_iter: - isc_interfaceiter_destroy(&iter); - return (result); -} - -static void -ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, - isc_boolean_t verbose) -{ - isc_boolean_t purge = ISC_TRUE; - - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - - mgr->generation++; /* Increment the generation count. */ - - if (do_scan(mgr, ext_listen, verbose) != ISC_R_SUCCESS) - purge = ISC_FALSE; - - /* - * Now go through the interface list and delete anything that - * does not have the current generation number. This is - * how we catch interfaces that go away or change their - * addresses. - */ - if (purge) - purge_old_interfaces(mgr); - - /* - * Warn if we are not listening on any interface, unless - * we're in lwresd-only mode, in which case that is to - * be expected. - */ - if (ext_listen == NULL && - ISC_LIST_EMPTY(mgr->interfaces) && ! ns_g_lwresdonly) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING, - "not listening on any interfaces"); - } -} - -void -ns_interfacemgr_scan(ns_interfacemgr_t *mgr, isc_boolean_t verbose) { - ns_interfacemgr_scan0(mgr, NULL, verbose); -} - -void -ns_interfacemgr_adjust(ns_interfacemgr_t *mgr, ns_listenlist_t *list, - isc_boolean_t verbose) -{ - ns_interfacemgr_scan0(mgr, list, verbose); -} - -void -ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value) { - LOCK(&mgr->lock); - ns_listenlist_detach(&mgr->listenon4); - ns_listenlist_attach(value, &mgr->listenon4); - UNLOCK(&mgr->lock); -} - -void -ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value) { - LOCK(&mgr->lock); - ns_listenlist_detach(&mgr->listenon6); - ns_listenlist_attach(value, &mgr->listenon6); - UNLOCK(&mgr->lock); -} - -void -ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr) { - ns_interface_t *interface; - - LOCK(&mgr->lock); - interface = ISC_LIST_HEAD(mgr->interfaces); - while (interface != NULL) { - if (interface->clientmgr != NULL) - ns_client_dumprecursing(f, interface->clientmgr); - interface = ISC_LIST_NEXT(interface, link); - } - UNLOCK(&mgr->lock); -} - -isc_boolean_t -ns_interfacemgr_listeningon(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) { - isc_sockaddr_t *old; - - old = ISC_LIST_HEAD(mgr->listenon); - for (old = ISC_LIST_HEAD(mgr->listenon); - old != NULL; - old = ISC_LIST_NEXT(old, link)) - if (isc_sockaddr_equal(old, addr)) - return (ISC_TRUE); - return (ISC_FALSE); -} diff --git a/contrib/bind9/bin/named/listenlist.c b/contrib/bind9/bin/named/listenlist.c deleted file mode 100644 index 7e70ac9..0000000 --- a/contrib/bind9/bin/named/listenlist.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: listenlist.c,v 1.10.18.2 2005/04/29 00:15:22 marka Exp $ */ - -/*! \file */ - -#include - -#include -#include - -#include - -#include - -static void -destroy(ns_listenlist_t *list); - -isc_result_t -ns_listenelt_create(isc_mem_t *mctx, in_port_t port, - dns_acl_t *acl, ns_listenelt_t **target) -{ - ns_listenelt_t *elt = NULL; - REQUIRE(target != NULL && *target == NULL); - elt = isc_mem_get(mctx, sizeof(*elt)); - if (elt == NULL) - return (ISC_R_NOMEMORY); - elt->mctx = mctx; - ISC_LINK_INIT(elt, link); - elt->port = port; - elt->acl = acl; - *target = elt; - return (ISC_R_SUCCESS); -} - -void -ns_listenelt_destroy(ns_listenelt_t *elt) { - if (elt->acl != NULL) - dns_acl_detach(&elt->acl); - isc_mem_put(elt->mctx, elt, sizeof(*elt)); -} - -isc_result_t -ns_listenlist_create(isc_mem_t *mctx, ns_listenlist_t **target) { - ns_listenlist_t *list = NULL; - REQUIRE(target != NULL && *target == NULL); - list = isc_mem_get(mctx, sizeof(*list)); - if (list == NULL) - return (ISC_R_NOMEMORY); - list->mctx = mctx; - list->refcount = 1; - ISC_LIST_INIT(list->elts); - *target = list; - return (ISC_R_SUCCESS); -} - -static void -destroy(ns_listenlist_t *list) { - ns_listenelt_t *elt, *next; - for (elt = ISC_LIST_HEAD(list->elts); - elt != NULL; - elt = next) - { - next = ISC_LIST_NEXT(elt, link); - ns_listenelt_destroy(elt); - } - isc_mem_put(list->mctx, list, sizeof(*list)); -} - -void -ns_listenlist_attach(ns_listenlist_t *source, ns_listenlist_t **target) { - INSIST(source->refcount > 0); - source->refcount++; - *target = source; -} - -void -ns_listenlist_detach(ns_listenlist_t **listp) { - ns_listenlist_t *list = *listp; - INSIST(list->refcount > 0); - list->refcount--; - if (list->refcount == 0) - destroy(list); - *listp = NULL; -} - -isc_result_t -ns_listenlist_default(isc_mem_t *mctx, in_port_t port, - isc_boolean_t enabled, ns_listenlist_t **target) -{ - isc_result_t result; - dns_acl_t *acl = NULL; - ns_listenelt_t *elt = NULL; - ns_listenlist_t *list = NULL; - - REQUIRE(target != NULL && *target == NULL); - if (enabled) - result = dns_acl_any(mctx, &acl); - else - result = dns_acl_none(mctx, &acl); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = ns_listenelt_create(mctx, port, acl, &elt); - if (result != ISC_R_SUCCESS) - goto cleanup_acl; - - result = ns_listenlist_create(mctx, &list); - if (result != ISC_R_SUCCESS) - goto cleanup_listenelt; - - ISC_LIST_APPEND(list->elts, elt, link); - - *target = list; - return (ISC_R_SUCCESS); - - cleanup_listenelt: - ns_listenelt_destroy(elt); - cleanup_acl: - dns_acl_detach(&acl); - cleanup: - return (result); -} diff --git a/contrib/bind9/bin/named/log.c b/contrib/bind9/bin/named/log.c deleted file mode 100644 index af75bab..0000000 --- a/contrib/bind9/bin/named/log.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: log.c,v 1.37.18.6 2006/06/09 00:54:08 marka Exp $ */ - -/*! \file */ - -#include - -#include - -#include - -#include - -#ifndef ISC_FACILITY -#define ISC_FACILITY LOG_DAEMON -#endif - -/*% - * When adding a new category, be sure to add the appropriate - * #define to and to update the list in - * bin/check/check-tool.c. - */ -static isc_logcategory_t categories[] = { - { "", 0 }, - { "client", 0 }, - { "network", 0 }, - { "update", 0 }, - { "queries", 0 }, - { "unmatched", 0 }, - { "update-security", 0 }, - { NULL, 0 } -}; - -/*% - * When adding a new module, be sure to add the appropriate - * #define to . - */ -static isc_logmodule_t modules[] = { - { "main", 0 }, - { "client", 0 }, - { "server", 0 }, - { "query", 0 }, - { "interfacemgr", 0 }, - { "update", 0 }, - { "xfer-in", 0 }, - { "xfer-out", 0 }, - { "notify", 0 }, - { "control", 0 }, - { "lwresd", 0 }, - { NULL, 0 } -}; - -isc_result_t -ns_log_init(isc_boolean_t safe) { - isc_result_t result; - isc_logconfig_t *lcfg = NULL; - - ns_g_categories = categories; - ns_g_modules = modules; - - /* - * Setup a logging context. - */ - result = isc_log_create(ns_g_mctx, &ns_g_lctx, &lcfg); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * named-checktool.c:setup_logging() needs to be kept in sync. - */ - isc_log_registercategories(ns_g_lctx, ns_g_categories); - isc_log_registermodules(ns_g_lctx, ns_g_modules); - isc_log_setcontext(ns_g_lctx); - dns_log_init(ns_g_lctx); - dns_log_setcontext(ns_g_lctx); - cfg_log_init(ns_g_lctx); - - if (safe) - result = ns_log_setsafechannels(lcfg); - else - result = ns_log_setdefaultchannels(lcfg); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = ns_log_setdefaultcategory(lcfg); - if (result != ISC_R_SUCCESS) - goto cleanup; - - return (ISC_R_SUCCESS); - - cleanup: - isc_log_destroy(&ns_g_lctx); - isc_log_setcontext(NULL); - dns_log_setcontext(NULL); - - return (result); -} - -isc_result_t -ns_log_setdefaultchannels(isc_logconfig_t *lcfg) { - isc_result_t result; - isc_logdestination_t destination; - - /* - * By default, the logging library makes "default_debug" log to - * stderr. In BIND, we want to override this and log to named.run - * instead, unless the the -g option was given. - */ - if (! ns_g_logstderr) { - destination.file.stream = NULL; - destination.file.name = "named.run"; - destination.file.versions = ISC_LOG_ROLLNEVER; - destination.file.maximum_size = 0; - result = isc_log_createchannel(lcfg, "default_debug", - ISC_LOG_TOFILE, - ISC_LOG_DYNAMIC, - &destination, - ISC_LOG_PRINTTIME| - ISC_LOG_DEBUGONLY); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - -#if ISC_FACILITY != LOG_DAEMON - destination.facility = ISC_FACILITY; - result = isc_log_createchannel(lcfg, "default_syslog", - ISC_LOG_TOSYSLOG, ISC_LOG_INFO, - &destination, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; -#endif - - /* - * Set the initial debug level. - */ - isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); - - result = ISC_R_SUCCESS; - - cleanup: - return (result); -} - -isc_result_t -ns_log_setsafechannels(isc_logconfig_t *lcfg) { - isc_result_t result; -#if ISC_FACILITY != LOG_DAEMON - isc_logdestination_t destination; -#endif - - if (! ns_g_logstderr) { - result = isc_log_createchannel(lcfg, "default_debug", - ISC_LOG_TONULL, - ISC_LOG_DYNAMIC, - NULL, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * Setting the debug level to zero should get the output - * discarded a bit faster. - */ - isc_log_setdebuglevel(ns_g_lctx, 0); - } else { - isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); - } - -#if ISC_FACILITY != LOG_DAEMON - destination.facility = ISC_FACILITY; - result = isc_log_createchannel(lcfg, "default_syslog", - ISC_LOG_TOSYSLOG, ISC_LOG_INFO, - &destination, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; -#endif - - result = ISC_R_SUCCESS; - - cleanup: - return (result); -} - -isc_result_t -ns_log_setdefaultcategory(isc_logconfig_t *lcfg) { - isc_result_t result; - - if (! ns_g_logstderr) { - result = isc_log_usechannel(lcfg, "default_syslog", - ISC_LOGCATEGORY_DEFAULT, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - result = isc_log_usechannel(lcfg, "default_debug", - ISC_LOGCATEGORY_DEFAULT, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = ISC_R_SUCCESS; - - cleanup: - return (result); -} - -isc_result_t -ns_log_setunmatchedcategory(isc_logconfig_t *lcfg) { - isc_result_t result; - - result = isc_log_usechannel(lcfg, "null", - NS_LOGCATEGORY_UNMATCHED, NULL); - return (result); -} - -void -ns_log_shutdown(void) { - isc_log_destroy(&ns_g_lctx); - isc_log_setcontext(NULL); - dns_log_setcontext(NULL); -} diff --git a/contrib/bind9/bin/named/logconf.c b/contrib/bind9/bin/named/logconf.c deleted file mode 100644 index ce815f4..0000000 --- a/contrib/bind9/bin/named/logconf.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: logconf.c,v 1.35.18.5 2006/03/02 00:37:21 marka Exp $ */ - -/*! \file */ - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ - } while (0) - -/*% - * Set up a logging category according to the named.conf data - * in 'ccat' and add it to 'lctx'. - */ -static isc_result_t -category_fromconf(const cfg_obj_t *ccat, isc_logconfig_t *lctx) { - isc_result_t result; - const char *catname; - isc_logcategory_t *category; - isc_logmodule_t *module; - const cfg_obj_t *destinations = NULL; - const cfg_listelt_t *element = NULL; - - catname = cfg_obj_asstring(cfg_tuple_get(ccat, "name")); - category = isc_log_categorybyname(ns_g_lctx, catname); - if (category == NULL) { - cfg_obj_log(ccat, ns_g_lctx, ISC_LOG_ERROR, - "unknown logging category '%s' ignored", - catname); - /* - * Allow further processing by returning success. - */ - return (ISC_R_SUCCESS); - } - - module = NULL; - - destinations = cfg_tuple_get(ccat, "destinations"); - for (element = cfg_list_first(destinations); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *channel = cfg_listelt_value(element); - const char *channelname = cfg_obj_asstring(channel); - - result = isc_log_usechannel(lctx, channelname, category, - module); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, CFG_LOGCATEGORY_CONFIG, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "logging channel '%s': %s", channelname, - isc_result_totext(result)); - return (result); - } - } - return (ISC_R_SUCCESS); -} - -/*% - * Set up a logging channel according to the named.conf data - * in 'cchan' and add it to 'lctx'. - */ -static isc_result_t -channel_fromconf(const cfg_obj_t *channel, isc_logconfig_t *lctx) { - isc_result_t result; - isc_logdestination_t dest; - unsigned int type; - unsigned int flags = 0; - int level; - const char *channelname; - const cfg_obj_t *fileobj = NULL; - const cfg_obj_t *syslogobj = NULL; - const cfg_obj_t *nullobj = NULL; - const cfg_obj_t *stderrobj = NULL; - const cfg_obj_t *severity = NULL; - int i; - - channelname = cfg_obj_asstring(cfg_map_getname(channel)); - - (void)cfg_map_get(channel, "file", &fileobj); - (void)cfg_map_get(channel, "syslog", &syslogobj); - (void)cfg_map_get(channel, "null", &nullobj); - (void)cfg_map_get(channel, "stderr", &stderrobj); - - i = 0; - if (fileobj != NULL) - i++; - if (syslogobj != NULL) - i++; - if (nullobj != NULL) - i++; - if (stderrobj != NULL) - i++; - - if (i != 1) { - cfg_obj_log(channel, ns_g_lctx, ISC_LOG_ERROR, - "channel '%s': exactly one of file, syslog, " - "null, and stderr must be present", channelname); - return (ISC_R_FAILURE); - } - - type = ISC_LOG_TONULL; - - if (fileobj != NULL) { - const cfg_obj_t *pathobj = cfg_tuple_get(fileobj, "file"); - const cfg_obj_t *sizeobj = cfg_tuple_get(fileobj, "size"); - const cfg_obj_t *versionsobj = - cfg_tuple_get(fileobj, "versions"); - isc_int32_t versions = ISC_LOG_ROLLNEVER; - isc_offset_t size = 0; - - type = ISC_LOG_TOFILE; - - if (versionsobj != NULL && cfg_obj_isuint32(versionsobj)) - versions = cfg_obj_asuint32(versionsobj); - if (versionsobj != NULL && cfg_obj_isstring(versionsobj) && - strcasecmp(cfg_obj_asstring(versionsobj), "unlimited") == 0) - versions = ISC_LOG_ROLLINFINITE; - if (sizeobj != NULL && - cfg_obj_isuint64(sizeobj) && - cfg_obj_asuint64(sizeobj) < ISC_OFFSET_MAXIMUM) - size = (isc_offset_t)cfg_obj_asuint64(sizeobj); - dest.file.stream = NULL; - dest.file.name = cfg_obj_asstring(pathobj); - dest.file.versions = versions; - dest.file.maximum_size = size; - } else if (syslogobj != NULL) { - int facility = LOG_DAEMON; - - type = ISC_LOG_TOSYSLOG; - - if (cfg_obj_isstring(syslogobj)) { - const char *facilitystr = cfg_obj_asstring(syslogobj); - (void)isc_syslog_facilityfromstring(facilitystr, - &facility); - } - dest.facility = facility; - } else if (stderrobj != NULL) { - type = ISC_LOG_TOFILEDESC; - dest.file.stream = stderr; - dest.file.name = NULL; - dest.file.versions = ISC_LOG_ROLLNEVER; - dest.file.maximum_size = 0; - } - - /* - * Munge flags. - */ - { - const cfg_obj_t *printcat = NULL; - const cfg_obj_t *printsev = NULL; - const cfg_obj_t *printtime = NULL; - - (void)cfg_map_get(channel, "print-category", &printcat); - (void)cfg_map_get(channel, "print-severity", &printsev); - (void)cfg_map_get(channel, "print-time", &printtime); - - if (printcat != NULL && cfg_obj_asboolean(printcat)) - flags |= ISC_LOG_PRINTCATEGORY; - if (printtime != NULL && cfg_obj_asboolean(printtime)) - flags |= ISC_LOG_PRINTTIME; - if (printsev != NULL && cfg_obj_asboolean(printsev)) - flags |= ISC_LOG_PRINTLEVEL; - } - - level = ISC_LOG_INFO; - if (cfg_map_get(channel, "severity", &severity) == ISC_R_SUCCESS) { - if (cfg_obj_isstring(severity)) { - const char *str = cfg_obj_asstring(severity); - if (strcasecmp(str, "critical") == 0) - level = ISC_LOG_CRITICAL; - else if (strcasecmp(str, "error") == 0) - level = ISC_LOG_ERROR; - else if (strcasecmp(str, "warning") == 0) - level = ISC_LOG_WARNING; - else if (strcasecmp(str, "notice") == 0) - level = ISC_LOG_NOTICE; - else if (strcasecmp(str, "info") == 0) - level = ISC_LOG_INFO; - else if (strcasecmp(str, "dynamic") == 0) - level = ISC_LOG_DYNAMIC; - } else - /* debug */ - level = cfg_obj_asuint32(severity); - } - - result = isc_log_createchannel(lctx, channelname, - type, level, &dest, flags); - - if (result == ISC_R_SUCCESS && type == ISC_LOG_TOFILE) { - FILE *fp; - - /* - * Test that the file can be opened, since isc_log_open() - * can't effectively report failures when called in - * isc_log_doit(). - */ - result = isc_stdio_open(dest.file.name, "a", &fp); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, CFG_LOGCATEGORY_CONFIG, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "logging channel '%s' file '%s': %s", - channelname, dest.file.name, - isc_result_totext(result)); - else - (void)isc_stdio_close(fp); - - /* - * Allow named to continue by returning success. - */ - result = ISC_R_SUCCESS; - } - - return (result); -} - -isc_result_t -ns_log_configure(isc_logconfig_t *logconf, const cfg_obj_t *logstmt) { - isc_result_t result; - const cfg_obj_t *channels = NULL; - const cfg_obj_t *categories = NULL; - const cfg_listelt_t *element; - isc_boolean_t default_set = ISC_FALSE; - isc_boolean_t unmatched_set = ISC_FALSE; - const cfg_obj_t *catname; - - CHECK(ns_log_setdefaultchannels(logconf)); - - (void)cfg_map_get(logstmt, "channel", &channels); - for (element = cfg_list_first(channels); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *channel = cfg_listelt_value(element); - CHECK(channel_fromconf(channel, logconf)); - } - - (void)cfg_map_get(logstmt, "category", &categories); - for (element = cfg_list_first(categories); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *category = cfg_listelt_value(element); - CHECK(category_fromconf(category, logconf)); - if (!default_set) { - catname = cfg_tuple_get(category, "name"); - if (strcmp(cfg_obj_asstring(catname), "default") == 0) - default_set = ISC_TRUE; - } - if (!unmatched_set) { - catname = cfg_tuple_get(category, "name"); - if (strcmp(cfg_obj_asstring(catname), "unmatched") == 0) - unmatched_set = ISC_TRUE; - } - } - - if (!default_set) - CHECK(ns_log_setdefaultcategory(logconf)); - - if (!unmatched_set) - CHECK(ns_log_setunmatchedcategory(logconf)); - - return (ISC_R_SUCCESS); - - cleanup: - if (logconf != NULL) - isc_logconfig_destroy(&logconf); - return (result); -} diff --git a/contrib/bind9/bin/named/lwaddr.c b/contrib/bind9/bin/named/lwaddr.c deleted file mode 100644 index 78c2b0b..0000000 --- a/contrib/bind9/bin/named/lwaddr.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: lwaddr.c,v 1.4.18.2 2005/04/29 00:15:23 marka Exp $ */ - -/*! \file */ - -#include - -#include - -#include -#include -#include - -#include - -#include - -/*% - * Convert addresses from lwres to isc format. - */ -isc_result_t -lwaddr_netaddr_fromlwresaddr(isc_netaddr_t *na, lwres_addr_t *la) { - if (la->family != LWRES_ADDRTYPE_V4 && la->family != LWRES_ADDRTYPE_V6) - return (ISC_R_FAMILYNOSUPPORT); - - if (la->family == LWRES_ADDRTYPE_V4) { - struct in_addr ina; - memcpy(&ina.s_addr, la->address, 4); - isc_netaddr_fromin(na, &ina); - } else { - struct in6_addr ina6; - memcpy(&ina6.s6_addr, la->address, 16); - isc_netaddr_fromin6(na, &ina6); - } - return (ISC_R_SUCCESS); -} - -isc_result_t -lwaddr_sockaddr_fromlwresaddr(isc_sockaddr_t *sa, lwres_addr_t *la, - in_port_t port) -{ - isc_netaddr_t na; - isc_result_t result; - - result = lwaddr_netaddr_fromlwresaddr(&na, la); - if (result != ISC_R_SUCCESS) - return (result); - isc_sockaddr_fromnetaddr(sa, &na, port); - return (ISC_R_SUCCESS); -} - -/*% - * Convert addresses from isc to lwres format. - */ - -isc_result_t -lwaddr_lwresaddr_fromnetaddr(lwres_addr_t *la, isc_netaddr_t *na) { - if (na->family != AF_INET && na->family != AF_INET6) - return (ISC_R_FAMILYNOSUPPORT); - - if (na->family == AF_INET) { - la->family = LWRES_ADDRTYPE_V4; - la->length = 4; - memcpy(la->address, &na->type.in, 4); - } else { - la->family = LWRES_ADDRTYPE_V6; - la->length = 16; - memcpy(la->address, &na->type.in, 16); - } - return (ISC_R_SUCCESS); -} - -isc_result_t -lwaddr_lwresaddr_fromsockaddr(lwres_addr_t *la, isc_sockaddr_t *sa) { - isc_netaddr_t na; - isc_netaddr_fromsockaddr(&na, sa); - return (lwaddr_lwresaddr_fromnetaddr(la, &na)); -} diff --git a/contrib/bind9/bin/named/lwdclient.c b/contrib/bind9/bin/named/lwdclient.c deleted file mode 100644 index 68069ed..0000000 --- a/contrib/bind9/bin/named/lwdclient.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: lwdclient.c,v 1.17.18.2 2005/04/29 00:15:23 marka Exp $ */ - -/*! \file */ - -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#define SHUTTINGDOWN(cm) ((cm->flags & NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN) != 0) - -static void -lwdclientmgr_shutdown_callback(isc_task_t *task, isc_event_t *ev); - -void -ns_lwdclient_log(int level, const char *format, ...) { - va_list args; - - va_start(args, format); - isc_log_vwrite(dns_lctx, - DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB, - ISC_LOG_DEBUG(level), format, args); - va_end(args); -} - -isc_result_t -ns_lwdclientmgr_create(ns_lwreslistener_t *listener, unsigned int nclients, - isc_taskmgr_t *taskmgr) -{ - ns_lwresd_t *lwresd = listener->manager; - ns_lwdclientmgr_t *cm; - ns_lwdclient_t *client; - unsigned int i; - isc_result_t result = ISC_R_FAILURE; - - cm = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclientmgr_t)); - if (cm == NULL) - return (ISC_R_NOMEMORY); - - cm->listener = NULL; - ns_lwreslistener_attach(listener, &cm->listener); - cm->mctx = lwresd->mctx; - cm->sock = NULL; - isc_socket_attach(listener->sock, &cm->sock); - cm->view = lwresd->view; - cm->lwctx = NULL; - cm->task = NULL; - cm->flags = 0; - ISC_LINK_INIT(cm, link); - ISC_LIST_INIT(cm->idle); - ISC_LIST_INIT(cm->running); - - if (lwres_context_create(&cm->lwctx, cm->mctx, - ns__lwresd_memalloc, ns__lwresd_memfree, - LWRES_CONTEXT_SERVERMODE) - != ISC_R_SUCCESS) - goto errout; - - for (i = 0; i < nclients; i++) { - client = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclient_t)); - if (client != NULL) { - ns_lwdclient_log(50, "created client %p, manager %p", - client, cm); - ns_lwdclient_initialize(client, cm); - } - } - - /* - * If we could create no clients, clean up and return. - */ - if (ISC_LIST_EMPTY(cm->idle)) - goto errout; - - result = isc_task_create(taskmgr, 0, &cm->task); - if (result != ISC_R_SUCCESS) - goto errout; - - /* - * This MUST be last, since there is no way to cancel an onshutdown... - */ - result = isc_task_onshutdown(cm->task, lwdclientmgr_shutdown_callback, - cm); - if (result != ISC_R_SUCCESS) - goto errout; - - ns_lwreslistener_linkcm(listener, cm); - - return (ISC_R_SUCCESS); - - errout: - client = ISC_LIST_HEAD(cm->idle); - while (client != NULL) { - ISC_LIST_UNLINK(cm->idle, client, link); - isc_mem_put(lwresd->mctx, client, sizeof(*client)); - client = ISC_LIST_HEAD(cm->idle); - } - - if (cm->task != NULL) - isc_task_detach(&cm->task); - - if (cm->lwctx != NULL) - lwres_context_destroy(&cm->lwctx); - - isc_mem_put(lwresd->mctx, cm, sizeof(*cm)); - return (result); -} - -static void -lwdclientmgr_destroy(ns_lwdclientmgr_t *cm) { - ns_lwdclient_t *client; - ns_lwreslistener_t *listener; - - if (!SHUTTINGDOWN(cm)) - return; - - /* - * run through the idle list and free the clients there. Idle - * clients do not have a recv running nor do they have any finds - * or similar running. - */ - client = ISC_LIST_HEAD(cm->idle); - while (client != NULL) { - ns_lwdclient_log(50, "destroying client %p, manager %p", - client, cm); - ISC_LIST_UNLINK(cm->idle, client, link); - isc_mem_put(cm->mctx, client, sizeof(*client)); - client = ISC_LIST_HEAD(cm->idle); - } - - if (!ISC_LIST_EMPTY(cm->running)) - return; - - lwres_context_destroy(&cm->lwctx); - cm->view = NULL; - isc_socket_detach(&cm->sock); - isc_task_detach(&cm->task); - - listener = cm->listener; - ns_lwreslistener_unlinkcm(listener, cm); - ns_lwdclient_log(50, "destroying manager %p", cm); - isc_mem_put(cm->mctx, cm, sizeof(*cm)); - ns_lwreslistener_detach(&listener); -} - -static void -process_request(ns_lwdclient_t *client) { - lwres_buffer_t b; - isc_result_t result; - - lwres_buffer_init(&b, client->buffer, client->recvlength); - lwres_buffer_add(&b, client->recvlength); - - result = lwres_lwpacket_parseheader(&b, &client->pkt); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_log(50, "invalid packet header received"); - goto restart; - } - - ns_lwdclient_log(50, "opcode %08x", client->pkt.opcode); - - switch (client->pkt.opcode) { - case LWRES_OPCODE_GETADDRSBYNAME: - ns_lwdclient_processgabn(client, &b); - return; - case LWRES_OPCODE_GETNAMEBYADDR: - ns_lwdclient_processgnba(client, &b); - return; - case LWRES_OPCODE_GETRDATABYNAME: - ns_lwdclient_processgrbn(client, &b); - return; - case LWRES_OPCODE_NOOP: - ns_lwdclient_processnoop(client, &b); - return; - default: - ns_lwdclient_log(50, "unknown opcode %08x", client->pkt.opcode); - goto restart; - } - - /* - * Drop the packet. - */ - restart: - ns_lwdclient_log(50, "restarting client %p...", client); - ns_lwdclient_stateidle(client); -} - -void -ns_lwdclient_recv(isc_task_t *task, isc_event_t *ev) { - isc_result_t result; - ns_lwdclient_t *client = ev->ev_arg; - ns_lwdclientmgr_t *cm = client->clientmgr; - isc_socketevent_t *dev = (isc_socketevent_t *)ev; - - INSIST(dev->region.base == client->buffer); - INSIST(NS_LWDCLIENT_ISRECV(client)); - - NS_LWDCLIENT_SETRECVDONE(client); - - INSIST((cm->flags & NS_LWDCLIENTMGR_FLAGRECVPENDING) != 0); - cm->flags &= ~NS_LWDCLIENTMGR_FLAGRECVPENDING; - - ns_lwdclient_log(50, - "event received: task %p, length %u, result %u (%s)", - task, dev->n, dev->result, - isc_result_totext(dev->result)); - - if (dev->result != ISC_R_SUCCESS) { - isc_event_free(&ev); - dev = NULL; - - /* - * Go idle. - */ - ns_lwdclient_stateidle(client); - - return; - } - - client->recvlength = dev->n; - client->address = dev->address; - if ((dev->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) { - client->pktinfo = dev->pktinfo; - client->pktinfo_valid = ISC_TRUE; - } else - client->pktinfo_valid = ISC_FALSE; - isc_event_free(&ev); - dev = NULL; - - result = ns_lwdclient_startrecv(cm); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, - "could not start lwres " - "client handler: %s", - isc_result_totext(result)); - - process_request(client); -} - -/* - * This function will start a new recv() on a socket for this client manager. - */ -isc_result_t -ns_lwdclient_startrecv(ns_lwdclientmgr_t *cm) { - ns_lwdclient_t *client; - isc_result_t result; - isc_region_t r; - - if (SHUTTINGDOWN(cm)) { - lwdclientmgr_destroy(cm); - return (ISC_R_SUCCESS); - } - - /* - * If a recv is already running, don't bother. - */ - if ((cm->flags & NS_LWDCLIENTMGR_FLAGRECVPENDING) != 0) - return (ISC_R_SUCCESS); - - /* - * If we have no idle slots, just return success. - */ - client = ISC_LIST_HEAD(cm->idle); - if (client == NULL) - return (ISC_R_SUCCESS); - INSIST(NS_LWDCLIENT_ISIDLE(client)); - - /* - * Issue the recv. If it fails, return that it did. - */ - r.base = client->buffer; - r.length = LWRES_RECVLENGTH; - result = isc_socket_recv(cm->sock, &r, 0, cm->task, ns_lwdclient_recv, - client); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Set the flag to say we've issued a recv() call. - */ - cm->flags |= NS_LWDCLIENTMGR_FLAGRECVPENDING; - - /* - * Remove the client from the idle list, and put it on the running - * list. - */ - NS_LWDCLIENT_SETRECV(client); - ISC_LIST_UNLINK(cm->idle, client, link); - ISC_LIST_APPEND(cm->running, client, link); - - return (ISC_R_SUCCESS); -} - -static void -lwdclientmgr_shutdown_callback(isc_task_t *task, isc_event_t *ev) { - ns_lwdclientmgr_t *cm = ev->ev_arg; - ns_lwdclient_t *client; - - REQUIRE(!SHUTTINGDOWN(cm)); - - ns_lwdclient_log(50, "got shutdown event, task %p, lwdclientmgr %p", - task, cm); - - /* - * run through the idle list and free the clients there. Idle - * clients do not have a recv running nor do they have any finds - * or similar running. - */ - client = ISC_LIST_HEAD(cm->idle); - while (client != NULL) { - ns_lwdclient_log(50, "destroying client %p, manager %p", - client, cm); - ISC_LIST_UNLINK(cm->idle, client, link); - isc_mem_put(cm->mctx, client, sizeof(*client)); - client = ISC_LIST_HEAD(cm->idle); - } - - /* - * Cancel any pending I/O. - */ - isc_socket_cancel(cm->sock, task, ISC_SOCKCANCEL_ALL); - - /* - * Run through the running client list and kill off any finds - * in progress. - */ - client = ISC_LIST_HEAD(cm->running); - while (client != NULL) { - if (client->find != client->v4find - && client->find != client->v6find) - dns_adb_cancelfind(client->find); - if (client->v4find != NULL) - dns_adb_cancelfind(client->v4find); - if (client->v6find != NULL) - dns_adb_cancelfind(client->v6find); - client = ISC_LIST_NEXT(client, link); - } - - cm->flags |= NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN; - - isc_event_free(&ev); -} - -/* - * Do all the crap needed to move a client from the run queue to the idle - * queue. - */ -void -ns_lwdclient_stateidle(ns_lwdclient_t *client) { - ns_lwdclientmgr_t *cm; - isc_result_t result; - - cm = client->clientmgr; - - INSIST(client->sendbuf == NULL); - INSIST(client->sendlength == 0); - INSIST(client->arg == NULL); - INSIST(client->v4find == NULL); - INSIST(client->v6find == NULL); - - ISC_LIST_UNLINK(cm->running, client, link); - ISC_LIST_PREPEND(cm->idle, client, link); - - NS_LWDCLIENT_SETIDLE(client); - - result = ns_lwdclient_startrecv(cm); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, - "could not start lwres " - "client handler: %s", - isc_result_totext(result)); -} - -void -ns_lwdclient_send(isc_task_t *task, isc_event_t *ev) { - ns_lwdclient_t *client = ev->ev_arg; - ns_lwdclientmgr_t *cm = client->clientmgr; - isc_socketevent_t *dev = (isc_socketevent_t *)ev; - - UNUSED(task); - UNUSED(dev); - - INSIST(NS_LWDCLIENT_ISSEND(client)); - INSIST(client->sendbuf == dev->region.base); - - ns_lwdclient_log(50, "task %p for client %p got send-done event", - task, client); - - if (client->sendbuf != client->buffer) - lwres_context_freemem(cm->lwctx, client->sendbuf, - client->sendlength); - client->sendbuf = NULL; - client->sendlength = 0; - - ns_lwdclient_stateidle(client); - - isc_event_free(&ev); -} - -isc_result_t -ns_lwdclient_sendreply(ns_lwdclient_t *client, isc_region_t *r) { - struct in6_pktinfo *pktinfo; - ns_lwdclientmgr_t *cm = client->clientmgr; - - if (client->pktinfo_valid) - pktinfo = &client->pktinfo; - else - pktinfo = NULL; - return (isc_socket_sendto(cm->sock, r, cm->task, ns_lwdclient_send, - client, &client->address, pktinfo)); -} - -void -ns_lwdclient_initialize(ns_lwdclient_t *client, ns_lwdclientmgr_t *cmgr) { - client->clientmgr = cmgr; - ISC_LINK_INIT(client, link); - NS_LWDCLIENT_SETIDLE(client); - client->arg = NULL; - - client->recvlength = 0; - - client->sendbuf = NULL; - client->sendlength = 0; - - client->find = NULL; - client->v4find = NULL; - client->v6find = NULL; - client->find_wanted = 0; - - client->options = 0; - client->byaddr = NULL; - - client->lookup = NULL; - - client->pktinfo_valid = ISC_FALSE; - - ISC_LIST_APPEND(cmgr->idle, client, link); -} diff --git a/contrib/bind9/bin/named/lwderror.c b/contrib/bind9/bin/named/lwderror.c deleted file mode 100644 index db25824..0000000 --- a/contrib/bind9/bin/named/lwderror.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: lwderror.c,v 1.8.18.2 2005/04/29 00:15:24 marka Exp $ */ - -/*! \file */ - -#include - -#include -#include - -#include -#include - -/*% - * Generate an error packet for the client, schedule a send, and put us in - * the SEND state. - * - * The client->pkt structure will be modified to form an error return. - * The receiver needs to verify that it is in fact an error, and do the - * right thing with it. The opcode will be unchanged. The result needs - * to be set before calling this function. - * - * The only change this code makes is to set the receive buffer size to the - * size we use, set the reply bit, and recompute any security information. - */ -void -ns_lwdclient_errorpktsend(ns_lwdclient_t *client, isc_uint32_t _result) { - isc_result_t result; - int lwres; - isc_region_t r; - lwres_buffer_t b; - - REQUIRE(NS_LWDCLIENT_ISRUNNING(client)); - - /* - * Since we are only sending the packet header, we can safely toss - * the receive buffer. This means we won't need to allocate space - * for sending an error reply. This is a Good Thing. - */ - client->pkt.length = LWRES_LWPACKET_LENGTH; - client->pkt.pktflags |= LWRES_LWPACKETFLAG_RESPONSE; - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - client->pkt.result = _result; - - lwres_buffer_init(&b, client->buffer, LWRES_RECVLENGTH); - lwres = lwres_lwpacket_renderheader(&b, &client->pkt); - if (lwres != LWRES_R_SUCCESS) { - ns_lwdclient_stateidle(client); - return; - } - - r.base = client->buffer; - r.length = b.used; - client->sendbuf = client->buffer; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_stateidle(client); - return; - } - - NS_LWDCLIENT_SETSEND(client); -} diff --git a/contrib/bind9/bin/named/lwdgabn.c b/contrib/bind9/bin/named/lwdgabn.c deleted file mode 100644 index 454d4df..0000000 --- a/contrib/bind9/bin/named/lwdgabn.c +++ /dev/null @@ -1,657 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: lwdgabn.c,v 1.15.18.5 2006/03/02 00:37:21 marka Exp $ */ - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define NEED_V4(c) ((((c)->find_wanted & LWRES_ADDRTYPE_V4) != 0) \ - && ((c)->v4find == NULL)) -#define NEED_V6(c) ((((c)->find_wanted & LWRES_ADDRTYPE_V6) != 0) \ - && ((c)->v6find == NULL)) - -static isc_result_t start_find(ns_lwdclient_t *); -static void restart_find(ns_lwdclient_t *); -static void init_gabn(ns_lwdclient_t *); - -/*% - * Destroy any finds. This can be used to "start over from scratch" and - * should only be called when events are _not_ being generated by the finds. - */ -static void -cleanup_gabn(ns_lwdclient_t *client) { - ns_lwdclient_log(50, "cleaning up client %p", client); - - if (client->v6find != NULL) { - if (client->v6find == client->v4find) - client->v6find = NULL; - else - dns_adb_destroyfind(&client->v6find); - } - if (client->v4find != NULL) - dns_adb_destroyfind(&client->v4find); -} - -static void -setup_addresses(ns_lwdclient_t *client, dns_adbfind_t *find, unsigned int at) { - dns_adbaddrinfo_t *ai; - lwres_addr_t *addr; - int af; - const struct sockaddr *sa; - isc_result_t result; - - if (at == DNS_ADBFIND_INET) - af = AF_INET; - else - af = AF_INET6; - - ai = ISC_LIST_HEAD(find->list); - while (ai != NULL && client->gabn.naddrs < LWRES_MAX_ADDRS) { - sa = &ai->sockaddr.type.sa; - if (sa->sa_family != af) - goto next; - - addr = &client->addrs[client->gabn.naddrs]; - - result = lwaddr_lwresaddr_fromsockaddr(addr, &ai->sockaddr); - if (result != ISC_R_SUCCESS) - goto next; - - ns_lwdclient_log(50, "adding address %p, family %d, length %d", - addr->address, addr->family, addr->length); - - client->gabn.naddrs++; - REQUIRE(!LWRES_LINK_LINKED(addr, link)); - LWRES_LIST_APPEND(client->gabn.addrs, addr, link); - - next: - ai = ISC_LIST_NEXT(ai, publink); - } -} - -typedef struct { - isc_netaddr_t address; - int rank; -} rankedaddress; - -static int -addr_compare(const void *av, const void *bv) { - const rankedaddress *a = (const rankedaddress *) av; - const rankedaddress *b = (const rankedaddress *) bv; - return (a->rank - b->rank); -} - -static void -sort_addresses(ns_lwdclient_t *client) { - unsigned int naddrs; - rankedaddress *addrs; - isc_netaddr_t remote; - dns_addressorderfunc_t order; - const void *arg; - ns_lwresd_t *lwresd = client->clientmgr->listener->manager; - unsigned int i; - isc_result_t result; - - naddrs = client->gabn.naddrs; - - if (naddrs <= 1 || lwresd->view->sortlist == NULL) - return; - - addrs = isc_mem_get(lwresd->mctx, sizeof(rankedaddress) * naddrs); - if (addrs == NULL) - return; - - isc_netaddr_fromsockaddr(&remote, &client->address); - ns_sortlist_byaddrsetup(lwresd->view->sortlist, - &remote, &order, &arg); - if (order == NULL) { - isc_mem_put(lwresd->mctx, addrs, - sizeof(rankedaddress) * naddrs); - return; - } - for (i = 0; i < naddrs; i++) { - result = lwaddr_netaddr_fromlwresaddr(&addrs[i].address, - &client->addrs[i]); - INSIST(result == ISC_R_SUCCESS); - addrs[i].rank = (*order)(&addrs[i].address, arg); - } - qsort(addrs, naddrs, sizeof(rankedaddress), addr_compare); - for (i = 0; i < naddrs; i++) { - result = lwaddr_lwresaddr_fromnetaddr(&client->addrs[i], - &addrs[i].address); - INSIST(result == ISC_R_SUCCESS); - } - - isc_mem_put(lwresd->mctx, addrs, sizeof(rankedaddress) * naddrs); -} - -static void -generate_reply(ns_lwdclient_t *client) { - isc_result_t result; - int lwres; - isc_region_t r; - lwres_buffer_t lwb; - ns_lwdclientmgr_t *cm; - - cm = client->clientmgr; - lwb.base = NULL; - - ns_lwdclient_log(50, "generating gabn reply for client %p", client); - - /* - * We must make certain the client->find is not still active. - * If it is either the v4 or v6 answer, just set it to NULL and - * let the cleanup code destroy it. Otherwise, destroy it now. - */ - if (client->find == client->v4find || client->find == client->v6find) - client->find = NULL; - else - if (client->find != NULL) - dns_adb_destroyfind(&client->find); - - /* - * perhaps there are some here? - */ - if (NEED_V6(client) && client->v4find != NULL) - client->v6find = client->v4find; - - /* - * Run through the finds we have and wire them up to the gabn - * structure. - */ - LWRES_LIST_INIT(client->gabn.addrs); - if (client->v4find != NULL) - setup_addresses(client, client->v4find, DNS_ADBFIND_INET); - if (client->v6find != NULL) - setup_addresses(client, client->v6find, DNS_ADBFIND_INET6); - - /* - * If there are no addresses, try the next element in the search - * path, if there are any more. Otherwise, fall through into - * the error handling code below. - */ - if (client->gabn.naddrs == 0) { - do { - result = ns_lwsearchctx_next(&client->searchctx); - if (result == ISC_R_SUCCESS) { - cleanup_gabn(client); - result = start_find(client); - if (result == ISC_R_SUCCESS) - return; - } - } while (result == ISC_R_SUCCESS); - } - - /* - * Render the packet. - */ - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - - /* - * If there are no addresses, return failure. - */ - if (client->gabn.naddrs != 0) - client->pkt.result = LWRES_R_SUCCESS; - else - client->pkt.result = LWRES_R_NOTFOUND; - - sort_addresses(client); - - lwres = lwres_gabnresponse_render(cm->lwctx, &client->gabn, - &client->pkt, &lwb); - if (lwres != LWRES_R_SUCCESS) - goto out; - - r.base = lwb.base; - r.length = lwb.used; - client->sendbuf = r.base; - client->sendlength = r.length; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) - goto out; - - NS_LWDCLIENT_SETSEND(client); - - /* - * All done! - */ - cleanup_gabn(client); - - return; - - out: - cleanup_gabn(client); - - if (lwb.base != NULL) - lwres_context_freemem(client->clientmgr->lwctx, - lwb.base, lwb.length); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} - -/* - * Take the current real name, move it to an alias slot (if any are - * open) then put this new name in as the real name for the target. - * - * Return success if it can be rendered, otherwise failure. Note that - * not having enough alias slots open is NOT a failure. - */ -static isc_result_t -add_alias(ns_lwdclient_t *client) { - isc_buffer_t b; - isc_result_t result; - isc_uint16_t naliases; - - b = client->recv_buffer; - - /* - * Render the new name to the buffer. - */ - result = dns_name_totext(dns_fixedname_name(&client->target_name), - ISC_TRUE, &client->recv_buffer); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Are there any open slots? - */ - naliases = client->gabn.naliases; - if (naliases < LWRES_MAX_ALIASES) { - client->gabn.aliases[naliases] = client->gabn.realname; - client->gabn.aliaslen[naliases] = client->gabn.realnamelen; - client->gabn.naliases++; - } - - /* - * Save this name away as the current real name. - */ - client->gabn.realname = (char *)(b.base) + b.used; - client->gabn.realnamelen = client->recv_buffer.used - b.used; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -store_realname(ns_lwdclient_t *client) { - isc_buffer_t b; - isc_result_t result; - dns_name_t *tname; - - b = client->recv_buffer; - - tname = dns_fixedname_name(&client->target_name); - result = ns_lwsearchctx_current(&client->searchctx, tname); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Render the new name to the buffer. - */ - result = dns_name_totext(tname, ISC_TRUE, &client->recv_buffer); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Save this name away as the current real name. - */ - client->gabn.realname = (char *) b.base + b.used; - client->gabn.realnamelen = client->recv_buffer.used - b.used; - - return (ISC_R_SUCCESS); -} - -static void -process_gabn_finddone(isc_task_t *task, isc_event_t *ev) { - ns_lwdclient_t *client = ev->ev_arg; - isc_eventtype_t evtype; - isc_boolean_t claimed; - - ns_lwdclient_log(50, "find done for task %p, client %p", task, client); - - evtype = ev->ev_type; - isc_event_free(&ev); - - /* - * No more info to be had? If so, we have all the good stuff - * right now, so we can render things. - */ - claimed = ISC_FALSE; - if (evtype == DNS_EVENT_ADBNOMOREADDRESSES) { - if (NEED_V4(client)) { - client->v4find = client->find; - claimed = ISC_TRUE; - } - if (NEED_V6(client)) { - client->v6find = client->find; - claimed = ISC_TRUE; - } - if (client->find != NULL) { - if (claimed) - client->find = NULL; - else - dns_adb_destroyfind(&client->find); - - } - generate_reply(client); - return; - } - - /* - * We probably don't need this find anymore. We're either going to - * reissue it, or an error occurred. Either way, we're done with - * it. - */ - if ((client->find != client->v4find) - && (client->find != client->v6find)) { - dns_adb_destroyfind(&client->find); - } else { - client->find = NULL; - } - - /* - * We have some new information we can gather. Run off and fetch - * it. - */ - if (evtype == DNS_EVENT_ADBMOREADDRESSES) { - restart_find(client); - return; - } - - /* - * An error or other strangeness happened. Drop this query. - */ - cleanup_gabn(client); - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} - -static void -restart_find(ns_lwdclient_t *client) { - unsigned int options; - isc_result_t result; - isc_boolean_t claimed; - - ns_lwdclient_log(50, "starting find for client %p", client); - - /* - * Issue a find for the name contained in the request. We won't - * set the bit that says "anything is good enough" -- we want it - * all. - */ - options = 0; - options |= DNS_ADBFIND_WANTEVENT; - options |= DNS_ADBFIND_RETURNLAME; - - /* - * Set the bits up here to mark that we want this address family - * and that we do not currently have a find pending. We will - * set that bit again below if it turns out we will get an event. - */ - if (NEED_V4(client)) - options |= DNS_ADBFIND_INET; - if (NEED_V6(client)) - options |= DNS_ADBFIND_INET6; - - find_again: - INSIST(client->find == NULL); - result = dns_adb_createfind(client->clientmgr->view->adb, - client->clientmgr->task, - process_gabn_finddone, client, - dns_fixedname_name(&client->target_name), - dns_rootname, 0, options, 0, - dns_fixedname_name(&client->target_name), - client->clientmgr->view->dstport, - &client->find); - - /* - * Did we get an alias? If so, save it and re-issue the query. - */ - if (result == DNS_R_ALIAS) { - ns_lwdclient_log(50, "found alias, restarting query"); - dns_adb_destroyfind(&client->find); - cleanup_gabn(client); - result = add_alias(client); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_log(50, - "out of buffer space adding alias"); - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } - goto find_again; - } - - ns_lwdclient_log(50, "find returned %d (%s)", result, - isc_result_totext(result)); - - /* - * Did we get an error? - */ - if (result != ISC_R_SUCCESS) { - if (client->find != NULL) - dns_adb_destroyfind(&client->find); - cleanup_gabn(client); - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } - - claimed = ISC_FALSE; - - /* - * Did we get our answer to V4 addresses? - */ - if (NEED_V4(client) - && ((client->find->query_pending & DNS_ADBFIND_INET) == 0)) { - ns_lwdclient_log(50, "client %p ipv4 satisfied by find %p", - client, client->find); - claimed = ISC_TRUE; - client->v4find = client->find; - } - - /* - * Did we get our answer to V6 addresses? - */ - if (NEED_V6(client) - && ((client->find->query_pending & DNS_ADBFIND_INET6) == 0)) { - ns_lwdclient_log(50, "client %p ipv6 satisfied by find %p", - client, client->find); - claimed = ISC_TRUE; - client->v6find = client->find; - } - - /* - * If we're going to get an event, set our internal pending flag - * and return. When we get an event back we'll do the right - * thing, basically by calling this function again, perhaps with a - * new target name. - * - * If we have both v4 and v6, and we are still getting an event, - * we have a programming error, so die hard. - */ - if ((client->find->options & DNS_ADBFIND_WANTEVENT) != 0) { - ns_lwdclient_log(50, "event will be sent"); - INSIST(client->v4find == NULL || client->v6find == NULL); - return; - } - ns_lwdclient_log(50, "no event will be sent"); - if (claimed) - client->find = NULL; - else - dns_adb_destroyfind(&client->find); - - /* - * We seem to have everything we asked for, or at least we are - * able to respond with things we've learned. - */ - - generate_reply(client); -} - -static isc_result_t -start_find(ns_lwdclient_t *client) { - isc_result_t result; - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - init_gabn(client); - - result = store_realname(client); - if (result != ISC_R_SUCCESS) - return (result); - restart_find(client); - return (ISC_R_SUCCESS); - -} - -static void -init_gabn(ns_lwdclient_t *client) { - int i; - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - for (i = 0; i < LWRES_MAX_ALIASES; i++) { - client->aliases[i] = NULL; - client->aliaslen[i] = 0; - } - for (i = 0; i < LWRES_MAX_ADDRS; i++) { - client->addrs[i].family = 0; - client->addrs[i].length = 0; - memset(client->addrs[i].address, 0, LWRES_ADDR_MAXLEN); - LWRES_LINK_INIT(&client->addrs[i], link); - } - - client->gabn.naliases = 0; - client->gabn.naddrs = 0; - client->gabn.realname = NULL; - client->gabn.aliases = client->aliases; - client->gabn.realnamelen = 0; - client->gabn.aliaslen = client->aliaslen; - LWRES_LIST_INIT(client->gabn.addrs); - client->gabn.base = NULL; - client->gabn.baselen = 0; - - /* - * Set up the internal buffer to point to the receive region. - */ - isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH); -} - -/* - * When we are called, we can be assured that: - * - * client->sockaddr contains the address we need to reply to, - * - * client->pkt contains the packet header data, - * - * the packet "checks out" overall -- any MD5 hashes or crypto - * bits have been verified, - * - * "b" points to the remaining data after the packet header - * was parsed off. - * - * We are in a the RECVDONE state. - * - * From this state we will enter the SEND state if we happen to have - * everything we need or we need to return an error packet, or to the - * FINDWAIT state if we need to look things up. - */ -void -ns_lwdclient_processgabn(ns_lwdclient_t *client, lwres_buffer_t *b) { - isc_result_t result; - lwres_gabnrequest_t *req; - ns_lwdclientmgr_t *cm; - isc_buffer_t namebuf; - - REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); - - cm = client->clientmgr; - req = NULL; - - result = lwres_gabnrequest_parse(client->clientmgr->lwctx, - b, &client->pkt, &req); - if (result != LWRES_R_SUCCESS) - goto out; - if (req->name == NULL) - goto out; - - isc_buffer_init(&namebuf, req->name, req->namelen); - isc_buffer_add(&namebuf, req->namelen); - - dns_fixedname_init(&client->target_name); - dns_fixedname_init(&client->query_name); - result = dns_name_fromtext(dns_fixedname_name(&client->query_name), - &namebuf, NULL, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) - goto out; - ns_lwsearchctx_init(&client->searchctx, - cm->listener->manager->search, - dns_fixedname_name(&client->query_name), - cm->listener->manager->ndots); - ns_lwsearchctx_first(&client->searchctx); - - client->find_wanted = req->addrtypes; - ns_lwdclient_log(50, "client %p looking for addrtypes %08x", - client, client->find_wanted); - - /* - * We no longer need to keep this around. - */ - lwres_gabnrequest_free(client->clientmgr->lwctx, &req); - - /* - * Start the find. - */ - result = start_find(client); - if (result != ISC_R_SUCCESS) - goto out; - - return; - - /* - * We're screwed. Return an error packet to our caller. - */ - out: - if (req != NULL) - lwres_gabnrequest_free(client->clientmgr->lwctx, &req); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} diff --git a/contrib/bind9/bin/named/lwdgnba.c b/contrib/bind9/bin/named/lwdgnba.c deleted file mode 100644 index a500d27..0000000 --- a/contrib/bind9/bin/named/lwdgnba.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-2002 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: lwdgnba.c,v 1.16.18.2 2005/04/29 00:15:24 marka Exp $ */ - -/*! \file */ - -#include - -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include -#include -#include - -#include -#include - -static void start_byaddr(ns_lwdclient_t *); - -static void -byaddr_done(isc_task_t *task, isc_event_t *event) { - ns_lwdclient_t *client; - ns_lwdclientmgr_t *cm; - dns_byaddrevent_t *bevent; - int lwres; - lwres_buffer_t lwb; - dns_name_t *name; - isc_result_t result; - lwres_result_t lwresult; - isc_region_t r; - isc_buffer_t b; - lwres_gnbaresponse_t *gnba; - isc_uint16_t naliases; - - UNUSED(task); - - lwb.base = NULL; - client = event->ev_arg; - cm = client->clientmgr; - INSIST(client->byaddr == (dns_byaddr_t *)event->ev_sender); - - bevent = (dns_byaddrevent_t *)event; - gnba = &client->gnba; - - ns_lwdclient_log(50, "byaddr event result = %s", - isc_result_totext(bevent->result)); - - result = bevent->result; - if (result != ISC_R_SUCCESS) { - dns_byaddr_destroy(&client->byaddr); - isc_event_free(&event); - bevent = NULL; - - if (client->na.family != AF_INET6 || - (client->options & DNS_BYADDROPT_IPV6INT) != 0) { - if (result == DNS_R_NCACHENXDOMAIN || - result == DNS_R_NCACHENXRRSET || - result == DNS_R_NXDOMAIN || - result == DNS_R_NXRRSET) - lwresult = LWRES_R_NOTFOUND; - else - lwresult = LWRES_R_FAILURE; - ns_lwdclient_errorpktsend(client, lwresult); - return; - } - - /* - * Fall back to ip6.int reverse if the default ip6.arpa - * fails. - */ - client->options |= DNS_BYADDROPT_IPV6INT; - - start_byaddr(client); - return; - } - - for (name = ISC_LIST_HEAD(bevent->names); - name != NULL; - name = ISC_LIST_NEXT(name, link)) - { - b = client->recv_buffer; - - result = dns_name_totext(name, ISC_TRUE, &client->recv_buffer); - if (result != ISC_R_SUCCESS) - goto out; - ns_lwdclient_log(50, "found name '%.*s'", - (int)(client->recv_buffer.used - b.used), - (char *)(b.base) + b.used); - if (gnba->realname == NULL) { - gnba->realname = (char *)(b.base) + b.used; - gnba->realnamelen = client->recv_buffer.used - b.used; - } else { - naliases = gnba->naliases; - if (naliases >= LWRES_MAX_ALIASES) - break; - gnba->aliases[naliases] = (char *)(b.base) + b.used; - gnba->aliaslen[naliases] = - client->recv_buffer.used - b.used; - gnba->naliases++; - } - } - - dns_byaddr_destroy(&client->byaddr); - isc_event_free(&event); - - /* - * Render the packet. - */ - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - client->pkt.result = LWRES_R_SUCCESS; - - lwres = lwres_gnbaresponse_render(cm->lwctx, - gnba, &client->pkt, &lwb); - if (lwres != LWRES_R_SUCCESS) - goto out; - - r.base = lwb.base; - r.length = lwb.used; - client->sendbuf = r.base; - client->sendlength = r.length; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) - goto out; - - NS_LWDCLIENT_SETSEND(client); - - return; - - out: - if (client->byaddr != NULL) - dns_byaddr_destroy(&client->byaddr); - if (lwb.base != NULL) - lwres_context_freemem(cm->lwctx, - lwb.base, lwb.length); - - if (event != NULL) - isc_event_free(&event); -} - -static void -start_byaddr(ns_lwdclient_t *client) { - isc_result_t result; - ns_lwdclientmgr_t *cm; - - cm = client->clientmgr; - - INSIST(client->byaddr == NULL); - - result = dns_byaddr_create(cm->mctx, &client->na, cm->view, - client->options, cm->task, byaddr_done, - client, &client->byaddr); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } -} - -static void -init_gnba(ns_lwdclient_t *client) { - int i; - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - for (i = 0; i < LWRES_MAX_ALIASES; i++) { - client->aliases[i] = NULL; - client->aliaslen[i] = 0; - } - for (i = 0; i < LWRES_MAX_ADDRS; i++) { - client->addrs[i].family = 0; - client->addrs[i].length = 0; - memset(client->addrs[i].address, 0, LWRES_ADDR_MAXLEN); - LWRES_LINK_INIT(&client->addrs[i], link); - } - - client->gnba.naliases = 0; - client->gnba.realname = NULL; - client->gnba.aliases = client->aliases; - client->gnba.realnamelen = 0; - client->gnba.aliaslen = client->aliaslen; - client->gnba.base = NULL; - client->gnba.baselen = 0; - isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH); -} - -void -ns_lwdclient_processgnba(ns_lwdclient_t *client, lwres_buffer_t *b) { - lwres_gnbarequest_t *req; - isc_result_t result; - isc_sockaddr_t sa; - ns_lwdclientmgr_t *cm; - - REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); - INSIST(client->byaddr == NULL); - - cm = client->clientmgr; - req = NULL; - - result = lwres_gnbarequest_parse(cm->lwctx, - b, &client->pkt, &req); - if (result != LWRES_R_SUCCESS) - goto out; - if (req->addr.address == NULL) - goto out; - - client->options = 0; - if (req->addr.family == LWRES_ADDRTYPE_V4) { - client->na.family = AF_INET; - if (req->addr.length != 4) - goto out; - memcpy(&client->na.type.in, req->addr.address, 4); - } else if (req->addr.family == LWRES_ADDRTYPE_V6) { - client->na.family = AF_INET6; - if (req->addr.length != 16) - goto out; - memcpy(&client->na.type.in6, req->addr.address, 16); - } else { - goto out; - } - isc_sockaddr_fromnetaddr(&sa, &client->na, 53); - - ns_lwdclient_log(50, "client %p looking for addrtype %08x", - client, req->addr.family); - - /* - * We no longer need to keep this around. - */ - lwres_gnbarequest_free(cm->lwctx, &req); - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - init_gnba(client); - client->options = 0; - - /* - * Start the find. - */ - start_byaddr(client); - - return; - - /* - * We're screwed. Return an error packet to our caller. - */ - out: - if (req != NULL) - lwres_gnbarequest_free(cm->lwctx, &req); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} diff --git a/contrib/bind9/bin/named/lwdgrbn.c b/contrib/bind9/bin/named/lwdgrbn.c deleted file mode 100644 index c1b2b1e..0000000 --- a/contrib/bind9/bin/named/lwdgrbn.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: lwdgrbn.c,v 1.13.18.5 2006/12/07 23:57:58 marka Exp $ */ - -/*! \file */ - -#include - -#include -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static void start_lookup(ns_lwdclient_t *); - -static isc_result_t -fill_array(int *pos, dns_rdataset_t *rdataset, - int size, unsigned char **rdatas, lwres_uint16_t *rdatalen) -{ - dns_rdata_t rdata; - isc_result_t result; - isc_region_t r; - - UNUSED(size); - - dns_rdata_init(&rdata); - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) - { - INSIST(*pos < size); - dns_rdataset_current(rdataset, &rdata); - dns_rdata_toregion(&rdata, &r); - rdatas[*pos] = r.base; - rdatalen[*pos] = r.length; - dns_rdata_reset(&rdata); - (*pos)++; - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - return (result); -} - -static isc_result_t -iterate_node(lwres_grbnresponse_t *grbn, dns_db_t *db, dns_dbnode_t *node, - isc_mem_t *mctx) -{ - int used = 0, count; - int size = 8, oldsize = 0; - unsigned char **rdatas = NULL, **oldrdatas = NULL, **newrdatas = NULL; - lwres_uint16_t *lens = NULL, *oldlens = NULL, *newlens = NULL; - dns_rdatasetiter_t *iter = NULL; - dns_rdataset_t set; - dns_ttl_t ttl = ISC_INT32_MAX; - lwres_uint32_t flags = LWRDATA_VALIDATED; - isc_result_t result = ISC_R_NOMEMORY; - - result = dns_db_allrdatasets(db, node, NULL, 0, &iter); - if (result != ISC_R_SUCCESS) - goto out; - - rdatas = isc_mem_get(mctx, size * sizeof(*rdatas)); - if (rdatas == NULL) - goto out; - lens = isc_mem_get(mctx, size * sizeof(*lens)); - if (lens == NULL) - goto out; - - for (result = dns_rdatasetiter_first(iter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(iter)) - { - result = ISC_R_NOMEMORY; - dns_rdataset_init(&set); - dns_rdatasetiter_current(iter, &set); - - if (set.type != dns_rdatatype_rrsig) { - dns_rdataset_disassociate(&set); - continue; - } - - count = dns_rdataset_count(&set); - if (used + count > size) { - /* copy & reallocate */ - oldsize = size; - oldrdatas = rdatas; - oldlens = lens; - rdatas = NULL; - lens = NULL; - - size *= 2; - - rdatas = isc_mem_get(mctx, size * sizeof(*rdatas)); - if (rdatas == NULL) - goto out; - lens = isc_mem_get(mctx, size * sizeof(*lens)); - if (lens == NULL) - goto out; - memcpy(rdatas, oldrdatas, used * sizeof(*rdatas)); - memcpy(lens, oldlens, used * sizeof(*lens)); - isc_mem_put(mctx, oldrdatas, - oldsize * sizeof(*oldrdatas)); - isc_mem_put(mctx, oldlens, oldsize * sizeof(*oldlens)); - oldrdatas = NULL; - oldlens = NULL; - } - if (set.ttl < ttl) - ttl = set.ttl; - if (set.trust != dns_trust_secure) - flags &= (~LWRDATA_VALIDATED); - result = fill_array(&used, &set, size, rdatas, lens); - dns_rdataset_disassociate(&set); - if (result != ISC_R_SUCCESS) - goto out; - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - if (result != ISC_R_SUCCESS) - goto out; - dns_rdatasetiter_destroy(&iter); - - /* - * If necessary, shrink and copy the arrays. - */ - if (size != used) { - result = ISC_R_NOMEMORY; - newrdatas = isc_mem_get(mctx, used * sizeof(*rdatas)); - if (newrdatas == NULL) - goto out; - newlens = isc_mem_get(mctx, used * sizeof(*lens)); - if (newlens == NULL) - goto out; - memcpy(newrdatas, rdatas, used * sizeof(*rdatas)); - memcpy(newlens, lens, used * sizeof(*lens)); - isc_mem_put(mctx, rdatas, size * sizeof(*rdatas)); - isc_mem_put(mctx, lens, size * sizeof(*lens)); - grbn->rdatas = newrdatas; - grbn->rdatalen = newlens; - } else { - grbn->rdatas = rdatas; - grbn->rdatalen = lens; - } - grbn->nrdatas = used; - grbn->ttl = ttl; - grbn->flags = flags; - return (ISC_R_SUCCESS); - - out: - dns_rdatasetiter_destroy(&iter); - if (rdatas != NULL) - isc_mem_put(mctx, rdatas, size * sizeof(*rdatas)); - if (lens != NULL) - isc_mem_put(mctx, lens, size * sizeof(*lens)); - if (oldrdatas != NULL) - isc_mem_put(mctx, oldrdatas, oldsize * sizeof(*oldrdatas)); - if (oldlens != NULL) - isc_mem_put(mctx, oldlens, oldsize * sizeof(*oldlens)); - if (newrdatas != NULL) - isc_mem_put(mctx, newrdatas, used * sizeof(*oldrdatas)); - return (result); -} - -static void -lookup_done(isc_task_t *task, isc_event_t *event) { - ns_lwdclient_t *client; - ns_lwdclientmgr_t *cm; - dns_lookupevent_t *levent; - lwres_buffer_t lwb; - dns_name_t *name; - dns_rdataset_t *rdataset; - dns_rdataset_t *sigrdataset; - isc_result_t result; - lwres_result_t lwresult; - isc_region_t r; - isc_buffer_t b; - lwres_grbnresponse_t *grbn; - int i; - - UNUSED(task); - - lwb.base = NULL; - client = event->ev_arg; - cm = client->clientmgr; - INSIST(client->lookup == (dns_lookup_t *)event->ev_sender); - - levent = (dns_lookupevent_t *)event; - grbn = &client->grbn; - - ns_lwdclient_log(50, "lookup event result = %s", - isc_result_totext(levent->result)); - - result = levent->result; - if (result != ISC_R_SUCCESS) { - dns_lookup_destroy(&client->lookup); - isc_event_free(&event); - levent = NULL; - - switch (result) { - case DNS_R_NXDOMAIN: - case DNS_R_NCACHENXDOMAIN: - result = ns_lwsearchctx_next(&client->searchctx); - if (result != ISC_R_SUCCESS) - lwresult = LWRES_R_NOTFOUND; - else { - start_lookup(client); - return; - } - break; - case DNS_R_NXRRSET: - case DNS_R_NCACHENXRRSET: - lwresult = LWRES_R_TYPENOTFOUND; - break; - default: - lwresult = LWRES_R_FAILURE; - } - ns_lwdclient_errorpktsend(client, lwresult); - return; - } - - name = levent->name; - b = client->recv_buffer; - - grbn->flags = 0; - - grbn->nrdatas = 0; - grbn->rdatas = NULL; - grbn->rdatalen = NULL; - - grbn->nsigs = 0; - grbn->sigs = NULL; - grbn->siglen = NULL; - - result = dns_name_totext(name, ISC_TRUE, &client->recv_buffer); - if (result != ISC_R_SUCCESS) - goto out; - grbn->realname = (char *)isc_buffer_used(&b); - grbn->realnamelen = isc_buffer_usedlength(&client->recv_buffer) - - isc_buffer_usedlength(&b); - ns_lwdclient_log(50, "found name '%.*s'", grbn->realnamelen, - grbn->realname); - - grbn->rdclass = cm->view->rdclass; - grbn->rdtype = client->rdtype; - - rdataset = levent->rdataset; - if (rdataset != NULL) { - /* The normal case */ - grbn->nrdatas = dns_rdataset_count(rdataset); - grbn->rdatas = isc_mem_get(cm->mctx, grbn->nrdatas * - sizeof(unsigned char *)); - if (grbn->rdatas == NULL) - goto out; - grbn->rdatalen = isc_mem_get(cm->mctx, grbn->nrdatas * - sizeof(lwres_uint16_t)); - if (grbn->rdatalen == NULL) - goto out; - - i = 0; - result = fill_array(&i, rdataset, grbn->nrdatas, grbn->rdatas, - grbn->rdatalen); - if (result != ISC_R_SUCCESS) - goto out; - INSIST(i == grbn->nrdatas); - grbn->ttl = rdataset->ttl; - if (rdataset->trust == dns_trust_secure) - grbn->flags |= LWRDATA_VALIDATED; - } else { - /* The SIG query case */ - result = iterate_node(grbn, levent->db, levent->node, - cm->mctx); - if (result != ISC_R_SUCCESS) - goto out; - } - ns_lwdclient_log(50, "filled in %d rdata%s", grbn->nrdatas, - (grbn->nrdatas == 1) ? "" : "s"); - - sigrdataset = levent->sigrdataset; - if (sigrdataset != NULL) { - grbn->nsigs = dns_rdataset_count(sigrdataset); - grbn->sigs = isc_mem_get(cm->mctx, grbn->nsigs * - sizeof(unsigned char *)); - if (grbn->sigs == NULL) - goto out; - grbn->siglen = isc_mem_get(cm->mctx, grbn->nsigs * - sizeof(lwres_uint16_t)); - if (grbn->siglen == NULL) - goto out; - - i = 0; - result = fill_array(&i, sigrdataset, grbn->nsigs, grbn->sigs, - grbn->siglen); - if (result != ISC_R_SUCCESS) - goto out; - INSIST(i == grbn->nsigs); - ns_lwdclient_log(50, "filled in %d signature%s", grbn->nsigs, - (grbn->nsigs == 1) ? "" : "s"); - } - - dns_lookup_destroy(&client->lookup); - isc_event_free(&event); - - /* - * Render the packet. - */ - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - client->pkt.result = LWRES_R_SUCCESS; - - lwresult = lwres_grbnresponse_render(cm->lwctx, - grbn, &client->pkt, &lwb); - if (lwresult != LWRES_R_SUCCESS) - goto out; - - isc_mem_put(cm->mctx, grbn->rdatas, - grbn->nrdatas * sizeof(unsigned char *)); - isc_mem_put(cm->mctx, grbn->rdatalen, - grbn->nrdatas * sizeof(lwres_uint16_t)); - - if (grbn->sigs != NULL) - isc_mem_put(cm->mctx, grbn->sigs, - grbn->nsigs * sizeof(unsigned char *)); - if (grbn->siglen != NULL) - isc_mem_put(cm->mctx, grbn->siglen, - grbn->nsigs * sizeof(lwres_uint16_t)); - - r.base = lwb.base; - r.length = lwb.used; - client->sendbuf = r.base; - client->sendlength = r.length; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) - goto out2; - - NS_LWDCLIENT_SETSEND(client); - - return; - - out: - if (grbn->rdatas != NULL) - isc_mem_put(cm->mctx, grbn->rdatas, - grbn->nrdatas * sizeof(unsigned char *)); - if (grbn->rdatalen != NULL) - isc_mem_put(cm->mctx, grbn->rdatalen, - grbn->nrdatas * sizeof(lwres_uint16_t)); - - if (grbn->sigs != NULL) - isc_mem_put(cm->mctx, grbn->sigs, - grbn->nsigs * sizeof(unsigned char *)); - if (grbn->siglen != NULL) - isc_mem_put(cm->mctx, grbn->siglen, - grbn->nsigs * sizeof(lwres_uint16_t)); - out2: - if (client->lookup != NULL) - dns_lookup_destroy(&client->lookup); - if (lwb.base != NULL) - lwres_context_freemem(cm->lwctx, lwb.base, lwb.length); - - if (event != NULL) - isc_event_free(&event); - - ns_lwdclient_log(50, "error constructing getrrsetbyname response"); - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} - -static void -start_lookup(ns_lwdclient_t *client) { - isc_result_t result; - ns_lwdclientmgr_t *cm; - dns_fixedname_t absname; - - cm = client->clientmgr; - - INSIST(client->lookup == NULL); - - dns_fixedname_init(&absname); - result = ns_lwsearchctx_current(&client->searchctx, - dns_fixedname_name(&absname)); - /* - * This will return failure if relative name + suffix is too long. - * In this case, just go on to the next entry in the search path. - */ - if (result != ISC_R_SUCCESS) - start_lookup(client); - - result = dns_lookup_create(cm->mctx, - dns_fixedname_name(&absname), - client->rdtype, cm->view, - client->options, cm->task, lookup_done, - client, &client->lookup); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } -} - -static void -init_grbn(ns_lwdclient_t *client) { - client->grbn.rdclass = 0; - client->grbn.rdtype = 0; - client->grbn.ttl = 0; - client->grbn.nrdatas = 0; - client->grbn.realname = NULL; - client->grbn.realnamelen = 0; - client->grbn.rdatas = 0; - client->grbn.rdatalen = 0; - client->grbn.base = NULL; - client->grbn.baselen = 0; - isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH); -} - -void -ns_lwdclient_processgrbn(ns_lwdclient_t *client, lwres_buffer_t *b) { - lwres_grbnrequest_t *req; - isc_result_t result; - ns_lwdclientmgr_t *cm; - isc_buffer_t namebuf; - - REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); - INSIST(client->byaddr == NULL); - - cm = client->clientmgr; - req = NULL; - - result = lwres_grbnrequest_parse(cm->lwctx, - b, &client->pkt, &req); - if (result != LWRES_R_SUCCESS) - goto out; - if (req->name == NULL) - goto out; - - client->options = 0; - if (req->rdclass != cm->view->rdclass) - goto out; - - if (req->rdclass == dns_rdataclass_any || - req->rdtype == dns_rdatatype_any) - goto out; - - client->rdtype = req->rdtype; - - isc_buffer_init(&namebuf, req->name, req->namelen); - isc_buffer_add(&namebuf, req->namelen); - - dns_fixedname_init(&client->query_name); - result = dns_name_fromtext(dns_fixedname_name(&client->query_name), - &namebuf, NULL, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) - goto out; - ns_lwsearchctx_init(&client->searchctx, - cm->listener->manager->search, - dns_fixedname_name(&client->query_name), - cm->listener->manager->ndots); - ns_lwsearchctx_first(&client->searchctx); - - ns_lwdclient_log(50, "client %p looking for type %d", - client, client->rdtype); - - /* - * We no longer need to keep this around. - */ - lwres_grbnrequest_free(cm->lwctx, &req); - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - init_grbn(client); - - /* - * Start the find. - */ - start_lookup(client); - - return; - - /* - * We're screwed. Return an error packet to our caller. - */ - out: - if (req != NULL) - lwres_grbnrequest_free(cm->lwctx, &req); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} diff --git a/contrib/bind9/bin/named/lwdnoop.c b/contrib/bind9/bin/named/lwdnoop.c deleted file mode 100644 index fa591b4..0000000 --- a/contrib/bind9/bin/named/lwdnoop.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: lwdnoop.c,v 1.7.18.2 2005/04/29 00:15:25 marka Exp $ */ - -/*! \file */ - -#include - -#include -#include - -#include -#include - -void -ns_lwdclient_processnoop(ns_lwdclient_t *client, lwres_buffer_t *b) { - lwres_nooprequest_t *req; - lwres_noopresponse_t resp; - isc_result_t result; - lwres_result_t lwres; - isc_region_t r; - lwres_buffer_t lwb; - - REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); - INSIST(client->byaddr == NULL); - - req = NULL; - - result = lwres_nooprequest_parse(client->clientmgr->lwctx, - b, &client->pkt, &req); - if (result != LWRES_R_SUCCESS) - goto out; - - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - client->pkt.result = LWRES_R_SUCCESS; - - resp.datalength = req->datalength; - resp.data = req->data; - - lwres = lwres_noopresponse_render(client->clientmgr->lwctx, &resp, - &client->pkt, &lwb); - if (lwres != LWRES_R_SUCCESS) - goto out; - - r.base = lwb.base; - r.length = lwb.used; - client->sendbuf = r.base; - client->sendlength = r.length; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) - goto out; - - /* - * We can now destroy request. - */ - lwres_nooprequest_free(client->clientmgr->lwctx, &req); - - NS_LWDCLIENT_SETSEND(client); - - return; - - out: - if (req != NULL) - lwres_nooprequest_free(client->clientmgr->lwctx, &req); - - if (lwb.base != NULL) - lwres_context_freemem(client->clientmgr->lwctx, - lwb.base, lwb.length); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} diff --git a/contrib/bind9/bin/named/lwresd.8 b/contrib/bind9/bin/named/lwresd.8 deleted file mode 100644 index 825645a..0000000 --- a/contrib/bind9/bin/named/lwresd.8 +++ /dev/null @@ -1,223 +0,0 @@ -.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") -.\" Copyright (C) 2000, 2001 Internet Software Consortium. -.\" -.\" Permission to use, copy, modify, and 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: lwresd.8,v 1.15.18.12 2007/05/16 06:11:27 marka Exp $ -.\" -.hy 0 -.ad l -.\" Title: lwresd -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.71.1 -.\" Date: June 30, 2000 -.\" Manual: BIND9 -.\" Source: BIND9 -.\" -.TH "LWRESD" "8" "June 30, 2000" "BIND9" "BIND9" -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.SH "NAME" -lwresd \- lightweight resolver daemon -.SH "SYNOPSIS" -.HP 7 -\fBlwresd\fR [\fB\-c\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-C\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-d\ \fR\fB\fIdebug\-level\fR\fR] [\fB\-f\fR] [\fB\-g\fR] [\fB\-i\ \fR\fB\fIpid\-file\fR\fR] [\fB\-m\ \fR\fB\fIflag\fR\fR] [\fB\-n\ \fR\fB\fI#cpus\fR\fR] [\fB\-P\ \fR\fB\fIport\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-s\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-4\fR] [\fB\-6\fR] -.SH "DESCRIPTION" -.PP -\fBlwresd\fR -is the daemon providing name lookup services to clients that use the BIND 9 lightweight resolver library. It is essentially a stripped\-down, caching\-only name server that answers queries using the BIND 9 lightweight resolver protocol rather than the DNS protocol. -.PP -\fBlwresd\fR -listens for resolver queries on a UDP port on the IPv4 loopback interface, 127.0.0.1. This means that -\fBlwresd\fR -can only be used by processes running on the local machine. By default UDP port number 921 is used for lightweight resolver requests and responses. -.PP -Incoming lightweight resolver requests are decoded by the server which then resolves them using the DNS protocol. When the DNS lookup completes, -\fBlwresd\fR -encodes the answers in the lightweight resolver format and returns them to the client that made the request. -.PP -If -\fI/etc/resolv.conf\fR -contains any -\fBnameserver\fR -entries, -\fBlwresd\fR -sends recursive DNS queries to those servers. This is similar to the use of forwarders in a caching name server. If no -\fBnameserver\fR -entries are present, or if forwarding fails, -\fBlwresd\fR -resolves the queries autonomously starting at the root name servers, using a built\-in list of root server hints. -.SH "OPTIONS" -.PP -\-4 -.RS 4 -Use IPv4 only even if the host machine is capable of IPv6. -\fB\-4\fR -and -\fB\-6\fR -are mutually exclusive. -.RE -.PP -\-6 -.RS 4 -Use IPv6 only even if the host machine is capable of IPv4. -\fB\-4\fR -and -\fB\-6\fR -are mutually exclusive. -.RE -.PP -\-c \fIconfig\-file\fR -.RS 4 -Use -\fIconfig\-file\fR -as the configuration file instead of the default, -\fI/etc/lwresd.conf\fR. -\-c -can not be used with -\-C. -.RE -.PP -\-C \fIconfig\-file\fR -.RS 4 -Use -\fIconfig\-file\fR -as the configuration file instead of the default, -\fI/etc/resolv.conf\fR. -\-C -can not be used with -\-c. -.RE -.PP -\-d \fIdebug\-level\fR -.RS 4 -Set the daemon's debug level to -\fIdebug\-level\fR. Debugging traces from -\fBlwresd\fR -become more verbose as the debug level increases. -.RE -.PP -\-f -.RS 4 -Run the server in the foreground (i.e. do not daemonize). -.RE -.PP -\-g -.RS 4 -Run the server in the foreground and force all logging to -\fIstderr\fR. -.RE -.PP -\-i \fIpid\-file\fR -.RS 4 -Use -\fIpid\-file\fR -as the PID file instead of the default, -\fI/var/run/lwresd.pid\fR. -.RE -.PP -\-m \fIflag\fR -.RS 4 -Turn on memory usage debugging flags. Possible flags are -\fIusage\fR, -\fItrace\fR, -\fIrecord\fR, -\fIsize\fR, and -\fImctx\fR. These correspond to the ISC_MEM_DEBUGXXXX flags described in -\fI\fR. -.RE -.PP -\-n \fI#cpus\fR -.RS 4 -Create -\fI#cpus\fR -worker threads to take advantage of multiple CPUs. If not specified, -\fBlwresd\fR -will try to determine the number of CPUs present and create one thread per CPU. If it is unable to determine the number of CPUs, a single worker thread will be created. -.RE -.PP -\-P \fIport\fR -.RS 4 -Listen for lightweight resolver queries on port -\fIport\fR. If not specified, the default is port 921. -.RE -.PP -\-p \fIport\fR -.RS 4 -Send DNS lookups to port -\fIport\fR. If not specified, the default is port 53. This provides a way of testing the lightweight resolver daemon with a name server that listens for queries on a non\-standard port number. -.RE -.PP -\-s -.RS 4 -Write memory usage statistics to -\fIstdout\fR -on exit. -.RS -.B "Note:" -This option is mainly of interest to BIND 9 developers and may be removed or changed in a future release. -.RE -.RE -.PP -\-t \fIdirectory\fR -.RS 4 -Chroot to -\fIdirectory\fR -after processing the command line arguments, but before reading the configuration file. -.RS -.B "Warning:" -This option should be used in conjunction with the -\fB\-u\fR -option, as chrooting a process running as root doesn't enhance security on most systems; the way -\fBchroot(2)\fR -is defined allows a process with root privileges to escape a chroot jail. -.RE -.RE -.PP -\-u \fIuser\fR -.RS 4 -Setuid to -\fIuser\fR -after completing privileged operations, such as creating sockets that listen on privileged ports. -.RE -.PP -\-v -.RS 4 -Report the version number and exit. -.RE -.SH "FILES" -.PP -\fI/etc/resolv.conf\fR -.RS 4 -The default configuration file. -.RE -.PP -\fI/var/run/lwresd.pid\fR -.RS 4 -The default process\-id file. -.RE -.SH "SEE ALSO" -.PP -\fBnamed\fR(8), -\fBlwres\fR(3), -\fBresolver\fR(5). -.SH "AUTHOR" -.PP -Internet Systems Consortium -.SH "COPYRIGHT" -Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") -.br -Copyright \(co 2000, 2001 Internet Software Consortium. -.br diff --git a/contrib/bind9/bin/named/lwresd.c b/contrib/bind9/bin/named/lwresd.c deleted file mode 100644 index a1073fa..0000000 --- a/contrib/bind9/bin/named/lwresd.c +++ /dev/null @@ -1,869 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: lwresd.c,v 1.46.18.7 2006/03/02 00:37:21 marka Exp $ */ - -/*! \file - * \brief - * Main program for the Lightweight Resolver Daemon. - * - * To paraphrase the old saying about X11, "It's not a lightweight deamon - * for resolvers, it's a deamon for lightweight resolvers". - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define LWRESD_MAGIC ISC_MAGIC('L', 'W', 'R', 'D') -#define VALID_LWRESD(l) ISC_MAGIC_VALID(l, LWRESD_MAGIC) - -#define LWRESLISTENER_MAGIC ISC_MAGIC('L', 'W', 'R', 'L') -#define VALID_LWRESLISTENER(l) ISC_MAGIC_VALID(l, LWRESLISTENER_MAGIC) - -/*! - * The total number of clients we can handle will be NTASKS * NRECVS. - */ -#define NTASKS 2 /*%< tasks to create to handle lwres queries */ -#define NRECVS 2 /*%< max clients per task */ - -typedef ISC_LIST(ns_lwreslistener_t) ns_lwreslistenerlist_t; - -static ns_lwreslistenerlist_t listeners; -static isc_mutex_t listeners_lock; -static isc_once_t once = ISC_ONCE_INIT; - - -static void -initialize_mutex(void) { - RUNTIME_CHECK(isc_mutex_init(&listeners_lock) == ISC_R_SUCCESS); -} - - -/*% - * Wrappers around our memory management stuff, for the lwres functions. - */ -void * -ns__lwresd_memalloc(void *arg, size_t size) { - return (isc_mem_get(arg, size)); -} - -void -ns__lwresd_memfree(void *arg, void *mem, size_t size) { - isc_mem_put(arg, mem, size); -} - - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ - } while (0) - -static isc_result_t -buffer_putstr(isc_buffer_t *b, const char *s) { - unsigned int len = strlen(s); - if (isc_buffer_availablelength(b) <= len) - return (ISC_R_NOSPACE); - isc_buffer_putmem(b, (const unsigned char *)s, len); - return (ISC_R_SUCCESS); -} - -/* - * Convert a resolv.conf file into a config structure. - */ -isc_result_t -ns_lwresd_parseeresolvconf(isc_mem_t *mctx, cfg_parser_t *pctx, - cfg_obj_t **configp) -{ - char text[4096]; - char str[16]; - isc_buffer_t b; - lwres_context_t *lwctx = NULL; - lwres_conf_t *lwc = NULL; - isc_sockaddr_t sa; - isc_netaddr_t na; - int i; - isc_result_t result; - lwres_result_t lwresult; - - lwctx = NULL; - lwresult = lwres_context_create(&lwctx, mctx, ns__lwresd_memalloc, - ns__lwresd_memfree, - LWRES_CONTEXT_SERVERMODE); - if (lwresult != LWRES_R_SUCCESS) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - - lwresult = lwres_conf_parse(lwctx, lwresd_g_resolvconffile); - if (lwresult != LWRES_R_SUCCESS) { - result = DNS_R_SYNTAX; - goto cleanup; - } - - lwc = lwres_conf_get(lwctx); - INSIST(lwc != NULL); - - isc_buffer_init(&b, text, sizeof(text)); - - CHECK(buffer_putstr(&b, "options {\n")); - - /* - * Build the list of forwarders. - */ - if (lwc->nsnext > 0) { - CHECK(buffer_putstr(&b, "\tforwarders {\n")); - - for (i = 0; i < lwc->nsnext; i++) { - CHECK(lwaddr_sockaddr_fromlwresaddr( - &sa, - &lwc->nameservers[i], - ns_g_port)); - isc_netaddr_fromsockaddr(&na, &sa); - CHECK(buffer_putstr(&b, "\t\t")); - CHECK(isc_netaddr_totext(&na, &b)); - CHECK(buffer_putstr(&b, ";\n")); - } - CHECK(buffer_putstr(&b, "\t};\n")); - } - - /* - * Build the sortlist - */ - if (lwc->sortlistnxt > 0) { - CHECK(buffer_putstr(&b, "\tsortlist {\n")); - CHECK(buffer_putstr(&b, "\t\t{\n")); - CHECK(buffer_putstr(&b, "\t\t\tany;\n")); - CHECK(buffer_putstr(&b, "\t\t\t{\n")); - for (i = 0; i < lwc->sortlistnxt; i++) { - lwres_addr_t *lwaddr = &lwc->sortlist[i].addr; - lwres_addr_t *lwmask = &lwc->sortlist[i].mask; - unsigned int mask; - - CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, lwmask, 0)); - isc_netaddr_fromsockaddr(&na, &sa); - result = isc_netaddr_masktoprefixlen(&na, &mask); - if (result != ISC_R_SUCCESS) { - char addrtext[ISC_NETADDR_FORMATSIZE]; - isc_netaddr_format(&na, addrtext, - sizeof(addrtext)); - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, - ISC_LOG_ERROR, - "processing sortlist: '%s' is " - "not a valid netmask", - addrtext); - goto cleanup; - } - - CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, lwaddr, 0)); - isc_netaddr_fromsockaddr(&na, &sa); - - CHECK(buffer_putstr(&b, "\t\t\t\t")); - CHECK(isc_netaddr_totext(&na, &b)); - snprintf(str, sizeof(str), "%u", mask); - CHECK(buffer_putstr(&b, "/")); - CHECK(buffer_putstr(&b, str)); - CHECK(buffer_putstr(&b, ";\n")); - } - CHECK(buffer_putstr(&b, "\t\t\t};\n")); - CHECK(buffer_putstr(&b, "\t\t};\n")); - CHECK(buffer_putstr(&b, "\t};\n")); - } - - CHECK(buffer_putstr(&b, "};\n\n")); - - CHECK(buffer_putstr(&b, "lwres {\n")); - - /* - * Build the search path - */ - if (lwc->searchnxt > 0) { - if (lwc->searchnxt > 0) { - CHECK(buffer_putstr(&b, "\tsearch {\n")); - for (i = 0; i < lwc->searchnxt; i++) { - CHECK(buffer_putstr(&b, "\t\t\"")); - CHECK(buffer_putstr(&b, lwc->search[i])); - CHECK(buffer_putstr(&b, "\";\n")); - } - CHECK(buffer_putstr(&b, "\t};\n")); - } - } - - /* - * Build the ndots line - */ - if (lwc->ndots != 1) { - CHECK(buffer_putstr(&b, "\tndots ")); - snprintf(str, sizeof(str), "%u", lwc->ndots); - CHECK(buffer_putstr(&b, str)); - CHECK(buffer_putstr(&b, ";\n")); - } - - /* - * Build the listen-on line - */ - if (lwc->lwnext > 0) { - CHECK(buffer_putstr(&b, "\tlisten-on {\n")); - - for (i = 0; i < lwc->lwnext; i++) { - CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, - &lwc->lwservers[i], - 0)); - isc_netaddr_fromsockaddr(&na, &sa); - CHECK(buffer_putstr(&b, "\t\t")); - CHECK(isc_netaddr_totext(&na, &b)); - CHECK(buffer_putstr(&b, ";\n")); - } - CHECK(buffer_putstr(&b, "\t};\n")); - } - - CHECK(buffer_putstr(&b, "};\n")); - -#if 0 - printf("%.*s\n", - (int)isc_buffer_usedlength(&b), - (char *)isc_buffer_base(&b)); -#endif - - lwres_conf_clear(lwctx); - lwres_context_destroy(&lwctx); - - return (cfg_parse_buffer(pctx, &b, &cfg_type_namedconf, configp)); - - cleanup: - - if (lwctx != NULL) { - lwres_conf_clear(lwctx); - lwres_context_destroy(&lwctx); - } - - return (result); -} - - -/* - * Handle lwresd manager objects - */ -isc_result_t -ns_lwdmanager_create(isc_mem_t *mctx, const cfg_obj_t *lwres, - ns_lwresd_t **lwresdp) -{ - ns_lwresd_t *lwresd; - const char *vname; - dns_rdataclass_t vclass; - const cfg_obj_t *obj, *viewobj, *searchobj; - const cfg_listelt_t *element; - isc_result_t result; - - INSIST(lwresdp != NULL && *lwresdp == NULL); - - lwresd = isc_mem_get(mctx, sizeof(ns_lwresd_t)); - if (lwresd == NULL) - return (ISC_R_NOMEMORY); - - lwresd->mctx = NULL; - isc_mem_attach(mctx, &lwresd->mctx); - lwresd->view = NULL; - lwresd->search = NULL; - lwresd->refs = 1; - - obj = NULL; - (void)cfg_map_get(lwres, "ndots", &obj); - if (obj != NULL) - lwresd->ndots = cfg_obj_asuint32(obj); - else - lwresd->ndots = 1; - - RUNTIME_CHECK(isc_mutex_init(&lwresd->lock) == ISC_R_SUCCESS); - - lwresd->shutting_down = ISC_FALSE; - - viewobj = NULL; - (void)cfg_map_get(lwres, "view", &viewobj); - if (viewobj != NULL) { - vname = cfg_obj_asstring(cfg_tuple_get(viewobj, "name")); - obj = cfg_tuple_get(viewobj, "class"); - result = ns_config_getclass(obj, dns_rdataclass_in, &vclass); - if (result != ISC_R_SUCCESS) - goto fail; - } else { - vname = "_default"; - vclass = dns_rdataclass_in; - } - - result = dns_viewlist_find(&ns_g_server->viewlist, vname, vclass, - &lwresd->view); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "couldn't find view %s", vname); - goto fail; - } - - searchobj = NULL; - (void)cfg_map_get(lwres, "search", &searchobj); - if (searchobj != NULL) { - lwresd->search = NULL; - result = ns_lwsearchlist_create(lwresd->mctx, - &lwresd->search); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "couldn't create searchlist"); - goto fail; - } - for (element = cfg_list_first(searchobj); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *search; - const char *searchstr; - isc_buffer_t namebuf; - dns_fixedname_t fname; - dns_name_t *name; - - search = cfg_listelt_value(element); - searchstr = cfg_obj_asstring(search); - - dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); - isc_buffer_init(&namebuf, searchstr, - strlen(searchstr)); - isc_buffer_add(&namebuf, strlen(searchstr)); - result = dns_name_fromtext(name, &namebuf, - dns_rootname, ISC_FALSE, - NULL); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, - ISC_LOG_WARNING, - "invalid name %s in searchlist", - searchstr); - continue; - } - - result = ns_lwsearchlist_append(lwresd->search, name); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, - ISC_LOG_WARNING, - "couldn't update searchlist"); - goto fail; - } - } - } - - lwresd->magic = LWRESD_MAGIC; - - *lwresdp = lwresd; - return (ISC_R_SUCCESS); - - fail: - if (lwresd->view != NULL) - dns_view_detach(&lwresd->view); - if (lwresd->search != NULL) - ns_lwsearchlist_detach(&lwresd->search); - if (lwresd->mctx != NULL) - isc_mem_detach(&lwresd->mctx); - isc_mem_put(mctx, lwresd, sizeof(ns_lwresd_t)); - return (result); -} - -void -ns_lwdmanager_attach(ns_lwresd_t *source, ns_lwresd_t **targetp) { - INSIST(VALID_LWRESD(source)); - INSIST(targetp != NULL && *targetp == NULL); - - LOCK(&source->lock); - source->refs++; - UNLOCK(&source->lock); - - *targetp = source; -} - -void -ns_lwdmanager_detach(ns_lwresd_t **lwresdp) { - ns_lwresd_t *lwresd; - isc_mem_t *mctx; - isc_boolean_t done = ISC_FALSE; - - INSIST(lwresdp != NULL && *lwresdp != NULL); - INSIST(VALID_LWRESD(*lwresdp)); - - lwresd = *lwresdp; - *lwresdp = NULL; - - LOCK(&lwresd->lock); - INSIST(lwresd->refs > 0); - lwresd->refs--; - if (lwresd->refs == 0) - done = ISC_TRUE; - UNLOCK(&lwresd->lock); - - if (!done) - return; - - dns_view_detach(&lwresd->view); - if (lwresd->search != NULL) - ns_lwsearchlist_detach(&lwresd->search); - mctx = lwresd->mctx; - lwresd->magic = 0; - isc_mem_put(mctx, lwresd, sizeof(*lwresd)); - isc_mem_detach(&mctx); -} - - -/* - * Handle listener objects - */ -void -ns_lwreslistener_attach(ns_lwreslistener_t *source, - ns_lwreslistener_t **targetp) -{ - INSIST(VALID_LWRESLISTENER(source)); - INSIST(targetp != NULL && *targetp == NULL); - - LOCK(&source->lock); - source->refs++; - UNLOCK(&source->lock); - - *targetp = source; -} - -void -ns_lwreslistener_detach(ns_lwreslistener_t **listenerp) { - ns_lwreslistener_t *listener; - isc_mem_t *mctx; - isc_boolean_t done = ISC_FALSE; - - INSIST(listenerp != NULL && *listenerp != NULL); - INSIST(VALID_LWRESLISTENER(*listenerp)); - - listener = *listenerp; - - LOCK(&listener->lock); - INSIST(listener->refs > 0); - listener->refs--; - if (listener->refs == 0) - done = ISC_TRUE; - UNLOCK(&listener->lock); - - if (!done) - return; - - if (listener->manager != NULL) - ns_lwdmanager_detach(&listener->manager); - - if (listener->sock != NULL) - isc_socket_detach(&listener->sock); - - listener->magic = 0; - mctx = listener->mctx; - isc_mem_put(mctx, listener, sizeof(*listener)); - isc_mem_detach(&mctx); - listenerp = NULL; -} - -static isc_result_t -listener_create(isc_mem_t *mctx, ns_lwresd_t *lwresd, - ns_lwreslistener_t **listenerp) -{ - ns_lwreslistener_t *listener; - isc_result_t result; - - REQUIRE(listenerp != NULL && *listenerp == NULL); - - listener = isc_mem_get(mctx, sizeof(ns_lwreslistener_t)); - if (listener == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&listener->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, listener, sizeof(ns_lwreslistener_t)); - return (result); - } - - listener->magic = LWRESLISTENER_MAGIC; - listener->refs = 1; - - listener->sock = NULL; - - listener->manager = NULL; - ns_lwdmanager_attach(lwresd, &listener->manager); - - listener->mctx = NULL; - isc_mem_attach(mctx, &listener->mctx); - - ISC_LINK_INIT(listener, link); - ISC_LIST_INIT(listener->cmgrs); - - *listenerp = listener; - return (ISC_R_SUCCESS); -} - -static isc_result_t -listener_bind(ns_lwreslistener_t *listener, isc_sockaddr_t *address) { - isc_socket_t *sock = NULL; - isc_result_t result = ISC_R_SUCCESS; - int pf; - - pf = isc_sockaddr_pf(address); - if ((pf == AF_INET && isc_net_probeipv4() != ISC_R_SUCCESS) || - (pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS)) - return (ISC_R_FAMILYNOSUPPORT); - - listener->address = *address; - - if (isc_sockaddr_getport(&listener->address) == 0) { - in_port_t port; - port = lwresd_g_listenport; - if (port == 0) - port = LWRES_UDP_PORT; - isc_sockaddr_setport(&listener->address, port); - } - - sock = NULL; - result = isc_socket_create(ns_g_socketmgr, pf, - isc_sockettype_udp, &sock); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "failed to create lwres socket: %s", - isc_result_totext(result)); - return (result); - } - - result = isc_socket_bind(sock, &listener->address); - if (result != ISC_R_SUCCESS) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&listener->address, socktext, - sizeof(socktext)); - isc_socket_detach(&sock); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "failed to add lwres socket: %s: %s", - socktext, isc_result_totext(result)); - return (result); - } - listener->sock = sock; - return (ISC_R_SUCCESS); -} - -static void -listener_copysock(ns_lwreslistener_t *oldlistener, - ns_lwreslistener_t *newlistener) -{ - newlistener->address = oldlistener->address; - isc_socket_attach(oldlistener->sock, &newlistener->sock); -} - -static isc_result_t -listener_startclients(ns_lwreslistener_t *listener) { - ns_lwdclientmgr_t *cm; - unsigned int i; - isc_result_t result; - - /* - * Create the client managers. - */ - result = ISC_R_SUCCESS; - for (i = 0; i < NTASKS && result == ISC_R_SUCCESS; i++) - result = ns_lwdclientmgr_create(listener, NRECVS, - ns_g_taskmgr); - - /* - * Ensure that we have created at least one. - */ - if (ISC_LIST_EMPTY(listener->cmgrs)) - return (result); - - /* - * Walk the list of clients and start each one up. - */ - LOCK(&listener->lock); - cm = ISC_LIST_HEAD(listener->cmgrs); - while (cm != NULL) { - result = ns_lwdclient_startrecv(cm); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, - "could not start lwres " - "client handler: %s", - isc_result_totext(result)); - cm = ISC_LIST_NEXT(cm, link); - } - UNLOCK(&listener->lock); - - return (ISC_R_SUCCESS); -} - -static void -listener_shutdown(ns_lwreslistener_t *listener) { - ns_lwdclientmgr_t *cm; - - cm = ISC_LIST_HEAD(listener->cmgrs); - while (cm != NULL) { - isc_task_shutdown(cm->task); - cm = ISC_LIST_NEXT(cm, link); - } -} - -static isc_result_t -find_listener(isc_sockaddr_t *address, ns_lwreslistener_t **listenerp) { - ns_lwreslistener_t *listener; - - INSIST(listenerp != NULL && *listenerp == NULL); - - for (listener = ISC_LIST_HEAD(listeners); - listener != NULL; - listener = ISC_LIST_NEXT(listener, link)) - { - if (!isc_sockaddr_equal(address, &listener->address)) - continue; - *listenerp = listener; - return (ISC_R_SUCCESS); - } - return (ISC_R_NOTFOUND); -} - -void -ns_lwreslistener_unlinkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm) -{ - REQUIRE(VALID_LWRESLISTENER(listener)); - - LOCK(&listener->lock); - ISC_LIST_UNLINK(listener->cmgrs, cm, link); - UNLOCK(&listener->lock); -} - -void -ns_lwreslistener_linkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm) { - REQUIRE(VALID_LWRESLISTENER(listener)); - - /* - * This does no locking, since it's called early enough that locking - * isn't needed. - */ - ISC_LIST_APPEND(listener->cmgrs, cm, link); -} - -static isc_result_t -configure_listener(isc_sockaddr_t *address, ns_lwresd_t *lwresd, - isc_mem_t *mctx, ns_lwreslistenerlist_t *newlisteners) -{ - ns_lwreslistener_t *listener, *oldlistener = NULL; - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_result_t result; - - (void)find_listener(address, &oldlistener); - listener = NULL; - result = listener_create(mctx, lwresd, &listener); - if (result != ISC_R_SUCCESS) { - isc_sockaddr_format(address, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "lwres failed to configure %s: %s", - socktext, isc_result_totext(result)); - return (result); - } - - /* - * If there's already a listener, don't rebind the socket. - */ - if (oldlistener == NULL) { - result = listener_bind(listener, address); - if (result != ISC_R_SUCCESS) { - ns_lwreslistener_detach(&listener); - return (ISC_R_SUCCESS); - } - } else - listener_copysock(oldlistener, listener); - - result = listener_startclients(listener); - if (result != ISC_R_SUCCESS) { - isc_sockaddr_format(address, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "lwres: failed to start %s: %s", socktext, - isc_result_totext(result)); - ns_lwreslistener_detach(&listener); - return (ISC_R_SUCCESS); - } - - if (oldlistener != NULL) { - /* - * Remove the old listener from the old list and shut it down. - */ - ISC_LIST_UNLINK(listeners, oldlistener, link); - listener_shutdown(oldlistener); - ns_lwreslistener_detach(&oldlistener); - } else { - isc_sockaddr_format(address, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_NOTICE, - "lwres listening on %s", socktext); - } - - ISC_LIST_APPEND(*newlisteners, listener, link); - return (result); -} - -isc_result_t -ns_lwresd_configure(isc_mem_t *mctx, const cfg_obj_t *config) { - const cfg_obj_t *lwreslist = NULL; - const cfg_obj_t *lwres = NULL; - const cfg_obj_t *listenerslist = NULL; - const cfg_listelt_t *element = NULL; - ns_lwreslistener_t *listener; - ns_lwreslistenerlist_t newlisteners; - isc_result_t result; - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_t *addrs = NULL; - ns_lwresd_t *lwresd = NULL; - isc_uint32_t count = 0; - - REQUIRE(mctx != NULL); - REQUIRE(config != NULL); - - RUNTIME_CHECK(isc_once_do(&once, initialize_mutex) == ISC_R_SUCCESS); - - ISC_LIST_INIT(newlisteners); - - result = cfg_map_get(config, "lwres", &lwreslist); - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - LOCK(&listeners_lock); - /* - * Run through the new lwres address list, noting sockets that - * are already being listened on and moving them to the new list. - * - * Identifying duplicates addr/port combinations is left to either - * the underlying config code, or to the bind attempt getting an - * address-in-use error. - */ - for (element = cfg_list_first(lwreslist); - element != NULL; - element = cfg_list_next(element)) - { - in_port_t port; - - lwres = cfg_listelt_value(element); - CHECK(ns_lwdmanager_create(mctx, lwres, &lwresd)); - - port = lwresd_g_listenport; - if (port == 0) - port = LWRES_UDP_PORT; - - listenerslist = NULL; - (void)cfg_map_get(lwres, "listen-on", &listenerslist); - if (listenerslist == NULL) { - struct in_addr localhost; - isc_sockaddr_t address; - - localhost.s_addr = htonl(INADDR_LOOPBACK); - isc_sockaddr_fromin(&address, &localhost, port); - CHECK(configure_listener(&address, lwresd, mctx, - &newlisteners)); - } else { - isc_uint32_t i; - - CHECK(ns_config_getiplist(config, listenerslist, - port, mctx, &addrs, &count)); - for (i = 0; i < count; i++) - CHECK(configure_listener(&addrs[i], lwresd, - mctx, &newlisteners)); - ns_config_putiplist(mctx, &addrs, count); - } - ns_lwdmanager_detach(&lwresd); - } - - /* - * Shutdown everything on the listeners list, and remove them from - * the list. Then put all of the new listeners on it. - */ - - while (!ISC_LIST_EMPTY(listeners)) { - listener = ISC_LIST_HEAD(listeners); - ISC_LIST_UNLINK(listeners, listener, link); - - isc_sockaddr_format(&listener->address, - socktext, sizeof(socktext)); - - listener_shutdown(listener); - ns_lwreslistener_detach(&listener); - - isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_NOTICE, - "lwres no longer listening on %s", socktext); - } - - cleanup: - ISC_LIST_APPENDLIST(listeners, newlisteners, link); - - if (addrs != NULL) - ns_config_putiplist(mctx, &addrs, count); - - if (lwresd != NULL) - ns_lwdmanager_detach(&lwresd); - - UNLOCK(&listeners_lock); - - return (result); -} - -void -ns_lwresd_shutdown(void) { - ns_lwreslistener_t *listener; - - RUNTIME_CHECK(isc_once_do(&once, initialize_mutex) == ISC_R_SUCCESS); - - while (!ISC_LIST_EMPTY(listeners)) { - listener = ISC_LIST_HEAD(listeners); - ISC_LIST_UNLINK(listeners, listener, link); - ns_lwreslistener_detach(&listener); - } -} diff --git a/contrib/bind9/bin/named/lwresd.docbook b/contrib/bind9/bin/named/lwresd.docbook deleted file mode 100644 index 5b3143e..0000000 --- a/contrib/bind9/bin/named/lwresd.docbook +++ /dev/null @@ -1,372 +0,0 @@ -]> - - - - - - June 30, 2000 - - - - lwresd - 8 - BIND9 - - - - lwresd - lightweight resolver daemon - - - - - 2004 - 2005 - 2007 - Internet Systems Consortium, Inc. ("ISC") - - - 2000 - 2001 - Internet Software Consortium. - - - - - - lwresd - - - - - - - - - - - - - - - - - - - - - DESCRIPTION - - lwresd - is the daemon providing name lookup - services to clients that use the BIND 9 lightweight resolver - library. It is essentially a stripped-down, caching-only name - server that answers queries using the BIND 9 lightweight - resolver protocol rather than the DNS protocol. - - - lwresd - listens for resolver queries on a - UDP port on the IPv4 loopback interface, 127.0.0.1. This - means that lwresd can only be used by - processes running on the local machine. By default UDP port - number 921 is used for lightweight resolver requests and - responses. - - - Incoming lightweight resolver requests are decoded by the - server which then resolves them using the DNS protocol. When - the DNS lookup completes, lwresd encodes - the answers in the lightweight resolver format and returns - them to the client that made the request. - - - If /etc/resolv.conf contains any - entries, lwresd - sends recursive DNS queries to those servers. This is similar - to the use of forwarders in a caching name server. If no - entries are present, or if - forwarding fails, lwresd resolves the - queries autonomously starting at the root name servers, using - a built-in list of root server hints. - - - - - OPTIONS - - - - - -4 - - - Use IPv4 only even if the host machine is capable of IPv6. - and are mutually - exclusive. - - - - - - -6 - - - Use IPv6 only even if the host machine is capable of IPv4. - and are mutually - exclusive. - - - - - - - -c config-file - - - Use config-file as the - configuration file instead of the default, - /etc/lwresd.conf. - - -c can not be used with -C. - - - - - - -C config-file - - - Use config-file as the - configuration file instead of the default, - /etc/resolv.conf. - -C can not be used with -c. - - - - - - -d debug-level - - - Set the daemon's debug level to debug-level. - Debugging traces from lwresd become - more verbose as the debug level increases. - - - - - - -f - - - Run the server in the foreground (i.e. do not daemonize). - - - - - - -g - - - Run the server in the foreground and force all logging - to stderr. - - - - - - -i pid-file - - - Use pid-file as the - PID file instead of the default, - /var/run/lwresd.pid. - - - - - - -m flag - - - Turn on memory usage debugging flags. Possible flags are - usage, - trace, - record, - size, and - mctx. - These correspond to the ISC_MEM_DEBUGXXXX flags described in - <isc/mem.h>. - - - - - - -n #cpus - - - Create #cpus worker threads - to take advantage of multiple CPUs. If not specified, - lwresd will try to determine the - number of CPUs present and create one thread per CPU. - If it is unable to determine the number of CPUs, a - single worker thread will be created. - - - - - - -P port - - - Listen for lightweight resolver queries on port - port. If - not specified, the default is port 921. - - - - - - -p port - - - Send DNS lookups to port port. If not - specified, the default is port 53. This provides a - way of testing the lightweight resolver daemon with a - name server that listens for queries on a non-standard - port number. - - - - - - -s - - - Write memory usage statistics to stdout - on exit. - - - - This option is mainly of interest to BIND 9 developers - and may be removed or changed in a future release. - - - - - - - -t directory - - Chroot - to directory after - processing the command line arguments, but before - reading the configuration file. - - - - This option should be used in conjunction with the - option, as chrooting a process - running as root doesn't enhance security on most - systems; the way chroot(2) is - defined allows a process with root privileges to - escape a chroot jail. - - - - - - - -u user - - Setuid - to user after completing - privileged operations, such as creating sockets that - listen on privileged ports. - - - - - - -v - - - Report the version number and exit. - - - - - - - - - - FILES - - - - - /etc/resolv.conf - - - The default configuration file. - - - - - - /var/run/lwresd.pid - - - The default process-id file. - - - - - - - - - - SEE ALSO - - named8 - , - - lwres3 - , - - resolver5 - . - - - - - AUTHOR - Internet Systems Consortium - - - - diff --git a/contrib/bind9/bin/named/lwresd.html b/contrib/bind9/bin/named/lwresd.html deleted file mode 100644 index b59a7cc..0000000 --- a/contrib/bind9/bin/named/lwresd.html +++ /dev/null @@ -1,225 +0,0 @@ - - - - - -lwresd - - -
-
-
-

Name

-

lwresd — lightweight resolver daemon

-
-
-

Synopsis

-

lwresd [-c config-file] [-C config-file] [-d debug-level] [-f] [-g] [-i pid-file] [-m flag] [-n #cpus] [-P port] [-p port] [-s] [-t directory] [-u user] [-v] [-4] [-6]

-
-
-

DESCRIPTION

-

lwresd - is the daemon providing name lookup - services to clients that use the BIND 9 lightweight resolver - library. It is essentially a stripped-down, caching-only name - server that answers queries using the BIND 9 lightweight - resolver protocol rather than the DNS protocol. -

-

lwresd - listens for resolver queries on a - UDP port on the IPv4 loopback interface, 127.0.0.1. This - means that lwresd can only be used by - processes running on the local machine. By default UDP port - number 921 is used for lightweight resolver requests and - responses. -

-

- Incoming lightweight resolver requests are decoded by the - server which then resolves them using the DNS protocol. When - the DNS lookup completes, lwresd encodes - the answers in the lightweight resolver format and returns - them to the client that made the request. -

-

- If /etc/resolv.conf contains any - nameserver entries, lwresd - sends recursive DNS queries to those servers. This is similar - to the use of forwarders in a caching name server. If no - nameserver entries are present, or if - forwarding fails, lwresd resolves the - queries autonomously starting at the root name servers, using - a built-in list of root server hints. -

-
-
-

OPTIONS

-
-
-4
-

- Use IPv4 only even if the host machine is capable of IPv6. - -4 and -6 are mutually - exclusive. -

-
-6
-

- Use IPv6 only even if the host machine is capable of IPv4. - -4 and -6 are mutually - exclusive. -

-
-c config-file
-

- Use config-file as the - configuration file instead of the default, - /etc/lwresd.conf. - - <term>-c</term> can not be used with <term>-C</term>. -

-
-C config-file
-

- Use config-file as the - configuration file instead of the default, - /etc/resolv.conf. - <term>-C</term> can not be used with <term>-c</term>. -

-
-d debug-level
-

- Set the daemon's debug level to debug-level. - Debugging traces from lwresd become - more verbose as the debug level increases. -

-
-f
-

- Run the server in the foreground (i.e. do not daemonize). -

-
-g
-

- Run the server in the foreground and force all logging - to stderr. -

-
-i pid-file
-

- Use pid-file as the - PID file instead of the default, - /var/run/lwresd.pid. -

-
-m flag
-

- Turn on memory usage debugging flags. Possible flags are - usage, - trace, - record, - size, and - mctx. - These correspond to the ISC_MEM_DEBUGXXXX flags described in - <isc/mem.h>. -

-
-n #cpus
-

- Create #cpus worker threads - to take advantage of multiple CPUs. If not specified, - lwresd will try to determine the - number of CPUs present and create one thread per CPU. - If it is unable to determine the number of CPUs, a - single worker thread will be created. -

-
-P port
-

- Listen for lightweight resolver queries on port - port. If - not specified, the default is port 921. -

-
-p port
-

- Send DNS lookups to port port. If not - specified, the default is port 53. This provides a - way of testing the lightweight resolver daemon with a - name server that listens for queries on a non-standard - port number. -

-
-s
-
-

- Write memory usage statistics to stdout - on exit. -

-
-

Note

-

- This option is mainly of interest to BIND 9 developers - and may be removed or changed in a future release. -

-
-
-
-t directory
-
-

Chroot - to directory after - processing the command line arguments, but before - reading the configuration file. -

-
-

Warning

-

- This option should be used in conjunction with the - -u option, as chrooting a process - running as root doesn't enhance security on most - systems; the way chroot(2) is - defined allows a process with root privileges to - escape a chroot jail. -

-
-
-
-u user
-

Setuid - to user after completing - privileged operations, such as creating sockets that - listen on privileged ports. -

-
-v
-

- Report the version number and exit. -

-
-
-
-

FILES

-
-
/etc/resolv.conf
-

- The default configuration file. -

-
/var/run/lwresd.pid
-

- The default process-id file. -

-
-
-
-

SEE ALSO

-

named(8), - lwres(3), - resolver(5). -

-
-
-

AUTHOR

-

Internet Systems Consortium -

-
-
- diff --git a/contrib/bind9/bin/named/lwsearch.c b/contrib/bind9/bin/named/lwsearch.c deleted file mode 100644 index 4a61f96..0000000 --- a/contrib/bind9/bin/named/lwsearch.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: lwsearch.c,v 1.8.18.3 2005/07/12 01:22:17 marka Exp $ */ - -/*! \file */ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#define LWSEARCHLIST_MAGIC ISC_MAGIC('L', 'W', 'S', 'L') -#define VALID_LWSEARCHLIST(l) ISC_MAGIC_VALID(l, LWSEARCHLIST_MAGIC) - -isc_result_t -ns_lwsearchlist_create(isc_mem_t *mctx, ns_lwsearchlist_t **listp) { - ns_lwsearchlist_t *list; - isc_result_t result; - - REQUIRE(mctx != NULL); - REQUIRE(listp != NULL && *listp == NULL); - - list = isc_mem_get(mctx, sizeof(ns_lwsearchlist_t)); - if (list == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&list->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, list, sizeof(ns_lwsearchlist_t)); - return (result); - } - list->mctx = NULL; - isc_mem_attach(mctx, &list->mctx); - list->refs = 1; - ISC_LIST_INIT(list->names); - list->magic = LWSEARCHLIST_MAGIC; - - *listp = list; - return (ISC_R_SUCCESS); -} - -void -ns_lwsearchlist_attach(ns_lwsearchlist_t *source, ns_lwsearchlist_t **target) { - REQUIRE(VALID_LWSEARCHLIST(source)); - REQUIRE(target != NULL && *target == NULL); - - LOCK(&source->lock); - INSIST(source->refs > 0); - source->refs++; - INSIST(source->refs != 0); - UNLOCK(&source->lock); - - *target = source; -} - -void -ns_lwsearchlist_detach(ns_lwsearchlist_t **listp) { - ns_lwsearchlist_t *list; - isc_mem_t *mctx; - - REQUIRE(listp != NULL); - list = *listp; - REQUIRE(VALID_LWSEARCHLIST(list)); - - LOCK(&list->lock); - INSIST(list->refs > 0); - list->refs--; - UNLOCK(&list->lock); - - *listp = NULL; - if (list->refs != 0) - return; - - mctx = list->mctx; - while (!ISC_LIST_EMPTY(list->names)) { - dns_name_t *name = ISC_LIST_HEAD(list->names); - ISC_LIST_UNLINK(list->names, name, link); - dns_name_free(name, list->mctx); - isc_mem_put(list->mctx, name, sizeof(dns_name_t)); - } - list->magic = 0; - isc_mem_put(mctx, list, sizeof(ns_lwsearchlist_t)); - isc_mem_detach(&mctx); -} - -isc_result_t -ns_lwsearchlist_append(ns_lwsearchlist_t *list, dns_name_t *name) { - dns_name_t *newname; - isc_result_t result; - - REQUIRE(VALID_LWSEARCHLIST(list)); - REQUIRE(name != NULL); - - newname = isc_mem_get(list->mctx, sizeof(dns_name_t)); - if (newname == NULL) - return (ISC_R_NOMEMORY); - dns_name_init(newname, NULL); - result = dns_name_dup(name, list->mctx, newname); - if (result != ISC_R_SUCCESS) { - isc_mem_put(list->mctx, newname, sizeof(dns_name_t)); - return (result); - } - ISC_LINK_INIT(newname, link); - ISC_LIST_APPEND(list->names, newname, link); - return (ISC_R_SUCCESS); -} - -void -ns_lwsearchctx_init(ns_lwsearchctx_t *sctx, ns_lwsearchlist_t *list, - dns_name_t *name, unsigned int ndots) -{ - INSIST(sctx != NULL); - sctx->relname = name; - sctx->searchname = NULL; - sctx->doneexact = ISC_FALSE; - sctx->exactfirst = ISC_FALSE; - sctx->ndots = ndots; - if (dns_name_isabsolute(name) || list == NULL) { - sctx->list = NULL; - return; - } - sctx->list = list; - sctx->searchname = ISC_LIST_HEAD(sctx->list->names); - if (dns_name_countlabels(name) > ndots) - sctx->exactfirst = ISC_TRUE; -} - -void -ns_lwsearchctx_first(ns_lwsearchctx_t *sctx) { - REQUIRE(sctx != NULL); - UNUSED(sctx); -} - -isc_result_t -ns_lwsearchctx_next(ns_lwsearchctx_t *sctx) { - REQUIRE(sctx != NULL); - - if (sctx->list == NULL) - return (ISC_R_NOMORE); - - if (sctx->searchname == NULL) { - INSIST (!sctx->exactfirst || sctx->doneexact); - if (sctx->exactfirst || sctx->doneexact) - return (ISC_R_NOMORE); - sctx->doneexact = ISC_TRUE; - } else { - if (sctx->exactfirst && !sctx->doneexact) - sctx->doneexact = ISC_TRUE; - else { - sctx->searchname = ISC_LIST_NEXT(sctx->searchname, - link); - if (sctx->searchname == NULL && sctx->doneexact) - return (ISC_R_NOMORE); - } - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_lwsearchctx_current(ns_lwsearchctx_t *sctx, dns_name_t *absname) { - dns_name_t *tname; - isc_boolean_t useexact = ISC_FALSE; - - REQUIRE(sctx != NULL); - - if (sctx->list == NULL || - sctx->searchname == NULL || - (sctx->exactfirst && !sctx->doneexact)) - useexact = ISC_TRUE; - - if (useexact) { - if (dns_name_isabsolute(sctx->relname)) - tname = NULL; - else - tname = dns_rootname; - } else - tname = sctx->searchname; - - return (dns_name_concatenate(sctx->relname, tname, absname, NULL)); -} diff --git a/contrib/bind9/bin/named/main.c b/contrib/bind9/bin/named/main.c deleted file mode 100644 index 6b9b67e..0000000 --- a/contrib/bind9/bin/named/main.c +++ /dev/null @@ -1,926 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: main.c,v 1.136.18.17 2006/11/10 18:51:14 marka Exp $ */ - -/*! \file */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include - -/* - * Defining NS_MAIN provides storage declarations (rather than extern) - * for variables in named/globals.h. - */ -#define NS_MAIN 1 - -#include -#include -#include /* Explicit, though named/log.h includes it. */ -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LIBSCF -#include -#endif - -/* - * Include header files for database drivers here. - */ -/* #include "xxdb.h" */ - -/* - * Include DLZ drivers if appropriate. - */ -#ifdef DLZ -#include -#endif - -static isc_boolean_t want_stats = ISC_FALSE; -static char program_name[ISC_DIR_NAMEMAX] = "named"; -static char absolute_conffile[ISC_DIR_PATHMAX]; -static char saved_command_line[512]; -static char version[512]; - -void -ns_main_earlywarning(const char *format, ...) { - va_list args; - - va_start(args, format); - if (ns_g_lctx != NULL) { - isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_WARNING, - format, args); - } else { - fprintf(stderr, "%s: ", program_name); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); - } - va_end(args); -} - -void -ns_main_earlyfatal(const char *format, ...) { - va_list args; - - va_start(args, format); - if (ns_g_lctx != NULL) { - isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - format, args); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "exiting (due to early fatal error)"); - } else { - fprintf(stderr, "%s: ", program_name); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); - } - va_end(args); - - exit(1); -} - -static void -assertion_failed(const char *file, int line, isc_assertiontype_t type, - const char *cond) -{ - /* - * Handle assertion failures. - */ - - if (ns_g_lctx != NULL) { - /* - * Reset the assetion callback in case it is the log - * routines causing the assertion. - */ - isc_assertion_setcallback(NULL); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "%s:%d: %s(%s) failed", file, line, - isc_assertion_typetotext(type), cond); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "exiting (due to assertion failure)"); - } else { - fprintf(stderr, "%s:%d: %s(%s) failed\n", - file, line, isc_assertion_typetotext(type), cond); - fflush(stderr); - } - - if (ns_g_coreok) - abort(); - exit(1); -} - -static void -library_fatal_error(const char *file, int line, const char *format, - va_list args) ISC_FORMAT_PRINTF(3, 0); - -static void -library_fatal_error(const char *file, int line, const char *format, - va_list args) -{ - /* - * Handle isc_error_fatal() calls from our libraries. - */ - - if (ns_g_lctx != NULL) { - /* - * Reset the error callback in case it is the log - * routines causing the assertion. - */ - isc_error_setfatal(NULL); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "%s:%d: fatal error:", file, line); - isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - format, args); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "exiting (due to fatal error in library)"); - } else { - fprintf(stderr, "%s:%d: fatal error: ", file, line); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); - } - - if (ns_g_coreok) - abort(); - exit(1); -} - -static void -library_unexpected_error(const char *file, int line, const char *format, - va_list args) ISC_FORMAT_PRINTF(3, 0); - -static void -library_unexpected_error(const char *file, int line, const char *format, - va_list args) -{ - /* - * Handle isc_error_unexpected() calls from our libraries. - */ - - if (ns_g_lctx != NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_ERROR, - "%s:%d: unexpected error:", file, line); - isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_ERROR, - format, args); - } else { - fprintf(stderr, "%s:%d: fatal error: ", file, line); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); - } -} - -static void -lwresd_usage(void) { - fprintf(stderr, - "usage: lwresd [-4|-6] [-c conffile | -C resolvconffile] " - "[-d debuglevel]\n" - " [-f|-g] [-n number_of_cpus] [-p port] " - "[-P listen-port] [-s]\n" - " [-t chrootdir] [-u username] [-i pidfile]\n" - " [-m {usage|trace|record|size|mctx}]\n"); -} - -static void -usage(void) { - if (ns_g_lwresdonly) { - lwresd_usage(); - return; - } - fprintf(stderr, - "usage: named [-4|-6] [-c conffile] [-d debuglevel] " - "[-f|-g] [-n number_of_cpus]\n" - " [-p port] [-s] [-t chrootdir] [-u username]\n" - " [-m {usage|trace|record|size|mctx}]\n"); -} - -static void -save_command_line(int argc, char *argv[]) { - int i; - char *src; - char *dst; - char *eob; - const char truncated[] = "..."; - isc_boolean_t quoted = ISC_FALSE; - - dst = saved_command_line; - eob = saved_command_line + sizeof(saved_command_line); - - for (i = 1; i < argc && dst < eob; i++) { - *dst++ = ' '; - - src = argv[i]; - while (*src != '\0' && dst < eob) { - /* - * This won't perfectly produce a shell-independent - * pastable command line in all circumstances, but - * comes close, and for practical purposes will - * nearly always be fine. - */ - if (quoted || isalnum(*src & 0xff) || - *src == '-' || *src == '_' || - *src == '.' || *src == '/') { - *dst++ = *src++; - quoted = ISC_FALSE; - } else { - *dst++ = '\\'; - quoted = ISC_TRUE; - } - } - } - - INSIST(sizeof(saved_command_line) >= sizeof(truncated)); - - if (dst == eob) - strcpy(eob - sizeof(truncated), truncated); - else - *dst = '\0'; -} - -static int -parse_int(char *arg, const char *desc) { - char *endp; - int tmp; - long int ltmp; - - ltmp = strtol(arg, &endp, 10); - tmp = (int) ltmp; - if (*endp != '\0') - ns_main_earlyfatal("%s '%s' must be numeric", desc, arg); - if (tmp < 0 || tmp != ltmp) - ns_main_earlyfatal("%s '%s' out of range", desc, arg); - return (tmp); -} - -static struct flag_def { - const char *name; - unsigned int value; -} mem_debug_flags[] = { - { "trace", ISC_MEM_DEBUGTRACE }, - { "record", ISC_MEM_DEBUGRECORD }, - { "usage", ISC_MEM_DEBUGUSAGE }, - { "size", ISC_MEM_DEBUGSIZE }, - { "mctx", ISC_MEM_DEBUGCTX }, - { NULL, 0 } -}; - -static void -set_flags(const char *arg, struct flag_def *defs, unsigned int *ret) { - for (;;) { - const struct flag_def *def; - const char *end = strchr(arg, ','); - int arglen; - if (end == NULL) - end = arg + strlen(arg); - arglen = end - arg; - for (def = defs; def->name != NULL; def++) { - if (arglen == (int)strlen(def->name) && - memcmp(arg, def->name, arglen) == 0) { - *ret |= def->value; - goto found; - } - } - ns_main_earlyfatal("unrecognized flag '%.*s'", arglen, arg); - found: - if (*end == '\0') - break; - arg = end + 1; - } -} - -static void -parse_command_line(int argc, char *argv[]) { - int ch; - int port; - isc_boolean_t disable6 = ISC_FALSE; - isc_boolean_t disable4 = ISC_FALSE; - - save_command_line(argc, argv); - - isc_commandline_errprint = ISC_FALSE; - while ((ch = isc_commandline_parse(argc, argv, - "46c:C:d:fgi:lm:n:N:p:P:st:u:vx:")) != -1) { - switch (ch) { - case '4': - if (disable4) - ns_main_earlyfatal("cannot specify -4 and -6"); - if (isc_net_probeipv4() != ISC_R_SUCCESS) - ns_main_earlyfatal("IPv4 not supported by OS"); - isc_net_disableipv6(); - disable6 = ISC_TRUE; - break; - case '6': - if (disable6) - ns_main_earlyfatal("cannot specify -4 and -6"); - if (isc_net_probeipv6() != ISC_R_SUCCESS) - ns_main_earlyfatal("IPv6 not supported by OS"); - isc_net_disableipv4(); - disable4 = ISC_TRUE; - break; - case 'c': - ns_g_conffile = isc_commandline_argument; - lwresd_g_conffile = isc_commandline_argument; - if (lwresd_g_useresolvconf) - ns_main_earlyfatal("cannot specify -c and -C"); - ns_g_conffileset = ISC_TRUE; - break; - case 'C': - lwresd_g_resolvconffile = isc_commandline_argument; - if (ns_g_conffileset) - ns_main_earlyfatal("cannot specify -c and -C"); - lwresd_g_useresolvconf = ISC_TRUE; - break; - case 'd': - ns_g_debuglevel = parse_int(isc_commandline_argument, - "debug level"); - break; - case 'f': - ns_g_foreground = ISC_TRUE; - break; - case 'g': - ns_g_foreground = ISC_TRUE; - ns_g_logstderr = ISC_TRUE; - break; - /* XXXBEW -i should be removed */ - case 'i': - lwresd_g_defaultpidfile = isc_commandline_argument; - break; - case 'l': - ns_g_lwresdonly = ISC_TRUE; - break; - case 'm': - set_flags(isc_commandline_argument, mem_debug_flags, - &isc_mem_debugging); - break; - case 'N': /* Deprecated. */ - case 'n': - ns_g_cpus = parse_int(isc_commandline_argument, - "number of cpus"); - if (ns_g_cpus == 0) - ns_g_cpus = 1; - break; - case 'p': - port = parse_int(isc_commandline_argument, "port"); - if (port < 1 || port > 65535) - ns_main_earlyfatal("port '%s' out of range", - isc_commandline_argument); - ns_g_port = port; - break; - /* XXXBEW Should -P be removed? */ - case 'P': - port = parse_int(isc_commandline_argument, "port"); - if (port < 1 || port > 65535) - ns_main_earlyfatal("port '%s' out of range", - isc_commandline_argument); - lwresd_g_listenport = port; - break; - case 's': - /* XXXRTH temporary syntax */ - want_stats = ISC_TRUE; - break; - case 't': - /* XXXJAB should we make a copy? */ - ns_g_chrootdir = isc_commandline_argument; - break; - case 'u': - ns_g_username = isc_commandline_argument; - break; - case 'v': - printf("BIND %s\n", ns_g_version); - exit(0); - case '?': - usage(); - ns_main_earlyfatal("unknown option '-%c'", - isc_commandline_option); - default: - ns_main_earlyfatal("parsing options returned %d", ch); - } - } - - argc -= isc_commandline_index; - argv += isc_commandline_index; - - if (argc > 0) { - usage(); - ns_main_earlyfatal("extra command line arguments"); - } -} - -static isc_result_t -create_managers(void) { - isc_result_t result; -#ifdef ISC_PLATFORM_USETHREADS - unsigned int cpus_detected; -#endif - -#ifdef ISC_PLATFORM_USETHREADS - cpus_detected = isc_os_ncpus(); - if (ns_g_cpus == 0) - ns_g_cpus = cpus_detected; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "found %u CPU%s, using %u worker thread%s", - cpus_detected, cpus_detected == 1 ? "" : "s", - ns_g_cpus, ns_g_cpus == 1 ? "" : "s"); -#else - ns_g_cpus = 1; -#endif - result = isc_taskmgr_create(ns_g_mctx, ns_g_cpus, 0, &ns_g_taskmgr); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_taskmgr_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - result = isc_timermgr_create(ns_g_mctx, &ns_g_timermgr); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_timermgr_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - result = isc_socketmgr_create(ns_g_mctx, &ns_g_socketmgr); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socketmgr_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - result = isc_entropy_create(ns_g_mctx, &ns_g_entropy); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_entropy_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - result = isc_hash_create(ns_g_mctx, ns_g_entropy, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_hash_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - return (ISC_R_SUCCESS); -} - -static void -destroy_managers(void) { - ns_lwresd_shutdown(); - - isc_entropy_detach(&ns_g_entropy); - if (ns_g_fallbackentropy != NULL) - isc_entropy_detach(&ns_g_fallbackentropy); - - /* - * isc_taskmgr_destroy() will block until all tasks have exited, - */ - isc_taskmgr_destroy(&ns_g_taskmgr); - isc_timermgr_destroy(&ns_g_timermgr); - isc_socketmgr_destroy(&ns_g_socketmgr); - - /* - * isc_hash_destroy() cannot be called as long as a resolver may be - * running. Calling this after isc_taskmgr_destroy() ensures the - * call is safe. - */ - isc_hash_destroy(); -} - -static void -setup(void) { - isc_result_t result; -#ifdef HAVE_LIBSCF - char *instance = NULL; -#endif - - /* - * Get the user and group information before changing the root - * directory, so the administrator does not need to keep a copy - * of the user and group databases in the chroot'ed environment. - */ - ns_os_inituserinfo(ns_g_username); - - /* - * Initialize time conversion information - */ - ns_os_tzset(); - - ns_os_opendevnull(); - -#ifdef HAVE_LIBSCF - /* Check if named is under smf control, before chroot. */ - result = ns_smf_get_instance(&instance, 0, ns_g_mctx); - /* We don't care about instance, just check if we got one. */ - if (result == ISC_R_SUCCESS) - ns_smf_got_instance = 1; - else - ns_smf_got_instance = 0; - if (instance != NULL) - isc_mem_free(ns_g_mctx, instance); -#endif /* HAVE_LIBSCF */ - -#ifdef PATH_RANDOMDEV - /* - * Initialize system's random device as fallback entropy source - * if running chroot'ed. - */ - if (ns_g_chrootdir != NULL) { - result = isc_entropy_create(ns_g_mctx, &ns_g_fallbackentropy); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("isc_entropy_create() failed: %s", - isc_result_totext(result)); - - result = isc_entropy_createfilesource(ns_g_fallbackentropy, - PATH_RANDOMDEV); - if (result != ISC_R_SUCCESS) { - ns_main_earlywarning("could not open pre-chroot " - "entropy source %s: %s", - PATH_RANDOMDEV, - isc_result_totext(result)); - isc_entropy_detach(&ns_g_fallbackentropy); - } - } -#endif - - ns_os_chroot(ns_g_chrootdir); - - /* - * For operating systems which have a capability mechanism, now - * is the time to switch to minimal privs and change our user id. - * On traditional UNIX systems, this call will be a no-op, and we - * will change the user ID after reading the config file the first - * time. (We need to read the config file to know which possibly - * privileged ports to bind() to.) - */ - ns_os_minprivs(); - - result = ns_log_init(ISC_TF(ns_g_username != NULL)); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("ns_log_init() failed: %s", - isc_result_totext(result)); - - /* - * Now is the time to daemonize (if we're not running in the - * foreground). We waited until now because we wanted to get - * a valid logging context setup. We cannot daemonize any later, - * because calling create_managers() will create threads, which - * would be lost after fork(). - */ - if (!ns_g_foreground) - ns_os_daemonize(); - - /* - * We call isc_app_start() here as some versions of FreeBSD's fork() - * destroys all the signal handling it sets up. - */ - result = isc_app_start(); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("isc_app_start() failed: %s", - isc_result_totext(result)); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "starting BIND %s%s", ns_g_version, - saved_command_line); - - /* - * Get the initial resource limits. - */ - (void)isc_resource_getlimit(isc_resource_stacksize, - &ns_g_initstacksize); - (void)isc_resource_getlimit(isc_resource_datasize, - &ns_g_initdatasize); - (void)isc_resource_getlimit(isc_resource_coresize, - &ns_g_initcoresize); - (void)isc_resource_getlimit(isc_resource_openfiles, - &ns_g_initopenfiles); - - /* - * If the named configuration filename is relative, prepend the current - * directory's name before possibly changing to another directory. - */ - if (! isc_file_isabsolute(ns_g_conffile)) { - result = isc_file_absolutepath(ns_g_conffile, - absolute_conffile, - sizeof(absolute_conffile)); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("could not construct absolute path of " - "configuration file: %s", - isc_result_totext(result)); - ns_g_conffile = absolute_conffile; - } - - result = create_managers(); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("create_managers() failed: %s", - isc_result_totext(result)); - - ns_builtin_init(); - - /* - * Add calls to register sdb drivers here. - */ - /* xxdb_init(); */ - -#ifdef DLZ - /* - * Registyer any DLZ drivers. - */ - result = dlz_drivers_init(); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("dlz_drivers_init() failed: %s", - isc_result_totext(result)); -#endif - - ns_server_create(ns_g_mctx, &ns_g_server); -} - -static void -cleanup(void) { - destroy_managers(); - - ns_server_destroy(&ns_g_server); - - ns_builtin_deinit(); - - /* - * Add calls to unregister sdb drivers here. - */ - /* xxdb_clear(); */ - -#ifdef DLZ - /* - * Unregister any DLZ drivers. - */ - dlz_drivers_clear(); -#endif - - dns_name_destroy(); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "exiting"); - ns_log_shutdown(); -} - -static char *memstats = NULL; - -void -ns_main_setmemstats(const char *filename) { - /* - * Caller has to ensure locking. - */ - - if (memstats != NULL) { - free(memstats); - memstats = NULL; - } - if (filename == NULL) - return; - memstats = malloc(strlen(filename) + 1); - if (memstats) - strcpy(memstats, filename); -} - -#ifdef HAVE_LIBSCF -/* - * Get FMRI for the named process. - */ -isc_result_t -ns_smf_get_instance(char **ins_name, int debug, isc_mem_t *mctx) { - scf_handle_t *h = NULL; - int namelen; - char *instance; - - REQUIRE(ins_name != NULL && *ins_name == NULL); - - if ((h = scf_handle_create(SCF_VERSION)) == NULL) { - if (debug) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "scf_handle_create() failed: %s", - scf_strerror(scf_error())); - return (ISC_R_FAILURE); - } - - if (scf_handle_bind(h) == -1) { - if (debug) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "scf_handle_bind() failed: %s", - scf_strerror(scf_error())); - scf_handle_destroy(h); - return (ISC_R_FAILURE); - } - - if ((namelen = scf_myname(h, NULL, 0)) == -1) { - if (debug) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "scf_myname() failed: %s", - scf_strerror(scf_error())); - scf_handle_destroy(h); - return (ISC_R_FAILURE); - } - - if ((instance = isc_mem_allocate(mctx, namelen + 1)) == NULL) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "ns_smf_get_instance memory " - "allocation failed: %s", - isc_result_totext(ISC_R_NOMEMORY)); - scf_handle_destroy(h); - return (ISC_R_FAILURE); - } - - if (scf_myname(h, instance, namelen + 1) == -1) { - if (debug) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "scf_myname() failed: %s", - scf_strerror(scf_error())); - scf_handle_destroy(h); - isc_mem_free(mctx, instance); - return (ISC_R_FAILURE); - } - - scf_handle_destroy(h); - *ins_name = instance; - return (ISC_R_SUCCESS); -} -#endif /* HAVE_LIBSCF */ - -int -main(int argc, char *argv[]) { - isc_result_t result; -#ifdef HAVE_LIBSCF - char *instance = NULL; -#endif - - /* - * Record version in core image. - * strings named.core | grep "named version:" - */ - strlcat(version, -#ifdef __DATE__ - "named version: BIND " VERSION " (" __DATE__ ")", -#else - "named version: BIND " VERSION, -#endif - sizeof(version)); - result = isc_file_progname(*argv, program_name, sizeof(program_name)); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("program name too long"); - - if (strcmp(program_name, "lwresd") == 0) - ns_g_lwresdonly = ISC_TRUE; - - isc_assertion_setcallback(assertion_failed); - isc_error_setfatal(library_fatal_error); - isc_error_setunexpected(library_unexpected_error); - - ns_os_init(program_name); - - dns_result_register(); - dst_result_register(); - isccc_result_register(); - - parse_command_line(argc, argv); - - /* - * Warn about common configuration error. - */ - if (ns_g_chrootdir != NULL) { - int len = strlen(ns_g_chrootdir); - if (strncmp(ns_g_chrootdir, ns_g_conffile, len) == 0 && - (ns_g_conffile[len] == '/' || ns_g_conffile[len] == '\\')) - ns_main_earlywarning("config filename (-c %s) contains " - "chroot path (-t %s)", - ns_g_conffile, ns_g_chrootdir); - } - - result = isc_mem_create(0, 0, &ns_g_mctx); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("isc_mem_create() failed: %s", - isc_result_totext(result)); - - setup(); - - /* - * Start things running and then wait for a shutdown request - * or reload. - */ - do { - result = isc_app_run(); - - if (result == ISC_R_RELOAD) { - ns_server_reloadwanted(ns_g_server); - } else if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_run(): %s", - isc_result_totext(result)); - /* - * Force exit. - */ - result = ISC_R_SUCCESS; - } - } while (result != ISC_R_SUCCESS); - -#ifdef HAVE_LIBSCF - if (ns_smf_want_disable == 1) { - result = ns_smf_get_instance(&instance, 1, ns_g_mctx); - if (result == ISC_R_SUCCESS && instance != NULL) { - if (smf_disable_instance(instance, 0) != 0) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "smf_disable_instance() " - "failed for %s : %s", - instance, - scf_strerror(scf_error())); - } - if (instance != NULL) - isc_mem_free(ns_g_mctx, instance); - } -#endif /* HAVE_LIBSCF */ - - cleanup(); - - if (want_stats) { - isc_mem_stats(ns_g_mctx, stdout); - isc_mutex_stats(stdout); - } - if (memstats != NULL) { - FILE *fp = NULL; - result = isc_stdio_open(memstats, "w", &fp); - if (result == ISC_R_SUCCESS) { - isc_mem_stats(ns_g_mctx, fp); - isc_mutex_stats(fp); - isc_stdio_close(fp); - } - } - isc_mem_destroy(&ns_g_mctx); - isc_mem_checkdestroyed(stderr); - - ns_main_setmemstats(NULL); - - isc_app_finish(); - - ns_os_closedevnull(); - - ns_os_shutdown(); - - return (0); -} diff --git a/contrib/bind9/bin/named/named.8 b/contrib/bind9/bin/named/named.8 deleted file mode 100644 index f5e8230..0000000 --- a/contrib/bind9/bin/named/named.8 +++ /dev/null @@ -1,236 +0,0 @@ -.\" Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") -.\" Copyright (C) 2000, 2001, 2003 Internet Software Consortium. -.\" -.\" Permission to use, copy, modify, and 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: named.8,v 1.20.18.15 2007/06/20 02:26:58 marka Exp $ -.\" -.hy 0 -.ad l -.\" Title: named -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.71.1 -.\" Date: June 30, 2000 -.\" Manual: BIND9 -.\" Source: BIND9 -.\" -.TH "NAMED" "8" "June 30, 2000" "BIND9" "BIND9" -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.SH "NAME" -named \- Internet domain name server -.SH "SYNOPSIS" -.HP 6 -\fBnamed\fR [\fB\-4\fR] [\fB\-6\fR] [\fB\-c\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-d\ \fR\fB\fIdebug\-level\fR\fR] [\fB\-f\fR] [\fB\-g\fR] [\fB\-m\ \fR\fB\fIflag\fR\fR] [\fB\-n\ \fR\fB\fI#cpus\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-s\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-x\ \fR\fB\fIcache\-file\fR\fR] -.SH "DESCRIPTION" -.PP -\fBnamed\fR -is a Domain Name System (DNS) server, part of the BIND 9 distribution from ISC. For more information on the DNS, see RFCs 1033, 1034, and 1035. -.PP -When invoked without arguments, -\fBnamed\fR -will read the default configuration file -\fI/etc/named.conf\fR, read any initial data, and listen for queries. -.SH "OPTIONS" -.PP -\-4 -.RS 4 -Use IPv4 only even if the host machine is capable of IPv6. -\fB\-4\fR -and -\fB\-6\fR -are mutually exclusive. -.RE -.PP -\-6 -.RS 4 -Use IPv6 only even if the host machine is capable of IPv4. -\fB\-4\fR -and -\fB\-6\fR -are mutually exclusive. -.RE -.PP -\-c \fIconfig\-file\fR -.RS 4 -Use -\fIconfig\-file\fR -as the configuration file instead of the default, -\fI/etc/named.conf\fR. To ensure that reloading the configuration file continues to work after the server has changed its working directory due to to a possible -\fBdirectory\fR -option in the configuration file, -\fIconfig\-file\fR -should be an absolute pathname. -.RE -.PP -\-d \fIdebug\-level\fR -.RS 4 -Set the daemon's debug level to -\fIdebug\-level\fR. Debugging traces from -\fBnamed\fR -become more verbose as the debug level increases. -.RE -.PP -\-f -.RS 4 -Run the server in the foreground (i.e. do not daemonize). -.RE -.PP -\-g -.RS 4 -Run the server in the foreground and force all logging to -\fIstderr\fR. -.RE -.PP -\-m \fIflag\fR -.RS 4 -Turn on memory usage debugging flags. Possible flags are -\fIusage\fR, -\fItrace\fR, -\fIrecord\fR, -\fIsize\fR, and -\fImctx\fR. These correspond to the ISC_MEM_DEBUGXXXX flags described in -\fI\fR. -.RE -.PP -\-n \fI#cpus\fR -.RS 4 -Create -\fI#cpus\fR -worker threads to take advantage of multiple CPUs. If not specified, -\fBnamed\fR -will try to determine the number of CPUs present and create one thread per CPU. If it is unable to determine the number of CPUs, a single worker thread will be created. -.RE -.PP -\-p \fIport\fR -.RS 4 -Listen for queries on port -\fIport\fR. If not specified, the default is port 53. -.RE -.PP -\-s -.RS 4 -Write memory usage statistics to -\fIstdout\fR -on exit. -.RS -.B "Note:" -This option is mainly of interest to BIND 9 developers and may be removed or changed in a future release. -.RE -.RE -.PP -\-t \fIdirectory\fR -.RS 4 -Chroot to -\fIdirectory\fR -after processing the command line arguments, but before reading the configuration file. -.RS -.B "Warning:" -This option should be used in conjunction with the -\fB\-u\fR -option, as chrooting a process running as root doesn't enhance security on most systems; the way -\fBchroot(2)\fR -is defined allows a process with root privileges to escape a chroot jail. -.RE -.RE -.PP -\-u \fIuser\fR -.RS 4 -Setuid to -\fIuser\fR -after completing privileged operations, such as creating sockets that listen on privileged ports. -.RS -.B "Note:" -On Linux, -\fBnamed\fR -uses the kernel's capability mechanism to drop all root privileges except the ability to -\fBbind(2)\fR -to a privileged port and set process resource limits. Unfortunately, this means that the -\fB\-u\fR -option only works when -\fBnamed\fR -is run on kernel 2.2.18 or later, or kernel 2.3.99\-pre3 or later, since previous kernels did not allow privileges to be retained after -\fBsetuid(2)\fR. -.RE -.RE -.PP -\-v -.RS 4 -Report the version number and exit. -.RE -.PP -\-x \fIcache\-file\fR -.RS 4 -Load data from -\fIcache\-file\fR -into the cache of the default view. -.RS -.B "Warning:" -This option must not be used. It is only of interest to BIND 9 developers and may be removed or changed in a future release. -.RE -.RE -.SH "SIGNALS" -.PP -In routine operation, signals should not be used to control the nameserver; -\fBrndc\fR -should be used instead. -.PP -SIGHUP -.RS 4 -Force a reload of the server. -.RE -.PP -SIGINT, SIGTERM -.RS 4 -Shut down the server. -.RE -.PP -The result of sending any other signals to the server is undefined. -.SH "CONFIGURATION" -.PP -The -\fBnamed\fR -configuration file is too complex to describe in detail here. A complete description is provided in the -BIND 9 Administrator Reference Manual. -.SH "FILES" -.PP -\fI/etc/named.conf\fR -.RS 4 -The default configuration file. -.RE -.PP -\fI/var/run/named.pid\fR -.RS 4 -The default process\-id file. -.RE -.SH "SEE ALSO" -.PP -RFC 1033, -RFC 1034, -RFC 1035, -\fBnamed\-checkconf\fR(8), -\fBnamed\-checkzone\fR(8), -\fBrndc\fR(8), -\fBlwresd\fR(8), -\fBnamed.conf\fR(5), -BIND 9 Administrator Reference Manual. -.SH "AUTHOR" -.PP -Internet Systems Consortium -.SH "COPYRIGHT" -Copyright \(co 2004\-2007 Internet Systems Consortium, Inc. ("ISC") -.br -Copyright \(co 2000, 2001, 2003 Internet Software Consortium. -.br diff --git a/contrib/bind9/bin/named/named.conf.5 b/contrib/bind9/bin/named/named.conf.5 deleted file mode 100644 index 00c92a6..0000000 --- a/contrib/bind9/bin/named/named.conf.5 +++ /dev/null @@ -1,520 +0,0 @@ -.\" Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") -.\" -.\" Permission to use, copy, modify, and 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: named.conf.5,v 1.1.2.26 2007/08/19 23:26:13 marka Exp $ -.\" -.hy 0 -.ad l -.\" Title: \fInamed.conf\fR -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.71.1 -.\" Date: Aug 13, 2004 -.\" Manual: BIND9 -.\" Source: BIND9 -.\" -.TH "\fINAMED.CONF\fR" "5" "Aug 13, 2004" "BIND9" "BIND9" -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.SH "NAME" -named.conf \- configuration file for named -.SH "SYNOPSIS" -.HP 11 -\fBnamed.conf\fR -.SH "DESCRIPTION" -.PP -\fInamed.conf\fR -is the configuration file for -\fBnamed\fR. Statements are enclosed in braces and terminated with a semi\-colon. Clauses in the statements are also semi\-colon terminated. The usual comment styles are supported: -.PP -C style: /* */ -.PP -C++ style: // to end of line -.PP -Unix style: # to end of line -.SH "ACL" -.sp -.RS 4 -.nf -acl \fIstring\fR { \fIaddress_match_element\fR; ... }; -.fi -.RE -.SH "KEY" -.sp -.RS 4 -.nf -key \fIdomain_name\fR { - algorithm \fIstring\fR; - secret \fIstring\fR; -}; -.fi -.RE -.SH "MASTERS" -.sp -.RS 4 -.nf -masters \fIstring\fR [ port \fIinteger\fR ] { - ( \fImasters\fR | \fIipv4_address\fR [port \fIinteger\fR] | - \fIipv6_address\fR [port \fIinteger\fR] ) [ key \fIstring\fR ]; ... -}; -.fi -.RE -.SH "SERVER" -.sp -.RS 4 -.nf -server ( \fIipv4_address\fR\fI[/prefixlen]\fR | \fIipv6_address\fR\fI[/prefixlen]\fR ) { - bogus \fIboolean\fR; - edns \fIboolean\fR; - edns\-udp\-size \fIinteger\fR; - max\-udp\-size \fIinteger\fR; - provide\-ixfr \fIboolean\fR; - request\-ixfr \fIboolean\fR; - keys \fIserver_key\fR; - transfers \fIinteger\fR; - transfer\-format ( many\-answers | one\-answer ); - transfer\-source ( \fIipv4_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - support\-ixfr \fIboolean\fR; // obsolete -}; -.fi -.RE -.SH "TRUSTED\-KEYS" -.sp -.RS 4 -.nf -trusted\-keys { - \fIdomain_name\fR \fIflags\fR \fIprotocol\fR \fIalgorithm\fR \fIkey\fR; ... -}; -.fi -.RE -.SH "CONTROLS" -.sp -.RS 4 -.nf -controls { - inet ( \fIipv4_address\fR | \fIipv6_address\fR | * ) - [ port ( \fIinteger\fR | * ) ] - allow { \fIaddress_match_element\fR; ... } - [ keys { \fIstring\fR; ... } ]; - unix \fIunsupported\fR; // not implemented -}; -.fi -.RE -.SH "LOGGING" -.sp -.RS 4 -.nf -logging { - channel \fIstring\fR { - file \fIlog_file\fR; - syslog \fIoptional_facility\fR; - null; - stderr; - severity \fIlog_severity\fR; - print\-time \fIboolean\fR; - print\-severity \fIboolean\fR; - print\-category \fIboolean\fR; - }; - category \fIstring\fR { \fIstring\fR; ... }; -}; -.fi -.RE -.SH "LWRES" -.sp -.RS 4 -.nf -lwres { - listen\-on [ port \fIinteger\fR ] { - ( \fIipv4_address\fR | \fIipv6_address\fR ) [ port \fIinteger\fR ]; ... - }; - view \fIstring\fR \fIoptional_class\fR; - search { \fIstring\fR; ... }; - ndots \fIinteger\fR; -}; -.fi -.RE -.SH "OPTIONS" -.sp -.RS 4 -.nf -options { - avoid\-v4\-udp\-ports { \fIport\fR; ... }; - avoid\-v6\-udp\-ports { \fIport\fR; ... }; - blackhole { \fIaddress_match_element\fR; ... }; - coresize \fIsize\fR; - datasize \fIsize\fR; - directory \fIquoted_string\fR; - dump\-file \fIquoted_string\fR; - files \fIsize\fR; - heartbeat\-interval \fIinteger\fR; - host\-statistics \fIboolean\fR; // not implemented - host\-statistics\-max \fInumber\fR; // not implemented - hostname ( \fIquoted_string\fR | none ); - interface\-interval \fIinteger\fR; - listen\-on [ port \fIinteger\fR ] { \fIaddress_match_element\fR; ... }; - listen\-on\-v6 [ port \fIinteger\fR ] { \fIaddress_match_element\fR; ... }; - match\-mapped\-addresses \fIboolean\fR; - memstatistics\-file \fIquoted_string\fR; - pid\-file ( \fIquoted_string\fR | none ); - port \fIinteger\fR; - querylog \fIboolean\fR; - recursing\-file \fIquoted_string\fR; - random\-device \fIquoted_string\fR; - recursive\-clients \fIinteger\fR; - serial\-query\-rate \fIinteger\fR; - server\-id ( \fIquoted_string\fR | none |; - stacksize \fIsize\fR; - statistics\-file \fIquoted_string\fR; - statistics\-interval \fIinteger\fR; // not yet implemented - tcp\-clients \fIinteger\fR; - tcp\-listen\-queue \fIinteger\fR; - tkey\-dhkey \fIquoted_string\fR \fIinteger\fR; - tkey\-gssapi\-credential \fIquoted_string\fR; - tkey\-domain \fIquoted_string\fR; - transfers\-per\-ns \fIinteger\fR; - transfers\-in \fIinteger\fR; - transfers\-out \fIinteger\fR; - use\-ixfr \fIboolean\fR; - version ( \fIquoted_string\fR | none ); - allow\-recursion { \fIaddress_match_element\fR; ... }; - sortlist { \fIaddress_match_element\fR; ... }; - topology { \fIaddress_match_element\fR; ... }; // not implemented - auth\-nxdomain \fIboolean\fR; // default changed - minimal\-responses \fIboolean\fR; - recursion \fIboolean\fR; - rrset\-order { - [ class \fIstring\fR ] [ type \fIstring\fR ] - [ name \fIquoted_string\fR ] \fIstring\fR \fIstring\fR; ... - }; - provide\-ixfr \fIboolean\fR; - request\-ixfr \fIboolean\fR; - rfc2308\-type1 \fIboolean\fR; // not yet implemented - additional\-from\-auth \fIboolean\fR; - additional\-from\-cache \fIboolean\fR; - query\-source ( ( \fIipv4_address\fR | * ) | [ address ( \fIipv4_address\fR | * ) ] ) [ port ( \fIinteger\fR | * ) ]; - query\-source\-v6 ( ( \fIipv6_address\fR | * ) | [ address ( \fIipv6_address\fR | * ) ] ) [ port ( \fIinteger\fR | * ) ]; - cleaning\-interval \fIinteger\fR; - min\-roots \fIinteger\fR; // not implemented - lame\-ttl \fIinteger\fR; - max\-ncache\-ttl \fIinteger\fR; - max\-cache\-ttl \fIinteger\fR; - transfer\-format ( many\-answers | one\-answer ); - max\-cache\-size \fIsize_no_default\fR; - max\-acache\-size \fIsize_no_default\fR; - clients\-per\-query \fInumber\fR; - max\-clients\-per\-query \fInumber\fR; - check\-names ( master | slave | response ) - ( fail | warn | ignore ); - check\-mx ( fail | warn | ignore ); - check\-integrity \fIboolean\fR; - check\-mx\-cname ( fail | warn | ignore ); - check\-srv\-cname ( fail | warn | ignore ); - cache\-file \fIquoted_string\fR; // test option - suppress\-initial\-notify \fIboolean\fR; // not yet implemented - preferred\-glue \fIstring\fR; - dual\-stack\-servers [ port \fIinteger\fR ] { - ( \fIquoted_string\fR [port \fIinteger\fR] | - \fIipv4_address\fR [port \fIinteger\fR] | - \fIipv6_address\fR [port \fIinteger\fR] ); ... - }; - edns\-udp\-size \fIinteger\fR; - max\-udp\-size \fIinteger\fR; - root\-delegation\-only [ exclude { \fIquoted_string\fR; ... } ]; - disable\-algorithms \fIstring\fR { \fIstring\fR; ... }; - dnssec\-enable \fIboolean\fR; - dnssec\-validation \fIboolean\fR; - dnssec\-lookaside \fIstring\fR trust\-anchor \fIstring\fR; - dnssec\-must\-be\-secure \fIstring\fR \fIboolean\fR; - dnssec\-accept\-expired \fIboolean\fR; - empty\-server \fIstring\fR; - empty\-contact \fIstring\fR; - empty\-zones\-enable \fIboolean\fR; - disable\-empty\-zone \fIstring\fR; - dialup \fIdialuptype\fR; - ixfr\-from\-differences \fIixfrdiff\fR; - allow\-query { \fIaddress_match_element\fR; ... }; - allow\-query\-cache { \fIaddress_match_element\fR; ... }; - allow\-transfer { \fIaddress_match_element\fR; ... }; - allow\-update { \fIaddress_match_element\fR; ... }; - allow\-update\-forwarding { \fIaddress_match_element\fR; ... }; - update\-check\-ksk \fIboolean\fR; - masterfile\-format ( text | raw ); - notify \fInotifytype\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; - notify\-delay \fIseconds\fR; - also\-notify [ port \fIinteger\fR ] { ( \fIipv4_address\fR | \fIipv6_address\fR ) - [ port \fIinteger\fR ]; ... }; - allow\-notify { \fIaddress_match_element\fR; ... }; - forward ( first | only ); - forwarders [ port \fIinteger\fR ] { - ( \fIipv4_address\fR | \fIipv6_address\fR ) [ port \fIinteger\fR ]; ... - }; - max\-journal\-size \fIsize_no_default\fR; - max\-transfer\-time\-in \fIinteger\fR; - max\-transfer\-time\-out \fIinteger\fR; - max\-transfer\-idle\-in \fIinteger\fR; - max\-transfer\-idle\-out \fIinteger\fR; - max\-retry\-time \fIinteger\fR; - min\-retry\-time \fIinteger\fR; - max\-refresh\-time \fIinteger\fR; - min\-refresh\-time \fIinteger\fR; - multi\-master \fIboolean\fR; - sig\-validity\-interval \fIinteger\fR; - transfer\-source ( \fIipv4_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - alt\-transfer\-source ( \fIipv4_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - alt\-transfer\-source\-v6 ( \fIipv6_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - use\-alt\-transfer\-source \fIboolean\fR; - zone\-statistics \fIboolean\fR; - key\-directory \fIquoted_string\fR; - zero\-no\-soa\-ttl \fIboolean\fR; - zero\-no\-soa\-ttl\-cache \fIboolean\fR; - allow\-v6\-synthesis { \fIaddress_match_element\fR; ... }; // obsolete - deallocate\-on\-exit \fIboolean\fR; // obsolete - fake\-iquery \fIboolean\fR; // obsolete - fetch\-glue \fIboolean\fR; // obsolete - has\-old\-clients \fIboolean\fR; // obsolete - maintain\-ixfr\-base \fIboolean\fR; // obsolete - max\-ixfr\-log\-size \fIsize\fR; // obsolete - multiple\-cnames \fIboolean\fR; // obsolete - named\-xfer \fIquoted_string\fR; // obsolete - serial\-queries \fIinteger\fR; // obsolete - treat\-cr\-as\-space \fIboolean\fR; // obsolete - use\-id\-pool \fIboolean\fR; // obsolete -}; -.fi -.RE -.SH "VIEW" -.sp -.RS 4 -.nf -view \fIstring\fR \fIoptional_class\fR { - match\-clients { \fIaddress_match_element\fR; ... }; - match\-destinations { \fIaddress_match_element\fR; ... }; - match\-recursive\-only \fIboolean\fR; - key \fIstring\fR { - algorithm \fIstring\fR; - secret \fIstring\fR; - }; - zone \fIstring\fR \fIoptional_class\fR { - ... - }; - server ( \fIipv4_address\fR\fI[/prefixlen]\fR | \fIipv6_address\fR\fI[/prefixlen]\fR ) { - ... - }; - trusted\-keys { - \fIstring\fR \fIinteger\fR \fIinteger\fR \fIinteger\fR \fIquoted_string\fR; ... - }; - allow\-recursion { \fIaddress_match_element\fR; ... }; - sortlist { \fIaddress_match_element\fR; ... }; - topology { \fIaddress_match_element\fR; ... }; // not implemented - auth\-nxdomain \fIboolean\fR; // default changed - minimal\-responses \fIboolean\fR; - recursion \fIboolean\fR; - rrset\-order { - [ class \fIstring\fR ] [ type \fIstring\fR ] - [ name \fIquoted_string\fR ] \fIstring\fR \fIstring\fR; ... - }; - provide\-ixfr \fIboolean\fR; - request\-ixfr \fIboolean\fR; - rfc2308\-type1 \fIboolean\fR; // not yet implemented - additional\-from\-auth \fIboolean\fR; - additional\-from\-cache \fIboolean\fR; - query\-source ( ( \fIipv4_address\fR | * ) | [ address ( \fIipv4_address\fR | * ) ] ) [ port ( \fIinteger\fR | * ) ]; - query\-source\-v6 ( ( \fIipv6_address\fR | * ) | [ address ( \fIipv6_address\fR | * ) ] ) [ port ( \fIinteger\fR | * ) ]; - cleaning\-interval \fIinteger\fR; - min\-roots \fIinteger\fR; // not implemented - lame\-ttl \fIinteger\fR; - max\-ncache\-ttl \fIinteger\fR; - max\-cache\-ttl \fIinteger\fR; - transfer\-format ( many\-answers | one\-answer ); - max\-cache\-size \fIsize_no_default\fR; - max\-acache\-size \fIsize_no_default\fR; - clients\-per\-query \fInumber\fR; - max\-clients\-per\-query \fInumber\fR; - check\-names ( master | slave | response ) - ( fail | warn | ignore ); - check\-mx ( fail | warn | ignore ); - check\-integrity \fIboolean\fR; - check\-mx\-cname ( fail | warn | ignore ); - check\-srv\-cname ( fail | warn | ignore ); - cache\-file \fIquoted_string\fR; // test option - suppress\-initial\-notify \fIboolean\fR; // not yet implemented - preferred\-glue \fIstring\fR; - dual\-stack\-servers [ port \fIinteger\fR ] { - ( \fIquoted_string\fR [port \fIinteger\fR] | - \fIipv4_address\fR [port \fIinteger\fR] | - \fIipv6_address\fR [port \fIinteger\fR] ); ... - }; - edns\-udp\-size \fIinteger\fR; - max\-udp\-size \fIinteger\fR; - root\-delegation\-only [ exclude { \fIquoted_string\fR; ... } ]; - disable\-algorithms \fIstring\fR { \fIstring\fR; ... }; - dnssec\-enable \fIboolean\fR; - dnssec\-validation \fIboolean\fR; - dnssec\-lookaside \fIstring\fR trust\-anchor \fIstring\fR; - dnssec\-must\-be\-secure \fIstring\fR \fIboolean\fR; - dnssec\-accept\-expired \fIboolean\fR; - empty\-server \fIstring\fR; - empty\-contact \fIstring\fR; - empty\-zones\-enable \fIboolean\fR; - disable\-empty\-zone \fIstring\fR; - dialup \fIdialuptype\fR; - ixfr\-from\-differences \fIixfrdiff\fR; - allow\-query { \fIaddress_match_element\fR; ... }; - allow\-query\-cache { \fIaddress_match_element\fR; ... }; - allow\-transfer { \fIaddress_match_element\fR; ... }; - allow\-update { \fIaddress_match_element\fR; ... }; - allow\-update\-forwarding { \fIaddress_match_element\fR; ... }; - update\-check\-ksk \fIboolean\fR; - masterfile\-format ( text | raw ); - notify \fInotifytype\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; - notify\-delay \fIseconds\fR; - also\-notify [ port \fIinteger\fR ] { ( \fIipv4_address\fR | \fIipv6_address\fR ) - [ port \fIinteger\fR ]; ... }; - allow\-notify { \fIaddress_match_element\fR; ... }; - forward ( first | only ); - forwarders [ port \fIinteger\fR ] { - ( \fIipv4_address\fR | \fIipv6_address\fR ) [ port \fIinteger\fR ]; ... - }; - max\-journal\-size \fIsize_no_default\fR; - max\-transfer\-time\-in \fIinteger\fR; - max\-transfer\-time\-out \fIinteger\fR; - max\-transfer\-idle\-in \fIinteger\fR; - max\-transfer\-idle\-out \fIinteger\fR; - max\-retry\-time \fIinteger\fR; - min\-retry\-time \fIinteger\fR; - max\-refresh\-time \fIinteger\fR; - min\-refresh\-time \fIinteger\fR; - multi\-master \fIboolean\fR; - sig\-validity\-interval \fIinteger\fR; - transfer\-source ( \fIipv4_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - alt\-transfer\-source ( \fIipv4_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - alt\-transfer\-source\-v6 ( \fIipv6_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - use\-alt\-transfer\-source \fIboolean\fR; - zone\-statistics \fIboolean\fR; - key\-directory \fIquoted_string\fR; - zero\-no\-soa\-ttl \fIboolean\fR; - zero\-no\-soa\-ttl\-cache \fIboolean\fR; - allow\-v6\-synthesis { \fIaddress_match_element\fR; ... }; // obsolete - fetch\-glue \fIboolean\fR; // obsolete - maintain\-ixfr\-base \fIboolean\fR; // obsolete - max\-ixfr\-log\-size \fIsize\fR; // obsolete -}; -.fi -.RE -.SH "ZONE" -.sp -.RS 4 -.nf -zone \fIstring\fR \fIoptional_class\fR { - type ( master | slave | stub | hint | - forward | delegation\-only ); - file \fIquoted_string\fR; - masters [ port \fIinteger\fR ] { - ( \fImasters\fR | - \fIipv4_address\fR [port \fIinteger\fR] | - \fIipv6_address\fR [ port \fIinteger\fR ] ) [ key \fIstring\fR ]; ... - }; - database \fIstring\fR; - delegation\-only \fIboolean\fR; - check\-names ( fail | warn | ignore ); - check\-mx ( fail | warn | ignore ); - check\-integrity \fIboolean\fR; - check\-mx\-cname ( fail | warn | ignore ); - check\-srv\-cname ( fail | warn | ignore ); - dialup \fIdialuptype\fR; - ixfr\-from\-differences \fIboolean\fR; - journal \fIquoted_string\fR; - zero\-no\-soa\-ttl \fIboolean\fR; - allow\-query { \fIaddress_match_element\fR; ... }; - allow\-transfer { \fIaddress_match_element\fR; ... }; - allow\-update { \fIaddress_match_element\fR; ... }; - allow\-update\-forwarding { \fIaddress_match_element\fR; ... }; - update\-policy { - ( grant | deny ) \fIstring\fR - ( name | subdomain | wildcard | self ) \fIstring\fR - \fIrrtypelist\fR; ... - }; - update\-check\-ksk \fIboolean\fR; - masterfile\-format ( text | raw ); - notify \fInotifytype\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; - notify\-delay \fIseconds\fR; - also\-notify [ port \fIinteger\fR ] { ( \fIipv4_address\fR | \fIipv6_address\fR ) - [ port \fIinteger\fR ]; ... }; - allow\-notify { \fIaddress_match_element\fR; ... }; - forward ( first | only ); - forwarders [ port \fIinteger\fR ] { - ( \fIipv4_address\fR | \fIipv6_address\fR ) [ port \fIinteger\fR ]; ... - }; - max\-journal\-size \fIsize_no_default\fR; - max\-transfer\-time\-in \fIinteger\fR; - max\-transfer\-time\-out \fIinteger\fR; - max\-transfer\-idle\-in \fIinteger\fR; - max\-transfer\-idle\-out \fIinteger\fR; - max\-retry\-time \fIinteger\fR; - min\-retry\-time \fIinteger\fR; - max\-refresh\-time \fIinteger\fR; - min\-refresh\-time \fIinteger\fR; - multi\-master \fIboolean\fR; - sig\-validity\-interval \fIinteger\fR; - transfer\-source ( \fIipv4_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - alt\-transfer\-source ( \fIipv4_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - alt\-transfer\-source\-v6 ( \fIipv6_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - use\-alt\-transfer\-source \fIboolean\fR; - zone\-statistics \fIboolean\fR; - key\-directory \fIquoted_string\fR; - ixfr\-base \fIquoted_string\fR; // obsolete - ixfr\-tmp\-file \fIquoted_string\fR; // obsolete - maintain\-ixfr\-base \fIboolean\fR; // obsolete - max\-ixfr\-log\-size \fIsize\fR; // obsolete - pubkey \fIinteger\fR \fIinteger\fR \fIinteger\fR \fIquoted_string\fR; // obsolete -}; -.fi -.RE -.SH "FILES" -.PP -\fI/etc/named.conf\fR -.SH "SEE ALSO" -.PP -\fBnamed\fR(8), -\fBnamed\-checkconf\fR(8), -\fBrndc\fR(8), -BIND 9 Administrator Reference Manual. -.SH "COPYRIGHT" -Copyright \(co 2004\-2007 Internet Systems Consortium, Inc. ("ISC") -.br diff --git a/contrib/bind9/bin/named/named.conf.docbook b/contrib/bind9/bin/named/named.conf.docbook deleted file mode 100644 index e4cfcc7..0000000 --- a/contrib/bind9/bin/named/named.conf.docbook +++ /dev/null @@ -1,597 +0,0 @@ -]> - - - - - - Aug 13, 2004 - - - - named.conf - 5 - BIND9 - - - - named.conf - configuration file for named - - - - - 2004 - 2005 - 2006 - 2007 - Internet Systems Consortium, Inc. ("ISC") - - - - - - named.conf - - - - - DESCRIPTION - named.conf is the configuration file - for - named. Statements are enclosed - in braces and terminated with a semi-colon. Clauses in - the statements are also semi-colon terminated. The usual - comment styles are supported: - - - C style: /* */ - - - C++ style: // to end of line - - - Unix style: # to end of line - - - - - ACL - -acl string { address_match_element; ... }; - - - - - - KEY - -key domain_name { - algorithm string; - secret string; -}; - - - - - MASTERS - -masters string port integer { - ( masters | ipv4_address port integer | - ipv6_address port integer ) key string ; ... -}; - - - - - SERVER - -server ( ipv4_address/prefixlen | ipv6_address/prefixlen ) { - bogus boolean; - edns boolean; - edns-udp-size integer; - max-udp-size integer; - provide-ixfr boolean; - request-ixfr boolean; - keys server_key; - transfers integer; - transfer-format ( many-answers | one-answer ); - transfer-source ( ipv4_address | * ) - port ( integer | * ) ; - transfer-source-v6 ( ipv6_address | * ) - port ( integer | * ) ; - - support-ixfr boolean; // obsolete -}; - - - - - TRUSTED-KEYS - -trusted-keys { - domain_name flags protocol algorithm key; ... -}; - - - - - CONTROLS - -controls { - inet ( ipv4_address | ipv6_address | * ) - port ( integer | * ) - allow { address_match_element; ... } - keys { string; ... } ; - unix unsupported; // not implemented -}; - - - - - LOGGING - -logging { - channel string { - file log_file; - syslog optional_facility; - null; - stderr; - severity log_severity; - print-time boolean; - print-severity boolean; - print-category boolean; - }; - category string { string; ... }; -}; - - - - - LWRES - -lwres { - listen-on port integer { - ( ipv4_address | ipv6_address ) port integer ; ... - }; - view string optional_class; - search { string; ... }; - ndots integer; -}; - - - - - OPTIONS - -options { - avoid-v4-udp-ports { port; ... }; - avoid-v6-udp-ports { port; ... }; - blackhole { address_match_element; ... }; - coresize size; - datasize size; - directory quoted_string; - dump-file quoted_string; - files size; - heartbeat-interval integer; - host-statistics boolean; // not implemented - host-statistics-max number; // not implemented - hostname ( quoted_string | none ); - interface-interval integer; - listen-on port integer { address_match_element; ... }; - listen-on-v6 port integer { address_match_element; ... }; - match-mapped-addresses boolean; - memstatistics-file quoted_string; - pid-file ( quoted_string | none ); - port integer; - querylog boolean; - recursing-file quoted_string; - random-device quoted_string; - recursive-clients integer; - serial-query-rate integer; - server-id ( quoted_string | none |; - stacksize size; - statistics-file quoted_string; - statistics-interval integer; // not yet implemented - tcp-clients integer; - tcp-listen-queue integer; - tkey-dhkey quoted_string integer; - tkey-gssapi-credential quoted_string; - tkey-domain quoted_string; - transfers-per-ns integer; - transfers-in integer; - transfers-out integer; - use-ixfr boolean; - version ( quoted_string | none ); - allow-recursion { address_match_element; ... }; - sortlist { address_match_element; ... }; - topology { address_match_element; ... }; // not implemented - auth-nxdomain boolean; // default changed - minimal-responses boolean; - recursion boolean; - rrset-order { - class string type string - name quoted_string string string; ... - }; - provide-ixfr boolean; - request-ixfr boolean; - rfc2308-type1 boolean; // not yet implemented - additional-from-auth boolean; - additional-from-cache boolean; - query-source ( ( ipv4_address | * ) | address ( ipv4_address | * ) ) port ( integer | * ) ; - query-source-v6 ( ( ipv6_address | * ) | address ( ipv6_address | * ) ) port ( integer | * ) ; - cleaning-interval integer; - min-roots integer; // not implemented - lame-ttl integer; - max-ncache-ttl integer; - max-cache-ttl integer; - transfer-format ( many-answers | one-answer ); - max-cache-size size_no_default; - max-acache-size size_no_default; - clients-per-query number; - max-clients-per-query number; - check-names ( master | slave | response ) - ( fail | warn | ignore ); - check-mx ( fail | warn | ignore ); - check-integrity boolean; - check-mx-cname ( fail | warn | ignore ); - check-srv-cname ( fail | warn | ignore ); - cache-file quoted_string; // test option - suppress-initial-notify boolean; // not yet implemented - preferred-glue string; - dual-stack-servers port integer { - ( quoted_string port integer | - ipv4_address port integer | - ipv6_address port integer ); ... - }; - edns-udp-size integer; - max-udp-size integer; - root-delegation-only exclude { quoted_string; ... } ; - disable-algorithms string { string; ... }; - dnssec-enable boolean; - dnssec-validation boolean; - dnssec-lookaside string trust-anchor string; - dnssec-must-be-secure string boolean; - dnssec-accept-expired boolean; - - empty-server string; - empty-contact string; - empty-zones-enable boolean; - disable-empty-zone string; - - dialup dialuptype; - ixfr-from-differences ixfrdiff; - - allow-query { address_match_element; ... }; - allow-query-cache { address_match_element; ... }; - allow-transfer { address_match_element; ... }; - allow-update { address_match_element; ... }; - allow-update-forwarding { address_match_element; ... }; - update-check-ksk boolean; - - masterfile-format ( text | raw ); - notify notifytype; - notify-source ( ipv4_address | * ) port ( integer | * ) ; - notify-source-v6 ( ipv6_address | * ) port ( integer | * ) ; - notify-delay seconds; - also-notify port integer { ( ipv4_address | ipv6_address ) - port integer ; ... }; - allow-notify { address_match_element; ... }; - - forward ( first | only ); - forwarders port integer { - ( ipv4_address | ipv6_address ) port integer ; ... - }; - - max-journal-size size_no_default; - max-transfer-time-in integer; - max-transfer-time-out integer; - max-transfer-idle-in integer; - max-transfer-idle-out integer; - max-retry-time integer; - min-retry-time integer; - max-refresh-time integer; - min-refresh-time integer; - multi-master boolean; - sig-validity-interval integer; - - transfer-source ( ipv4_address | * ) - port ( integer | * ) ; - transfer-source-v6 ( ipv6_address | * ) - port ( integer | * ) ; - - alt-transfer-source ( ipv4_address | * ) - port ( integer | * ) ; - alt-transfer-source-v6 ( ipv6_address | * ) - port ( integer | * ) ; - use-alt-transfer-source boolean; - - zone-statistics boolean; - key-directory quoted_string; - zero-no-soa-ttl boolean; - zero-no-soa-ttl-cache boolean; - - allow-v6-synthesis { address_match_element; ... }; // obsolete - deallocate-on-exit boolean; // obsolete - fake-iquery boolean; // obsolete - fetch-glue boolean; // obsolete - has-old-clients boolean; // obsolete - maintain-ixfr-base boolean; // obsolete - max-ixfr-log-size size; // obsolete - multiple-cnames boolean; // obsolete - named-xfer quoted_string; // obsolete - serial-queries integer; // obsolete - treat-cr-as-space boolean; // obsolete - use-id-pool boolean; // obsolete -}; - - - - - VIEW - -view string optional_class { - match-clients { address_match_element; ... }; - match-destinations { address_match_element; ... }; - match-recursive-only boolean; - - key string { - algorithm string; - secret string; - }; - - zone string optional_class { - ... - }; - - server ( ipv4_address/prefixlen | ipv6_address/prefixlen ) { - ... - }; - - trusted-keys { - string integer integer integer quoted_string; ... - }; - - allow-recursion { address_match_element; ... }; - sortlist { address_match_element; ... }; - topology { address_match_element; ... }; // not implemented - auth-nxdomain boolean; // default changed - minimal-responses boolean; - recursion boolean; - rrset-order { - class string type string - name quoted_string string string; ... - }; - provide-ixfr boolean; - request-ixfr boolean; - rfc2308-type1 boolean; // not yet implemented - additional-from-auth boolean; - additional-from-cache boolean; - query-source ( ( ipv4_address | * ) | address ( ipv4_address | * ) ) port ( integer | * ) ; - query-source-v6 ( ( ipv6_address | * ) | address ( ipv6_address | * ) ) port ( integer | * ) ; - cleaning-interval integer; - min-roots integer; // not implemented - lame-ttl integer; - max-ncache-ttl integer; - max-cache-ttl integer; - transfer-format ( many-answers | one-answer ); - max-cache-size size_no_default; - max-acache-size size_no_default; - clients-per-query number; - max-clients-per-query number; - check-names ( master | slave | response ) - ( fail | warn | ignore ); - check-mx ( fail | warn | ignore ); - check-integrity boolean; - check-mx-cname ( fail | warn | ignore ); - check-srv-cname ( fail | warn | ignore ); - cache-file quoted_string; // test option - suppress-initial-notify boolean; // not yet implemented - preferred-glue string; - dual-stack-servers port integer { - ( quoted_string port integer | - ipv4_address port integer | - ipv6_address port integer ); ... - }; - edns-udp-size integer; - max-udp-size integer; - root-delegation-only exclude { quoted_string; ... } ; - disable-algorithms string { string; ... }; - dnssec-enable boolean; - dnssec-validation boolean; - dnssec-lookaside string trust-anchor string; - dnssec-must-be-secure string boolean; - dnssec-accept-expired boolean; - - empty-server string; - empty-contact string; - empty-zones-enable boolean; - disable-empty-zone string; - - dialup dialuptype; - ixfr-from-differences ixfrdiff; - - allow-query { address_match_element; ... }; - allow-query-cache { address_match_element; ... }; - allow-transfer { address_match_element; ... }; - allow-update { address_match_element; ... }; - allow-update-forwarding { address_match_element; ... }; - update-check-ksk boolean; - - masterfile-format ( text | raw ); - notify notifytype; - notify-source ( ipv4_address | * ) port ( integer | * ) ; - notify-source-v6 ( ipv6_address | * ) port ( integer | * ) ; - notify-delay seconds; - also-notify port integer { ( ipv4_address | ipv6_address ) - port integer ; ... }; - allow-notify { address_match_element; ... }; - - forward ( first | only ); - forwarders port integer { - ( ipv4_address | ipv6_address ) port integer ; ... - }; - - max-journal-size size_no_default; - max-transfer-time-in integer; - max-transfer-time-out integer; - max-transfer-idle-in integer; - max-transfer-idle-out integer; - max-retry-time integer; - min-retry-time integer; - max-refresh-time integer; - min-refresh-time integer; - multi-master boolean; - sig-validity-interval integer; - - transfer-source ( ipv4_address | * ) - port ( integer | * ) ; - transfer-source-v6 ( ipv6_address | * ) - port ( integer | * ) ; - - alt-transfer-source ( ipv4_address | * ) - port ( integer | * ) ; - alt-transfer-source-v6 ( ipv6_address | * ) - port ( integer | * ) ; - use-alt-transfer-source boolean; - - zone-statistics boolean; - key-directory quoted_string; - zero-no-soa-ttl boolean; - zero-no-soa-ttl-cache boolean; - - allow-v6-synthesis { address_match_element; ... }; // obsolete - fetch-glue boolean; // obsolete - maintain-ixfr-base boolean; // obsolete - max-ixfr-log-size size; // obsolete -}; - - - - - ZONE - -zone string optional_class { - type ( master | slave | stub | hint | - forward | delegation-only ); - file quoted_string; - - masters port integer { - ( masters | - ipv4_address port integer | - ipv6_address port integer ) key string ; ... - }; - - database string; - delegation-only boolean; - check-names ( fail | warn | ignore ); - check-mx ( fail | warn | ignore ); - check-integrity boolean; - check-mx-cname ( fail | warn | ignore ); - check-srv-cname ( fail | warn | ignore ); - dialup dialuptype; - ixfr-from-differences boolean; - journal quoted_string; - zero-no-soa-ttl boolean; - - allow-query { address_match_element; ... }; - allow-transfer { address_match_element; ... }; - allow-update { address_match_element; ... }; - allow-update-forwarding { address_match_element; ... }; - update-policy { - ( grant | deny ) string - ( name | subdomain | wildcard | self ) string - rrtypelist; ... - }; - update-check-ksk boolean; - - masterfile-format ( text | raw ); - notify notifytype; - notify-source ( ipv4_address | * ) port ( integer | * ) ; - notify-source-v6 ( ipv6_address | * ) port ( integer | * ) ; - notify-delay seconds; - also-notify port integer { ( ipv4_address | ipv6_address ) - port integer ; ... }; - allow-notify { address_match_element; ... }; - - forward ( first | only ); - forwarders port integer { - ( ipv4_address | ipv6_address ) port integer ; ... - }; - - max-journal-size size_no_default; - max-transfer-time-in integer; - max-transfer-time-out integer; - max-transfer-idle-in integer; - max-transfer-idle-out integer; - max-retry-time integer; - min-retry-time integer; - max-refresh-time integer; - min-refresh-time integer; - multi-master boolean; - sig-validity-interval integer; - - transfer-source ( ipv4_address | * ) - port ( integer | * ) ; - transfer-source-v6 ( ipv6_address | * ) - port ( integer | * ) ; - - alt-transfer-source ( ipv4_address | * ) - port ( integer | * ) ; - alt-transfer-source-v6 ( ipv6_address | * ) - port ( integer | * ) ; - use-alt-transfer-source boolean; - - zone-statistics boolean; - key-directory quoted_string; - - ixfr-base quoted_string; // obsolete - ixfr-tmp-file quoted_string; // obsolete - maintain-ixfr-base boolean; // obsolete - max-ixfr-log-size size; // obsolete - pubkey integer integer integer quoted_string; // obsolete -}; - - - - - FILES - /etc/named.conf - - - - - SEE ALSO - - named8 - , - - named-checkconf8 - , - - rndc8 - , - BIND 9 Administrator Reference Manual. - - - - diff --git a/contrib/bind9/bin/named/named.conf.html b/contrib/bind9/bin/named/named.conf.html deleted file mode 100644 index 09e71a3..0000000 --- a/contrib/bind9/bin/named/named.conf.html +++ /dev/null @@ -1,554 +0,0 @@ - - - - - -named.conf - - -
-
-
-

Name

-

named.conf — configuration file for named

-
-
-

Synopsis

-

named.conf

-
-
-

DESCRIPTION

-

named.conf is the configuration file - for - named. Statements are enclosed - in braces and terminated with a semi-colon. Clauses in - the statements are also semi-colon terminated. The usual - comment styles are supported: -

-

- C style: /* */ -

-

- C++ style: // to end of line -

-

- Unix style: # to end of line -

-
-
-

ACL

-


-acl string { address_match_element; ... };
-
-

-
-
-

KEY

-


-key domain_name {
- algorithm string;
- secret string;
-};
-

-
-
-

MASTERS

-


-masters string [ port integer ] {
- ( masters | ipv4_address [port integer] |
- ipv6_address [port integer] ) [ key string ]; ...
-};
-

-
-
-

SERVER

-


-server ( ipv4_address[/prefixlen] | ipv6_address[/prefixlen] ) {
- bogus boolean;
- edns boolean;
- edns-udp-size integer;
- max-udp-size integer;
- provide-ixfr boolean;
- request-ixfr boolean;
- keys server_key;
- transfers integer;
- transfer-format ( many-answers | one-answer );
- transfer-source ( ipv4_address | * )
- [ port ( integer | * ) ];
- transfer-source-v6 ( ipv6_address | * )
- [ port ( integer | * ) ];
-
- support-ixfr boolean; // obsolete
-};
-

-
-
-

TRUSTED-KEYS

-


-trusted-keys {
- domain_name flags protocol algorithm key; ... 
-};
-

-
-
-

CONTROLS

-


-controls {
- inet ( ipv4_address | ipv6_address | * )
- [ port ( integer | * ) ]
- allow { address_match_element; ... }
- [ keys { string; ... } ];
- unix unsupported; // not implemented
-};
-

-
-
-

LOGGING

-


-logging {
- channel string {
- file log_file;
- syslog optional_facility;
- null;
- stderr;
- severity log_severity;
- print-time boolean;
- print-severity boolean;
- print-category boolean;
- };
- category string { string; ... };
-};
-

-
-
-

LWRES

-


-lwres {
- listen-on [ port integer ] {
- ( ipv4_address | ipv6_address ) [ port integer ]; ...
- };
- view string optional_class;
- search { string; ... };
- ndots integer;
-};
-

-
-
-

OPTIONS

-


-options {
- avoid-v4-udp-ports { port; ... };
- avoid-v6-udp-ports { port; ... };
- blackhole { address_match_element; ... };
- coresize size;
- datasize size;
- directory quoted_string;
- dump-file quoted_string;
- files size;
- heartbeat-interval integer;
- host-statistics boolean; // not implemented
- host-statistics-max number; // not implemented
- hostname ( quoted_string | none );
- interface-interval integer;
- listen-on [ port integer ] { address_match_element; ... };
- listen-on-v6 [ port integer ] { address_match_element; ... };
- match-mapped-addresses boolean;
- memstatistics-file quoted_string;
- pid-file ( quoted_string | none );
- port integer;
- querylog boolean;
- recursing-file quoted_string;
- random-device quoted_string;
- recursive-clients integer;
- serial-query-rate integer;
- server-id ( quoted_string | none |;
- stacksize size;
- statistics-file quoted_string;
- statistics-interval integer; // not yet implemented
- tcp-clients integer;
- tcp-listen-queue integer;
- tkey-dhkey quoted_string integer;
- tkey-gssapi-credential quoted_string;
- tkey-domain quoted_string;
- transfers-per-ns integer;
- transfers-in integer;
- transfers-out integer;
- use-ixfr boolean;
- version ( quoted_string | none );
- allow-recursion { address_match_element; ... };
- sortlist { address_match_element; ... };
- topology { address_match_element; ... }; // not implemented
- auth-nxdomain boolean; // default changed
- minimal-responses boolean;
- recursion boolean;
- rrset-order {
- [ class string ] [ type string ]
- [ name quoted_string string string; ...
- };
- provide-ixfr boolean;
- request-ixfr boolean;
- rfc2308-type1 boolean; // not yet implemented
- additional-from-auth boolean;
- additional-from-cache boolean;
- query-source ( ( ipv4_address | * ) | [ address ( ipv4_address | * ) ] ) [ port ( integer | * ) ];
- query-source-v6 ( ( ipv6_address | * ) | [ address ( ipv6_address | * ) ] ) [ port ( integer | * ) ];
- cleaning-interval integer;
- min-roots integer; // not implemented
- lame-ttl integer;
- max-ncache-ttl integer;
- max-cache-ttl integer;
- transfer-format ( many-answers | one-answer );
- max-cache-size size_no_default;
- max-acache-size size_no_default;
- clients-per-query number;
- max-clients-per-query number;
- check-names ( master | slave | response )
- ( fail | warn | ignore );
- check-mx ( fail | warn | ignore );
- check-integrity boolean;
- check-mx-cname ( fail | warn | ignore );
- check-srv-cname ( fail | warn | ignore );
- cache-file quoted_string; // test option
- suppress-initial-notify boolean; // not yet implemented
- preferred-glue string;
- dual-stack-servers [ port integer ] {
- ( quoted_string [port integer] |
- ipv4_address [port integer] |
- ipv6_address [port integer] ); ...
- };
- edns-udp-size integer;
- max-udp-size integer;
- root-delegation-only [ exclude { quoted_string; ... } ];
- disable-algorithms string { string; ... };
- dnssec-enable boolean;
- dnssec-validation boolean;
- dnssec-lookaside string trust-anchor string;
- dnssec-must-be-secure string boolean;
- dnssec-accept-expired boolean;
-
- empty-server string;
- empty-contact string;
- empty-zones-enable boolean;
- disable-empty-zone string;
-
- dialup dialuptype;
- ixfr-from-differences ixfrdiff;
-
- allow-query { address_match_element; ... };
- allow-query-cache { address_match_element; ... };
- allow-transfer { address_match_element; ... };
- allow-update { address_match_element; ... };
- allow-update-forwarding { address_match_element; ... };
- update-check-ksk boolean;
-
- masterfile-format ( text | raw );
- notify notifytype;
- notify-source ( ipv4_address | * ) [ port ( integer | * ) ];
- notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ];
- notify-delay seconds;
- also-notify [ port integer ] { ( ipv4_address | ipv6_address )
- [ port integer ]; ... };
- allow-notify { address_match_element; ... };
-
- forward ( first | only );
- forwarders [ port integer ] {
- ( ipv4_address | ipv6_address ) [ port integer ]; ...
- };
-
- max-journal-size size_no_default;
- max-transfer-time-in integer;
- max-transfer-time-out integer;
- max-transfer-idle-in integer;
- max-transfer-idle-out integer;
- max-retry-time integer;
- min-retry-time integer;
- max-refresh-time integer;
- min-refresh-time integer;
- multi-master boolean;
- sig-validity-interval integer;
-
- transfer-source ( ipv4_address | * )
- [ port ( integer | * ) ];
- transfer-source-v6 ( ipv6_address | * )
- [ port ( integer | * ) ];
-
- alt-transfer-source ( ipv4_address | * )
- [ port ( integer | * ) ];
- alt-transfer-source-v6 ( ipv6_address | * )
- [ port ( integer | * ) ];
- use-alt-transfer-source boolean;
-
- zone-statistics boolean;
- key-directory quoted_string;
- zero-no-soa-ttl boolean;
- zero-no-soa-ttl-cache boolean;
-
- allow-v6-synthesis { address_match_element; ... }; // obsolete
- deallocate-on-exit boolean; // obsolete
- fake-iquery boolean; // obsolete
- fetch-glue boolean; // obsolete
- has-old-clients boolean; // obsolete
- maintain-ixfr-base boolean; // obsolete
- max-ixfr-log-size size; // obsolete
- multiple-cnames boolean; // obsolete
- named-xfer quoted_string; // obsolete
- serial-queries integer; // obsolete
- treat-cr-as-space boolean; // obsolete
- use-id-pool boolean; // obsolete
-};
-

-
-
-

VIEW

-


-view string optional_class {
- match-clients { address_match_element; ... };
- match-destinations { address_match_element; ... };
- match-recursive-only boolean;
-
- key string {
- algorithm string;
- secret string;
- };
-
- zone string optional_class {
- ...
- };
-
- server ( ipv4_address[/prefixlen] | ipv6_address[/prefixlen] ) {
- ...
- };
-
- trusted-keys {
- string integer integer integer quoted_string; ...
- };
-
- allow-recursion { address_match_element; ... };
- sortlist { address_match_element; ... };
- topology { address_match_element; ... }; // not implemented
- auth-nxdomain boolean; // default changed
- minimal-responses boolean;
- recursion boolean;
- rrset-order {
- [ class string ] [ type string ]
- [ name quoted_string string string; ...
- };
- provide-ixfr boolean;
- request-ixfr boolean;
- rfc2308-type1 boolean; // not yet implemented
- additional-from-auth boolean;
- additional-from-cache boolean;
- query-source ( ( ipv4_address | * ) | [ address ( ipv4_address | * ) ] ) [ port ( integer | * ) ];
- query-source-v6 ( ( ipv6_address | * ) | [ address ( ipv6_address | * ) ] ) [ port ( integer | * ) ];
- cleaning-interval integer;
- min-roots integer; // not implemented
- lame-ttl integer;
- max-ncache-ttl integer;
- max-cache-ttl integer;
- transfer-format ( many-answers | one-answer );
- max-cache-size size_no_default;
- max-acache-size size_no_default;
- clients-per-query number;
- max-clients-per-query number;
- check-names ( master | slave | response )
- ( fail | warn | ignore );
- check-mx ( fail | warn | ignore );
- check-integrity boolean;
- check-mx-cname ( fail | warn | ignore );
- check-srv-cname ( fail | warn | ignore );
- cache-file quoted_string; // test option
- suppress-initial-notify boolean; // not yet implemented
- preferred-glue string;
- dual-stack-servers [ port integer ] {
- ( quoted_string [port integer] |
- ipv4_address [port integer] |
- ipv6_address [port integer] ); ...
- };
- edns-udp-size integer;
- max-udp-size integer;
- root-delegation-only [ exclude { quoted_string; ... } ];
- disable-algorithms string { string; ... };
- dnssec-enable boolean;
- dnssec-validation boolean;
- dnssec-lookaside string trust-anchor string;
- dnssec-must-be-secure string boolean;
- dnssec-accept-expired boolean;
-
- empty-server string;
- empty-contact string;
- empty-zones-enable boolean;
- disable-empty-zone string;
-
- dialup dialuptype;
- ixfr-from-differences ixfrdiff;
-
- allow-query { address_match_element; ... };
- allow-query-cache { address_match_element; ... };
- allow-transfer { address_match_element; ... };
- allow-update { address_match_element; ... };
- allow-update-forwarding { address_match_element; ... };
- update-check-ksk boolean;
-
- masterfile-format ( text | raw );
- notify notifytype;
- notify-source ( ipv4_address | * ) [ port ( integer | * ) ];
- notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ];
- notify-delay seconds;
- also-notify [ port integer ] { ( ipv4_address | ipv6_address )
- [ port integer ]; ... };
- allow-notify { address_match_element; ... };
-
- forward ( first | only );
- forwarders [ port integer ] {
- ( ipv4_address | ipv6_address ) [ port integer ]; ...
- };
-
- max-journal-size size_no_default;
- max-transfer-time-in integer;
- max-transfer-time-out integer;
- max-transfer-idle-in integer;
- max-transfer-idle-out integer;
- max-retry-time integer;
- min-retry-time integer;
- max-refresh-time integer;
- min-refresh-time integer;
- multi-master boolean;
- sig-validity-interval integer;
-
- transfer-source ( ipv4_address | * )
- [ port ( integer | * ) ];
- transfer-source-v6 ( ipv6_address | * )
- [ port ( integer | * ) ];
-
- alt-transfer-source ( ipv4_address | * )
- [ port ( integer | * ) ];
- alt-transfer-source-v6 ( ipv6_address | * )
- [ port ( integer | * ) ];
- use-alt-transfer-source boolean;
-
- zone-statistics boolean;
- key-directory quoted_string;
- zero-no-soa-ttl boolean;
- zero-no-soa-ttl-cache boolean;
-
- allow-v6-synthesis { address_match_element; ... }; // obsolete
- fetch-glue boolean; // obsolete
- maintain-ixfr-base boolean; // obsolete
- max-ixfr-log-size size; // obsolete
-};
-

-
-
-

ZONE

-


-zone string optional_class {
- type ( master | slave | stub | hint |
- forward | delegation-only );
- file quoted_string;
-
- masters [ port integer ] {
- ( masters |
- ipv4_address [port integer] |
- ipv6_address [ port integer ] ) [ key string ]; ...
- };
-
- database string;
- delegation-only boolean;
- check-names ( fail | warn | ignore );
- check-mx ( fail | warn | ignore );
- check-integrity boolean;
- check-mx-cname ( fail | warn | ignore );
- check-srv-cname ( fail | warn | ignore );
- dialup dialuptype;
- ixfr-from-differences boolean;
- journal quoted_string;
- zero-no-soa-ttl boolean;
-
- allow-query { address_match_element; ... };
- allow-transfer { address_match_element; ... };
- allow-update { address_match_element; ... };
- allow-update-forwarding { address_match_element; ... };
- update-policy {
- ( grant | deny ) string
- ( name | subdomain | wildcard | self ) string
- rrtypelist; ...
- };
- update-check-ksk boolean;
-
- masterfile-format ( text | raw );
- notify notifytype;
- notify-source ( ipv4_address | * ) [ port ( integer | * ) ];
- notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ];
- notify-delay seconds;
- also-notify [ port integer ] { ( ipv4_address | ipv6_address )
- [ port integer ]; ... };
- allow-notify { address_match_element; ... };
-
- forward ( first | only );
- forwarders [ port integer ] {
- ( ipv4_address | ipv6_address ) [ port integer ]; ...
- };
-
- max-journal-size size_no_default;
- max-transfer-time-in integer;
- max-transfer-time-out integer;
- max-transfer-idle-in integer;
- max-transfer-idle-out integer;
- max-retry-time integer;
- min-retry-time integer;
- max-refresh-time integer;
- min-refresh-time integer;
- multi-master boolean;
- sig-validity-interval integer;
-
- transfer-source ( ipv4_address | * )
- [ port ( integer | * ) ];
- transfer-source-v6 ( ipv6_address | * )
- [ port ( integer | * ) ];
-
- alt-transfer-source ( ipv4_address | * )
- [ port ( integer | * ) ];
- alt-transfer-source-v6 ( ipv6_address | * )
- [ port ( integer | * ) ];
- use-alt-transfer-source boolean;
-
- zone-statistics boolean;
- key-directory quoted_string;
-
- ixfr-base quoted_string; // obsolete
- ixfr-tmp-file quoted_string; // obsolete
- maintain-ixfr-base boolean; // obsolete
- max-ixfr-log-size size; // obsolete
- pubkey integer integer integer quoted_string; // obsolete
-};
-

-
-
-

FILES

-

/etc/named.conf -

-
-
-

SEE ALSO

-

named(8), - named-checkconf(8), - rndc(8), - BIND 9 Administrator Reference Manual. -

-
-
- diff --git a/contrib/bind9/bin/named/named.docbook b/contrib/bind9/bin/named/named.docbook deleted file mode 100644 index 74b41f5..0000000 --- a/contrib/bind9/bin/named/named.docbook +++ /dev/null @@ -1,406 +0,0 @@ -]> - - - - - - June 30, 2000 - - - - named - 8 - BIND9 - - - - named - Internet domain name server - - - - - 2004 - 2005 - 2006 - 2007 - Internet Systems Consortium, Inc. ("ISC") - - - 2000 - 2001 - 2003 - Internet Software Consortium. - - - - - - named - - - - - - - - - - - - - - - - - - - DESCRIPTION - named - is a Domain Name System (DNS) server, - part of the BIND 9 distribution from ISC. For more - information on the DNS, see RFCs 1033, 1034, and 1035. - - - When invoked without arguments, named - will - read the default configuration file - /etc/named.conf, read any initial - data, and listen for queries. - - - - - OPTIONS - - - - -4 - - - Use IPv4 only even if the host machine is capable of IPv6. - and are mutually - exclusive. - - - - - - -6 - - - Use IPv6 only even if the host machine is capable of IPv4. - and are mutually - exclusive. - - - - - -c config-file - - - Use config-file as the - configuration file instead of the default, - /etc/named.conf. To - ensure that reloading the configuration file continues - to work after the server has changed its working - directory due to to a possible - option in the configuration - file, config-file should be - an absolute pathname. - - - - - - -d debug-level - - - Set the daemon's debug level to debug-level. - Debugging traces from named become - more verbose as the debug level increases. - - - - - - -f - - - Run the server in the foreground (i.e. do not daemonize). - - - - - - -g - - - Run the server in the foreground and force all logging - to stderr. - - - - - - -m flag - - - Turn on memory usage debugging flags. Possible flags are - usage, - trace, - record, - size, and - mctx. - These correspond to the ISC_MEM_DEBUGXXXX flags described in - <isc/mem.h>. - - - - - - -n #cpus - - - Create #cpus worker threads - to take advantage of multiple CPUs. If not specified, - named will try to determine the - number of CPUs present and create one thread per CPU. - If it is unable to determine the number of CPUs, a - single worker thread will be created. - - - - - - -p port - - - Listen for queries on port port. If not - specified, the default is port 53. - - - - - - -s - - - Write memory usage statistics to stdout on exit. - - - - This option is mainly of interest to BIND 9 developers - and may be removed or changed in a future release. - - - - - - - -t directory - - Chroot - to directory after - processing the command line arguments, but before - reading the configuration file. - - - - This option should be used in conjunction with the - option, as chrooting a process - running as root doesn't enhance security on most - systems; the way chroot(2) is - defined allows a process with root privileges to - escape a chroot jail. - - - - - - - -u user - - Setuid - to user after completing - privileged operations, such as creating sockets that - listen on privileged ports. - - - - On Linux, named uses the kernel's - capability mechanism to drop all root privileges - except the ability to bind(2) to - a - privileged port and set process resource limits. - Unfortunately, this means that the - option only works when named is - run - on kernel 2.2.18 or later, or kernel 2.3.99-pre3 or - later, since previous kernels did not allow privileges - to be retained after setuid(2). - - - - - - - -v - - - Report the version number and exit. - - - - - - -x cache-file - - - Load data from cache-file into the - cache of the default view. - - - - This option must not be used. It is only of interest - to BIND 9 developers and may be removed or changed in a - future release. - - - - - - - - - - - SIGNALS - - In routine operation, signals should not be used to control - the nameserver; rndc should be used - instead. - - - - - - SIGHUP - - - Force a reload of the server. - - - - - - SIGINT, SIGTERM - - - Shut down the server. - - - - - - - - The result of sending any other signals to the server is undefined. - - - - - - CONFIGURATION - - The named configuration file is too complex - to describe in detail here. A complete description is provided - in the - BIND 9 Administrator Reference Manual. - - - - - FILES - - - - - /etc/named.conf - - - The default configuration file. - - - - - - /var/run/named.pid - - - The default process-id file. - - - - - - - - - - SEE ALSO - RFC 1033, - RFC 1034, - RFC 1035, - - named-checkconf - 8 - , - - named-checkzone - 8 - , - - rndc - 8 - , - - lwresd - 8 - , - - named.conf - 5 - , - BIND 9 Administrator Reference Manual. - - - - - AUTHOR - Internet Systems Consortium - - - - diff --git a/contrib/bind9/bin/named/named.html b/contrib/bind9/bin/named/named.html deleted file mode 100644 index 294ecce..0000000 --- a/contrib/bind9/bin/named/named.html +++ /dev/null @@ -1,255 +0,0 @@ - - - - - -named - - -
-
-
-

Name

-

named — Internet domain name server

-
-
-

Synopsis

-

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

-
-
-

DESCRIPTION

-

named - is a Domain Name System (DNS) server, - part of the BIND 9 distribution from ISC. For more - information on the DNS, see RFCs 1033, 1034, and 1035. -

-

- When invoked without arguments, named - will - read the default configuration file - /etc/named.conf, read any initial - data, and listen for queries. -

-
-
-

OPTIONS

-
-
-4
-

- Use IPv4 only even if the host machine is capable of IPv6. - -4 and -6 are mutually - exclusive. -

-
-6
-

- Use IPv6 only even if the host machine is capable of IPv4. - -4 and -6 are mutually - exclusive. -

-
-c config-file
-

- Use config-file as the - configuration file instead of the default, - /etc/named.conf. To - ensure that reloading the configuration file continues - to work after the server has changed its working - directory due to to a possible - directory option in the configuration - file, config-file should be - an absolute pathname. -

-
-d debug-level
-

- Set the daemon's debug level to debug-level. - Debugging traces from named become - more verbose as the debug level increases. -

-
-f
-

- Run the server in the foreground (i.e. do not daemonize). -

-
-g
-

- Run the server in the foreground and force all logging - to stderr. -

-
-m flag
-

- Turn on memory usage debugging flags. Possible flags are - usage, - trace, - record, - size, and - mctx. - These correspond to the ISC_MEM_DEBUGXXXX flags described in - <isc/mem.h>. -

-
-n #cpus
-

- Create #cpus worker threads - to take advantage of multiple CPUs. If not specified, - named will try to determine the - number of CPUs present and create one thread per CPU. - If it is unable to determine the number of CPUs, a - single worker thread will be created. -

-
-p port
-

- Listen for queries on port port. If not - specified, the default is port 53. -

-
-s
-
-

- Write memory usage statistics to stdout on exit. -

-
-

Note

-

- This option is mainly of interest to BIND 9 developers - and may be removed or changed in a future release. -

-
-
-
-t directory
-
-

Chroot - to directory after - processing the command line arguments, but before - reading the configuration file. -

-
-

Warning

-

- This option should be used in conjunction with the - -u option, as chrooting a process - running as root doesn't enhance security on most - systems; the way chroot(2) is - defined allows a process with root privileges to - escape a chroot jail. -

-
-
-
-u user
-
-

Setuid - to user after completing - privileged operations, such as creating sockets that - listen on privileged ports. -

-
-

Note

-

- On Linux, named uses the kernel's - capability mechanism to drop all root privileges - except the ability to bind(2) to - a - privileged port and set process resource limits. - Unfortunately, this means that the -u - option only works when named is - run - on kernel 2.2.18 or later, or kernel 2.3.99-pre3 or - later, since previous kernels did not allow privileges - to be retained after setuid(2). -

-
-
-
-v
-

- Report the version number and exit. -

-
-x cache-file
-
-

- Load data from cache-file into the - cache of the default view. -

-
-

Warning

-

- This option must not be used. It is only of interest - to BIND 9 developers and may be removed or changed in a - future release. -

-
-
-
-
-
-

SIGNALS

-

- In routine operation, signals should not be used to control - the nameserver; rndc should be used - instead. -

-
-
SIGHUP
-

- Force a reload of the server. -

-
SIGINT, SIGTERM
-

- Shut down the server. -

-
-

- The result of sending any other signals to the server is undefined. -

-
-
-

CONFIGURATION

-

- The named configuration file is too complex - to describe in detail here. A complete description is provided - in the - BIND 9 Administrator Reference Manual. -

-
-
-

FILES

-
-
/etc/named.conf
-

- The default configuration file. -

-
/var/run/named.pid
-

- The default process-id file. -

-
-
-
-

SEE ALSO

-

RFC 1033, - RFC 1034, - RFC 1035, - named-checkconf(8), - named-checkzone(8), - rndc(8), - lwresd(8), - named.conf(5), - BIND 9 Administrator Reference Manual. -

-
-
-

AUTHOR

-

Internet Systems Consortium -

-
-
- diff --git a/contrib/bind9/bin/named/notify.c b/contrib/bind9/bin/named/notify.c deleted file mode 100644 index db2be71..0000000 --- a/contrib/bind9/bin/named/notify.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: notify.c,v 1.30.18.3 2005/04/29 00:15:26 marka Exp $ */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -/*! \file - * \brief - * This module implements notify as in RFC1996. - */ - -static void -notify_log(ns_client_t *client, int level, const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - ns_client_logv(client, DNS_LOGCATEGORY_NOTIFY, NS_LOGMODULE_NOTIFY, - level, fmt, ap); - va_end(ap); -} - -static void -respond(ns_client_t *client, isc_result_t result) { - dns_rcode_t rcode; - dns_message_t *message; - isc_result_t msg_result; - - message = client->message; - rcode = dns_result_torcode(result); - - msg_result = dns_message_reply(message, ISC_TRUE); - if (msg_result != ISC_R_SUCCESS) - msg_result = dns_message_reply(message, ISC_FALSE); - if (msg_result != ISC_R_SUCCESS) { - ns_client_next(client, msg_result); - return; - } - message->rcode = rcode; - if (rcode == dns_rcode_noerror) - message->flags |= DNS_MESSAGEFLAG_AA; - else - message->flags &= ~DNS_MESSAGEFLAG_AA; - ns_client_send(client); -} - -void -ns_notify_start(ns_client_t *client) { - dns_message_t *request = client->message; - isc_result_t result; - dns_name_t *zonename; - dns_rdataset_t *zone_rdataset; - dns_zone_t *zone = NULL; - char namebuf[DNS_NAME_FORMATSIZE]; - char tsigbuf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")]; - dns_name_t *tsigname; - - /* - * Interpret the question section. - */ - result = dns_message_firstname(request, DNS_SECTION_QUESTION); - if (result != ISC_R_SUCCESS) { - notify_log(client, ISC_LOG_NOTICE, - "notify question section empty"); - goto formerr; - } - - /* - * The question section must contain exactly one question. - */ - zonename = NULL; - dns_message_currentname(request, DNS_SECTION_QUESTION, &zonename); - zone_rdataset = ISC_LIST_HEAD(zonename->list); - if (ISC_LIST_NEXT(zone_rdataset, link) != NULL) { - notify_log(client, ISC_LOG_NOTICE, - "notify question section contains multiple RRs"); - goto formerr; - } - - /* The zone section must have exactly one name. */ - result = dns_message_nextname(request, DNS_SECTION_ZONE); - if (result != ISC_R_NOMORE) { - notify_log(client, ISC_LOG_NOTICE, - "notify question section contains multiple RRs"); - goto formerr; - } - - /* The one rdataset must be an SOA. */ - if (zone_rdataset->type != dns_rdatatype_soa) { - notify_log(client, ISC_LOG_NOTICE, - "notify question section contains no SOA"); - goto formerr; - } - - tsigname = NULL; - if (dns_message_gettsig(request, &tsigname) != NULL) { - dns_name_format(tsigname, namebuf, sizeof(namebuf)); - snprintf(tsigbuf, sizeof(tsigbuf), ": TSIG '%s'", namebuf); - } else - tsigbuf[0] = '\0'; - dns_name_format(zonename, namebuf, sizeof(namebuf)); - result = dns_zt_find(client->view->zonetable, zonename, 0, NULL, - &zone); - if (result != ISC_R_SUCCESS) - goto notauth; - - switch (dns_zone_gettype(zone)) { - case dns_zone_master: - case dns_zone_slave: - case dns_zone_stub: /* Allow dialup passive to work. */ - notify_log(client, ISC_LOG_INFO, - "received notify for zone '%s'%s", namebuf, tsigbuf); - respond(client, dns_zone_notifyreceive(zone, - ns_client_getsockaddr(client), request)); - break; - default: - goto notauth; - } - dns_zone_detach(&zone); - return; - - notauth: - notify_log(client, ISC_LOG_NOTICE, - "received notify for zone '%s'%s: not authoritative", - namebuf, tsigbuf); - result = DNS_R_NOTAUTH; - goto failure; - - formerr: - result = DNS_R_FORMERR; - - failure: - if (zone != NULL) - dns_zone_detach(&zone); - respond(client, result); -} diff --git a/contrib/bind9/bin/named/query.c b/contrib/bind9/bin/named/query.c deleted file mode 100644 index 38eb9a1..0000000 --- a/contrib/bind9/bin/named/query.c +++ /dev/null @@ -1,4603 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-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: query.c,v 1.257.18.40 2007/09/26 03:08:14 each Exp $ */ - -/*! \file */ - -#include - -#include - -#include -#include - -#include -#include -#include -#ifdef DLZ -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/*% Partial answer? */ -#define PARTIALANSWER(c) (((c)->query.attributes & \ - NS_QUERYATTR_PARTIALANSWER) != 0) -/*% Use Cache? */ -#define USECACHE(c) (((c)->query.attributes & \ - NS_QUERYATTR_CACHEOK) != 0) -/*% Recursion OK? */ -#define RECURSIONOK(c) (((c)->query.attributes & \ - NS_QUERYATTR_RECURSIONOK) != 0) -/*% Recursing? */ -#define RECURSING(c) (((c)->query.attributes & \ - NS_QUERYATTR_RECURSING) != 0) -/*% Cache glue ok? */ -#define CACHEGLUEOK(c) (((c)->query.attributes & \ - NS_QUERYATTR_CACHEGLUEOK) != 0) -/*% Want Recursion? */ -#define WANTRECURSION(c) (((c)->query.attributes & \ - NS_QUERYATTR_WANTRECURSION) != 0) -/*% Want DNSSEC? */ -#define WANTDNSSEC(c) (((c)->attributes & \ - NS_CLIENTATTR_WANTDNSSEC) != 0) -/*% No authority? */ -#define NOAUTHORITY(c) (((c)->query.attributes & \ - NS_QUERYATTR_NOAUTHORITY) != 0) -/*% No additional? */ -#define NOADDITIONAL(c) (((c)->query.attributes & \ - NS_QUERYATTR_NOADDITIONAL) != 0) -/*% Secure? */ -#define SECURE(c) (((c)->query.attributes & \ - NS_QUERYATTR_SECURE) != 0) - -#if 0 -#define CTRACE(m) isc_log_write(ns_g_lctx, \ - NS_LOGCATEGORY_CLIENT, \ - NS_LOGMODULE_QUERY, \ - ISC_LOG_DEBUG(3), \ - "client %p: %s", client, (m)) -#define QTRACE(m) isc_log_write(ns_g_lctx, \ - NS_LOGCATEGORY_GENERAL, \ - NS_LOGMODULE_QUERY, \ - ISC_LOG_DEBUG(3), \ - "query %p: %s", query, (m)) -#else -#define CTRACE(m) ((void)m) -#define QTRACE(m) ((void)m) -#endif - -#define DNS_GETDB_NOEXACT 0x01U -#define DNS_GETDB_NOLOG 0x02U -#define DNS_GETDB_PARTIAL 0x04U - -typedef struct client_additionalctx { - ns_client_t *client; - dns_rdataset_t *rdataset; -} client_additionalctx_t; - -static void -query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype); - -static isc_boolean_t -validate(ns_client_t *client, dns_db_t *db, dns_name_t *name, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); - -/*% - * Increment query statistics counters. - */ -static inline void -inc_stats(ns_client_t *client, dns_statscounter_t counter) { - dns_zone_t *zone = client->query.authzone; - - REQUIRE(counter < DNS_STATS_NCOUNTERS); - - ns_g_server->querystats[counter]++; - - if (zone != NULL) { - isc_uint64_t *zonestats = dns_zone_getstatscounters(zone); - if (zonestats != NULL) - zonestats[counter]++; - } -} - -static void -query_send(ns_client_t *client) { - dns_statscounter_t counter; - if (client->message->rcode == dns_rcode_noerror) { - if (ISC_LIST_EMPTY(client->message->sections[DNS_SECTION_ANSWER])) { - if (client->query.isreferral) { - counter = dns_statscounter_referral; - } else { - counter = dns_statscounter_nxrrset; - } - } else { - counter = dns_statscounter_success; - } - } else if (client->message->rcode == dns_rcode_nxdomain) { - counter = dns_statscounter_nxdomain; - } else { - /* We end up here in case of YXDOMAIN, and maybe others */ - counter = dns_statscounter_failure; - } - inc_stats(client, counter); - ns_client_send(client); -} - -static void -query_error(ns_client_t *client, isc_result_t result) { - inc_stats(client, dns_statscounter_failure); - ns_client_error(client, result); -} - -static void -query_next(ns_client_t *client, isc_result_t result) { - if (result == DNS_R_DUPLICATE) - inc_stats(client, dns_statscounter_duplicate); - else if (result == DNS_R_DROP) - inc_stats(client, dns_statscounter_dropped); - else - inc_stats(client, dns_statscounter_failure); - ns_client_next(client, result); -} - -static inline void -query_freefreeversions(ns_client_t *client, isc_boolean_t everything) { - ns_dbversion_t *dbversion, *dbversion_next; - unsigned int i; - - for (dbversion = ISC_LIST_HEAD(client->query.freeversions), i = 0; - dbversion != NULL; - dbversion = dbversion_next, i++) - { - dbversion_next = ISC_LIST_NEXT(dbversion, link); - /* - * If we're not freeing everything, we keep the first three - * dbversions structures around. - */ - if (i > 3 || everything) { - ISC_LIST_UNLINK(client->query.freeversions, dbversion, - link); - isc_mem_put(client->mctx, dbversion, - sizeof(*dbversion)); - } - } -} - -void -ns_query_cancel(ns_client_t *client) { - LOCK(&client->query.fetchlock); - if (client->query.fetch != NULL) { - dns_resolver_cancelfetch(client->query.fetch); - - client->query.fetch = NULL; - } - UNLOCK(&client->query.fetchlock); -} - -static inline void -query_reset(ns_client_t *client, isc_boolean_t everything) { - isc_buffer_t *dbuf, *dbuf_next; - ns_dbversion_t *dbversion, *dbversion_next; - - /*% - * Reset the query state of a client to its default state. - */ - - /* - * Cancel the fetch if it's running. - */ - ns_query_cancel(client); - - /* - * Cleanup any active versions. - */ - for (dbversion = ISC_LIST_HEAD(client->query.activeversions); - dbversion != NULL; - dbversion = dbversion_next) { - dbversion_next = ISC_LIST_NEXT(dbversion, link); - dns_db_closeversion(dbversion->db, &dbversion->version, - ISC_FALSE); - dns_db_detach(&dbversion->db); - ISC_LIST_INITANDAPPEND(client->query.freeversions, - dbversion, link); - } - ISC_LIST_INIT(client->query.activeversions); - - if (client->query.authdb != NULL) - dns_db_detach(&client->query.authdb); - if (client->query.authzone != NULL) - dns_zone_detach(&client->query.authzone); - - query_freefreeversions(client, everything); - - for (dbuf = ISC_LIST_HEAD(client->query.namebufs); - dbuf != NULL; - dbuf = dbuf_next) { - dbuf_next = ISC_LIST_NEXT(dbuf, link); - if (dbuf_next != NULL || everything) { - ISC_LIST_UNLINK(client->query.namebufs, dbuf, link); - isc_buffer_free(&dbuf); - } - } - - if (client->query.restarts > 0) { - /* - * client->query.qname was dynamically allocated. - */ - dns_message_puttempname(client->message, - &client->query.qname); - } - client->query.qname = NULL; - client->query.attributes = (NS_QUERYATTR_RECURSIONOK | - NS_QUERYATTR_CACHEOK | - NS_QUERYATTR_SECURE); - client->query.restarts = 0; - client->query.timerset = ISC_FALSE; - client->query.origqname = NULL; - client->query.qname = NULL; - client->query.dboptions = 0; - client->query.fetchoptions = 0; - client->query.gluedb = NULL; - client->query.authdbset = ISC_FALSE; - client->query.isreferral = ISC_FALSE; -} - -static void -query_next_callback(ns_client_t *client) { - query_reset(client, ISC_FALSE); -} - -void -ns_query_free(ns_client_t *client) { - query_reset(client, ISC_TRUE); -} - -static inline isc_result_t -query_newnamebuf(ns_client_t *client) { - isc_buffer_t *dbuf; - isc_result_t result; - - CTRACE("query_newnamebuf"); - /*% - * Allocate a name buffer. - */ - - dbuf = NULL; - result = isc_buffer_allocate(client->mctx, &dbuf, 1024); - if (result != ISC_R_SUCCESS) { - CTRACE("query_newnamebuf: isc_buffer_allocate failed: done"); - return (result); - } - ISC_LIST_APPEND(client->query.namebufs, dbuf, link); - - CTRACE("query_newnamebuf: done"); - return (ISC_R_SUCCESS); -} - -static inline isc_buffer_t * -query_getnamebuf(ns_client_t *client) { - isc_buffer_t *dbuf; - isc_result_t result; - isc_region_t r; - - CTRACE("query_getnamebuf"); - /*% - * Return a name buffer with space for a maximal name, allocating - * a new one if necessary. - */ - - if (ISC_LIST_EMPTY(client->query.namebufs)) { - result = query_newnamebuf(client); - if (result != ISC_R_SUCCESS) { - CTRACE("query_getnamebuf: query_newnamebuf failed: done"); - return (NULL); - } - } - - dbuf = ISC_LIST_TAIL(client->query.namebufs); - INSIST(dbuf != NULL); - isc_buffer_availableregion(dbuf, &r); - if (r.length < 255) { - result = query_newnamebuf(client); - if (result != ISC_R_SUCCESS) { - CTRACE("query_getnamebuf: query_newnamebuf failed: done"); - return (NULL); - - } - dbuf = ISC_LIST_TAIL(client->query.namebufs); - isc_buffer_availableregion(dbuf, &r); - INSIST(r.length >= 255); - } - CTRACE("query_getnamebuf: done"); - return (dbuf); -} - -static inline void -query_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf) { - isc_region_t r; - - CTRACE("query_keepname"); - /*% - * 'name' is using space in 'dbuf', but 'dbuf' has not yet been - * adjusted to take account of that. We do the adjustment. - */ - - REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) != 0); - - dns_name_toregion(name, &r); - isc_buffer_add(dbuf, r.length); - dns_name_setbuffer(name, NULL); - client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED; -} - -static inline void -query_releasename(ns_client_t *client, dns_name_t **namep) { - dns_name_t *name = *namep; - - /*% - * 'name' is no longer needed. Return it to our pool of temporary - * names. If it is using a name buffer, relinquish its exclusive - * rights on the buffer. - */ - - CTRACE("query_releasename"); - if (dns_name_hasbuffer(name)) { - INSIST((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) - != 0); - client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED; - } - dns_message_puttempname(client->message, namep); - CTRACE("query_releasename: done"); -} - -static inline dns_name_t * -query_newname(ns_client_t *client, isc_buffer_t *dbuf, - isc_buffer_t *nbuf) -{ - dns_name_t *name; - isc_region_t r; - isc_result_t result; - - REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) == 0); - - CTRACE("query_newname"); - name = NULL; - result = dns_message_gettempname(client->message, &name); - if (result != ISC_R_SUCCESS) { - CTRACE("query_newname: dns_message_gettempname failed: done"); - return (NULL); - } - isc_buffer_availableregion(dbuf, &r); - isc_buffer_init(nbuf, r.base, r.length); - dns_name_init(name, NULL); - dns_name_setbuffer(name, nbuf); - client->query.attributes |= NS_QUERYATTR_NAMEBUFUSED; - - CTRACE("query_newname: done"); - return (name); -} - -static inline dns_rdataset_t * -query_newrdataset(ns_client_t *client) { - dns_rdataset_t *rdataset; - isc_result_t result; - - CTRACE("query_newrdataset"); - rdataset = NULL; - result = dns_message_gettemprdataset(client->message, &rdataset); - if (result != ISC_R_SUCCESS) { - CTRACE("query_newrdataset: " - "dns_message_gettemprdataset failed: done"); - return (NULL); - } - dns_rdataset_init(rdataset); - - CTRACE("query_newrdataset: done"); - return (rdataset); -} - -static inline void -query_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) { - dns_rdataset_t *rdataset = *rdatasetp; - - CTRACE("query_putrdataset"); - if (rdataset != NULL) { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - dns_message_puttemprdataset(client->message, rdatasetp); - } - CTRACE("query_putrdataset: done"); -} - - -static inline isc_result_t -query_newdbversion(ns_client_t *client, unsigned int n) { - unsigned int i; - ns_dbversion_t *dbversion; - - for (i = 0; i < n; i++) { - dbversion = isc_mem_get(client->mctx, sizeof(*dbversion)); - if (dbversion != NULL) { - dbversion->db = NULL; - dbversion->version = NULL; - ISC_LIST_INITANDAPPEND(client->query.freeversions, - dbversion, link); - } else { - /* - * We only return ISC_R_NOMEMORY if we couldn't - * allocate anything. - */ - if (i == 0) - return (ISC_R_NOMEMORY); - else - return (ISC_R_SUCCESS); - } - } - - return (ISC_R_SUCCESS); -} - -static inline ns_dbversion_t * -query_getdbversion(ns_client_t *client) { - isc_result_t result; - ns_dbversion_t *dbversion; - - if (ISC_LIST_EMPTY(client->query.freeversions)) { - result = query_newdbversion(client, 1); - if (result != ISC_R_SUCCESS) - return (NULL); - } - dbversion = ISC_LIST_HEAD(client->query.freeversions); - INSIST(dbversion != NULL); - ISC_LIST_UNLINK(client->query.freeversions, dbversion, link); - - return (dbversion); -} - -isc_result_t -ns_query_init(ns_client_t *client) { - isc_result_t result; - - ISC_LIST_INIT(client->query.namebufs); - ISC_LIST_INIT(client->query.activeversions); - ISC_LIST_INIT(client->query.freeversions); - client->query.restarts = 0; - client->query.timerset = ISC_FALSE; - client->query.qname = NULL; - result = isc_mutex_init(&client->query.fetchlock); - if (result != ISC_R_SUCCESS) - return (result); - client->query.fetch = NULL; - client->query.authdb = NULL; - client->query.authzone = NULL; - client->query.authdbset = ISC_FALSE; - client->query.isreferral = ISC_FALSE; - query_reset(client, ISC_FALSE); - result = query_newdbversion(client, 3); - if (result != ISC_R_SUCCESS) { - DESTROYLOCK(&client->query.fetchlock); - return (result); - } - result = query_newnamebuf(client); - if (result != ISC_R_SUCCESS) - query_freefreeversions(client, ISC_TRUE); - - return (result); -} - -static inline ns_dbversion_t * -query_findversion(ns_client_t *client, dns_db_t *db, - isc_boolean_t *newzonep) -{ - ns_dbversion_t *dbversion; - - /*% - * We may already have done a query related to this - * database. If so, we must be sure to make subsequent - * queries from the same version. - */ - for (dbversion = ISC_LIST_HEAD(client->query.activeversions); - dbversion != NULL; - dbversion = ISC_LIST_NEXT(dbversion, link)) { - if (dbversion->db == db) - break; - } - - if (dbversion == NULL) { - /* - * This is a new zone for this query. Add it to - * the active list. - */ - dbversion = query_getdbversion(client); - if (dbversion == NULL) - return (NULL); - dns_db_attach(db, &dbversion->db); - dns_db_currentversion(db, &dbversion->version); - dbversion->queryok = ISC_FALSE; - ISC_LIST_APPEND(client->query.activeversions, - dbversion, link); - *newzonep = ISC_TRUE; - } else - *newzonep = ISC_FALSE; - - return (dbversion); -} - -static inline isc_result_t -query_validatezonedb(ns_client_t *client, dns_name_t *name, - dns_rdatatype_t qtype, unsigned int options, - dns_zone_t *zone, dns_db_t *db, - dns_dbversion_t **versionp) -{ - isc_result_t result; - isc_boolean_t check_acl, new_zone; - dns_acl_t *queryacl; - ns_dbversion_t *dbversion; - - REQUIRE(zone != NULL); - REQUIRE(db != NULL); - - /* - * This limits our searching to the zone where the first name - * (the query target) was looked for. This prevents following - * CNAMES or DNAMES into other zones and prevents returning - * additional data from other zones. - */ - if (!client->view->additionalfromauth && - client->query.authdbset && - db != client->query.authdb) - goto refuse; - - /* - * If the zone has an ACL, we'll check it, otherwise - * we use the view's "allow-query" ACL. Each ACL is only checked - * once per query. - * - * Also, get the database version to use. - */ - - check_acl = ISC_TRUE; /* Keep compiler happy. */ - queryacl = NULL; - - /* - * Get the current version of this database. - */ - dbversion = query_findversion(client, db, &new_zone); - if (dbversion == NULL) { - result = DNS_R_SERVFAIL; - goto fail; - } - if (new_zone) { - check_acl = ISC_TRUE; - } else if (!dbversion->queryok) { - goto refuse; - } else { - check_acl = ISC_FALSE; - } - - queryacl = dns_zone_getqueryacl(zone); - if (queryacl == NULL) { - queryacl = client->view->queryacl; - if ((client->query.attributes & - NS_QUERYATTR_QUERYOKVALID) != 0) { - /* - * We've evaluated the view's queryacl already. If - * NS_QUERYATTR_QUERYOK is set, then the client is - * allowed to make queries, otherwise the query should - * be refused. - */ - check_acl = ISC_FALSE; - if ((client->query.attributes & - NS_QUERYATTR_QUERYOK) == 0) - goto refuse; - } else { - /* - * We haven't evaluated the view's queryacl yet. - */ - check_acl = ISC_TRUE; - } - } - - if (check_acl) { - isc_boolean_t log = ISC_TF((options & DNS_GETDB_NOLOG) == 0); - - result = ns_client_checkaclsilent(client, queryacl, ISC_TRUE); - if (log) { - char msg[NS_CLIENT_ACLMSGSIZE("query")]; - if (result == ISC_R_SUCCESS) { - if (isc_log_wouldlog(ns_g_lctx, - ISC_LOG_DEBUG(3))) - { - ns_client_aclmsg("query", name, qtype, - client->view->rdclass, - msg, sizeof(msg)); - ns_client_log(client, - DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, - ISC_LOG_DEBUG(3), - "%s approved", msg); - } - } else { - ns_client_aclmsg("query", name, qtype, - client->view->rdclass, - msg, sizeof(msg)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "%s denied", msg); - } - } - - if (queryacl == client->view->queryacl) { - if (result == ISC_R_SUCCESS) { - /* - * We were allowed by the default - * "allow-query" ACL. Remember this so we - * don't have to check again. - */ - client->query.attributes |= - NS_QUERYATTR_QUERYOK; - } - /* - * We've now evaluated the view's query ACL, and - * the NS_QUERYATTR_QUERYOK attribute is now valid. - */ - client->query.attributes |= NS_QUERYATTR_QUERYOKVALID; - } - - if (result != ISC_R_SUCCESS) - goto refuse; - } - - /* Approved. */ - - /* - * Remember the result of the ACL check so we - * don't have to check again. - */ - dbversion->queryok = ISC_TRUE; - - /* Transfer ownership, if necessary. */ - if (versionp != NULL) - *versionp = dbversion->version; - - return (ISC_R_SUCCESS); - - refuse: - return (DNS_R_REFUSED); - - fail: - return (result); -} - -static inline isc_result_t -query_getzonedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, - unsigned int options, dns_zone_t **zonep, dns_db_t **dbp, - dns_dbversion_t **versionp) -{ - isc_result_t result; - unsigned int ztoptions; - dns_zone_t *zone = NULL; - dns_db_t *db = NULL; - isc_boolean_t partial = ISC_FALSE; - - REQUIRE(zonep != NULL && *zonep == NULL); - REQUIRE(dbp != NULL && *dbp == NULL); - - /*% - * Find a zone database to answer the query. - */ - ztoptions = ((options & DNS_GETDB_NOEXACT) != 0) ? - DNS_ZTFIND_NOEXACT : 0; - - result = dns_zt_find(client->view->zonetable, name, ztoptions, NULL, - &zone); - if (result == DNS_R_PARTIALMATCH) - partial = ISC_TRUE; - if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) - result = dns_zone_getdb(zone, &db); - - if (result != ISC_R_SUCCESS) - goto fail; - - result = query_validatezonedb(client, name, qtype, options, zone, db, - versionp); - - if (result != ISC_R_SUCCESS) - goto fail; - - /* Transfer ownership. */ - *zonep = zone; - *dbp = db; - - if (partial && (options & DNS_GETDB_PARTIAL) != 0) - return (DNS_R_PARTIALMATCH); - return (ISC_R_SUCCESS); - - fail: - if (zone != NULL) - dns_zone_detach(&zone); - if (db != NULL) - dns_db_detach(&db); - - return (result); -} - -static inline isc_result_t -query_getcachedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, - dns_db_t **dbp, unsigned int options) -{ - isc_result_t result; - isc_boolean_t check_acl; - dns_db_t *db = NULL; - - REQUIRE(dbp != NULL && *dbp == NULL); - - /*% - * Find a cache database to answer the query. - * This may fail with DNS_R_REFUSED if the client - * is not allowed to use the cache. - */ - - if (!USECACHE(client)) - return (DNS_R_REFUSED); - dns_db_attach(client->view->cachedb, &db); - - if ((client->query.attributes & - NS_QUERYATTR_QUERYOKVALID) != 0) { - /* - * We've evaluated the view's queryacl already. If - * NS_QUERYATTR_QUERYOK is set, then the client is - * allowed to make queries, otherwise the query should - * be refused. - */ - check_acl = ISC_FALSE; - if ((client->query.attributes & - NS_QUERYATTR_QUERYOK) == 0) - goto refuse; - } else { - /* - * We haven't evaluated the view's queryacl yet. - */ - check_acl = ISC_TRUE; - } - - if (check_acl) { - isc_boolean_t log = ISC_TF((options & DNS_GETDB_NOLOG) == 0); - char msg[NS_CLIENT_ACLMSGSIZE("query (cache)")]; - - result = ns_client_checkaclsilent(client, - client->view->queryacl, - ISC_TRUE); - if (result == ISC_R_SUCCESS) { - /* - * We were allowed by the default - * "allow-query" ACL. Remember this so we - * don't have to check again. - */ - client->query.attributes |= - NS_QUERYATTR_QUERYOK; - if (log && isc_log_wouldlog(ns_g_lctx, - ISC_LOG_DEBUG(3))) - { - ns_client_aclmsg("query (cache)", name, qtype, - client->view->rdclass, - msg, sizeof(msg)); - ns_client_log(client, - DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, - ISC_LOG_DEBUG(3), - "%s approved", msg); - } - } else if (log) { - ns_client_aclmsg("query (cache)", name, qtype, - client->view->rdclass, msg, - sizeof(msg)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "%s denied", msg); - } - /* - * We've now evaluated the view's query ACL, and - * the NS_QUERYATTR_QUERYOK attribute is now valid. - */ - client->query.attributes |= NS_QUERYATTR_QUERYOKVALID; - - if (result != ISC_R_SUCCESS) - goto refuse; - } - - /* Approved. */ - - /* Transfer ownership. */ - *dbp = db; - - return (ISC_R_SUCCESS); - - refuse: - result = DNS_R_REFUSED; - - if (db != NULL) - dns_db_detach(&db); - - return (result); -} - - -static inline isc_result_t -query_getdb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, - unsigned int options, dns_zone_t **zonep, dns_db_t **dbp, - dns_dbversion_t **versionp, isc_boolean_t *is_zonep) -{ - isc_result_t result; - -#ifdef DLZ - isc_result_t tresult; - unsigned int namelabels; - unsigned int zonelabels; - dns_zone_t *zone = NULL; - dns_db_t *tdbp; - - REQUIRE(zonep != NULL && *zonep == NULL); - - tdbp = NULL; - - /* Calculate how many labels are in name. */ - namelabels = dns_name_countlabels(name); - zonelabels = 0; - - /* Try to find name in bind's standard database. */ - result = query_getzonedb(client, name, qtype, options, &zone, - dbp, versionp); - - /* See how many labels are in the zone's name. */ - if (result == ISC_R_SUCCESS && zone != NULL) - zonelabels = dns_name_countlabels(dns_zone_getorigin(zone)); - /* - * If # zone labels < # name labels, try to find an even better match - * Only try if a DLZ driver is loaded for this view - */ - if (zonelabels < namelabels && client->view->dlzdatabase != NULL) { - tresult = dns_dlzfindzone(client->view, name, - zonelabels, &tdbp); - /* If we successful, we found a better match. */ - if (tresult == ISC_R_SUCCESS) { - /* - * If the previous search returned a zone, detach it. - */ - if (zone != NULL) - dns_zone_detach(&zone); - - /* - * If the previous search returned a database, - * detach it. - */ - if (*dbp != NULL) - dns_db_detach(dbp); - - /* - * If the previous search returned a version, clear it. - */ - *versionp = NULL; - - /* - * Get our database version. - */ - dns_db_currentversion(tdbp, versionp); - - /* - * Be sure to return our database. - */ - *dbp = tdbp; - - /* - * We return a null zone, No stats for DLZ zones. - */ - zone = NULL; - result = tresult; - } - } -#else - result = query_getzonedb(client, name, qtype, options, - zonep, dbp, versionp); -#endif - - /* If successfull, Transfer ownership of zone. */ - if (result == ISC_R_SUCCESS) { -#ifdef DLZ - *zonep = zone; -#endif - /* - * If neither attempt above succeeded, return the cache instead - */ - *is_zonep = ISC_TRUE; - } else if (result == ISC_R_NOTFOUND) { - result = query_getcachedb(client, name, qtype, dbp, options); - *is_zonep = ISC_FALSE; - } - return (result); -} - -static inline isc_boolean_t -query_isduplicate(ns_client_t *client, dns_name_t *name, - dns_rdatatype_t type, dns_name_t **mnamep) -{ - dns_section_t section; - dns_name_t *mname = NULL; - isc_result_t result; - - CTRACE("query_isduplicate"); - - for (section = DNS_SECTION_ANSWER; - section <= DNS_SECTION_ADDITIONAL; - section++) { - result = dns_message_findname(client->message, section, - name, type, 0, &mname, NULL); - if (result == ISC_R_SUCCESS) { - /* - * We've already got this RRset in the response. - */ - CTRACE("query_isduplicate: true: done"); - return (ISC_TRUE); - } else if (result == DNS_R_NXRRSET) { - /* - * The name exists, but the rdataset does not. - */ - if (section == DNS_SECTION_ADDITIONAL) - break; - } else - RUNTIME_CHECK(result == DNS_R_NXDOMAIN); - mname = NULL; - } - - /* - * If the dns_name_t we're looking up is already in the message, - * we don't want to trigger the caller's name replacement logic. - */ - if (name == mname) - mname = NULL; - - *mnamep = mname; - - CTRACE("query_isduplicate: false: done"); - return (ISC_FALSE); -} - -static isc_result_t -query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { - ns_client_t *client = arg; - isc_result_t result, eresult; - dns_dbnode_t *node; - dns_db_t *db; - dns_name_t *fname, *mname; - dns_rdataset_t *rdataset, *sigrdataset, *trdataset; - isc_buffer_t *dbuf; - isc_buffer_t b; - dns_dbversion_t *version; - isc_boolean_t added_something, need_addname; - dns_zone_t *zone; - dns_rdatatype_t type; - - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(qtype != dns_rdatatype_any); - - if (!WANTDNSSEC(client) && dns_rdatatype_isdnssec(qtype)) - return (ISC_R_SUCCESS); - - CTRACE("query_addadditional"); - - /* - * Initialization. - */ - eresult = ISC_R_SUCCESS; - fname = NULL; - rdataset = NULL; - sigrdataset = NULL; - trdataset = NULL; - db = NULL; - version = NULL; - node = NULL; - added_something = ISC_FALSE; - need_addname = ISC_FALSE; - zone = NULL; - - /* - * We treat type A additional section processing as if it - * were "any address type" additional section processing. - * To avoid multiple lookups, we do an 'any' database - * lookup and iterate over the node. - */ - if (qtype == dns_rdatatype_a) - type = dns_rdatatype_any; - else - type = qtype; - - /* - * Get some resources. - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - rdataset = query_newrdataset(client); - if (fname == NULL || rdataset == NULL) - goto cleanup; - if (WANTDNSSEC(client)) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) - goto cleanup; - } - - /* - * Look for a zone database that might contain authoritative - * additional data. - */ - result = query_getzonedb(client, name, qtype, DNS_GETDB_NOLOG, - &zone, &db, &version); - if (result != ISC_R_SUCCESS) - goto try_cache; - - CTRACE("query_addadditional: db_find"); - - /* - * Since we are looking for authoritative data, we do not set - * the GLUEOK flag. Glue will be looked for later, but not - * necessarily in the same database. - */ - node = NULL; - result = dns_db_find(db, name, version, type, client->query.dboptions, - client->now, &node, fname, rdataset, - sigrdataset); - if (result == ISC_R_SUCCESS) - goto found; - - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - version = NULL; - dns_db_detach(&db); - - /* - * No authoritative data was found. The cache is our next best bet. - */ - - try_cache: - result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG); - if (result != ISC_R_SUCCESS) - /* - * Most likely the client isn't allowed to query the cache. - */ - goto try_glue; - /* - * Attempt to validate glue. - */ - if (sigrdataset == NULL) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) - goto cleanup; - } - result = dns_db_find(db, name, version, type, - client->query.dboptions | DNS_DBFIND_GLUEOK, - client->now, &node, fname, rdataset, - sigrdataset); - if (result == DNS_R_GLUE && - validate(client, db, fname, rdataset, sigrdataset)) - result = ISC_R_SUCCESS; - if (!WANTDNSSEC(client)) - query_putrdataset(client, &sigrdataset); - if (result == ISC_R_SUCCESS) - goto found; - - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - dns_db_detach(&db); - - try_glue: - /* - * No cached data was found. Glue is our last chance. - * RFC1035 sayeth: - * - * NS records cause both the usual additional section - * processing to locate a type A record, and, when used - * in a referral, a special search of the zone in which - * they reside for glue information. - * - * This is the "special search". Note that we must search - * the zone where the NS record resides, not the zone it - * points to, and that we only do the search in the delegation - * case (identified by client->query.gluedb being set). - */ - - if (client->query.gluedb == NULL) - goto cleanup; - - /* - * Don't poision caches using the bailiwick protection model. - */ - if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb))) - goto cleanup; - - dns_db_attach(client->query.gluedb, &db); - result = dns_db_find(db, name, version, type, - client->query.dboptions | DNS_DBFIND_GLUEOK, - client->now, &node, fname, rdataset, - sigrdataset); - if (!(result == ISC_R_SUCCESS || - result == DNS_R_ZONECUT || - result == DNS_R_GLUE)) - goto cleanup; - - found: - /* - * We have found a potential additional data rdataset, or - * at least a node to iterate over. - */ - query_keepname(client, fname, dbuf); - - /* - * If we have an rdataset, add it to the additional data - * section. - */ - mname = NULL; - if (dns_rdataset_isassociated(rdataset) && - !query_isduplicate(client, fname, type, &mname)) { - if (mname != NULL) { - query_releasename(client, &fname); - fname = mname; - } else - need_addname = ISC_TRUE; - ISC_LIST_APPEND(fname->list, rdataset, link); - trdataset = rdataset; - rdataset = NULL; - added_something = ISC_TRUE; - /* - * Note: we only add SIGs if we've added the type they cover, - * so we do not need to check if the SIG rdataset is already - * in the response. - */ - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - { - ISC_LIST_APPEND(fname->list, sigrdataset, link); - sigrdataset = NULL; - } - } - - if (qtype == dns_rdatatype_a) { - /* - * We now go looking for A and AAAA records, along with - * their signatures. - * - * XXXRTH This code could be more efficient. - */ - if (rdataset != NULL) { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - } else { - rdataset = query_newrdataset(client); - if (rdataset == NULL) - goto addname; - } - if (sigrdataset != NULL) { - if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } else if (WANTDNSSEC(client)) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) - goto addname; - } - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_a, 0, - client->now, rdataset, - sigrdataset); - if (result == DNS_R_NCACHENXDOMAIN) - goto addname; - if (result == DNS_R_NCACHENXRRSET) { - dns_rdataset_disassociate(rdataset); - /* - * Negative cache entries don't have sigrdatasets. - */ - INSIST(sigrdataset == NULL || - ! dns_rdataset_isassociated(sigrdataset)); - } - if (result == ISC_R_SUCCESS) { - mname = NULL; - if (!query_isduplicate(client, fname, - dns_rdatatype_a, &mname)) { - if (mname != NULL) { - query_releasename(client, &fname); - fname = mname; - } else - need_addname = ISC_TRUE; - ISC_LIST_APPEND(fname->list, rdataset, link); - added_something = ISC_TRUE; - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - { - ISC_LIST_APPEND(fname->list, - sigrdataset, link); - sigrdataset = - query_newrdataset(client); - } - rdataset = query_newrdataset(client); - if (rdataset == NULL) - goto addname; - if (WANTDNSSEC(client) && sigrdataset == NULL) - goto addname; - } else { - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - } - } - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_aaaa, 0, - client->now, rdataset, - sigrdataset); - if (result == DNS_R_NCACHENXDOMAIN) - goto addname; - if (result == DNS_R_NCACHENXRRSET) { - dns_rdataset_disassociate(rdataset); - INSIST(sigrdataset == NULL || - ! dns_rdataset_isassociated(sigrdataset)); - } - if (result == ISC_R_SUCCESS) { - mname = NULL; - if (!query_isduplicate(client, fname, - dns_rdatatype_aaaa, &mname)) { - if (mname != NULL) { - query_releasename(client, &fname); - fname = mname; - } else - need_addname = ISC_TRUE; - ISC_LIST_APPEND(fname->list, rdataset, link); - added_something = ISC_TRUE; - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - { - ISC_LIST_APPEND(fname->list, - sigrdataset, link); - sigrdataset = NULL; - } - rdataset = NULL; - } - } - } - - addname: - CTRACE("query_addadditional: addname"); - /* - * If we haven't added anything, then we're done. - */ - if (!added_something) - goto cleanup; - - /* - * We may have added our rdatasets to an existing name, if so, then - * need_addname will be ISC_FALSE. Whether we used an existing name - * or a new one, we must set fname to NULL to prevent cleanup. - */ - if (need_addname) - dns_message_addname(client->message, fname, - DNS_SECTION_ADDITIONAL); - fname = NULL; - - /* - * In a few cases, we want to add additional data for additional - * data. It's simpler to just deal with special cases here than - * to try to create a general purpose mechanism and allow the - * rdata implementations to do it themselves. - * - * This involves recursion, but the depth is limited. The - * most complex case is adding a SRV rdataset, which involves - * recursing to add address records, which in turn can cause - * recursion to add KEYs. - */ - if (type == dns_rdatatype_srv && trdataset != NULL) { - /* - * If we're adding SRV records to the additional data - * section, it's helpful if we add the SRV additional data - * as well. - */ - eresult = dns_rdataset_additionaldata(trdataset, - query_addadditional, - client); - } - - cleanup: - CTRACE("query_addadditional: cleanup"); - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (fname != NULL) - query_releasename(client, &fname); - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - - CTRACE("query_addadditional: done"); - return (eresult); -} - -static inline void -query_discardcache(ns_client_t *client, dns_rdataset_t *rdataset_base, - dns_rdatasetadditional_t additionaltype, - dns_rdatatype_t type, dns_zone_t **zonep, dns_db_t **dbp, - dns_dbversion_t **versionp, dns_dbnode_t **nodep, - dns_name_t *fname) -{ - dns_rdataset_t *rdataset; - - while ((rdataset = ISC_LIST_HEAD(fname->list)) != NULL) { - ISC_LIST_UNLINK(fname->list, rdataset, link); - query_putrdataset(client, &rdataset); - } - if (*versionp != NULL) - dns_db_closeversion(*dbp, versionp, ISC_FALSE); - if (*nodep != NULL) - dns_db_detachnode(*dbp, nodep); - if (*dbp != NULL) - dns_db_detach(dbp); - if (*zonep != NULL) - dns_zone_detach(zonep); - (void)dns_rdataset_putadditional(client->view->acache, rdataset_base, - additionaltype, type); -} - -static inline isc_result_t -query_iscachevalid(dns_zone_t *zone, dns_db_t *db, dns_db_t *db0, - dns_dbversion_t *version) -{ - isc_result_t result = ISC_R_SUCCESS; - dns_dbversion_t *version_current = NULL; - dns_db_t *db_current = db0; - - if (db_current == NULL) { - result = dns_zone_getdb(zone, &db_current); - if (result != ISC_R_SUCCESS) - return (result); - } - dns_db_currentversion(db_current, &version_current); - if (db_current != db || version_current != version) { - result = ISC_R_FAILURE; - goto cleanup; - } - - cleanup: - dns_db_closeversion(db_current, &version_current, ISC_FALSE); - if (db0 == NULL && db_current != NULL) - dns_db_detach(&db_current); - - return (result); -} - -static isc_result_t -query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { - client_additionalctx_t *additionalctx = arg; - dns_rdataset_t *rdataset_base; - ns_client_t *client; - isc_result_t result, eresult; - dns_dbnode_t *node, *cnode; - dns_db_t *db, *cdb; - dns_name_t *fname, *mname0, cfname; - dns_rdataset_t *rdataset, *sigrdataset; - dns_rdataset_t *crdataset, *crdataset_next; - isc_buffer_t *dbuf; - isc_buffer_t b; - dns_dbversion_t *version, *cversion; - isc_boolean_t added_something, need_addname, needadditionalcache; - isc_boolean_t need_sigrrset; - dns_zone_t *zone; - dns_rdatatype_t type; - dns_rdatasetadditional_t additionaltype; - - if (qtype != dns_rdatatype_a) { - /* - * This function is optimized for "address" types. For other - * types, use a generic routine. - * XXX: ideally, this function should be generic enough. - */ - return (query_addadditional(additionalctx->client, - name, qtype)); - } - - /* - * Initialization. - */ - rdataset_base = additionalctx->rdataset; - client = additionalctx->client; - REQUIRE(NS_CLIENT_VALID(client)); - eresult = ISC_R_SUCCESS; - fname = NULL; - rdataset = NULL; - sigrdataset = NULL; - db = NULL; - cdb = NULL; - version = NULL; - cversion = NULL; - node = NULL; - cnode = NULL; - added_something = ISC_FALSE; - need_addname = ISC_FALSE; - zone = NULL; - needadditionalcache = ISC_FALSE; - additionaltype = dns_rdatasetadditional_fromauth; - dns_name_init(&cfname, NULL); - - CTRACE("query_addadditional2"); - - /* - * We treat type A additional section processing as if it - * were "any address type" additional section processing. - * To avoid multiple lookups, we do an 'any' database - * lookup and iterate over the node. - * XXXJT: this approach can cause a suboptimal result when the cache - * DB only has partial address types and the glue DB has remaining - * ones. - */ - type = dns_rdatatype_any; - - /* - * Get some resources. - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - if (fname == NULL) - goto cleanup; - dns_name_setbuffer(&cfname, &b); /* share the buffer */ - - /* Check additional cache */ - result = dns_rdataset_getadditional(rdataset_base, additionaltype, - type, client->view->acache, &zone, - &cdb, &cversion, &cnode, &cfname, - client->message, client->now); - if (result != ISC_R_SUCCESS) - goto findauthdb; - if (zone == NULL) { - CTRACE("query_addadditional2: auth zone not found"); - goto try_cache; - } - - /* Is the cached DB up-to-date? */ - result = query_iscachevalid(zone, cdb, NULL, cversion); - if (result != ISC_R_SUCCESS) { - CTRACE("query_addadditional2: old auth additional cache"); - query_discardcache(client, rdataset_base, additionaltype, - type, &zone, &cdb, &cversion, &cnode, - &cfname); - goto findauthdb; - } - - if (cnode == NULL) { - /* - * We have a negative cache. We don't have to check the zone - * ACL, since the result (not using this zone) would be same - * regardless of the result. - */ - CTRACE("query_addadditional2: negative auth additional cache"); - dns_db_closeversion(cdb, &cversion, ISC_FALSE); - dns_db_detach(&cdb); - dns_zone_detach(&zone); - goto try_cache; - } - - result = query_validatezonedb(client, name, qtype, DNS_GETDB_NOLOG, - zone, cdb, NULL); - if (result != ISC_R_SUCCESS) { - query_discardcache(client, rdataset_base, additionaltype, - type, &zone, &cdb, &cversion, &cnode, - &cfname); - goto try_cache; - } - - /* We've got an active cache. */ - CTRACE("query_addadditional2: auth additional cache"); - dns_db_closeversion(cdb, &cversion, ISC_FALSE); - db = cdb; - node = cnode; - dns_name_clone(&cfname, fname); - query_keepname(client, fname, dbuf); - goto foundcache; - - /* - * Look for a zone database that might contain authoritative - * additional data. - */ - findauthdb: - result = query_getzonedb(client, name, qtype, DNS_GETDB_NOLOG, - &zone, &db, &version); - if (result != ISC_R_SUCCESS) { - /* Cache the negative result */ - (void)dns_rdataset_setadditional(rdataset_base, additionaltype, - type, client->view->acache, - NULL, NULL, NULL, NULL, - NULL); - goto try_cache; - } - - CTRACE("query_addadditional2: db_find"); - - /* - * Since we are looking for authoritative data, we do not set - * the GLUEOK flag. Glue will be looked for later, but not - * necessarily in the same database. - */ - node = NULL; - result = dns_db_find(db, name, version, type, client->query.dboptions, - client->now, &node, fname, NULL, NULL); - if (result == ISC_R_SUCCESS) - goto found; - - /* Cache the negative result */ - (void)dns_rdataset_setadditional(rdataset_base, additionaltype, - type, client->view->acache, zone, db, - version, NULL, fname); - - if (node != NULL) - dns_db_detachnode(db, &node); - version = NULL; - dns_db_detach(&db); - - /* - * No authoritative data was found. The cache is our next best bet. - */ - - try_cache: - additionaltype = dns_rdatasetadditional_fromcache; - result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG); - if (result != ISC_R_SUCCESS) - /* - * Most likely the client isn't allowed to query the cache. - */ - goto try_glue; - - result = dns_db_find(db, name, version, type, - client->query.dboptions | DNS_DBFIND_GLUEOK, - client->now, &node, fname, NULL, NULL); - if (result == ISC_R_SUCCESS) - goto found; - - if (node != NULL) - dns_db_detachnode(db, &node); - dns_db_detach(&db); - - try_glue: - /* - * No cached data was found. Glue is our last chance. - * RFC1035 sayeth: - * - * NS records cause both the usual additional section - * processing to locate a type A record, and, when used - * in a referral, a special search of the zone in which - * they reside for glue information. - * - * This is the "special search". Note that we must search - * the zone where the NS record resides, not the zone it - * points to, and that we only do the search in the delegation - * case (identified by client->query.gluedb being set). - */ - if (client->query.gluedb == NULL) - goto cleanup; - - /* - * Don't poision caches using the bailiwick protection model. - */ - if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb))) - goto cleanup; - - /* Check additional cache */ - additionaltype = dns_rdatasetadditional_fromglue; - result = dns_rdataset_getadditional(rdataset_base, additionaltype, - type, client->view->acache, NULL, - &cdb, &cversion, &cnode, &cfname, - client->message, client->now); - if (result != ISC_R_SUCCESS) - goto findglue; - - result = query_iscachevalid(zone, cdb, client->query.gluedb, cversion); - if (result != ISC_R_SUCCESS) { - CTRACE("query_addadditional2: old glue additional cache"); - query_discardcache(client, rdataset_base, additionaltype, - type, &zone, &cdb, &cversion, &cnode, - &cfname); - goto findglue; - } - - if (cnode == NULL) { - /* We have a negative cache. */ - CTRACE("query_addadditional2: negative glue additional cache"); - dns_db_closeversion(cdb, &cversion, ISC_FALSE); - dns_db_detach(&cdb); - goto cleanup; - } - - /* Cache hit. */ - CTRACE("query_addadditional2: glue additional cache"); - dns_db_closeversion(cdb, &cversion, ISC_FALSE); - db = cdb; - node = cnode; - dns_name_clone(&cfname, fname); - query_keepname(client, fname, dbuf); - goto foundcache; - - findglue: - dns_db_attach(client->query.gluedb, &db); - result = dns_db_find(db, name, version, type, - client->query.dboptions | DNS_DBFIND_GLUEOK, - client->now, &node, fname, NULL, NULL); - if (!(result == ISC_R_SUCCESS || - result == DNS_R_ZONECUT || - result == DNS_R_GLUE)) { - /* cache the negative result */ - (void)dns_rdataset_setadditional(rdataset_base, additionaltype, - type, client->view->acache, - NULL, db, version, NULL, - fname); - goto cleanup; - } - - found: - /* - * We have found a DB node to iterate over from a DB. - * We are going to look for address RRsets (i.e., A and AAAA) in the DB - * node we've just found. We'll then store the complete information - * in the additional data cache. - */ - dns_name_clone(fname, &cfname); - query_keepname(client, fname, dbuf); - needadditionalcache = ISC_TRUE; - - rdataset = query_newrdataset(client); - if (rdataset == NULL) - goto cleanup; - - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) - goto cleanup; - - /* - * Find A RRset with sig RRset. Even if we don't find a sig RRset - * for a client using DNSSEC, we'll continue the process to make a - * complete list to be cached. However, we need to cancel the - * caching when something unexpected happens, in order to avoid - * caching incomplete information. - */ - result = dns_db_findrdataset(db, node, version, dns_rdatatype_a, 0, - client->now, rdataset, sigrdataset); - /* - * If we can't promote glue/pending from the cache to secure - * then drop it. - */ - if (result == ISC_R_SUCCESS && - additionaltype == dns_rdatasetadditional_fromcache && - (rdataset->trust == dns_trust_pending || - rdataset->trust == dns_trust_glue) && - !validate(client, db, fname, rdataset, sigrdataset)) { - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - result = ISC_R_NOTFOUND; - } - if (result == DNS_R_NCACHENXDOMAIN) - goto setcache; - if (result == DNS_R_NCACHENXRRSET) { - dns_rdataset_disassociate(rdataset); - /* - * Negative cache entries don't have sigrdatasets. - */ - INSIST(! dns_rdataset_isassociated(sigrdataset)); - } - if (result == ISC_R_SUCCESS) { - /* Remember the result as a cache */ - ISC_LIST_APPEND(cfname.list, rdataset, link); - if (dns_rdataset_isassociated(sigrdataset)) { - ISC_LIST_APPEND(cfname.list, sigrdataset, link); - sigrdataset = query_newrdataset(client); - } - rdataset = query_newrdataset(client); - if (sigrdataset == NULL || rdataset == NULL) { - /* do not cache incomplete information */ - goto foundcache; - } - } - - /* Find AAAA RRset with sig RRset */ - result = dns_db_findrdataset(db, node, version, dns_rdatatype_aaaa, - 0, client->now, rdataset, sigrdataset); - /* - * If we can't promote glue/pending from the cache to secure - * then drop it. - */ - if (result == ISC_R_SUCCESS && - additionaltype == dns_rdatasetadditional_fromcache && - (rdataset->trust == dns_trust_pending || - rdataset->trust == dns_trust_glue) && - !validate(client, db, fname, rdataset, sigrdataset)) { - dns_rdataset_disassociate(rdataset); - if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - result = ISC_R_NOTFOUND; - } - if (result == ISC_R_SUCCESS) { - ISC_LIST_APPEND(cfname.list, rdataset, link); - rdataset = NULL; - if (dns_rdataset_isassociated(sigrdataset)) { - ISC_LIST_APPEND(cfname.list, sigrdataset, link); - sigrdataset = NULL; - } - } - - setcache: - /* - * Set the new result in the cache if required. We do not support - * caching additional data from a cache DB. - */ - if (needadditionalcache == ISC_TRUE && - (additionaltype == dns_rdatasetadditional_fromauth || - additionaltype == dns_rdatasetadditional_fromglue)) { - (void)dns_rdataset_setadditional(rdataset_base, additionaltype, - type, client->view->acache, - zone, db, version, node, - &cfname); - } - - foundcache: - need_sigrrset = ISC_FALSE; - mname0 = NULL; - for (crdataset = ISC_LIST_HEAD(cfname.list); - crdataset != NULL; - crdataset = crdataset_next) { - dns_name_t *mname; - - crdataset_next = ISC_LIST_NEXT(crdataset, link); - - mname = NULL; - if (crdataset->type == dns_rdatatype_a || - crdataset->type == dns_rdatatype_aaaa) { - if (!query_isduplicate(client, fname, crdataset->type, - &mname)) { - if (mname != NULL) { - /* - * A different type of this name is - * already stored in the additional - * section. We'll reuse the name. - * Note that this should happen at most - * once. Otherwise, fname->link could - * leak below. - */ - INSIST(mname0 == NULL); - - query_releasename(client, &fname); - fname = mname; - mname0 = mname; - } else - need_addname = ISC_TRUE; - ISC_LIST_UNLINK(cfname.list, crdataset, link); - ISC_LIST_APPEND(fname->list, crdataset, link); - added_something = ISC_TRUE; - need_sigrrset = ISC_TRUE; - } else - need_sigrrset = ISC_FALSE; - } else if (crdataset->type == dns_rdatatype_rrsig && - need_sigrrset && WANTDNSSEC(client)) { - ISC_LIST_UNLINK(cfname.list, crdataset, link); - ISC_LIST_APPEND(fname->list, crdataset, link); - added_something = ISC_TRUE; /* just in case */ - need_sigrrset = ISC_FALSE; - } - } - - CTRACE("query_addadditional2: addname"); - - /* - * If we haven't added anything, then we're done. - */ - if (!added_something) - goto cleanup; - - /* - * We may have added our rdatasets to an existing name, if so, then - * need_addname will be ISC_FALSE. Whether we used an existing name - * or a new one, we must set fname to NULL to prevent cleanup. - */ - if (need_addname) - dns_message_addname(client->message, fname, - DNS_SECTION_ADDITIONAL); - fname = NULL; - - cleanup: - CTRACE("query_addadditional2: cleanup"); - - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - while ((crdataset = ISC_LIST_HEAD(cfname.list)) != NULL) { - ISC_LIST_UNLINK(cfname.list, crdataset, link); - query_putrdataset(client, &crdataset); - } - if (fname != NULL) - query_releasename(client, &fname); - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - - CTRACE("query_addadditional2: done"); - return (eresult); -} - -static inline void -query_addrdataset(ns_client_t *client, dns_name_t *fname, - dns_rdataset_t *rdataset) -{ - client_additionalctx_t additionalctx; - - /* - * Add 'rdataset' and any pertinent additional data to - * 'fname', a name in the response message for 'client'. - */ - - CTRACE("query_addrdataset"); - - ISC_LIST_APPEND(fname->list, rdataset, link); - - if (client->view->order != NULL) - rdataset->attributes |= dns_order_find(client->view->order, - fname, rdataset->type, - rdataset->rdclass); - rdataset->attributes |= DNS_RDATASETATTR_LOADORDER; - - if (NOADDITIONAL(client)) - return; - - /* - * Add additional data. - * - * We don't care if dns_rdataset_additionaldata() fails. - */ - additionalctx.client = client; - additionalctx.rdataset = rdataset; - (void)dns_rdataset_additionaldata(rdataset, query_addadditional2, - &additionalctx); - CTRACE("query_addrdataset: done"); -} - -static void -query_addrrset(ns_client_t *client, dns_name_t **namep, - dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp, - isc_buffer_t *dbuf, dns_section_t section) -{ - dns_name_t *name, *mname; - dns_rdataset_t *rdataset, *mrdataset, *sigrdataset; - isc_result_t result; - - /*% - * To the current response for 'client', add the answer RRset - * '*rdatasetp' and an optional signature set '*sigrdatasetp', with - * owner name '*namep', to section 'section', unless they are - * already there. Also add any pertinent additional data. - * - * If 'dbuf' is not NULL, then '*namep' is the name whose data is - * stored in 'dbuf'. In this case, query_addrrset() guarantees that - * when it returns the name will either have been kept or released. - */ - CTRACE("query_addrrset"); - name = *namep; - rdataset = *rdatasetp; - if (sigrdatasetp != NULL) - sigrdataset = *sigrdatasetp; - else - sigrdataset = NULL; - mname = NULL; - mrdataset = NULL; - result = dns_message_findname(client->message, section, - name, rdataset->type, rdataset->covers, - &mname, &mrdataset); - if (result == ISC_R_SUCCESS) { - /* - * We've already got an RRset of the given name and type. - * There's nothing else to do; - */ - CTRACE("query_addrrset: dns_message_findname succeeded: done"); - if (dbuf != NULL) - query_releasename(client, namep); - return; - } else if (result == DNS_R_NXDOMAIN) { - /* - * The name doesn't exist. - */ - if (dbuf != NULL) - query_keepname(client, name, dbuf); - dns_message_addname(client->message, name, section); - *namep = NULL; - mname = name; - } else { - RUNTIME_CHECK(result == DNS_R_NXRRSET); - if (dbuf != NULL) - query_releasename(client, namep); - } - - if (rdataset->trust != dns_trust_secure && - (section == DNS_SECTION_ANSWER || - section == DNS_SECTION_AUTHORITY)) - client->query.attributes &= ~NS_QUERYATTR_SECURE; - /* - * Note: we only add SIGs if we've added the type they cover, so - * we do not need to check if the SIG rdataset is already in the - * response. - */ - query_addrdataset(client, mname, rdataset); - *rdatasetp = NULL; - if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) { - /* - * We have a signature. Add it to the response. - */ - ISC_LIST_APPEND(mname->list, sigrdataset, link); - *sigrdatasetp = NULL; - } - CTRACE("query_addrrset: done"); -} - -static inline isc_result_t -query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version, - isc_boolean_t zero_ttl) -{ - dns_name_t *name; - dns_dbnode_t *node; - isc_result_t result, eresult; - dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; - dns_rdataset_t **sigrdatasetp = NULL; - - CTRACE("query_addsoa"); - /* - * Initialization. - */ - eresult = ISC_R_SUCCESS; - name = NULL; - rdataset = NULL; - node = NULL; - - /* - * Get resources and make 'name' be the database origin. - */ - result = dns_message_gettempname(client->message, &name); - if (result != ISC_R_SUCCESS) - return (result); - dns_name_init(name, NULL); - dns_name_clone(dns_db_origin(db), name); - rdataset = query_newrdataset(client); - if (rdataset == NULL) { - eresult = DNS_R_SERVFAIL; - goto cleanup; - } - if (WANTDNSSEC(client)) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) { - eresult = DNS_R_SERVFAIL; - goto cleanup; - } - } - - /* - * Find the SOA. - */ - result = dns_db_getoriginnode(db, &node); - if (result == ISC_R_SUCCESS) { - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_soa, - 0, client->now, rdataset, - sigrdataset); - } else { - dns_fixedname_t foundname; - dns_name_t *fname; - - dns_fixedname_init(&foundname); - fname = dns_fixedname_name(&foundname); - - result = dns_db_find(db, name, version, dns_rdatatype_soa, - client->query.dboptions, 0, &node, - fname, rdataset, sigrdataset); - } - if (result != ISC_R_SUCCESS) { - /* - * This is bad. We tried to get the SOA RR at the zone top - * and it didn't work! - */ - eresult = DNS_R_SERVFAIL; - } else { - /* - * Extract the SOA MINIMUM. - */ - dns_rdata_soa_t soa; - dns_rdata_t rdata = DNS_RDATA_INIT; - result = dns_rdataset_first(rdataset); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &soa, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - - if (zero_ttl) { - rdataset->ttl = 0; - if (sigrdataset != NULL) - sigrdataset->ttl = 0; - } - - /* - * Add the SOA and its SIG to the response, with the - * TTLs adjusted per RFC2308 section 3. - */ - if (rdataset->ttl > soa.minimum) - rdataset->ttl = soa.minimum; - if (sigrdataset != NULL && sigrdataset->ttl > soa.minimum) - sigrdataset->ttl = soa.minimum; - - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL, - DNS_SECTION_AUTHORITY); - } - - cleanup: - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (name != NULL) - query_releasename(client, &name); - if (node != NULL) - dns_db_detachnode(db, &node); - - return (eresult); -} - -static inline isc_result_t -query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) { - dns_name_t *name, *fname; - dns_dbnode_t *node; - isc_result_t result, eresult; - dns_fixedname_t foundname; - dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; - dns_rdataset_t **sigrdatasetp = NULL; - - CTRACE("query_addns"); - /* - * Initialization. - */ - eresult = ISC_R_SUCCESS; - name = NULL; - rdataset = NULL; - node = NULL; - dns_fixedname_init(&foundname); - fname = dns_fixedname_name(&foundname); - - /* - * Get resources and make 'name' be the database origin. - */ - result = dns_message_gettempname(client->message, &name); - if (result != ISC_R_SUCCESS) { - CTRACE("query_addns: dns_message_gettempname failed: done"); - return (result); - } - dns_name_init(name, NULL); - dns_name_clone(dns_db_origin(db), name); - rdataset = query_newrdataset(client); - if (rdataset == NULL) { - CTRACE("query_addns: query_newrdataset failed"); - eresult = DNS_R_SERVFAIL; - goto cleanup; - } - if (WANTDNSSEC(client)) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) { - CTRACE("query_addns: query_newrdataset failed"); - eresult = DNS_R_SERVFAIL; - goto cleanup; - } - } - - /* - * Find the NS rdataset. - */ - result = dns_db_getoriginnode(db, &node); - if (result == ISC_R_SUCCESS) { - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_ns, - 0, client->now, rdataset, - sigrdataset); - } else { - CTRACE("query_addns: calling dns_db_find"); - result = dns_db_find(db, name, NULL, dns_rdatatype_ns, - client->query.dboptions, 0, &node, - fname, rdataset, sigrdataset); - CTRACE("query_addns: dns_db_find complete"); - } - if (result != ISC_R_SUCCESS) { - CTRACE("query_addns: " - "dns_db_findrdataset or dns_db_find failed"); - /* - * This is bad. We tried to get the NS rdataset at the zone - * top and it didn't work! - */ - eresult = DNS_R_SERVFAIL; - } else { - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL, - DNS_SECTION_AUTHORITY); - } - - cleanup: - CTRACE("query_addns: cleanup"); - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (name != NULL) - query_releasename(client, &name); - if (node != NULL) - dns_db_detachnode(db, &node); - - CTRACE("query_addns: done"); - return (eresult); -} - -static inline isc_result_t -query_addcnamelike(ns_client_t *client, dns_name_t *qname, dns_name_t *tname, - dns_trust_t trust, dns_name_t **anamep, dns_rdatatype_t type) -{ - dns_rdataset_t *rdataset; - dns_rdatalist_t *rdatalist; - dns_rdata_t *rdata; - isc_result_t result; - isc_region_t r; - - /* - * We assume the name data referred to by tname won't go away. - */ - - REQUIRE(anamep != NULL); - - rdatalist = NULL; - result = dns_message_gettemprdatalist(client->message, &rdatalist); - if (result != ISC_R_SUCCESS) - return (result); - rdata = NULL; - result = dns_message_gettemprdata(client->message, &rdata); - if (result != ISC_R_SUCCESS) - return (result); - rdataset = NULL; - result = dns_message_gettemprdataset(client->message, &rdataset); - if (result != ISC_R_SUCCESS) - return (result); - dns_rdataset_init(rdataset); - result = dns_name_dup(qname, client->mctx, *anamep); - if (result != ISC_R_SUCCESS) { - dns_message_puttemprdataset(client->message, &rdataset); - return (result); - } - - rdatalist->type = type; - rdatalist->covers = 0; - rdatalist->rdclass = client->message->rdclass; - rdatalist->ttl = 0; - - dns_name_toregion(tname, &r); - rdata->data = r.base; - rdata->length = r.length; - rdata->rdclass = client->message->rdclass; - rdata->type = type; - - ISC_LIST_INIT(rdatalist->rdata); - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) - == ISC_R_SUCCESS); - rdataset->trust = trust; - - query_addrrset(client, anamep, &rdataset, NULL, NULL, - DNS_SECTION_ANSWER); - - if (rdataset != NULL) { - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - dns_message_puttemprdataset(client->message, &rdataset); - } - - return (ISC_R_SUCCESS); -} - -/* - * Mark the RRsets as secure. Update the cache (db) to reflect the - * change in trust level. - */ -static void -mark_secure(ns_client_t *client, dns_db_t *db, dns_name_t *name, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - isc_result_t result; - dns_dbnode_t *node = NULL; - - rdataset->trust = dns_trust_secure; - sigrdataset->trust = dns_trust_secure; - - /* - * Save the updated secure state. Ignore failures. - */ - result = dns_db_findnode(db, name, ISC_TRUE, &node); - if (result != ISC_R_SUCCESS) - return; - (void)dns_db_addrdataset(db, node, NULL, client->now, rdataset, - 0, NULL); - (void)dns_db_addrdataset(db, node, NULL, client->now, sigrdataset, - 0, NULL); - dns_db_detachnode(db, &node); -} - -/* - * Find the secure key that corresponds to rrsig. - * Note: 'keyrdataset' maintains state between sucessive calls, - * there may be multiple keys with the same keyid. - * Return ISC_FALSE if we have exhausted all the possible keys. - */ -static isc_boolean_t -get_key(ns_client_t *client, dns_db_t *db, dns_rdata_rrsig_t *rrsig, - dns_rdataset_t *keyrdataset, dst_key_t **keyp) -{ - isc_result_t result; - dns_dbnode_t *node = NULL; - isc_boolean_t secure = ISC_FALSE; - - if (!dns_rdataset_isassociated(keyrdataset)) { - result = dns_db_findnode(db, &rrsig->signer, ISC_FALSE, &node); - if (result != ISC_R_SUCCESS) - return (ISC_FALSE); - - result = dns_db_findrdataset(db, node, NULL, - dns_rdatatype_dnskey, 0, - client->now, keyrdataset, NULL); - dns_db_detachnode(db, &node); - if (result != ISC_R_SUCCESS) - return (ISC_FALSE); - - if (keyrdataset->trust != dns_trust_secure) - return (ISC_FALSE); - - result = dns_rdataset_first(keyrdataset); - } else - result = dns_rdataset_next(keyrdataset); - - for ( ; result == ISC_R_SUCCESS; - result = dns_rdataset_next(keyrdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - isc_buffer_t b; - - dns_rdataset_current(keyrdataset, &rdata); - isc_buffer_init(&b, rdata.data, rdata.length); - isc_buffer_add(&b, rdata.length); - result = dst_key_fromdns(&rrsig->signer, rdata.rdclass, &b, - client->mctx, keyp); - if (result != ISC_R_SUCCESS) - continue; - if (rrsig->algorithm == (dns_secalg_t)dst_key_alg(*keyp) && - rrsig->keyid == (dns_keytag_t)dst_key_id(*keyp) && - dst_key_iszonekey(*keyp)) { - secure = ISC_TRUE; - break; - } - dst_key_free(keyp); - } - return (secure); -} - -static isc_boolean_t -verify(dst_key_t *key, dns_name_t *name, dns_rdataset_t *rdataset, - dns_rdata_t *rdata, isc_mem_t *mctx, isc_boolean_t acceptexpired) -{ - isc_result_t result; - dns_fixedname_t fixed; - isc_boolean_t ignore = ISC_FALSE; - - dns_fixedname_init(&fixed); - -again: - result = dns_dnssec_verify2(name, rdataset, key, ignore, mctx, - rdata, NULL); - if (result == DNS_R_SIGEXPIRED && acceptexpired) { - ignore = ISC_TRUE; - goto again; - } - if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD) - return (ISC_TRUE); - return (ISC_FALSE); -} - -/* - * Validate the rdataset if possible with available records. - */ -static isc_boolean_t -validate(ns_client_t *client, dns_db_t *db, dns_name_t *name, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - isc_result_t result; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_rrsig_t rrsig; - dst_key_t *key = NULL; - dns_rdataset_t keyrdataset; - - if (sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset)) - return (ISC_FALSE); - - for (result = dns_rdataset_first(sigrdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(sigrdataset)) { - - dns_rdata_reset(&rdata); - dns_rdataset_current(sigrdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &rrsig, NULL); - if (result != ISC_R_SUCCESS) - return (ISC_FALSE); - if (!dns_resolver_algorithm_supported(client->view->resolver, - name, rrsig.algorithm)) - continue; - if (!dns_name_issubdomain(name, &rrsig.signer)) - continue; - dns_rdataset_init(&keyrdataset); - do { - if (!get_key(client, db, &rrsig, &keyrdataset, &key)) - break; - if (verify(key, name, rdataset, &rdata, client->mctx, - client->view->acceptexpired)) { - dst_key_free(&key); - dns_rdataset_disassociate(&keyrdataset); - mark_secure(client, db, name, rdataset, - sigrdataset); - return (ISC_TRUE); - } - dst_key_free(&key); - } while (1); - if (dns_rdataset_isassociated(&keyrdataset)) - dns_rdataset_disassociate(&keyrdataset); - } - return (ISC_FALSE); -} - -static void -query_addbestns(ns_client_t *client) { - dns_db_t *db, *zdb; - dns_dbnode_t *node; - dns_name_t *fname, *zfname; - dns_rdataset_t *rdataset, *sigrdataset, *zrdataset, *zsigrdataset; - isc_boolean_t is_zone, use_zone; - isc_buffer_t *dbuf; - isc_result_t result; - dns_dbversion_t *version; - dns_zone_t *zone; - isc_buffer_t b; - - CTRACE("query_addbestns"); - fname = NULL; - zfname = NULL; - rdataset = NULL; - zrdataset = NULL; - sigrdataset = NULL; - zsigrdataset = NULL; - node = NULL; - db = NULL; - zdb = NULL; - version = NULL; - zone = NULL; - is_zone = ISC_FALSE; - use_zone = ISC_FALSE; - - /* - * Find the right database. - */ - result = query_getdb(client, client->query.qname, dns_rdatatype_ns, 0, - &zone, &db, &version, &is_zone); - if (result != ISC_R_SUCCESS) - goto cleanup; - - db_find: - /* - * We'll need some resources... - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - rdataset = query_newrdataset(client); - if (fname == NULL || rdataset == NULL) - goto cleanup; - /* - * Get the RRSIGs if the client requested them or if we may - * need to validate answers from the cache. - */ - if (WANTDNSSEC(client) || !is_zone) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) - goto cleanup; - } - - /* - * Now look for the zonecut. - */ - if (is_zone) { - result = dns_db_find(db, client->query.qname, version, - dns_rdatatype_ns, client->query.dboptions, - client->now, &node, fname, - rdataset, sigrdataset); - if (result != DNS_R_DELEGATION) - goto cleanup; - if (USECACHE(client)) { - query_keepname(client, fname, dbuf); - zdb = db; - zfname = fname; - fname = NULL; - zrdataset = rdataset; - rdataset = NULL; - zsigrdataset = sigrdataset; - sigrdataset = NULL; - dns_db_detachnode(db, &node); - version = NULL; - db = NULL; - dns_db_attach(client->view->cachedb, &db); - is_zone = ISC_FALSE; - goto db_find; - } - } else { - result = dns_db_findzonecut(db, client->query.qname, - client->query.dboptions, - client->now, &node, fname, - rdataset, sigrdataset); - if (result == ISC_R_SUCCESS) { - if (zfname != NULL && - !dns_name_issubdomain(fname, zfname)) { - /* - * We found a zonecut in the cache, but our - * zone delegation is better. - */ - use_zone = ISC_TRUE; - } - } else if (result == ISC_R_NOTFOUND && zfname != NULL) { - /* - * We didn't find anything in the cache, but we - * have a zone delegation, so use it. - */ - use_zone = ISC_TRUE; - } else - goto cleanup; - } - - if (use_zone) { - query_releasename(client, &fname); - fname = zfname; - zfname = NULL; - /* - * We've already done query_keepname() on - * zfname, so we must set dbuf to NULL to - * prevent query_addrrset() from trying to - * call query_keepname() again. - */ - dbuf = NULL; - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - rdataset = zrdataset; - zrdataset = NULL; - sigrdataset = zsigrdataset; - zsigrdataset = NULL; - } - - /* - * Attempt to validate RRsets that are pending or that are glue. - */ - if ((rdataset->trust == dns_trust_pending || - (sigrdataset != NULL && sigrdataset->trust == dns_trust_pending)) - && !validate(client, db, fname, rdataset, sigrdataset) && - (client->query.dboptions & DNS_DBFIND_PENDINGOK) == 0) - goto cleanup; - - if ((rdataset->trust == dns_trust_glue || - (sigrdataset != NULL && sigrdataset->trust == dns_trust_glue)) && - !validate(client, db, fname, rdataset, sigrdataset) && - SECURE(client) && WANTDNSSEC(client)) - goto cleanup; - - /* - * If the client doesn't want DNSSEC we can discard the sigrdataset - * now. - */ - if (!WANTDNSSEC(client)) - query_putrdataset(client, &sigrdataset); - query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf, - DNS_SECTION_AUTHORITY); - - cleanup: - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (fname != NULL) - query_releasename(client, &fname); - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - if (zdb != NULL) { - query_putrdataset(client, &zrdataset); - if (zsigrdataset != NULL) - query_putrdataset(client, &zsigrdataset); - if (zfname != NULL) - query_releasename(client, &zfname); - dns_db_detach(&zdb); - } -} - -static void -query_addds(ns_client_t *client, dns_db_t *db, dns_dbnode_t *node, - dns_dbversion_t *version) -{ - dns_name_t *rname; - dns_rdataset_t *rdataset, *sigrdataset; - isc_result_t result; - - CTRACE("query_addds"); - rname = NULL; - rdataset = NULL; - sigrdataset = NULL; - - /* - * We'll need some resources... - */ - rdataset = query_newrdataset(client); - sigrdataset = query_newrdataset(client); - if (rdataset == NULL || sigrdataset == NULL) - goto cleanup; - - /* - * Look for the DS record, which may or may not be present. - */ - result = dns_db_findrdataset(db, node, version, dns_rdatatype_ds, 0, - client->now, rdataset, sigrdataset); - /* - * If we didn't find it, look for an NSEC. */ - if (result == ISC_R_NOTFOUND) - result = dns_db_findrdataset(db, node, version, - dns_rdatatype_nsec, 0, client->now, - rdataset, sigrdataset); - if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) - goto cleanup; - if (!dns_rdataset_isassociated(rdataset) || - !dns_rdataset_isassociated(sigrdataset)) - goto cleanup; - - /* - * We've already added the NS record, so if the name's not there, - * we have other problems. Use this name rather than calling - * query_addrrset(). - */ - result = dns_message_firstname(client->message, DNS_SECTION_AUTHORITY); - if (result != ISC_R_SUCCESS) - goto cleanup; - - rname = NULL; - dns_message_currentname(client->message, DNS_SECTION_AUTHORITY, - &rname); - result = dns_message_findtype(rname, dns_rdatatype_ns, 0, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - - ISC_LIST_APPEND(rname->list, rdataset, link); - ISC_LIST_APPEND(rname->list, sigrdataset, link); - rdataset = NULL; - sigrdataset = NULL; - - cleanup: - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); -} - -static void -query_addwildcardproof(ns_client_t *client, dns_db_t *db, - dns_dbversion_t *version, dns_name_t *name, - isc_boolean_t ispositive) -{ - isc_buffer_t *dbuf, b; - dns_name_t *fname; - dns_rdataset_t *rdataset, *sigrdataset; - dns_fixedname_t wfixed; - dns_name_t *wname; - dns_dbnode_t *node; - unsigned int options; - unsigned int olabels, nlabels; - isc_result_t result; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_nsec_t nsec; - isc_boolean_t have_wname; - int order; - - CTRACE("query_addwildcardproof"); - fname = NULL; - rdataset = NULL; - sigrdataset = NULL; - node = NULL; - - /* - * Get the NOQNAME proof then if !ispositve - * get the NOWILDCARD proof. - * - * DNS_DBFIND_NOWILD finds the NSEC records that covers the - * name ignoring any wildcard. From the owner and next names - * of this record you can compute which wildcard (if it exists) - * will match by finding the longest common suffix of the - * owner name and next names with the qname and prefixing that - * with the wildcard label. - * - * e.g. - * Given: - * example SOA - * example NSEC b.example - * b.example A - * b.example NSEC a.d.example - * a.d.example A - * a.d.example NSEC g.f.example - * g.f.example A - * g.f.example NSEC z.i.example - * z.i.example A - * z.i.example NSEC example - * - * QNAME: - * a.example -> example NSEC b.example - * owner common example - * next common example - * wild *.example - * d.b.example -> b.example NSEC a.d.example - * owner common b.example - * next common example - * wild *.b.example - * a.f.example -> a.d.example NSEC g.f.example - * owner common example - * next common f.example - * wild *.f.example - * j.example -> z.i.example NSEC example - * owner common example - * next common example - * wild *.f.example - */ - options = client->query.dboptions | DNS_DBFIND_NOWILD; - dns_fixedname_init(&wfixed); - wname = dns_fixedname_name(&wfixed); - again: - have_wname = ISC_FALSE; - /* - * We'll need some resources... - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - rdataset = query_newrdataset(client); - sigrdataset = query_newrdataset(client); - if (fname == NULL || rdataset == NULL || sigrdataset == NULL) - goto cleanup; - - result = dns_db_find(db, name, version, dns_rdatatype_nsec, options, - 0, &node, fname, rdataset, sigrdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - if (result == DNS_R_NXDOMAIN) { - if (!ispositive) - result = dns_rdataset_first(rdataset); - if (result == ISC_R_SUCCESS) { - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &nsec, NULL); - } - if (result == ISC_R_SUCCESS) { - (void)dns_name_fullcompare(name, fname, &order, - &olabels); - (void)dns_name_fullcompare(name, &nsec.next, &order, - &nlabels); - if (olabels > nlabels) - dns_name_split(name, olabels, NULL, wname); - else - dns_name_split(name, nlabels, NULL, wname); - result = dns_name_concatenate(dns_wildcardname, - wname, wname, NULL); - if (result == ISC_R_SUCCESS) - have_wname = ISC_TRUE; - dns_rdata_freestruct(&nsec); - } - query_addrrset(client, &fname, &rdataset, &sigrdataset, - dbuf, DNS_SECTION_AUTHORITY); - } - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (fname != NULL) - query_releasename(client, &fname); - if (have_wname) { - ispositive = ISC_TRUE; /* prevent loop */ - if (!dns_name_equal(name, wname)) { - name = wname; - goto again; - } - } - cleanup: - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (fname != NULL) - query_releasename(client, &fname); -} - -static void -query_addnxrrsetnsec(ns_client_t *client, dns_db_t *db, - dns_dbversion_t *version, dns_name_t **namep, - dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp) -{ - dns_name_t *name; - dns_rdataset_t *sigrdataset; - dns_rdata_t sigrdata; - dns_rdata_rrsig_t sig; - unsigned int labels; - isc_buffer_t *dbuf, b; - dns_name_t *fname; - isc_result_t result; - - name = *namep; - if ((name->attributes & DNS_NAMEATTR_WILDCARD) == 0) { - query_addrrset(client, namep, rdatasetp, sigrdatasetp, - NULL, DNS_SECTION_AUTHORITY); - return; - } - - if (sigrdatasetp == NULL) - return; - sigrdataset = *sigrdatasetp; - if (sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset)) - return; - result = dns_rdataset_first(sigrdataset); - if (result != ISC_R_SUCCESS) - return; - dns_rdata_init(&sigrdata); - dns_rdataset_current(sigrdataset, &sigrdata); - result = dns_rdata_tostruct(&sigrdata, &sig, NULL); - if (result != ISC_R_SUCCESS) - return; - - labels = dns_name_countlabels(name); - if ((unsigned int)sig.labels + 1 >= labels) - return; - - /* XXX */ - query_addwildcardproof(client, db, version, client->query.qname, - ISC_TRUE); - - /* - * We'll need some resources... - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - return; - fname = query_newname(client, dbuf, &b); - if (fname == NULL) - return; - dns_name_split(name, sig.labels + 1, NULL, fname); - /* This will succeed, since we've stripped labels. */ - RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname, fname, fname, - NULL) == ISC_R_SUCCESS); - query_addrrset(client, &fname, rdatasetp, sigrdatasetp, - dbuf, DNS_SECTION_AUTHORITY); -} - -static void -query_resume(isc_task_t *task, isc_event_t *event) { - dns_fetchevent_t *devent = (dns_fetchevent_t *)event; - ns_client_t *client; - isc_boolean_t fetch_cancelled, client_shuttingdown; - - /* - * Resume a query after recursion. - */ - - UNUSED(task); - - REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); - client = devent->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - REQUIRE(RECURSING(client)); - - LOCK(&client->query.fetchlock); - if (client->query.fetch != NULL) { - /* - * This is the fetch we've been waiting for. - */ - INSIST(devent->fetch == client->query.fetch); - client->query.fetch = NULL; - fetch_cancelled = ISC_FALSE; - /* - * Update client->now. - */ - isc_stdtime_get(&client->now); - } else { - /* - * This is a fetch completion event for a cancelled fetch. - * Clean up and don't resume the find. - */ - fetch_cancelled = ISC_TRUE; - } - UNLOCK(&client->query.fetchlock); - INSIST(client->query.fetch == NULL); - - client->query.attributes &= ~NS_QUERYATTR_RECURSING; - dns_resolver_destroyfetch(&devent->fetch); - - /* - * If this client is shutting down, or this transaction - * has timed out, do not resume the find. - */ - client_shuttingdown = ns_client_shuttingdown(client); - if (fetch_cancelled || client_shuttingdown) { - if (devent->node != NULL) - dns_db_detachnode(devent->db, &devent->node); - if (devent->db != NULL) - dns_db_detach(&devent->db); - query_putrdataset(client, &devent->rdataset); - if (devent->sigrdataset != NULL) - query_putrdataset(client, &devent->sigrdataset); - isc_event_free(&event); - if (fetch_cancelled) - query_error(client, DNS_R_SERVFAIL); - else - query_next(client, ISC_R_CANCELED); - /* - * This may destroy the client. - */ - ns_client_detach(&client); - } else { - query_find(client, devent, 0); - } -} - -static isc_result_t -query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qdomain, - dns_rdataset_t *nameservers) -{ - isc_result_t result; - dns_rdataset_t *rdataset, *sigrdataset; - isc_sockaddr_t *peeraddr; - - inc_stats(client, dns_statscounter_recursion); - - /* - * We are about to recurse, which means that this client will - * be unavailable for serving new requests for an indeterminate - * amount of time. If this client is currently responsible - * for handling incoming queries, set up a new client - * object to handle them while we are waiting for a - * response. There is no need to replace TCP clients - * because those have already been replaced when the - * connection was accepted (if allowed by the TCP quota). - */ - if (client->recursionquota == NULL) { - result = isc_quota_attach(&ns_g_server->recursionquota, - &client->recursionquota); - if (result == ISC_R_SOFTQUOTA) { - static isc_stdtime_t last = 0; - isc_stdtime_t now; - isc_stdtime_get(&now); - if (now != last) { - last = now; - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, - ISC_LOG_WARNING, - "recursive-clients soft limit " - "exceeded, aborting oldest query"); - } - ns_client_killoldestquery(client); - result = ISC_R_SUCCESS; - } else if (result == ISC_R_QUOTA) { - static isc_stdtime_t last = 0; - isc_stdtime_t now; - isc_stdtime_get(&now); - if (now != last) { - last = now; - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, - ISC_LOG_WARNING, - "no more recursive clients: %s", - isc_result_totext(result)); - } - ns_client_killoldestquery(client); - } - if (result == ISC_R_SUCCESS && !client->mortal && - (client->attributes & NS_CLIENTATTR_TCP) == 0) { - result = ns_client_replace(client); - if (result != ISC_R_SUCCESS) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_QUERY, - ISC_LOG_WARNING, - "ns_client_replace() failed: %s", - isc_result_totext(result)); - isc_quota_detach(&client->recursionquota); - } - } - if (result != ISC_R_SUCCESS) - return (result); - ns_client_recursing(client); - } - - /* - * Invoke the resolver. - */ - REQUIRE(nameservers == NULL || nameservers->type == dns_rdatatype_ns); - REQUIRE(client->query.fetch == NULL); - - rdataset = query_newrdataset(client); - if (rdataset == NULL) - return (ISC_R_NOMEMORY); - if (WANTDNSSEC(client)) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) { - query_putrdataset(client, &rdataset); - return (ISC_R_NOMEMORY); - } - } else - sigrdataset = NULL; - - if (client->query.timerset == ISC_FALSE) - ns_client_settimeout(client, 60); - if ((client->attributes & NS_CLIENTATTR_TCP) == 0) - peeraddr = &client->peeraddr; - else - peeraddr = NULL; - result = dns_resolver_createfetch2(client->view->resolver, - client->query.qname, - qtype, qdomain, nameservers, - NULL, peeraddr, client->message->id, - client->query.fetchoptions, - client->task, - query_resume, client, - rdataset, sigrdataset, - &client->query.fetch); - - if (result == ISC_R_SUCCESS) { - /* - * Record that we're waiting for an event. A client which - * is shutting down will not be destroyed until all the - * events have been received. - */ - } else { - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - } - - return (result); -} - -#define MAX_RESTARTS 16 - -#define QUERY_ERROR(r) \ -do { \ - eresult = r; \ - want_restart = ISC_FALSE; \ -} while (0) - -/* - * Extract a network address from the RDATA of an A or AAAA - * record. - * - * Returns: - * ISC_R_SUCCESS - * ISC_R_NOTIMPLEMENTED The rdata is not a known address type. - */ -static isc_result_t -rdata_tonetaddr(const dns_rdata_t *rdata, isc_netaddr_t *netaddr) { - struct in_addr ina; - struct in6_addr in6a; - - switch (rdata->type) { - case dns_rdatatype_a: - INSIST(rdata->length == 4); - memcpy(&ina.s_addr, rdata->data, 4); - isc_netaddr_fromin(netaddr, &ina); - return (ISC_R_SUCCESS); - case dns_rdatatype_aaaa: - INSIST(rdata->length == 16); - memcpy(in6a.s6_addr, rdata->data, 16); - isc_netaddr_fromin6(netaddr, &in6a); - return (ISC_R_SUCCESS); - default: - return (ISC_R_NOTIMPLEMENTED); - } -} - -/* - * Find the sort order of 'rdata' in the topology-like - * ACL forming the second element in a 2-element top-level - * sortlist statement. - */ -static int -query_sortlist_order_2element(const dns_rdata_t *rdata, const void *arg) { - isc_netaddr_t netaddr; - - if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS) - return (INT_MAX); - return (ns_sortlist_addrorder2(&netaddr, arg)); -} - -/* - * Find the sort order of 'rdata' in the matching element - * of a 1-element top-level sortlist statement. - */ -static int -query_sortlist_order_1element(const dns_rdata_t *rdata, const void *arg) { - isc_netaddr_t netaddr; - - if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS) - return (INT_MAX); - return (ns_sortlist_addrorder1(&netaddr, arg)); -} - -/* - * Find the sortlist statement that applies to 'client' and set up - * the sortlist info in in client->message appropriately. - */ -static void -setup_query_sortlist(ns_client_t *client) { - isc_netaddr_t netaddr; - dns_rdatasetorderfunc_t order = NULL; - const void *order_arg = NULL; - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - switch (ns_sortlist_setup(client->view->sortlist, - &netaddr, &order_arg)) { - case NS_SORTLISTTYPE_1ELEMENT: - order = query_sortlist_order_1element; - break; - case NS_SORTLISTTYPE_2ELEMENT: - order = query_sortlist_order_2element; - break; - case NS_SORTLISTTYPE_NONE: - order = NULL; - break; - default: - INSIST(0); - break; - } - dns_message_setsortorder(client->message, order, order_arg); -} - -static void -query_addnoqnameproof(ns_client_t *client, dns_rdataset_t *rdataset) { - isc_buffer_t *dbuf, b; - dns_name_t *fname; - dns_rdataset_t *nsec, *nsecsig; - isc_result_t result = ISC_R_NOMEMORY; - - CTRACE("query_addnoqnameproof"); - - fname = NULL; - nsec = NULL; - nsecsig = NULL; - - dbuf = query_getnamebuf(client); - if (dbuf == NULL) - goto cleanup; - fname = query_newname(client, dbuf, &b); - nsec = query_newrdataset(client); - nsecsig = query_newrdataset(client); - if (fname == NULL || nsec == NULL || nsecsig == NULL) - goto cleanup; - - result = dns_rdataset_getnoqname(rdataset, fname, nsec, nsecsig); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - query_addrrset(client, &fname, &nsec, &nsecsig, dbuf, - DNS_SECTION_AUTHORITY); - - cleanup: - if (nsec != NULL) - query_putrdataset(client, &nsec); - if (nsecsig != NULL) - query_putrdataset(client, &nsecsig); - if (fname != NULL) - query_releasename(client, &fname); -} - -static inline void -answer_in_glue(ns_client_t *client, dns_rdatatype_t qtype) { - dns_name_t *name; - dns_message_t *msg; - dns_section_t section = DNS_SECTION_ADDITIONAL; - dns_rdataset_t *rdataset = NULL; - - msg = client->message; - for (name = ISC_LIST_HEAD(msg->sections[section]); - name != NULL; - name = ISC_LIST_NEXT(name, link)) - if (dns_name_equal(name, client->query.qname)) { - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) - if (rdataset->type == qtype) - break; - break; - } - if (rdataset != NULL) { - ISC_LIST_UNLINK(msg->sections[section], name, link); - ISC_LIST_PREPEND(msg->sections[section], name, link); - ISC_LIST_UNLINK(name->list, rdataset, link); - ISC_LIST_PREPEND(name->list, rdataset, link); - rdataset->attributes |= DNS_RDATASETATTR_REQUIREDGLUE; - } -} - -#define NS_NAME_INIT(A,B) \ - { \ - DNS_NAME_MAGIC, \ - A, sizeof(A), sizeof(B), \ - DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, \ - B, NULL, { (void *)-1, (void *)-1}, \ - {NULL, NULL} \ - } - -static unsigned char inaddr10_offsets[] = { 0, 3, 11, 16 }; -static unsigned char inaddr172_offsets[] = { 0, 3, 7, 15, 20 }; -static unsigned char inaddr192_offsets[] = { 0, 4, 8, 16, 21 }; - -static unsigned char inaddr10[] = "\00210\007IN-ADDR\004ARPA"; - -static unsigned char inaddr16172[] = "\00216\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr17172[] = "\00217\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr18172[] = "\00218\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr19172[] = "\00219\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr20172[] = "\00220\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr21172[] = "\00221\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr22172[] = "\00222\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr23172[] = "\00223\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr24172[] = "\00224\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr25172[] = "\00225\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr26172[] = "\00226\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr27172[] = "\00227\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr28172[] = "\00228\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr29172[] = "\00229\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr30172[] = "\00230\003172\007IN-ADDR\004ARPA"; -static unsigned char inaddr31172[] = "\00231\003172\007IN-ADDR\004ARPA"; - -static unsigned char inaddr168192[] = "\003168\003192\007IN-ADDR\004ARPA"; - -static dns_name_t rfc1918names[] = { - NS_NAME_INIT(inaddr10, inaddr10_offsets), - NS_NAME_INIT(inaddr16172, inaddr172_offsets), - NS_NAME_INIT(inaddr17172, inaddr172_offsets), - NS_NAME_INIT(inaddr18172, inaddr172_offsets), - NS_NAME_INIT(inaddr19172, inaddr172_offsets), - NS_NAME_INIT(inaddr20172, inaddr172_offsets), - NS_NAME_INIT(inaddr21172, inaddr172_offsets), - NS_NAME_INIT(inaddr22172, inaddr172_offsets), - NS_NAME_INIT(inaddr23172, inaddr172_offsets), - NS_NAME_INIT(inaddr24172, inaddr172_offsets), - NS_NAME_INIT(inaddr25172, inaddr172_offsets), - NS_NAME_INIT(inaddr26172, inaddr172_offsets), - NS_NAME_INIT(inaddr27172, inaddr172_offsets), - NS_NAME_INIT(inaddr28172, inaddr172_offsets), - NS_NAME_INIT(inaddr29172, inaddr172_offsets), - NS_NAME_INIT(inaddr30172, inaddr172_offsets), - NS_NAME_INIT(inaddr31172, inaddr172_offsets), - NS_NAME_INIT(inaddr168192, inaddr192_offsets) -}; - - -static unsigned char prisoner_data[] = "\010prisoner\004iana\003org"; -static unsigned char hostmaster_data[] = "\012hostmaster\014root-servers\003org"; - -static unsigned char prisoner_offsets[] = { 0, 9, 14, 18 }; -static unsigned char hostmaster_offsets[] = { 0, 11, 24, 28 }; - -static dns_name_t prisoner = NS_NAME_INIT(prisoner_data, prisoner_offsets); -static dns_name_t hostmaster = NS_NAME_INIT(hostmaster_data, hostmaster_offsets); - -static void -warn_rfc1918(ns_client_t *client, dns_name_t *fname, dns_rdataset_t *rdataset) { - unsigned int i; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_soa_t soa; - dns_rdataset_t found; - isc_result_t result; - - for (i = 0; i < (sizeof(rfc1918names)/sizeof(*rfc1918names)); i++) { - if (dns_name_issubdomain(fname, &rfc1918names[i])) { - dns_rdataset_init(&found); - result = dns_ncache_getrdataset(rdataset, - &rfc1918names[i], - dns_rdatatype_soa, - &found); - if (result != ISC_R_SUCCESS) - return; - - result = dns_rdataset_first(&found); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_rdataset_current(&found, &rdata); - result = dns_rdata_tostruct(&rdata, &soa, NULL); - if (result != ISC_R_SUCCESS) - return; - if (dns_name_equal(&soa.origin, &prisoner) && - dns_name_equal(&soa.contact, &hostmaster)) { - char buf[DNS_NAME_FORMATSIZE]; - dns_name_format(fname, buf, sizeof(buf)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, - ISC_LOG_WARNING, - "RFC 1918 response from " - "Internet for %s", buf); - } - dns_rdataset_disassociate(&found); - return; - } - } -} - -/* - * Do the bulk of query processing for the current query of 'client'. - * If 'event' is non-NULL, we are returning from recursion and 'qtype' - * is ignored. Otherwise, 'qtype' is the query type. - */ -static void -query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) -{ - dns_db_t *db, *zdb; - dns_dbnode_t *node; - dns_rdatatype_t type; - dns_name_t *fname, *zfname, *tname, *prefix; - dns_rdataset_t *rdataset, *trdataset; - dns_rdataset_t *sigrdataset, *zrdataset, *zsigrdataset; - dns_rdataset_t **sigrdatasetp; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdatasetiter_t *rdsiter; - isc_boolean_t want_restart, authoritative, is_zone, need_wildcardproof; - unsigned int n, nlabels; - dns_namereln_t namereln; - int order; - isc_buffer_t *dbuf; - isc_buffer_t b; - isc_result_t result, eresult; - dns_fixedname_t fixed; - dns_fixedname_t wildcardname; - dns_dbversion_t *version; - dns_zone_t *zone; - dns_rdata_cname_t cname; - dns_rdata_dname_t dname; - unsigned int options; - isc_boolean_t empty_wild; - dns_rdataset_t *noqname; - - CTRACE("query_find"); - - /* - * One-time initialization. - * - * It's especially important to initialize anything that the cleanup - * code might cleanup. - */ - - eresult = ISC_R_SUCCESS; - fname = NULL; - zfname = NULL; - rdataset = NULL; - zrdataset = NULL; - sigrdataset = NULL; - zsigrdataset = NULL; - node = NULL; - db = NULL; - zdb = NULL; - version = NULL; - zone = NULL; - need_wildcardproof = ISC_FALSE; - empty_wild = ISC_FALSE; - options = 0; - - if (event != NULL) { - /* - * We're returning from recursion. Restore the query context - * and resume. - */ - - want_restart = ISC_FALSE; - authoritative = ISC_FALSE; - is_zone = ISC_FALSE; - - qtype = event->qtype; - if (qtype == dns_rdatatype_rrsig || qtype == dns_rdatatype_sig) - type = dns_rdatatype_any; - else - type = qtype; - db = event->db; - node = event->node; - rdataset = event->rdataset; - sigrdataset = event->sigrdataset; - - /* - * We'll need some resources... - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) { - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - fname = query_newname(client, dbuf, &b); - if (fname == NULL) { - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - tname = dns_fixedname_name(&event->foundname); - result = dns_name_copy(tname, fname, NULL); - if (result != ISC_R_SUCCESS) { - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - - result = event->result; - - goto resume; - } - - /* - * Not returning from recursion. - */ - - /* - * If it's a SIG query, we'll iterate the node. - */ - if (qtype == dns_rdatatype_rrsig || qtype == dns_rdatatype_sig) - type = dns_rdatatype_any; - else - type = qtype; - - restart: - CTRACE("query_find: restart"); - want_restart = ISC_FALSE; - authoritative = ISC_FALSE; - version = NULL; - need_wildcardproof = ISC_FALSE; - - if (client->view->checknames && - !dns_rdata_checkowner(client->query.qname, - client->message->rdclass, - qtype, ISC_FALSE)) { - char namebuf[DNS_NAME_FORMATSIZE]; - char typename[DNS_RDATATYPE_FORMATSIZE]; - char classname[DNS_RDATACLASS_FORMATSIZE]; - - dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); - dns_rdatatype_format(qtype, typename, sizeof(typename)); - dns_rdataclass_format(client->message->rdclass, classname, - sizeof(classname)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_QUERY, ISC_LOG_ERROR, - "check-names failure %s/%s/%s", namebuf, - typename, classname); - QUERY_ERROR(DNS_R_REFUSED); - goto cleanup; - } - - /* - * First we must find the right database. - */ - options &= DNS_GETDB_NOLOG; /* Preserve DNS_GETDB_NOLOG. */ - if (dns_rdatatype_atparent(qtype) && - !dns_name_equal(client->query.qname, dns_rootname)) - options |= DNS_GETDB_NOEXACT; - result = query_getdb(client, client->query.qname, qtype, options, - &zone, &db, &version, &is_zone); - if ((result != ISC_R_SUCCESS || !is_zone) && !RECURSIONOK(client) && - (options & DNS_GETDB_NOEXACT) != 0 && qtype == dns_rdatatype_ds) { - /* - * Look to see if we are authoritative for the - * child zone if the query type is DS. - */ - dns_db_t *tdb = NULL; - dns_zone_t *tzone = NULL; - dns_dbversion_t *tversion = NULL; - isc_result_t tresult; - - tresult = query_getzonedb(client, client->query.qname, qtype, - DNS_GETDB_PARTIAL, &tzone, &tdb, - &tversion); - if (tresult == ISC_R_SUCCESS) { - options &= ~DNS_GETDB_NOEXACT; - query_putrdataset(client, &rdataset); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - version = tversion; - db = tdb; - zone = tzone; - is_zone = ISC_TRUE; - result = ISC_R_SUCCESS; - } else { - if (tdb != NULL) - dns_db_detach(&tdb); - if (tzone != NULL) - dns_zone_detach(&tzone); - } - } - if (result != ISC_R_SUCCESS) { - if (result == DNS_R_REFUSED) { - if (!PARTIALANSWER(client)) - QUERY_ERROR(DNS_R_REFUSED); - } else - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - - if (is_zone) - authoritative = ISC_TRUE; - - if (event == NULL && client->query.restarts == 0) { - if (is_zone) { -#ifdef DLZ - if (zone != NULL) { - /* - * if is_zone = true, zone = NULL then this is - * a DLZ zone. Don't attempt to attach zone. - */ -#endif - dns_zone_attach(zone, &client->query.authzone); -#ifdef DLZ - } -#endif - dns_db_attach(db, &client->query.authdb); - } - client->query.authdbset = ISC_TRUE; - } - - db_find: - CTRACE("query_find: db_find"); - /* - * We'll need some resources... - */ - dbuf = query_getnamebuf(client); - if (dbuf == NULL) { - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - fname = query_newname(client, dbuf, &b); - rdataset = query_newrdataset(client); - if (fname == NULL || rdataset == NULL) { - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - if (WANTDNSSEC(client)) { - sigrdataset = query_newrdataset(client); - if (sigrdataset == NULL) { - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } - - /* - * Now look for an answer in the database. - */ - result = dns_db_find(db, client->query.qname, version, type, - client->query.dboptions, client->now, - &node, fname, rdataset, sigrdataset); - - resume: - CTRACE("query_find: resume"); - switch (result) { - case ISC_R_SUCCESS: - /* - * This case is handled in the main line below. - */ - break; - case DNS_R_GLUE: - case DNS_R_ZONECUT: - /* - * These cases are handled in the main line below. - */ - INSIST(is_zone); - authoritative = ISC_FALSE; - break; - case ISC_R_NOTFOUND: - /* - * The cache doesn't even have the root NS. Get them from - * the hints DB. - */ - INSIST(!is_zone); - if (db != NULL) - dns_db_detach(&db); - - if (client->view->hints == NULL) { - /* We have no hints. */ - result = ISC_R_FAILURE; - } else { - dns_db_attach(client->view->hints, &db); - result = dns_db_find(db, dns_rootname, - NULL, dns_rdatatype_ns, - 0, client->now, &node, fname, - rdataset, sigrdataset); - } - if (result != ISC_R_SUCCESS) { - /* - * Nonsensical root hints may require cleanup. - */ - if (dns_rdataset_isassociated(rdataset)) - dns_rdataset_disassociate(rdataset); - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - - /* - * We don't have any root server hints, but - * we may have working forwarders, so try to - * recurse anyway. - */ - if (RECURSIONOK(client)) { - result = query_recurse(client, qtype, - NULL, NULL); - if (result == ISC_R_SUCCESS) - client->query.attributes |= - NS_QUERYATTR_RECURSING; - else if (result == DNS_R_DUPLICATE || - result == DNS_R_DROP) { - /* Duplicate query. */ - QUERY_ERROR(result); - } else { - /* Unable to recurse. */ - QUERY_ERROR(DNS_R_SERVFAIL); - } - goto cleanup; - } else { - /* Unable to give root server referral. */ - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } - /* - * XXXRTH We should trigger root server priming here. - */ - /* FALLTHROUGH */ - case DNS_R_DELEGATION: - authoritative = ISC_FALSE; - if (is_zone) { - /* - * Look to see if we are authoritative for the - * child zone if the query type is DS. - */ - if (!RECURSIONOK(client) && - (options & DNS_GETDB_NOEXACT) != 0 && - qtype == dns_rdatatype_ds) { - dns_db_t *tdb = NULL; - dns_zone_t *tzone = NULL; - dns_dbversion_t *tversion = NULL; - result = query_getzonedb(client, - client->query.qname, - qtype, - DNS_GETDB_PARTIAL, - &tzone, &tdb, - &tversion); - if (result == ISC_R_SUCCESS) { - options &= ~DNS_GETDB_NOEXACT; - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, - &sigrdataset); - if (fname != NULL) - query_releasename(client, - &fname); - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - version = tversion; - db = tdb; - zone = tzone; - authoritative = ISC_TRUE; - goto db_find; - } - if (tdb != NULL) - dns_db_detach(&tdb); - if (tzone != NULL) - dns_zone_detach(&tzone); - } - /* - * We're authoritative for an ancestor of QNAME. - */ - if (!USECACHE(client) || !RECURSIONOK(client)) { - /* - * If we don't have a cache, this is the best - * answer. - * - * If the client is making a nonrecursive - * query we always give out the authoritative - * delegation. This way even if we get - * junk in our cache, we won't fail in our - * role as the delegating authority if another - * nameserver asks us about a delegated - * subzone. - * - * We enable the retrieval of glue for this - * database by setting client->query.gluedb. - */ - client->query.gluedb = db; - client->query.isreferral = ISC_TRUE; - /* - * We must ensure NOADDITIONAL is off, - * because the generation of - * additional data is required in - * delegations. - */ - client->query.attributes &= - ~NS_QUERYATTR_NOADDITIONAL; - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - query_addrrset(client, &fname, - &rdataset, sigrdatasetp, - dbuf, DNS_SECTION_AUTHORITY); - client->query.gluedb = NULL; - if (WANTDNSSEC(client) && dns_db_issecure(db)) - query_addds(client, db, node, version); - } else { - /* - * We might have a better answer or delegation - * in the cache. We'll remember the current - * values of fname, rdataset, and sigrdataset. - * We'll then go looking for QNAME in the - * cache. If we find something better, we'll - * use it instead. - */ - query_keepname(client, fname, dbuf); - zdb = db; - zfname = fname; - fname = NULL; - zrdataset = rdataset; - rdataset = NULL; - zsigrdataset = sigrdataset; - sigrdataset = NULL; - dns_db_detachnode(db, &node); - version = NULL; - db = NULL; - dns_db_attach(client->view->cachedb, &db); - is_zone = ISC_FALSE; - goto db_find; - } - } else { - if (zfname != NULL && - !dns_name_issubdomain(fname, zfname)) { - /* - * We've already got a delegation from - * authoritative data, and it is better - * than what we found in the cache. Use - * it instead of the cache delegation. - */ - query_releasename(client, &fname); - fname = zfname; - zfname = NULL; - /* - * We've already done query_keepname() on - * zfname, so we must set dbuf to NULL to - * prevent query_addrrset() from trying to - * call query_keepname() again. - */ - dbuf = NULL; - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, - &sigrdataset); - rdataset = zrdataset; - zrdataset = NULL; - sigrdataset = zsigrdataset; - zsigrdataset = NULL; - /* - * We don't clean up zdb here because we - * may still need it. It will get cleaned - * up by the main cleanup code. - */ - } - - if (RECURSIONOK(client)) { - /* - * Recurse! - */ - if (dns_rdatatype_atparent(type)) - result = query_recurse(client, qtype, - NULL, NULL); - else - result = query_recurse(client, qtype, - fname, rdataset); - if (result == ISC_R_SUCCESS) - client->query.attributes |= - NS_QUERYATTR_RECURSING; - else if (result == DNS_R_DUPLICATE || - result == DNS_R_DROP) - QUERY_ERROR(result); - else - QUERY_ERROR(DNS_R_SERVFAIL); - } else { - /* - * This is the best answer. - */ - client->query.attributes |= - NS_QUERYATTR_CACHEGLUEOK; - client->query.gluedb = zdb; - client->query.isreferral = ISC_TRUE; - /* - * We must ensure NOADDITIONAL is off, - * because the generation of - * additional data is required in - * delegations. - */ - client->query.attributes &= - ~NS_QUERYATTR_NOADDITIONAL; - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - query_addrrset(client, &fname, - &rdataset, sigrdatasetp, - dbuf, DNS_SECTION_AUTHORITY); - client->query.gluedb = NULL; - client->query.attributes &= - ~NS_QUERYATTR_CACHEGLUEOK; - if (WANTDNSSEC(client)) - query_addds(client, db, node, version); - } - } - goto cleanup; - case DNS_R_EMPTYNAME: - result = DNS_R_NXRRSET; - /* FALLTHROUGH */ - case DNS_R_NXRRSET: - INSIST(is_zone); - if (dns_rdataset_isassociated(rdataset)) { - /* - * If we've got a NSEC record, we need to save the - * name now because we're going call query_addsoa() - * below, and it needs to use the name buffer. - */ - query_keepname(client, fname, dbuf); - } else { - /* - * We're not going to use fname, and need to release - * our hold on the name buffer so query_addsoa() - * may use it. - */ - query_releasename(client, &fname); - } - /* - * Add SOA. - */ - result = query_addsoa(client, db, version, ISC_FALSE); - if (result != ISC_R_SUCCESS) { - QUERY_ERROR(result); - goto cleanup; - } - /* - * Add NSEC record if we found one. - */ - if (WANTDNSSEC(client)) { - if (dns_rdataset_isassociated(rdataset)) - query_addnxrrsetnsec(client, db, version, - &fname, &rdataset, - &sigrdataset); - } - goto cleanup; - case DNS_R_EMPTYWILD: - empty_wild = ISC_TRUE; - /* FALLTHROUGH */ - case DNS_R_NXDOMAIN: - INSIST(is_zone); - if (dns_rdataset_isassociated(rdataset)) { - /* - * If we've got a NSEC record, we need to save the - * name now because we're going call query_addsoa() - * below, and it needs to use the name buffer. - */ - query_keepname(client, fname, dbuf); - } else { - /* - * We're not going to use fname, and need to release - * our hold on the name buffer so query_addsoa() - * may use it. - */ - query_releasename(client, &fname); - } - /* - * Add SOA. If the query was for a SOA record force the - * ttl to zero so that it is possible for clients to find - * the containing zone of an arbitrary name with a stub - * resolver and not have it cached. - */ - if (qtype == dns_rdatatype_soa && -#ifdef DLZ - zone != NULL && -#endif - dns_zone_getzeronosoattl(zone)) - result = query_addsoa(client, db, version, ISC_TRUE); - else - result = query_addsoa(client, db, version, ISC_FALSE); - if (result != ISC_R_SUCCESS) { - QUERY_ERROR(result); - goto cleanup; - } - /* - * Add NSEC record if we found one. - */ - if (dns_rdataset_isassociated(rdataset)) { - if (WANTDNSSEC(client)) { - query_addrrset(client, &fname, &rdataset, - &sigrdataset, - NULL, DNS_SECTION_AUTHORITY); - query_addwildcardproof(client, db, version, - client->query.qname, - ISC_FALSE); - } - } - /* - * Set message rcode. - */ - if (empty_wild) - client->message->rcode = dns_rcode_noerror; - else - client->message->rcode = dns_rcode_nxdomain; - goto cleanup; - case DNS_R_NCACHENXDOMAIN: - case DNS_R_NCACHENXRRSET: - INSIST(!is_zone); - authoritative = ISC_FALSE; - /* - * Set message rcode, if required. - */ - if (result == DNS_R_NCACHENXDOMAIN) - client->message->rcode = dns_rcode_nxdomain; - /* - * Look for RFC 1918 leakage from Internet. - */ - if (result == DNS_R_NCACHENXDOMAIN && - qtype == dns_rdatatype_ptr && - client->message->rdclass == dns_rdataclass_in && - dns_name_countlabels(fname) == 7) - warn_rfc1918(client, fname, rdataset); - /* - * We don't call query_addrrset() because we don't need any - * of its extra features (and things would probably break!). - */ - query_keepname(client, fname, dbuf); - dns_message_addname(client->message, fname, - DNS_SECTION_AUTHORITY); - ISC_LIST_APPEND(fname->list, rdataset, link); - fname = NULL; - rdataset = NULL; - goto cleanup; - case DNS_R_CNAME: - /* - * Keep a copy of the rdataset. We have to do this because - * query_addrrset may clear 'rdataset' (to prevent the - * cleanup code from cleaning it up). - */ - trdataset = rdataset; - /* - * Add the CNAME to the answer section. - */ - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - if (WANTDNSSEC(client) && - (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) - { - dns_fixedname_init(&wildcardname); - dns_name_copy(fname, dns_fixedname_name(&wildcardname), - NULL); - need_wildcardproof = ISC_TRUE; - } - if ((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0 && - WANTDNSSEC(client)) - noqname = rdataset; - else - noqname = NULL; - query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf, - DNS_SECTION_ANSWER); - if (noqname != NULL) - query_addnoqnameproof(client, noqname); - /* - * We set the PARTIALANSWER attribute so that if anything goes - * wrong later on, we'll return what we've got so far. - */ - client->query.attributes |= NS_QUERYATTR_PARTIALANSWER; - /* - * Reset qname to be the target name of the CNAME and restart - * the query. - */ - tname = NULL; - result = dns_message_gettempname(client->message, &tname); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_rdataset_first(trdataset); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &tname); - goto cleanup; - } - dns_rdataset_current(trdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &cname, NULL); - dns_rdata_reset(&rdata); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &tname); - goto cleanup; - } - dns_name_init(tname, NULL); - result = dns_name_dup(&cname.cname, client->mctx, tname); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &tname); - dns_rdata_freestruct(&cname); - goto cleanup; - } - dns_rdata_freestruct(&cname); - ns_client_qnamereplace(client, tname); - want_restart = ISC_TRUE; - if (!WANTRECURSION(client)) - options |= DNS_GETDB_NOLOG; - goto addauth; - case DNS_R_DNAME: - /* - * Compare the current qname to the found name. We need - * to know how many labels and bits are in common because - * we're going to have to split qname later on. - */ - namereln = dns_name_fullcompare(client->query.qname, fname, - &order, &nlabels); - INSIST(namereln == dns_namereln_subdomain); - /* - * Keep a copy of the rdataset. We have to do this because - * query_addrrset may clear 'rdataset' (to prevent the - * cleanup code from cleaning it up). - */ - trdataset = rdataset; - /* - * Add the DNAME to the answer section. - */ - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - if (WANTDNSSEC(client) && - (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) - { - dns_fixedname_init(&wildcardname); - dns_name_copy(fname, dns_fixedname_name(&wildcardname), - NULL); - need_wildcardproof = ISC_TRUE; - } - query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf, - DNS_SECTION_ANSWER); - /* - * We set the PARTIALANSWER attribute so that if anything goes - * wrong later on, we'll return what we've got so far. - */ - client->query.attributes |= NS_QUERYATTR_PARTIALANSWER; - /* - * Get the target name of the DNAME. - */ - tname = NULL; - result = dns_message_gettempname(client->message, &tname); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_rdataset_first(trdataset); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &tname); - goto cleanup; - } - dns_rdataset_current(trdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &dname, NULL); - dns_rdata_reset(&rdata); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &tname); - goto cleanup; - } - dns_name_init(tname, NULL); - dns_name_clone(&dname.dname, tname); - dns_rdata_freestruct(&dname); - /* - * Construct the new qname. - */ - dns_fixedname_init(&fixed); - prefix = dns_fixedname_name(&fixed); - dns_name_split(client->query.qname, nlabels, prefix, NULL); - INSIST(fname == NULL); - dbuf = query_getnamebuf(client); - if (dbuf == NULL) { - dns_message_puttempname(client->message, &tname); - goto cleanup; - } - fname = query_newname(client, dbuf, &b); - if (fname == NULL) { - dns_message_puttempname(client->message, &tname); - goto cleanup; - } - result = dns_name_concatenate(prefix, tname, fname, NULL); - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(client->message, &tname); - if (result == ISC_R_NOSPACE) { - /* - * RFC2672, section 4.1, subsection 3c says - * we should return YXDOMAIN if the constructed - * name would be too long. - */ - client->message->rcode = dns_rcode_yxdomain; - } - goto cleanup; - } - query_keepname(client, fname, dbuf); - /* - * Synthesize a CNAME for this DNAME. - * - * We want to synthesize a CNAME since if we don't - * then older software that doesn't understand DNAME - * will not chain like it should. - * - * We do not try to synthesize a signature because we hope - * that security aware servers will understand DNAME. Also, - * even if we had an online key, making a signature - * on-the-fly is costly, and not really legitimate anyway - * since the synthesized CNAME is NOT in the zone. - */ - dns_name_init(tname, NULL); - (void)query_addcnamelike(client, client->query.qname, fname, - trdataset->trust, &tname, - dns_rdatatype_cname); - if (tname != NULL) - dns_message_puttempname(client->message, &tname); - /* - * Switch to the new qname and restart. - */ - ns_client_qnamereplace(client, fname); - fname = NULL; - want_restart = ISC_TRUE; - if (!WANTRECURSION(client)) - options |= DNS_GETDB_NOLOG; - goto addauth; - default: - /* - * Something has gone wrong. - */ - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - - if (WANTDNSSEC(client) && - (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) - { - dns_fixedname_init(&wildcardname); - dns_name_copy(fname, dns_fixedname_name(&wildcardname), NULL); - need_wildcardproof = ISC_TRUE; - } - - if (type == dns_rdatatype_any) { - /* - * XXXRTH Need to handle zonecuts with special case - * code. - */ - n = 0; - rdsiter = NULL; - result = dns_db_allrdatasets(db, node, version, 0, &rdsiter); - if (result != ISC_R_SUCCESS) { - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - /* - * Calling query_addrrset() with a non-NULL dbuf is going - * to either keep or release the name. We don't want it to - * release fname, since we may have to call query_addrrset() - * more than once. That means we have to call query_keepname() - * now, and pass a NULL dbuf to query_addrrset(). - * - * If we do a query_addrrset() below, we must set fname to - * NULL before leaving this block, otherwise we might try to - * cleanup fname even though we're using it! - */ - query_keepname(client, fname, dbuf); - tname = fname; - result = dns_rdatasetiter_first(rdsiter); - while (result == ISC_R_SUCCESS) { - dns_rdatasetiter_current(rdsiter, rdataset); - if ((qtype == dns_rdatatype_any || - rdataset->type == qtype) && rdataset->type != 0) { - query_addrrset(client, - fname != NULL ? &fname : &tname, - &rdataset, NULL, - NULL, DNS_SECTION_ANSWER); - n++; - INSIST(tname != NULL); - /* - * rdataset is non-NULL only in certain pathological - * cases involving DNAMEs. - */ - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - rdataset = query_newrdataset(client); - if (rdataset == NULL) - break; - } else { - /* - * We're not interested in this rdataset. - */ - dns_rdataset_disassociate(rdataset); - } - result = dns_rdatasetiter_next(rdsiter); - } - - if (fname != NULL) - dns_message_puttempname(client->message, &fname); - - if (n == 0) { - /* - * We didn't match any rdatasets. - */ - if (qtype == dns_rdatatype_rrsig && - result == ISC_R_NOMORE) { - /* - * XXXRTH If this is a secure zone and we - * didn't find any SIGs, we should generate - * an error unless we were searching for - * glue. Ugh. - */ - if (!is_zone) { - authoritative = ISC_FALSE; - dns_rdatasetiter_destroy(&rdsiter); - if (RECURSIONOK(client)) { - result = query_recurse(client, - qtype, - NULL, - NULL); - if (result == ISC_R_SUCCESS) - client->query.attributes |= - NS_QUERYATTR_RECURSING; - else - QUERY_ERROR(DNS_R_SERVFAIL); } - goto addauth; - } - /* - * We were searching for SIG records in - * a nonsecure zone. Send a "no error, - * no data" response. - */ - /* - * Add SOA. - */ - result = query_addsoa(client, db, version, - ISC_FALSE); - if (result == ISC_R_SUCCESS) - result = ISC_R_NOMORE; - } else { - /* - * Something went wrong. - */ - result = DNS_R_SERVFAIL; - } - } - dns_rdatasetiter_destroy(&rdsiter); - if (result != ISC_R_NOMORE) { - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - } else { - /* - * This is the "normal" case -- an ordinary question to which - * we know the answer. - */ - if (sigrdataset != NULL) - sigrdatasetp = &sigrdataset; - else - sigrdatasetp = NULL; - if ((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0 && - WANTDNSSEC(client)) - noqname = rdataset; - else - noqname = NULL; - /* - * BIND 8 priming queries need the additional section. - */ - if (is_zone && qtype == dns_rdatatype_ns && - dns_name_equal(client->query.qname, dns_rootname)) - client->query.attributes &= ~NS_QUERYATTR_NOADDITIONAL; - - query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf, - DNS_SECTION_ANSWER); - if (noqname != NULL) - query_addnoqnameproof(client, noqname); - /* - * We shouldn't ever fail to add 'rdataset' - * because it's already in the answer. - */ - INSIST(rdataset == NULL); - } - - addauth: - CTRACE("query_find: addauth"); - /* - * Add NS records to the authority section (if we haven't already - * added them to the answer section). - */ - if (!want_restart && !NOAUTHORITY(client)) { - if (is_zone) { - if (!((qtype == dns_rdatatype_ns || - qtype == dns_rdatatype_any) && - dns_name_equal(client->query.qname, - dns_db_origin(db)))) - (void)query_addns(client, db, version); - } else if (qtype != dns_rdatatype_ns) { - if (fname != NULL) - query_releasename(client, &fname); - query_addbestns(client); - } - } - - /* - * Add NSEC records to the authority section if they're needed for - * DNSSEC wildcard proofs. - */ - if (need_wildcardproof && dns_db_issecure(db)) - query_addwildcardproof(client, db, version, - dns_fixedname_name(&wildcardname), - ISC_TRUE); - cleanup: - CTRACE("query_find: cleanup"); - /* - * General cleanup. - */ - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if (sigrdataset != NULL) - query_putrdataset(client, &sigrdataset); - if (fname != NULL) - query_releasename(client, &fname); - if (node != NULL) - dns_db_detachnode(db, &node); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - if (zdb != NULL) { - query_putrdataset(client, &zrdataset); - if (zsigrdataset != NULL) - query_putrdataset(client, &zsigrdataset); - if (zfname != NULL) - query_releasename(client, &zfname); - dns_db_detach(&zdb); - } - if (event != NULL) - isc_event_free(ISC_EVENT_PTR(&event)); - - /* - * AA bit. - */ - if (client->query.restarts == 0 && !authoritative) { - /* - * We're not authoritative, so we must ensure the AA bit - * isn't set. - */ - client->message->flags &= ~DNS_MESSAGEFLAG_AA; - } - - /* - * Restart the query? - */ - if (want_restart && client->query.restarts < MAX_RESTARTS) { - client->query.restarts++; - goto restart; - } - - if (eresult != ISC_R_SUCCESS && - (!PARTIALANSWER(client) || WANTRECURSION(client))) { - if (eresult == DNS_R_DUPLICATE || eresult == DNS_R_DROP) { - /* - * This was a duplicate query that we are - * recursing on. Don't send a response now. - * The original query will still cause a response. - */ - query_next(client, eresult); - } else { - /* - * If we don't have any answer to give the client, - * or if the client requested recursion and thus wanted - * the complete answer, send an error response. - */ - query_error(client, eresult); - } - ns_client_detach(&client); - } else if (!RECURSING(client)) { - /* - * We are done. Set up sortlist data for the message - * rendering code, make a final tweak to the AA bit if the - * auth-nxdomain config option says so, then render and - * send the response. - */ - setup_query_sortlist(client); - - /* - * If this is a referral and the answer to the question - * is in the glue sort it to the start of the additional - * section. - */ - if (client->message->counts[DNS_SECTION_ANSWER] == 0 && - client->message->rcode == dns_rcode_noerror && - (qtype == dns_rdatatype_a || qtype == dns_rdatatype_aaaa)) - answer_in_glue(client, qtype); - - if (client->message->rcode == dns_rcode_nxdomain && - client->view->auth_nxdomain == ISC_TRUE) - client->message->flags |= DNS_MESSAGEFLAG_AA; - - query_send(client); - ns_client_detach(&client); - } - CTRACE("query_find: done"); -} - -static inline void -log_query(ns_client_t *client) { - char namebuf[DNS_NAME_FORMATSIZE]; - char typename[DNS_RDATATYPE_FORMATSIZE]; - char classname[DNS_RDATACLASS_FORMATSIZE]; - dns_rdataset_t *rdataset; - int level = ISC_LOG_INFO; - - if (! isc_log_wouldlog(ns_g_lctx, level)) - return; - - rdataset = ISC_LIST_HEAD(client->query.qname->list); - INSIST(rdataset != NULL); - dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); - dns_rdataclass_format(rdataset->rdclass, classname, sizeof(classname)); - dns_rdatatype_format(rdataset->type, typename, sizeof(typename)); - - ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY, - level, "query: %s %s %s %s%s%s", namebuf, classname, - typename, WANTRECURSION(client) ? "+" : "-", - (client->signer != NULL) ? "S": "", - (client->opt != NULL) ? "E" : ""); -} - -void -ns_query_start(ns_client_t *client) { - isc_result_t result; - dns_message_t *message = client->message; - dns_rdataset_t *rdataset; - ns_client_t *qclient; - dns_rdatatype_t qtype; - - CTRACE("ns_query_start"); - - /* - * Ensure that appropriate cleanups occur. - */ - client->next = query_next_callback; - - /* - * Behave as if we don't support DNSSEC if not enabled. - */ - if (!client->view->enablednssec) { - message->flags &= ~DNS_MESSAGEFLAG_CD; - client->extflags &= ~DNS_MESSAGEEXTFLAG_DO; - if (client->opt != NULL) - client->opt->ttl &= ~DNS_MESSAGEEXTFLAG_DO; - } - - if ((message->flags & DNS_MESSAGEFLAG_RD) != 0) - client->query.attributes |= NS_QUERYATTR_WANTRECURSION; - - if ((client->extflags & DNS_MESSAGEEXTFLAG_DO) != 0) - client->attributes |= NS_CLIENTATTR_WANTDNSSEC; - - if (client->view->minimalresponses) - client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | - NS_QUERYATTR_NOADDITIONAL); - - if ((client->view->cachedb == NULL) - || (!client->view->additionalfromcache)) { - /* - * We don't have a cache. Turn off cache support and - * recursion. - */ - client->query.attributes &= - ~(NS_QUERYATTR_RECURSIONOK|NS_QUERYATTR_CACHEOK); - } else if ((client->attributes & NS_CLIENTATTR_RA) == 0 || - (message->flags & DNS_MESSAGEFLAG_RD) == 0) { - /* - * If the client isn't allowed to recurse (due to - * "recursion no", the allow-recursion ACL, or the - * lack of a resolver in this view), or if it - * doesn't want recursion, turn recursion off. - */ - client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK; - } - - /* - * Get the question name. - */ - result = dns_message_firstname(message, DNS_SECTION_QUESTION); - if (result != ISC_R_SUCCESS) { - query_error(client, result); - return; - } - dns_message_currentname(message, DNS_SECTION_QUESTION, - &client->query.qname); - client->query.origqname = client->query.qname; - result = dns_message_nextname(message, DNS_SECTION_QUESTION); - if (result != ISC_R_NOMORE) { - if (result == ISC_R_SUCCESS) { - /* - * There's more than one QNAME in the question - * section. - */ - query_error(client, DNS_R_FORMERR); - } else - query_error(client, result); - return; - } - - if (ns_g_server->log_queries) - log_query(client); - - /* - * Check for multiple question queries, since edns1 is dead. - */ - if (message->counts[DNS_SECTION_QUESTION] > 1) { - query_error(client, DNS_R_FORMERR); - return; - } - - /* - * Check for meta-queries like IXFR and AXFR. - */ - rdataset = ISC_LIST_HEAD(client->query.qname->list); - INSIST(rdataset != NULL); - qtype = rdataset->type; - if (dns_rdatatype_ismeta(qtype)) { - switch (qtype) { - case dns_rdatatype_any: - break; /* Let query_find handle it. */ - case dns_rdatatype_ixfr: - case dns_rdatatype_axfr: - ns_xfr_start(client, rdataset->type); - return; - case dns_rdatatype_maila: - case dns_rdatatype_mailb: - query_error(client, DNS_R_NOTIMP); - return; - case dns_rdatatype_tkey: - result = dns_tkey_processquery(client->message, - ns_g_server->tkeyctx, - client->view->dynamickeys); - if (result == ISC_R_SUCCESS) - query_send(client); - else - query_error(client, result); - return; - default: /* TSIG, etc. */ - query_error(client, DNS_R_FORMERR); - return; - } - } - - /* - * If the client has requested that DNSSEC checking be disabled, - * allow lookups to return pending data and instruct the resolver - * to return data before validation has completed. - * - * We don't need to set DNS_DBFIND_PENDINGOK when validation is - * disabled as there will be no pending data. - */ - if (message->flags & DNS_MESSAGEFLAG_CD || - qtype == dns_rdatatype_rrsig) - { - client->query.dboptions |= DNS_DBFIND_PENDINGOK; - client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE; - } else if (!client->view->enablevalidation) - client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE; - - /* - * Allow glue NS records to be added to the authority section - * if the answer is secure. - */ - if (message->flags & DNS_MESSAGEFLAG_CD) - client->query.attributes &= ~NS_QUERYATTR_SECURE; - - /* - * This is an ordinary query. - */ - result = dns_message_reply(message, ISC_TRUE); - if (result != ISC_R_SUCCESS) { - query_next(client, result); - return; - } - - /* - * Assume authoritative response until it is known to be - * otherwise. - */ - message->flags |= DNS_MESSAGEFLAG_AA; - - /* - * Set AD. We must clear it if we add non-validated data to a - * response. - */ - if (WANTDNSSEC(client)) - message->flags |= DNS_MESSAGEFLAG_AD; - - qclient = NULL; - ns_client_attach(client, &qclient); - query_find(qclient, NULL, qtype); -} diff --git a/contrib/bind9/bin/named/server.c b/contrib/bind9/bin/named/server.c deleted file mode 100644 index cd8bff1..0000000 --- a/contrib/bind9/bin/named/server.c +++ /dev/null @@ -1,4835 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-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: server.c,v 1.419.18.57 2007/08/28 07:20:01 tbox Exp $ */ - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#ifdef DLZ -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LIBSCF -#include -#include -#endif - -/*% - * Check an operation for failure. Assumes that the function - * using it has a 'result' variable and a 'cleanup' label. - */ -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ - } while (0) - -#define CHECKM(op, msg) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) { \ - isc_log_write(ns_g_lctx, \ - NS_LOGCATEGORY_GENERAL, \ - NS_LOGMODULE_SERVER, \ - ISC_LOG_ERROR, \ - "%s: %s", msg, \ - isc_result_totext(result)); \ - goto cleanup; \ - } \ - } while (0) \ - -#define CHECKMF(op, msg, file) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) { \ - isc_log_write(ns_g_lctx, \ - NS_LOGCATEGORY_GENERAL, \ - NS_LOGMODULE_SERVER, \ - ISC_LOG_ERROR, \ - "%s '%s': %s", msg, file, \ - isc_result_totext(result)); \ - goto cleanup; \ - } \ - } while (0) \ - -#define CHECKFATAL(op, msg) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) \ - fatal(msg, result); \ - } while (0) \ - -struct ns_dispatch { - isc_sockaddr_t addr; - unsigned int dispatchgen; - dns_dispatch_t *dispatch; - ISC_LINK(struct ns_dispatch) link; -}; - -struct dumpcontext { - isc_mem_t *mctx; - isc_boolean_t dumpcache; - isc_boolean_t dumpzones; - FILE *fp; - ISC_LIST(struct viewlistentry) viewlist; - struct viewlistentry *view; - struct zonelistentry *zone; - dns_dumpctx_t *mdctx; - dns_db_t *db; - dns_db_t *cache; - isc_task_t *task; - dns_dbversion_t *version; -}; - -struct viewlistentry { - dns_view_t *view; - ISC_LINK(struct viewlistentry) link; - ISC_LIST(struct zonelistentry) zonelist; -}; - -struct zonelistentry { - dns_zone_t *zone; - ISC_LINK(struct zonelistentry) link; -}; - -/* - * These zones should not leak onto the Internet. - */ -static const struct { - const char *zone; - isc_boolean_t rfc1918; -} empty_zones[] = { -#ifdef notyet - /* RFC 1918 */ - { "10.IN-ADDR.ARPA", ISC_TRUE }, - { "16.172.IN-ADDR.ARPA", ISC_TRUE }, - { "17.172.IN-ADDR.ARPA", ISC_TRUE }, - { "18.172.IN-ADDR.ARPA", ISC_TRUE }, - { "19.172.IN-ADDR.ARPA", ISC_TRUE }, - { "20.172.IN-ADDR.ARPA", ISC_TRUE }, - { "21.172.IN-ADDR.ARPA", ISC_TRUE }, - { "22.172.IN-ADDR.ARPA", ISC_TRUE }, - { "23.172.IN-ADDR.ARPA", ISC_TRUE }, - { "24.172.IN-ADDR.ARPA", ISC_TRUE }, - { "25.172.IN-ADDR.ARPA", ISC_TRUE }, - { "26.172.IN-ADDR.ARPA", ISC_TRUE }, - { "27.172.IN-ADDR.ARPA", ISC_TRUE }, - { "28.172.IN-ADDR.ARPA", ISC_TRUE }, - { "29.172.IN-ADDR.ARPA", ISC_TRUE }, - { "30.172.IN-ADDR.ARPA", ISC_TRUE }, - { "31.172.IN-ADDR.ARPA", ISC_TRUE }, - { "168.192.IN-ADDR.ARPA", ISC_TRUE }, -#endif - - /* RFC 3330 */ - { "127.IN-ADDR.ARPA", ISC_FALSE }, /* LOOPBACK */ - { "254.169.IN-ADDR.ARPA", ISC_FALSE }, /* LINK LOCAL */ - { "2.0.192.IN-ADDR.ARPA", ISC_FALSE }, /* TEST NET */ - { "255.255.255.255.IN-ADDR.ARPA", ISC_FALSE }, /* BROADCAST */ - - /* Local IPv6 Unicast Addresses */ - { "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA", ISC_FALSE }, - { "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA", ISC_FALSE }, - /* LOCALLY ASSIGNED LOCAL ADDRES S SCOPE */ - { "D.F.IP6.ARPA", ISC_FALSE }, - { "8.E.F.IP6.ARPA", ISC_FALSE }, /* LINK LOCAL */ - { "9.E.F.IP6.ARPA", ISC_FALSE }, /* LINK LOCAL */ - { "A.E.F.IP6.ARPA", ISC_FALSE }, /* LINK LOCAL */ - { "B.E.F.IP6.ARPA", ISC_FALSE }, /* LINK LOCAL */ - - { NULL, ISC_FALSE } -}; - -static void -fatal(const char *msg, isc_result_t result); - -static void -ns_server_reload(isc_task_t *task, isc_event_t *event); - -static isc_result_t -ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, - isc_mem_t *mctx, ns_listenelt_t **target); -static isc_result_t -ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, - isc_mem_t *mctx, ns_listenlist_t **target); - -static isc_result_t -configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin, - const cfg_obj_t *forwarders, const cfg_obj_t *forwardtype); - -static isc_result_t -configure_alternates(const cfg_obj_t *config, dns_view_t *view, - const cfg_obj_t *alternates); - -static isc_result_t -configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig, - const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view, - cfg_aclconfctx_t *aclconf); - -static void -end_reserved_dispatches(ns_server_t *server, isc_boolean_t all); - -/*% - * Configure a single view ACL at '*aclp'. Get its configuration by - * calling 'getvcacl' (for per-view configuration) and maybe 'getscacl' - * (for a global default). - */ -static isc_result_t -configure_view_acl(const cfg_obj_t *vconfig, const cfg_obj_t *config, - const char *aclname, cfg_aclconfctx_t *actx, - isc_mem_t *mctx, dns_acl_t **aclp) -{ - isc_result_t result; - const cfg_obj_t *maps[3]; - const cfg_obj_t *aclobj = NULL; - int i = 0; - - if (*aclp != NULL) - dns_acl_detach(aclp); - if (vconfig != NULL) - maps[i++] = cfg_tuple_get(vconfig, "options"); - if (config != NULL) { - const cfg_obj_t *options = NULL; - (void)cfg_map_get(config, "options", &options); - if (options != NULL) - maps[i++] = options; - } - maps[i] = NULL; - - (void)ns_config_get(maps, aclname, &aclobj); - if (aclobj == NULL) - /* - * No value available. *aclp == NULL. - */ - return (ISC_R_SUCCESS); - - result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx, - actx, mctx, aclp); - - return (result); -} - -static isc_result_t -configure_view_dnsseckey(const cfg_obj_t *vconfig, const cfg_obj_t *key, - dns_keytable_t *keytable, isc_mem_t *mctx) -{ - dns_rdataclass_t viewclass; - dns_rdata_dnskey_t keystruct; - isc_uint32_t flags, proto, alg; - const char *keystr, *keynamestr; - unsigned char keydata[4096]; - isc_buffer_t keydatabuf; - unsigned char rrdata[4096]; - isc_buffer_t rrdatabuf; - isc_region_t r; - dns_fixedname_t fkeyname; - dns_name_t *keyname; - isc_buffer_t namebuf; - isc_result_t result; - dst_key_t *dstkey = NULL; - - flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags")); - proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol")); - alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm")); - keyname = dns_fixedname_name(&fkeyname); - keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name")); - - if (vconfig == NULL) - viewclass = dns_rdataclass_in; - else { - const cfg_obj_t *classobj = cfg_tuple_get(vconfig, "class"); - CHECK(ns_config_getclass(classobj, dns_rdataclass_in, - &viewclass)); - } - keystruct.common.rdclass = viewclass; - keystruct.common.rdtype = dns_rdatatype_dnskey; - /* - * The key data in keystruct is not dynamically allocated. - */ - keystruct.mctx = NULL; - - ISC_LINK_INIT(&keystruct.common, link); - - if (flags > 0xffff) - CHECKM(ISC_R_RANGE, "key flags"); - if (proto > 0xff) - CHECKM(ISC_R_RANGE, "key protocol"); - if (alg > 0xff) - CHECKM(ISC_R_RANGE, "key algorithm"); - keystruct.flags = (isc_uint16_t)flags; - keystruct.protocol = (isc_uint8_t)proto; - keystruct.algorithm = (isc_uint8_t)alg; - - isc_buffer_init(&keydatabuf, keydata, sizeof(keydata)); - isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata)); - - keystr = cfg_obj_asstring(cfg_tuple_get(key, "key")); - CHECK(isc_base64_decodestring(keystr, &keydatabuf)); - isc_buffer_usedregion(&keydatabuf, &r); - keystruct.datalen = r.length; - keystruct.data = r.base; - - if ((keystruct.algorithm == DST_ALG_RSASHA1 || - keystruct.algorithm == DST_ALG_RSAMD5) && - r.length > 1 && r.base[0] == 1 && r.base[1] == 3) - cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, - "trusted key '%s' has a weak exponent", - keynamestr); - - CHECK(dns_rdata_fromstruct(NULL, - keystruct.common.rdclass, - keystruct.common.rdtype, - &keystruct, &rrdatabuf)); - dns_fixedname_init(&fkeyname); - isc_buffer_init(&namebuf, keynamestr, strlen(keynamestr)); - isc_buffer_add(&namebuf, strlen(keynamestr)); - CHECK(dns_name_fromtext(keyname, &namebuf, - dns_rootname, ISC_FALSE, - NULL)); - CHECK(dst_key_fromdns(keyname, viewclass, &rrdatabuf, - mctx, &dstkey)); - - CHECK(dns_keytable_add(keytable, &dstkey)); - INSIST(dstkey == NULL); - return (ISC_R_SUCCESS); - - cleanup: - if (result == DST_R_NOCRYPTO) { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, - "ignoring trusted key for '%s': no crypto support", - keynamestr); - result = ISC_R_SUCCESS; - } else { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, - "configuring trusted key for '%s': %s", - keynamestr, isc_result_totext(result)); - result = ISC_R_FAILURE; - } - - if (dstkey != NULL) - dst_key_free(&dstkey); - - return (result); -} - -/*% - * Configure DNSSEC keys for a view. Currently used only for - * the security roots. - * - * The per-view configuration values and the server-global defaults are read - * from 'vconfig' and 'config'. The variable to be configured is '*target'. - */ -static isc_result_t -configure_view_dnsseckeys(const cfg_obj_t *vconfig, const cfg_obj_t *config, - isc_mem_t *mctx, dns_keytable_t **target) -{ - isc_result_t result; - const cfg_obj_t *keys = NULL; - const cfg_obj_t *voptions = NULL; - const cfg_listelt_t *element, *element2; - const cfg_obj_t *keylist; - const cfg_obj_t *key; - dns_keytable_t *keytable = NULL; - - CHECK(dns_keytable_create(mctx, &keytable)); - - if (vconfig != NULL) - voptions = cfg_tuple_get(vconfig, "options"); - - keys = NULL; - if (voptions != NULL) - (void)cfg_map_get(voptions, "trusted-keys", &keys); - if (keys == NULL) - (void)cfg_map_get(config, "trusted-keys", &keys); - - for (element = cfg_list_first(keys); - element != NULL; - element = cfg_list_next(element)) - { - keylist = cfg_listelt_value(element); - for (element2 = cfg_list_first(keylist); - element2 != NULL; - element2 = cfg_list_next(element2)) - { - key = cfg_listelt_value(element2); - CHECK(configure_view_dnsseckey(vconfig, key, - keytable, mctx)); - } - } - - dns_keytable_detach(target); - *target = keytable; /* Transfer ownership. */ - keytable = NULL; - result = ISC_R_SUCCESS; - - cleanup: - return (result); -} - -static isc_result_t -mustbesecure(const cfg_obj_t *mbs, dns_resolver_t *resolver) -{ - const cfg_listelt_t *element; - const cfg_obj_t *obj; - const char *str; - dns_fixedname_t fixed; - dns_name_t *name; - isc_boolean_t value; - isc_result_t result; - isc_buffer_t b; - - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - for (element = cfg_list_first(mbs); - element != NULL; - element = cfg_list_next(element)) - { - obj = cfg_listelt_value(element); - str = cfg_obj_asstring(cfg_tuple_get(obj, "name")); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, - ISC_FALSE, NULL)); - value = cfg_obj_asboolean(cfg_tuple_get(obj, "value")); - CHECK(dns_resolver_setmustbesecure(resolver, name, value)); - } - - result = ISC_R_SUCCESS; - - cleanup: - return (result); -} - -/*% - * Get a dispatch appropriate for the resolver of a given view. - */ -static isc_result_t -get_view_querysource_dispatch(const cfg_obj_t **maps, - int af, dns_dispatch_t **dispatchp) -{ - isc_result_t result; - dns_dispatch_t *disp; - isc_sockaddr_t sa; - unsigned int attrs, attrmask; - const cfg_obj_t *obj = NULL; - - /* - * Make compiler happy. - */ - result = ISC_R_FAILURE; - - switch (af) { - case AF_INET: - result = ns_config_get(maps, "query-source", &obj); - INSIST(result == ISC_R_SUCCESS); - break; - case AF_INET6: - result = ns_config_get(maps, "query-source-v6", &obj); - INSIST(result == ISC_R_SUCCESS); - break; - default: - INSIST(0); - } - - sa = *(cfg_obj_assockaddr(obj)); - INSIST(isc_sockaddr_pf(&sa) == af); - - /* - * If we don't support this address family, we're done! - */ - switch (af) { - case AF_INET: - result = isc_net_probeipv4(); - break; - case AF_INET6: - result = isc_net_probeipv6(); - break; - default: - INSIST(0); - } - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - /* - * Try to find a dispatcher that we can share. - */ - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; - switch (af) { - case AF_INET: - attrs |= DNS_DISPATCHATTR_IPV4; - break; - case AF_INET6: - attrs |= DNS_DISPATCHATTR_IPV6; - break; - } - attrmask = 0; - attrmask |= DNS_DISPATCHATTR_UDP; - attrmask |= DNS_DISPATCHATTR_TCP; - attrmask |= DNS_DISPATCHATTR_IPV4; - attrmask |= DNS_DISPATCHATTR_IPV6; - - disp = NULL; - result = dns_dispatch_getudp(ns_g_dispatchmgr, ns_g_socketmgr, - ns_g_taskmgr, &sa, 4096, - 1000, 32768, 16411, 16433, - attrs, attrmask, &disp); - if (result != ISC_R_SUCCESS) { - isc_sockaddr_t any; - char buf[ISC_SOCKADDR_FORMATSIZE]; - - switch (af) { - case AF_INET: - isc_sockaddr_any(&any); - break; - case AF_INET6: - isc_sockaddr_any6(&any); - break; - } - if (isc_sockaddr_equal(&sa, &any)) - return (ISC_R_SUCCESS); - isc_sockaddr_format(&sa, buf, sizeof(buf)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "could not get query source dispatcher (%s)", - buf); - return (result); - } - - *dispatchp = disp; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -configure_order(dns_order_t *order, const cfg_obj_t *ent) { - dns_rdataclass_t rdclass; - dns_rdatatype_t rdtype; - const cfg_obj_t *obj; - dns_fixedname_t fixed; - unsigned int mode = 0; - const char *str; - isc_buffer_t b; - isc_result_t result; - isc_boolean_t addroot; - - result = ns_config_getclass(cfg_tuple_get(ent, "class"), - dns_rdataclass_any, &rdclass); - if (result != ISC_R_SUCCESS) - return (result); - - result = ns_config_gettype(cfg_tuple_get(ent, "type"), - dns_rdatatype_any, &rdtype); - if (result != ISC_R_SUCCESS) - return (result); - - obj = cfg_tuple_get(ent, "name"); - if (cfg_obj_isstring(obj)) - str = cfg_obj_asstring(obj); - else - str = "*"; - addroot = ISC_TF(strcmp(str, "*") == 0); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - dns_fixedname_init(&fixed); - result = dns_name_fromtext(dns_fixedname_name(&fixed), &b, - dns_rootname, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - obj = cfg_tuple_get(ent, "ordering"); - INSIST(cfg_obj_isstring(obj)); - str = cfg_obj_asstring(obj); - if (!strcasecmp(str, "fixed")) - mode = DNS_RDATASETATTR_FIXEDORDER; - else if (!strcasecmp(str, "random")) - mode = DNS_RDATASETATTR_RANDOMIZE; - else if (!strcasecmp(str, "cyclic")) - mode = 0; - else - INSIST(0); - - /* - * "*" should match everything including the root (BIND 8 compat). - * As dns_name_matcheswildcard(".", "*.") returns FALSE add a - * explicit entry for "." when the name is "*". - */ - if (addroot) { - result = dns_order_add(order, dns_rootname, - rdtype, rdclass, mode); - if (result != ISC_R_SUCCESS) - return (result); - } - - return (dns_order_add(order, dns_fixedname_name(&fixed), - rdtype, rdclass, mode)); -} - -static isc_result_t -configure_peer(const cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) { - isc_netaddr_t na; - dns_peer_t *peer; - const cfg_obj_t *obj; - const char *str; - isc_result_t result; - unsigned int prefixlen; - - cfg_obj_asnetprefix(cfg_map_getname(cpeer), &na, &prefixlen); - - peer = NULL; - result = dns_peer_new(mctx, &na, &peer); - if (result != ISC_R_SUCCESS) - return (result); - - obj = NULL; - (void)cfg_map_get(cpeer, "bogus", &obj); - if (obj != NULL) - CHECK(dns_peer_setbogus(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "provide-ixfr", &obj); - if (obj != NULL) - CHECK(dns_peer_setprovideixfr(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "request-ixfr", &obj); - if (obj != NULL) - CHECK(dns_peer_setrequestixfr(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "edns", &obj); - if (obj != NULL) - CHECK(dns_peer_setsupportedns(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "edns-udp-size", &obj); - if (obj != NULL) { - isc_uint32_t udpsize = cfg_obj_asuint32(obj); - if (udpsize < 512) - udpsize = 512; - if (udpsize > 4096) - udpsize = 4096; - CHECK(dns_peer_setudpsize(peer, (isc_uint16_t)udpsize)); - } - - obj = NULL; - (void)cfg_map_get(cpeer, "max-udp-size", &obj); - if (obj != NULL) { - isc_uint32_t udpsize = cfg_obj_asuint32(obj); - if (udpsize < 512) - udpsize = 512; - if (udpsize > 4096) - udpsize = 4096; - CHECK(dns_peer_setmaxudp(peer, (isc_uint16_t)udpsize)); - } - - obj = NULL; - (void)cfg_map_get(cpeer, "transfers", &obj); - if (obj != NULL) - CHECK(dns_peer_settransfers(peer, cfg_obj_asuint32(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "transfer-format", &obj); - if (obj != NULL) { - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "many-answers") == 0) - CHECK(dns_peer_settransferformat(peer, - dns_many_answers)); - else if (strcasecmp(str, "one-answer") == 0) - CHECK(dns_peer_settransferformat(peer, - dns_one_answer)); - else - INSIST(0); - } - - obj = NULL; - (void)cfg_map_get(cpeer, "keys", &obj); - if (obj != NULL) { - result = dns_peer_setkeybycharp(peer, cfg_obj_asstring(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - obj = NULL; - if (na.family == AF_INET) - (void)cfg_map_get(cpeer, "transfer-source", &obj); - else - (void)cfg_map_get(cpeer, "transfer-source-v6", &obj); - if (obj != NULL) { - result = dns_peer_settransfersource(peer, - cfg_obj_assockaddr(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - } - - obj = NULL; - if (na.family == AF_INET) - (void)cfg_map_get(cpeer, "notify-source", &obj); - else - (void)cfg_map_get(cpeer, "notify-source-v6", &obj); - if (obj != NULL) { - result = dns_peer_setnotifysource(peer, - cfg_obj_assockaddr(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - } - - obj = NULL; - if (na.family == AF_INET) - (void)cfg_map_get(cpeer, "query-source", &obj); - else - (void)cfg_map_get(cpeer, "query-source-v6", &obj); - if (obj != NULL) { - result = dns_peer_setquerysource(peer, - cfg_obj_assockaddr(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - } - - *peerp = peer; - return (ISC_R_SUCCESS); - - cleanup: - dns_peer_detach(&peer); - return (result); -} - -static isc_result_t -disable_algorithms(const cfg_obj_t *disabled, dns_resolver_t *resolver) { - isc_result_t result; - const cfg_obj_t *algorithms; - const cfg_listelt_t *element; - const char *str; - dns_fixedname_t fixed; - dns_name_t *name; - isc_buffer_t b; - - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - str = cfg_obj_asstring(cfg_tuple_get(disabled, "name")); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL)); - - algorithms = cfg_tuple_get(disabled, "algorithms"); - for (element = cfg_list_first(algorithms); - element != NULL; - element = cfg_list_next(element)) - { - isc_textregion_t r; - dns_secalg_t alg; - - DE_CONST(cfg_obj_asstring(cfg_listelt_value(element)), r.base); - r.length = strlen(r.base); - - result = dns_secalg_fromtext(&alg, &r); - if (result != ISC_R_SUCCESS) { - isc_uint8_t ui; - result = isc_parse_uint8(&ui, r.base, 10); - alg = ui; - } - if (result != ISC_R_SUCCESS) { - cfg_obj_log(cfg_listelt_value(element), - ns_g_lctx, ISC_LOG_ERROR, - "invalid algorithm"); - CHECK(result); - } - CHECK(dns_resolver_disable_algorithm(resolver, name, alg)); - } - cleanup: - return (result); -} - -static isc_boolean_t -on_disable_list(const cfg_obj_t *disablelist, dns_name_t *zonename) { - const cfg_listelt_t *element; - dns_fixedname_t fixed; - dns_name_t *name; - isc_result_t result; - const cfg_obj_t *value; - const char *str; - isc_buffer_t b; - - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - - for (element = cfg_list_first(disablelist); - element != NULL; - element = cfg_list_next(element)) - { - value = cfg_listelt_value(element); - str = cfg_obj_asstring(value); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - result = dns_name_fromtext(name, &b, dns_rootname, - ISC_TRUE, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - if (dns_name_equal(name, zonename)) - return (ISC_TRUE); - } - return (ISC_FALSE); -} - -static void -check_dbtype(dns_zone_t **zonep, unsigned int dbtypec, const char **dbargv, - isc_mem_t *mctx) -{ - char **argv = NULL; - unsigned int i; - isc_result_t result; - - result = dns_zone_getdbtype(*zonep, &argv, mctx); - if (result != ISC_R_SUCCESS) { - dns_zone_detach(zonep); - return; - } - - /* - * Check that all the arguments match. - */ - for (i = 0; i < dbtypec; i++) - if (argv[i] == NULL || strcmp(argv[i], dbargv[i]) != 0) { - dns_zone_detach(zonep); - break; - } - - /* - * Check that there are not extra arguments. - */ - if (i == dbtypec && argv[i] != NULL) - dns_zone_detach(zonep); - isc_mem_free(mctx, argv); -} - - -/* - * Configure 'view' according to 'vconfig', taking defaults from 'config' - * where values are missing in 'vconfig'. - * - * When configuring the default view, 'vconfig' will be NULL and the - * global defaults in 'config' used exclusively. - */ -static isc_result_t -configure_view(dns_view_t *view, const cfg_obj_t *config, - const cfg_obj_t *vconfig, isc_mem_t *mctx, - cfg_aclconfctx_t *actx, isc_boolean_t need_hints) -{ - const cfg_obj_t *maps[4]; - const cfg_obj_t *cfgmaps[3]; - const cfg_obj_t *options = NULL; - const cfg_obj_t *voptions = NULL; - const cfg_obj_t *forwardtype; - const cfg_obj_t *forwarders; - const cfg_obj_t *alternates; - const cfg_obj_t *zonelist; -#ifdef DLZ - const cfg_obj_t *dlz; - unsigned int dlzargc; - char **dlzargv; -#endif - const cfg_obj_t *disabled; - const cfg_obj_t *obj; - const cfg_listelt_t *element; - in_port_t port; - dns_cache_t *cache = NULL; - isc_result_t result; - isc_uint32_t max_adb_size; - isc_uint32_t max_cache_size; - isc_uint32_t max_acache_size; - isc_uint32_t lame_ttl; - dns_tsig_keyring_t *ring; - dns_view_t *pview = NULL; /* Production view */ - isc_mem_t *cmctx; - dns_dispatch_t *dispatch4 = NULL; - dns_dispatch_t *dispatch6 = NULL; - isc_boolean_t reused_cache = ISC_FALSE; - int i; - const char *str; - dns_order_t *order = NULL; - isc_uint32_t udpsize; - unsigned int check = 0; - dns_zone_t *zone = NULL; - isc_uint32_t max_clients_per_query; - const char *sep = ": view "; - const char *viewname = view->name; - const char *forview = " for view "; - isc_boolean_t rfc1918; - isc_boolean_t empty_zones_enable; - const cfg_obj_t *disablelist = NULL; - - REQUIRE(DNS_VIEW_VALID(view)); - - cmctx = NULL; - - if (config != NULL) - (void)cfg_map_get(config, "options", &options); - - i = 0; - if (vconfig != NULL) { - voptions = cfg_tuple_get(vconfig, "options"); - maps[i++] = voptions; - } - if (options != NULL) - maps[i++] = options; - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - i = 0; - if (voptions != NULL) - cfgmaps[i++] = voptions; - if (config != NULL) - cfgmaps[i++] = config; - cfgmaps[i] = NULL; - - if (!strcmp(viewname, "_default")) { - sep = ""; - viewname = ""; - forview = ""; - } - - /* - * Set the view's port number for outgoing queries. - */ - CHECKM(ns_config_getport(config, &port), "port"); - dns_view_setdstport(view, port); - - /* - * Create additional cache for this view and zones under the view - * if explicitly enabled. - * XXX950 default to on. - */ - obj = NULL; - (void)ns_config_get(maps, "acache-enable", &obj); - if (obj != NULL && cfg_obj_asboolean(obj)) { - cmctx = NULL; - CHECK(isc_mem_create(0, 0, &cmctx)); - CHECK(dns_acache_create(&view->acache, cmctx, ns_g_taskmgr, - ns_g_timermgr)); - isc_mem_detach(&cmctx); - } - if (view->acache != NULL) { - obj = NULL; - result = ns_config_get(maps, "acache-cleaning-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_acache_setcleaninginterval(view->acache, - cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-acache-size", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isstring(obj)) { - str = cfg_obj_asstring(obj); - INSIST(strcasecmp(str, "unlimited") == 0); - max_acache_size = ISC_UINT32_MAX; - } else { - isc_resourcevalue_t value; - - value = cfg_obj_asuint64(obj); - if (value > ISC_UINT32_MAX) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, - "'max-acache-size " - "%" ISC_PRINT_QUADFORMAT - "d' is too large", - value); - result = ISC_R_RANGE; - goto cleanup; - } - max_acache_size = (isc_uint32_t)value; - } - dns_acache_setcachesize(view->acache, max_acache_size); - } - - /* - * Configure the zones. - */ - zonelist = NULL; - if (voptions != NULL) - (void)cfg_map_get(voptions, "zone", &zonelist); - else - (void)cfg_map_get(config, "zone", &zonelist); - for (element = cfg_list_first(zonelist); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *zconfig = cfg_listelt_value(element); - CHECK(configure_zone(config, zconfig, vconfig, mctx, view, - actx)); - } - -#ifdef DLZ - /* - * Create Dynamically Loadable Zone driver. - */ - dlz = NULL; - if (voptions != NULL) - (void)cfg_map_get(voptions, "dlz", &dlz); - else - (void)cfg_map_get(config, "dlz", &dlz); - - obj = NULL; - if (dlz != NULL) { - (void)cfg_map_get(cfg_tuple_get(dlz, "options"), - "database", &obj); - if (obj != NULL) { - char *s = isc_mem_strdup(mctx, cfg_obj_asstring(obj)); - if (s == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - - result = dns_dlzstrtoargv(mctx, s, &dlzargc, &dlzargv); - if (result != ISC_R_SUCCESS) { - isc_mem_free(mctx, s); - goto cleanup; - } - - obj = cfg_tuple_get(dlz, "name"); - result = dns_dlzcreate(mctx, cfg_obj_asstring(obj), - dlzargv[0], dlzargc, dlzargv, - &view->dlzdatabase); - isc_mem_free(mctx, s); - isc_mem_put(mctx, dlzargv, dlzargc * sizeof(*dlzargv)); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - } -#endif - - /* - * Configure the view's cache. Try to reuse an existing - * cache if possible, otherwise create a new cache. - * Note that the ADB is not preserved in either case. - * - * XXX Determining when it is safe to reuse a cache is - * tricky. When the view's configuration changes, the cached - * data may become invalid because it reflects our old - * view of the world. As more view attributes become - * configurable, we will have to add code here to check - * whether they have changed in ways that could - * invalidate the cache. - */ - result = dns_viewlist_find(&ns_g_server->viewlist, - view->name, view->rdclass, - &pview); - if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) - goto cleanup; - if (pview != NULL) { - INSIST(pview->cache != NULL); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(3), - "reusing existing cache"); - reused_cache = ISC_TRUE; - dns_cache_attach(pview->cache, &cache); - dns_view_detach(&pview); - } else { - CHECK(isc_mem_create(0, 0, &cmctx)); - CHECK(dns_cache_create(cmctx, ns_g_taskmgr, ns_g_timermgr, - view->rdclass, "rbt", 0, NULL, &cache)); - } - dns_view_setcache(view, cache); - - /* - * cache-file cannot be inherited if views are present, but this - * should be caught by the configuration checking stage. - */ - obj = NULL; - result = ns_config_get(maps, "cache-file", &obj); - if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") != 0) { - CHECK(dns_cache_setfilename(cache, cfg_obj_asstring(obj))); - if (!reused_cache) - CHECK(dns_cache_load(cache)); - } - - obj = NULL; - result = ns_config_get(maps, "cleaning-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_cache_setcleaninginterval(cache, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-cache-size", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isstring(obj)) { - str = cfg_obj_asstring(obj); - INSIST(strcasecmp(str, "unlimited") == 0); - max_cache_size = ISC_UINT32_MAX; - } else { - isc_resourcevalue_t value; - value = cfg_obj_asuint64(obj); - if (value > ISC_UINT32_MAX) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, - "'max-cache-size " - "%" ISC_PRINT_QUADFORMAT "d' is too large", - value); - result = ISC_R_RANGE; - goto cleanup; - } - max_cache_size = (isc_uint32_t)value; - } - dns_cache_setcachesize(cache, max_cache_size); - - dns_cache_detach(&cache); - - /* - * Check-names. - */ - obj = NULL; - result = ns_checknames_get(maps, "response", &obj); - INSIST(result == ISC_R_SUCCESS); - - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "fail") == 0) { - check = DNS_RESOLVER_CHECKNAMES | - DNS_RESOLVER_CHECKNAMESFAIL; - view->checknames = ISC_TRUE; - } else if (strcasecmp(str, "warn") == 0) { - check = DNS_RESOLVER_CHECKNAMES; - view->checknames = ISC_FALSE; - } else if (strcasecmp(str, "ignore") == 0) { - check = 0; - view->checknames = ISC_FALSE; - } else - INSIST(0); - - /* - * Resolver. - * - * XXXRTH Hardwired number of tasks. - */ - CHECK(get_view_querysource_dispatch(maps, AF_INET, &dispatch4)); - CHECK(get_view_querysource_dispatch(maps, AF_INET6, &dispatch6)); - if (dispatch4 == NULL && dispatch6 == NULL) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "unable to obtain neither an IPv4 nor" - " an IPv6 dispatch"); - result = ISC_R_UNEXPECTED; - goto cleanup; - } - CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31, - ns_g_socketmgr, ns_g_timermgr, - check, ns_g_dispatchmgr, - dispatch4, dispatch6)); - - /* - * Set the ADB cache size to 1/8th of the max-cache-size. - */ - max_adb_size = 0; - if (max_cache_size != 0) { - max_adb_size = max_cache_size / 8; - if (max_adb_size == 0) - max_adb_size = 1; /* Force minimum. */ - } - dns_adb_setadbsize(view->adb, max_adb_size); - - /* - * Set resolver's lame-ttl. - */ - obj = NULL; - result = ns_config_get(maps, "lame-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - lame_ttl = cfg_obj_asuint32(obj); - if (lame_ttl > 1800) - lame_ttl = 1800; - dns_resolver_setlamettl(view->resolver, lame_ttl); - - obj = NULL; - result = ns_config_get(maps, "zero-no-soa-ttl-cache", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_resolver_setzeronosoattl(view->resolver, cfg_obj_asboolean(obj)); - - /* - * Set the resolver's EDNS UDP size. - */ - obj = NULL; - result = ns_config_get(maps, "edns-udp-size", &obj); - INSIST(result == ISC_R_SUCCESS); - udpsize = cfg_obj_asuint32(obj); - if (udpsize < 512) - udpsize = 512; - if (udpsize > 4096) - udpsize = 4096; - dns_resolver_setudpsize(view->resolver, (isc_uint16_t)udpsize); - - /* - * Set the maximum UDP response size. - */ - obj = NULL; - result = ns_config_get(maps, "max-udp-size", &obj); - INSIST(result == ISC_R_SUCCESS); - udpsize = cfg_obj_asuint32(obj); - if (udpsize < 512) - udpsize = 512; - if (udpsize > 4096) - udpsize = 4096; - view->maxudp = udpsize; - - /* - * Set supported DNSSEC algorithms. - */ - dns_resolver_reset_algorithms(view->resolver); - disabled = NULL; - (void)ns_config_get(maps, "disable-algorithms", &disabled); - if (disabled != NULL) { - for (element = cfg_list_first(disabled); - element != NULL; - element = cfg_list_next(element)) - CHECK(disable_algorithms(cfg_listelt_value(element), - view->resolver)); - } - - /* - * A global or view "forwarders" option, if present, - * creates an entry for "." in the forwarding table. - */ - forwardtype = NULL; - forwarders = NULL; - (void)ns_config_get(maps, "forward", &forwardtype); - (void)ns_config_get(maps, "forwarders", &forwarders); - if (forwarders != NULL) - CHECK(configure_forward(config, view, dns_rootname, - forwarders, forwardtype)); - - /* - * Dual Stack Servers. - */ - alternates = NULL; - (void)ns_config_get(maps, "dual-stack-servers", &alternates); - if (alternates != NULL) - CHECK(configure_alternates(config, view, alternates)); - - /* - * We have default hints for class IN if we need them. - */ - if (view->rdclass == dns_rdataclass_in && view->hints == NULL) - dns_view_sethints(view, ns_g_server->in_roothints); - - /* - * If we still have no hints, this is a non-IN view with no - * "hints zone" configured. Issue a warning, except if this - * is a root server. Root servers never need to consult - * their hints, so it's no point requiring users to configure - * them. - */ - if (view->hints == NULL) { - dns_zone_t *rootzone = NULL; - (void)dns_view_findzone(view, dns_rootname, &rootzone); - if (rootzone != NULL) { - dns_zone_detach(&rootzone); - need_hints = ISC_FALSE; - } - if (need_hints) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "no root hints for view '%s'", - view->name); - } - - /* - * Configure the view's TSIG keys. - */ - ring = NULL; - CHECK(ns_tsigkeyring_fromconfig(config, vconfig, view->mctx, &ring)); - dns_view_setkeyring(view, ring); - - /* - * Configure the view's peer list. - */ - { - const cfg_obj_t *peers = NULL; - const cfg_listelt_t *element; - dns_peerlist_t *newpeers = NULL; - - (void)ns_config_get(cfgmaps, "server", &peers); - CHECK(dns_peerlist_new(mctx, &newpeers)); - for (element = cfg_list_first(peers); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *cpeer = cfg_listelt_value(element); - dns_peer_t *peer; - - CHECK(configure_peer(cpeer, mctx, &peer)); - dns_peerlist_addpeer(newpeers, peer); - dns_peer_detach(&peer); - } - dns_peerlist_detach(&view->peers); - view->peers = newpeers; /* Transfer ownership. */ - } - - /* - * Configure the views rrset-order. - */ - { - const cfg_obj_t *rrsetorder = NULL; - const cfg_listelt_t *element; - - (void)ns_config_get(maps, "rrset-order", &rrsetorder); - CHECK(dns_order_create(mctx, &order)); - for (element = cfg_list_first(rrsetorder); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *ent = cfg_listelt_value(element); - - CHECK(configure_order(order, ent)); - } - if (view->order != NULL) - dns_order_detach(&view->order); - dns_order_attach(order, &view->order); - dns_order_detach(&order); - } - /* - * Copy the aclenv object. - */ - dns_aclenv_copy(&view->aclenv, &ns_g_server->aclenv); - - /* - * Configure the "match-clients" and "match-destinations" ACL. - */ - CHECK(configure_view_acl(vconfig, config, "match-clients", actx, - ns_g_mctx, &view->matchclients)); - CHECK(configure_view_acl(vconfig, config, "match-destinations", actx, - ns_g_mctx, &view->matchdestinations)); - - /* - * Configure the "match-recursive-only" option. - */ - obj = NULL; - (void)ns_config_get(maps, "match-recursive-only", &obj); - if (obj != NULL && cfg_obj_asboolean(obj)) - view->matchrecursiveonly = ISC_TRUE; - else - view->matchrecursiveonly = ISC_FALSE; - - /* - * Configure other configurable data. - */ - obj = NULL; - result = ns_config_get(maps, "recursion", &obj); - INSIST(result == ISC_R_SUCCESS); - view->recursion = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "auth-nxdomain", &obj); - INSIST(result == ISC_R_SUCCESS); - view->auth_nxdomain = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "minimal-responses", &obj); - INSIST(result == ISC_R_SUCCESS); - view->minimalresponses = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "transfer-format", &obj); - INSIST(result == ISC_R_SUCCESS); - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "many-answers") == 0) - view->transfer_format = dns_many_answers; - else if (strcasecmp(str, "one-answer") == 0) - view->transfer_format = dns_one_answer; - else - INSIST(0); - - /* - * Set sources where additional data and CNAME/DNAME - * targets for authoritative answers may be found. - */ - obj = NULL; - result = ns_config_get(maps, "additional-from-auth", &obj); - INSIST(result == ISC_R_SUCCESS); - view->additionalfromauth = cfg_obj_asboolean(obj); - if (view->recursion && ! view->additionalfromauth) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, - "'additional-from-auth no' is only supported " - "with 'recursion no'"); - view->additionalfromauth = ISC_TRUE; - } - - obj = NULL; - result = ns_config_get(maps, "additional-from-cache", &obj); - INSIST(result == ISC_R_SUCCESS); - view->additionalfromcache = cfg_obj_asboolean(obj); - if (view->recursion && ! view->additionalfromcache) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, - "'additional-from-cache no' is only supported " - "with 'recursion no'"); - view->additionalfromcache = ISC_TRUE; - } - - /* - * Set "allow-query-cache" and "allow-recursion" acls if - * configured in named.conf. - */ - CHECK(configure_view_acl(vconfig, config, "allow-query-cache", - actx, ns_g_mctx, &view->queryacl)); - - if (strcmp(view->name, "_bind") != 0) - CHECK(configure_view_acl(vconfig, config, "allow-recursion", - actx, ns_g_mctx, &view->recursionacl)); - - /* - * Warning if both "recursion no;" and allow-recursion are active - * except for "allow-recursion { none; };". - */ - if (!view->recursion && view->recursionacl != NULL && - (view->recursionacl->length != 1 || - view->recursionacl->elements[0].type != dns_aclelementtype_any || - view->recursionacl->elements[0].negative != ISC_TRUE)) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "both \"recursion no;\" and \"allow-recursion\" " - "active%s%s", forview, viewname); - - /* - * "allow-query-cache" inherits from "allow-recursion" if set, - * otherwise from "allow-query" if set. - * "allow-recursion" inherits from "allow-query-cache" if set, - * otherwise from "allow-query" if set. - */ - if (view->queryacl == NULL && view->recursionacl != NULL) - dns_acl_attach(view->recursionacl, &view->queryacl); - if (view->queryacl == NULL) - CHECK(configure_view_acl(vconfig, config, "allow-query", - actx, ns_g_mctx, &view->queryacl)); - if (view->recursionacl == NULL && view->queryacl != NULL) - dns_acl_attach(view->queryacl, &view->recursionacl); - - /* - * Set default "allow-recursion" and "allow-query-cache" acls. - */ - if (view->recursionacl == NULL && view->recursion) - CHECK(configure_view_acl(NULL, ns_g_config, "allow-recursion", - actx, ns_g_mctx, &view->recursionacl)); - if (view->queryacl == NULL) - CHECK(configure_view_acl(NULL, ns_g_config, - "allow-query-cache", actx, - ns_g_mctx, &view->queryacl)); - - CHECK(configure_view_acl(vconfig, config, "sortlist", - actx, ns_g_mctx, &view->sortlist)); - - obj = NULL; - result = ns_config_get(maps, "request-ixfr", &obj); - INSIST(result == ISC_R_SUCCESS); - view->requestixfr = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "provide-ixfr", &obj); - INSIST(result == ISC_R_SUCCESS); - view->provideixfr = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "max-clients-per-query", &obj); - INSIST(result == ISC_R_SUCCESS); - max_clients_per_query = cfg_obj_asuint32(obj); - - obj = NULL; - result = ns_config_get(maps, "clients-per-query", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_resolver_setclientsperquery(view->resolver, - cfg_obj_asuint32(obj), - max_clients_per_query); - - obj = NULL; - result = ns_config_get(maps, "dnssec-enable", &obj); - INSIST(result == ISC_R_SUCCESS); - view->enablednssec = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "dnssec-accept-expired", &obj); - INSIST(result == ISC_R_SUCCESS); - view->acceptexpired = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "dnssec-validation", &obj); - INSIST(result == ISC_R_SUCCESS); - view->enablevalidation = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "dnssec-lookaside", &obj); - if (result == ISC_R_SUCCESS) { - for (element = cfg_list_first(obj); - element != NULL; - element = cfg_list_next(element)) - { - const char *str; - isc_buffer_t b; - dns_name_t *dlv; - - obj = cfg_listelt_value(element); -#if 0 - dns_fixedname_t fixed; - dns_name_t *name; - - /* - * When we support multiple dnssec-lookaside - * entries this is how to find the domain to be - * checked. XXXMPA - */ - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - str = cfg_obj_asstring(cfg_tuple_get(obj, - "domain")); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, - ISC_TRUE, NULL)); -#endif - str = cfg_obj_asstring(cfg_tuple_get(obj, - "trust-anchor")); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - dlv = dns_fixedname_name(&view->dlv_fixed); - CHECK(dns_name_fromtext(dlv, &b, dns_rootname, - ISC_TRUE, NULL)); - view->dlv = dns_fixedname_name(&view->dlv_fixed); - } - } else - view->dlv = NULL; - - /* - * For now, there is only one kind of trusted keys, the - * "security roots". - */ - CHECK(configure_view_dnsseckeys(vconfig, config, mctx, - &view->secroots)); - dns_resolver_resetmustbesecure(view->resolver); - obj = NULL; - result = ns_config_get(maps, "dnssec-must-be-secure", &obj); - if (result == ISC_R_SUCCESS) - CHECK(mustbesecure(obj, view->resolver)); - - obj = NULL; - result = ns_config_get(maps, "max-cache-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - view->maxcachettl = cfg_obj_asuint32(obj); - - obj = NULL; - result = ns_config_get(maps, "max-ncache-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - view->maxncachettl = cfg_obj_asuint32(obj); - if (view->maxncachettl > 7 * 24 * 3600) - view->maxncachettl = 7 * 24 * 3600; - - obj = NULL; - result = ns_config_get(maps, "preferred-glue", &obj); - if (result == ISC_R_SUCCESS) { - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "a") == 0) - view->preferred_glue = dns_rdatatype_a; - else if (strcasecmp(str, "aaaa") == 0) - view->preferred_glue = dns_rdatatype_aaaa; - else - view->preferred_glue = 0; - } else - view->preferred_glue = 0; - - obj = NULL; - result = ns_config_get(maps, "root-delegation-only", &obj); - if (result == ISC_R_SUCCESS) { - dns_view_setrootdelonly(view, ISC_TRUE); - if (!cfg_obj_isvoid(obj)) { - dns_fixedname_t fixed; - dns_name_t *name; - isc_buffer_t b; - const char *str; - const cfg_obj_t *exclude; - - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - for (element = cfg_list_first(obj); - element != NULL; - element = cfg_list_next(element)) { - exclude = cfg_listelt_value(element); - str = cfg_obj_asstring(exclude); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, - ISC_FALSE, NULL)); - CHECK(dns_view_excludedelegationonly(view, - name)); - } - } - } else - dns_view_setrootdelonly(view, ISC_FALSE); - - /* - * Setup automatic empty zones. If recursion is off then - * they are disabled by default. - */ - obj = NULL; - (void)ns_config_get(maps, "empty-zones-enable", &obj); - (void)ns_config_get(maps, "disable-empty-zone", &disablelist); - if (obj == NULL && disablelist == NULL && - view->rdclass == dns_rdataclass_in) { - rfc1918 = ISC_FALSE; - empty_zones_enable = view->recursion; - } else if (view->rdclass == dns_rdataclass_in) { - rfc1918 = ISC_TRUE; - if (obj != NULL) - empty_zones_enable = cfg_obj_asboolean(obj); - else - empty_zones_enable = view->recursion; - } else { - rfc1918 = ISC_FALSE; - empty_zones_enable = ISC_FALSE; - } - if (empty_zones_enable) { - const char *empty; - int empty_zone = 0; - dns_fixedname_t fixed; - dns_name_t *name; - isc_buffer_t buffer; - const char *str; - char server[DNS_NAME_FORMATSIZE + 1]; - char contact[DNS_NAME_FORMATSIZE + 1]; - isc_boolean_t logit; - const char *empty_dbtype[4] = - { "_builtin", "empty", NULL, NULL }; - int empty_dbtypec = 4; - - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - - obj = NULL; - result = ns_config_get(maps, "empty-server", &obj); - if (result == ISC_R_SUCCESS) { - str = cfg_obj_asstring(obj); - isc_buffer_init(&buffer, str, strlen(str)); - isc_buffer_add(&buffer, strlen(str)); - CHECK(dns_name_fromtext(name, &buffer, dns_rootname, - ISC_FALSE, NULL)); - isc_buffer_init(&buffer, server, sizeof(server) - 1); - CHECK(dns_name_totext(name, ISC_FALSE, &buffer)); - server[isc_buffer_usedlength(&buffer)] = 0; - empty_dbtype[2] = server; - } else - empty_dbtype[2] = "@"; - - obj = NULL; - result = ns_config_get(maps, "empty-contact", &obj); - if (result == ISC_R_SUCCESS) { - str = cfg_obj_asstring(obj); - isc_buffer_init(&buffer, str, strlen(str)); - isc_buffer_add(&buffer, strlen(str)); - CHECK(dns_name_fromtext(name, &buffer, dns_rootname, - ISC_FALSE, NULL)); - isc_buffer_init(&buffer, contact, sizeof(contact) - 1); - CHECK(dns_name_totext(name, ISC_FALSE, &buffer)); - contact[isc_buffer_usedlength(&buffer)] = 0; - empty_dbtype[3] = contact; - } else - empty_dbtype[3] = "."; - - logit = ISC_TRUE; - for (empty = empty_zones[empty_zone].zone; - empty != NULL; - empty = empty_zones[++empty_zone].zone) - { - dns_forwarders_t *forwarders = NULL; - dns_view_t *pview = NULL; - - isc_buffer_init(&buffer, empty, strlen(empty)); - isc_buffer_add(&buffer, strlen(empty)); - /* - * Look for zone on drop list. - */ - CHECK(dns_name_fromtext(name, &buffer, dns_rootname, - ISC_FALSE, NULL)); - if (disablelist != NULL && - on_disable_list(disablelist, name)) - continue; - - /* - * This zone already exists. - */ - (void)dns_view_findzone(view, name, &zone); - if (zone != NULL) { - dns_zone_detach(&zone); - continue; - } - - /* - * If we would forward this name don't add a - * empty zone for it. - */ - result = dns_fwdtable_find(view->fwdtable, name, - &forwarders); - if (result == ISC_R_SUCCESS && - forwarders->fwdpolicy == dns_fwdpolicy_only) - continue; - - if (!rfc1918 && empty_zones[empty_zone].rfc1918) { - if (logit) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_WARNING, - "Warning%s%s: " - "'empty-zones-enable/" - "disable-empty-zone' " - "not set: disabling " - "RFC 1918 empty zones", - sep, viewname); - logit = ISC_FALSE; - } - continue; - } - - /* - * See if we can re-use a existing zone. - */ - result = dns_viewlist_find(&ns_g_server->viewlist, - view->name, view->rdclass, - &pview); - if (result != ISC_R_NOTFOUND && - result != ISC_R_SUCCESS) - goto cleanup; - - if (pview != NULL) { - (void)dns_view_findzone(pview, name, &zone); - dns_view_detach(&pview); - if (zone != NULL) - check_dbtype(&zone, empty_dbtypec, - empty_dbtype, mctx); - if (zone != NULL) { - dns_zone_setview(zone, view); - CHECK(dns_view_addzone(view, zone)); - dns_zone_detach(&zone); - continue; - } - } - - CHECK(dns_zone_create(&zone, mctx)); - CHECK(dns_zone_setorigin(zone, name)); - dns_zone_setview(zone, view); - CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone)); - dns_zone_setclass(zone, view->rdclass); - dns_zone_settype(zone, dns_zone_master); - CHECK(dns_zone_setdbtype(zone, empty_dbtypec, - empty_dbtype)); - if (view->queryacl != NULL) - dns_zone_setqueryacl(zone, view->queryacl); - dns_zone_setdialup(zone, dns_dialuptype_no); - dns_zone_setnotifytype(zone, dns_notifytype_no); - dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, - ISC_TRUE); - CHECK(dns_view_addzone(view, zone)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "automatic empty zone%s%s: %s", - sep, viewname, empty); - dns_zone_detach(&zone); - } - } - - result = ISC_R_SUCCESS; - - cleanup: - if (zone != NULL) - dns_zone_detach(&zone); - if (dispatch4 != NULL) - dns_dispatch_detach(&dispatch4); - if (dispatch6 != NULL) - dns_dispatch_detach(&dispatch6); - if (order != NULL) - dns_order_detach(&order); - if (cmctx != NULL) - isc_mem_detach(&cmctx); - - if (cache != NULL) - dns_cache_detach(&cache); - - return (result); -} - -static isc_result_t -configure_hints(dns_view_t *view, const char *filename) { - isc_result_t result; - dns_db_t *db; - - db = NULL; - result = dns_rootns_create(view->mctx, view->rdclass, filename, &db); - if (result == ISC_R_SUCCESS) { - dns_view_sethints(view, db); - dns_db_detach(&db); - } - - return (result); -} - -static isc_result_t -configure_alternates(const cfg_obj_t *config, dns_view_t *view, - const cfg_obj_t *alternates) -{ - const cfg_obj_t *portobj; - const cfg_obj_t *addresses; - const cfg_listelt_t *element; - isc_result_t result = ISC_R_SUCCESS; - in_port_t port; - - /* - * Determine which port to send requests to. - */ - if (ns_g_lwresdonly && ns_g_port != 0) - port = ns_g_port; - else - CHECKM(ns_config_getport(config, &port), "port"); - - if (alternates != NULL) { - portobj = cfg_tuple_get(alternates, "port"); - if (cfg_obj_isuint32(portobj)) { - isc_uint32_t val = cfg_obj_asuint32(portobj); - if (val > ISC_UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", val); - return (ISC_R_RANGE); - } - port = (in_port_t) val; - } - } - - addresses = NULL; - if (alternates != NULL) - addresses = cfg_tuple_get(alternates, "addresses"); - - for (element = cfg_list_first(addresses); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *alternate = cfg_listelt_value(element); - isc_sockaddr_t sa; - - if (!cfg_obj_issockaddr(alternate)) { - dns_fixedname_t fixed; - dns_name_t *name; - const char *str = cfg_obj_asstring(cfg_tuple_get( - alternate, "name")); - isc_buffer_t buffer; - in_port_t myport = port; - - isc_buffer_init(&buffer, str, strlen(str)); - isc_buffer_add(&buffer, strlen(str)); - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - CHECK(dns_name_fromtext(name, &buffer, dns_rootname, - ISC_FALSE, NULL)); - - portobj = cfg_tuple_get(alternate, "port"); - if (cfg_obj_isuint32(portobj)) { - isc_uint32_t val = cfg_obj_asuint32(portobj); - if (val > ISC_UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, - ISC_LOG_ERROR, - "port '%u' out of range", - val); - return (ISC_R_RANGE); - } - myport = (in_port_t) val; - } - CHECK(dns_resolver_addalternate(view->resolver, NULL, - name, myport)); - continue; - } - - sa = *cfg_obj_assockaddr(alternate); - if (isc_sockaddr_getport(&sa) == 0) - isc_sockaddr_setport(&sa, port); - CHECK(dns_resolver_addalternate(view->resolver, &sa, - NULL, 0)); - } - - cleanup: - return (result); -} - -static isc_result_t -configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin, - const cfg_obj_t *forwarders, const cfg_obj_t *forwardtype) -{ - const cfg_obj_t *portobj; - const cfg_obj_t *faddresses; - const cfg_listelt_t *element; - dns_fwdpolicy_t fwdpolicy = dns_fwdpolicy_none; - isc_sockaddrlist_t addresses; - isc_sockaddr_t *sa; - isc_result_t result; - in_port_t port; - - /* - * Determine which port to send forwarded requests to. - */ - if (ns_g_lwresdonly && ns_g_port != 0) - port = ns_g_port; - else - CHECKM(ns_config_getport(config, &port), "port"); - - if (forwarders != NULL) { - portobj = cfg_tuple_get(forwarders, "port"); - if (cfg_obj_isuint32(portobj)) { - isc_uint32_t val = cfg_obj_asuint32(portobj); - if (val > ISC_UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", val); - return (ISC_R_RANGE); - } - port = (in_port_t) val; - } - } - - faddresses = NULL; - if (forwarders != NULL) - faddresses = cfg_tuple_get(forwarders, "addresses"); - - ISC_LIST_INIT(addresses); - - for (element = cfg_list_first(faddresses); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *forwarder = cfg_listelt_value(element); - sa = isc_mem_get(view->mctx, sizeof(isc_sockaddr_t)); - if (sa == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - *sa = *cfg_obj_assockaddr(forwarder); - if (isc_sockaddr_getport(sa) == 0) - isc_sockaddr_setport(sa, port); - ISC_LINK_INIT(sa, link); - ISC_LIST_APPEND(addresses, sa, link); - } - - if (ISC_LIST_EMPTY(addresses)) { - if (forwardtype != NULL) - cfg_obj_log(forwarders, ns_g_lctx, ISC_LOG_WARNING, - "no forwarders seen; disabling " - "forwarding"); - fwdpolicy = dns_fwdpolicy_none; - } else { - if (forwardtype == NULL) - fwdpolicy = dns_fwdpolicy_first; - else { - const char *forwardstr = cfg_obj_asstring(forwardtype); - if (strcasecmp(forwardstr, "first") == 0) - fwdpolicy = dns_fwdpolicy_first; - else if (strcasecmp(forwardstr, "only") == 0) - fwdpolicy = dns_fwdpolicy_only; - else - INSIST(0); - } - } - - result = dns_fwdtable_add(view->fwdtable, origin, &addresses, - fwdpolicy); - if (result != ISC_R_SUCCESS) { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(origin, namebuf, sizeof(namebuf)); - cfg_obj_log(forwarders, ns_g_lctx, ISC_LOG_WARNING, - "could not set up forwarding for domain '%s': %s", - namebuf, isc_result_totext(result)); - goto cleanup; - } - - result = ISC_R_SUCCESS; - - cleanup: - - while (!ISC_LIST_EMPTY(addresses)) { - sa = ISC_LIST_HEAD(addresses); - ISC_LIST_UNLINK(addresses, sa, link); - isc_mem_put(view->mctx, sa, sizeof(isc_sockaddr_t)); - } - - return (result); -} - -/* - * Create a new view and add it to the list. - * - * If 'vconfig' is NULL, create the default view. - * - * The view created is attached to '*viewp'. - */ -static isc_result_t -create_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist, - dns_view_t **viewp) -{ - isc_result_t result; - const char *viewname; - dns_rdataclass_t viewclass; - dns_view_t *view = NULL; - - if (vconfig != NULL) { - const cfg_obj_t *classobj = NULL; - - viewname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name")); - classobj = cfg_tuple_get(vconfig, "class"); - result = ns_config_getclass(classobj, dns_rdataclass_in, - &viewclass); - } else { - viewname = "_default"; - viewclass = dns_rdataclass_in; - } - result = dns_viewlist_find(viewlist, viewname, viewclass, &view); - if (result == ISC_R_SUCCESS) - return (ISC_R_EXISTS); - if (result != ISC_R_NOTFOUND) - return (result); - INSIST(view == NULL); - - result = dns_view_create(ns_g_mctx, viewclass, viewname, &view); - if (result != ISC_R_SUCCESS) - return (result); - - ISC_LIST_APPEND(*viewlist, view, link); - dns_view_attach(view, viewp); - return (ISC_R_SUCCESS); -} - -/* - * Configure or reconfigure a zone. - */ -static isc_result_t -configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig, - const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view, - cfg_aclconfctx_t *aclconf) -{ - dns_view_t *pview = NULL; /* Production view */ - dns_zone_t *zone = NULL; /* New or reused zone */ - dns_zone_t *dupzone = NULL; - const cfg_obj_t *options = NULL; - const cfg_obj_t *zoptions = NULL; - const cfg_obj_t *typeobj = NULL; - const cfg_obj_t *forwarders = NULL; - const cfg_obj_t *forwardtype = NULL; - const cfg_obj_t *only = NULL; - isc_result_t result; - isc_result_t tresult; - isc_buffer_t buffer; - dns_fixedname_t fixorigin; - dns_name_t *origin; - const char *zname; - dns_rdataclass_t zclass; - const char *ztypestr; - - options = NULL; - (void)cfg_map_get(config, "options", &options); - - zoptions = cfg_tuple_get(zconfig, "options"); - - /* - * Get the zone origin as a dns_name_t. - */ - zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); - isc_buffer_init(&buffer, zname, strlen(zname)); - isc_buffer_add(&buffer, strlen(zname)); - dns_fixedname_init(&fixorigin); - CHECK(dns_name_fromtext(dns_fixedname_name(&fixorigin), - &buffer, dns_rootname, ISC_FALSE, NULL)); - origin = dns_fixedname_name(&fixorigin); - - CHECK(ns_config_getclass(cfg_tuple_get(zconfig, "class"), - view->rdclass, &zclass)); - if (zclass != view->rdclass) { - const char *vname = NULL; - if (vconfig != NULL) - vname = cfg_obj_asstring(cfg_tuple_get(vconfig, - "name")); - else - vname = ""; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "zone '%s': wrong class for view '%s'", - zname, vname); - result = ISC_R_FAILURE; - goto cleanup; - } - - (void)cfg_map_get(zoptions, "type", &typeobj); - if (typeobj == NULL) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "zone '%s' 'type' not specified", zname); - return (ISC_R_FAILURE); - } - ztypestr = cfg_obj_asstring(typeobj); - - /* - * "hints zones" aren't zones. If we've got one, - * configure it and return. - */ - if (strcasecmp(ztypestr, "hint") == 0) { - const cfg_obj_t *fileobj = NULL; - if (cfg_map_get(zoptions, "file", &fileobj) != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "zone '%s': 'file' not specified", - zname); - result = ISC_R_FAILURE; - goto cleanup; - } - if (dns_name_equal(origin, dns_rootname)) { - const char *hintsfile = cfg_obj_asstring(fileobj); - - result = configure_hints(view, hintsfile); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "could not configure root hints " - "from '%s': %s", hintsfile, - isc_result_totext(result)); - goto cleanup; - } - /* - * Hint zones may also refer to delegation only points. - */ - only = NULL; - tresult = cfg_map_get(zoptions, "delegation-only", - &only); - if (tresult == ISC_R_SUCCESS && cfg_obj_asboolean(only)) - CHECK(dns_view_adddelegationonly(view, origin)); - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "ignoring non-root hint zone '%s'", - zname); - result = ISC_R_SUCCESS; - } - /* Skip ordinary zone processing. */ - goto cleanup; - } - - /* - * "forward zones" aren't zones either. Translate this syntax into - * the appropriate selective forwarding configuration and return. - */ - if (strcasecmp(ztypestr, "forward") == 0) { - forwardtype = NULL; - forwarders = NULL; - - (void)cfg_map_get(zoptions, "forward", &forwardtype); - (void)cfg_map_get(zoptions, "forwarders", &forwarders); - result = configure_forward(config, view, origin, forwarders, - forwardtype); - goto cleanup; - } - - /* - * "delegation-only zones" aren't zones either. - */ - if (strcasecmp(ztypestr, "delegation-only") == 0) { - result = dns_view_adddelegationonly(view, origin); - goto cleanup; - } - - /* - * Check for duplicates in the new zone table. - */ - result = dns_view_findzone(view, origin, &dupzone); - if (result == ISC_R_SUCCESS) { - /* - * We already have this zone! - */ - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "zone '%s' already exists", zname); - dns_zone_detach(&dupzone); - result = ISC_R_EXISTS; - goto cleanup; - } - INSIST(dupzone == NULL); - - /* - * See if we can reuse an existing zone. This is - * only possible if all of these are true: - * - The zone's view exists - * - A zone with the right name exists in the view - * - The zone is compatible with the config - * options (e.g., an existing master zone cannot - * be reused if the options specify a slave zone) - */ - result = dns_viewlist_find(&ns_g_server->viewlist, - view->name, view->rdclass, - &pview); - if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) - goto cleanup; - if (pview != NULL) - result = dns_view_findzone(pview, origin, &zone); - if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) - goto cleanup; - if (zone != NULL && !ns_zone_reusable(zone, zconfig)) - dns_zone_detach(&zone); - - if (zone != NULL) { - /* - * We found a reusable zone. Make it use the - * new view. - */ - dns_zone_setview(zone, view); - if (view->acache != NULL) - dns_zone_setacache(zone, view->acache); - } else { - /* - * We cannot reuse an existing zone, we have - * to create a new one. - */ - CHECK(dns_zone_create(&zone, mctx)); - CHECK(dns_zone_setorigin(zone, origin)); - dns_zone_setview(zone, view); - if (view->acache != NULL) - dns_zone_setacache(zone, view->acache); - CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone)); - } - - /* - * If the zone contains a 'forwarders' statement, configure - * selective forwarding. - */ - forwarders = NULL; - if (cfg_map_get(zoptions, "forwarders", &forwarders) == ISC_R_SUCCESS) - { - forwardtype = NULL; - (void)cfg_map_get(zoptions, "forward", &forwardtype); - CHECK(configure_forward(config, view, origin, forwarders, - forwardtype)); - } - - /* - * Stub and forward zones may also refer to delegation only points. - */ - only = NULL; - if (cfg_map_get(zoptions, "delegation-only", &only) == ISC_R_SUCCESS) - { - if (cfg_obj_asboolean(only)) - CHECK(dns_view_adddelegationonly(view, origin)); - } - - /* - * Configure the zone. - */ - CHECK(ns_zone_configure(config, vconfig, zconfig, aclconf, zone)); - - /* - * Add the zone to its view in the new view list. - */ - CHECK(dns_view_addzone(view, zone)); - - cleanup: - if (zone != NULL) - dns_zone_detach(&zone); - if (pview != NULL) - dns_view_detach(&pview); - - return (result); -} - -/* - * Configure a single server quota. - */ -static void -configure_server_quota(const cfg_obj_t **maps, const char *name, - isc_quota_t *quota) -{ - const cfg_obj_t *obj = NULL; - isc_result_t result; - - result = ns_config_get(maps, name, &obj); - INSIST(result == ISC_R_SUCCESS); - isc_quota_max(quota, cfg_obj_asuint32(obj)); -} - -/* - * This function is called as soon as the 'directory' statement has been - * parsed. This can be extended to support other options if necessary. - */ -static isc_result_t -directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) { - isc_result_t result; - const char *directory; - - REQUIRE(strcasecmp("directory", clausename) == 0); - - UNUSED(arg); - UNUSED(clausename); - - /* - * Change directory. - */ - directory = cfg_obj_asstring(obj); - - if (! isc_file_ischdiridempotent(directory)) - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, - "option 'directory' contains relative path '%s'", - directory); - - result = isc_dir_chdir(directory); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, - "change directory to '%s' failed: %s", - directory, isc_result_totext(result)); - return (result); - } - - return (ISC_R_SUCCESS); -} - -static void -scan_interfaces(ns_server_t *server, isc_boolean_t verbose) { - isc_boolean_t match_mapped = server->aclenv.match_mapped; - - ns_interfacemgr_scan(server->interfacemgr, verbose); - /* - * Update the "localhost" and "localnets" ACLs to match the - * current set of network interfaces. - */ - dns_aclenv_copy(&server->aclenv, - ns_interfacemgr_getaclenv(server->interfacemgr)); - - server->aclenv.match_mapped = match_mapped; -} - -static isc_result_t -add_listenelt(isc_mem_t *mctx, ns_listenlist_t *list, isc_sockaddr_t *addr) { - ns_listenelt_t *lelt = NULL; - dns_acl_t *src_acl = NULL; - dns_aclelement_t aelt; - isc_result_t result; - isc_sockaddr_t any_sa6; - - REQUIRE(isc_sockaddr_pf(addr) == AF_INET6); - - isc_sockaddr_any6(&any_sa6); - if (!isc_sockaddr_equal(&any_sa6, addr)) { - aelt.type = dns_aclelementtype_ipprefix; - aelt.negative = ISC_FALSE; - aelt.u.ip_prefix.prefixlen = 128; - isc_netaddr_fromin6(&aelt.u.ip_prefix.address, - &addr->type.sin6.sin6_addr); - - result = dns_acl_create(mctx, 1, &src_acl); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_acl_appendelement(src_acl, &aelt); - if (result != ISC_R_SUCCESS) - goto clean; - - result = ns_listenelt_create(mctx, isc_sockaddr_getport(addr), - src_acl, &lelt); - if (result != ISC_R_SUCCESS) - goto clean; - ISC_LIST_APPEND(list->elts, lelt, link); - } - - return (ISC_R_SUCCESS); - - clean: - INSIST(lelt == NULL); - dns_acl_detach(&src_acl); - - return (result); -} - -/* - * Make a list of xxx-source addresses and call ns_interfacemgr_adjust() - * to update the listening interfaces accordingly. - * We currently only consider IPv6, because this only affects IPv6 wildcard - * sockets. - */ -static void -adjust_interfaces(ns_server_t *server, isc_mem_t *mctx) { - isc_result_t result; - ns_listenlist_t *list = NULL; - dns_view_t *view; - dns_zone_t *zone, *next; - isc_sockaddr_t addr, *addrp; - - result = ns_listenlist_create(mctx, &list); - if (result != ISC_R_SUCCESS) - return; - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - dns_dispatch_t *dispatch6; - - dispatch6 = dns_resolver_dispatchv6(view->resolver); - if (dispatch6 == NULL) - continue; - result = dns_dispatch_getlocaladdress(dispatch6, &addr); - if (result != ISC_R_SUCCESS) - goto fail; - result = add_listenelt(mctx, list, &addr); - if (result != ISC_R_SUCCESS) - goto fail; - } - - zone = NULL; - for (result = dns_zone_first(server->zonemgr, &zone); - result == ISC_R_SUCCESS; - next = NULL, result = dns_zone_next(zone, &next), zone = next) { - dns_view_t *zoneview; - - /* - * At this point the zone list may contain a stale zone - * just removed from the configuration. To see the validity, - * check if the corresponding view is in our current view list. - * There may also be old zones that are still in the process - * of shutting down and have detached from their old view - * (zoneview == NULL). - */ - zoneview = dns_zone_getview(zone); - if (zoneview == NULL) - continue; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL && view != zoneview; - view = ISC_LIST_NEXT(view, link)) - ; - if (view == NULL) - continue; - - addrp = dns_zone_getnotifysrc6(zone); - result = add_listenelt(mctx, list, addrp); - if (result != ISC_R_SUCCESS) - goto fail; - - addrp = dns_zone_getxfrsource6(zone); - result = add_listenelt(mctx, list, addrp); - if (result != ISC_R_SUCCESS) - goto fail; - } - - ns_interfacemgr_adjust(server->interfacemgr, list, ISC_TRUE); - - clean: - ns_listenlist_detach(&list); - return; - - fail: - /* - * Even when we failed the procedure, most of other interfaces - * should work correctly. We therefore just warn it. - */ - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "could not adjust the listen-on list; " - "some interfaces may not work"); - goto clean; -} - -/* - * This event callback is invoked to do periodic network - * interface scanning. - */ -static void -interface_timer_tick(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - ns_server_t *server = (ns_server_t *) event->ev_arg; - INSIST(task == server->task); - UNUSED(task); - isc_event_free(&event); - /* - * XXX should scan interfaces unlocked and get exclusive access - * only to replace ACLs. - */ - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - scan_interfaces(server, ISC_FALSE); - isc_task_endexclusive(server->task); -} - -static void -heartbeat_timer_tick(isc_task_t *task, isc_event_t *event) { - ns_server_t *server = (ns_server_t *) event->ev_arg; - dns_view_t *view; - - UNUSED(task); - isc_event_free(&event); - view = ISC_LIST_HEAD(server->viewlist); - while (view != NULL) { - dns_view_dialup(view); - view = ISC_LIST_NEXT(view, link); - } -} - -static void -pps_timer_tick(isc_task_t *task, isc_event_t *event) { - static unsigned int oldrequests = 0; - unsigned int requests = ns_client_requests; - - UNUSED(task); - isc_event_free(&event); - - /* - * Don't worry about wrapping as the overflow result will be right. - */ - dns_pps = (requests - oldrequests) / 1200; - oldrequests = requests; -} - -/* - * Replace the current value of '*field', a dynamically allocated - * string or NULL, with a dynamically allocated copy of the - * null-terminated string pointed to by 'value', or NULL. - */ -static isc_result_t -setstring(ns_server_t *server, char **field, const char *value) { - char *copy; - - if (value != NULL) { - copy = isc_mem_strdup(server->mctx, value); - if (copy == NULL) - return (ISC_R_NOMEMORY); - } else { - copy = NULL; - } - - if (*field != NULL) - isc_mem_free(server->mctx, *field); - - *field = copy; - return (ISC_R_SUCCESS); -} - -/* - * Replace the current value of '*field', a dynamically allocated - * string or NULL, with another dynamically allocated string - * or NULL if whether 'obj' is a string or void value, respectively. - */ -static isc_result_t -setoptstring(ns_server_t *server, char **field, const cfg_obj_t *obj) { - if (cfg_obj_isvoid(obj)) - return (setstring(server, field, NULL)); - else - return (setstring(server, field, cfg_obj_asstring(obj))); -} - -static void -set_limit(const cfg_obj_t **maps, const char *configname, - const char *description, isc_resource_t resourceid, - isc_resourcevalue_t defaultvalue) -{ - const cfg_obj_t *obj = NULL; - const char *resource; - isc_resourcevalue_t value; - isc_result_t result; - - if (ns_config_get(maps, configname, &obj) != ISC_R_SUCCESS) - return; - - if (cfg_obj_isstring(obj)) { - resource = cfg_obj_asstring(obj); - if (strcasecmp(resource, "unlimited") == 0) - value = ISC_RESOURCE_UNLIMITED; - else { - INSIST(strcasecmp(resource, "default") == 0); - value = defaultvalue; - } - } else - value = cfg_obj_asuint64(obj); - - result = isc_resource_setlimit(resourceid, value); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - result == ISC_R_SUCCESS ? - ISC_LOG_DEBUG(3) : ISC_LOG_WARNING, - "set maximum %s to %" ISC_PRINT_QUADFORMAT "d: %s", - description, value, isc_result_totext(result)); -} - -#define SETLIMIT(cfgvar, resource, description) \ - set_limit(maps, cfgvar, description, isc_resource_ ## resource, \ - ns_g_init ## resource) - -static void -set_limits(const cfg_obj_t **maps) { - SETLIMIT("stacksize", stacksize, "stack size"); - SETLIMIT("datasize", datasize, "data size"); - SETLIMIT("coresize", coresize, "core size"); - SETLIMIT("files", openfiles, "open files"); -} - -static isc_result_t -portlist_fromconf(dns_portlist_t *portlist, unsigned int family, - const cfg_obj_t *ports) -{ - const cfg_listelt_t *element; - isc_result_t result = ISC_R_SUCCESS; - - for (element = cfg_list_first(ports); - element != NULL; - element = cfg_list_next(element)) { - const cfg_obj_t *obj = cfg_listelt_value(element); - in_port_t port = (in_port_t)cfg_obj_asuint32(obj); - - result = dns_portlist_add(portlist, family, port); - if (result != ISC_R_SUCCESS) - break; - } - return (result); -} - -static isc_result_t -removed(dns_zone_t *zone, void *uap) { - const char *type; - - if (dns_zone_getview(zone) != uap) - return (ISC_R_SUCCESS); - - switch (dns_zone_gettype(zone)) { - case dns_zone_master: - type = "master"; - break; - case dns_zone_slave: - type = "slave"; - break; - case dns_zone_stub: - type = "stub"; - break; - default: - type = "other"; - break; - } - dns_zone_log(zone, ISC_LOG_INFO, "(%s) removed", type); - return (ISC_R_SUCCESS); -} - -static isc_result_t -load_configuration(const char *filename, ns_server_t *server, - isc_boolean_t first_time) -{ - isc_result_t result; - isc_interval_t interval; - cfg_parser_t *parser = NULL; - cfg_obj_t *config; - const cfg_obj_t *options; - const cfg_obj_t *views; - const cfg_obj_t *obj; - const cfg_obj_t *v4ports, *v6ports; - const cfg_obj_t *maps[3]; - const cfg_obj_t *builtin_views; - const cfg_listelt_t *element; - dns_view_t *view = NULL; - dns_view_t *view_next; - dns_viewlist_t viewlist; - dns_viewlist_t tmpviewlist; - cfg_aclconfctx_t aclconfctx; - isc_uint32_t interface_interval; - isc_uint32_t heartbeat_interval; - isc_uint32_t udpsize; - in_port_t listen_port; - int i; - - cfg_aclconfctx_init(&aclconfctx); - ISC_LIST_INIT(viewlist); - - /* Ensure exclusive access to configuration data. */ - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - /* - * Parse the global default pseudo-config file. - */ - if (first_time) { - CHECK(ns_config_parsedefaults(ns_g_parser, &ns_g_config)); - RUNTIME_CHECK(cfg_map_get(ns_g_config, "options", - &ns_g_defaults) == - ISC_R_SUCCESS); - } - - /* - * Parse the configuration file using the new config code. - */ - result = ISC_R_FAILURE; - config = NULL; - - /* - * Unless this is lwresd with the -C option, parse the config file. - */ - if (!(ns_g_lwresdonly && lwresd_g_useresolvconf)) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "loading configuration from '%s'", - filename); - CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &parser)); - cfg_parser_setcallback(parser, directory_callback, NULL); - result = cfg_parse_file(parser, filename, &cfg_type_namedconf, - &config); - } - - /* - * If this is lwresd with the -C option, or lwresd with no -C or -c - * option where the above parsing failed, parse resolv.conf. - */ - if (ns_g_lwresdonly && - (lwresd_g_useresolvconf || - (!ns_g_conffileset && result == ISC_R_FILENOTFOUND))) - { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "loading configuration from '%s'", - lwresd_g_resolvconffile); - if (parser != NULL) - cfg_parser_destroy(&parser); - CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &parser)); - result = ns_lwresd_parseeresolvconf(ns_g_mctx, parser, - &config); - } - CHECK(result); - - /* - * Check the validity of the configuration. - */ - CHECK(bind9_check_namedconf(config, ns_g_lctx, ns_g_mctx)); - - /* - * Fill in the maps array, used for resolving defaults. - */ - i = 0; - options = NULL; - result = cfg_map_get(config, "options", &options); - if (result == ISC_R_SUCCESS) - maps[i++] = options; - maps[i++] = ns_g_defaults; - maps[i++] = NULL; - - /* - * Set process limits, which (usually) needs to be done as root. - */ - set_limits(maps); - - /* - * Configure various server options. - */ - configure_server_quota(maps, "transfers-out", &server->xfroutquota); - configure_server_quota(maps, "tcp-clients", &server->tcpquota); - configure_server_quota(maps, "recursive-clients", - &server->recursionquota); - if (server->recursionquota.max > 1000) - isc_quota_soft(&server->recursionquota, - server->recursionquota.max - 100); - else - isc_quota_soft(&server->recursionquota, 0); - - CHECK(configure_view_acl(NULL, config, "blackhole", &aclconfctx, - ns_g_mctx, &server->blackholeacl)); - if (server->blackholeacl != NULL) - dns_dispatchmgr_setblackhole(ns_g_dispatchmgr, - server->blackholeacl); - - obj = NULL; - result = ns_config_get(maps, "match-mapped-addresses", &obj); - INSIST(result == ISC_R_SUCCESS); - server->aclenv.match_mapped = cfg_obj_asboolean(obj); - - v4ports = NULL; - v6ports = NULL; - (void)ns_config_get(maps, "avoid-v4-udp-ports", &v4ports); - (void)ns_config_get(maps, "avoid-v6-udp-ports", &v6ports); - if (v4ports != NULL || v6ports != NULL) { - dns_portlist_t *portlist = NULL; - result = dns_portlist_create(ns_g_mctx, &portlist); - if (result == ISC_R_SUCCESS && v4ports != NULL) - result = portlist_fromconf(portlist, AF_INET, v4ports); - if (result == ISC_R_SUCCESS && v6ports != NULL) - portlist_fromconf(portlist, AF_INET6, v6ports); - if (result == ISC_R_SUCCESS) - dns_dispatchmgr_setblackportlist(ns_g_dispatchmgr, portlist); - if (portlist != NULL) - dns_portlist_detach(&portlist); - CHECK(result); - } else - dns_dispatchmgr_setblackportlist(ns_g_dispatchmgr, NULL); - - /* - * Set the EDNS UDP size when we don't match a view. - */ - obj = NULL; - result = ns_config_get(maps, "edns-udp-size", &obj); - INSIST(result == ISC_R_SUCCESS); - udpsize = cfg_obj_asuint32(obj); - if (udpsize < 512) - udpsize = 512; - if (udpsize > 4096) - udpsize = 4096; - ns_g_udpsize = (isc_uint16_t)udpsize; - - /* - * Configure the zone manager. - */ - obj = NULL; - result = ns_config_get(maps, "transfers-in", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zonemgr_settransfersin(server->zonemgr, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "transfers-per-ns", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zonemgr_settransfersperns(server->zonemgr, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "serial-query-rate", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zonemgr_setserialqueryrate(server->zonemgr, cfg_obj_asuint32(obj)); - - /* - * Determine which port to use for listening for incoming connections. - */ - if (ns_g_port != 0) - listen_port = ns_g_port; - else - CHECKM(ns_config_getport(config, &listen_port), "port"); - - /* - * Find the listen queue depth. - */ - obj = NULL; - result = ns_config_get(maps, "tcp-listen-queue", &obj); - INSIST(result == ISC_R_SUCCESS); - ns_g_listen = cfg_obj_asuint32(obj); - if (ns_g_listen < 3) - ns_g_listen = 3; - - /* - * Configure the interface manager according to the "listen-on" - * statement. - */ - { - const cfg_obj_t *clistenon = NULL; - ns_listenlist_t *listenon = NULL; - - clistenon = NULL; - /* - * Even though listen-on is present in the default - * configuration, we can't use it here, since it isn't - * used if we're in lwresd mode. This way is easier. - */ - if (options != NULL) - (void)cfg_map_get(options, "listen-on", &clistenon); - if (clistenon != NULL) { - result = ns_listenlist_fromconfig(clistenon, - config, - &aclconfctx, - ns_g_mctx, - &listenon); - } else if (!ns_g_lwresdonly) { - /* - * Not specified, use default. - */ - CHECK(ns_listenlist_default(ns_g_mctx, listen_port, - ISC_TRUE, &listenon)); - } - if (listenon != NULL) { - ns_interfacemgr_setlistenon4(server->interfacemgr, - listenon); - ns_listenlist_detach(&listenon); - } - } - /* - * Ditto for IPv6. - */ - { - const cfg_obj_t *clistenon = NULL; - ns_listenlist_t *listenon = NULL; - - if (options != NULL) - (void)cfg_map_get(options, "listen-on-v6", &clistenon); - if (clistenon != NULL) { - result = ns_listenlist_fromconfig(clistenon, - config, - &aclconfctx, - ns_g_mctx, - &listenon); - } else if (!ns_g_lwresdonly) { - /* - * Not specified, use default. - */ - CHECK(ns_listenlist_default(ns_g_mctx, listen_port, - ISC_FALSE, &listenon)); - } - if (listenon != NULL) { - ns_interfacemgr_setlistenon6(server->interfacemgr, - listenon); - ns_listenlist_detach(&listenon); - } - } - - /* - * Rescan the interface list to pick up changes in the - * listen-on option. It's important that we do this before we try - * to configure the query source, since the dispatcher we use might - * be shared with an interface. - */ - scan_interfaces(server, ISC_TRUE); - - /* - * Arrange for further interface scanning to occur periodically - * as specified by the "interface-interval" option. - */ - obj = NULL; - result = ns_config_get(maps, "interface-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - interface_interval = cfg_obj_asuint32(obj) * 60; - if (interface_interval == 0) { - CHECK(isc_timer_reset(server->interface_timer, - isc_timertype_inactive, - NULL, NULL, ISC_TRUE)); - } else if (server->interface_interval != interface_interval) { - isc_interval_set(&interval, interface_interval, 0); - CHECK(isc_timer_reset(server->interface_timer, - isc_timertype_ticker, - NULL, &interval, ISC_FALSE)); - } - server->interface_interval = interface_interval; - - /* - * Configure the dialup heartbeat timer. - */ - obj = NULL; - result = ns_config_get(maps, "heartbeat-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - heartbeat_interval = cfg_obj_asuint32(obj) * 60; - if (heartbeat_interval == 0) { - CHECK(isc_timer_reset(server->heartbeat_timer, - isc_timertype_inactive, - NULL, NULL, ISC_TRUE)); - } else if (server->heartbeat_interval != heartbeat_interval) { - isc_interval_set(&interval, heartbeat_interval, 0); - CHECK(isc_timer_reset(server->heartbeat_timer, - isc_timertype_ticker, - NULL, &interval, ISC_FALSE)); - } - server->heartbeat_interval = heartbeat_interval; - - isc_interval_set(&interval, 1200, 0); - CHECK(isc_timer_reset(server->pps_timer, isc_timertype_ticker, NULL, - &interval, ISC_FALSE)); - - /* - * Configure and freeze all explicit views. Explicit - * views that have zones were already created at parsing - * time, but views with no zones must be created here. - */ - views = NULL; - (void)cfg_map_get(config, "view", &views); - for (element = cfg_list_first(views); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *vconfig = cfg_listelt_value(element); - view = NULL; - - CHECK(create_view(vconfig, &viewlist, &view)); - INSIST(view != NULL); - CHECK(configure_view(view, config, vconfig, - ns_g_mctx, &aclconfctx, ISC_TRUE)); - dns_view_freeze(view); - dns_view_detach(&view); - } - - /* - * Make sure we have a default view if and only if there - * were no explicit views. - */ - if (views == NULL) { - /* - * No explicit views; there ought to be a default view. - * There may already be one created as a side effect - * of zone statements, or we may have to create one. - * In either case, we need to configure and freeze it. - */ - CHECK(create_view(NULL, &viewlist, &view)); - CHECK(configure_view(view, config, NULL, ns_g_mctx, - &aclconfctx, ISC_TRUE)); - dns_view_freeze(view); - dns_view_detach(&view); - } - - /* - * Create (or recreate) the built-in views. Currently - * there is only one, the _bind view. - */ - builtin_views = NULL; - RUNTIME_CHECK(cfg_map_get(ns_g_config, "view", - &builtin_views) == ISC_R_SUCCESS); - for (element = cfg_list_first(builtin_views); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *vconfig = cfg_listelt_value(element); - CHECK(create_view(vconfig, &viewlist, &view)); - CHECK(configure_view(view, config, vconfig, ns_g_mctx, - &aclconfctx, ISC_FALSE)); - dns_view_freeze(view); - dns_view_detach(&view); - view = NULL; - } - - /* - * Swap our new view list with the production one. - */ - tmpviewlist = server->viewlist; - server->viewlist = viewlist; - viewlist = tmpviewlist; - - /* - * Load the TKEY information from the configuration. - */ - if (options != NULL) { - dns_tkeyctx_t *t = NULL; - CHECKM(ns_tkeyctx_fromconfig(options, ns_g_mctx, ns_g_entropy, - &t), - "configuring TKEY"); - if (server->tkeyctx != NULL) - dns_tkeyctx_destroy(&server->tkeyctx); - server->tkeyctx = t; - } - - /* - * Bind the control port(s). - */ - CHECKM(ns_controls_configure(ns_g_server->controls, config, - &aclconfctx), - "binding control channel(s)"); - - /* - * Bind the lwresd port(s). - */ - CHECKM(ns_lwresd_configure(ns_g_mctx, config), - "binding lightweight resolver ports"); - - /* - * Open the source of entropy. - */ - if (first_time) { - obj = NULL; - result = ns_config_get(maps, "random-device", &obj); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "no source of entropy found"); - } else { - const char *randomdev = cfg_obj_asstring(obj); - result = isc_entropy_createfilesource(ns_g_entropy, - randomdev); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_INFO, - "could not open entropy source " - "%s: %s", - randomdev, - isc_result_totext(result)); -#ifdef PATH_RANDOMDEV - if (ns_g_fallbackentropy != NULL) { - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_INFO, - "using pre-chroot entropy source " - "%s", - PATH_RANDOMDEV); - isc_entropy_detach(&ns_g_entropy); - isc_entropy_attach(ns_g_fallbackentropy, - &ns_g_entropy); - } - isc_entropy_detach(&ns_g_fallbackentropy); - } -#endif - } - } - - /* - * Relinquish root privileges. - */ - if (first_time) - ns_os_changeuser(); - - /* - * Configure the logging system. - * - * Do this after changing UID to make sure that any log - * files specified in named.conf get created by the - * unprivileged user, not root. - */ - if (ns_g_logstderr) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "ignoring config file logging " - "statement due to -g option"); - } else { - const cfg_obj_t *logobj = NULL; - isc_logconfig_t *logc = NULL; - - CHECKM(isc_logconfig_create(ns_g_lctx, &logc), - "creating new logging configuration"); - - logobj = NULL; - (void)cfg_map_get(config, "logging", &logobj); - if (logobj != NULL) { - CHECKM(ns_log_configure(logc, logobj), - "configuring logging"); - } else { - CHECKM(ns_log_setdefaultchannels(logc), - "setting up default logging channels"); - CHECKM(ns_log_setunmatchedcategory(logc), - "setting up default 'category unmatched'"); - CHECKM(ns_log_setdefaultcategory(logc), - "setting up default 'category default'"); - } - - result = isc_logconfig_use(ns_g_lctx, logc); - if (result != ISC_R_SUCCESS) { - isc_logconfig_destroy(&logc); - CHECKM(result, "installing logging configuration"); - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1), - "now using logging configuration from " - "config file"); - } - - /* - * Set the default value of the query logging flag depending - * whether a "queries" category has been defined. This is - * a disgusting hack, but we need to do this for BIND 8 - * compatibility. - */ - if (first_time) { - const cfg_obj_t *logobj = NULL; - const cfg_obj_t *categories = NULL; - - obj = NULL; - if (ns_config_get(maps, "querylog", &obj) == ISC_R_SUCCESS) { - server->log_queries = cfg_obj_asboolean(obj); - } else { - - (void)cfg_map_get(config, "logging", &logobj); - if (logobj != NULL) - (void)cfg_map_get(logobj, "category", - &categories); - if (categories != NULL) { - const cfg_listelt_t *element; - for (element = cfg_list_first(categories); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *catobj; - const char *str; - - obj = cfg_listelt_value(element); - catobj = cfg_tuple_get(obj, "name"); - str = cfg_obj_asstring(catobj); - if (strcasecmp(str, "queries") == 0) - server->log_queries = ISC_TRUE; - } - } - } - } - - obj = NULL; - if (ns_config_get(maps, "pid-file", &obj) == ISC_R_SUCCESS) - if (cfg_obj_isvoid(obj)) - ns_os_writepidfile(NULL, first_time); - else - ns_os_writepidfile(cfg_obj_asstring(obj), first_time); - else if (ns_g_lwresdonly) - ns_os_writepidfile(lwresd_g_defaultpidfile, first_time); - else - ns_os_writepidfile(ns_g_defaultpidfile, first_time); - - obj = NULL; - if (options != NULL && - cfg_map_get(options, "memstatistics-file", &obj) == ISC_R_SUCCESS) - ns_main_setmemstats(cfg_obj_asstring(obj)); - else - ns_main_setmemstats(NULL); - - obj = NULL; - result = ns_config_get(maps, "statistics-file", &obj); - INSIST(result == ISC_R_SUCCESS); - CHECKM(setstring(server, &server->statsfile, cfg_obj_asstring(obj)), - "strdup"); - - obj = NULL; - result = ns_config_get(maps, "dump-file", &obj); - INSIST(result == ISC_R_SUCCESS); - CHECKM(setstring(server, &server->dumpfile, cfg_obj_asstring(obj)), - "strdup"); - - obj = NULL; - result = ns_config_get(maps, "recursing-file", &obj); - INSIST(result == ISC_R_SUCCESS); - CHECKM(setstring(server, &server->recfile, cfg_obj_asstring(obj)), - "strdup"); - - obj = NULL; - result = ns_config_get(maps, "version", &obj); - if (result == ISC_R_SUCCESS) { - CHECKM(setoptstring(server, &server->version, obj), "strdup"); - server->version_set = ISC_TRUE; - } else { - server->version_set = ISC_FALSE; - } - - obj = NULL; - result = ns_config_get(maps, "hostname", &obj); - if (result == ISC_R_SUCCESS) { - CHECKM(setoptstring(server, &server->hostname, obj), "strdup"); - server->hostname_set = ISC_TRUE; - } else { - server->hostname_set = ISC_FALSE; - } - - obj = NULL; - result = ns_config_get(maps, "server-id", &obj); - server->server_usehostname = ISC_FALSE; - if (result == ISC_R_SUCCESS && cfg_obj_isboolean(obj)) { - server->server_usehostname = ISC_TRUE; - } else if (result == ISC_R_SUCCESS) { - CHECKM(setoptstring(server, &server->server_id, obj), "strdup"); - } else { - result = setstring(server, &server->server_id, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - - obj = NULL; - result = ns_config_get(maps, "flush-zones-on-shutdown", &obj); - if (result == ISC_R_SUCCESS) { - server->flushonshutdown = cfg_obj_asboolean(obj); - } else { - server->flushonshutdown = ISC_FALSE; - } - - result = ISC_R_SUCCESS; - - cleanup: - cfg_aclconfctx_destroy(&aclconfctx); - - if (parser != NULL) { - if (config != NULL) - cfg_obj_destroy(parser, &config); - cfg_parser_destroy(&parser); - } - - if (view != NULL) - dns_view_detach(&view); - - /* - * This cleans up either the old production view list - * or our temporary list depending on whether they - * were swapped above or not. - */ - for (view = ISC_LIST_HEAD(viewlist); - view != NULL; - view = view_next) { - view_next = ISC_LIST_NEXT(view, link); - ISC_LIST_UNLINK(viewlist, view, link); - if (result == ISC_R_SUCCESS && - strcmp(view->name, "_bind") != 0) - (void)dns_zt_apply(view->zonetable, ISC_FALSE, - removed, view); - dns_view_detach(&view); - } - - /* - * Adjust the listening interfaces in accordance with the source - * addresses specified in views and zones. - */ - if (isc_net_probeipv6() == ISC_R_SUCCESS) - adjust_interfaces(server, ns_g_mctx); - - /* Relinquish exclusive access to configuration data. */ - isc_task_endexclusive(server->task); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_DEBUG(1), "load_configuration: %s", - isc_result_totext(result)); - - return (result); -} - -static isc_result_t -load_zones(ns_server_t *server, isc_boolean_t stop) { - isc_result_t result; - dns_view_t *view; - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - /* - * Load zone data from disk. - */ - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - CHECK(dns_view_load(view, stop)); - } - - /* - * Force zone maintenance. Do this after loading - * so that we know when we need to force AXFR of - * slave zones whose master files are missing. - */ - CHECK(dns_zonemgr_forcemaint(server->zonemgr)); - cleanup: - isc_task_endexclusive(server->task); - return (result); -} - -static isc_result_t -load_new_zones(ns_server_t *server, isc_boolean_t stop) { - isc_result_t result; - dns_view_t *view; - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - /* - * Load zone data from disk. - */ - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - CHECK(dns_view_loadnew(view, stop)); - } - /* - * Force zone maintenance. Do this after loading - * so that we know when we need to force AXFR of - * slave zones whose master files are missing. - */ - dns_zonemgr_resumexfrs(server->zonemgr); - cleanup: - isc_task_endexclusive(server->task); - return (result); -} - -static void -run_server(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - ns_server_t *server = (ns_server_t *)event->ev_arg; - - INSIST(task == server->task); - - isc_event_free(&event); - - CHECKFATAL(dns_dispatchmgr_create(ns_g_mctx, ns_g_entropy, - &ns_g_dispatchmgr), - "creating dispatch manager"); - - CHECKFATAL(ns_interfacemgr_create(ns_g_mctx, ns_g_taskmgr, - ns_g_socketmgr, ns_g_dispatchmgr, - &server->interfacemgr), - "creating interface manager"); - - CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive, - NULL, NULL, server->task, - interface_timer_tick, - server, &server->interface_timer), - "creating interface timer"); - - CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive, - NULL, NULL, server->task, - heartbeat_timer_tick, - server, &server->heartbeat_timer), - "creating heartbeat timer"); - - CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive, - NULL, NULL, server->task, pps_timer_tick, - server, &server->pps_timer), - "creating pps timer"); - - CHECKFATAL(cfg_parser_create(ns_g_mctx, NULL, &ns_g_parser), - "creating default configuration parser"); - - if (ns_g_lwresdonly) - CHECKFATAL(load_configuration(lwresd_g_conffile, server, - ISC_TRUE), - "loading configuration"); - else - CHECKFATAL(load_configuration(ns_g_conffile, server, ISC_TRUE), - "loading configuration"); - - isc_hash_init(); - - CHECKFATAL(load_zones(server, ISC_FALSE), "loading zones"); - - ns_os_started(); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_NOTICE, "running"); -} - -void -ns_server_flushonshutdown(ns_server_t *server, isc_boolean_t flush) { - - REQUIRE(NS_SERVER_VALID(server)); - - server->flushonshutdown = flush; -} - -static void -shutdown_server(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - dns_view_t *view, *view_next; - ns_server_t *server = (ns_server_t *)event->ev_arg; - isc_boolean_t flush = server->flushonshutdown; - - UNUSED(task); - INSIST(task == server->task); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "shutting down%s", - flush ? ": flushing changes" : ""); - - ns_controls_shutdown(server->controls); - end_reserved_dispatches(server, ISC_TRUE); - - cfg_obj_destroy(ns_g_parser, &ns_g_config); - cfg_parser_destroy(&ns_g_parser); - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = view_next) { - view_next = ISC_LIST_NEXT(view, link); - ISC_LIST_UNLINK(server->viewlist, view, link); - if (flush) - dns_view_flushanddetach(&view); - else - dns_view_detach(&view); - } - - isc_timer_detach(&server->interface_timer); - isc_timer_detach(&server->heartbeat_timer); - isc_timer_detach(&server->pps_timer); - - ns_interfacemgr_shutdown(server->interfacemgr); - ns_interfacemgr_detach(&server->interfacemgr); - - dns_dispatchmgr_destroy(&ns_g_dispatchmgr); - - dns_zonemgr_shutdown(server->zonemgr); - - if (server->blackholeacl != NULL) - dns_acl_detach(&server->blackholeacl); - - dns_db_detach(&server->in_roothints); - - isc_task_endexclusive(server->task); - - isc_task_detach(&server->task); - - isc_event_free(&event); -} - -void -ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) { - isc_result_t result; - - ns_server_t *server = isc_mem_get(mctx, sizeof(*server)); - if (server == NULL) - fatal("allocating server object", ISC_R_NOMEMORY); - - server->mctx = mctx; - server->task = NULL; - - /* Initialize configuration data with default values. */ - - result = isc_quota_init(&server->xfroutquota, 10); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - result = isc_quota_init(&server->tcpquota, 10); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - result = isc_quota_init(&server->recursionquota, 100); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - result = dns_aclenv_init(mctx, &server->aclenv); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - /* Initialize server data structures. */ - server->zonemgr = NULL; - server->interfacemgr = NULL; - ISC_LIST_INIT(server->viewlist); - server->in_roothints = NULL; - server->blackholeacl = NULL; - - CHECKFATAL(dns_rootns_create(mctx, dns_rdataclass_in, NULL, - &server->in_roothints), - "setting up root hints"); - - CHECKFATAL(isc_mutex_init(&server->reload_event_lock), - "initializing reload event lock"); - server->reload_event = - isc_event_allocate(ns_g_mctx, server, - NS_EVENT_RELOAD, - ns_server_reload, - server, - sizeof(isc_event_t)); - CHECKFATAL(server->reload_event == NULL ? - ISC_R_NOMEMORY : ISC_R_SUCCESS, - "allocating reload event"); - - CHECKFATAL(dst_lib_init(ns_g_mctx, ns_g_entropy, ISC_ENTROPY_GOODONLY), - "initializing DST"); - - server->tkeyctx = NULL; - CHECKFATAL(dns_tkeyctx_create(ns_g_mctx, ns_g_entropy, - &server->tkeyctx), - "creating TKEY context"); - - /* - * Setup the server task, which is responsible for coordinating - * startup and shutdown of the server. - */ - CHECKFATAL(isc_task_create(ns_g_taskmgr, 0, &server->task), - "creating server task"); - isc_task_setname(server->task, "server", server); - CHECKFATAL(isc_task_onshutdown(server->task, shutdown_server, server), - "isc_task_onshutdown"); - CHECKFATAL(isc_app_onrun(ns_g_mctx, server->task, run_server, server), - "isc_app_onrun"); - - server->interface_timer = NULL; - server->heartbeat_timer = NULL; - server->pps_timer = NULL; - - server->interface_interval = 0; - server->heartbeat_interval = 0; - - CHECKFATAL(dns_zonemgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr, - ns_g_socketmgr, &server->zonemgr), - "dns_zonemgr_create"); - - server->statsfile = isc_mem_strdup(server->mctx, "named.stats"); - CHECKFATAL(server->statsfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS, - "isc_mem_strdup"); - server->querystats = NULL; - - server->dumpfile = isc_mem_strdup(server->mctx, "named_dump.db"); - CHECKFATAL(server->dumpfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS, - "isc_mem_strdup"); - - server->recfile = isc_mem_strdup(server->mctx, "named.recursing"); - CHECKFATAL(server->recfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS, - "isc_mem_strdup"); - - server->hostname_set = ISC_FALSE; - server->hostname = NULL; - server->version_set = ISC_FALSE; - server->version = NULL; - server->server_usehostname = ISC_FALSE; - server->server_id = NULL; - - CHECKFATAL(dns_stats_alloccounters(ns_g_mctx, &server->querystats), - "dns_stats_alloccounters"); - - server->flushonshutdown = ISC_FALSE; - server->log_queries = ISC_FALSE; - - server->controls = NULL; - CHECKFATAL(ns_controls_create(server, &server->controls), - "ns_controls_create"); - server->dispatchgen = 0; - ISC_LIST_INIT(server->dispatches); - - server->magic = NS_SERVER_MAGIC; - *serverp = server; -} - -void -ns_server_destroy(ns_server_t **serverp) { - ns_server_t *server = *serverp; - REQUIRE(NS_SERVER_VALID(server)); - - ns_controls_destroy(&server->controls); - - dns_stats_freecounters(server->mctx, &server->querystats); - - isc_mem_free(server->mctx, server->statsfile); - isc_mem_free(server->mctx, server->dumpfile); - isc_mem_free(server->mctx, server->recfile); - - if (server->version != NULL) - isc_mem_free(server->mctx, server->version); - if (server->hostname != NULL) - isc_mem_free(server->mctx, server->hostname); - if (server->server_id != NULL) - isc_mem_free(server->mctx, server->server_id); - - dns_zonemgr_detach(&server->zonemgr); - - if (server->tkeyctx != NULL) - dns_tkeyctx_destroy(&server->tkeyctx); - - dst_lib_destroy(); - - isc_event_free(&server->reload_event); - - INSIST(ISC_LIST_EMPTY(server->viewlist)); - - dns_aclenv_destroy(&server->aclenv); - - isc_quota_destroy(&server->recursionquota); - isc_quota_destroy(&server->tcpquota); - isc_quota_destroy(&server->xfroutquota); - - server->magic = 0; - isc_mem_put(server->mctx, server, sizeof(*server)); - *serverp = NULL; -} - -static void -fatal(const char *msg, isc_result_t result) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_CRITICAL, "%s: %s", msg, - isc_result_totext(result)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_CRITICAL, "exiting (due to fatal error)"); - exit(1); -} - -static void -start_reserved_dispatches(ns_server_t *server) { - - REQUIRE(NS_SERVER_VALID(server)); - - server->dispatchgen++; -} - -static void -end_reserved_dispatches(ns_server_t *server, isc_boolean_t all) { - ns_dispatch_t *dispatch, *nextdispatch; - - REQUIRE(NS_SERVER_VALID(server)); - - for (dispatch = ISC_LIST_HEAD(server->dispatches); - dispatch != NULL; - dispatch = nextdispatch) { - nextdispatch = ISC_LIST_NEXT(dispatch, link); - if (!all && server->dispatchgen == dispatch-> dispatchgen) - continue; - ISC_LIST_UNLINK(server->dispatches, dispatch, link); - dns_dispatch_detach(&dispatch->dispatch); - isc_mem_put(server->mctx, dispatch, sizeof(*dispatch)); - } -} - -void -ns_add_reserved_dispatch(ns_server_t *server, const isc_sockaddr_t *addr) { - ns_dispatch_t *dispatch; - in_port_t port; - char addrbuf[ISC_SOCKADDR_FORMATSIZE]; - isc_result_t result; - unsigned int attrs, attrmask; - - REQUIRE(NS_SERVER_VALID(server)); - - port = isc_sockaddr_getport(addr); - if (port == 0 || port >= 1024) - return; - - for (dispatch = ISC_LIST_HEAD(server->dispatches); - dispatch != NULL; - dispatch = ISC_LIST_NEXT(dispatch, link)) { - if (isc_sockaddr_equal(&dispatch->addr, addr)) - break; - } - if (dispatch != NULL) { - dispatch->dispatchgen = server->dispatchgen; - return; - } - - dispatch = isc_mem_get(server->mctx, sizeof(*dispatch)); - if (dispatch == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - - dispatch->addr = *addr; - dispatch->dispatchgen = server->dispatchgen; - dispatch->dispatch = NULL; - - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; - switch (isc_sockaddr_pf(addr)) { - case AF_INET: - attrs |= DNS_DISPATCHATTR_IPV4; - break; - case AF_INET6: - attrs |= DNS_DISPATCHATTR_IPV6; - break; - default: - result = ISC_R_NOTIMPLEMENTED; - goto cleanup; - } - attrmask = 0; - attrmask |= DNS_DISPATCHATTR_UDP; - attrmask |= DNS_DISPATCHATTR_TCP; - attrmask |= DNS_DISPATCHATTR_IPV4; - attrmask |= DNS_DISPATCHATTR_IPV6; - - result = dns_dispatch_getudp(ns_g_dispatchmgr, ns_g_socketmgr, - ns_g_taskmgr, &dispatch->addr, 4096, - 1000, 32768, 16411, 16433, - attrs, attrmask, &dispatch->dispatch); - if (result != ISC_R_SUCCESS) - goto cleanup; - - ISC_LIST_INITANDPREPEND(server->dispatches, dispatch, link); - - return; - - cleanup: - if (dispatch != NULL) - isc_mem_put(server->mctx, dispatch, sizeof(*dispatch)); - isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "unable to create dispatch for reserved port %s: %s", - addrbuf, isc_result_totext(result)); -} - - -static isc_result_t -loadconfig(ns_server_t *server) { - isc_result_t result; - start_reserved_dispatches(server); - result = load_configuration(ns_g_lwresdonly ? - lwresd_g_conffile : ns_g_conffile, - server, ISC_FALSE); - if (result == ISC_R_SUCCESS) - end_reserved_dispatches(server, ISC_FALSE); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "reloading configuration failed: %s", - isc_result_totext(result)); - return (result); -} - -static isc_result_t -reload(ns_server_t *server) { - isc_result_t result; - CHECK(loadconfig(server)); - - result = load_zones(server, ISC_FALSE); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "reloading zones failed: %s", - isc_result_totext(result)); - } - cleanup: - return (result); -} - -static void -reconfig(ns_server_t *server) { - isc_result_t result; - CHECK(loadconfig(server)); - - result = load_new_zones(server, ISC_FALSE); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "loading new zones failed: %s", - isc_result_totext(result)); - } - cleanup: ; -} - -/* - * Handle a reload event (from SIGHUP). - */ -static void -ns_server_reload(isc_task_t *task, isc_event_t *event) { - ns_server_t *server = (ns_server_t *)event->ev_arg; - - INSIST(task = server->task); - UNUSED(task); - - (void)reload(server); - - LOCK(&server->reload_event_lock); - INSIST(server->reload_event == NULL); - server->reload_event = event; - UNLOCK(&server->reload_event_lock); -} - -void -ns_server_reloadwanted(ns_server_t *server) { - LOCK(&server->reload_event_lock); - if (server->reload_event != NULL) - isc_task_send(server->task, &server->reload_event); - UNLOCK(&server->reload_event_lock); -} - -static char * -next_token(char **stringp, const char *delim) { - char *res; - - do { - res = strsep(stringp, delim); - if (res == NULL) - break; - } while (*res == '\0'); - return (res); -} - -/* - * Find the zone specified in the control channel command 'args', - * if any. If a zone is specified, point '*zonep' at it, otherwise - * set '*zonep' to NULL. - */ -static isc_result_t -zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep) { - char *input, *ptr; - const char *zonetxt; - char *classtxt; - const char *viewtxt = NULL; - dns_fixedname_t name; - isc_result_t result; - isc_buffer_t buf; - dns_view_t *view = NULL; - dns_rdataclass_t rdclass; - - REQUIRE(zonep != NULL && *zonep == NULL); - - input = args; - - /* Skip the command name. */ - ptr = next_token(&input, " \t"); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Look for the zone name. */ - zonetxt = next_token(&input, " \t"); - if (zonetxt == NULL) - return (ISC_R_SUCCESS); - - /* Look for the optional class name. */ - classtxt = next_token(&input, " \t"); - if (classtxt != NULL) { - /* Look for the optional view name. */ - viewtxt = next_token(&input, " \t"); - } - - isc_buffer_init(&buf, zonetxt, strlen(zonetxt)); - isc_buffer_add(&buf, strlen(zonetxt)); - dns_fixedname_init(&name); - result = dns_name_fromtext(dns_fixedname_name(&name), - &buf, dns_rootname, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) - goto fail1; - - if (classtxt != NULL) { - isc_textregion_t r; - r.base = classtxt; - r.length = strlen(classtxt); - result = dns_rdataclass_fromtext(&rdclass, &r); - if (result != ISC_R_SUCCESS) - goto fail1; - } else { - rdclass = dns_rdataclass_in; - } - - if (viewtxt == NULL) - viewtxt = "_default"; - result = dns_viewlist_find(&server->viewlist, viewtxt, - rdclass, &view); - if (result != ISC_R_SUCCESS) - goto fail1; - - result = dns_zt_find(view->zonetable, dns_fixedname_name(&name), - 0, NULL, zonep); - /* Partial match? */ - if (result != ISC_R_SUCCESS && *zonep != NULL) - dns_zone_detach(zonep); - dns_view_detach(&view); - fail1: - return (result); -} - -/* - * Act on a "retransfer" command from the command channel. - */ -isc_result_t -ns_server_retransfercommand(ns_server_t *server, char *args) { - isc_result_t result; - dns_zone_t *zone = NULL; - dns_zonetype_t type; - - result = zone_from_args(server, args, &zone); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) - return (ISC_R_UNEXPECTEDEND); - type = dns_zone_gettype(zone); - if (type == dns_zone_slave || type == dns_zone_stub) - dns_zone_forcereload(zone); - else - result = ISC_R_NOTFOUND; - dns_zone_detach(&zone); - return (result); -} - -/* - * Act on a "reload" command from the command channel. - */ -isc_result_t -ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t *text) { - isc_result_t result; - dns_zone_t *zone = NULL; - dns_zonetype_t type; - const char *msg = NULL; - - result = zone_from_args(server, args, &zone); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) { - result = reload(server); - if (result == ISC_R_SUCCESS) - msg = "server reload successful"; - } else { - type = dns_zone_gettype(zone); - if (type == dns_zone_slave || type == dns_zone_stub) { - dns_zone_refresh(zone); - dns_zone_detach(&zone); - msg = "zone refresh queued"; - } else { - result = dns_zone_load(zone); - dns_zone_detach(&zone); - switch (result) { - case ISC_R_SUCCESS: - msg = "zone reload successful"; - break; - case DNS_R_CONTINUE: - msg = "zone reload queued"; - result = ISC_R_SUCCESS; - break; - case DNS_R_UPTODATE: - msg = "zone reload up-to-date"; - result = ISC_R_SUCCESS; - break; - default: - /* failure message will be generated by rndc */ - break; - } - } - } - if (msg != NULL && strlen(msg) < isc_buffer_availablelength(text)) - isc_buffer_putmem(text, (const unsigned char *)msg, - strlen(msg) + 1); - return (result); -} - -/* - * Act on a "reconfig" command from the command channel. - */ -isc_result_t -ns_server_reconfigcommand(ns_server_t *server, char *args) { - UNUSED(args); - - reconfig(server); - return (ISC_R_SUCCESS); -} - -/* - * Act on a "notify" command from the command channel. - */ -isc_result_t -ns_server_notifycommand(ns_server_t *server, char *args, isc_buffer_t *text) { - isc_result_t result; - dns_zone_t *zone = NULL; - const unsigned char msg[] = "zone notify queued"; - - result = zone_from_args(server, args, &zone); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) - return (ISC_R_UNEXPECTEDEND); - - dns_zone_notify(zone); - dns_zone_detach(&zone); - if (sizeof(msg) <= isc_buffer_availablelength(text)) - isc_buffer_putmem(text, msg, sizeof(msg)); - - return (ISC_R_SUCCESS); -} - -/* - * Act on a "refresh" command from the command channel. - */ -isc_result_t -ns_server_refreshcommand(ns_server_t *server, char *args, isc_buffer_t *text) { - isc_result_t result; - dns_zone_t *zone = NULL; - const unsigned char msg1[] = "zone refresh queued"; - const unsigned char msg2[] = "not a slave or stub zone"; - dns_zonetype_t type; - - result = zone_from_args(server, args, &zone); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) - return (ISC_R_UNEXPECTEDEND); - - type = dns_zone_gettype(zone); - if (type == dns_zone_slave || type == dns_zone_stub) { - dns_zone_refresh(zone); - dns_zone_detach(&zone); - if (sizeof(msg1) <= isc_buffer_availablelength(text)) - isc_buffer_putmem(text, msg1, sizeof(msg1)); - return (ISC_R_SUCCESS); - } - - dns_zone_detach(&zone); - if (sizeof(msg2) <= isc_buffer_availablelength(text)) - isc_buffer_putmem(text, msg2, sizeof(msg2)); - return (ISC_R_FAILURE); -} - -isc_result_t -ns_server_togglequerylog(ns_server_t *server) { - server->log_queries = server->log_queries ? ISC_FALSE : ISC_TRUE; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "query logging is now %s", - server->log_queries ? "on" : "off"); - return (ISC_R_SUCCESS); -} - -static isc_result_t -ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, - isc_mem_t *mctx, ns_listenlist_t **target) -{ - isc_result_t result; - const cfg_listelt_t *element; - ns_listenlist_t *dlist = NULL; - - REQUIRE(target != NULL && *target == NULL); - - result = ns_listenlist_create(mctx, &dlist); - if (result != ISC_R_SUCCESS) - return (result); - - for (element = cfg_list_first(listenlist); - element != NULL; - element = cfg_list_next(element)) - { - ns_listenelt_t *delt = NULL; - const cfg_obj_t *listener = cfg_listelt_value(element); - result = ns_listenelt_fromconfig(listener, config, actx, - mctx, &delt); - if (result != ISC_R_SUCCESS) - goto cleanup; - ISC_LIST_APPEND(dlist->elts, delt, link); - } - *target = dlist; - return (ISC_R_SUCCESS); - - cleanup: - ns_listenlist_detach(&dlist); - return (result); -} - -/* - * Create a listen list from the corresponding configuration - * data structure. - */ -static isc_result_t -ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, - isc_mem_t *mctx, ns_listenelt_t **target) -{ - isc_result_t result; - const cfg_obj_t *portobj; - in_port_t port; - ns_listenelt_t *delt = NULL; - REQUIRE(target != NULL && *target == NULL); - - portobj = cfg_tuple_get(listener, "port"); - if (!cfg_obj_isuint32(portobj)) { - if (ns_g_port != 0) { - port = ns_g_port; - } else { - result = ns_config_getport(config, &port); - if (result != ISC_R_SUCCESS) - return (result); - } - } else { - if (cfg_obj_asuint32(portobj) >= ISC_UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port value '%u' is out of range", - cfg_obj_asuint32(portobj)); - return (ISC_R_RANGE); - } - port = (in_port_t)cfg_obj_asuint32(portobj); - } - - result = ns_listenelt_create(mctx, port, NULL, &delt); - if (result != ISC_R_SUCCESS) - return (result); - - result = cfg_acl_fromconfig(cfg_tuple_get(listener, "acl"), - config, ns_g_lctx, actx, mctx, &delt->acl); - if (result != ISC_R_SUCCESS) { - ns_listenelt_destroy(delt); - return (result); - } - *target = delt; - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_server_dumpstats(ns_server_t *server) { - isc_result_t result; - dns_zone_t *zone, *next; - isc_stdtime_t now; - FILE *fp = NULL; - int i; - int ncounters; - - isc_stdtime_get(&now); - - CHECKMF(isc_stdio_open(server->statsfile, "a", &fp), - "could not open statistics dump file", server->statsfile); - - ncounters = DNS_STATS_NCOUNTERS; - fprintf(fp, "+++ Statistics Dump +++ (%lu)\n", (unsigned long)now); - - for (i = 0; i < ncounters; i++) - fprintf(fp, "%s %" ISC_PRINT_QUADFORMAT "u\n", - dns_statscounter_names[i], - server->querystats[i]); - - zone = NULL; - for (result = dns_zone_first(server->zonemgr, &zone); - result == ISC_R_SUCCESS; - next = NULL, result = dns_zone_next(zone, &next), zone = next) - { - isc_uint64_t *zonestats = dns_zone_getstatscounters(zone); - if (zonestats != NULL) { - char zonename[DNS_NAME_FORMATSIZE]; - dns_view_t *view; - char *viewname; - - dns_name_format(dns_zone_getorigin(zone), - zonename, sizeof(zonename)); - view = dns_zone_getview(zone); - viewname = view->name; - for (i = 0; i < ncounters; i++) { - fprintf(fp, "%s %" ISC_PRINT_QUADFORMAT - "u %s", - dns_statscounter_names[i], - zonestats[i], - zonename); - if (strcmp(viewname, "_default") != 0) - fprintf(fp, " %s", viewname); - fprintf(fp, "\n"); - } - } - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - CHECK(result); - - fprintf(fp, "--- Statistics Dump --- (%lu)\n", (unsigned long)now); - - cleanup: - if (fp != NULL) - (void)isc_stdio_close(fp); - return (result); -} - -static isc_result_t -add_zone_tolist(dns_zone_t *zone, void *uap) { - struct dumpcontext *dctx = uap; - struct zonelistentry *zle; - - zle = isc_mem_get(dctx->mctx, sizeof *zle); - if (zle == NULL) - return (ISC_R_NOMEMORY); - zle->zone = NULL; - dns_zone_attach(zone, &zle->zone); - ISC_LINK_INIT(zle, link); - ISC_LIST_APPEND(ISC_LIST_TAIL(dctx->viewlist)->zonelist, zle, link); - return (ISC_R_SUCCESS); -} - -static isc_result_t -add_view_tolist(struct dumpcontext *dctx, dns_view_t *view) { - struct viewlistentry *vle; - isc_result_t result = ISC_R_SUCCESS; - - /* - * Prevent duplicate views. - */ - for (vle = ISC_LIST_HEAD(dctx->viewlist); - vle != NULL; - vle = ISC_LIST_NEXT(vle, link)) - if (vle->view == view) - return (ISC_R_SUCCESS); - - vle = isc_mem_get(dctx->mctx, sizeof *vle); - if (vle == NULL) - return (ISC_R_NOMEMORY); - vle->view = NULL; - dns_view_attach(view, &vle->view); - ISC_LINK_INIT(vle, link); - ISC_LIST_INIT(vle->zonelist); - ISC_LIST_APPEND(dctx->viewlist, vle, link); - if (dctx->dumpzones) - result = dns_zt_apply(view->zonetable, ISC_TRUE, - add_zone_tolist, dctx); - return (result); -} - -static void -dumpcontext_destroy(struct dumpcontext *dctx) { - struct viewlistentry *vle; - struct zonelistentry *zle; - - vle = ISC_LIST_HEAD(dctx->viewlist); - while (vle != NULL) { - ISC_LIST_UNLINK(dctx->viewlist, vle, link); - zle = ISC_LIST_HEAD(vle->zonelist); - while (zle != NULL) { - ISC_LIST_UNLINK(vle->zonelist, zle, link); - dns_zone_detach(&zle->zone); - isc_mem_put(dctx->mctx, zle, sizeof *zle); - zle = ISC_LIST_HEAD(vle->zonelist); - } - dns_view_detach(&vle->view); - isc_mem_put(dctx->mctx, vle, sizeof *vle); - vle = ISC_LIST_HEAD(dctx->viewlist); - } - if (dctx->version != NULL) - dns_db_closeversion(dctx->db, &dctx->version, ISC_FALSE); - if (dctx->db != NULL) - dns_db_detach(&dctx->db); - if (dctx->cache != NULL) - dns_db_detach(&dctx->cache); - if (dctx->task != NULL) - isc_task_detach(&dctx->task); - if (dctx->fp != NULL) - (void)isc_stdio_close(dctx->fp); - if (dctx->mdctx != NULL) - dns_dumpctx_detach(&dctx->mdctx); - isc_mem_put(dctx->mctx, dctx, sizeof *dctx); -} - -static void -dumpdone(void *arg, isc_result_t result) { - struct dumpcontext *dctx = arg; - char buf[1024+32]; - const dns_master_style_t *style; - - if (result != ISC_R_SUCCESS) - goto cleanup; - if (dctx->mdctx != NULL) - dns_dumpctx_detach(&dctx->mdctx); - if (dctx->view == NULL) { - dctx->view = ISC_LIST_HEAD(dctx->viewlist); - if (dctx->view == NULL) - goto done; - INSIST(dctx->zone == NULL); - } else - goto resume; - nextview: - fprintf(dctx->fp, ";\n; Start view %s\n;\n", dctx->view->view->name); - resume: - if (dctx->zone == NULL && dctx->cache == NULL && dctx->dumpcache) { - style = &dns_master_style_cache; - /* start cache dump */ - if (dctx->view->view->cachedb != NULL) - dns_db_attach(dctx->view->view->cachedb, &dctx->cache); - if (dctx->cache != NULL) { - - fprintf(dctx->fp, ";\n; Cache dump of view '%s'\n;\n", - dctx->view->view->name); - result = dns_master_dumptostreaminc(dctx->mctx, - dctx->cache, NULL, - style, dctx->fp, - dctx->task, - dumpdone, dctx, - &dctx->mdctx); - if (result == DNS_R_CONTINUE) - return; - if (result == ISC_R_NOTIMPLEMENTED) - fprintf(dctx->fp, "; %s\n", - dns_result_totext(result)); - else if (result != ISC_R_SUCCESS) - goto cleanup; - } - } - if (dctx->cache != NULL) { - dns_adb_dump(dctx->view->view->adb, dctx->fp); - dns_db_detach(&dctx->cache); - } - if (dctx->dumpzones) { - style = &dns_master_style_full; - nextzone: - if (dctx->version != NULL) - dns_db_closeversion(dctx->db, &dctx->version, - ISC_FALSE); - if (dctx->db != NULL) - dns_db_detach(&dctx->db); - if (dctx->zone == NULL) - dctx->zone = ISC_LIST_HEAD(dctx->view->zonelist); - else - dctx->zone = ISC_LIST_NEXT(dctx->zone, link); - if (dctx->zone != NULL) { - /* start zone dump */ - dns_zone_name(dctx->zone->zone, buf, sizeof(buf)); - fprintf(dctx->fp, ";\n; Zone dump of '%s'\n;\n", buf); - result = dns_zone_getdb(dctx->zone->zone, &dctx->db); - if (result != ISC_R_SUCCESS) { - fprintf(dctx->fp, "; %s\n", - dns_result_totext(result)); - goto nextzone; - } - dns_db_currentversion(dctx->db, &dctx->version); - result = dns_master_dumptostreaminc(dctx->mctx, - dctx->db, - dctx->version, - style, dctx->fp, - dctx->task, - dumpdone, dctx, - &dctx->mdctx); - if (result == DNS_R_CONTINUE) - return; - if (result == ISC_R_NOTIMPLEMENTED) { - fprintf(dctx->fp, "; %s\n", - dns_result_totext(result)); - result = ISC_R_SUCCESS; - goto nextzone; - } - if (result != ISC_R_SUCCESS) - goto cleanup; - } - } - if (dctx->view != NULL) - dctx->view = ISC_LIST_NEXT(dctx->view, link); - if (dctx->view != NULL) - goto nextview; - done: - fprintf(dctx->fp, "; Dump complete\n"); - result = isc_stdio_flush(dctx->fp); - if (result == ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumpdb complete"); - cleanup: - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumpdb failed: %s", dns_result_totext(result)); - dumpcontext_destroy(dctx); -} - -isc_result_t -ns_server_dumpdb(ns_server_t *server, char *args) { - struct dumpcontext *dctx = NULL; - dns_view_t *view; - isc_result_t result; - char *ptr; - const char *sep; - - /* Skip the command name. */ - ptr = next_token(&args, " \t"); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - dctx = isc_mem_get(server->mctx, sizeof(*dctx)); - if (dctx == NULL) - return (ISC_R_NOMEMORY); - - dctx->mctx = server->mctx; - dctx->dumpcache = ISC_TRUE; - dctx->dumpzones = ISC_FALSE; - dctx->fp = NULL; - ISC_LIST_INIT(dctx->viewlist); - dctx->view = NULL; - dctx->zone = NULL; - dctx->cache = NULL; - dctx->mdctx = NULL; - dctx->db = NULL; - dctx->cache = NULL; - dctx->task = NULL; - dctx->version = NULL; - isc_task_attach(server->task, &dctx->task); - - CHECKMF(isc_stdio_open(server->dumpfile, "w", &dctx->fp), - "could not open dump file", server->dumpfile); - - sep = (args == NULL) ? "" : ": "; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumpdb started%s%s", sep, (args != NULL) ? args : ""); - - ptr = next_token(&args, " \t"); - if (ptr != NULL && strcmp(ptr, "-all") == 0) { - dctx->dumpzones = ISC_TRUE; - dctx->dumpcache = ISC_TRUE; - ptr = next_token(&args, " \t"); - } else if (ptr != NULL && strcmp(ptr, "-cache") == 0) { - dctx->dumpzones = ISC_FALSE; - dctx->dumpcache = ISC_TRUE; - ptr = next_token(&args, " \t"); - } else if (ptr != NULL && strcmp(ptr, "-zones") == 0) { - dctx->dumpzones = ISC_TRUE; - dctx->dumpcache = ISC_FALSE; - ptr = next_token(&args, " \t"); - } - - nextview: - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (ptr != NULL && strcmp(view->name, ptr) != 0) - continue; - CHECK(add_view_tolist(dctx, view)); - } - if (ptr != NULL) { - ptr = next_token(&args, " \t"); - if (ptr != NULL) - goto nextview; - } - dumpdone(dctx, ISC_R_SUCCESS); - return (ISC_R_SUCCESS); - - cleanup: - if (dctx != NULL) - dumpcontext_destroy(dctx); - return (result); -} - -isc_result_t -ns_server_dumprecursing(ns_server_t *server) { - FILE *fp = NULL; - isc_result_t result; - - CHECKMF(isc_stdio_open(server->recfile, "w", &fp), - "could not open dump file", server->recfile); - fprintf(fp,";\n; Recursing Queries\n;\n"); - ns_interfacemgr_dumprecursing(fp, server->interfacemgr); - fprintf(fp, "; Dump complete\n"); - - cleanup: - if (fp != NULL) - result = isc_stdio_close(fp); - return (result); -} - -isc_result_t -ns_server_setdebuglevel(ns_server_t *server, char *args) { - char *ptr; - char *levelstr; - char *endp; - long newlevel; - - UNUSED(server); - - /* Skip the command name. */ - ptr = next_token(&args, " \t"); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Look for the new level name. */ - levelstr = next_token(&args, " \t"); - if (levelstr == NULL) { - if (ns_g_debuglevel < 99) - ns_g_debuglevel++; - } else { - newlevel = strtol(levelstr, &endp, 10); - if (*endp != '\0' || newlevel < 0 || newlevel > 99) - return (ISC_R_RANGE); - ns_g_debuglevel = (unsigned int)newlevel; - } - isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_server_validation(ns_server_t *server, char *args) { - char *ptr, *viewname; - dns_view_t *view; - isc_boolean_t changed = ISC_FALSE; - isc_result_t result; - isc_boolean_t enable; - - /* Skip the command name. */ - ptr = next_token(&args, " \t"); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Find out what we are to do. */ - ptr = next_token(&args, " \t"); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - if (!strcasecmp(ptr, "on") || !strcasecmp(ptr, "yes") || - !strcasecmp(ptr, "enable") || !strcasecmp(ptr, "true")) - enable = ISC_TRUE; - else if (!strcasecmp(ptr, "off") || !strcasecmp(ptr, "no") || - !strcasecmp(ptr, "disable") || !strcasecmp(ptr, "false")) - enable = ISC_FALSE; - else - return (DNS_R_SYNTAX); - - /* Look for the view name. */ - viewname = next_token(&args, " \t"); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (viewname != NULL && strcasecmp(viewname, view->name) != 0) - continue; - result = dns_view_flushcache(view); - if (result != ISC_R_SUCCESS) - goto out; - view->enablevalidation = enable; - changed = ISC_TRUE; - } - if (changed) - result = ISC_R_SUCCESS; - else - result = ISC_R_FAILURE; - out: - isc_task_endexclusive(server->task); - return (result); -} - -isc_result_t -ns_server_flushcache(ns_server_t *server, char *args) { - char *ptr, *viewname; - dns_view_t *view; - isc_boolean_t flushed; - isc_boolean_t found; - isc_result_t result; - - /* Skip the command name. */ - ptr = next_token(&args, " \t"); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Look for the view name. */ - viewname = next_token(&args, " \t"); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - flushed = ISC_TRUE; - found = ISC_FALSE; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (viewname != NULL && strcasecmp(viewname, view->name) != 0) - continue; - found = ISC_TRUE; - result = dns_view_flushcache(view); - if (result != ISC_R_SUCCESS) - flushed = ISC_FALSE; - } - if (flushed && found) { - result = ISC_R_SUCCESS; - } else { - if (!found) - result = ISC_R_NOTFOUND; - else - result = ISC_R_FAILURE; - } - isc_task_endexclusive(server->task); - return (result); -} - -isc_result_t -ns_server_flushname(ns_server_t *server, char *args) { - char *ptr, *target, *viewname; - dns_view_t *view; - isc_boolean_t flushed; - isc_boolean_t found; - isc_result_t result; - isc_buffer_t b; - dns_fixedname_t fixed; - dns_name_t *name; - - /* Skip the command name. */ - ptr = next_token(&args, " \t"); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Find the domain name to flush. */ - target = next_token(&args, " \t"); - if (target == NULL) - return (ISC_R_UNEXPECTEDEND); - - isc_buffer_init(&b, target, strlen(target)); - isc_buffer_add(&b, strlen(target)); - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - /* Look for the view name. */ - viewname = next_token(&args, " \t"); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - flushed = ISC_TRUE; - found = ISC_FALSE; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (viewname != NULL && strcasecmp(viewname, view->name) != 0) - continue; - found = ISC_TRUE; - result = dns_view_flushname(view, name); - if (result != ISC_R_SUCCESS) - flushed = ISC_FALSE; - } - if (flushed && found) - result = ISC_R_SUCCESS; - else if (!found) - result = ISC_R_NOTFOUND; - else - result = ISC_R_FAILURE; - isc_task_endexclusive(server->task); - return (result); -} - -isc_result_t -ns_server_status(ns_server_t *server, isc_buffer_t *text) { - int zonecount, xferrunning, xferdeferred, soaqueries; - unsigned int n; - - zonecount = dns_zonemgr_getcount(server->zonemgr, DNS_ZONESTATE_ANY); - xferrunning = dns_zonemgr_getcount(server->zonemgr, - DNS_ZONESTATE_XFERRUNNING); - xferdeferred = dns_zonemgr_getcount(server->zonemgr, - DNS_ZONESTATE_XFERDEFERRED); - soaqueries = dns_zonemgr_getcount(server->zonemgr, - DNS_ZONESTATE_SOAQUERY); - n = snprintf((char *)isc_buffer_used(text), - isc_buffer_availablelength(text), - "number of zones: %u\n" - "debug level: %d\n" - "xfers running: %u\n" - "xfers deferred: %u\n" - "soa queries in progress: %u\n" - "query logging is %s\n" - "recursive clients: %d/%d/%d\n" - "tcp clients: %d/%d\n" - "server is up and running", - zonecount, ns_g_debuglevel, xferrunning, xferdeferred, - soaqueries, server->log_queries ? "ON" : "OFF", - server->recursionquota.used, server->recursionquota.soft, - server->recursionquota.max, - server->tcpquota.used, server->tcpquota.max); - if (n >= isc_buffer_availablelength(text)) - return (ISC_R_NOSPACE); - isc_buffer_add(text, n); - return (ISC_R_SUCCESS); -} - -/* - * Act on a "freeze" or "thaw" command from the command channel. - */ -isc_result_t -ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args) { - isc_result_t result, tresult; - dns_zone_t *zone = NULL; - dns_zonetype_t type; - char classstr[DNS_RDATACLASS_FORMATSIZE]; - char zonename[DNS_NAME_FORMATSIZE]; - dns_view_t *view; - char *journal; - const char *vname, *sep; - isc_boolean_t frozen; - - result = zone_from_args(server, args, &zone); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) { - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - tresult = ISC_R_SUCCESS; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - result = dns_view_freezezones(view, freeze); - if (result != ISC_R_SUCCESS && - tresult == ISC_R_SUCCESS) - tresult = result; - } - isc_task_endexclusive(server->task); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "%s all zones: %s", - freeze ? "freezing" : "thawing", - isc_result_totext(tresult)); - return (tresult); - } - type = dns_zone_gettype(zone); - if (type != dns_zone_master) { - dns_zone_detach(&zone); - return (ISC_R_NOTFOUND); - } - - frozen = dns_zone_getupdatedisabled(zone); - if (freeze) { - if (frozen) - 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); - if (result == DNS_R_CONTINUE || - result == DNS_R_UPTODATE) - result = ISC_R_SUCCESS; - } - } - if (result == ISC_R_SUCCESS) - dns_zone_setupdatedisabled(zone, freeze); - - view = dns_zone_getview(zone); - if (strcmp(view->name, "_bind") == 0 || - strcmp(view->name, "_default") == 0) - { - vname = ""; - sep = ""; - } else { - vname = view->name; - sep = " "; - } - dns_rdataclass_format(dns_zone_getclass(zone), classstr, - sizeof(classstr)); - dns_name_format(dns_zone_getorigin(zone), - zonename, sizeof(zonename)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "%s zone '%s/%s'%s%s: %s", - freeze ? "freezing" : "thawing", - zonename, classstr, sep, vname, - isc_result_totext(result)); - dns_zone_detach(&zone); - return (result); -} - -#ifdef HAVE_LIBSCF -/* - * This function adds a message for rndc to echo if named - * is managed by smf and is also running chroot. - */ -isc_result_t -ns_smf_add_message(isc_buffer_t *text) { - unsigned int n; - - n = snprintf((char *)isc_buffer_used(text), - isc_buffer_availablelength(text), - "use svcadm(1M) to manage named"); - if (n >= isc_buffer_availablelength(text)) - return (ISC_R_NOSPACE); - isc_buffer_add(text, n); - return (ISC_R_SUCCESS); -} -#endif /* HAVE_LIBSCF */ diff --git a/contrib/bind9/bin/named/sortlist.c b/contrib/bind9/bin/named/sortlist.c deleted file mode 100644 index 28f0360..0000000 --- a/contrib/bind9/bin/named/sortlist.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: sortlist.c,v 1.9.18.4 2006/03/02 00:37:21 marka Exp $ */ - -/*! \file */ - -#include - -#include -#include - -#include -#include - -#include -#include -#include - -ns_sortlisttype_t -ns_sortlist_setup(dns_acl_t *acl, isc_netaddr_t *clientaddr, - const void **argp) -{ - unsigned int i; - - if (acl == NULL) - goto dont_sort; - - for (i = 0; i < acl->length; i++) { - /* - * 'e' refers to the current 'top level statement' - * in the sortlist (see ARM). - */ - dns_aclelement_t *e = &acl->elements[i]; - dns_aclelement_t *try_elt; - dns_aclelement_t *order_elt = NULL; - const dns_aclelement_t *matched_elt = NULL; - - if (e->type == dns_aclelementtype_nestedacl) { - dns_acl_t *inner = e->u.nestedacl; - - if (inner->length < 1 || inner->length > 2) - goto dont_sort; - if (inner->elements[0].negative) - goto dont_sort; - try_elt = &inner->elements[0]; - if (inner->length == 2) - order_elt = &inner->elements[1]; - } else { - /* - * BIND 8 allows bare elements at the top level - * as an undocumented feature. - */ - try_elt = e; - } - - if (dns_aclelement_match(clientaddr, NULL, try_elt, - &ns_g_server->aclenv, - &matched_elt)) { - if (order_elt != NULL) { - if (order_elt->type == - dns_aclelementtype_nestedacl) { - *argp = order_elt->u.nestedacl; - return (NS_SORTLISTTYPE_2ELEMENT); - } else if (order_elt->type == - dns_aclelementtype_localhost && - ns_g_server->aclenv.localhost != NULL) { - *argp = ns_g_server->aclenv.localhost; - return (NS_SORTLISTTYPE_2ELEMENT); - } else if (order_elt->type == - dns_aclelementtype_localnets && - ns_g_server->aclenv.localnets != NULL) { - *argp = ns_g_server->aclenv.localnets; - return (NS_SORTLISTTYPE_2ELEMENT); - } else { - /* - * BIND 8 allows a bare IP prefix as - * the 2nd element of a 2-element - * sortlist statement. - */ - *argp = order_elt; - return (NS_SORTLISTTYPE_1ELEMENT); - } - } else { - INSIST(matched_elt != NULL); - *argp = matched_elt; - return (NS_SORTLISTTYPE_1ELEMENT); - } - } - } - - /* No match; don't sort. */ - dont_sort: - *argp = NULL; - return (NS_SORTLISTTYPE_NONE); -} - -int -ns_sortlist_addrorder2(const isc_netaddr_t *addr, const void *arg) { - const dns_acl_t *sortacl = (const dns_acl_t *) arg; - int match; - - (void)dns_acl_match(addr, NULL, sortacl, - &ns_g_server->aclenv, - &match, NULL); - if (match > 0) - return (match); - else if (match < 0) - return (INT_MAX - (-match)); - else - return (INT_MAX / 2); -} - -int -ns_sortlist_addrorder1(const isc_netaddr_t *addr, const void *arg) { - const dns_aclelement_t *matchelt = (const dns_aclelement_t *) arg; - if (dns_aclelement_match(addr, NULL, matchelt, - &ns_g_server->aclenv, - NULL)) { - return (0); - } else { - return (INT_MAX); - } -} - -void -ns_sortlist_byaddrsetup(dns_acl_t *sortlist_acl, isc_netaddr_t *client_addr, - dns_addressorderfunc_t *orderp, - const void **argp) -{ - ns_sortlisttype_t sortlisttype; - - sortlisttype = ns_sortlist_setup(sortlist_acl, client_addr, argp); - - switch (sortlisttype) { - case NS_SORTLISTTYPE_1ELEMENT: - *orderp = ns_sortlist_addrorder1; - break; - case NS_SORTLISTTYPE_2ELEMENT: - *orderp = ns_sortlist_addrorder2; - break; - case NS_SORTLISTTYPE_NONE: - *orderp = NULL; - break; - default: - UNEXPECTED_ERROR(__FILE__, __LINE__, - "unexpected return from ns_sortlist_setup(): " - "%d", sortlisttype); - break; - } -} - diff --git a/contrib/bind9/bin/named/tkeyconf.c b/contrib/bind9/bin/named/tkeyconf.c deleted file mode 100644 index 3c843ac..0000000 --- a/contrib/bind9/bin/named/tkeyconf.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: tkeyconf.c,v 1.20.18.6 2006/03/02 00:37:21 marka Exp $ */ - -/*! \file */ - -#include - -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include - -#include -#include -#include -#include - -#include - -#include - -#define RETERR(x) do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto failure; \ - } while (0) - - -isc_result_t -ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx, - isc_entropy_t *ectx, dns_tkeyctx_t **tctxp) -{ - isc_result_t result; - dns_tkeyctx_t *tctx = NULL; - const char *s; - isc_uint32_t n; - dns_fixedname_t fname; - dns_name_t *name; - isc_buffer_t b; - const cfg_obj_t *obj; - int type; - - result = dns_tkeyctx_create(mctx, ectx, &tctx); - if (result != ISC_R_SUCCESS) - return (result); - - obj = NULL; - result = cfg_map_get(options, "tkey-dhkey", &obj); - if (result == ISC_R_SUCCESS) { - s = cfg_obj_asstring(cfg_tuple_get(obj, "name")); - n = cfg_obj_asuint32(cfg_tuple_get(obj, "keyid")); - isc_buffer_init(&b, s, strlen(s)); - isc_buffer_add(&b, strlen(s)); - dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); - RETERR(dns_name_fromtext(name, &b, dns_rootname, - ISC_FALSE, NULL)); - type = DST_TYPE_PUBLIC|DST_TYPE_PRIVATE|DST_TYPE_KEY; - RETERR(dst_key_fromfile(name, (dns_keytag_t) n, DNS_KEYALG_DH, - type, NULL, mctx, &tctx->dhkey)); - } - - obj = NULL; - result = cfg_map_get(options, "tkey-domain", &obj); - if (result == ISC_R_SUCCESS) { - s = cfg_obj_asstring(obj); - isc_buffer_init(&b, s, strlen(s)); - isc_buffer_add(&b, strlen(s)); - dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); - RETERR(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, - NULL)); - tctx->domain = isc_mem_get(mctx, sizeof(dns_name_t)); - if (tctx->domain == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - dns_name_init(tctx->domain, NULL); - RETERR(dns_name_dup(name, mctx, tctx->domain)); - } - - obj = NULL; - result = cfg_map_get(options, "tkey-gssapi-credential", &obj); - if (result == ISC_R_SUCCESS) { - s = cfg_obj_asstring(obj); - isc_buffer_init(&b, s, strlen(s)); - isc_buffer_add(&b, strlen(s)); - dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); - RETERR(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, - NULL)); - RETERR(dst_gssapi_acquirecred(name, ISC_FALSE, - &tctx->gsscred)); - } - - *tctxp = tctx; - return (ISC_R_SUCCESS); - - failure: - dns_tkeyctx_destroy(&tctx); - return (result); -} - diff --git a/contrib/bind9/bin/named/tsigconf.c b/contrib/bind9/bin/named/tsigconf.c deleted file mode 100644 index 7fa7fe5..0000000 --- a/contrib/bind9/bin/named/tsigconf.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: tsigconf.c,v 1.22.18.6 2006/02/28 03:10:47 marka Exp $ */ - -/*! \file */ - -#include - -#include -#include -#include -#include - -#include - -#include -#include - -#include - -#include -#include - -static isc_result_t -add_initial_keys(const cfg_obj_t *list, dns_tsig_keyring_t *ring, - isc_mem_t *mctx) -{ - dns_tsigkey_t *tsigkey = NULL; - const cfg_listelt_t *element; - const cfg_obj_t *key = NULL; - const char *keyid = NULL; - unsigned char *secret = NULL; - int secretalloc = 0; - int secretlen = 0; - isc_result_t ret; - isc_stdtime_t now; - isc_uint16_t bits; - - for (element = cfg_list_first(list); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *algobj = NULL; - const cfg_obj_t *secretobj = NULL; - dns_name_t keyname; - dns_name_t *alg; - const char *algstr; - char keynamedata[1024]; - isc_buffer_t keynamesrc, keynamebuf; - const char *secretstr; - isc_buffer_t secretbuf; - - key = cfg_listelt_value(element); - keyid = cfg_obj_asstring(cfg_map_getname(key)); - - algobj = NULL; - secretobj = NULL; - (void)cfg_map_get(key, "algorithm", &algobj); - (void)cfg_map_get(key, "secret", &secretobj); - INSIST(algobj != NULL && secretobj != NULL); - - /* - * Create the key name. - */ - dns_name_init(&keyname, NULL); - isc_buffer_init(&keynamesrc, keyid, strlen(keyid)); - isc_buffer_add(&keynamesrc, strlen(keyid)); - isc_buffer_init(&keynamebuf, keynamedata, sizeof(keynamedata)); - ret = dns_name_fromtext(&keyname, &keynamesrc, dns_rootname, - ISC_TRUE, &keynamebuf); - if (ret != ISC_R_SUCCESS) - goto failure; - - /* - * Create the algorithm. - */ - algstr = cfg_obj_asstring(algobj); - if (ns_config_getkeyalgorithm(algstr, &alg, &bits) - != ISC_R_SUCCESS) { - cfg_obj_log(algobj, ns_g_lctx, ISC_LOG_ERROR, - "key '%s': has a unsupported algorithm '%s'", - keyid, algstr); - ret = DNS_R_BADALG; - goto failure; - } - - secretstr = cfg_obj_asstring(secretobj); - secretalloc = secretlen = strlen(secretstr) * 3 / 4; - secret = isc_mem_get(mctx, secretlen); - if (secret == NULL) { - ret = ISC_R_NOMEMORY; - goto failure; - } - isc_buffer_init(&secretbuf, secret, secretlen); - ret = isc_base64_decodestring(secretstr, &secretbuf); - if (ret != ISC_R_SUCCESS) - goto failure; - secretlen = isc_buffer_usedlength(&secretbuf); - - isc_stdtime_get(&now); - ret = dns_tsigkey_create(&keyname, alg, secret, secretlen, - ISC_FALSE, NULL, now, now, - mctx, ring, &tsigkey); - isc_mem_put(mctx, secret, secretalloc); - secret = NULL; - if (ret != ISC_R_SUCCESS) - goto failure; - /* - * Set digest bits. - */ - dst_key_setbits(tsigkey->key, bits); - dns_tsigkey_detach(&tsigkey); - } - - return (ISC_R_SUCCESS); - - failure: - cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, - "configuring key '%s': %s", keyid, - isc_result_totext(ret)); - - if (secret != NULL) - isc_mem_put(mctx, secret, secretalloc); - return (ret); -} - -isc_result_t -ns_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig, - isc_mem_t *mctx, dns_tsig_keyring_t **ringp) -{ - const cfg_obj_t *maps[3]; - const cfg_obj_t *keylist; - dns_tsig_keyring_t *ring = NULL; - isc_result_t result; - int i; - - i = 0; - if (config != NULL) - maps[i++] = config; - if (vconfig != NULL) - maps[i++] = cfg_tuple_get(vconfig, "options"); - maps[i] = NULL; - - result = dns_tsigkeyring_create(mctx, &ring); - if (result != ISC_R_SUCCESS) - return (result); - - for (i = 0; ; i++) { - if (maps[i] == NULL) - break; - keylist = NULL; - result = cfg_map_get(maps[i], "key", &keylist); - if (result != ISC_R_SUCCESS) - continue; - result = add_initial_keys(keylist, ring, mctx); - if (result != ISC_R_SUCCESS) - goto failure; - } - - *ringp = ring; - return (ISC_R_SUCCESS); - - failure: - dns_tsigkeyring_destroy(&ring); - return (result); -} diff --git a/contrib/bind9/bin/named/unix/Makefile.in b/contrib/bind9/bin/named/unix/Makefile.in deleted file mode 100644 index a18351a..0000000 --- a/contrib/bind9/bin/named/unix/Makefile.in +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 1999-2001 Internet Software Consortium. -# -# Permission to use, copy, modify, and 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: Makefile.in,v 1.8 2004/03/05 04:58:01 marka Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -@BIND9_MAKE_INCLUDES@ - -CINCLUDES = -I${srcdir}/include -I${srcdir}/../include \ - ${DNS_INCLUDES} ${ISC_INCLUDES} - -CDEFINES = -CWARNINGS = - -OBJS = os.@O@ - -SRCS = os.c - -TARGETS = ${OBJS} - -@BIND9_MAKE_RULES@ diff --git a/contrib/bind9/bin/named/unix/include/named/os.h b/contrib/bind9/bin/named/unix/include/named/os.h deleted file mode 100644 index 24afdcb..0000000 --- a/contrib/bind9/bin/named/unix/include/named/os.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: os.h,v 1.22.18.3 2005/04/29 00:15:39 marka Exp $ */ - -#ifndef NS_OS_H -#define NS_OS_H 1 - -/*! \file */ - -#include - -void -ns_os_init(const char *progname); - -void -ns_os_daemonize(void); - -void -ns_os_opendevnull(void); - -void -ns_os_closedevnull(void); - -void -ns_os_chroot(const char *root); - -void -ns_os_inituserinfo(const char *username); - -void -ns_os_changeuser(void); - -void -ns_os_minprivs(void); - -void -ns_os_writepidfile(const char *filename, isc_boolean_t first_time); - -void -ns_os_shutdown(void); - -isc_result_t -ns_os_gethostname(char *buf, size_t len); - -void -ns_os_shutdownmsg(char *command, isc_buffer_t *text); - -void -ns_os_tzset(void); - -void -ns_os_started(void); - -#endif /* NS_OS_H */ diff --git a/contrib/bind9/bin/named/unix/os.c b/contrib/bind9/bin/named/unix/os.c deleted file mode 100644 index 3864612..0000000 --- a/contrib/bind9/bin/named/unix/os.c +++ /dev/null @@ -1,691 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: os.c,v 1.66.18.11 2006/02/03 23:51:38 marka Exp $ */ - -/*! \file */ - -#include -#include - -#include /* dev_t FreeBSD 2.1 */ -#include - -#include -#include -#include -#include /* Required for initgroups() on IRIX. */ -#include -#include -#include -#include -#include -#ifdef HAVE_TZSET -#include -#endif -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#ifdef HAVE_LIBSCF -#include -#endif - -static char *pidfile = NULL; -static int devnullfd = -1; - -#ifndef ISC_FACILITY -#define ISC_FACILITY LOG_DAEMON -#endif - -/* - * If there's no , we don't care about - */ -#ifndef HAVE_LINUX_CAPABILITY_H -#undef HAVE_SYS_PRCTL_H -#endif - -/* - * Linux defines: - * (T) HAVE_LINUXTHREADS - * (C) HAVE_LINUX_CAPABILITY_H - * (P) HAVE_SYS_PRCTL_H - * The possible cases are: - * none: setuid() normally - * T: no setuid() - * C: setuid() normally, drop caps (keep CAP_SETUID) - * T+C: no setuid(), drop caps (don't keep CAP_SETUID) - * T+C+P: setuid() early, drop caps (keep CAP_SETUID) - * C+P: setuid() normally, drop caps (keep CAP_SETUID) - * P: not possible - * T+P: not possible - * - * if (C) - * caps = BIND_SERVICE + CHROOT + SETGID - * if ((T && C && P) || !T) - * caps += SETUID - * endif - * capset(caps) - * endif - * if (T && C && P && -u) - * setuid() - * else if (T && -u) - * fail - * --> start threads - * if (!T && -u) - * setuid() - * if (C && (P || !-u)) - * caps = BIND_SERVICE - * capset(caps) - * endif - * - * It will be nice when Linux threads work properly with setuid(). - */ - -#ifdef HAVE_LINUXTHREADS -static pid_t mainpid = 0; -#endif - -static struct passwd *runas_pw = NULL; -static isc_boolean_t done_setuid = ISC_FALSE; -static int dfd[2] = { -1, -1 }; - -#ifdef HAVE_LINUX_CAPABILITY_H - -static isc_boolean_t non_root = ISC_FALSE; -static isc_boolean_t non_root_caps = ISC_FALSE; - -/*% - * We define _LINUX_FS_H to prevent it from being included. We don't need - * anything from it, and the files it includes cause warnings with 2.2 - * kernels, and compilation failures (due to conflicts between - * and ) on 2.3 kernels. - */ -#define _LINUX_FS_H - -#include /* Required for syscall(). */ -#include /* Required for _LINUX_CAPABILITY_VERSION. */ - -#ifdef HAVE_SYS_PRCTL_H -#include /* Required for prctl(). */ - -/* - * If the value of PR_SET_KEEPCAPS is not in , define it - * here. This allows setuid() to work on systems running a new enough - * kernel but with /usr/include/linux pointing to "standard" kernel - * headers. - */ -#ifndef PR_SET_KEEPCAPS -#define PR_SET_KEEPCAPS 8 -#endif - -#endif /* HAVE_SYS_PRCTL_H */ - -#ifndef SYS_capset -#ifndef __NR_capset -#include /* Slackware 4.0 needs this. */ -#endif -#define SYS_capset __NR_capset -#endif - -static void -linux_setcaps(unsigned int caps) { - struct __user_cap_header_struct caphead; - struct __user_cap_data_struct cap; - char strbuf[ISC_STRERRORSIZE]; - - if ((getuid() != 0 && !non_root_caps) || non_root) - return; - - memset(&caphead, 0, sizeof(caphead)); - caphead.version = _LINUX_CAPABILITY_VERSION; - caphead.pid = 0; - memset(&cap, 0, sizeof(cap)); - cap.effective = caps; - cap.permitted = caps; - cap.inheritable = 0; - if (syscall(SYS_capset, &caphead, &cap) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("capset failed: %s:" - " please ensure that the capset kernel" - " module is loaded. see insmod(8)", - strbuf); - } -} - -static void -linux_initialprivs(void) { - unsigned int caps; - - /*% - * We don't need most privileges, so we drop them right away. - * Later on linux_minprivs() will be called, which will drop our - * capabilities to the minimum needed to run the server. - */ - - caps = 0; - - /* - * We need to be able to bind() to privileged ports, notably port 53! - */ - caps |= (1 << CAP_NET_BIND_SERVICE); - - /* - * We need chroot() initially too. - */ - caps |= (1 << CAP_SYS_CHROOT); - -#if defined(HAVE_SYS_PRCTL_H) || !defined(HAVE_LINUXTHREADS) - /* - * We can setuid() only if either the kernel supports keeping - * capabilities after setuid() (which we don't know until we've - * tried) or we're not using threads. If either of these is - * true, we want the setuid capability. - */ - caps |= (1 << CAP_SETUID); -#endif - - /* - * Since we call initgroups, we need this. - */ - caps |= (1 << CAP_SETGID); - - /* - * Without this, we run into problems reading a configuration file - * owned by a non-root user and non-world-readable on startup. - */ - caps |= (1 << CAP_DAC_READ_SEARCH); - - /* - * XXX We might want to add CAP_SYS_RESOURCE, though it's not - * clear it would work right given the way linuxthreads work. - * XXXDCL But since we need to be able to set the maximum number - * of files, the stack size, data size, and core dump size to - * support named.conf options, this is now being added to test. - */ - caps |= (1 << CAP_SYS_RESOURCE); - - linux_setcaps(caps); -} - -static void -linux_minprivs(void) { - unsigned int caps; - - /*% - * Drop all privileges except the ability to bind() to privileged - * ports. - * - * It's important that we drop CAP_SYS_CHROOT. If we didn't, it - * chroot() could be used to escape from the chrooted area. - */ - - caps = 0; - caps |= (1 << CAP_NET_BIND_SERVICE); - - /* - * XXX We might want to add CAP_SYS_RESOURCE, though it's not - * clear it would work right given the way linuxthreads work. - * XXXDCL But since we need to be able to set the maximum number - * of files, the stack size, data size, and core dump size to - * support named.conf options, this is now being added to test. - */ - caps |= (1 << CAP_SYS_RESOURCE); - - linux_setcaps(caps); -} - -#ifdef HAVE_SYS_PRCTL_H -static void -linux_keepcaps(void) { - char strbuf[ISC_STRERRORSIZE]; - /*% - * Ask the kernel to allow us to keep our capabilities after we - * setuid(). - */ - - if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) { - if (errno != EINVAL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("prctl() failed: %s", strbuf); - } - } else { - non_root_caps = ISC_TRUE; - if (getuid() != 0) - non_root = ISC_TRUE; - } -} -#endif - -#endif /* HAVE_LINUX_CAPABILITY_H */ - - -static void -setup_syslog(const char *progname) { - int options; - - options = LOG_PID; -#ifdef LOG_NDELAY - options |= LOG_NDELAY; -#endif - openlog(isc_file_basename(progname), options, ISC_FACILITY); -} - -void -ns_os_init(const char *progname) { - setup_syslog(progname); -#ifdef HAVE_LINUX_CAPABILITY_H - linux_initialprivs(); -#endif -#ifdef HAVE_LINUXTHREADS - mainpid = getpid(); -#endif -#ifdef SIGXFSZ - signal(SIGXFSZ, SIG_IGN); -#endif -} - -void -ns_os_daemonize(void) { - pid_t pid; - char strbuf[ISC_STRERRORSIZE]; - - if (pipe(dfd) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("pipe(): %s", strbuf); - } - - pid = fork(); - if (pid == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("fork(): %s", strbuf); - } - if (pid != 0) { - int n; - /* - * Wait for the child to finish loading for the first time. - * This would be so much simpler if fork() worked once we - * were multi-threaded. - */ - (void)close(dfd[1]); - do { - char buf; - n = read(dfd[0], &buf, 1); - if (n == 1) - _exit(0); - } while (n == -1 && errno == EINTR); - _exit(1); - } - (void)close(dfd[0]); - - /* - * We're the child. - */ - -#ifdef HAVE_LINUXTHREADS - mainpid = getpid(); -#endif - - if (setsid() == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("setsid(): %s", strbuf); - } - - /* - * Try to set stdin, stdout, and stderr to /dev/null, but press - * on even if it fails. - * - * XXXMLG The close() calls here are unneeded on all but NetBSD, but - * are harmless to include everywhere. dup2() is supposed to close - * the FD if it is in use, but unproven-pthreads-0.16 is broken - * and will end up closing the wrong FD. This will be fixed eventually, - * and these calls will be removed. - */ - if (devnullfd != -1) { - if (devnullfd != STDIN_FILENO) { - (void)close(STDIN_FILENO); - (void)dup2(devnullfd, STDIN_FILENO); - } - if (devnullfd != STDOUT_FILENO) { - (void)close(STDOUT_FILENO); - (void)dup2(devnullfd, STDOUT_FILENO); - } - if (devnullfd != STDERR_FILENO) { - (void)close(STDERR_FILENO); - (void)dup2(devnullfd, STDERR_FILENO); - } - } -} - -void -ns_os_started(void) { - char buf = 0; - - /* - * Signal to the parent that we stated successfully. - */ - if (dfd[0] != -1 && dfd[1] != -1) { - write(dfd[1], &buf, 1); - close(dfd[1]); - dfd[0] = dfd[1] = -1; - } -} - -void -ns_os_opendevnull(void) { - devnullfd = open("/dev/null", O_RDWR, 0); -} - -void -ns_os_closedevnull(void) { - if (devnullfd != STDIN_FILENO && - devnullfd != STDOUT_FILENO && - devnullfd != STDERR_FILENO) { - close(devnullfd); - devnullfd = -1; - } -} - -static isc_boolean_t -all_digits(const char *s) { - if (*s == '\0') - return (ISC_FALSE); - while (*s != '\0') { - if (!isdigit((*s)&0xff)) - return (ISC_FALSE); - s++; - } - return (ISC_TRUE); -} - -void -ns_os_chroot(const char *root) { - char strbuf[ISC_STRERRORSIZE]; -#ifdef HAVE_LIBSCF - ns_smf_chroot = 0; -#endif - if (root != NULL) { - if (chroot(root) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("chroot(): %s", strbuf); - } - if (chdir("/") < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("chdir(/): %s", strbuf); - } -#ifdef HAVE_LIBSCF - /* Set ns_smf_chroot flag on successful chroot. */ - ns_smf_chroot = 1; -#endif - } -} - -void -ns_os_inituserinfo(const char *username) { - char strbuf[ISC_STRERRORSIZE]; - if (username == NULL) - return; - - if (all_digits(username)) - runas_pw = getpwuid((uid_t)atoi(username)); - else - runas_pw = getpwnam(username); - endpwent(); - - if (runas_pw == NULL) - ns_main_earlyfatal("user '%s' unknown", username); - - if (getuid() == 0) { - if (initgroups(runas_pw->pw_name, runas_pw->pw_gid) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("initgroups(): %s", strbuf); - } - } - -} - -void -ns_os_changeuser(void) { - char strbuf[ISC_STRERRORSIZE]; - if (runas_pw == NULL || done_setuid) - return; - - done_setuid = ISC_TRUE; - -#ifdef HAVE_LINUXTHREADS -#ifdef HAVE_LINUX_CAPABILITY_H - if (!non_root_caps) - ns_main_earlyfatal("-u with Linux threads not supported: " - "requires kernel support for " - "prctl(PR_SET_KEEPCAPS)"); -#else - ns_main_earlyfatal("-u with Linux threads not supported: " - "no capabilities support or capabilities " - "disabled at build time"); -#endif -#endif - - if (setgid(runas_pw->pw_gid) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("setgid(): %s", strbuf); - } - - if (setuid(runas_pw->pw_uid) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("setuid(): %s", strbuf); - } - -#if defined(HAVE_LINUX_CAPABILITY_H) && !defined(HAVE_LINUXTHREADS) - linux_minprivs(); -#endif -#if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_DUMPABLE) - /* - * Restore the ability of named to drop core after the setuid() - * call has disabled it. - */ - prctl(PR_SET_DUMPABLE,1,0,0,0); -#endif -} - -void -ns_os_minprivs(void) { -#ifdef HAVE_SYS_PRCTL_H - linux_keepcaps(); -#endif - -#ifdef HAVE_LINUXTHREADS - ns_os_changeuser(); /* Call setuid() before threads are started */ -#endif - -#if defined(HAVE_LINUX_CAPABILITY_H) && defined(HAVE_LINUXTHREADS) - linux_minprivs(); -#endif -} - -static int -safe_open(const char *filename, isc_boolean_t append) { - int fd; - struct stat sb; - - if (stat(filename, &sb) == -1) { - if (errno != ENOENT) - return (-1); - } else if ((sb.st_mode & S_IFREG) == 0) { - errno = EOPNOTSUPP; - return (-1); - } - - if (append) - fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - else { - (void)unlink(filename); - fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - } - return (fd); -} - -static void -cleanup_pidfile(void) { - if (pidfile != NULL) { - (void)unlink(pidfile); - free(pidfile); - } - pidfile = NULL; -} - -void -ns_os_writepidfile(const char *filename, isc_boolean_t first_time) { - int fd; - FILE *lockfile; - size_t len; - pid_t pid; - char strbuf[ISC_STRERRORSIZE]; - void (*report)(const char *, ...); - - /* - * The caller must ensure any required synchronization. - */ - - report = first_time ? ns_main_earlyfatal : ns_main_earlywarning; - - cleanup_pidfile(); - - if (filename == NULL) - return; - - len = strlen(filename); - pidfile = malloc(len + 1); - if (pidfile == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - (*report)("couldn't malloc '%s': %s", filename, strbuf); - return; - } - /* This is safe. */ - strcpy(pidfile, filename); - - fd = safe_open(filename, ISC_FALSE); - if (fd < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - (*report)("couldn't open pid file '%s': %s", filename, strbuf); - free(pidfile); - pidfile = NULL; - return; - } - lockfile = fdopen(fd, "w"); - if (lockfile == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - (*report)("could not fdopen() pid file '%s': %s", - filename, strbuf); - (void)close(fd); - cleanup_pidfile(); - return; - } -#ifdef HAVE_LINUXTHREADS - pid = mainpid; -#else - pid = getpid(); -#endif - if (fprintf(lockfile, "%ld\n", (long)pid) < 0) { - (*report)("fprintf() to pid file '%s' failed", filename); - (void)fclose(lockfile); - cleanup_pidfile(); - return; - } - if (fflush(lockfile) == EOF) { - (*report)("fflush() to pid file '%s' failed", filename); - (void)fclose(lockfile); - cleanup_pidfile(); - return; - } - (void)fclose(lockfile); -} - -void -ns_os_shutdown(void) { - closelog(); - cleanup_pidfile(); -} - -isc_result_t -ns_os_gethostname(char *buf, size_t len) { - int n; - - n = gethostname(buf, len); - return ((n == 0) ? ISC_R_SUCCESS : ISC_R_FAILURE); -} - -static char * -next_token(char **stringp, const char *delim) { - char *res; - - do { - res = strsep(stringp, delim); - if (res == NULL) - break; - } while (*res == '\0'); - return (res); -} - -void -ns_os_shutdownmsg(char *command, isc_buffer_t *text) { - char *input, *ptr; - unsigned int n; - pid_t pid; - - input = command; - - /* Skip the command name. */ - ptr = next_token(&input, " \t"); - if (ptr == NULL) - return; - - ptr = next_token(&input, " \t"); - if (ptr == NULL) - return; - - if (strcmp(ptr, "-p") != 0) - return; - -#ifdef HAVE_LINUXTHREADS - pid = mainpid; -#else - pid = getpid(); -#endif - - n = snprintf((char *)isc_buffer_used(text), - isc_buffer_availablelength(text), - "pid: %ld", (long)pid); - /* Only send a message if it is complete. */ - if (n < isc_buffer_availablelength(text)) - isc_buffer_add(text, n); -} - -void -ns_os_tzset(void) { -#ifdef HAVE_TZSET - tzset(); -#endif -} diff --git a/contrib/bind9/bin/named/update.c b/contrib/bind9/bin/named/update.c deleted file mode 100644 index 98054f8..0000000 --- a/contrib/bind9/bin/named/update.c +++ /dev/null @@ -1,3026 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-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: update.c,v 1.109.18.23 2007/08/28 07:20:01 tbox Exp $ */ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/*! \file - * \brief - * This module implements dynamic update as in RFC2136. - */ - -/* - XXX TODO: - - document strict minimality -*/ - -/**************************************************************************/ - -/*% - * Log level for tracing dynamic update protocol requests. - */ -#define LOGLEVEL_PROTOCOL ISC_LOG_INFO - -/*% - * Log level for low-level debug tracing. - */ -#define LOGLEVEL_DEBUG ISC_LOG_DEBUG(8) - -/*% - * Check an operation for failure. These macros all assume that - * the function using them has a 'result' variable and a 'failure' - * label. - */ -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -/*% - * Fail unconditionally with result 'code', which must not - * be ISC_R_SUCCESS. The reason for failure presumably has - * been logged already. - * - * The test against ISC_R_SUCCESS is there to keep the Solaris compiler - * from complaining about "end-of-loop code not reached". - */ - -#define FAIL(code) \ - do { \ - result = (code); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -/*% - * Fail unconditionally and log as a client error. - * The test against ISC_R_SUCCESS is there to keep the Solaris compiler - * from complaining about "end-of-loop code not reached". - */ -#define FAILC(code, msg) \ - do { \ - const char *_what = "failed"; \ - result = (code); \ - switch (result) { \ - case DNS_R_NXDOMAIN: \ - case DNS_R_YXDOMAIN: \ - case DNS_R_YXRRSET: \ - case DNS_R_NXRRSET: \ - _what = "unsuccessful"; \ - } \ - update_log(client, zone, LOGLEVEL_PROTOCOL, \ - "update %s: %s (%s)", _what, \ - msg, isc_result_totext(result)); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -#define FAILN(code, name, msg) \ - do { \ - const char *_what = "failed"; \ - result = (code); \ - switch (result) { \ - case DNS_R_NXDOMAIN: \ - case DNS_R_YXDOMAIN: \ - case DNS_R_YXRRSET: \ - case DNS_R_NXRRSET: \ - _what = "unsuccessful"; \ - } \ - if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { \ - char _nbuf[DNS_NAME_FORMATSIZE]; \ - dns_name_format(name, _nbuf, sizeof(_nbuf)); \ - update_log(client, zone, LOGLEVEL_PROTOCOL, \ - "update %s: %s: %s (%s)", _what, _nbuf, \ - msg, isc_result_totext(result)); \ - } \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -#define FAILNT(code, name, type, msg) \ - do { \ - const char *_what = "failed"; \ - result = (code); \ - switch (result) { \ - case DNS_R_NXDOMAIN: \ - case DNS_R_YXDOMAIN: \ - case DNS_R_YXRRSET: \ - case DNS_R_NXRRSET: \ - _what = "unsuccessful"; \ - } \ - if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { \ - char _nbuf[DNS_NAME_FORMATSIZE]; \ - char _tbuf[DNS_RDATATYPE_FORMATSIZE]; \ - dns_name_format(name, _nbuf, sizeof(_nbuf)); \ - dns_rdatatype_format(type, _tbuf, sizeof(_tbuf)); \ - update_log(client, zone, LOGLEVEL_PROTOCOL, \ - "update %s: %s/%s: %s (%s)", \ - _what, _nbuf, _tbuf, msg, \ - isc_result_totext(result)); \ - } \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) -/*% - * Fail unconditionally and log as a server error. - * The test against ISC_R_SUCCESS is there to keep the Solaris compiler - * from complaining about "end-of-loop code not reached". - */ -#define FAILS(code, msg) \ - do { \ - result = (code); \ - update_log(client, zone, LOGLEVEL_PROTOCOL, \ - "error: %s: %s", \ - msg, isc_result_totext(result)); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -/**************************************************************************/ - -typedef struct rr rr_t; - -struct rr { - /* dns_name_t name; */ - isc_uint32_t ttl; - dns_rdata_t rdata; -}; - -typedef struct update_event update_event_t; - -struct update_event { - ISC_EVENT_COMMON(update_event_t); - dns_zone_t *zone; - isc_result_t result; - dns_message_t *answer; -}; - -/**************************************************************************/ -/* - * Forward declarations. - */ - -static void update_action(isc_task_t *task, isc_event_t *event); -static void updatedone_action(isc_task_t *task, isc_event_t *event); -static isc_result_t send_forward_event(ns_client_t *client, dns_zone_t *zone); -static void forward_done(isc_task_t *task, isc_event_t *event); - -/**************************************************************************/ - -static void -update_log(ns_client_t *client, dns_zone_t *zone, - int level, const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5); - -static void -update_log(ns_client_t *client, dns_zone_t *zone, - int level, const char *fmt, ...) -{ - va_list ap; - char message[4096]; - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - - if (client == NULL || zone == NULL) - return; - - if (isc_log_wouldlog(ns_g_lctx, level) == ISC_FALSE) - return; - - dns_name_format(dns_zone_getorigin(zone), namebuf, - sizeof(namebuf)); - dns_rdataclass_format(dns_zone_getclass(zone), classbuf, - sizeof(classbuf)); - - va_start(ap, fmt); - vsnprintf(message, sizeof(message), fmt, ap); - va_end(ap); - - ns_client_log(client, NS_LOGCATEGORY_UPDATE, NS_LOGMODULE_UPDATE, - level, "updating zone '%s/%s': %s", - namebuf, classbuf, message); -} - -static isc_result_t -checkupdateacl(ns_client_t *client, dns_acl_t *acl, const char *message, - dns_name_t *zonename, isc_boolean_t slave) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - int level = ISC_LOG_ERROR; - const char *msg = "denied"; - isc_result_t result; - - if (slave && acl == NULL) { - result = DNS_R_NOTIMP; - level = ISC_LOG_DEBUG(3); - msg = "disabled"; - } else - result = ns_client_checkaclsilent(client, acl, ISC_FALSE); - - if (result == ISC_R_SUCCESS) { - level = ISC_LOG_DEBUG(3); - msg = "approved"; - } - - dns_name_format(zonename, namebuf, sizeof(namebuf)); - dns_rdataclass_format(client->view->rdclass, classbuf, - sizeof(classbuf)); - - ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY, - NS_LOGMODULE_UPDATE, level, "%s '%s/%s' %s", - message, namebuf, classbuf, msg); - return (result); -} - -/*% - * Update a single RR in version 'ver' of 'db' and log the - * update in 'diff'. - * - * Ensures: - * \li '*tuple' == NULL. Either the tuple is freed, or its - * ownership has been transferred to the diff. - */ -static isc_result_t -do_one_tuple(dns_difftuple_t **tuple, - dns_db_t *db, dns_dbversion_t *ver, - dns_diff_t *diff) -{ - dns_diff_t temp_diff; - isc_result_t result; - - /* - * Create a singleton diff. - */ - dns_diff_init(diff->mctx, &temp_diff); - ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); - - /* - * Apply it to the database. - */ - result = dns_diff_apply(&temp_diff, db, ver); - ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); - if (result != ISC_R_SUCCESS) { - dns_difftuple_free(tuple); - return (result); - } - - /* - * Merge it into the current pending journal entry. - */ - dns_diff_appendminimal(diff, tuple); - - /* - * Do not clear temp_diff. - */ - return (ISC_R_SUCCESS); -} - -/*% - * Perform the updates in 'updates' in version 'ver' of 'db' and log the - * update in 'diff'. - * - * Ensures: - * \li 'updates' is empty. - */ -static isc_result_t -do_diff(dns_diff_t *updates, dns_db_t *db, dns_dbversion_t *ver, - dns_diff_t *diff) -{ - isc_result_t result; - while (! ISC_LIST_EMPTY(updates->tuples)) { - dns_difftuple_t *t = ISC_LIST_HEAD(updates->tuples); - ISC_LIST_UNLINK(updates->tuples, t, link); - CHECK(do_one_tuple(&t, db, ver, diff)); - } - return (ISC_R_SUCCESS); - - failure: - dns_diff_clear(diff); - return (result); -} - -static isc_result_t -update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, - dns_diffop_t op, dns_name_t *name, - dns_ttl_t ttl, dns_rdata_t *rdata) -{ - dns_difftuple_t *tuple = NULL; - isc_result_t result; - result = dns_difftuple_create(diff->mctx, op, - name, ttl, rdata, &tuple); - if (result != ISC_R_SUCCESS) - return (result); - return (do_one_tuple(&tuple, db, ver, diff)); -} - -/**************************************************************************/ -/* - * Callback-style iteration over rdatasets and rdatas. - * - * foreach_rrset() can be used to iterate over the RRsets - * of a name and call a callback function with each - * one. Similarly, foreach_rr() can be used to iterate - * over the individual RRs at name, optionally restricted - * to RRs of a given type. - * - * The callback functions are called "actions" and take - * two arguments: a void pointer for passing arbitrary - * context information, and a pointer to the current RRset - * or RR. By convention, their names end in "_action". - */ - -/* - * XXXRTH We might want to make this public somewhere in libdns. - */ - -/*% - * Function type for foreach_rrset() iterator actions. - */ -typedef isc_result_t rrset_func(void *data, dns_rdataset_t *rrset); - -/*% - * Function type for foreach_rr() iterator actions. - */ -typedef isc_result_t rr_func(void *data, rr_t *rr); - -/*% - * Internal context struct for foreach_node_rr(). - */ -typedef struct { - rr_func * rr_action; - void * rr_action_data; -} foreach_node_rr_ctx_t; - -/*% - * Internal helper function for foreach_node_rr(). - */ -static isc_result_t -foreach_node_rr_action(void *data, dns_rdataset_t *rdataset) { - isc_result_t result; - foreach_node_rr_ctx_t *ctx = data; - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) - { - rr_t rr = { 0, DNS_RDATA_INIT }; - - dns_rdataset_current(rdataset, &rr.rdata); - rr.ttl = rdataset->ttl; - result = (*ctx->rr_action)(ctx->rr_action_data, &rr); - if (result != ISC_R_SUCCESS) - return (result); - } - if (result != ISC_R_NOMORE) - return (result); - return (ISC_R_SUCCESS); -} - -/*% - * For each rdataset of 'name' in 'ver' of 'db', call 'action' - * with the rdataset and 'action_data' as arguments. If the name - * does not exist, do nothing. - * - * If 'action' returns an error, abort iteration and return the error. - */ -static isc_result_t -foreach_rrset(dns_db_t *db, - dns_dbversion_t *ver, - dns_name_t *name, - rrset_func *action, - void *action_data) -{ - isc_result_t result; - dns_dbnode_t *node; - dns_rdatasetiter_t *iter; - - node = NULL; - result = dns_db_findnode(db, name, ISC_FALSE, &node); - if (result == ISC_R_NOTFOUND) - return (ISC_R_SUCCESS); - if (result != ISC_R_SUCCESS) - return (result); - - iter = NULL; - result = dns_db_allrdatasets(db, node, ver, - (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)) - { - dns_rdataset_t rdataset; - - dns_rdataset_init(&rdataset); - dns_rdatasetiter_current(iter, &rdataset); - - result = (*action)(action_data, &rdataset); - - dns_rdataset_disassociate(&rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup_iterator; - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - cleanup_iterator: - dns_rdatasetiter_destroy(&iter); - - cleanup_node: - dns_db_detachnode(db, &node); - - return (result); -} - -/*% - * For each RR of 'name' in 'ver' of 'db', call 'action' - * with the RR and 'action_data' as arguments. If the name - * does not exist, do nothing. - * - * If 'action' returns an error, abort iteration - * and return the error. - */ -static isc_result_t -foreach_node_rr(dns_db_t *db, - dns_dbversion_t *ver, - dns_name_t *name, - rr_func *rr_action, - void *rr_action_data) -{ - foreach_node_rr_ctx_t ctx; - ctx.rr_action = rr_action; - ctx.rr_action_data = rr_action_data; - return (foreach_rrset(db, ver, name, - foreach_node_rr_action, &ctx)); -} - - -/*% - * For each of the RRs specified by 'db', 'ver', 'name', 'type', - * (which can be dns_rdatatype_any to match any type), and 'covers', call - * 'action' with the RR and 'action_data' as arguments. If the name - * does not exist, or if no RRset of the given type exists at the name, - * do nothing. - * - * If 'action' returns an error, abort iteration and return the error. - */ -static isc_result_t -foreach_rr(dns_db_t *db, - dns_dbversion_t *ver, - dns_name_t *name, - dns_rdatatype_t type, - dns_rdatatype_t covers, - rr_func *rr_action, - void *rr_action_data) -{ - - isc_result_t result; - dns_dbnode_t *node; - dns_rdataset_t rdataset; - - if (type == dns_rdatatype_any) - return (foreach_node_rr(db, ver, name, - rr_action, rr_action_data)); - - node = NULL; - result = dns_db_findnode(db, name, ISC_FALSE, &node); - if (result == ISC_R_NOTFOUND) - return (ISC_R_SUCCESS); - if (result != ISC_R_SUCCESS) - return (result); - - dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(db, node, ver, type, covers, - (isc_stdtime_t) 0, &rdataset, NULL); - if (result == ISC_R_NOTFOUND) { - result = ISC_R_SUCCESS; - goto cleanup_node; - } - if (result != ISC_R_SUCCESS) - goto cleanup_node; - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) - { - rr_t rr = { 0, DNS_RDATA_INIT }; - dns_rdataset_current(&rdataset, &rr.rdata); - rr.ttl = rdataset.ttl; - result = (*rr_action)(rr_action_data, &rr); - if (result != ISC_R_SUCCESS) - goto cleanup_rdataset; - } - if (result != ISC_R_NOMORE) - goto cleanup_rdataset; - result = ISC_R_SUCCESS; - - cleanup_rdataset: - dns_rdataset_disassociate(&rdataset); - cleanup_node: - dns_db_detachnode(db, &node); - - return (result); -} - -/**************************************************************************/ -/* - * Various tests on the database contents (for prerequisites, etc). - */ - -/*% - * Function type for predicate functions that compare a database RR 'db_rr' - * against an update RR 'update_rr'. - */ -typedef isc_boolean_t rr_predicate(dns_rdata_t *update_rr, dns_rdata_t *db_rr); - -/*% - * Helper function for rrset_exists(). - */ -static isc_result_t -rrset_exists_action(void *data, rr_t *rr) { - UNUSED(data); - UNUSED(rr); - return (ISC_R_EXISTS); -} - -/*% - * Utility macro for RR existence checking functions. - * - * If the variable 'result' has the value ISC_R_EXISTS or - * ISC_R_SUCCESS, set *exists to ISC_TRUE or ISC_FALSE, - * respectively, and return success. - * - * If 'result' has any other value, there was a failure. - * Return the failure result code and do not set *exists. - * - * This would be more readable as "do { if ... } while(0)", - * but that form generates tons of warnings on Solaris 2.6. - */ -#define RETURN_EXISTENCE_FLAG \ - return ((result == ISC_R_EXISTS) ? \ - (*exists = ISC_TRUE, ISC_R_SUCCESS) : \ - ((result == ISC_R_SUCCESS) ? \ - (*exists = ISC_FALSE, ISC_R_SUCCESS) : \ - result)) - -/*% - * Set '*exists' to true iff an rrset of the given type exists, - * to false otherwise. - */ -static isc_result_t -rrset_exists(dns_db_t *db, dns_dbversion_t *ver, - dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers, - isc_boolean_t *exists) -{ - isc_result_t result; - result = foreach_rr(db, ver, name, type, covers, - rrset_exists_action, NULL); - RETURN_EXISTENCE_FLAG; -} - -/*% - * Helper function for cname_incompatible_rrset_exists. - */ -static isc_result_t -cname_compatibility_action(void *data, dns_rdataset_t *rrset) { - UNUSED(data); - if (rrset->type != dns_rdatatype_cname && - ! dns_rdatatype_isdnssec(rrset->type)) - return (ISC_R_EXISTS); - return (ISC_R_SUCCESS); -} - -/*% - * Check whether there is an rrset incompatible with adding a CNAME RR, - * i.e., anything but another CNAME (which can be replaced) or a - * DNSSEC RR (which can coexist). - * - * If such an incompatible rrset exists, set '*exists' to ISC_TRUE. - * Otherwise, set it to ISC_FALSE. - */ -static isc_result_t -cname_incompatible_rrset_exists(dns_db_t *db, dns_dbversion_t *ver, - dns_name_t *name, isc_boolean_t *exists) { - isc_result_t result; - result = foreach_rrset(db, ver, name, - cname_compatibility_action, NULL); - RETURN_EXISTENCE_FLAG; -} - -/*% - * Helper function for rr_count(). - */ -static isc_result_t -count_rr_action(void *data, rr_t *rr) { - int *countp = data; - UNUSED(rr); - (*countp)++; - return (ISC_R_SUCCESS); -} - -/*% - * Count the number of RRs of 'type' belonging to 'name' in 'ver' of 'db'. - */ -static isc_result_t -rr_count(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_rdatatype_t type, dns_rdatatype_t covers, int *countp) -{ - *countp = 0; - return (foreach_rr(db, ver, name, type, covers, - count_rr_action, countp)); -} - -/*% - * Context struct and helper function for name_exists(). - */ - -static isc_result_t -name_exists_action(void *data, dns_rdataset_t *rrset) { - UNUSED(data); - UNUSED(rrset); - return (ISC_R_EXISTS); -} - -/*% - * Set '*exists' to true iff the given name exists, to false otherwise. - */ -static isc_result_t -name_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - isc_boolean_t *exists) -{ - isc_result_t result; - result = foreach_rrset(db, ver, name, - name_exists_action, NULL); - RETURN_EXISTENCE_FLAG; -} - -typedef struct { - dns_name_t *name, *signer; - dns_ssutable_t *table; -} ssu_check_t; - -static isc_result_t -ssu_checkrule(void *data, dns_rdataset_t *rrset) { - ssu_check_t *ssuinfo = data; - isc_boolean_t result; - - /* - * If we're deleting all records, it's ok to delete RRSIG and NSEC even - * if we're normally not allowed to. - */ - if (rrset->type == dns_rdatatype_rrsig || - rrset->type == dns_rdatatype_nsec) - return (ISC_R_SUCCESS); - result = dns_ssutable_checkrules(ssuinfo->table, ssuinfo->signer, - ssuinfo->name, rrset->type); - return (result == ISC_TRUE ? ISC_R_SUCCESS : ISC_R_FAILURE); -} - -static isc_boolean_t -ssu_checkall(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_ssutable_t *ssutable, dns_name_t *signer) -{ - isc_result_t result; - ssu_check_t ssuinfo; - - ssuinfo.name = name; - ssuinfo.table = ssutable; - ssuinfo.signer = signer; - result = foreach_rrset(db, ver, name, ssu_checkrule, &ssuinfo); - return (ISC_TF(result == ISC_R_SUCCESS)); -} - -/**************************************************************************/ -/* - * Checking of "RRset exists (value dependent)" prerequisites. - * - * In the RFC2136 section 3.2.5, this is the pseudocode involving - * a variable called "temp", a mapping of tuples to rrsets. - * - * Here, we represent the "temp" data structure as (non-minimial) "dns_diff_t" - * where each typle has op==DNS_DIFFOP_EXISTS. - */ - - -/*% - * Append a tuple asserting the existence of the RR with - * 'name' and 'rdata' to 'diff'. - */ -static isc_result_t -temp_append(dns_diff_t *diff, dns_name_t *name, dns_rdata_t *rdata) { - isc_result_t result; - dns_difftuple_t *tuple = NULL; - - REQUIRE(DNS_DIFF_VALID(diff)); - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_EXISTS, - name, 0, rdata, &tuple)); - ISC_LIST_APPEND(diff->tuples, tuple, link); - failure: - return (result); -} - -/*% - * Compare two rdatasets represented as sorted lists of tuples. - * All list elements must have the same owner name and type. - * Return ISC_R_SUCCESS if the rdatasets are equal, rcode(dns_rcode_nxrrset) - * if not. - */ -static isc_result_t -temp_check_rrset(dns_difftuple_t *a, dns_difftuple_t *b) { - for (;;) { - if (a == NULL || b == NULL) - break; - INSIST(a->op == DNS_DIFFOP_EXISTS && - b->op == DNS_DIFFOP_EXISTS); - INSIST(a->rdata.type == b->rdata.type); - INSIST(dns_name_equal(&a->name, &b->name)); - if (dns_rdata_compare(&a->rdata, &b->rdata) != 0) - return (DNS_R_NXRRSET); - a = ISC_LIST_NEXT(a, link); - b = ISC_LIST_NEXT(b, link); - } - if (a != NULL || b != NULL) - return (DNS_R_NXRRSET); - return (ISC_R_SUCCESS); -} - -/*% - * A comparison function defining the sorting order for the entries - * in the "temp" data structure. The major sort key is the owner name, - * followed by the type and rdata. - */ -static int -temp_order(const void *av, const void *bv) { - dns_difftuple_t const * const *ap = av; - dns_difftuple_t const * const *bp = bv; - dns_difftuple_t const *a = *ap; - dns_difftuple_t const *b = *bp; - int r; - r = dns_name_compare(&a->name, &b->name); - if (r != 0) - return (r); - r = (b->rdata.type - a->rdata.type); - if (r != 0) - return (r); - r = dns_rdata_compare(&a->rdata, &b->rdata); - return (r); -} - -/*% - * Check the "RRset exists (value dependent)" prerequisite information - * in 'temp' against the contents of the database 'db'. - * - * Return ISC_R_SUCCESS if the prerequisites are satisfied, - * rcode(dns_rcode_nxrrset) if not. - * - * 'temp' must be pre-sorted. - */ - -static isc_result_t -temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db, - dns_dbversion_t *ver, dns_name_t *tmpname, dns_rdatatype_t *typep) -{ - isc_result_t result; - dns_name_t *name; - dns_dbnode_t *node; - dns_difftuple_t *t; - dns_diff_t trash; - - dns_diff_init(mctx, &trash); - - /* - * For each name and type in the prerequisites, - * construct a sorted rdata list of the corresponding - * database contents, and compare the lists. - */ - t = ISC_LIST_HEAD(temp->tuples); - while (t != NULL) { - name = &t->name; - (void)dns_name_copy(name, tmpname, NULL); - *typep = t->rdata.type; - - /* A new unique name begins here. */ - node = NULL; - result = dns_db_findnode(db, name, ISC_FALSE, &node); - if (result == ISC_R_NOTFOUND) - return (DNS_R_NXRRSET); - if (result != ISC_R_SUCCESS) - return (result); - - /* A new unique type begins here. */ - while (t != NULL && dns_name_equal(&t->name, name)) { - dns_rdatatype_t type, covers; - dns_rdataset_t rdataset; - dns_diff_t d_rrs; /* Database RRs with - this name and type */ - dns_diff_t u_rrs; /* Update RRs with - this name and type */ - - *typep = type = t->rdata.type; - if (type == dns_rdatatype_rrsig || - type == dns_rdatatype_sig) - covers = dns_rdata_covers(&t->rdata); - else - covers = 0; - - /* - * Collect all database RRs for this name and type - * onto d_rrs and sort them. - */ - dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(db, node, ver, type, - covers, (isc_stdtime_t) 0, - &rdataset, NULL); - if (result != ISC_R_SUCCESS) { - dns_db_detachnode(db, &node); - return (DNS_R_NXRRSET); - } - - dns_diff_init(mctx, &d_rrs); - dns_diff_init(mctx, &u_rrs); - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) - { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(&rdataset, &rdata); - result = temp_append(&d_rrs, name, &rdata); - if (result != ISC_R_SUCCESS) - goto failure; - } - if (result != ISC_R_NOMORE) - goto failure; - result = dns_diff_sort(&d_rrs, temp_order); - if (result != ISC_R_SUCCESS) - goto failure; - - /* - * Collect all update RRs for this name and type - * onto u_rrs. No need to sort them here - - * they are already sorted. - */ - while (t != NULL && - dns_name_equal(&t->name, name) && - t->rdata.type == type) - { - dns_difftuple_t *next = - ISC_LIST_NEXT(t, link); - ISC_LIST_UNLINK(temp->tuples, t, link); - ISC_LIST_APPEND(u_rrs.tuples, t, link); - t = next; - } - - /* Compare the two sorted lists. */ - result = temp_check_rrset(ISC_LIST_HEAD(u_rrs.tuples), - ISC_LIST_HEAD(d_rrs.tuples)); - if (result != ISC_R_SUCCESS) - goto failure; - - /* - * We are done with the tuples, but we can't free - * them yet because "name" still points into one - * of them. Move them on a temporary list. - */ - ISC_LIST_APPENDLIST(trash.tuples, u_rrs.tuples, link); - ISC_LIST_APPENDLIST(trash.tuples, d_rrs.tuples, link); - dns_rdataset_disassociate(&rdataset); - - continue; - - failure: - dns_diff_clear(&d_rrs); - dns_diff_clear(&u_rrs); - dns_diff_clear(&trash); - dns_rdataset_disassociate(&rdataset); - dns_db_detachnode(db, &node); - return (result); - } - - dns_db_detachnode(db, &node); - } - - dns_diff_clear(&trash); - return (ISC_R_SUCCESS); -} - -/**************************************************************************/ -/* - * Conditional deletion of RRs. - */ - -/*% - * Context structure for delete_if(). - */ - -typedef struct { - rr_predicate *predicate; - dns_db_t *db; - dns_dbversion_t *ver; - dns_diff_t *diff; - dns_name_t *name; - dns_rdata_t *update_rr; -} conditional_delete_ctx_t; - -/*% - * Predicate functions for delete_if(). - */ - -/*% - * Return true iff 'db_rr' is neither a SOA nor an NS RR nor - * an RRSIG nor a NSEC. - */ -static isc_boolean_t -type_not_soa_nor_ns_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - UNUSED(update_rr); - return ((db_rr->type != dns_rdatatype_soa && - db_rr->type != dns_rdatatype_ns && - db_rr->type != dns_rdatatype_rrsig && - db_rr->type != dns_rdatatype_nsec) ? - ISC_TRUE : ISC_FALSE); -} - -/*% - * Return true iff 'db_rr' is neither a RRSIG nor a NSEC. - */ -static isc_boolean_t -type_not_dnssec(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - UNUSED(update_rr); - return ((db_rr->type != dns_rdatatype_rrsig && - db_rr->type != dns_rdatatype_nsec) ? - ISC_TRUE : ISC_FALSE); -} - -/*% - * Return true always. - */ -static isc_boolean_t -true_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - UNUSED(update_rr); - UNUSED(db_rr); - return (ISC_TRUE); -} - -/*% - * Return true iff the two RRs have identical rdata. - */ -static isc_boolean_t -rr_equal_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - /* - * XXXRTH This is not a problem, but we should consider creating - * dns_rdata_equal() (that used dns_name_equal()), since it - * would be faster. Not a priority. - */ - return (dns_rdata_compare(update_rr, db_rr) == 0 ? - ISC_TRUE : ISC_FALSE); -} - -/*% - * Return true iff 'update_rr' should replace 'db_rr' according - * to the special RFC2136 rules for CNAME, SOA, and WKS records. - * - * RFC2136 does not mention NSEC or DNAME, but multiple NSECs or DNAMEs - * make little sense, so we replace those, too. - */ -static isc_boolean_t -replaces_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - if (db_rr->type != update_rr->type) - return (ISC_FALSE); - if (db_rr->type == dns_rdatatype_cname) - return (ISC_TRUE); - if (db_rr->type == dns_rdatatype_dname) - return (ISC_TRUE); - if (db_rr->type == dns_rdatatype_soa) - return (ISC_TRUE); - if (db_rr->type == dns_rdatatype_nsec) - return (ISC_TRUE); - if (db_rr->type == dns_rdatatype_wks) { - /* - * Compare the address and protocol fields only. These - * form the first five bytes of the RR data. Do a - * raw binary comparison; unpacking the WKS RRs using - * dns_rdata_tostruct() might be cleaner in some ways, - * but it would require us to pass around an mctx. - */ - INSIST(db_rr->length >= 5 && update_rr->length >= 5); - return (memcmp(db_rr->data, update_rr->data, 5) == 0 ? - ISC_TRUE : ISC_FALSE); - } - return (ISC_FALSE); -} - -/*% - * Internal helper function for delete_if(). - */ -static isc_result_t -delete_if_action(void *data, rr_t *rr) { - conditional_delete_ctx_t *ctx = data; - if ((*ctx->predicate)(ctx->update_rr, &rr->rdata)) { - isc_result_t result; - result = update_one_rr(ctx->db, ctx->ver, ctx->diff, - DNS_DIFFOP_DEL, ctx->name, - rr->ttl, &rr->rdata); - return (result); - } else { - return (ISC_R_SUCCESS); - } -} - -/*% - * Conditionally delete RRs. Apply 'predicate' to the RRs - * specified by 'db', 'ver', 'name', and 'type' (which can - * be dns_rdatatype_any to match any type). Delete those - * RRs for which the predicate returns true, and log the - * deletions in 'diff'. - */ -static isc_result_t -delete_if(rr_predicate *predicate, - dns_db_t *db, - dns_dbversion_t *ver, - dns_name_t *name, - dns_rdatatype_t type, - dns_rdatatype_t covers, - dns_rdata_t *update_rr, - dns_diff_t *diff) -{ - conditional_delete_ctx_t ctx; - ctx.predicate = predicate; - ctx.db = db; - ctx.ver = ver; - ctx.diff = diff; - ctx.name = name; - ctx.update_rr = update_rr; - return (foreach_rr(db, ver, name, type, covers, - delete_if_action, &ctx)); -} - -/**************************************************************************/ -/*% - * Prepare an RR for the addition of the new RR 'ctx->update_rr', - * with TTL 'ctx->update_rr_ttl', to its rdataset, by deleting - * the RRs if it is replaced by the new RR or has a conflicting TTL. - * The necessary changes are appended to ctx->del_diff and ctx->add_diff; - * we need to do all deletions before any additions so that we don't run - * into transient states with conflicting TTLs. - */ - -typedef struct { - dns_db_t *db; - dns_dbversion_t *ver; - dns_diff_t *diff; - dns_name_t *name; - dns_rdata_t *update_rr; - dns_ttl_t update_rr_ttl; - isc_boolean_t ignore_add; - dns_diff_t del_diff; - dns_diff_t add_diff; -} add_rr_prepare_ctx_t; - -static isc_result_t -add_rr_prepare_action(void *data, rr_t *rr) { - isc_result_t result = ISC_R_SUCCESS; - add_rr_prepare_ctx_t *ctx = data; - dns_difftuple_t *tuple = NULL; - isc_boolean_t equal; - - /* - * If the update RR is a "duplicate" of the update RR, - * the update should be silently ignored. - */ - equal = ISC_TF(dns_rdata_compare(&rr->rdata, ctx->update_rr) == 0); - if (equal && rr->ttl == ctx->update_rr_ttl) { - ctx->ignore_add = ISC_TRUE; - return (ISC_R_SUCCESS); - } - - /* - * If this RR is "equal" to the update RR, it should - * be deleted before the update RR is added. - */ - if (replaces_p(ctx->update_rr, &rr->rdata)) { - CHECK(dns_difftuple_create(ctx->del_diff.mctx, - DNS_DIFFOP_DEL, ctx->name, - rr->ttl, - &rr->rdata, - &tuple)); - dns_diff_append(&ctx->del_diff, &tuple); - return (ISC_R_SUCCESS); - } - - /* - * If this RR differs in TTL from the update RR, - * its TTL must be adjusted. - */ - if (rr->ttl != ctx->update_rr_ttl) { - CHECK(dns_difftuple_create(ctx->del_diff.mctx, - DNS_DIFFOP_DEL, ctx->name, - rr->ttl, - &rr->rdata, - &tuple)); - dns_diff_append(&ctx->del_diff, &tuple); - if (!equal) { - CHECK(dns_difftuple_create(ctx->add_diff.mctx, - DNS_DIFFOP_ADD, ctx->name, - ctx->update_rr_ttl, - &rr->rdata, - &tuple)); - dns_diff_append(&ctx->add_diff, &tuple); - } - } - failure: - return (result); -} - -/**************************************************************************/ -/* - * Miscellaneous subroutines. - */ - -/*% - * Extract a single update RR from 'section' of dynamic update message - * 'msg', with consistency checking. - * - * Stores the owner name, rdata, and TTL of the update RR at 'name', - * 'rdata', and 'ttl', respectively. - */ -static void -get_current_rr(dns_message_t *msg, dns_section_t section, - dns_rdataclass_t zoneclass, - dns_name_t **name, dns_rdata_t *rdata, dns_rdatatype_t *covers, - dns_ttl_t *ttl, - dns_rdataclass_t *update_class) -{ - dns_rdataset_t *rdataset; - isc_result_t result; - dns_message_currentname(msg, section, name); - rdataset = ISC_LIST_HEAD((*name)->list); - INSIST(rdataset != NULL); - INSIST(ISC_LIST_NEXT(rdataset, link) == NULL); - *covers = rdataset->covers; - *ttl = rdataset->ttl; - result = dns_rdataset_first(rdataset); - INSIST(result == ISC_R_SUCCESS); - dns_rdataset_current(rdataset, rdata); - INSIST(dns_rdataset_next(rdataset) == ISC_R_NOMORE); - *update_class = rdata->rdclass; - rdata->rdclass = zoneclass; -} - -/*% - * Increment the SOA serial number of database 'db', version 'ver'. - * Replace the SOA record in the database, and log the - * change in 'diff'. - */ - - /* - * XXXRTH Failures in this routine will be worth logging, when - * we have a logging system. Failure to find the zonename - * or the SOA rdataset warrant at least an UNEXPECTED_ERROR(). - */ - -static isc_result_t -increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver, - dns_diff_t *diff, isc_mem_t *mctx) -{ - dns_difftuple_t *deltuple = NULL; - dns_difftuple_t *addtuple = NULL; - isc_uint32_t serial; - isc_result_t result; - - CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple)); - CHECK(dns_difftuple_copy(deltuple, &addtuple)); - addtuple->op = DNS_DIFFOP_ADD; - - serial = dns_soa_getserial(&addtuple->rdata); - - /* RFC1982 */ - serial = (serial + 1) & 0xFFFFFFFF; - if (serial == 0) - serial = 1; - - dns_soa_setserial(serial, &addtuple->rdata); - CHECK(do_one_tuple(&deltuple, db, ver, diff)); - CHECK(do_one_tuple(&addtuple, db, ver, diff)); - result = ISC_R_SUCCESS; - - failure: - if (addtuple != NULL) - dns_difftuple_free(&addtuple); - if (deltuple != NULL) - dns_difftuple_free(&deltuple); - return (result); -} - -/*% - * Check that the new SOA record at 'update_rdata' does not - * illegally cause the SOA serial number to decrease or stay - * unchanged relative to the existing SOA in 'db'. - * - * Sets '*ok' to ISC_TRUE if the update is legal, ISC_FALSE if not. - * - * William King points out that RFC2136 is inconsistent about - * the case where the serial number stays unchanged: - * - * section 3.4.2.2 requires a server to ignore a SOA update request - * if the serial number on the update SOA is less_than_or_equal to - * the zone SOA serial. - * - * section 3.6 requires a server to ignore a SOA update request if - * the serial is less_than the zone SOA serial. - * - * Paul says 3.4.2.2 is correct. - * - */ -static isc_result_t -check_soa_increment(dns_db_t *db, dns_dbversion_t *ver, - dns_rdata_t *update_rdata, - isc_boolean_t *ok) -{ - isc_uint32_t db_serial; - isc_uint32_t update_serial; - isc_result_t result; - - update_serial = dns_soa_getserial(update_rdata); - - result = dns_db_getsoaserial(db, ver, &db_serial); - if (result != ISC_R_SUCCESS) - return (result); - - if (DNS_SERIAL_GE(db_serial, update_serial)) { - *ok = ISC_FALSE; - } else { - *ok = ISC_TRUE; - } - - return (ISC_R_SUCCESS); - -} - -/**************************************************************************/ -/* - * Incremental updating of NSECs and RRSIGs. - */ - -#define MAXZONEKEYS 32 /*%< Maximum number of zone keys supported. */ - -/*% - * We abuse the dns_diff_t type to represent a set of domain names - * affected by the update. - */ -static isc_result_t -namelist_append_name(dns_diff_t *list, dns_name_t *name) { - isc_result_t result; - dns_difftuple_t *tuple = NULL; - static dns_rdata_t dummy_rdata = DNS_RDATA_INIT; - - CHECK(dns_difftuple_create(list->mctx, DNS_DIFFOP_EXISTS, name, 0, - &dummy_rdata, &tuple)); - dns_diff_append(list, &tuple); - failure: - return (result); -} - -static isc_result_t -namelist_append_subdomain(dns_db_t *db, dns_name_t *name, dns_diff_t *affected) -{ - isc_result_t result; - dns_fixedname_t fixedname; - dns_name_t *child; - dns_dbiterator_t *dbit = NULL; - - dns_fixedname_init(&fixedname); - child = dns_fixedname_name(&fixedname); - - CHECK(dns_db_createiterator(db, ISC_FALSE, &dbit)); - - for (result = dns_dbiterator_seek(dbit, name); - result == ISC_R_SUCCESS; - result = dns_dbiterator_next(dbit)) - { - dns_dbnode_t *node = NULL; - CHECK(dns_dbiterator_current(dbit, &node, child)); - dns_db_detachnode(db, &node); - if (! dns_name_issubdomain(child, name)) - break; - CHECK(namelist_append_name(affected, child)); - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - failure: - if (dbit != NULL) - dns_dbiterator_destroy(&dbit); - return (result); -} - - - -/*% - * Helper function for non_nsec_rrset_exists(). - */ -static isc_result_t -is_non_nsec_action(void *data, dns_rdataset_t *rrset) { - UNUSED(data); - if (!(rrset->type == dns_rdatatype_nsec || - (rrset->type == dns_rdatatype_rrsig && - rrset->covers == dns_rdatatype_nsec))) - return (ISC_R_EXISTS); - return (ISC_R_SUCCESS); -} - -/*% - * Check whether there is an rrset other than a NSEC or RRSIG NSEC, - * i.e., anything that justifies the continued existence of a name - * after a secure update. - * - * If such an rrset exists, set '*exists' to ISC_TRUE. - * Otherwise, set it to ISC_FALSE. - */ -static isc_result_t -non_nsec_rrset_exists(dns_db_t *db, dns_dbversion_t *ver, - dns_name_t *name, isc_boolean_t *exists) -{ - isc_result_t result; - result = foreach_rrset(db, ver, name, - is_non_nsec_action, NULL); - RETURN_EXISTENCE_FLAG; -} - -/*% - * A comparison function for sorting dns_diff_t:s by name. - */ -static int -name_order(const void *av, const void *bv) { - dns_difftuple_t const * const *ap = av; - dns_difftuple_t const * const *bp = bv; - dns_difftuple_t const *a = *ap; - dns_difftuple_t const *b = *bp; - return (dns_name_compare(&a->name, &b->name)); -} - -static isc_result_t -uniqify_name_list(dns_diff_t *list) { - isc_result_t result; - dns_difftuple_t *p, *q; - - CHECK(dns_diff_sort(list, name_order)); - - p = ISC_LIST_HEAD(list->tuples); - while (p != NULL) { - do { - q = ISC_LIST_NEXT(p, link); - if (q == NULL || ! dns_name_equal(&p->name, &q->name)) - break; - ISC_LIST_UNLINK(list->tuples, q, link); - dns_difftuple_free(&q); - } while (1); - p = ISC_LIST_NEXT(p, link); - } - failure: - return (result); -} - - -static isc_result_t -is_glue(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - isc_boolean_t *flag) -{ - isc_result_t result; - dns_fixedname_t foundname; - dns_fixedname_init(&foundname); - result = dns_db_find(db, name, ver, dns_rdatatype_any, - DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD, - (isc_stdtime_t) 0, NULL, - dns_fixedname_name(&foundname), - NULL, NULL); - if (result == ISC_R_SUCCESS) { - *flag = ISC_FALSE; - return (ISC_R_SUCCESS); - } else if (result == DNS_R_ZONECUT) { - /* - * We are at the zonecut. The name will have an NSEC, but - * non-delegation will be omitted from the type bit map. - */ - *flag = ISC_FALSE; - return (ISC_R_SUCCESS); - } else if (result == DNS_R_GLUE || result == DNS_R_DNAME) { - *flag = ISC_TRUE; - return (ISC_R_SUCCESS); - } else { - return (result); - } -} - -/*% - * Find the next/previous name that has a NSEC record. - * In other words, skip empty database nodes and names that - * have had their NSECs removed because they are obscured by - * a zone cut. - */ -static isc_result_t -next_active(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, - dns_dbversion_t *ver, dns_name_t *oldname, dns_name_t *newname, - isc_boolean_t forward) -{ - isc_result_t result; - dns_dbiterator_t *dbit = NULL; - isc_boolean_t has_nsec; - unsigned int wraps = 0; - - CHECK(dns_db_createiterator(db, ISC_FALSE, &dbit)); - - CHECK(dns_dbiterator_seek(dbit, oldname)); - do { - dns_dbnode_t *node = NULL; - - if (forward) - result = dns_dbiterator_next(dbit); - else - result = dns_dbiterator_prev(dbit); - if (result == ISC_R_NOMORE) { - /* - * Wrap around. - */ - if (forward) - CHECK(dns_dbiterator_first(dbit)); - else - CHECK(dns_dbiterator_last(dbit)); - wraps++; - if (wraps == 2) { - update_log(client, zone, ISC_LOG_ERROR, - "secure zone with no NSECs"); - result = DNS_R_BADZONE; - goto failure; - } - } - CHECK(dns_dbiterator_current(dbit, &node, newname)); - dns_db_detachnode(db, &node); - - /* - * The iterator may hold the tree lock, and - * rrset_exists() calls dns_db_findnode() which - * may try to reacquire it. To avoid deadlock - * we must pause the iterator first. - */ - CHECK(dns_dbiterator_pause(dbit)); - CHECK(rrset_exists(db, ver, newname, - dns_rdatatype_nsec, 0, &has_nsec)); - - } while (! has_nsec); - failure: - if (dbit != NULL) - dns_dbiterator_destroy(&dbit); - - return (result); -} - -/*% - * Add a NSEC record for "name", recording the change in "diff". - * The existing NSEC is removed. - */ -static isc_result_t -add_nsec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, - dns_dbversion_t *ver, dns_name_t *name, dns_ttl_t nsecttl, - dns_diff_t *diff) -{ - isc_result_t result; - dns_dbnode_t *node = NULL; - unsigned char buffer[DNS_NSEC_BUFFERSIZE]; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_difftuple_t *tuple = NULL; - dns_fixedname_t fixedname; - dns_name_t *target; - - dns_fixedname_init(&fixedname); - target = dns_fixedname_name(&fixedname); - - /* - * Find the successor name, aka NSEC target. - */ - CHECK(next_active(client, zone, db, ver, name, target, ISC_TRUE)); - - /* - * Create the NSEC RDATA. - */ - CHECK(dns_db_findnode(db, name, ISC_FALSE, &node)); - dns_rdata_init(&rdata); - CHECK(dns_nsec_buildrdata(db, ver, node, target, buffer, &rdata)); - dns_db_detachnode(db, &node); - - /* - * Delete the old NSEC and record the change. - */ - CHECK(delete_if(true_p, db, ver, name, dns_rdatatype_nsec, 0, - NULL, diff)); - /* - * Add the new NSEC and record the change. - */ - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, - nsecttl, &rdata, &tuple)); - CHECK(do_one_tuple(&tuple, db, ver, diff)); - INSIST(tuple == NULL); - - failure: - if (node != NULL) - dns_db_detachnode(db, &node); - return (result); -} - -/*% - * Add a placeholder NSEC record for "name", recording the change in "diff". - */ -static isc_result_t -add_placeholder_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_diff_t *diff) { - isc_result_t result; - dns_difftuple_t *tuple = NULL; - isc_region_t r; - unsigned char data[1] = { 0 }; /* The root domain, no bits. */ - dns_rdata_t rdata = DNS_RDATA_INIT; - - r.base = data; - r.length = sizeof(data); - dns_rdata_fromregion(&rdata, dns_db_class(db), dns_rdatatype_nsec, &r); - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, 0, - &rdata, &tuple)); - CHECK(do_one_tuple(&tuple, db, ver, diff)); - failure: - return (result); -} - -static isc_result_t -find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, - isc_mem_t *mctx, unsigned int maxkeys, - dst_key_t **keys, unsigned int *nkeys) -{ - isc_result_t result; - dns_dbnode_t *node = NULL; - const char *directory = dns_zone_getkeydirectory(zone); - CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node)); - CHECK(dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db), - directory, mctx, maxkeys, keys, nkeys)); - failure: - if (node != NULL) - dns_db_detachnode(db, &node); - return (result); -} - -static isc_boolean_t -ksk_sanity(dns_db_t *db, dns_dbversion_t *ver) { - isc_boolean_t ret = ISC_FALSE; - isc_boolean_t have_ksk = ISC_FALSE, have_nonksk = ISC_FALSE; - isc_result_t result; - dns_dbnode_t *node = NULL; - dns_rdataset_t rdataset; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_dnskey_t dnskey; - - dns_rdataset_init(&rdataset); - CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node)); - CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0, - &rdataset, NULL)); - CHECK(dns_rdataset_first(&rdataset)); - while (result == ISC_R_SUCCESS && (!have_ksk || !have_nonksk)) { - dns_rdataset_current(&rdataset, &rdata); - CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL)); - if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH)) - == DNS_KEYOWNER_ZONE) { - if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) - have_ksk = ISC_TRUE; - else - have_nonksk = ISC_TRUE; - } - dns_rdata_reset(&rdata); - result = dns_rdataset_next(&rdataset); - } - if (have_ksk && have_nonksk) - ret = ISC_TRUE; - failure: - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - return (ret); -} - -/*% - * Add RRSIG records for an RRset, recording the change in "diff". - */ -static isc_result_t -add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, - unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception, - isc_stdtime_t expire, isc_boolean_t check_ksk) -{ - isc_result_t result; - dns_dbnode_t *node = NULL; - dns_rdataset_t rdataset; - dns_rdata_t sig_rdata = DNS_RDATA_INIT; - isc_buffer_t buffer; - unsigned char data[1024]; /* XXX */ - unsigned int i; - - dns_rdataset_init(&rdataset); - isc_buffer_init(&buffer, data, sizeof(data)); - - /* Get the rdataset to sign. */ - CHECK(dns_db_findnode(db, name, ISC_FALSE, &node)); - CHECK(dns_db_findrdataset(db, node, ver, type, 0, - (isc_stdtime_t) 0, - &rdataset, NULL)); - dns_db_detachnode(db, &node); - - for (i = 0; i < nkeys; i++) { - - if (check_ksk && type != dns_rdatatype_dnskey && - (dst_key_flags(keys[i]) & DNS_KEYFLAG_KSK) != 0) - continue; - - if (!dst_key_isprivate(keys[i])) - continue; - - /* Calculate the signature, creating a RRSIG RDATA. */ - CHECK(dns_dnssec_sign(name, &rdataset, keys[i], - &inception, &expire, - mctx, &buffer, &sig_rdata)); - - /* Update the database and journal with the RRSIG. */ - /* XXX inefficient - will cause dataset merging */ - CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, - rdataset.ttl, &sig_rdata)); - dns_rdata_reset(&sig_rdata); - } - - failure: - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - return (result); -} - -/*% - * Update RRSIG and NSEC records affected by an update. The original - * update, including the SOA serial update but exluding the RRSIG & NSEC - * changes, is in "diff" and has already been applied to "newver" of "db". - * The database version prior to the update is "oldver". - * - * The necessary RRSIG and NSEC changes will be applied to "newver" - * and added (as a minimal diff) to "diff". - * - * The RRSIGs generated will be valid for 'sigvalidityinterval' seconds. - */ -static isc_result_t -update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, - dns_dbversion_t *oldver, dns_dbversion_t *newver, - dns_diff_t *diff, isc_uint32_t sigvalidityinterval) -{ - isc_result_t result; - dns_difftuple_t *t; - dns_diff_t diffnames; - dns_diff_t affected; - dns_diff_t sig_diff; - dns_diff_t nsec_diff; - dns_diff_t nsec_mindiff; - isc_boolean_t flag; - dst_key_t *zone_keys[MAXZONEKEYS]; - unsigned int nkeys = 0; - unsigned int i; - isc_stdtime_t now, inception, expire; - dns_ttl_t nsecttl; - dns_rdata_soa_t soa; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_t rdataset; - dns_dbnode_t *node = NULL; - isc_boolean_t check_ksk; - - dns_diff_init(client->mctx, &diffnames); - dns_diff_init(client->mctx, &affected); - - dns_diff_init(client->mctx, &sig_diff); - dns_diff_init(client->mctx, &nsec_diff); - dns_diff_init(client->mctx, &nsec_mindiff); - - result = find_zone_keys(zone, db, newver, client->mctx, - MAXZONEKEYS, zone_keys, &nkeys); - if (result != ISC_R_SUCCESS) { - update_log(client, zone, ISC_LOG_ERROR, - "could not get zone keys for secure dynamic update"); - goto failure; - } - - isc_stdtime_get(&now); - inception = now - 3600; /* Allow for some clock skew. */ - expire = now + sigvalidityinterval; - - /* - * Do we look at the KSK flag on the DNSKEY to determining which - * keys sign which RRsets? First check the zone option then - * check the keys flags to make sure atleast one has a ksk set - * and one doesn't. - */ - check_ksk = ISC_TF((dns_zone_getoptions(zone) & - DNS_ZONEOPT_UPDATECHECKKSK) != 0); - if (check_ksk) - check_ksk = ksk_sanity(db, newver); - - /* - * Get the NSEC's TTL from the SOA MINIMUM field. - */ - CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node)); - dns_rdataset_init(&rdataset); - CHECK(dns_db_findrdataset(db, node, newver, dns_rdatatype_soa, 0, - (isc_stdtime_t) 0, &rdataset, NULL)); - CHECK(dns_rdataset_first(&rdataset)); - dns_rdataset_current(&rdataset, &rdata); - CHECK(dns_rdata_tostruct(&rdata, &soa, NULL)); - nsecttl = soa.minimum; - dns_rdataset_disassociate(&rdataset); - dns_db_detachnode(db, &node); - - /* - * Find all RRsets directly affected by the update, and - * update their RRSIGs. Also build a list of names affected - * by the update in "diffnames". - */ - CHECK(dns_diff_sort(diff, temp_order)); - - t = ISC_LIST_HEAD(diff->tuples); - while (t != NULL) { - dns_name_t *name = &t->name; - /* Now "name" is a new, unique name affected by the update. */ - - CHECK(namelist_append_name(&diffnames, name)); - - while (t != NULL && dns_name_equal(&t->name, name)) { - dns_rdatatype_t type; - type = t->rdata.type; - - /* - * Now "name" and "type" denote a new unique RRset - * affected by the update. - */ - - /* Don't sign RRSIGs. */ - if (type == dns_rdatatype_rrsig) - goto skip; - - /* - * Delete all old RRSIGs covering this type, since they - * are all invalid when the signed RRset has changed. - * We may not be able to recreate all of them - tough. - */ - CHECK(delete_if(true_p, db, newver, name, - dns_rdatatype_rrsig, type, - NULL, &sig_diff)); - - /* - * If this RRset still exists after the update, - * add a new signature for it. - */ - CHECK(rrset_exists(db, newver, name, type, 0, &flag)); - if (flag) { - CHECK(add_sigs(db, newver, name, type, - &sig_diff, zone_keys, nkeys, - client->mctx, inception, - expire, check_ksk)); - } - skip: - /* Skip any other updates to the same RRset. */ - while (t != NULL && - dns_name_equal(&t->name, name) && - t->rdata.type == type) - { - t = ISC_LIST_NEXT(t, link); - } - } - } - - /* Remove orphaned NSECs and RRSIG NSECs. */ - for (t = ISC_LIST_HEAD(diffnames.tuples); - t != NULL; - t = ISC_LIST_NEXT(t, link)) - { - CHECK(non_nsec_rrset_exists(db, newver, &t->name, &flag)); - if (! flag) { - CHECK(delete_if(true_p, db, newver, &t->name, - dns_rdatatype_any, 0, - NULL, &sig_diff)); - } - } - - /* - * When a name is created or deleted, its predecessor needs to - * have its NSEC updated. - */ - for (t = ISC_LIST_HEAD(diffnames.tuples); - t != NULL; - t = ISC_LIST_NEXT(t, link)) - { - isc_boolean_t existed, exists; - dns_fixedname_t fixedname; - dns_name_t *prevname; - - dns_fixedname_init(&fixedname); - prevname = dns_fixedname_name(&fixedname); - - CHECK(name_exists(db, oldver, &t->name, &existed)); - CHECK(name_exists(db, newver, &t->name, &exists)); - if (exists == existed) - continue; - - /* - * Find the predecessor. - * When names become obscured or unobscured in this update - * transaction, we may find the wrong predecessor because - * the NSECs have not yet been updated to reflect the delegation - * change. This should not matter because in this case, - * the correct predecessor is either the delegation node or - * a newly unobscured node, and those nodes are on the - * "affected" list in any case. - */ - CHECK(next_active(client, zone, db, newver, - &t->name, prevname, ISC_FALSE)); - CHECK(namelist_append_name(&affected, prevname)); - } - - /* - * Find names potentially affected by delegation changes - * (obscured by adding an NS or DNAME, or unobscured by - * removing one). - */ - for (t = ISC_LIST_HEAD(diffnames.tuples); - t != NULL; - t = ISC_LIST_NEXT(t, link)) - { - isc_boolean_t ns_existed, dname_existed; - isc_boolean_t ns_exists, dname_exists; - - CHECK(rrset_exists(db, oldver, &t->name, dns_rdatatype_ns, 0, - &ns_existed)); - CHECK(rrset_exists(db, oldver, &t->name, dns_rdatatype_dname, 0, - &dname_existed)); - CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_ns, 0, - &ns_exists)); - CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_dname, 0, - &dname_exists)); - if ((ns_exists || dname_exists) == (ns_existed || dname_existed)) - continue; - /* - * There was a delegation change. Mark all subdomains - * of t->name as potentially needing a NSEC update. - */ - CHECK(namelist_append_subdomain(db, &t->name, &affected)); - } - - ISC_LIST_APPENDLIST(affected.tuples, diffnames.tuples, link); - INSIST(ISC_LIST_EMPTY(diffnames.tuples)); - - CHECK(uniqify_name_list(&affected)); - - /* - * Determine which names should have NSECs, and delete/create - * NSECs to make it so. We don't know the final NSEC targets yet, - * so we just create placeholder NSECs with arbitrary contents - * to indicate that their respective owner names should be part of - * the NSEC chain. - */ - for (t = ISC_LIST_HEAD(affected.tuples); - t != NULL; - t = ISC_LIST_NEXT(t, link)) - { - isc_boolean_t exists; - CHECK(name_exists(db, newver, &t->name, &exists)); - if (! exists) - continue; - CHECK(is_glue(db, newver, &t->name, &flag)); - if (flag) { - /* - * This name is obscured. Delete any - * existing NSEC record. - */ - CHECK(delete_if(true_p, db, newver, &t->name, - dns_rdatatype_nsec, 0, - NULL, &nsec_diff)); - } else { - /* - * This name is not obscured. It should have a NSEC. - */ - CHECK(rrset_exists(db, newver, &t->name, - dns_rdatatype_nsec, 0, &flag)); - if (! flag) - CHECK(add_placeholder_nsec(db, newver, &t->name, - diff)); - } - } - - /* - * Now we know which names are part of the NSEC chain. - * Make them all point at their correct targets. - */ - for (t = ISC_LIST_HEAD(affected.tuples); - t != NULL; - t = ISC_LIST_NEXT(t, link)) - { - CHECK(rrset_exists(db, newver, &t->name, - dns_rdatatype_nsec, 0, &flag)); - if (flag) { - /* - * There is a NSEC, but we don't know if it is correct. - * Delete it and create a correct one to be sure. - * If the update was unnecessary, the diff minimization - * will take care of eliminating it from the journal, - * IXFRs, etc. - * - * The RRSIG bit should always be set in the NSECs - * we generate, because they will all get RRSIG NSECs. - * (XXX what if the zone keys are missing?). - * Because the RRSIG NSECs have not necessarily been - * created yet, the correctness of the bit mask relies - * on the assumption that NSECs are only created if - * there is other data, and if there is other data, - * there are other RRSIGs. - */ - CHECK(add_nsec(client, zone, db, newver, &t->name, - nsecttl, &nsec_diff)); - } - } - - /* - * Minimize the set of NSEC updates so that we don't - * have to regenerate the RRSIG NSECs for NSECs that were - * replaced with identical ones. - */ - while ((t = ISC_LIST_HEAD(nsec_diff.tuples)) != NULL) { - ISC_LIST_UNLINK(nsec_diff.tuples, t, link); - dns_diff_appendminimal(&nsec_mindiff, &t); - } - - /* Update RRSIG NSECs. */ - for (t = ISC_LIST_HEAD(nsec_mindiff.tuples); - t != NULL; - t = ISC_LIST_NEXT(t, link)) - { - if (t->op == DNS_DIFFOP_DEL) { - CHECK(delete_if(true_p, db, newver, &t->name, - dns_rdatatype_rrsig, dns_rdatatype_nsec, - NULL, &sig_diff)); - } else if (t->op == DNS_DIFFOP_ADD) { - CHECK(add_sigs(db, newver, &t->name, dns_rdatatype_nsec, - &sig_diff, zone_keys, nkeys, - client->mctx, inception, expire, - check_ksk)); - } else { - INSIST(0); - } - } - - /* Record our changes for the journal. */ - while ((t = ISC_LIST_HEAD(sig_diff.tuples)) != NULL) { - ISC_LIST_UNLINK(sig_diff.tuples, t, link); - dns_diff_appendminimal(diff, &t); - } - while ((t = ISC_LIST_HEAD(nsec_mindiff.tuples)) != NULL) { - ISC_LIST_UNLINK(nsec_mindiff.tuples, t, link); - dns_diff_appendminimal(diff, &t); - } - - INSIST(ISC_LIST_EMPTY(sig_diff.tuples)); - INSIST(ISC_LIST_EMPTY(nsec_diff.tuples)); - INSIST(ISC_LIST_EMPTY(nsec_mindiff.tuples)); - - failure: - dns_diff_clear(&sig_diff); - dns_diff_clear(&nsec_diff); - dns_diff_clear(&nsec_mindiff); - - dns_diff_clear(&affected); - dns_diff_clear(&diffnames); - - for (i = 0; i < nkeys; i++) - dst_key_free(&zone_keys[i]); - - return (result); -} - - -/**************************************************************************/ -/*% - * The actual update code in all its glory. We try to follow - * the RFC2136 pseudocode as closely as possible. - */ - -static isc_result_t -send_update_event(ns_client_t *client, dns_zone_t *zone) { - isc_result_t result = ISC_R_SUCCESS; - update_event_t *event = NULL; - isc_task_t *zonetask = NULL; - ns_client_t *evclient; - - event = (update_event_t *) - isc_event_allocate(client->mctx, client, DNS_EVENT_UPDATE, - update_action, NULL, sizeof(*event)); - if (event == NULL) - FAIL(ISC_R_NOMEMORY); - event->zone = zone; - event->result = ISC_R_SUCCESS; - - evclient = NULL; - ns_client_attach(client, &evclient); - INSIST(client->nupdates == 0); - client->nupdates++; - event->ev_arg = evclient; - - dns_zone_gettask(zone, &zonetask); - isc_task_send(zonetask, ISC_EVENT_PTR(&event)); - - failure: - if (event != NULL) - isc_event_free(ISC_EVENT_PTR(&event)); - return (result); -} - -static void -respond(ns_client_t *client, isc_result_t result) { - isc_result_t msg_result; - - msg_result = dns_message_reply(client->message, ISC_TRUE); - if (msg_result != ISC_R_SUCCESS) - goto msg_failure; - client->message->rcode = dns_result_torcode(result); - - ns_client_send(client); - return; - - msg_failure: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_UPDATE, NS_LOGMODULE_UPDATE, - ISC_LOG_ERROR, - "could not create update response message: %s", - isc_result_totext(msg_result)); - ns_client_next(client, msg_result); -} - -void -ns_update_start(ns_client_t *client, isc_result_t sigresult) { - dns_message_t *request = client->message; - isc_result_t result; - dns_name_t *zonename; - dns_rdataset_t *zone_rdataset; - dns_zone_t *zone = NULL; - - /* - * Interpret the zone section. - */ - result = dns_message_firstname(request, DNS_SECTION_ZONE); - if (result != ISC_R_SUCCESS) - FAILC(DNS_R_FORMERR, - "update zone section empty"); - - /* - * The zone section must contain exactly one "question", and - * it must be of type SOA. - */ - zonename = NULL; - dns_message_currentname(request, DNS_SECTION_ZONE, &zonename); - zone_rdataset = ISC_LIST_HEAD(zonename->list); - if (zone_rdataset->type != dns_rdatatype_soa) - FAILC(DNS_R_FORMERR, - "update zone section contains non-SOA"); - if (ISC_LIST_NEXT(zone_rdataset, link) != NULL) - FAILC(DNS_R_FORMERR, - "update zone section contains multiple RRs"); - - /* The zone section must have exactly one name. */ - result = dns_message_nextname(request, DNS_SECTION_ZONE); - if (result != ISC_R_NOMORE) - FAILC(DNS_R_FORMERR, - "update zone section contains multiple RRs"); - - result = dns_zt_find(client->view->zonetable, zonename, 0, NULL, - &zone); - if (result != ISC_R_SUCCESS) - FAILC(DNS_R_NOTAUTH, - "not authoritative for update zone"); - - switch(dns_zone_gettype(zone)) { - case dns_zone_master: - /* - * We can now fail due to a bad signature as we now know - * that we are the master. - */ - if (sigresult != ISC_R_SUCCESS) - FAIL(sigresult); - CHECK(send_update_event(client, zone)); - break; - case dns_zone_slave: - CHECK(checkupdateacl(client, dns_zone_getforwardacl(zone), - "update forwarding", zonename, ISC_TRUE)); - CHECK(send_forward_event(client, zone)); - break; - default: - FAILC(DNS_R_NOTAUTH, - "not authoritative for update zone"); - } - return; - - failure: - /* - * We failed without having sent an update event to the zone. - * We are still in the client task context, so we can - * simply give an error response without switching tasks. - */ - respond(client, result); - if (zone != NULL) - dns_zone_detach(&zone); -} - -/*% - * DS records are not allowed to exist without corresponding NS records, - * draft-ietf-dnsext-delegation-signer-11.txt, 2.2 Protocol Change, - * "DS RRsets MUST NOT appear at non-delegation points or at a zone's apex". - */ - -static isc_result_t -remove_orphaned_ds(dns_db_t *db, dns_dbversion_t *newver, dns_diff_t *diff) { - isc_result_t result; - isc_boolean_t ns_exists, ds_exists; - dns_difftuple_t *t; - - for (t = ISC_LIST_HEAD(diff->tuples); - t != NULL; - t = ISC_LIST_NEXT(t, link)) { - if (t->op != DNS_DIFFOP_ADD || - t->rdata.type != dns_rdatatype_ns) - continue; - CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_ns, 0, - &ns_exists)); - if (ns_exists) - continue; - CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_ds, 0, - &ds_exists)); - if (!ds_exists) - continue; - CHECK(delete_if(true_p, db, newver, &t->name, - dns_rdatatype_ds, 0, NULL, diff)); - } - return (ISC_R_SUCCESS); - - failure: - return (result); -} - -/* - * This implements the post load integrity checks for mx records. - */ -static isc_result_t -check_mx(ns_client_t *client, dns_zone_t *zone, - dns_db_t *db, dns_dbversion_t *newver, dns_diff_t *diff) -{ - char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123.")]; - char ownerbuf[DNS_NAME_FORMATSIZE]; - char namebuf[DNS_NAME_FORMATSIZE]; - char altbuf[DNS_NAME_FORMATSIZE]; - dns_difftuple_t *t; - dns_fixedname_t fixed; - dns_name_t *foundname; - dns_rdata_mx_t mx; - dns_rdata_t rdata; - isc_boolean_t ok = ISC_TRUE; - isc_boolean_t isaddress; - isc_result_t result; - struct in6_addr addr6; - struct in_addr addr; - unsigned int options; - - dns_fixedname_init(&fixed); - foundname = dns_fixedname_name(&fixed); - dns_rdata_init(&rdata); - options = dns_zone_getoptions(zone); - - for (t = ISC_LIST_HEAD(diff->tuples); - t != NULL; - t = ISC_LIST_NEXT(t, link)) { - if (t->op != DNS_DIFFOP_ADD || - t->rdata.type != dns_rdatatype_mx) - continue; - - result = dns_rdata_tostruct(&t->rdata, &mx, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - /* - * Check if we will error out if we attempt to reload the - * zone. - */ - dns_name_format(&mx.mx, namebuf, sizeof(namebuf)); - dns_name_format(&t->name, ownerbuf, sizeof(ownerbuf)); - isaddress = ISC_FALSE; - if ((options & DNS_RDATA_CHECKMX) != 0 && - strlcpy(tmp, namebuf, sizeof(tmp)) < sizeof(tmp)) { - if (tmp[strlen(tmp) - 1] == '.') - tmp[strlen(tmp) - 1] = '\0'; - if (inet_aton(tmp, &addr) == 1 || - inet_pton(AF_INET6, tmp, &addr6) == 1) - isaddress = ISC_TRUE; - } - - if (isaddress && (options & DNS_RDATA_CHECKMXFAIL) != 0) { - update_log(client, zone, ISC_LOG_ERROR, - "%s/MX: '%s': %s", - ownerbuf, namebuf, - dns_result_totext(DNS_R_MXISADDRESS)); - ok = ISC_FALSE; - } else if (isaddress) { - update_log(client, zone, ISC_LOG_WARNING, - "%s/MX: warning: '%s': %s", - ownerbuf, namebuf, - dns_result_totext(DNS_R_MXISADDRESS)); - } - - /* - * Check zone integrity checks. - */ - if ((options & DNS_ZONEOPT_CHECKINTEGRITY) == 0) - continue; - result = dns_db_find(db, &mx.mx, newver, dns_rdatatype_a, - 0, 0, NULL, foundname, NULL, NULL); - if (result == ISC_R_SUCCESS) - continue; - - if (result == DNS_R_NXRRSET) { - result = dns_db_find(db, &mx.mx, newver, - dns_rdatatype_aaaa, - 0, 0, NULL, foundname, - NULL, NULL); - if (result == ISC_R_SUCCESS) - continue; - } - - if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN) { - update_log(client, zone, ISC_LOG_ERROR, - "%s/MX '%s' has no address records " - "(A or AAAA)", ownerbuf, namebuf); - ok = ISC_FALSE; - } else if (result == DNS_R_CNAME) { - update_log(client, zone, ISC_LOG_ERROR, - "%s/MX '%s' is a CNAME (illegal)", - ownerbuf, namebuf); - ok = ISC_FALSE; - } else if (result == DNS_R_DNAME) { - dns_name_format(foundname, altbuf, sizeof altbuf); - update_log(client, zone, ISC_LOG_ERROR, - "%s/MX '%s' is below a DNAME '%s' (illegal)", - ownerbuf, namebuf, altbuf); - ok = ISC_FALSE; - } - } - return (ok ? ISC_R_SUCCESS : DNS_R_REFUSED); -} - -static void -update_action(isc_task_t *task, isc_event_t *event) { - update_event_t *uev = (update_event_t *) event; - dns_zone_t *zone = uev->zone; - ns_client_t *client = (ns_client_t *)event->ev_arg; - - isc_result_t result; - dns_db_t *db = NULL; - dns_dbversion_t *oldver = NULL; - dns_dbversion_t *ver = NULL; - dns_diff_t diff; /* Pending updates. */ - dns_diff_t temp; /* Pending RR existence assertions. */ - isc_boolean_t soa_serial_changed = ISC_FALSE; - isc_mem_t *mctx = client->mctx; - dns_rdatatype_t covers; - dns_message_t *request = client->message; - dns_rdataclass_t zoneclass; - dns_name_t *zonename; - dns_ssutable_t *ssutable = NULL; - dns_fixedname_t tmpnamefixed; - dns_name_t *tmpname = NULL; - unsigned int options; - - INSIST(event->ev_type == DNS_EVENT_UPDATE); - - dns_diff_init(mctx, &diff); - dns_diff_init(mctx, &temp); - - CHECK(dns_zone_getdb(zone, &db)); - zonename = dns_db_origin(db); - zoneclass = dns_db_class(db); - dns_zone_getssutable(zone, &ssutable); - dns_db_currentversion(db, &oldver); - CHECK(dns_db_newversion(db, &ver)); - - /* - * Check prerequisites. - */ - - for (result = dns_message_firstname(request, DNS_SECTION_PREREQUISITE); - result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_PREREQUISITE)) - { - dns_name_t *name = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_ttl_t ttl; - dns_rdataclass_t update_class; - isc_boolean_t flag; - - get_current_rr(request, DNS_SECTION_PREREQUISITE, zoneclass, - &name, &rdata, &covers, &ttl, &update_class); - - if (ttl != 0) - FAILC(DNS_R_FORMERR, "prerequisite TTL is not zero"); - - if (! dns_name_issubdomain(name, zonename)) - FAILN(DNS_R_NOTZONE, name, - "prerequisite name is out of zone"); - - if (update_class == dns_rdataclass_any) { - if (rdata.length != 0) - FAILC(DNS_R_FORMERR, - "class ANY prerequisite " - "RDATA is not empty"); - if (rdata.type == dns_rdatatype_any) { - CHECK(name_exists(db, ver, name, &flag)); - if (! flag) { - FAILN(DNS_R_NXDOMAIN, name, - "'name in use' prerequisite " - "not satisfied"); - } - } else { - CHECK(rrset_exists(db, ver, name, - rdata.type, covers, &flag)); - if (! flag) { - /* RRset does not exist. */ - FAILNT(DNS_R_NXRRSET, name, rdata.type, - "'rrset exists (value independent)' " - "prerequisite not satisfied"); - } - } - } else if (update_class == dns_rdataclass_none) { - if (rdata.length != 0) - FAILC(DNS_R_FORMERR, - "class NONE prerequisite " - "RDATA is not empty"); - if (rdata.type == dns_rdatatype_any) { - CHECK(name_exists(db, ver, name, &flag)); - if (flag) { - FAILN(DNS_R_YXDOMAIN, name, - "'name not in use' prerequisite " - "not satisfied"); - } - } else { - CHECK(rrset_exists(db, ver, name, - rdata.type, covers, &flag)); - if (flag) { - /* RRset exists. */ - FAILNT(DNS_R_YXRRSET, name, rdata.type, - "'rrset does not exist' " - "prerequisite not satisfied"); - } - } - } else if (update_class == zoneclass) { - /* "temp += rr;" */ - result = temp_append(&temp, name, &rdata); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "temp entry creation failed: %s", - dns_result_totext(result)); - FAIL(ISC_R_UNEXPECTED); - } - } else { - FAILC(DNS_R_FORMERR, "malformed prerequisite"); - } - } - if (result != ISC_R_NOMORE) - FAIL(result); - - - /* - * Perform the final check of the "rrset exists (value dependent)" - * prerequisites. - */ - if (ISC_LIST_HEAD(temp.tuples) != NULL) { - dns_rdatatype_t type; - - /* - * Sort the prerequisite records by owner name, - * type, and rdata. - */ - result = dns_diff_sort(&temp, temp_order); - if (result != ISC_R_SUCCESS) - FAILC(result, "'RRset exists (value dependent)' " - "prerequisite not satisfied"); - - dns_fixedname_init(&tmpnamefixed); - tmpname = dns_fixedname_name(&tmpnamefixed); - result = temp_check(mctx, &temp, db, ver, tmpname, &type); - if (result != ISC_R_SUCCESS) - FAILNT(result, tmpname, type, - "'RRset exists (value dependent)' " - "prerequisite not satisfied"); - } - - update_log(client, zone, LOGLEVEL_DEBUG, - "prerequisites are OK"); - - /* - * Check Requestor's Permissions. It seems a bit silly to do this - * only after prerequisite testing, but that is what RFC2136 says. - */ - result = ISC_R_SUCCESS; - if (ssutable == NULL) - CHECK(checkupdateacl(client, dns_zone_getupdateacl(zone), - "update", zonename, ISC_FALSE)); - else if (client->signer == NULL) - CHECK(checkupdateacl(client, NULL, "update", zonename, - ISC_FALSE)); - - if (dns_zone_getupdatedisabled(zone)) - FAILC(DNS_R_REFUSED, "dynamic update temporarily disabled"); - - /* - * Perform the Update Section Prescan. - */ - - for (result = dns_message_firstname(request, DNS_SECTION_UPDATE); - result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_UPDATE)) - { - dns_name_t *name = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_ttl_t ttl; - dns_rdataclass_t update_class; - get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, - &name, &rdata, &covers, &ttl, &update_class); - - if (! dns_name_issubdomain(name, zonename)) - FAILC(DNS_R_NOTZONE, - "update RR is outside zone"); - if (update_class == zoneclass) { - /* - * Check for meta-RRs. The RFC2136 pseudocode says - * check for ANY|AXFR|MAILA|MAILB, but the text adds - * "or any other QUERY metatype" - */ - if (dns_rdatatype_ismeta(rdata.type)) { - FAILC(DNS_R_FORMERR, - "meta-RR in update"); - } - result = dns_zone_checknames(zone, name, &rdata); - if (result != ISC_R_SUCCESS) - FAIL(DNS_R_REFUSED); - } else if (update_class == dns_rdataclass_any) { - if (ttl != 0 || rdata.length != 0 || - (dns_rdatatype_ismeta(rdata.type) && - rdata.type != dns_rdatatype_any)) - FAILC(DNS_R_FORMERR, - "meta-RR in update"); - } else if (update_class == dns_rdataclass_none) { - if (ttl != 0 || - dns_rdatatype_ismeta(rdata.type)) - FAILC(DNS_R_FORMERR, - "meta-RR in update"); - } else { - update_log(client, zone, ISC_LOG_WARNING, - "update RR has incorrect class %d", - update_class); - FAIL(DNS_R_FORMERR); - } - /* - * draft-ietf-dnsind-simple-secure-update-01 says - * "Unlike traditional dynamic update, the client - * is forbidden from updating NSEC records." - */ - if (dns_db_issecure(db)) { - if (rdata.type == dns_rdatatype_nsec) { - FAILC(DNS_R_REFUSED, - "explicit NSEC updates are not allowed " - "in secure zones"); - } - else if (rdata.type == dns_rdatatype_rrsig) { - FAILC(DNS_R_REFUSED, - "explicit RRSIG updates are currently not " - "supported in secure zones"); - } - } - - if (ssutable != NULL && client->signer != NULL) { - if (rdata.type != dns_rdatatype_any) { - if (!dns_ssutable_checkrules(ssutable, - client->signer, - name, rdata.type)) - FAILC(DNS_R_REFUSED, - "rejected by secure update"); - } - else { - if (!ssu_checkall(db, ver, name, ssutable, - client->signer)) - FAILC(DNS_R_REFUSED, - "rejected by secure update"); - } - } - } - if (result != ISC_R_NOMORE) - FAIL(result); - - update_log(client, zone, LOGLEVEL_DEBUG, - "update section prescan OK"); - - /* - * Process the Update Section. - */ - - options = dns_zone_getoptions(zone); - for (result = dns_message_firstname(request, DNS_SECTION_UPDATE); - result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_UPDATE)) - { - dns_name_t *name = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_ttl_t ttl; - dns_rdataclass_t update_class; - isc_boolean_t flag; - - get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, - &name, &rdata, &covers, &ttl, &update_class); - - if (update_class == zoneclass) { - - /* - * RFC1123 doesn't allow MF and MD in master zones. */ - if (rdata.type == dns_rdatatype_md || - rdata.type == dns_rdatatype_mf) { - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - - dns_rdatatype_format(rdata.type, typebuf, - sizeof(typebuf)); - update_log(client, zone, LOGLEVEL_PROTOCOL, - "attempt to add %s ignored", - typebuf); - continue; - } - if (rdata.type == dns_rdatatype_ns && - dns_name_iswildcard(name)) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to add wildcard NS record" - "ignored"); - continue; - } - if (rdata.type == dns_rdatatype_cname) { - CHECK(cname_incompatible_rrset_exists(db, ver, - name, - &flag)); - if (flag) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to add CNAME " - "alongside non-CNAME " - "ignored"); - continue; - } - } else { - CHECK(rrset_exists(db, ver, name, - dns_rdatatype_cname, 0, - &flag)); - if (flag && - ! dns_rdatatype_isdnssec(rdata.type)) - { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to add non-CNAME " - "alongside CNAME ignored"); - continue; - } - } - if (rdata.type == dns_rdatatype_soa) { - isc_boolean_t ok; - CHECK(rrset_exists(db, ver, name, - dns_rdatatype_soa, 0, - &flag)); - if (! flag) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to create 2nd " - "SOA ignored"); - continue; - } - CHECK(check_soa_increment(db, ver, &rdata, - &ok)); - if (! ok) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "SOA update failed to " - "increment serial, " - "ignoring it"); - continue; - } - soa_serial_changed = ISC_TRUE; - } - if ((options & DNS_ZONEOPT_CHECKWILDCARD) != 0 && - dns_name_internalwildcard(name)) { - char namestr[DNS_NAME_FORMATSIZE]; - dns_name_format(name, namestr, - sizeof(namestr)); - update_log(client, zone, LOGLEVEL_PROTOCOL, - "warning: ownername '%s' contains " - "a non-terminal wildcard", namestr); - } - - if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { - char namestr[DNS_NAME_FORMATSIZE]; - char typestr[DNS_RDATATYPE_FORMATSIZE]; - dns_name_format(name, namestr, - sizeof(namestr)); - dns_rdatatype_format(rdata.type, typestr, - sizeof(typestr)); - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "adding an RR at '%s' %s", - namestr, typestr); - } - - /* Prepare the affected RRset for the addition. */ - { - add_rr_prepare_ctx_t ctx; - ctx.db = db; - ctx.ver = ver; - ctx.diff = &diff; - ctx.name = name; - ctx.update_rr = &rdata; - ctx.update_rr_ttl = ttl; - ctx.ignore_add = ISC_FALSE; - dns_diff_init(mctx, &ctx.del_diff); - dns_diff_init(mctx, &ctx.add_diff); - CHECK(foreach_rr(db, ver, name, rdata.type, - covers, add_rr_prepare_action, - &ctx)); - - if (ctx.ignore_add) { - dns_diff_clear(&ctx.del_diff); - dns_diff_clear(&ctx.add_diff); - } else { - CHECK(do_diff(&ctx.del_diff, db, ver, &diff)); - CHECK(do_diff(&ctx.add_diff, db, ver, &diff)); - CHECK(update_one_rr(db, ver, &diff, - DNS_DIFFOP_ADD, - name, ttl, &rdata)); - } - } - } else if (update_class == dns_rdataclass_any) { - if (rdata.type == dns_rdatatype_any) { - if (isc_log_wouldlog(ns_g_lctx, - LOGLEVEL_PROTOCOL)) - { - char namestr[DNS_NAME_FORMATSIZE]; - dns_name_format(name, namestr, - sizeof(namestr)); - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "delete all rrsets from " - "name '%s'", namestr); - } - if (dns_name_equal(name, zonename)) { - CHECK(delete_if(type_not_soa_nor_ns_p, - db, ver, name, - dns_rdatatype_any, 0, - &rdata, &diff)); - } else { - CHECK(delete_if(type_not_dnssec, - db, ver, name, - dns_rdatatype_any, 0, - &rdata, &diff)); - } - } else if (dns_name_equal(name, zonename) && - (rdata.type == dns_rdatatype_soa || - rdata.type == dns_rdatatype_ns)) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to delete all SOA " - "or NS records ignored"); - continue; - } else { - if (isc_log_wouldlog(ns_g_lctx, - LOGLEVEL_PROTOCOL)) - { - char namestr[DNS_NAME_FORMATSIZE]; - char typestr[DNS_RDATATYPE_FORMATSIZE]; - dns_name_format(name, namestr, - sizeof(namestr)); - dns_rdatatype_format(rdata.type, - typestr, - sizeof(typestr)); - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "deleting rrset at '%s' %s", - namestr, typestr); - } - CHECK(delete_if(true_p, db, ver, name, - rdata.type, covers, &rdata, - &diff)); - } - } else if (update_class == dns_rdataclass_none) { - /* - * The (name == zonename) condition appears in - * RFC2136 3.4.2.4 but is missing from the pseudocode. - */ - if (dns_name_equal(name, zonename)) { - if (rdata.type == dns_rdatatype_soa) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to delete SOA " - "ignored"); - continue; - } - if (rdata.type == dns_rdatatype_ns) { - int count; - CHECK(rr_count(db, ver, name, - dns_rdatatype_ns, - 0, &count)); - if (count == 1) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to " - "delete last " - "NS ignored"); - continue; - } - } - } - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "deleting an RR"); - CHECK(delete_if(rr_equal_p, db, ver, name, - rdata.type, covers, &rdata, &diff)); - } - } - if (result != ISC_R_NOMORE) - FAIL(result); - - /* - * If any changes were made, increment the SOA serial number, - * update RRSIGs and NSECs (if zone is secure), and write the update - * to the journal. - */ - if (! ISC_LIST_EMPTY(diff.tuples)) { - char *journalfile; - dns_journal_t *journal; - - /* - * Increment the SOA serial, but only if it was not - * changed as a result of an update operation. - */ - if (! soa_serial_changed) { - CHECK(increment_soa_serial(db, ver, &diff, mctx)); - } - - CHECK(check_mx(client, zone, db, ver, &diff)); - - CHECK(remove_orphaned_ds(db, ver, &diff)); - - if (dns_db_issecure(db)) { - result = update_signatures(client, zone, db, oldver, - ver, &diff, - dns_zone_getsigvalidityinterval(zone)); - if (result != ISC_R_SUCCESS) { - update_log(client, zone, - ISC_LOG_ERROR, - "RRSIG/NSEC update failed: %s", - isc_result_totext(result)); - goto failure; - } - } - - journalfile = dns_zone_getjournal(zone); - if (journalfile != NULL) { - update_log(client, zone, LOGLEVEL_DEBUG, - "writing journal %s", journalfile); - - journal = NULL; - result = dns_journal_open(mctx, journalfile, - ISC_TRUE, &journal); - if (result != ISC_R_SUCCESS) - FAILS(result, "journal open failed"); - - result = dns_journal_write_transaction(journal, &diff); - if (result != ISC_R_SUCCESS) { - dns_journal_destroy(&journal); - FAILS(result, "journal write failed"); - } - - dns_journal_destroy(&journal); - } - - /* - * XXXRTH Just a note that this committing code will have - * to change to handle databases that need two-phase - * commit, but this isn't a priority. - */ - update_log(client, zone, LOGLEVEL_DEBUG, - "committing update transaction"); - dns_db_closeversion(db, &ver, ISC_TRUE); - - /* - * Mark the zone as dirty so that it will be written to disk. - */ - dns_zone_markdirty(zone); - - /* - * Notify slaves of the change we just made. - */ - dns_zone_notify(zone); - } else { - update_log(client, zone, LOGLEVEL_DEBUG, "redundant request"); - dns_db_closeversion(db, &ver, ISC_TRUE); - } - result = ISC_R_SUCCESS; - goto common; - - failure: - /* - * The reason for failure should have been logged at this point. - */ - if (ver != NULL) { - update_log(client, zone, LOGLEVEL_DEBUG, - "rolling back"); - dns_db_closeversion(db, &ver, ISC_FALSE); - } - - common: - dns_diff_clear(&temp); - dns_diff_clear(&diff); - - if (oldver != NULL) - dns_db_closeversion(db, &oldver, ISC_FALSE); - - if (db != NULL) - dns_db_detach(&db); - - if (ssutable != NULL) - dns_ssutable_detach(&ssutable); - - if (zone != NULL) - dns_zone_detach(&zone); - - isc_task_detach(&task); - uev->result = result; - uev->ev_type = DNS_EVENT_UPDATEDONE; - uev->ev_action = updatedone_action; - isc_task_send(client->task, &event); - INSIST(event == NULL); -} - -static void -updatedone_action(isc_task_t *task, isc_event_t *event) { - update_event_t *uev = (update_event_t *) event; - ns_client_t *client = (ns_client_t *) event->ev_arg; - - UNUSED(task); - - INSIST(event->ev_type == DNS_EVENT_UPDATEDONE); - INSIST(task == client->task); - - INSIST(client->nupdates > 0); - client->nupdates--; - respond(client, uev->result); - isc_event_free(&event); - ns_client_detach(&client); -} - -/*% - * Update forwarding support. - */ - -static void -forward_fail(isc_task_t *task, isc_event_t *event) { - ns_client_t *client = (ns_client_t *)event->ev_arg; - - UNUSED(task); - - INSIST(client->nupdates > 0); - client->nupdates--; - respond(client, DNS_R_SERVFAIL); - isc_event_free(&event); - ns_client_detach(&client); -} - - -static void -forward_callback(void *arg, isc_result_t result, dns_message_t *answer) { - update_event_t *uev = arg; - ns_client_t *client = uev->ev_arg; - - if (result != ISC_R_SUCCESS) { - INSIST(answer == NULL); - uev->ev_type = DNS_EVENT_UPDATEDONE; - uev->ev_action = forward_fail; - } else { - uev->ev_type = DNS_EVENT_UPDATEDONE; - uev->ev_action = forward_done; - uev->answer = answer; - } - isc_task_send(client->task, ISC_EVENT_PTR(&uev)); -} - -static void -forward_done(isc_task_t *task, isc_event_t *event) { - update_event_t *uev = (update_event_t *) event; - ns_client_t *client = (ns_client_t *)event->ev_arg; - - UNUSED(task); - - INSIST(client->nupdates > 0); - client->nupdates--; - ns_client_sendraw(client, uev->answer); - dns_message_destroy(&uev->answer); - isc_event_free(&event); - ns_client_detach(&client); -} - -static void -forward_action(isc_task_t *task, isc_event_t *event) { - update_event_t *uev = (update_event_t *) event; - dns_zone_t *zone = uev->zone; - ns_client_t *client = (ns_client_t *)event->ev_arg; - isc_result_t result; - - result = dns_zone_forwardupdate(zone, client->message, - forward_callback, event); - if (result != ISC_R_SUCCESS) { - uev->ev_type = DNS_EVENT_UPDATEDONE; - uev->ev_action = forward_fail; - isc_task_send(client->task, &event); - } - dns_zone_detach(&zone); - isc_task_detach(&task); -} - -static isc_result_t -send_forward_event(ns_client_t *client, dns_zone_t *zone) { - isc_result_t result = ISC_R_SUCCESS; - update_event_t *event = NULL; - isc_task_t *zonetask = NULL; - ns_client_t *evclient; - - event = (update_event_t *) - isc_event_allocate(client->mctx, client, DNS_EVENT_UPDATE, - forward_action, NULL, sizeof(*event)); - if (event == NULL) - FAIL(ISC_R_NOMEMORY); - event->zone = zone; - event->result = ISC_R_SUCCESS; - - evclient = NULL; - ns_client_attach(client, &evclient); - INSIST(client->nupdates == 0); - client->nupdates++; - event->ev_arg = evclient; - - dns_zone_gettask(zone, &zonetask); - isc_task_send(zonetask, ISC_EVENT_PTR(&event)); - - failure: - if (event != NULL) - isc_event_free(ISC_EVENT_PTR(&event)); - return (result); -} diff --git a/contrib/bind9/bin/named/xfrout.c b/contrib/bind9/bin/named/xfrout.c deleted file mode 100644 index 9fe90a2..0000000 --- a/contrib/bind9/bin/named/xfrout.c +++ /dev/null @@ -1,1810 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: xfrout.c,v 1.115.18.8 2006/03/05 23:58:51 marka Exp $ */ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#ifdef DLZ -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/*! \file - * \brief - * Outgoing AXFR and IXFR. - */ - -/* - * TODO: - * - IXFR over UDP - */ - -#define XFROUT_COMMON_LOGARGS \ - ns_g_lctx, DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT - -#define XFROUT_PROTOCOL_LOGARGS \ - XFROUT_COMMON_LOGARGS, ISC_LOG_INFO - -#define XFROUT_DEBUG_LOGARGS(n) \ - XFROUT_COMMON_LOGARGS, ISC_LOG_DEBUG(n) - -#define XFROUT_RR_LOGARGS \ - XFROUT_COMMON_LOGARGS, XFROUT_RR_LOGLEVEL - -#define XFROUT_RR_LOGLEVEL ISC_LOG_DEBUG(8) - -/*% - * Fail unconditionally and log as a client error. - * The test against ISC_R_SUCCESS is there to keep the Solaris compiler - * from complaining about "end-of-loop code not reached". - */ -#define FAILC(code, msg) \ - do { \ - result = (code); \ - ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \ - NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \ - "bad zone transfer request: %s (%s)", \ - msg, isc_result_totext(code)); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -#define FAILQ(code, msg, question, rdclass) \ - do { \ - char _buf1[DNS_NAME_FORMATSIZE]; \ - char _buf2[DNS_RDATACLASS_FORMATSIZE]; \ - result = (code); \ - dns_name_format(question, _buf1, sizeof(_buf1)); \ - dns_rdataclass_format(rdclass, _buf2, sizeof(_buf2)); \ - ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \ - NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \ - "bad zone transfer request: '%s/%s': %s (%s)", \ - _buf1, _buf2, msg, isc_result_totext(code)); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -/**************************************************************************/ -/*% - * A db_rr_iterator_t is an iterator that iterates over an entire database, - * returning one RR at a time, in some arbitrary order. - */ - -typedef struct db_rr_iterator db_rr_iterator_t; - -/*% db_rr_iterator structure */ -struct db_rr_iterator { - isc_result_t result; - dns_db_t *db; - dns_dbiterator_t *dbit; - dns_dbversion_t *ver; - isc_stdtime_t now; - dns_dbnode_t *node; - dns_fixedname_t fixedname; - dns_rdatasetiter_t *rdatasetit; - dns_rdataset_t rdataset; - dns_rdata_t rdata; -}; - -static isc_result_t -db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver, - isc_stdtime_t now); - -static isc_result_t -db_rr_iterator_first(db_rr_iterator_t *it); - -static isc_result_t -db_rr_iterator_next(db_rr_iterator_t *it); - -static void -db_rr_iterator_current(db_rr_iterator_t *it, dns_name_t **name, - isc_uint32_t *ttl, dns_rdata_t **rdata); - -static void -db_rr_iterator_destroy(db_rr_iterator_t *it); - -static isc_result_t -db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver, - isc_stdtime_t now) -{ - isc_result_t result; - it->db = db; - it->dbit = NULL; - it->ver = ver; - it->now = now; - it->node = NULL; - result = dns_db_createiterator(it->db, ISC_FALSE, &it->dbit); - if (result != ISC_R_SUCCESS) - return (result); - it->rdatasetit = NULL; - dns_rdata_init(&it->rdata); - dns_rdataset_init(&it->rdataset); - dns_fixedname_init(&it->fixedname); - INSIST(! dns_rdataset_isassociated(&it->rdataset)); - it->result = ISC_R_SUCCESS; - return (it->result); -} - -static isc_result_t -db_rr_iterator_first(db_rr_iterator_t *it) { - it->result = dns_dbiterator_first(it->dbit); - /* - * The top node may be empty when out of zone glue exists. - * Walk the tree to find the first node with data. - */ - while (it->result == ISC_R_SUCCESS) { - it->result = dns_dbiterator_current(it->dbit, &it->node, - dns_fixedname_name(&it->fixedname)); - if (it->result != ISC_R_SUCCESS) - return (it->result); - - it->result = dns_db_allrdatasets(it->db, it->node, - it->ver, it->now, - &it->rdatasetit); - if (it->result != ISC_R_SUCCESS) - return (it->result); - - it->result = dns_rdatasetiter_first(it->rdatasetit); - if (it->result != ISC_R_SUCCESS) { - /* - * This node is empty. Try next node. - */ - dns_rdatasetiter_destroy(&it->rdatasetit); - dns_db_detachnode(it->db, &it->node); - it->result = dns_dbiterator_next(it->dbit); - continue; - } - dns_rdatasetiter_current(it->rdatasetit, &it->rdataset); - it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER; - it->result = dns_rdataset_first(&it->rdataset); - return (it->result); - } - return (it->result); -} - - -static isc_result_t -db_rr_iterator_next(db_rr_iterator_t *it) { - if (it->result != ISC_R_SUCCESS) - return (it->result); - - INSIST(it->dbit != NULL); - INSIST(it->node != NULL); - INSIST(it->rdatasetit != NULL); - - it->result = dns_rdataset_next(&it->rdataset); - if (it->result == ISC_R_NOMORE) { - dns_rdataset_disassociate(&it->rdataset); - it->result = dns_rdatasetiter_next(it->rdatasetit); - /* - * The while loop body is executed more than once - * only when an empty dbnode needs to be skipped. - */ - while (it->result == ISC_R_NOMORE) { - dns_rdatasetiter_destroy(&it->rdatasetit); - dns_db_detachnode(it->db, &it->node); - it->result = dns_dbiterator_next(it->dbit); - if (it->result == ISC_R_NOMORE) { - /* We are at the end of the entire database. */ - return (it->result); - } - if (it->result != ISC_R_SUCCESS) - return (it->result); - it->result = dns_dbiterator_current(it->dbit, - &it->node, - dns_fixedname_name(&it->fixedname)); - if (it->result != ISC_R_SUCCESS) - return (it->result); - it->result = dns_db_allrdatasets(it->db, it->node, - it->ver, it->now, - &it->rdatasetit); - if (it->result != ISC_R_SUCCESS) - return (it->result); - it->result = dns_rdatasetiter_first(it->rdatasetit); - } - if (it->result != ISC_R_SUCCESS) - return (it->result); - dns_rdatasetiter_current(it->rdatasetit, &it->rdataset); - it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER; - it->result = dns_rdataset_first(&it->rdataset); - if (it->result != ISC_R_SUCCESS) - return (it->result); - } - return (it->result); -} - -static void -db_rr_iterator_pause(db_rr_iterator_t *it) { - RUNTIME_CHECK(dns_dbiterator_pause(it->dbit) == ISC_R_SUCCESS); -} - -static void -db_rr_iterator_destroy(db_rr_iterator_t *it) { - if (dns_rdataset_isassociated(&it->rdataset)) - dns_rdataset_disassociate(&it->rdataset); - if (it->rdatasetit != NULL) - dns_rdatasetiter_destroy(&it->rdatasetit); - if (it->node != NULL) - dns_db_detachnode(it->db, &it->node); - dns_dbiterator_destroy(&it->dbit); -} - -static void -db_rr_iterator_current(db_rr_iterator_t *it, dns_name_t **name, - isc_uint32_t *ttl, dns_rdata_t **rdata) -{ - REQUIRE(name != NULL && *name == NULL); - REQUIRE(it->result == ISC_R_SUCCESS); - *name = dns_fixedname_name(&it->fixedname); - *ttl = it->rdataset.ttl; - dns_rdata_reset(&it->rdata); - dns_rdataset_current(&it->rdataset, &it->rdata); - *rdata = &it->rdata; -} - -/**************************************************************************/ - -/*% Log an RR (for debugging) */ - -static void -log_rr(dns_name_t *name, dns_rdata_t *rdata, isc_uint32_t ttl) { - isc_result_t result; - isc_buffer_t buf; - char mem[2000]; - dns_rdatalist_t rdl; - dns_rdataset_t rds; - dns_rdata_t rd = DNS_RDATA_INIT; - - rdl.type = rdata->type; - rdl.rdclass = rdata->rdclass; - rdl.ttl = ttl; - ISC_LIST_INIT(rdl.rdata); - ISC_LINK_INIT(&rdl, link); - dns_rdataset_init(&rds); - dns_rdata_init(&rd); - dns_rdata_clone(rdata, &rd); - ISC_LIST_APPEND(rdl.rdata, &rd, link); - RUNTIME_CHECK(dns_rdatalist_tordataset(&rdl, &rds) == ISC_R_SUCCESS); - - isc_buffer_init(&buf, mem, sizeof(mem)); - result = dns_rdataset_totext(&rds, name, - ISC_FALSE, ISC_FALSE, &buf); - - /* - * We could use xfrout_log(), but that would produce - * very long lines with a repetitive prefix. - */ - if (result == ISC_R_SUCCESS) { - /* - * Get rid of final newline. - */ - INSIST(buf.used >= 1 && - ((char *) buf.base)[buf.used - 1] == '\n'); - buf.used--; - - isc_log_write(XFROUT_RR_LOGARGS, "%.*s", - (int)isc_buffer_usedlength(&buf), - (char *)isc_buffer_base(&buf)); - } else { - isc_log_write(XFROUT_RR_LOGARGS, ""); - } -} - -/**************************************************************************/ -/* - * An 'rrstream_t' is a polymorphic iterator that returns - * a stream of resource records. There are multiple implementations, - * e.g. for generating AXFR and IXFR records streams. - */ - -typedef struct rrstream_methods rrstream_methods_t; - -typedef struct rrstream { - isc_mem_t *mctx; - rrstream_methods_t *methods; -} rrstream_t; - -struct rrstream_methods { - isc_result_t (*first)(rrstream_t *); - isc_result_t (*next)(rrstream_t *); - void (*current)(rrstream_t *, - dns_name_t **, - isc_uint32_t *, - dns_rdata_t **); - void (*pause)(rrstream_t *); - void (*destroy)(rrstream_t **); -}; - -static void -rrstream_noop_pause(rrstream_t *rs) { - UNUSED(rs); -} - -/**************************************************************************/ -/* - * An 'ixfr_rrstream_t' is an 'rrstream_t' that returns - * an IXFR-like RR stream from a journal file. - * - * The SOA at the beginning of each sequence of additions - * or deletions are included in the stream, but the extra - * SOAs at the beginning and end of the entire transfer are - * not included. - */ - -typedef struct ixfr_rrstream { - rrstream_t common; - dns_journal_t *journal; -} ixfr_rrstream_t; - -/* Forward declarations. */ -static void -ixfr_rrstream_destroy(rrstream_t **sp); - -static rrstream_methods_t ixfr_rrstream_methods; - -/* - * Returns: anything dns_journal_open() or dns_journal_iter_init() - * may return. - */ - -static isc_result_t -ixfr_rrstream_create(isc_mem_t *mctx, - const char *journal_filename, - isc_uint32_t begin_serial, - isc_uint32_t end_serial, - rrstream_t **sp) -{ - ixfr_rrstream_t *s; - isc_result_t result; - - INSIST(sp != NULL && *sp == NULL); - - s = isc_mem_get(mctx, sizeof(*s)); - if (s == NULL) - return (ISC_R_NOMEMORY); - s->common.mctx = mctx; - s->common.methods = &ixfr_rrstream_methods; - s->journal = NULL; - - CHECK(dns_journal_open(mctx, journal_filename, - ISC_FALSE, &s->journal)); - CHECK(dns_journal_iter_init(s->journal, begin_serial, end_serial)); - - *sp = (rrstream_t *) s; - return (ISC_R_SUCCESS); - - failure: - ixfr_rrstream_destroy((rrstream_t **) (void *)&s); - return (result); -} - -static isc_result_t -ixfr_rrstream_first(rrstream_t *rs) { - ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; - return (dns_journal_first_rr(s->journal)); -} - -static isc_result_t -ixfr_rrstream_next(rrstream_t *rs) { - ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; - return (dns_journal_next_rr(s->journal)); -} - -static void -ixfr_rrstream_current(rrstream_t *rs, - dns_name_t **name, isc_uint32_t *ttl, - dns_rdata_t **rdata) -{ - ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; - dns_journal_current_rr(s->journal, name, ttl, rdata); -} - -static void -ixfr_rrstream_destroy(rrstream_t **rsp) { - ixfr_rrstream_t *s = (ixfr_rrstream_t *) *rsp; - if (s->journal != 0) - dns_journal_destroy(&s->journal); - isc_mem_put(s->common.mctx, s, sizeof(*s)); -} - -static rrstream_methods_t ixfr_rrstream_methods = { - ixfr_rrstream_first, - ixfr_rrstream_next, - ixfr_rrstream_current, - rrstream_noop_pause, - ixfr_rrstream_destroy -}; - -/**************************************************************************/ -/* - * An 'axfr_rrstream_t' is an 'rrstream_t' that returns - * an AXFR-like RR stream from a database. - * - * The SOAs at the beginning and end of the transfer are - * not included in the stream. - */ - -typedef struct axfr_rrstream { - rrstream_t common; - db_rr_iterator_t it; - isc_boolean_t it_valid; -} axfr_rrstream_t; - -/* - * Forward declarations. - */ -static void -axfr_rrstream_destroy(rrstream_t **rsp); - -static rrstream_methods_t axfr_rrstream_methods; - -static isc_result_t -axfr_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver, - rrstream_t **sp) -{ - axfr_rrstream_t *s; - isc_result_t result; - - INSIST(sp != NULL && *sp == NULL); - - s = isc_mem_get(mctx, sizeof(*s)); - if (s == NULL) - return (ISC_R_NOMEMORY); - s->common.mctx = mctx; - s->common.methods = &axfr_rrstream_methods; - s->it_valid = ISC_FALSE; - - CHECK(db_rr_iterator_init(&s->it, db, ver, 0)); - s->it_valid = ISC_TRUE; - - *sp = (rrstream_t *) s; - return (ISC_R_SUCCESS); - - failure: - axfr_rrstream_destroy((rrstream_t **) (void *)&s); - return (result); -} - -static isc_result_t -axfr_rrstream_first(rrstream_t *rs) { - axfr_rrstream_t *s = (axfr_rrstream_t *) rs; - isc_result_t result; - result = db_rr_iterator_first(&s->it); - if (result != ISC_R_SUCCESS) - return (result); - /* Skip SOA records. */ - for (;;) { - dns_name_t *name_dummy = NULL; - isc_uint32_t ttl_dummy; - dns_rdata_t *rdata = NULL; - db_rr_iterator_current(&s->it, &name_dummy, - &ttl_dummy, &rdata); - if (rdata->type != dns_rdatatype_soa) - break; - result = db_rr_iterator_next(&s->it); - if (result != ISC_R_SUCCESS) - break; - } - return (result); -} - -static isc_result_t -axfr_rrstream_next(rrstream_t *rs) { - axfr_rrstream_t *s = (axfr_rrstream_t *) rs; - isc_result_t result; - - /* Skip SOA records. */ - for (;;) { - dns_name_t *name_dummy = NULL; - isc_uint32_t ttl_dummy; - dns_rdata_t *rdata = NULL; - result = db_rr_iterator_next(&s->it); - if (result != ISC_R_SUCCESS) - break; - db_rr_iterator_current(&s->it, &name_dummy, - &ttl_dummy, &rdata); - if (rdata->type != dns_rdatatype_soa) - break; - } - return (result); -} - -static void -axfr_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, - dns_rdata_t **rdata) -{ - axfr_rrstream_t *s = (axfr_rrstream_t *) rs; - db_rr_iterator_current(&s->it, name, ttl, rdata); -} - -static void -axfr_rrstream_pause(rrstream_t *rs) { - axfr_rrstream_t *s = (axfr_rrstream_t *) rs; - db_rr_iterator_pause(&s->it); -} - -static void -axfr_rrstream_destroy(rrstream_t **rsp) { - axfr_rrstream_t *s = (axfr_rrstream_t *) *rsp; - if (s->it_valid) - db_rr_iterator_destroy(&s->it); - isc_mem_put(s->common.mctx, s, sizeof(*s)); -} - -static rrstream_methods_t axfr_rrstream_methods = { - axfr_rrstream_first, - axfr_rrstream_next, - axfr_rrstream_current, - axfr_rrstream_pause, - axfr_rrstream_destroy -}; - -/**************************************************************************/ -/* - * An 'soa_rrstream_t' is a degenerate 'rrstream_t' that returns - * a single SOA record. - */ - -typedef struct soa_rrstream { - rrstream_t common; - dns_difftuple_t *soa_tuple; -} soa_rrstream_t; - -/* - * Forward declarations. - */ -static void -soa_rrstream_destroy(rrstream_t **rsp); - -static rrstream_methods_t soa_rrstream_methods; - -static isc_result_t -soa_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver, - rrstream_t **sp) -{ - soa_rrstream_t *s; - isc_result_t result; - - INSIST(sp != NULL && *sp == NULL); - - s = isc_mem_get(mctx, sizeof(*s)); - if (s == NULL) - return (ISC_R_NOMEMORY); - s->common.mctx = mctx; - s->common.methods = &soa_rrstream_methods; - s->soa_tuple = NULL; - - CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, - &s->soa_tuple)); - - *sp = (rrstream_t *) s; - return (ISC_R_SUCCESS); - - failure: - soa_rrstream_destroy((rrstream_t **) (void *)&s); - return (result); -} - -static isc_result_t -soa_rrstream_first(rrstream_t *rs) { - UNUSED(rs); - return (ISC_R_SUCCESS); -} - -static isc_result_t -soa_rrstream_next(rrstream_t *rs) { - UNUSED(rs); - return (ISC_R_NOMORE); -} - -static void -soa_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, - dns_rdata_t **rdata) -{ - soa_rrstream_t *s = (soa_rrstream_t *) rs; - *name = &s->soa_tuple->name; - *ttl = s->soa_tuple->ttl; - *rdata = &s->soa_tuple->rdata; -} - -static void -soa_rrstream_destroy(rrstream_t **rsp) { - soa_rrstream_t *s = (soa_rrstream_t *) *rsp; - if (s->soa_tuple != NULL) - dns_difftuple_free(&s->soa_tuple); - isc_mem_put(s->common.mctx, s, sizeof(*s)); -} - -static rrstream_methods_t soa_rrstream_methods = { - soa_rrstream_first, - soa_rrstream_next, - soa_rrstream_current, - rrstream_noop_pause, - soa_rrstream_destroy -}; - -/**************************************************************************/ -/* - * A 'compound_rrstream_t' objects owns a soa_rrstream - * and another rrstream, the "data stream". It returns - * a concatenated stream consisting of the soa_rrstream, then - * the data stream, then the soa_rrstream again. - * - * The component streams are owned by the compound_rrstream_t - * and are destroyed with it. - */ - -typedef struct compound_rrstream { - rrstream_t common; - rrstream_t *components[3]; - int state; - isc_result_t result; -} compound_rrstream_t; - -/* - * Forward declarations. - */ -static void -compound_rrstream_destroy(rrstream_t **rsp); - -static isc_result_t -compound_rrstream_next(rrstream_t *rs); - -static rrstream_methods_t compound_rrstream_methods; - -/* - * Requires: - * soa_stream != NULL && *soa_stream != NULL - * data_stream != NULL && *data_stream != NULL - * sp != NULL && *sp == NULL - * - * Ensures: - * *soa_stream == NULL - * *data_stream == NULL - * *sp points to a valid compound_rrstream_t - * The soa and data streams will be destroyed - * when the compound_rrstream_t is destroyed. - */ -static isc_result_t -compound_rrstream_create(isc_mem_t *mctx, rrstream_t **soa_stream, - rrstream_t **data_stream, rrstream_t **sp) -{ - compound_rrstream_t *s; - - INSIST(sp != NULL && *sp == NULL); - - s = isc_mem_get(mctx, sizeof(*s)); - if (s == NULL) - return (ISC_R_NOMEMORY); - s->common.mctx = mctx; - s->common.methods = &compound_rrstream_methods; - s->components[0] = *soa_stream; - s->components[1] = *data_stream; - s->components[2] = *soa_stream; - s->state = -1; - s->result = ISC_R_FAILURE; - - *soa_stream = NULL; - *data_stream = NULL; - *sp = (rrstream_t *) s; - return (ISC_R_SUCCESS); -} - -static isc_result_t -compound_rrstream_first(rrstream_t *rs) { - compound_rrstream_t *s = (compound_rrstream_t *) rs; - s->state = 0; - do { - rrstream_t *curstream = s->components[s->state]; - s->result = curstream->methods->first(curstream); - } while (s->result == ISC_R_NOMORE && s->state < 2); - return (s->result); -} - -static isc_result_t -compound_rrstream_next(rrstream_t *rs) { - compound_rrstream_t *s = (compound_rrstream_t *) rs; - rrstream_t *curstream = s->components[s->state]; - s->result = curstream->methods->next(curstream); - while (s->result == ISC_R_NOMORE) { - /* - * Make sure locks held by the current stream - * are released before we switch streams. - */ - curstream->methods->pause(curstream); - if (s->state == 2) - return (ISC_R_NOMORE); - s->state++; - curstream = s->components[s->state]; - s->result = curstream->methods->first(curstream); - } - return (s->result); -} - -static void -compound_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, - dns_rdata_t **rdata) -{ - compound_rrstream_t *s = (compound_rrstream_t *) rs; - rrstream_t *curstream; - INSIST(0 <= s->state && s->state < 3); - INSIST(s->result == ISC_R_SUCCESS); - curstream = s->components[s->state]; - curstream->methods->current(curstream, name, ttl, rdata); -} - -static void -compound_rrstream_pause(rrstream_t *rs) -{ - compound_rrstream_t *s = (compound_rrstream_t *) rs; - rrstream_t *curstream; - INSIST(0 <= s->state && s->state < 3); - curstream = s->components[s->state]; - curstream->methods->pause(curstream); -} - -static void -compound_rrstream_destroy(rrstream_t **rsp) { - compound_rrstream_t *s = (compound_rrstream_t *) *rsp; - s->components[0]->methods->destroy(&s->components[0]); - s->components[1]->methods->destroy(&s->components[1]); - s->components[2] = NULL; /* Copy of components[0]. */ - isc_mem_put(s->common.mctx, s, sizeof(*s)); -} - -static rrstream_methods_t compound_rrstream_methods = { - compound_rrstream_first, - compound_rrstream_next, - compound_rrstream_current, - compound_rrstream_pause, - compound_rrstream_destroy -}; - -/**************************************************************************/ -/* - * An 'xfrout_ctx_t' contains the state of an outgoing AXFR or IXFR - * in progress. - */ - -typedef struct { - isc_mem_t *mctx; - ns_client_t *client; - unsigned int id; /* ID of request */ - dns_name_t *qname; /* Question name of request */ - dns_rdatatype_t qtype; /* dns_rdatatype_{a,i}xfr */ - dns_rdataclass_t qclass; - dns_db_t *db; - dns_dbversion_t *ver; - isc_quota_t *quota; - rrstream_t *stream; /* The XFR RR stream */ - isc_boolean_t end_of_stream; /* EOS has been reached */ - isc_buffer_t buf; /* Buffer for message owner - names and rdatas */ - isc_buffer_t txlenbuf; /* Transmit length buffer */ - isc_buffer_t txbuf; /* Transmit message buffer */ - void *txmem; - unsigned int txmemlen; - unsigned int nmsg; /* Number of messages sent */ - dns_tsigkey_t *tsigkey; /* Key used to create TSIG */ - isc_buffer_t *lasttsig; /* the last TSIG */ - isc_boolean_t many_answers; - int sends; /* Send in progress */ - isc_boolean_t shuttingdown; - const char *mnemonic; /* Style of transfer */ -} xfrout_ctx_t; - -static isc_result_t -xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, - unsigned int id, dns_name_t *qname, dns_rdatatype_t qtype, - dns_rdataclass_t qclass, - dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota, - rrstream_t *stream, dns_tsigkey_t *tsigkey, - isc_buffer_t *lasttsig, - unsigned int maxtime, - unsigned int idletime, - isc_boolean_t many_answers, - xfrout_ctx_t **xfrp); - -static void -sendstream(xfrout_ctx_t *xfr); - -static void -xfrout_senddone(isc_task_t *task, isc_event_t *event); - -static void -xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg); - -static void -xfrout_maybe_destroy(xfrout_ctx_t *xfr); - -static void -xfrout_ctx_destroy(xfrout_ctx_t **xfrp); - -static void -xfrout_client_shutdown(void *arg, isc_result_t result); - -static void -xfrout_log1(ns_client_t *client, dns_name_t *zonename, - dns_rdataclass_t rdclass, int level, - const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); - -static void -xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) - ISC_FORMAT_PRINTF(3, 4); - -/**************************************************************************/ - -void -ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) { - isc_result_t result; - dns_name_t *question_name; - dns_rdataset_t *question_rdataset; - dns_zone_t *zone = NULL; - dns_db_t *db = NULL; - dns_dbversion_t *ver = NULL; - dns_rdataclass_t question_class; - rrstream_t *soa_stream = NULL; - rrstream_t *data_stream = NULL; - rrstream_t *stream = NULL; - dns_difftuple_t *current_soa_tuple = NULL; - dns_name_t *soa_name; - dns_rdataset_t *soa_rdataset; - dns_rdata_t soa_rdata = DNS_RDATA_INIT; - isc_boolean_t have_soa = ISC_FALSE; - const char *mnemonic = NULL; - isc_mem_t *mctx = client->mctx; - dns_message_t *request = client->message; - xfrout_ctx_t *xfr = NULL; - isc_quota_t *quota = NULL; - dns_transfer_format_t format = client->view->transfer_format; - isc_netaddr_t na; - dns_peer_t *peer = NULL; - isc_buffer_t *tsigbuf = NULL; - char *journalfile; - char msg[NS_CLIENT_ACLMSGSIZE("zone transfer")]; - char keyname[DNS_NAME_FORMATSIZE]; - isc_boolean_t is_poll = ISC_FALSE; -#ifdef DLZ - isc_boolean_t is_dlz = ISC_FALSE; -#endif - - switch (reqtype) { - case dns_rdatatype_axfr: - mnemonic = "AXFR"; - break; - case dns_rdatatype_ixfr: - mnemonic = "IXFR"; - break; - default: - INSIST(0); - break; - } - - ns_client_log(client, - DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT, - ISC_LOG_DEBUG(6), "%s request", mnemonic); - /* - * Apply quota. - */ - result = isc_quota_attach(&ns_g_server->xfroutquota, "a); - if (result != ISC_R_SUCCESS) { - isc_log_write(XFROUT_COMMON_LOGARGS, ISC_LOG_WARNING, - "%s request denied: %s", mnemonic, - isc_result_totext(result)); - goto failure; - } - - /* - * Interpret the question section. - */ - result = dns_message_firstname(request, DNS_SECTION_QUESTION); - INSIST(result == ISC_R_SUCCESS); - - /* - * The question section must contain exactly one question, and - * it must be for AXFR/IXFR as appropriate. - */ - question_name = NULL; - dns_message_currentname(request, DNS_SECTION_QUESTION, &question_name); - question_rdataset = ISC_LIST_HEAD(question_name->list); - question_class = question_rdataset->rdclass; - INSIST(question_rdataset->type == reqtype); - if (ISC_LIST_NEXT(question_rdataset, link) != NULL) - FAILC(DNS_R_FORMERR, "multiple questions"); - result = dns_message_nextname(request, DNS_SECTION_QUESTION); - if (result != ISC_R_NOMORE) - FAILC(DNS_R_FORMERR, "multiple questions"); - - result = dns_zt_find(client->view->zonetable, question_name, 0, NULL, - &zone); - - if (result != ISC_R_SUCCESS) -#ifdef DLZ - { - /* - * Normal zone table does not have a match. Try the DLZ database - */ - if (client->view->dlzdatabase != NULL) { - result = dns_dlzallowzonexfr(client->view, - question_name, &client->peeraddr, - &db); - - if (result == ISC_R_NOPERM) { - char _buf1[DNS_NAME_FORMATSIZE]; - char _buf2[DNS_RDATACLASS_FORMATSIZE]; - - result = DNS_R_REFUSED; - dns_name_format(question_name, _buf1, - sizeof(_buf1)); - dns_rdataclass_format(question_class, - _buf2, sizeof(_buf2)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_XFER_OUT, - ISC_LOG_ERROR, - "zone transfer '%s/%s' denied", - _buf1, _buf2); - goto failure; - } - if (result != ISC_R_SUCCESS) -#endif - FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", - question_name, question_class); -#ifdef DLZ - is_dlz = ISC_TRUE; - /* - * DLZ only support full zone transfer, not incremental - */ - if (reqtype != dns_rdatatype_axfr) { - mnemonic = "AXFR-style IXFR"; - reqtype = dns_rdatatype_axfr; - } - - } else { - /* - * not DLZ and not in normal zone table, we are - * not authoritative - */ - FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", - question_name, question_class); - } - } else { - /* zone table has a match */ -#endif - switch(dns_zone_gettype(zone)) { - case dns_zone_master: - case dns_zone_slave: - break; /* Master and slave zones are OK for transfer. */ - default: - FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", question_name, question_class); - } - CHECK(dns_zone_getdb(zone, &db)); - dns_db_currentversion(db, &ver); -#ifdef DLZ - } -#endif - - xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), - "%s question section OK", mnemonic); - - /* - * Check the authority section. Look for a SOA record with - * the same name and class as the question. - */ - for (result = dns_message_firstname(request, DNS_SECTION_AUTHORITY); - result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_AUTHORITY)) - { - soa_name = NULL; - dns_message_currentname(request, DNS_SECTION_AUTHORITY, - &soa_name); - - /* - * Ignore data whose owner name is not the zone apex. - */ - if (! dns_name_equal(soa_name, question_name)) - continue; - - for (soa_rdataset = ISC_LIST_HEAD(soa_name->list); - soa_rdataset != NULL; - soa_rdataset = ISC_LIST_NEXT(soa_rdataset, link)) - { - /* - * Ignore non-SOA data. - */ - if (soa_rdataset->type != dns_rdatatype_soa) - continue; - if (soa_rdataset->rdclass != question_class) - continue; - - CHECK(dns_rdataset_first(soa_rdataset)); - dns_rdataset_current(soa_rdataset, &soa_rdata); - result = dns_rdataset_next(soa_rdataset); - if (result == ISC_R_SUCCESS) - FAILC(DNS_R_FORMERR, - "IXFR authority section " - "has multiple SOAs"); - have_soa = ISC_TRUE; - goto got_soa; - } - } - got_soa: - if (result != ISC_R_NOMORE) - CHECK(result); - - xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), - "%s authority section OK", mnemonic); - - /* - * Decide whether to allow this transfer. - */ -#ifdef DLZ - /* - * if not a DLZ zone decide whether to allow this transfer. - */ - if (!is_dlz) { -#endif - ns_client_aclmsg("zone transfer", question_name, reqtype, - client->view->rdclass, msg, sizeof(msg)); - CHECK(ns_client_checkacl(client, msg, - dns_zone_getxfracl(zone), ISC_TRUE, - ISC_LOG_ERROR)); -#ifdef DLZ - } -#endif - - /* - * AXFR over UDP is not possible. - */ - if (reqtype == dns_rdatatype_axfr && - (client->attributes & NS_CLIENTATTR_TCP) == 0) - FAILC(DNS_R_FORMERR, "attempted AXFR over UDP"); - - /* - * Look up the requesting server in the peer table. - */ - isc_netaddr_fromsockaddr(&na, &client->peeraddr); - (void)dns_peerlist_peerbyaddr(client->view->peers, &na, &peer); - - /* - * Decide on the transfer format (one-answer or many-answers). - */ - if (peer != NULL) - (void)dns_peer_gettransferformat(peer, &format); - - /* - * Get a dynamically allocated copy of the current SOA. - */ -#ifdef DLZ - if (is_dlz) - dns_db_currentversion(db, &ver); -#endif - CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, - ¤t_soa_tuple)); - - if (reqtype == dns_rdatatype_ixfr) { - isc_uint32_t begin_serial, current_serial; - isc_boolean_t provide_ixfr; - - /* - * Outgoing IXFR may have been disabled for this peer - * or globally. - */ - provide_ixfr = client->view->provideixfr; - if (peer != NULL) - (void) dns_peer_getprovideixfr(peer, &provide_ixfr); - if (provide_ixfr == ISC_FALSE) - goto axfr_fallback; - - if (! have_soa) - FAILC(DNS_R_FORMERR, - "IXFR request missing SOA"); - - begin_serial = dns_soa_getserial(&soa_rdata); - current_serial = dns_soa_getserial(¤t_soa_tuple->rdata); - - /* - * RFC1995 says "If an IXFR query with the same or - * newer version number than that of the server - * is received, it is replied to with a single SOA - * record of the server's current version, just as - * in AXFR". The claim about AXFR is incorrect, - * but other than that, we do as the RFC says. - * - * Sending a single SOA record is also how we refuse - * IXFR over UDP (currently, we always do). - */ - if (DNS_SERIAL_GE(begin_serial, current_serial) || - (client->attributes & NS_CLIENTATTR_TCP) == 0) - { - CHECK(soa_rrstream_create(mctx, db, ver, &stream)); - is_poll = ISC_TRUE; - goto have_stream; - } - journalfile = dns_zone_getjournal(zone); - if (journalfile != NULL) - result = ixfr_rrstream_create(mctx, - journalfile, - begin_serial, - current_serial, - &data_stream); - else - result = ISC_R_NOTFOUND; - if (result == ISC_R_NOTFOUND || - result == ISC_R_RANGE) { - xfrout_log1(client, question_name, question_class, - ISC_LOG_DEBUG(4), - "IXFR version not in journal, " - "falling back to AXFR"); - mnemonic = "AXFR-style IXFR"; - goto axfr_fallback; - } - CHECK(result); - } else { - axfr_fallback: - CHECK(axfr_rrstream_create(mctx, db, ver, - &data_stream)); - } - - /* - * Bracket the the data stream with SOAs. - */ - CHECK(soa_rrstream_create(mctx, db, ver, &soa_stream)); - CHECK(compound_rrstream_create(mctx, &soa_stream, &data_stream, - &stream)); - soa_stream = NULL; - data_stream = NULL; - - have_stream: - CHECK(dns_message_getquerytsig(request, mctx, &tsigbuf)); - /* - * Create the xfrout context object. This transfers the ownership - * of "stream", "db", "ver", and "quota" to the xfrout context object. - */ - - - -#ifdef DLZ - if (is_dlz) - CHECK(xfrout_ctx_create(mctx, client, request->id, question_name, - reqtype, question_class, db, ver, quota, - stream, dns_message_gettsigkey(request), - tsigbuf, - 3600, - 3600, - (format == dns_many_answers) ? - ISC_TRUE : ISC_FALSE, - &xfr)); - else -#endif - CHECK(xfrout_ctx_create(mctx, client, request->id, question_name, - reqtype, question_class, db, ver, quota, - stream, dns_message_gettsigkey(request), - tsigbuf, - dns_zone_getmaxxfrout(zone), - dns_zone_getidleout(zone), - (format == dns_many_answers) ? - ISC_TRUE : ISC_FALSE, - &xfr)); - - xfr->mnemonic = mnemonic; - stream = NULL; - quota = NULL; - - CHECK(xfr->stream->methods->first(xfr->stream)); - - if (xfr->tsigkey != NULL) { - dns_name_format(&xfr->tsigkey->name, keyname, sizeof(keyname)); - } else - keyname[0] = '\0'; - if (is_poll) - xfrout_log1(client, question_name, question_class, - ISC_LOG_DEBUG(1), "IXFR poll up to date%s%s", - (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname); - else - xfrout_log1(client, question_name, question_class, - ISC_LOG_INFO, "%s started%s%s", mnemonic, - (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname); - - /* - * Hand the context over to sendstream(). Set xfr to NULL; - * sendstream() is responsible for either passing the - * context on to a later event handler or destroying it. - */ - sendstream(xfr); - xfr = NULL; - - result = ISC_R_SUCCESS; - - failure: - if (quota != NULL) - isc_quota_detach("a); - if (current_soa_tuple != NULL) - dns_difftuple_free(¤t_soa_tuple); - if (stream != NULL) - stream->methods->destroy(&stream); - if (soa_stream != NULL) - soa_stream->methods->destroy(&soa_stream); - if (data_stream != NULL) - data_stream->methods->destroy(&data_stream); - if (ver != NULL) - dns_db_closeversion(db, &ver, ISC_FALSE); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - /* XXX kludge */ - if (xfr != NULL) { - xfrout_fail(xfr, result, "setting up zone transfer"); - } else if (result != ISC_R_SUCCESS) { - ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, - NS_LOGMODULE_XFER_OUT, - ISC_LOG_DEBUG(3), "zone transfer setup failed"); - ns_client_error(client, result); - } -} - -static isc_result_t -xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id, - dns_name_t *qname, dns_rdatatype_t qtype, - dns_rdataclass_t qclass, - dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota, - rrstream_t *stream, dns_tsigkey_t *tsigkey, - isc_buffer_t *lasttsig, unsigned int maxtime, - unsigned int idletime, isc_boolean_t many_answers, - xfrout_ctx_t **xfrp) -{ - xfrout_ctx_t *xfr; - isc_result_t result; - unsigned int len; - void *mem; - - INSIST(xfrp != NULL && *xfrp == NULL); - xfr = isc_mem_get(mctx, sizeof(*xfr)); - if (xfr == NULL) - return (ISC_R_NOMEMORY); - xfr->mctx = mctx; - xfr->client = NULL; - ns_client_attach(client, &xfr->client); - xfr->id = id; - xfr->qname = qname; - xfr->qtype = qtype; - xfr->qclass = qclass; - xfr->db = NULL; - xfr->ver = NULL; - dns_db_attach(db, &xfr->db); - dns_db_attachversion(db, ver, &xfr->ver); - xfr->end_of_stream = ISC_FALSE; - xfr->tsigkey = tsigkey; - xfr->lasttsig = lasttsig; - xfr->txmem = NULL; - xfr->txmemlen = 0; - xfr->nmsg = 0; - xfr->many_answers = many_answers, - xfr->sends = 0; - xfr->shuttingdown = ISC_FALSE; - xfr->mnemonic = NULL; - xfr->buf.base = NULL; - xfr->buf.length = 0; - xfr->txmem = NULL; - xfr->txmemlen = 0; - xfr->stream = NULL; - xfr->quota = NULL; - - /* - * Allocate a temporary buffer for the uncompressed response - * message data. The size should be no more than 65535 bytes - * so that the compressed data will fit in a TCP message, - * and no less than 65535 bytes so that an almost maximum-sized - * RR will fit. Note that although 65535-byte RRs are allowed - * in principle, they cannot be zone-transferred (at least not - * if uncompressible), because the message and RR headers would - * push the size of the TCP message over the 65536 byte limit. - */ - len = 65535; - mem = isc_mem_get(mctx, len); - if (mem == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - isc_buffer_init(&xfr->buf, mem, len); - - /* - * Allocate another temporary buffer for the compressed - * response message and its TCP length prefix. - */ - len = 2 + 65535; - mem = isc_mem_get(mctx, len); - if (mem == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - isc_buffer_init(&xfr->txlenbuf, mem, 2); - isc_buffer_init(&xfr->txbuf, (char *) mem + 2, len - 2); - xfr->txmem = mem; - xfr->txmemlen = len; - - CHECK(dns_timer_setidle(xfr->client->timer, - maxtime, idletime, ISC_FALSE)); - - /* - * Register a shutdown callback with the client, so that we - * can stop the transfer immediately when the client task - * gets a shutdown event. - */ - xfr->client->shutdown = xfrout_client_shutdown; - xfr->client->shutdown_arg = xfr; - /* - * These MUST be after the last "goto failure;" / CHECK to - * prevent a double free by the caller. - */ - xfr->quota = quota; - xfr->stream = stream; - - *xfrp = xfr; - return (ISC_R_SUCCESS); - -failure: - xfrout_ctx_destroy(&xfr); - return (result); -} - - -/* - * Arrange to send as much as we can of "stream" without blocking. - * - * Requires: - * The stream iterator is initialized and points at an RR, - * or possiby at the end of the stream (that is, the - * _first method of the iterator has been called). - */ -static void -sendstream(xfrout_ctx_t *xfr) { - dns_message_t *tcpmsg = NULL; - dns_message_t *msg = NULL; /* Client message if UDP, tcpmsg if TCP */ - isc_result_t result; - isc_region_t used; - isc_region_t region; - dns_rdataset_t *qrdataset; - dns_name_t *msgname = NULL; - dns_rdata_t *msgrdata = NULL; - dns_rdatalist_t *msgrdl = NULL; - dns_rdataset_t *msgrds = NULL; - dns_compress_t cctx; - isc_boolean_t cleanup_cctx = ISC_FALSE; - - int n_rrs; - - isc_buffer_clear(&xfr->buf); - isc_buffer_clear(&xfr->txlenbuf); - isc_buffer_clear(&xfr->txbuf); - - if ((xfr->client->attributes & NS_CLIENTATTR_TCP) == 0) { - /* - * In the UDP case, we put the response data directly into - * the client message. - */ - msg = xfr->client->message; - CHECK(dns_message_reply(msg, ISC_TRUE)); - } else { - /* - * TCP. Build a response dns_message_t, temporarily storing - * the raw, uncompressed owner names and RR data contiguously - * in xfr->buf. We know that if the uncompressed data fits - * in xfr->buf, the compressed data will surely fit in a TCP - * message. - */ - - CHECK(dns_message_create(xfr->mctx, - DNS_MESSAGE_INTENTRENDER, &tcpmsg)); - msg = tcpmsg; - - msg->id = xfr->id; - msg->rcode = dns_rcode_noerror; - msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA; - if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0) - msg->flags |= DNS_MESSAGEFLAG_RA; - CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); - CHECK(dns_message_setquerytsig(msg, xfr->lasttsig)); - if (xfr->lasttsig != NULL) - isc_buffer_free(&xfr->lasttsig); - - /* - * Include a question section in the first message only. - * BIND 8.2.1 will not recognize an IXFR if it does not - * have a question section. - */ - if (xfr->nmsg == 0) { - dns_name_t *qname = NULL; - isc_region_t r; - - /* - * Reserve space for the 12-byte message header - * and 4 bytes of question. - */ - isc_buffer_add(&xfr->buf, 12 + 4); - - qrdataset = NULL; - result = dns_message_gettemprdataset(msg, &qrdataset); - if (result != ISC_R_SUCCESS) - goto failure; - dns_rdataset_init(qrdataset); - dns_rdataset_makequestion(qrdataset, - xfr->client->message->rdclass, - xfr->qtype); - - result = dns_message_gettempname(msg, &qname); - if (result != ISC_R_SUCCESS) - goto failure; - dns_name_init(qname, NULL); - isc_buffer_availableregion(&xfr->buf, &r); - INSIST(r.length >= xfr->qname->length); - r.length = xfr->qname->length; - isc_buffer_putmem(&xfr->buf, xfr->qname->ndata, - xfr->qname->length); - dns_name_fromregion(qname, &r); - ISC_LIST_INIT(qname->list); - ISC_LIST_APPEND(qname->list, qrdataset, link); - - dns_message_addname(msg, qname, DNS_SECTION_QUESTION); - } - else - msg->tcp_continuation = 1; - } - - /* - * Try to fit in as many RRs as possible, unless "one-answer" - * format has been requested. - */ - for (n_rrs = 0; ; n_rrs++) { - dns_name_t *name = NULL; - isc_uint32_t ttl; - dns_rdata_t *rdata = NULL; - - unsigned int size; - isc_region_t r; - - msgname = NULL; - msgrdata = NULL; - msgrdl = NULL; - msgrds = NULL; - - xfr->stream->methods->current(xfr->stream, - &name, &ttl, &rdata); - size = name->length + 10 + rdata->length; - isc_buffer_availableregion(&xfr->buf, &r); - if (size >= r.length) { - /* - * RR would not fit. If there are other RRs in the - * buffer, send them now and leave this RR to the - * next message. If this RR overflows the buffer - * all by itself, fail. - * - * In theory some RRs might fit in a TCP message - * when compressed even if they do not fit when - * uncompressed, but surely we don't want - * to send such monstrosities to an unsuspecting - * slave. - */ - if (n_rrs == 0) { - xfrout_log(xfr, ISC_LOG_WARNING, - "RR too large for zone transfer " - "(%d bytes)", size); - /* XXX DNS_R_RRTOOLARGE? */ - result = ISC_R_NOSPACE; - goto failure; - } - break; - } - - if (isc_log_wouldlog(ns_g_lctx, XFROUT_RR_LOGLEVEL)) - log_rr(name, rdata, ttl); /* XXX */ - - result = dns_message_gettempname(msg, &msgname); - if (result != ISC_R_SUCCESS) - goto failure; - dns_name_init(msgname, NULL); - isc_buffer_availableregion(&xfr->buf, &r); - INSIST(r.length >= name->length); - r.length = name->length; - isc_buffer_putmem(&xfr->buf, name->ndata, name->length); - dns_name_fromregion(msgname, &r); - - /* Reserve space for RR header. */ - isc_buffer_add(&xfr->buf, 10); - - result = dns_message_gettemprdata(msg, &msgrdata); - if (result != ISC_R_SUCCESS) - goto failure; - isc_buffer_availableregion(&xfr->buf, &r); - r.length = rdata->length; - isc_buffer_putmem(&xfr->buf, rdata->data, rdata->length); - dns_rdata_init(msgrdata); - dns_rdata_fromregion(msgrdata, - rdata->rdclass, rdata->type, &r); - - result = dns_message_gettemprdatalist(msg, &msgrdl); - if (result != ISC_R_SUCCESS) - goto failure; - msgrdl->type = rdata->type; - msgrdl->rdclass = rdata->rdclass; - msgrdl->ttl = ttl; - ISC_LINK_INIT(msgrdl, link); - ISC_LIST_INIT(msgrdl->rdata); - ISC_LIST_APPEND(msgrdl->rdata, msgrdata, link); - - result = dns_message_gettemprdataset(msg, &msgrds); - if (result != ISC_R_SUCCESS) - goto failure; - dns_rdataset_init(msgrds); - result = dns_rdatalist_tordataset(msgrdl, msgrds); - INSIST(result == ISC_R_SUCCESS); - - ISC_LIST_APPEND(msgname->list, msgrds, link); - - dns_message_addname(msg, msgname, DNS_SECTION_ANSWER); - msgname = NULL; - - result = xfr->stream->methods->next(xfr->stream); - if (result == ISC_R_NOMORE) { - xfr->end_of_stream = ISC_TRUE; - break; - } - CHECK(result); - - if (! xfr->many_answers) - break; - } - - if ((xfr->client->attributes & NS_CLIENTATTR_TCP) != 0) { - CHECK(dns_compress_init(&cctx, -1, xfr->mctx)); - dns_compress_setsensitive(&cctx, ISC_TRUE); - cleanup_cctx = ISC_TRUE; - CHECK(dns_message_renderbegin(msg, &cctx, &xfr->txbuf)); - CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0)); - CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0)); - CHECK(dns_message_renderend(msg)); - dns_compress_invalidate(&cctx); - cleanup_cctx = ISC_FALSE; - - isc_buffer_usedregion(&xfr->txbuf, &used); - isc_buffer_putuint16(&xfr->txlenbuf, - (isc_uint16_t)used.length); - region.base = xfr->txlenbuf.base; - region.length = 2 + used.length; - xfrout_log(xfr, ISC_LOG_DEBUG(8), - "sending TCP message of %d bytes", - used.length); - CHECK(isc_socket_send(xfr->client->tcpsocket, /* XXX */ - ®ion, xfr->client->task, - xfrout_senddone, - xfr)); - xfr->sends++; - } else { - xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response"); - ns_client_send(xfr->client); - xfr->stream->methods->pause(xfr->stream); - xfrout_ctx_destroy(&xfr); - return; - } - - /* Advance lasttsig to be the last TSIG generated */ - CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig)); - - xfr->nmsg++; - - failure: - if (msgname != NULL) { - if (msgrds != NULL) { - if (dns_rdataset_isassociated(msgrds)) - dns_rdataset_disassociate(msgrds); - dns_message_puttemprdataset(msg, &msgrds); - } - if (msgrdl != NULL) { - ISC_LIST_UNLINK(msgrdl->rdata, msgrdata, link); - dns_message_puttemprdatalist(msg, &msgrdl); - } - if (msgrdata != NULL) - dns_message_puttemprdata(msg, &msgrdata); - dns_message_puttempname(msg, &msgname); - } - - if (tcpmsg != NULL) - dns_message_destroy(&tcpmsg); - - if (cleanup_cctx) - dns_compress_invalidate(&cctx); - /* - * Make sure to release any locks held by database - * iterators before returning from the event handler. - */ - xfr->stream->methods->pause(xfr->stream); - - if (result == ISC_R_SUCCESS) - return; - - xfrout_fail(xfr, result, "sending zone data"); -} - -static void -xfrout_ctx_destroy(xfrout_ctx_t **xfrp) { - xfrout_ctx_t *xfr = *xfrp; - - INSIST(xfr->sends == 0); - - xfr->client->shutdown = NULL; - xfr->client->shutdown_arg = NULL; - - if (xfr->stream != NULL) - xfr->stream->methods->destroy(&xfr->stream); - if (xfr->buf.base != NULL) - isc_mem_put(xfr->mctx, xfr->buf.base, xfr->buf.length); - if (xfr->txmem != NULL) - isc_mem_put(xfr->mctx, xfr->txmem, xfr->txmemlen); - if (xfr->lasttsig != NULL) - isc_buffer_free(&xfr->lasttsig); - if (xfr->quota != NULL) - isc_quota_detach(&xfr->quota); - if (xfr->ver != NULL) - dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE); - if (xfr->db != NULL) - dns_db_detach(&xfr->db); - - ns_client_detach(&xfr->client); - - isc_mem_put(xfr->mctx, xfr, sizeof(*xfr)); - - *xfrp = NULL; -} - -static void -xfrout_senddone(isc_task_t *task, isc_event_t *event) { - isc_socketevent_t *sev = (isc_socketevent_t *)event; - xfrout_ctx_t *xfr = (xfrout_ctx_t *)event->ev_arg; - isc_result_t evresult = sev->result; - - UNUSED(task); - - INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE); - - isc_event_free(&event); - xfr->sends--; - INSIST(xfr->sends == 0); - - (void)isc_timer_touch(xfr->client->timer); - if (xfr->shuttingdown == ISC_TRUE) { - xfrout_maybe_destroy(xfr); - } else if (evresult != ISC_R_SUCCESS) { - xfrout_fail(xfr, evresult, "send"); - } else if (xfr->end_of_stream == ISC_FALSE) { - sendstream(xfr); - } else { - /* End of zone transfer stream. */ - xfrout_log(xfr, ISC_LOG_INFO, "%s ended", xfr->mnemonic); - ns_client_next(xfr->client, ISC_R_SUCCESS); - xfrout_ctx_destroy(&xfr); - } -} - -static void -xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg) { - xfr->shuttingdown = ISC_TRUE; - xfrout_log(xfr, ISC_LOG_ERROR, "%s: %s", - msg, isc_result_totext(result)); - xfrout_maybe_destroy(xfr); -} - -static void -xfrout_maybe_destroy(xfrout_ctx_t *xfr) { - INSIST(xfr->shuttingdown == ISC_TRUE); - if (xfr->sends > 0) { - /* - * If we are currently sending, cancel it and wait for - * cancel event before destroying the context. - */ - isc_socket_cancel(xfr->client->tcpsocket, xfr->client->task, - ISC_SOCKCANCEL_SEND); - } else { - ns_client_next(xfr->client, ISC_R_CANCELED); - xfrout_ctx_destroy(&xfr); - } -} - -static void -xfrout_client_shutdown(void *arg, isc_result_t result) { - xfrout_ctx_t *xfr = (xfrout_ctx_t *) arg; - xfrout_fail(xfr, result, "aborted"); -} - -/* - * Log outgoing zone transfer messages in a format like - * : transfer of : - */ - -static void -xfrout_logv(ns_client_t *client, dns_name_t *zonename, - dns_rdataclass_t rdclass, int level, const char *fmt, va_list ap) - ISC_FORMAT_PRINTF(5, 0); - -static void -xfrout_logv(ns_client_t *client, dns_name_t *zonename, - dns_rdataclass_t rdclass, int level, const char *fmt, va_list ap) -{ - char msgbuf[2048]; - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - - dns_name_format(zonename, namebuf, sizeof(namebuf)); - dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf)); - vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); - ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, - NS_LOGMODULE_XFER_OUT, level, - "transfer of '%s/%s': %s", namebuf, classbuf, msgbuf); -} - -/* - * Logging function for use when a xfrout_ctx_t has not yet been created. - */ -static void -xfrout_log1(ns_client_t *client, dns_name_t *zonename, - dns_rdataclass_t rdclass, int level, const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - xfrout_logv(client, zonename, rdclass, level, fmt, ap); - va_end(ap); -} - -/* - * Logging function for use when there is a xfrout_ctx_t. - */ -static void -xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - xfrout_logv(xfr->client, xfr->qname, xfr->qclass, level, fmt, ap); - va_end(ap); -} diff --git a/contrib/bind9/bin/named/zoneconf.c b/contrib/bind9/bin/named/zoneconf.c deleted file mode 100644 index a0c1bab..0000000 --- a/contrib/bind9/bin/named/zoneconf.c +++ /dev/null @@ -1,913 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: zoneconf.c,v 1.110.18.23 2006/05/16 03:39:57 marka Exp $ */ - -/*% */ - -#include - -#include -#include -#include -#include -#include /* Required for HP/UX (and others?) */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -/*% - * These are BIND9 server defaults, not necessarily identical to the - * library defaults defined in zone.c. - */ -#define RETERR(x) do { \ - isc_result_t _r = (x); \ - if (_r != ISC_R_SUCCESS) \ - return (_r); \ - } while (0) - -/*% - * Convenience function for configuring a single zone ACL. - */ -static isc_result_t -configure_zone_acl(const cfg_obj_t *zconfig, const cfg_obj_t *vconfig, - const cfg_obj_t *config, const char *aclname, - cfg_aclconfctx_t *actx, dns_zone_t *zone, - void (*setzacl)(dns_zone_t *, dns_acl_t *), - void (*clearzacl)(dns_zone_t *)) -{ - isc_result_t result; - const cfg_obj_t *maps[5]; - const cfg_obj_t *aclobj = NULL; - int i = 0; - dns_acl_t *dacl = NULL; - - if (zconfig != NULL) - maps[i++] = cfg_tuple_get(zconfig, "options"); - if (vconfig != NULL) - maps[i++] = cfg_tuple_get(vconfig, "options"); - if (config != NULL) { - const cfg_obj_t *options = NULL; - (void)cfg_map_get(config, "options", &options); - if (options != NULL) - maps[i++] = options; - } - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - result = ns_config_get(maps, aclname, &aclobj); - if (aclobj == NULL) { - (*clearzacl)(zone); - return (ISC_R_SUCCESS); - } - - result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx, actx, - dns_zone_getmctx(zone), &dacl); - if (result != ISC_R_SUCCESS) - return (result); - (*setzacl)(zone, dacl); - dns_acl_detach(&dacl); - return (ISC_R_SUCCESS); -} - -/*% - * Parse the zone update-policy statement. - */ -static isc_result_t -configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone) { - const cfg_obj_t *updatepolicy = NULL; - const cfg_listelt_t *element, *element2; - dns_ssutable_t *table = NULL; - isc_mem_t *mctx = dns_zone_getmctx(zone); - isc_result_t result; - - (void)cfg_map_get(zconfig, "update-policy", &updatepolicy); - if (updatepolicy == NULL) { - dns_zone_setssutable(zone, NULL); - return (ISC_R_SUCCESS); - } - - result = dns_ssutable_create(mctx, &table); - if (result != ISC_R_SUCCESS) - return (result); - - for (element = cfg_list_first(updatepolicy); - element != NULL; - element = cfg_list_next(element)) - { - const cfg_obj_t *stmt = cfg_listelt_value(element); - const cfg_obj_t *mode = cfg_tuple_get(stmt, "mode"); - const cfg_obj_t *identity = cfg_tuple_get(stmt, "identity"); - const cfg_obj_t *matchtype = cfg_tuple_get(stmt, "matchtype"); - const cfg_obj_t *dname = cfg_tuple_get(stmt, "name"); - const cfg_obj_t *typelist = cfg_tuple_get(stmt, "types"); - const char *str; - isc_boolean_t grant = ISC_FALSE; - unsigned int mtype = DNS_SSUMATCHTYPE_NAME; - dns_fixedname_t fname, fident; - isc_buffer_t b; - dns_rdatatype_t *types; - unsigned int i, n; - - str = cfg_obj_asstring(mode); - if (strcasecmp(str, "grant") == 0) - grant = ISC_TRUE; - else if (strcasecmp(str, "deny") == 0) - grant = ISC_FALSE; - else - INSIST(0); - - str = cfg_obj_asstring(matchtype); - if (strcasecmp(str, "name") == 0) - mtype = DNS_SSUMATCHTYPE_NAME; - else if (strcasecmp(str, "subdomain") == 0) - mtype = DNS_SSUMATCHTYPE_SUBDOMAIN; - else if (strcasecmp(str, "wildcard") == 0) - mtype = DNS_SSUMATCHTYPE_WILDCARD; - else if (strcasecmp(str, "self") == 0) - mtype = DNS_SSUMATCHTYPE_SELF; - else if (strcasecmp(str, "selfsub") == 0) - mtype = DNS_SSUMATCHTYPE_SELFSUB; - else if (strcasecmp(str, "selfwild") == 0) - mtype = DNS_SSUMATCHTYPE_SELFWILD; - else - INSIST(0); - - dns_fixedname_init(&fident); - str = cfg_obj_asstring(identity); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - result = dns_name_fromtext(dns_fixedname_name(&fident), &b, - dns_rootname, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR, - "'%s' is not a valid name", str); - goto cleanup; - } - - dns_fixedname_init(&fname); - str = cfg_obj_asstring(dname); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - result = dns_name_fromtext(dns_fixedname_name(&fname), &b, - dns_rootname, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR, - "'%s' is not a valid name", str); - goto cleanup; - } - - n = ns_config_listcount(typelist); - if (n == 0) - types = NULL; - else { - types = isc_mem_get(mctx, n * sizeof(dns_rdatatype_t)); - if (types == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - } - - i = 0; - for (element2 = cfg_list_first(typelist); - element2 != NULL; - element2 = cfg_list_next(element2)) - { - const cfg_obj_t *typeobj; - isc_textregion_t r; - - INSIST(i < n); - - typeobj = cfg_listelt_value(element2); - str = cfg_obj_asstring(typeobj); - DE_CONST(str, r.base); - r.length = strlen(str); - - result = dns_rdatatype_fromtext(&types[i++], &r); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR, - "'%s' is not a valid type", str); - isc_mem_put(mctx, types, - n * sizeof(dns_rdatatype_t)); - goto cleanup; - } - } - INSIST(i == n); - - result = dns_ssutable_addrule(table, grant, - dns_fixedname_name(&fident), - mtype, - dns_fixedname_name(&fname), - n, types); - if (types != NULL) - isc_mem_put(mctx, types, n * sizeof(dns_rdatatype_t)); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - - } - - result = ISC_R_SUCCESS; - dns_zone_setssutable(zone, table); - - cleanup: - dns_ssutable_detach(&table); - return (result); -} - -/*% - * Convert a config file zone type into a server zone type. - */ -static inline dns_zonetype_t -zonetype_fromconfig(const cfg_obj_t *map) { - const cfg_obj_t *obj = NULL; - isc_result_t result; - - result = cfg_map_get(map, "type", &obj); - INSIST(result == ISC_R_SUCCESS); - return (ns_config_getzonetype(obj)); -} - -/*% - * Helper function for strtoargv(). Pardon the gratuitous recursion. - */ -static isc_result_t -strtoargvsub(isc_mem_t *mctx, char *s, unsigned int *argcp, - char ***argvp, unsigned int n) -{ - isc_result_t result; - - /* Discard leading whitespace. */ - while (*s == ' ' || *s == '\t') - s++; - - if (*s == '\0') { - /* We have reached the end of the string. */ - *argcp = n; - *argvp = isc_mem_get(mctx, n * sizeof(char *)); - if (*argvp == NULL) - return (ISC_R_NOMEMORY); - } else { - char *p = s; - while (*p != ' ' && *p != '\t' && *p != '\0') - p++; - if (*p != '\0') - *p++ = '\0'; - - result = strtoargvsub(mctx, p, argcp, argvp, n + 1); - if (result != ISC_R_SUCCESS) - return (result); - (*argvp)[n] = s; - } - return (ISC_R_SUCCESS); -} - -/*% - * Tokenize the string "s" into whitespace-separated words, - * return the number of words in '*argcp' and an array - * of pointers to the words in '*argvp'. The caller - * must free the array using isc_mem_put(). The string - * is modified in-place. - */ -static isc_result_t -strtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp) { - return (strtoargvsub(mctx, s, argcp, argvp, 0)); -} - -static void -checknames(dns_zonetype_t ztype, const cfg_obj_t **maps, - const cfg_obj_t **objp) -{ - const char *zone = NULL; - isc_result_t result; - - switch (ztype) { - case dns_zone_slave: zone = "slave"; break; - case dns_zone_master: zone = "master"; break; - default: - INSIST(0); - } - result = ns_checknames_get(maps, zone, objp); - INSIST(result == ISC_R_SUCCESS); -} - -isc_result_t -ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, - const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac, - dns_zone_t *zone) -{ - isc_result_t result; - const char *zname; - dns_rdataclass_t zclass; - dns_rdataclass_t vclass; - const cfg_obj_t *maps[5]; - const cfg_obj_t *zoptions = NULL; - const cfg_obj_t *options = NULL; - const cfg_obj_t *obj; - const char *filename = NULL; - dns_notifytype_t notifytype = dns_notifytype_yes; - isc_sockaddr_t *addrs; - dns_name_t **keynames; - isc_uint32_t count; - char *cpval; - unsigned int dbargc; - char **dbargv; - static char default_dbtype[] = "rbt"; - isc_mem_t *mctx = dns_zone_getmctx(zone); - dns_dialuptype_t dialup = dns_dialuptype_no; - dns_zonetype_t ztype; - int i; - isc_int32_t journal_size; - isc_boolean_t multi; - isc_boolean_t alt; - dns_view_t *view; - isc_boolean_t check = ISC_FALSE, fail = ISC_FALSE; - isc_boolean_t warn = ISC_FALSE, ignore = ISC_FALSE; - isc_boolean_t ixfrdiff; - dns_masterformat_t masterformat; - - i = 0; - if (zconfig != NULL) { - zoptions = cfg_tuple_get(zconfig, "options"); - maps[i++] = zoptions; - } - if (vconfig != NULL) - maps[i++] = cfg_tuple_get(vconfig, "options"); - if (config != NULL) { - (void)cfg_map_get(config, "options", &options); - if (options != NULL) - maps[i++] = options; - } - maps[i++] = ns_g_defaults; - maps[i++] = NULL; - - if (vconfig != NULL) - RETERR(ns_config_getclass(cfg_tuple_get(vconfig, "class"), - dns_rdataclass_in, &vclass)); - else - vclass = dns_rdataclass_in; - - /* - * Configure values common to all zone types. - */ - - zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); - - RETERR(ns_config_getclass(cfg_tuple_get(zconfig, "class"), - vclass, &zclass)); - dns_zone_setclass(zone, zclass); - - ztype = zonetype_fromconfig(zoptions); - dns_zone_settype(zone, ztype); - - obj = NULL; - result = cfg_map_get(zoptions, "database", &obj); - if (result == ISC_R_SUCCESS) - cpval = isc_mem_strdup(mctx, cfg_obj_asstring(obj)); - else - cpval = default_dbtype; - - if (cpval == NULL) - return(ISC_R_NOMEMORY); - - result = strtoargv(mctx, cpval, &dbargc, &dbargv); - if (result != ISC_R_SUCCESS && cpval != default_dbtype) { - isc_mem_free(mctx, cpval); - return (result); - } - - /* - * ANSI C is strange here. There is no logical reason why (char **) - * cannot be promoted automatically to (const char * const *) by the - * compiler w/o generating a warning. - */ - result = dns_zone_setdbtype(zone, dbargc, (const char * const *)dbargv); - isc_mem_put(mctx, dbargv, dbargc * sizeof(*dbargv)); - if (cpval != default_dbtype) - isc_mem_free(mctx, cpval); - if (result != ISC_R_SUCCESS) - return (result); - - obj = NULL; - result = cfg_map_get(zoptions, "file", &obj); - if (result == ISC_R_SUCCESS) - filename = cfg_obj_asstring(obj); - - masterformat = dns_masterformat_text; - obj = NULL; - result= ns_config_get(maps, "masterfile-format", &obj); - if (result == ISC_R_SUCCESS) { - const char *masterformatstr = cfg_obj_asstring(obj); - - if (strcasecmp(masterformatstr, "text") == 0) - masterformat = dns_masterformat_text; - else if (strcasecmp(masterformatstr, "raw") == 0) - masterformat = dns_masterformat_raw; - else - INSIST(0); - } - RETERR(dns_zone_setfile2(zone, filename, masterformat)); - - obj = NULL; - result = cfg_map_get(zoptions, "journal", &obj); - if (result == ISC_R_SUCCESS) - RETERR(dns_zone_setjournal(zone, cfg_obj_asstring(obj))); - - if (ztype == dns_zone_slave) - RETERR(configure_zone_acl(zconfig, vconfig, config, - "allow-notify", ac, zone, - dns_zone_setnotifyacl, - dns_zone_clearnotifyacl)); - /* - * XXXAG This probably does not make sense for stubs. - */ - RETERR(configure_zone_acl(zconfig, vconfig, config, - "allow-query", ac, zone, - dns_zone_setqueryacl, - dns_zone_clearqueryacl)); - - obj = NULL; - result = ns_config_get(maps, "dialup", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - dialup = dns_dialuptype_yes; - else - dialup = dns_dialuptype_no; - } else { - const char *dialupstr = cfg_obj_asstring(obj); - if (strcasecmp(dialupstr, "notify") == 0) - dialup = dns_dialuptype_notify; - else if (strcasecmp(dialupstr, "notify-passive") == 0) - dialup = dns_dialuptype_notifypassive; - else if (strcasecmp(dialupstr, "refresh") == 0) - dialup = dns_dialuptype_refresh; - else if (strcasecmp(dialupstr, "passive") == 0) - dialup = dns_dialuptype_passive; - else - INSIST(0); - } - dns_zone_setdialup(zone, dialup); - - obj = NULL; - result = ns_config_get(maps, "zone-statistics", &obj); - INSIST(result == ISC_R_SUCCESS); - RETERR(dns_zone_setstatistics(zone, cfg_obj_asboolean(obj))); - - /* - * Configure master functionality. This applies - * to primary masters (type "master") and slaves - * acting as masters (type "slave"), but not to stubs. - */ - if (ztype != dns_zone_stub) { - obj = NULL; - result = ns_config_get(maps, "notify", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - notifytype = dns_notifytype_yes; - else - notifytype = dns_notifytype_no; - } else { - const char *notifystr = cfg_obj_asstring(obj); - if (strcasecmp(notifystr, "explicit") == 0) - notifytype = dns_notifytype_explicit; - else if (strcasecmp(notifystr, "master-only") == 0) - notifytype = dns_notifytype_masteronly; - else - INSIST(0); - } - dns_zone_setnotifytype(zone, notifytype); - - obj = NULL; - result = ns_config_get(maps, "also-notify", &obj); - if (result == ISC_R_SUCCESS) { - isc_sockaddr_t *addrs = NULL; - isc_uint32_t addrcount; - result = ns_config_getiplist(config, obj, 0, mctx, - &addrs, &addrcount); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_zone_setalsonotify(zone, addrs, - addrcount); - ns_config_putiplist(mctx, &addrs, addrcount); - if (result != ISC_R_SUCCESS) - return (result); - } else - RETERR(dns_zone_setalsonotify(zone, NULL, 0)); - - obj = NULL; - result = ns_config_get(maps, "notify-source", &obj); - INSIST(result == ISC_R_SUCCESS); - RETERR(dns_zone_setnotifysrc4(zone, cfg_obj_assockaddr(obj))); - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - - obj = NULL; - result = ns_config_get(maps, "notify-source-v6", &obj); - INSIST(result == ISC_R_SUCCESS); - RETERR(dns_zone_setnotifysrc6(zone, cfg_obj_assockaddr(obj))); - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - - dns_zone_setisself(zone, ns_client_isself, NULL); - - RETERR(configure_zone_acl(zconfig, vconfig, config, - "allow-transfer", ac, zone, - dns_zone_setxfracl, - dns_zone_clearxfracl)); - - obj = NULL; - result = ns_config_get(maps, "max-transfer-time-out", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setmaxxfrout(zone, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-transfer-idle-out", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setidleout(zone, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-journal-size", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setjournalsize(zone, -1); - if (cfg_obj_isstring(obj)) { - const char *str = cfg_obj_asstring(obj); - INSIST(strcasecmp(str, "unlimited") == 0); - journal_size = ISC_UINT32_MAX / 2; - } else { - isc_resourcevalue_t value; - value = cfg_obj_asuint64(obj); - if (value > ISC_UINT32_MAX / 2) { - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_ERROR, - "'max-journal-size " - "%" ISC_PRINT_QUADFORMAT "d' " - "is too large", - value); - RETERR(ISC_R_RANGE); - } - journal_size = (isc_uint32_t)value; - } - dns_zone_setjournalsize(zone, journal_size); - - obj = NULL; - result = ns_config_get(maps, "ixfr-from-differences", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isboolean(obj)) - ixfrdiff = cfg_obj_asboolean(obj); - else if (strcasecmp(cfg_obj_asstring(obj), "master") && - ztype == dns_zone_master) - ixfrdiff = ISC_TRUE; - else if (strcasecmp(cfg_obj_asstring(obj), "slave") && - ztype == dns_zone_slave) - ixfrdiff = ISC_TRUE; - else - ixfrdiff = ISC_FALSE; - dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS, ixfrdiff); - - checknames(ztype, maps, &obj); - INSIST(obj != NULL); - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - fail = ISC_FALSE; - check = ISC_TRUE; - } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { - fail = check = ISC_TRUE; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - fail = check = ISC_FALSE; - } else - INSIST(0); - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES, check); - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL, fail); - - obj = NULL; - result = ns_config_get(maps, "notify-delay", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setnotifydelay(zone, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "check-sibling", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSIBLING, - cfg_obj_asboolean(obj)); - - obj = NULL; - result = ns_config_get(maps, "zero-no-soa-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setzeronosoattl(zone, cfg_obj_asboolean(obj)); - } - - /* - * Configure update-related options. These apply to - * primary masters only. - */ - if (ztype == dns_zone_master) { - dns_acl_t *updateacl; - RETERR(configure_zone_acl(zconfig, vconfig, config, - "allow-update", ac, zone, - dns_zone_setupdateacl, - dns_zone_clearupdateacl)); - - updateacl = dns_zone_getupdateacl(zone); - if (updateacl != NULL && dns_acl_isinsecure(updateacl)) - isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "zone '%s' allows updates by IP " - "address, which is insecure", - zname); - - RETERR(configure_zone_ssutable(zoptions, zone)); - - obj = NULL; - result = ns_config_get(maps, "sig-validity-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setsigvalidityinterval(zone, - cfg_obj_asuint32(obj) * 86400); - - obj = NULL; - result = ns_config_get(maps, "key-directory", &obj); - if (result == ISC_R_SUCCESS) { - filename = cfg_obj_asstring(obj); - if (!isc_file_isabsolute(filename)) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, - "key-directory '%s' " - "is not absolute", filename); - return (ISC_R_FAILURE); - } - RETERR(dns_zone_setkeydirectory(zone, filename)); - } - - obj = NULL; - result = ns_config_get(maps, "check-wildcard", &obj); - if (result == ISC_R_SUCCESS) - check = cfg_obj_asboolean(obj); - else - check = ISC_FALSE; - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKWILDCARD, check); - - obj = NULL; - result = ns_config_get(maps, "check-mx", &obj); - INSIST(obj != NULL); - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - fail = ISC_FALSE; - check = ISC_TRUE; - } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { - fail = check = ISC_TRUE; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - fail = check = ISC_FALSE; - } else - INSIST(0); - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKMX, check); - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKMXFAIL, fail); - - obj = NULL; - result = ns_config_get(maps, "check-integrity", &obj); - INSIST(obj != NULL); - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKINTEGRITY, - cfg_obj_asboolean(obj)); - - obj = NULL; - result = ns_config_get(maps, "check-mx-cname", &obj); - INSIST(obj != NULL); - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - warn = ISC_TRUE; - ignore = ISC_FALSE; - } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { - warn = ignore = ISC_FALSE; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - warn = ignore = ISC_TRUE; - } else - INSIST(0); - dns_zone_setoption(zone, DNS_ZONEOPT_WARNMXCNAME, warn); - dns_zone_setoption(zone, DNS_ZONEOPT_IGNOREMXCNAME, ignore); - - obj = NULL; - result = ns_config_get(maps, "check-srv-cname", &obj); - INSIST(obj != NULL); - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - warn = ISC_TRUE; - ignore = ISC_FALSE; - } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { - warn = ignore = ISC_FALSE; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - warn = ignore = ISC_TRUE; - } else - INSIST(0); - dns_zone_setoption(zone, DNS_ZONEOPT_WARNSRVCNAME, warn); - dns_zone_setoption(zone, DNS_ZONEOPT_IGNORESRVCNAME, ignore); - - obj = NULL; - result = ns_config_get(maps, "update-check-ksk", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setoption(zone, DNS_ZONEOPT_UPDATECHECKKSK, - cfg_obj_asboolean(obj)); - } - - /* - * Configure update-related options. These apply to - * primary masters only. - */ - if (ztype == dns_zone_master) { - dns_acl_t *updateacl; - RETERR(configure_zone_acl(zconfig, vconfig, config, - "allow-update", ac, zone, - dns_zone_setupdateacl, - dns_zone_clearupdateacl)); - - updateacl = dns_zone_getupdateacl(zone); - if (updateacl != NULL && dns_acl_isinsecure(updateacl)) - isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "zone '%s' allows updates by IP " - "address, which is insecure", - zname); - - RETERR(configure_zone_ssutable(zoptions, zone)); - - obj = NULL; - result = ns_config_get(maps, "sig-validity-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setsigvalidityinterval(zone, - cfg_obj_asuint32(obj) * 86400); - - obj = NULL; - result = ns_config_get(maps, "key-directory", &obj); - if (result == ISC_R_SUCCESS) { - filename = cfg_obj_asstring(obj); - if (!isc_file_isabsolute(filename)) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, - "key-directory '%s' " - "is not absolute", filename); - return (ISC_R_FAILURE); - } - RETERR(dns_zone_setkeydirectory(zone, filename)); - } - - } else if (ztype == dns_zone_slave) { - RETERR(configure_zone_acl(zconfig, vconfig, config, - "allow-update-forwarding", ac, zone, - dns_zone_setforwardacl, - dns_zone_clearforwardacl)); - } - - /* - * Configure slave functionality. - */ - switch (ztype) { - case dns_zone_slave: - case dns_zone_stub: - count = 0; - obj = NULL; - result = cfg_map_get(zoptions, "masters", &obj); - if (obj != NULL) { - addrs = NULL; - keynames = NULL; - RETERR(ns_config_getipandkeylist(config, obj, mctx, - &addrs, &keynames, - &count)); - result = dns_zone_setmasterswithkeys(zone, addrs, - keynames, count); - ns_config_putipandkeylist(mctx, &addrs, &keynames, - count); - } else - result = dns_zone_setmasters(zone, NULL, 0); - RETERR(result); - - multi = ISC_FALSE; - if (count > 1) { - obj = NULL; - result = ns_config_get(maps, "multi-master", &obj); - INSIST(result == ISC_R_SUCCESS); - multi = cfg_obj_asboolean(obj); - } - dns_zone_setoption(zone, DNS_ZONEOPT_MULTIMASTER, multi); - - obj = NULL; - result = ns_config_get(maps, "max-transfer-time-in", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setmaxxfrin(zone, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-transfer-idle-in", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setidlein(zone, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-refresh-time", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setmaxrefreshtime(zone, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "min-refresh-time", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setminrefreshtime(zone, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "max-retry-time", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setmaxretrytime(zone, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "min-retry-time", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setminretrytime(zone, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "transfer-source", &obj); - INSIST(result == ISC_R_SUCCESS); - RETERR(dns_zone_setxfrsource4(zone, cfg_obj_assockaddr(obj))); - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - - obj = NULL; - result = ns_config_get(maps, "transfer-source-v6", &obj); - INSIST(result == ISC_R_SUCCESS); - RETERR(dns_zone_setxfrsource6(zone, cfg_obj_assockaddr(obj))); - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - - obj = NULL; - result = ns_config_get(maps, "alt-transfer-source", &obj); - INSIST(result == ISC_R_SUCCESS); - RETERR(dns_zone_setaltxfrsource4(zone, cfg_obj_assockaddr(obj))); - - obj = NULL; - result = ns_config_get(maps, "alt-transfer-source-v6", &obj); - INSIST(result == ISC_R_SUCCESS); - RETERR(dns_zone_setaltxfrsource6(zone, cfg_obj_assockaddr(obj))); - - obj = NULL; - (void)ns_config_get(maps, "use-alt-transfer-source", &obj); - if (obj == NULL) { - /* - * Default off when views are in use otherwise - * on for BIND 8 compatibility. - */ - view = dns_zone_getview(zone); - if (view != NULL && strcmp(view->name, "_default") == 0) - alt = ISC_TRUE; - else - alt = ISC_FALSE; - } else - alt = cfg_obj_asboolean(obj); - dns_zone_setoption(zone, DNS_ZONEOPT_USEALTXFRSRC, alt); - - break; - - default: - break; - } - - return (ISC_R_SUCCESS); -} - -isc_boolean_t -ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) { - const cfg_obj_t *zoptions = NULL; - const cfg_obj_t *obj = NULL; - const char *cfilename; - const char *zfilename; - - zoptions = cfg_tuple_get(zconfig, "options"); - - if (zonetype_fromconfig(zoptions) != dns_zone_gettype(zone)) - return (ISC_FALSE); - - obj = NULL; - (void)cfg_map_get(zoptions, "file", &obj); - if (obj != NULL) - cfilename = cfg_obj_asstring(obj); - else - cfilename = NULL; - zfilename = dns_zone_getfile(zone); - if (!((cfilename == NULL && zfilename == NULL) || - (cfilename != NULL && zfilename != NULL && - strcmp(cfilename, zfilename) == 0))) - return (ISC_FALSE); - - return (ISC_TRUE); -} diff --git a/contrib/bind9/bin/nsupdate/Makefile.in b/contrib/bind9/bin/nsupdate/Makefile.in deleted file mode 100644 index 6bb22f8..0000000 --- a/contrib/bind9/bin/nsupdate/Makefile.in +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 2000-2002 Internet Software Consortium. -# -# Permission to use, copy, modify, and 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: Makefile.in,v 1.22.18.1 2004/07/20 07:03:20 marka Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -@BIND9_VERSION@ - -@BIND9_MAKE_INCLUDES@ - -CINCLUDES = ${LWRES_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} \ - ${ISC_INCLUDES} - -CDEFINES = -CWARNINGS = - -LWRESLIBS = ../../lib/lwres/liblwres.@A@ -DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ -BIND9LIBS = ../../lib/bind9/libbind9.@A@ -ISCLIBS = ../../lib/isc/libisc.@A@ -ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ - -LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@ -DNSDEPLIBS = ../../lib/dns/libdns.@A@ -BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ -ISCDEPLIBS = ../../lib/isc/libisc.@A@ -ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ - -DEPLIBS = ${DNSDEPLIBS} ${BIND9DEPLIBS} ${ISCDEPLIBS} ${ISCCFGDEPLIBS} - -LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCLIBS} ${ISCCFGLIBS} @LIBS@ - -SUBDIRS = - -TARGETS = nsupdate@EXEEXT@ - -OBJS = nsupdate.@O@ - -UOBJS = - -SRCS = nsupdate.c - -MANPAGES = nsupdate.8 - -HTMLPAGES = nsupdate.html - -MANOBJS = ${MANPAGES} ${HTMLPAGES} - -@BIND9_MAKE_RULES@ - -nsupdate@EXEEXT@: nsupdate.@O@ ${UOBJS} ${DEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ nsupdate.@O@ ${UOBJS} ${LIBS} - -doc man:: ${MANOBJS} - -docclean manclean maintainer-clean:: - rm -f ${MANOBJS} - -clean distclean:: - rm -f ${TARGETS} - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${bindir} - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 - -install:: nsupdate@EXEEXT@ installdirs - ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} nsupdate@EXEEXT@ ${DESTDIR}${bindir} - ${INSTALL_DATA} ${srcdir}/nsupdate.8 ${DESTDIR}${mandir}/man8 diff --git a/contrib/bind9/bin/nsupdate/nsupdate.8 b/contrib/bind9/bin/nsupdate/nsupdate.8 deleted file mode 100644 index 8e3963a..0000000 --- a/contrib/bind9/bin/nsupdate/nsupdate.8 +++ /dev/null @@ -1,348 +0,0 @@ -.\" Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") -.\" Copyright (C) 2000-2003 Internet Software Consortium. -.\" -.\" Permission to use, copy, modify, and 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: nsupdate.8,v 1.30.18.14 2007/05/09 03:33:13 marka Exp $ -.\" -.hy 0 -.ad l -.\" Title: nsupdate -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.71.1 -.\" Date: Jun 30, 2000 -.\" Manual: BIND9 -.\" Source: BIND9 -.\" -.TH "NSUPDATE" "8" "Jun 30, 2000" "BIND9" "BIND9" -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.SH "NAME" -nsupdate \- Dynamic DNS update utility -.SH "SYNOPSIS" -.HP 9 -\fBnsupdate\fR [\fB\-d\fR] [[\fB\-y\ \fR\fB\fI[hmac:]\fR\fIkeyname:secret\fR\fR] | [\fB\-k\ \fR\fB\fIkeyfile\fR\fR]] [\fB\-t\ \fR\fB\fItimeout\fR\fR] [\fB\-u\ \fR\fB\fIudptimeout\fR\fR] [\fB\-r\ \fR\fB\fIudpretries\fR\fR] [\fB\-v\fR] [filename] -.SH "DESCRIPTION" -.PP -\fBnsupdate\fR -is used to submit Dynamic DNS Update requests as defined in RFC2136 to a name server. This allows resource records to be added or removed from a zone without manually editing the zone file. A single update request can contain requests to add or remove more than one resource record. -.PP -Zones that are under dynamic control via -\fBnsupdate\fR -or a DHCP server should not be edited by hand. Manual edits could conflict with dynamic updates and cause data to be lost. -.PP -The resource records that are dynamically added or removed with -\fBnsupdate\fR -have to be in the same zone. Requests are sent to the zone's master server. This is identified by the MNAME field of the zone's SOA record. -.PP -The -\fB\-d\fR -option makes -\fBnsupdate\fR -operate in debug mode. This provides tracing information about the update requests that are made and the replies received from the name server. -.PP -Transaction signatures can be used to authenticate the Dynamic DNS updates. These use the TSIG resource record type described in RFC2845 or the SIG(0) record described in RFC3535 and RFC2931. TSIG relies on a shared secret that should only be known to -\fBnsupdate\fR -and the name server. Currently, the only supported encryption algorithm for TSIG is HMAC\-MD5, which is defined in RFC 2104. Once other algorithms are defined for TSIG, applications will need to ensure they select the appropriate algorithm as well as the key when authenticating each other. For instance, suitable -\fBkey\fR -and -\fBserver\fR -statements would be added to -\fI/etc/named.conf\fR -so that the name server can associate the appropriate secret key and algorithm with the IP address of the client application that will be using TSIG authentication. SIG(0) uses public key cryptography. To use a SIG(0) key, the public key must be stored in a KEY record in a zone served by the name server. -\fBnsupdate\fR -does not read -\fI/etc/named.conf\fR. -.PP -\fBnsupdate\fR -uses the -\fB\-y\fR -or -\fB\-k\fR -option to provide the shared secret needed to generate a TSIG record for authenticating Dynamic DNS update requests, default type HMAC\-MD5. These options are mutually exclusive. With the -\fB\-k\fR -option, -\fBnsupdate\fR -reads the shared secret from the file -\fIkeyfile\fR, whose name is of the form -\fIK{name}.+157.+{random}.private\fR. For historical reasons, the file -\fIK{name}.+157.+{random}.key\fR -must also be present. When the -\fB\-y\fR -option is used, a signature is generated from -[\fIhmac:\fR]\fIkeyname:secret.\fR -\fIkeyname\fR -is the name of the key, and -\fIsecret\fR -is the base64 encoded shared secret. Use of the -\fB\-y\fR -option is discouraged because the shared secret is supplied as a command line argument in clear text. This may be visible in the output from -\fBps\fR(1) -or in a history file maintained by the user's shell. -.PP -The -\fB\-k\fR -may also be used to specify a SIG(0) key used to authenticate Dynamic DNS update requests. In this case, the key specified is not an HMAC\-MD5 key. -.PP -By default -\fBnsupdate\fR -uses UDP to send update requests to the name server unless they are too large to fit in a UDP request in which case TCP will be used. The -\fB\-v\fR -option makes -\fBnsupdate\fR -use a TCP connection. This may be preferable when a batch of update requests is made. -.PP -The -\fB\-t\fR -option sets the maximum time an update request can take before it is aborted. The default is 300 seconds. Zero can be used to disable the timeout. -.PP -The -\fB\-u\fR -option sets the UDP retry interval. The default is 3 seconds. If zero, the interval will be computed from the timeout interval and number of UDP retries. -.PP -The -\fB\-r\fR -option sets the number of UDP retries. The default is 3. If zero, only one update request will be made. -.SH "INPUT FORMAT" -.PP -\fBnsupdate\fR -reads input from -\fIfilename\fR -or standard input. Each command is supplied on exactly one line of input. Some commands are for administrative purposes. The others are either update instructions or prerequisite checks on the contents of the zone. These checks set conditions that some name or set of resource records (RRset) either exists or is absent from the zone. These conditions must be met if the entire update request is to succeed. Updates will be rejected if the tests for the prerequisite conditions fail. -.PP -Every update request consists of zero or more prerequisites and zero or more updates. This allows a suitably authenticated update request to proceed if some specified resource records are present or missing from the zone. A blank input line (or the -\fBsend\fR -command) causes the accumulated commands to be sent as one Dynamic DNS update request to the name server. -.PP -The command formats and their meaning are as follows: -.PP -\fBserver\fR {servername} [port] -.RS 4 -Sends all dynamic update requests to the name server -\fIservername\fR. When no server statement is provided, -\fBnsupdate\fR -will send updates to the master server of the correct zone. The MNAME field of that zone's SOA record will identify the master server for that zone. -\fIport\fR -is the port number on -\fIservername\fR -where the dynamic update requests get sent. If no port number is specified, the default DNS port number of 53 is used. -.RE -.PP -\fBlocal\fR {address} [port] -.RS 4 -Sends all dynamic update requests using the local -\fIaddress\fR. When no local statement is provided, -\fBnsupdate\fR -will send updates using an address and port chosen by the system. -\fIport\fR -can additionally be used to make requests come from a specific port. If no port number is specified, the system will assign one. -.RE -.PP -\fBzone\fR {zonename} -.RS 4 -Specifies that all updates are to be made to the zone -\fIzonename\fR. If no -\fIzone\fR -statement is provided, -\fBnsupdate\fR -will attempt determine the correct zone to update based on the rest of the input. -.RE -.PP -\fBclass\fR {classname} -.RS 4 -Specify the default class. If no -\fIclass\fR -is specified, the default class is -\fIIN\fR. -.RE -.PP -\fBkey\fR {name} {secret} -.RS 4 -Specifies that all updates are to be TSIG\-signed using the -\fIkeyname\fR -\fIkeysecret\fR -pair. The -\fBkey\fR -command overrides any key specified on the command line via -\fB\-y\fR -or -\fB\-k\fR. -.RE -.PP -\fBprereq nxdomain\fR {domain\-name} -.RS 4 -Requires that no resource record of any type exists with name -\fIdomain\-name\fR. -.RE -.PP -\fBprereq yxdomain\fR {domain\-name} -.RS 4 -Requires that -\fIdomain\-name\fR -exists (has as at least one resource record, of any type). -.RE -.PP -\fBprereq nxrrset\fR {domain\-name} [class] {type} -.RS 4 -Requires that no resource record exists of the specified -\fItype\fR, -\fIclass\fR -and -\fIdomain\-name\fR. If -\fIclass\fR -is omitted, IN (internet) is assumed. -.RE -.PP -\fBprereq yxrrset\fR {domain\-name} [class] {type} -.RS 4 -This requires that a resource record of the specified -\fItype\fR, -\fIclass\fR -and -\fIdomain\-name\fR -must exist. If -\fIclass\fR -is omitted, IN (internet) is assumed. -.RE -.PP -\fBprereq yxrrset\fR {domain\-name} [class] {type} {data...} -.RS 4 -The -\fIdata\fR -from each set of prerequisites of this form sharing a common -\fItype\fR, -\fIclass\fR, and -\fIdomain\-name\fR -are combined to form a set of RRs. This set of RRs must exactly match the set of RRs existing in the zone at the given -\fItype\fR, -\fIclass\fR, and -\fIdomain\-name\fR. The -\fIdata\fR -are written in the standard text representation of the resource record's RDATA. -.RE -.PP -\fBupdate delete\fR {domain\-name} [ttl] [class] [type\ [data...]] -.RS 4 -Deletes any resource records named -\fIdomain\-name\fR. If -\fItype\fR -and -\fIdata\fR -is provided, only matching resource records will be removed. The internet class is assumed if -\fIclass\fR -is not supplied. The -\fIttl\fR -is ignored, and is only allowed for compatibility. -.RE -.PP -\fBupdate add\fR {domain\-name} {ttl} [class] {type} {data...} -.RS 4 -Adds a new resource record with the specified -\fIttl\fR, -\fIclass\fR -and -\fIdata\fR. -.RE -.PP -\fBshow\fR -.RS 4 -Displays the current message, containing all of the prerequisites and updates specified since the last send. -.RE -.PP -\fBsend\fR -.RS 4 -Sends the current message. This is equivalent to entering a blank line. -.RE -.PP -\fBanswer\fR -.RS 4 -Displays the answer. -.RE -.PP -Lines beginning with a semicolon are comments and are ignored. -.SH "EXAMPLES" -.PP -The examples below show how -\fBnsupdate\fR -could be used to insert and delete resource records from the -\fBexample.com\fR -zone. Notice that the input in each example contains a trailing blank line so that a group of commands are sent as one dynamic update request to the master name server for -\fBexample.com\fR. -.sp -.RS 4 -.nf -# nsupdate -> update delete oldhost.example.com A -> update add newhost.example.com 86400 A 172.16.1.1 -> send -.fi -.RE -.sp -.PP -Any A records for -\fBoldhost.example.com\fR -are deleted. And an A record for -\fBnewhost.example.com\fR -with IP address 172.16.1.1 is added. The newly\-added record has a 1 day TTL (86400 seconds). -.sp -.RS 4 -.nf -# nsupdate -> prereq nxdomain nickname.example.com -> update add nickname.example.com 86400 CNAME somehost.example.com -> send -.fi -.RE -.sp -.PP -The prerequisite condition gets the name server to check that there are no resource records of any type for -\fBnickname.example.com\fR. If there are, the update request fails. If this name does not exist, a CNAME for it is added. This ensures that when the CNAME is added, it cannot conflict with the long\-standing rule in RFC1034 that a name must not exist as any other record type if it exists as a CNAME. (The rule has been updated for DNSSEC in RFC2535 to allow CNAMEs to have RRSIG, DNSKEY and NSEC records.) -.SH "FILES" -.PP -\fB/etc/resolv.conf\fR -.RS 4 -used to identify default name server -.RE -.PP -\fBK{name}.+157.+{random}.key\fR -.RS 4 -base\-64 encoding of HMAC\-MD5 key created by -\fBdnssec\-keygen\fR(8). -.RE -.PP -\fBK{name}.+157.+{random}.private\fR -.RS 4 -base\-64 encoding of HMAC\-MD5 key created by -\fBdnssec\-keygen\fR(8). -.RE -.SH "SEE ALSO" -.PP -\fBRFC2136\fR(), -\fBRFC3007\fR(), -\fBRFC2104\fR(), -\fBRFC2845\fR(), -\fBRFC1034\fR(), -\fBRFC2535\fR(), -\fBRFC2931\fR(), -\fBnamed\fR(8), -\fBdnssec\-keygen\fR(8). -.SH "BUGS" -.PP -The TSIG key is redundantly stored in two separate files. This is a consequence of nsupdate using the DST library for its cryptographic operations, and may change in future releases. -.SH "COPYRIGHT" -Copyright \(co 2004\-2007 Internet Systems Consortium, Inc. ("ISC") -.br -Copyright \(co 2000\-2003 Internet Software Consortium. -.br diff --git a/contrib/bind9/bin/nsupdate/nsupdate.c b/contrib/bind9/bin/nsupdate/nsupdate.c deleted file mode 100644 index 7f10174..0000000 --- a/contrib/bind9/bin/nsupdate/nsupdate.c +++ /dev/null @@ -1,2176 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-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: nsupdate.c,v 1.130.18.19 2007/08/28 07:20:01 tbox Exp $ */ - -/*! \file */ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include - -#ifdef HAVE_ADDRINFO -#ifdef HAVE_GETADDRINFO -#ifdef HAVE_GAISTRERROR -#define USE_GETADDRINFO -#endif -#endif -#endif - -#ifndef USE_GETADDRINFO -#ifndef ISC_PLATFORM_NONSTDHERRNO -extern int h_errno; -#endif -#endif - -#define MAXCMD (4 * 1024) -#define MAXWIRE (64 * 1024) -#define PACKETSIZE ((64 * 1024) - 1) -#define INITTEXT (2 * 1024) -#define MAXTEXT (128 * 1024) -#define FIND_TIMEOUT 5 -#define TTL_MAX 2147483647U /* Maximum signed 32 bit integer. */ - -#define DNSDEFAULTPORT 53 - -#ifndef RESOLV_CONF -#define RESOLV_CONF "/etc/resolv.conf" -#endif - -static isc_boolean_t debugging = ISC_FALSE, ddebugging = ISC_FALSE; -static isc_boolean_t memdebugging = ISC_FALSE; -static isc_boolean_t have_ipv4 = ISC_FALSE; -static isc_boolean_t have_ipv6 = ISC_FALSE; -static isc_boolean_t is_dst_up = ISC_FALSE; -static isc_boolean_t usevc = ISC_FALSE; -static isc_taskmgr_t *taskmgr = NULL; -static isc_task_t *global_task = NULL; -static isc_event_t *global_event = NULL; -static isc_mem_t *mctx = NULL; -static dns_dispatchmgr_t *dispatchmgr = NULL; -static dns_requestmgr_t *requestmgr = NULL; -static isc_socketmgr_t *socketmgr = NULL; -static isc_timermgr_t *timermgr = NULL; -static dns_dispatch_t *dispatchv4 = NULL; -static dns_dispatch_t *dispatchv6 = NULL; -static dns_message_t *updatemsg = NULL; -static dns_fixedname_t fuserzone; -static dns_name_t *userzone = NULL; -static dns_tsigkey_t *tsigkey = NULL; -static dst_key_t *sig0key; -static lwres_context_t *lwctx = NULL; -static lwres_conf_t *lwconf; -static isc_sockaddr_t *servers; -static int ns_inuse = 0; -static int ns_total = 0; -static isc_sockaddr_t *userserver = NULL; -static isc_sockaddr_t *localaddr = NULL; -static char *keystr = NULL, *keyfile = NULL; -static isc_entropy_t *entp = NULL; -static isc_boolean_t shuttingdown = ISC_FALSE; -static FILE *input; -static isc_boolean_t interactive = ISC_TRUE; -static isc_boolean_t seenerror = ISC_FALSE; -static const dns_master_style_t *style; -static int requests = 0; -static unsigned int timeout = 300; -static unsigned int udp_timeout = 3; -static unsigned int udp_retries = 3; -static dns_rdataclass_t defaultclass = dns_rdataclass_in; -static dns_rdataclass_t zoneclass = dns_rdataclass_none; -static dns_message_t *answer = NULL; - -typedef struct nsu_requestinfo { - dns_message_t *msg; - isc_sockaddr_t *addr; -} nsu_requestinfo_t; - -static void -sendrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - dns_message_t *msg, dns_request_t **request); -static void -fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); - -static void -debug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); - -static void -ddebug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); - -static void -error(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); - -#define STATUS_MORE (isc_uint16_t)0 -#define STATUS_SEND (isc_uint16_t)1 -#define STATUS_QUIT (isc_uint16_t)2 -#define STATUS_SYNTAX (isc_uint16_t)3 - -static dns_rdataclass_t -getzoneclass(void) { - if (zoneclass == dns_rdataclass_none) - zoneclass = defaultclass; - return (zoneclass); -} - -static isc_boolean_t -setzoneclass(dns_rdataclass_t rdclass) { - if (zoneclass == dns_rdataclass_none || - rdclass == dns_rdataclass_none) - zoneclass = rdclass; - if (zoneclass != rdclass) - return (ISC_FALSE); - return (ISC_TRUE); -} - -static void -fatal(const char *format, ...) { - va_list args; - - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); - fprintf(stderr, "\n"); - exit(1); -} - -static void -error(const char *format, ...) { - va_list args; - - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); - fprintf(stderr, "\n"); -} - -static void -debug(const char *format, ...) { - va_list args; - - if (debugging) { - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); - fprintf(stderr, "\n"); - } -} - -static void -ddebug(const char *format, ...) { - va_list args; - - if (ddebugging) { - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); - fprintf(stderr, "\n"); - } -} - -static inline void -check_result(isc_result_t result, const char *msg) { - if (result != ISC_R_SUCCESS) - fatal("%s: %s", msg, isc_result_totext(result)); -} - -static void * -mem_alloc(void *arg, size_t size) { - return (isc_mem_get(arg, size)); -} - -static void -mem_free(void *arg, void *mem, size_t size) { - isc_mem_put(arg, mem, size); -} - -static char * -nsu_strsep(char **stringp, const char *delim) { - char *string = *stringp; - char *s; - const char *d; - char sc, dc; - - if (string == NULL) - return (NULL); - - for (; *string != '\0'; string++) { - sc = *string; - for (d = delim; (dc = *d) != '\0'; d++) { - if (sc == dc) - break; - } - if (dc == 0) - break; - } - - for (s = string; *s != '\0'; s++) { - sc = *s; - for (d = delim; (dc = *d) != '\0'; d++) { - if (sc == dc) { - *s++ = '\0'; - *stringp = s; - return (string); - } - } - } - *stringp = NULL; - return (string); -} - -static void -reset_system(void) { - isc_result_t result; - - ddebug("reset_system()"); - /* If the update message is still around, destroy it */ - if (updatemsg != NULL) - dns_message_reset(updatemsg, DNS_MESSAGE_INTENTRENDER); - else { - result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, - &updatemsg); - check_result(result, "dns_message_create"); - } - updatemsg->opcode = dns_opcode_update; -} - -static isc_uint16_t -parse_hmac(dns_name_t **hmac, const char *hmacstr, size_t len) { - isc_uint16_t digestbits = 0; - isc_result_t result; - char buf[20]; - - REQUIRE(hmac != NULL && *hmac == NULL); - REQUIRE(hmacstr != NULL); - - if (len >= sizeof(buf)) - fatal("unknown key type '%.*s'", (int)(len), hmacstr); - - strncpy(buf, hmacstr, len); - buf[len] = 0; - - if (strcasecmp(buf, "hmac-md5") == 0) { - *hmac = DNS_TSIG_HMACMD5_NAME; - } else if (strncasecmp(buf, "hmac-md5-", 9) == 0) { - *hmac = DNS_TSIG_HMACMD5_NAME; - result = isc_parse_uint16(&digestbits, &buf[9], 10); - if (result != ISC_R_SUCCESS || digestbits > 128) - fatal("digest-bits out of range [0..128]"); - digestbits = (digestbits +7) & ~0x7U; - } else if (strcasecmp(buf, "hmac-sha1") == 0) { - *hmac = DNS_TSIG_HMACSHA1_NAME; - } else if (strncasecmp(buf, "hmac-sha1-", 10) == 0) { - *hmac = DNS_TSIG_HMACSHA1_NAME; - result = isc_parse_uint16(&digestbits, &buf[10], 10); - if (result != ISC_R_SUCCESS || digestbits > 160) - fatal("digest-bits out of range [0..160]"); - digestbits = (digestbits +7) & ~0x7U; - } else if (strcasecmp(buf, "hmac-sha224") == 0) { - *hmac = DNS_TSIG_HMACSHA224_NAME; - } else if (strncasecmp(buf, "hmac-sha224-", 12) == 0) { - *hmac = DNS_TSIG_HMACSHA224_NAME; - result = isc_parse_uint16(&digestbits, &buf[12], 10); - if (result != ISC_R_SUCCESS || digestbits > 224) - fatal("digest-bits out of range [0..224]"); - digestbits = (digestbits +7) & ~0x7U; - } else if (strcasecmp(buf, "hmac-sha256") == 0) { - *hmac = DNS_TSIG_HMACSHA256_NAME; - } else if (strncasecmp(buf, "hmac-sha256-", 12) == 0) { - *hmac = DNS_TSIG_HMACSHA256_NAME; - result = isc_parse_uint16(&digestbits, &buf[12], 10); - if (result != ISC_R_SUCCESS || digestbits > 256) - fatal("digest-bits out of range [0..256]"); - digestbits = (digestbits +7) & ~0x7U; - } else if (strcasecmp(buf, "hmac-sha384") == 0) { - *hmac = DNS_TSIG_HMACSHA384_NAME; - } else if (strncasecmp(buf, "hmac-sha384-", 12) == 0) { - *hmac = DNS_TSIG_HMACSHA384_NAME; - result = isc_parse_uint16(&digestbits, &buf[12], 10); - if (result != ISC_R_SUCCESS || digestbits > 384) - fatal("digest-bits out of range [0..384]"); - digestbits = (digestbits +7) & ~0x7U; - } else if (strcasecmp(buf, "hmac-sha512") == 0) { - *hmac = DNS_TSIG_HMACSHA512_NAME; - } else if (strncasecmp(buf, "hmac-sha512-", 12) == 0) { - *hmac = DNS_TSIG_HMACSHA512_NAME; - result = isc_parse_uint16(&digestbits, &buf[12], 10); - if (result != ISC_R_SUCCESS || digestbits > 512) - fatal("digest-bits out of range [0..512]"); - digestbits = (digestbits +7) & ~0x7U; - } else - fatal("unknown key type '%s'", buf); - return (digestbits); -} - -static void -setup_keystr(void) { - unsigned char *secret = NULL; - int secretlen; - isc_buffer_t secretbuf; - isc_result_t result; - isc_buffer_t keynamesrc; - char *secretstr; - char *s, *n; - dns_fixedname_t fkeyname; - dns_name_t *keyname; - char *name; - dns_name_t *hmacname = NULL; - isc_uint16_t digestbits = 0; - - dns_fixedname_init(&fkeyname); - keyname = dns_fixedname_name(&fkeyname); - - debug("Creating key..."); - - s = strchr(keystr, ':'); - if (s == NULL || s == keystr || s[1] == 0) - fatal("key option must specify [hmac:]keyname:secret"); - secretstr = s + 1; - n = strchr(secretstr, ':'); - if (n != NULL) { - if (n == secretstr || n[1] == 0) - fatal("key option must specify [hmac:]keyname:secret"); - name = secretstr; - secretstr = n + 1; - digestbits = parse_hmac(&hmacname, keystr, s - keystr); - } else { - hmacname = DNS_TSIG_HMACMD5_NAME; - name = keystr; - n = s; - } - - isc_buffer_init(&keynamesrc, name, n - name); - isc_buffer_add(&keynamesrc, n - name); - - debug("namefromtext"); - result = dns_name_fromtext(keyname, &keynamesrc, dns_rootname, - ISC_FALSE, NULL); - check_result(result, "dns_name_fromtext"); - - secretlen = strlen(secretstr) * 3 / 4; - secret = isc_mem_allocate(mctx, secretlen); - if (secret == NULL) - fatal("out of memory"); - - isc_buffer_init(&secretbuf, secret, secretlen); - result = isc_base64_decodestring(secretstr, &secretbuf); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "could not create key from %s: %s\n", - keystr, isc_result_totext(result)); - goto failure; - } - - secretlen = isc_buffer_usedlength(&secretbuf); - - debug("keycreate"); - result = dns_tsigkey_create(keyname, hmacname, secret, secretlen, - ISC_TRUE, NULL, 0, 0, mctx, NULL, &tsigkey); - if (result != ISC_R_SUCCESS) - fprintf(stderr, "could not create key from %s: %s\n", - keystr, dns_result_totext(result)); - else - dst_key_setbits(tsigkey->key, digestbits); - failure: - if (secret != NULL) - isc_mem_free(mctx, secret); -} - -static void -setup_keyfile(void) { - dst_key_t *dstkey = NULL; - isc_result_t result; - dns_name_t *hmacname = NULL; - - debug("Creating key..."); - - result = dst_key_fromnamedfile(keyfile, - DST_TYPE_PRIVATE | DST_TYPE_KEY, mctx, - &dstkey); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "could not read key from %s: %s\n", - keyfile, isc_result_totext(result)); - return; - } - switch (dst_key_alg(dstkey)) { - case DST_ALG_HMACMD5: - hmacname = DNS_TSIG_HMACMD5_NAME; - break; - case DST_ALG_HMACSHA1: - hmacname = DNS_TSIG_HMACSHA1_NAME; - break; - case DST_ALG_HMACSHA224: - hmacname = DNS_TSIG_HMACSHA224_NAME; - break; - case DST_ALG_HMACSHA256: - hmacname = DNS_TSIG_HMACSHA256_NAME; - break; - case DST_ALG_HMACSHA384: - hmacname = DNS_TSIG_HMACSHA384_NAME; - break; - case DST_ALG_HMACSHA512: - hmacname = DNS_TSIG_HMACSHA512_NAME; - break; - } - if (hmacname != NULL) { - result = dns_tsigkey_createfromkey(dst_key_name(dstkey), - hmacname, dstkey, ISC_FALSE, - NULL, 0, 0, mctx, NULL, - &tsigkey); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "could not create key from %s: %s\n", - keyfile, isc_result_totext(result)); - dst_key_free(&dstkey); - return; - } - } else - sig0key = dstkey; -} - -static void -doshutdown(void) { - isc_task_detach(&global_task); - - if (userserver != NULL) - isc_mem_put(mctx, userserver, sizeof(isc_sockaddr_t)); - - if (localaddr != NULL) - isc_mem_put(mctx, localaddr, sizeof(isc_sockaddr_t)); - - if (tsigkey != NULL) { - ddebug("Freeing TSIG key"); - dns_tsigkey_detach(&tsigkey); - } - - if (sig0key != NULL) { - ddebug("Freeing SIG(0) key"); - dst_key_free(&sig0key); - } - - if (updatemsg != NULL) - dns_message_destroy(&updatemsg); - - if (is_dst_up) { - ddebug("Destroy DST lib"); - dst_lib_destroy(); - is_dst_up = ISC_FALSE; - } - - if (entp != NULL) { - ddebug("Detach from entropy"); - isc_entropy_detach(&entp); - } - - lwres_conf_clear(lwctx); - lwres_context_destroy(&lwctx); - - isc_mem_put(mctx, servers, ns_total * sizeof(isc_sockaddr_t)); - - ddebug("Destroying request manager"); - dns_requestmgr_detach(&requestmgr); - - ddebug("Freeing the dispatchers"); - if (have_ipv4) - dns_dispatch_detach(&dispatchv4); - if (have_ipv6) - dns_dispatch_detach(&dispatchv6); - - ddebug("Shutting down dispatch manager"); - dns_dispatchmgr_destroy(&dispatchmgr); - -} - -static void -maybeshutdown(void) { - ddebug("Shutting down request manager"); - dns_requestmgr_shutdown(requestmgr); - - if (requests != 0) - return; - - doshutdown(); -} - -static void -shutdown_program(isc_task_t *task, isc_event_t *event) { - REQUIRE(task == global_task); - UNUSED(task); - - ddebug("shutdown_program()"); - isc_event_free(&event); - - shuttingdown = ISC_TRUE; - maybeshutdown(); -} - -static void -setup_system(void) { - isc_result_t result; - isc_sockaddr_t bind_any, bind_any6; - lwres_result_t lwresult; - unsigned int attrs, attrmask; - int i; - - ddebug("setup_system()"); - - dns_result_register(); - - result = isc_net_probeipv4(); - if (result == ISC_R_SUCCESS) - have_ipv4 = ISC_TRUE; - - result = isc_net_probeipv6(); - if (result == ISC_R_SUCCESS) - have_ipv6 = ISC_TRUE; - - if (!have_ipv4 && !have_ipv6) - fatal("could not find either IPv4 or IPv6"); - - result = isc_mem_create(0, 0, &mctx); - check_result(result, "isc_mem_create"); - - lwresult = lwres_context_create(&lwctx, mctx, mem_alloc, mem_free, 1); - if (lwresult != LWRES_R_SUCCESS) - fatal("lwres_context_create failed"); - - (void)lwres_conf_parse(lwctx, RESOLV_CONF); - lwconf = lwres_conf_get(lwctx); - - ns_total = lwconf->nsnext; - if (ns_total <= 0) { - /* No name servers in resolv.conf; default to loopback. */ - struct in_addr localhost; - ns_total = 1; - servers = isc_mem_get(mctx, ns_total * sizeof(isc_sockaddr_t)); - if (servers == NULL) - fatal("out of memory"); - localhost.s_addr = htonl(INADDR_LOOPBACK); - isc_sockaddr_fromin(&servers[0], &localhost, DNSDEFAULTPORT); - } else { - servers = isc_mem_get(mctx, ns_total * sizeof(isc_sockaddr_t)); - if (servers == NULL) - fatal("out of memory"); - for (i = 0; i < ns_total; i++) { - if (lwconf->nameservers[i].family == LWRES_ADDRTYPE_V4) { - struct in_addr in4; - memcpy(&in4, lwconf->nameservers[i].address, 4); - isc_sockaddr_fromin(&servers[i], &in4, DNSDEFAULTPORT); - } else { - struct in6_addr in6; - memcpy(&in6, lwconf->nameservers[i].address, 16); - isc_sockaddr_fromin6(&servers[i], &in6, - DNSDEFAULTPORT); - } - } - } - - result = isc_entropy_create(mctx, &entp); - check_result(result, "isc_entropy_create"); - - result = isc_hash_create(mctx, entp, DNS_NAME_MAXWIRE); - check_result(result, "isc_hash_create"); - isc_hash_init(); - - result = dns_dispatchmgr_create(mctx, entp, &dispatchmgr); - check_result(result, "dns_dispatchmgr_create"); - - result = isc_socketmgr_create(mctx, &socketmgr); - check_result(result, "dns_socketmgr_create"); - - result = isc_timermgr_create(mctx, &timermgr); - check_result(result, "dns_timermgr_create"); - - result = isc_taskmgr_create(mctx, 1, 0, &taskmgr); - check_result(result, "isc_taskmgr_create"); - - result = isc_task_create(taskmgr, 0, &global_task); - check_result(result, "isc_task_create"); - - result = isc_task_onshutdown(global_task, shutdown_program, NULL); - check_result(result, "isc_task_onshutdown"); - - result = dst_lib_init(mctx, entp, 0); - check_result(result, "dst_lib_init"); - is_dst_up = ISC_TRUE; - - attrmask = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP; - attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6; - - if (have_ipv6) { - attrs = DNS_DISPATCHATTR_UDP; - attrs |= DNS_DISPATCHATTR_MAKEQUERY; - attrs |= DNS_DISPATCHATTR_IPV6; - isc_sockaddr_any6(&bind_any6); - result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, - &bind_any6, PACKETSIZE, - 4, 2, 3, 5, - attrs, attrmask, &dispatchv6); - check_result(result, "dns_dispatch_getudp (v6)"); - } - - if (have_ipv4) { - attrs = DNS_DISPATCHATTR_UDP; - attrs |= DNS_DISPATCHATTR_MAKEQUERY; - attrs |= DNS_DISPATCHATTR_IPV4; - isc_sockaddr_any(&bind_any); - result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, - &bind_any, PACKETSIZE, - 4, 2, 3, 5, - attrs, attrmask, &dispatchv4); - check_result(result, "dns_dispatch_getudp (v4)"); - } - - result = dns_requestmgr_create(mctx, timermgr, - socketmgr, taskmgr, dispatchmgr, - dispatchv4, dispatchv6, &requestmgr); - check_result(result, "dns_requestmgr_create"); - - if (keystr != NULL) - setup_keystr(); - else if (keyfile != NULL) - setup_keyfile(); -} - -static void -get_address(char *host, in_port_t port, isc_sockaddr_t *sockaddr) { - int count; - isc_result_t result; - - isc_app_block(); - result = bind9_getaddresses(host, port, sockaddr, 1, &count); - isc_app_unblock(); - if (result != ISC_R_SUCCESS) - fatal("couldn't get address for '%s': %s", - host, isc_result_totext(result)); - INSIST(count == 1); -} - -static void -parse_args(int argc, char **argv) { - int ch; - isc_result_t result; - - debug("parse_args"); - while ((ch = isc_commandline_parse(argc, argv, "dDMy:vk:r:t:u:")) != -1) - { - switch (ch) { - case 'd': - debugging = ISC_TRUE; - break; - case 'D': /* was -dd */ - debugging = ISC_TRUE; - ddebugging = ISC_TRUE; - break; - case 'M': /* was -dm */ - debugging = ISC_TRUE; - ddebugging = ISC_TRUE; - memdebugging = ISC_TRUE; - isc_mem_debugging = ISC_MEM_DEBUGTRACE | - ISC_MEM_DEBUGRECORD; - break; - case 'y': - keystr = isc_commandline_argument; - break; - case 'v': - usevc = ISC_TRUE; - break; - case 'k': - keyfile = isc_commandline_argument; - break; - case 't': - result = isc_parse_uint32(&timeout, - isc_commandline_argument, 10); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "bad timeout '%s'\n", isc_commandline_argument); - exit(1); - } - if (timeout == 0) - timeout = UINT_MAX; - break; - case 'u': - result = isc_parse_uint32(&udp_timeout, - isc_commandline_argument, 10); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "bad udp timeout '%s'\n", isc_commandline_argument); - exit(1); - } - if (udp_timeout == 0) - udp_timeout = UINT_MAX; - break; - case 'r': - result = isc_parse_uint32(&udp_retries, - isc_commandline_argument, 10); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "bad udp retries '%s'\n", isc_commandline_argument); - exit(1); - } - break; - default: - fprintf(stderr, "%s: invalid argument -%c\n", - argv[0], ch); - fprintf(stderr, "usage: nsupdate [-d] " - "[-y keyname:secret | -k keyfile] [-v] " - "[filename]\n"); - exit(1); - } - } - if (keyfile != NULL && keystr != NULL) { - fprintf(stderr, "%s: cannot specify both -k and -y\n", - argv[0]); - exit(1); - } - - if (argv[isc_commandline_index] != NULL) { - if (strcmp(argv[isc_commandline_index], "-") == 0) { - input = stdin; - } else { - result = isc_stdio_open(argv[isc_commandline_index], - "r", &input); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "could not open '%s': %s\n", - argv[isc_commandline_index], - isc_result_totext(result)); - exit(1); - } - } - interactive = ISC_FALSE; - } -} - -static isc_uint16_t -parse_name(char **cmdlinep, dns_message_t *msg, dns_name_t **namep) { - isc_result_t result; - char *word; - isc_buffer_t *namebuf = NULL; - isc_buffer_t source; - - word = nsu_strsep(cmdlinep, " \t\r\n"); - if (*word == 0) { - fprintf(stderr, "could not read owner name\n"); - return (STATUS_SYNTAX); - } - - result = dns_message_gettempname(msg, namep); - check_result(result, "dns_message_gettempname"); - result = isc_buffer_allocate(mctx, &namebuf, DNS_NAME_MAXWIRE); - check_result(result, "isc_buffer_allocate"); - dns_name_init(*namep, NULL); - dns_name_setbuffer(*namep, namebuf); - dns_message_takebuffer(msg, &namebuf); - isc_buffer_init(&source, word, strlen(word)); - isc_buffer_add(&source, strlen(word)); - result = dns_name_fromtext(*namep, &source, dns_rootname, - ISC_FALSE, NULL); - check_result(result, "dns_name_fromtext"); - isc_buffer_invalidate(&source); - return (STATUS_MORE); -} - -static isc_uint16_t -parse_rdata(char **cmdlinep, dns_rdataclass_t rdataclass, - dns_rdatatype_t rdatatype, dns_message_t *msg, - dns_rdata_t *rdata) -{ - char *cmdline = *cmdlinep; - isc_buffer_t source, *buf = NULL, *newbuf = NULL; - isc_region_t r; - isc_lex_t *lex = NULL; - dns_rdatacallbacks_t callbacks; - isc_result_t result; - - while (*cmdline != 0 && isspace((unsigned char)*cmdline)) - cmdline++; - - if (*cmdline != 0) { - dns_rdatacallbacks_init(&callbacks); - result = isc_lex_create(mctx, strlen(cmdline), &lex); - check_result(result, "isc_lex_create"); - isc_buffer_init(&source, cmdline, strlen(cmdline)); - isc_buffer_add(&source, strlen(cmdline)); - result = isc_lex_openbuffer(lex, &source); - check_result(result, "isc_lex_openbuffer"); - result = isc_buffer_allocate(mctx, &buf, MAXWIRE); - check_result(result, "isc_buffer_allocate"); - result = dns_rdata_fromtext(rdata, rdataclass, rdatatype, lex, - dns_rootname, 0, mctx, buf, - &callbacks); - isc_lex_destroy(&lex); - if (result == ISC_R_SUCCESS) { - isc_buffer_usedregion(buf, &r); - result = isc_buffer_allocate(mctx, &newbuf, r.length); - check_result(result, "isc_buffer_allocate"); - isc_buffer_putmem(newbuf, r.base, r.length); - isc_buffer_usedregion(newbuf, &r); - dns_rdata_fromregion(rdata, rdataclass, rdatatype, &r); - isc_buffer_free(&buf); - dns_message_takebuffer(msg, &newbuf); - } else { - fprintf(stderr, "invalid rdata format: %s\n", - isc_result_totext(result)); - isc_buffer_free(&buf); - return (STATUS_SYNTAX); - } - } else { - rdata->flags = DNS_RDATA_UPDATE; - } - *cmdlinep = cmdline; - return (STATUS_MORE); -} - -static isc_uint16_t -make_prereq(char *cmdline, isc_boolean_t ispositive, isc_boolean_t isrrset) { - isc_result_t result; - char *word; - dns_name_t *name = NULL; - isc_textregion_t region; - dns_rdataset_t *rdataset = NULL; - dns_rdatalist_t *rdatalist = NULL; - dns_rdataclass_t rdataclass; - dns_rdatatype_t rdatatype; - dns_rdata_t *rdata = NULL; - isc_uint16_t retval; - - ddebug("make_prereq()"); - - /* - * Read the owner name - */ - retval = parse_name(&cmdline, updatemsg, &name); - if (retval != STATUS_MORE) - return (retval); - - /* - * If this is an rrset prereq, read the class or type. - */ - if (isrrset) { - word = nsu_strsep(&cmdline, " \t\r\n"); - if (*word == 0) { - fprintf(stderr, "could not read class or type\n"); - goto failure; - } - region.base = word; - region.length = strlen(word); - result = dns_rdataclass_fromtext(&rdataclass, ®ion); - if (result == ISC_R_SUCCESS) { - if (!setzoneclass(rdataclass)) { - fprintf(stderr, "class mismatch: %s\n", word); - goto failure; - } - /* - * Now read the type. - */ - word = nsu_strsep(&cmdline, " \t\r\n"); - if (*word == 0) { - fprintf(stderr, "could not read type\n"); - goto failure; - } - region.base = word; - region.length = strlen(word); - result = dns_rdatatype_fromtext(&rdatatype, ®ion); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "invalid type: %s\n", word); - goto failure; - } - } else { - rdataclass = getzoneclass(); - result = dns_rdatatype_fromtext(&rdatatype, ®ion); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "invalid type: %s\n", word); - goto failure; - } - } - } else - rdatatype = dns_rdatatype_any; - - result = dns_message_gettemprdata(updatemsg, &rdata); - check_result(result, "dns_message_gettemprdata"); - - rdata->data = NULL; - rdata->length = 0; - - if (isrrset && ispositive) { - retval = parse_rdata(&cmdline, rdataclass, rdatatype, - updatemsg, rdata); - if (retval != STATUS_MORE) - goto failure; - } else - rdata->flags = DNS_RDATA_UPDATE; - - result = dns_message_gettemprdatalist(updatemsg, &rdatalist); - check_result(result, "dns_message_gettemprdatalist"); - result = dns_message_gettemprdataset(updatemsg, &rdataset); - check_result(result, "dns_message_gettemprdataset"); - dns_rdatalist_init(rdatalist); - rdatalist->type = rdatatype; - if (ispositive) { - if (isrrset && rdata->data != NULL) - rdatalist->rdclass = rdataclass; - else - rdatalist->rdclass = dns_rdataclass_any; - } else - rdatalist->rdclass = dns_rdataclass_none; - rdatalist->covers = 0; - rdatalist->ttl = 0; - rdata->rdclass = rdatalist->rdclass; - rdata->type = rdatatype; - ISC_LIST_INIT(rdatalist->rdata); - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - dns_rdataset_init(rdataset); - dns_rdatalist_tordataset(rdatalist, rdataset); - ISC_LIST_INIT(name->list); - ISC_LIST_APPEND(name->list, rdataset, link); - dns_message_addname(updatemsg, name, DNS_SECTION_PREREQUISITE); - return (STATUS_MORE); - - failure: - if (name != NULL) - dns_message_puttempname(updatemsg, &name); - return (STATUS_SYNTAX); -} - -static isc_uint16_t -evaluate_prereq(char *cmdline) { - char *word; - isc_boolean_t ispositive, isrrset; - - ddebug("evaluate_prereq()"); - word = nsu_strsep(&cmdline, " \t\r\n"); - if (*word == 0) { - fprintf(stderr, "could not read operation code\n"); - return (STATUS_SYNTAX); - } - if (strcasecmp(word, "nxdomain") == 0) { - ispositive = ISC_FALSE; - isrrset = ISC_FALSE; - } else if (strcasecmp(word, "yxdomain") == 0) { - ispositive = ISC_TRUE; - isrrset = ISC_FALSE; - } else if (strcasecmp(word, "nxrrset") == 0) { - ispositive = ISC_FALSE; - isrrset = ISC_TRUE; - } else if (strcasecmp(word, "yxrrset") == 0) { - ispositive = ISC_TRUE; - isrrset = ISC_TRUE; - } else { - fprintf(stderr, "incorrect operation code: %s\n", word); - return (STATUS_SYNTAX); - } - return (make_prereq(cmdline, ispositive, isrrset)); -} - -static isc_uint16_t -evaluate_server(char *cmdline) { - char *word, *server; - long port; - - word = nsu_strsep(&cmdline, " \t\r\n"); - if (*word == 0) { - fprintf(stderr, "could not read server name\n"); - return (STATUS_SYNTAX); - } - server = word; - - word = nsu_strsep(&cmdline, " \t\r\n"); - if (*word == 0) - port = DNSDEFAULTPORT; - else { - char *endp; - port = strtol(word, &endp, 10); - if (*endp != 0) { - fprintf(stderr, "port '%s' is not numeric\n", word); - return (STATUS_SYNTAX); - } else if (port < 1 || port > 65535) { - fprintf(stderr, "port '%s' is out of range " - "(1 to 65535)\n", word); - return (STATUS_SYNTAX); - } - } - - if (userserver == NULL) { - userserver = isc_mem_get(mctx, sizeof(isc_sockaddr_t)); - if (userserver == NULL) - fatal("out of memory"); - } - - get_address(server, (in_port_t)port, userserver); - - return (STATUS_MORE); -} - -static isc_uint16_t -evaluate_local(char *cmdline) { - char *word, *local; - long port; - struct in_addr in4; - struct in6_addr in6; - - word = nsu_strsep(&cmdline, " \t\r\n"); - if (*word == 0) { - fprintf(stderr, "could not read server name\n"); - return (STATUS_SYNTAX); - } - local = word; - - word = nsu_strsep(&cmdline, " \t\r\n"); - if (*word == 0) - port = 0; - else { - char *endp; - port = strtol(word, &endp, 10); - if (*endp != 0) { - fprintf(stderr, "port '%s' is not numeric\n", word); - return (STATUS_SYNTAX); - } else if (port < 1 || port > 65535) { - fprintf(stderr, "port '%s' is out of range " - "(1 to 65535)\n", word); - return (STATUS_SYNTAX); - } - } - - if (localaddr == NULL) { - localaddr = isc_mem_get(mctx, sizeof(isc_sockaddr_t)); - if (localaddr == NULL) - fatal("out of memory"); - } - - if (have_ipv6 && inet_pton(AF_INET6, local, &in6) == 1) - isc_sockaddr_fromin6(localaddr, &in6, (in_port_t)port); - else if (have_ipv4 && inet_pton(AF_INET, local, &in4) == 1) - isc_sockaddr_fromin(localaddr, &in4, (in_port_t)port); - else { - fprintf(stderr, "invalid address %s", local); - return (STATUS_SYNTAX); - } - - return (STATUS_MORE); -} - -static isc_uint16_t -evaluate_key(char *cmdline) { - char *namestr; - char *secretstr; - isc_buffer_t b; - isc_result_t result; - dns_fixedname_t fkeyname; - dns_name_t *keyname; - int secretlen; - unsigned char *secret = NULL; - isc_buffer_t secretbuf; - dns_name_t *hmacname = NULL; - isc_uint16_t digestbits = 0; - char *n; - - namestr = nsu_strsep(&cmdline, " \t\r\n"); - if (*namestr == 0) { - fprintf(stderr, "could not read key name\n"); - return (STATUS_SYNTAX); - } - - dns_fixedname_init(&fkeyname); - keyname = dns_fixedname_name(&fkeyname); - - n = strchr(namestr, ':'); - if (n != NULL) { - digestbits = parse_hmac(&hmacname, namestr, n - namestr); - namestr = n + 1; - } else - hmacname = DNS_TSIG_HMACMD5_NAME; - - isc_buffer_init(&b, namestr, strlen(namestr)); - isc_buffer_add(&b, strlen(namestr)); - result = dns_name_fromtext(keyname, &b, dns_rootname, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "could not parse key name\n"); - return (STATUS_SYNTAX); - } - - secretstr = nsu_strsep(&cmdline, "\r\n"); - if (*secretstr == 0) { - fprintf(stderr, "could not read key secret\n"); - return (STATUS_SYNTAX); - } - secretlen = strlen(secretstr) * 3 / 4; - secret = isc_mem_allocate(mctx, secretlen); - if (secret == NULL) - fatal("out of memory"); - - isc_buffer_init(&secretbuf, secret, secretlen); - result = isc_base64_decodestring(secretstr, &secretbuf); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "could not create key from %s: %s\n", - secretstr, isc_result_totext(result)); - isc_mem_free(mctx, secret); - return (STATUS_SYNTAX); - } - secretlen = isc_buffer_usedlength(&secretbuf); - - if (tsigkey != NULL) - dns_tsigkey_detach(&tsigkey); - result = dns_tsigkey_create(keyname, hmacname, secret, secretlen, - ISC_TRUE, NULL, 0, 0, mctx, NULL, - &tsigkey); - isc_mem_free(mctx, secret); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "could not create key from %s %s: %s\n", - namestr, secretstr, dns_result_totext(result)); - return (STATUS_SYNTAX); - } - dst_key_setbits(tsigkey->key, digestbits); - return (STATUS_MORE); -} - -static isc_uint16_t -evaluate_zone(char *cmdline) { - char *word; - isc_buffer_t b; - isc_result_t result; - - word = nsu_strsep(&cmdline, " \t\r\n"); - if (*word == 0) { - fprintf(stderr, "could not read zone name\n"); - return (STATUS_SYNTAX); - } - - dns_fixedname_init(&fuserzone); - userzone = dns_fixedname_name(&fuserzone); - isc_buffer_init(&b, word, strlen(word)); - isc_buffer_add(&b, strlen(word)); - result = dns_name_fromtext(userzone, &b, dns_rootname, ISC_FALSE, - NULL); - if (result != ISC_R_SUCCESS) { - userzone = NULL; /* Lest it point to an invalid name */ - fprintf(stderr, "could not parse zone name\n"); - return (STATUS_SYNTAX); - } - - return (STATUS_MORE); -} - -static isc_uint16_t -evaluate_class(char *cmdline) { - char *word; - isc_textregion_t r; - isc_result_t result; - dns_rdataclass_t rdclass; - - word = nsu_strsep(&cmdline, " \t\r\n"); - if (*word == 0) { - fprintf(stderr, "could not read class name\n"); - return (STATUS_SYNTAX); - } - - r.base = word; - r.length = strlen(word); - result = dns_rdataclass_fromtext(&rdclass, &r); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "could not parse class name: %s\n", word); - return (STATUS_SYNTAX); - } - switch (rdclass) { - case dns_rdataclass_none: - case dns_rdataclass_any: - case dns_rdataclass_reserved0: - fprintf(stderr, "bad default class: %s\n", word); - return (STATUS_SYNTAX); - default: - defaultclass = rdclass; - } - - return (STATUS_MORE); -} - -static isc_uint16_t -update_addordelete(char *cmdline, isc_boolean_t isdelete) { - isc_result_t result; - dns_name_t *name = NULL; - isc_uint32_t ttl; - char *word; - dns_rdataclass_t rdataclass; - dns_rdatatype_t rdatatype; - dns_rdata_t *rdata = NULL; - dns_rdatalist_t *rdatalist = NULL; - dns_rdataset_t *rdataset = NULL; - isc_textregion_t region; - isc_uint16_t retval; - - ddebug("update_addordelete()"); - - /* - * Read the owner name. - */ - retval = parse_name(&cmdline, updatemsg, &name); - if (retval != STATUS_MORE) - return (retval); - - result = dns_message_gettemprdata(updatemsg, &rdata); - check_result(result, "dns_message_gettemprdata"); - - rdata->rdclass = 0; - rdata->type = 0; - rdata->data = NULL; - rdata->length = 0; - - /* - * If this is an add, read the TTL and verify that it's in range. - * If it's a delete, ignore a TTL if present (for compatibility). - */ - word = nsu_strsep(&cmdline, " \t\r\n"); - if (*word == 0) { - if (!isdelete) { - fprintf(stderr, "could not read owner ttl\n"); - goto failure; - } - else { - ttl = 0; - rdataclass = dns_rdataclass_any; - rdatatype = dns_rdatatype_any; - rdata->flags = DNS_RDATA_UPDATE; - goto doneparsing; - } - } - result = isc_parse_uint32(&ttl, word, 10); - if (result != ISC_R_SUCCESS) { - if (isdelete) { - ttl = 0; - goto parseclass; - } else { - fprintf(stderr, "ttl '%s': %s\n", word, - isc_result_totext(result)); - goto failure; - } - } - - if (isdelete) - ttl = 0; - else if (ttl > TTL_MAX) { - fprintf(stderr, "ttl '%s' is out of range (0 to %u)\n", - word, TTL_MAX); - goto failure; - } - - /* - * Read the class or type. - */ - word = nsu_strsep(&cmdline, " \t\r\n"); - parseclass: - if (*word == 0) { - if (isdelete) { - rdataclass = dns_rdataclass_any; - rdatatype = dns_rdatatype_any; - rdata->flags = DNS_RDATA_UPDATE; - goto doneparsing; - } else { - fprintf(stderr, "could not read class or type\n"); - goto failure; - } - } - region.base = word; - region.length = strlen(word); - result = dns_rdataclass_fromtext(&rdataclass, ®ion); - if (result == ISC_R_SUCCESS) { - if (!setzoneclass(rdataclass)) { - fprintf(stderr, "class mismatch: %s\n", word); - goto failure; - } - /* - * Now read the type. - */ - word = nsu_strsep(&cmdline, " \t\r\n"); - if (*word == 0) { - if (isdelete) { - rdataclass = dns_rdataclass_any; - rdatatype = dns_rdatatype_any; - rdata->flags = DNS_RDATA_UPDATE; - goto doneparsing; - } else { - fprintf(stderr, "could not read type\n"); - goto failure; - } - } - region.base = word; - region.length = strlen(word); - result = dns_rdatatype_fromtext(&rdatatype, ®ion); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "'%s' is not a valid type: %s\n", - word, isc_result_totext(result)); - goto failure; - } - } else { - rdataclass = getzoneclass(); - result = dns_rdatatype_fromtext(&rdatatype, ®ion); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "'%s' is not a valid class or type: " - "%s\n", word, isc_result_totext(result)); - goto failure; - } - } - - retval = parse_rdata(&cmdline, rdataclass, rdatatype, updatemsg, - rdata); - if (retval != STATUS_MORE) - goto failure; - - if (isdelete) { - if ((rdata->flags & DNS_RDATA_UPDATE) != 0) - rdataclass = dns_rdataclass_any; - else - rdataclass = dns_rdataclass_none; - } else { - if ((rdata->flags & DNS_RDATA_UPDATE) != 0) { - fprintf(stderr, "could not read rdata\n"); - goto failure; - } - } - - doneparsing: - - result = dns_message_gettemprdatalist(updatemsg, &rdatalist); - check_result(result, "dns_message_gettemprdatalist"); - result = dns_message_gettemprdataset(updatemsg, &rdataset); - check_result(result, "dns_message_gettemprdataset"); - dns_rdatalist_init(rdatalist); - rdatalist->type = rdatatype; - rdatalist->rdclass = rdataclass; - rdatalist->covers = rdatatype; - rdatalist->ttl = (dns_ttl_t)ttl; - ISC_LIST_INIT(rdatalist->rdata); - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - dns_rdataset_init(rdataset); - dns_rdatalist_tordataset(rdatalist, rdataset); - ISC_LIST_INIT(name->list); - ISC_LIST_APPEND(name->list, rdataset, link); - dns_message_addname(updatemsg, name, DNS_SECTION_UPDATE); - return (STATUS_MORE); - - failure: - if (name != NULL) - dns_message_puttempname(updatemsg, &name); - if (rdata != NULL) - dns_message_puttemprdata(updatemsg, &rdata); - return (STATUS_SYNTAX); -} - -static isc_uint16_t -evaluate_update(char *cmdline) { - char *word; - isc_boolean_t isdelete; - - ddebug("evaluate_update()"); - word = nsu_strsep(&cmdline, " \t\r\n"); - if (*word == 0) { - fprintf(stderr, "could not read operation code\n"); - return (STATUS_SYNTAX); - } - if (strcasecmp(word, "delete") == 0) - isdelete = ISC_TRUE; - else if (strcasecmp(word, "add") == 0) - isdelete = ISC_FALSE; - else { - fprintf(stderr, "incorrect operation code: %s\n", word); - return (STATUS_SYNTAX); - } - return (update_addordelete(cmdline, isdelete)); -} - -static void -setzone(dns_name_t *zonename) { - isc_result_t result; - dns_name_t *name = NULL; - dns_rdataset_t *rdataset = NULL; - - result = dns_message_firstname(updatemsg, DNS_SECTION_ZONE); - if (result == ISC_R_SUCCESS) { - dns_message_currentname(updatemsg, DNS_SECTION_ZONE, &name); - dns_message_removename(updatemsg, name, DNS_SECTION_ZONE); - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_HEAD(name->list)) { - ISC_LIST_UNLINK(name->list, rdataset, link); - dns_rdataset_disassociate(rdataset); - dns_message_puttemprdataset(updatemsg, &rdataset); - } - dns_message_puttempname(updatemsg, &name); - } - - if (zonename != NULL) { - result = dns_message_gettempname(updatemsg, &name); - check_result(result, "dns_message_gettempname"); - dns_name_init(name, NULL); - dns_name_clone(zonename, name); - result = dns_message_gettemprdataset(updatemsg, &rdataset); - check_result(result, "dns_message_gettemprdataset"); - dns_rdataset_makequestion(rdataset, getzoneclass(), - dns_rdatatype_soa); - ISC_LIST_INIT(name->list); - ISC_LIST_APPEND(name->list, rdataset, link); - dns_message_addname(updatemsg, name, DNS_SECTION_ZONE); - } -} - -static void -show_message(dns_message_t *msg) { - isc_result_t result; - isc_buffer_t *buf = NULL; - int bufsz; - - ddebug("show_message()"); - - setzone(userzone); - - bufsz = INITTEXT; - do { - if (bufsz > MAXTEXT) { - fprintf(stderr, "could not allocate large enough " - "buffer to display message\n"); - exit(1); - } - if (buf != NULL) - isc_buffer_free(&buf); - result = isc_buffer_allocate(mctx, &buf, bufsz); - check_result(result, "isc_buffer_allocate"); - result = dns_message_totext(msg, style, 0, buf); - bufsz *= 2; - } while (result == ISC_R_NOSPACE); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "could not convert message to text format.\n"); - isc_buffer_free(&buf); - return; - } - printf("Outgoing update query:\n%.*s", - (int)isc_buffer_usedlength(buf), - (char*)isc_buffer_base(buf)); - isc_buffer_free(&buf); -} - - -static isc_uint16_t -get_next_command(void) { - char cmdlinebuf[MAXCMD]; - char *cmdline; - char *word; - - ddebug("get_next_command()"); - if (interactive) { - fprintf(stdout, "> "); - fflush(stdout); - } - isc_app_block(); - cmdline = fgets(cmdlinebuf, MAXCMD, input); - isc_app_unblock(); - if (cmdline == NULL) - return (STATUS_QUIT); - word = nsu_strsep(&cmdline, " \t\r\n"); - - if (feof(input)) - return (STATUS_QUIT); - if (*word == 0) - return (STATUS_SEND); - if (word[0] == ';') - return (STATUS_MORE); - if (strcasecmp(word, "quit") == 0) - return (STATUS_QUIT); - if (strcasecmp(word, "prereq") == 0) - return (evaluate_prereq(cmdline)); - if (strcasecmp(word, "update") == 0) - return (evaluate_update(cmdline)); - if (strcasecmp(word, "server") == 0) - return (evaluate_server(cmdline)); - if (strcasecmp(word, "local") == 0) - return (evaluate_local(cmdline)); - if (strcasecmp(word, "zone") == 0) - return (evaluate_zone(cmdline)); - if (strcasecmp(word, "class") == 0) - return (evaluate_class(cmdline)); - if (strcasecmp(word, "send") == 0) - return (STATUS_SEND); - if (strcasecmp(word, "show") == 0) { - show_message(updatemsg); - return (STATUS_MORE); - } - if (strcasecmp(word, "answer") == 0) { - if (answer != NULL) - show_message(answer); - return (STATUS_MORE); - } - if (strcasecmp(word, "key") == 0) - return (evaluate_key(cmdline)); - fprintf(stderr, "incorrect section name: %s\n", word); - return (STATUS_SYNTAX); -} - -static isc_boolean_t -user_interaction(void) { - isc_uint16_t result = STATUS_MORE; - - ddebug("user_interaction()"); - while ((result == STATUS_MORE) || (result == STATUS_SYNTAX)) { - result = get_next_command(); - if (!interactive && result == STATUS_SYNTAX) - fatal("syntax error"); - } - if (result == STATUS_SEND) - return (ISC_TRUE); - return (ISC_FALSE); - -} - -static void -done_update(void) { - isc_event_t *event = global_event; - ddebug("done_update()"); - isc_task_send(global_task, &event); -} - -static void -check_tsig_error(dns_rdataset_t *rdataset, isc_buffer_t *b) { - isc_result_t result; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_any_tsig_t tsig; - - result = dns_rdataset_first(rdataset); - check_result(result, "dns_rdataset_first"); - dns_rdataset_current(rdataset, &rdata); - result = dns_rdata_tostruct(&rdata, &tsig, NULL); - check_result(result, "dns_rdata_tostruct"); - if (tsig.error != 0) { - if (isc_buffer_remaininglength(b) < 1) - check_result(ISC_R_NOSPACE, "isc_buffer_remaininglength"); - isc__buffer_putstr(b, "(" /*)*/); - result = dns_tsigrcode_totext(tsig.error, b); - check_result(result, "dns_tsigrcode_totext"); - if (isc_buffer_remaininglength(b) < 1) - check_result(ISC_R_NOSPACE, "isc_buffer_remaininglength"); - isc__buffer_putstr(b, /*(*/ ")"); - } -} - -static void -update_completed(isc_task_t *task, isc_event_t *event) { - dns_requestevent_t *reqev = NULL; - isc_result_t result; - dns_request_t *request; - - UNUSED(task); - - ddebug("update_completed()"); - - requests--; - - REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE); - reqev = (dns_requestevent_t *)event; - request = reqev->request; - - if (shuttingdown) { - dns_request_destroy(&request); - isc_event_free(&event); - maybeshutdown(); - return; - } - - if (reqev->result != ISC_R_SUCCESS) { - fprintf(stderr, "; Communication with server failed: %s\n", - isc_result_totext(reqev->result)); - seenerror = ISC_TRUE; - goto done; - } - - result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &answer); - check_result(result, "dns_message_create"); - result = dns_request_getresponse(request, answer, - DNS_MESSAGEPARSE_PRESERVEORDER); - switch (result) { - case ISC_R_SUCCESS: - break; - case DNS_R_CLOCKSKEW: - case DNS_R_EXPECTEDTSIG: - case DNS_R_TSIGERRORSET: - case DNS_R_TSIGVERIFYFAILURE: - case DNS_R_UNEXPECTEDTSIG: - fprintf(stderr, "; TSIG error with server: %s\n", - isc_result_totext(result)); - seenerror = ISC_TRUE; - break; - default: - check_result(result, "dns_request_getresponse"); - } - - if (answer->rcode != dns_rcode_noerror) { - seenerror = ISC_TRUE; - if (!debugging) { - char buf[64]; - isc_buffer_t b; - dns_rdataset_t *rds; - - isc_buffer_init(&b, buf, sizeof(buf) - 1); - result = dns_rcode_totext(answer->rcode, &b); - check_result(result, "dns_rcode_totext"); - rds = dns_message_gettsig(answer, NULL); - if (rds != NULL) - check_tsig_error(rds, &b); - fprintf(stderr, "update failed: %.*s\n", - (int)isc_buffer_usedlength(&b), buf); - } - } - if (debugging) { - isc_buffer_t *buf = NULL; - int bufsz; - - bufsz = INITTEXT; - do { - if (bufsz > MAXTEXT) { - fprintf(stderr, "could not allocate large " - "enough buffer to display message\n"); - exit(1); - } - if (buf != NULL) - isc_buffer_free(&buf); - result = isc_buffer_allocate(mctx, &buf, bufsz); - check_result(result, "isc_buffer_allocate"); - result = dns_message_totext(answer, style, 0, buf); - bufsz *= 2; - } while (result == ISC_R_NOSPACE); - check_result(result, "dns_message_totext"); - fprintf(stderr, "\nReply from update query:\n%.*s\n", - (int)isc_buffer_usedlength(buf), - (char*)isc_buffer_base(buf)); - isc_buffer_free(&buf); - } - done: - dns_request_destroy(&request); - isc_event_free(&event); - done_update(); -} - -static void -send_update(dns_name_t *zonename, isc_sockaddr_t *master, - isc_sockaddr_t *srcaddr) -{ - isc_result_t result; - dns_request_t *request = NULL; - unsigned int options = 0; - - ddebug("send_update()"); - - setzone(zonename); - - if (usevc) - options |= DNS_REQUESTOPT_TCP; - if (tsigkey == NULL && sig0key != NULL) { - result = dns_message_setsig0key(updatemsg, sig0key); - check_result(result, "dns_message_setsig0key"); - } - if (debugging) { - char addrbuf[ISC_SOCKADDR_FORMATSIZE]; - - isc_sockaddr_format(master, addrbuf, sizeof(addrbuf)); - fprintf(stderr, "Sending update to %s\n", addrbuf); - } - result = dns_request_createvia3(requestmgr, updatemsg, srcaddr, - master, options, tsigkey, timeout, - udp_timeout, udp_retries, global_task, - update_completed, NULL, &request); - check_result(result, "dns_request_createvia3"); - - if (debugging) - show_message(updatemsg); - - requests++; -} - -static void -recvsoa(isc_task_t *task, isc_event_t *event) { - dns_requestevent_t *reqev = NULL; - dns_request_t *request = NULL; - isc_result_t result, eresult; - dns_message_t *rcvmsg = NULL; - dns_section_t section; - dns_name_t *name = NULL; - dns_rdataset_t *soaset = NULL; - dns_rdata_soa_t soa; - dns_rdata_t soarr = DNS_RDATA_INIT; - int pass = 0; - dns_name_t master; - isc_sockaddr_t *serveraddr, tempaddr; - dns_name_t *zonename; - nsu_requestinfo_t *reqinfo; - dns_message_t *soaquery = NULL; - isc_sockaddr_t *addr; - isc_boolean_t seencname = ISC_FALSE; - dns_name_t tname; - unsigned int nlabels; - - UNUSED(task); - - ddebug("recvsoa()"); - - requests--; - - REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE); - reqev = (dns_requestevent_t *)event; - request = reqev->request; - eresult = reqev->result; - reqinfo = reqev->ev_arg; - soaquery = reqinfo->msg; - addr = reqinfo->addr; - - if (shuttingdown) { - dns_request_destroy(&request); - dns_message_destroy(&soaquery); - isc_mem_put(mctx, reqinfo, sizeof(nsu_requestinfo_t)); - isc_event_free(&event); - maybeshutdown(); - return; - } - - if (eresult != ISC_R_SUCCESS) { - char addrbuf[ISC_SOCKADDR_FORMATSIZE]; - - isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf)); - fprintf(stderr, "; Communication with %s failed: %s\n", - addrbuf, isc_result_totext(eresult)); - if (userserver != NULL) - fatal("could not talk to specified name server"); - else if (++ns_inuse >= lwconf->nsnext) - fatal("could not talk to any default name server"); - ddebug("Destroying request [%p]", request); - dns_request_destroy(&request); - dns_message_renderreset(soaquery); - dns_message_settsigkey(soaquery, NULL); - sendrequest(localaddr, &servers[ns_inuse], soaquery, &request); - isc_mem_put(mctx, reqinfo, sizeof(nsu_requestinfo_t)); - isc_event_free(&event); - setzoneclass(dns_rdataclass_none); - return; - } - - isc_mem_put(mctx, reqinfo, sizeof(nsu_requestinfo_t)); - reqinfo = NULL; - isc_event_free(&event); - reqev = NULL; - - ddebug("About to create rcvmsg"); - result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg); - check_result(result, "dns_message_create"); - result = dns_request_getresponse(request, rcvmsg, - DNS_MESSAGEPARSE_PRESERVEORDER); - if (result == DNS_R_TSIGERRORSET && userserver != NULL) { - dns_message_destroy(&rcvmsg); - ddebug("Destroying request [%p]", request); - dns_request_destroy(&request); - reqinfo = isc_mem_get(mctx, sizeof(nsu_requestinfo_t)); - if (reqinfo == NULL) - fatal("out of memory"); - reqinfo->msg = soaquery; - reqinfo->addr = addr; - dns_message_renderreset(soaquery); - ddebug("retrying soa request without TSIG"); - result = dns_request_createvia3(requestmgr, soaquery, - localaddr, addr, 0, NULL, - FIND_TIMEOUT * 20, - FIND_TIMEOUT, 3, - global_task, recvsoa, reqinfo, - &request); - check_result(result, "dns_request_createvia"); - requests++; - return; - } - check_result(result, "dns_request_getresponse"); - section = DNS_SECTION_ANSWER; - if (debugging) { - isc_buffer_t *buf = NULL; - int bufsz; - bufsz = INITTEXT; - do { - if (buf != NULL) - isc_buffer_free(&buf); - if (bufsz > MAXTEXT) { - fprintf(stderr, "could not allocate enough " - "space for debugging message\n"); - exit(1); - } - result = isc_buffer_allocate(mctx, &buf, bufsz); - check_result(result, "isc_buffer_allocate"); - result = dns_message_totext(rcvmsg, style, 0, buf); - } while (result == ISC_R_NOSPACE); - check_result(result, "dns_message_totext"); - fprintf(stderr, "Reply from SOA query:\n%.*s\n", - (int)isc_buffer_usedlength(buf), - (char*)isc_buffer_base(buf)); - isc_buffer_free(&buf); - } - - if (rcvmsg->rcode != dns_rcode_noerror && - rcvmsg->rcode != dns_rcode_nxdomain) - fatal("response to SOA query was unsuccessful"); - - if (userzone != NULL && rcvmsg->rcode == dns_rcode_nxdomain) { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(userzone, namebuf, sizeof(namebuf)); - error("specified zone '%s' does not exist (NXDOMAIN)", - namebuf); - dns_message_destroy(&rcvmsg); - dns_request_destroy(&request); - dns_message_destroy(&soaquery); - ddebug("Out of recvsoa"); - done_update(); - return; - } - - lookforsoa: - if (pass == 0) - section = DNS_SECTION_ANSWER; - else if (pass == 1) - section = DNS_SECTION_AUTHORITY; - else - goto droplabel; - - result = dns_message_firstname(rcvmsg, section); - if (result != ISC_R_SUCCESS) { - pass++; - goto lookforsoa; - } - while (result == ISC_R_SUCCESS) { - name = NULL; - dns_message_currentname(rcvmsg, section, &name); - soaset = NULL; - result = dns_message_findtype(name, dns_rdatatype_soa, 0, - &soaset); - if (result == ISC_R_SUCCESS) - break; - if (section == DNS_SECTION_ANSWER) { - dns_rdataset_t *tset = NULL; - if (dns_message_findtype(name, dns_rdatatype_cname, 0, - &tset) == ISC_R_SUCCESS - || - dns_message_findtype(name, dns_rdatatype_dname, 0, - &tset) == ISC_R_SUCCESS - ) - { - seencname = ISC_TRUE; - break; - } - } - - result = dns_message_nextname(rcvmsg, section); - } - - if (soaset == NULL && !seencname) { - pass++; - goto lookforsoa; - } - - if (seencname) - goto droplabel; - - if (debugging) { - char namestr[DNS_NAME_FORMATSIZE]; - dns_name_format(name, namestr, sizeof(namestr)); - fprintf(stderr, "Found zone name: %s\n", namestr); - } - - result = dns_rdataset_first(soaset); - check_result(result, "dns_rdataset_first"); - - dns_rdata_init(&soarr); - dns_rdataset_current(soaset, &soarr); - result = dns_rdata_tostruct(&soarr, &soa, NULL); - check_result(result, "dns_rdata_tostruct"); - - dns_name_init(&master, NULL); - dns_name_clone(&soa.origin, &master); - - if (userzone != NULL) - zonename = userzone; - else - zonename = name; - - if (debugging) { - char namestr[DNS_NAME_FORMATSIZE]; - dns_name_format(&master, namestr, sizeof(namestr)); - fprintf(stderr, "The master is: %s\n", namestr); - } - - if (userserver != NULL) - serveraddr = userserver; - else { - char serverstr[DNS_NAME_MAXTEXT+1]; - isc_buffer_t buf; - - isc_buffer_init(&buf, serverstr, sizeof(serverstr)); - result = dns_name_totext(&master, ISC_TRUE, &buf); - check_result(result, "dns_name_totext"); - serverstr[isc_buffer_usedlength(&buf)] = 0; - get_address(serverstr, DNSDEFAULTPORT, &tempaddr); - serveraddr = &tempaddr; - } - dns_rdata_freestruct(&soa); - - send_update(zonename, serveraddr, localaddr); - setzoneclass(dns_rdataclass_none); - - dns_message_destroy(&soaquery); - dns_request_destroy(&request); - - out: - dns_message_destroy(&rcvmsg); - ddebug("Out of recvsoa"); - return; - - droplabel: - result = dns_message_firstname(soaquery, DNS_SECTION_QUESTION); - INSIST(result == ISC_R_SUCCESS); - name = NULL; - dns_message_currentname(soaquery, DNS_SECTION_QUESTION, &name); - nlabels = dns_name_countlabels(name); - if (nlabels == 1) - fatal("could not find enclosing zone"); - dns_name_init(&tname, NULL); - dns_name_getlabelsequence(name, 1, nlabels - 1, &tname); - dns_name_clone(&tname, name); - dns_request_destroy(&request); - dns_message_renderreset(soaquery); - dns_message_settsigkey(soaquery, NULL); - if (userserver != NULL) - sendrequest(localaddr, userserver, soaquery, &request); - else - sendrequest(localaddr, &servers[ns_inuse], soaquery, - &request); - goto out; -} - -static void -sendrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, - dns_message_t *msg, dns_request_t **request) -{ - isc_result_t result; - nsu_requestinfo_t *reqinfo; - - reqinfo = isc_mem_get(mctx, sizeof(nsu_requestinfo_t)); - if (reqinfo == NULL) - fatal("out of memory"); - reqinfo->msg = msg; - reqinfo->addr = destaddr; - result = dns_request_createvia3(requestmgr, msg, srcaddr, destaddr, 0, - (userserver != NULL) ? tsigkey : NULL, - FIND_TIMEOUT * 20, FIND_TIMEOUT, 3, - global_task, recvsoa, reqinfo, request); - check_result(result, "dns_request_createvia"); - requests++; -} - -static void -start_update(void) { - isc_result_t result; - dns_rdataset_t *rdataset = NULL; - dns_name_t *name = NULL; - dns_request_t *request = NULL; - dns_message_t *soaquery = NULL; - dns_name_t *firstname; - dns_section_t section = DNS_SECTION_UPDATE; - - ddebug("start_update()"); - - if (answer != NULL) - dns_message_destroy(&answer); - - if (userzone != NULL && userserver != NULL) { - send_update(userzone, userserver, localaddr); - setzoneclass(dns_rdataclass_none); - return; - } - - result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, - &soaquery); - check_result(result, "dns_message_create"); - - if (userserver == NULL) - soaquery->flags |= DNS_MESSAGEFLAG_RD; - - result = dns_message_gettempname(soaquery, &name); - check_result(result, "dns_message_gettempname"); - - result = dns_message_gettemprdataset(soaquery, &rdataset); - check_result(result, "dns_message_gettemprdataset"); - - dns_rdataset_makequestion(rdataset, getzoneclass(), dns_rdatatype_soa); - - if (userzone != NULL) { - dns_name_init(name, NULL); - dns_name_clone(userzone, name); - } else { - result = dns_message_firstname(updatemsg, section); - if (result == ISC_R_NOMORE) { - section = DNS_SECTION_PREREQUISITE; - result = dns_message_firstname(updatemsg, section); - } - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(soaquery, &name); - dns_rdataset_disassociate(rdataset); - dns_message_puttemprdataset(soaquery, &rdataset); - dns_message_destroy(&soaquery); - done_update(); - return; - } - firstname = NULL; - dns_message_currentname(updatemsg, section, &firstname); - dns_name_init(name, NULL); - dns_name_clone(firstname, name); - } - - ISC_LIST_INIT(name->list); - ISC_LIST_APPEND(name->list, rdataset, link); - dns_message_addname(soaquery, name, DNS_SECTION_QUESTION); - - if (userserver != NULL) - sendrequest(localaddr, userserver, soaquery, &request); - else { - ns_inuse = 0; - sendrequest(localaddr, &servers[ns_inuse], soaquery, &request); - } -} - -static void -cleanup(void) { - ddebug("cleanup()"); - - if (answer != NULL) - dns_message_destroy(&answer); - ddebug("Shutting down task manager"); - isc_taskmgr_destroy(&taskmgr); - - ddebug("Destroying event"); - isc_event_free(&global_event); - - ddebug("Shutting down socket manager"); - isc_socketmgr_destroy(&socketmgr); - - ddebug("Shutting down timer manager"); - isc_timermgr_destroy(&timermgr); - - ddebug("Destroying hash context"); - isc_hash_destroy(); - - ddebug("Destroying name state"); - dns_name_destroy(); - - ddebug("Destroying memory context"); - if (memdebugging) - isc_mem_stats(mctx, stderr); - isc_mem_destroy(&mctx); -} - -static void -getinput(isc_task_t *task, isc_event_t *event) { - isc_boolean_t more; - - UNUSED(task); - - if (shuttingdown) { - maybeshutdown(); - return; - } - - if (global_event == NULL) - global_event = event; - - reset_system(); - more = user_interaction(); - if (!more) { - isc_app_shutdown(); - return; - } - start_update(); - return; -} - -int -main(int argc, char **argv) { - isc_result_t result; - style = &dns_master_style_debug; - - input = stdin; - - interactive = ISC_TF(isatty(0)); - - isc_app_start(); - - parse_args(argc, argv); - - setup_system(); - - result = isc_app_onrun(mctx, global_task, getinput, NULL); - check_result(result, "isc_app_onrun"); - - (void)isc_app_run(); - - cleanup(); - - isc_app_finish(); - - if (seenerror) - return (2); - else - return (0); -} diff --git a/contrib/bind9/bin/nsupdate/nsupdate.docbook b/contrib/bind9/bin/nsupdate/nsupdate.docbook deleted file mode 100644 index 0ea4906..0000000 --- a/contrib/bind9/bin/nsupdate/nsupdate.docbook +++ /dev/null @@ -1,657 +0,0 @@ -]> - - - - - - Jun 30, 2000 - - - nsupdate - 8 - BIND9 - - - nsupdate - Dynamic DNS update utility - - - - - 2004 - 2005 - 2006 - 2007 - Internet Systems Consortium, Inc. ("ISC") - - - 2000 - 2001 - 2002 - 2003 - Internet Software Consortium. - - - - - - nsupdate - - - - - - - - - - filename - - - - - DESCRIPTION - nsupdate - is used to submit Dynamic DNS Update requests as defined in RFC2136 - to a name server. - This allows resource records to be added or removed from a zone - without manually editing the zone file. - A single update request can contain requests to add or remove more than - one - resource record. - - - Zones that are under dynamic control via - nsupdate - or a DHCP server should not be edited by hand. - Manual edits could - conflict with dynamic updates and cause data to be lost. - - - The resource records that are dynamically added or removed with - nsupdate - have to be in the same zone. - Requests are sent to the zone's master server. - This is identified by the MNAME field of the zone's SOA record. - - - The - - option makes - nsupdate - operate in debug mode. - This provides tracing information about the update requests that are - made and the replies received from the name server. - - - Transaction signatures can be used to authenticate the Dynamic DNS - updates. - These use the TSIG resource record type described in RFC2845 or the - SIG(0) record described in RFC3535 and RFC2931. - TSIG relies on a shared secret that should only be known to - nsupdate and the name server. - Currently, the only supported encryption algorithm for TSIG is - HMAC-MD5, which is defined in RFC 2104. - Once other algorithms are defined for TSIG, applications will need to - ensure they select the appropriate algorithm as well as the key when - authenticating each other. - For instance, suitable - key - and - server - statements would be added to - /etc/named.conf - so that the name server can associate the appropriate secret key - and algorithm with the IP address of the - client application that will be using TSIG authentication. - SIG(0) uses public key cryptography. To use a SIG(0) key, the public - key must be stored in a KEY record in a zone served by the name server. - nsupdate - does not read - /etc/named.conf. - - nsupdate - uses the or option - to provide the shared secret needed to generate a TSIG record - for authenticating Dynamic DNS update requests, default type - HMAC-MD5. These options are mutually exclusive. With the - option, nsupdate reads - the shared secret from the file keyfile, - whose name is of the form - K{name}.+157.+{random}.private. For - historical reasons, the file - K{name}.+157.+{random}.key must also be - present. When the option is used, a - signature is generated from - hmac:keyname:secret. - keyname is the name of the key, and - secret is the base64 encoded shared - secret. Use of the option is discouraged - because the shared secret is supplied as a command line - argument in clear text. This may be visible in the output - from - - ps1 - or in a history file maintained by the user's - shell. - - - The may also be used to specify a SIG(0) key used - to authenticate Dynamic DNS update requests. In this case, the key - specified is not an HMAC-MD5 key. - - - By default - nsupdate - uses UDP to send update requests to the name server unless they are too - large to fit in a UDP request in which case TCP will be used. - The - - option makes - nsupdate - use a TCP connection. - This may be preferable when a batch of update requests is made. - - - The option sets the maximum time an update request - can - take before it is aborted. The default is 300 seconds. Zero can be - used - to disable the timeout. - - - The option sets the UDP retry interval. The default - is - 3 seconds. If zero, the interval will be computed from the timeout - interval - and number of UDP retries. - - - The option sets the number of UDP retries. The - default is - 3. If zero, only one update request will be made. - - - - - INPUT FORMAT - nsupdate - reads input from - filename - or standard input. - Each command is supplied on exactly one line of input. - Some commands are for administrative purposes. - The others are either update instructions or prerequisite checks on the - contents of the zone. - These checks set conditions that some name or set of - resource records (RRset) either exists or is absent from the zone. - These conditions must be met if the entire update request is to succeed. - Updates will be rejected if the tests for the prerequisite conditions - fail. - - - Every update request consists of zero or more prerequisites - and zero or more updates. - This allows a suitably authenticated update request to proceed if some - specified resource records are present or missing from the zone. - A blank input line (or the send command) - causes the - accumulated commands to be sent as one Dynamic DNS update request to the - name server. - - - The command formats and their meaning are as follows: - - - - - server - servername - port - - - - Sends all dynamic update requests to the name server - servername. - When no server statement is provided, - nsupdate - will send updates to the master server of the correct zone. - The MNAME field of that zone's SOA record will identify the - master - server for that zone. - port - is the port number on - servername - where the dynamic update requests get sent. - If no port number is specified, the default DNS port number of - 53 is - used. - - - - - - - local - address - port - - - - Sends all dynamic update requests using the local - address. - - When no local statement is provided, - nsupdate - will send updates using an address and port chosen by the - system. - port - can additionally be used to make requests come from a specific - port. - If no port number is specified, the system will assign one. - - - - - - - zone - zonename - - - - Specifies that all updates are to be made to the zone - zonename. - If no - zone - statement is provided, - nsupdate - will attempt determine the correct zone to update based on the - rest of the input. - - - - - - - class - classname - - - - Specify the default class. - If no class is specified, the - default class is - IN. - - - - - - - key - name - secret - - - - Specifies that all updates are to be TSIG-signed using the - keyname keysecret pair. - The key command - overrides any key specified on the command line via - or . - - - - - - - prereq nxdomain - domain-name - - - - Requires that no resource record of any type exists with name - domain-name. - - - - - - - - prereq yxdomain - domain-name - - - - Requires that - domain-name - exists (has as at least one resource record, of any type). - - - - - - - prereq nxrrset - domain-name - class - type - - - - Requires that no resource record exists of the specified - type, - class - and - domain-name. - If - class - is omitted, IN (internet) is assumed. - - - - - - - - prereq yxrrset - domain-name - class - type - - - - This requires that a resource record of the specified - type, - class - and - domain-name - must exist. - If - class - is omitted, IN (internet) is assumed. - - - - - - - prereq yxrrset - domain-name - class - type - data - - - - The - data - from each set of prerequisites of this form - sharing a common - type, - class, - and - domain-name - are combined to form a set of RRs. This set of RRs must - exactly match the set of RRs existing in the zone at the - given - type, - class, - and - domain-name. - The - data - are written in the standard text representation of the resource - record's - RDATA. - - - - - - - update delete - domain-name - ttl - class - type data - - - - Deletes any resource records named - domain-name. - If - type - and - data - is provided, only matching resource records will be removed. - The internet class is assumed if - class - is not supplied. The - ttl - is ignored, and is only allowed for compatibility. - - - - - - - update add - domain-name - ttl - class - type - data - - - - Adds a new resource record with the specified - ttl, - class - and - data. - - - - - - - show - - - - Displays the current message, containing all of the - prerequisites and - updates specified since the last send. - - - - - - - send - - - - Sends the current message. This is equivalent to entering a - blank line. - - - - - - - answer - - - - Displays the answer. - - - - - - - - - Lines beginning with a semicolon are comments and are ignored. - - - - - - EXAMPLES - - The examples below show how - nsupdate - could be used to insert and delete resource records from the - example.com - zone. - Notice that the input in each example contains a trailing blank line so - that - a group of commands are sent as one dynamic update request to the - master name server for - example.com. - - -# nsupdate -> update delete oldhost.example.com A -> update add newhost.example.com 86400 A 172.16.1.1 -> send - - - - Any A records for - oldhost.example.com - are deleted. - And an A record for - newhost.example.com - with IP address 172.16.1.1 is added. - The newly-added record has a 1 day TTL (86400 seconds). - -# nsupdate -> prereq nxdomain nickname.example.com -> update add nickname.example.com 86400 CNAME somehost.example.com -> send - - - - The prerequisite condition gets the name server to check that there - are no resource records of any type for - nickname.example.com. - - If there are, the update request fails. - If this name does not exist, a CNAME for it is added. - This ensures that when the CNAME is added, it cannot conflict with the - long-standing rule in RFC1034 that a name must not exist as any other - record type if it exists as a CNAME. - (The rule has been updated for DNSSEC in RFC2535 to allow CNAMEs to have - RRSIG, DNSKEY and NSEC records.) - - - - - FILES - - - - /etc/resolv.conf - - - used to identify default name server - - - - - - K{name}.+157.+{random}.key - - - base-64 encoding of HMAC-MD5 key created by - - dnssec-keygen8 - . - - - - - - K{name}.+157.+{random}.private - - - base-64 encoding of HMAC-MD5 key created by - - dnssec-keygen8 - . - - - - - - - - - SEE ALSO - - RFC2136 - , - - RFC3007 - , - - RFC2104 - , - - RFC2845 - , - - RFC1034 - , - - RFC2535 - , - - RFC2931 - , - - named8 - , - - dnssec-keygen8 - . - - - - - BUGS - - The TSIG key is redundantly stored in two separate files. - This is a consequence of nsupdate using the DST library - for its cryptographic operations, and may change in future - releases. - - - diff --git a/contrib/bind9/bin/nsupdate/nsupdate.html b/contrib/bind9/bin/nsupdate/nsupdate.html deleted file mode 100644 index d11b57e..0000000 --- a/contrib/bind9/bin/nsupdate/nsupdate.html +++ /dev/null @@ -1,500 +0,0 @@ - - - - - -nsupdate - - -
-
-
-

Name

-

nsupdate — Dynamic DNS update utility

-
-
-

Synopsis

-

nsupdate [-d] [[-y [hmac:]keyname:secret] | [-k keyfile]] [-t timeout] [-u udptimeout] [-r udpretries] [-v] [filename]

-
-
-

DESCRIPTION

-

nsupdate - is used to submit Dynamic DNS Update requests as defined in RFC2136 - to a name server. - This allows resource records to be added or removed from a zone - without manually editing the zone file. - A single update request can contain requests to add or remove more than - one - resource record. -

-

- Zones that are under dynamic control via - nsupdate - or a DHCP server should not be edited by hand. - Manual edits could - conflict with dynamic updates and cause data to be lost. -

-

- The resource records that are dynamically added or removed with - nsupdate - have to be in the same zone. - Requests are sent to the zone's master server. - This is identified by the MNAME field of the zone's SOA record. -

-

- The - -d - option makes - nsupdate - operate in debug mode. - This provides tracing information about the update requests that are - made and the replies received from the name server. -

-

- Transaction signatures can be used to authenticate the Dynamic DNS - updates. - These use the TSIG resource record type described in RFC2845 or the - SIG(0) record described in RFC3535 and RFC2931. - TSIG relies on a shared secret that should only be known to - nsupdate and the name server. - Currently, the only supported encryption algorithm for TSIG is - HMAC-MD5, which is defined in RFC 2104. - Once other algorithms are defined for TSIG, applications will need to - ensure they select the appropriate algorithm as well as the key when - authenticating each other. - For instance, suitable - key - and - server - statements would be added to - /etc/named.conf - so that the name server can associate the appropriate secret key - and algorithm with the IP address of the - client application that will be using TSIG authentication. - SIG(0) uses public key cryptography. To use a SIG(0) key, the public - key must be stored in a KEY record in a zone served by the name server. - nsupdate - does not read - /etc/named.conf. -

-

nsupdate - uses the -y or -k option - to provide the shared secret needed to generate a TSIG record - for authenticating Dynamic DNS update requests, default type - HMAC-MD5. These options are mutually exclusive. With the - -k option, nsupdate reads - the shared secret from the file keyfile, - whose name is of the form - K{name}.+157.+{random}.private. For - historical reasons, the file - K{name}.+157.+{random}.key must also be - present. When the -y option is used, a - signature is generated from - [hmac:]keyname:secret. - keyname is the name of the key, and - secret is the base64 encoded shared - secret. Use of the -y option is discouraged - because the shared secret is supplied as a command line - argument in clear text. This may be visible in the output - from - ps(1) or in a history file maintained by the user's - shell. -

-

- The -k may also be used to specify a SIG(0) key used - to authenticate Dynamic DNS update requests. In this case, the key - specified is not an HMAC-MD5 key. -

-

- By default - nsupdate - uses UDP to send update requests to the name server unless they are too - large to fit in a UDP request in which case TCP will be used. - The - -v - option makes - nsupdate - use a TCP connection. - This may be preferable when a batch of update requests is made. -

-

- The -t option sets the maximum time an update request - can - take before it is aborted. The default is 300 seconds. Zero can be - used - to disable the timeout. -

-

- The -u option sets the UDP retry interval. The default - is - 3 seconds. If zero, the interval will be computed from the timeout - interval - and number of UDP retries. -

-

- The -r option sets the number of UDP retries. The - default is - 3. If zero, only one update request will be made. -

-
-
-

INPUT FORMAT

-

nsupdate - reads input from - filename - or standard input. - Each command is supplied on exactly one line of input. - Some commands are for administrative purposes. - The others are either update instructions or prerequisite checks on the - contents of the zone. - These checks set conditions that some name or set of - resource records (RRset) either exists or is absent from the zone. - These conditions must be met if the entire update request is to succeed. - Updates will be rejected if the tests for the prerequisite conditions - fail. -

-

- Every update request consists of zero or more prerequisites - and zero or more updates. - This allows a suitably authenticated update request to proceed if some - specified resource records are present or missing from the zone. - A blank input line (or the send command) - causes the - accumulated commands to be sent as one Dynamic DNS update request to the - name server. -

-

- The command formats and their meaning are as follows: -

-
-
- server - {servername} - [port] -
-

- Sends all dynamic update requests to the name server - servername. - When no server statement is provided, - nsupdate - will send updates to the master server of the correct zone. - The MNAME field of that zone's SOA record will identify the - master - server for that zone. - port - is the port number on - servername - where the dynamic update requests get sent. - If no port number is specified, the default DNS port number of - 53 is - used. -

-
- local - {address} - [port] -
-

- Sends all dynamic update requests using the local - address. - - When no local statement is provided, - nsupdate - will send updates using an address and port chosen by the - system. - port - can additionally be used to make requests come from a specific - port. - If no port number is specified, the system will assign one. -

-
- zone - {zonename} -
-

- Specifies that all updates are to be made to the zone - zonename. - If no - zone - statement is provided, - nsupdate - will attempt determine the correct zone to update based on the - rest of the input. -

-
- class - {classname} -
-

- Specify the default class. - If no class is specified, the - default class is - IN. -

-
- key - {name} - {secret} -
-

- Specifies that all updates are to be TSIG-signed using the - keyname keysecret pair. - The key command - overrides any key specified on the command line via - -y or -k. -

-
- prereq nxdomain - {domain-name} -
-

- Requires that no resource record of any type exists with name - domain-name. -

-
- prereq yxdomain - {domain-name} -
-

- Requires that - domain-name - exists (has as at least one resource record, of any type). -

-
- prereq nxrrset - {domain-name} - [class] - {type} -
-

- Requires that no resource record exists of the specified - type, - class - and - domain-name. - If - class - is omitted, IN (internet) is assumed. -

-
- prereq yxrrset - {domain-name} - [class] - {type} -
-

- This requires that a resource record of the specified - type, - class - and - domain-name - must exist. - If - class - is omitted, IN (internet) is assumed. -

-
- prereq yxrrset - {domain-name} - [class] - {type} - {data...} -
-

- The - data - from each set of prerequisites of this form - sharing a common - type, - class, - and - domain-name - are combined to form a set of RRs. This set of RRs must - exactly match the set of RRs existing in the zone at the - given - type, - class, - and - domain-name. - The - data - are written in the standard text representation of the resource - record's - RDATA. -

-
- update delete - {domain-name} - [ttl] - [class] - [type [data...]] -
-

- Deletes any resource records named - domain-name. - If - type - and - data - is provided, only matching resource records will be removed. - The internet class is assumed if - class - is not supplied. The - ttl - is ignored, and is only allowed for compatibility. -

-
- update add - {domain-name} - {ttl} - [class] - {type} - {data...} -
-

- Adds a new resource record with the specified - ttl, - class - and - data. -

-
- show -
-

- Displays the current message, containing all of the - prerequisites and - updates specified since the last send. -

-
- send -
-

- Sends the current message. This is equivalent to entering a - blank line. -

-
- answer -
-

- Displays the answer. -

-
-

-

-

- Lines beginning with a semicolon are comments and are ignored. -

-
-
-

EXAMPLES

-

- The examples below show how - nsupdate - could be used to insert and delete resource records from the - example.com - zone. - Notice that the input in each example contains a trailing blank line so - that - a group of commands are sent as one dynamic update request to the - master name server for - example.com. - -

-
-# nsupdate
-> update delete oldhost.example.com A
-> update add newhost.example.com 86400 A 172.16.1.1
-> send
-
-

-

-

- Any A records for - oldhost.example.com - are deleted. - And an A record for - newhost.example.com - with IP address 172.16.1.1 is added. - The newly-added record has a 1 day TTL (86400 seconds). -

-
-# nsupdate
-> prereq nxdomain nickname.example.com
-> update add nickname.example.com 86400 CNAME somehost.example.com
-> send
-
-

-

-

- The prerequisite condition gets the name server to check that there - are no resource records of any type for - nickname.example.com. - - If there are, the update request fails. - If this name does not exist, a CNAME for it is added. - This ensures that when the CNAME is added, it cannot conflict with the - long-standing rule in RFC1034 that a name must not exist as any other - record type if it exists as a CNAME. - (The rule has been updated for DNSSEC in RFC2535 to allow CNAMEs to have - RRSIG, DNSKEY and NSEC records.) -

-
-
-

FILES

-
-
/etc/resolv.conf
-

- used to identify default name server -

-
K{name}.+157.+{random}.key
-

- base-64 encoding of HMAC-MD5 key created by - dnssec-keygen(8). -

-
K{name}.+157.+{random}.private
-

- base-64 encoding of HMAC-MD5 key created by - dnssec-keygen(8). -

-
-
-
-

SEE ALSO

-

RFC2136, - RFC3007, - RFC2104, - RFC2845, - RFC1034, - RFC2535, - RFC2931, - named(8), - dnssec-keygen(8). -

-
-
-

BUGS

-

- The TSIG key is redundantly stored in two separate files. - This is a consequence of nsupdate using the DST library - for its cryptographic operations, and may change in future - releases. -

-
-
- diff --git a/contrib/bind9/bin/rndc/Makefile.in b/contrib/bind9/bin/rndc/Makefile.in deleted file mode 100644 index 3bc72b1..0000000 --- a/contrib/bind9/bin/rndc/Makefile.in +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 2000-2002 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: Makefile.in,v 1.40.18.4 2007/08/28 07:20:01 tbox Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -@BIND9_VERSION@ - -@BIND9_MAKE_INCLUDES@ - -CINCLUDES = -I${srcdir}/include ${ISC_INCLUDES} ${ISCCC_INCLUDES} \ - ${ISCCFG_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} - -CDEFINES = -CWARNINGS = - -ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ -ISCCCLIBS = ../../lib/isccc/libisccc.@A@ -ISCLIBS = ../../lib/isc/libisc.@A@ -DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ -BIND9LIBS = ../../lib/bind9/libbind9.@A@ - -ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ -ISCCCDEPLIBS = ../../lib/isccc/libisccc.@A@ -ISCDEPLIBS = ../../lib/isc/libisc.@A@ -DNSDEPLIBS = ../../lib/dns/libdns.@A@ -BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ - -RNDCLIBS = ${ISCCFGLIBS} ${ISCCCLIBS} ${BIND9LIBS} ${DNSLIBS} ${ISCLIBS} @LIBS@ -RNDCDEPLIBS = ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${BIND9DEPLIBS} ${DNSDEPLIBS} ${ISCDEPLIBS} - -CONFLIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@ -CONFDEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS} - -SRCS= rndc.c rndc-confgen.c - -SUBDIRS = unix - -TARGETS = rndc@EXEEXT@ rndc-confgen@EXEEXT@ - -MANPAGES = rndc.8 rndc-confgen.8 rndc.conf.5 - -HTMLPAGES = rndc.html rndc-confgen.html rndc.conf.html - -MANOBJS = ${MANPAGES} ${HTMLPAGES} - -UOBJS = unix/os.@O@ - -@BIND9_MAKE_RULES@ - -rndc.@O@: rndc.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ - -DVERSION=\"${VERSION}\" \ - -DRNDC_CONFFILE=\"${sysconfdir}/rndc.conf\" \ - -DRNDC_KEYFILE=\"${sysconfdir}/rndc.key\" \ - -c ${srcdir}/rndc.c - -rndc-confgen.@O@: rndc-confgen.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ - -DRNDC_KEYFILE=\"${sysconfdir}/rndc.key\" \ - -c ${srcdir}/rndc-confgen.c - -rndc@EXEEXT@: rndc.@O@ util.@O@ ${RNDCDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ rndc.@O@ util.@O@ \ - ${RNDCLIBS} - -rndc-confgen@EXEEXT@: rndc-confgen.@O@ util.@O@ ${UOBJS} ${CONFDEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ rndc-confgen.@O@ util.@O@ \ - ${UOBJS} ${CONFLIBS} - -doc man:: ${MANOBJS} - -docclean manclean maintainer-clean:: - rm -f ${MANOBJS} - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man5 - -install:: rndc@EXEEXT@ rndc-confgen@EXEEXT@ installdirs - ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} rndc@EXEEXT@ ${DESTDIR}${sbindir} - ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} rndc-confgen@EXEEXT@ ${DESTDIR}${sbindir} - ${INSTALL_DATA} ${srcdir}/rndc.8 ${DESTDIR}${mandir}/man8 - ${INSTALL_DATA} ${srcdir}/rndc-confgen.8 ${DESTDIR}${mandir}/man8 - ${INSTALL_DATA} ${srcdir}/rndc.conf.5 ${DESTDIR}${mandir}/man5 - -clean distclean maintainer-clean:: - rm -f ${TARGETS} diff --git a/contrib/bind9/bin/rndc/include/rndc/os.h b/contrib/bind9/bin/rndc/include/rndc/os.h deleted file mode 100644 index b5c1d24..0000000 --- a/contrib/bind9/bin/rndc/include/rndc/os.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: os.h,v 1.5.18.2 2005/04/29 00:15:41 marka Exp $ */ - -/*! \file */ - -#ifndef RNDC_OS_H -#define RNDC_OS_H 1 - -#include -#include - -ISC_LANG_BEGINDECLS - -FILE *safe_create(const char *filename); -/*%< - * Open 'filename' for writing, truncate if necessary. If the file was - * created ensure that only the owner can read/write it. - */ - -int set_user(FILE *fd, const char *user); -/*%< - * Set the owner of the file refernced by 'fd' to 'user'. - * Returns: - * 0 success - * -1 insufficient permissions, or 'user' does not exist. - */ - -ISC_LANG_ENDDECLS - -#endif diff --git a/contrib/bind9/bin/rndc/rndc-confgen.8 b/contrib/bind9/bin/rndc/rndc-confgen.8 deleted file mode 100644 index fe25a7b..0000000 --- a/contrib/bind9/bin/rndc/rndc-confgen.8 +++ /dev/null @@ -1,211 +0,0 @@ -.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") -.\" Copyright (C) 2001, 2003 Internet Software Consortium. -.\" -.\" Permission to use, copy, modify, and 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: rndc-confgen.8,v 1.9.18.11 2007/01/30 00:23:44 marka Exp $ -.\" -.hy 0 -.ad l -.\" Title: rndc\-confgen -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.71.1 -.\" Date: Aug 27, 2001 -.\" Manual: BIND9 -.\" Source: BIND9 -.\" -.TH "RNDC\-CONFGEN" "8" "Aug 27, 2001" "BIND9" "BIND9" -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.SH "NAME" -rndc\-confgen \- rndc key generation tool -.SH "SYNOPSIS" -.HP 13 -\fBrndc\-confgen\fR [\fB\-a\fR] [\fB\-b\ \fR\fB\fIkeysize\fR\fR] [\fB\-c\ \fR\fB\fIkeyfile\fR\fR] [\fB\-h\fR] [\fB\-k\ \fR\fB\fIkeyname\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-r\ \fR\fB\fIrandomfile\fR\fR] [\fB\-s\ \fR\fB\fIaddress\fR\fR] [\fB\-t\ \fR\fB\fIchrootdir\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] -.SH "DESCRIPTION" -.PP -\fBrndc\-confgen\fR -generates configuration files for -\fBrndc\fR. It can be used as a convenient alternative to writing the -\fIrndc.conf\fR -file and the corresponding -\fBcontrols\fR -and -\fBkey\fR -statements in -\fInamed.conf\fR -by hand. Alternatively, it can be run with the -\fB\-a\fR -option to set up a -\fIrndc.key\fR -file and avoid the need for a -\fIrndc.conf\fR -file and a -\fBcontrols\fR -statement altogether. -.SH "OPTIONS" -.PP -\-a -.RS 4 -Do automatic -\fBrndc\fR -configuration. This creates a file -\fIrndc.key\fR -in -\fI/etc\fR -(or whatever -\fIsysconfdir\fR -was specified as when -BIND -was built) that is read by both -\fBrndc\fR -and -\fBnamed\fR -on startup. The -\fIrndc.key\fR -file defines a default command channel and authentication key allowing -\fBrndc\fR -to communicate with -\fBnamed\fR -on the local host with no further configuration. -.sp -Running -\fBrndc\-confgen \-a\fR -allows BIND 9 and -\fBrndc\fR -to be used as drop\-in replacements for BIND 8 and -\fBndc\fR, with no changes to the existing BIND 8 -\fInamed.conf\fR -file. -.sp -If a more elaborate configuration than that generated by -\fBrndc\-confgen \-a\fR -is required, for example if rndc is to be used remotely, you should run -\fBrndc\-confgen\fR -without the -\fB\-a\fR -option and set up a -\fIrndc.conf\fR -and -\fInamed.conf\fR -as directed. -.RE -.PP -\-b \fIkeysize\fR -.RS 4 -Specifies the size of the authentication key in bits. Must be between 1 and 512 bits; the default is 128. -.RE -.PP -\-c \fIkeyfile\fR -.RS 4 -Used with the -\fB\-a\fR -option to specify an alternate location for -\fIrndc.key\fR. -.RE -.PP -\-h -.RS 4 -Prints a short summary of the options and arguments to -\fBrndc\-confgen\fR. -.RE -.PP -\-k \fIkeyname\fR -.RS 4 -Specifies the key name of the rndc authentication key. This must be a valid domain name. The default is -\fBrndc\-key\fR. -.RE -.PP -\-p \fIport\fR -.RS 4 -Specifies the command channel port where -\fBnamed\fR -listens for connections from -\fBrndc\fR. The default is 953. -.RE -.PP -\-r \fIrandomfile\fR -.RS 4 -Specifies a source of random data for generating the authorization. If the operating system does not provide a -\fI/dev/random\fR -or equivalent device, the default source of randomness is keyboard input. -\fIrandomdev\fR -specifies the name of a character device or file containing random data to be used instead of the default. The special value -\fIkeyboard\fR -indicates that keyboard input should be used. -.RE -.PP -\-s \fIaddress\fR -.RS 4 -Specifies the IP address where -\fBnamed\fR -listens for command channel connections from -\fBrndc\fR. The default is the loopback address 127.0.0.1. -.RE -.PP -\-t \fIchrootdir\fR -.RS 4 -Used with the -\fB\-a\fR -option to specify a directory where -\fBnamed\fR -will run chrooted. An additional copy of the -\fIrndc.key\fR -will be written relative to this directory so that it will be found by the chrooted -\fBnamed\fR. -.RE -.PP -\-u \fIuser\fR -.RS 4 -Used with the -\fB\-a\fR -option to set the owner of the -\fIrndc.key\fR -file generated. If -\fB\-t\fR -is also specified only the file in the chroot area has its owner changed. -.RE -.SH "EXAMPLES" -.PP -To allow -\fBrndc\fR -to be used with no manual configuration, run -.PP -\fBrndc\-confgen \-a\fR -.PP -To print a sample -\fIrndc.conf\fR -file and corresponding -\fBcontrols\fR -and -\fBkey\fR -statements to be manually inserted into -\fInamed.conf\fR, run -.PP -\fBrndc\-confgen\fR -.SH "SEE ALSO" -.PP -\fBrndc\fR(8), -\fBrndc.conf\fR(5), -\fBnamed\fR(8), -BIND 9 Administrator Reference Manual. -.SH "AUTHOR" -.PP -Internet Systems Consortium -.SH "COPYRIGHT" -Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") -.br -Copyright \(co 2001, 2003 Internet Software Consortium. -.br diff --git a/contrib/bind9/bin/rndc/rndc-confgen.c b/contrib/bind9/bin/rndc/rndc-confgen.c deleted file mode 100644 index 0764104..0000000 --- a/contrib/bind9/bin/rndc/rndc-confgen.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001, 2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: rndc-confgen.c,v 1.18.18.3 2005/04/29 00:15:40 marka Exp $ */ - -/*! \file */ - -/** - * rndc-confgen generates configuration files for rndc. It can be used - * as a convenient alternative to writing the rndc.conf file and the - * corresponding controls and key statements in named.conf by hand. - * Alternatively, it can be run with the -a option to set up a - * rndc.key file and avoid the need for a rndc.conf file and a - * controls statement altogether. - */ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "util.h" - -#define DEFAULT_KEYLENGTH 128 /*% Bits. */ -#define DEFAULT_KEYNAME "rndc-key" -#define DEFAULT_SERVER "127.0.0.1" -#define DEFAULT_PORT 953 - -static char program[256]; -char *progname; - -isc_boolean_t verbose = ISC_FALSE; - -const char *keyfile, *keydef; - -static void -usage(int status) { - - fprintf(stderr, "\ -Usage:\n\ - %s [-a] [-b bits] [-c keyfile] [-k keyname] [-p port] [-r randomfile] \ -[-s addr] [-t chrootdir] [-u user]\n\ - -a: generate just the key clause and write it to keyfile (%s)\n\ - -b bits: from 1 through 512, default %d; total length of the secret\n\ - -c keyfile: specify an alternate key file (requires -a)\n\ - -k keyname: the name as it will be used in named.conf and rndc.conf\n\ - -p port: the port named will listen on and rndc will connect to\n\ - -r randomfile: a file containing random data\n\ - -s addr: the address to which rndc should connect\n\ - -t chrootdir: write a keyfile in chrootdir as well (requires -a)\n\ - -u user: set the keyfile owner to \"user\" (requires -a)\n", - progname, keydef, DEFAULT_KEYLENGTH); - - exit (status); -} - -/*% - * Write an rndc.key file to 'keyfile'. If 'user' is non-NULL, - * make that user the owner of the file. The key will have - * the name 'keyname' and the secret in the buffer 'secret'. - */ -static void -write_key_file(const char *keyfile, const char *user, - const char *keyname, isc_buffer_t *secret ) -{ - FILE *fd; - - fd = safe_create(keyfile); - if (fd == NULL) - fatal( "unable to create \"%s\"\n", keyfile); - if (user != NULL) { - if (set_user(fd, user) == -1) - fatal("unable to set file owner\n"); - } - fprintf(fd, "key \"%s\" {\n\talgorithm hmac-md5;\n" - "\tsecret \"%.*s\";\n};\n", keyname, - (int)isc_buffer_usedlength(secret), - (char *)isc_buffer_base(secret)); - fflush(fd); - if (ferror(fd)) - fatal("write to %s failed\n", keyfile); - if (fclose(fd)) - fatal("fclose(%s) failed\n", keyfile); - fprintf(stderr, "wrote key file \"%s\"\n", keyfile); -} - -int -main(int argc, char **argv) { - isc_boolean_t show_final_mem = ISC_FALSE; - isc_buffer_t key_rawbuffer; - isc_buffer_t key_txtbuffer; - isc_region_t key_rawregion; - isc_mem_t *mctx = NULL; - isc_entropy_t *ectx = NULL; - isc_entropysource_t *entropy_source = NULL; - isc_result_t result = ISC_R_SUCCESS; - dst_key_t *key = NULL; - const char *keyname = NULL; - const char *randomfile = NULL; - const char *serveraddr = NULL; - char key_rawsecret[64]; - char key_txtsecret[256]; - char *p; - int ch; - int port; - int keysize; - int entropy_flags = 0; - int open_keyboard = ISC_ENTROPY_KEYBOARDMAYBE; - struct in_addr addr4_dummy; - struct in6_addr addr6_dummy; - char *chrootdir = NULL; - char *user = NULL; - isc_boolean_t keyonly = ISC_FALSE; - int len; - - keydef = keyfile = RNDC_KEYFILE; - - result = isc_file_progname(*argv, program, sizeof(program)); - if (result != ISC_R_SUCCESS) - memcpy(program, "rndc-confgen", 13); - progname = program; - - keyname = DEFAULT_KEYNAME; - keysize = DEFAULT_KEYLENGTH; - serveraddr = DEFAULT_SERVER; - port = DEFAULT_PORT; - - while ((ch = isc_commandline_parse(argc, argv, - "ab:c:hk:Mmp:r:s:t:u:Vy")) != -1) { - switch (ch) { - case 'a': - keyonly = ISC_TRUE; - break; - case 'b': - keysize = strtol(isc_commandline_argument, &p, 10); - if (*p != '\0' || keysize < 0) - fatal("-b requires a non-negative number"); - if (keysize < 1 || keysize > 512) - fatal("-b must be in the range 1 through 512"); - break; - case 'c': - keyfile = isc_commandline_argument; - break; - case 'h': - usage(0); - case 'k': - case 'y': /* Compatible with rndc -y. */ - keyname = isc_commandline_argument; - break; - case 'M': - isc_mem_debugging = ISC_MEM_DEBUGTRACE; - break; - - case 'm': - show_final_mem = ISC_TRUE; - break; - case 'p': - port = strtol(isc_commandline_argument, &p, 10); - if (*p != '\0' || port < 0 || port > 65535) - fatal("port '%s' out of range", - isc_commandline_argument); - break; - case 'r': - randomfile = isc_commandline_argument; - break; - case 's': - serveraddr = isc_commandline_argument; - if (inet_pton(AF_INET, serveraddr, &addr4_dummy) != 1 && - inet_pton(AF_INET6, serveraddr, &addr6_dummy) != 1) - fatal("-s should be an IPv4 or IPv6 address"); - break; - case 't': - chrootdir = isc_commandline_argument; - break; - case 'u': - user = isc_commandline_argument; - break; - case 'V': - verbose = ISC_TRUE; - break; - case '?': - usage(1); - break; - default: - fatal("unexpected error parsing command arguments: " - "got %c\n", ch); - break; - } - } - - argc -= isc_commandline_index; - argv += isc_commandline_index; - - if (argc > 0) - usage(1); - - DO("create memory context", isc_mem_create(0, 0, &mctx)); - - DO("create entropy context", isc_entropy_create(mctx, &ectx)); - - if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) { - randomfile = NULL; - open_keyboard = ISC_ENTROPY_KEYBOARDYES; - } - DO("start entropy source", isc_entropy_usebestsource(ectx, - &entropy_source, - randomfile, - open_keyboard)); - - entropy_flags = ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY; - - DO("initialize dst library", dst_lib_init(mctx, ectx, entropy_flags)); - - DO("generate key", dst_key_generate(dns_rootname, DST_ALG_HMACMD5, - keysize, 0, 0, - DNS_KEYPROTO_ANY, - dns_rdataclass_in, mctx, &key)); - - isc_buffer_init(&key_rawbuffer, &key_rawsecret, sizeof(key_rawsecret)); - - DO("dump key to buffer", dst_key_tobuffer(key, &key_rawbuffer)); - - isc_buffer_init(&key_txtbuffer, &key_txtsecret, sizeof(key_txtsecret)); - isc_buffer_usedregion(&key_rawbuffer, &key_rawregion); - - DO("bsse64 encode secret", isc_base64_totext(&key_rawregion, -1, "", - &key_txtbuffer)); - - /* - * Shut down the entropy source now so the "stop typing" message - * does not muck with the output. - */ - if (entropy_source != NULL) - isc_entropy_destroysource(&entropy_source); - - if (key != NULL) - dst_key_free(&key); - - isc_entropy_detach(&ectx); - dst_lib_destroy(); - - if (keyonly) { - write_key_file(keyfile, chrootdir == NULL ? user : NULL, - keyname, &key_txtbuffer); - - if (chrootdir != NULL) { - char *buf; - len = strlen(chrootdir) + strlen(keyfile) + 2; - buf = isc_mem_get(mctx, len); - if (buf == NULL) - fatal("isc_mem_get(%d) failed\n", len); - snprintf(buf, len, "%s%s%s", chrootdir, - (*keyfile != '/') ? "/" : "", keyfile); - - write_key_file(buf, user, keyname, &key_txtbuffer); - isc_mem_put(mctx, buf, len); - } - } else { - printf("\ -# Start of rndc.conf\n\ -key \"%s\" {\n\ - algorithm hmac-md5;\n\ - secret \"%.*s\";\n\ -};\n\ -\n\ -options {\n\ - default-key \"%s\";\n\ - default-server %s;\n\ - default-port %d;\n\ -};\n\ -# End of rndc.conf\n\ -\n\ -# Use with the following in named.conf, adjusting the allow list as needed:\n\ -# key \"%s\" {\n\ -# algorithm hmac-md5;\n\ -# secret \"%.*s\";\n\ -# };\n\ -# \n\ -# controls {\n\ -# inet %s port %d\n\ -# allow { %s; } keys { \"%s\"; };\n\ -# };\n\ -# End of named.conf\n", - keyname, - (int)isc_buffer_usedlength(&key_txtbuffer), - (char *)isc_buffer_base(&key_txtbuffer), - keyname, serveraddr, port, - keyname, - (int)isc_buffer_usedlength(&key_txtbuffer), - (char *)isc_buffer_base(&key_txtbuffer), - serveraddr, port, serveraddr, keyname); - } - - if (show_final_mem) - isc_mem_stats(mctx, stderr); - - isc_mem_destroy(&mctx); - - return (0); -} diff --git a/contrib/bind9/bin/rndc/rndc-confgen.docbook b/contrib/bind9/bin/rndc/rndc-confgen.docbook deleted file mode 100644 index c694f4b..0000000 --- a/contrib/bind9/bin/rndc/rndc-confgen.docbook +++ /dev/null @@ -1,286 +0,0 @@ -]> - - - - - - Aug 27, 2001 - - - - rndc-confgen - 8 - BIND9 - - - - rndc-confgen - rndc key generation tool - - - - - 2004 - 2005 - 2007 - Internet Systems Consortium, Inc. ("ISC") - - - 2001 - 2003 - Internet Software Consortium. - - - - - - rndc-confgen - - - - - - - - - - - - - - - DESCRIPTION - rndc-confgen - generates configuration files - for rndc. It can be used as a - convenient alternative to writing the - rndc.conf file - and the corresponding controls - and key - statements in named.conf by hand. - Alternatively, it can be run with the -a - option to set up a rndc.key file and - avoid the need for a rndc.conf file - and a controls statement altogether. - - - - - - OPTIONS - - - - -a - - - Do automatic rndc configuration. - This creates a file rndc.key - in /etc (or whatever - sysconfdir - was specified as when BIND was - built) - that is read by both rndc - and named on startup. The - rndc.key file defines a default - command channel and authentication key allowing - rndc to communicate with - named on the local host - with no further configuration. - - - Running rndc-confgen -a allows - BIND 9 and rndc to be used as - drop-in - replacements for BIND 8 and ndc, - with no changes to the existing BIND 8 - named.conf file. - - - If a more elaborate configuration than that - generated by rndc-confgen -a - is required, for example if rndc is to be used remotely, - you should run rndc-confgen without - the - -a option and set up a - rndc.conf and - named.conf - as directed. - - - - - - -b keysize - - - Specifies the size of the authentication key in bits. - Must be between 1 and 512 bits; the default is 128. - - - - - - -c keyfile - - - Used with the -a option to specify - an alternate location for rndc.key. - - - - - - -h - - - Prints a short summary of the options and arguments to - rndc-confgen. - - - - - - -k keyname - - - Specifies the key name of the rndc authentication key. - This must be a valid domain name. - The default is rndc-key. - - - - - - -p port - - - Specifies the command channel port where named - listens for connections from rndc. - The default is 953. - - - - - - -r randomfile - - - Specifies a source of random data for generating the - authorization. If the operating - system does not provide a /dev/random - or equivalent device, the default source of randomness - is keyboard input. randomdev - specifies - the name of a character device or file containing random - data to be used instead of the default. The special value - keyboard indicates that keyboard - input should be used. - - - - - - -s address - - - Specifies the IP address where named - listens for command channel connections from - rndc. The default is the loopback - address 127.0.0.1. - - - - - - -t chrootdir - - - Used with the -a option to specify - a directory where named will run - chrooted. An additional copy of the rndc.key - will be written relative to this directory so that - it will be found by the chrooted named. - - - - - - -u user - - - Used with the -a option to set the - owner - of the rndc.key file generated. - If - -t is also specified only the file - in - the chroot area has its owner changed. - - - - - - - - - EXAMPLES - - To allow rndc to be used with - no manual configuration, run - - rndc-confgen -a - - - To print a sample rndc.conf file and - corresponding controls and key - statements to be manually inserted into named.conf, - run - - rndc-confgen - - - - - SEE ALSO - - rndc8 - , - - rndc.conf5 - , - - named8 - , - BIND 9 Administrator Reference Manual. - - - - - AUTHOR - Internet Systems Consortium - - - - diff --git a/contrib/bind9/bin/rndc/rndc-confgen.html b/contrib/bind9/bin/rndc/rndc-confgen.html deleted file mode 100644 index fd40a81..0000000 --- a/contrib/bind9/bin/rndc/rndc-confgen.html +++ /dev/null @@ -1,188 +0,0 @@ - - - - - -rndc-confgen - - -
-
-
-

Name

-

rndc-confgen — rndc key generation tool

-
-
-

Synopsis

-

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

-
-
-

DESCRIPTION

-

rndc-confgen - generates configuration files - for rndc. It can be used as a - convenient alternative to writing the - rndc.conf file - and the corresponding controls - and key - statements in named.conf by hand. - Alternatively, it can be run with the -a - option to set up a rndc.key file and - avoid the need for a rndc.conf file - and a controls statement altogether. -

-
-
-

OPTIONS

-
-
-a
-
-

- Do automatic rndc configuration. - This creates a file rndc.key - in /etc (or whatever - sysconfdir - was specified as when BIND was - built) - that is read by both rndc - and named on startup. The - rndc.key file defines a default - command channel and authentication key allowing - rndc to communicate with - named on the local host - with no further configuration. -

-

- Running rndc-confgen -a allows - BIND 9 and rndc to be used as - drop-in - replacements for BIND 8 and ndc, - with no changes to the existing BIND 8 - named.conf file. -

-

- If a more elaborate configuration than that - generated by rndc-confgen -a - is required, for example if rndc is to be used remotely, - you should run rndc-confgen without - the - -a option and set up a - rndc.conf and - named.conf - as directed. -

-
-
-b keysize
-

- Specifies the size of the authentication key in bits. - Must be between 1 and 512 bits; the default is 128. -

-
-c keyfile
-

- Used with the -a option to specify - an alternate location for rndc.key. -

-
-h
-

- Prints a short summary of the options and arguments to - rndc-confgen. -

-
-k keyname
-

- Specifies the key name of the rndc authentication key. - This must be a valid domain name. - The default is rndc-key. -

-
-p port
-

- Specifies the command channel port where named - listens for connections from rndc. - The default is 953. -

-
-r randomfile
-

- Specifies a source of random data for generating the - authorization. If the operating - system does not provide a /dev/random - or equivalent device, the default source of randomness - is keyboard input. randomdev - specifies - the name of a character device or file containing random - data to be used instead of the default. The special value - keyboard indicates that keyboard - input should be used. -

-
-s address
-

- Specifies the IP address where named - listens for command channel connections from - rndc. The default is the loopback - address 127.0.0.1. -

-
-t chrootdir
-

- Used with the -a option to specify - a directory where named will run - chrooted. An additional copy of the rndc.key - will be written relative to this directory so that - it will be found by the chrooted named. -

-
-u user
-

- Used with the -a option to set the - owner - of the rndc.key file generated. - If - -t is also specified only the file - in - the chroot area has its owner changed. -

-
-
-
-

EXAMPLES

-

- To allow rndc to be used with - no manual configuration, run -

-

rndc-confgen -a -

-

- To print a sample rndc.conf file and - corresponding controls and key - statements to be manually inserted into named.conf, - run -

-

rndc-confgen -

-
-
-

SEE ALSO

-

rndc(8), - rndc.conf(5), - named(8), - BIND 9 Administrator Reference Manual. -

-
-
-

AUTHOR

-

Internet Systems Consortium -

-
-
- diff --git a/contrib/bind9/bin/rndc/rndc.8 b/contrib/bind9/bin/rndc/rndc.8 deleted file mode 100644 index 14a51b3..0000000 --- a/contrib/bind9/bin/rndc/rndc.8 +++ /dev/null @@ -1,147 +0,0 @@ -.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") -.\" Copyright (C) 2000, 2001 Internet Software Consortium. -.\" -.\" Permission to use, copy, modify, and 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: rndc.8,v 1.26.18.15 2007/06/20 02:26:58 marka Exp $ -.\" -.hy 0 -.ad l -.\" Title: rndc -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.71.1 -.\" Date: June 30, 2000 -.\" Manual: BIND9 -.\" Source: BIND9 -.\" -.TH "RNDC" "8" "June 30, 2000" "BIND9" "BIND9" -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.SH "NAME" -rndc \- name server control utility -.SH "SYNOPSIS" -.HP 5 -\fBrndc\fR [\fB\-b\ \fR\fB\fIsource\-address\fR\fR] [\fB\-c\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-k\ \fR\fB\fIkey\-file\fR\fR] [\fB\-s\ \fR\fB\fIserver\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-V\fR] [\fB\-y\ \fR\fB\fIkey_id\fR\fR] {command} -.SH "DESCRIPTION" -.PP -\fBrndc\fR -controls the operation of a name server. It supersedes the -\fBndc\fR -utility that was provided in old BIND releases. If -\fBrndc\fR -is invoked with no command line options or arguments, it prints a short summary of the supported commands and the available options and their arguments. -.PP -\fBrndc\fR -communicates with the name server over a TCP connection, sending commands authenticated with digital signatures. In the current versions of -\fBrndc\fR -and -\fBnamed\fR, the only supported authentication algorithm is HMAC\-MD5, which uses a shared secret on each end of the connection. This provides TSIG\-style authentication for the command request and the name server's response. All commands sent over the channel must be signed by a key_id known to the server. -.PP -\fBrndc\fR -reads a configuration file to determine how to contact the name server and decide what algorithm and key it should use. -.SH "OPTIONS" -.PP -\-b \fIsource\-address\fR -.RS 4 -Use -\fIsource\-address\fR -as the source address for the connection to the server. Multiple instances are permitted to allow setting of both the IPv4 and IPv6 source addresses. -.RE -.PP -\-c \fIconfig\-file\fR -.RS 4 -Use -\fIconfig\-file\fR -as the configuration file instead of the default, -\fI/etc/rndc.conf\fR. -.RE -.PP -\-k \fIkey\-file\fR -.RS 4 -Use -\fIkey\-file\fR -as the key file instead of the default, -\fI/etc/rndc.key\fR. The key in -\fI/etc/rndc.key\fR -will be used to authenticate commands sent to the server if the -\fIconfig\-file\fR -does not exist. -.RE -.PP -\-s \fIserver\fR -.RS 4 -\fIserver\fR -is the name or address of the server which matches a server statement in the configuration file for -\fBrndc\fR. If no server is supplied on the command line, the host named by the default\-server clause in the options statement of the -\fBrndc\fR -configuration file will be used. -.RE -.PP -\-p \fIport\fR -.RS 4 -Send commands to TCP port -\fIport\fR -instead of BIND 9's default control channel port, 953. -.RE -.PP -\-V -.RS 4 -Enable verbose logging. -.RE -.PP -\-y \fIkey_id\fR -.RS 4 -Use the key -\fIkey_id\fR -from the configuration file. -\fIkey_id\fR -must be known by named with the same algorithm and secret string in order for control message validation to succeed. If no -\fIkey_id\fR -is specified, -\fBrndc\fR -will first look for a key clause in the server statement of the server being used, or if no server statement is present for that host, then the default\-key clause of the options statement. Note that the configuration file contains shared secrets which are used to send authenticated control commands to name servers. It should therefore not have general read or write access. -.RE -.PP -For the complete set of commands supported by -\fBrndc\fR, see the BIND 9 Administrator Reference Manual or run -\fBrndc\fR -without arguments to see its help message. -.SH "LIMITATIONS" -.PP -\fBrndc\fR -does not yet support all the commands of the BIND 8 -\fBndc\fR -utility. -.PP -There is currently no way to provide the shared secret for a -\fBkey_id\fR -without using the configuration file. -.PP -Several error messages could be clearer. -.SH "SEE ALSO" -.PP -\fBrndc.conf\fR(5), -\fBnamed\fR(8), -\fBnamed.conf\fR(5), -\fBndc\fR(8), -BIND 9 Administrator Reference Manual. -.SH "AUTHOR" -.PP -Internet Systems Consortium -.SH "COPYRIGHT" -Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") -.br -Copyright \(co 2000, 2001 Internet Software Consortium. -.br diff --git a/contrib/bind9/bin/rndc/rndc.c b/contrib/bind9/bin/rndc/rndc.c deleted file mode 100644 index 8fd0d8e..0000000 --- a/contrib/bind9/bin/rndc/rndc.c +++ /dev/null @@ -1,852 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: rndc.c,v 1.96.18.17 2006/08/04 03:03:41 marka Exp $ */ - -/*! \file */ - -/* - * Principal Author: DCL - */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "util.h" - -#define SERVERADDRS 10 - -char *progname; -isc_boolean_t verbose; - -static const char *admin_conffile; -static const char *admin_keyfile; -static const char *version = VERSION; -static const char *servername = NULL; -static isc_sockaddr_t serveraddrs[SERVERADDRS]; -static isc_sockaddr_t local4, local6; -static isc_boolean_t local4set = ISC_FALSE, local6set = ISC_FALSE; -static int nserveraddrs; -static int currentaddr = 0; -static unsigned int remoteport = 0; -static isc_socketmgr_t *socketmgr = NULL; -static unsigned char databuf[2048]; -static isccc_ccmsg_t ccmsg; -static isccc_region_t secret; -static isc_boolean_t failed = ISC_FALSE; -static isc_mem_t *mctx; -static int sends, recvs, connects; -static char *command; -static char *args; -static char program[256]; -static isc_socket_t *sock = NULL; -static isc_uint32_t serial; - -static void rndc_startconnect(isc_sockaddr_t *addr, isc_task_t *task); - -static void -usage(int status) { - fprintf(stderr, "\ -Usage: %s [-c config] [-s server] [-p port]\n\ - [-k key-file ] [-y key] [-V] command\n\ -\n\ -command is one of the following:\n\ -\n\ - reload Reload configuration file and zones.\n\ - reload zone [class [view]]\n\ - Reload a single zone.\n\ - refresh zone [class [view]]\n\ - Schedule immediate maintenance for a zone.\n\ - retransfer zone [class [view]]\n\ - Retransfer a single zone without checking serial number.\n\ - freeze Suspend updates to all dynamic zones.\n\ - freeze zone [class [view]]\n\ - Suspend updates to a dynamic zone.\n\ - thaw Enable updates to all dynamic zones and reload them.\n\ - thaw zone [class [view]]\n\ - Enable updates to a frozen dynamic zone and reload it.\n\ - notify zone [class [view]]\n\ - Resend NOTIFY messages for the zone.\n\ - reconfig Reload configuration file and new zones only.\n\ - stats Write server statistics to the statistics file.\n\ - querylog Toggle query logging.\n\ - dumpdb [-all|-cache|-zones] [view ...]\n\ - Dump cache(s) to the dump file (named_dump.db).\n\ - stop Save pending updates to master files and stop the server.\n\ - stop -p Save pending updates to master files and stop the server\n\ - reporting process id.\n\ - halt Stop the server without saving pending updates.\n\ - halt -p Stop the server without saving pending updates reporting\n\ - process id.\n\ - trace Increment debugging level by one.\n\ - trace level Change the debugging level.\n\ - notrace Set debugging level to 0.\n\ - flush Flushes all of the server's caches.\n\ - flush [view] Flushes the server's cache for a view.\n\ - flushname name [view]\n\ - Flush the given name from the server's cache(s)\n\ - status Display status of the server.\n\ - recursing Dump the queries that are currently recursing (named.recursing)\n\ - validation newstate [view]\n\ - Enable / disable DNSSEC validation.\n\ - *restart Restart the server.\n\ -\n\ -* == not yet implemented\n\ -Version: %s\n", - progname, version); - - exit(status); -} - -static void -get_addresses(const char *host, in_port_t port) { - isc_result_t result; - int found = 0, count; - - if (*host == '/') { - result = isc_sockaddr_frompath(&serveraddrs[nserveraddrs], - host); - if (result == ISC_R_SUCCESS) - nserveraddrs++; - } else { - count = SERVERADDRS - nserveraddrs; - result = bind9_getaddresses(host, port, - &serveraddrs[nserveraddrs], - count, &found); - nserveraddrs += found; - } - if (result != ISC_R_SUCCESS) - fatal("couldn't get address for '%s': %s", - host, isc_result_totext(result)); - INSIST(nserveraddrs > 0); -} - -static void -rndc_senddone(isc_task_t *task, isc_event_t *event) { - isc_socketevent_t *sevent = (isc_socketevent_t *)event; - - UNUSED(task); - - sends--; - if (sevent->result != ISC_R_SUCCESS) - fatal("send failed: %s", isc_result_totext(sevent->result)); - isc_event_free(&event); - if (sends == 0 && recvs == 0) { - isc_socket_detach(&sock); - isc_task_shutdown(task); - RUNTIME_CHECK(isc_app_shutdown() == ISC_R_SUCCESS); - } -} - -static void -rndc_recvdone(isc_task_t *task, isc_event_t *event) { - isccc_sexpr_t *response = NULL; - isccc_sexpr_t *data; - isccc_region_t source; - char *errormsg = NULL; - char *textmsg = NULL; - isc_result_t result; - - recvs--; - - if (ccmsg.result == ISC_R_EOF) - fatal("connection to remote host closed\n" - "This may indicate that\n" - "* the remote server is using an older version of" - " the command protocol,\n" - "* this host is not authorized to connect,\n" - "* the clocks are not syncronized, or\n" - "* the key is invalid."); - - if (ccmsg.result != ISC_R_SUCCESS) - fatal("recv failed: %s", isc_result_totext(ccmsg.result)); - - source.rstart = isc_buffer_base(&ccmsg.buffer); - source.rend = isc_buffer_used(&ccmsg.buffer); - - DO("parse message", isccc_cc_fromwire(&source, &response, &secret)); - - data = isccc_alist_lookup(response, "_data"); - if (data == NULL) - fatal("no data section in response"); - result = isccc_cc_lookupstring(data, "err", &errormsg); - if (result == ISC_R_SUCCESS) { - failed = ISC_TRUE; - fprintf(stderr, "%s: '%s' failed: %s\n", - progname, command, errormsg); - } - else if (result != ISC_R_NOTFOUND) - fprintf(stderr, "%s: parsing response failed: %s\n", - progname, isc_result_totext(result)); - - result = isccc_cc_lookupstring(data, "text", &textmsg); - if (result == ISC_R_SUCCESS) - printf("%s\n", textmsg); - else if (result != ISC_R_NOTFOUND) - fprintf(stderr, "%s: parsing response failed: %s\n", - progname, isc_result_totext(result)); - - isc_event_free(&event); - isccc_sexpr_free(&response); - if (sends == 0 && recvs == 0) { - isc_socket_detach(&sock); - isc_task_shutdown(task); - RUNTIME_CHECK(isc_app_shutdown() == ISC_R_SUCCESS); - } -} - -static void -rndc_recvnonce(isc_task_t *task, isc_event_t *event) { - isccc_sexpr_t *response = NULL; - isccc_sexpr_t *_ctrl; - isccc_region_t source; - isc_result_t result; - isc_uint32_t nonce; - isccc_sexpr_t *request = NULL; - isccc_time_t now; - isc_region_t r; - isccc_sexpr_t *data; - isccc_region_t message; - isc_uint32_t len; - isc_buffer_t b; - - recvs--; - - if (ccmsg.result == ISC_R_EOF) - fatal("connection to remote host closed\n" - "This may indicate that\n" - "* the remote server is using an older version of" - " the command protocol,\n" - "* this host is not authorized to connect,\n" - "* the clocks are not syncronized, or\n" - "* the key is invalid."); - - if (ccmsg.result != ISC_R_SUCCESS) - fatal("recv failed: %s", isc_result_totext(ccmsg.result)); - - source.rstart = isc_buffer_base(&ccmsg.buffer); - source.rend = isc_buffer_used(&ccmsg.buffer); - - DO("parse message", isccc_cc_fromwire(&source, &response, &secret)); - - _ctrl = isccc_alist_lookup(response, "_ctrl"); - if (_ctrl == NULL) - fatal("_ctrl section missing"); - nonce = 0; - if (isccc_cc_lookupuint32(_ctrl, "_nonce", &nonce) != ISC_R_SUCCESS) - nonce = 0; - - isc_stdtime_get(&now); - - DO("create message", isccc_cc_createmessage(1, NULL, NULL, ++serial, - now, now + 60, &request)); - data = isccc_alist_lookup(request, "_data"); - if (data == NULL) - fatal("_data section missing"); - if (isccc_cc_definestring(data, "type", args) == NULL) - fatal("out of memory"); - if (nonce != 0) { - _ctrl = isccc_alist_lookup(request, "_ctrl"); - if (_ctrl == NULL) - fatal("_ctrl section missing"); - if (isccc_cc_defineuint32(_ctrl, "_nonce", nonce) == NULL) - fatal("out of memory"); - } - message.rstart = databuf + 4; - message.rend = databuf + sizeof(databuf); - DO("render message", isccc_cc_towire(request, &message, &secret)); - len = sizeof(databuf) - REGION_SIZE(message); - isc_buffer_init(&b, databuf, 4); - isc_buffer_putuint32(&b, len - 4); - r.length = len; - r.base = databuf; - - isccc_ccmsg_cancelread(&ccmsg); - DO("schedule recv", isccc_ccmsg_readmessage(&ccmsg, task, - rndc_recvdone, NULL)); - recvs++; - DO("send message", isc_socket_send(sock, &r, task, rndc_senddone, - NULL)); - sends++; - - isc_event_free(&event); - isccc_sexpr_free(&response); - return; -} - -static void -rndc_connected(isc_task_t *task, isc_event_t *event) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_socketevent_t *sevent = (isc_socketevent_t *)event; - isccc_sexpr_t *request = NULL; - isccc_sexpr_t *data; - isccc_time_t now; - isccc_region_t message; - isc_region_t r; - isc_uint32_t len; - isc_buffer_t b; - isc_result_t result; - - connects--; - - if (sevent->result != ISC_R_SUCCESS) { - isc_sockaddr_format(&serveraddrs[currentaddr], socktext, - sizeof(socktext)); - if (sevent->result != ISC_R_CANCELED && - ++currentaddr < nserveraddrs) - { - notify("connection failed: %s: %s", socktext, - isc_result_totext(sevent->result)); - isc_socket_detach(&sock); - isc_event_free(&event); - rndc_startconnect(&serveraddrs[currentaddr], task); - return; - } else - fatal("connect failed: %s: %s", socktext, - isc_result_totext(sevent->result)); - } - - isc_stdtime_get(&now); - DO("create message", isccc_cc_createmessage(1, NULL, NULL, ++serial, - now, now + 60, &request)); - data = isccc_alist_lookup(request, "_data"); - if (data == NULL) - fatal("_data section missing"); - if (isccc_cc_definestring(data, "type", "null") == NULL) - fatal("out of memory"); - message.rstart = databuf + 4; - message.rend = databuf + sizeof(databuf); - DO("render message", isccc_cc_towire(request, &message, &secret)); - len = sizeof(databuf) - REGION_SIZE(message); - isc_buffer_init(&b, databuf, 4); - isc_buffer_putuint32(&b, len - 4); - r.length = len; - r.base = databuf; - - isccc_ccmsg_init(mctx, sock, &ccmsg); - isccc_ccmsg_setmaxsize(&ccmsg, 1024); - - DO("schedule recv", isccc_ccmsg_readmessage(&ccmsg, task, - rndc_recvnonce, NULL)); - recvs++; - DO("send message", isc_socket_send(sock, &r, task, rndc_senddone, - NULL)); - sends++; - isc_event_free(&event); -} - -static void -rndc_startconnect(isc_sockaddr_t *addr, isc_task_t *task) { - isc_result_t result; - int pf; - isc_sockettype_t type; - - char socktext[ISC_SOCKADDR_FORMATSIZE]; - - isc_sockaddr_format(addr, socktext, sizeof(socktext)); - - notify("using server %s (%s)", servername, socktext); - - pf = isc_sockaddr_pf(addr); - if (pf == AF_INET || pf == AF_INET6) - type = isc_sockettype_tcp; - else - type = isc_sockettype_unix; - DO("create socket", isc_socket_create(socketmgr, pf, type, &sock)); - switch (isc_sockaddr_pf(addr)) { - case AF_INET: - DO("bind socket", isc_socket_bind(sock, &local4)); - break; - case AF_INET6: - DO("bind socket", isc_socket_bind(sock, &local6)); - break; - default: - break; - } - DO("connect", isc_socket_connect(sock, addr, task, rndc_connected, - NULL)); - connects++; -} - -static void -rndc_start(isc_task_t *task, isc_event_t *event) { - isc_event_free(&event); - - currentaddr = 0; - rndc_startconnect(&serveraddrs[currentaddr], task); -} - -static void -parse_config(isc_mem_t *mctx, isc_log_t *log, const char *keyname, - cfg_parser_t **pctxp, cfg_obj_t **configp) -{ - isc_result_t result; - const char *conffile = admin_conffile; - const cfg_obj_t *addresses = NULL; - const cfg_obj_t *defkey = NULL; - const cfg_obj_t *options = NULL; - const cfg_obj_t *servers = NULL; - const cfg_obj_t *server = NULL; - const cfg_obj_t *keys = NULL; - const cfg_obj_t *key = NULL; - const cfg_obj_t *defport = NULL; - const cfg_obj_t *secretobj = NULL; - const cfg_obj_t *algorithmobj = NULL; - cfg_obj_t *config = NULL; - const cfg_obj_t *address = NULL; - const cfg_listelt_t *elt; - const char *secretstr; - const char *algorithm; - static char secretarray[1024]; - const cfg_type_t *conftype = &cfg_type_rndcconf; - isc_boolean_t key_only = ISC_FALSE; - const cfg_listelt_t *element; - - if (! isc_file_exists(conffile)) { - conffile = admin_keyfile; - conftype = &cfg_type_rndckey; - - if (! isc_file_exists(conffile)) - fatal("neither %s nor %s was found", - admin_conffile, admin_keyfile); - key_only = ISC_TRUE; - } - - DO("create parser", cfg_parser_create(mctx, log, pctxp)); - - /* - * The parser will output its own errors, so DO() is not used. - */ - result = cfg_parse_file(*pctxp, conffile, conftype, &config); - if (result != ISC_R_SUCCESS) - fatal("could not load rndc configuration"); - - if (!key_only) - (void)cfg_map_get(config, "options", &options); - - if (key_only && servername == NULL) - servername = "127.0.0.1"; - else if (servername == NULL && options != NULL) { - const cfg_obj_t *defserverobj = NULL; - (void)cfg_map_get(options, "default-server", &defserverobj); - if (defserverobj != NULL) - servername = cfg_obj_asstring(defserverobj); - } - - if (servername == NULL) - fatal("no server specified and no default"); - - if (!key_only) { - (void)cfg_map_get(config, "server", &servers); - if (servers != NULL) { - for (elt = cfg_list_first(servers); - elt != NULL; - elt = cfg_list_next(elt)) - { - const char *name; - server = cfg_listelt_value(elt); - name = cfg_obj_asstring(cfg_map_getname(server)); - if (strcasecmp(name, servername) == 0) - break; - server = NULL; - } - } - } - - /* - * Look for the name of the key to use. - */ - if (keyname != NULL) - ; /* Was set on command line, do nothing. */ - else if (server != NULL) { - DO("get key for server", cfg_map_get(server, "key", &defkey)); - keyname = cfg_obj_asstring(defkey); - } else if (options != NULL) { - DO("get default key", cfg_map_get(options, "default-key", - &defkey)); - keyname = cfg_obj_asstring(defkey); - } else if (!key_only) - fatal("no key for server and no default"); - - /* - * Get the key's definition. - */ - if (key_only) - DO("get key", cfg_map_get(config, "key", &key)); - else { - DO("get config key list", cfg_map_get(config, "key", &keys)); - for (elt = cfg_list_first(keys); - elt != NULL; - elt = cfg_list_next(elt)) - { - key = cfg_listelt_value(elt); - if (strcasecmp(cfg_obj_asstring(cfg_map_getname(key)), - keyname) == 0) - break; - } - if (elt == NULL) - fatal("no key definition for name %s", keyname); - } - (void)cfg_map_get(key, "secret", &secretobj); - (void)cfg_map_get(key, "algorithm", &algorithmobj); - if (secretobj == NULL || algorithmobj == NULL) - fatal("key must have algorithm and secret"); - - secretstr = cfg_obj_asstring(secretobj); - algorithm = cfg_obj_asstring(algorithmobj); - - if (strcasecmp(algorithm, "hmac-md5") != 0) - fatal("unsupported algorithm: %s", algorithm); - - secret.rstart = (unsigned char *)secretarray; - secret.rend = (unsigned char *)secretarray + sizeof(secretarray); - DO("decode base64 secret", isccc_base64_decode(secretstr, &secret)); - secret.rend = secret.rstart; - secret.rstart = (unsigned char *)secretarray; - - /* - * Find the port to connect to. - */ - if (remoteport != 0) - ; /* Was set on command line, do nothing. */ - else { - if (server != NULL) - (void)cfg_map_get(server, "port", &defport); - if (defport == NULL && options != NULL) - (void)cfg_map_get(options, "default-port", &defport); - } - if (defport != NULL) { - remoteport = cfg_obj_asuint32(defport); - if (remoteport > 65535 || remoteport == 0) - fatal("port %u out of range", remoteport); - } else if (remoteport == 0) - remoteport = NS_CONTROL_PORT; - - if (server != NULL) - result = cfg_map_get(server, "addresses", &addresses); - else - result = ISC_R_NOTFOUND; - if (result == ISC_R_SUCCESS) { - for (element = cfg_list_first(addresses); - element != NULL; - element = cfg_list_next(element)) - { - isc_sockaddr_t sa; - - address = cfg_listelt_value(element); - if (!cfg_obj_issockaddr(address)) { - unsigned int myport; - const char *name; - const cfg_obj_t *obj; - - obj = cfg_tuple_get(address, "name"); - name = cfg_obj_asstring(obj); - obj = cfg_tuple_get(address, "port"); - if (cfg_obj_isuint32(obj)) { - myport = cfg_obj_asuint32(obj); - if (myport > ISC_UINT16_MAX || - myport == 0) - fatal("port %u out of range", - myport); - } else - myport = remoteport; - if (nserveraddrs < SERVERADDRS) - get_addresses(name, (in_port_t) myport); - else - fprintf(stderr, "too many address: " - "%s: dropped\n", name); - continue; - } - sa = *cfg_obj_assockaddr(address); - if (isc_sockaddr_getport(&sa) == 0) - isc_sockaddr_setport(&sa, remoteport); - if (nserveraddrs < SERVERADDRS) - serveraddrs[nserveraddrs++] = sa; - else { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - - isc_sockaddr_format(&sa, socktext, - sizeof(socktext)); - fprintf(stderr, - "too many address: %s: dropped\n", - socktext); - } - } - } - - if (!local4set && server != NULL) { - address = NULL; - cfg_map_get(server, "source-address", &address); - if (address != NULL) { - local4 = *cfg_obj_assockaddr(address); - local4set = ISC_TRUE; - } - } - if (!local4set && options != NULL) { - address = NULL; - cfg_map_get(options, "default-source-address", &address); - if (address != NULL) { - local4 = *cfg_obj_assockaddr(address); - local4set = ISC_TRUE; - } - } - - if (!local6set && server != NULL) { - address = NULL; - cfg_map_get(server, "source-address-v6", &address); - if (address != NULL) { - local6 = *cfg_obj_assockaddr(address); - local6set = ISC_TRUE; - } - } - if (!local6set && options != NULL) { - address = NULL; - cfg_map_get(options, "default-source-address-v6", &address); - if (address != NULL) { - local6 = *cfg_obj_assockaddr(address); - local6set = ISC_TRUE; - } - } - - *configp = config; -} - -int -main(int argc, char **argv) { - isc_boolean_t show_final_mem = ISC_FALSE; - isc_result_t result = ISC_R_SUCCESS; - isc_taskmgr_t *taskmgr = NULL; - isc_task_t *task = NULL; - isc_log_t *log = NULL; - isc_logconfig_t *logconfig = NULL; - isc_logdestination_t logdest; - cfg_parser_t *pctx = NULL; - cfg_obj_t *config = NULL; - const char *keyname = NULL; - struct in_addr in; - struct in6_addr in6; - char *p; - size_t argslen; - int ch; - int i; - - result = isc_file_progname(*argv, program, sizeof(program)); - if (result != ISC_R_SUCCESS) - memcpy(program, "rndc", 5); - progname = program; - - admin_conffile = RNDC_CONFFILE; - admin_keyfile = RNDC_KEYFILE; - - isc_sockaddr_any(&local4); - isc_sockaddr_any6(&local6); - - result = isc_app_start(); - if (result != ISC_R_SUCCESS) - fatal("isc_app_start() failed: %s", isc_result_totext(result)); - - while ((ch = isc_commandline_parse(argc, argv, "b:c:k:Mmp:s:Vy:")) - != -1) { - switch (ch) { - case 'b': - if (inet_pton(AF_INET, isc_commandline_argument, - &in) == 1) { - isc_sockaddr_fromin(&local4, &in, 0); - local4set = ISC_TRUE; - } else if (inet_pton(AF_INET6, isc_commandline_argument, - &in6) == 1) { - isc_sockaddr_fromin6(&local6, &in6, 0); - local6set = ISC_TRUE; - } - break; - - case 'c': - admin_conffile = isc_commandline_argument; - break; - - case 'k': - admin_keyfile = isc_commandline_argument; - break; - - case 'M': - isc_mem_debugging = ISC_MEM_DEBUGTRACE; - break; - - case 'm': - show_final_mem = ISC_TRUE; - break; - - case 'p': - remoteport = atoi(isc_commandline_argument); - if (remoteport > 65535 || remoteport == 0) - fatal("port '%s' out of range", - isc_commandline_argument); - break; - - case 's': - servername = isc_commandline_argument; - break; - - case 'V': - verbose = ISC_TRUE; - break; - - case 'y': - keyname = isc_commandline_argument; - break; - - case '?': - usage(0); - break; - - default: - fatal("unexpected error parsing command arguments: " - "got %c\n", ch); - break; - } - } - - argc -= isc_commandline_index; - argv += isc_commandline_index; - - if (argc < 1) - usage(1); - - isc_random_get(&serial); - - DO("create memory context", isc_mem_create(0, 0, &mctx)); - DO("create socket manager", isc_socketmgr_create(mctx, &socketmgr)); - DO("create task manager", isc_taskmgr_create(mctx, 1, 0, &taskmgr)); - DO("create task", isc_task_create(taskmgr, 0, &task)); - - DO("create logging context", isc_log_create(mctx, &log, &logconfig)); - isc_log_setcontext(log); - DO("setting log tag", isc_log_settag(logconfig, progname)); - logdest.file.stream = stderr; - logdest.file.name = NULL; - logdest.file.versions = ISC_LOG_ROLLNEVER; - logdest.file.maximum_size = 0; - DO("creating log channel", - isc_log_createchannel(logconfig, "stderr", - ISC_LOG_TOFILEDESC, ISC_LOG_INFO, &logdest, - ISC_LOG_PRINTTAG|ISC_LOG_PRINTLEVEL)); - DO("enabling log channel", isc_log_usechannel(logconfig, "stderr", - NULL, NULL)); - - parse_config(mctx, log, keyname, &pctx, &config); - - isccc_result_register(); - - command = *argv; - - /* - * Convert argc/argv into a space-delimited command string - * similar to what the user might enter in interactive mode - * (if that were implemented). - */ - argslen = 0; - for (i = 0; i < argc; i++) - argslen += strlen(argv[i]) + 1; - - args = isc_mem_get(mctx, argslen); - if (args == NULL) - DO("isc_mem_get", ISC_R_NOMEMORY); - - p = args; - for (i = 0; i < argc; i++) { - size_t len = strlen(argv[i]); - memcpy(p, argv[i], len); - p += len; - *p++ = ' '; - } - - p--; - *p++ = '\0'; - INSIST(p == args + argslen); - - notify("%s", command); - - if (strcmp(command, "restart") == 0) - fatal("'%s' is not implemented", command); - - if (nserveraddrs == 0) - get_addresses(servername, (in_port_t) remoteport); - - DO("post event", isc_app_onrun(mctx, task, rndc_start, NULL)); - - result = isc_app_run(); - if (result != ISC_R_SUCCESS) - fatal("isc_app_run() failed: %s", isc_result_totext(result)); - - if (connects > 0 || sends > 0 || recvs > 0) - isc_socket_cancel(sock, task, ISC_SOCKCANCEL_ALL); - - isc_task_detach(&task); - isc_taskmgr_destroy(&taskmgr); - isc_socketmgr_destroy(&socketmgr); - isc_log_destroy(&log); - isc_log_setcontext(NULL); - - cfg_obj_destroy(pctx, &config); - cfg_parser_destroy(&pctx); - - isc_mem_put(mctx, args, argslen); - isccc_ccmsg_invalidate(&ccmsg); - - dns_name_destroy(); - - if (show_final_mem) - isc_mem_stats(mctx, stderr); - - isc_mem_destroy(&mctx); - - if (failed) - return (1); - - return (0); -} diff --git a/contrib/bind9/bin/rndc/rndc.conf b/contrib/bind9/bin/rndc/rndc.conf deleted file mode 100644 index e303535..0000000 --- a/contrib/bind9/bin/rndc/rndc.conf +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: rndc.conf,v 1.8.18.1 2004/06/18 04:39:39 marka Exp $ */ - -/* - * Sample rndc configuration file. - */ - -options { - default-server localhost; - default-key "key"; -}; - -server localhost { - key "key"; -}; - -key "cc64b3d1db63fc88d7cb5d2f9f57d258" { - algorithm hmac-md5; - secret "34f88008d07deabbe65bd01f1d233d47"; -}; - -server "test1" { - key "cc64b3d1db63fc88d7cb5d2f9f57d258"; - port 5353; - addresses { 10.53.0.1; }; -}; - -key "key" { - algorithm hmac-md5; - secret "c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K"; -}; diff --git a/contrib/bind9/bin/rndc/rndc.conf.5 b/contrib/bind9/bin/rndc/rndc.conf.5 deleted file mode 100644 index dbeb707..0000000 --- a/contrib/bind9/bin/rndc/rndc.conf.5 +++ /dev/null @@ -1,214 +0,0 @@ -.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") -.\" Copyright (C) 2000, 2001 Internet Software Consortium. -.\" -.\" Permission to use, copy, modify, and 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: rndc.conf.5,v 1.23.18.15 2007/05/09 13:35:47 marka Exp $ -.\" -.hy 0 -.ad l -.\" Title: \fIrndc.conf\fR -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.71.1 -.\" Date: June 30, 2000 -.\" Manual: BIND9 -.\" Source: BIND9 -.\" -.TH "\fIRNDC.CONF\fR" "5" "June 30, 2000" "BIND9" "BIND9" -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.SH "NAME" -rndc.conf \- rndc configuration file -.SH "SYNOPSIS" -.HP 10 -\fBrndc.conf\fR -.SH "DESCRIPTION" -.PP -\fIrndc.conf\fR -is the configuration file for -\fBrndc\fR, the BIND 9 name server control utility. This file has a similar structure and syntax to -\fInamed.conf\fR. Statements are enclosed in braces and terminated with a semi\-colon. Clauses in the statements are also semi\-colon terminated. The usual comment styles are supported: -.PP -C style: /* */ -.PP -C++ style: // to end of line -.PP -Unix style: # to end of line -.PP -\fIrndc.conf\fR -is much simpler than -\fInamed.conf\fR. The file uses three statements: an options statement, a server statement and a key statement. -.PP -The -\fBoptions\fR -statement contains five clauses. The -\fBdefault\-server\fR -clause is followed by the name or address of a name server. This host will be used when no name server is given as an argument to -\fBrndc\fR. The -\fBdefault\-key\fR -clause is followed by the name of a key which is identified by a -\fBkey\fR -statement. If no -\fBkeyid\fR -is provided on the rndc command line, and no -\fBkey\fR -clause is found in a matching -\fBserver\fR -statement, this default key will be used to authenticate the server's commands and responses. The -\fBdefault\-port\fR -clause is followed by the port to connect to on the remote name server. If no -\fBport\fR -option is provided on the rndc command line, and no -\fBport\fR -clause is found in a matching -\fBserver\fR -statement, this default port will be used to connect. The -\fBdefault\-source\-address\fR -and -\fBdefault\-source\-address\-v6\fR -clauses which can be used to set the IPv4 and IPv6 source addresses respectively. -.PP -After the -\fBserver\fR -keyword, the server statement includes a string which is the hostname or address for a name server. The statement has three possible clauses: -\fBkey\fR, -\fBport\fR -and -\fBaddresses\fR. The key name must match the name of a key statement in the file. The port number specifies the port to connect to. If an -\fBaddresses\fR -clause is supplied these addresses will be used instead of the server name. Each address can take an optional port. If an -\fBsource\-address\fR -or -\fBsource\-address\-v6\fR -of supplied then these will be used to specify the IPv4 and IPv6 source addresses respectively. -.PP -The -\fBkey\fR -statement begins with an identifying string, the name of the key. The statement has two clauses. -\fBalgorithm\fR -identifies the encryption algorithm for -\fBrndc\fR -to use; currently only HMAC\-MD5 is supported. This is followed by a secret clause which contains the base\-64 encoding of the algorithm's encryption key. The base\-64 string is enclosed in double quotes. -.PP -There are two common ways to generate the base\-64 string for the secret. The BIND 9 program -\fBrndc\-confgen\fR -can be used to generate a random key, or the -\fBmmencode\fR -program, also known as -\fBmimencode\fR, can be used to generate a base\-64 string from known input. -\fBmmencode\fR -does not ship with BIND 9 but is available on many systems. See the EXAMPLE section for sample command lines for each. -.SH "EXAMPLE" -.PP -.RS 4 -.nf - options { - default\-server localhost; - default\-key samplekey; - }; -.fi -.RE -.sp -.PP -.RS 4 -.nf - server localhost { - key samplekey; - }; -.fi -.RE -.sp -.PP -.RS 4 -.nf - server testserver { - key testkey; - addresses { localhost port 5353; }; - }; -.fi -.RE -.sp -.PP -.RS 4 -.nf - key samplekey { - algorithm hmac\-md5; - secret "6FMfj43Osz4lyb24OIe2iGEz9lf1llJO+lz"; - }; -.fi -.RE -.sp -.PP -.RS 4 -.nf - key testkey { - algorithm hmac\-md5; - secret "R3HI8P6BKw9ZwXwN3VZKuQ=="; - }; -.fi -.RE -.sp -.PP -In the above example, -\fBrndc\fR -will by default use the server at localhost (127.0.0.1) and the key called samplekey. Commands to the localhost server will use the samplekey key, which must also be defined in the server's configuration file with the same name and secret. The key statement indicates that samplekey uses the HMAC\-MD5 algorithm and its secret clause contains the base\-64 encoding of the HMAC\-MD5 secret enclosed in double quotes. -.PP -If -\fBrndc \-s testserver\fR -is used then -\fBrndc\fR -will connect to server on localhost port 5353 using the key testkey. -.PP -To generate a random secret with -\fBrndc\-confgen\fR: -.PP -\fBrndc\-confgen\fR -.PP -A complete -\fIrndc.conf\fR -file, including the randomly generated key, will be written to the standard output. Commented\-out -\fBkey\fR -and -\fBcontrols\fR -statements for -\fInamed.conf\fR -are also printed. -.PP -To generate a base\-64 secret with -\fBmmencode\fR: -.PP -\fBecho "known plaintext for a secret" | mmencode\fR -.SH "NAME SERVER CONFIGURATION" -.PP -The name server must be configured to accept rndc connections and to recognize the key specified in the -\fIrndc.conf\fR -file, using the controls statement in -\fInamed.conf\fR. See the sections on the -\fBcontrols\fR -statement in the BIND 9 Administrator Reference Manual for details. -.SH "SEE ALSO" -.PP -\fBrndc\fR(8), -\fBrndc\-confgen\fR(8), -\fBmmencode\fR(1), -BIND 9 Administrator Reference Manual. -.SH "AUTHOR" -.PP -Internet Systems Consortium -.SH "COPYRIGHT" -Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") -.br -Copyright \(co 2000, 2001 Internet Software Consortium. -.br diff --git a/contrib/bind9/bin/rndc/rndc.conf.docbook b/contrib/bind9/bin/rndc/rndc.conf.docbook deleted file mode 100644 index ebea7af..0000000 --- a/contrib/bind9/bin/rndc/rndc.conf.docbook +++ /dev/null @@ -1,252 +0,0 @@ -]> - - - - - - June 30, 2000 - - - - rndc.conf - 5 - BIND9 - - - - rndc.conf - rndc configuration file - - - - - 2004 - 2005 - 2007 - Internet Systems Consortium, Inc. ("ISC") - - - 2000 - 2001 - Internet Software Consortium. - - - - - - rndc.conf - - - - - 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 - named.conf. Statements are enclosed - in braces and terminated with a semi-colon. Clauses in - the statements are also semi-colon terminated. The usual - comment styles are supported: - - - C style: /* */ - - - C++ style: // to end of line - - - Unix style: # to end of line - - rndc.conf is much simpler than - named.conf. The file uses three - statements: an options statement, a server statement - and a key statement. - - - The statement contains five clauses. - The clause is followed by the - name or address of a name server. This host will be used when - no name server is given as an argument to - rndc. The - clause is followed by the name of a key which is identified by - a statement. If no - is provided on the rndc command line, - and no clause is found in a matching - statement, this default key will be - used to authenticate the server's commands and responses. The - clause is followed by the port - to connect to on the remote name server. If no - option is provided on the rndc command - line, and no clause is found in a - matching statement, this default port - will be used to connect. - The and - clauses which - can be used to set the IPv4 and IPv6 source addresses - respectively. - - - After the keyword, the server - statement includes a string which is the hostname or address - for a name server. The statement has three possible clauses: - , and - . The key name must match the - name of a key statement in the file. The port number - specifies the port to connect to. If an - clause is supplied these addresses will be used instead of - the server name. Each address can take an optional port. - If an or - of supplied then these will be used to specify the IPv4 and IPv6 - source addresses respectively. - - - The statement begins with an identifying - string, the name of the key. The statement has two clauses. - identifies the encryption algorithm - for rndc to use; currently only HMAC-MD5 - is - supported. This is followed by a secret clause which contains - the base-64 encoding of the algorithm's encryption key. The - base-64 string is enclosed in double quotes. - - - There are two common ways to generate the base-64 string for the - secret. The BIND 9 program rndc-confgen - can - be used to generate a random key, or the - mmencode program, also known as - mimencode, can be used to generate a - base-64 - string from known input. mmencode does - not - ship with BIND 9 but is available on many systems. See the - EXAMPLE section for sample command lines for each. - - - - - EXAMPLE - - - options { - default-server localhost; - default-key samplekey; - }; - - - - server localhost { - key samplekey; - }; - - - - server testserver { - key testkey; - addresses { localhost port 5353; }; - }; - - - - key samplekey { - algorithm hmac-md5; - secret "6FMfj43Osz4lyb24OIe2iGEz9lf1llJO+lz"; - }; - - - - key testkey { - algorithm hmac-md5; - secret "R3HI8P6BKw9ZwXwN3VZKuQ=="; - }; - - - - - In the above example, rndc will by - default use - the server at localhost (127.0.0.1) and the key called samplekey. - Commands to the localhost server will use the samplekey key, which - must also be defined in the server's configuration file with the - same name and secret. The key statement indicates that samplekey - uses the HMAC-MD5 algorithm and its secret clause contains the - base-64 encoding of the HMAC-MD5 secret enclosed in double quotes. - - - If rndc -s testserver is used then rndc will - connect to server on localhost port 5353 using the key testkey. - - - To generate a random secret with rndc-confgen: - - rndc-confgen - - - A complete rndc.conf file, including - the - randomly generated key, will be written to the standard - output. Commented-out and - statements for - named.conf are also printed. - - - To generate a base-64 secret with mmencode: - - echo "known plaintext for a secret" | mmencode - - - - - NAME SERVER CONFIGURATION - - The name server must be configured to accept rndc connections and - to recognize the key specified in the rndc.conf - file, using the controls statement in named.conf. - See the sections on the statement in the - BIND 9 Administrator Reference Manual for details. - - - - - SEE ALSO - - rndc8 - , - - rndc-confgen8 - , - - mmencode1 - , - BIND 9 Administrator Reference Manual. - - - - - AUTHOR - Internet Systems Consortium - - - - diff --git a/contrib/bind9/bin/rndc/rndc.conf.html b/contrib/bind9/bin/rndc/rndc.conf.html deleted file mode 100644 index d11f9df..0000000 --- a/contrib/bind9/bin/rndc/rndc.conf.html +++ /dev/null @@ -1,217 +0,0 @@ - - - - - -rndc.conf - - -
-
-
-

Name

-

rndc.conf — rndc configuration file

-
-
-

Synopsis

-

rndc.conf

-
-
-

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 - named.conf. Statements are enclosed - in braces and terminated with a semi-colon. Clauses in - the statements are also semi-colon terminated. The usual - comment styles are supported: -

-

- C style: /* */ -

-

- C++ style: // to end of line -

-

- Unix style: # to end of line -

-

rndc.conf is much simpler than - named.conf. The file uses three - statements: an options statement, a server statement - and a key statement. -

-

- The options statement contains five clauses. - The default-server clause is followed by the - name or address of a name server. This host will be used when - no name server is given as an argument to - rndc. The default-key - clause is followed by the name of a key which is identified by - a key statement. If no - keyid is provided on the rndc command line, - and no key clause is found in a matching - server statement, this default key will be - used to authenticate the server's commands and responses. The - default-port clause is followed by the port - to connect to on the remote name server. If no - port option is provided on the rndc command - line, and no port clause is found in a - matching server statement, this default port - will be used to connect. - The default-source-address and - default-source-address-v6 clauses which - can be used to set the IPv4 and IPv6 source addresses - respectively. -

-

- After the server keyword, the server - statement includes a string which is the hostname or address - for a name server. The statement has three possible clauses: - key, port and - addresses. The key name must match the - name of a key statement in the file. The port number - specifies the port to connect to. If an addresses - clause is supplied these addresses will be used instead of - the server name. Each address can take an optional port. - If an source-address or source-address-v6 - of supplied then these will be used to specify the IPv4 and IPv6 - source addresses respectively. -

-

- The key statement begins with an identifying - string, the name of the key. The statement has two clauses. - algorithm identifies the encryption algorithm - for rndc to use; currently only HMAC-MD5 - is - supported. This is followed by a secret clause which contains - the base-64 encoding of the algorithm's encryption key. The - base-64 string is enclosed in double quotes. -

-

- There are two common ways to generate the base-64 string for the - secret. The BIND 9 program rndc-confgen - can - be used to generate a random key, or the - mmencode program, also known as - mimencode, can be used to generate a - base-64 - string from known input. mmencode does - not - ship with BIND 9 but is available on many systems. See the - EXAMPLE section for sample command lines for each. -

-
-
-

EXAMPLE

-
-      options {
-        default-server  localhost;
-        default-key     samplekey;
-      };
-
-

-

-
-      server localhost {
-        key             samplekey;
-      };
-
-

-

-
-      server testserver {
-        key		testkey;
-        addresses	{ localhost port 5353; };
-      };
-
-

-

-
-      key samplekey {
-        algorithm       hmac-md5;
-        secret          "6FMfj43Osz4lyb24OIe2iGEz9lf1llJO+lz";
-      };
-
-

-

-
-      key testkey {
-        algorithm	hmac-md5;
-        secret		"R3HI8P6BKw9ZwXwN3VZKuQ==";
-      };
-    
-

-

-

- In the above example, rndc will by - default use - the server at localhost (127.0.0.1) and the key called samplekey. - Commands to the localhost server will use the samplekey key, which - must also be defined in the server's configuration file with the - same name and secret. The key statement indicates that samplekey - uses the HMAC-MD5 algorithm and its secret clause contains the - base-64 encoding of the HMAC-MD5 secret enclosed in double quotes. -

-

- If rndc -s testserver is used then rndc will - connect to server on localhost port 5353 using the key testkey. -

-

- To generate a random secret with rndc-confgen: -

-

rndc-confgen -

-

- A complete rndc.conf file, including - the - randomly generated key, will be written to the standard - output. Commented-out key and - controls statements for - named.conf are also printed. -

-

- To generate a base-64 secret with mmencode: -

-

echo "known plaintext for a secret" | mmencode -

-
-
-

NAME SERVER CONFIGURATION

-

- The name server must be configured to accept rndc connections and - to recognize the key specified in the rndc.conf - file, using the controls statement in named.conf. - See the sections on the controls statement in the - BIND 9 Administrator Reference Manual for details. -

-
-
-

SEE ALSO

-

rndc(8), - rndc-confgen(8), - mmencode(1), - BIND 9 Administrator Reference Manual. -

-
-
-

AUTHOR

-

Internet Systems Consortium -

-
-
- diff --git a/contrib/bind9/bin/rndc/rndc.docbook b/contrib/bind9/bin/rndc/rndc.docbook deleted file mode 100644 index 0719a74..0000000 --- a/contrib/bind9/bin/rndc/rndc.docbook +++ /dev/null @@ -1,250 +0,0 @@ -]> - - - - - - June 30, 2000 - - - - rndc - 8 - BIND9 - - - - rndc - name server control utility - - - - - 2004 - 2005 - 2007 - Internet Systems Consortium, Inc. ("ISC") - - - 2000 - 2001 - Internet Software Consortium. - - - - - - rndc - - - - - - - - command - - - - - DESCRIPTION - rndc - controls the operation of a name - server. It supersedes the ndc utility - that was provided in old BIND releases. If - rndc is invoked with no command line - options or arguments, it prints a short summary of the - supported commands and the available options and their - arguments. - - rndc - communicates with the name server - over a TCP connection, sending commands authenticated with - digital signatures. In the current versions of - rndc and named, - the only supported authentication algorithm is HMAC-MD5, - which uses a shared secret on each end of the connection. - This provides TSIG-style authentication for the command - request and the name server's response. All commands sent - over the channel must be signed by a key_id known to the - server. - - rndc - reads a configuration file to - determine how to contact the name server and decide what - algorithm and key it should use. - - - - - OPTIONS - - - - -b source-address - - - Use source-address - as the source address for the connection to the server. - Multiple instances are permitted to allow setting of both - the IPv4 and IPv6 source addresses. - - - - - - -c config-file - - - Use config-file - as the configuration file instead of the default, - /etc/rndc.conf. - - - - - - -k key-file - - - Use key-file - as the key file instead of the default, - /etc/rndc.key. The key in - /etc/rndc.key will be used to - authenticate - commands sent to the server if the config-file - does not exist. - - - - - - -s server - - server is - the name or address of the server which matches a - server statement in the configuration file for - rndc. If no server is supplied on the - command line, the host named by the default-server clause - in the options statement of the rndc - configuration file will be used. - - - - - - -p port - - - Send commands to TCP port - port - instead - of BIND 9's default control channel port, 953. - - - - - - -V - - - Enable verbose logging. - - - - - - -y key_id - - - Use the key key_id - from the configuration file. - key_id - must be - known by named with the same algorithm and secret string - in order for control message validation to succeed. - If no key_id - is specified, rndc will first look - for a key clause in the server statement of the server - being used, or if no server statement is present for that - host, then the default-key clause of the options statement. - Note that the configuration file contains shared secrets - which are used to send authenticated control commands - to name servers. It should therefore not have general read - or write access. - - - - - - - - For the complete set of commands supported by rndc, - see the BIND 9 Administrator Reference Manual or run - rndc without arguments to see its help - message. - - - - - - LIMITATIONS - rndc - does not yet support all the commands of - the BIND 8 ndc utility. - - - There is currently no way to provide the shared secret for a - without using the configuration file. - - - Several error messages could be clearer. - - - - - SEE ALSO - - rndc.conf5 - , - - named8 - , - - named.conf5 - , - - ndc8 - , - BIND 9 Administrator Reference Manual. - - - - - AUTHOR - Internet Systems Consortium - - - - diff --git a/contrib/bind9/bin/rndc/rndc.html b/contrib/bind9/bin/rndc/rndc.html deleted file mode 100644 index d4d0ebb..0000000 --- a/contrib/bind9/bin/rndc/rndc.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - - -rndc - - -
-
-
-

Name

-

rndc — name server control utility

-
-
-

Synopsis

-

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

-
-
-

DESCRIPTION

-

rndc - controls the operation of a name - server. It supersedes the ndc utility - that was provided in old BIND releases. If - rndc is invoked with no command line - options or arguments, it prints a short summary of the - supported commands and the available options and their - arguments. -

-

rndc - communicates with the name server - over a TCP connection, sending commands authenticated with - digital signatures. In the current versions of - rndc and named, - the only supported authentication algorithm is HMAC-MD5, - which uses a shared secret on each end of the connection. - This provides TSIG-style authentication for the command - request and the name server's response. All commands sent - over the channel must be signed by a key_id known to the - server. -

-

rndc - reads a configuration file to - determine how to contact the name server and decide what - algorithm and key it should use. -

-
-
-

OPTIONS

-
-
-b source-address
-

- Use source-address - as the source address for the connection to the server. - Multiple instances are permitted to allow setting of both - the IPv4 and IPv6 source addresses. -

-
-c config-file
-

- Use config-file - as the configuration file instead of the default, - /etc/rndc.conf. -

-
-k key-file
-

- Use key-file - as the key file instead of the default, - /etc/rndc.key. The key in - /etc/rndc.key will be used to - authenticate - commands sent to the server if the config-file - does not exist. -

-
-s server
-

server is - the name or address of the server which matches a - server statement in the configuration file for - rndc. If no server is supplied on the - command line, the host named by the default-server clause - in the options statement of the rndc - configuration file will be used. -

-
-p port
-

- Send commands to TCP port - port - instead - of BIND 9's default control channel port, 953. -

-
-V
-

- Enable verbose logging. -

-
-y key_id
-

- Use the key key_id - from the configuration file. - key_id - must be - known by named with the same algorithm and secret string - in order for control message validation to succeed. - If no key_id - is specified, rndc will first look - for a key clause in the server statement of the server - being used, or if no server statement is present for that - host, then the default-key clause of the options statement. - Note that the configuration file contains shared secrets - which are used to send authenticated control commands - to name servers. It should therefore not have general read - or write access. -

-
-

- For the complete set of commands supported by rndc, - see the BIND 9 Administrator Reference Manual or run - rndc without arguments to see its help - message. -

-
-
-

LIMITATIONS

-

rndc - does not yet support all the commands of - the BIND 8 ndc utility. -

-

- There is currently no way to provide the shared secret for a - key_id without using the configuration file. -

-

- Several error messages could be clearer. -

-
-
-

SEE ALSO

-

rndc.conf(5), - named(8), - named.conf(5), - ndc(8), - BIND 9 Administrator Reference Manual. -

-
-
-

AUTHOR

-

Internet Systems Consortium -

-
-
- diff --git a/contrib/bind9/bin/rndc/unix/Makefile.in b/contrib/bind9/bin/rndc/unix/Makefile.in deleted file mode 100644 index 6696c23..0000000 --- a/contrib/bind9/bin/rndc/unix/Makefile.in +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 2001 Internet Software Consortium. -# -# Permission to use, copy, modify, and 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: Makefile.in,v 1.3 2004/03/05 04:58:29 marka Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -@BIND9_MAKE_INCLUDES@ - -CINCLUDES = -I${srcdir}/include -I${srcdir}/../include \ - ${DNS_INCLUDES} ${ISC_INCLUDES} - -CDEFINES = -CWARNINGS = - -OBJS = os.@O@ - -SRCS = os.c - -TARGETS = ${OBJS} - -@BIND9_MAKE_RULES@ diff --git a/contrib/bind9/bin/rndc/unix/os.c b/contrib/bind9/bin/rndc/unix/os.c deleted file mode 100644 index f5f6a91..0000000 --- a/contrib/bind9/bin/rndc/unix/os.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: os.c,v 1.6.18.2 2005/04/29 00:15:41 marka Exp $ */ - -/*! \file */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -int -set_user(FILE *fd, const char *user) { - struct passwd *pw; - - pw = getpwnam(user); - if (pw == NULL) { - errno = EINVAL; - return (-1); - } - return (fchown(fileno(fd), pw->pw_uid, -1)); -} - -FILE * -safe_create(const char *filename) { - int fd; - FILE *f; - struct stat sb; - int flags = O_WRONLY; - - if (stat(filename, &sb) == -1) { - if (errno != ENOENT) - return (NULL); - flags = O_WRONLY | O_CREAT | O_EXCL; - } else if ((sb.st_mode & S_IFREG) == 0) { - errno = EOPNOTSUPP; - return (NULL); - } else - flags = O_WRONLY | O_TRUNC; - - fd = open(filename, flags, S_IRUSR | S_IWUSR); - if (fd == -1) - return (NULL); - f = fdopen(fd, "w"); - if (f == NULL) - close(fd); - return (f); -} diff --git a/contrib/bind9/bin/rndc/util.c b/contrib/bind9/bin/rndc/util.c deleted file mode 100644 index c64add72..0000000 --- a/contrib/bind9/bin/rndc/util.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: util.c,v 1.3.18.2 2005/04/29 00:15:40 marka Exp $ */ - -/*! \file */ - -#include - -#include -#include -#include - -#include - -#include "util.h" - -extern isc_boolean_t verbose; -extern const char *progname; - -void -notify(const char *fmt, ...) { - va_list ap; - - if (verbose) { - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fputs("\n", stderr); - } -} - -void -fatal(const char *format, ...) { - va_list args; - - fprintf(stderr, "%s: ", progname); - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); - fprintf(stderr, "\n"); - exit(1); -} diff --git a/contrib/bind9/bin/rndc/util.h b/contrib/bind9/bin/rndc/util.h deleted file mode 100644 index 6414861..0000000 --- a/contrib/bind9/bin/rndc/util.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and 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: util.h,v 1.6.18.2 2005/04/29 00:15:41 marka Exp $ */ - -#ifndef RNDC_UTIL_H -#define RNDC_UTIL_H 1 - -/*! \file */ - -#include - -#include - -#define NS_CONTROL_PORT 953 - -#undef DO -#define DO(name, function) \ - do { \ - result = function; \ - if (result != ISC_R_SUCCESS) \ - fatal("%s: %s", name, isc_result_totext(result)); \ - else \ - notify("%s", name); \ - } while (0) - -ISC_LANG_BEGINDECLS - -void -notify(const char *fmt, ...) ISC_FORMAT_PRINTF(1, 2); - -void -fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); - -ISC_LANG_ENDDECLS - -#endif /* RNDC_UTIL_H */ diff --git a/contrib/bind9/config.guess b/contrib/bind9/config.guess deleted file mode 100644 index 7d0185e..0000000 --- a/contrib/bind9/config.guess +++ /dev/null @@ -1,1447 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - -timestamp='2004-09-07' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Per Bothner . -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; - --version | -v ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit 0 ;; - amd64:OpenBSD:*:*) - echo x86_64-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - amiga:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - cats:OpenBSD:*:*) - echo arm-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - hp300:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - luna88k:OpenBSD:*:*) - echo m88k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mac68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - macppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme88k:OpenBSD:*:*) - echo m88k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvmeppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sgi:OpenBSD:*:*) - echo mips64-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sun3:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - *:OpenBSD:*:*) - echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit 0 ;; - macppc:MirBSD:*:*) - echo powerppc-unknown-mirbsd${UNAME_RELEASE} - exit 0 ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit 0 ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit 0 ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit 0 ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit 0 ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit 0;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit 0 ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit 0 ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit 0 ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit 0 ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit 0;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit 0;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit 0 ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit 0 ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit 0 ;; - DRS?6000:UNIX_SV:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7 && exit 0 ;; - esac ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit 0 ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit 0 ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit 0 ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit 0 ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit 0 ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit 0 ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit 0 ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit 0 ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit 0 ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit 0 ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit 0 ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c \ - && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ - && exit 0 - echo mips-mips-riscos${UNAME_RELEASE} - exit 0 ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit 0 ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit 0 ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit 0 ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit 0 ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit 0 ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit 0 ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit 0 ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit 0 ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit 0 ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit 0 ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit 0 ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit 0 ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit 0 ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit 0 ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 - echo rs6000-ibm-aix3.2.5 - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit 0 ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit 0 ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit 0 ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit 0 ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit 0 ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit 0 ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit 0 ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit 0 ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - # avoid double evaluation of $set_cc_for_build - test -n "$CC_FOR_BUILD" || eval $set_cc_for_build - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit 0 ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit 0 ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 - echo unknown-hitachi-hiuxwe2 - exit 0 ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit 0 ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit 0 ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit 0 ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit 0 ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit 0 ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit 0 ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit 0 ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit 0 ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit 0 ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit 0 ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit 0 ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit 0 ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit 0 ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit 0 ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit 0 ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit 0 ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit 0 ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit 0 ;; - x86:Interix*:[34]*) - echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' - exit 0 ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit 0 ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit 0 ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit 0 ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit 0 ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit 0 ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit 0 ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit 0 ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit 0 ;; - crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu - exit 0 ;; - frv:Linux:*:*) - echo frv-unknown-linux-gnu - exit 0 ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 - ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit 0 ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit 0 ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit 0 ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit 0 ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit 0 ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit 0 ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit 0 ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit 0 ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit 0 ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit 0 ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #ifdef __INTEL_COMPILER - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 - test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit 0 ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit 0 ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit 0 ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit 0 ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit 0 ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit 0 ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit 0 ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit 0 ;; - i*86:*:5:[78]*) - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit 0 ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit 0 ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit 0 ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit 0 ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit 0 ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit 0 ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit 0 ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit 0 ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit 0 ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4.3${OS_REL} && exit 0 - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4 && exit 0 ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit 0 ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit 0 ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit 0 ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit 0 ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit 0 ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit 0 ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit 0 ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit 0 ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit 0 ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit 0 ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit 0 ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit 0 ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit 0 ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit 0 ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit 0 ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit 0 ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - *86) UNAME_PROCESSOR=i686 ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit 0 ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit 0 ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit 0 ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit 0 ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit 0 ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit 0 ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit 0 ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit 0 ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit 0 ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit 0 ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit 0 ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit 0 ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit 0 ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit 0 ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit 0 ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit 0 ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms && exit 0 ;; - I*) echo ia64-dec-vms && exit 0 ;; - V*) echo vax-dec-vms && exit 0 ;; - esac -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit 0 ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - c34*) - echo c34-convex-bsd - exit 0 ;; - c38*) - echo c38-convex-bsd - exit 0 ;; - c4*) - echo c4-convex-bsd - exit 0 ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/contrib/bind9/config.sub b/contrib/bind9/config.sub deleted file mode 100644 index edb6b66..0000000 --- a/contrib/bind9/config.sub +++ /dev/null @@ -1,1555 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - -timestamp='2004-08-29' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; - --version | -v ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit 0;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ - kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray) - os= - basic_machine=$1 - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | m32r | m32rle | m68000 | m68k | m88k | mcore \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64vr | mips64vrel \ - | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | msp430 \ - | ns16k | ns32k \ - | openrisc | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \ - | strongarm \ - | tahoe | thumb | tic4x | tic80 | tron \ - | v850 | v850e \ - | we32k \ - | x86 | xscale | xstormy16 | xtensa \ - | z8k) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* \ - | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | mcore-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | msp430-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tron-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ - | xtensa-* \ - | ymp-* \ - | z8k-*) - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16c) - basic_machine=cr16c-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - or32 | or32-*) - basic_machine=or32-unknown - os=-coff - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tic55x | c55x*) - basic_machine=tic55x-unknown - os=-coff - ;; - tic6x | c6x*) - basic_machine=tic6x-unknown - os=-coff - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -kaos*) - os=-kaos - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit 0 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/contrib/bind9/config.threads.in b/contrib/bind9/config.threads.in deleted file mode 100644 index c1c113b..0000000 --- a/contrib/bind9/config.threads.in +++ /dev/null @@ -1,177 +0,0 @@ -# -# Begin pthreads checking. -# -# First, decide whether to use multithreading or not. -# -# Enable multithreading by default on systems where it is known -# to work well, and where debugging of multithreaded programs -# is supported. -# - -AC_MSG_CHECKING(whether to build with thread support) - -case $host in -*-dec-osf*) - use_threads=true ;; -[*-solaris2.[0-6]]) - # Thread signals are broken on Solaris 2.6; they are sometimes - # delivered to the wrong thread. - use_threads=false ;; -*-solaris*) - use_threads=true ;; -*-ibm-aix*) - use_threads=true ;; -*-hp-hpux10*) - use_threads=false ;; -*-hp-hpux11*) - use_threads=true ;; -*-sgi-irix*) - use_threads=true ;; -*-sco-sysv*uw*|*-*-sysv*UnixWare*) - # UnixWare - use_threads=false ;; -*-*-sysv*OpenUNIX*) - # UnixWare - use_threads=true ;; -*-netbsd*) - if test -r /usr/lib/libpthread.so ; then - use_threads=true - else - # Socket I/O optimizations introduced in 9.2 expose a - # bug in unproven-pthreads; see PR #12650 - use_threads=false - fi - ;; -*-openbsd*) - # OpenBSD users have reported that named dumps core on - # startup when built with threads. - use_threads=false ;; -*-freebsd*) - use_threads=false ;; -*-bsdi[234]*) - # Thread signals do not work reliably on some versions of BSD/OS. - use_threads=false ;; -*-bsdi5*) - use_threads=true ;; -*-linux*) - # Threads are disabled on Linux by default because most - # Linux kernels produce unusable core dumps from multithreaded - # programs, and because of limitations in setuid(). - use_threads=false ;; -*) - use_threads=false ;; -esac - -AC_ARG_ENABLE(threads, - [ --enable-threads enable multithreading]) -case "$enable_threads" in - yes) - use_threads=true - ;; - no) - use_threads=false - ;; - '') - # Use system-dependent default - ;; - *) - AC_MSG_ERROR([--enable-threads takes yes or no]) - ;; -esac - -if $use_threads -then - AC_MSG_RESULT(yes) -else - AC_MSG_RESULT(no) -fi - -if $use_threads -then - # - # Search for / configure pthreads in a system-dependent fashion. - # - case "$host" in - *-netbsd*) - # NetBSD has multiple pthreads implementations. The - # recommended one to use is "unproven-pthreads". The - # older "mit-pthreads" may also work on some NetBSD - # versions. The PTL2 thread library does not - # currently work with bind9, but can be chosen with - # the --with-ptl2 option for those who wish to - # experiment with it. - CC="gcc" - AC_MSG_CHECKING(which NetBSD thread library to use) - - AC_ARG_WITH(ptl2, -[ --with-ptl2 on NetBSD, use the ptl2 thread library (experimental)], - use_ptl2="$withval", use_ptl2="no") - - : ${LOCALBASE:=/usr/pkg} - - if test "X$use_ptl2" = "Xyes" - then - AC_MSG_RESULT(PTL2) - AC_MSG_WARN( -[linking with PTL2 is highly experimental and not expected to work]) - CC=ptlgcc - else - if test -r /usr/lib/libpthread.so - then - AC_MSG_RESULT(native) - LIBS="-lpthread $LIBS" - else - if test ! -d $LOCALBASE/pthreads - then - AC_MSG_RESULT(none) - AC_MSG_ERROR("could not find thread libraries") - fi - - if $use_threads - then - AC_MSG_RESULT(mit-pthreads/unproven-pthreads) - pkg="$LOCALBASE/pthreads" - lib1="-L$pkg/lib -Wl,-R$pkg/lib" - lib2="-lpthread -lm -lgcc -lpthread" - LIBS="$lib1 $lib2 $LIBS" - CPPFLAGS="$CPPFLAGS -I$pkg/include" - STD_CINCLUDES="$STD_CINCLUDES -I$pkg/include" - fi - fi - fi - ;; - *-freebsd*) - # We don't want to set -lpthread as that break - # the ability to choose threads library at final - # link time and is not valid for all architectures. - - PTHREAD= - if test "X$GCC" = "Xyes"; then - saved_cc="$CC" - CC="$CC -pthread" - AC_MSG_CHECKING(for gcc -pthread support); - AC_TRY_LINK([#include ], - [printf("%x\n", pthread_create);], - PTHREAD="yes" - AC_MSG_RESULT(yes), - AC_MSG_RESULT(no)) - CC="$saved_cc" - fi - if test "X$PTHREAD" != "Xyes"; then - AC_CHECK_LIB(pthread, pthread_create,, - AC_CHECK_LIB(thr, thread_create,, - AC_CHECK_LIB(c_r, pthread_create,, - AC_CHECK_LIB(c, pthread_create,, - AC_MSG_ERROR("could not find thread libraries"))))) - fi - ;; - *) - AC_CHECK_LIB(pthread, pthread_create,, - AC_CHECK_LIB(pthread, __pthread_create,, - AC_CHECK_LIB(pthread, __pthread_create_system,, - AC_CHECK_LIB(c_r, pthread_create,, - AC_CHECK_LIB(c, pthread_create,, - AC_MSG_ERROR("could not find thread libraries")))))) - ;; - esac -fi diff --git a/contrib/bind9/configure.in b/contrib/bind9/configure.in deleted file mode 100644 index b9280a3..0000000 --- a/contrib/bind9/configure.in +++ /dev/null @@ -1,2546 +0,0 @@ -# Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 1998-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. - -dnl -AC_DIVERT_PUSH(1)dnl -esyscmd([sed "s/^/# /" COPYRIGHT])dnl -AC_DIVERT_POP()dnl - -AC_REVISION($Revision: 1.355.18.71 $) - -AC_INIT(lib/dns/name.c) -AC_PREREQ(2.59) - -AC_CONFIG_HEADER(config.h) -AC_CONFIG_SUBDIRS(lib/bind) - -AC_CANONICAL_HOST - -AC_PROG_MAKE_SET -AC_PROG_RANLIB -AC_PROG_INSTALL -AC_PROG_LN_S - -AC_SUBST(STD_CINCLUDES) -AC_SUBST(STD_CDEFINES) -AC_SUBST(STD_CWARNINGS) -AC_SUBST(CCOPT) - -# -# Make very sure that these are the first files processed by -# config.status, since we use the processed output as the input for -# AC_SUBST_FILE() subsitutions in other files. -# -AC_CONFIG_FILES([make/rules make/includes]) - -AC_PATH_PROG(AR, ar) -ARFLAGS="cruv" -AC_SUBST(AR) -AC_SUBST(ARFLAGS) - -# The POSIX ln(1) program. Non-POSIX systems may substitute -# "copy" or something. -LN=ln -AC_SUBST(LN) - -case "$AR" in - "") - AC_MSG_ERROR([ -ar program not found. Please fix your PATH to include the directory in -which ar resides, or set AR in the environment with the full path to ar. -]) - - ;; -esac - -# -# Etags. -# -AC_PATH_PROGS(ETAGS, etags emacs-etags) - -# -# Some systems, e.g. RH7, have the Exuberant Ctags etags instead of -# GNU emacs etags, and it requires the -L flag. -# -if test "X$ETAGS" != "X"; then - AC_MSG_CHECKING(for Exuberant Ctags etags) - if $ETAGS --version 2>&1 | grep 'Exuberant Ctags' >/dev/null 2>&1; then - AC_MSG_RESULT(yes) - ETAGS="$ETAGS -L" - else - AC_MSG_RESULT(no) - fi -fi -AC_SUBST(ETAGS) - -# -# Perl is optional; it is used only by some of the system test scripts. -# -AC_PATH_PROGS(PERL, perl5 perl) -AC_SUBST(PERL) - -# -# Special processing of paths depending on whether --prefix, -# --sysconfdir or --localstatedir arguments were given. What's -# desired is some compatibility with the way previous versions -# of BIND built; they defaulted to /usr/local for most parts of -# the installation, but named.boot/named.conf was in /etc -# and named.pid was in /var/run. -# -# So ... if none of --prefix, --sysconfdir or --localstatedir are -# specified, set things up that way. If --prefix is given, use -# it for sysconfdir and localstatedir the way configure normally -# would. To change the prefix for everything but leave named.conf -# in /etc or named.pid in /var/run, then do this the usual configure way: -# ./configure --prefix=/somewhere --sysconfdir=/etc -# ./configure --prefix=/somewhere --localstatedir=/var -# -# To put named.conf and named.pid in /usr/local with everything else, -# set the prefix explicitly to /usr/local even though that's the default: -# ./configure --prefix=/usr/local -# -case "$prefix" in - NONE) - case "$sysconfdir" in - '${prefix}/etc') - sysconfdir=/etc - ;; - esac - case "$localstatedir" in - '${prefix}/var') - localstatedir=/var - ;; - esac - ;; -esac - -# -# Make sure INSTALL uses an absolute path, else it will be wrong in all -# Makefiles, since they use make/rules.in and INSTALL will be adjusted by -# configure based on the location of the file where it is substituted. -# Since in BIND9 INSTALL is only substituted into make/rules.in, an immediate -# subdirectory of install-sh, This relative path will be wrong for all -# directories more than one level down from install-sh. -# -case "$INSTALL" in - /*) - ;; - *) - # - # Not all systems have dirname. - # - changequote({, }) - ac_dir="`echo $INSTALL | sed 's%/[^/]*$%%'`" - changequote([, ]) - - ac_prog="`echo $INSTALL | sed 's%.*/%%'`" - test "$ac_dir" = "$ac_prog" && ac_dir=. - test -d "$ac_dir" && ac_dir="`(cd \"$ac_dir\" && pwd)`" - INSTALL="$ac_dir/$ac_prog" - ;; -esac - -# -# On these hosts, we really want to use cc, not gcc, even if it is -# found. The gcc that these systems have will not correctly handle -# pthreads. -# -# However, if the user sets $CC to be something, let that override -# our change. -# -if test "X$CC" = "X" ; then - case "$host" in - *-dec-osf*) - CC="cc" - ;; - *-solaris*) - # Use Sun's cc if it is available, but watch - # out for /usr/ucb/cc; it will never be the right - # compiler to use. - # - # If setting CC here fails, the AC_PROG_CC done - # below might still find gcc. - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - case "$ac_dir" in - /usr/ucb) - # exclude - ;; - *) - if test -f "$ac_dir/cc"; then - CC="$ac_dir/cc" - break - fi - ;; - esac - done - IFS="$ac_save_ifs" - ;; - *-hp-hpux*) - CC="cc" - ;; - mips-sgi-irix*) - CC="cc" - ;; - esac -fi - -AC_PROG_CC - -# -# gcc's optimiser is broken at -02 for ultrasparc -# -if test "$ac_env_CFLAGS_set" != set -a "X$GCC" = "Xyes"; then - case "$host" in - sparc-*) - CCFLAGS="-g -O1" - ;; - esac -fi - -# -# OS dependent CC flags -# -case "$host" in - # OSF 5.0: recv/send are only avaliable with -D_POSIX_PII_SOCKET or - # -D_XOPEN_SOURCE_EXTENDED. - *-dec-osf*) - STD_CDEFINES="$STD_CDEFINES -D_POSIX_PII_SOCKET" - CPPFLAGS="$CPPFLAGS -D_POSIX_PII_SOCKET" - ;; - #HP-UX: need -D_XOPEN_SOURCE_EXTENDED and -lxnet for CMSG macros - *-hp-hpux*) - STD_CDEFINES="$STD_CDEFINES -D_XOPEN_SOURCE_EXTENDED" - CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE_EXTENDED" - LIBS="-lxnet $LIBS" - ;; - # Solaris: need -D_XPG4_2 and -D__EXTENSIONS__ for CMSG macros - *-solaris*) - STD_CDEFINES="$STD_CDEFINES -D_XPG4_2 -D__EXTENSIONS__" - CPPFLAGS="$CPPFLAGS -D_XPG4_2 -D__EXTENSIONS__" - ;; -esac - -AC_HEADER_STDC - -AC_CHECK_HEADERS(fcntl.h sys/time.h unistd.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h,,, -[$ac_includes_default -#ifdef HAVE_SYS_PARAM_H -# include -#endif -]) - -AC_C_CONST -AC_C_INLINE -AC_CHECK_FUNC(sysctlbyname, AC_DEFINE(HAVE_SYSCTLBYNAME)) - -# -# UnixWare 7.1.1 with the feature supplement to the UDK compiler -# is reported to not support "static inline" (RT #1212). -# -AC_MSG_CHECKING(for static inline breakage) -AC_TRY_COMPILE(, [ - foo1(); - } - - static inline int foo1() { - return 0; - } - - static inline int foo2() { - return foo1(); - ], - [AC_MSG_RESULT(no)], - [AC_MSG_RESULT(yes) - AC_DEFINE(inline, )]) - -AC_TYPE_SIZE_T -AC_CHECK_TYPE(ssize_t, int) -AC_CHECK_TYPE(uintptr_t,unsigned long) -AC_CHECK_TYPE(socklen_t, -[AC_DEFINE(ISC_SOCKADDR_LEN_T, socklen_t)], -[ -AC_TRY_COMPILE( -[ -#include -#include -int getsockname(int, struct sockaddr *, size_t *); -],[], -[AC_DEFINE(ISC_SOCKADDR_LEN_T, size_t)], -[AC_DEFINE(ISC_SOCKADDR_LEN_T, int)]) -], -[ -#include -#include -]) -AC_SUBST(ISC_SOCKADDR_LEN_T) -AC_HEADER_TIME -AC_MSG_CHECKING(for long long) -AC_TRY_COMPILE([],[long long i = 0; return (0);], - [AC_MSG_RESULT(yes) - ISC_PLATFORM_HAVELONGLONG="#define ISC_PLATFORM_HAVELONGLONG 1"], - [AC_MSG_RESULT(no) - ISC_PLATFORM_HAVELONGLONG="#undef ISC_PLATFORM_HAVELONGLONG"]) -AC_SUBST(ISC_PLATFORM_HAVELONGLONG) - -# -# check if we have lifconf -# -AC_MSG_CHECKING(for struct lifconf) -AC_TRY_COMPILE([ -#include -#include -#include -], -[ -struct lifconf lifconf; -lifconf.lifc_len = 0; -] -, - [AC_MSG_RESULT(yes) - ISC_PLATFORM_HAVELIFCONF="#define ISC_PLATFORM_HAVELIFCONF 1"], - [AC_MSG_RESULT(no) - ISC_PLATFORM_HAVELIFCONF="#undef ISC_PLATFORM_HAVELIFCONF"]) -AC_SUBST(ISC_PLATFORM_HAVELIFCONF) - - -# -# check if we need to #include sys/select.h explicitly -# -case $ac_cv_header_unistd_h in -yes) -AC_MSG_CHECKING(if unistd.h or sys/types.h defines fd_set) -AC_TRY_COMPILE([ -#include /* Ultrix */ -#include ], -[fd_set read_set; return (0);], - [AC_MSG_RESULT(yes) - ISC_PLATFORM_NEEDSYSSELECTH="#undef ISC_PLATFORM_NEEDSYSSELECTH" - LWRES_PLATFORM_NEEDSYSSELECTH="#undef LWRES_PLATFORM_NEEDSYSSELECTH"], - [AC_MSG_RESULT(no) - case $ac_cv_header_sys_select_h in - yes) - ISC_PLATFORM_NEEDSYSSELECTH="#define ISC_PLATFORM_NEEDSYSSELECTH 1" - LWRES_PLATFORM_NEEDSYSSELECTH="#define LWRES_PLATFORM_NEEDSYSSELECTH 1" - ;; - no) - AC_MSG_ERROR([need either working unistd.h or sys/select.h]) - ;; - esac - ]) - ;; -no) - case $ac_cv_header_sys_select_h in - yes) - ISC_PLATFORM_NEEDSYSSELECTH="#define ISC_PLATFORM_NEEDSYSSELECTH 1" - LWRES_PLATFORM_NEEDSYSSELECTH="#define LWRES_PLATFORM_NEEDSYSSELECTH 1" - ;; - no) - AC_MSG_ERROR([need either unistd.h or sys/select.h]) - ;; - esac - ;; -esac -AC_SUBST(ISC_PLATFORM_NEEDSYSSELECTH) -AC_SUBST(LWRES_PLATFORM_NEEDSYSSELECTH) - -# -# Find the machine's endian flavor. -# -AC_C_BIGENDIAN - - -# -# was --with-openssl specified? -# -OPENSSL_WARNING= -AC_MSG_CHECKING(for OpenSSL library) -AC_ARG_WITH(openssl, -[ --with-openssl[=PATH] Build with OpenSSL [yes|no|path]. - (Required for DNSSEC)], - use_openssl="$withval", use_openssl="auto") - -openssldirs="/usr /usr/local /usr/local/ssl /usr/pkg /usr/sfw" -if test "$use_openssl" = "auto" -then - for d in $openssldirs - do - if test -f $d/include/openssl/opensslv.h - then - use_openssl=$d - break - fi - done -fi -case "$use_openssl" in - no) - AC_MSG_RESULT(no) - DST_OPENSSL_INC="" - USE_OPENSSL="" - ;; - auto) - DST_OPENSSL_INC="" - USE_OPENSSL="" - AC_MSG_RESULT(not found) - ;; - *) - if test "$use_openssl" = "yes" - then - # User did not specify a path - guess it - for d in $openssldirs - do - if test -f $d/include/openssl/opensslv.h - then - use_openssl=$d - break - fi - done - if test "$use_openssl" = "yes" - then - AC_MSG_RESULT(not found) - AC_MSG_ERROR( -[OpenSSL was not found in any of $openssldirs; use --with-openssl=/path]) - fi - fi - USE_OPENSSL='-DOPENSSL' - if test "$use_openssl" = "/usr" - then - DST_OPENSSL_INC="" - DNS_OPENSSL_LIBS="-lcrypto" - else - DST_OPENSSL_INC="-I$use_openssl/include" - case $host in - *-solaris*) - DNS_OPENSSL_LIBS="-L$use_openssl/lib -R$use_openssl/lib -lcrypto" - ;; - *-hp-hpux*) - DNS_OPENSSL_LIBS="-L$use_openssl/lib -Wl,+b: -lcrypto" - ;; - *-apple-darwin*) - # - # Apple's ld seaches for serially for dynamic - # then static libraries. This means you can't - # use -L to override dynamic system libraries - # with static ones when linking. Instead - # we specify a absolute path. - # - if test -f "$use_openssl/lib/libcrypto.dylib" - then - DNS_OPENSSL_LIBS="-L$use_openssl/lib -lcrypto" - else - DNS_OPENSSL_LIBS="$use_openssl/lib/libcrypto.a" - fi - ;; - *) - DNS_OPENSSL_LIBS="-L$use_openssl/lib -lcrypto" - ;; - esac - fi - AC_MSG_RESULT(using openssl from $use_openssl/lib and $use_openssl/include) - - saved_cflags="$CFLAGS" - saved_libs="$LIBS" - CFLAGS="$CFLAGS $DST_OPENSSL_INC" - LIBS="$LIBS $DNS_OPENSSL_LIBS" - AC_MSG_CHECKING(whether linking with OpenSSL works) - AC_TRY_RUN([ -#include -int main() { - ERR_clear_error(); - return (0); -} -], - [AC_MSG_RESULT(yes)], - [AC_MSG_RESULT(no) - AC_MSG_ERROR(Could not run test program using OpenSSL from -$use_openssl/lib and $use_openssl/include. -Please check the argument to --with-openssl and your -shared library configuration (e.g., LD_LIBRARY_PATH).)], - [AC_MSG_RESULT(assuming it does work on target platform)]) - - AC_MSG_CHECKING(whether linking with OpenSSL requires -ldl) - AC_TRY_LINK([ -#include ], -[ DSO_METHOD_dlfcn(); ], - [AC_MSG_RESULT(no)], - [LIBS="$LIBS -ldl" - AC_TRY_LINK([ -#include -],[ DSO_METHOD_dlfcn(); ], - [AC_MSG_RESULT(yes) - DNS_OPENSSL_LIBS="$DNS_OPENSSL_LIBS -ldl" - ], - [AC_MSG_RESULT(unknown) - AC_MSG_ERROR(OpenSSL has unsupported dynamic loading)], - [AC_MSG_RESULT(assuming it does work on target platform)]) - ], - [AC_MSG_RESULT(assuming it does work on target platform)] - ) - -AC_ARG_ENABLE(openssl-version-check, -[AC_HELP_STRING([--enable-openssl-version-check], - [Check OpenSSL Version @<:@default=yes@:>@])]) -case "$enable_openssl_version_check" in -yes|'') - AC_MSG_CHECKING(OpenSSL library version) - AC_TRY_RUN([ -#include -#include -int main() { - if ((OPENSSL_VERSION_NUMBER >= 0x009070cfL && - OPENSSL_VERSION_NUMBER < 0x00908000L) || - OPENSSL_VERSION_NUMBER >= 0x0090804fL) - return (0); - printf("\n\nFound OPENSSL_VERSION_NUMBER %#010x\n", - OPENSSL_VERSION_NUMBER); - printf("Require OPENSSL_VERSION_NUMBER 0x009070cf or greater (0.9.7l)\n" - "Require OPENSSL_VERSION_NUMBER 0x0090804f or greater (0.9.8d)\n\n"); - return (1); -} - ], - [AC_MSG_RESULT(ok)], - [AC_MSG_RESULT(not compatible) - OPENSSL_WARNING=yes - ], - [AC_MSG_RESULT(assuming target platform has compatible version)]) -;; -no) - AC_MSG_RESULT(Skipped OpenSSL version check) -;; -esac - - AC_MSG_CHECKING(for OpenSSL DSA support) - if test -f $use_openssl/include/openssl/dsa.h - then - AC_DEFINE(HAVE_OPENSSL_DSA) - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi - CFLAGS="$saved_cflags" - LIBS="$saved_libs" - ;; -esac - -# -# This would include the system openssl path (and linker options to use -# it as needed) if it is found. -# - -AC_SUBST(USE_OPENSSL) -AC_SUBST(DST_OPENSSL_INC) -DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DNS_OPENSSL_LIBS" - -# -# was --with-gssapi specified? -# -#AC_MSG_CHECKING(for GSSAPI library) -#AC_ARG_WITH(gssapi, -#[ --with-gssapi=PATH Specify path for system-supplied GSSAPI], -# use_gssapi="$withval", use_gssapi="no") -# -#case "$use_gssapi" in -# no) -# USE_GSSAPI='' -# DST_GSSAPI_INC='' -# DNS_GSSAPI_LIBS='' -# AC_MSG_RESULT(not specified) -# ;; -# yes) -# AC_MSG_ERROR([--with-gssapi must specify a path]) -# ;; -# *) -# USE_GSSAPI='-DGSSAPI' -# DST_GSSAPI_INC="-I$use_gssapi/include" -# DNS_GSSAPI_LIBS="-L$use_gssapi/lib -lgssapi_krb5" -# AC_MSG_RESULT(using gssapi from $use_gssapi/lib and $use_gssapi/include) -# ;; -#esac - -USE_GSSAPI='' -DST_GSSAPI_INC='' -DNS_GSSAPI_LIBS='' - -AC_SUBST(USE_GSSAPI) -AC_SUBST(DST_GSSAPI_INC) -DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DNS_GSSAPI_LIBS" - -# -# Applications linking with libdns also need to link with these libraries. -# - -AC_SUBST(DNS_CRYPTO_LIBS) - -# -# was --with-randomdev specified? -# -AC_MSG_CHECKING(for random device) -AC_ARG_WITH(randomdev, -[ --with-randomdev=PATH Specify path for random device], - use_randomdev="$withval", use_randomdev="unspec") - -case "$use_randomdev" in - unspec) - case "$host" in - *-openbsd*) - devrandom=/dev/arandom - ;; - *) - devrandom=/dev/random - ;; - esac - AC_MSG_RESULT($devrandom) - AC_CHECK_FILE($devrandom, - AC_DEFINE_UNQUOTED(PATH_RANDOMDEV, - "$devrandom"),) - ;; - yes) - AC_MSG_ERROR([--with-randomdev must specify a path]) - ;; - no) - AC_MSG_RESULT(disabled) - ;; - *) - AC_DEFINE_UNQUOTED(PATH_RANDOMDEV, "$use_randomdev") - AC_MSG_RESULT(using "$use_randomdev") - ;; -esac - -# -# Do we have arc4random() ? -# -AC_CHECK_FUNC(arc4random, AC_DEFINE(HAVE_ARC4RANDOM)) - -sinclude(config.threads.in)dnl - -if $use_threads -then - if test "X$GCC" = "Xyes"; then - case "$host" in - *-freebsd*) - CC="$CC -pthread" - CCOPT="$CCOPT -pthread" - STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE" - ;; - *-openbsd*) - CC="$CC -pthread" - CCOPT="$CCOPT -pthread" - ;; - *-solaris*) - LIBS="$LIBS -lthread" - ;; - *-ibm-aix*) - STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE" - ;; - esac - else - case $host in - *-dec-osf*) - CC="$CC -pthread" - CCOPT="$CCOPT -pthread" - ;; - *-solaris*) - CC="$CC -mt" - CCOPT="$CCOPT -mt" - ;; - *-ibm-aix*) - STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE" - ;; - *-sco-sysv*uw*|*-*-sysv*UnixWare*) - CC="$CC -Kthread" - CCOPT="$CCOPT -Kthread" - ;; - *-*-sysv*OpenUNIX*) - CC="$CC -Kpthread" - CCOPT="$CCOPT -Kpthread" - ;; - esac - fi - ALWAYS_DEFINES="-D_REENTRANT" - ISC_PLATFORM_USETHREADS="#define ISC_PLATFORM_USETHREADS 1" - thread_dir=pthreads - # - # We'd like to use sigwait() too - # - AC_CHECK_FUNC(sigwait, - AC_DEFINE(HAVE_SIGWAIT), - AC_CHECK_LIB(c, sigwait, - AC_DEFINE(HAVE_SIGWAIT), - AC_CHECK_LIB(pthread, sigwait, - AC_DEFINE(HAVE_SIGWAIT), - AC_CHECK_LIB(pthread, _Psigwait, - AC_DEFINE(HAVE_SIGWAIT),)))) - - AC_CHECK_FUNC(pthread_attr_getstacksize, - AC_DEFINE(HAVE_PTHREAD_ATTR_GETSTACKSIZE),) - - AC_CHECK_FUNC(pthread_attr_setstacksize, - AC_DEFINE(HAVE_PTHREAD_ATTR_SETSTACKSIZE),) - - # - # Additional OS-specific issues related to pthreads and sigwait. - # - case "$host" in - # - # One more place to look for sigwait. - # - *-freebsd*) - AC_CHECK_LIB(c_r, sigwait, AC_DEFINE(HAVE_SIGWAIT),) - case $host in - *-freebsd5.[[012]]|*-freebsd5.[[012]].*);; - *-freebsd5.[[3456789]]|*-freebsd5.[[3456789]].*) - AC_DEFINE(NEED_PTHREAD_SCOPE_SYSTEM) - ;; - *-freebsd6.*) - AC_DEFINE(NEED_PTHREAD_SCOPE_SYSTEM) - ;; - esac - ;; - # - # BSDI 3.0 through 4.0.1 needs pthread_init() to be - # called before certain pthreads calls. This is deprecated - # in BSD/OS 4.1. - # - *-bsdi3.*|*-bsdi4.0*) - AC_DEFINE(NEED_PTHREAD_INIT) - ;; - # - # LinuxThreads requires some changes to the way we - # deal with signals. - # - *-linux*) - AC_DEFINE(HAVE_LINUXTHREADS) - ;; - # - # Ensure the right sigwait() semantics on Solaris and make - # sure we call pthread_setconcurrency. - # - *-solaris*) - AC_DEFINE(_POSIX_PTHREAD_SEMANTICS) - AC_CHECK_FUNC(pthread_setconcurrency, - AC_DEFINE(CALL_PTHREAD_SETCONCURRENCY)) - ;; - # - # UnixWare does things its own way. - # - *-sco-sysv*uw*|*-*-sysv*UnixWare*|*-*-sysv*OpenUNIX*) - AC_DEFINE(HAVE_UNIXWARE_SIGWAIT) - ;; - esac - - # - # Look for sysconf to allow detection of the number of processors. - # - AC_CHECK_FUNC(sysconf, AC_DEFINE(HAVE_SYSCONF),) - -else - ISC_PLATFORM_USETHREADS="#undef ISC_PLATFORM_USETHREADS" - thread_dir=nothreads - ALWAYS_DEFINES="" -fi - -AC_SUBST(ALWAYS_DEFINES) -AC_SUBST(ISC_PLATFORM_USETHREADS) -ISC_THREAD_DIR=$thread_dir -AC_SUBST(ISC_THREAD_DIR) - -# -# In solaris 10, SMF can manage named service -# -AC_CHECK_LIB(scf, smf_enable_instance) - -# -# flockfile is usually provided by pthreads, but we may want to use it -# even if compiled with --disable-threads. getc_unlocked might also not -# be defined. -# -AC_CHECK_FUNC(flockfile, AC_DEFINE(HAVE_FLOCKFILE),) -AC_CHECK_FUNC(getc_unlocked, AC_DEFINE(HAVE_GETCUNLOCKED),) - -# -# Indicate what the final decision was regarding threads. -# -AC_MSG_CHECKING(whether to build with threads) -if $use_threads; then - AC_MSG_RESULT(yes) -else - AC_MSG_RESULT(no) -fi - -# -# End of pthreads stuff. -# - -# -# Large File -# -AC_ARG_ENABLE(largefile, [ --enable-largefile 64-bit file support], - want_largefile="yes", want_largefile="no") -case $want_largefile in - yes) - ALWAYS_DEFINES="$ALWAYS_DEFINES -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" - ;; - *) - ;; -esac - -# -# Additional compiler settings. -# -MKDEPCC="$CC" -MKDEPCFLAGS="-M" -IRIX_DNSSEC_WARNINGS_HACK="" - -if test "X$GCC" = "Xyes"; then - AC_MSG_CHECKING(if "$CC" supports -fno-strict-aliasing) - SAVE_CFLAGS=$CFLAGS - CFLAGS=-fno-strict-aliasing - AC_TRY_COMPILE(,, [FNOSTRICTALIASING=yes],[FNOSTRICTALIASING=no]) - CFLAGS=$SAVE_CFLAGS - if test "$FNOSTRICTALIASING" = "yes"; then - AC_MSG_RESULT(yes) - STD_CWARNINGS="$STD_CWARNINGS -W -Wall -Wmissing-prototypes -Wcast-qual -Wwrite-strings -Wformat -Wpointer-arith -fno-strict-aliasing" - else - AC_MSG_RESULT(no) - STD_CWARNINGS="$STD_CWARNINGS -W -Wall -Wmissing-prototypes -Wcast-qual -Wwrite-strings -Wformat -Wpointer-arith" - fi - case "$host" in - *-hp-hpux*) - LDFLAGS="-Wl,+vnocompatwarnings $LDFLAGS" - ;; - esac -else - case $host in - *-dec-osf*) - CC="$CC -std" - CCOPT="$CCOPT -std" - MKDEPCC="$CC" - ;; - *-hp-hpux*) - CC="$CC -Ae -z" - # The version of the C compiler that constantly warns about - # 'const' as well as alignment issues is unfortunately not - # able to be discerned via the version of the operating - # system, nor does cc have a version flag. - case "`$CC +W 123 2>&1`" in - *Unknown?option*) - STD_CWARNINGS="+w1" - ;; - *) - # Turn off the pointlessly noisy warnings. - STD_CWARNINGS="+w1 +W 474,530,2193,2236" - ;; - esac - CCOPT="$CCOPT -Ae -z" - LDFLAGS="-Wl,+vnocompatwarnings $LDFLAGS" - MKDEPPROG='cc -Ae -E -Wp,-M >/dev/null 2>>$TMP' - ;; - *-sgi-irix*) - STD_CWARNINGS="-fullwarn -woff 1209" - # - # Silence more than 250 instances of - # "prototyped function redeclared without prototype" - # and 11 instances of - # "variable ... was set but never used" - # from lib/dns/sec/openssl. - # - IRIX_DNSSEC_WARNINGS_HACK="-woff 1692,1552" - ;; - *-solaris*) - MKDEPCFLAGS="-xM" - ;; - *-sco-sysv*uw*|*-*-sysv*UnixWare*|*-*-sysv*OpenUNIX*) - # UnixWare - CC="$CC -w" - ;; - esac -fi - -AC_SUBST(MKDEPCC) -AC_SUBST(MKDEPCFLAGS) -AC_SUBST(MKDEPPROG) -AC_SUBST(IRIX_DNSSEC_WARNINGS_HACK) - -# -# NLS -# -AC_CHECK_FUNC(catgets, AC_DEFINE(HAVE_CATGETS),) - -# -# -lxnet buys us one big porting headache... standards, gotta love 'em. -# -# AC_CHECK_LIB(xnet, socket, , -# AC_CHECK_LIB(socket, socket) -# AC_CHECK_LIB(nsl, inet_ntoa) -# ) -# -# Use this for now, instead: -# -case "$host" in - mips-sgi-irix*) - ;; - *) - AC_CHECK_LIB(socket, socket) - AC_CHECK_LIB(nsl, inet_ntoa) - ;; -esac - -# -# Purify support -# -AC_MSG_CHECKING(whether to use purify) -AC_ARG_WITH(purify, - [ --with-purify[=PATH] use Rational purify], - use_purify="$withval", use_purify="no") - -case "$use_purify" in - no) - ;; - yes) - AC_PATH_PROG(purify_path, purify, purify) - ;; - *) - purify_path="$use_purify" - ;; -esac - -case "$use_purify" in - no) - AC_MSG_RESULT(no) - PURIFY="" - ;; - *) - if test -f $purify_path || test $purify_path = purify; then - AC_MSG_RESULT($purify_path) - PURIFYFLAGS="`echo $PURIFYOPTIONS`" - PURIFY="$purify_path $PURIFYFLAGS" - else - AC_MSG_ERROR([$purify_path not found. - -Please choose the proper path with the following command: - - configure --with-purify=PATH -]) - fi - ;; -esac - -AC_SUBST(PURIFY) - -# -# GNU libtool support -# -AC_ARG_WITH(libtool, - [ --with-libtool use GNU libtool (following indented options supported)], - use_libtool="$withval", use_libtool="no") - -case $use_libtool in - yes) - AM_PROG_LIBTOOL - O=lo - A=la - LIBTOOL_MKDEP_SED='s;\.o;\.lo;' - LIBTOOL_MODE_COMPILE='--mode=compile' - LIBTOOL_MODE_INSTALL='--mode=install' - LIBTOOL_MODE_LINK='--mode=link' - case "$host" in - *) LIBTOOL_ALLOW_UNDEFINED= ;; - esac - case "$host" in - *-ibm-aix*) LIBTOOL_IN_MAIN="-Wl,-bI:T_testlist.imp" ;; - *) LIBTOOL_IN_MAIN= ;; - esac; - ;; - *) - O=o - A=a - LIBTOOL= - AC_SUBST(LIBTOOL) - LIBTOOL_MKDEP_SED= - LIBTOOL_MODE_COMPILE= - LIBTOOL_MODE_INSTALL= - LIBTOOL_MODE_LINK= - LIBTOOL_ALLOW_UNDEFINED= - LIBTOOL_IN_MAIN= - ;; -esac - -# -# File name extension for static archive files, for those few places -# where they are treated differently from dynamic ones. -# -SA=a - -AC_SUBST(O) -AC_SUBST(A) -AC_SUBST(SA) -AC_SUBST(LIBTOOL_MKDEP_SED) -AC_SUBST(LIBTOOL_MODE_COMPILE) -AC_SUBST(LIBTOOL_MODE_INSTALL) -AC_SUBST(LIBTOOL_MODE_LINK) -AC_SUBST(LIBTOOL_ALLOW_UNDEFINED) -AC_SUBST(LIBTOOL_IN_MAIN) - -# -# build libbind? -# -AC_ARG_ENABLE(libbind, - [ --enable-libbind build libbind [default=no]]) - -case "$enable_libbind" in - yes) - LIBBIND=lib/bind - AC_SUBST(LIBBIND) - ;; - no|'') - ;; -esac - - -# -# Here begins a very long section to determine the system's networking -# capabilities. The order of the tests is signficant. -# - -# -# IPv6 -# -AC_ARG_ENABLE(ipv6, - [ --enable-ipv6 use IPv6 [default=autodetect]]) - -case "$enable_ipv6" in - yes|''|autodetect) - AC_DEFINE(WANT_IPV6) - ;; - no) - ;; -esac - -# -# We do the IPv6 compilation checking after libtool so that we can put -# the right suffix on the files. -# -AC_MSG_CHECKING(for IPv6 structures) -AC_TRY_COMPILE([ -#include -#include -#include ], -[struct sockaddr_in6 sin6; return (0);], - [AC_MSG_RESULT(yes) - found_ipv6=yes], - [AC_MSG_RESULT(no) - found_ipv6=no]) - -# -# See whether IPv6 support is provided via a Kame add-on. -# This is done before other IPv6 linking tests to LIBS is properly set. -# -AC_MSG_CHECKING(for Kame IPv6 support) -AC_ARG_WITH(kame, - [ --with-kame[=PATH] use Kame IPv6 [default path /usr/local/v6]], - use_kame="$withval", use_kame="no") - -case "$use_kame" in - no) - ;; - yes) - kame_path=/usr/local/v6 - ;; - *) - kame_path="$use_kame" - ;; -esac - -case "$use_kame" in - no) - AC_MSG_RESULT(no) - ;; - *) - if test -f $kame_path/lib/libinet6.a; then - AC_MSG_RESULT($kame_path/lib/libinet6.a) - LIBS="-L$kame_path/lib -linet6 $LIBS" - else - AC_MSG_ERROR([$kame_path/lib/libinet6.a not found. - -Please choose the proper path with the following command: - - configure --with-kame=PATH -]) - fi - ;; -esac - -# -# Whether netinet6/in6.h is needed has to be defined in isc/platform.h. -# Including it on Kame-using platforms is very bad, though, because -# Kame uses #error against direct inclusion. So include it on only -# the platform that is otherwise broken without it -- BSD/OS 4.0 through 4.1. -# This is done before the in6_pktinfo check because that's what -# netinet6/in6.h is needed for. -# -changequote({, }) -case "$host" in -*-bsdi4.[01]*) - ISC_PLATFORM_NEEDNETINET6IN6H="#define ISC_PLATFORM_NEEDNETINET6IN6H 1" - LWRES_PLATFORM_NEEDNETINET6IN6H="#define LWRES_PLATFORM_NEEDNETINET6IN6H 1" - isc_netinet6in6_hack="#include " - ;; -*) - ISC_PLATFORM_NEEDNETINET6IN6H="#undef ISC_PLATFORM_NEEDNETINET6IN6H" - LWRES_PLATFORM_NEEDNETINET6IN6H="#undef LWRES_PLATFORM_NEEDNETINET6IN6H" - isc_netinet6in6_hack="" - ;; -esac -changequote([, ]) - -# -# This is similar to the netinet6/in6.h issue. -# -case "$host" in -*-sco-sysv*uw*|*-*-sysv*UnixWare*|*-*-sysv*OpenUNIX*) - # UnixWare - ISC_PLATFORM_NEEDNETINETIN6H="#define ISC_PLATFORM_NEEDNETINETIN6H 1" - LWRES_PLATFORM_NEEDNETINETIN6H="#define LWRES_PLATFORM_NEEDNETINETIN6H 1" - ISC_PLATFORM_FIXIN6ISADDR="#define ISC_PLATFORM_FIXIN6ISADDR 1" - isc_netinetin6_hack="#include " - ;; -*) - ISC_PLATFORM_NEEDNETINETIN6H="#undef ISC_PLATFORM_NEEDNETINETIN6H" - LWRES_PLATFORM_NEEDNETINETIN6H="#undef LWRES_PLATFORM_NEEDNETINETIN6H" - ISC_PLATFORM_FIXIN6ISADDR="#undef ISC_PLATFORM_FIXIN6ISADDR" - isc_netinetin6_hack="" - ;; -esac - -# -# Now delve deeper into the suitability of the IPv6 support. -# -case "$found_ipv6" in - yes) - ISC_PLATFORM_HAVEIPV6="#define ISC_PLATFORM_HAVEIPV6 1" - LWRES_PLATFORM_HAVEIPV6="#define LWRES_PLATFORM_HAVEIPV6 1" - - AC_MSG_CHECKING(for in6_addr) - AC_TRY_COMPILE([ -#include -#include -#include -$isc_netinetin6_hack -$isc_netinet6in6_hack -], -[struct in6_addr in6; return (0);], - [AC_MSG_RESULT(yes) - ISC_PLATFORM_HAVEINADDR6="#undef ISC_PLATFORM_HAVEINADDR6" - LWRES_PLATFORM_HAVEINADDR6="#undef LWRES_PLATFORM_HAVEINADDR6" - isc_in_addr6_hack=""], - [AC_MSG_RESULT(no) - ISC_PLATFORM_HAVEINADDR6="#define ISC_PLATFORM_HAVEINADDR6 1" - LWRES_PLATFORM_HAVEINADDR6="#define LWRES_PLATFORM_HAVEINADDR6 1" - isc_in_addr6_hack="#define in6_addr in_addr6"]) - - AC_MSG_CHECKING(for in6addr_any) - AC_TRY_LINK([ -#include -#include -#include -$isc_netinetin6_hack -$isc_netinet6in6_hack -$isc_in_addr6_hack -], - [struct in6_addr in6; in6 = in6addr_any; return (in6.s6_addr[0]);], - [AC_MSG_RESULT(yes) - ISC_PLATFORM_NEEDIN6ADDRANY="#undef ISC_PLATFORM_NEEDIN6ADDRANY" - LWRES_PLATFORM_NEEDIN6ADDRANY="#undef LWRES_PLATFORM_NEEDIN6ADDRANY"], - [AC_MSG_RESULT(no) - ISC_PLATFORM_NEEDIN6ADDRANY="#define ISC_PLATFORM_NEEDIN6ADDRANY 1" - LWRES_PLATFORM_NEEDIN6ADDRANY="#define LWRES_PLATFORM_NEEDIN6ADDRANY 1"]) - - AC_MSG_CHECKING(for in6addr_loopback) - AC_TRY_LINK([ -#include -#include -#include -$isc_netinetin6_hack -$isc_netinet6in6_hack -$isc_in_addr6_hack -], - [struct in6_addr in6; in6 = in6addr_loopback; return (in6.s6_addr[0]);], - [AC_MSG_RESULT(yes) - ISC_PLATFORM_NEEDIN6ADDRLOOPBACK="#undef ISC_PLATFORM_NEEDIN6ADDRLOOPBACK" - LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK="#undef LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK"], - [AC_MSG_RESULT(no) - ISC_PLATFORM_NEEDIN6ADDRLOOPBACK="#define ISC_PLATFORM_NEEDIN6ADDRLOOPBACK 1" - LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK="#define LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK 1"]) - - AC_MSG_CHECKING(for sin6_scope_id in struct sockaddr_in6) - AC_TRY_COMPILE([ -#include -#include -#include -$isc_netinetin6_hack -$isc_netinet6in6_hack -], - [struct sockaddr_in6 xyzzy; xyzzy.sin6_scope_id = 0; return (0);], - [AC_MSG_RESULT(yes) - ISC_PLATFORM_HAVESCOPEID="#define ISC_PLATFORM_HAVESCOPEID 1" - result="#define LWRES_HAVE_SIN6_SCOPE_ID 1"], - [AC_MSG_RESULT(no) - ISC_PLATFORM_HAVESCOPEID="#undef ISC_PLATFORM_HAVESCOPEID" - result="#undef LWRES_HAVE_SIN6_SCOPE_ID"]) - LWRES_HAVE_SIN6_SCOPE_ID="$result" - - AC_MSG_CHECKING(for in6_pktinfo) - AC_TRY_COMPILE([ -#include -#include -#include -$isc_netinetin6_hack -$isc_netinet6in6_hack -], - [struct in6_pktinfo xyzzy; return (0);], - [AC_MSG_RESULT(yes) - ISC_PLATFORM_HAVEIN6PKTINFO="#define ISC_PLATFORM_HAVEIN6PKTINFO 1"], - [AC_MSG_RESULT(no -- disabling runtime ipv6 support) - ISC_PLATFORM_HAVEIN6PKTINFO="#undef ISC_PLATFORM_HAVEIN6PKTINFO"]) - ;; - no) - ISC_PLATFORM_HAVEIPV6="#undef ISC_PLATFORM_HAVEIPV6" - LWRES_PLATFORM_HAVEIPV6="#undef LWRES_PLATFORM_HAVEIPV6" - ISC_PLATFORM_NEEDIN6ADDRANY="#undef ISC_PLATFORM_NEEDIN6ADDRANY" - LWRES_PLATFORM_NEEDIN6ADDRANY="#undef LWRES_PLATFORM_NEEDIN6ADDRANY" - ISC_PLATFORM_HAVEIN6PKTINFO="#undef ISC_PLATFORM_HAVEIN6PKTINFO" - LWRES_HAVE_SIN6_SCOPE_ID="#define LWRES_HAVE_SIN6_SCOPE_ID 1" - ISC_PLATFORM_HAVESCOPEID="#define ISC_PLATFORM_HAVESCOPEID 1" - ISC_IPV6_H="ipv6.h" - ISC_IPV6_O="ipv6.$O" - ISC_ISCIPV6_O="unix/ipv6.$O" - ISC_IPV6_C="ipv6.c" - ;; -esac - -AC_SUBST(ISC_PLATFORM_HAVEIPV6) -AC_SUBST(LWRES_PLATFORM_HAVEIPV6) -AC_SUBST(ISC_PLATFORM_NEEDNETINETIN6H) -AC_SUBST(LWRES_PLATFORM_NEEDNETINETIN6H) -AC_SUBST(ISC_PLATFORM_NEEDNETINET6IN6H) -AC_SUBST(LWRES_PLATFORM_NEEDNETINET6IN6H) -AC_SUBST(ISC_PLATFORM_HAVEINADDR6) -AC_SUBST(LWRES_PLATFORM_HAVEINADDR6) -AC_SUBST(ISC_PLATFORM_NEEDIN6ADDRANY) -AC_SUBST(LWRES_PLATFORM_NEEDIN6ADDRANY) -AC_SUBST(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK) -AC_SUBST(LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK) -AC_SUBST(ISC_PLATFORM_HAVEIN6PKTINFO) -AC_SUBST(ISC_PLATFORM_FIXIN6ISADDR) -AC_SUBST(ISC_IPV6_H) -AC_SUBST(ISC_IPV6_O) -AC_SUBST(ISC_ISCIPV6_O) -AC_SUBST(ISC_IPV6_C) -AC_SUBST(LWRES_HAVE_SIN6_SCOPE_ID) -AC_SUBST(ISC_PLATFORM_HAVESCOPEID) - -AC_MSG_CHECKING([for struct if_laddrreq]) -AC_TRY_LINK([ -#include -#include -],[ struct if_laddrreq a; ], - [AC_MSG_RESULT(yes) - ISC_PLATFORM_HAVEIF_LADDRREQ="#define ISC_PLATFORM_HAVEIF_LADDRREQ 1"], - [AC_MSG_RESULT(no) - ISC_PLATFORM_HAVEIF_LADDRREQ="#undef ISC_PLATFORM_HAVEIF_LADDRREQ"]) -AC_SUBST(ISC_PLATFORM_HAVEIF_LADDRREQ) - -AC_MSG_CHECKING([for struct if_laddrconf]) -AC_TRY_LINK([ -#include -#include -],[ struct if_laddrconf a; ], - [AC_MSG_RESULT(yes) - ISC_PLATFORM_HAVEIF_LADDRCONF="#define ISC_PLATFORM_HAVEIF_LADDRCONF 1"], - [AC_MSG_RESULT(no) - ISC_PLATFORM_HAVEIF_LADDRCONF="#undef ISC_PLATFORM_HAVEIF_LADDRCONF"]) -AC_SUBST(ISC_PLATFORM_HAVEIF_LADDRCONF) - -# -# Check for network functions that are often missing. We do this -# after the libtool checking, so we can put the right suffix on -# the files. It also needs to come after checking for a Kame add-on, -# which provides some (all?) of the desired functions. -# - -AC_MSG_CHECKING([for inet_ntop with IPv6 support]) -AC_TRY_RUN([ -#include -#include -#include -#include -main() { -char a[16],b[64]; return(inet_ntop(AF_INET6, a, b, sizeof(b)) == (char*)0);}], - [AC_MSG_RESULT(yes) - ISC_PLATFORM_NEEDNTOP="#undef ISC_PLATFORM_NEEDNTOP"], - - [AC_MSG_RESULT(no) - ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS inet_ntop.$O" - ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS inet_ntop.c" - ISC_PLATFORM_NEEDNTOP="#define ISC_PLATFORM_NEEDNTOP 1"], - [AC_MSG_RESULT(assuming inet_ntop needed) - ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS inet_ntop.$O" - ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS inet_ntop.c" - ISC_PLATFORM_NEEDNTOP="#define ISC_PLATFORM_NEEDNTOP 1"]) - - -# On NetBSD 1.4.2 and maybe others, inet_pton() incorrectly accepts -# addresses with less than four octets, like "1.2.3". Also leading -# zeros should also be rejected. - -AC_MSG_CHECKING([for working inet_pton with IPv6 support]) -AC_TRY_RUN([ -#include -#include -#include -#include -main() { char a[16]; return (inet_pton(AF_INET, "1.2.3", a) == 1 ? 1 : - inet_pton(AF_INET, "1.2.3.04", a) == 1 ? 1 : - (inet_pton(AF_INET6, "::1.2.3.4", a) != 1)); }], - [AC_MSG_RESULT(yes) - ISC_PLATFORM_NEEDPTON="#undef ISC_PLATFORM_NEEDPTON"], - [AC_MSG_RESULT(no) - ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS inet_pton.$O" - ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS inet_pton.c" - ISC_PLATFORM_NEEDPTON="#define ISC_PLATFORM_NEEDPTON 1"], - [AC_MSG_RESULT(assuming target platform has working inet_pton) - ISC_PLATFORM_NEEDPTON="#undef ISC_PLATFORM_NEEDPTON"], - [AC_MSG_RESULT(assuming inet_pton needed) - ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS inet_pton.$O" - ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS inet_pton.c" - ISC_PLATFORM_NEEDPTON="#define ISC_PLATFORM_NEEDPTON 1"], - [AC_MSG_RESULT(assuming target platform has working inet_pton) - ISC_PLATFORM_NEEDPTON="#undef ISC_PLATFORM_NEEDPTON"]) - -AC_MSG_CHECKING([for inet_aton]) -AC_TRY_LINK([ -#include -#include -#include ], - [struct in_addr in; inet_aton(0, &in); return (0);], - [AC_MSG_RESULT(yes) - ISC_PLATFORM_NEEDATON="#undef ISC_PLATFORM_NEEDATON"], - - [AC_MSG_RESULT(no) - ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS inet_aton.$O" - ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS inet_aton.c" - ISC_PLATFORM_NEEDATON="#define ISC_PLATFORM_NEEDATON 1"]) - -AC_SUBST(ISC_PLATFORM_NEEDNTOP) -AC_SUBST(ISC_PLATFORM_NEEDPTON) -AC_SUBST(ISC_PLATFORM_NEEDATON) - -# -# Look for a 4.4BSD-style sa_len member in struct sockaddr. -# -case "$host" in - *-dec-osf*) - # Turn on 4.4BSD style sa_len support. - AC_DEFINE(_SOCKADDR_LEN) - ;; -esac - -AC_MSG_CHECKING(for sa_len in struct sockaddr) -AC_TRY_COMPILE([ -#include -#include ], -[struct sockaddr sa; sa.sa_len = 0; return (0);], - [AC_MSG_RESULT(yes) - ISC_PLATFORM_HAVESALEN="#define ISC_PLATFORM_HAVESALEN 1" - LWRES_PLATFORM_HAVESALEN="#define LWRES_PLATFORM_HAVESALEN 1"], - [AC_MSG_RESULT(no) - ISC_PLATFORM_HAVESALEN="#undef ISC_PLATFORM_HAVESALEN" - LWRES_PLATFORM_HAVESALEN="#undef LWRES_PLATFORM_HAVESALEN"]) -AC_SUBST(ISC_PLATFORM_HAVESALEN) -AC_SUBST(LWRES_PLATFORM_HAVESALEN) - -# -# Look for a 4.4BSD or 4.3BSD struct msghdr -# -AC_MSG_CHECKING(for struct msghdr flavor) -AC_TRY_COMPILE([ -#include -#include ], -[struct msghdr msg; msg.msg_flags = 0; return (0);], - [AC_MSG_RESULT(4.4BSD) - ISC_PLATFORM_MSGHDRFLAVOR="#define ISC_NET_BSD44MSGHDR 1"], - [AC_MSG_RESULT(4.3BSD) - ISC_PLATFORM_MSGHDRFLAVOR="#define ISC_NET_BSD43MSGHDR 1"]) -AC_SUBST(ISC_PLATFORM_MSGHDRFLAVOR) - -# -# Look for in_port_t. -# -AC_MSG_CHECKING(for type in_port_t) -AC_TRY_COMPILE([ -#include -#include ], -[in_port_t port = 25; return (0);], - [AC_MSG_RESULT(yes) - ISC_PLATFORM_NEEDPORTT="#undef ISC_PLATFORM_NEEDPORTT"], - [AC_MSG_RESULT(no) - ISC_PLATFORM_NEEDPORTT="#define ISC_PLATFORM_NEEDPORTT 1"]) -AC_SUBST(ISC_PLATFORM_NEEDPORTT) - -# -# Check for addrinfo -# -AC_MSG_CHECKING(for struct addrinfo) -AC_TRY_COMPILE([ -#include ], -[struct addrinfo a; return (0);], - [AC_MSG_RESULT(yes) - ISC_LWRES_NEEDADDRINFO="#undef ISC_LWRES_NEEDADDRINFO" - AC_DEFINE(HAVE_ADDRINFO)], - [AC_MSG_RESULT(no) - ISC_LWRES_NEEDADDRINFO="#define ISC_LWRES_NEEDADDRINFO 1"]) -AC_SUBST(ISC_LWRES_NEEDADDRINFO) - -# -# Check for rrsetinfo -# -AC_MSG_CHECKING(for struct rrsetinfo) -AC_TRY_COMPILE([ -#include ], -[struct rrsetinfo r; return (0);], - [AC_MSG_RESULT(yes) - ISC_LWRES_NEEDRRSETINFO="#undef ISC_LWRES_NEEDRRSETINFO"], - [AC_MSG_RESULT(no) - ISC_LWRES_NEEDRRSETINFO="#define ISC_LWRES_NEEDRRSETINFO 1"]) -AC_SUBST(ISC_LWRES_NEEDRRSETINFO) - -AC_MSG_CHECKING(for int sethostent) -AC_TRY_COMPILE([ -#include ], -[int i = sethostent(0); return(0);], - [AC_MSG_RESULT(yes) - ISC_LWRES_SETHOSTENTINT="#define ISC_LWRES_SETHOSTENTINT 1"], - [AC_MSG_RESULT(no) - ISC_LWRES_SETHOSTENTINT="#undef ISC_LWRES_SETHOSTENTINT"]) -AC_SUBST(ISC_LWRES_SETHOSTENTINT) - -AC_MSG_CHECKING(for int endhostent) -AC_TRY_COMPILE([ -#include ], -[int i = endhostent(); return(0);], - [AC_MSG_RESULT(yes) - ISC_LWRES_ENDHOSTENTINT="#define ISC_LWRES_ENDHOSTENTINT 1"], - [AC_MSG_RESULT(no) - ISC_LWRES_ENDHOSTENTINT="#undef ISC_LWRES_ENDHOSTENTINT"]) -AC_SUBST(ISC_LWRES_ENDHOSTENTINT) - -AC_MSG_CHECKING(for getnetbyaddr(in_addr_t, ...)) -AC_TRY_COMPILE([ -#include -struct netent *getnetbyaddr(in_addr_t, int);], -[], - [AC_MSG_RESULT(yes) - ISC_LWRES_GETNETBYADDRINADDR="#define ISC_LWRES_GETNETBYADDRINADDR 1"], - [AC_MSG_RESULT(no) - ISC_LWRES_GETNETBYADDRINADDR="#undef ISC_LWRES_GETNETBYADDRINADDR"]) -AC_SUBST(ISC_LWRES_GETNETBYADDRINADDR) - -AC_MSG_CHECKING(for int setnetent) -AC_TRY_COMPILE([ -#include ], -[int i = setnetent(0); return(0);], - [AC_MSG_RESULT(yes) - ISC_LWRES_SETNETENTINT="#define ISC_LWRES_SETNETENTINT 1"], - [AC_MSG_RESULT(no) - ISC_LWRES_SETNETENTINT="#undef ISC_LWRES_SETNETENTINT"]) -AC_SUBST(ISC_LWRES_SETNETENTINT) - -AC_MSG_CHECKING(for int endnetent) -AC_TRY_COMPILE([ -#include ], -[int i = endnetent(); return(0);], - [AC_MSG_RESULT(yes) - ISC_LWRES_ENDNETENTINT="#define ISC_LWRES_ENDNETENTINT 1"], - [AC_MSG_RESULT(no) - ISC_LWRES_ENDNETENTINT="#undef ISC_LWRES_ENDNETENTINT"]) -AC_SUBST(ISC_LWRES_ENDNETENTINT) - -AC_MSG_CHECKING(for gethostbyaddr(const void *, size_t, ...)) -AC_TRY_COMPILE([ -#include -struct hostent *gethostbyaddr(const void *, size_t, int);], -[return(0);], - [AC_MSG_RESULT(yes) - ISC_LWRES_GETHOSTBYADDRVOID="#define ISC_LWRES_GETHOSTBYADDRVOID 1"], - [AC_MSG_RESULT(no) - ISC_LWRES_GETHOSTBYADDRVOID="#undef ISC_LWRES_GETHOSTBYADDRVOID"]) -AC_SUBST(ISC_LWRES_GETHOSTBYADDRVOID) - -AC_MSG_CHECKING(for h_errno in netdb.h) -AC_TRY_COMPILE([ -#include ], -[h_errno = 1; return(0);], - [AC_MSG_RESULT(yes) - ISC_LWRES_NEEDHERRNO="#undef ISC_LWRES_NEEDHERRNO"], - [AC_MSG_RESULT(no) - ISC_LWRES_NEEDHERRNO="#define ISC_LWRES_NEEDHERRNO 1"]) -AC_SUBST(ISC_LWRES_NEEDHERRNO) - -AC_CHECK_FUNC(getipnodebyname, - [ISC_LWRES_GETIPNODEPROTO="#undef ISC_LWRES_GETIPNODEPROTO"], - [ISC_LWRES_GETIPNODEPROTO="#define ISC_LWRES_GETIPNODEPROTO 1"]) -AC_CHECK_FUNC(getnameinfo, - [ISC_LWRES_GETNAMEINFOPROTO="#undef ISC_LWRES_GETNAMEINFOPROTO"], - [ISC_LWRES_GETNAMEINFOPROTO="#define ISC_LWRES_GETNAMEINFOPROTO 1"]) -AC_CHECK_FUNC(getaddrinfo, - [ISC_LWRES_GETADDRINFOPROTO="#undef ISC_LWRES_GETADDRINFOPROTO" - AC_DEFINE(HAVE_GETADDRINFO)], - [ISC_LWRES_GETADDRINFOPROTO="#define ISC_LWRES_GETADDRINFOPROTO 1"]) -AC_CHECK_FUNC(gai_strerror, AC_DEFINE(HAVE_GAISTRERROR)) -AC_SUBST(ISC_LWRES_GETIPNODEPROTO) -AC_SUBST(ISC_LWRES_GETADDRINFOPROTO) -AC_SUBST(ISC_LWRES_GETNAMEINFOPROTO) - -AC_ARG_ENABLE(getifaddrs, -[ --enable-getifaddrs Enable the use of getifaddrs() [[yes|no|glibc]]. - glibc: Use getifaddrs() in glibc if you know it supports IPv6.], - want_getifaddrs="$enableval", want_getifaddrs="yes") - -case $want_getifaddrs in -yes|glibc) -# -# Do we have getifaddrs() ? -# -case $host in -*-linux*) - # Some recent versions of glibc support getifaddrs() which does not - # provide AF_INET6 addresses while the function provided by the USAGI - # project handles the AF_INET6 case correctly. We need to avoid - # using the former but prefer the latter unless overridden by - # --enable-getifaddrs=glibc. - if test $want_getifaddrs = glibc - then - AC_CHECK_FUNC(getifaddrs, AC_DEFINE(HAVE_GETIFADDRS)) - else - save_LIBS="$LIBS" - LIBS="-L/usr/local/v6/lib $LIBS" - AC_CHECK_LIB(inet6, getifaddrs, - LIBS="$LIBS -linet6" - AC_DEFINE(HAVE_GETIFADDRS), - LIBS=${save_LIBS}) - fi - ;; -*) - AC_CHECK_FUNC(getifaddrs, AC_DEFINE(HAVE_GETIFADDRS)) - ;; -esac -;; -no) -;; -esac - -# -# Look for a sysctl call to get the list of network interfaces. -# -case $ac_cv_header_sys_sysctl_h in -yes) -AC_MSG_CHECKING(for interface list sysctl) -AC_EGREP_CPP(found_rt_iflist, [ -#include -#include -#include -#ifdef NET_RT_IFLIST -found_rt_iflist -#endif -], - [AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_IFLIST_SYSCTL)], - [AC_MSG_RESULT(no)]) -;; -esac - -# -# Check for some other useful functions that are not ever-present. -# - -# We test for strsep() using AC_TRY_LINK instead of AC_CHECK_FUNC -# because AIX 4.3.3 with patches for bos.adt.include to version 4.3.3.77 -# reportedly defines strsep() without declaring it in when -# -D_LINUX_SOURCE_COMPAT is not defined [RT #2190], and -# AC_CHECK_FUNC() incorrectly succeeds because it declares -# the function itself. -AC_MSG_CHECKING(for correctly declared strsep()) -AC_TRY_LINK([#include ], [char *sp; char *foo = strsep(&sp, ".");], - [AC_MSG_RESULT(yes); ISC_PLATFORM_NEEDSTRSEP="#undef ISC_PLATFORM_NEEDSTRSEP"], - [AC_MSG_RESULT(no); ISC_PLATFORM_NEEDSTRSEP="#define ISC_PLATFORM_NEEDSTRSEP 1"]) -AC_SUBST(ISC_PLATFORM_NEEDSTRSEP) - -AC_CHECK_FUNC(memmove, - [ISC_PLATFORM_NEEDMEMMOVE="#undef ISC_PLATFORM_NEEDMEMMOVE"], - [ISC_PLATFORM_NEEDMEMMOVE="#define ISC_PLATFORM_NEEDMEMMOVE 1"]) -AC_SUBST(ISC_PLATFORM_NEEDMEMMOVE) - -AC_CHECK_FUNC(strtoul, - [ISC_PLATFORM_NEEDSTRTOUL="#undef ISC_PLATFORM_NEEDSTRTOUL" - LWRES_PLATFORM_NEEDSTRTOUL="#undef LWRES_PLATFORM_NEEDSTRTOUL" - GENRANDOMLIB=""], - [ISC_PLATFORM_NEEDSTRTOUL="#define ISC_PLATFORM_NEEDSTRTOUL 1" - LWRES_PLATFORM_NEEDSTRTOUL="#define LWRES_PLATFORM_NEEDSTRTOUL 1" - GENRANDOMLIB='${ISCLIBS}']) -AC_SUBST(ISC_PLATFORM_NEEDSTRTOUL) -AC_SUBST(LWRES_PLATFORM_NEEDSTRTOUL) -AC_SUBST(GENRANDOMLIB) - -AC_CHECK_FUNC(strlcpy, - [ISC_PLATFORM_NEEDSTRLCPY="#undef ISC_PLATFORM_NEEDSTRLCPY"], - [ISC_PLATFORM_NEEDSTRLCPY="#define ISC_PLATFORM_NEEDSTRLCPY 1"]) -AC_SUBST(ISC_PLATFORM_NEEDSTRLCPY) - -AC_CHECK_FUNC(strlcat, - [ISC_PLATFORM_NEEDSTRLCAT="#undef ISC_PLATFORM_NEEDSTRLCAT"], - [ISC_PLATFORM_NEEDSTRLCAT="#define ISC_PLATFORM_NEEDSTRLCAT 1"]) -AC_SUBST(ISC_PLATFORM_NEEDSTRLCAT) - -ISC_PRINT_OBJS= -ISC_PRINT_SRCS= -AC_MSG_CHECKING(sprintf) -AC_TRY_COMPILE([ -#include -], -[ char buf[2]; return(*sprintf(buf,"x"));], -[ -ISC_PRINT_OBJS="print.$O" -ISC_PRINT_SRCS="print.c" -ISC_PLATFORM_NEEDSPRINTF="#define ISC_PLATFORM_NEEDSPRINTF" -LWRES_PLATFORM_NEEDSPRINTF="#define LWRES_PLATFORM_NEEDSPRINTF" -], -[ISC_PLATFORM_NEEDSPRINTF="#undef ISC_PLATFORM_NEEDSPRINTF" - LWRES_PLATFORM_NEEDSPRINTF="#undef LWRES_PLATFORM_NEEDSPRINTF"] -) -AC_SUBST(ISC_PLATFORM_NEEDSPRINTF) -AC_SUBST(LWRES_PLATFORM_NEEDSPRINTF) - -AC_CHECK_FUNC(vsnprintf, - [ISC_PLATFORM_NEEDVSNPRINTF="#undef ISC_PLATFORM_NEEDVSNPRINTF" - LWRES_PLATFORM_NEEDVSNPRINTF="#undef LWRES_PLATFORM_NEEDVSNPRINTF"], - [ISC_PRINT_OBJS="print.$O" - ISC_PRINT_SRCS="print.c" - ISC_PLATFORM_NEEDVSNPRINTF="#define ISC_PLATFORM_NEEDVSNPRINTF 1" - LWRES_PLATFORM_NEEDVSNPRINTF="#define LWRES_PLATFORM_NEEDVSNPRINTF 1"]) -AC_SUBST(ISC_PLATFORM_NEEDVSNPRINTF) -AC_SUBST(LWRES_PLATFORM_NEEDVSNPRINTF) -ISC_EXTRA_OBJS="$ISC_EXTRA_OBJS $ISC_PRINT_OBJS" -ISC_EXTRA_SRCS="$ISC_EXTRA_SRCS $ISC_PRINT_SRCS" - -AC_CHECK_FUNC(strerror, AC_DEFINE(HAVE_STRERROR)) - -AC_SUBST(ISC_EXTRA_OBJS) -AC_SUBST(ISC_EXTRA_SRCS) - -# Determine the printf format characters to use when printing -# values of type isc_int64_t. This will normally be "ll", but where -# the compiler treats "long long" as a alias for "long" and printf -# doesn't know about "long long" use "l". Hopefully the sprintf -# will produce a inconsistant result in the later case. If the compiler -# fails due to seeing "%lld" we fall back to "l". -# -# Digital Unix 4.0 (gcc?) (long long) is 64 bits as is its long. It uses -# %ld even for (long long)/ -# -# Win32 uses "%I64d", but that's defined elsewhere since we don't use -# configure on Win32. -# -AC_MSG_CHECKING(printf format modifier for 64-bit integers) -AC_TRY_RUN([ -#include -main() { - long long int j = 0; - char buf[100]; - buf[0] = 0; - sprintf(buf, "%lld", j); - exit((sizeof(long long int) != sizeof(long int))? 0 : - (strcmp(buf, "0") != 0)); -} -], - [AC_MSG_RESULT(ll) - ISC_PLATFORM_QUADFORMAT='#define ISC_PLATFORM_QUADFORMAT "ll"' - LWRES_PLATFORM_QUADFORMAT='#define LWRES_PLATFORM_QUADFORMAT "ll"'], - [AC_MSG_RESULT(l) - ISC_PLATFORM_QUADFORMAT='#define ISC_PLATFORM_QUADFORMAT "l"' - LWRES_PLATFORM_QUADFORMAT='#define LWRES_PLATFORM_QUADFORMAT "l"'], - [AC_MSG_RESULT(assuming target platform uses ll) - ISC_PLATFORM_QUADFORMAT='#define ISC_PLATFORM_QUADFORMAT "ll"' - LWRES_PLATFORM_QUADFORMAT='#define LWRES_PLATFORM_QUADFORMAT "ll"']) -AC_SUBST(ISC_PLATFORM_QUADFORMAT) -AC_SUBST(LWRES_PLATFORM_QUADFORMAT) - -# -# Security Stuff -# -AC_CHECK_FUNC(chroot, AC_DEFINE(HAVE_CHROOT)) -AC_ARG_ENABLE(linux-caps, - [ --disable-linux-caps disable linux capabilities]) -case "$enable_linux_caps" in - yes|'') - AC_CHECK_HEADERS(linux/capability.h) - ;; - no) - ;; -esac -AC_CHECK_HEADERS(sys/prctl.h) - -AC_CHECK_HEADERS(sys/un.h, -ISC_PLATFORM_HAVESYSUNH="#define ISC_PLATFORM_HAVESYSUNH 1" -, -ISC_PLATFORM_HAVESYSUNH="#undef ISC_PLATFORM_HAVESYSUNH" -) -AC_SUBST(ISC_PLATFORM_HAVESYSUNH) - -case "$host" in -*-solaris*) - AC_DEFINE(NEED_SECURE_DIRECTORY, 1, - [Define if connect does not honour the permission on the UNIX domain socket.]) - ;; -*-sunos*) - AC_DEFINE(NEED_SECURE_DIRECTORY, 1, - [Define if connect does not honour the permission on the UNIX domain socket.]) - ;; -esac - -# -# Time Zone Stuff -# -AC_CHECK_FUNC(tzset, AC_DEFINE(HAVE_TZSET)) - -AC_MSG_CHECKING(for optarg decarartion) -AC_TRY_COMPILE([ -#include -], -[optarg = 0;], -[AC_MSG_RESULT(yes)], -[AC_MSG_RESULT(no) -GEN_NEED_OPTARG="-DNEED_OPTARG=1" -AC_DEFINE(NEED_OPTARG, 1, [Defined if extern char *optarg is not declared.])]) - -# -# BSD/OS, and perhaps some others, don't define rlim_t. -# -AC_MSG_CHECKING(for type rlim_t) -AC_TRY_COMPILE([ -#include -#include -#include ], -[rlim_t rl = 19671212; return (0);], -[AC_MSG_RESULT(yes) - ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE rlim_t"], -[AC_MSG_RESULT(no) - -AC_MSG_CHECKING(type of rlim_cur) -AC_TRY_RUN([ -#include -#include -#include -main() { struct rlimit r; exit(!(sizeof(r.rlim_cur) == sizeof(int)));}], -[AC_MSG_RESULT(int) -ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE int"], -[ -AC_TRY_RUN([ -#include -#include -#include -main() { struct rlimit r; exit(!(sizeof(r.rlim_cur) == sizeof(long int)));}], -[AC_MSG_RESULT(long int) -ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE long int"], -[ -AC_TRY_RUN([ -#include -#include -#include -main() { struct rlimit r; exit((!sizeof(r.rlim_cur) == sizeof(long long int)));}], -[AC_MSG_RESULT(long long int) -ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE long long int"], -[AC_MSG_ERROR([unable to determine sizeof rlim_cur]) -],[AC_MSG_ERROR(this cannot happen)]) -],[AC_MSG_ERROR(this cannot happen)]) -],[ -ISC_PLATFORM_RLIMITTYPE="#define ISC_PLATFORM_RLIMITTYPE long long int" -AC_MSG_RESULT(cannot determine type of rlim_cur when cross compiling - assuming long long int)]) -]) -AC_SUBST(ISC_PLATFORM_RLIMITTYPE) - -# -# Compaq TruCluster requires more code for handling cluster IP aliases -# -case "$host" in - *-dec-osf*) - AC_CHECK_LIB(clua, clua_getaliasaddress, LIBS="-lclua $LIBS") - AC_CHECK_FUNC(clua_getaliasaddress, - AC_DEFINE(HAVE_TRUCLUSTER, 1, - [Define if running under Compaq TruCluster])) - ;; - *) - ;; -esac - -# -# Some hosts need msg_namelen to match the size of the socket structure. -# Some hosts don't set msg_namelen appropriately on return from recvmsg(). -# -case $host in -*os2*|*hp-mpeix*) - AC_DEFINE(BROKEN_RECVMSG, 1, - [Define if recvmsg() does not meet all of the BSD socket API specifications.]) - ;; -esac - -# -# Microsoft has their own way of handling shared libraries that requires -# additional qualifiers on extern variables. Unix systems don't need it. -# -AC_SUBST(ISC_PLATFORM_USEDECLSPEC) -ISC_PLATFORM_USEDECLSPEC="#undef ISC_PLATFORM_USEDECLSPEC" -AC_SUBST(LWRES_PLATFORM_USEDECLSPEC) -LWRES_PLATFORM_USEDECLSPEC="#undef LWRES_PLATFORM_USEDECLSPEC" - -# -# Random remaining OS-specific issues involving compiler warnings. -# XXXDCL print messages to indicate some compensation is being done? -# -AC_SUBST(ISC_PLATFORM_BRACEPTHREADONCEINIT) -ISC_PLATFORM_BRACEPTHREADONCEINIT="#undef ISC_PLATFORM_BRACEPTHREADONCEINIT" - -case "$host" in - *-aix5.[[123]].*) - hack_shutup_pthreadonceinit=yes - ;; - *-bsdi3.1*) - hack_shutup_sputaux=yes - ;; - *-bsdi4.0*) - hack_shutup_sigwait=yes - hack_shutup_sputaux=yes - ;; - [*-bsdi4.[12]*]) - hack_shutup_stdargcast=yes - ;; - [*-solaris2.[89]]) - hack_shutup_pthreadonceinit=yes - ;; - *-solaris2.10) - hack_shutup_pthreadonceinit=yes - ;; -esac - -case "$hack_shutup_pthreadonceinit" in - yes) - # - # Shut up PTHREAD_ONCE_INIT unbraced initializer warnings. - # - ISC_PLATFORM_BRACEPTHREADONCEINIT="#define ISC_PLATFORM_BRACEPTHREADONCEINIT 1" - ;; -esac - -case "$hack_shutup_sigwait" in - yes) - # - # Shut up a -Wmissing-prototypes warning for sigwait(). - # - AC_DEFINE(SHUTUP_SIGWAIT) - ;; -esac - -case "$hack_shutup_sputaux" in - yes) - # - # Shut up a -Wmissing-prototypes warning from . - # - AC_DEFINE(SHUTUP_SPUTAUX) - ;; -esac - -case "$hack_shutup_stdargcast" in - yes) - # - # Shut up a -Wcast-qual warning from va_start(). - # - AC_DEFINE(SHUTUP_STDARG_CAST) - ;; -esac - -AC_CHECK_HEADERS(strings.h, - ISC_PLATFORM_HAVESTRINGSH="#define ISC_PLATFORM_HAVESTRINGSH 1" -, - ISC_PLATFORM_HAVESTRINGSH="#undef ISC_PLATFORM_HAVESTRINGSH" -) -AC_SUBST(ISC_PLATFORM_HAVESTRINGSH) - -# -# Check for if_nametoindex() for IPv6 scoped addresses support -# -AC_CHECK_FUNC(if_nametoindex, ac_cv_have_if_nametoindex=yes, - ac_cv_have_if_nametoindex=no) -case $ac_cv_have_if_nametoindex in -no) - case "$host" in - *-hp-hpux*) - AC_CHECK_LIB(ipv6, if_nametoindex, - ac_cv_have_if_nametoindex=yes - LIBS="-lipv6 $LIBS",) - ;; - esac -esac -case $ac_cv_have_if_nametoindex in -yes) - ISC_PLATFORM_HAVEIFNAMETOINDEX="#define ISC_PLATFORM_HAVEIFNAMETOINDEX 1" - ;; -*) - ISC_PLATFORM_HAVEIFNAMETOINDEX="#undef ISC_PLATFORM_HAVEIFNAMETOINDEX" - ;; -esac -AC_SUBST(ISC_PLATFORM_HAVEIFNAMETOINDEX) - -# -# Machine architecture dependent features -# -AC_ARG_ENABLE(atomic, - [ --enable-atomic enable machine specific atomic operations - [[default=autodetect]]], - enable_atomic="$enableval", - enable_atomic="autodetect") -case "$enable_atomic" in - yes|''|autodetect) - use_atomic=yes - ;; - no) - use_atomic=no - arch=noatomic - ;; -esac - -ISC_PLATFORM_USEOSFASM="#undef ISC_PLATFORM_USEOSFASM" -if test "$use_atomic" = "yes"; then - AC_MSG_CHECKING([architecture type for atomic operations]) - have_atomic=yes # set default - case "$host" in - [i[3456]86-*]) - # XXX: some old x86 architectures actually do not support - # (some of) these operations. Do we need stricter checks? -AC_TRY_RUN([ -main() { - exit((sizeof(void *) == 8) ? 0 : 1); -} -], - [arch=x86_64], - [arch=x86_32], - [arch=x86_32]) - ;; - x86_64-*) - arch=x86_64 - ;; - alpha*-*) - arch=alpha - ;; - powerpc-*) - arch=powerpc - ;; - mips-*|mipsel-*|mips64-*|mips64el-*) - arch=mips - ;; - ia64-*) - arch=ia64 - ;; - *) - have_atomic=no - arch=noatomic - ;; - esac - AC_MSG_RESULT($arch) -fi - -if test "$have_atomic" = "yes"; then - AC_MSG_CHECKING([compiler support for inline assembly code]) - - compiler=generic - # Check whether the compiler supports the assembly syntax we provide. - if test "X$GCC" = "Xyes"; then - # GCC's ASM extension always works - compiler=gcc - if test $arch = "x86_64"; then - # We can share the same code for gcc with x86_32 - arch=x86_32 - fi - if test $arch = "powerpc"; then - # - # The MacOS (and maybe others) uses "r0" for register - # zero. Under linux/ibm it is "0" for register 0. - # Probe to see if we have a MacOS style assembler. - # - AC_MSG_CHECKING([Checking for MacOS style assembler syntax]) - AC_TRY_COMPILE(, [ - __asm__ volatile ("li r0, 0x0\n"::); - ], [ - AC_MSG_RESULT(yes) - compiler="mac" - ISC_PLATFORM_USEMACASM="#define ISC_PLATFORM_USEMACASM 1" - ], [AC_MSG_RESULT(no)]) - fi - else - case "$host" in - alpha*-dec-osf*) - # Tru64 compiler has its own syntax for inline - # assembly. - AC_TRY_COMPILE(, [ -#ifndef __DECC -#error "unexpected compiler" -#endif - return (0);], - [compiler=osf],) - ;; - powerpc-ibm-aix*) - compiler=aix - ;; - esac - fi - case "$compiler" in - gcc) - ISC_PLATFORM_USEGCCASM="#define ISC_PLATFORM_USEGCCASM 1" - ;; - osf) - ISC_PLATFORM_USEOSFASM="#define ISC_PLATFORM_USEOSFASM 1" - ;; - aix) - ;; - mac) - ;; - *) - # See if the generic __asm function works. If not, - # we need to disable the atomic operations. - AC_TRY_LINK(, [ - __asm("nop") - ], - [compiler="standard" - ISC_PLATFORM_USESTDASM="#define ISC_PLATFORM_USESTDASM 1"], - [compiler="not supported (atomic operations disabled)" - have_atomic=no - arch=noatomic ]); - ;; - esac - - AC_MSG_RESULT($compiler) -fi - -if test "$have_atomic" = "yes"; then - ISC_PLATFORM_HAVEXADD="#define ISC_PLATFORM_HAVEXADD 1" - ISC_PLATFORM_HAVECMPXCHG="#define ISC_PLATFORM_HAVECMPXCHG 1" - ISC_PLATFORM_HAVEATOMICSTORE="#define ISC_PLATFORM_HAVEATOMICSTORE 1" -else - ISC_PLATFORM_HAVEXADD="#undef ISC_PLATFORM_HAVEXADD" - ISC_PLATFORM_HAVECMPXCHG="#undef ISC_PLATFORM_HAVECMPXCHG" - ISC_PLATFORM_HAVEATOMICSTORE="#undef ISC_PLATFORM_HAVEATOMICSTORE" -fi - -AC_SUBST(ISC_PLATFORM_HAVEXADD) -AC_SUBST(ISC_PLATFORM_HAVECMPXCHG) -AC_SUBST(ISC_PLATFORM_HAVEATOMICSTORE) - -AC_SUBST(ISC_PLATFORM_USEGCCASM) -AC_SUBST(ISC_PLATFORM_USEOSFASM) -AC_SUBST(ISC_PLATFORM_USESTDASM) -AC_SUBST(ISC_PLATFORM_USEMACASM) - -ISC_ARCH_DIR=$arch -AC_SUBST(ISC_ARCH_DIR) - -# -# The following sets up how non-blocking i/o is established. -# Sunos, cygwin and solaris 2.x (x<5) require special handling. -# -case "$host" in -*-sunos*) AC_DEFINE(PORT_NONBLOCK, O_NDELAY);; -*-cygwin*) AC_DEFINE(PORT_NONBLOCK, O_NDELAY);; -*-solaris2.[[01234]]) - AC_DEFINE(PORT_NONBLOCK, O_NONBLOCK) - AC_DEFINE(USE_FIONBIO_IOCTL, 1, - [Defined if you need to use ioctl(FIONBIO) instead a fcntl call to make non-blocking.]) - ;; -*) AC_DEFINE(PORT_NONBLOCK, O_NONBLOCK, - [Sets which flag to pass to open/fcntl to make non-blocking (O_NDELAY/O_NONBLOCK).]) - ;; -esac -# -# Solaris 2.5.1 and earlier cannot bind() then connect() a TCP socket. -# This prevents the source address being set. -# -case "$host" in -*-solaris2.[[012345]]|*-solaris2.5.1) - AC_DEFINE(BROKEN_TCP_BIND_BEFORE_CONNECT, 1, - [Define if you cannot bind() before connect() for TCP sockets.]) - ;; -esac -# -# The following sections deal with tools used for formatting -# the documentation. They are all optional, unless you are -# a developer editing the documentation source. -# - -# -# Look for TeX. -# - -AC_PATH_PROGS(LATEX, latex, latex) -AC_SUBST(LATEX) - -AC_PATH_PROGS(PDFLATEX, pdflatex, pdflatex) -AC_SUBST(PDFLATEX) - -# -# Look for w3m -# - -AC_PATH_PROGS(W3M, w3m, w3m) -AC_SUBST(W3M) - -# -# Look for xsltproc (libxslt) -# - -AC_PATH_PROG(XSLTPROC, xsltproc, xsltproc) -AC_SUBST(XSLTPROC) - -# -# Look for xmllint (libxml2) -# - -AC_PATH_PROG(XMLLINT, xmllint, xmllint) -AC_SUBST(XMLLINT) - -# -# Subroutine for searching for an ordinary file (e.g., a stylesheet) -# in a number of directories: -# -# NOM_PATH_FILE(VARIABLE, FILENAME, DIRECTORIES) -# -# If the file FILENAME is found in one of the DIRECTORIES, the shell -# variable VARIABLE is defined to its absolute pathname. Otherwise, -# it is set to FILENAME, with no directory prefix (that's not terribly -# useful, but looks less confusing in substitutions than leaving it -# empty). The variable VARIABLE will be substituted into output files. -# - -AC_DEFUN(NOM_PATH_FILE, [ -$1="" -AC_MSG_CHECKING(for $2) -for d in $3 -do - f=$d/$2 - if test -f $f - then - $1=$f - AC_MSG_RESULT($f) - break - fi -done -if test "X[$]$1" = "X" -then - AC_MSG_RESULT("not found"); - $1=$2 -fi -AC_SUBST($1) -]) - -# -# Look for Docbook-XSL stylesheets. Location probably varies by -# system. Guessing where it might be found, based on where SGML stuff -# lives on some systems. FreeBSD is the only one I'm sure of at the -# moment. -# - -docbook_xsl_trees="/usr/pkg/share/xsl /usr/local/share/xsl /usr/share/xsl" - -# -# Look for stylesheets we need. -# - -NOM_PATH_FILE(XSLT_DOCBOOK_STYLE_HTML, docbook/html/docbook.xsl, $docbook_xsl_trees) -NOM_PATH_FILE(XSLT_DOCBOOK_STYLE_XHTML, docbook/xhtml/docbook.xsl, $docbook_xsl_trees) -NOM_PATH_FILE(XSLT_DOCBOOK_STYLE_MAN, docbook/manpages/docbook.xsl, $docbook_xsl_trees) -NOM_PATH_FILE(XSLT_DOCBOOK_CHUNK_HTML, docbook/html/chunk.xsl, $docbook_xsl_trees) -NOM_PATH_FILE(XSLT_DOCBOOK_CHUNK_XHTML, docbook/xhtml/chunk.xsl, $docbook_xsl_trees) -NOM_PATH_FILE(XSLT_DOCBOOK_CHUNKTOC_HTML, docbook/html/chunktoc.xsl, $docbook_xsl_trees) -NOM_PATH_FILE(XSLT_DOCBOOK_CHUNKTOC_XHTML, docbook/xhtml/chunktoc.xsl, $docbook_xsl_trees) -NOM_PATH_FILE(XSLT_DOCBOOK_MAKETOC_HTML, docbook/html/maketoc.xsl, $docbook_xsl_trees) -NOM_PATH_FILE(XSLT_DOCBOOK_MAKETOC_XHTML, docbook/xhtml/maketoc.xsl, $docbook_xsl_trees) - -# -# Same dance for db2latex -# -# No idea where this lives except on FreeBSD. -# - -db2latex_xsl_trees="/usr/local/share" - -# -# Look for stylesheets we need. -# - -NOM_PATH_FILE(XSLT_DB2LATEX_STYLE, db2latex/xsl/docbook.xsl, $db2latex_xsl_trees) - -# -# Look for "admonition" image directory. Can't use NOM_PATH_FILE() -# because it's a directory, so just do the same things, inline. -# - -AC_MSG_CHECKING(for db2latex/xsl/figures) -for d in $db2latex_xsl_trees -do - dd=$d/db2latex/xsl/figures - if test -d $dd - then - XSLT_DB2LATEX_ADMONITIONS=$dd - AC_MSG_RESULT($dd) - break - fi -done -if test "X$XSLT_DB2LATEX_ADMONITIONS" = "X" -then - AC_MSG_RESULT(not found) - XSLT_DB2LATEX_ADMONITIONS=db2latex/xsl/figures -fi -AC_SUBST(XSLT_DB2LATEX_ADMONITIONS) - -# -# IDN support -# -AC_ARG_WITH(idn, - [ --with-idn[=MPREFIX] enable IDN support using idnkit [default PREFIX]], - use_idn="$withval", use_idn="no") -case "$use_idn" in -yes) - if test X$prefix = XNONE ; then - idn_path=/usr/local - else - idn_path=$prefix - fi - ;; -no) - ;; -*) - idn_path="$use_idn" - ;; -esac - -iconvinc= -iconvlib= -AC_ARG_WITH(libiconv, - [ --with-libiconv[=IPREFIX] GNU libiconv are in IPREFIX [default PREFIX]], - use_libiconv="$withval", use_libiconv="no") -case "$use_libiconv" in -yes) - if test X$prefix = XNONE ; then - iconvlib="-L/usr/local/lib -R/usr/local/lib -liconv" - else - iconvlib="-L$prefix/lib -R$prefix/lib -liconv" - fi - ;; -no) - iconvlib= - ;; -*) - iconvlib="-L$use_libiconv/lib -R$use_libiconv/lib -liconv" - ;; -esac - -AC_ARG_WITH(iconv, - [ --with-iconv[=LIBSPEC] specify iconv library [default -liconv]], - iconvlib="$withval") -case "$iconvlib" in -no) - iconvlib= - ;; -yes) - iconvlib=-liconv - ;; -esac - -AC_ARG_WITH(idnlib, - [ --with-idnlib=ARG specify libidnkit], - idnlib="$withval", idnlib="no") -if test "$idnlib" = yes; then - AC_MSG_ERROR([You must specify ARG for --with-idnlib.]) -fi - -IDNLIBS= -if test "$use_idn" != no; then - AC_DEFINE(WITH_IDN, 1, [define if idnkit support is to be included.]) - STD_CINCLUDES="$STD_CINCLUDES -I$idn_path/include" - if test "$idnlib" != no; then - IDNLIBS="$idnlib $iconvlib" - else - IDNLIBS="-L$idn_path/lib -lidnkit $iconvlib" - fi -fi -AC_SUBST(IDNLIBS) - -AC_CHECK_HEADERS(locale.h) -AC_CHECK_FUNCS(setlocale) - -# -# Substitutions -# -AC_SUBST(BIND9_TOP_BUILDDIR) -BIND9_TOP_BUILDDIR=`pwd` - -AC_SUBST(BIND9_ISC_BUILDINCLUDE) -AC_SUBST(BIND9_ISCCC_BUILDINCLUDE) -AC_SUBST(BIND9_ISCCFG_BUILDINCLUDE) -AC_SUBST(BIND9_DNS_BUILDINCLUDE) -AC_SUBST(BIND9_LWRES_BUILDINCLUDE) -AC_SUBST(BIND9_BIND9_BUILDINCLUDE) -if test "X$srcdir" != "X"; then - BIND9_ISC_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/isc/include" - BIND9_ISCCC_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/isccc/include" - BIND9_ISCCFG_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/isccfg/include" - BIND9_DNS_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/dns/include" - BIND9_LWRES_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/lwres/include" - BIND9_BIND9_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/bind9/include" -else - BIND9_ISC_BUILDINCLUDE="" - BIND9_ISCCC_BUILDINCLUDE="" - BIND9_ISCCFG_BUILDINCLUDE="" - BIND9_DNS_BUILDINCLUDE="" - BIND9_LWRES_BUILDINCLUDE="" - BIND9_BIND9_BUILDINCLUDE="" -fi - -AC_SUBST_FILE(BIND9_MAKE_INCLUDES) -BIND9_MAKE_INCLUDES=$BIND9_TOP_BUILDDIR/make/includes - -AC_SUBST_FILE(BIND9_MAKE_RULES) -BIND9_MAKE_RULES=$BIND9_TOP_BUILDDIR/make/rules - -. $srcdir/version -BIND9_VERSION="VERSION=${MAJORVER}.${MINORVER}.${PATCHVER}${RELEASETYPE}${RELEASEVER}" -AC_SUBST(BIND9_VERSION) - -AC_SUBST_FILE(LIBISC_API) -LIBISC_API=$srcdir/lib/isc/api - -AC_SUBST_FILE(LIBISCCC_API) -LIBISCCC_API=$srcdir/lib/isccc/api - -AC_SUBST_FILE(LIBISCCFG_API) -LIBISCCFG_API=$srcdir/lib/isccfg/api - -AC_SUBST_FILE(LIBDNS_API) -LIBDNS_API=$srcdir/lib/dns/api - -AC_SUBST_FILE(LIBBIND9_API) -LIBBIND9_API=$srcdir/lib/bind9/api - -AC_SUBST_FILE(LIBLWRES_API) -LIBLWRES_API=$srcdir/lib/lwres/api - -# -# Configure any DLZ drivers. -# -# If config.dlz.in selects one or more DLZ drivers, it will set -# USE_DLZ to a non-empty value, which will be our clue to -# enable the DLZ core functions. -# -# This section has to come after the libtool stuff because it needs to -# know how to name the driver object files. -# - -USE_DLZ="" -DLZ_DRIVER_INCLUDES="" -DLZ_DRIVER_LIBS="" -DLZ_DRIVER_SRCS="" -DLZ_DRIVER_OBJS="" - -sinclude(contrib/dlz/config.dlz.in) - -AC_MSG_CHECKING(for DLZ) - -if test -n "$USE_DLZ" -then - AC_MSG_RESULT(yes) - USE_DLZ="-DDLZ $USE_DLZ" - DLZ_DRIVER_RULES=contrib/dlz/drivers/rules - AC_CONFIG_FILES([$DLZ_DRIVER_RULES]) -else - AC_MSG_RESULT(no) - DLZ_DRIVER_RULES=/dev/null -fi - -AC_SUBST(USE_DLZ) -AC_SUBST(DLZ_DRIVER_INCLUDES) -AC_SUBST(DLZ_DRIVER_LIBS) -AC_SUBST(DLZ_DRIVER_SRCS) -AC_SUBST(DLZ_DRIVER_OBJS) -AC_SUBST_FILE(DLZ_DRIVER_RULES) - -if test "$cross_compiling" = "yes"; then - if test -z "$BUILD_CC"; then - AC_ERROR([BUILD_CC not set]) - fi - BUILD_CFLAGS="$BUILD_CFLAGS" - BUILD_CPPFLAGS="$BUILD_CPPFLAGS" - BUILD_LDFLAGS="$BUILD_LDFLAGS" - BUILD_LIBS="$BUILD_LIBS" -else - BUILD_CC="$CC" - BUILD_CFLAGS="$CFLAGS" - BUILD_CPPFLAGS="$CPPFLAGS $GEN_NEED_OPTARG" - BUILD_LDFLAGS="$LDFLAGS" - BUILD_LIBS="$LIBS" -fi - -AC_SUBST(BUILD_CC) -AC_SUBST(BUILD_CFLAGS) -AC_SUBST(BUILD_CPPFLAGS) -AC_SUBST(BUILD_LDFLAGS) -AC_SUBST(BUILD_LIBS) - -# -# Commands to run at the end of config.status. -# Don't just put these into configure, it won't work right if somebody -# runs config.status directly (which autoconf allows). -# - -AC_CONFIG_COMMANDS( - [chmod], - [chmod a+x isc-config.sh]) - -# -# Files to configure. These are listed here because we used to -# specify them as arguments to AC_OUTPUT. It's (now) ok to move these -# elsewhere if there's a good reason for doing so. -# - -AC_CONFIG_FILES([ - Makefile - make/Makefile - make/mkdep - lib/Makefile - lib/isc/Makefile - lib/isc/include/Makefile - lib/isc/include/isc/Makefile - lib/isc/include/isc/platform.h - lib/isc/unix/Makefile - lib/isc/unix/include/Makefile - lib/isc/unix/include/isc/Makefile - lib/isc/nls/Makefile - lib/isc/$thread_dir/Makefile - lib/isc/$thread_dir/include/Makefile - lib/isc/$thread_dir/include/isc/Makefile - lib/isc/$arch/Makefile - lib/isc/$arch/include/Makefile - lib/isc/$arch/include/isc/Makefile - lib/isccc/Makefile - lib/isccc/include/Makefile - lib/isccc/include/isccc/Makefile - lib/isccfg/Makefile - lib/isccfg/include/Makefile - lib/isccfg/include/isccfg/Makefile - lib/dns/Makefile - lib/dns/include/Makefile - lib/dns/include/dns/Makefile - lib/dns/include/dst/Makefile - lib/bind9/Makefile - lib/bind9/include/Makefile - lib/bind9/include/bind9/Makefile - lib/lwres/Makefile - lib/lwres/include/Makefile - lib/lwres/include/lwres/Makefile - lib/lwres/include/lwres/netdb.h - lib/lwres/include/lwres/platform.h - lib/lwres/man/Makefile - lib/lwres/unix/Makefile - lib/lwres/unix/include/Makefile - lib/lwres/unix/include/lwres/Makefile - lib/tests/Makefile - lib/tests/include/Makefile - lib/tests/include/tests/Makefile - bin/Makefile - bin/check/Makefile - bin/named/Makefile - bin/named/unix/Makefile - bin/rndc/Makefile - bin/rndc/unix/Makefile - bin/dig/Makefile - bin/nsupdate/Makefile - bin/tests/Makefile - bin/tests/names/Makefile - bin/tests/master/Makefile - bin/tests/rbt/Makefile - bin/tests/db/Makefile - bin/tests/tasks/Makefile - bin/tests/timers/Makefile - bin/tests/dst/Makefile - bin/tests/mem/Makefile - bin/tests/net/Makefile - bin/tests/sockaddr/Makefile - bin/tests/system/Makefile - bin/tests/system/conf.sh - bin/tests/system/lwresd/Makefile - bin/tests/system/tkey/Makefile - bin/tests/headerdep_test.sh - bin/dnssec/Makefile - doc/Makefile - doc/arm/Makefile - doc/misc/Makefile - isc-config.sh - doc/xsl/Makefile - doc/xsl/isc-docbook-chunk.xsl - doc/xsl/isc-docbook-html.xsl - doc/xsl/isc-docbook-latex.xsl - doc/xsl/isc-manpage.xsl -]) - -# -# Do it -# - -AC_OUTPUT - -if test "X$OPENSSL_WARNING" != "X"; then -cat << \EOF -WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING -WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING -WARNING WARNING -WARNING Your OpenSSL crypto library may be vulnerable to WARNING -WARNING one or more of the the following known security WARNING -WARNING flaws: WARNING -WARNING WARNING -WARNING CAN-2002-0659, CAN-2006-4339, CVE-2006-2937 and WARNING -WARNING CVE-2006-2940. WARNING -WARNING WARNING -WARNING It is recommended that you upgrade to OpenSSL WARNING -WARNING version 0.9.8d/0.9.7l (or greater). WARNING -WARNING WARNING -WARNING You can disable this warning by specifying: WARNING -WARNING WARNING -WARNING --disable-openssl-version-check WARNING -WARNING WARNING -WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING -WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING -EOF -fi - -# Tell Emacs to edit this file in shell mode. -# Local Variables: -# mode: sh -# End: diff --git a/contrib/bind9/doc/Makefile.in b/contrib/bind9/doc/Makefile.in deleted file mode 100644 index f307f41..0000000 --- a/contrib/bind9/doc/Makefile.in +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 2000, 2001 Internet Software Consortium. -# -# Permission to use, copy, modify, and 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: Makefile.in,v 1.5.18.2 2005/07/23 04:35:12 marka Exp $ - -# This Makefile is a placeholder. It exists merely to make -# sure that its directory gets created in the object directory -# tree when doing a build using separate object directories. - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -SUBDIRS = arm misc xsl -TARGETS = - -@BIND9_MAKE_RULES@ diff --git a/contrib/bind9/doc/arm/Bv9ARM-book.xml b/contrib/bind9/doc/arm/Bv9ARM-book.xml deleted file mode 100644 index e30ca3f..0000000 --- a/contrib/bind9/doc/arm/Bv9ARM-book.xml +++ /dev/null @@ -1,12326 +0,0 @@ -]> - - - - - BIND 9 Administrator Reference Manual - - - - 2004 - 2005 - 2006 - 2007 - Internet Systems Consortium, Inc. ("ISC") - - - 2000 - 2001 - 2002 - 2003 - Internet Software Consortium. - - - - - Introduction - - The Internet Domain Name System (DNS) - consists of the syntax - to specify the names of entities in the Internet in a hierarchical - manner, the rules used for delegating authority over names, and the - system implementation that actually maps names to Internet - addresses. DNS data is maintained in a - group of distributed - hierarchical databases. - - - - Scope of Document - - - The Berkeley Internet Name Domain - (BIND) implements a - domain name server for a number of operating systems. This - document provides basic information about the installation and - care of the Internet Systems Consortium (ISC) - BIND version 9 software package for - system administrators. - - - - This version of the manual corresponds to BIND version 9.4. - - - - - Organization of This Document - - In this document, Section 1 introduces - the basic DNS and BIND concepts. Section 2 - describes resource requirements for running BIND in various - environments. Information in Section 3 is - task-oriented in its presentation and is - organized functionally, to aid in the process of installing the - BIND 9 software. The task-oriented - section is followed by - Section 4, which contains more advanced - concepts that the system administrator may need for implementing - certain options. Section 5 - describes the BIND 9 lightweight - resolver. The contents of Section 6 are - organized as in a reference manual to aid in the ongoing - maintenance of the software. Section 7 addresses - security considerations, and - Section 8 contains troubleshooting help. The - main body of the document is followed by several - appendices which contain useful reference - information, such as a bibliography and - historic information related to BIND - and the Domain Name - System. - - - - Conventions Used in This Document - - - In this document, we use the following general typographic - conventions: - - - - - - - - - - - To describe: - - - - - We use the style: - - - - - - - a pathname, filename, URL, hostname, - mailing list name, or new term or concept - - - - - Fixed width - - - - - - - literal user - input - - - - - Fixed Width Bold - - - - - - - program output - - - - - Fixed Width - - - - - - - - - The following conventions are used in descriptions of the - BIND configuration file: - - - - - - - - To describe: - - - - - We use the style: - - - - - - - keywords - - - - - Fixed Width - - - - - - - variables - - - - - Fixed Width - - - - - - - Optional input - - - - - Text is enclosed in square brackets - - - - - - - - - - The Domain Name System (<acronym>DNS</acronym>) - - The purpose of this document is to explain the installation - and upkeep of the BIND (Berkeley Internet - Name Domain) software package, and we - begin by reviewing the fundamentals of the Domain Name System - (DNS) as they relate to BIND. - - - - DNS Fundamentals - - - The Domain Name System (DNS) is a hierarchical, distributed - database. It stores information for mapping Internet host names to - IP - addresses and vice versa, mail routing information, and other data - used by Internet applications. - - - - Clients look up information in the DNS by calling a - resolver library, which sends queries to one or - more name servers and interprets the responses. - The BIND 9 software distribution - contains a - name server, named, and two resolver - libraries, liblwres and libbind. - - - - Domains and Domain Names - - - The data stored in the DNS is identified by domain names that are organized as a tree according to - organizational or administrative boundaries. Each node of the tree, - called a domain, is given a label. The domain - name of the - node is the concatenation of all the labels on the path from the - node to the root node. This is represented - in written form as a string of labels listed from right to left and - separated by dots. A label need only be unique within its parent - domain. - - - - For example, a domain name for a host at the - company Example, Inc. could be - ourhost.example.com, - where com is the - top level domain to which - ourhost.example.com belongs, - example is - a subdomain of com, and - ourhost is the - name of the host. - - - - For administrative purposes, the name space is partitioned into - areas called zones, each starting at a node and - extending down to the leaf nodes or to nodes where other zones - start. - The data for each zone is stored in a name server, which answers queries about the zone using the - DNS protocol. - - - - The data associated with each domain name is stored in the - form of resource records (RRs). - Some of the supported resource record types are described in - . - - - - For more detailed information about the design of the DNS and - the DNS protocol, please refer to the standards documents listed in - . - - - - - Zones - - To properly operate a name server, it is important to understand - the difference between a zone - and a domain. - - - - As stated previously, a zone is a point of delegation in - the DNS tree. A zone consists of - those contiguous parts of the domain - tree for which a name server has complete information and over which - it has authority. It contains all domain names from a certain point - downward in the domain tree except those which are delegated to - other zones. A delegation point is marked by one or more - NS records in the - parent zone, which should be matched by equivalent NS records at - the root of the delegated zone. - - - - For instance, consider the example.com - domain which includes names - such as host.aaa.example.com and - host.bbb.example.com even though - the example.com zone includes - only delegations for the aaa.example.com and - bbb.example.com zones. A zone can - map - exactly to a single domain, but could also include only part of a - domain, the rest of which could be delegated to other - name servers. Every name in the DNS - tree is a - domain, even if it is - terminal, that is, has no - subdomains. Every subdomain is a domain and - every domain except the root is also a subdomain. The terminology is - not intuitive and we suggest that you read RFCs 1033, 1034 and 1035 - to - gain a complete understanding of this difficult and subtle - topic. - - - - Though BIND is called a "domain name - server", - it deals primarily in terms of zones. The master and slave - declarations in the named.conf file - specify - zones, not domains. When you ask some other site if it is willing to - be a slave server for your domain, you are - actually asking for slave service for some collection of zones. - - - - - Authoritative Name Servers - - - Each zone is served by at least - one authoritative name server, - which contains the complete data for the zone. - To make the DNS tolerant of server and network failures, - most zones have two or more authoritative servers, on - different networks. - - - - Responses from authoritative servers have the "authoritative - answer" (AA) bit set in the response packets. This makes them - easy to identify when debugging DNS configurations using tools like - dig (). - - - - The Primary Master - - - The authoritative server where the master copy of the zone - data is maintained is called the - primary master server, or simply the - primary. Typically it loads the zone - contents from some local file edited by humans or perhaps - generated mechanically from some other local file which is - edited by humans. This file is called the - zone file or - master file. - - - - In some cases, however, the master file may not be edited - by humans at all, but may instead be the result of - dynamic update operations. - - - - - Slave Servers - - The other authoritative servers, the slave - servers (also known as secondary servers) - load - the zone contents from another server using a replication process - known as a zone transfer. Typically the data - are - transferred directly from the primary master, but it is also - possible - to transfer it from another slave. In other words, a slave server - may itself act as a master to a subordinate slave server. - - - - - Stealth Servers - - - Usually all of the zone's authoritative servers are listed in - NS records in the parent zone. These NS records constitute - a delegation of the zone from the parent. - The authoritative servers are also listed in the zone file itself, - at the top level or apex - of the zone. You can list servers in the zone's top-level NS - records that are not in the parent's NS delegation, but you cannot - list servers in the parent's delegation that are not present at - the zone's top level. - - - - A stealth server is a server that is - authoritative for a zone but is not listed in that zone's NS - records. Stealth servers can be used for keeping a local copy of - a - zone to speed up access to the zone's records or to make sure that - the - zone is available even if all the "official" servers for the zone - are - inaccessible. - - - - A configuration where the primary master server itself is a - stealth server is often referred to as a "hidden primary" - configuration. One use for this configuration is when the primary - master - is behind a firewall and therefore unable to communicate directly - with the outside world. - - - - - - - - Caching Name Servers - - - - - The resolver libraries provided by most operating systems are - stub resolvers, meaning that they are not - capable of - performing the full DNS resolution process by themselves by talking - directly to the authoritative servers. Instead, they rely on a - local - name server to perform the resolution on their behalf. Such a - server - is called a recursive name server; it performs - recursive lookups for local clients. - - - - To improve performance, recursive servers cache the results of - the lookups they perform. Since the processes of recursion and - caching are intimately connected, the terms - recursive server and - caching server are often used synonymously. - - - - The length of time for which a record may be retained in - the cache of a caching name server is controlled by the - Time To Live (TTL) field associated with each resource record. - - - - Forwarding - - - Even a caching name server does not necessarily perform - the complete recursive lookup itself. Instead, it can - forward some or all of the queries - that it cannot satisfy from its cache to another caching name - server, - commonly referred to as a forwarder. - - - - There may be one or more forwarders, - and they are queried in turn until the list is exhausted or an - answer - is found. Forwarders are typically used when you do not - wish all the servers at a given site to interact directly with the - rest of - the Internet servers. A typical scenario would involve a number - of internal DNS servers and an - Internet firewall. Servers unable - to pass packets through the firewall would forward to the server - that can do it, and that server would query the Internet DNS servers - on the internal server's behalf. - - - - - - - Name Servers in Multiple Roles - - - The BIND name server can - simultaneously act as - a master for some zones, a slave for other zones, and as a caching - (recursive) server for a set of local clients. - - - - However, since the functions of authoritative name service - and caching/recursive name service are logically separate, it is - often advantageous to run them on separate server machines. - - A server that only provides authoritative name service - (an authoritative-only server) can run with - recursion disabled, improving reliability and security. - - A server that is not authoritative for any zones and only provides - recursive service to local - clients (a caching-only server) - does not need to be reachable from the Internet at large and can - be placed inside a firewall. - - - - - - - - - <acronym>BIND</acronym> Resource Requirements - - - Hardware requirements - - - DNS hardware requirements have - traditionally been quite modest. - For many installations, servers that have been pensioned off from - active duty have performed admirably as DNS servers. - - - The DNSSEC features of BIND 9 - may prove to be quite - CPU intensive however, so organizations that make heavy use of these - features may wish to consider larger systems for these applications. - BIND 9 is fully multithreaded, allowing - full utilization of - multiprocessor systems for installations that need it. - - - - CPU Requirements - - CPU requirements for BIND 9 range from - i486-class machines - for serving of static zones without caching, to enterprise-class - machines if you intend to process many dynamic updates and DNSSEC - signed zones, serving many thousands of queries per second. - - - - - Memory Requirements - - The memory of the server has to be large enough to fit the - cache and zones loaded off disk. The max-cache-size - option can be used to limit the amount of memory used by the cache, - at the expense of reducing cache hit rates and causing more DNS - traffic. - Additionally, if additional section caching - () is enabled, - the max-acache-size option can be used to - limit the amount - of memory used by the mechanism. - It is still good practice to have enough memory to load - all zone and cache data into memory — unfortunately, the best - way - to determine this for a given installation is to watch the name server - in operation. After a few weeks the server process should reach - a relatively stable size where entries are expiring from the cache as - fast as they are being inserted. - - - - - - Name Server Intensive Environment Issues - - For name server intensive environments, there are two alternative - configurations that may be used. The first is where clients and - any second-level internal name servers query a main name server, which - has enough memory to build a large cache. This approach minimizes - the bandwidth used by external name lookups. The second alternative - is to set up second-level internal name servers to make queries - independently. - In this configuration, none of the individual machines needs to - have as much memory or CPU power as in the first alternative, but - this has the disadvantage of making many more external queries, - as none of the name servers share their cached data. - - - - - Supported Operating Systems - - ISC BIND 9 compiles and runs on a large - number - of Unix-like operating system and on NT-derived versions of - Microsoft Windows such as Windows 2000 and Windows XP. For an - up-to-date - list of supported systems, see the README file in the top level - directory - of the BIND 9 source distribution. - - - - - - Name Server Configuration - - In this section we provide some suggested configurations along - with guidelines for their use. We suggest reasonable values for - certain option settings. - - - - Sample Configurations - - A Caching-only Name Server - - The following sample configuration is appropriate for a caching-only - name server for use by clients internal to a corporation. All - queries - from outside clients are refused using the allow-query - option. Alternatively, the same effect could be achieved using - suitable - firewall rules. - - - -// Two corporate subnets we wish to allow queries from. -acl corpnets { 192.168.4.0/24; 192.168.7.0/24; }; -options { - directory "/etc/namedb"; // Working directory - allow-query { corpnets; }; -}; -// Provide a reverse mapping for the loopback address 127.0.0.1 -zone "0.0.127.in-addr.arpa" { - type master; - file "localhost.rev"; - notify no; -}; - - - - - - An Authoritative-only Name Server - - This sample configuration is for an authoritative-only server - that is the master server for "example.com" - and a slave for the subdomain "eng.example.com". - - - -options { - directory "/etc/namedb"; // Working directory - allow-query-cache { none; }; // Do not allow access to cache - allow-query { any; }; // This is the default - recursion no; // Do not provide recursive service -}; - -// Provide a reverse mapping for the loopback address 127.0.0.1 -zone "0.0.127.in-addr.arpa" { - type master; - file "localhost.rev"; - notify no; -}; -// We are the master server for example.com -zone "example.com" { - type master; - file "example.com.db"; - // IP addresses of slave servers allowed to transfer example.com - allow-transfer { - 192.168.4.14; - 192.168.5.53; - }; -}; -// We are a slave server for eng.example.com -zone "eng.example.com" { - type slave; - file "eng.example.com.bk"; - // IP address of eng.example.com master server - masters { 192.168.4.12; }; -}; - - - - - - - Load Balancing - - - - A primitive form of load balancing can be achieved in - the DNS by using multiple records - (such as multiple A records) for one name. - - - - For example, if you have three WWW servers with network addresses - of 10.0.0.1, 10.0.0.2 and 10.0.0.3, a set of records such as the - following means that clients will connect to each machine one third - of the time: - - - - - - - - - - - - - - Name - - - - - TTL - - - - - CLASS - - - - - TYPE - - - - - Resource Record (RR) Data - - - - - - - www - - - - - 600 - - - - - IN - - - - - A - - - - - 10.0.0.1 - - - - - - - - - - 600 - - - - - IN - - - - - A - - - - - 10.0.0.2 - - - - - - - - - - 600 - - - - - IN - - - - - A - - - - - 10.0.0.3 - - - - - - - - When a resolver queries for these records, BIND will rotate - them and respond to the query with the records in a different - order. In the example above, clients will randomly receive - records in the order 1, 2, 3; 2, 3, 1; and 3, 1, 2. Most clients - will use the first record returned and discard the rest. - - - For more detail on ordering responses, check the - rrset-order substatement in the - options statement, see - . - - - - - - Name Server Operations - - - Tools for Use With the Name Server Daemon - - This section describes several indispensable diagnostic, - administrative and monitoring tools available to the system - administrator for controlling and debugging the name server - daemon. - - - Diagnostic Tools - - The dig, host, and - nslookup programs are all command - line tools - for manually querying name servers. They differ in style and - output format. - - - - - dig - - - The domain information groper (dig) - is the most versatile and complete of these lookup tools. - It has two modes: simple interactive - mode for a single query, and batch mode which executes a - query for - each in a list of several query lines. All query options are - accessible - from the command line. - - - dig - @server - domain - query-type - query-class - +query-option - -dig-option - %comment - - - The usual simple use of dig will take the form - - - dig @server domain query-type query-class - - - For more information and a list of available commands and - options, see the dig man - page. - - - - - - host - - - The host utility emphasizes - simplicity - and ease of use. By default, it converts - between host names and Internet addresses, but its - functionality - can be extended with the use of options. - - - host - -aCdlnrsTwv - -c class - -N ndots - -t type - -W timeout - -R retries - -m flag - -4 - -6 - hostname - server - - - For more information and a list of available commands and - options, see the host man - page. - - - - - - nslookup - - nslookup - has two modes: interactive and - non-interactive. Interactive mode allows the user to - query name servers for information about various - hosts and domains or to print a list of hosts in a - domain. Non-interactive mode is used to print just - the name and requested information for a host or - domain. - - - nslookup - -option - - host-to-find - - server - - - - Interactive mode is entered when no arguments are given (the - default name server will be used) or when the first argument - is a - hyphen (`-') and the second argument is the host name or - Internet address - of a name server. - - - Non-interactive mode is used when the name or Internet - address - of the host to be looked up is given as the first argument. - The - optional second argument specifies the host name or address - of a name server. - - - Due to its arcane user interface and frequently inconsistent - behavior, we do not recommend the use of nslookup. - Use dig instead. - - - - - - - - - Administrative Tools - - Administrative tools play an integral part in the management - of a server. - - - - - named-checkconf - - - The named-checkconf program - checks the syntax of a named.conf file. - - - named-checkconf - -jvz - -t directory - filename - - - - - - named-checkzone - - - The named-checkzone program - checks a master file for - syntax and consistency. - - - named-checkzone - -djqvD - -c class - -o output - -t directory - -w directory - -k (ignore|warn|fail) - -n (ignore|warn|fail) - -W (ignore|warn) - zone - filename - - - - - named-compilezone - - - Similar to named-checkzone, but - it always dumps the zone content to a specified file - (typically in a different format). - - - - - - rndc - - - The remote name daemon control - (rndc) program allows the - system - administrator to control the operation of a name server. - Since BIND 9.2, rndc - supports all the commands of the BIND 8 ndc - utility except ndc start and - ndc restart, which were also - not supported in ndc's - channel mode. - If you run rndc without any - options - it will display a usage message as follows: - - - rndc - -c config - -s server - -p port - -y key - command - command - - The command - is one of the following: - - - - - - reload - - - Reload configuration file and zones. - - - - - - reload zone - class - view - - - Reload the given zone. - - - - - - refresh zone - class - view - - - Schedule zone maintenance for the given zone. - - - - - - retransfer zone - - class - view - - - Retransfer the given zone from the master. - - - - - - - freeze - zone - class - view - - - Suspend updates to a dynamic zone. If no zone is - specified, - then all zones are suspended. This allows manual - edits to be made to a zone normally updated by dynamic - update. It - also causes changes in the journal file to be synced - into the master - and the journal file to be removed. All dynamic - update attempts will - be refused while the zone is frozen. - - - - - - thaw - zone - class - view - - - Enable updates to a frozen dynamic zone. If no zone - is - specified, then all frozen zones are enabled. This - causes - the server to reload the zone from disk, and - re-enables dynamic updates - after the load has completed. After a zone is thawed, - dynamic updates - will no longer be refused. - - - - - - notify zone - class - view - - - Resend NOTIFY messages for the zone. - - - - - - reconfig - - - Reload the configuration file and load new zones, - but do not reload existing zone files even if they - have changed. - This is faster than a full reload when there - is a large number of zones because it avoids the need - to examine the - modification times of the zones files. - - - - - - stats - - - Write server statistics to the statistics file. - - - - - - querylog - - - Toggle query logging. Query logging can also be enabled - by explicitly directing the queries - category to a - channel in the - logging section of - named.conf or by specifying - querylog yes; in the - options section of - named.conf. - - - - - - dumpdb - -all|-cache|-zone - view ... - - - Dump the server's caches (default) and/or zones to - the - dump file for the specified views. If no view is - specified, all - views are dumped. - - - - - - stop -p - - - Stop the server, making sure any recent changes - made through dynamic update or IXFR are first saved to - the master files of the updated zones. - If -p is specified named's process id is returned. - This allows an external process to determine when named - had completed stopping. - - - - - - halt -p - - - Stop the server immediately. Recent changes - made through dynamic update or IXFR are not saved to - the master files, but will be rolled forward from the - journal files when the server is restarted. - If -p is specified named's process id is returned. - This allows an external process to determine when named - had completed halting. - - - - - - trace - - - Increment the servers debugging level by one. - - - - - - trace level - - - Sets the server's debugging level to an explicit - value. - - - - - - notrace - - - Sets the server's debugging level to 0. - - - - - - flush - - - Flushes the server's cache. - - - - - - flushname name - - - Flushes the given name from the server's cache. - - - - - - status - - - Display status of the server. - Note that the number of zones includes the internal bind/CH zone - and the default ./IN - hint zone if there is not an - explicit root zone configured. - - - - - - recursing - - - Dump the list of queries named is currently recursing - on. - - - - - - - - A configuration file is required, since all - communication with the server is authenticated with - digital signatures that rely on a shared secret, and - there is no way to provide that secret other than with a - configuration file. The default location for the - rndc configuration file is - /etc/rndc.conf, but an - alternate - location can be specified with the - option. If the configuration file is not found, - rndc will also look in - /etc/rndc.key (or whatever - sysconfdir was defined when - the BIND build was - configured). - The rndc.key file is - generated by - running rndc-confgen -a as - described in - . - - - - The format of the configuration file is similar to - that of named.conf, but - limited to - only four statements, the options, - key, server and - include - statements. These statements are what associate the - secret keys to the servers with which they are meant to - be shared. The order of statements is not - significant. - - - - The options statement has - three clauses: - default-server, default-key, - and default-port. - default-server takes a - host name or address argument and represents the server - that will - be contacted if no - option is provided on the command line. - default-key takes - the name of a key as its argument, as defined by a key statement. - default-port specifies the - port to which - rndc should connect if no - port is given on the command line or in a - server statement. - - - - The key statement defines a - key to be used - by rndc when authenticating - with - named. Its syntax is - identical to the - key statement in named.conf. - The keyword key is - followed by a key name, which must be a valid - domain name, though it need not actually be hierarchical; - thus, - a string like "rndc_key" is a valid - name. - The key statement has two - clauses: - algorithm and secret. - While the configuration parser will accept any string as the - argument - to algorithm, currently only the string "hmac-md5" - has any meaning. The secret is a base-64 encoded string - as specified in RFC 3548. - - - - The server statement - associates a key - defined using the key - statement with a server. - The keyword server is followed by a - host name or address. The server statement - has two clauses: key and port. - The key clause specifies the - name of the key - to be used when communicating with this server, and the - port clause can be used to - specify the port rndc should - connect - to on the server. - - - - A sample minimal configuration file is as follows: - - - -key rndc_key { - algorithm "hmac-md5"; - secret "c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K"; -}; -options { - default-server 127.0.0.1; - default-key rndc_key; -}; - - - - This file, if installed as /etc/rndc.conf, - would allow the command: - - - - $ rndc reload - - - - to connect to 127.0.0.1 port 953 and cause the name server - to reload, if a name server on the local machine were - running with - following controls statements: - - - -controls { - inet 127.0.0.1 allow { localhost; } keys { rndc_key; }; -}; - - - - and it had an identical key statement for - rndc_key. - - - - Running the rndc-confgen - program will - conveniently create a rndc.conf - file for you, and also display the - corresponding controls - statement that you need to - add to named.conf. - Alternatively, - you can run rndc-confgen -a - to set up - a rndc.key file and not - modify - named.conf at all. - - - - - - - - - - - Signals - - Certain UNIX signals cause the name server to take specific - actions, as described in the following table. These signals can - be sent using the kill command. - - - - - - - - - SIGHUP - - - - Causes the server to read named.conf and - reload the database. - - - - - - SIGTERM - - - - Causes the server to clean up and exit. - - - - - - SIGINT - - - - Causes the server to clean up and exit. - - - - - - - - - - - - Advanced DNS Features - - - - Notify - - DNS NOTIFY is a mechanism that allows master - servers to notify their slave servers of changes to a zone's data. In - response to a NOTIFY from a master server, the - slave will check to see that its version of the zone is the - current version and, if not, initiate a zone transfer. - - - - For more information about DNS - NOTIFY, see the description of the - notify option in and - the description of the zone option also-notify in - . The NOTIFY - protocol is specified in RFC 1996. - - - - As a slave zone can also be a master to other slaves, named, - by default, sends NOTIFY messages for every zone - it loads. Specifying notify master-only; will - cause named to only send NOTIFY for master - zones that it loads. - - - - - - Dynamic Update - - - Dynamic Update is a method for adding, replacing or deleting - records in a master server by sending it a special form of DNS - messages. The format and meaning of these messages is specified - in RFC 2136. - - - - Dynamic update is enabled by - including an allow-update or - update-policy clause in the - zone statement. - - - - Updating of secure zones (zones using DNSSEC) follows - RFC 3007: RRSIG and NSEC records affected by updates are automatically - regenerated by the server using an online zone key. - Update authorization is based - on transaction signatures and an explicit server policy. - - - - The journal file - - - All changes made to a zone using dynamic update are stored - in the zone's journal file. This file is automatically created - by the server when the first dynamic update takes place. - The name of the journal file is formed by appending the extension - .jnl to the name of the - corresponding zone - file unless specifically overridden. The journal file is in a - binary format and should not be edited manually. - - - - The server will also occasionally write ("dump") - the complete contents of the updated zone to its zone file. - This is not done immediately after - each dynamic update, because that would be too slow when a large - zone is updated frequently. Instead, the dump is delayed by - up to 15 minutes, allowing additional updates to take place. - - - - When a server is restarted after a shutdown or crash, it will replay - the journal file to incorporate into the zone any updates that - took - place after the last zone dump. - - - - Changes that result from incoming incremental zone transfers are - also - journalled in a similar way. - - - - The zone files of dynamic zones cannot normally be edited by - hand because they are not guaranteed to contain the most recent - dynamic changes — those are only in the journal file. - The only way to ensure that the zone file of a dynamic zone - is up to date is to run rndc stop. - - - - If you have to make changes to a dynamic zone - manually, the following procedure will work: Disable dynamic updates - to the zone using - rndc freeze zone. - This will also remove the zone's .jnl file - and update the master file. Edit the zone file. Run - rndc thaw zone - to reload the changed zone and re-enable dynamic updates. - - - - - - - - Incremental Zone Transfers (IXFR) - - - The incremental zone transfer (IXFR) protocol is a way for - slave servers to transfer only changed data, instead of having to - transfer the entire zone. The IXFR protocol is specified in RFC - 1995. See . - - - - When acting as a master, BIND 9 - supports IXFR for those zones - where the necessary change history information is available. These - include master zones maintained by dynamic update and slave zones - whose data was obtained by IXFR. For manually maintained master - zones, and for slave zones obtained by performing a full zone - transfer (AXFR), IXFR is supported only if the option - ixfr-from-differences is set - to yes. - - - - When acting as a slave, BIND 9 will - attempt to use IXFR unless - it is explicitly disabled. For more information about disabling - IXFR, see the description of the request-ixfr clause - of the server statement. - - - - - Split DNS - - Setting up different views, or visibility, of the DNS space to - internal and external resolvers is usually referred to as a - Split DNS setup. There are several - reasons an organization would want to set up its DNS this way. - - - One common reason for setting up a DNS system this way is - to hide "internal" DNS information from "external" clients on the - Internet. There is some debate as to whether or not this is actually - useful. - Internal DNS information leaks out in many ways (via email headers, - for example) and most savvy "attackers" can find the information - they need using other means. - However, since listing addresses of internal servers that - external clients cannot possibly reach can result in - connection delays and other annoyances, an organization may - choose to use a Split DNS to present a consistent view of itself - to the outside world. - - - Another common reason for setting up a Split DNS system is - to allow internal networks that are behind filters or in RFC 1918 - space (reserved IP space, as documented in RFC 1918) to resolve DNS - on the Internet. Split DNS can also be used to allow mail from outside - back in to the internal network. - - - Example split DNS setup - - Let's say a company named Example, Inc. - (example.com) - has several corporate sites that have an internal network with - reserved - Internet Protocol (IP) space and an external demilitarized zone (DMZ), - or "outside" section of a network, that is available to the public. - - - Example, Inc. wants its internal clients - to be able to resolve external hostnames and to exchange mail with - people on the outside. The company also wants its internal resolvers - to have access to certain internal-only zones that are not available - at all outside of the internal network. - - - In order to accomplish this, the company will set up two sets - of name servers. One set will be on the inside network (in the - reserved - IP space) and the other set will be on bastion hosts, which are - "proxy" - hosts that can talk to both sides of its network, in the DMZ. - - - The internal servers will be configured to forward all queries, - except queries for site1.internal, site2.internal, site1.example.com, - and site2.example.com, to the servers - in the - DMZ. These internal servers will have complete sets of information - for site1.example.com, site2.example.com, site1.internal, - and site2.internal. - - - To protect the site1.internal and site2.internal domains, - the internal name servers must be configured to disallow all queries - to these domains from any external hosts, including the bastion - hosts. - - - The external servers, which are on the bastion hosts, will - be configured to serve the "public" version of the site1 and site2.example.com zones. - This could include things such as the host records for public servers - (www.example.com and ftp.example.com), - and mail exchange (MX) records (a.mx.example.com and b.mx.example.com). - - - In addition, the public site1 and site2.example.com zones - should have special MX records that contain wildcard (`*') records - pointing to the bastion hosts. This is needed because external mail - servers do not have any other way of looking up how to deliver mail - to those internal hosts. With the wildcard records, the mail will - be delivered to the bastion host, which can then forward it on to - internal hosts. - - - Here's an example of a wildcard MX record: - - * IN MX 10 external1.example.com. - - Now that they accept mail on behalf of anything in the internal - network, the bastion hosts will need to know how to deliver mail - to internal hosts. In order for this to work properly, the resolvers - on - the bastion hosts will need to be configured to point to the internal - name servers for DNS resolution. - - - Queries for internal hostnames will be answered by the internal - servers, and queries for external hostnames will be forwarded back - out to the DNS servers on the bastion hosts. - - - In order for all this to work properly, internal clients will - need to be configured to query only the internal - name servers for DNS queries. This could also be enforced via - selective - filtering on the network. - - - If everything has been set properly, Example, Inc.'s - internal clients will now be able to: - - - - - Look up any hostnames in the site1 - and - site2.example.com zones. - - - - - Look up any hostnames in the site1.internal and - site2.internal domains. - - - - Look up any hostnames on the Internet. - - - Exchange mail with both internal and external people. - - - - Hosts on the Internet will be able to: - - - - - Look up any hostnames in the site1 - and - site2.example.com zones. - - - - - Exchange mail with anyone in the site1 and - site2.example.com zones. - - - - - - Here is an example configuration for the setup we just - described above. Note that this is only configuration information; - for information on how to configure your zone files, see . - - - - Internal DNS server config: - - - - -acl internals { 172.16.72.0/24; 192.168.1.0/24; }; - -acl externals { bastion-ips-go-here; }; - -options { - ... - ... - forward only; - forwarders { // forward to external servers - bastion-ips-go-here; - }; - allow-transfer { none; }; // sample allow-transfer (no one) - allow-query { internals; externals; }; // restrict query access - allow-recursion { internals; }; // restrict recursion - ... - ... -}; - -zone "site1.example.com" { // sample master zone - type master; - file "m/site1.example.com"; - forwarders { }; // do normal iterative - // resolution (do not forward) - allow-query { internals; externals; }; - allow-transfer { internals; }; -}; - -zone "site2.example.com" { // sample slave zone - type slave; - file "s/site2.example.com"; - masters { 172.16.72.3; }; - forwarders { }; - allow-query { internals; externals; }; - allow-transfer { internals; }; -}; - -zone "site1.internal" { - type master; - file "m/site1.internal"; - forwarders { }; - allow-query { internals; }; - allow-transfer { internals; } -}; - -zone "site2.internal" { - type slave; - file "s/site2.internal"; - masters { 172.16.72.3; }; - forwarders { }; - allow-query { internals }; - allow-transfer { internals; } -}; - - - - External (bastion host) DNS server config: - - - -acl internals { 172.16.72.0/24; 192.168.1.0/24; }; - -acl externals { bastion-ips-go-here; }; - -options { - ... - ... - allow-transfer { none; }; // sample allow-transfer (no one) - allow-query { any; }; // default query access - allow-query-cache { internals; externals; }; // restrict cache access - allow-recursion { internals; externals; }; // restrict recursion - ... - ... -}; - -zone "site1.example.com" { // sample slave zone - type master; - file "m/site1.foo.com"; - allow-transfer { internals; externals; }; -}; - -zone "site2.example.com" { - type slave; - file "s/site2.foo.com"; - masters { another_bastion_host_maybe; }; - allow-transfer { internals; externals; } -}; - - - - In the resolv.conf (or equivalent) on - the bastion host(s): - - - -search ... -nameserver 172.16.72.2 -nameserver 172.16.72.3 -nameserver 172.16.72.4 - - - - - - TSIG - - This is a short guide to setting up Transaction SIGnatures - (TSIG) based transaction security in BIND. It describes changes - to the configuration file as well as what changes are required for - different features, including the process of creating transaction - keys and using transaction signatures with BIND. - - - BIND primarily supports TSIG for server - to server communication. - This includes zone transfer, notify, and recursive query messages. - Resolvers based on newer versions of BIND 8 have limited support - for TSIG. - - - - TSIG can also be useful for dynamic update. A primary - server for a dynamic zone should control access to the dynamic - update service, but IP-based access control is insufficient. - The cryptographic access control provided by TSIG - is far superior. The nsupdate - program supports TSIG via the and - command line options or inline by use - of the key. - - - - Generate Shared Keys for Each Pair of Hosts - - A shared secret is generated to be shared between host1 and host2. - An arbitrary key name is chosen: "host1-host2.". The key name must - be the same on both hosts. - - - Automatic Generation - - The following command will generate a 128-bit (16 byte) HMAC-MD5 - key as described above. Longer keys are better, but shorter keys - are easier to read. Note that the maximum key length is 512 bits; - keys longer than that will be digested with MD5 to produce a - 128-bit key. - - - dnssec-keygen -a hmac-md5 -b 128 -n HOST host1-host2. - - - The key is in the file Khost1-host2.+157+00000.private. - Nothing directly uses this file, but the base-64 encoded string - following "Key:" - can be extracted from the file and used as a shared secret: - - Key: La/E5CjG9O+os1jq0a2jdA== - - The string "La/E5CjG9O+os1jq0a2jdA==" can - be used as the shared secret. - - - - Manual Generation - - The shared secret is simply a random sequence of bits, encoded - in base-64. Most ASCII strings are valid base-64 strings (assuming - the length is a multiple of 4 and only valid characters are used), - so the shared secret can be manually generated. - - - Also, a known string can be run through mmencode or - a similar program to generate base-64 encoded data. - - - - - Copying the Shared Secret to Both Machines - - This is beyond the scope of DNS. A secure transport mechanism - should be used. This could be secure FTP, ssh, telephone, etc. - - - - Informing the Servers of the Key's Existence - - Imagine host1 and host 2 - are - both servers. The following is added to each server's named.conf file: - - - -key host1-host2. { - algorithm hmac-md5; - secret "La/E5CjG9O+os1jq0a2jdA=="; -}; - - - - The algorithm, hmac-md5, is the only one supported by BIND. - The secret is the one generated above. Since this is a secret, it - is recommended that either named.conf be non-world - readable, or the key directive be added to a non-world readable - file that is included by - named.conf. - - - At this point, the key is recognized. This means that if the - server receives a message signed by this key, it can verify the - signature. If the signature is successfully verified, the - response is signed by the same key. - - - - - Instructing the Server to Use the Key - - Since keys are shared between two hosts only, the server must - be told when keys are to be used. The following is added to the named.conf file - for host1, if the IP address of host2 is - 10.1.2.3: - - - -server 10.1.2.3 { - keys { host1-host2. ;}; -}; - - - - Multiple keys may be present, but only the first is used. - This directive does not contain any secrets, so it may be in a - world-readable - file. - - - If host1 sends a message that is a request - to that address, the message will be signed with the specified key. host1 will - expect any responses to signed messages to be signed with the same - key. - - - A similar statement must be present in host2's - configuration file (with host1's address) for host2 to - sign request messages to host1. - - - - TSIG Key Based Access Control - - BIND allows IP addresses and ranges - to be specified in ACL - definitions and - allow-{ query | transfer | update } - directives. - This has been extended to allow TSIG keys also. The above key would - be denoted key host1-host2. - - - An example of an allow-update directive would be: - - - -allow-update { key host1-host2. ;}; - - - - This allows dynamic updates to succeed only if the request - was signed by a key named - "host1-host2.". - - - You may want to read about the more - powerful update-policy statement in . - - - - - Errors - - - The processing of TSIG signed messages can result in - several errors. If a signed message is sent to a non-TSIG aware - server, a FORMERR (format error) will be returned, since the server will not - understand the record. This is a result of misconfiguration, - since the server must be explicitly configured to send a TSIG - signed message to a specific server. - - - - If a TSIG aware server receives a message signed by an - unknown key, the response will be unsigned with the TSIG - extended error code set to BADKEY. If a TSIG aware server - receives a message with a signature that does not validate, the - response will be unsigned with the TSIG extended error code set - to BADSIG. If a TSIG aware server receives a message with a time - outside of the allowed range, the response will be signed with - the TSIG extended error code set to BADTIME, and the time values - will be adjusted so that the response can be successfully - verified. In any of these cases, the message's rcode (response code) is set to - NOTAUTH (not authenticated). - - - - - - TKEY - - TKEY - is a mechanism for automatically generating a shared secret - between two hosts. There are several "modes" of - TKEY that specify how the key is generated - or assigned. BIND 9 implements only one of - these modes, the Diffie-Hellman key exchange. Both hosts are - required to have a Diffie-Hellman KEY record (although this - record is not required to be present in a zone). The - TKEY process must use signed messages, - signed either by TSIG or SIG(0). The result of - TKEY is a shared secret that can be used to - sign messages with TSIG. TKEY can also be - used to delete shared secrets that it had previously - generated. - - - - The TKEY process is initiated by a - client - or server by sending a signed TKEY - query - (including any appropriate KEYs) to a TKEY-aware server. The - server response, if it indicates success, will contain a - TKEY record and any appropriate keys. - After - this exchange, both participants have enough information to - determine the shared secret; the exact process depends on the - TKEY mode. When using the - Diffie-Hellman - TKEY mode, Diffie-Hellman keys are - exchanged, - and the shared secret is derived by both participants. - - - - - SIG(0) - - - BIND 9 partially supports DNSSEC SIG(0) - transaction signatures as specified in RFC 2535 and RFC2931. - SIG(0) - uses public/private keys to authenticate messages. Access control - is performed in the same manner as TSIG keys; privileges can be - granted or denied based on the key name. - - - - When a SIG(0) signed message is received, it will only be - verified if the key is known and trusted by the server; the server - will not attempt to locate and/or validate the key. - - - - SIG(0) signing of multiple-message TCP streams is not - supported. - - - - The only tool shipped with BIND 9 that - generates SIG(0) signed messages is nsupdate. - - - - - DNSSEC - - - Cryptographic authentication of DNS information is possible - through the DNS Security (DNSSEC-bis) extensions, - defined in RFC 4033, RFC 4034, and RFC 4035. - This section describes the creation and use of DNSSEC signed zones. - - - - In order to set up a DNSSEC secure zone, there are a series - of steps which must be followed. BIND - 9 ships - with several tools - that are used in this process, which are explained in more detail - below. In all cases, the option prints a - full list of parameters. Note that the DNSSEC tools require the - keyset files to be in the working directory or the - directory specified by the option, and - that the tools shipped with BIND 9.2.x and earlier are not compatible - with the current ones. - - - - There must also be communication with the administrators of - the parent and/or child zone to transmit keys. A zone's security - status must be indicated by the parent zone for a DNSSEC capable - resolver to trust its data. This is done through the presence - or absence of a DS record at the - delegation - point. - - - - For other servers to trust data in this zone, they must - either be statically configured with this zone's zone key or the - zone key of another zone above this one in the DNS tree. - - - - Generating Keys - - - The dnssec-keygen program is used to - generate keys. - - - - A secure zone must contain one or more zone keys. The - zone keys will sign all other records in the zone, as well as - the zone keys of any secure delegated zones. Zone keys must - have the same name as the zone, a name type of - ZONE, and must be usable for - authentication. - It is recommended that zone keys use a cryptographic algorithm - designated as "mandatory to implement" by the IETF; currently - the only one is RSASHA1. - - - - The following command will generate a 768-bit RSASHA1 key for - the child.example zone: - - - - dnssec-keygen -a RSASHA1 -b 768 -n ZONE child.example. - - - - Two output files will be produced: - Kchild.example.+005+12345.key and - Kchild.example.+005+12345.private - (where - 12345 is an example of a key tag). The key filenames contain - the key name (child.example.), - algorithm (3 - is DSA, 1 is RSAMD5, 5 is RSASHA1, etc.), and the key tag (12345 in - this case). - The private key (in the .private - file) is - used to generate signatures, and the public key (in the - .key file) is used for signature - verification. - - - - To generate another key with the same properties (but with - a different key tag), repeat the above command. - - - - The public keys should be inserted into the zone file by - including the .key files using - $INCLUDE statements. - - - - - Signing the Zone - - - The dnssec-signzone program is used - to - sign a zone. - - - - Any keyset files corresponding - to secure subzones should be present. The zone signer will - generate NSEC and RRSIG - records for the zone, as well as DS - for - the child zones if '-d' is specified. - If '-d' is not specified, then - DS RRsets for - the secure child zones need to be added manually. - - - - The following command signs the zone, assuming it is in a - file called zone.child.example. By - default, all zone keys which have an available private key are - used to generate signatures. - - - - dnssec-signzone -o child.example zone.child.example - - - - One output file is produced: - zone.child.example.signed. This - file - should be referenced by named.conf - as the - input file for the zone. - - - dnssec-signzone - will also produce a keyset and dsset files and optionally a - dlvset file. These are used to provide the parent zone - administrators with the DNSKEYs (or their - corresponding DS records) that are the - secure entry point to the zone. - - - - - - Configuring Servers - - - To enable named to respond appropriately - to DNS requests from DNSSEC aware clients, - dnssec-enable must be set to yes. - - - - To enable named to validate answers from - other servers both dnssec-enable and - dnssec-validation must be set and some - trusted-keys must be configured - into named.conf. - - - - trusted-keys are copies of DNSKEY RRs - for zones that are used to form the first link in the - cryptographic chain of trust. All keys listed in - trusted-keys (and corresponding zones) - are deemed to exist and only the listed keys will be used - to validated the DNSKEY RRset that they are from. - - - - trusted-keys are described in more detail - later in this document. - - - - Unlike BIND 8, BIND - 9 does not verify signatures on load, so zone keys for - authoritative zones do not need to be specified in the - configuration file. - - - - After DNSSEC gets established, a typical DNSSEC configuration - will look something like the following. It has a one or - more public keys for the root. This allows answers from - outside the organization to be validated. It will also - have several keys for parts of the namespace the organization - controls. These are here to ensure that named is immune - to compromises in the DNSSEC components of the security - of parent zones. - - - -trusted-keys { - - /* Root Key */ -"." 257 3 3 "BNY4wrWM1nCfJ+CXd0rVXyYmobt7sEEfK3clRbGaTwSJxrGkxJWoZu6I7PzJu/ - E9gx4UC1zGAHlXKdE4zYIpRhaBKnvcC2U9mZhkdUpd1Vso/HAdjNe8LmMlnzY3 - zy2Xy4klWOADTPzSv9eamj8V18PHGjBLaVtYvk/ln5ZApjYghf+6fElrmLkdaz - MQ2OCnACR817DF4BBa7UR/beDHyp5iWTXWSi6XmoJLbG9Scqc7l70KDqlvXR3M - /lUUVRbkeg1IPJSidmK3ZyCllh4XSKbje/45SKucHgnwU5jefMtq66gKodQj+M - iA21AfUVe7u99WzTLzY3qlxDhxYQQ20FQ97S+LKUTpQcq27R7AT3/V5hRQxScI - Nqwcz4jYqZD2fQdgxbcDTClU0CRBdiieyLMNzXG3"; - -/* Key for our organization's forward zone */ -example.com. 257 3 5 "AwEAAaxPMcR2x0HbQV4WeZB6oEDX+r0QM65KbhTjrW1ZaARmPhEZZe - 3Y9ifgEuq7vZ/zGZUdEGNWy+JZzus0lUptwgjGwhUS1558Hb4JKUbb - OTcM8pwXlj0EiX3oDFVmjHO444gLkBO UKUf/mC7HvfwYH/Be22GnC - lrinKJp1Og4ywzO9WglMk7jbfW33gUKvirTHr25GL7STQUzBb5Usxt - 8lgnyTUHs1t3JwCY5hKZ6CqFxmAVZP20igTixin/1LcrgX/KMEGd/b - iuvF4qJCyduieHukuY3H4XMAcR+xia2 nIUPvm/oyWR8BW/hWdzOvn - SCThlHf3xiYleDbt/o1OTQ09A0="; - -/* Key for our reverse zone. */ -2.0.192.IN-ADDRPA.NET. 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwcxOdNax071L18QqZnQQQA - VVr+iLhGTnNGp3HoWQLUIzKrJVZ3zggy3WwNT6kZo6c0 - tszYqbtvchmgQC8CzKojM/W16i6MG/ea fGU3siaOdS0 - yOI6BgPsw+YZdzlYMaIJGf4M4dyoKIhzdZyQ2bYQrjyQ - 4LB0lC7aOnsMyYKHHYeRv PxjIQXmdqgOJGq+vsevG06 - zW+1xgYJh9rCIfnm1GX/KMgxLPG2vXTD/RnLX+D3T3UL - 7HJYHJhAZD5L59VvjSPsZJHeDCUyWYrvPZesZDIRvhDD - 52SKvbheeTJUm6EhkzytNN2SN96QRk8j/iI8ib"; -}; - -options { - ... - dnssec-enable yes; - dnssec-validation yes; -}; - - - - None of the keys listed in this example are valid. In particular, - the root key is not valid. - - - - - - - IPv6 Support in <acronym>BIND</acronym> 9 - - - BIND 9 fully supports all currently - defined forms of IPv6 - name to address and address to name lookups. It will also use - IPv6 addresses to make queries when running on an IPv6 capable - system. - - - - For forward lookups, BIND 9 supports - only AAAA records. RFC 3363 deprecated the use of A6 records, - and client-side support for A6 records was accordingly removed - from BIND 9. - However, authoritative BIND 9 name servers still - load zone files containing A6 records correctly, answer queries - for A6 records, and accept zone transfer for a zone containing A6 - records. - - - - For IPv6 reverse lookups, BIND 9 supports - the traditional "nibble" format used in the - ip6.arpa domain, as well as the older, deprecated - ip6.int domain. - Older versions of BIND 9 - supported the "binary label" (also known as "bitstring") format, - but support of binary labels has been completely removed per - RFC 3363. - Many applications in BIND 9 do not understand - the binary label format at all any more, and will return an - error if given. - In particular, an authoritative BIND 9 - name server will not load a zone file containing binary labels. - - - - For an overview of the format and structure of IPv6 addresses, - see . - - - - Address Lookups Using AAAA Records - - - The IPv6 AAAA record is a parallel to the IPv4 A record, - and, unlike the deprecated A6 record, specifies the entire - IPv6 address in a single record. For example, - - - -$ORIGIN example.com. -host 3600 IN AAAA 2001:db8::1 - - - - Use of IPv4-in-IPv6 mapped addresses is not recommended. - If a host has an IPv4 address, use an A record, not - a AAAA, with ::ffff:192.168.42.1 as - the address. - - - - Address to Name Lookups Using Nibble Format - - - When looking up an address in nibble format, the address - components are simply reversed, just as in IPv4, and - ip6.arpa. is appended to the - resulting name. - For example, the following would provide reverse name lookup for - a host with address - 2001:db8::1. - - - -$ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. -1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 14400 IN PTR host.example.com. - - - - - - - - The <acronym>BIND</acronym> 9 Lightweight Resolver - - The Lightweight Resolver Library - - Traditionally applications have been linked with a stub resolver - library that sends recursive DNS queries to a local caching name - server. - - - IPv6 once introduced new complexity into the resolution process, - such as following A6 chains and DNAME records, and simultaneous - lookup of IPv4 and IPv6 addresses. Though most of the complexity was - then removed, these are hard or impossible - to implement in a traditional stub resolver. - - - BIND 9 therefore can also provide resolution - services to local clients - using a combination of a lightweight resolver library and a resolver - daemon process running on the local host. These communicate using - a simple UDP-based protocol, the "lightweight resolver protocol" - that is distinct from and simpler than the full DNS protocol. - - - - Running a Resolver Daemon - - - To use the lightweight resolver interface, the system must - run the resolver daemon lwresd or a - local - name server configured with a lwres - statement. - - - - By default, applications using the lightweight resolver library will - make - UDP requests to the IPv4 loopback address (127.0.0.1) on port 921. - The - address can be overridden by lwserver - lines in - /etc/resolv.conf. - - - - The daemon currently only looks in the DNS, but in the future - it may use other sources such as /etc/hosts, - NIS, etc. - - - - The lwresd daemon is essentially a - caching-only name server that responds to requests using the - lightweight - resolver protocol rather than the DNS protocol. Because it needs - to run on each host, it is designed to require no or minimal - configuration. - Unless configured otherwise, it uses the name servers listed on - nameserver lines in /etc/resolv.conf - as forwarders, but is also capable of doing the resolution - autonomously if - none are specified. - - - The lwresd daemon may also be - configured with a - named.conf style configuration file, - in - /etc/lwresd.conf by default. A name - server may also - be configured to act as a lightweight resolver daemon using the - lwres statement in named.conf. - - - - - - - <acronym>BIND</acronym> 9 Configuration Reference - - - BIND 9 configuration is broadly similar - to BIND 8; however, there are a few new - areas - of configuration, such as views. BIND - 8 configuration files should work with few alterations in BIND - 9, although more complex configurations should be reviewed to check - if they can be more efficiently implemented using the new features - found in BIND 9. - - - - BIND 4 configuration files can be - converted to the new format - using the shell script - contrib/named-bootconf/named-bootconf.sh. - - - Configuration File Elements - - Following is a list of elements used throughout the BIND configuration - file documentation: - - - - - - - - - - acl_name - - - - - The name of an address_match_list as - defined by the acl statement. - - - - - - - address_match_list - - - - - A list of one or more - ip_addr, - ip_prefix, key_id, - or acl_name elements, see - . - - - - - - - masters_list - - - - - A named list of one or more ip_addr - with optional key_id and/or - ip_port. - A masters_list may include other - masters_lists. - - - - - - - domain_name - - - - - A quoted string which will be used as - a DNS name, for example "my.test.domain". - - - - - - - dotted_decimal - - - - - One to four integers valued 0 through - 255 separated by dots (`.'), such as 123, - 45.67 or 89.123.45.67. - - - - - - - ip4_addr - - - - - An IPv4 address with exactly four elements - in dotted_decimal notation. - - - - - - - ip6_addr - - - - - An IPv6 address, such as 2001:db8::1234. - IPv6 scoped addresses that have ambiguity on their scope - zones must be - disambiguated by an appropriate zone ID with the percent - character - (`%') as delimiter. - It is strongly recommended to use string zone names rather - than - numeric identifiers, in order to be robust against system - configuration changes. - However, since there is no standard mapping for such names - and - identifier values, currently only interface names as link - identifiers - are supported, assuming one-to-one mapping between - interfaces and links. - For example, a link-local address fe80::1 on the - link attached to the interface ne0 - can be specified as fe80::1%ne0. - Note that on most systems link-local addresses always have - the - ambiguity, and need to be disambiguated. - - - - - - - ip_addr - - - - - An ip4_addr or ip6_addr. - - - - - - - ip_port - - - - - An IP port number. - The number is limited to 0 - through 65535, with values - below 1024 typically restricted to use by processes running - as root. - In some cases, an asterisk (`*') character can be used as a - placeholder to - select a random high-numbered port. - - - - - - - ip_prefix - - - - - An IP network specified as an ip_addr, - followed by a slash (`/') and then the number of bits in the - netmask. - Trailing zeros in a ip_addr - may omitted. - For example, 127/8 is the - network 127.0.0.0 with - netmask 255.0.0.0 and 1.2.3.0/28 is - network 1.2.3.0 with netmask 255.255.255.240. - - - - - - - key_id - - - - - A domain_name representing - the name of a shared key, to be used for transaction - security. - - - - - - - key_list - - - - - A list of one or more - key_ids, - separated by semicolons and ending with a semicolon. - - - - - - - number - - - - - A non-negative 32-bit integer - (i.e., a number between 0 and 4294967295, inclusive). - Its acceptable value might further - be limited by the context in which it is used. - - - - - - - path_name - - - - - A quoted string which will be used as - a pathname, such as zones/master/my.test.domain. - - - - - - - size_spec - - - - - A number, the word unlimited, - or the word default. - - - An unlimited size_spec requests unlimited - use, or the maximum available amount. A default size_spec uses - the limit that was in force when the server was started. - - - A number can optionally be - followed by a scaling factor: - K or k - for kilobytes, - M or m - for megabytes, and - G or g for gigabytes, - which scale by 1024, 1024*1024, and 1024*1024*1024 - respectively. - - - The value must be representable as a 64-bit unsigned integer - (0 to 18446744073709551615, inclusive). - Using unlimited is the best - way - to safely set a really large number. - - - - - - - yes_or_no - - - - - Either yes or no. - The words true and false are - also accepted, as are the numbers 1 - and 0. - - - - - - - dialup_option - - - - - One of yes, - no, notify, - notify-passive, refresh or - passive. - When used in a zone, notify-passive, - refresh, and passive - are restricted to slave and stub zones. - - - - - - - - Address Match Lists - - Syntax - -address_match_list = address_match_list_element ; - address_match_list_element; ... -address_match_list_element = ! (ip_address /length | - key key_id | acl_name | { address_match_list } ) - - - - - Definition and Usage - - Address match lists are primarily used to determine access - control for various server operations. They are also used in - the listen-on and sortlist - statements. The elements - which constitute an address match list can be any of the - following: - - - - an IP address (IPv4 or IPv6) - - - an IP prefix (in `/' notation) - - - - a key ID, as defined by the key - statement - - - - the name of an address match list defined with - the acl statement - - - - a nested address match list enclosed in braces - - - - - Elements can be negated with a leading exclamation mark (`!'), - and the match list names "any", "none", "localhost", and - "localnets" - are predefined. More information on those names can be found in - the description of the acl statement. - - - - The addition of the key clause made the name of this syntactic - element something of a misnomer, since security keys can be used - to validate access without regard to a host or network address. - Nonetheless, - the term "address match list" is still used throughout the - documentation. - - - - When a given IP address or prefix is compared to an address - match list, the list is traversed in order until an element - matches. - The interpretation of a match depends on whether the list is being - used - for access control, defining listen-on ports, or in a sortlist, - and whether the element was negated. - - - - When used as an access control list, a non-negated match - allows access and a negated match denies access. If - there is no match, access is denied. The clauses - allow-notify, - allow-query, - allow-query-cache, - allow-transfer, - allow-update, - allow-update-forwarding, and - blackhole all use address match - lists. Similarly, the listen-on option will cause the - server to not accept queries on any of the machine's - addresses which do not match the list. - - - - Because of the first-match aspect of the algorithm, an element - that defines a subset of another element in the list should come - before the broader element, regardless of whether either is - negated. For - example, in - 1.2.3/24; ! 1.2.3.13; the 1.2.3.13 - element is - completely useless because the algorithm will match any lookup for - 1.2.3.13 to the 1.2.3/24 element. - Using ! 1.2.3.13; 1.2.3/24 fixes - that problem by having 1.2.3.13 blocked by the negation but all - other 1.2.3.* hosts fall through. - - - - - - Comment Syntax - - - The BIND 9 comment syntax allows for - comments to appear - anywhere that whitespace may appear in a BIND configuration - file. To appeal to programmers of all kinds, they can be written - in the C, C++, or shell/perl style. - - - - Syntax - - - /* This is a BIND comment as in C */ - // This is a BIND comment as in C++ - # This is a BIND comment as in common UNIX shells and perl - - - - Definition and Usage - - Comments may appear anywhere that whitespace may appear in - a BIND configuration file. - - - C-style comments start with the two characters /* (slash, - star) and end with */ (star, slash). Because they are completely - delimited with these characters, they can be used to comment only - a portion of a line or to span multiple lines. - - - C-style comments cannot be nested. For example, the following - is not valid because the entire comment ends with the first */: - - - -/* This is the start of a comment. - This is still part of the comment. -/* This is an incorrect attempt at nesting a comment. */ - This is no longer in any comment. */ - - - - - - C++-style comments start with the two characters // (slash, - slash) and continue to the end of the physical line. They cannot - be continued across multiple physical lines; to have one logical - comment span multiple lines, each line must use the // pair. - - - For example: - - - -// This is the start of a comment. The next line -// is a new comment, even though it is logically -// part of the previous comment. - - - - - Shell-style (or perl-style, if you prefer) comments start - with the character # (number sign) - and continue to the end of the - physical line, as in C++ comments. - - - For example: - - - - -# This is the start of a comment. The next line -# is a new comment, even though it is logically -# part of the previous comment. - - - - - - - You cannot use the semicolon (`;') character - to start a comment such as you would in a zone file. The - semicolon indicates the end of a configuration - statement. - - - - - - - - Configuration File Grammar - - - A BIND 9 configuration consists of - statements and comments. - Statements end with a semicolon. Statements and comments are the - only elements that can appear without enclosing braces. Many - statements contain a block of sub-statements, which are also - terminated with a semicolon. - - - - The following statements are supported: - - - - - - - - - - acl - - - - defines a named IP address - matching list, for access control and other uses. - - - - - - controls - - - - declares control channels to be used - by the rndc utility. - - - - - - include - - - - includes a file. - - - - - - key - - - - specifies key information for use in - authentication and authorization using TSIG. - - - - - - logging - - - - specifies what the server logs, and where - the log messages are sent. - - - - - - lwres - - - - configures named to - also act as a light-weight resolver daemon (lwresd). - - - - - - masters - - - - defines a named masters list for - inclusion in stub and slave zone masters clauses. - - - - - - options - - - - controls global server configuration - options and sets defaults for other statements. - - - - - - server - - - - sets certain configuration options on - a per-server basis. - - - - - - trusted-keys - - - - defines trusted DNSSEC keys. - - - - - - view - - - - defines a view. - - - - - - zone - - - - defines a zone. - - - - - - - - - The logging and - options statements may only occur once - per - configuration. - - - - <command>acl</command> Statement Grammar - -acl acl-name { - address_match_list -}; - - - - - <command>acl</command> Statement Definition and - Usage - - - The acl statement assigns a symbolic - name to an address match list. It gets its name from a primary - use of address match lists: Access Control Lists (ACLs). - - - - Note that an address match list's name must be defined - with acl before it can be used - elsewhere; no - forward references are allowed. - - - - The following ACLs are built-in: - - - - - - - - - - any - - - - Matches all hosts. - - - - - - none - - - - Matches no hosts. - - - - - - localhost - - - - Matches the IPv4 and IPv6 addresses of all network - interfaces on the system. - - - - - - localnets - - - - Matches any host on an IPv4 or IPv6 network - for which the system has an interface. - Some systems do not provide a way to determine the prefix - lengths of - local IPv6 addresses. - In such a case, localnets - only matches the local - IPv6 addresses, just like localhost. - - - - - - - - - - <command>controls</command> Statement Grammar - -controls { - [ inet ( ip_addr | * ) [ port ip_port ] allow { address_match_list } - keys { key_list }; ] - [ inet ...; ] - [ unix path perm number owner number group number keys { key_list }; ] - [ unix ...; ] -}; - - - - - - <command>controls</command> Statement Definition and - Usage - - - The controls statement declares control - channels to be used by system administrators to control the - operation of the name server. These control channels are - used by the rndc utility to send - commands to and retrieve non-DNS results from a name server. - - - - An inet control channel is a TCP socket - listening at the specified ip_port on the - specified ip_addr, which can be an IPv4 or IPv6 - address. An ip_addr of * (asterisk) is - interpreted as the IPv4 wildcard address; connections will be - accepted on any of the system's IPv4 addresses. - To listen on the IPv6 wildcard address, - use an ip_addr of ::. - If you will only use rndc on the local host, - using the loopback address (127.0.0.1 - or ::1) is recommended for maximum security. - - - - If no port is specified, port 953 is used. The asterisk - "*" cannot be used for ip_port. - - - - The ability to issue commands over the control channel is - restricted by the allow and - keys clauses. - Connections to the control channel are permitted based on the - address_match_list. This is for simple - IP address based filtering only; any key_id - elements of the address_match_list - are ignored. - - - - A unix control channel is a UNIX domain - socket listening at the specified path in the file system. - Access to the socket is specified by the perm, - owner and group clauses. - Note on some platforms (SunOS and Solaris) the permissions - (perm) are applied to the parent directory - as the permissions on the socket itself are ignored. - - - - The primary authorization mechanism of the command - channel is the key_list, which - contains a list of key_ids. - Each key_id in the key_list - is authorized to execute commands over the control channel. - See in ) - for information about configuring keys in rndc. - - - - If no controls statement is present, - named will set up a default - control channel listening on the loopback address 127.0.0.1 - and its IPv6 counterpart ::1. - In this case, and also when the controls statement - is present but does not have a keys clause, - named will attempt to load the command channel key - from the file rndc.key in - /etc (or whatever sysconfdir - was specified as when BIND was built). - To create a rndc.key file, run - rndc-confgen -a. - - - - The rndc.key feature was created to - ease the transition of systems from BIND 8, - which did not have digital signatures on its command channel - messages and thus did not have a keys clause. - - It makes it possible to use an existing BIND 8 - configuration file in BIND 9 unchanged, - and still have rndc work the same way - ndc worked in BIND 8, simply by executing the - command rndc-confgen -a after BIND 9 is - installed. - - - - Since the rndc.key feature - is only intended to allow the backward-compatible usage of - BIND 8 configuration files, this - feature does not - have a high degree of configurability. You cannot easily change - the key name or the size of the secret, so you should make a - rndc.conf with your own key if you - wish to change - those things. The rndc.key file - also has its - permissions set such that only the owner of the file (the user that - named is running as) can access it. - If you - desire greater flexibility in allowing other users to access - rndc commands, then you need to create - a - rndc.conf file and make it group - readable by a group - that contains the users who should have access. - - - - To disable the command channel, use an empty - controls statement: - controls { };. - - - - - <command>include</command> Statement Grammar - include filename; - - - <command>include</command> Statement Definition and - Usage - - - The include statement inserts the - specified file at the point where the include - statement is encountered. The include - statement facilitates the administration of configuration - files - by permitting the reading or writing of some things but not - others. For example, the statement could include private keys - that are readable only by the name server. - - - - - <command>key</command> Statement Grammar - -key key_id { - algorithm string; - secret string; -}; - - - - - - <command>key</command> Statement Definition and Usage - - - The key statement defines a shared - secret key for use with TSIG (see ) - or the command channel - (see ). - - - - The key statement can occur at the - top level - of the configuration file or inside a view - statement. Keys defined in top-level key - statements can be used in all views. Keys intended for use in - a controls statement - (see ) - must be defined at the top level. - - - - The key_id, also known as the - key name, is a domain name uniquely identifying the key. It can - be used in a server - statement to cause requests sent to that - server to be signed with this key, or in address match lists to - verify that incoming requests have been signed with a key - matching this name, algorithm, and secret. - - - - The algorithm_id is a string - that specifies a security/authentication algorithm. Named - supports hmac-md5, - hmac-sha1, hmac-sha224, - hmac-sha256, hmac-sha384 - and hmac-sha512 TSIG authentication. - Truncated hashes are supported by appending the minimum - number of required bits preceded by a dash, e.g. - hmac-sha1-80. The - secret_string is the secret - to be used by the algorithm, and is treated as a base-64 - encoded string. - - - - - <command>logging</command> Statement Grammar - -logging { - [ channel channel_name { - ( file path name - [ versions ( number | unlimited ) ] - [ size size spec ] - | syslog syslog_facility - | stderr - | null ); - [ severity ( | | | | - | [ level ] | ); ] - [ print-category or ; ] - [ print-severity or ; ] - [ print-time or ; ] - }; ] - [ category category_name { - channel_name ; [ channel_name ; ... ] - }; ] - ... -}; - - - - - - <command>logging</command> Statement Definition and - Usage - - - The logging statement configures a - wide - variety of logging options for the name server. Its channel phrase - associates output methods, format options and severity levels with - a name that can then be used with the category phrase - to select how various classes of messages are logged. - - - Only one logging statement is used to - define - as many channels and categories as are wanted. If there is no logging statement, - the logging configuration will be: - - -logging { - category default { default_syslog; default_debug; }; - category unmatched { null; }; -}; - - - - In BIND 9, the logging configuration - is only established when - the entire configuration file has been parsed. In BIND 8, it was - established as soon as the logging - statement - was parsed. When the server is starting up, all logging messages - regarding syntax errors in the configuration file go to the default - channels, or to standard error if the "" option - was specified. - - - - The <command>channel</command> Phrase - - - All log output goes to one or more channels; - you can make as many of them as you want. - - - - Every channel definition must include a destination clause that - says whether messages selected for the channel go to a file, to a - particular syslog facility, to the standard error stream, or are - discarded. It can optionally also limit the message severity level - that will be accepted by the channel (the default is - info), and whether to include a - named-generated time stamp, the - category name - and/or severity level (the default is not to include any). - - - - The null destination clause - causes all messages sent to the channel to be discarded; - in that case, other options for the channel are meaningless. - - - - The file destination clause directs - the channel - to a disk file. It can include limitations - both on how large the file is allowed to become, and how many - versions - of the file will be saved each time the file is opened. - - - - If you use the versions log file - option, then - named will retain that many backup - versions of the file by - renaming them when opening. For example, if you choose to keep - three old versions - of the file lamers.log, then just - before it is opened - lamers.log.1 is renamed to - lamers.log.2, lamers.log.0 is renamed - to lamers.log.1, and lamers.log is - renamed to lamers.log.0. - You can say versions unlimited to - not limit - the number of versions. - If a size option is associated with - the log file, - then renaming is only done when the file being opened exceeds the - indicated size. No backup versions are kept by default; any - existing - log file is simply appended. - - - - The size option for files is used - to limit log - growth. If the file ever exceeds the size, then named will - stop writing to the file unless it has a versions option - associated with it. If backup versions are kept, the files are - rolled as - described above and a new one begun. If there is no - versions option, no more data will - be written to the log - until some out-of-band mechanism removes or truncates the log to - less than the - maximum size. The default behavior is not to limit the size of - the - file. - - - - Example usage of the size and - versions options: - - -channel an_example_channel { - file "example.log" versions 3 size 20m; - print-time yes; - print-category yes; -}; - - - - The syslog destination clause - directs the - channel to the system log. Its argument is a - syslog facility as described in the syslog man - page. Known facilities are kern, user, - mail, daemon, auth, - syslog, lpr, news, - uucp, cron, authpriv, - ftp, local0, local1, - local2, local3, local4, - local5, local6 and - local7, however not all facilities - are supported on - all operating systems. - How syslog will handle messages - sent to - this facility is described in the syslog.conf man - page. If you have a system which uses a very old version of syslog that - only uses two arguments to the openlog() function, - then this clause is silently ignored. - - - The severity clause works like syslog's - "priorities", except that they can also be used if you are writing - straight to a file rather than using syslog. - Messages which are not at least of the severity level given will - not be selected for the channel; messages of higher severity - levels - will be accepted. - - - If you are using syslog, then the syslog.conf priorities - will also determine what eventually passes through. For example, - defining a channel facility and severity as daemon and debug but - only logging daemon.warning via syslog.conf will - cause messages of severity info and - notice to - be dropped. If the situation were reversed, with named writing - messages of only warning or higher, - then syslogd would - print all messages it received from the channel. - - - - The stderr destination clause - directs the - channel to the server's standard error stream. This is intended - for - use when the server is running as a foreground process, for - example - when debugging a configuration. - - - - The server can supply extensive debugging information when - it is in debugging mode. If the server's global debug level is - greater - than zero, then debugging mode will be active. The global debug - level is set either by starting the named server - with the flag followed by a positive integer, - or by running rndc trace. - The global debug level - can be set to zero, and debugging mode turned off, by running rndc -notrace. All debugging messages in the server have a debug - level, and higher debug levels give more detailed output. Channels - that specify a specific debug severity, for example: - - -channel specific_debug_level { - file "foo"; - severity debug 3; -}; - - - - will get debugging output of level 3 or less any time the - server is in debugging mode, regardless of the global debugging - level. Channels with dynamic - severity use the - server's global debug level to determine what messages to print. - - - If print-time has been turned on, - then - the date and time will be logged. print-time may - be specified for a syslog channel, - but is usually - pointless since syslog also prints - the date and - time. If print-category is - requested, then the - category of the message will be logged as well. Finally, if print-severity is - on, then the severity level of the message will be logged. The print- options may - be used in any combination, and will always be printed in the - following - order: time, category, severity. Here is an example where all - three print- options - are on: - - - - 28-Feb-2000 15:05:32.863 general: notice: running - - - - There are four predefined channels that are used for - named's default logging as follows. - How they are - used is described in . - - -channel default_syslog { - syslog daemon; // send to syslog's daemon - // facility - severity info; // only send priority info - // and higher -}; - -channel default_debug { - file "named.run"; // write to named.run in - // the working directory - // Note: stderr is used instead - // of "named.run" - // if the server is started - // with the '-f' option. - severity dynamic; // log at the server's - // current debug level -}; - -channel default_stderr { - stderr; // writes to stderr - severity info; // only send priority info - // and higher -}; - -channel null { - null; // toss anything sent to - // this channel -}; - - - - The default_debug channel has the - special - property that it only produces output when the server's debug - level is - nonzero. It normally writes to a file called named.run - in the server's working directory. - - - - For security reasons, when the "" - command line option is used, the named.run file - is created only after named has - changed to the - new UID, and any debug output generated while named is - starting up and still running as root is discarded. If you need - to capture this output, you must run the server with the "" - option and redirect standard error to a file. - - - - Once a channel is defined, it cannot be redefined. Thus you - cannot alter the built-in channels directly, but you can modify - the default logging by pointing categories at channels you have - defined. - - - - - The <command>category</command> Phrase - - - There are many categories, so you can send the logs you want - to see wherever you want, without seeing logs you don't want. If - you don't specify a list of channels for a category, then log - messages - in that category will be sent to the default category - instead. If you don't specify a default category, the following - "default default" is used: - - -category default { default_syslog; default_debug; }; - - - - As an example, let's say you want to log security events to - a file, but you also want keep the default logging behavior. You'd - specify the following: - - -channel my_security_channel { - file "my_security_file"; - severity info; -}; -category security { - my_security_channel; - default_syslog; - default_debug; -}; - - - To discard all messages in a category, specify the null channel: - - -category xfer-out { null; }; -category notify { null; }; - - - - Following are the available categories and brief descriptions - of the types of log information they contain. More - categories may be added in future BIND releases. - - - - - - - - - default - - - - The default category defines the logging - options for those categories where no specific - configuration has been - defined. - - - - - - general - - - - The catch-all. Many things still aren't - classified into categories, and they all end up here. - - - - - - database - - - - Messages relating to the databases used - internally by the name server to store zone and cache - data. - - - - - - security - - - - Approval and denial of requests. - - - - - - config - - - - Configuration file parsing and processing. - - - - - - resolver - - - - DNS resolution, such as the recursive - lookups performed on behalf of clients by a caching name - server. - - - - - - xfer-in - - - - Zone transfers the server is receiving. - - - - - - xfer-out - - - - Zone transfers the server is sending. - - - - - - notify - - - - The NOTIFY protocol. - - - - - - client - - - - Processing of client requests. - - - - - - unmatched - - - - Messages that named was unable to determine the - class of or for which there was no matching view. - A one line summary is also logged to the client category. - This category is best sent to a file or stderr, by - default it is sent to - the null channel. - - - - - - network - - - - Network operations. - - - - - - update - - - - Dynamic updates. - - - - - - update-security - - - - Approval and denial of update requests. - - - - - - queries - - - - Specify where queries should be logged to. - - - At startup, specifying the category queries will also - enable query logging unless querylog option has been - specified. - - - The query log entry reports the client's IP address and - port number, and the - query name, class and type. It also reports whether the - Recursion Desired - flag was set (+ if set, - if not set), EDNS was in use - (E) or if the - query was signed (S). - - - client 127.0.0.1#62536: query: www.example.com IN AAAA +SE - - - client ::1#62537: query: www.example.net IN AAAA -SE - - - - - - dispatch - - - - Dispatching of incoming packets to the - server modules where they are to be processed. - - - - - - dnssec - - - - DNSSEC and TSIG protocol processing. - - - - - - lame-servers - - - - Lame servers. These are misconfigurations - in remote servers, discovered by BIND 9 when trying to - query - those servers during resolution. - - - - - - delegation-only - - - - Delegation only. Logs queries that have have - been forced to NXDOMAIN as the result of a - delegation-only zone or - a delegation-only in a - hint or stub zone declaration. - - - - - - - - - - - <command>lwres</command> Statement Grammar - - - This is the grammar of the lwres - statement in the named.conf file: - - -lwres { - listen-on { ip_addr port ip_port ; ip_addr port ip_port ; ... }; - view view_name; - search { domain_name ; domain_name ; ... }; - ndots number; -}; - - - - - <command>lwres</command> Statement Definition and Usage - - - The lwres statement configures the - name - server to also act as a lightweight resolver server. (See - .) There may be multiple - lwres statements configuring - lightweight resolver servers with different properties. - - - - The listen-on statement specifies a - list of - addresses (and ports) that this instance of a lightweight resolver - daemon - should accept requests on. If no port is specified, port 921 is - used. - If this statement is omitted, requests will be accepted on - 127.0.0.1, - port 921. - - - - The view statement binds this - instance of a - lightweight resolver daemon to a view in the DNS namespace, so that - the - response will be constructed in the same manner as a normal DNS - query - matching this view. If this statement is omitted, the default view - is - used, and if there is no default view, an error is triggered. - - - - The search statement is equivalent to - the - search statement in - /etc/resolv.conf. It provides a - list of domains - which are appended to relative names in queries. - - - - The ndots statement is equivalent to - the - ndots statement in - /etc/resolv.conf. It indicates the - minimum - number of dots in a relative domain name that should result in an - exact match lookup before search path elements are appended. - - - - <command>masters</command> Statement Grammar - - -masters name port ip_port { ( masters_list | ip_addr port ip_port key key ) ; ... }; - - - - - - <command>masters</command> Statement Definition and - Usage - masters - lists allow for a common set of masters to be easily used by - multiple stub and slave zones. - - - - - <command>options</command> Statement Grammar - - - This is the grammar of the options - statement in the named.conf file: - - -options { - version version_string; - hostname hostname_string; - server-id server_id_string; - directory path_name; - key-directory path_name; - named-xfer path_name; - tkey-domain domainname; - tkey-dhkey key_name key_tag; - cache-file path_name; - dump-file path_name; - memstatistics-file path_name; - pid-file path_name; - recursing-file path_name; - statistics-file path_name; - zone-statistics yes_or_no; - auth-nxdomain yes_or_no; - deallocate-on-exit yes_or_no; - dialup dialup_option; - fake-iquery yes_or_no; - fetch-glue yes_or_no; - flush-zones-on-shutdown yes_or_no; - has-old-clients yes_or_no; - host-statistics yes_or_no; - host-statistics-max number; - minimal-responses yes_or_no; - multiple-cnames yes_or_no; - notify yes_or_no | explicit | master-only; - recursion yes_or_no; - rfc2308-type1 yes_or_no; - use-id-pool yes_or_no; - maintain-ixfr-base yes_or_no; - dnssec-enable yes_or_no; - dnssec-validation yes_or_no; - dnssec-lookaside domain trust-anchor domain; - dnssec-must-be-secure domain yes_or_no; - dnssec-accept-expired yes_or_no; - forward ( only | first ); - forwarders { ip_addr port ip_port ; ... }; - dual-stack-servers port ip_port { - ( domain_name port ip_port | - ip_addr port ip_port ) ; - ... }; - check-names ( master | slave | response ) - ( warn | fail | ignore ); - check-mx ( warn | fail | ignore ); - check-wildcard yes_or_no; - check-integrity yes_or_no; - check-mx-cname ( warn | fail | ignore ); - check-srv-cname ( warn | fail | ignore ); - check-sibling yes_or_no; - allow-notify { address_match_list }; - allow-query { address_match_list }; - allow-query-cache { address_match_list }; - allow-transfer { address_match_list }; - allow-recursion { address_match_list }; - allow-update { address_match_list }; - allow-update-forwarding { address_match_list }; - update-check-ksk yes_or_no; - allow-v6-synthesis { address_match_list }; - blackhole { address_match_list }; - avoid-v4-udp-ports { port_list }; - avoid-v6-udp-ports { port_list }; - listen-on port ip_port { address_match_list }; - listen-on-v6 port ip_port { address_match_list }; - query-source ( ( ip4_addr | * ) - port ( ip_port | * ) | - address ( ip4_addr | * ) - port ( ip_port | * ) ) ; - query-source-v6 ( ( ip6_addr | * ) - port ( ip_port | * ) | - address ( ip6_addr | * ) - port ( ip_port | * ) ) ; - max-transfer-time-in number; - max-transfer-time-out number; - max-transfer-idle-in number; - max-transfer-idle-out number; - tcp-clients number; - recursive-clients number; - serial-query-rate number; - serial-queries number; - tcp-listen-queue number; - transfer-format ( one-answer | many-answers ); - transfers-in number; - transfers-out number; - transfers-per-ns number; - transfer-source (ip4_addr | *) port ip_port ; - transfer-source-v6 (ip6_addr | *) port ip_port ; - alt-transfer-source (ip4_addr | *) port ip_port ; - alt-transfer-source-v6 (ip6_addr | *) port ip_port ; - use-alt-transfer-source yes_or_no; - notify-delay seconds ; - notify-source (ip4_addr | *) port ip_port ; - notify-source-v6 (ip6_addr | *) port ip_port ; - also-notify { ip_addr port ip_port ; ip_addr port ip_port ; ... }; - max-ixfr-log-size number; - max-journal-size size_spec; - coresize size_spec ; - datasize size_spec ; - files size_spec ; - stacksize size_spec ; - cleaning-interval number; - heartbeat-interval number; - interface-interval number; - statistics-interval number; - topology { address_match_list }; - sortlist { address_match_list }; - rrset-order { order_spec ; order_spec ; ... }; - lame-ttl number; - max-ncache-ttl number; - max-cache-ttl number; - sig-validity-interval number ; - min-roots number; - use-ixfr yes_or_no ; - provide-ixfr yes_or_no; - request-ixfr yes_or_no; - treat-cr-as-space yes_or_no ; - min-refresh-time number ; - max-refresh-time number ; - min-retry-time number ; - max-retry-time number ; - port ip_port; - additional-from-auth yes_or_no ; - additional-from-cache yes_or_no ; - random-device path_name ; - max-cache-size size_spec ; - match-mapped-addresses yes_or_no; - preferred-glue ( A | AAAA | NONE ); - edns-udp-size number; - max-udp-size number; - root-delegation-only exclude { namelist } ; - querylog yes_or_no ; - disable-algorithms domain { algorithm; algorithm; }; - acache-enable yes_or_no ; - acache-cleaning-interval number; - max-acache-size size_spec ; - clients-per-query number ; - max-clients-per-query number ; - masterfile-format (text|raw) ; - empty-server name ; - empty-contact name ; - empty-zones-enable yes_or_no ; - disable-empty-zone zone_name ; - zero-no-soa-ttl yes_or_no ; - zero-no-soa-ttl-cache yes_or_no ; -}; - - - - - - <command>options</command> Statement Definition and - Usage - - - The options statement sets up global - options - to be used by BIND. This statement - may appear only - once in a configuration file. If there is no options - statement, an options block with each option set to its default will - be used. - - - - - - directory - - - The working directory of the server. - Any non-absolute pathnames in the configuration file will be - taken - as relative to this directory. The default location for most - server - output files (e.g. named.run) - is this directory. - If a directory is not specified, the working directory - defaults to `.', the directory from - which the server - was started. The directory specified should be an absolute - path. - - - - - - key-directory - - - When performing dynamic update of secure zones, the - directory where the public and private key files should be - found, - if different than the current working directory. The - directory specified - must be an absolute path. - - - - - - named-xfer - - - This option is obsolete. - It was used in BIND 8 to - specify the pathname to the named-xfer program. - In BIND 9, no separate named-xfer program is - needed; its functionality is built into the name server. - - - - - - - tkey-domain - - - The domain appended to the names of all - shared keys generated with - TKEY. When a client - requests a TKEY exchange, it - may or may not specify - the desired name for the key. If present, the name of the - shared - key will be "client specified part" + - "tkey-domain". - Otherwise, the name of the shared key will be "random hex -digits" + "tkey-domain". In most cases, - the domainname should be the - server's domain - name. - - - - - - tkey-dhkey - - - The Diffie-Hellman key used by the server - to generate shared keys with clients using the Diffie-Hellman - mode - of TKEY. The server must be - able to load the - public and private keys from files in the working directory. - In - most cases, the keyname should be the server's host name. - - - - - - cache-file - - - This is for testing only. Do not use. - - - - - - dump-file - - - The pathname of the file the server dumps - the database to when instructed to do so with - rndc dumpdb. - If not specified, the default is named_dump.db. - - - - - - memstatistics-file - - - The pathname of the file the server writes memory - usage statistics to on exit. If specified the - statistics will be written to the file on exit. - - - In BIND 9.5 and later this will - default to named.memstats. - BIND 9.5 will also introduce - memstatistics to control the - writing. - - - - - - pid-file - - - The pathname of the file the server writes its process ID - in. If not specified, the default is /var/run/named.pid. - The pid-file is used by programs that want to send signals to - the running - name server. Specifying pid-file none disables the - use of a PID file — no file will be written and any - existing one will be removed. Note that none - is a keyword, not a filename, and therefore is not enclosed - in - double quotes. - - - - - - recursing-file - - - The pathname of the file the server dumps - the queries that are currently recursing when instructed - to do so with rndc recursing. - If not specified, the default is named.recursing. - - - - - - statistics-file - - - The pathname of the file the server appends statistics - to when instructed to do so using rndc stats. - If not specified, the default is named.stats in the - server's current directory. The format of the file is - described - in . - - - - - - port - - - The UDP/TCP port number the server uses for - receiving and sending DNS protocol traffic. - The default is 53. This option is mainly intended for server - testing; - a server using a port other than 53 will not be able to - communicate with - the global DNS. - - - - - - random-device - - - The source of entropy to be used by the server. Entropy is - primarily needed - for DNSSEC operations, such as TKEY transactions and dynamic - update of signed - zones. This options specifies the device (or file) from which - to read - entropy. If this is a file, operations requiring entropy will - fail when the - file has been exhausted. If not specified, the default value - is - /dev/random - (or equivalent) when present, and none otherwise. The - random-device option takes - effect during - the initial configuration load at server startup time and - is ignored on subsequent reloads. - - - - - - preferred-glue - - - If specified, the listed type (A or AAAA) will be emitted - before other glue - in the additional section of a query response. - The default is not to prefer any type (NONE). - - - - - - root-delegation-only - - - Turn on enforcement of delegation-only in TLDs (top level domains) and root zones - with an optional - exclude list. - - - Note some TLDs are not delegation only (e.g. "DE", "LV", "US" - and "MUSEUM"). - - - -options { - root-delegation-only exclude { "de"; "lv"; "us"; "museum"; }; -}; - - - - - - - disable-algorithms - - - Disable the specified DNSSEC algorithms at and below the - specified name. - Multiple disable-algorithms - statements are allowed. - Only the most specific will be applied. - - - - - - dnssec-lookaside - - - When set, dnssec-lookaside - provides the - validator with an alternate method to validate DNSKEY records - at the - top of a zone. When a DNSKEY is at or below a domain - specified by the - deepest dnssec-lookaside, and - the normal dnssec validation - has left the key untrusted, the trust-anchor will be append to - the key - name and a DLV record will be looked up to see if it can - validate the - key. If the DLV record validates a DNSKEY (similarly to the - way a DS - record does) the DNSKEY RRset is deemed to be trusted. - - - - - - dnssec-must-be-secure - - - Specify hierarchies which must be or may not be secure (signed and - validated). - If yes, then named will only accept - answers if they - are secure. - If no, then normal dnssec validation - applies - allowing for insecure answers to be accepted. - The specified domain must be under a trusted-key or - dnssec-lookaside must be - active. - - - - - - - - Boolean Options - - - - - auth-nxdomain - - - If yes, then the AA bit - is always set on NXDOMAIN responses, even if the server is - not actually - authoritative. The default is no; - this is - a change from BIND 8. If you - are using very old DNS software, you - may need to set it to yes. - - - - - - deallocate-on-exit - - - This option was used in BIND - 8 to enable checking - for memory leaks on exit. BIND 9 ignores the option and always performs - the checks. - - - - - - dialup - - - If yes, then the - server treats all zones as if they are doing zone transfers - across - a dial-on-demand dialup link, which can be brought up by - traffic - originating from this server. This has different effects - according - to zone type and concentrates the zone maintenance so that - it all - happens in a short interval, once every heartbeat-interval and - hopefully during the one call. It also suppresses some of - the normal - zone maintenance traffic. The default is no. - - - The dialup option - may also be specified in the view and - zone statements, - in which case it overrides the global dialup - option. - - - If the zone is a master zone, then the server will send out a - NOTIFY - request to all the slaves (default). This should trigger the - zone serial - number check in the slave (providing it supports NOTIFY) - allowing the slave - to verify the zone while the connection is active. - The set of servers to which NOTIFY is sent can be controlled - by - notify and also-notify. - - - If the - zone is a slave or stub zone, then the server will suppress - the regular - "zone up to date" (refresh) queries and only perform them - when the - heartbeat-interval expires in - addition to sending - NOTIFY requests. - - - Finer control can be achieved by using - notify which only sends NOTIFY - messages, - notify-passive which sends NOTIFY - messages and - suppresses the normal refresh queries, refresh - which suppresses normal refresh processing and sends refresh - queries - when the heartbeat-interval - expires, and - passive which just disables normal - refresh - processing. - - - - - - - - - - - - - dialup mode - - - - - normal refresh - - - - - heart-beat refresh - - - - - heart-beat notify - - - - - - no (default) - - - - yes - - - - - no - - - - - no - - - - - - yes - - - - no - - - - - yes - - - - - yes - - - - - - notify - - - - yes - - - - - no - - - - - yes - - - - - - refresh - - - - no - - - - - yes - - - - - no - - - - - - passive - - - - no - - - - - no - - - - - no - - - - - - notify-passive - - - - no - - - - - no - - - - - yes - - - - - - - - - Note that normal NOTIFY processing is not affected by - dialup. - - - - - - - fake-iquery - - - In BIND 8, this option - enabled simulating the obsolete DNS query type - IQUERY. BIND 9 never does - IQUERY simulation. - - - - - - fetch-glue - - - This option is obsolete. - In BIND 8, fetch-glue yes - caused the server to attempt to fetch glue resource records - it - didn't have when constructing the additional - data section of a response. This is now considered a bad - idea - and BIND 9 never does it. - - - - - - flush-zones-on-shutdown - - - When the nameserver exits due receiving SIGTERM, - flush or do not flush any pending zone writes. The default - is - flush-zones-on-shutdown no. - - - - - - has-old-clients - - - This option was incorrectly implemented - in BIND 8, and is ignored by BIND 9. - To achieve the intended effect - of - has-old-clients yes, specify - the two separate options auth-nxdomain yes - and rfc2308-type1 no instead. - - - - - - host-statistics - - - In BIND 8, this enables keeping of - statistics for every host that the name server interacts - with. - Not implemented in BIND 9. - - - - - - maintain-ixfr-base - - - This option is obsolete. - It was used in BIND 8 to - determine whether a transaction log was - kept for Incremental Zone Transfer. BIND 9 maintains a transaction - log whenever possible. If you need to disable outgoing - incremental zone - transfers, use provide-ixfr no. - - - - - - minimal-responses - - - If yes, then when generating - responses the server will only add records to the authority - and additional data sections when they are required (e.g. - delegations, negative responses). This may improve the - performance of the server. - The default is no. - - - - - - multiple-cnames - - - This option was used in BIND 8 to allow - a domain name to have multiple CNAME records in violation of - the DNS standards. BIND 9.2 onwards - always strictly enforces the CNAME rules both in master - files and dynamic updates. - - - - - - notify - - - If yes (the default), - DNS NOTIFY messages are sent when a zone the server is - authoritative for - changes, see . The messages are - sent to the - servers listed in the zone's NS records (except the master - server identified - in the SOA MNAME field), and to any servers listed in the - also-notify option. - - - If master-only, notifies are only - sent - for master zones. - If explicit, notifies are sent only - to - servers explicitly listed using also-notify. - If no, no notifies are sent. - - - The notify option may also be - specified in the zone - statement, - in which case it overrides the options notify statement. - It would only be necessary to turn off this option if it - caused slaves - to crash. - - - - - - recursion - - - If yes, and a - DNS query requests recursion, then the server will attempt - to do - all the work required to answer the query. If recursion is - off - and the server does not already know the answer, it will - return a - referral response. The default is - yes. - Note that setting recursion no does not prevent - clients from getting data from the server's cache; it only - prevents new data from being cached as an effect of client - queries. - Caching may still occur as an effect the server's internal - operation, such as NOTIFY address lookups. - See also fetch-glue above. - - - - - - rfc2308-type1 - - - Setting this to yes will - cause the server to send NS records along with the SOA - record for negative - answers. The default is no. - - - - Not yet implemented in BIND - 9. - - - - - - - use-id-pool - - - This option is obsolete. - BIND 9 always allocates query - IDs from a pool. - - - - - - zone-statistics - - - If yes, the server will collect - statistical data on all zones (unless specifically turned - off - on a per-zone basis by specifying zone-statistics no - in the zone statement). - These statistics may be accessed - using rndc stats, which will - dump them to the file listed - in the statistics-file. See - also . - - - - - - use-ixfr - - - This option is obsolete. - If you need to disable IXFR to a particular server or - servers, see - the information on the provide-ixfr option - in . - See also - . - - - - - - provide-ixfr - - - See the description of - provide-ixfr in - . - - - - - - request-ixfr - - - See the description of - request-ixfr in - . - - - - - - treat-cr-as-space - - - This option was used in BIND - 8 to make - the server treat carriage return ("\r") characters the same way - as a space or tab character, - to facilitate loading of zone files on a UNIX system that - were generated - on an NT or DOS machine. In BIND 9, both UNIX "\n" - and NT/DOS "\r\n" newlines - are always accepted, - and the option is ignored. - - - - - - additional-from-auth - additional-from-cache - - - - These options control the behavior of an authoritative - server when - answering queries which have additional data, or when - following CNAME - and DNAME chains. - - - - When both of these options are set to yes - (the default) and a - query is being answered from authoritative data (a zone - configured into the server), the additional data section of - the - reply will be filled in using data from other authoritative - zones - and from the cache. In some situations this is undesirable, - such - as when there is concern over the correctness of the cache, - or - in servers where slave zones may be added and modified by - untrusted third parties. Also, avoiding - the search for this additional data will speed up server - operations - at the possible expense of additional queries to resolve - what would - otherwise be provided in the additional section. - - - - For example, if a query asks for an MX record for host foo.example.com, - and the record found is "MX 10 mail.example.net", normally the address - records (A and AAAA) for mail.example.net will be provided as well, - if known, even though they are not in the example.com zone. - Setting these options to no - disables this behavior and makes - the server only search for additional data in the zone it - answers from. - - - - These options are intended for use in authoritative-only - servers, or in authoritative-only views. Attempts to set - them to no without also - specifying - recursion no will cause the - server to - ignore the options and log a warning message. - - - - Specifying additional-from-cache no actually - disables the use of the cache not only for additional data - lookups - but also when looking up the answer. This is usually the - desired - behavior in an authoritative-only server where the - correctness of - the cached data is an issue. - - - - When a name server is non-recursively queried for a name - that is not - below the apex of any served zone, it normally answers with - an - "upwards referral" to the root servers or the servers of - some other - known parent of the query name. Since the data in an - upwards referral - comes from the cache, the server will not be able to provide - upwards - referrals when additional-from-cache no - has been specified. Instead, it will respond to such - queries - with REFUSED. This should not cause any problems since - upwards referrals are not required for the resolution - process. - - - - - - - match-mapped-addresses - - - If yes, then an - IPv4-mapped IPv6 address will match any address match - list entries that match the corresponding IPv4 address. - Enabling this option is sometimes useful on IPv6-enabled - Linux - systems, to work around a kernel quirk that causes IPv4 - TCP connections such as zone transfers to be accepted - on an IPv6 socket using mapped addresses, causing - address match lists designed for IPv4 to fail to match. - The use of this option for any other purpose is discouraged. - - - - - - ixfr-from-differences - - - When yes and the server loads a new version of a master - zone from its zone file or receives a new version of a slave - file by a non-incremental zone transfer, it will compare - the new version to the previous one and calculate a set - of differences. The differences are then logged in the - zone's journal file such that the changes can be transmitted - to downstream slaves as an incremental zone transfer. - - - By allowing incremental zone transfers to be used for - non-dynamic zones, this option saves bandwidth at the - expense of increased CPU and memory consumption at the - master. - In particular, if the new version of a zone is completely - different from the previous one, the set of differences - will be of a size comparable to the combined size of the - old and new zone version, and the server will need to - temporarily allocate memory to hold this complete - difference set. - - ixfr-from-differences - also accepts master and - slave at the view and options - levels which causes - ixfr-from-differences to apply to - all master or - slave zones respectively. - - - - - - multi-master - - - This should be set when you have multiple masters for a zone - and the - addresses refer to different machines. If yes, named will - not log - when the serial number on the master is less than what named - currently - has. The default is no. - - - - - - dnssec-enable - - - Enable DNSSEC support in named. Unless set to yes, - named behaves as if it does not support DNSSEC. - The default is yes. - - - - - - dnssec-validation - - - Enable DNSSEC validation in named. - Note dnssec-enable also needs to be - set to yes to be effective. - The default is no. - - - - - - dnssec-accept-expired - - - Accept expired signatures when verifying DNSSEC signatures. - The default is no. - Setting this option to "yes" leaves named vulnerable to replay attacks. - - - - - - querylog - - - Specify whether query logging should be started when named - starts. - If querylog is not specified, - then the query logging - is determined by the presence of the logging category queries. - - - - - - check-names - - - This option is used to restrict the character set and syntax - of - certain domain names in master files and/or DNS responses - received - from the network. The default varies according to usage - area. For - master zones the default is fail. - For slave zones the default - is warn. - For answers received from the network (response) - the default is ignore. - - - The rules for legal hostnames and mail domains are derived - from RFC 952 and RFC 821 as modified by RFC 1123. - - check-names - applies to the owner names of A, AAA and MX records. - It also applies to the domain names in the RDATA of NS, SOA - and MX records. - It also applies to the RDATA of PTR records where the owner - name indicated that it is a reverse lookup of a hostname - (the owner name ends in IN-ADDR.ARPA, IP6.ARPA, or IP6.INT). - - - - - - check-mx - - - Check whether the MX record appears to refer to a IP address. - The default is to warn. Other possible - values are fail and - ignore. - - - - - - check-wildcard - - - This option is used to check for non-terminal wildcards. - The use of non-terminal wildcards is almost always as a - result of a failure - to understand the wildcard matching algorithm (RFC 1034). - This option - affects master zones. The default (yes) is to check - for non-terminal wildcards and issue a warning. - - - - - - check-integrity - - - Perform post load zone integrity checks on master - zones. This checks that MX and SRV records refer - to address (A or AAAA) records and that glue - address records exist for delegated zones. For - MX and SRV records only in-zone hostnames are - checked (for out-of-zone hostnames use named-checkzone). - For NS records only names below top of zone are - checked (for out-of-zone names and glue consistency - checks use named-checkzone). The default is - yes. - - - - - - check-mx-cname - - - If check-integrity is set then - fail, warn or ignore MX records that refer - to CNAMES. The default is to warn. - - - - - - check-srv-cname - - - If check-integrity is set then - fail, warn or ignore SRV records that refer - to CNAMES. The default is to warn. - - - - - - check-sibling - - - When performing integrity checks, also check that - sibling glue exists. The default is yes. - - - - - - zero-no-soa-ttl - - - When returning authoritative negative responses to - SOA queries set the TTL of the SOA recored returned in - the authority section to zero. - The default is yes. - - - - - - zero-no-soa-ttl-cache - - - When caching a negative response to a SOA query - set the TTL to zero. - The default is no. - - - - - - update-check-ksk - - - When regenerating the RRSIGs following a UPDATE - request to a secure zone, check the KSK flag on - the DNSKEY RR to determine if this key should be - used to generate the RRSIG. This flag is ignored - if there are not DNSKEY RRs both with and without - a KSK. - The default is yes. - - - - - - - - - - Forwarding - - The forwarding facility can be used to create a large site-wide - cache on a few servers, reducing traffic over links to external - name servers. It can also be used to allow queries by servers that - do not have direct access to the Internet, but wish to look up - exterior - names anyway. Forwarding occurs only on those queries for which - the server is not authoritative and does not have the answer in - its cache. - - - - - forward - - - This option is only meaningful if the - forwarders list is not empty. A value of first, - the default, causes the server to query the forwarders - first — and - if that doesn't answer the question, the server will then - look for - the answer itself. If only is - specified, the - server will only query the forwarders. - - - - - - forwarders - - - Specifies the IP addresses to be used - for forwarding. The default is the empty list (no - forwarding). - - - - - - - - Forwarding can also be configured on a per-domain basis, allowing - for the global forwarding options to be overridden in a variety - of ways. You can set particular domains to use different - forwarders, - or have a different forward only/first behavior, - or not forward at all, see . - - - - - Dual-stack Servers - - Dual-stack servers are used as servers of last resort to work - around - problems in reachability due the lack of support for either IPv4 - or IPv6 - on the host machine. - - - - - dual-stack-servers - - - Specifies host names or addresses of machines with access to - both IPv4 and IPv6 transports. If a hostname is used, the - server must be able - to resolve the name using only the transport it has. If the - machine is dual - stacked, then the dual-stack-servers have no effect unless - access to a transport has been disabled on the command line - (e.g. named -4). - - - - - - - - Access Control - - - Access to the server can be restricted based on the IP address - of the requesting system. See for - details on how to specify IP address lists. - - - - - - allow-notify - - - Specifies which hosts are allowed to - notify this server, a slave, of zone changes in addition - to the zone masters. - allow-notify may also be - specified in the - zone statement, in which case - it overrides the - options allow-notify - statement. It is only meaningful - for a slave zone. If not specified, the default is to - process notify messages - only from a zone's master. - - - - - - allow-query - - - Specifies which hosts are allowed to ask ordinary - DNS questions. allow-query may - also be specified in the zone - statement, in which case it overrides the - options allow-query statement. - If not specified, the default is to allow queries - from all hosts. - - - - allow-query-cache is now - used to specify access to the cache. - - - - - - - allow-query-cache - - - Specifies which hosts are allowed to get answers - from the cache. If allow-query-cache - is not set then allow-recursion - is used if set, otherwise allow-query - is used if set, otherwise the default - (localnets; - localhost;) is used. - - - - - - allow-recursion - - - Specifies which hosts are allowed to make recursive - queries through this server. If - allow-recursion is not set - then allow-query-cache is - used if set, otherwise allow-query - is used if set, otherwise the default - (localnets; - localhost;) is used. - - - - - - allow-update - - - Specifies which hosts are allowed to - submit Dynamic DNS updates for master zones. The default is - to deny - updates from all hosts. Note that allowing updates based - on the requestor's IP address is insecure; see - for details. - - - - - - allow-update-forwarding - - - Specifies which hosts are allowed to - submit Dynamic DNS updates to slave zones to be forwarded to - the - master. The default is { none; }, - which - means that no update forwarding will be performed. To - enable - update forwarding, specify - allow-update-forwarding { any; };. - Specifying values other than { none; } or - { any; } is usually - counterproductive, since - the responsibility for update access control should rest - with the - master server, not the slaves. - - - Note that enabling the update forwarding feature on a slave - server - may expose master servers relying on insecure IP address - based - access control to attacks; see - for more details. - - - - - - allow-v6-synthesis - - - This option was introduced for the smooth transition from - AAAA - to A6 and from "nibble labels" to binary labels. - However, since both A6 and binary labels were then - deprecated, - this option was also deprecated. - It is now ignored with some warning messages. - - - - - - allow-transfer - - - Specifies which hosts are allowed to - receive zone transfers from the server. allow-transfer may - also be specified in the zone - statement, in which - case it overrides the options allow-transfer statement. - If not specified, the default is to allow transfers to all - hosts. - - - - - - blackhole - - - Specifies a list of addresses that the - server will not accept queries from or use to resolve a - query. Queries - from these addresses will not be responded to. The default - is none. - - - - - - - - - - Interfaces - - The interfaces and ports that the server will answer queries - from may be specified using the listen-on option. listen-on takes - an optional port, and an address_match_list. - The server will listen on all interfaces allowed by the address - match list. If a port is not specified, port 53 will be used. - - - Multiple listen-on statements are - allowed. - For example, - - -listen-on { 5.6.7.8; }; -listen-on port 1234 { !1.2.3.4; 1.2/16; }; - - - - will enable the name server on port 53 for the IP address - 5.6.7.8, and on port 1234 of an address on the machine in net - 1.2 that is not 1.2.3.4. - - - - If no listen-on is specified, the - server will listen on port 53 on all interfaces. - - - - The listen-on-v6 option is used to - specify the interfaces and the ports on which the server will - listen - for incoming queries sent using IPv6. - - - - When { any; } is - specified - as the address_match_list for the - listen-on-v6 option, - the server does not bind a separate socket to each IPv6 interface - address as it does for IPv4 if the operating system has enough API - support for IPv6 (specifically if it conforms to RFC 3493 and RFC - 3542). - Instead, it listens on the IPv6 wildcard address. - If the system only has incomplete API support for IPv6, however, - the behavior is the same as that for IPv4. - - - - A list of particular IPv6 addresses can also be specified, in - which case - the server listens on a separate socket for each specified - address, - regardless of whether the desired API is supported by the system. - - - - Multiple listen-on-v6 options can - be used. - For example, - - -listen-on-v6 { any; }; -listen-on-v6 port 1234 { !2001:db8::/32; any; }; - - - - will enable the name server on port 53 for any IPv6 addresses - (with a single wildcard socket), - and on port 1234 of IPv6 addresses that is not in the prefix - 2001:db8::/32 (with separate sockets for each matched address.) - - - - To make the server not listen on any IPv6 address, use - - -listen-on-v6 { none; }; - - - - If no listen-on-v6 option is - specified, - the server will not listen on any IPv6 address. - - - - - Query Address - - If the server doesn't know the answer to a question, it will - query other name servers. query-source specifies - the address and port used for such queries. For queries sent over - IPv6, there is a separate query-source-v6 option. - If address is * (asterisk) or is omitted, - a wildcard IP address (INADDR_ANY) - will be used. - If port is * or is omitted, - a random unprivileged port will be used. The avoid-v4-udp-ports - and avoid-v6-udp-ports options can be used - to prevent named - from selecting certain ports. The defaults are: - - -query-source address * port *; -query-source-v6 address * port *; - - - - - The address specified in the query-source option - is used for both UDP and TCP queries, but the port applies only - to - UDP queries. TCP queries always use a random - unprivileged port. - - - - - Solaris 2.5.1 and earlier does not support setting the source - address for TCP sockets. - - - - - See also transfer-source and - notify-source. - - - - - - Zone Transfers - - BIND has mechanisms in place to - facilitate zone transfers - and set limits on the amount of load that transfers place on the - system. The following options apply to zone transfers. - - - - - - also-notify - - - Defines a global list of IP addresses of name servers - that are also sent NOTIFY messages whenever a fresh copy of - the - zone is loaded, in addition to the servers listed in the - zone's NS records. - This helps to ensure that copies of the zones will - quickly converge on stealth servers. If an also-notify list - is given in a zone statement, - it will override - the options also-notify - statement. When a zone notify - statement - is set to no, the IP - addresses in the global also-notify list will - not be sent NOTIFY messages for that zone. The default is - the empty - list (no global notification list). - - - - - - max-transfer-time-in - - - Inbound zone transfers running longer than - this many minutes will be terminated. The default is 120 - minutes - (2 hours). The maximum value is 28 days (40320 minutes). - - - - - - max-transfer-idle-in - - - Inbound zone transfers making no progress - in this many minutes will be terminated. The default is 60 - minutes - (1 hour). The maximum value is 28 days (40320 minutes). - - - - - - max-transfer-time-out - - - Outbound zone transfers running longer than - this many minutes will be terminated. The default is 120 - minutes - (2 hours). The maximum value is 28 days (40320 minutes). - - - - - - max-transfer-idle-out - - - Outbound zone transfers making no progress - in this many minutes will be terminated. The default is 60 - minutes (1 - hour). The maximum value is 28 days (40320 minutes). - - - - - - serial-query-rate - - - Slave servers will periodically query master servers - to find out if zone serial numbers have changed. Each such - query uses - a minute amount of the slave server's network bandwidth. To - limit the - amount of bandwidth used, BIND 9 limits the rate at which - queries are - sent. The value of the serial-query-rate option, - an integer, is the maximum number of queries sent per - second. - The default is 20. - - - - - - serial-queries - - - In BIND 8, the serial-queries - option - set the maximum number of concurrent serial number queries - allowed to be outstanding at any given time. - BIND 9 does not limit the number of outstanding - serial queries and ignores the serial-queries option. - Instead, it limits the rate at which the queries are sent - as defined using the serial-query-rate option. - - - - - - transfer-format - - - - Zone transfers can be sent using two different formats, - one-answer and - many-answers. - The transfer-format option is used - on the master server to determine which format it sends. - one-answer uses one DNS message per - resource record transferred. - many-answers packs as many resource - records as possible into a message. - many-answers is more efficient, but is - only supported by relatively new slave servers, - such as BIND 9, BIND - 8.x and BIND 4.9.5 onwards. - The many-answers format is also supported by - recent Microsoft Windows nameservers. - The default is many-answers. - transfer-format may be overridden on a - per-server basis by using the server - statement. - - - - - - - transfers-in - - - The maximum number of inbound zone transfers - that can be running concurrently. The default value is 10. - Increasing transfers-in may - speed up the convergence - of slave zones, but it also may increase the load on the - local system. - - - - - - transfers-out - - - The maximum number of outbound zone transfers - that can be running concurrently. Zone transfer requests in - excess - of the limit will be refused. The default value is 10. - - - - - - transfers-per-ns - - - The maximum number of inbound zone transfers - that can be concurrently transferring from a given remote - name server. - The default value is 2. - Increasing transfers-per-ns - may - speed up the convergence of slave zones, but it also may - increase - the load on the remote name server. transfers-per-ns may - be overridden on a per-server basis by using the transfers phrase - of the server statement. - - - - - - transfer-source - - transfer-source - determines which local address will be bound to IPv4 - TCP connections used to fetch zones transferred - inbound by the server. It also determines the - source IPv4 address, and optionally the UDP port, - used for the refresh queries and forwarded dynamic - updates. If not set, it defaults to a system - controlled value which will usually be the address - of the interface "closest to" the remote end. This - address must appear in the remote end's - allow-transfer option for the - zone being transferred, if one is specified. This - statement sets the - transfer-source for all zones, - but can be overridden on a per-view or per-zone - basis by including a - transfer-source statement within - the view or - zone block in the configuration - file. - - - - Solaris 2.5.1 and earlier does not support setting the - source address for TCP sockets. - - - - - - - transfer-source-v6 - - - The same as transfer-source, - except zone transfers are performed using IPv6. - - - - - - alt-transfer-source - - - An alternate transfer source if the one listed in - transfer-source fails and - use-alt-transfer-source is - set. - - - If you do not wish the alternate transfer source - to be used, you should set - use-alt-transfer-source - appropriately and you should not depend upon - getting a answer back to the first refresh - query. - - - - - - alt-transfer-source-v6 - - - An alternate transfer source if the one listed in - transfer-source-v6 fails and - use-alt-transfer-source is - set. - - - - - - use-alt-transfer-source - - - Use the alternate transfer sources or not. If views are - specified this defaults to no - otherwise it defaults to - yes (for BIND 8 - compatibility). - - - - - - notify-source - - notify-source - determines which local source address, and - optionally UDP port, will be used to send NOTIFY - messages. This address must appear in the slave - server's masters zone clause or - in an allow-notify clause. This - statement sets the notify-source - for all zones, but can be overridden on a per-zone or - per-view basis by including a - notify-source statement within - the zone or - view block in the configuration - file. - - - - Solaris 2.5.1 and earlier does not support setting the - source address for TCP sockets. - - - - - - - notify-source-v6 - - - Like notify-source, - but applies to notify messages sent to IPv6 addresses. - - - - - - - - - - Bad UDP Port Lists - avoid-v4-udp-ports - and avoid-v6-udp-ports specify a list - of IPv4 and IPv6 UDP ports that will not be used as system - assigned source ports for UDP sockets. These lists - prevent named from choosing as its random source port a - port that is blocked by your firewall. If a query went - out with such a source port, the answer would not get by - the firewall and the name server would have to query - again. - - - - - Operating System Resource Limits - - - The server's usage of many system resources can be limited. - Scaled values are allowed when specifying resource limits. For - example, 1G can be used instead of - 1073741824 to specify a limit of - one - gigabyte. unlimited requests - unlimited use, or the - maximum available amount. default - uses the limit - that was in force when the server was started. See the description - of size_spec in . - - - - The following options set operating system resource limits for - the name server process. Some operating systems don't support - some or - any of the limits. On such systems, a warning will be issued if - the - unsupported limit is used. - - - - - - coresize - - - The maximum size of a core dump. The default - is default. - - - - - - datasize - - - The maximum amount of data memory the server - may use. The default is default. - This is a hard limit on server memory usage. - If the server attempts to allocate memory in excess of this - limit, the allocation will fail, which may in turn leave - the server unable to perform DNS service. Therefore, - this option is rarely useful as a way of limiting the - amount of memory used by the server, but it can be used - to raise an operating system data size limit that is - too small by default. If you wish to limit the amount - of memory used by the server, use the - max-cache-size and - recursive-clients - options instead. - - - - - - files - - - The maximum number of files the server - may have open concurrently. The default is unlimited. - - - - - - stacksize - - - The maximum amount of stack memory the server - may use. The default is default. - - - - - - - - - - Server Resource Limits - - - The following options set limits on the server's - resource consumption that are enforced internally by the - server rather than the operating system. - - - - - - max-ixfr-log-size - - - This option is obsolete; it is accepted - and ignored for BIND 8 compatibility. The option - max-journal-size performs a - similar function in BIND 9. - - - - - - max-journal-size - - - Sets a maximum size for each journal file - (see ). When the journal file - approaches - the specified size, some of the oldest transactions in the - journal - will be automatically removed. The default is - unlimited. - - - - - - host-statistics-max - - - In BIND 8, specifies the maximum number of host statistics - entries to be kept. - Not implemented in BIND 9. - - - - - - recursive-clients - - - The maximum number of simultaneous recursive lookups - the server will perform on behalf of clients. The default - is - 1000. Because each recursing - client uses a fair - bit of memory, on the order of 20 kilobytes, the value of - the - recursive-clients option may - have to be decreased - on hosts with limited memory. - - - - - - tcp-clients - - - The maximum number of simultaneous client TCP - connections that the server will accept. - The default is 100. - - - - - - max-cache-size - - - The maximum amount of memory to use for the - server's cache, in bytes. When the amount of data in the - cache - reaches this limit, the server will cause records to expire - prematurely so that the limit is not exceeded. In a server - with - multiple views, the limit applies separately to the cache of - each - view. The default is unlimited, meaning that - records are purged from the cache only when their TTLs - expire. - - - - - - tcp-listen-queue - - - The listen queue depth. The default and minimum is 3. - If the kernel supports the accept filter "dataready" this - also controls how - many TCP connections that will be queued in kernel space - waiting for - some data before being passed to accept. Values less than 3 - will be - silently raised. - - - - - - - - - - Periodic Task Intervals - - - - - cleaning-interval - - - The server will remove expired resource records - from the cache every cleaning-interval minutes. - The default is 60 minutes. The maximum value is 28 days - (40320 minutes). - If set to 0, no periodic cleaning will occur. - - - - - - heartbeat-interval - - - The server will perform zone maintenance tasks - for all zones marked as dialup whenever this - interval expires. The default is 60 minutes. Reasonable - values are up - to 1 day (1440 minutes). The maximum value is 28 days - (40320 minutes). - If set to 0, no zone maintenance for these zones will occur. - - - - - - interface-interval - - - The server will scan the network interface list - every interface-interval - minutes. The default - is 60 minutes. The maximum value is 28 days (40320 minutes). - If set to 0, interface scanning will only occur when - the configuration file is loaded. After the scan, the - server will - begin listening for queries on any newly discovered - interfaces (provided they are allowed by the - listen-on configuration), and - will - stop listening on interfaces that have gone away. - - - - - - statistics-interval - - - Name server statistics will be logged - every statistics-interval - minutes. The default is - 60. The maximum value is 28 days (40320 minutes). - If set to 0, no statistics will be logged. - - - Not yet implemented in - BIND 9. - - - - - - - - - - - Topology - - - All other things being equal, when the server chooses a name - server - to query from a list of name servers, it prefers the one that is - topologically closest to itself. The topology statement - takes an address_match_list and - interprets it - in a special way. Each top-level list element is assigned a - distance. - Non-negated elements get a distance based on their position in the - list, where the closer the match is to the start of the list, the - shorter the distance is between it and the server. A negated match - will be assigned the maximum distance from the server. If there - is no match, the address will get a distance which is further than - any non-negated list element, and closer than any negated element. - For example, - - -topology { - 10/8; - !1.2.3/24; - { 1.2/16; 3/8; }; -}; - - - will prefer servers on network 10 the most, followed by hosts - on network 1.2.0.0 (netmask 255.255.0.0) and network 3, with the - exception of hosts on network 1.2.3 (netmask 255.255.255.0), which - is preferred least of all. - - - The default topology is - - - topology { localhost; localnets; }; - - - - - The topology option - is not implemented in BIND 9. - - - - - - - The <command>sortlist</command> Statement - - - The response to a DNS query may consist of multiple resource - records (RRs) forming a resource records set (RRset). - The name server will normally return the - RRs within the RRset in an indeterminate order - (but see the rrset-order - statement in ). - The client resolver code should rearrange the RRs as appropriate, - that is, using any addresses on the local net in preference to - other addresses. - However, not all resolvers can do this or are correctly - configured. - When a client is using a local server, the sorting can be performed - in the server, based on the client's address. This only requires - configuring the name servers, not all the clients. - - - - The sortlist statement (see below) - takes - an address_match_list and - interprets it even - more specifically than the topology - statement - does (). - Each top level statement in the sortlist must - itself be an explicit address_match_list with - one or two elements. The first element (which may be an IP - address, - an IP prefix, an ACL name or a nested address_match_list) - of each top level list is checked against the source address of - the query until a match is found. - - - Once the source address of the query has been matched, if - the top level statement contains only one element, the actual - primitive - element that matched the source address is used to select the - address - in the response to move to the beginning of the response. If the - statement is a list of two elements, then the second element is - treated the same as the address_match_list in - a topology statement. Each top - level element - is assigned a distance and the address in the response with the - minimum - distance is moved to the beginning of the response. - - - In the following example, any queries received from any of - the addresses of the host itself will get responses preferring - addresses - on any of the locally connected networks. Next most preferred are - addresses - on the 192.168.1/24 network, and after that either the - 192.168.2/24 - or - 192.168.3/24 network with no preference shown between these two - networks. Queries received from a host on the 192.168.1/24 network - will prefer other addresses on that network to the 192.168.2/24 - and - 192.168.3/24 networks. Queries received from a host on the - 192.168.4/24 - or the 192.168.5/24 network will only prefer other addresses on - their directly connected networks. - - -sortlist { - { localhost; // IF the local host - { localnets; // THEN first fit on the - 192.168.1/24; // following nets - { 192.168.2/24; 192.168.3/24; }; }; }; - { 192.168.1/24; // IF on class C 192.168.1 - { 192.168.1/24; // THEN use .1, or .2 or .3 - { 192.168.2/24; 192.168.3/24; }; }; }; - { 192.168.2/24; // IF on class C 192.168.2 - { 192.168.2/24; // THEN use .2, or .1 or .3 - { 192.168.1/24; 192.168.3/24; }; }; }; - { 192.168.3/24; // IF on class C 192.168.3 - { 192.168.3/24; // THEN use .3, or .1 or .2 - { 192.168.1/24; 192.168.2/24; }; }; }; - { { 192.168.4/24; 192.168.5/24; }; // if .4 or .5, prefer that net - }; -}; - - - The following example will give reasonable behavior for the - local host and hosts on directly connected networks. It is similar - to the behavior of the address sort in BIND 4.9.x. Responses sent - to queries from the local host will favor any of the directly - connected - networks. Responses sent to queries from any other hosts on a - directly - connected network will prefer addresses on that same network. - Responses - to other queries will not be sorted. - - -sortlist { - { localhost; localnets; }; - { localnets; }; -}; - - - - - RRset Ordering - - When multiple records are returned in an answer it may be - useful to configure the order of the records placed into the - response. - The rrset-order statement permits - configuration - of the ordering of the records in a multiple record response. - See also the sortlist statement, - . - - - - An order_spec is defined as - follows: - - - class class_name - type type_name - name "domain_name" - order ordering - - - If no class is specified, the default is ANY. - If no type is specified, the default is ANY. - If no name is specified, the default is "*" (asterisk). - - - The legal values for ordering are: - - - - - - - - - fixed - - - - Records are returned in the order they - are defined in the zone file. - - - - - - random - - - - Records are returned in some random order. - - - - - - cyclic - - - - Records are returned in a round-robin - order. - - - - - - - - For example: - - -rrset-order { - class IN type A name "host.example.com" order random; - order cyclic; -}; - - - - will cause any responses for type A records in class IN that - have "host.example.com" as a - suffix, to always be returned - in random order. All other records are returned in cyclic order. - - - If multiple rrset-order statements - appear, - they are not combined — the last one applies. - - - - - The rrset-order statement - is not yet fully implemented in BIND 9. - BIND 9 currently does not fully support "fixed" ordering. - - - - - - Tuning - - - - - lame-ttl - - - Sets the number of seconds to cache a - lame server indication. 0 disables caching. (This is - NOT recommended.) - The default is 600 (10 minutes) and the - maximum value is - 1800 (30 minutes). - - - - - - - max-ncache-ttl - - - To reduce network traffic and increase performance, - the server stores negative answers. max-ncache-ttl is - used to set a maximum retention time for these answers in - the server - in seconds. The default - max-ncache-ttl is 10800 seconds (3 hours). - max-ncache-ttl cannot exceed - 7 days and will - be silently truncated to 7 days if set to a greater value. - - - - - - max-cache-ttl - - - Sets the maximum time for which the server will - cache ordinary (positive) answers. The default is - one week (7 days). - - - - - - min-roots - - - The minimum number of root servers that - is required for a request for the root servers to be - accepted. The default - is 2. - - - - Not implemented in BIND 9. - - - - - - - sig-validity-interval - - - Specifies the number of days into the - future when DNSSEC signatures automatically generated as a - result - of dynamic updates () - will expire. The default is 30 days. - The maximum value is 10 years (3660 days). The signature - inception time is unconditionally set to one hour before the - current time - to allow for a limited amount of clock skew. - - - - - - min-refresh-time - max-refresh-time - min-retry-time - max-retry-time - - - These options control the server's behavior on refreshing a - zone - (querying for SOA changes) or retrying failed transfers. - Usually the SOA values for the zone are used, but these - values - are set by the master, giving slave server administrators - little - control over their contents. - - - These options allow the administrator to set a minimum and - maximum - refresh and retry time either per-zone, per-view, or - globally. - These options are valid for slave and stub zones, - and clamp the SOA refresh and retry times to the specified - values. - - - - - - edns-udp-size - - - Sets the advertised EDNS UDP buffer size in bytes. Valid - values are 512 to 4096 (values outside this range - will be silently adjusted). The default value is - 4096. The usual reason for setting edns-udp-size to - a non-default value is to get UDP answers to pass - through broken firewalls that block fragmented - packets and/or block UDP packets that are greater - than 512 bytes. - - - - - - max-udp-size - - - Sets the maximum EDNS UDP message size named will - send in bytes. Valid values are 512 to 4096 (values outside - this range will be silently adjusted). The default - value is 4096. The usual reason for setting - max-udp-size to a non-default value is to get UDP - answers to pass through broken firewalls that - block fragmented packets and/or block UDP packets - that are greater than 512 bytes. - This is independent of the advertised receive - buffer (edns-udp-size). - - - - - - masterfile-format - - Specifies - the file format of zone files (see - ). - The default value is text, which is the - standard textual representation. Files in other formats - than text are typically expected - to be generated by the named-compilezone tool. - Note that when a zone file in a different format than - text is loaded, named - may omit some of the checks which would be performed for a - file in the text format. In particular, - check-names checks do not apply - for the raw format. This means - a zone file in the raw format - must be generated with the same check level as that - specified in the named configuration - file. This statement sets the - masterfile-format for all zones, - but can be overridden on a per-zone or per-view basis - by including a masterfile-format - statement within the zone or - view block in the configuration - file. - - - - - - clients-per-query - max-clients-per-query - - These set the - initial value (minimum) and maximum number of recursive - simultanious clients for any given query - (<qname,qtype,qclass>) that the server will accept - before dropping additional clients. named will attempt to - self tune this value and changes will be logged. The - default values are 10 and 100. - - - This value should reflect how many queries come in for - a given name in the time it takes to resolve that name. - If the number of queries exceed this value, named will - assume that it is dealing with a non-responsive zone - and will drop additional queries. If it gets a response - after dropping queries, it will raise the estimate. The - estimate will then be lowered in 20 minutes if it has - remained unchanged. - - - If clients-per-query is set to zero, - then there is no limit on the number of clients per query - and no queries will be dropped. - - - If max-clients-per-query is set to zero, - then there is no upper bound other than imposed by - recursive-clients. - - - - - - notify-delay - - - The delay, in seconds, between sending sets of notify - messages for a zone. The default is zero. - - - - - - - - - Built-in server information zones - - - The server provides some helpful diagnostic information - through a number of built-in zones under the - pseudo-top-level-domain bind in the - CHAOS class. These zones are part - of a - built-in view (see ) of - class - CHAOS which is separate from the - default view of - class IN; therefore, any global - server options - such as allow-query do not apply - the these zones. - If you feel the need to disable these zones, use the options - below, or hide the built-in CHAOS - view by - defining an explicit view of class CHAOS - that matches all clients. - - - - - - version - - - The version the server should report - via a query of the name version.bind - with type TXT, class CHAOS. - The default is the real version number of this server. - Specifying version none - disables processing of the queries. - - - - - - hostname - - - The hostname the server should report via a query of - the name hostname.bind - with type TXT, class CHAOS. - This defaults to the hostname of the machine hosting the - name server as - found by the gethostname() function. The primary purpose of such queries - is to - identify which of a group of anycast servers is actually - answering your queries. Specifying hostname none; - disables processing of the queries. - - - - - - server-id - - - The ID of the server should report via a query of - the name ID.SERVER - with type TXT, class CHAOS. - The primary purpose of such queries is to - identify which of a group of anycast servers is actually - answering your queries. Specifying server-id none; - disables processing of the queries. - Specifying server-id hostname; will cause named to - use the hostname as found by the gethostname() function. - The default server-id is none. - - - - - - - - - - Built-in Empty Zones - - Named has some built-in empty zones (SOA and NS records only). - These are for zones that should normally be answered locally - and which queries should not be sent to the Internet's root - servers. The official servers which cover these namespaces - return NXDOMAIN responses to these queries. In particular, - these cover the reverse namespace for addresses from RFC 1918 and - RFC 3330. They also include the reverse namespace for IPv6 local - address (locally assigned), IPv6 link local addresses, the IPv6 - loopback address and the IPv6 unknown addresss. - - - Named will attempt to determine if a built in zone already exists - or is active (covered by a forward-only forwarding declaration) - and will not not create a empty zone in that case. - - - The current list of empty zones is: - - 10.IN-ADDR.ARPA - 127.IN-ADDR.ARPA - 254.169.IN-ADDR.ARPA - 16.172.IN-ADDR.ARPA - 17.172.IN-ADDR.ARPA - 18.172.IN-ADDR.ARPA - 19.172.IN-ADDR.ARPA - 20.172.IN-ADDR.ARPA - 21.172.IN-ADDR.ARPA - 22.172.IN-ADDR.ARPA - 23.172.IN-ADDR.ARPA - 24.172.IN-ADDR.ARPA - 25.172.IN-ADDR.ARPA - 26.172.IN-ADDR.ARPA - 27.172.IN-ADDR.ARPA - 28.172.IN-ADDR.ARPA - 29.172.IN-ADDR.ARPA - 30.172.IN-ADDR.ARPA - 31.172.IN-ADDR.ARPA - 168.192.IN-ADDR.ARPA - 2.0.192.IN-ADDR.ARPA - 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA - 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA - D.F.IP6.ARPA - 8.E.F.IP6.ARPA - 9.E.F.IP6.ARPA - A.E.F.IP6.ARPA - B.E.F.IP6.ARPA - - - - Empty zones are settable at the view level and only apply to - views of class IN. Disabled empty zones are only inherited - from options if there are no disabled empty zones specified - at the view level. To override the options list of disabled - zones, you can disable the root zone at the view level, for example: - - disable-empty-zone "."; - - - - If you are using the address ranges covered here, you should - already have reverse zones covering the addresses you use. - In practice this appears to not be the case with many queries - being made to the infrastructure servers for names in these - spaces. So many in fact that sacrificial servers were needed - to be deployed to channel the query load away from the - infrastructure servers. - - - The real parent servers for these zones should disable all - empty zone under the parent zone they serve. For the real - root servers, this is all built in empty zones. This will - enable them to return referrals to deeper in the tree. - - - - empty-server - - - Specify what server name will appear in the returned - SOA record for empty zones. If none is specified, then - the zone's name will be used. - - - - - - empty-contact - - - Specify what contact name will appear in the returned - SOA record for empty zones. If none is specified, then - "." will be used. - - - - - - empty-zones-enable - - - Enable or disable all empty zones. By default they - are enabled. - - - - - - disable-empty-zone - - - Disable individual empty zones. By default none are - disabled. This option can be specified multiple times. - - - - - - - - The Statistics File - - - The statistics file generated by BIND 9 - is similar, but not identical, to that - generated by BIND 8. - - - The statistics dump begins with a line, like: - - - +++ Statistics Dump +++ (973798949) - - - The number in parentheses is a standard - Unix-style timestamp, measured as seconds since January 1, 1970. - Following - that line are a series of lines containing a counter type, the - value of the - counter, optionally a zone name, and optionally a view name. - The lines without view and zone listed are global statistics for - the entire server. - Lines with a zone and view name for the given view and zone (the - view name is - omitted for the default view). - - - The statistics dump ends with the line where the - number is identical to the number in the beginning line; for example: - - - --- Statistics Dump --- (973798949) - - - The following statistics counters are maintained: - - - - - - - - - success - - - - The number of - successful queries made to the server or zone. A - successful query - is defined as query which returns a NOERROR response - with at least - one answer RR. - - - - - - referral - - - - The number of queries which resulted - in referral responses. - - - - - - nxrrset - - - - The number of queries which resulted in - NOERROR responses with no data. - - - - - - nxdomain - - - - The number - of queries which resulted in NXDOMAIN responses. - - - - - - failure - - - - The number of queries which resulted in a - failure response other than those above. - - - - - - recursion - - - - The number of queries which caused the server - to perform recursion in order to find the final answer. - - - - - - duplicate - - - - The number of queries which the server attempted to - recurse but discover a existing query with the same - IP address, port, query id, name, type and class - already being processed. - - - - - - dropped - - - - The number of queries for which the server - discovered a excessive number of existing - recursive queries for the same name, type and - class and were subsequently dropped. - - - - - - - - - Each query received by the server will cause exactly one of - success, - referral, - nxrrset, - nxdomain, or - failure - to be incremented, and may additionally cause the - recursion counter to be - incremented. - - - - - - Additional Section Caching - - - The additional section cache, also called acache, - is an internal cache to improve the response performance of BIND 9. - When additional section caching is enabled, BIND 9 will - cache an internal short-cut to the additional section content for - each answer RR. - Note that acache is an internal caching - mechanism of BIND 9, and is not related to the DNS caching - server function. - - - - Additional section caching does not change the - response content (except the RRsets ordering of the additional - section, see below), but can improve the response performance - significantly. - It is particularly effective when BIND 9 acts as an authoritative - server for a zone that has many delegations with many glue RRs. - - - - In order to obtain the maximum performance improvement - from additional section caching, setting - additional-from-cache - to no is recommended, since the current - implementation of acache - does not short-cut of additional section information from the - DNS cache data. - - - - One obvious disadvantage of acache is - that it requires much more - memory for the internal cached data. - Thus, if the response performance does not matter and memory - consumption is much more critical, the - acache mechanism can be - disabled by setting acache-enable to - no. - It is also possible to specify the upper limit of memory - consumption - for acache by using max-acache-size. - - - - Additional section caching also has a minor effect on the - RRset ordering in the additional section. - Without acache, - cyclic order is effective for the additional - section as well as the answer and authority sections. - However, additional section caching fixes the ordering when it - first caches an RRset for the additional section, and the same - ordering will be kept in succeeding responses, regardless of the - setting of rrset-order. - The effect of this should be minor, however, since an - RRset in the additional section - typically only contains a small number of RRs (and in many cases - it only contains a single RR), in which case the - ordering does not matter much. - - - - The following is a summary of options related to - acache. - - - - - - acache-enable - - - If yes, additional section caching is - enabled. The default value is no. - - - - - - acache-cleaning-interval - - - The server will remove stale cache entries, based on an LRU - based - algorithm, every acache-cleaning-interval minutes. - The default is 60 minutes. - If set to 0, no periodic cleaning will occur. - - - - - - max-acache-size - - - The maximum amount of memory in bytes to use for the server's acache. - When the amount of data in the acache reaches this limit, - the server - will clean more aggressively so that the limit is not - exceeded. - In a server with multiple views, the limit applies - separately to the - acache of each view. - The default is unlimited, - meaning that - entries are purged from the acache only at the - periodic cleaning time. - - - - - - - - - - - - <command>server</command> Statement Grammar - -server ip_addr[/prefixlen] { - bogus yes_or_no ; - provide-ixfr yes_or_no ; - request-ixfr yes_or_no ; - edns yes_or_no ; - edns-udp-size number ; - max-udp-size number ; - transfers number ; - transfer-format ( one-answer | many-answers ) ; ] - keys { string ; string ; ... } ; - transfer-source (ip4_addr | *) port ip_port ; - transfer-source-v6 (ip6_addr | *) port ip_port ; - notify-source (ip4_addr | *) port ip_port ; - notify-source-v6 (ip6_addr | *) port ip_port ; - query-source address ( ip_addr | * ) port ( ip_port | * ) ; - query-source-v6 address ( ip_addr | * ) port ( ip_port | * ) ; -}; - - - - - - <command>server</command> Statement Definition and - Usage - - - The server statement defines - characteristics - to be associated with a remote name server. If a prefix length is - specified, then a range of servers is covered. Only the most - specific - server clause applies regardless of the order in - named.conf. - - - - The server statement can occur at - the top level of the - configuration file or inside a view - statement. - If a view statement contains - one or more server statements, only - those - apply to the view and any top-level ones are ignored. - If a view contains no server - statements, - any top-level server statements are - used as - defaults. - - - - If you discover that a remote server is giving out bad data, - marking it as bogus will prevent further queries to it. The - default - value of bogus is no. - - - The provide-ixfr clause determines - whether - the local server, acting as master, will respond with an - incremental - zone transfer when the given remote server, a slave, requests it. - If set to yes, incremental transfer - will be provided - whenever possible. If set to no, - all transfers - to the remote server will be non-incremental. If not set, the - value - of the provide-ixfr option in the - view or - global options block is used as a default. - - - - The request-ixfr clause determines - whether - the local server, acting as a slave, will request incremental zone - transfers from the given remote server, a master. If not set, the - value of the request-ixfr option in - the view or - global options block is used as a default. - - - - IXFR requests to servers that do not support IXFR will - automatically - fall back to AXFR. Therefore, there is no need to manually list - which servers support IXFR and which ones do not; the global - default - of yes should always work. - The purpose of the provide-ixfr and - request-ixfr clauses is - to make it possible to disable the use of IXFR even when both - master - and slave claim to support it, for example if one of the servers - is buggy and crashes or corrupts data when IXFR is used. - - - - The edns clause determines whether - the local server will attempt to use EDNS when communicating - with the remote server. The default is yes. - - - - The edns-udp-size option sets the EDNS UDP size - that is advertised by named when querying the remote server. - Valid values are 512 to 4096 bytes (values outside this range will be - silently adjusted). This option is useful when you wish to - advertises a different value to this server than the value you - advertise globally, for example, when there is a firewall at the - remote site that is blocking large replies. - - - - The max-udp-size option sets the - maximum EDNS UDP message size named will send. Valid - values are 512 to 4096 bytes (values outside this range will - be silently adjusted). This option is useful when you - know that there is a firewall that is blocking large - replies from named. - - - - The server supports two zone transfer methods. The first, one-answer, - uses one DNS message per resource record transferred. many-answers packs - as many resource records as possible into a message. many-answers is - more efficient, but is only known to be understood by BIND 9, BIND - 8.x, and patched versions of BIND - 4.9.5. You can specify which method - to use for a server with the transfer-format option. - If transfer-format is not - specified, the transfer-format - specified - by the options statement will be - used. - - - transfers - is used to limit the number of concurrent inbound zone - transfers from the specified server. If no - transfers clause is specified, the - limit is set according to the - transfers-per-ns option. - - - - The keys clause identifies a - key_id defined by the key statement, - to be used for transaction security (TSIG, ) - when talking to the remote server. - When a request is sent to the remote server, a request signature - will be generated using the key specified here and appended to the - message. A request originating from the remote server is not - required - to be signed by this key. - - - - Although the grammar of the keys - clause - allows for multiple keys, only a single key per server is - currently - supported. - - - - The transfer-source and - transfer-source-v6 clauses specify - the IPv4 and IPv6 source - address to be used for zone transfer with the remote server, - respectively. - For an IPv4 remote server, only transfer-source can - be specified. - Similarly, for an IPv6 remote server, only - transfer-source-v6 can be - specified. - For more details, see the description of - transfer-source and - transfer-source-v6 in - . - - - - The notify-source and - notify-source-v6 clauses specify the - IPv4 and IPv6 source address to be used for notify - messages sent to remote servers, respectively. For an - IPv4 remote server, only notify-source - can be specified. Similarly, for an IPv6 remote server, - only notify-source-v6 can be specified. - - - - The query-source and - query-source-v6 clauses specify the - IPv4 and IPv6 source address to be used for queries - sent to remote servers, respectively. For an IPv4 - remote server, only query-source can - be specified. Similarly, for an IPv6 remote server, - only query-source-v6 can be specified. - - - - - - <command>trusted-keys</command> Statement Grammar - -trusted-keys { - string number number number string ; - string number number number string ; ... -}; - - - - - <command>trusted-keys</command> Statement Definition - and Usage - - The trusted-keys statement defines - DNSSEC security roots. DNSSEC is described in . A security root is defined when the - public key for a non-authoritative zone is known, but - cannot be securely obtained through DNS, either because - it is the DNS root zone or because its parent zone is - unsigned. Once a key has been configured as a trusted - key, it is treated as if it had been validated and - proven secure. The resolver attempts DNSSEC validation - on all DNS data in subdomains of a security root. - - - All keys (and corresponding zones) listed in - trusted-keys are deemed to exist regardless - of what parent zones say. Similarly for all keys listed in - trusted-keys only those keys are - used to validate the DNSKEY RRset. The parent's DS RRset - will not be used. - - - The trusted-keys statement can contain - multiple key entries, each consisting of the key's - domain name, flags, protocol, algorithm, and the Base-64 - representation of the key data. - - - - - <command>view</command> Statement Grammar - -view view_name - class { - match-clients { address_match_list }; - match-destinations { address_match_list }; - match-recursive-only yes_or_no ; - view_option; ... - zone_statement; ... -}; - - - - - <command>view</command> Statement Definition and Usage - - - The view statement is a powerful - feature - of BIND 9 that lets a name server - answer a DNS query differently - depending on who is asking. It is particularly useful for - implementing - split DNS setups without having to run multiple servers. - - - - Each view statement defines a view - of the - DNS namespace that will be seen by a subset of clients. A client - matches - a view if its source IP address matches the - address_match_list of the view's - match-clients clause and its - destination IP address matches - the address_match_list of the - view's - match-destinations clause. If not - specified, both - match-clients and match-destinations - default to matching all addresses. In addition to checking IP - addresses - match-clients and match-destinations - can also take keys which provide an - mechanism for the - client to select the view. A view can also be specified - as match-recursive-only, which - means that only recursive - requests from matching clients will match that view. - The order of the view statements is - significant — - a client request will be resolved in the context of the first - view that it matches. - - - - Zones defined within a view - statement will - be only be accessible to clients that match the view. - By defining a zone of the same name in multiple views, different - zone data can be given to different clients, for example, - "internal" - and "external" clients in a split DNS setup. - - - - Many of the options given in the options statement - can also be used within a view - statement, and then - apply only when resolving queries with that view. When no - view-specific - value is given, the value in the options statement - is used as a default. Also, zone options can have default values - specified - in the view statement; these - view-specific defaults - take precedence over those in the options statement. - - - - Views are class specific. If no class is given, class IN - is assumed. Note that all non-IN views must contain a hint zone, - since only the IN class has compiled-in default hints. - - - - If there are no view statements in - the config - file, a default view that matches any client is automatically - created - in class IN. Any zone statements - specified on - the top level of the configuration file are considered to be part - of - this default view, and the options - statement will - apply to the default view. If any explicit view - statements are present, all zone - statements must - occur inside view statements. - - - - Here is an example of a typical split DNS setup implemented - using view statements: - - -view "internal" { - // This should match our internal networks. - match-clients { 10.0.0.0/8; }; - - // Provide recursive service to internal clients only. - recursion yes; - - // Provide a complete view of the example.com zone - // including addresses of internal hosts. - zone "example.com" { - type master; - file "example-internal.db"; - }; -}; - -view "external" { - // Match all clients not matched by the previous view. - match-clients { any; }; - - // Refuse recursive service to external clients. - recursion no; - - // Provide a restricted view of the example.com zone - // containing only publicly accessible hosts. - zone "example.com" { - type master; - file "example-external.db"; - }; -}; - - - - - <command>zone</command> - Statement Grammar - -zone zone_name class { - type master; - allow-query { address_match_list }; - allow-transfer { address_match_list }; - allow-update { address_match_list }; - update-policy { update_policy_rule ... }; - also-notify { ip_addr port ip_port ; ip_addr port ip_port ; ... }; - check-names (warn|fail|ignore) ; - check-mx (warn|fail|ignore) ; - check-wildcard yes_or_no; - check-integrity yes_or_no ; - dialup dialup_option ; - file string ; - masterfile-format (text|raw) ; - journal string ; - forward (only|first) ; - forwarders { ip_addr port ip_port ; ... }; - ixfr-base string ; - ixfr-tmp-file string ; - maintain-ixfr-base yes_or_no ; - max-ixfr-log-size number ; - max-transfer-idle-out number ; - max-transfer-time-out number ; - notify yes_or_no | explicit | master-only ; - notify-delay seconds ; - pubkey number number number string ; - notify-source (ip4_addr | *) port ip_port ; - notify-source-v6 (ip6_addr | *) port ip_port ; - zone-statistics yes_or_no ; - sig-validity-interval number ; - database string ; - min-refresh-time number ; - max-refresh-time number ; - min-retry-time number ; - max-retry-time number ; - key-directory path_name; - zero-no-soa-ttl yes_or_no ; -}; - -zone zone_name class { - type slave; - allow-notify { address_match_list }; - allow-query { address_match_list }; - allow-transfer { address_match_list }; - allow-update-forwarding { address_match_list }; - update-check-ksk yes_or_no; - also-notify { ip_addr port ip_port ; ip_addr port ip_port ; ... }; - check-names (warn|fail|ignore) ; - dialup dialup_option ; - file string ; - masterfile-format (text|raw) ; - journal string ; - forward (only|first) ; - forwarders { ip_addr port ip_port ; ... }; - ixfr-base string ; - ixfr-tmp-file string ; - maintain-ixfr-base yes_or_no ; - masters port ip_port { ( masters_list | ip_addr port ip_port key key ) ; ... }; - max-ixfr-log-size number ; - max-transfer-idle-in number ; - max-transfer-idle-out number ; - max-transfer-time-in number ; - max-transfer-time-out number ; - notify yes_or_no | explicit | master-only ; - pubkey number number number string ; - transfer-source (ip4_addr | *) port ip_port ; - transfer-source-v6 (ip6_addr | *) port ip_port ; - alt-transfer-source (ip4_addr | *) port ip_port ; - alt-transfer-source-v6 (ip6_addr | *) port ip_port ; - use-alt-transfer-source yes_or_no; - notify-source (ip4_addr | *) port ip_port ; - notify-source-v6 (ip6_addr | *) port ip_port ; - zone-statistics yes_or_no ; - database string ; - min-refresh-time number ; - max-refresh-time number ; - min-retry-time number ; - max-retry-time number ; - multi-master yes_or_no ; - zero-no-soa-ttl yes_or_no ; -}; - -zone zone_name class { - type hint; - file string ; - delegation-only yes_or_no ; - check-names (warn|fail|ignore) ; // Not Implemented. -}; - -zone zone_name class { - type stub; - allow-query { address_match_list }; - check-names (warn|fail|ignore) ; - dialup dialup_option ; - delegation-only yes_or_no ; - file string ; - masterfile-format (text|raw) ; - forward (only|first) ; - forwarders { ip_addr port ip_port ; ... }; - masters port ip_port { ( masters_list | ip_addr port ip_port key key ) ; ... }; - max-transfer-idle-in number ; - max-transfer-time-in number ; - pubkey number number number string ; - transfer-source (ip4_addr | *) port ip_port ; - transfer-source-v6 (ip6_addr | *) port ip_port ; - alt-transfer-source (ip4_addr | *) port ip_port ; - alt-transfer-source-v6 (ip6_addr | *) port ip_port ; - use-alt-transfer-source yes_or_no; - zone-statistics yes_or_no ; - database string ; - min-refresh-time number ; - max-refresh-time number ; - min-retry-time number ; - max-retry-time number ; - multi-master yes_or_no ; -}; - -zone zone_name class { - type forward; - forward (only|first) ; - forwarders { ip_addr port ip_port ; ... }; - delegation-only yes_or_no ; -}; - -zone zone_name class { - type delegation-only; -}; - - - - - - <command>zone</command> Statement Definition and Usage - - Zone Types - - - - - - - - - - - master - - - - - The server has a master copy of the data - for the zone and will be able to provide authoritative - answers for - it. - - - - - - - slave - - - - - A slave zone is a replica of a master - zone. The masters list - specifies one or more IP addresses - of master servers that the slave contacts to update - its copy of the zone. - Masters list elements can also be names of other - masters lists. - By default, transfers are made from port 53 on the - servers; this can - be changed for all servers by specifying a port number - before the - list of IP addresses, or on a per-server basis after - the IP address. - Authentication to the master can also be done with - per-server TSIG keys. - If a file is specified, then the - replica will be written to this file whenever the zone - is changed, - and reloaded from this file on a server restart. Use - of a file is - recommended, since it often speeds server startup and - eliminates - a needless waste of bandwidth. Note that for large - numbers (in the - tens or hundreds of thousands) of zones per server, it - is best to - use a two-level naming scheme for zone filenames. For - example, - a slave server for the zone example.com might place - the zone contents into a file called - ex/example.com where ex/ is - just the first two letters of the zone name. (Most - operating systems - behave very slowly if you put 100 000 files into - a single directory.) - - - - - - - stub - - - - - A stub zone is similar to a slave zone, - except that it replicates only the NS records of a - master zone instead - of the entire zone. Stub zones are not a standard part - of the DNS; - they are a feature specific to the BIND implementation. - - - - Stub zones can be used to eliminate the need for glue - NS record - in a parent zone at the expense of maintaining a stub - zone entry and - a set of name server addresses in named.conf. - This usage is not recommended for new configurations, - and BIND 9 - supports it only in a limited way. - In BIND 4/8, zone - transfers of a parent zone - included the NS records from stub children of that - zone. This meant - that, in some cases, users could get away with - configuring child stubs - only in the master server for the parent zone. BIND - 9 never mixes together zone data from different zones - in this - way. Therefore, if a BIND 9 master serving a parent - zone has child stub zones configured, all the slave - servers for the - parent zone also need to have the same child stub - zones - configured. - - - - Stub zones can also be used as a way of forcing the - resolution - of a given domain to use a particular set of - authoritative servers. - For example, the caching name servers on a private - network using - RFC1918 addressing may be configured with stub zones - for - 10.in-addr.arpa - to use a set of internal name servers as the - authoritative - servers for that domain. - - - - - - - forward - - - - - A "forward zone" is a way to configure - forwarding on a per-domain basis. A zone statement - of type forward can - contain a forward - and/or forwarders - statement, - which will apply to queries within the domain given by - the zone - name. If no forwarders - statement is present or - an empty list for forwarders is given, then no - forwarding will be done for the domain, canceling the - effects of - any forwarders in the options statement. Thus - if you want to use this type of zone to change the - behavior of the - global forward option - (that is, "forward first" - to, then "forward only", or vice versa, but want to - use the same - servers as set globally) you need to re-specify the - global forwarders. - - - - - - - hint - - - - - The initial set of root name servers is - specified using a "hint zone". When the server starts - up, it uses - the root hints to find a root name server and get the - most recent - list of root name servers. If no hint zone is - specified for class - IN, the server uses a compiled-in default set of root - servers hints. - Classes other than IN have no built-in defaults hints. - - - - - - - delegation-only - - - - - This is used to enforce the delegation-only - status of infrastructure zones (e.g. COM, NET, ORG). - Any answer that - is received without an explicit or implicit delegation - in the authority - section will be treated as NXDOMAIN. This does not - apply to the zone - apex. This should not be applied to leaf zones. - - - delegation-only has no - effect on answers received - from forwarders. - - - - - - - - - - Class - - The zone's name may optionally be followed by a class. If - a class is not specified, class IN (for Internet), - is assumed. This is correct for the vast majority of cases. - - - The hesiod class is - named for an information service from MIT's Project Athena. It - is - used to share information about various systems databases, such - as users, groups, printers and so on. The keyword - HS is - a synonym for hesiod. - - - Another MIT development is Chaosnet, a LAN protocol created - in the mid-1970s. Zone data for it can be specified with the CHAOS class. - - - - - Zone Options - - - - - allow-notify - - - See the description of - allow-notify in . - - - - - - allow-query - - - See the description of - allow-query in . - - - - - - allow-transfer - - - See the description of allow-transfer - in . - - - - - - allow-update - - - See the description of allow-update - in . - - - - - - update-policy - - - Specifies a "Simple Secure Update" policy. See - . - - - - - - allow-update-forwarding - - - See the description of allow-update-forwarding - in . - - - - - - also-notify - - - Only meaningful if notify - is - active for this zone. The set of machines that will - receive a - DNS NOTIFY message - for this zone is made up of all the listed name servers - (other than - the primary master) for the zone plus any IP addresses - specified - with also-notify. A port - may be specified - with each also-notify - address to send the notify - messages to a port other than the default of 53. - also-notify is not - meaningful for stub zones. - The default is the empty list. - - - - - - check-names - - - This option is used to restrict the character set and - syntax of - certain domain names in master files and/or DNS responses - received from the - network. The default varies according to zone type. For master zones the default is fail. For slave - zones the default is warn. - - - - - - check-mx - - - See the description of - check-mx in . - - - - - - check-wildcard - - - See the description of - check-wildcard in . - - - - - - check-integrity - - - See the description of - check-integrity in . - - - - - - check-sibling - - - See the description of - check-sibling in . - - - - - - zero-no-soa-ttl - - - See the description of - zero-no-soa-ttl in . - - - - - - update-check-ksk - - - See the description of - update-check-ksk in . - - - - - - database - - - Specify the type of database to be used for storing the - zone data. The string following the database keyword - is interpreted as a list of whitespace-delimited words. - The first word - identifies the database type, and any subsequent words are - passed - as arguments to the database to be interpreted in a way - specific - to the database type. - - - The default is "rbt", BIND 9's - native in-memory - red-black-tree database. This database does not take - arguments. - - - Other values are possible if additional database drivers - have been linked into the server. Some sample drivers are - included - with the distribution but none are linked in by default. - - - - - - dialup - - - See the description of - dialup in . - - - - - - delegation-only - - - The flag only applies to hint and stub zones. If set - to yes, then the zone will also be - treated as if it - is also a delegation-only type zone. - - - - - - forward - - - Only meaningful if the zone has a forwarders - list. The only value causes - the lookup to fail - after trying the forwarders and getting no answer, while first would - allow a normal lookup to be tried. - - - - - - forwarders - - - Used to override the list of global forwarders. - If it is not specified in a zone of type forward, - no forwarding is done for the zone and the global options are - not used. - - - - - - ixfr-base - - - Was used in BIND 8 to - specify the name - of the transaction log (journal) file for dynamic update - and IXFR. - BIND 9 ignores the option - and constructs the name of the journal - file by appending ".jnl" - to the name of the - zone file. - - - - - - ixfr-tmp-file - - - Was an undocumented option in BIND 8. - Ignored in BIND 9. - - - - - - journal - - - Allow the default journal's filename to be overridden. - The default is the zone's filename with ".jnl" appended. - This is applicable to master and slave zones. - - - - - - max-transfer-time-in - - - See the description of - max-transfer-time-in in . - - - - - - max-transfer-idle-in - - - See the description of - max-transfer-idle-in in . - - - - - - max-transfer-time-out - - - See the description of - max-transfer-time-out in . - - - - - - max-transfer-idle-out - - - See the description of - max-transfer-idle-out in . - - - - - - notify - - - See the description of - notify in . - - - - - - notify-delay - - - See the description of - notify-delay in . - - - - - - pubkey - - - In BIND 8, this option was - intended for specifying - a public zone key for verification of signatures in DNSSEC - signed - zones when they are loaded from disk. BIND 9 does not verify signatures - on load and ignores the option. - - - - - - zone-statistics - - - If yes, the server will keep - statistical - information for this zone, which can be dumped to the - statistics-file defined in - the server options. - - - - - - sig-validity-interval - - - See the description of - sig-validity-interval in . - - - - - - transfer-source - - - See the description of - transfer-source in . - - - - - - transfer-source-v6 - - - See the description of - transfer-source-v6 in . - - - - - - alt-transfer-source - - - See the description of - alt-transfer-source in . - - - - - - alt-transfer-source-v6 - - - See the description of - alt-transfer-source-v6 in . - - - - - - use-alt-transfer-source - - - See the description of - use-alt-transfer-source in . - - - - - - - notify-source - - - See the description of - notify-source in . - - - - - - notify-source-v6 - - - See the description of - notify-source-v6 in . - - - - - - min-refresh-time - max-refresh-time - min-retry-time - max-retry-time - - - See the description in . - - - - - - ixfr-from-differences - - - See the description of - ixfr-from-differences in . - - - - - - key-directory - - - See the description of - key-directory in . - - - - - - multi-master - - - See the description of multi-master in - . - - - - - - masterfile-format - - - See the description of masterfile-format - in . - - - - - - - - - Dynamic Update Policies - - BIND 9 supports two alternative - methods of granting clients - the right to perform dynamic updates to a zone, - configured by the allow-update - and - update-policy option, - respectively. - - - The allow-update clause works the - same - way as in previous versions of BIND. It grants given clients the - permission to update any record of any name in the zone. - - - The update-policy clause is new - in BIND - 9 and allows more fine-grained control over what updates are - allowed. - A set of rules is specified, where each rule either grants or - denies - permissions for one or more names to be updated by one or more - identities. - If the dynamic update request message is signed (that is, it - includes - either a TSIG or SIG(0) record), the identity of the signer can - be determined. - - - Rules are specified in the update-policy zone - option, and are only meaningful for master zones. When the update-policy statement - is present, it is a configuration error for the allow-update statement - to be present. The update-policy - statement only - examines the signer of a message; the source address is not - relevant. - - - This is how a rule definition looks: - - - -( grant | deny ) identity nametype name types - - - - Each rule grants or denies privileges. Once a message has - successfully matched a rule, the operation is immediately - granted - or denied and no further rules are examined. A rule is matched - when the signer matches the identity field, the name matches the - name field in accordance with the nametype field, and the type - matches - the types specified in the type field. - - - - The identity field specifies a name or a wildcard name. - Normally, this - is the name of the TSIG or SIG(0) key used to sign the update - request. When a - TKEY exchange has been used to create a shared secret, the - identity of the - shared secret is the same as the identity of the key used to - authenticate the - TKEY exchange. When the identity field specifies a - wildcard name, it is subject to DNS wildcard expansion, so the - rule will apply - to multiple identities. The identity field must - contain a fully-qualified domain name. - - - - The nametype field has 6 - values: - name, subdomain, - wildcard, self, - selfsub, and selfwild. - - - - - - - - - - name - - - - Exact-match semantics. This rule matches - when the name being updated is identical - to the contents of the - name field. - - - - - - - subdomain - - - - This rule matches when the name being updated - is a subdomain of, or identical to, the - contents of the name - field. - - - - - - - wildcard - - - - The name field - is subject to DNS wildcard expansion, and - this rule matches when the name being updated - name is a valid expansion of the wildcard. - - - - - - - self - - - - - This rule matches when the name being updated - matches the contents of the - identity field. - The name field - is ignored, but should be the same as the - identity field. - The self nametype is - most useful when allowing using one key per - name to update, where the key has the same - name as the name to be updated. The - identity would - be specified as * (an asterisk) in - this case. - - - - - - - selfsub - - - - This rule is similar to self - except that subdomains of self - can also be updated. - - - - - - - selfwild - - - - This rule is similar to self - except that only subdomains of - self can be updated. - - - - - - - - - In all cases, the name - field must - specify a fully-qualified domain name. - - - - If no types are explicitly specified, this rule matches all - types except - RRSIG, NS, SOA, and NSEC. Types may be specified by name, including - "ANY" (ANY matches all types except NSEC, which can never be - updated). - Note that when an attempt is made to delete all records - associated with a - name, the rules are checked for each existing record type. - - - - - - Zone File - - Types of Resource Records and When to Use Them - - This section, largely borrowed from RFC 1034, describes the - concept of a Resource Record (RR) and explains when each is used. - Since the publication of RFC 1034, several new RRs have been - identified - and implemented in the DNS. These are also included. - - - Resource Records - - - A domain name identifies a node. Each node has a set of - resource information, which may be empty. The set of resource - information associated with a particular name is composed of - separate RRs. The order of RRs in a set is not significant and - need not be preserved by name servers, resolvers, or other - parts of the DNS. However, sorting of multiple RRs is - permitted for optimization purposes, for example, to specify - that a particular nearby server be tried first. See and . - - - - The components of a Resource Record are: - - - - - - - - - - owner name - - - - - The domain name where the RR is found. - - - - - - - type - - - - - An encoded 16-bit value that specifies - the type of the resource record. - - - - - - - TTL - - - - - The time-to-live of the RR. This field - is a 32-bit integer in units of seconds, and is - primarily used by - resolvers when they cache RRs. The TTL describes how - long a RR can - be cached before it should be discarded. - - - - - - - class - - - - - An encoded 16-bit value that identifies - a protocol family or instance of a protocol. - - - - - - - RDATA - - - - - The resource data. The format of the - data is type (and sometimes class) specific. - - - - - - - - The following are types of valid RRs: - - - - - - - - - - A - - - - - A host address. In the IN class, this is a - 32-bit IP address. Described in RFC 1035. - - - - - - - AAAA - - - - - IPv6 address. Described in RFC 1886. - - - - - - - A6 - - - - - IPv6 address. This can be a partial - address (a suffix) and an indirection to the name - where the rest of the - address (the prefix) can be found. Experimental. - Described in RFC 2874. - - - - - - - AFSDB - - - - - Location of AFS database servers. - Experimental. Described in RFC 1183. - - - - - - - APL - - - - - Address prefix list. Experimental. - Described in RFC 3123. - - - - - - - CERT - - - - - Holds a digital certificate. - Described in RFC 2538. - - - - - - - CNAME - - - - - Identifies the canonical name of an alias. - Described in RFC 1035. - - - - - - - DNAME - - - - - Replaces the domain name specified with - another name to be looked up, effectively aliasing an - entire - subtree of the domain name space rather than a single - record - as in the case of the CNAME RR. - Described in RFC 2672. - - - - - - - DNSKEY - - - - - Stores a public key associated with a signed - DNS zone. Described in RFC 4034. - - - - - - - DS - - - - - Stores the hash of a public key associated with a - signed DNS zone. Described in RFC 4034. - - - - - - - GPOS - - - - - Specifies the global position. Superseded by LOC. - - - - - - - HINFO - - - - - Identifies the CPU and OS used by a host. - Described in RFC 1035. - - - - - - - ISDN - - - - - Representation of ISDN addresses. - Experimental. Described in RFC 1183. - - - - - - - KEY - - - - - Stores a public key associated with a - DNS name. Used in original DNSSEC; replaced - by DNSKEY in DNSSECbis, but still used with - SIG(0). Described in RFCs 2535 and 2931. - - - - - - - KX - - - - - Identifies a key exchanger for this - DNS name. Described in RFC 2230. - - - - - - - LOC - - - - - For storing GPS info. Described in RFC 1876. - Experimental. - - - - - - - MX - - - - - Identifies a mail exchange for the domain with - a 16-bit preference value (lower is better) - followed by the host name of the mail exchange. - Described in RFC 974, RFC 1035. - - - - - - - NAPTR - - - - - Name authority pointer. Described in RFC 2915. - - - - - - - NSAP - - - - - A network service access point. - Described in RFC 1706. - - - - - - - NS - - - - - The authoritative name server for the - domain. Described in RFC 1035. - - - - - - - NSEC - - - - - Used in DNSSECbis to securely indicate that - RRs with an owner name in a certain name interval do - not exist in - a zone and indicate what RR types are present for an - existing name. - Described in RFC 4034. - - - - - - - NXT - - - - - Used in DNSSEC to securely indicate that - RRs with an owner name in a certain name interval do - not exist in - a zone and indicate what RR types are present for an - existing name. - Used in original DNSSEC; replaced by NSEC in - DNSSECbis. - Described in RFC 2535. - - - - - - - PTR - - - - - A pointer to another part of the domain - name space. Described in RFC 1035. - - - - - - - PX - - - - - Provides mappings between RFC 822 and X.400 - addresses. Described in RFC 2163. - - - - - - - RP - - - - - Information on persons responsible - for the domain. Experimental. Described in RFC 1183. - - - - - - - RRSIG - - - - - Contains DNSSECbis signature data. Described - in RFC 4034. - - - - - - - RT - - - - - Route-through binding for hosts that - do not have their own direct wide area network - addresses. - Experimental. Described in RFC 1183. - - - - - - - SIG - - - - - Contains DNSSEC signature data. Used in - original DNSSEC; replaced by RRSIG in - DNSSECbis, but still used for SIG(0). - Described in RFCs 2535 and 2931. - - - - - - - SOA - - - - - Identifies the start of a zone of authority. - Described in RFC 1035. - - - - - - - SRV - - - - - Information about well known network - services (replaces WKS). Described in RFC 2782. - - - - - - - TXT - - - - - Text records. Described in RFC 1035. - - - - - - - WKS - - - - - Information about which well known - network services, such as SMTP, that a domain - supports. Historical. - - - - - - - X25 - - - - - Representation of X.25 network addresses. - Experimental. Described in RFC 1183. - - - - - - - - The following classes of resource records - are currently valid in the DNS: - - - - - - - - - - IN - - - - - The Internet. - - - - - - - - CH - - - - - Chaosnet, a LAN protocol created at MIT in the - mid-1970s. - Rarely used for its historical purpose, but reused for - BIND's - built-in server information zones, e.g., - version.bind. - - - - - - - - HS - - - - - Hesiod, an information service - developed by MIT's Project Athena. It is used to share - information - about various systems databases, such as users, - groups, printers - and so on. - - - - - - - - - - The owner name is often implicit, rather than forming an - integral - part of the RR. For example, many name servers internally form - tree - or hash structures for the name space, and chain RRs off nodes. - The remaining RR parts are the fixed header (type, class, TTL) - which is consistent for all RRs, and a variable part (RDATA) - that - fits the needs of the resource being described. - - - The meaning of the TTL field is a time limit on how long an - RR can be kept in a cache. This limit does not apply to - authoritative - data in zones; it is also timed out, but by the refreshing - policies - for the zone. The TTL is assigned by the administrator for the - zone where the data originates. While short TTLs can be used to - minimize caching, and a zero TTL prohibits caching, the - realities - of Internet performance suggest that these times should be on - the - order of days for the typical host. If a change can be - anticipated, - the TTL can be reduced prior to the change to minimize - inconsistency - during the change, and then increased back to its former value - following - the change. - - - The data in the RDATA section of RRs is carried as a combination - of binary strings and domain names. The domain names are - frequently - used as "pointers" to other data in the DNS. - - - - Textual expression of RRs - - RRs are represented in binary form in the packets of the DNS - protocol, and are usually represented in highly encoded form - when - stored in a name server or resolver. In the examples provided - in - RFC 1034, a style similar to that used in master files was - employed - in order to show the contents of RRs. In this format, most RRs - are shown on a single line, although continuation lines are - possible - using parentheses. - - - The start of the line gives the owner of the RR. If a line - begins with a blank, then the owner is assumed to be the same as - that of the previous RR. Blank lines are often included for - readability. - - - Following the owner, we list the TTL, type, and class of the - RR. Class and type use the mnemonics defined above, and TTL is - an integer before the type field. In order to avoid ambiguity - in - parsing, type and class mnemonics are disjoint, TTLs are - integers, - and the type mnemonic is always last. The IN class and TTL - values - are often omitted from examples in the interests of clarity. - - - The resource data or RDATA section of the RR are given using - knowledge of the typical representation for the data. - - - For example, we might show the RRs carried in a message as: - - - - - - - - - - ISI.EDU. - - - - - MX - - - - - 10 VENERA.ISI.EDU. - - - - - - - - - - MX - - - - - 10 VAXA.ISI.EDU - - - - - - - VENERA.ISI.EDU - - - - - A - - - - - 128.9.0.32 - - - - - - - - - - A - - - - - 10.1.0.52 - - - - - - - VAXA.ISI.EDU - - - - - A - - - - - 10.2.0.27 - - - - - - - - - - A - - - - - 128.9.0.33 - - - - - - - - The MX RRs have an RDATA section which consists of a 16-bit - number followed by a domain name. The address RRs use a - standard - IP address format to contain a 32-bit internet address. - - - The above example shows six RRs, with two RRs at each of three - domain names. - - - Similarly we might see: - - - - - - - - - - XX.LCS.MIT.EDU. - - - - - IN A - - - - - 10.0.0.44 - - - - - - - - CH A - - - - - MIT.EDU. 2420 - - - - - - - - This example shows two addresses for - XX.LCS.MIT.EDU, each of a different class. - - - - - - Discussion of MX Records - - - As described above, domain servers store information as a - series of resource records, each of which contains a particular - piece of information about a given domain name (which is usually, - but not always, a host). The simplest way to think of a RR is as - a typed pair of data, a domain name matched with a relevant datum, - and stored with some additional type information to help systems - determine when the RR is relevant. - - - - MX records are used to control delivery of email. The data - specified in the record is a priority and a domain name. The - priority - controls the order in which email delivery is attempted, with the - lowest number first. If two priorities are the same, a server is - chosen randomly. If no servers at a given priority are responding, - the mail transport agent will fall back to the next largest - priority. - Priority numbers do not have any absolute meaning — they are - relevant - only respective to other MX records for that domain name. The - domain - name given is the machine to which the mail will be delivered. - It must have an associated address record - (A or AAAA) — CNAME is not sufficient. - - - For a given domain, if there is both a CNAME record and an - MX record, the MX record is in error, and will be ignored. - Instead, - the mail will be delivered to the server specified in the MX - record - pointed to by the CNAME. - - - For example: - - - - - - - - - - - - - example.com. - - - - - IN - - - - - MX - - - - - 10 - - - - - mail.example.com. - - - - - - - - - - IN - - - - - MX - - - - - 10 - - - - - mail2.example.com. - - - - - - - - - - IN - - - - - MX - - - - - 20 - - - - - mail.backup.org. - - - - - - - mail.example.com. - - - - - IN - - - - - A - - - - - 10.0.0.1 - - - - - - - - - - mail2.example.com. - - - - - IN - - - - - A - - - - - 10.0.0.2 - - - - - - - - - - Mail delivery will be attempted to mail.example.com and - mail2.example.com (in - any order), and if neither of those succeed, delivery to mail.backup.org will - be attempted. - - - - Setting TTLs - - The time-to-live of the RR field is a 32-bit integer represented - in units of seconds, and is primarily used by resolvers when they - cache RRs. The TTL describes how long a RR can be cached before it - should be discarded. The following three types of TTL are - currently - used in a zone file. - - - - - - - - - - SOA - - - - - The last field in the SOA is the negative - caching TTL. This controls how long other servers will - cache no-such-domain - (NXDOMAIN) responses from you. - - - The maximum time for - negative caching is 3 hours (3h). - - - - - - - $TTL - - - - - The $TTL directive at the top of the - zone file (before the SOA) gives a default TTL for every - RR without - a specific TTL set. - - - - - - - RR TTLs - - - - - Each RR can have a TTL as the second - field in the RR, which will control how long other - servers can cache - the it. - - - - - - - - All of these TTLs default to units of seconds, though units - can be explicitly specified, for example, 1h30m. - - - - Inverse Mapping in IPv4 - - Reverse name resolution (that is, translation from IP address - to name) is achieved by means of the in-addr.arpa domain - and PTR records. Entries in the in-addr.arpa domain are made in - least-to-most significant order, read left to right. This is the - opposite order to the way IP addresses are usually written. Thus, - a machine with an IP address of 10.1.2.3 would have a - corresponding - in-addr.arpa name of - 3.2.1.10.in-addr.arpa. This name should have a PTR resource record - whose data field is the name of the machine or, optionally, - multiple - PTR records if the machine has more than one name. For example, - in the example.com domain: - - - - - - - - - - $ORIGIN - - - - - 2.1.10.in-addr.arpa - - - - - - - 3 - - - - - IN PTR foo.example.com. - - - - - - - - - The $ORIGIN lines in the examples - are for providing context to the examples only — they do not - necessarily - appear in the actual usage. They are only used here to indicate - that the example is relative to the listed origin. - - - - - Other Zone File Directives - - The Master File Format was initially defined in RFC 1035 and - has subsequently been extended. While the Master File Format - itself - is class independent all records in a Master File must be of the - same - class. - - - Master File Directives include $ORIGIN, $INCLUDE, - and $TTL. - - - The <command>$ORIGIN</command> Directive - - Syntax: $ORIGIN - domain-name - comment - - $ORIGIN - sets the domain name that will be appended to any - unqualified records. When a zone is first read in there - is an implicit $ORIGIN - <zone-name>. - The current $ORIGIN is appended to - the domain specified in the $ORIGIN - argument if it is not absolute. - - - -$ORIGIN example.com. -WWW CNAME MAIN-SERVER - - - - is equivalent to - - - -WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM. - - - - - The <command>$INCLUDE</command> Directive - - Syntax: $INCLUDE - filename - -origin - comment - - - Read and process the file filename as - if it were included into the file at this point. If origin is - specified the file is processed with $ORIGIN set - to that value, otherwise the current $ORIGIN is - used. - - - The origin and the current domain name - revert to the values they had prior to the $INCLUDE once - the file has been read. - - - - RFC 1035 specifies that the current origin should be restored - after - an $INCLUDE, but it is silent - on whether the current - domain name should also be restored. BIND 9 restores both of - them. - This could be construed as a deviation from RFC 1035, a - feature, or both. - - - - - The <command>$TTL</command> Directive - - Syntax: $TTL - default-ttl - -comment - - - Set the default Time To Live (TTL) for subsequent records - with undefined TTLs. Valid TTLs are of the range 0-2147483647 - seconds. - - $TTL - is defined in RFC 2308. - - - - - <acronym>BIND</acronym> Master File Extension: the <command>$GENERATE</command> Directive - - Syntax: $GENERATE - range - lhs - ttl - class - type - rhs - comment - - $GENERATE - is used to create a series of resource records that only - differ from each other by an - iterator. $GENERATE can be used to - easily generate the sets of records required to support - sub /24 reverse delegations described in RFC 2317: - Classless IN-ADDR.ARPA delegation. - - -$ORIGIN 0.0.192.IN-ADDR.ARPA. -$GENERATE 1-2 0 NS SERVER$.EXAMPLE. -$GENERATE 1-127 $ CNAME $.0 - - - is equivalent to - - -0.0.0.192.IN-ADDR.ARPA NS SERVER1.EXAMPLE. -0.0.0.192.IN-ADDR.ARPA. NS SERVER2.EXAMPLE. -1.0.0.192.IN-ADDR.ARPA. CNAME 1.0.0.0.192.IN-ADDR.ARPA. -2.0.0.192.IN-ADDR.ARPA. CNAME 2.0.0.0.192.IN-ADDR.ARPA. -... -127.0.0.192.IN-ADDR.ARPA. CNAME 127.0.0.0.192.IN-ADDR.ARPA. - - - - - - - - - - range - - - - This can be one of two forms: start-stop - or start-stop/step. If the first form is used, then step - is set to - 1. All of start, stop and step must be positive. - - - - - - lhs - - - This - describes the owner name of the resource records - to be created. Any single $ - (dollar sign) - symbols within the lhs side - are replaced by the iterator value. - - To get a $ in the output, you need to escape the - $ using a backslash - \, - e.g. \$. The - $ may optionally be followed - by modifiers which change the offset from the - iterator, field width and base. - - Modifiers are introduced by a - { (left brace) immediately following the - $ as - ${offset[,width[,base]]}. - For example, ${-20,3,d} - subtracts 20 from the current value, prints the - result as a decimal in a zero-padded field of - width 3. - - Available output forms are decimal - (d), octal - (o) and hexadecimal - (x or X - for uppercase). The default modifier is - ${0,0,d}. If the - lhs is not absolute, the - current $ORIGIN is appended - to the name. - - - For compatibility with earlier versions, $$ is still - recognized as indicating a literal $ in the output. - - - - - - ttl - - - - Specifies the time-to-live of the generated records. If - not specified this will be inherited using the - normal ttl inheritance rules. - - class - and ttl can be - entered in either order. - - - - - - class - - - - Specifies the class of the generated records. - This must match the zone class if it is - specified. - - class - and ttl can be - entered in either order. - - - - - - type - - - - At present the only supported types are - PTR, CNAME, DNAME, A, AAAA and NS. - - - - - - rhs - - - - rhs is a domain name. It is processed - similarly to lhs. - - - - - - - - The $GENERATE directive is a BIND extension - and not part of the standard zone file format. - - - BIND 8 does not support the optional TTL and CLASS fields. - - - - - Additional File Formats - - In addition to the standard textual format, BIND 9 - supports the ability to read or dump to zone files in - other formats. The raw format is - currently available as an additional format. It is a - binary format representing BIND 9's internal data - structure directly, thereby remarkably improving the - loading time. - - - For a primary server, a zone file in the - raw format is expected to be - generated from a textual zone file by the - named-compilezone command. For a - secondary server or for a dynamic zone, it is automatically - generated (if this format is specified by the - masterfile-format option) when - named dumps the zone contents after - zone transfer or when applying prior updates. - - - If a zone file in a binary format needs manual modification, - it first must be converted to a textual form by the - named-compilezone command. All - necessary modification should go to the text file, which - should then be converted to the binary form by the - named-compilezone command again. - - - Although the raw format uses the - network byte order and avoids architecture-dependent - data alignment so that it is as much portable as - possible, it is primarily expected to be used inside - the same single system. In order to export a zone - file in the raw format or make a - portable backup of the file, it is recommended to - convert the file to the standard textual representation. - - - - - - <acronym>BIND</acronym> 9 Security Considerations - - Access Control Lists - - Access Control Lists (ACLs), are address match lists that - you can set up and nickname for future use in allow-notify, - allow-query, allow-recursion, - blackhole, allow-transfer, - etc. - - - Using ACLs allows you to have finer control over who can access - your name server, without cluttering up your config files with huge - lists of IP addresses. - - - It is a good idea to use ACLs, and to - control access to your server. Limiting access to your server by - outside parties can help prevent spoofing and denial of service (DoS) attacks against - your server. - - - Here is an example of how to properly apply ACLs: - - - -// Set up an ACL named "bogusnets" that will block RFC1918 space -// and some reserved space, which is commonly used in spoofing attacks. -acl bogusnets { - 0.0.0.0/8; 1.0.0.0/8; 2.0.0.0/8; 192.0.2.0/24; 224.0.0.0/3; - 10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16; -}; - -// Set up an ACL called our-nets. Replace this with the real IP numbers. -acl our-nets { x.x.x.x/24; x.x.x.x/21; }; -options { - ... - ... - allow-query { our-nets; }; - allow-recursion { our-nets; }; - ... - blackhole { bogusnets; }; - ... -}; - -zone "example.com" { - type master; - file "m/example.com"; - allow-query { any; }; -}; - - - - This allows recursive queries of the server from the outside - unless recursion has been previously disabled. - - - For more information on how to use ACLs to protect your server, - see the AUSCERT advisory at: - - - ftp://ftp.auscert.org.au/pub/auscert/advisory/AL-1999.004.dns_dos - - - - <command>Chroot</command> and <command>Setuid</command> - - On UNIX servers, it is possible to run BIND in a chrooted environment - (using the chroot() function) by specifying the "" - option. This can help improve system security by placing BIND in - a "sandbox", which will limit the damage done if a server is - compromised. - - - Another useful feature in the UNIX version of BIND is the - ability to run the daemon as an unprivileged user ( user ). - We suggest running as an unprivileged user when using the chroot feature. - - - Here is an example command line to load BIND in a chroot sandbox, - /var/named, and to run named setuid to - user 202: - - - /usr/local/bin/named -u 202 -t /var/named - - - - The <command>chroot</command> Environment - - - In order for a chroot environment - to - work properly in a particular directory - (for example, /var/named), - you will need to set up an environment that includes everything - BIND needs to run. - From BIND's point of view, /var/named is - the root of the filesystem. You will need to adjust the values of - options like - like directory and pid-file to account - for this. - - - Unlike with earlier versions of BIND, you typically will - not need to compile named - statically nor install shared libraries under the new root. - However, depending on your operating system, you may need - to set up things like - /dev/zero, - /dev/random, - /dev/log, and - /etc/localtime. - - - - - Using the <command>setuid</command> Function - - - Prior to running the named daemon, - use - the touch utility (to change file - access and - modification times) or the chown - utility (to - set the user id and/or group id) on files - to which you want BIND - to write. - - - Note that if the named daemon is running as an - unprivileged user, it will not be able to bind to new restricted - ports if the server is reloaded. - - - - - - Dynamic Update Security - - - Access to the dynamic - update facility should be strictly limited. In earlier versions of - BIND, the only way to do this was - based on the IP - address of the host requesting the update, by listing an IP address - or - network prefix in the allow-update - zone option. - This method is insecure since the source address of the update UDP - packet - is easily forged. Also note that if the IP addresses allowed by the - allow-update option include the - address of a slave - server which performs forwarding of dynamic updates, the master can - be - trivially attacked by sending the update to the slave, which will - forward it to the master with its own source IP address causing the - master to approve it without question. - - - - For these reasons, we strongly recommend that updates be - cryptographically authenticated by means of transaction signatures - (TSIG). That is, the allow-update - option should - list only TSIG key names, not IP addresses or network - prefixes. Alternatively, the new update-policy - option can be used. - - - - Some sites choose to keep all dynamically-updated DNS data - in a subdomain and delegate that subdomain to a separate zone. This - way, the top-level zone containing critical data such as the IP - addresses - of public web and mail servers need not allow dynamic update at - all. - - - - - - - Troubleshooting - - Common Problems - - It's not working; how can I figure out what's wrong? - - - The best solution to solving installation and - configuration issues is to take preventative measures by setting - up logging files beforehand. The log files provide a - source of hints and information that can be used to figure out - what went wrong and how to fix the problem. - - - - - - Incrementing and Changing the Serial Number - - - Zone serial numbers are just numbers — they aren't - date related. A lot of people set them to a number that - represents a date, usually of the form YYYYMMDDRR. - Occasionally they will make a mistake and set them to a - "date in the future" then try to correct them by setting - them to the "current date". This causes problems because - serial numbers are used to indicate that a zone has been - updated. If the serial number on the slave server is - lower than the serial number on the master, the slave - server will attempt to update its copy of the zone. - - - - Setting the serial number to a lower number on the master - server than the slave server means that the slave will not perform - updates to its copy of the zone. - - - - The solution to this is to add 2147483647 (2^31-1) to the - number, reload the zone and make sure all slaves have updated to - the new zone serial number, then reset the number to what you want - it to be, and reload the zone again. - - - - - Where Can I Get Help? - - - The Internet Systems Consortium - (ISC) offers a wide range - of support and service agreements for BIND and DHCP servers. Four - levels of premium support are available and each level includes - support for all ISC programs, - significant discounts on products - and training, and a recognized priority on bug fixes and - non-funded feature requests. In addition, ISC offers a standard - support agreement package which includes services ranging from bug - fix announcements to remote support. It also includes training in - BIND and DHCP. - - - - To discuss arrangements for support, contact - info@isc.org or visit the - ISC web page at - http://www.isc.org/services/support/ - to read more. - - - - - Appendices - - Acknowledgments - - A Brief History of the <acronym>DNS</acronym> and <acronym>BIND</acronym> - - - Although the "official" beginning of the Domain Name - System occurred in 1984 with the publication of RFC 920, the - core of the new system was described in 1983 in RFCs 882 and - 883. From 1984 to 1987, the ARPAnet (the precursor to today's - Internet) became a testbed of experimentation for developing the - new naming/addressing scheme in a rapidly expanding, - operational network environment. New RFCs were written and - published in 1987 that modified the original documents to - incorporate improvements based on the working model. RFC 1034, - "Domain Names-Concepts and Facilities", and RFC 1035, "Domain - Names-Implementation and Specification" were published and - became the standards upon which all DNS implementations are - built. - - - - The first working domain name server, called "Jeeves", was - written in 1983-84 by Paul Mockapetris for operation on DEC - Tops-20 - machines located at the University of Southern California's - Information - Sciences Institute (USC-ISI) and SRI International's Network - Information - Center (SRI-NIC). A DNS server for - Unix machines, the Berkeley Internet - Name Domain (BIND) package, was - written soon after by a group of - graduate students at the University of California at Berkeley - under - a grant from the US Defense Advanced Research Projects - Administration - (DARPA). - - - Versions of BIND through - 4.8.3 were maintained by the Computer - Systems Research Group (CSRG) at UC Berkeley. Douglas Terry, Mark - Painter, David Riggle and Songnian Zhou made up the initial BIND - project team. After that, additional work on the software package - was done by Ralph Campbell. Kevin Dunlap, a Digital Equipment - Corporation - employee on loan to the CSRG, worked on BIND for 2 years, from 1985 - to 1987. Many other people also contributed to BIND development - during that time: Doug Kingston, Craig Partridge, Smoot - Carl-Mitchell, - Mike Muuss, Jim Bloom and Mike Schwartz. BIND maintenance was subsequently - handled by Mike Karels and Øivind Kure. - - - BIND versions 4.9 and 4.9.1 were - released by Digital Equipment - Corporation (now Compaq Computer Corporation). Paul Vixie, then - a DEC employee, became BIND's - primary caretaker. He was assisted - by Phil Almquist, Robert Elz, Alan Barrett, Paul Albitz, Bryan - Beecher, Andrew - Partan, Andy Cherenson, Tom Limoncelli, Berthold Paffrath, Fuat - Baran, Anant Kumar, Art Harkin, Win Treese, Don Lewis, Christophe - Wolfhugel, and others. - - - In 1994, BIND version 4.9.2 was sponsored by - Vixie Enterprises. Paul - Vixie became BIND's principal - architect/programmer. - - - BIND versions from 4.9.3 onward - have been developed and maintained - by the Internet Systems Consortium and its predecessor, - the Internet Software Consortium, with support being provided - by ISC's sponsors. - - - As co-architects/programmers, Bob Halley and - Paul Vixie released the first production-ready version of - BIND version 8 in May 1997. - - - BIND version 9 was released in September 2000 and is a - major rewrite of nearly all aspects of the underlying - BIND architecture. - - - BIND version 4 is officially deprecated and BIND version - 8 development is considered maintenance-only in favor - of BIND version 9. No additional development is done - on BIND version 4 or BIND version 8 other than for - security-related patches. - - - BIND development work is made - possible today by the sponsorship - of several corporations, and by the tireless work efforts of - numerous individuals. - - - - - General <acronym>DNS</acronym> Reference Information - - IPv6 addresses (AAAA) - - IPv6 addresses are 128-bit identifiers for interfaces and - sets of interfaces which were introduced in the DNS to facilitate - scalable Internet routing. There are three types of addresses: Unicast, - an identifier for a single interface; - Anycast, - an identifier for a set of interfaces; and Multicast, - an identifier for a set of interfaces. Here we describe the global - Unicast address scheme. For more information, see RFC 3587, - "Global Unicast Address Format." - - - IPv6 unicast addresses consist of a - global routing prefix, a - subnet identifier, and an - interface identifier. - - - The global routing prefix is provided by the - upstream provider or ISP, and (roughly) corresponds to the - IPv4 network section - of the address range. - - The subnet identifier is for local subnetting, much the - same as subnetting an - IPv4 /16 network into /24 subnets. - - The interface identifier is the address of an individual - interface on a given network; in IPv6, addresses belong to - interfaces rather than to machines. - - - The subnetting capability of IPv6 is much more flexible than - that of IPv4: subnetting can be carried out on bit boundaries, - in much the same way as Classless InterDomain Routing - (CIDR), and the DNS PTR representation ("nibble" format) - makes setting up reverse zones easier. - - - The Interface Identifier must be unique on the local link, - and is usually generated automatically by the IPv6 - implementation, although it is usually possible to - override the default setting if necessary. A typical IPv6 - address might look like: - 2001:db8:201:9:a00:20ff:fe81:2b32 - - - IPv6 address specifications often contain long strings - of zeros, so the architects have included a shorthand for - specifying - them. The double colon (`::') indicates the longest possible - string - of zeros that can fit, and can be used only once in an address. - - - - - Bibliography (and Suggested Reading) - - Request for Comments (RFCs) - - Specification documents for the Internet protocol suite, including - the DNS, are published as part of - the Request for Comments (RFCs) - series of technical notes. The standards themselves are defined - by the Internet Engineering Task Force (IETF) and the Internet - Engineering Steering Group (IESG). RFCs can be obtained online via FTP at: - - - - ftp://www.isi.edu/in-notes/RFCxxxx.txt - - - - (where xxxx is - the number of the RFC). RFCs are also available via the Web at: - - - http://www.ietf.org/rfc/. - - - - - Standards - - RFC974 - - Partridge - C. - - Mail Routing and the Domain System - January 1986 - - - RFC1034 - - Mockapetris - P.V. - - Domain Names — Concepts and Facilities - November 1987 - - - RFC1035 - - Mockapetris - P. V. - Domain Names — Implementation and - Specification - November 1987 - - - - - Proposed Standards - - - RFC2181 - - Elz - R., R. Bush - - Clarifications to the <acronym>DNS</acronym> - Specification - July 1997 - - - RFC2308 - - Andrews - M. - - Negative Caching of <acronym>DNS</acronym> - Queries - March 1998 - - - RFC1995 - - Ohta - M. - - Incremental Zone Transfer in <acronym>DNS</acronym> - August 1996 - - - RFC1996 - - Vixie - P. - - A Mechanism for Prompt Notification of Zone Changes - August 1996 - - - RFC2136 - - - Vixie - P. - - - S. - Thomson - - - Y. - Rekhter - - - J. - Bound - - - Dynamic Updates in the Domain Name System - April 1997 - - - RFC2671 - - - P. - Vixie - - - Extension Mechanisms for DNS (EDNS0) - August 1997 - - - RFC2672 - - - M. - Crawford - - - Non-Terminal DNS Name Redirection - August 1999 - - - RFC2845 - - - Vixie - P. - - - O. - Gudmundsson - - - D. - Eastlake - 3rd - - - B. - Wellington - - - Secret Key Transaction Authentication for <acronym>DNS</acronym> (TSIG) - May 2000 - - - RFC2930 - - - D. - Eastlake - 3rd - - - Secret Key Establishment for DNS (TKEY RR) - September 2000 - - - RFC2931 - - - D. - Eastlake - 3rd - - - DNS Request and Transaction Signatures (SIG(0)s) - September 2000 - - - RFC3007 - - - B. - Wellington - - - Secure Domain Name System (DNS) Dynamic Update - November 2000 - - - RFC3645 - - - S. - Kwan - - - P. - Garg - - - J. - Gilroy - - - L. - Esibov - - - J. - Westhead - - - R. - Hall - - - Generic Security Service Algorithm for Secret - Key Transaction Authentication for DNS - (GSS-TSIG) - October 2003 - - - - <acronym>DNS</acronym> Security Proposed Standards - - RFC3225 - - - D. - Conrad - - - Indicating Resolver Support of DNSSEC - December 2001 - - - RFC3833 - - - D. - Atkins - - - R. - Austein - - - Threat Analysis of the Domain Name System (DNS) - August 2004 - - - RFC4033 - - - R. - Arends - - - R. - Austein - - - M. - Larson - - - D. - Massey - - - S. - Rose - - - DNS Security Introduction and Requirements - March 2005 - - - RFC4044 - - - R. - Arends - - - R. - Austein - - - M. - Larson - - - D. - Massey - - - S. - Rose - - - Resource Records for the DNS Security Extensions - March 2005 - - - RFC4035 - - - R. - Arends - - - R. - Austein - - - M. - Larson - - - D. - Massey - - - S. - Rose - - - Protocol Modifications for the DNS - Security Extensions - March 2005 - - - - Other Important RFCs About <acronym>DNS</acronym> - Implementation - - RFC1535 - - Gavron - E. - - A Security Problem and Proposed Correction With Widely - Deployed <acronym>DNS</acronym> Software. - October 1993 - - - RFC1536 - - - Kumar - A. - - - J. - Postel - - - C. - Neuman - - - P. - Danzig - - - S. - Miller - - - Common <acronym>DNS</acronym> Implementation - Errors and Suggested Fixes - October 1993 - - - RFC1982 - - - Elz - R. - - - R. - Bush - - - Serial Number Arithmetic - August 1996 - - - RFC4074 - - - Morishita - Y. - - - T. - Jinmei - - - Common Misbehaviour Against <acronym>DNS</acronym> - Queries for IPv6 Addresses - May 2005 - - - - Resource Record Types - - RFC1183 - - - Everhart - C.F. - - - L. A. - Mamakos - - - R. - Ullmann - - - P. - Mockapetris - - - New <acronym>DNS</acronym> RR Definitions - October 1990 - - - RFC1706 - - - Manning - B. - - - R. - Colella - - - <acronym>DNS</acronym> NSAP Resource Records - October 1994 - - - RFC2168 - - - Daniel - R. - - - M. - Mealling - - - Resolution of Uniform Resource Identifiers using - the Domain Name System - June 1997 - - - RFC1876 - - - Davis - C. - - - P. - Vixie - - - T. - Goodwin - - - I. - Dickinson - - - A Means for Expressing Location Information in the - Domain - Name System - January 1996 - - - RFC2052 - - - Gulbrandsen - A. - - - P. - Vixie - - - A <acronym>DNS</acronym> RR for Specifying the - Location of - Services. - October 1996 - - - RFC2163 - - Allocchio - A. - - Using the Internet <acronym>DNS</acronym> to - Distribute MIXER - Conformant Global Address Mapping - January 1998 - - - RFC2230 - - Atkinson - R. - - Key Exchange Delegation Record for the <acronym>DNS</acronym> - October 1997 - - - RFC2536 - - Eastlake - D. - 3rd - - DSA KEYs and SIGs in the Domain Name System (DNS) - March 1999 - - - RFC2537 - - Eastlake - D. - 3rd - - RSA/MD5 KEYs and SIGs in the Domain Name System (DNS) - March 1999 - - - RFC2538 - - - Eastlake - D. - 3rd - - - Gudmundsson - O. - - - Storing Certificates in the Domain Name System (DNS) - March 1999 - - - RFC2539 - - - Eastlake - D. - 3rd - - - Storage of Diffie-Hellman Keys in the Domain Name System (DNS) - March 1999 - - - RFC2540 - - - Eastlake - D. - 3rd - - - Detached Domain Name System (DNS) Information - March 1999 - - - RFC2782 - - Gulbrandsen - A. - - - Vixie - P. - - - Esibov - L. - - A DNS RR for specifying the location of services (DNS SRV) - February 2000 - - - RFC2915 - - Mealling - M. - - - Daniel - R. - - The Naming Authority Pointer (NAPTR) DNS Resource Record - September 2000 - - - RFC3110 - - Eastlake - D. - 3rd - - RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS) - May 2001 - - - RFC3123 - - Koch - P. - - A DNS RR Type for Lists of Address Prefixes (APL RR) - June 2001 - - - RFC3596 - - - Thomson - S. - - - C. - Huitema - - - V. - Ksinant - - - M. - Souissi - - - <acronym>DNS</acronym> Extensions to support IP - version 6 - October 2003 - - - RFC3597 - - Gustafsson - A. - - Handling of Unknown DNS Resource Record (RR) Types - September 2003 - - - - <acronym>DNS</acronym> and the Internet - - RFC1101 - - Mockapetris - P. V. - - <acronym>DNS</acronym> Encoding of Network Names - and Other Types - April 1989 - - - RFC1123 - - Braden - R. - - Requirements for Internet Hosts - Application and - Support - October 1989 - - - RFC1591 - - Postel - J. - - Domain Name System Structure and Delegation - March 1994 - - - RFC2317 - - - Eidnes - H. - - - G. - de Groot - - - P. - Vixie - - - Classless IN-ADDR.ARPA Delegation - March 1998 - - - RFC2826 - - - Internet Architecture Board - - - IAB Technical Comment on the Unique DNS Root - May 2000 - - - RFC2929 - - - Eastlake - D. - 3rd - - - Brunner-Williams - E. - - - Manning - B. - - - Domain Name System (DNS) IANA Considerations - September 2000 - - - - <acronym>DNS</acronym> Operations - - RFC1033 - - Lottor - M. - - Domain administrators operations guide. - November 1987 - - - RFC1537 - - Beertema - P. - - Common <acronym>DNS</acronym> Data File - Configuration Errors - October 1993 - - - RFC1912 - - Barr - D. - - Common <acronym>DNS</acronym> Operational and - Configuration Errors - February 1996 - - - RFC2010 - - - Manning - B. - - - P. - Vixie - - - Operational Criteria for Root Name Servers. - October 1996 - - - RFC2219 - - - Hamilton - M. - - - R. - Wright - - - Use of <acronym>DNS</acronym> Aliases for - Network Services. - October 1997 - - - - Internationalized Domain Names - - RFC2825 - - - IAB - - - Daigle - R. - - - A Tangled Web: Issues of I18N, Domain Names, - and the Other Internet protocols - May 2000 - - - RFC3490 - - - Faltstrom - P. - - - Hoffman - P. - - - Costello - A. - - - Internationalizing Domain Names in Applications (IDNA) - March 2003 - - - RFC3491 - - - Hoffman - P. - - - Blanchet - M. - - - Nameprep: A Stringprep Profile for Internationalized Domain Names - March 2003 - - - RFC3492 - - - Costello - A. - - - Punycode: A Bootstring encoding of Unicode - for Internationalized Domain Names in - Applications (IDNA) - March 2003 - - - - Other <acronym>DNS</acronym>-related RFCs - - - Note: the following list of RFCs, although - DNS-related, are not - concerned with implementing software. - - - - RFC1464 - - Rosenbaum - R. - - Using the Domain Name System To Store Arbitrary String - Attributes - May 1993 - - - RFC1713 - - Romao - A. - - Tools for <acronym>DNS</acronym> Debugging - November 1994 - - - RFC1794 - - Brisco - T. - - <acronym>DNS</acronym> Support for Load - Balancing - April 1995 - - - RFC2240 - - Vaughan - O. - - A Legal Basis for Domain Name Allocation - November 1997 - - - RFC2345 - - - Klensin - J. - - - T. - Wolf - - - G. - Oglesby - - - Domain Names and Company Name Retrieval - May 1998 - - - RFC2352 - - Vaughan - O. - - A Convention For Using Legal Names as Domain Names - May 1998 - - - RFC3071 - - - Klensin - J. - - - Reflections on the DNS, RFC 1591, and Categories of Domains - February 2001 - - - RFC3258 - - - Hardie - T. - - - Distributing Authoritative Name Servers via - Shared Unicast Addresses - April 2002 - - - RFC3901 - - - Durand - A. - - - J. - Ihren - - - DNS IPv6 Transport Operational Guidelines - September 2004 - - - - Obsolete and Unimplemented Experimental RFC - - RFC1712 - - - Farrell - C. - - - M. - Schulze - - - S. - Pleitner - - - D. - Baldoni - - - <acronym>DNS</acronym> Encoding of Geographical - Location - November 1994 - - - RFC2673 - - - Crawford - M. - - - Binary Labels in the Domain Name System - August 1999 - - - RFC2874 - - - Crawford - M. - - - Huitema - C. - - - DNS Extensions to Support IPv6 Address Aggregation - and Renumbering - July 2000 - - - - Obsoleted DNS Security RFCs - - - Most of these have been consolidated into RFC4033, - RFC4034 and RFC4035 which collectively describe DNSSECbis. - - - - RFC2065 - - - Eastlake - 3rd - D. - - - C. - Kaufman - - - Domain Name System Security Extensions - January 1997 - - - RFC2137 - - Eastlake - 3rd - D. - - Secure Domain Name System Dynamic Update - April 1997 - - - RFC2535 - - - Eastlake - 3rd - D. - - - Domain Name System Security Extensions - March 1999 - - - RFC3008 - - - Wellington - B. - - - Domain Name System Security (DNSSEC) - Signing Authority - November 2000 - - - RFC3090 - - - Lewis - E. - - - DNS Security Extension Clarification on Zone Status - March 2001 - - - RFC3445 - - - Massey - D. - - - Rose - S. - - - Limiting the Scope of the KEY Resource Record (RR) - December 2002 - - - RFC3655 - - - Wellington - B. - - - Gudmundsson - O. - - - Redefinition of DNS Authenticated Data (AD) bit - November 2003 - - - RFC3658 - - - Gudmundsson - O. - - - Delegation Signer (DS) Resource Record (RR) - December 2003 - - - RFC3755 - - - Weiler - S. - - - Legacy Resolver Compatibility for Delegation Signer (DS) - May 2004 - - - RFC3757 - - - Kolkman - O. - - - Schlyter - J. - - - Lewis - E. - - - Domain Name System KEY (DNSKEY) Resource Record - (RR) Secure Entry Point (SEP) Flag - April 2004 - - - RFC3845 - - - Schlyter - J. - - - DNS Security (DNSSEC) NextSECure (NSEC) RDATA Format - August 2004 - - - - - - Internet Drafts - - Internet Drafts (IDs) are rough-draft working documents of - the Internet Engineering Task Force. They are, in essence, RFCs - in the preliminary stages of development. Implementors are - cautioned not - to regard IDs as archival, and they should not be quoted or cited - in any formal documents unless accompanied by the disclaimer that - they are "works in progress." IDs have a lifespan of six months - after which they are deleted unless updated by their authors. - - - - Other Documents About <acronym>BIND</acronym> - - - - - - Albitz - Paul - - - Cricket - Liu - - - <acronym>DNS</acronym> and <acronym>BIND</acronym> - - 1998 - Sebastopol, CA: O'Reilly and Associates - - - - - - - - - Manual pages - - - - - - - - - - - - - - - - - diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch01.html b/contrib/bind9/doc/arm/Bv9ARM.ch01.html deleted file mode 100644 index 30e9e0d..0000000 --- a/contrib/bind9/doc/arm/Bv9ARM.ch01.html +++ /dev/null @@ -1,560 +0,0 @@ - - - - - -Chapter 1. Introduction - - - - - - - - -
-

-Chapter 1. Introduction

- -

- The Internet Domain Name System (DNS) - consists of the syntax - to specify the names of entities in the Internet in a hierarchical - manner, the rules used for delegating authority over names, and the - system implementation that actually maps names to Internet - addresses. DNS data is maintained in a - group of distributed - hierarchical databases. -

-
-

-Scope of Document

-

- The Berkeley Internet Name Domain - (BIND) implements a - domain name server for a number of operating systems. This - document provides basic information about the installation and - care of the Internet Systems Consortium (ISC) - BIND version 9 software package for - system administrators. -

-

- This version of the manual corresponds to BIND version 9.4. -

-
-
-

-Organization of This Document

-

- In this document, Section 1 introduces - the basic DNS and BIND concepts. Section 2 - describes resource requirements for running BIND in various - environments. Information in Section 3 is - task-oriented in its presentation and is - organized functionally, to aid in the process of installing the - BIND 9 software. The task-oriented - section is followed by - Section 4, which contains more advanced - concepts that the system administrator may need for implementing - certain options. Section 5 - describes the BIND 9 lightweight - resolver. The contents of Section 6 are - organized as in a reference manual to aid in the ongoing - maintenance of the software. Section 7 addresses - security considerations, and - Section 8 contains troubleshooting help. The - main body of the document is followed by several - appendices which contain useful reference - information, such as a bibliography and - historic information related to BIND - and the Domain Name - System. -

-
-
-

-Conventions Used in This Document

-

- In this document, we use the following general typographic - conventions: -

-
---- - - - - - - - - - - - - - - - - - - -
-

- To describe: -

-
-

- We use the style: -

-
-

- a pathname, filename, URL, hostname, - mailing list name, or new term or concept -

-
-

- Fixed width -

-
-

- literal user - input -

-
-

- Fixed Width Bold -

-
-

- program output -

-
-

- Fixed Width -

-
-

- The following conventions are used in descriptions of the - BIND configuration file:

-
---- - - - - - - - - - - - - - - - - - - -
-

- To describe: -

-
-

- We use the style: -

-
-

- keywords -

-
-

- Fixed Width -

-
-

- variables -

-
-

- Fixed Width -

-
-

- Optional input -

-
-

- [Text is enclosed in square brackets] -

-
-

-

-
-
-

-The Domain Name System (DNS)

-

- The purpose of this document is to explain the installation - and upkeep of the BIND (Berkeley Internet - Name Domain) software package, and we - begin by reviewing the fundamentals of the Domain Name System - (DNS) as they relate to BIND. -

-
-

-DNS Fundamentals

-

- The Domain Name System (DNS) is a hierarchical, distributed - database. It stores information for mapping Internet host names to - IP - addresses and vice versa, mail routing information, and other data - used by Internet applications. -

-

- Clients look up information in the DNS by calling a - resolver library, which sends queries to one or - more name servers and interprets the responses. - The BIND 9 software distribution - contains a - name server, named, and two resolver - libraries, liblwres and libbind. -

-
-
-

-Domains and Domain Names

-

- The data stored in the DNS is identified by domain names that are organized as a tree according to - organizational or administrative boundaries. Each node of the tree, - called a domain, is given a label. The domain - name of the - node is the concatenation of all the labels on the path from the - node to the root node. This is represented - in written form as a string of labels listed from right to left and - separated by dots. A label need only be unique within its parent - domain. -

-

- For example, a domain name for a host at the - company Example, Inc. could be - ourhost.example.com, - where com is the - top level domain to which - ourhost.example.com belongs, - example is - a subdomain of com, and - ourhost is the - name of the host. -

-

- For administrative purposes, the name space is partitioned into - areas called zones, each starting at a node and - extending down to the leaf nodes or to nodes where other zones - start. - The data for each zone is stored in a name server, which answers queries about the zone using the - DNS protocol. -

-

- The data associated with each domain name is stored in the - form of resource records (RRs). - Some of the supported resource record types are described in - the section called “Types of Resource Records and When to Use Them”. -

-

- For more detailed information about the design of the DNS and - the DNS protocol, please refer to the standards documents listed in - the section called “Request for Comments (RFCs)”. -

-
-
-

-Zones

-

- To properly operate a name server, it is important to understand - the difference between a zone - and a domain. -

-

- As stated previously, a zone is a point of delegation in - the DNS tree. A zone consists of - those contiguous parts of the domain - tree for which a name server has complete information and over which - it has authority. It contains all domain names from a certain point - downward in the domain tree except those which are delegated to - other zones. A delegation point is marked by one or more - NS records in the - parent zone, which should be matched by equivalent NS records at - the root of the delegated zone. -

-

- For instance, consider the example.com - domain which includes names - such as host.aaa.example.com and - host.bbb.example.com even though - the example.com zone includes - only delegations for the aaa.example.com and - bbb.example.com zones. A zone can - map - exactly to a single domain, but could also include only part of a - domain, the rest of which could be delegated to other - name servers. Every name in the DNS - tree is a - domain, even if it is - terminal, that is, has no - subdomains. Every subdomain is a domain and - every domain except the root is also a subdomain. The terminology is - not intuitive and we suggest that you read RFCs 1033, 1034 and 1035 - to - gain a complete understanding of this difficult and subtle - topic. -

-

- Though BIND is called a "domain name - server", - it deals primarily in terms of zones. The master and slave - declarations in the named.conf file - specify - zones, not domains. When you ask some other site if it is willing to - be a slave server for your domain, you are - actually asking for slave service for some collection of zones. -

-
-
-

-Authoritative Name Servers

-

- Each zone is served by at least - one authoritative name server, - which contains the complete data for the zone. - To make the DNS tolerant of server and network failures, - most zones have two or more authoritative servers, on - different networks. -

-

- Responses from authoritative servers have the "authoritative - answer" (AA) bit set in the response packets. This makes them - easy to identify when debugging DNS configurations using tools like - dig (the section called “Diagnostic Tools”). -

-
-

-The Primary Master

-

- The authoritative server where the master copy of the zone - data is maintained is called the - primary master server, or simply the - primary. Typically it loads the zone - contents from some local file edited by humans or perhaps - generated mechanically from some other local file which is - edited by humans. This file is called the - zone file or - master file. -

-

- In some cases, however, the master file may not be edited - by humans at all, but may instead be the result of - dynamic update operations. -

-
-
-

-Slave Servers

-

- The other authoritative servers, the slave - servers (also known as secondary servers) - load - the zone contents from another server using a replication process - known as a zone transfer. Typically the data - are - transferred directly from the primary master, but it is also - possible - to transfer it from another slave. In other words, a slave server - may itself act as a master to a subordinate slave server. -

-
-
-

-Stealth Servers

-

- Usually all of the zone's authoritative servers are listed in - NS records in the parent zone. These NS records constitute - a delegation of the zone from the parent. - The authoritative servers are also listed in the zone file itself, - at the top level or apex - of the zone. You can list servers in the zone's top-level NS - records that are not in the parent's NS delegation, but you cannot - list servers in the parent's delegation that are not present at - the zone's top level. -

-

- A stealth server is a server that is - authoritative for a zone but is not listed in that zone's NS - records. Stealth servers can be used for keeping a local copy of - a - zone to speed up access to the zone's records or to make sure that - the - zone is available even if all the "official" servers for the zone - are - inaccessible. -

-

- A configuration where the primary master server itself is a - stealth server is often referred to as a "hidden primary" - configuration. One use for this configuration is when the primary - master - is behind a firewall and therefore unable to communicate directly - with the outside world. -

-
-
-
-

-Caching Name Servers

-

- The resolver libraries provided by most operating systems are - stub resolvers, meaning that they are not - capable of - performing the full DNS resolution process by themselves by talking - directly to the authoritative servers. Instead, they rely on a - local - name server to perform the resolution on their behalf. Such a - server - is called a recursive name server; it performs - recursive lookups for local clients. -

-

- To improve performance, recursive servers cache the results of - the lookups they perform. Since the processes of recursion and - caching are intimately connected, the terms - recursive server and - caching server are often used synonymously. -

-

- The length of time for which a record may be retained in - the cache of a caching name server is controlled by the - Time To Live (TTL) field associated with each resource record. -

-
-

-Forwarding

-

- Even a caching name server does not necessarily perform - the complete recursive lookup itself. Instead, it can - forward some or all of the queries - that it cannot satisfy from its cache to another caching name - server, - commonly referred to as a forwarder. -

-

- There may be one or more forwarders, - and they are queried in turn until the list is exhausted or an - answer - is found. Forwarders are typically used when you do not - wish all the servers at a given site to interact directly with the - rest of - the Internet servers. A typical scenario would involve a number - of internal DNS servers and an - Internet firewall. Servers unable - to pass packets through the firewall would forward to the server - that can do it, and that server would query the Internet DNS servers - on the internal server's behalf. -

-
-
-
-

-Name Servers in Multiple Roles

-

- The BIND name server can - simultaneously act as - a master for some zones, a slave for other zones, and as a caching - (recursive) server for a set of local clients. -

-

- However, since the functions of authoritative name service - and caching/recursive name service are logically separate, it is - often advantageous to run them on separate server machines. - - A server that only provides authoritative name service - (an authoritative-only server) can run with - recursion disabled, improving reliability and security. - - A server that is not authoritative for any zones and only provides - recursive service to local - clients (a caching-only server) - does not need to be reachable from the Internet at large and can - be placed inside a firewall. -

-
-
-
- - - diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch02.html b/contrib/bind9/doc/arm/Bv9ARM.ch02.html deleted file mode 100644 index cbf6c15..0000000 --- a/contrib/bind9/doc/arm/Bv9ARM.ch02.html +++ /dev/null @@ -1,158 +0,0 @@ - - - - - -Chapter 2. BIND Resource Requirements - - - - - - - - -
-

-Chapter 2. BIND Resource Requirements

- -
-

-Hardware requirements

-

- DNS hardware requirements have - traditionally been quite modest. - For many installations, servers that have been pensioned off from - active duty have performed admirably as DNS servers. -

-

- The DNSSEC features of BIND 9 - may prove to be quite - CPU intensive however, so organizations that make heavy use of these - features may wish to consider larger systems for these applications. - BIND 9 is fully multithreaded, allowing - full utilization of - multiprocessor systems for installations that need it. -

-
-
-

-CPU Requirements

-

- CPU requirements for BIND 9 range from - i486-class machines - for serving of static zones without caching, to enterprise-class - machines if you intend to process many dynamic updates and DNSSEC - signed zones, serving many thousands of queries per second. -

-
-
-

-Memory Requirements

-

- The memory of the server has to be large enough to fit the - cache and zones loaded off disk. The max-cache-size - option can be used to limit the amount of memory used by the cache, - at the expense of reducing cache hit rates and causing more DNS - traffic. - Additionally, if additional section caching - (the section called “Additional Section Caching”) is enabled, - the max-acache-size option can be used to - limit the amount - of memory used by the mechanism. - It is still good practice to have enough memory to load - all zone and cache data into memory — unfortunately, the best - way - to determine this for a given installation is to watch the name server - in operation. After a few weeks the server process should reach - a relatively stable size where entries are expiring from the cache as - fast as they are being inserted. -

-
-
-

-Name Server Intensive Environment Issues

-

- For name server intensive environments, there are two alternative - configurations that may be used. The first is where clients and - any second-level internal name servers query a main name server, which - has enough memory to build a large cache. This approach minimizes - the bandwidth used by external name lookups. The second alternative - is to set up second-level internal name servers to make queries - independently. - In this configuration, none of the individual machines needs to - have as much memory or CPU power as in the first alternative, but - this has the disadvantage of making many more external queries, - as none of the name servers share their cached data. -

-
-
-

-Supported Operating Systems

-

- ISC BIND 9 compiles and runs on a large - number - of Unix-like operating system and on NT-derived versions of - Microsoft Windows such as Windows 2000 and Windows XP. For an - up-to-date - list of supported systems, see the README file in the top level - directory - of the BIND 9 source distribution. -

-
-
- - - diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch03.html b/contrib/bind9/doc/arm/Bv9ARM.ch03.html deleted file mode 100644 index 18f2711..0000000 --- a/contrib/bind9/doc/arm/Bv9ARM.ch03.html +++ /dev/null @@ -1,808 +0,0 @@ - - - - - -Chapter 3. Name Server Configuration - - - - - - - - -
-

-Chapter 3. Name Server Configuration

- -

- In this section we provide some suggested configurations along - with guidelines for their use. We suggest reasonable values for - certain option settings. -

-
-

-Sample Configurations

-
-

-A Caching-only Name Server

-

- The following sample configuration is appropriate for a caching-only - name server for use by clients internal to a corporation. All - queries - from outside clients are refused using the allow-query - option. Alternatively, the same effect could be achieved using - suitable - firewall rules. -

-
-// Two corporate subnets we wish to allow queries from.
-acl corpnets { 192.168.4.0/24; 192.168.7.0/24; };
-options {
-     directory "/etc/namedb";           // Working directory
-     allow-query { corpnets; };
-};
-// Provide a reverse mapping for the loopback address 127.0.0.1
-zone "0.0.127.in-addr.arpa" {
-     type master;
-     file "localhost.rev";
-     notify no;
-};
-
-
-
-

-An Authoritative-only Name Server

-

- This sample configuration is for an authoritative-only server - that is the master server for "example.com" - and a slave for the subdomain "eng.example.com". -

-
-options {
-     directory "/etc/namedb";           // Working directory
-     allow-query-cache { none; };       // Do not allow access to cache
-     allow-query { any; };              // This is the default
-     recursion no;                      // Do not provide recursive service
-};
-
-// Provide a reverse mapping for the loopback address 127.0.0.1
-zone "0.0.127.in-addr.arpa" {
-     type master;
-     file "localhost.rev";
-     notify no;
-};
-// We are the master server for example.com
-zone "example.com" {
-     type master;
-     file "example.com.db";
-     // IP addresses of slave servers allowed to transfer example.com
-     allow-transfer {
-          192.168.4.14;
-          192.168.5.53;
-     };
-};
-// We are a slave server for eng.example.com
-zone "eng.example.com" {
-     type slave;
-     file "eng.example.com.bk";
-     // IP address of eng.example.com master server
-     masters { 192.168.4.12; };
-};
-
-
-
-
-

-Load Balancing

-

- A primitive form of load balancing can be achieved in - the DNS by using multiple records - (such as multiple A records) for one name. -

-

- For example, if you have three WWW servers with network addresses - of 10.0.0.1, 10.0.0.2 and 10.0.0.3, a set of records such as the - following means that clients will connect to each machine one third - of the time: -

-
------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

- Name -

-
-

- TTL -

-
-

- CLASS -

-
-

- TYPE -

-
-

- Resource Record (RR) Data -

-
-

- www -

-
-

- 600 -

-
-

- IN -

-
-

- A -

-
-

- 10.0.0.1 -

-
-

-
-

- 600 -

-
-

- IN -

-
-

- A -

-
-

- 10.0.0.2 -

-
-

-
-

- 600 -

-
-

- IN -

-
-

- A -

-
-

- 10.0.0.3 -

-
-

- When a resolver queries for these records, BIND will rotate - them and respond to the query with the records in a different - order. In the example above, clients will randomly receive - records in the order 1, 2, 3; 2, 3, 1; and 3, 1, 2. Most clients - will use the first record returned and discard the rest. -

-

- For more detail on ordering responses, check the - rrset-order substatement in the - options statement, see - RRset Ordering. -

-
-
-

-Name Server Operations

-
-

-Tools for Use With the Name Server Daemon

-

- This section describes several indispensable diagnostic, - administrative and monitoring tools available to the system - administrator for controlling and debugging the name server - daemon. -

-
-

-Diagnostic Tools

-

- The dig, host, and - nslookup programs are all command - line tools - for manually querying name servers. They differ in style and - output format. -

-
-
dig
-
-

- The domain information groper (dig) - is the most versatile and complete of these lookup tools. - It has two modes: simple interactive - mode for a single query, and batch mode which executes a - query for - each in a list of several query lines. All query options are - accessible - from the command line. -

-

dig [@server] domain [query-type] [query-class] [+query-option] [-dig-option] [%comment]

-

- The usual simple use of dig will take the form -

-

- dig @server domain query-type query-class -

-

- For more information and a list of available commands and - options, see the dig man - page. -

-
-
host
-
-

- The host utility emphasizes - simplicity - and ease of use. By default, it converts - between host names and Internet addresses, but its - functionality - can be extended with the use of options. -

-

host [-aCdlnrsTwv] [-c class] [-N ndots] [-t type] [-W timeout] [-R retries] [-m flag] [-4] [-6] hostname [server]

-

- For more information and a list of available commands and - options, see the host man - page. -

-
-
nslookup
-
-

nslookup - has two modes: interactive and - non-interactive. Interactive mode allows the user to - query name servers for information about various - hosts and domains or to print a list of hosts in a - domain. Non-interactive mode is used to print just - the name and requested information for a host or - domain. -

-

nslookup [-option...] [[host-to-find] | [- [server]]]

-

- Interactive mode is entered when no arguments are given (the - default name server will be used) or when the first argument - is a - hyphen (`-') and the second argument is the host name or - Internet address - of a name server. -

-

- Non-interactive mode is used when the name or Internet - address - of the host to be looked up is given as the first argument. - The - optional second argument specifies the host name or address - of a name server. -

-

- Due to its arcane user interface and frequently inconsistent - behavior, we do not recommend the use of nslookup. - Use dig instead. -

-
-
-
-
-

-Administrative Tools

-

- Administrative tools play an integral part in the management - of a server. -

-
-
-named-checkconf -
-
-

- The named-checkconf program - checks the syntax of a named.conf file. -

-

named-checkconf [-jvz] [-t directory] [filename]

-
-
-named-checkzone -
-
-

- The named-checkzone program - checks a master file for - syntax and consistency. -

-

named-checkzone [-djqvD] [-c class] [-o output] [-t directory] [-w directory] [-k (ignore|warn|fail)] [-n (ignore|warn|fail)] [-W (ignore|warn)] zone [filename]

-
-
-named-compilezone -
-

- Similar to named-checkzone, but - it always dumps the zone content to a specified file - (typically in a different format). -

-
-rndc -
-
-

- The remote name daemon control - (rndc) program allows the - system - administrator to control the operation of a name server. - Since BIND 9.2, rndc - supports all the commands of the BIND 8 ndc - utility except ndc start and - ndc restart, which were also - not supported in ndc's - channel mode. - If you run rndc without any - options - it will display a usage message as follows: -

-

rndc [-c config] [-s server] [-p port] [-y key] command [command...]

-

The command - is one of the following: -

-
-
reload
-

- Reload configuration file and zones. -

-
reload zone - [class - [view]]
-

- Reload the given zone. -

-
refresh zone - [class - [view]]
-

- Schedule zone maintenance for the given zone. -

-
retransfer zone - - [class - [view]]
-

- Retransfer the given zone from the master. -

-
freeze - [zone - [class - [view]]]
-

- Suspend updates to a dynamic zone. If no zone is - specified, - then all zones are suspended. This allows manual - edits to be made to a zone normally updated by dynamic - update. It - also causes changes in the journal file to be synced - into the master - and the journal file to be removed. All dynamic - update attempts will - be refused while the zone is frozen. -

-
thaw - [zone - [class - [view]]]
-

- Enable updates to a frozen dynamic zone. If no zone - is - specified, then all frozen zones are enabled. This - causes - the server to reload the zone from disk, and - re-enables dynamic updates - after the load has completed. After a zone is thawed, - dynamic updates - will no longer be refused. -

-
notify zone - [class - [view]]
-

- Resend NOTIFY messages for the zone. -

-
reconfig
-

- Reload the configuration file and load new zones, - but do not reload existing zone files even if they - have changed. - This is faster than a full reload when there - is a large number of zones because it avoids the need - to examine the - modification times of the zones files. -

-
stats
-

- Write server statistics to the statistics file. -

-
querylog
-

- Toggle query logging. Query logging can also be enabled - by explicitly directing the queries - category to a - channel in the - logging section of - named.conf or by specifying - querylog yes; in the - options section of - named.conf. -

-
dumpdb - [-all|-cache|-zone] - [view ...]
-

- Dump the server's caches (default) and/or zones to - the - dump file for the specified views. If no view is - specified, all - views are dumped. -

-
stop [-p]
-

- Stop the server, making sure any recent changes - made through dynamic update or IXFR are first saved to - the master files of the updated zones. - If -p is specified named's process id is returned. - This allows an external process to determine when named - had completed stopping. -

-
halt [-p]
-

- Stop the server immediately. Recent changes - made through dynamic update or IXFR are not saved to - the master files, but will be rolled forward from the - journal files when the server is restarted. - If -p is specified named's process id is returned. - This allows an external process to determine when named - had completed halting. -

-
trace
-

- Increment the servers debugging level by one. -

-
trace level
-

- Sets the server's debugging level to an explicit - value. -

-
notrace
-

- Sets the server's debugging level to 0. -

-
flush
-

- Flushes the server's cache. -

-
flushname name
-

- Flushes the given name from the server's cache. -

-
status
-

- Display status of the server. - Note that the number of zones includes the internal bind/CH zone - and the default ./IN - hint zone if there is not an - explicit root zone configured. -

-
recursing
-

- Dump the list of queries named is currently recursing - on. -

-
-

- A configuration file is required, since all - communication with the server is authenticated with - digital signatures that rely on a shared secret, and - there is no way to provide that secret other than with a - configuration file. The default location for the - rndc configuration file is - /etc/rndc.conf, but an - alternate - location can be specified with the -c - option. If the configuration file is not found, - rndc will also look in - /etc/rndc.key (or whatever - sysconfdir was defined when - the BIND build was - configured). - The rndc.key file is - generated by - running rndc-confgen -a as - described in - the section called “controls Statement Definition and - Usage”. -

-

- The format of the configuration file is similar to - that of named.conf, but - limited to - only four statements, the options, - key, server and - include - statements. These statements are what associate the - secret keys to the servers with which they are meant to - be shared. The order of statements is not - significant. -

-

- The options statement has - three clauses: - default-server, default-key, - and default-port. - default-server takes a - host name or address argument and represents the server - that will - be contacted if no -s - option is provided on the command line. - default-key takes - the name of a key as its argument, as defined by a key statement. - default-port specifies the - port to which - rndc should connect if no - port is given on the command line or in a - server statement. -

-

- The key statement defines a - key to be used - by rndc when authenticating - with - named. Its syntax is - identical to the - key statement in named.conf. - The keyword key is - followed by a key name, which must be a valid - domain name, though it need not actually be hierarchical; - thus, - a string like "rndc_key" is a valid - name. - The key statement has two - clauses: - algorithm and secret. - While the configuration parser will accept any string as the - argument - to algorithm, currently only the string "hmac-md5" - has any meaning. The secret is a base-64 encoded string - as specified in RFC 3548. -

-

- The server statement - associates a key - defined using the key - statement with a server. - The keyword server is followed by a - host name or address. The server statement - has two clauses: key and port. - The key clause specifies the - name of the key - to be used when communicating with this server, and the - port clause can be used to - specify the port rndc should - connect - to on the server. -

-

- A sample minimal configuration file is as follows: -

-
-key rndc_key {
-     algorithm "hmac-md5";
-     secret "c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K";
-};
-options {
-     default-server 127.0.0.1;
-     default-key    rndc_key;
-};
-
-

- This file, if installed as /etc/rndc.conf, - would allow the command: -

-

- $ rndc reload -

-

- to connect to 127.0.0.1 port 953 and cause the name server - to reload, if a name server on the local machine were - running with - following controls statements: -

-
-controls {
-        inet 127.0.0.1 allow { localhost; } keys { rndc_key; };
-};
-
-

- and it had an identical key statement for - rndc_key. -

-

- Running the rndc-confgen - program will - conveniently create a rndc.conf - file for you, and also display the - corresponding controls - statement that you need to - add to named.conf. - Alternatively, - you can run rndc-confgen -a - to set up - a rndc.key file and not - modify - named.conf at all. -

-
-
-
-
-
-

-Signals

-

- Certain UNIX signals cause the name server to take specific - actions, as described in the following table. These signals can - be sent using the kill command. -

-
---- - - - - - - - - - - - - - - -
-

SIGHUP

-
-

- Causes the server to read named.conf and - reload the database. -

-
-

SIGTERM

-
-

- Causes the server to clean up and exit. -

-
-

SIGINT

-
-

- Causes the server to clean up and exit. -

-
-
-
-
- - - diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch04.html b/contrib/bind9/doc/arm/Bv9ARM.ch04.html deleted file mode 100644 index 09507fe..0000000 --- a/contrib/bind9/doc/arm/Bv9ARM.ch04.html +++ /dev/null @@ -1,1028 +0,0 @@ - - - - - -Chapter 4. Advanced DNS Features - - - - - - - - -
-

-Chapter 4. Advanced DNS Features

- -
-

-Notify

-

- DNS NOTIFY is a mechanism that allows master - servers to notify their slave servers of changes to a zone's data. In - response to a NOTIFY from a master server, the - slave will check to see that its version of the zone is the - current version and, if not, initiate a zone transfer. -

-

- For more information about DNS - NOTIFY, see the description of the - notify option in the section called “Boolean Options” and - the description of the zone option also-notify in - the section called “Zone Transfers”. The NOTIFY - protocol is specified in RFC 1996. -

-
-

Note

- As a slave zone can also be a master to other slaves, named, - by default, sends NOTIFY messages for every zone - it loads. Specifying notify master-only; will - cause named to only send NOTIFY for master - zones that it loads. -
-
-
-

-Dynamic Update

-

- Dynamic Update is a method for adding, replacing or deleting - records in a master server by sending it a special form of DNS - messages. The format and meaning of these messages is specified - in RFC 2136. -

-

- Dynamic update is enabled by - including an allow-update or - update-policy clause in the - zone statement. -

-

- Updating of secure zones (zones using DNSSEC) follows - RFC 3007: RRSIG and NSEC records affected by updates are automatically - regenerated by the server using an online zone key. - Update authorization is based - on transaction signatures and an explicit server policy. -

-
-

-The journal file

-

- All changes made to a zone using dynamic update are stored - in the zone's journal file. This file is automatically created - by the server when the first dynamic update takes place. - The name of the journal file is formed by appending the extension - .jnl to the name of the - corresponding zone - file unless specifically overridden. The journal file is in a - binary format and should not be edited manually. -

-

- The server will also occasionally write ("dump") - the complete contents of the updated zone to its zone file. - This is not done immediately after - each dynamic update, because that would be too slow when a large - zone is updated frequently. Instead, the dump is delayed by - up to 15 minutes, allowing additional updates to take place. -

-

- When a server is restarted after a shutdown or crash, it will replay - the journal file to incorporate into the zone any updates that - took - place after the last zone dump. -

-

- Changes that result from incoming incremental zone transfers are - also - journalled in a similar way. -

-

- The zone files of dynamic zones cannot normally be edited by - hand because they are not guaranteed to contain the most recent - dynamic changes — those are only in the journal file. - The only way to ensure that the zone file of a dynamic zone - is up to date is to run rndc stop. -

-

- If you have to make changes to a dynamic zone - manually, the following procedure will work: Disable dynamic updates - to the zone using - rndc freeze zone. - This will also remove the zone's .jnl file - and update the master file. Edit the zone file. Run - rndc thaw zone - to reload the changed zone and re-enable dynamic updates. -

-
-
-
-

-Incremental Zone Transfers (IXFR)

-

- The incremental zone transfer (IXFR) protocol is a way for - slave servers to transfer only changed data, instead of having to - transfer the entire zone. The IXFR protocol is specified in RFC - 1995. See Proposed Standards. -

-

- When acting as a master, BIND 9 - supports IXFR for those zones - where the necessary change history information is available. These - include master zones maintained by dynamic update and slave zones - whose data was obtained by IXFR. For manually maintained master - zones, and for slave zones obtained by performing a full zone - transfer (AXFR), IXFR is supported only if the option - ixfr-from-differences is set - to yes. -

-

- When acting as a slave, BIND 9 will - attempt to use IXFR unless - it is explicitly disabled. For more information about disabling - IXFR, see the description of the request-ixfr clause - of the server statement. -

-
-
-

-Split DNS

-

- Setting up different views, or visibility, of the DNS space to - internal and external resolvers is usually referred to as a - Split DNS setup. There are several - reasons an organization would want to set up its DNS this way. -

-

- One common reason for setting up a DNS system this way is - to hide "internal" DNS information from "external" clients on the - Internet. There is some debate as to whether or not this is actually - useful. - Internal DNS information leaks out in many ways (via email headers, - for example) and most savvy "attackers" can find the information - they need using other means. - However, since listing addresses of internal servers that - external clients cannot possibly reach can result in - connection delays and other annoyances, an organization may - choose to use a Split DNS to present a consistent view of itself - to the outside world. -

-

- Another common reason for setting up a Split DNS system is - to allow internal networks that are behind filters or in RFC 1918 - space (reserved IP space, as documented in RFC 1918) to resolve DNS - on the Internet. Split DNS can also be used to allow mail from outside - back in to the internal network. -

-
-

-Example split DNS setup

-

- Let's say a company named Example, Inc. - (example.com) - has several corporate sites that have an internal network with - reserved - Internet Protocol (IP) space and an external demilitarized zone (DMZ), - or "outside" section of a network, that is available to the public. -

-

- Example, Inc. wants its internal clients - to be able to resolve external hostnames and to exchange mail with - people on the outside. The company also wants its internal resolvers - to have access to certain internal-only zones that are not available - at all outside of the internal network. -

-

- In order to accomplish this, the company will set up two sets - of name servers. One set will be on the inside network (in the - reserved - IP space) and the other set will be on bastion hosts, which are - "proxy" - hosts that can talk to both sides of its network, in the DMZ. -

-

- The internal servers will be configured to forward all queries, - except queries for site1.internal, site2.internal, site1.example.com, - and site2.example.com, to the servers - in the - DMZ. These internal servers will have complete sets of information - for site1.example.com, site2.example.com, site1.internal, - and site2.internal. -

-

- To protect the site1.internal and site2.internal domains, - the internal name servers must be configured to disallow all queries - to these domains from any external hosts, including the bastion - hosts. -

-

- The external servers, which are on the bastion hosts, will - be configured to serve the "public" version of the site1 and site2.example.com zones. - This could include things such as the host records for public servers - (www.example.com and ftp.example.com), - and mail exchange (MX) records (a.mx.example.com and b.mx.example.com). -

-

- In addition, the public site1 and site2.example.com zones - should have special MX records that contain wildcard (`*') records - pointing to the bastion hosts. This is needed because external mail - servers do not have any other way of looking up how to deliver mail - to those internal hosts. With the wildcard records, the mail will - be delivered to the bastion host, which can then forward it on to - internal hosts. -

-

- Here's an example of a wildcard MX record: -

-
*   IN MX 10 external1.example.com.
-

- Now that they accept mail on behalf of anything in the internal - network, the bastion hosts will need to know how to deliver mail - to internal hosts. In order for this to work properly, the resolvers - on - the bastion hosts will need to be configured to point to the internal - name servers for DNS resolution. -

-

- Queries for internal hostnames will be answered by the internal - servers, and queries for external hostnames will be forwarded back - out to the DNS servers on the bastion hosts. -

-

- In order for all this to work properly, internal clients will - need to be configured to query only the internal - name servers for DNS queries. This could also be enforced via - selective - filtering on the network. -

-

- If everything has been set properly, Example, Inc.'s - internal clients will now be able to: -

-
    -
  • - Look up any hostnames in the site1 - and - site2.example.com zones. -
  • -
  • - Look up any hostnames in the site1.internal and - site2.internal domains. -
  • -
  • Look up any hostnames on the Internet.
  • -
  • Exchange mail with both internal and external people.
  • -
-

- Hosts on the Internet will be able to: -

-
    -
  • - Look up any hostnames in the site1 - and - site2.example.com zones. -
  • -
  • - Exchange mail with anyone in the site1 and - site2.example.com zones. -
  • -
-

- Here is an example configuration for the setup we just - described above. Note that this is only configuration information; - for information on how to configure your zone files, see the section called “Sample Configurations”. -

-

- Internal DNS server config: -

-
-
-acl internals { 172.16.72.0/24; 192.168.1.0/24; };
-
-acl externals { bastion-ips-go-here; };
-
-options {
-    ...
-    ...
-    forward only;
-    forwarders {                                // forward to external servers
-        bastion-ips-go-here;
-    };
-    allow-transfer { none; };                   // sample allow-transfer (no one)
-    allow-query { internals; externals; };      // restrict query access
-    allow-recursion { internals; };             // restrict recursion
-    ...
-    ...
-};
-
-zone "site1.example.com" {                      // sample master zone
-  type master;
-  file "m/site1.example.com";
-  forwarders { };                               // do normal iterative
-                                                // resolution (do not forward)
-  allow-query { internals; externals; };
-  allow-transfer { internals; };
-};
-
-zone "site2.example.com" {                      // sample slave zone
-  type slave;
-  file "s/site2.example.com";
-  masters { 172.16.72.3; };
-  forwarders { };
-  allow-query { internals; externals; };
-  allow-transfer { internals; };
-};
-
-zone "site1.internal" {
-  type master;
-  file "m/site1.internal";
-  forwarders { };
-  allow-query { internals; };
-  allow-transfer { internals; }
-};
-
-zone "site2.internal" {
-  type slave;
-  file "s/site2.internal";
-  masters { 172.16.72.3; };
-  forwarders { };
-  allow-query { internals };
-  allow-transfer { internals; }
-};
-
-

- External (bastion host) DNS server config: -

-
-acl internals { 172.16.72.0/24; 192.168.1.0/24; };
-
-acl externals { bastion-ips-go-here; };
-
-options {
-  ...
-  ...
-  allow-transfer { none; };                     // sample allow-transfer (no one)
-  allow-query { any; };                         // default query access
-  allow-query-cache { internals; externals; };  // restrict cache access
-  allow-recursion { internals; externals; };    // restrict recursion
-  ...
-  ...
-};
-
-zone "site1.example.com" {                      // sample slave zone
-  type master;
-  file "m/site1.foo.com";
-  allow-transfer { internals; externals; };
-};
-
-zone "site2.example.com" {
-  type slave;
-  file "s/site2.foo.com";
-  masters { another_bastion_host_maybe; };
-  allow-transfer { internals; externals; }
-};
-
-

- In the resolv.conf (or equivalent) on - the bastion host(s): -

-
-search ...
-nameserver 172.16.72.2
-nameserver 172.16.72.3
-nameserver 172.16.72.4
-
-
-
-
-

-TSIG

-

- This is a short guide to setting up Transaction SIGnatures - (TSIG) based transaction security in BIND. It describes changes - to the configuration file as well as what changes are required for - different features, including the process of creating transaction - keys and using transaction signatures with BIND. -

-

- BIND primarily supports TSIG for server - to server communication. - This includes zone transfer, notify, and recursive query messages. - Resolvers based on newer versions of BIND 8 have limited support - for TSIG. -

-

- TSIG can also be useful for dynamic update. A primary - server for a dynamic zone should control access to the dynamic - update service, but IP-based access control is insufficient. - The cryptographic access control provided by TSIG - is far superior. The nsupdate - program supports TSIG via the -k and - -y command line options or inline by use - of the key. -

-
-

-Generate Shared Keys for Each Pair of Hosts

-

- A shared secret is generated to be shared between host1 and host2. - An arbitrary key name is chosen: "host1-host2.". The key name must - be the same on both hosts. -

-
-

-Automatic Generation

-

- The following command will generate a 128-bit (16 byte) HMAC-MD5 - key as described above. Longer keys are better, but shorter keys - are easier to read. Note that the maximum key length is 512 bits; - keys longer than that will be digested with MD5 to produce a - 128-bit key. -

-

- dnssec-keygen -a hmac-md5 -b 128 -n HOST host1-host2. -

-

- The key is in the file Khost1-host2.+157+00000.private. - Nothing directly uses this file, but the base-64 encoded string - following "Key:" - can be extracted from the file and used as a shared secret: -

-
Key: La/E5CjG9O+os1jq0a2jdA==
-

- The string "La/E5CjG9O+os1jq0a2jdA==" can - be used as the shared secret. -

-
-
-

-Manual Generation

-

- The shared secret is simply a random sequence of bits, encoded - in base-64. Most ASCII strings are valid base-64 strings (assuming - the length is a multiple of 4 and only valid characters are used), - so the shared secret can be manually generated. -

-

- Also, a known string can be run through mmencode or - a similar program to generate base-64 encoded data. -

-
-
-
-

-Copying the Shared Secret to Both Machines

-

- This is beyond the scope of DNS. A secure transport mechanism - should be used. This could be secure FTP, ssh, telephone, etc. -

-
-
-

-Informing the Servers of the Key's Existence

-

- Imagine host1 and host 2 - are - both servers. The following is added to each server's named.conf file: -

-
-key host1-host2. {
-  algorithm hmac-md5;
-  secret "La/E5CjG9O+os1jq0a2jdA==";
-};
-
-

- The algorithm, hmac-md5, is the only one supported by BIND. - The secret is the one generated above. Since this is a secret, it - is recommended that either named.conf be non-world - readable, or the key directive be added to a non-world readable - file that is included by - named.conf. -

-

- At this point, the key is recognized. This means that if the - server receives a message signed by this key, it can verify the - signature. If the signature is successfully verified, the - response is signed by the same key. -

-
-
-

-Instructing the Server to Use the Key

-

- Since keys are shared between two hosts only, the server must - be told when keys are to be used. The following is added to the named.conf file - for host1, if the IP address of host2 is - 10.1.2.3: -

-
-server 10.1.2.3 {
-  keys { host1-host2. ;};
-};
-
-

- Multiple keys may be present, but only the first is used. - This directive does not contain any secrets, so it may be in a - world-readable - file. -

-

- If host1 sends a message that is a request - to that address, the message will be signed with the specified key. host1 will - expect any responses to signed messages to be signed with the same - key. -

-

- A similar statement must be present in host2's - configuration file (with host1's address) for host2 to - sign request messages to host1. -

-
-
-

-TSIG Key Based Access Control

-

- BIND allows IP addresses and ranges - to be specified in ACL - definitions and - allow-{ query | transfer | update } - directives. - This has been extended to allow TSIG keys also. The above key would - be denoted key host1-host2. -

-

- An example of an allow-update directive would be: -

-
-allow-update { key host1-host2. ;};
-
-

- This allows dynamic updates to succeed only if the request - was signed by a key named - "host1-host2.". -

-

- You may want to read about the more - powerful update-policy statement in the section called “Dynamic Update Policies”. -

-
-
-

-Errors

-

- The processing of TSIG signed messages can result in - several errors. If a signed message is sent to a non-TSIG aware - server, a FORMERR (format error) will be returned, since the server will not - understand the record. This is a result of misconfiguration, - since the server must be explicitly configured to send a TSIG - signed message to a specific server. -

-

- If a TSIG aware server receives a message signed by an - unknown key, the response will be unsigned with the TSIG - extended error code set to BADKEY. If a TSIG aware server - receives a message with a signature that does not validate, the - response will be unsigned with the TSIG extended error code set - to BADSIG. If a TSIG aware server receives a message with a time - outside of the allowed range, the response will be signed with - the TSIG extended error code set to BADTIME, and the time values - will be adjusted so that the response can be successfully - verified. In any of these cases, the message's rcode (response code) is set to - NOTAUTH (not authenticated). -

-
-
-
-

-TKEY

-

TKEY - is a mechanism for automatically generating a shared secret - between two hosts. There are several "modes" of - TKEY that specify how the key is generated - or assigned. BIND 9 implements only one of - these modes, the Diffie-Hellman key exchange. Both hosts are - required to have a Diffie-Hellman KEY record (although this - record is not required to be present in a zone). The - TKEY process must use signed messages, - signed either by TSIG or SIG(0). The result of - TKEY is a shared secret that can be used to - sign messages with TSIG. TKEY can also be - used to delete shared secrets that it had previously - generated. -

-

- The TKEY process is initiated by a - client - or server by sending a signed TKEY - query - (including any appropriate KEYs) to a TKEY-aware server. The - server response, if it indicates success, will contain a - TKEY record and any appropriate keys. - After - this exchange, both participants have enough information to - determine the shared secret; the exact process depends on the - TKEY mode. When using the - Diffie-Hellman - TKEY mode, Diffie-Hellman keys are - exchanged, - and the shared secret is derived by both participants. -

-
-
-

-SIG(0)

-

- BIND 9 partially supports DNSSEC SIG(0) - transaction signatures as specified in RFC 2535 and RFC2931. - SIG(0) - uses public/private keys to authenticate messages. Access control - is performed in the same manner as TSIG keys; privileges can be - granted or denied based on the key name. -

-

- When a SIG(0) signed message is received, it will only be - verified if the key is known and trusted by the server; the server - will not attempt to locate and/or validate the key. -

-

- SIG(0) signing of multiple-message TCP streams is not - supported. -

-

- The only tool shipped with BIND 9 that - generates SIG(0) signed messages is nsupdate. -

-
-
-

-DNSSEC

-

- Cryptographic authentication of DNS information is possible - through the DNS Security (DNSSEC-bis) extensions, - defined in RFC 4033, RFC 4034, and RFC 4035. - This section describes the creation and use of DNSSEC signed zones. -

-

- In order to set up a DNSSEC secure zone, there are a series - of steps which must be followed. BIND - 9 ships - with several tools - that are used in this process, which are explained in more detail - below. In all cases, the -h option prints a - full list of parameters. Note that the DNSSEC tools require the - keyset files to be in the working directory or the - directory specified by the -d option, and - that the tools shipped with BIND 9.2.x and earlier are not compatible - with the current ones. -

-

- There must also be communication with the administrators of - the parent and/or child zone to transmit keys. A zone's security - status must be indicated by the parent zone for a DNSSEC capable - resolver to trust its data. This is done through the presence - or absence of a DS record at the - delegation - point. -

-

- For other servers to trust data in this zone, they must - either be statically configured with this zone's zone key or the - zone key of another zone above this one in the DNS tree. -

-
-

-Generating Keys

-

- The dnssec-keygen program is used to - generate keys. -

-

- A secure zone must contain one or more zone keys. The - zone keys will sign all other records in the zone, as well as - the zone keys of any secure delegated zones. Zone keys must - have the same name as the zone, a name type of - ZONE, and must be usable for - authentication. - It is recommended that zone keys use a cryptographic algorithm - designated as "mandatory to implement" by the IETF; currently - the only one is RSASHA1. -

-

- The following command will generate a 768-bit RSASHA1 key for - the child.example zone: -

-

- dnssec-keygen -a RSASHA1 -b 768 -n ZONE child.example. -

-

- Two output files will be produced: - Kchild.example.+005+12345.key and - Kchild.example.+005+12345.private - (where - 12345 is an example of a key tag). The key filenames contain - the key name (child.example.), - algorithm (3 - is DSA, 1 is RSAMD5, 5 is RSASHA1, etc.), and the key tag (12345 in - this case). - The private key (in the .private - file) is - used to generate signatures, and the public key (in the - .key file) is used for signature - verification. -

-

- To generate another key with the same properties (but with - a different key tag), repeat the above command. -

-

- The public keys should be inserted into the zone file by - including the .key files using - $INCLUDE statements. -

-
-
-

-Signing the Zone

-

- The dnssec-signzone program is used - to - sign a zone. -

-

- Any keyset files corresponding - to secure subzones should be present. The zone signer will - generate NSEC and RRSIG - records for the zone, as well as DS - for - the child zones if '-d' is specified. - If '-d' is not specified, then - DS RRsets for - the secure child zones need to be added manually. -

-

- The following command signs the zone, assuming it is in a - file called zone.child.example. By - default, all zone keys which have an available private key are - used to generate signatures. -

-

- dnssec-signzone -o child.example zone.child.example -

-

- One output file is produced: - zone.child.example.signed. This - file - should be referenced by named.conf - as the - input file for the zone. -

-

dnssec-signzone - will also produce a keyset and dsset files and optionally a - dlvset file. These are used to provide the parent zone - administrators with the DNSKEYs (or their - corresponding DS records) that are the - secure entry point to the zone. -

-
-
-

-Configuring Servers

-

- To enable named to respond appropriately - to DNS requests from DNSSEC aware clients, - dnssec-enable must be set to yes. -

-

- To enable named to validate answers from - other servers both dnssec-enable and - dnssec-validation must be set and some - trusted-keys must be configured - into named.conf. -

-

- trusted-keys are copies of DNSKEY RRs - for zones that are used to form the first link in the - cryptographic chain of trust. All keys listed in - trusted-keys (and corresponding zones) - are deemed to exist and only the listed keys will be used - to validated the DNSKEY RRset that they are from. -

-

- trusted-keys are described in more detail - later in this document. -

-

- Unlike BIND 8, BIND - 9 does not verify signatures on load, so zone keys for - authoritative zones do not need to be specified in the - configuration file. -

-

- After DNSSEC gets established, a typical DNSSEC configuration - will look something like the following. It has a one or - more public keys for the root. This allows answers from - outside the organization to be validated. It will also - have several keys for parts of the namespace the organization - controls. These are here to ensure that named is immune - to compromises in the DNSSEC components of the security - of parent zones. -

-
-trusted-keys {
-
-        /* Root Key */
-"." 257 3 3 "BNY4wrWM1nCfJ+CXd0rVXyYmobt7sEEfK3clRbGaTwSJxrGkxJWoZu6I7PzJu/
-             E9gx4UC1zGAHlXKdE4zYIpRhaBKnvcC2U9mZhkdUpd1Vso/HAdjNe8LmMlnzY3
-             zy2Xy4klWOADTPzSv9eamj8V18PHGjBLaVtYvk/ln5ZApjYghf+6fElrmLkdaz
-             MQ2OCnACR817DF4BBa7UR/beDHyp5iWTXWSi6XmoJLbG9Scqc7l70KDqlvXR3M
-             /lUUVRbkeg1IPJSidmK3ZyCllh4XSKbje/45SKucHgnwU5jefMtq66gKodQj+M
-             iA21AfUVe7u99WzTLzY3qlxDhxYQQ20FQ97S+LKUTpQcq27R7AT3/V5hRQxScI
-             Nqwcz4jYqZD2fQdgxbcDTClU0CRBdiieyLMNzXG3";
-
-/* Key for our organization's forward zone */
-example.com. 257 3 5 "AwEAAaxPMcR2x0HbQV4WeZB6oEDX+r0QM65KbhTjrW1ZaARmPhEZZe
-                      3Y9ifgEuq7vZ/zGZUdEGNWy+JZzus0lUptwgjGwhUS1558Hb4JKUbb
-                      OTcM8pwXlj0EiX3oDFVmjHO444gLkBO UKUf/mC7HvfwYH/Be22GnC
-                      lrinKJp1Og4ywzO9WglMk7jbfW33gUKvirTHr25GL7STQUzBb5Usxt
-                      8lgnyTUHs1t3JwCY5hKZ6CqFxmAVZP20igTixin/1LcrgX/KMEGd/b
-                      iuvF4qJCyduieHukuY3H4XMAcR+xia2 nIUPvm/oyWR8BW/hWdzOvn
-                      SCThlHf3xiYleDbt/o1OTQ09A0=";
-
-/* Key for our reverse zone. */
-2.0.192.IN-ADDRPA.NET. 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwcxOdNax071L18QqZnQQQA
-                                VVr+iLhGTnNGp3HoWQLUIzKrJVZ3zggy3WwNT6kZo6c0
-                                tszYqbtvchmgQC8CzKojM/W16i6MG/ea fGU3siaOdS0
-                                yOI6BgPsw+YZdzlYMaIJGf4M4dyoKIhzdZyQ2bYQrjyQ
-                                4LB0lC7aOnsMyYKHHYeRv PxjIQXmdqgOJGq+vsevG06
-                                zW+1xgYJh9rCIfnm1GX/KMgxLPG2vXTD/RnLX+D3T3UL
-                                7HJYHJhAZD5L59VvjSPsZJHeDCUyWYrvPZesZDIRvhDD
-                                52SKvbheeTJUm6EhkzytNN2SN96QRk8j/iI8ib";
-};
-
-options {
-        ...
-        dnssec-enable yes;
-        dnssec-validation yes;
-};
-
-
-

Note

- None of the keys listed in this example are valid. In particular, - the root key is not valid. -
-
-
-
-

-IPv6 Support in BIND 9

-

- BIND 9 fully supports all currently - defined forms of IPv6 - name to address and address to name lookups. It will also use - IPv6 addresses to make queries when running on an IPv6 capable - system. -

-

- For forward lookups, BIND 9 supports - only AAAA records. RFC 3363 deprecated the use of A6 records, - and client-side support for A6 records was accordingly removed - from BIND 9. - However, authoritative BIND 9 name servers still - load zone files containing A6 records correctly, answer queries - for A6 records, and accept zone transfer for a zone containing A6 - records. -

-

- For IPv6 reverse lookups, BIND 9 supports - the traditional "nibble" format used in the - ip6.arpa domain, as well as the older, deprecated - ip6.int domain. - Older versions of BIND 9 - supported the "binary label" (also known as "bitstring") format, - but support of binary labels has been completely removed per - RFC 3363. - Many applications in BIND 9 do not understand - the binary label format at all any more, and will return an - error if given. - In particular, an authoritative BIND 9 - name server will not load a zone file containing binary labels. -

-

- For an overview of the format and structure of IPv6 addresses, - see the section called “IPv6 addresses (AAAA)”. -

-
-

-Address Lookups Using AAAA Records

-

- The IPv6 AAAA record is a parallel to the IPv4 A record, - and, unlike the deprecated A6 record, specifies the entire - IPv6 address in a single record. For example, -

-
-$ORIGIN example.com.
-host            3600    IN      AAAA    2001:db8::1
-
-

- Use of IPv4-in-IPv6 mapped addresses is not recommended. - If a host has an IPv4 address, use an A record, not - a AAAA, with ::ffff:192.168.42.1 as - the address. -

-
-
-

-Address to Name Lookups Using Nibble Format

-

- When looking up an address in nibble format, the address - components are simply reversed, just as in IPv4, and - ip6.arpa. is appended to the - resulting name. - For example, the following would provide reverse name lookup for - a host with address - 2001:db8::1. -

-
-$ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
-1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0   14400 IN      PTR     host.example.com.
-
-
-
-
- - - diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch05.html b/contrib/bind9/doc/arm/Bv9ARM.ch05.html deleted file mode 100644 index 80418b9..0000000 --- a/contrib/bind9/doc/arm/Bv9ARM.ch05.html +++ /dev/null @@ -1,143 +0,0 @@ - - - - - -Chapter 5. The BIND 9 Lightweight Resolver - - - - - - - - -
-

-Chapter 5. The BIND 9 Lightweight Resolver

- -
-

-The Lightweight Resolver Library

-

- Traditionally applications have been linked with a stub resolver - library that sends recursive DNS queries to a local caching name - server. -

-

- IPv6 once introduced new complexity into the resolution process, - such as following A6 chains and DNAME records, and simultaneous - lookup of IPv4 and IPv6 addresses. Though most of the complexity was - then removed, these are hard or impossible - to implement in a traditional stub resolver. -

-

- BIND 9 therefore can also provide resolution - services to local clients - using a combination of a lightweight resolver library and a resolver - daemon process running on the local host. These communicate using - a simple UDP-based protocol, the "lightweight resolver protocol" - that is distinct from and simpler than the full DNS protocol. -

-
-
-

-Running a Resolver Daemon

-

- To use the lightweight resolver interface, the system must - run the resolver daemon lwresd or a - local - name server configured with a lwres - statement. -

-

- By default, applications using the lightweight resolver library will - make - UDP requests to the IPv4 loopback address (127.0.0.1) on port 921. - The - address can be overridden by lwserver - lines in - /etc/resolv.conf. -

-

- The daemon currently only looks in the DNS, but in the future - it may use other sources such as /etc/hosts, - NIS, etc. -

-

- The lwresd daemon is essentially a - caching-only name server that responds to requests using the - lightweight - resolver protocol rather than the DNS protocol. Because it needs - to run on each host, it is designed to require no or minimal - configuration. - Unless configured otherwise, it uses the name servers listed on - nameserver lines in /etc/resolv.conf - as forwarders, but is also capable of doing the resolution - autonomously if - none are specified. -

-

- The lwresd daemon may also be - configured with a - named.conf style configuration file, - in - /etc/lwresd.conf by default. A name - server may also - be configured to act as a lightweight resolver daemon using the - lwres statement in named.conf. -

-
-
- - - diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch06.html b/contrib/bind9/doc/arm/Bv9ARM.ch06.html deleted file mode 100644 index d829a17..0000000 --- a/contrib/bind9/doc/arm/Bv9ARM.ch06.html +++ /dev/null @@ -1,7114 +0,0 @@ - - - - - -Chapter 6. BIND 9 Configuration Reference - - - - - - - - -
-

-Chapter 6. BIND 9 Configuration Reference

- -

- BIND 9 configuration is broadly similar - to BIND 8; however, there are a few new - areas - of configuration, such as views. BIND - 8 configuration files should work with few alterations in BIND - 9, although more complex configurations should be reviewed to check - if they can be more efficiently implemented using the new features - found in BIND 9. -

-

- BIND 4 configuration files can be - converted to the new format - using the shell script - contrib/named-bootconf/named-bootconf.sh. -

-
-

-Configuration File Elements

-

- Following is a list of elements used throughout the BIND configuration - file documentation: -

-
---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

- acl_name -

-
-

- The name of an address_match_list as - defined by the acl statement. -

-
-

- address_match_list -

-
-

- A list of one or more - ip_addr, - ip_prefix, key_id, - or acl_name elements, see - the section called “Address Match Lists”. -

-
-

- masters_list -

-
-

- A named list of one or more ip_addr - with optional key_id and/or - ip_port. - A masters_list may include other - masters_lists. -

-
-

- domain_name -

-
-

- A quoted string which will be used as - a DNS name, for example "my.test.domain". -

-
-

- dotted_decimal -

-
-

- One to four integers valued 0 through - 255 separated by dots (`.'), such as 123, - 45.67 or 89.123.45.67. -

-
-

- ip4_addr -

-
-

- An IPv4 address with exactly four elements - in dotted_decimal notation. -

-
-

- ip6_addr -

-
-

- An IPv6 address, such as 2001:db8::1234. - IPv6 scoped addresses that have ambiguity on their scope - zones must be - disambiguated by an appropriate zone ID with the percent - character - (`%') as delimiter. - It is strongly recommended to use string zone names rather - than - numeric identifiers, in order to be robust against system - configuration changes. - However, since there is no standard mapping for such names - and - identifier values, currently only interface names as link - identifiers - are supported, assuming one-to-one mapping between - interfaces and links. - For example, a link-local address fe80::1 on the - link attached to the interface ne0 - can be specified as fe80::1%ne0. - Note that on most systems link-local addresses always have - the - ambiguity, and need to be disambiguated. -

-
-

- ip_addr -

-
-

- An ip4_addr or ip6_addr. -

-
-

- ip_port -

-
-

- An IP port number. - The number is limited to 0 - through 65535, with values - below 1024 typically restricted to use by processes running - as root. - In some cases, an asterisk (`*') character can be used as a - placeholder to - select a random high-numbered port. -

-
-

- ip_prefix -

-
-

- An IP network specified as an ip_addr, - followed by a slash (`/') and then the number of bits in the - netmask. - Trailing zeros in a ip_addr - may omitted. - For example, 127/8 is the - network 127.0.0.0 with - netmask 255.0.0.0 and 1.2.3.0/28 is - network 1.2.3.0 with netmask 255.255.255.240. -

-
-

- key_id -

-
-

- A domain_name representing - the name of a shared key, to be used for transaction - security. -

-
-

- key_list -

-
-

- A list of one or more - key_ids, - separated by semicolons and ending with a semicolon. -

-
-

- number -

-
-

- A non-negative 32-bit integer - (i.e., a number between 0 and 4294967295, inclusive). - Its acceptable value might further - be limited by the context in which it is used. -

-
-

- path_name -

-
-

- A quoted string which will be used as - a pathname, such as zones/master/my.test.domain. -

-
-

- size_spec -

-
-

- A number, the word unlimited, - or the word default. -

-

- An unlimited size_spec requests unlimited - use, or the maximum available amount. A default size_spec uses - the limit that was in force when the server was started. -

-

- A number can optionally be - followed by a scaling factor: - K or k - for kilobytes, - M or m - for megabytes, and - G or g for gigabytes, - which scale by 1024, 1024*1024, and 1024*1024*1024 - respectively. -

-

- The value must be representable as a 64-bit unsigned integer - (0 to 18446744073709551615, inclusive). - Using unlimited is the best - way - to safely set a really large number. -

-
-

- yes_or_no -

-
-

- Either yes or no. - The words true and false are - also accepted, as are the numbers 1 - and 0. -

-
-

- dialup_option -

-
-

- One of yes, - no, notify, - notify-passive, refresh or - passive. - When used in a zone, notify-passive, - refresh, and passive - are restricted to slave and stub zones. -

-
-
-

-Address Match Lists

-
-

-Syntax

-
address_match_list = address_match_list_element ;
-  [ address_match_list_element; ... ]
-address_match_list_element = [ ! ] (ip_address [/length] |
-   key key_id | acl_name | { address_match_list } )
-
-
-
-

-Definition and Usage

-

- Address match lists are primarily used to determine access - control for various server operations. They are also used in - the listen-on and sortlist - statements. The elements - which constitute an address match list can be any of the - following: -

-
    -
  • an IP address (IPv4 or IPv6)
  • -
  • an IP prefix (in `/' notation)
  • -
  • - a key ID, as defined by the key - statement -
  • -
  • the name of an address match list defined with - the acl statement -
  • -
  • a nested address match list enclosed in braces
  • -
-

- Elements can be negated with a leading exclamation mark (`!'), - and the match list names "any", "none", "localhost", and - "localnets" - are predefined. More information on those names can be found in - the description of the acl statement. -

-

- The addition of the key clause made the name of this syntactic - element something of a misnomer, since security keys can be used - to validate access without regard to a host or network address. - Nonetheless, - the term "address match list" is still used throughout the - documentation. -

-

- When a given IP address or prefix is compared to an address - match list, the list is traversed in order until an element - matches. - The interpretation of a match depends on whether the list is being - used - for access control, defining listen-on ports, or in a sortlist, - and whether the element was negated. -

-

- When used as an access control list, a non-negated match - allows access and a negated match denies access. If - there is no match, access is denied. The clauses - allow-notify, - allow-query, - allow-query-cache, - allow-transfer, - allow-update, - allow-update-forwarding, and - blackhole all use address match - lists. Similarly, the listen-on option will cause the - server to not accept queries on any of the machine's - addresses which do not match the list. -

-

- Because of the first-match aspect of the algorithm, an element - that defines a subset of another element in the list should come - before the broader element, regardless of whether either is - negated. For - example, in - 1.2.3/24; ! 1.2.3.13; the 1.2.3.13 - element is - completely useless because the algorithm will match any lookup for - 1.2.3.13 to the 1.2.3/24 element. - Using ! 1.2.3.13; 1.2.3/24 fixes - that problem by having 1.2.3.13 blocked by the negation but all - other 1.2.3.* hosts fall through. -

-
-
-
-

-Comment Syntax

-

- The BIND 9 comment syntax allows for - comments to appear - anywhere that whitespace may appear in a BIND configuration - file. To appeal to programmers of all kinds, they can be written - in the C, C++, or shell/perl style. -

-
-

-Syntax

-

-

-
/* This is a BIND comment as in C */
-

-

-
// This is a BIND comment as in C++
-

-

-
# This is a BIND comment as in common UNIX shells and perl
-

-

-
-
-

-Definition and Usage

-

- Comments may appear anywhere that whitespace may appear in - a BIND configuration file. -

-

- C-style comments start with the two characters /* (slash, - star) and end with */ (star, slash). Because they are completely - delimited with these characters, they can be used to comment only - a portion of a line or to span multiple lines. -

-

- C-style comments cannot be nested. For example, the following - is not valid because the entire comment ends with the first */: -

-

- -

-
/* This is the start of a comment.
-   This is still part of the comment.
-/* This is an incorrect attempt at nesting a comment. */
-   This is no longer in any comment. */
-
-

- -

-

- C++-style comments start with the two characters // (slash, - slash) and continue to the end of the physical line. They cannot - be continued across multiple physical lines; to have one logical - comment span multiple lines, each line must use the // pair. -

-

- For example: -

-

- -

-
// This is the start of a comment.  The next line
-// is a new comment, even though it is logically
-// part of the previous comment.
-
-

- -

-

- Shell-style (or perl-style, if you prefer) comments start - with the character # (number sign) - and continue to the end of the - physical line, as in C++ comments. -

-

- For example: -

-

- -

-
# This is the start of a comment.  The next line
-# is a new comment, even though it is logically
-# part of the previous comment.
-
-

- -

-
-

Warning

-

- You cannot use the semicolon (`;') character - to start a comment such as you would in a zone file. The - semicolon indicates the end of a configuration - statement. -

-
-
-
-
-
-

-Configuration File Grammar

-

- A BIND 9 configuration consists of - statements and comments. - Statements end with a semicolon. Statements and comments are the - only elements that can appear without enclosing braces. Many - statements contain a block of sub-statements, which are also - terminated with a semicolon. -

-

- The following statements are supported: -

-
---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

acl

-
-

- defines a named IP address - matching list, for access control and other uses. -

-
-

controls

-
-

- declares control channels to be used - by the rndc utility. -

-
-

include

-
-

- includes a file. -

-
-

key

-
-

- specifies key information for use in - authentication and authorization using TSIG. -

-
-

logging

-
-

- specifies what the server logs, and where - the log messages are sent. -

-
-

lwres

-
-

- configures named to - also act as a light-weight resolver daemon (lwresd). -

-
-

masters

-
-

- defines a named masters list for - inclusion in stub and slave zone masters clauses. -

-
-

options

-
-

- controls global server configuration - options and sets defaults for other statements. -

-
-

server

-
-

- sets certain configuration options on - a per-server basis. -

-
-

trusted-keys

-
-

- defines trusted DNSSEC keys. -

-
-

view

-
-

- defines a view. -

-
-

zone

-
-

- defines a zone. -

-
-

- The logging and - options statements may only occur once - per - configuration. -

-
-

-acl Statement Grammar

-
acl acl-name {
-    address_match_list
-};
-
-
-
-

-acl Statement Definition and - Usage

-

- The acl statement assigns a symbolic - name to an address match list. It gets its name from a primary - use of address match lists: Access Control Lists (ACLs). -

-

- Note that an address match list's name must be defined - with acl before it can be used - elsewhere; no - forward references are allowed. -

-

- The following ACLs are built-in: -

-
---- - - - - - - - - - - - - - - - - - - -
-

any

-
-

- Matches all hosts. -

-
-

none

-
-

- Matches no hosts. -

-
-

localhost

-
-

- Matches the IPv4 and IPv6 addresses of all network - interfaces on the system. -

-
-

localnets

-
-

- Matches any host on an IPv4 or IPv6 network - for which the system has an interface. - Some systems do not provide a way to determine the prefix - lengths of - local IPv6 addresses. - In such a case, localnets - only matches the local - IPv6 addresses, just like localhost. -

-
-
-
-

-controls Statement Grammar

-
controls {
-   [ inet ( ip_addr | * ) [ port ip_port ] allow {  address_match_list  }
-                keys { key_list }; ]
-   [ inet ...; ]
-   [ unix path perm number owner number group number keys { key_list }; ]
-   [ unix ...; ]
-};
-
-
-
-

-controls Statement Definition and - Usage

-

- The controls statement declares control - channels to be used by system administrators to control the - operation of the name server. These control channels are - used by the rndc utility to send - commands to and retrieve non-DNS results from a name server. -

-

- An inet control channel is a TCP socket - listening at the specified ip_port on the - specified ip_addr, which can be an IPv4 or IPv6 - address. An ip_addr of * (asterisk) is - interpreted as the IPv4 wildcard address; connections will be - accepted on any of the system's IPv4 addresses. - To listen on the IPv6 wildcard address, - use an ip_addr of ::. - If you will only use rndc on the local host, - using the loopback address (127.0.0.1 - or ::1) is recommended for maximum security. -

-

- If no port is specified, port 953 is used. The asterisk - "*" cannot be used for ip_port. -

-

- The ability to issue commands over the control channel is - restricted by the allow and - keys clauses. - Connections to the control channel are permitted based on the - address_match_list. This is for simple - IP address based filtering only; any key_id - elements of the address_match_list - are ignored. -

-

- A unix control channel is a UNIX domain - socket listening at the specified path in the file system. - Access to the socket is specified by the perm, - owner and group clauses. - Note on some platforms (SunOS and Solaris) the permissions - (perm) are applied to the parent directory - as the permissions on the socket itself are ignored. -

-

- The primary authorization mechanism of the command - channel is the key_list, which - contains a list of key_ids. - Each key_id in the key_list - is authorized to execute commands over the control channel. - See Remote Name Daemon Control application in the section called “Administrative Tools”) - for information about configuring keys in rndc. -

-

- If no controls statement is present, - named will set up a default - control channel listening on the loopback address 127.0.0.1 - and its IPv6 counterpart ::1. - In this case, and also when the controls statement - is present but does not have a keys clause, - named will attempt to load the command channel key - from the file rndc.key in - /etc (or whatever sysconfdir - was specified as when BIND was built). - To create a rndc.key file, run - rndc-confgen -a. -

-

- The rndc.key feature was created to - ease the transition of systems from BIND 8, - which did not have digital signatures on its command channel - messages and thus did not have a keys clause. - - It makes it possible to use an existing BIND 8 - configuration file in BIND 9 unchanged, - and still have rndc work the same way - ndc worked in BIND 8, simply by executing the - command rndc-confgen -a after BIND 9 is - installed. -

-

- Since the rndc.key feature - is only intended to allow the backward-compatible usage of - BIND 8 configuration files, this - feature does not - have a high degree of configurability. You cannot easily change - the key name or the size of the secret, so you should make a - rndc.conf with your own key if you - wish to change - those things. The rndc.key file - also has its - permissions set such that only the owner of the file (the user that - named is running as) can access it. - If you - desire greater flexibility in allowing other users to access - rndc commands, then you need to create - a - rndc.conf file and make it group - readable by a group - that contains the users who should have access. -

-

- To disable the command channel, use an empty - controls statement: - controls { };. -

-
-
-

-include Statement Grammar

-
include filename;
-
-
-

-include Statement Definition and - Usage

-

- The include statement inserts the - specified file at the point where the include - statement is encountered. The include - statement facilitates the administration of configuration - files - by permitting the reading or writing of some things but not - others. For example, the statement could include private keys - that are readable only by the name server. -

-
-
-

-key Statement Grammar

-
key key_id {
-    algorithm string;
-    secret string;
-};
-
-
-
-

-key Statement Definition and Usage

-

- The key statement defines a shared - secret key for use with TSIG (see the section called “TSIG”) - or the command channel - (see the section called “controls Statement Definition and - Usage”). -

-

- The key statement can occur at the - top level - of the configuration file or inside a view - statement. Keys defined in top-level key - statements can be used in all views. Keys intended for use in - a controls statement - (see the section called “controls Statement Definition and - Usage”) - must be defined at the top level. -

-

- The key_id, also known as the - key name, is a domain name uniquely identifying the key. It can - be used in a server - statement to cause requests sent to that - server to be signed with this key, or in address match lists to - verify that incoming requests have been signed with a key - matching this name, algorithm, and secret. -

-

- The algorithm_id is a string - that specifies a security/authentication algorithm. Named - supports hmac-md5, - hmac-sha1, hmac-sha224, - hmac-sha256, hmac-sha384 - and hmac-sha512 TSIG authentication. - Truncated hashes are supported by appending the minimum - number of required bits preceded by a dash, e.g. - hmac-sha1-80. The - secret_string is the secret - to be used by the algorithm, and is treated as a base-64 - encoded string. -

-
-
-

-logging Statement Grammar

-
logging {
-   [ channel channel_name {
-     ( file path name
-         [ versions ( number | unlimited ) ]
-         [ size size spec ]
-       | syslog syslog_facility
-       | stderr
-       | null );
-     [ severity (critical | error | warning | notice |
-                 info | debug [ level ] | dynamic ); ]
-     [ print-category yes or no; ]
-     [ print-severity yes or no; ]
-     [ print-time yes or no; ]
-   }; ]
-   [ category category_name {
-     channel_name ; [ channel_name ; ... ]
-   }; ]
-   ...
-};
-
-
-
-

-logging Statement Definition and - Usage

-

- The logging statement configures a - wide - variety of logging options for the name server. Its channel phrase - associates output methods, format options and severity levels with - a name that can then be used with the category phrase - to select how various classes of messages are logged. -

-

- Only one logging statement is used to - define - as many channels and categories as are wanted. If there is no logging statement, - the logging configuration will be: -

-
logging {
-     category default { default_syslog; default_debug; };
-     category unmatched { null; };
-};
-
-

- In BIND 9, the logging configuration - is only established when - the entire configuration file has been parsed. In BIND 8, it was - established as soon as the logging - statement - was parsed. When the server is starting up, all logging messages - regarding syntax errors in the configuration file go to the default - channels, or to standard error if the "-g" option - was specified. -

-
-

-The channel Phrase

-

- All log output goes to one or more channels; - you can make as many of them as you want. -

-

- Every channel definition must include a destination clause that - says whether messages selected for the channel go to a file, to a - particular syslog facility, to the standard error stream, or are - discarded. It can optionally also limit the message severity level - that will be accepted by the channel (the default is - info), and whether to include a - named-generated time stamp, the - category name - and/or severity level (the default is not to include any). -

-

- The null destination clause - causes all messages sent to the channel to be discarded; - in that case, other options for the channel are meaningless. -

-

- The file destination clause directs - the channel - to a disk file. It can include limitations - both on how large the file is allowed to become, and how many - versions - of the file will be saved each time the file is opened. -

-

- If you use the versions log file - option, then - named will retain that many backup - versions of the file by - renaming them when opening. For example, if you choose to keep - three old versions - of the file lamers.log, then just - before it is opened - lamers.log.1 is renamed to - lamers.log.2, lamers.log.0 is renamed - to lamers.log.1, and lamers.log is - renamed to lamers.log.0. - You can say versions unlimited to - not limit - the number of versions. - If a size option is associated with - the log file, - then renaming is only done when the file being opened exceeds the - indicated size. No backup versions are kept by default; any - existing - log file is simply appended. -

-

- The size option for files is used - to limit log - growth. If the file ever exceeds the size, then named will - stop writing to the file unless it has a versions option - associated with it. If backup versions are kept, the files are - rolled as - described above and a new one begun. If there is no - versions option, no more data will - be written to the log - until some out-of-band mechanism removes or truncates the log to - less than the - maximum size. The default behavior is not to limit the size of - the - file. -

-

- Example usage of the size and - versions options: -

-
channel an_example_channel {
-    file "example.log" versions 3 size 20m;
-    print-time yes;
-    print-category yes;
-};
-
-

- The syslog destination clause - directs the - channel to the system log. Its argument is a - syslog facility as described in the syslog man - page. Known facilities are kern, user, - mail, daemon, auth, - syslog, lpr, news, - uucp, cron, authpriv, - ftp, local0, local1, - local2, local3, local4, - local5, local6 and - local7, however not all facilities - are supported on - all operating systems. - How syslog will handle messages - sent to - this facility is described in the syslog.conf man - page. If you have a system which uses a very old version of syslog that - only uses two arguments to the openlog() function, - then this clause is silently ignored. -

-

- The severity clause works like syslog's - "priorities", except that they can also be used if you are writing - straight to a file rather than using syslog. - Messages which are not at least of the severity level given will - not be selected for the channel; messages of higher severity - levels - will be accepted. -

-

- If you are using syslog, then the syslog.conf priorities - will also determine what eventually passes through. For example, - defining a channel facility and severity as daemon and debug but - only logging daemon.warning via syslog.conf will - cause messages of severity info and - notice to - be dropped. If the situation were reversed, with named writing - messages of only warning or higher, - then syslogd would - print all messages it received from the channel. -

-

- The stderr destination clause - directs the - channel to the server's standard error stream. This is intended - for - use when the server is running as a foreground process, for - example - when debugging a configuration. -

-

- The server can supply extensive debugging information when - it is in debugging mode. If the server's global debug level is - greater - than zero, then debugging mode will be active. The global debug - level is set either by starting the named server - with the -d flag followed by a positive integer, - or by running rndc trace. - The global debug level - can be set to zero, and debugging mode turned off, by running rndc -notrace. All debugging messages in the server have a debug - level, and higher debug levels give more detailed output. Channels - that specify a specific debug severity, for example: -

-
channel specific_debug_level {
-    file "foo";
-    severity debug 3;
-};
-
-

- will get debugging output of level 3 or less any time the - server is in debugging mode, regardless of the global debugging - level. Channels with dynamic - severity use the - server's global debug level to determine what messages to print. -

-

- If print-time has been turned on, - then - the date and time will be logged. print-time may - be specified for a syslog channel, - but is usually - pointless since syslog also prints - the date and - time. If print-category is - requested, then the - category of the message will be logged as well. Finally, if print-severity is - on, then the severity level of the message will be logged. The print- options may - be used in any combination, and will always be printed in the - following - order: time, category, severity. Here is an example where all - three print- options - are on: -

-

- 28-Feb-2000 15:05:32.863 general: notice: running -

-

- There are four predefined channels that are used for - named's default logging as follows. - How they are - used is described in the section called “The category Phrase”. -

-
channel default_syslog {
-    syslog daemon;                      // send to syslog's daemon
-                                        // facility
-    severity info;                      // only send priority info
-                                        // and higher
-};
-
-channel default_debug {
-    file "named.run";                   // write to named.run in
-                                        // the working directory
-                                        // Note: stderr is used instead
-                                        // of "named.run"
-                                        // if the server is started
-                                        // with the '-f' option.
-    severity dynamic;                   // log at the server's
-                                        // current debug level
-};
-
-channel default_stderr {
-    stderr;                             // writes to stderr
-    severity info;                      // only send priority info
-                                        // and higher
-};
-
-channel null {
-   null;                                // toss anything sent to
-                                        // this channel
-};
-
-

- The default_debug channel has the - special - property that it only produces output when the server's debug - level is - nonzero. It normally writes to a file called named.run - in the server's working directory. -

-

- For security reasons, when the "-u" - command line option is used, the named.run file - is created only after named has - changed to the - new UID, and any debug output generated while named is - starting up and still running as root is discarded. If you need - to capture this output, you must run the server with the "-g" - option and redirect standard error to a file. -

-

- Once a channel is defined, it cannot be redefined. Thus you - cannot alter the built-in channels directly, but you can modify - the default logging by pointing categories at channels you have - defined. -

-
-
-

-The category Phrase

-

- There are many categories, so you can send the logs you want - to see wherever you want, without seeing logs you don't want. If - you don't specify a list of channels for a category, then log - messages - in that category will be sent to the default category - instead. If you don't specify a default category, the following - "default default" is used: -

-
category default { default_syslog; default_debug; };
-
-

- As an example, let's say you want to log security events to - a file, but you also want keep the default logging behavior. You'd - specify the following: -

-
channel my_security_channel {
-    file "my_security_file";
-    severity info;
-};
-category security {
-    my_security_channel;
-    default_syslog;
-    default_debug;
-};
-

- To discard all messages in a category, specify the null channel: -

-
category xfer-out { null; };
-category notify { null; };
-
-

- Following are the available categories and brief descriptions - of the types of log information they contain. More - categories may be added in future BIND releases. -

-
---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

default

-
-

- The default category defines the logging - options for those categories where no specific - configuration has been - defined. -

-
-

general

-
-

- The catch-all. Many things still aren't - classified into categories, and they all end up here. -

-
-

database

-
-

- Messages relating to the databases used - internally by the name server to store zone and cache - data. -

-
-

security

-
-

- Approval and denial of requests. -

-
-

config

-
-

- Configuration file parsing and processing. -

-
-

resolver

-
-

- DNS resolution, such as the recursive - lookups performed on behalf of clients by a caching name - server. -

-
-

xfer-in

-
-

- Zone transfers the server is receiving. -

-
-

xfer-out

-
-

- Zone transfers the server is sending. -

-
-

notify

-
-

- The NOTIFY protocol. -

-
-

client

-
-

- Processing of client requests. -

-
-

unmatched

-
-

- Messages that named was unable to determine the - class of or for which there was no matching view. - A one line summary is also logged to the client category. - This category is best sent to a file or stderr, by - default it is sent to - the null channel. -

-
-

network

-
-

- Network operations. -

-
-

update

-
-

- Dynamic updates. -

-
-

update-security

-
-

- Approval and denial of update requests. -

-
-

queries

-
-

- Specify where queries should be logged to. -

-

- At startup, specifying the category queries will also - enable query logging unless querylog option has been - specified. -

-

- The query log entry reports the client's IP address and - port number, and the - query name, class and type. It also reports whether the - Recursion Desired - flag was set (+ if set, - if not set), EDNS was in use - (E) or if the - query was signed (S). -

-

- client 127.0.0.1#62536: query: www.example.com IN AAAA +SE -

-

- client ::1#62537: query: www.example.net IN AAAA -SE -

-
-

dispatch

-
-

- Dispatching of incoming packets to the - server modules where they are to be processed. -

-
-

dnssec

-
-

- DNSSEC and TSIG protocol processing. -

-
-

lame-servers

-
-

- Lame servers. These are misconfigurations - in remote servers, discovered by BIND 9 when trying to - query - those servers during resolution. -

-
-

delegation-only

-
-

- Delegation only. Logs queries that have have - been forced to NXDOMAIN as the result of a - delegation-only zone or - a delegation-only in a - hint or stub zone declaration. -

-
-
-
-
-

-lwres Statement Grammar

-

- This is the grammar of the lwres - statement in the named.conf file: -

-
lwres {
-    [ listen-on { ip_addr [port ip_port] ; [ ip_addr [port ip_port] ; ... ] }; ]
-    [ view view_name; ]
-    [ search { domain_name ; [ domain_name ; ... ] }; ]
-    [ ndots number; ]
-};
-
-
-
-

-lwres Statement Definition and Usage

-

- The lwres statement configures the - name - server to also act as a lightweight resolver server. (See - the section called “Running a Resolver Daemon”.) There may be multiple - lwres statements configuring - lightweight resolver servers with different properties. -

-

- The listen-on statement specifies a - list of - addresses (and ports) that this instance of a lightweight resolver - daemon - should accept requests on. If no port is specified, port 921 is - used. - If this statement is omitted, requests will be accepted on - 127.0.0.1, - port 921. -

-

- The view statement binds this - instance of a - lightweight resolver daemon to a view in the DNS namespace, so that - the - response will be constructed in the same manner as a normal DNS - query - matching this view. If this statement is omitted, the default view - is - used, and if there is no default view, an error is triggered. -

-

- The search statement is equivalent to - the - search statement in - /etc/resolv.conf. It provides a - list of domains - which are appended to relative names in queries. -

-

- The ndots statement is equivalent to - the - ndots statement in - /etc/resolv.conf. It indicates the - minimum - number of dots in a relative domain name that should result in an - exact match lookup before search path elements are appended. -

-
-
-

-masters Statement Grammar

-
-masters name [port ip_port] { ( masters_list | ip_addr [port ip_port] [key key] ) ; [...] };
-
-
-
-

-masters Statement Definition and - Usage

-

masters - lists allow for a common set of masters to be easily used by - multiple stub and slave zones. -

-
-
-

-options Statement Grammar

-

- This is the grammar of the options - statement in the named.conf file: -

-
options {
-    [ version version_string; ]
-    [ hostname hostname_string; ]
-    [ server-id server_id_string; ]
-    [ directory path_name; ]
-    [ key-directory path_name; ]
-    [ named-xfer path_name; ]
-    [ tkey-domain domainname; ]
-    [ tkey-dhkey key_name key_tag; ]
-    [ cache-file path_name; ]
-    [ dump-file path_name; ]
-    [ memstatistics-file path_name; ]
-    [ pid-file path_name; ]
-    [ recursing-file path_name; ]
-    [ statistics-file path_name; ]
-    [ zone-statistics yes_or_no; ]
-    [ auth-nxdomain yes_or_no; ]
-    [ deallocate-on-exit yes_or_no; ]
-    [ dialup dialup_option; ]
-    [ fake-iquery yes_or_no; ]
-    [ fetch-glue yes_or_no; ]
-    [ flush-zones-on-shutdown yes_or_no; ]
-    [ has-old-clients yes_or_no; ]
-    [ host-statistics yes_or_no; ]
-    [ host-statistics-max number; ]
-    [ minimal-responses yes_or_no; ]
-    [ multiple-cnames yes_or_no; ]
-    [ notify yes_or_no | explicit | master-only; ]
-    [ recursion yes_or_no; ]
-    [ rfc2308-type1 yes_or_no; ]
-    [ use-id-pool yes_or_no; ]
-    [ maintain-ixfr-base yes_or_no; ]
-    [ dnssec-enable yes_or_no; ]
-    [ dnssec-validation yes_or_no; ]
-    [ dnssec-lookaside domain trust-anchor domain; ]
-    [ dnssec-must-be-secure domain yes_or_no; ]
-    [ dnssec-accept-expired yes_or_no; ]
-    [ forward ( only | first ); ]
-    [ forwarders { [ ip_addr [port ip_port] ; ... ] }; ]
-    [ dual-stack-servers [port ip_port] {
-        ( domain_name [port ip_port] |
-          ip_addr [port ip_port] ) ; 
-        ... }; ]
-    [ check-names ( master | slave | response )
-        ( warn | fail | ignore ); ]
-    [ check-mx ( warn | fail | ignore ); ]
-    [ check-wildcard yes_or_no; ]
-    [ check-integrity yes_or_no; ]
-    [ check-mx-cname ( warn | fail | ignore ); ]
-    [ check-srv-cname ( warn | fail | ignore ); ]
-    [ check-sibling yes_or_no; ]
-    [ allow-notify { address_match_list }; ]
-    [ allow-query { address_match_list }; ]
-    [ allow-query-cache { address_match_list }; ]
-    [ allow-transfer { address_match_list }; ]
-    [ allow-recursion { address_match_list }; ]
-    [ allow-update { address_match_list }; ]
-    [ allow-update-forwarding { address_match_list }; ]
-    [ update-check-ksk yes_or_no; ]
-    [ allow-v6-synthesis { address_match_list }; ]
-    [ blackhole { address_match_list }; ]
-    [ avoid-v4-udp-ports { port_list }; ]
-    [ avoid-v6-udp-ports { port_list }; ]
-    [ listen-on [ port ip_port ] { address_match_list }; ]
-    [ listen-on-v6 [ port ip_port ] { address_match_list }; ]
-    [ query-source ( ( ip4_addr | * )
-        [ port ( ip_port | * ) ] |
-        [ address ( ip4_addr | * ) ]
-        [ port ( ip_port | * ) ] ) ; ]
-    [ query-source-v6 ( ( ip6_addr | * )
-        [ port ( ip_port | * ) ] | 
-        [ address ( ip6_addr | * ) ] 
-        [ port ( ip_port | * ) ] ) ; ]
-    [ max-transfer-time-in number; ]
-    [ max-transfer-time-out number; ]
-    [ max-transfer-idle-in number; ]
-    [ max-transfer-idle-out number; ]
-    [ tcp-clients number; ]
-    [ recursive-clients number; ]
-    [ serial-query-rate number; ]
-    [ serial-queries number; ]
-    [ tcp-listen-queue number; ]
-    [ transfer-format ( one-answer | many-answers ); ]
-    [ transfers-in  number; ]
-    [ transfers-out number; ]
-    [ transfers-per-ns number; ]
-    [ transfer-source (ip4_addr | *) [port ip_port] ; ]
-    [ transfer-source-v6 (ip6_addr | *) [port ip_port] ; ]
-    [ alt-transfer-source (ip4_addr | *) [port ip_port] ; ]
-    [ alt-transfer-source-v6 (ip6_addr | *) [port ip_port] ; ]
-    [ use-alt-transfer-source yes_or_no; ]
-    [ notify-delay seconds ; ]
-    [ notify-source (ip4_addr | *) [port ip_port] ; ]
-    [ notify-source-v6 (ip6_addr | *) [port ip_port] ; ]
-    [ also-notify { ip_addr [port ip_port] ; [ ip_addr [port ip_port] ; ... ] }; ]
-    [ max-ixfr-log-size number; ]
-    [ max-journal-size size_spec; ]
-    [ coresize size_spec ; ]
-    [ datasize size_spec ; ]
-    [ files size_spec ; ]
-    [ stacksize size_spec ; ]
-    [ cleaning-interval number; ]
-    [ heartbeat-interval number; ]
-    [ interface-interval number; ]
-    [ statistics-interval number; ]
-    [ topology { address_match_list }];
-    [ sortlist { address_match_list }];
-    [ rrset-order { order_spec ; [ order_spec ; ... ] ] };
-    [ lame-ttl number; ]
-    [ max-ncache-ttl number; ]
-    [ max-cache-ttl number; ]
-    [ sig-validity-interval number ; ]
-    [ min-roots number; ]
-    [ use-ixfr yes_or_no ; ]
-    [ provide-ixfr yes_or_no; ]
-    [ request-ixfr yes_or_no; ]
-    [ treat-cr-as-space yes_or_no ; ]
-    [ min-refresh-time number ; ]
-    [ max-refresh-time number ; ]
-    [ min-retry-time number ; ]
-    [ max-retry-time number ; ]
-    [ port ip_port; ]
-    [ additional-from-auth yes_or_no ; ]
-    [ additional-from-cache yes_or_no ; ]
-    [ random-device path_name ; ]
-    [ max-cache-size size_spec ; ]
-    [ match-mapped-addresses yes_or_no; ]
-    [ preferred-glue ( A | AAAA | NONE ); ]
-    [ edns-udp-size number; ]
-    [ max-udp-size number; ]
-    [ root-delegation-only [ exclude { namelist } ] ; ]
-    [ querylog yes_or_no ; ]
-    [ disable-algorithms domain { algorithm; [ algorithm; ] }; ]
-    [ acache-enable yes_or_no ; ]
-    [ acache-cleaning-interval number; ]
-    [ max-acache-size size_spec ; ]
-    [ clients-per-query number ; ]
-    [ max-clients-per-query number ; ]
-    [ masterfile-format (text|raw) ; ]
-    [ empty-server name ; ]
-    [ empty-contact name ; ]
-    [ empty-zones-enable yes_or_no ; ]
-    [ disable-empty-zone zone_name ; ]
-    [ zero-no-soa-ttl yes_or_no ; ]
-    [ zero-no-soa-ttl-cache yes_or_no ; ]
-};
-
-
-
-

-options Statement Definition and - Usage

-

- The options statement sets up global - options - to be used by BIND. This statement - may appear only - once in a configuration file. If there is no options - statement, an options block with each option set to its default will - be used. -

-
-
directory
-

- The working directory of the server. - Any non-absolute pathnames in the configuration file will be - taken - as relative to this directory. The default location for most - server - output files (e.g. named.run) - is this directory. - If a directory is not specified, the working directory - defaults to `.', the directory from - which the server - was started. The directory specified should be an absolute - path. -

-
key-directory
-

- When performing dynamic update of secure zones, the - directory where the public and private key files should be - found, - if different than the current working directory. The - directory specified - must be an absolute path. -

-
named-xfer
-

- This option is obsolete. - It was used in BIND 8 to - specify the pathname to the named-xfer program. - In BIND 9, no separate named-xfer program is - needed; its functionality is built into the name server. -

-
tkey-domain
-

- The domain appended to the names of all - shared keys generated with - TKEY. When a client - requests a TKEY exchange, it - may or may not specify - the desired name for the key. If present, the name of the - shared - key will be "client specified part" + - "tkey-domain". - Otherwise, the name of the shared key will be "random hex -digits" + "tkey-domain". In most cases, - the domainname should be the - server's domain - name. -

-
tkey-dhkey
-

- The Diffie-Hellman key used by the server - to generate shared keys with clients using the Diffie-Hellman - mode - of TKEY. The server must be - able to load the - public and private keys from files in the working directory. - In - most cases, the keyname should be the server's host name. -

-
cache-file
-

- This is for testing only. Do not use. -

-
dump-file
-

- The pathname of the file the server dumps - the database to when instructed to do so with - rndc dumpdb. - If not specified, the default is named_dump.db. -

-
memstatistics-file
-
-

- The pathname of the file the server writes memory - usage statistics to on exit. If specified the - statistics will be written to the file on exit. -

-

- In BIND 9.5 and later this will - default to named.memstats. - BIND 9.5 will also introduce - memstatistics to control the - writing. -

-
-
pid-file
-

- The pathname of the file the server writes its process ID - in. If not specified, the default is /var/run/named.pid. - The pid-file is used by programs that want to send signals to - the running - name server. Specifying pid-file none disables the - use of a PID file — no file will be written and any - existing one will be removed. Note that none - is a keyword, not a filename, and therefore is not enclosed - in - double quotes. -

-
recursing-file
-

- The pathname of the file the server dumps - the queries that are currently recursing when instructed - to do so with rndc recursing. - If not specified, the default is named.recursing. -

-
statistics-file
-

- The pathname of the file the server appends statistics - to when instructed to do so using rndc stats. - If not specified, the default is named.stats in the - server's current directory. The format of the file is - described - in the section called “The Statistics File”. -

-
port
-

- The UDP/TCP port number the server uses for - receiving and sending DNS protocol traffic. - The default is 53. This option is mainly intended for server - testing; - a server using a port other than 53 will not be able to - communicate with - the global DNS. -

-
random-device
-

- The source of entropy to be used by the server. Entropy is - primarily needed - for DNSSEC operations, such as TKEY transactions and dynamic - update of signed - zones. This options specifies the device (or file) from which - to read - entropy. If this is a file, operations requiring entropy will - fail when the - file has been exhausted. If not specified, the default value - is - /dev/random - (or equivalent) when present, and none otherwise. The - random-device option takes - effect during - the initial configuration load at server startup time and - is ignored on subsequent reloads. -

-
preferred-glue
-

- If specified, the listed type (A or AAAA) will be emitted - before other glue - in the additional section of a query response. - The default is not to prefer any type (NONE). -

-
root-delegation-only
-
-

- Turn on enforcement of delegation-only in TLDs (top level domains) and root zones - with an optional - exclude list. -

-

- Note some TLDs are not delegation only (e.g. "DE", "LV", "US" - and "MUSEUM"). -

-
-options {
-        root-delegation-only exclude { "de"; "lv"; "us"; "museum"; };
-};
-
-
-
disable-algorithms
-

- Disable the specified DNSSEC algorithms at and below the - specified name. - Multiple disable-algorithms - statements are allowed. - Only the most specific will be applied. -

-
dnssec-lookaside
-

- When set, dnssec-lookaside - provides the - validator with an alternate method to validate DNSKEY records - at the - top of a zone. When a DNSKEY is at or below a domain - specified by the - deepest dnssec-lookaside, and - the normal dnssec validation - has left the key untrusted, the trust-anchor will be append to - the key - name and a DLV record will be looked up to see if it can - validate the - key. If the DLV record validates a DNSKEY (similarly to the - way a DS - record does) the DNSKEY RRset is deemed to be trusted. -

-
dnssec-must-be-secure
-

- Specify hierarchies which must be or may not be secure (signed and - validated). - If yes, then named will only accept - answers if they - are secure. - If no, then normal dnssec validation - applies - allowing for insecure answers to be accepted. - The specified domain must be under a trusted-key or - dnssec-lookaside must be - active. -

-
-
-

-Boolean Options

-
-
auth-nxdomain
-

- If yes, then the AA bit - is always set on NXDOMAIN responses, even if the server is - not actually - authoritative. The default is no; - this is - a change from BIND 8. If you - are using very old DNS software, you - may need to set it to yes. -

-
deallocate-on-exit
-

- This option was used in BIND - 8 to enable checking - for memory leaks on exit. BIND 9 ignores the option and always performs - the checks. -

-
dialup
-
-

- If yes, then the - server treats all zones as if they are doing zone transfers - across - a dial-on-demand dialup link, which can be brought up by - traffic - originating from this server. This has different effects - according - to zone type and concentrates the zone maintenance so that - it all - happens in a short interval, once every heartbeat-interval and - hopefully during the one call. It also suppresses some of - the normal - zone maintenance traffic. The default is no. -

-

- The dialup option - may also be specified in the view and - zone statements, - in which case it overrides the global dialup - option. -

-

- If the zone is a master zone, then the server will send out a - NOTIFY - request to all the slaves (default). This should trigger the - zone serial - number check in the slave (providing it supports NOTIFY) - allowing the slave - to verify the zone while the connection is active. - The set of servers to which NOTIFY is sent can be controlled - by - notify and also-notify. -

-

- If the - zone is a slave or stub zone, then the server will suppress - the regular - "zone up to date" (refresh) queries and only perform them - when the - heartbeat-interval expires in - addition to sending - NOTIFY requests. -

-

- Finer control can be achieved by using - notify which only sends NOTIFY - messages, - notify-passive which sends NOTIFY - messages and - suppresses the normal refresh queries, refresh - which suppresses normal refresh processing and sends refresh - queries - when the heartbeat-interval - expires, and - passive which just disables normal - refresh - processing. -

-
------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

- dialup mode -

-
-

- normal refresh -

-
-

- heart-beat refresh -

-
-

- heart-beat notify -

-
-

no (default)

-
-

- yes -

-
-

- no -

-
-

- no -

-
-

yes

-
-

- no -

-
-

- yes -

-
-

- yes -

-
-

notify

-
-

- yes -

-
-

- no -

-
-

- yes -

-
-

refresh

-
-

- no -

-
-

- yes -

-
-

- no -

-
-

passive

-
-

- no -

-
-

- no -

-
-

- no -

-
-

notify-passive

-
-

- no -

-
-

- no -

-
-

- yes -

-
-

- Note that normal NOTIFY processing is not affected by - dialup. -

-
-
fake-iquery
-

- In BIND 8, this option - enabled simulating the obsolete DNS query type - IQUERY. BIND 9 never does - IQUERY simulation. -

-
fetch-glue
-

- This option is obsolete. - In BIND 8, fetch-glue yes - caused the server to attempt to fetch glue resource records - it - didn't have when constructing the additional - data section of a response. This is now considered a bad - idea - and BIND 9 never does it. -

-
flush-zones-on-shutdown
-

- When the nameserver exits due receiving SIGTERM, - flush or do not flush any pending zone writes. The default - is - flush-zones-on-shutdown no. -

-
has-old-clients
-

- This option was incorrectly implemented - in BIND 8, and is ignored by BIND 9. - To achieve the intended effect - of - has-old-clients yes, specify - the two separate options auth-nxdomain yes - and rfc2308-type1 no instead. -

-
host-statistics
-

- In BIND 8, this enables keeping of - statistics for every host that the name server interacts - with. - Not implemented in BIND 9. -

-
maintain-ixfr-base
-

- This option is obsolete. - It was used in BIND 8 to - determine whether a transaction log was - kept for Incremental Zone Transfer. BIND 9 maintains a transaction - log whenever possible. If you need to disable outgoing - incremental zone - transfers, use provide-ixfr no. -

-
minimal-responses
-

- If yes, then when generating - responses the server will only add records to the authority - and additional data sections when they are required (e.g. - delegations, negative responses). This may improve the - performance of the server. - The default is no. -

-
multiple-cnames
-

- This option was used in BIND 8 to allow - a domain name to have multiple CNAME records in violation of - the DNS standards. BIND 9.2 onwards - always strictly enforces the CNAME rules both in master - files and dynamic updates. -

-
notify
-
-

- If yes (the default), - DNS NOTIFY messages are sent when a zone the server is - authoritative for - changes, see the section called “Notify”. The messages are - sent to the - servers listed in the zone's NS records (except the master - server identified - in the SOA MNAME field), and to any servers listed in the - also-notify option. -

-

- If master-only, notifies are only - sent - for master zones. - If explicit, notifies are sent only - to - servers explicitly listed using also-notify. - If no, no notifies are sent. -

-

- The notify option may also be - specified in the zone - statement, - in which case it overrides the options notify statement. - It would only be necessary to turn off this option if it - caused slaves - to crash. -

-
-
recursion
-

- If yes, and a - DNS query requests recursion, then the server will attempt - to do - all the work required to answer the query. If recursion is - off - and the server does not already know the answer, it will - return a - referral response. The default is - yes. - Note that setting recursion no does not prevent - clients from getting data from the server's cache; it only - prevents new data from being cached as an effect of client - queries. - Caching may still occur as an effect the server's internal - operation, such as NOTIFY address lookups. - See also fetch-glue above. -

-
rfc2308-type1
-
-

- Setting this to yes will - cause the server to send NS records along with the SOA - record for negative - answers. The default is no. -

-
-

Note

-

- Not yet implemented in BIND - 9. -

-
-
-
use-id-pool
-

- This option is obsolete. - BIND 9 always allocates query - IDs from a pool. -

-
zone-statistics
-

- If yes, the server will collect - statistical data on all zones (unless specifically turned - off - on a per-zone basis by specifying zone-statistics no - in the zone statement). - These statistics may be accessed - using rndc stats, which will - dump them to the file listed - in the statistics-file. See - also the section called “The Statistics File”. -

-
use-ixfr
-

- This option is obsolete. - If you need to disable IXFR to a particular server or - servers, see - the information on the provide-ixfr option - in the section called “server Statement Definition and - Usage”. - See also - the section called “Incremental Zone Transfers (IXFR)”. -

-
provide-ixfr
-

- See the description of - provide-ixfr in - the section called “server Statement Definition and - Usage”. -

-
request-ixfr
-

- See the description of - request-ixfr in - the section called “server Statement Definition and - Usage”. -

-
treat-cr-as-space
-

- This option was used in BIND - 8 to make - the server treat carriage return ("\r") characters the same way - as a space or tab character, - to facilitate loading of zone files on a UNIX system that - were generated - on an NT or DOS machine. In BIND 9, both UNIX "\n" - and NT/DOS "\r\n" newlines - are always accepted, - and the option is ignored. -

-
-additional-from-auth, additional-from-cache -
-
-

- These options control the behavior of an authoritative - server when - answering queries which have additional data, or when - following CNAME - and DNAME chains. -

-

- When both of these options are set to yes - (the default) and a - query is being answered from authoritative data (a zone - configured into the server), the additional data section of - the - reply will be filled in using data from other authoritative - zones - and from the cache. In some situations this is undesirable, - such - as when there is concern over the correctness of the cache, - or - in servers where slave zones may be added and modified by - untrusted third parties. Also, avoiding - the search for this additional data will speed up server - operations - at the possible expense of additional queries to resolve - what would - otherwise be provided in the additional section. -

-

- For example, if a query asks for an MX record for host foo.example.com, - and the record found is "MX 10 mail.example.net", normally the address - records (A and AAAA) for mail.example.net will be provided as well, - if known, even though they are not in the example.com zone. - Setting these options to no - disables this behavior and makes - the server only search for additional data in the zone it - answers from. -

-

- These options are intended for use in authoritative-only - servers, or in authoritative-only views. Attempts to set - them to no without also - specifying - recursion no will cause the - server to - ignore the options and log a warning message. -

-

- Specifying additional-from-cache no actually - disables the use of the cache not only for additional data - lookups - but also when looking up the answer. This is usually the - desired - behavior in an authoritative-only server where the - correctness of - the cached data is an issue. -

-

- When a name server is non-recursively queried for a name - that is not - below the apex of any served zone, it normally answers with - an - "upwards referral" to the root servers or the servers of - some other - known parent of the query name. Since the data in an - upwards referral - comes from the cache, the server will not be able to provide - upwards - referrals when additional-from-cache no - has been specified. Instead, it will respond to such - queries - with REFUSED. This should not cause any problems since - upwards referrals are not required for the resolution - process. -

-
-
match-mapped-addresses
-

- If yes, then an - IPv4-mapped IPv6 address will match any address match - list entries that match the corresponding IPv4 address. - Enabling this option is sometimes useful on IPv6-enabled - Linux - systems, to work around a kernel quirk that causes IPv4 - TCP connections such as zone transfers to be accepted - on an IPv6 socket using mapped addresses, causing - address match lists designed for IPv4 to fail to match. - The use of this option for any other purpose is discouraged. -

-
ixfr-from-differences
-
-

- When yes and the server loads a new version of a master - zone from its zone file or receives a new version of a slave - file by a non-incremental zone transfer, it will compare - the new version to the previous one and calculate a set - of differences. The differences are then logged in the - zone's journal file such that the changes can be transmitted - to downstream slaves as an incremental zone transfer. -

-

- By allowing incremental zone transfers to be used for - non-dynamic zones, this option saves bandwidth at the - expense of increased CPU and memory consumption at the - master. - In particular, if the new version of a zone is completely - different from the previous one, the set of differences - will be of a size comparable to the combined size of the - old and new zone version, and the server will need to - temporarily allocate memory to hold this complete - difference set. -

-

ixfr-from-differences - also accepts master and - slave at the view and options - levels which causes - ixfr-from-differences to apply to - all master or - slave zones respectively. -

-
-
multi-master
-

- This should be set when you have multiple masters for a zone - and the - addresses refer to different machines. If yes, named will - not log - when the serial number on the master is less than what named - currently - has. The default is no. -

-
dnssec-enable
-

- Enable DNSSEC support in named. Unless set to yes, - named behaves as if it does not support DNSSEC. - The default is yes. -

-
dnssec-validation
-

- Enable DNSSEC validation in named. - Note dnssec-enable also needs to be - set to yes to be effective. - The default is no. -

-
dnssec-accept-expired
-

- Accept expired signatures when verifying DNSSEC signatures. - The default is no. - Setting this option to "yes" leaves named vulnerable to replay attacks. -

-
querylog
-

- Specify whether query logging should be started when named - starts. - If querylog is not specified, - then the query logging - is determined by the presence of the logging category queries. -

-
check-names
-
-

- This option is used to restrict the character set and syntax - of - certain domain names in master files and/or DNS responses - received - from the network. The default varies according to usage - area. For - master zones the default is fail. - For slave zones the default - is warn. - For answers received from the network (response) - the default is ignore. -

-

- The rules for legal hostnames and mail domains are derived - from RFC 952 and RFC 821 as modified by RFC 1123. -

-

check-names - applies to the owner names of A, AAA and MX records. - It also applies to the domain names in the RDATA of NS, SOA - and MX records. - It also applies to the RDATA of PTR records where the owner - name indicated that it is a reverse lookup of a hostname - (the owner name ends in IN-ADDR.ARPA, IP6.ARPA, or IP6.INT). -

-
-
check-mx
-

- Check whether the MX record appears to refer to a IP address. - The default is to warn. Other possible - values are fail and - ignore. -

-
check-wildcard
-

- This option is used to check for non-terminal wildcards. - The use of non-terminal wildcards is almost always as a - result of a failure - to understand the wildcard matching algorithm (RFC 1034). - This option - affects master zones. The default (yes) is to check - for non-terminal wildcards and issue a warning. -

-
check-integrity
-

- Perform post load zone integrity checks on master - zones. This checks that MX and SRV records refer - to address (A or AAAA) records and that glue - address records exist for delegated zones. For - MX and SRV records only in-zone hostnames are - checked (for out-of-zone hostnames use named-checkzone). - For NS records only names below top of zone are - checked (for out-of-zone names and glue consistency - checks use named-checkzone). The default is - yes. -

-
check-mx-cname
-

- If check-integrity is set then - fail, warn or ignore MX records that refer - to CNAMES. The default is to warn. -

-
check-srv-cname
-

- If check-integrity is set then - fail, warn or ignore SRV records that refer - to CNAMES. The default is to warn. -

-
check-sibling
-

- When performing integrity checks, also check that - sibling glue exists. The default is yes. -

-
zero-no-soa-ttl
-

- When returning authoritative negative responses to - SOA queries set the TTL of the SOA recored returned in - the authority section to zero. - The default is yes. -

-
zero-no-soa-ttl-cache
-

- When caching a negative response to a SOA query - set the TTL to zero. - The default is no. -

-
update-check-ksk
-

- When regenerating the RRSIGs following a UPDATE - request to a secure zone, check the KSK flag on - the DNSKEY RR to determine if this key should be - used to generate the RRSIG. This flag is ignored - if there are not DNSKEY RRs both with and without - a KSK. - The default is yes. -

-
-
-
-

-Forwarding

-

- The forwarding facility can be used to create a large site-wide - cache on a few servers, reducing traffic over links to external - name servers. It can also be used to allow queries by servers that - do not have direct access to the Internet, but wish to look up - exterior - names anyway. Forwarding occurs only on those queries for which - the server is not authoritative and does not have the answer in - its cache. -

-
-
forward
-

- This option is only meaningful if the - forwarders list is not empty. A value of first, - the default, causes the server to query the forwarders - first — and - if that doesn't answer the question, the server will then - look for - the answer itself. If only is - specified, the - server will only query the forwarders. -

-
forwarders
-

- Specifies the IP addresses to be used - for forwarding. The default is the empty list (no - forwarding). -

-
-

- Forwarding can also be configured on a per-domain basis, allowing - for the global forwarding options to be overridden in a variety - of ways. You can set particular domains to use different - forwarders, - or have a different forward only/first behavior, - or not forward at all, see the section called “zone - Statement Grammar”. -

-
-
-

-Dual-stack Servers

-

- Dual-stack servers are used as servers of last resort to work - around - problems in reachability due the lack of support for either IPv4 - or IPv6 - on the host machine. -

-
-
dual-stack-servers
-

- Specifies host names or addresses of machines with access to - both IPv4 and IPv6 transports. If a hostname is used, the - server must be able - to resolve the name using only the transport it has. If the - machine is dual - stacked, then the dual-stack-servers have no effect unless - access to a transport has been disabled on the command line - (e.g. named -4). -

-
-
-
-

-Access Control

-

- Access to the server can be restricted based on the IP address - of the requesting system. See the section called “Address Match Lists” for - details on how to specify IP address lists. -

-
-
allow-notify
-

- Specifies which hosts are allowed to - notify this server, a slave, of zone changes in addition - to the zone masters. - allow-notify may also be - specified in the - zone statement, in which case - it overrides the - options allow-notify - statement. It is only meaningful - for a slave zone. If not specified, the default is to - process notify messages - only from a zone's master. -

-
allow-query
-
-

- Specifies which hosts are allowed to ask ordinary - DNS questions. allow-query may - also be specified in the zone - statement, in which case it overrides the - options allow-query statement. - If not specified, the default is to allow queries - from all hosts. -

-
-

Note

-

- allow-query-cache is now - used to specify access to the cache. -

-
-
-
allow-query-cache
-

- Specifies which hosts are allowed to get answers - from the cache. If allow-query-cache - is not set then allow-recursion - is used if set, otherwise allow-query - is used if set, otherwise the default - (localnets; - localhost;) is used. -

-
allow-recursion
-

- Specifies which hosts are allowed to make recursive - queries through this server. If - allow-recursion is not set - then allow-query-cache is - used if set, otherwise allow-query - is used if set, otherwise the default - (localnets; - localhost;) is used. -

-
allow-update
-

- Specifies which hosts are allowed to - submit Dynamic DNS updates for master zones. The default is - to deny - updates from all hosts. Note that allowing updates based - on the requestor's IP address is insecure; see - the section called “Dynamic Update Security” for details. -

-
allow-update-forwarding
-
-

- Specifies which hosts are allowed to - submit Dynamic DNS updates to slave zones to be forwarded to - the - master. The default is { none; }, - which - means that no update forwarding will be performed. To - enable - update forwarding, specify - allow-update-forwarding { any; };. - Specifying values other than { none; } or - { any; } is usually - counterproductive, since - the responsibility for update access control should rest - with the - master server, not the slaves. -

-

- Note that enabling the update forwarding feature on a slave - server - may expose master servers relying on insecure IP address - based - access control to attacks; see the section called “Dynamic Update Security” - for more details. -

-
-
allow-v6-synthesis
-

- This option was introduced for the smooth transition from - AAAA - to A6 and from "nibble labels" to binary labels. - However, since both A6 and binary labels were then - deprecated, - this option was also deprecated. - It is now ignored with some warning messages. -

-
allow-transfer
-

- Specifies which hosts are allowed to - receive zone transfers from the server. allow-transfer may - also be specified in the zone - statement, in which - case it overrides the options allow-transfer statement. - If not specified, the default is to allow transfers to all - hosts. -

-
blackhole
-

- Specifies a list of addresses that the - server will not accept queries from or use to resolve a - query. Queries - from these addresses will not be responded to. The default - is none. -

-
-
-
-

-Interfaces

-

- The interfaces and ports that the server will answer queries - from may be specified using the listen-on option. listen-on takes - an optional port, and an address_match_list. - The server will listen on all interfaces allowed by the address - match list. If a port is not specified, port 53 will be used. -

-

- Multiple listen-on statements are - allowed. - For example, -

-
listen-on { 5.6.7.8; };
-listen-on port 1234 { !1.2.3.4; 1.2/16; };
-
-

- will enable the name server on port 53 for the IP address - 5.6.7.8, and on port 1234 of an address on the machine in net - 1.2 that is not 1.2.3.4. -

-

- If no listen-on is specified, the - server will listen on port 53 on all interfaces. -

-

- The listen-on-v6 option is used to - specify the interfaces and the ports on which the server will - listen - for incoming queries sent using IPv6. -

-

- When

-
{ any; }
-

is - specified - as the address_match_list for the - listen-on-v6 option, - the server does not bind a separate socket to each IPv6 interface - address as it does for IPv4 if the operating system has enough API - support for IPv6 (specifically if it conforms to RFC 3493 and RFC - 3542). - Instead, it listens on the IPv6 wildcard address. - If the system only has incomplete API support for IPv6, however, - the behavior is the same as that for IPv4. -

-

- A list of particular IPv6 addresses can also be specified, in - which case - the server listens on a separate socket for each specified - address, - regardless of whether the desired API is supported by the system. -

-

- Multiple listen-on-v6 options can - be used. - For example, -

-
listen-on-v6 { any; };
-listen-on-v6 port 1234 { !2001:db8::/32; any; };
-
-

- will enable the name server on port 53 for any IPv6 addresses - (with a single wildcard socket), - and on port 1234 of IPv6 addresses that is not in the prefix - 2001:db8::/32 (with separate sockets for each matched address.) -

-

- To make the server not listen on any IPv6 address, use -

-
listen-on-v6 { none; };
-
-

- If no listen-on-v6 option is - specified, - the server will not listen on any IPv6 address. -

-
-
-

-Query Address

-

- If the server doesn't know the answer to a question, it will - query other name servers. query-source specifies - the address and port used for such queries. For queries sent over - IPv6, there is a separate query-source-v6 option. - If address is * (asterisk) or is omitted, - a wildcard IP address (INADDR_ANY) - will be used. - If port is * or is omitted, - a random unprivileged port will be used. The avoid-v4-udp-ports - and avoid-v6-udp-ports options can be used - to prevent named - from selecting certain ports. The defaults are: -

-
query-source address * port *;
-query-source-v6 address * port *;
-
-
-

Note

-

- The address specified in the query-source option - is used for both UDP and TCP queries, but the port applies only - to - UDP queries. TCP queries always use a random - unprivileged port. -

-
-
-

Note

-

- Solaris 2.5.1 and earlier does not support setting the source - address for TCP sockets. -

-
-
-

Note

-

- See also transfer-source and - notify-source. -

-
-
-
-

-Zone Transfers

-

- BIND has mechanisms in place to - facilitate zone transfers - and set limits on the amount of load that transfers place on the - system. The following options apply to zone transfers. -

-
-
also-notify
-

- Defines a global list of IP addresses of name servers - that are also sent NOTIFY messages whenever a fresh copy of - the - zone is loaded, in addition to the servers listed in the - zone's NS records. - This helps to ensure that copies of the zones will - quickly converge on stealth servers. If an also-notify list - is given in a zone statement, - it will override - the options also-notify - statement. When a zone notify - statement - is set to no, the IP - addresses in the global also-notify list will - not be sent NOTIFY messages for that zone. The default is - the empty - list (no global notification list). -

-
max-transfer-time-in
-

- Inbound zone transfers running longer than - this many minutes will be terminated. The default is 120 - minutes - (2 hours). The maximum value is 28 days (40320 minutes). -

-
max-transfer-idle-in
-

- Inbound zone transfers making no progress - in this many minutes will be terminated. The default is 60 - minutes - (1 hour). The maximum value is 28 days (40320 minutes). -

-
max-transfer-time-out
-

- Outbound zone transfers running longer than - this many minutes will be terminated. The default is 120 - minutes - (2 hours). The maximum value is 28 days (40320 minutes). -

-
max-transfer-idle-out
-

- Outbound zone transfers making no progress - in this many minutes will be terminated. The default is 60 - minutes (1 - hour). The maximum value is 28 days (40320 minutes). -

-
serial-query-rate
-

- Slave servers will periodically query master servers - to find out if zone serial numbers have changed. Each such - query uses - a minute amount of the slave server's network bandwidth. To - limit the - amount of bandwidth used, BIND 9 limits the rate at which - queries are - sent. The value of the serial-query-rate option, - an integer, is the maximum number of queries sent per - second. - The default is 20. -

-
serial-queries
-

- In BIND 8, the serial-queries - option - set the maximum number of concurrent serial number queries - allowed to be outstanding at any given time. - BIND 9 does not limit the number of outstanding - serial queries and ignores the serial-queries option. - Instead, it limits the rate at which the queries are sent - as defined using the serial-query-rate option. -

-
transfer-format
-

- Zone transfers can be sent using two different formats, - one-answer and - many-answers. - The transfer-format option is used - on the master server to determine which format it sends. - one-answer uses one DNS message per - resource record transferred. - many-answers packs as many resource - records as possible into a message. - many-answers is more efficient, but is - only supported by relatively new slave servers, - such as BIND 9, BIND - 8.x and BIND 4.9.5 onwards. - The many-answers format is also supported by - recent Microsoft Windows nameservers. - The default is many-answers. - transfer-format may be overridden on a - per-server basis by using the server - statement. -

-
transfers-in
-

- The maximum number of inbound zone transfers - that can be running concurrently. The default value is 10. - Increasing transfers-in may - speed up the convergence - of slave zones, but it also may increase the load on the - local system. -

-
transfers-out
-

- The maximum number of outbound zone transfers - that can be running concurrently. Zone transfer requests in - excess - of the limit will be refused. The default value is 10. -

-
transfers-per-ns
-

- The maximum number of inbound zone transfers - that can be concurrently transferring from a given remote - name server. - The default value is 2. - Increasing transfers-per-ns - may - speed up the convergence of slave zones, but it also may - increase - the load on the remote name server. transfers-per-ns may - be overridden on a per-server basis by using the transfers phrase - of the server statement. -

-
transfer-source
-
-

transfer-source - determines which local address will be bound to IPv4 - TCP connections used to fetch zones transferred - inbound by the server. It also determines the - source IPv4 address, and optionally the UDP port, - used for the refresh queries and forwarded dynamic - updates. If not set, it defaults to a system - controlled value which will usually be the address - of the interface "closest to" the remote end. This - address must appear in the remote end's - allow-transfer option for the - zone being transferred, if one is specified. This - statement sets the - transfer-source for all zones, - but can be overridden on a per-view or per-zone - basis by including a - transfer-source statement within - the view or - zone block in the configuration - file. -

-
-

Note

-

- Solaris 2.5.1 and earlier does not support setting the - source address for TCP sockets. -

-
-
-
transfer-source-v6
-

- The same as transfer-source, - except zone transfers are performed using IPv6. -

-
alt-transfer-source
-
-

- An alternate transfer source if the one listed in - transfer-source fails and - use-alt-transfer-source is - set. -

-
-

Note

- If you do not wish the alternate transfer source - to be used, you should set - use-alt-transfer-source - appropriately and you should not depend upon - getting a answer back to the first refresh - query. -
-
-
alt-transfer-source-v6
-

- An alternate transfer source if the one listed in - transfer-source-v6 fails and - use-alt-transfer-source is - set. -

-
use-alt-transfer-source
-

- Use the alternate transfer sources or not. If views are - specified this defaults to no - otherwise it defaults to - yes (for BIND 8 - compatibility). -

-
notify-source
-
-

notify-source - determines which local source address, and - optionally UDP port, will be used to send NOTIFY - messages. This address must appear in the slave - server's masters zone clause or - in an allow-notify clause. This - statement sets the notify-source - for all zones, but can be overridden on a per-zone or - per-view basis by including a - notify-source statement within - the zone or - view block in the configuration - file. -

-
-

Note

-

- Solaris 2.5.1 and earlier does not support setting the - source address for TCP sockets. -

-
-
-
notify-source-v6
-

- Like notify-source, - but applies to notify messages sent to IPv6 addresses. -

-
-
-
-

-Bad UDP Port Lists

-

avoid-v4-udp-ports - and avoid-v6-udp-ports specify a list - of IPv4 and IPv6 UDP ports that will not be used as system - assigned source ports for UDP sockets. These lists - prevent named from choosing as its random source port a - port that is blocked by your firewall. If a query went - out with such a source port, the answer would not get by - the firewall and the name server would have to query - again. -

-
-
-

-Operating System Resource Limits

-

- The server's usage of many system resources can be limited. - Scaled values are allowed when specifying resource limits. For - example, 1G can be used instead of - 1073741824 to specify a limit of - one - gigabyte. unlimited requests - unlimited use, or the - maximum available amount. default - uses the limit - that was in force when the server was started. See the description - of size_spec in the section called “Configuration File Elements”. -

-

- The following options set operating system resource limits for - the name server process. Some operating systems don't support - some or - any of the limits. On such systems, a warning will be issued if - the - unsupported limit is used. -

-
-
coresize
-

- The maximum size of a core dump. The default - is default. -

-
datasize
-

- The maximum amount of data memory the server - may use. The default is default. - This is a hard limit on server memory usage. - If the server attempts to allocate memory in excess of this - limit, the allocation will fail, which may in turn leave - the server unable to perform DNS service. Therefore, - this option is rarely useful as a way of limiting the - amount of memory used by the server, but it can be used - to raise an operating system data size limit that is - too small by default. If you wish to limit the amount - of memory used by the server, use the - max-cache-size and - recursive-clients - options instead. -

-
files
-

- The maximum number of files the server - may have open concurrently. The default is unlimited. -

-
stacksize
-

- The maximum amount of stack memory the server - may use. The default is default. -

-
-
-
-

-Server Resource Limits

-

- The following options set limits on the server's - resource consumption that are enforced internally by the - server rather than the operating system. -

-
-
max-ixfr-log-size
-

- This option is obsolete; it is accepted - and ignored for BIND 8 compatibility. The option - max-journal-size performs a - similar function in BIND 9. -

-
max-journal-size
-

- Sets a maximum size for each journal file - (see the section called “The journal file”). When the journal file - approaches - the specified size, some of the oldest transactions in the - journal - will be automatically removed. The default is - unlimited. -

-
host-statistics-max
-

- In BIND 8, specifies the maximum number of host statistics - entries to be kept. - Not implemented in BIND 9. -

-
recursive-clients
-

- The maximum number of simultaneous recursive lookups - the server will perform on behalf of clients. The default - is - 1000. Because each recursing - client uses a fair - bit of memory, on the order of 20 kilobytes, the value of - the - recursive-clients option may - have to be decreased - on hosts with limited memory. -

-
tcp-clients
-

- The maximum number of simultaneous client TCP - connections that the server will accept. - The default is 100. -

-
max-cache-size
-

- The maximum amount of memory to use for the - server's cache, in bytes. When the amount of data in the - cache - reaches this limit, the server will cause records to expire - prematurely so that the limit is not exceeded. In a server - with - multiple views, the limit applies separately to the cache of - each - view. The default is unlimited, meaning that - records are purged from the cache only when their TTLs - expire. -

-
tcp-listen-queue
-

- The listen queue depth. The default and minimum is 3. - If the kernel supports the accept filter "dataready" this - also controls how - many TCP connections that will be queued in kernel space - waiting for - some data before being passed to accept. Values less than 3 - will be - silently raised. -

-
-
-
-

-Periodic Task Intervals

-
-
cleaning-interval
-

- The server will remove expired resource records - from the cache every cleaning-interval minutes. - The default is 60 minutes. The maximum value is 28 days - (40320 minutes). - If set to 0, no periodic cleaning will occur. -

-
heartbeat-interval
-

- The server will perform zone maintenance tasks - for all zones marked as dialup whenever this - interval expires. The default is 60 minutes. Reasonable - values are up - to 1 day (1440 minutes). The maximum value is 28 days - (40320 minutes). - If set to 0, no zone maintenance for these zones will occur. -

-
interface-interval
-

- The server will scan the network interface list - every interface-interval - minutes. The default - is 60 minutes. The maximum value is 28 days (40320 minutes). - If set to 0, interface scanning will only occur when - the configuration file is loaded. After the scan, the - server will - begin listening for queries on any newly discovered - interfaces (provided they are allowed by the - listen-on configuration), and - will - stop listening on interfaces that have gone away. -

-
statistics-interval
-
-

- Name server statistics will be logged - every statistics-interval - minutes. The default is - 60. The maximum value is 28 days (40320 minutes). - If set to 0, no statistics will be logged. -

-
-

Note

-

- Not yet implemented in - BIND 9. -

-
-
-
-
-
-

-Topology

-

- All other things being equal, when the server chooses a name - server - to query from a list of name servers, it prefers the one that is - topologically closest to itself. The topology statement - takes an address_match_list and - interprets it - in a special way. Each top-level list element is assigned a - distance. - Non-negated elements get a distance based on their position in the - list, where the closer the match is to the start of the list, the - shorter the distance is between it and the server. A negated match - will be assigned the maximum distance from the server. If there - is no match, the address will get a distance which is further than - any non-negated list element, and closer than any negated element. - For example, -

-
topology {
-    10/8;
-    !1.2.3/24;
-    { 1.2/16; 3/8; };
-};
-

- will prefer servers on network 10 the most, followed by hosts - on network 1.2.0.0 (netmask 255.255.0.0) and network 3, with the - exception of hosts on network 1.2.3 (netmask 255.255.255.0), which - is preferred least of all. -

-

- The default topology is -

-
    topology { localhost; localnets; };
-
-
-

Note

-

- The topology option - is not implemented in BIND 9. -

-
-
-
-

-The sortlist Statement

-

- The response to a DNS query may consist of multiple resource - records (RRs) forming a resource records set (RRset). - The name server will normally return the - RRs within the RRset in an indeterminate order - (but see the rrset-order - statement in the section called “RRset Ordering”). - The client resolver code should rearrange the RRs as appropriate, - that is, using any addresses on the local net in preference to - other addresses. - However, not all resolvers can do this or are correctly - configured. - When a client is using a local server, the sorting can be performed - in the server, based on the client's address. This only requires - configuring the name servers, not all the clients. -

-

- The sortlist statement (see below) - takes - an address_match_list and - interprets it even - more specifically than the topology - statement - does (the section called “Topology”). - Each top level statement in the sortlist must - itself be an explicit address_match_list with - one or two elements. The first element (which may be an IP - address, - an IP prefix, an ACL name or a nested address_match_list) - of each top level list is checked against the source address of - the query until a match is found. -

-

- Once the source address of the query has been matched, if - the top level statement contains only one element, the actual - primitive - element that matched the source address is used to select the - address - in the response to move to the beginning of the response. If the - statement is a list of two elements, then the second element is - treated the same as the address_match_list in - a topology statement. Each top - level element - is assigned a distance and the address in the response with the - minimum - distance is moved to the beginning of the response. -

-

- In the following example, any queries received from any of - the addresses of the host itself will get responses preferring - addresses - on any of the locally connected networks. Next most preferred are - addresses - on the 192.168.1/24 network, and after that either the - 192.168.2/24 - or - 192.168.3/24 network with no preference shown between these two - networks. Queries received from a host on the 192.168.1/24 network - will prefer other addresses on that network to the 192.168.2/24 - and - 192.168.3/24 networks. Queries received from a host on the - 192.168.4/24 - or the 192.168.5/24 network will only prefer other addresses on - their directly connected networks. -

-
sortlist {
-    { localhost;                                   // IF   the local host
-        { localnets;                               // THEN first fit on the
-            192.168.1/24;                          //   following nets
-            { 192.168.2/24; 192.168.3/24; }; }; };
-    { 192.168.1/24;                                // IF   on class C 192.168.1
-        { 192.168.1/24;                            // THEN use .1, or .2 or .3
-            { 192.168.2/24; 192.168.3/24; }; }; };
-    { 192.168.2/24;                                // IF   on class C 192.168.2
-        { 192.168.2/24;                            // THEN use .2, or .1 or .3
-            { 192.168.1/24; 192.168.3/24; }; }; };
-    { 192.168.3/24;                                // IF   on class C 192.168.3
-        { 192.168.3/24;                            // THEN use .3, or .1 or .2
-            { 192.168.1/24; 192.168.2/24; }; }; };
-    { { 192.168.4/24; 192.168.5/24; };             // if .4 or .5, prefer that net
-    };
-};
-

- The following example will give reasonable behavior for the - local host and hosts on directly connected networks. It is similar - to the behavior of the address sort in BIND 4.9.x. Responses sent - to queries from the local host will favor any of the directly - connected - networks. Responses sent to queries from any other hosts on a - directly - connected network will prefer addresses on that same network. - Responses - to other queries will not be sorted. -

-
sortlist {
-           { localhost; localnets; };
-           { localnets; };
-};
-
-
-
-

-RRset Ordering

-

- When multiple records are returned in an answer it may be - useful to configure the order of the records placed into the - response. - The rrset-order statement permits - configuration - of the ordering of the records in a multiple record response. - See also the sortlist statement, - the section called “The sortlist Statement”. -

-

- An order_spec is defined as - follows: -

-

- [class class_name] - [type type_name] - [name "domain_name"] - order ordering -

-

- If no class is specified, the default is ANY. - If no type is specified, the default is ANY. - If no name is specified, the default is "*" (asterisk). -

-

- The legal values for ordering are: -

-
---- - - - - - - - - - - - - - - -
-

fixed

-
-

- Records are returned in the order they - are defined in the zone file. -

-
-

random

-
-

- Records are returned in some random order. -

-
-

cyclic

-
-

- Records are returned in a round-robin - order. -

-
-

- For example: -

-
rrset-order {
-   class IN type A name "host.example.com" order random;
-   order cyclic;
-};
-
-

- will cause any responses for type A records in class IN that - have "host.example.com" as a - suffix, to always be returned - in random order. All other records are returned in cyclic order. -

-

- If multiple rrset-order statements - appear, - they are not combined — the last one applies. -

-
-

Note

-

- The rrset-order statement - is not yet fully implemented in BIND 9. - BIND 9 currently does not fully support "fixed" ordering. -

-
-
-
-

-Tuning

-
-
lame-ttl
-

- Sets the number of seconds to cache a - lame server indication. 0 disables caching. (This is - NOT recommended.) - The default is 600 (10 minutes) and the - maximum value is - 1800 (30 minutes). -

-
max-ncache-ttl
-

- To reduce network traffic and increase performance, - the server stores negative answers. max-ncache-ttl is - used to set a maximum retention time for these answers in - the server - in seconds. The default - max-ncache-ttl is 10800 seconds (3 hours). - max-ncache-ttl cannot exceed - 7 days and will - be silently truncated to 7 days if set to a greater value. -

-
max-cache-ttl
-

- Sets the maximum time for which the server will - cache ordinary (positive) answers. The default is - one week (7 days). -

-
min-roots
-
-

- The minimum number of root servers that - is required for a request for the root servers to be - accepted. The default - is 2. -

-
-

Note

-

- Not implemented in BIND 9. -

-
-
-
sig-validity-interval
-

- Specifies the number of days into the - future when DNSSEC signatures automatically generated as a - result - of dynamic updates (the section called “Dynamic Update”) - will expire. The default is 30 days. - The maximum value is 10 years (3660 days). The signature - inception time is unconditionally set to one hour before the - current time - to allow for a limited amount of clock skew. -

-
-min-refresh-time, max-refresh-time, min-retry-time, max-retry-time -
-
-

- These options control the server's behavior on refreshing a - zone - (querying for SOA changes) or retrying failed transfers. - Usually the SOA values for the zone are used, but these - values - are set by the master, giving slave server administrators - little - control over their contents. -

-

- These options allow the administrator to set a minimum and - maximum - refresh and retry time either per-zone, per-view, or - globally. - These options are valid for slave and stub zones, - and clamp the SOA refresh and retry times to the specified - values. -

-
-
edns-udp-size
-

- Sets the advertised EDNS UDP buffer size in bytes. Valid - values are 512 to 4096 (values outside this range - will be silently adjusted). The default value is - 4096. The usual reason for setting edns-udp-size to - a non-default value is to get UDP answers to pass - through broken firewalls that block fragmented - packets and/or block UDP packets that are greater - than 512 bytes. -

-
max-udp-size
-

- Sets the maximum EDNS UDP message size named will - send in bytes. Valid values are 512 to 4096 (values outside - this range will be silently adjusted). The default - value is 4096. The usual reason for setting - max-udp-size to a non-default value is to get UDP - answers to pass through broken firewalls that - block fragmented packets and/or block UDP packets - that are greater than 512 bytes. - This is independent of the advertised receive - buffer (edns-udp-size). -

-
masterfile-format
-

Specifies - the file format of zone files (see - the section called “Additional File Formats”). - The default value is text, which is the - standard textual representation. Files in other formats - than text are typically expected - to be generated by the named-compilezone tool. - Note that when a zone file in a different format than - text is loaded, named - may omit some of the checks which would be performed for a - file in the text format. In particular, - check-names checks do not apply - for the raw format. This means - a zone file in the raw format - must be generated with the same check level as that - specified in the named configuration - file. This statement sets the - masterfile-format for all zones, - but can be overridden on a per-zone or per-view basis - by including a masterfile-format - statement within the zone or - view block in the configuration - file. -

-
-clients-per-query, max-clients-per-query -
-
-

These set the - initial value (minimum) and maximum number of recursive - simultanious clients for any given query - (<qname,qtype,qclass>) that the server will accept - before dropping additional clients. named will attempt to - self tune this value and changes will be logged. The - default values are 10 and 100. -

-

- This value should reflect how many queries come in for - a given name in the time it takes to resolve that name. - If the number of queries exceed this value, named will - assume that it is dealing with a non-responsive zone - and will drop additional queries. If it gets a response - after dropping queries, it will raise the estimate. The - estimate will then be lowered in 20 minutes if it has - remained unchanged. -

-

- If clients-per-query is set to zero, - then there is no limit on the number of clients per query - and no queries will be dropped. -

-

- If max-clients-per-query is set to zero, - then there is no upper bound other than imposed by - recursive-clients. -

-
-
notify-delay
-

- The delay, in seconds, between sending sets of notify - messages for a zone. The default is zero. -

-
-
-
-

-Built-in server information zones

-

- The server provides some helpful diagnostic information - through a number of built-in zones under the - pseudo-top-level-domain bind in the - CHAOS class. These zones are part - of a - built-in view (see the section called “view Statement Grammar”) of - class - CHAOS which is separate from the - default view of - class IN; therefore, any global - server options - such as allow-query do not apply - the these zones. - If you feel the need to disable these zones, use the options - below, or hide the built-in CHAOS - view by - defining an explicit view of class CHAOS - that matches all clients. -

-
-
version
-

- The version the server should report - via a query of the name version.bind - with type TXT, class CHAOS. - The default is the real version number of this server. - Specifying version none - disables processing of the queries. -

-
hostname
-

- The hostname the server should report via a query of - the name hostname.bind - with type TXT, class CHAOS. - This defaults to the hostname of the machine hosting the - name server as - found by the gethostname() function. The primary purpose of such queries - is to - identify which of a group of anycast servers is actually - answering your queries. Specifying hostname none; - disables processing of the queries. -

-
server-id
-

- The ID of the server should report via a query of - the name ID.SERVER - with type TXT, class CHAOS. - The primary purpose of such queries is to - identify which of a group of anycast servers is actually - answering your queries. Specifying server-id none; - disables processing of the queries. - Specifying server-id hostname; will cause named to - use the hostname as found by the gethostname() function. - The default server-id is none. -

-
-
-
-

-Built-in Empty Zones

-

- Named has some built-in empty zones (SOA and NS records only). - These are for zones that should normally be answered locally - and which queries should not be sent to the Internet's root - servers. The official servers which cover these namespaces - return NXDOMAIN responses to these queries. In particular, - these cover the reverse namespace for addresses from RFC 1918 and - RFC 3330. They also include the reverse namespace for IPv6 local - address (locally assigned), IPv6 link local addresses, the IPv6 - loopback address and the IPv6 unknown addresss. -

-

- Named will attempt to determine if a built in zone already exists - or is active (covered by a forward-only forwarding declaration) - and will not not create a empty zone in that case. -

-

- The current list of empty zones is: -

-
    -
  • 10.IN-ADDR.ARPA
  • -
  • 127.IN-ADDR.ARPA
  • -
  • 254.169.IN-ADDR.ARPA
  • -
  • 16.172.IN-ADDR.ARPA
  • -
  • 17.172.IN-ADDR.ARPA
  • -
  • 18.172.IN-ADDR.ARPA
  • -
  • 19.172.IN-ADDR.ARPA
  • -
  • 20.172.IN-ADDR.ARPA
  • -
  • 21.172.IN-ADDR.ARPA
  • -
  • 22.172.IN-ADDR.ARPA
  • -
  • 23.172.IN-ADDR.ARPA
  • -
  • 24.172.IN-ADDR.ARPA
  • -
  • 25.172.IN-ADDR.ARPA
  • -
  • 26.172.IN-ADDR.ARPA
  • -
  • 27.172.IN-ADDR.ARPA
  • -
  • 28.172.IN-ADDR.ARPA
  • -
  • 29.172.IN-ADDR.ARPA
  • -
  • 30.172.IN-ADDR.ARPA
  • -
  • 31.172.IN-ADDR.ARPA
  • -
  • 168.192.IN-ADDR.ARPA
  • -
  • 2.0.192.IN-ADDR.ARPA
  • -
  • 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA
  • -
  • 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA
  • -
  • D.F.IP6.ARPA
  • -
  • 8.E.F.IP6.ARPA
  • -
  • 9.E.F.IP6.ARPA
  • -
  • A.E.F.IP6.ARPA
  • -
  • B.E.F.IP6.ARPA
  • -
-

-

-

- Empty zones are settable at the view level and only apply to - views of class IN. Disabled empty zones are only inherited - from options if there are no disabled empty zones specified - at the view level. To override the options list of disabled - zones, you can disable the root zone at the view level, for example: -

-
-            disable-empty-zone ".";
-
-

-

-

- If you are using the address ranges covered here, you should - already have reverse zones covering the addresses you use. - In practice this appears to not be the case with many queries - being made to the infrastructure servers for names in these - spaces. So many in fact that sacrificial servers were needed - to be deployed to channel the query load away from the - infrastructure servers. -

-
-

Note

- The real parent servers for these zones should disable all - empty zone under the parent zone they serve. For the real - root servers, this is all built in empty zones. This will - enable them to return referrals to deeper in the tree. -
-
-
empty-server
-

- Specify what server name will appear in the returned - SOA record for empty zones. If none is specified, then - the zone's name will be used. -

-
empty-contact
-

- Specify what contact name will appear in the returned - SOA record for empty zones. If none is specified, then - "." will be used. -

-
empty-zones-enable
-

- Enable or disable all empty zones. By default they - are enabled. -

-
disable-empty-zone
-

- Disable individual empty zones. By default none are - disabled. This option can be specified multiple times. -

-
-
-
-

-The Statistics File

-

- The statistics file generated by BIND 9 - is similar, but not identical, to that - generated by BIND 8. -

-

- The statistics dump begins with a line, like: -

-

- +++ Statistics Dump +++ (973798949) -

-

- The number in parentheses is a standard - Unix-style timestamp, measured as seconds since January 1, 1970. - Following - that line are a series of lines containing a counter type, the - value of the - counter, optionally a zone name, and optionally a view name. - The lines without view and zone listed are global statistics for - the entire server. - Lines with a zone and view name for the given view and zone (the - view name is - omitted for the default view). -

-

- The statistics dump ends with the line where the - number is identical to the number in the beginning line; for example: -

-

- --- Statistics Dump --- (973798949) -

-

- The following statistics counters are maintained: -

-
---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

success

-
-

- The number of - successful queries made to the server or zone. A - successful query - is defined as query which returns a NOERROR response - with at least - one answer RR. -

-
-

referral

-
-

- The number of queries which resulted - in referral responses. -

-
-

nxrrset

-
-

- The number of queries which resulted in - NOERROR responses with no data. -

-
-

nxdomain

-
-

- The number - of queries which resulted in NXDOMAIN responses. -

-
-

failure

-
-

- The number of queries which resulted in a - failure response other than those above. -

-
-

recursion

-
-

- The number of queries which caused the server - to perform recursion in order to find the final answer. -

-
-

duplicate

-
-

- The number of queries which the server attempted to - recurse but discover a existing query with the same - IP address, port, query id, name, type and class - already being processed. -

-
-

dropped

-
-

- The number of queries for which the server - discovered a excessive number of existing - recursive queries for the same name, type and - class and were subsequently dropped. -

-
-

- Each query received by the server will cause exactly one of - success, - referral, - nxrrset, - nxdomain, or - failure - to be incremented, and may additionally cause the - recursion counter to be - incremented. -

-
-
-

-Additional Section Caching

-

- The additional section cache, also called acache, - is an internal cache to improve the response performance of BIND 9. - When additional section caching is enabled, BIND 9 will - cache an internal short-cut to the additional section content for - each answer RR. - Note that acache is an internal caching - mechanism of BIND 9, and is not related to the DNS caching - server function. -

-

- Additional section caching does not change the - response content (except the RRsets ordering of the additional - section, see below), but can improve the response performance - significantly. - It is particularly effective when BIND 9 acts as an authoritative - server for a zone that has many delegations with many glue RRs. -

-

- In order to obtain the maximum performance improvement - from additional section caching, setting - additional-from-cache - to no is recommended, since the current - implementation of acache - does not short-cut of additional section information from the - DNS cache data. -

-

- One obvious disadvantage of acache is - that it requires much more - memory for the internal cached data. - Thus, if the response performance does not matter and memory - consumption is much more critical, the - acache mechanism can be - disabled by setting acache-enable to - no. - It is also possible to specify the upper limit of memory - consumption - for acache by using max-acache-size. -

-

- Additional section caching also has a minor effect on the - RRset ordering in the additional section. - Without acache, - cyclic order is effective for the additional - section as well as the answer and authority sections. - However, additional section caching fixes the ordering when it - first caches an RRset for the additional section, and the same - ordering will be kept in succeeding responses, regardless of the - setting of rrset-order. - The effect of this should be minor, however, since an - RRset in the additional section - typically only contains a small number of RRs (and in many cases - it only contains a single RR), in which case the - ordering does not matter much. -

-

- The following is a summary of options related to - acache. -

-
-
acache-enable
-

- If yes, additional section caching is - enabled. The default value is no. -

-
acache-cleaning-interval
-

- The server will remove stale cache entries, based on an LRU - based - algorithm, every acache-cleaning-interval minutes. - The default is 60 minutes. - If set to 0, no periodic cleaning will occur. -

-
max-acache-size
-

- The maximum amount of memory in bytes to use for the server's acache. - When the amount of data in the acache reaches this limit, - the server - will clean more aggressively so that the limit is not - exceeded. - In a server with multiple views, the limit applies - separately to the - acache of each view. - The default is unlimited, - meaning that - entries are purged from the acache only at the - periodic cleaning time. -

-
-
-
-
-

-server Statement Grammar

-
server ip_addr[/prefixlen] {
-    [ bogus yes_or_no ; ]
-    [ provide-ixfr yes_or_no ; ]
-    [ request-ixfr yes_or_no ; ]
-    [ edns yes_or_no ; ]
-    [ edns-udp-size number ; ]
-    [ max-udp-size number ; ]
-    [ transfers number ; ]
-    [ transfer-format ( one-answer | many-answers ) ; ]]
-    [ keys { string ; [ string ; [...]] } ; ]
-    [ transfer-source (ip4_addr | *) [port ip_port] ; ]
-    [ transfer-source-v6 (ip6_addr | *) [port ip_port] ; ]
-    [ notify-source (ip4_addr | *) [port ip_port] ; ]
-    [ notify-source-v6 (ip6_addr | *) [port ip_port] ; ]
-    [ query-source [ address ( ip_addr | * ) ] [ port ( ip_port | * ) ]; ]
-    [ query-source-v6 [ address ( ip_addr | * ) ] [ port ( ip_port | * ) ]; ]
-};
-
-
-
-

-server Statement Definition and - Usage

-

- The server statement defines - characteristics - to be associated with a remote name server. If a prefix length is - specified, then a range of servers is covered. Only the most - specific - server clause applies regardless of the order in - named.conf. -

-

- The server statement can occur at - the top level of the - configuration file or inside a view - statement. - If a view statement contains - one or more server statements, only - those - apply to the view and any top-level ones are ignored. - If a view contains no server - statements, - any top-level server statements are - used as - defaults. -

-

- If you discover that a remote server is giving out bad data, - marking it as bogus will prevent further queries to it. The - default - value of bogus is no. -

-

- The provide-ixfr clause determines - whether - the local server, acting as master, will respond with an - incremental - zone transfer when the given remote server, a slave, requests it. - If set to yes, incremental transfer - will be provided - whenever possible. If set to no, - all transfers - to the remote server will be non-incremental. If not set, the - value - of the provide-ixfr option in the - view or - global options block is used as a default. -

-

- The request-ixfr clause determines - whether - the local server, acting as a slave, will request incremental zone - transfers from the given remote server, a master. If not set, the - value of the request-ixfr option in - the view or - global options block is used as a default. -

-

- IXFR requests to servers that do not support IXFR will - automatically - fall back to AXFR. Therefore, there is no need to manually list - which servers support IXFR and which ones do not; the global - default - of yes should always work. - The purpose of the provide-ixfr and - request-ixfr clauses is - to make it possible to disable the use of IXFR even when both - master - and slave claim to support it, for example if one of the servers - is buggy and crashes or corrupts data when IXFR is used. -

-

- The edns clause determines whether - the local server will attempt to use EDNS when communicating - with the remote server. The default is yes. -

-

- The edns-udp-size option sets the EDNS UDP size - that is advertised by named when querying the remote server. - Valid values are 512 to 4096 bytes (values outside this range will be - silently adjusted). This option is useful when you wish to - advertises a different value to this server than the value you - advertise globally, for example, when there is a firewall at the - remote site that is blocking large replies. -

-

- The max-udp-size option sets the - maximum EDNS UDP message size named will send. Valid - values are 512 to 4096 bytes (values outside this range will - be silently adjusted). This option is useful when you - know that there is a firewall that is blocking large - replies from named. -

-

- The server supports two zone transfer methods. The first, one-answer, - uses one DNS message per resource record transferred. many-answers packs - as many resource records as possible into a message. many-answers is - more efficient, but is only known to be understood by BIND 9, BIND - 8.x, and patched versions of BIND - 4.9.5. You can specify which method - to use for a server with the transfer-format option. - If transfer-format is not - specified, the transfer-format - specified - by the options statement will be - used. -

-

transfers - is used to limit the number of concurrent inbound zone - transfers from the specified server. If no - transfers clause is specified, the - limit is set according to the - transfers-per-ns option. -

-

- The keys clause identifies a - key_id defined by the key statement, - to be used for transaction security (TSIG, the section called “TSIG”) - when talking to the remote server. - When a request is sent to the remote server, a request signature - will be generated using the key specified here and appended to the - message. A request originating from the remote server is not - required - to be signed by this key. -

-

- Although the grammar of the keys - clause - allows for multiple keys, only a single key per server is - currently - supported. -

-

- The transfer-source and - transfer-source-v6 clauses specify - the IPv4 and IPv6 source - address to be used for zone transfer with the remote server, - respectively. - For an IPv4 remote server, only transfer-source can - be specified. - Similarly, for an IPv6 remote server, only - transfer-source-v6 can be - specified. - For more details, see the description of - transfer-source and - transfer-source-v6 in - the section called “Zone Transfers”. -

-

- The notify-source and - notify-source-v6 clauses specify the - IPv4 and IPv6 source address to be used for notify - messages sent to remote servers, respectively. For an - IPv4 remote server, only notify-source - can be specified. Similarly, for an IPv6 remote server, - only notify-source-v6 can be specified. -

-

- The query-source and - query-source-v6 clauses specify the - IPv4 and IPv6 source address to be used for queries - sent to remote servers, respectively. For an IPv4 - remote server, only query-source can - be specified. Similarly, for an IPv6 remote server, - only query-source-v6 can be specified. -

-
-
-

-trusted-keys Statement Grammar

-
trusted-keys {
-    string number number number string ;
-    [ string number number number string ; [...]]
-};
-
-
-
-

-trusted-keys Statement Definition - and Usage

-

- The trusted-keys statement defines - DNSSEC security roots. DNSSEC is described in the section called “DNSSEC”. A security root is defined when the - public key for a non-authoritative zone is known, but - cannot be securely obtained through DNS, either because - it is the DNS root zone or because its parent zone is - unsigned. Once a key has been configured as a trusted - key, it is treated as if it had been validated and - proven secure. The resolver attempts DNSSEC validation - on all DNS data in subdomains of a security root. -

-

- All keys (and corresponding zones) listed in - trusted-keys are deemed to exist regardless - of what parent zones say. Similarly for all keys listed in - trusted-keys only those keys are - used to validate the DNSKEY RRset. The parent's DS RRset - will not be used. -

-

- The trusted-keys statement can contain - multiple key entries, each consisting of the key's - domain name, flags, protocol, algorithm, and the Base-64 - representation of the key data. -

-
-
-

-view Statement Grammar

-
view view_name
-      [class] {
-      match-clients { address_match_list };
-      match-destinations { address_match_list };
-      match-recursive-only yes_or_no ;
-      [ view_option; ...]
-      [ zone_statement; ...]
-};
-
-
-
-

-view Statement Definition and Usage

-

- The view statement is a powerful - feature - of BIND 9 that lets a name server - answer a DNS query differently - depending on who is asking. It is particularly useful for - implementing - split DNS setups without having to run multiple servers. -

-

- Each view statement defines a view - of the - DNS namespace that will be seen by a subset of clients. A client - matches - a view if its source IP address matches the - address_match_list of the view's - match-clients clause and its - destination IP address matches - the address_match_list of the - view's - match-destinations clause. If not - specified, both - match-clients and match-destinations - default to matching all addresses. In addition to checking IP - addresses - match-clients and match-destinations - can also take keys which provide an - mechanism for the - client to select the view. A view can also be specified - as match-recursive-only, which - means that only recursive - requests from matching clients will match that view. - The order of the view statements is - significant — - a client request will be resolved in the context of the first - view that it matches. -

-

- Zones defined within a view - statement will - be only be accessible to clients that match the view. - By defining a zone of the same name in multiple views, different - zone data can be given to different clients, for example, - "internal" - and "external" clients in a split DNS setup. -

-

- Many of the options given in the options statement - can also be used within a view - statement, and then - apply only when resolving queries with that view. When no - view-specific - value is given, the value in the options statement - is used as a default. Also, zone options can have default values - specified - in the view statement; these - view-specific defaults - take precedence over those in the options statement. -

-

- Views are class specific. If no class is given, class IN - is assumed. Note that all non-IN views must contain a hint zone, - since only the IN class has compiled-in default hints. -

-

- If there are no view statements in - the config - file, a default view that matches any client is automatically - created - in class IN. Any zone statements - specified on - the top level of the configuration file are considered to be part - of - this default view, and the options - statement will - apply to the default view. If any explicit view - statements are present, all zone - statements must - occur inside view statements. -

-

- Here is an example of a typical split DNS setup implemented - using view statements: -

-
view "internal" {
-      // This should match our internal networks.
-      match-clients { 10.0.0.0/8; };
-
-      // Provide recursive service to internal clients only.
-      recursion yes;
-
-      // Provide a complete view of the example.com zone
-      // including addresses of internal hosts.
-      zone "example.com" {
-            type master;
-            file "example-internal.db";
-      };
-};
-
-view "external" {
-      // Match all clients not matched by the previous view.
-      match-clients { any; };
-
-      // Refuse recursive service to external clients.
-      recursion no;
-
-      // Provide a restricted view of the example.com zone
-      // containing only publicly accessible hosts.
-      zone "example.com" {
-           type master;
-           file "example-external.db";
-      };
-};
-
-
-
-

-zone - Statement Grammar

-
zone zone_name [class] {
-    type master;
-    [ allow-query { address_match_list }; ]
-    [ allow-transfer { address_match_list }; ]
-    [ allow-update { address_match_list }; ]
-    [ update-policy { update_policy_rule [...] }; ]
-    [ also-notify { ip_addr [port ip_port] ; [ ip_addr [port ip_port] ; ... ] }; ]
-    [ check-names (warn|fail|ignore) ; ]
-    [ check-mx (warn|fail|ignore) ; ]
-    [ check-wildcard yes_or_no; ]
-    [ check-integrity yes_or_no ; ]
-    [ dialup dialup_option ; ]
-    [ file string ; ]
-    [ masterfile-format (text|raw) ; ]
-    [ journal string ; ]
-    [ forward (only|first) ; ]
-    [ forwarders { [ ip_addr [port ip_port] ; ... ] }; ]
-    [ ixfr-base string ; ]
-    [ ixfr-tmp-file string ; ]
-    [ maintain-ixfr-base yes_or_no ; ]
-    [ max-ixfr-log-size number ; ]
-    [ max-transfer-idle-out number ; ]
-    [ max-transfer-time-out number ; ]
-    [ notify yes_or_no | explicit | master-only ; ]
-    [ notify-delay seconds ; ]
-    [ pubkey number number number string ; ]
-    [ notify-source (ip4_addr | *) [port ip_port] ; ]
-    [ notify-source-v6 (ip6_addr | *) [port ip_port] ; ]
-    [ zone-statistics yes_or_no ; ]
-    [ sig-validity-interval number ; ]
-    [ database string ; ]
-    [ min-refresh-time number ; ]
-    [ max-refresh-time number ; ]
-    [ min-retry-time number ; ]
-    [ max-retry-time number ; ]
-    [ key-directory path_name; ]
-    [ zero-no-soa-ttl yes_or_no ; ]
-};
-
-zone zone_name [class] {
-    type slave;
-    [ allow-notify { address_match_list }; ]
-    [ allow-query { address_match_list }; ]
-    [ allow-transfer { address_match_list }; ]
-    [ allow-update-forwarding { address_match_list }; ]
-    [ update-check-ksk yes_or_no; ]
-    [ also-notify { ip_addr [port ip_port] ; [ ip_addr [port ip_port] ; ... ] }; ]
-    [ check-names (warn|fail|ignore) ; ]
-    [ dialup dialup_option ; ]
-    [ file string ; ]
-    [ masterfile-format (text|raw) ; ]
-    [ journal string ; ]
-    [ forward (only|first) ; ]
-    [ forwarders { [ ip_addr [port ip_port] ; ... ] }; ]
-    [ ixfr-base string ; ]
-    [ ixfr-tmp-file string ; ]
-    [ maintain-ixfr-base yes_or_no ; ]
-    [ masters [port ip_port] { ( masters_list | ip_addr [port ip_port] [key key] ) ; [...] }; ]
-    [ max-ixfr-log-size number ; ]
-    [ max-transfer-idle-in number ; ]
-    [ max-transfer-idle-out number ; ]
-    [ max-transfer-time-in number ; ]
-    [ max-transfer-time-out number ; ]
-    [ notify yes_or_no | explicit | master-only ; ]
-    [ pubkey number number number string ; ]
-    [ transfer-source (ip4_addr | *) [port ip_port] ; ]
-    [ transfer-source-v6 (ip6_addr | *) [port ip_port] ; ]
-    [ alt-transfer-source (ip4_addr | *) [port ip_port] ; ]
-    [ alt-transfer-source-v6 (ip6_addr | *) [port ip_port] ; ]
-    [ use-alt-transfer-source yes_or_no; ]
-    [ notify-source (ip4_addr | *) [port ip_port] ; ]
-    [ notify-source-v6 (ip6_addr | *) [port ip_port] ; ]
-    [ zone-statistics yes_or_no ; ]
-    [ database string ; ]
-    [ min-refresh-time number ; ]
-    [ max-refresh-time number ; ]
-    [ min-retry-time number ; ]
-    [ max-retry-time number ; ]
-    [ multi-master yes_or_no ; ]
-    [ zero-no-soa-ttl yes_or_no ; ]
-};
-
-zone zone_name [class] {
-    type hint;
-    file string ;
-    [ delegation-only yes_or_no ; ]
-    [ check-names (warn|fail|ignore) ; // Not Implemented. ]
-};
-
-zone zone_name [class] {
-    type stub;
-    [ allow-query { address_match_list }; ]
-    [ check-names (warn|fail|ignore) ; ]
-    [ dialup dialup_option ; ]
-    [ delegation-only yes_or_no ; ]
-    [ file string ; ]
-    [ masterfile-format (text|raw) ; ]
-    [ forward (only|first) ; ]
-    [ forwarders { [ ip_addr [port ip_port] ; ... ] }; ]
-    [ masters [port ip_port] { ( masters_list | ip_addr [port ip_port] [key key] ) ; [...] }; ]
-    [ max-transfer-idle-in number ; ]
-    [ max-transfer-time-in number ; ]
-    [ pubkey number number number string ; ]
-    [ transfer-source (ip4_addr | *) [port ip_port] ; ]
-    [ transfer-source-v6 (ip6_addr | *) [port ip_port] ; ]
-    [ alt-transfer-source (ip4_addr | *) [port ip_port] ; ]
-    [ alt-transfer-source-v6 (ip6_addr | *) [port ip_port] ; ]
-    [ use-alt-transfer-source yes_or_no; ]
-    [ zone-statistics yes_or_no ; ]
-    [ database string ; ]
-    [ min-refresh-time number ; ]
-    [ max-refresh-time number ; ]
-    [ min-retry-time number ; ]
-    [ max-retry-time number ; ]
-    [ multi-master yes_or_no ; ]
-};
-
-zone zone_name [class] {
-    type forward;
-    [ forward (only|first) ; ]
-    [ forwarders { [ ip_addr [port ip_port] ; ... ] }; ]
-    [ delegation-only yes_or_no ; ]
-};
-
-zone zone_name [class] {
-    type delegation-only;
-};
-
-
-
-
-

-zone Statement Definition and Usage

-
-

-Zone Types

-
---- - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

- master -

-
-

- The server has a master copy of the data - for the zone and will be able to provide authoritative - answers for - it. -

-
-

- slave -

-
-

- A slave zone is a replica of a master - zone. The masters list - specifies one or more IP addresses - of master servers that the slave contacts to update - its copy of the zone. - Masters list elements can also be names of other - masters lists. - By default, transfers are made from port 53 on the - servers; this can - be changed for all servers by specifying a port number - before the - list of IP addresses, or on a per-server basis after - the IP address. - Authentication to the master can also be done with - per-server TSIG keys. - If a file is specified, then the - replica will be written to this file whenever the zone - is changed, - and reloaded from this file on a server restart. Use - of a file is - recommended, since it often speeds server startup and - eliminates - a needless waste of bandwidth. Note that for large - numbers (in the - tens or hundreds of thousands) of zones per server, it - is best to - use a two-level naming scheme for zone filenames. For - example, - a slave server for the zone example.com might place - the zone contents into a file called - ex/example.com where ex/ is - just the first two letters of the zone name. (Most - operating systems - behave very slowly if you put 100 000 files into - a single directory.) -

-
-

- stub -

-
-

- A stub zone is similar to a slave zone, - except that it replicates only the NS records of a - master zone instead - of the entire zone. Stub zones are not a standard part - of the DNS; - they are a feature specific to the BIND implementation. -

- -

- Stub zones can be used to eliminate the need for glue - NS record - in a parent zone at the expense of maintaining a stub - zone entry and - a set of name server addresses in named.conf. - This usage is not recommended for new configurations, - and BIND 9 - supports it only in a limited way. - In BIND 4/8, zone - transfers of a parent zone - included the NS records from stub children of that - zone. This meant - that, in some cases, users could get away with - configuring child stubs - only in the master server for the parent zone. BIND - 9 never mixes together zone data from different zones - in this - way. Therefore, if a BIND 9 master serving a parent - zone has child stub zones configured, all the slave - servers for the - parent zone also need to have the same child stub - zones - configured. -

- -

- Stub zones can also be used as a way of forcing the - resolution - of a given domain to use a particular set of - authoritative servers. - For example, the caching name servers on a private - network using - RFC1918 addressing may be configured with stub zones - for - 10.in-addr.arpa - to use a set of internal name servers as the - authoritative - servers for that domain. -

-
-

- forward -

-
-

- A "forward zone" is a way to configure - forwarding on a per-domain basis. A zone statement - of type forward can - contain a forward - and/or forwarders - statement, - which will apply to queries within the domain given by - the zone - name. If no forwarders - statement is present or - an empty list for forwarders is given, then no - forwarding will be done for the domain, canceling the - effects of - any forwarders in the options statement. Thus - if you want to use this type of zone to change the - behavior of the - global forward option - (that is, "forward first" - to, then "forward only", or vice versa, but want to - use the same - servers as set globally) you need to re-specify the - global forwarders. -

-
-

- hint -

-
-

- The initial set of root name servers is - specified using a "hint zone". When the server starts - up, it uses - the root hints to find a root name server and get the - most recent - list of root name servers. If no hint zone is - specified for class - IN, the server uses a compiled-in default set of root - servers hints. - Classes other than IN have no built-in defaults hints. -

-
-

- delegation-only -

-
-

- This is used to enforce the delegation-only - status of infrastructure zones (e.g. COM, NET, ORG). - Any answer that - is received without an explicit or implicit delegation - in the authority - section will be treated as NXDOMAIN. This does not - apply to the zone - apex. This should not be applied to leaf zones. -

-

- delegation-only has no - effect on answers received - from forwarders. -

-
-
-
-

-Class

-

- The zone's name may optionally be followed by a class. If - a class is not specified, class IN (for Internet), - is assumed. This is correct for the vast majority of cases. -

-

- The hesiod class is - named for an information service from MIT's Project Athena. It - is - used to share information about various systems databases, such - as users, groups, printers and so on. The keyword - HS is - a synonym for hesiod. -

-

- Another MIT development is Chaosnet, a LAN protocol created - in the mid-1970s. Zone data for it can be specified with the CHAOS class. -

-
-
-

-Zone Options

-
-
allow-notify
-

- See the description of - allow-notify in the section called “Access Control”. -

-
allow-query
-

- See the description of - allow-query in the section called “Access Control”. -

-
allow-transfer
-

- See the description of allow-transfer - in the section called “Access Control”. -

-
allow-update
-

- See the description of allow-update - in the section called “Access Control”. -

-
update-policy
-

- Specifies a "Simple Secure Update" policy. See - the section called “Dynamic Update Policies”. -

-
allow-update-forwarding
-

- See the description of allow-update-forwarding - in the section called “Access Control”. -

-
also-notify
-

- Only meaningful if notify - is - active for this zone. The set of machines that will - receive a - DNS NOTIFY message - for this zone is made up of all the listed name servers - (other than - the primary master) for the zone plus any IP addresses - specified - with also-notify. A port - may be specified - with each also-notify - address to send the notify - messages to a port other than the default of 53. - also-notify is not - meaningful for stub zones. - The default is the empty list. -

-
check-names
-

- This option is used to restrict the character set and - syntax of - certain domain names in master files and/or DNS responses - received from the - network. The default varies according to zone type. For master zones the default is fail. For slave - zones the default is warn. -

-
check-mx
-

- See the description of - check-mx in the section called “Boolean Options”. -

-
check-wildcard
-

- See the description of - check-wildcard in the section called “Boolean Options”. -

-
check-integrity
-

- See the description of - check-integrity in the section called “Boolean Options”. -

-
check-sibling
-

- See the description of - check-sibling in the section called “Boolean Options”. -

-
zero-no-soa-ttl
-

- See the description of - zero-no-soa-ttl in the section called “Boolean Options”. -

-
update-check-ksk
-

- See the description of - update-check-ksk in the section called “Boolean Options”. -

-
database
-
-

- Specify the type of database to be used for storing the - zone data. The string following the database keyword - is interpreted as a list of whitespace-delimited words. - The first word - identifies the database type, and any subsequent words are - passed - as arguments to the database to be interpreted in a way - specific - to the database type. -

-

- The default is "rbt", BIND 9's - native in-memory - red-black-tree database. This database does not take - arguments. -

-

- Other values are possible if additional database drivers - have been linked into the server. Some sample drivers are - included - with the distribution but none are linked in by default. -

-
-
dialup
-

- See the description of - dialup in the section called “Boolean Options”. -

-
delegation-only
-

- The flag only applies to hint and stub zones. If set - to yes, then the zone will also be - treated as if it - is also a delegation-only type zone. -

-
forward
-

- Only meaningful if the zone has a forwarders - list. The only value causes - the lookup to fail - after trying the forwarders and getting no answer, while first would - allow a normal lookup to be tried. -

-
forwarders
-

- Used to override the list of global forwarders. - If it is not specified in a zone of type forward, - no forwarding is done for the zone and the global options are - not used. -

-
ixfr-base
-

- Was used in BIND 8 to - specify the name - of the transaction log (journal) file for dynamic update - and IXFR. - BIND 9 ignores the option - and constructs the name of the journal - file by appending ".jnl" - to the name of the - zone file. -

-
ixfr-tmp-file
-

- Was an undocumented option in BIND 8. - Ignored in BIND 9. -

-
journal
-

- Allow the default journal's filename to be overridden. - The default is the zone's filename with ".jnl" appended. - This is applicable to master and slave zones. -

-
max-transfer-time-in
-

- See the description of - max-transfer-time-in in the section called “Zone Transfers”. -

-
max-transfer-idle-in
-

- See the description of - max-transfer-idle-in in the section called “Zone Transfers”. -

-
max-transfer-time-out
-

- See the description of - max-transfer-time-out in the section called “Zone Transfers”. -

-
max-transfer-idle-out
-

- See the description of - max-transfer-idle-out in the section called “Zone Transfers”. -

-
notify
-

- See the description of - notify in the section called “Boolean Options”. -

-
notify-delay
-

- See the description of - notify-delay in the section called “Tuning”. -

-
pubkey
-

- In BIND 8, this option was - intended for specifying - a public zone key for verification of signatures in DNSSEC - signed - zones when they are loaded from disk. BIND 9 does not verify signatures - on load and ignores the option. -

-
zone-statistics
-

- If yes, the server will keep - statistical - information for this zone, which can be dumped to the - statistics-file defined in - the server options. -

-
sig-validity-interval
-

- See the description of - sig-validity-interval in the section called “Tuning”. -

-
transfer-source
-

- See the description of - transfer-source in the section called “Zone Transfers”. -

-
transfer-source-v6
-

- See the description of - transfer-source-v6 in the section called “Zone Transfers”. -

-
alt-transfer-source
-

- See the description of - alt-transfer-source in the section called “Zone Transfers”. -

-
alt-transfer-source-v6
-

- See the description of - alt-transfer-source-v6 in the section called “Zone Transfers”. -

-
use-alt-transfer-source
-

- See the description of - use-alt-transfer-source in the section called “Zone Transfers”. -

-
notify-source
-

- See the description of - notify-source in the section called “Zone Transfers”. -

-
notify-source-v6
-

- See the description of - notify-source-v6 in the section called “Zone Transfers”. -

-
-min-refresh-time, max-refresh-time, min-retry-time, max-retry-time -
-

- See the description in the section called “Tuning”. -

-
ixfr-from-differences
-

- See the description of - ixfr-from-differences in the section called “Boolean Options”. -

-
key-directory
-

- See the description of - key-directory in the section called “options Statement Definition and - Usage”. -

-
multi-master
-

- See the description of multi-master in - the section called “Boolean Options”. -

-
masterfile-format
-

- See the description of masterfile-format - in the section called “Tuning”. -

-
-
-
-

-Dynamic Update Policies

-

- BIND 9 supports two alternative - methods of granting clients - the right to perform dynamic updates to a zone, - configured by the allow-update - and - update-policy option, - respectively. -

-

- The allow-update clause works the - same - way as in previous versions of BIND. It grants given clients the - permission to update any record of any name in the zone. -

-

- The update-policy clause is new - in BIND - 9 and allows more fine-grained control over what updates are - allowed. - A set of rules is specified, where each rule either grants or - denies - permissions for one or more names to be updated by one or more - identities. - If the dynamic update request message is signed (that is, it - includes - either a TSIG or SIG(0) record), the identity of the signer can - be determined. -

-

- Rules are specified in the update-policy zone - option, and are only meaningful for master zones. When the update-policy statement - is present, it is a configuration error for the allow-update statement - to be present. The update-policy - statement only - examines the signer of a message; the source address is not - relevant. -

-

- This is how a rule definition looks: -

-
-( grant | deny ) identity nametype name [ types ]
-
-

- Each rule grants or denies privileges. Once a message has - successfully matched a rule, the operation is immediately - granted - or denied and no further rules are examined. A rule is matched - when the signer matches the identity field, the name matches the - name field in accordance with the nametype field, and the type - matches - the types specified in the type field. -

-

- The identity field specifies a name or a wildcard name. - Normally, this - is the name of the TSIG or SIG(0) key used to sign the update - request. When a - TKEY exchange has been used to create a shared secret, the - identity of the - shared secret is the same as the identity of the key used to - authenticate the - TKEY exchange. When the identity field specifies a - wildcard name, it is subject to DNS wildcard expansion, so the - rule will apply - to multiple identities. The identity field must - contain a fully-qualified domain name. -

-

- The nametype field has 6 - values: - name, subdomain, - wildcard, self, - selfsub, and selfwild. -

-
---- - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

- name -

-
-

- Exact-match semantics. This rule matches - when the name being updated is identical - to the contents of the - name field. -

-
-

- subdomain -

-
-

- This rule matches when the name being updated - is a subdomain of, or identical to, the - contents of the name - field. -

-
-

- wildcard -

-
-

- The name field - is subject to DNS wildcard expansion, and - this rule matches when the name being updated - name is a valid expansion of the wildcard. -

-
-

- self -

-
-

- This rule matches when the name being updated - matches the contents of the - identity field. - The name field - is ignored, but should be the same as the - identity field. - The self nametype is - most useful when allowing using one key per - name to update, where the key has the same - name as the name to be updated. The - identity would - be specified as * (an asterisk) in - this case. -

-
-

- selfsub -

-
-

- This rule is similar to self - except that subdomains of self - can also be updated. -

-
-

- selfwild -

-
-

- This rule is similar to self - except that only subdomains of - self can be updated. -

-
-

- In all cases, the name - field must - specify a fully-qualified domain name. -

-

- If no types are explicitly specified, this rule matches all - types except - RRSIG, NS, SOA, and NSEC. Types may be specified by name, including - "ANY" (ANY matches all types except NSEC, which can never be - updated). - Note that when an attempt is made to delete all records - associated with a - name, the rules are checked for each existing record type. -

-
-
-
-
-

-Zone File

-
-

-Types of Resource Records and When to Use Them

-

- This section, largely borrowed from RFC 1034, describes the - concept of a Resource Record (RR) and explains when each is used. - Since the publication of RFC 1034, several new RRs have been - identified - and implemented in the DNS. These are also included. -

-
-

-Resource Records

-

- A domain name identifies a node. Each node has a set of - resource information, which may be empty. The set of resource - information associated with a particular name is composed of - separate RRs. The order of RRs in a set is not significant and - need not be preserved by name servers, resolvers, or other - parts of the DNS. However, sorting of multiple RRs is - permitted for optimization purposes, for example, to specify - that a particular nearby server be tried first. See the section called “The sortlist Statement” and the section called “RRset Ordering”. -

-

- The components of a Resource Record are: -

-
---- - - - - - - - - - - - - - - - - - - - - - - -
-

- owner name -

-
-

- The domain name where the RR is found. -

-
-

- type -

-
-

- An encoded 16-bit value that specifies - the type of the resource record. -

-
-

- TTL -

-
-

- The time-to-live of the RR. This field - is a 32-bit integer in units of seconds, and is - primarily used by - resolvers when they cache RRs. The TTL describes how - long a RR can - be cached before it should be discarded. -

-
-

- class -

-
-

- An encoded 16-bit value that identifies - a protocol family or instance of a protocol. -

-
-

- RDATA -

-
-

- The resource data. The format of the - data is type (and sometimes class) specific. -

-
-

- The following are types of valid RRs: -

-
---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

- A -

-
-

- A host address. In the IN class, this is a - 32-bit IP address. Described in RFC 1035. -

-
-

- AAAA -

-
-

- IPv6 address. Described in RFC 1886. -

-
-

- A6 -

-
-

- IPv6 address. This can be a partial - address (a suffix) and an indirection to the name - where the rest of the - address (the prefix) can be found. Experimental. - Described in RFC 2874. -

-
-

- AFSDB -

-
-

- Location of AFS database servers. - Experimental. Described in RFC 1183. -

-
-

- APL -

-
-

- Address prefix list. Experimental. - Described in RFC 3123. -

-
-

- CERT -

-
-

- Holds a digital certificate. - Described in RFC 2538. -

-
-

- CNAME -

-
-

- Identifies the canonical name of an alias. - Described in RFC 1035. -

-
-

- DNAME -

-
-

- Replaces the domain name specified with - another name to be looked up, effectively aliasing an - entire - subtree of the domain name space rather than a single - record - as in the case of the CNAME RR. - Described in RFC 2672. -

-
-

- DNSKEY -

-
-

- Stores a public key associated with a signed - DNS zone. Described in RFC 4034. -

-
-

- DS -

-
-

- Stores the hash of a public key associated with a - signed DNS zone. Described in RFC 4034. -

-
-

- GPOS -

-
-

- Specifies the global position. Superseded by LOC. -

-
-

- HINFO -

-
-

- Identifies the CPU and OS used by a host. - Described in RFC 1035. -

-
-

- ISDN -

-
-

- Representation of ISDN addresses. - Experimental. Described in RFC 1183. -

-
-

- KEY -

-
-

- Stores a public key associated with a - DNS name. Used in original DNSSEC; replaced - by DNSKEY in DNSSECbis, but still used with - SIG(0). Described in RFCs 2535 and 2931. -

-
-

- KX -

-
-

- Identifies a key exchanger for this - DNS name. Described in RFC 2230. -

-
-

- LOC -

-
-

- For storing GPS info. Described in RFC 1876. - Experimental. -

-
-

- MX -

-
-

- Identifies a mail exchange for the domain with - a 16-bit preference value (lower is better) - followed by the host name of the mail exchange. - Described in RFC 974, RFC 1035. -

-
-

- NAPTR -

-
-

- Name authority pointer. Described in RFC 2915. -

-
-

- NSAP -

-
-

- A network service access point. - Described in RFC 1706. -

-
-

- NS -

-
-

- The authoritative name server for the - domain. Described in RFC 1035. -

-
-

- NSEC -

-
-

- Used in DNSSECbis to securely indicate that - RRs with an owner name in a certain name interval do - not exist in - a zone and indicate what RR types are present for an - existing name. - Described in RFC 4034. -

-
-

- NXT -

-
-

- Used in DNSSEC to securely indicate that - RRs with an owner name in a certain name interval do - not exist in - a zone and indicate what RR types are present for an - existing name. - Used in original DNSSEC; replaced by NSEC in - DNSSECbis. - Described in RFC 2535. -

-
-

- PTR -

-
-

- A pointer to another part of the domain - name space. Described in RFC 1035. -

-
-

- PX -

-
-

- Provides mappings between RFC 822 and X.400 - addresses. Described in RFC 2163. -

-
-

- RP -

-
-

- Information on persons responsible - for the domain. Experimental. Described in RFC 1183. -

-
-

- RRSIG -

-
-

- Contains DNSSECbis signature data. Described - in RFC 4034. -

-
-

- RT -

-
-

- Route-through binding for hosts that - do not have their own direct wide area network - addresses. - Experimental. Described in RFC 1183. -

-
-

- SIG -

-
-

- Contains DNSSEC signature data. Used in - original DNSSEC; replaced by RRSIG in - DNSSECbis, but still used for SIG(0). - Described in RFCs 2535 and 2931. -

-
-

- SOA -

-
-

- Identifies the start of a zone of authority. - Described in RFC 1035. -

-
-

- SRV -

-
-

- Information about well known network - services (replaces WKS). Described in RFC 2782. -

-
-

- TXT -

-
-

- Text records. Described in RFC 1035. -

-
-

- WKS -

-
-

- Information about which well known - network services, such as SMTP, that a domain - supports. Historical. -

-
-

- X25 -

-
-

- Representation of X.25 network addresses. - Experimental. Described in RFC 1183. -

-
-

- The following classes of resource records - are currently valid in the DNS: -

-
---- - - - - - - - - - - - - - - -
-

- IN -

-
-

- The Internet. -

-
-

- CH -

-
-

- Chaosnet, a LAN protocol created at MIT in the - mid-1970s. - Rarely used for its historical purpose, but reused for - BIND's - built-in server information zones, e.g., - version.bind. -

-
-

- HS -

-
-

- Hesiod, an information service - developed by MIT's Project Athena. It is used to share - information - about various systems databases, such as users, - groups, printers - and so on. -

-
-

- The owner name is often implicit, rather than forming an - integral - part of the RR. For example, many name servers internally form - tree - or hash structures for the name space, and chain RRs off nodes. - The remaining RR parts are the fixed header (type, class, TTL) - which is consistent for all RRs, and a variable part (RDATA) - that - fits the needs of the resource being described. -

-

- The meaning of the TTL field is a time limit on how long an - RR can be kept in a cache. This limit does not apply to - authoritative - data in zones; it is also timed out, but by the refreshing - policies - for the zone. The TTL is assigned by the administrator for the - zone where the data originates. While short TTLs can be used to - minimize caching, and a zero TTL prohibits caching, the - realities - of Internet performance suggest that these times should be on - the - order of days for the typical host. If a change can be - anticipated, - the TTL can be reduced prior to the change to minimize - inconsistency - during the change, and then increased back to its former value - following - the change. -

-

- The data in the RDATA section of RRs is carried as a combination - of binary strings and domain names. The domain names are - frequently - used as "pointers" to other data in the DNS. -

-
-
-

-Textual expression of RRs

-

- RRs are represented in binary form in the packets of the DNS - protocol, and are usually represented in highly encoded form - when - stored in a name server or resolver. In the examples provided - in - RFC 1034, a style similar to that used in master files was - employed - in order to show the contents of RRs. In this format, most RRs - are shown on a single line, although continuation lines are - possible - using parentheses. -

-

- The start of the line gives the owner of the RR. If a line - begins with a blank, then the owner is assumed to be the same as - that of the previous RR. Blank lines are often included for - readability. -

-

- Following the owner, we list the TTL, type, and class of the - RR. Class and type use the mnemonics defined above, and TTL is - an integer before the type field. In order to avoid ambiguity - in - parsing, type and class mnemonics are disjoint, TTLs are - integers, - and the type mnemonic is always last. The IN class and TTL - values - are often omitted from examples in the interests of clarity. -

-

- The resource data or RDATA section of the RR are given using - knowledge of the typical representation for the data. -

-

- For example, we might show the RRs carried in a message as: -

-
----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

- ISI.EDU. -

-
-

- MX -

-
-

- 10 VENERA.ISI.EDU. -

-
-

-
-

- MX -

-
-

- 10 VAXA.ISI.EDU -

-
-

- VENERA.ISI.EDU -

-
-

- A -

-
-

- 128.9.0.32 -

-
-

-
-

- A -

-
-

- 10.1.0.52 -

-
-

- VAXA.ISI.EDU -

-
-

- A -

-
-

- 10.2.0.27 -

-
-

-
-

- A -

-
-

- 128.9.0.33 -

-
-

- The MX RRs have an RDATA section which consists of a 16-bit - number followed by a domain name. The address RRs use a - standard - IP address format to contain a 32-bit internet address. -

-

- The above example shows six RRs, with two RRs at each of three - domain names. -

-

- Similarly we might see: -

-
----- - - - - - - - - - - - - -
-

- XX.LCS.MIT.EDU. -

-
-

- IN A -

-
-

- 10.0.0.44 -

-
  -

- CH A -

-
-

- MIT.EDU. 2420 -

-
-

- This example shows two addresses for - XX.LCS.MIT.EDU, each of a different class. -

-
-
-
-

-Discussion of MX Records

-

- As described above, domain servers store information as a - series of resource records, each of which contains a particular - piece of information about a given domain name (which is usually, - but not always, a host). The simplest way to think of a RR is as - a typed pair of data, a domain name matched with a relevant datum, - and stored with some additional type information to help systems - determine when the RR is relevant. -

-

- MX records are used to control delivery of email. The data - specified in the record is a priority and a domain name. The - priority - controls the order in which email delivery is attempted, with the - lowest number first. If two priorities are the same, a server is - chosen randomly. If no servers at a given priority are responding, - the mail transport agent will fall back to the next largest - priority. - Priority numbers do not have any absolute meaning — they are - relevant - only respective to other MX records for that domain name. The - domain - name given is the machine to which the mail will be delivered. - It must have an associated address record - (A or AAAA) — CNAME is not sufficient. -

-

- For a given domain, if there is both a CNAME record and an - MX record, the MX record is in error, and will be ignored. - Instead, - the mail will be delivered to the server specified in the MX - record - pointed to by the CNAME. -

-

- For example: -

-
------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

- example.com. -

-
-

- IN -

-
-

- MX -

-
-

- 10 -

-
-

- mail.example.com. -

-
-

-
-

- IN -

-
-

- MX -

-
-

- 10 -

-
-

- mail2.example.com. -

-
-

-
-

- IN -

-
-

- MX -

-
-

- 20 -

-
-

- mail.backup.org. -

-
-

- mail.example.com. -

-
-

- IN -

-
-

- A -

-
-

- 10.0.0.1 -

-
-

-
-

- mail2.example.com. -

-
-

- IN -

-
-

- A -

-
-

- 10.0.0.2 -

-
-

-
-

- Mail delivery will be attempted to mail.example.com and - mail2.example.com (in - any order), and if neither of those succeed, delivery to mail.backup.org will - be attempted. -

-
-
-

-Setting TTLs

-

- The time-to-live of the RR field is a 32-bit integer represented - in units of seconds, and is primarily used by resolvers when they - cache RRs. The TTL describes how long a RR can be cached before it - should be discarded. The following three types of TTL are - currently - used in a zone file. -

-
---- - - - - - - - - - - - - - - -
-

- SOA -

-
-

- The last field in the SOA is the negative - caching TTL. This controls how long other servers will - cache no-such-domain - (NXDOMAIN) responses from you. -

-

- The maximum time for - negative caching is 3 hours (3h). -

-
-

- $TTL -

-
-

- The $TTL directive at the top of the - zone file (before the SOA) gives a default TTL for every - RR without - a specific TTL set. -

-
-

- RR TTLs -

-
-

- Each RR can have a TTL as the second - field in the RR, which will control how long other - servers can cache - the it. -

-
-

- All of these TTLs default to units of seconds, though units - can be explicitly specified, for example, 1h30m. -

-
-
-

-Inverse Mapping in IPv4

-

- Reverse name resolution (that is, translation from IP address - to name) is achieved by means of the in-addr.arpa domain - and PTR records. Entries in the in-addr.arpa domain are made in - least-to-most significant order, read left to right. This is the - opposite order to the way IP addresses are usually written. Thus, - a machine with an IP address of 10.1.2.3 would have a - corresponding - in-addr.arpa name of - 3.2.1.10.in-addr.arpa. This name should have a PTR resource record - whose data field is the name of the machine or, optionally, - multiple - PTR records if the machine has more than one name. For example, - in the [example.com] domain: -

-
---- - - - - - - - - - - -
-

- $ORIGIN -

-
-

- 2.1.10.in-addr.arpa -

-
-

- 3 -

-
-

- IN PTR foo.example.com. -

-
-
-

Note

-

- The $ORIGIN lines in the examples - are for providing context to the examples only — they do not - necessarily - appear in the actual usage. They are only used here to indicate - that the example is relative to the listed origin. -

-
-
-
-

-Other Zone File Directives

-

- The Master File Format was initially defined in RFC 1035 and - has subsequently been extended. While the Master File Format - itself - is class independent all records in a Master File must be of the - same - class. -

-

- Master File Directives include $ORIGIN, $INCLUDE, - and $TTL. -

-
-

-The $ORIGIN Directive

-

- Syntax: $ORIGIN - domain-name - [comment] -

-

$ORIGIN - sets the domain name that will be appended to any - unqualified records. When a zone is first read in there - is an implicit $ORIGIN - <zone-name>. - The current $ORIGIN is appended to - the domain specified in the $ORIGIN - argument if it is not absolute. -

-
-$ORIGIN example.com.
-WWW     CNAME   MAIN-SERVER
-
-

- is equivalent to -

-
-WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM.
-
-
-
-

-The $INCLUDE Directive

-

- Syntax: $INCLUDE - filename - [ -origin ] - [ comment ] -

-

- Read and process the file filename as - if it were included into the file at this point. If origin is - specified the file is processed with $ORIGIN set - to that value, otherwise the current $ORIGIN is - used. -

-

- The origin and the current domain name - revert to the values they had prior to the $INCLUDE once - the file has been read. -

-
-

Note

-

- RFC 1035 specifies that the current origin should be restored - after - an $INCLUDE, but it is silent - on whether the current - domain name should also be restored. BIND 9 restores both of - them. - This could be construed as a deviation from RFC 1035, a - feature, or both. -

-
-
-
-

-The $TTL Directive

-

- Syntax: $TTL - default-ttl - [ -comment ] -

-

- Set the default Time To Live (TTL) for subsequent records - with undefined TTLs. Valid TTLs are of the range 0-2147483647 - seconds. -

-

$TTL - is defined in RFC 2308. -

-
-
-
-

-BIND Master File Extension: the $GENERATE Directive

-

- Syntax: $GENERATE - range - lhs - [ttl] - [class] - type - rhs - [comment] -

-

$GENERATE - is used to create a series of resource records that only - differ from each other by an - iterator. $GENERATE can be used to - easily generate the sets of records required to support - sub /24 reverse delegations described in RFC 2317: - Classless IN-ADDR.ARPA delegation. -

-
$ORIGIN 0.0.192.IN-ADDR.ARPA.
-$GENERATE 1-2 0 NS SERVER$.EXAMPLE.
-$GENERATE 1-127 $ CNAME $.0
-

- is equivalent to -

-
0.0.0.192.IN-ADDR.ARPA NS SERVER1.EXAMPLE.
-0.0.0.192.IN-ADDR.ARPA. NS SERVER2.EXAMPLE.
-1.0.0.192.IN-ADDR.ARPA. CNAME 1.0.0.0.192.IN-ADDR.ARPA.
-2.0.0.192.IN-ADDR.ARPA. CNAME 2.0.0.0.192.IN-ADDR.ARPA.
-...
-127.0.0.192.IN-ADDR.ARPA. CNAME 127.0.0.0.192.IN-ADDR.ARPA.
-
-
---- - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

range

-
-

- This can be one of two forms: start-stop - or start-stop/step. If the first form is used, then step - is set to - 1. All of start, stop and step must be positive. -

-
-

lhs

-
-

This - describes the owner name of the resource records - to be created. Any single $ - (dollar sign) - symbols within the lhs side - are replaced by the iterator value. - - To get a $ in the output, you need to escape the - $ using a backslash - \, - e.g. \$. The - $ may optionally be followed - by modifiers which change the offset from the - iterator, field width and base. - - Modifiers are introduced by a - { (left brace) immediately following the - $ as - ${offset[,width[,base]]}. - For example, ${-20,3,d} - subtracts 20 from the current value, prints the - result as a decimal in a zero-padded field of - width 3. - - Available output forms are decimal - (d), octal - (o) and hexadecimal - (x or X - for uppercase). The default modifier is - ${0,0,d}. If the - lhs is not absolute, the - current $ORIGIN is appended - to the name. -

-

- For compatibility with earlier versions, $$ is still - recognized as indicating a literal $ in the output. -

-
-

ttl

-
-

- Specifies the time-to-live of the generated records. If - not specified this will be inherited using the - normal ttl inheritance rules. -

-

class - and ttl can be - entered in either order. -

-
-

class

-
-

- Specifies the class of the generated records. - This must match the zone class if it is - specified. -

-

class - and ttl can be - entered in either order. -

-
-

type

-
-

- At present the only supported types are - PTR, CNAME, DNAME, A, AAAA and NS. -

-
-

rhs

-
-

- rhs is a domain name. It is processed - similarly to lhs. -

-
-

- The $GENERATE directive is a BIND extension - and not part of the standard zone file format. -

-

- BIND 8 does not support the optional TTL and CLASS fields. -

-
-
-

-Additional File Formats

-

- In addition to the standard textual format, BIND 9 - supports the ability to read or dump to zone files in - other formats. The raw format is - currently available as an additional format. It is a - binary format representing BIND 9's internal data - structure directly, thereby remarkably improving the - loading time. -

-

- For a primary server, a zone file in the - raw format is expected to be - generated from a textual zone file by the - named-compilezone command. For a - secondary server or for a dynamic zone, it is automatically - generated (if this format is specified by the - masterfile-format option) when - named dumps the zone contents after - zone transfer or when applying prior updates. -

-

- If a zone file in a binary format needs manual modification, - it first must be converted to a textual form by the - named-compilezone command. All - necessary modification should go to the text file, which - should then be converted to the binary form by the - named-compilezone command again. -

-

- Although the raw format uses the - network byte order and avoids architecture-dependent - data alignment so that it is as much portable as - possible, it is primarily expected to be used inside - the same single system. In order to export a zone - file in the raw format or make a - portable backup of the file, it is recommended to - convert the file to the standard textual representation. -

-
-
-
- - - diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch07.html b/contrib/bind9/doc/arm/Bv9ARM.ch07.html deleted file mode 100644 index 96acfe6..0000000 --- a/contrib/bind9/doc/arm/Bv9ARM.ch07.html +++ /dev/null @@ -1,253 +0,0 @@ - - - - - -Chapter 7. BIND 9 Security Considerations - - - - - - - - -
-

-Chapter 7. BIND 9 Security Considerations

- -
-

-Access Control Lists

-

- Access Control Lists (ACLs), are address match lists that - you can set up and nickname for future use in allow-notify, - allow-query, allow-recursion, - blackhole, allow-transfer, - etc. -

-

- Using ACLs allows you to have finer control over who can access - your name server, without cluttering up your config files with huge - lists of IP addresses. -

-

- It is a good idea to use ACLs, and to - control access to your server. Limiting access to your server by - outside parties can help prevent spoofing and denial of service (DoS) attacks against - your server. -

-

- Here is an example of how to properly apply ACLs: -

-
-// Set up an ACL named "bogusnets" that will block RFC1918 space
-// and some reserved space, which is commonly used in spoofing attacks.
-acl bogusnets {
-        0.0.0.0/8; 1.0.0.0/8; 2.0.0.0/8; 192.0.2.0/24; 224.0.0.0/3;
-        10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16;
-};
-
-// Set up an ACL called our-nets. Replace this with the real IP numbers.
-acl our-nets { x.x.x.x/24; x.x.x.x/21; };
-options {
-  ...
-  ...
-  allow-query { our-nets; };
-  allow-recursion { our-nets; };
-  ...
-  blackhole { bogusnets; };
-  ...
-};
-
-zone "example.com" {
-  type master;
-  file "m/example.com";
-  allow-query { any; };
-};
-
-

- This allows recursive queries of the server from the outside - unless recursion has been previously disabled. -

-

- For more information on how to use ACLs to protect your server, - see the AUSCERT advisory at: -

-

- ftp://ftp.auscert.org.au/pub/auscert/advisory/AL-1999.004.dns_dos -

-
-
-

-Chroot and Setuid -

-

- On UNIX servers, it is possible to run BIND in a chrooted environment - (using the chroot() function) by specifying the "-t" - option. This can help improve system security by placing BIND in - a "sandbox", which will limit the damage done if a server is - compromised. -

-

- Another useful feature in the UNIX version of BIND is the - ability to run the daemon as an unprivileged user ( -u user ). - We suggest running as an unprivileged user when using the chroot feature. -

-

- Here is an example command line to load BIND in a chroot sandbox, - /var/named, and to run named setuid to - user 202: -

-

- /usr/local/bin/named -u 202 -t /var/named -

-
-

-The chroot Environment

-

- In order for a chroot environment - to - work properly in a particular directory - (for example, /var/named), - you will need to set up an environment that includes everything - BIND needs to run. - From BIND's point of view, /var/named is - the root of the filesystem. You will need to adjust the values of - options like - like directory and pid-file to account - for this. -

-

- Unlike with earlier versions of BIND, you typically will - not need to compile named - statically nor install shared libraries under the new root. - However, depending on your operating system, you may need - to set up things like - /dev/zero, - /dev/random, - /dev/log, and - /etc/localtime. -

-
-
-

-Using the setuid Function

-

- Prior to running the named daemon, - use - the touch utility (to change file - access and - modification times) or the chown - utility (to - set the user id and/or group id) on files - to which you want BIND - to write. -

-
-

Note

- Note that if the named daemon is running as an - unprivileged user, it will not be able to bind to new restricted - ports if the server is reloaded. -
-
-
-
-

-Dynamic Update Security

-

- Access to the dynamic - update facility should be strictly limited. In earlier versions of - BIND, the only way to do this was - based on the IP - address of the host requesting the update, by listing an IP address - or - network prefix in the allow-update - zone option. - This method is insecure since the source address of the update UDP - packet - is easily forged. Also note that if the IP addresses allowed by the - allow-update option include the - address of a slave - server which performs forwarding of dynamic updates, the master can - be - trivially attacked by sending the update to the slave, which will - forward it to the master with its own source IP address causing the - master to approve it without question. -

-

- For these reasons, we strongly recommend that updates be - cryptographically authenticated by means of transaction signatures - (TSIG). That is, the allow-update - option should - list only TSIG key names, not IP addresses or network - prefixes. Alternatively, the new update-policy - option can be used. -

-

- Some sites choose to keep all dynamically-updated DNS data - in a subdomain and delegate that subdomain to a separate zone. This - way, the top-level zone containing critical data such as the IP - addresses - of public web and mail servers need not allow dynamic update at - all. -

-
-
- - - diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch08.html b/contrib/bind9/doc/arm/Bv9ARM.ch08.html deleted file mode 100644 index a475378..0000000 --- a/contrib/bind9/doc/arm/Bv9ARM.ch08.html +++ /dev/null @@ -1,139 +0,0 @@ - - - - - -Chapter 8. Troubleshooting - - - - - - - - -
-

-Chapter 8. Troubleshooting

- -
-

-Common Problems

-
-

-It's not working; how can I figure out what's wrong?

-

- The best solution to solving installation and - configuration issues is to take preventative measures by setting - up logging files beforehand. The log files provide a - source of hints and information that can be used to figure out - what went wrong and how to fix the problem. -

-
-
-
-

-Incrementing and Changing the Serial Number

-

- Zone serial numbers are just numbers — they aren't - date related. A lot of people set them to a number that - represents a date, usually of the form YYYYMMDDRR. - Occasionally they will make a mistake and set them to a - "date in the future" then try to correct them by setting - them to the "current date". This causes problems because - serial numbers are used to indicate that a zone has been - updated. If the serial number on the slave server is - lower than the serial number on the master, the slave - server will attempt to update its copy of the zone. -

-

- Setting the serial number to a lower number on the master - server than the slave server means that the slave will not perform - updates to its copy of the zone. -

-

- The solution to this is to add 2147483647 (2^31-1) to the - number, reload the zone and make sure all slaves have updated to - the new zone serial number, then reset the number to what you want - it to be, and reload the zone again. -

-
-
-

-Where Can I Get Help?

-

- The Internet Systems Consortium - (ISC) offers a wide range - of support and service agreements for BIND and DHCP servers. Four - levels of premium support are available and each level includes - support for all ISC programs, - significant discounts on products - and training, and a recognized priority on bug fixes and - non-funded feature requests. In addition, ISC offers a standard - support agreement package which includes services ranging from bug - fix announcements to remote support. It also includes training in - BIND and DHCP. -

-

- To discuss arrangements for support, contact - info@isc.org or visit the - ISC web page at - http://www.isc.org/services/support/ - to read more. -

-
-
- - - diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch09.html b/contrib/bind9/doc/arm/Bv9ARM.ch09.html deleted file mode 100644 index 3c2e779..0000000 --- a/contrib/bind9/doc/arm/Bv9ARM.ch09.html +++ /dev/null @@ -1,630 +0,0 @@ - - - - - -Appendix A. Appendices - - - - - - - - -
-

-Appendix A. Appendices

- -
-

-Acknowledgments

-
-

-A Brief History of the DNS and BIND -

-

- Although the "official" beginning of the Domain Name - System occurred in 1984 with the publication of RFC 920, the - core of the new system was described in 1983 in RFCs 882 and - 883. From 1984 to 1987, the ARPAnet (the precursor to today's - Internet) became a testbed of experimentation for developing the - new naming/addressing scheme in a rapidly expanding, - operational network environment. New RFCs were written and - published in 1987 that modified the original documents to - incorporate improvements based on the working model. RFC 1034, - "Domain Names-Concepts and Facilities", and RFC 1035, "Domain - Names-Implementation and Specification" were published and - became the standards upon which all DNS implementations are - built. -

-

- The first working domain name server, called "Jeeves", was - written in 1983-84 by Paul Mockapetris for operation on DEC - Tops-20 - machines located at the University of Southern California's - Information - Sciences Institute (USC-ISI) and SRI International's Network - Information - Center (SRI-NIC). A DNS server for - Unix machines, the Berkeley Internet - Name Domain (BIND) package, was - written soon after by a group of - graduate students at the University of California at Berkeley - under - a grant from the US Defense Advanced Research Projects - Administration - (DARPA). -

-

- Versions of BIND through - 4.8.3 were maintained by the Computer - Systems Research Group (CSRG) at UC Berkeley. Douglas Terry, Mark - Painter, David Riggle and Songnian Zhou made up the initial BIND - project team. After that, additional work on the software package - was done by Ralph Campbell. Kevin Dunlap, a Digital Equipment - Corporation - employee on loan to the CSRG, worked on BIND for 2 years, from 1985 - to 1987. Many other people also contributed to BIND development - during that time: Doug Kingston, Craig Partridge, Smoot - Carl-Mitchell, - Mike Muuss, Jim Bloom and Mike Schwartz. BIND maintenance was subsequently - handled by Mike Karels and Øivind Kure. -

-

- BIND versions 4.9 and 4.9.1 were - released by Digital Equipment - Corporation (now Compaq Computer Corporation). Paul Vixie, then - a DEC employee, became BIND's - primary caretaker. He was assisted - by Phil Almquist, Robert Elz, Alan Barrett, Paul Albitz, Bryan - Beecher, Andrew - Partan, Andy Cherenson, Tom Limoncelli, Berthold Paffrath, Fuat - Baran, Anant Kumar, Art Harkin, Win Treese, Don Lewis, Christophe - Wolfhugel, and others. -

-

- In 1994, BIND version 4.9.2 was sponsored by - Vixie Enterprises. Paul - Vixie became BIND's principal - architect/programmer. -

-

- BIND versions from 4.9.3 onward - have been developed and maintained - by the Internet Systems Consortium and its predecessor, - the Internet Software Consortium, with support being provided - by ISC's sponsors. -

-

- As co-architects/programmers, Bob Halley and - Paul Vixie released the first production-ready version of - BIND version 8 in May 1997. -

-

- BIND version 9 was released in September 2000 and is a - major rewrite of nearly all aspects of the underlying - BIND architecture. -

-

- BIND version 4 is officially deprecated and BIND version - 8 development is considered maintenance-only in favor - of BIND version 9. No additional development is done - on BIND version 4 or BIND version 8 other than for - security-related patches. -

-

- BIND development work is made - possible today by the sponsorship - of several corporations, and by the tireless work efforts of - numerous individuals. -

-
-
-
-

-General DNS Reference Information

-
-

-IPv6 addresses (AAAA)

-

- IPv6 addresses are 128-bit identifiers for interfaces and - sets of interfaces which were introduced in the DNS to facilitate - scalable Internet routing. There are three types of addresses: Unicast, - an identifier for a single interface; - Anycast, - an identifier for a set of interfaces; and Multicast, - an identifier for a set of interfaces. Here we describe the global - Unicast address scheme. For more information, see RFC 3587, - "Global Unicast Address Format." -

-

- IPv6 unicast addresses consist of a - global routing prefix, a - subnet identifier, and an - interface identifier. -

-

- The global routing prefix is provided by the - upstream provider or ISP, and (roughly) corresponds to the - IPv4 network section - of the address range. - - The subnet identifier is for local subnetting, much the - same as subnetting an - IPv4 /16 network into /24 subnets. - - The interface identifier is the address of an individual - interface on a given network; in IPv6, addresses belong to - interfaces rather than to machines. -

-

- The subnetting capability of IPv6 is much more flexible than - that of IPv4: subnetting can be carried out on bit boundaries, - in much the same way as Classless InterDomain Routing - (CIDR), and the DNS PTR representation ("nibble" format) - makes setting up reverse zones easier. -

-

- The Interface Identifier must be unique on the local link, - and is usually generated automatically by the IPv6 - implementation, although it is usually possible to - override the default setting if necessary. A typical IPv6 - address might look like: - 2001:db8:201:9:a00:20ff:fe81:2b32 -

-

- IPv6 address specifications often contain long strings - of zeros, so the architects have included a shorthand for - specifying - them. The double colon (`::') indicates the longest possible - string - of zeros that can fit, and can be used only once in an address. -

-
-
-
-

-Bibliography (and Suggested Reading)

-
-

-Request for Comments (RFCs)

-

- Specification documents for the Internet protocol suite, including - the DNS, are published as part of - the Request for Comments (RFCs) - series of technical notes. The standards themselves are defined - by the Internet Engineering Task Force (IETF) and the Internet - Engineering Steering Group (IESG). RFCs can be obtained online via FTP at: -

-

- - ftp://www.isi.edu/in-notes/RFCxxxx.txt - -

-

- (where xxxx is - the number of the RFC). RFCs are also available via the Web at: -

-

- http://www.ietf.org/rfc/. -

-
-

-Bibliography

-
-

Standards

-
-

[RFC974] C. Partridge. Mail Routing and the Domain System. January 1986.

-
-
-

[RFC1034] P.V. Mockapetris. Domain Names — Concepts and Facilities. November 1987.

-
-
-

[RFC1035] P. V. Mockapetris. Domain Names — Implementation and - Specification. November 1987.

-
-
-
-

-Proposed Standards

-
-

[RFC2181] R., R. Bush Elz. Clarifications to the DNS - Specification. July 1997.

-
-
-

[RFC2308] M. Andrews. Negative Caching of DNS - Queries. March 1998.

-
-
-

[RFC1995] M. Ohta. Incremental Zone Transfer in DNS. August 1996.

-
-
-

[RFC1996] P. Vixie. A Mechanism for Prompt Notification of Zone Changes. August 1996.

-
-
-

[RFC2136] P. Vixie, S. Thomson, Y. Rekhter, and J. Bound. Dynamic Updates in the Domain Name System. April 1997.

-
-
-

[RFC2671] P. Vixie. Extension Mechanisms for DNS (EDNS0). August 1997.

-
-
-

[RFC2672] M. Crawford. Non-Terminal DNS Name Redirection. August 1999.

-
-
-

[RFC2845] P. Vixie, O. Gudmundsson, D. Eastlake, 3rd, and B. Wellington. Secret Key Transaction Authentication for DNS (TSIG). May 2000.

-
-
-

[RFC2930] D. Eastlake, 3rd. Secret Key Establishment for DNS (TKEY RR). September 2000.

-
-
-

[RFC2931] D. Eastlake, 3rd. DNS Request and Transaction Signatures (SIG(0)s). September 2000.

-
-
-

[RFC3007] B. Wellington. Secure Domain Name System (DNS) Dynamic Update. November 2000.

-
-
-

[RFC3645] S. Kwan, P. Garg, J. Gilroy, L. Esibov, J. Westhead, and R. Hall. Generic Security Service Algorithm for Secret - Key Transaction Authentication for DNS - (GSS-TSIG). October 2003.

-
-
-
-

-DNS Security Proposed Standards

-
-

[RFC3225] D. Conrad. Indicating Resolver Support of DNSSEC. December 2001.

-
-
-

[RFC3833] D. Atkins and R. Austein. Threat Analysis of the Domain Name System (DNS). August 2004.

-
-
-

[RFC4033] R. Arends, R. Austein, M. Larson, D. Massey, and S. Rose. DNS Security Introduction and Requirements. March 2005.

-
-
-

[RFC4044] R. Arends, R. Austein, M. Larson, D. Massey, and S. Rose. Resource Records for the DNS Security Extensions. March 2005.

-
-
-

[RFC4035] R. Arends, R. Austein, M. Larson, D. Massey, and S. Rose. Protocol Modifications for the DNS - Security Extensions. March 2005.

-
-
-
-

Other Important RFCs About DNS - Implementation

-
-

[RFC1535] E. Gavron. A Security Problem and Proposed Correction With Widely - Deployed DNS Software.. October 1993.

-
-
-

[RFC1536] A. Kumar, J. Postel, C. Neuman, P. Danzig, and S. Miller. Common DNS Implementation - Errors and Suggested Fixes. October 1993.

-
-
-

[RFC1982] R. Elz and R. Bush. Serial Number Arithmetic. August 1996.

-
-
-

[RFC4074] Y. Morishita and T. Jinmei. Common Misbehaviour Against DNS - Queries for IPv6 Addresses. May 2005.

-
-
-
-

Resource Record Types

-
-

[RFC1183] C.F. Everhart, L. A. Mamakos, R. Ullmann, and P. Mockapetris. New DNS RR Definitions. October 1990.

-
-
-

[RFC1706] B. Manning and R. Colella. DNS NSAP Resource Records. October 1994.

-
-
-

[RFC2168] R. Daniel and M. Mealling. Resolution of Uniform Resource Identifiers using - the Domain Name System. June 1997.

-
-
-

[RFC1876] C. Davis, P. Vixie, T., and I. Dickinson. A Means for Expressing Location Information in the - Domain - Name System. January 1996.

-
-
-

[RFC2052] A. Gulbrandsen and P. Vixie. A DNS RR for Specifying the - Location of - Services.. October 1996.

-
-
-

[RFC2163] A. Allocchio. Using the Internet DNS to - Distribute MIXER - Conformant Global Address Mapping. January 1998.

-
-
-

[RFC2230] R. Atkinson. Key Exchange Delegation Record for the DNS. October 1997.

-
-
-

[RFC2536] D. Eastlake, 3rd. DSA KEYs and SIGs in the Domain Name System (DNS). March 1999.

-
-
-

[RFC2537] D. Eastlake, 3rd. RSA/MD5 KEYs and SIGs in the Domain Name System (DNS). March 1999.

-
-
-

[RFC2538] D. Eastlake, 3rd and O. Gudmundsson. Storing Certificates in the Domain Name System (DNS). March 1999.

-
-
-

[RFC2539] D. Eastlake, 3rd. Storage of Diffie-Hellman Keys in the Domain Name System (DNS). March 1999.

-
-
-

[RFC2540] D. Eastlake, 3rd. Detached Domain Name System (DNS) Information. March 1999.

-
-
-

[RFC2782] A. Gulbrandsen. P. Vixie. L. Esibov. A DNS RR for specifying the location of services (DNS SRV). February 2000.

-
-
-

[RFC2915] M. Mealling. R. Daniel. The Naming Authority Pointer (NAPTR) DNS Resource Record. September 2000.

-
-
-

[RFC3110] D. Eastlake, 3rd. RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS). May 2001.

-
-
-

[RFC3123] P. Koch. A DNS RR Type for Lists of Address Prefixes (APL RR). June 2001.

-
-
-

[RFC3596] S. Thomson, C. Huitema, V. Ksinant, and M. Souissi. DNS Extensions to support IP - version 6. October 2003.

-
-
-

[RFC3597] A. Gustafsson. Handling of Unknown DNS Resource Record (RR) Types. September 2003.

-
-
-
-

-DNS and the Internet

-
-

[RFC1101] P. V. Mockapetris. DNS Encoding of Network Names - and Other Types. April 1989.

-
-
-

[RFC1123] Braden. Requirements for Internet Hosts - Application and - Support. October 1989.

-
-
-

[RFC1591] J. Postel. Domain Name System Structure and Delegation. March 1994.

-
-
-

[RFC2317] H. Eidnes, G. de Groot, and P. Vixie. Classless IN-ADDR.ARPA Delegation. March 1998.

-
-
-

[RFC2826] Internet Architecture Board. IAB Technical Comment on the Unique DNS Root. May 2000.

-
-
-

[RFC2929] D. Eastlake, 3rd, E. Brunner-Williams, and B. Manning. Domain Name System (DNS) IANA Considerations. September 2000.

-
-
-
-

-DNS Operations

-
-

[RFC1033] M. Lottor. Domain administrators operations guide.. November 1987.

-
-
-

[RFC1537] P. Beertema. Common DNS Data File - Configuration Errors. October 1993.

-
-
-

[RFC1912] D. Barr. Common DNS Operational and - Configuration Errors. February 1996.

-
-
-

[RFC2010] B. Manning and P. Vixie. Operational Criteria for Root Name Servers.. October 1996.

-
-
-

[RFC2219] M. Hamilton and R. Wright. Use of DNS Aliases for - Network Services.. October 1997.

-
-
-
-

Internationalized Domain Names

-
-

[RFC2825] IAB and R. Daigle. A Tangled Web: Issues of I18N, Domain Names, - and the Other Internet protocols. May 2000.

-
-
-

[RFC3490] P. Faltstrom, P. Hoffman, and A. Costello. Internationalizing Domain Names in Applications (IDNA). March 2003.

-
-
-

[RFC3491] P. Hoffman and M. Blanchet. Nameprep: A Stringprep Profile for Internationalized Domain Names. March 2003.

-
-
-

[RFC3492] A. Costello. Punycode: A Bootstring encoding of Unicode - for Internationalized Domain Names in - Applications (IDNA). March 2003.

-
-
-
-

Other DNS-related RFCs

-
-

Note

-

- Note: the following list of RFCs, although - DNS-related, are not - concerned with implementing software. -

-
-
-

[RFC1464] R. Rosenbaum. Using the Domain Name System To Store Arbitrary String - Attributes. May 1993.

-
-
-

[RFC1713] A. Romao. Tools for DNS Debugging. November 1994.

-
-
-

[RFC1794] T. Brisco. DNS Support for Load - Balancing. April 1995.

-
-
-

[RFC2240] O. Vaughan. A Legal Basis for Domain Name Allocation. November 1997.

-
-
-

[RFC2345] J. Klensin, T. Wolf, and G. Oglesby. Domain Names and Company Name Retrieval. May 1998.

-
-
-

[RFC2352] O. Vaughan. A Convention For Using Legal Names as Domain Names. May 1998.

-
-
-

[RFC3071] J. Klensin. Reflections on the DNS, RFC 1591, and Categories of Domains. February 2001.

-
-
-

[RFC3258] T. Hardie. Distributing Authoritative Name Servers via - Shared Unicast Addresses. April 2002.

-
-
-

[RFC3901] A. Durand and J. Ihren. DNS IPv6 Transport Operational Guidelines. September 2004.

-
-
-
-

Obsolete and Unimplemented Experimental RFC

-
-

[RFC1712] C. Farrell, M. Schulze, S. Pleitner, and D. Baldoni. DNS Encoding of Geographical - Location. November 1994.

-
-
-

[RFC2673] M. Crawford. Binary Labels in the Domain Name System. August 1999.

-
-
-

[RFC2874] M. Crawford and C. Huitema. DNS Extensions to Support IPv6 Address Aggregation - and Renumbering. July 2000.

-
-
-
-

Obsoleted DNS Security RFCs

-
-

Note

-

- Most of these have been consolidated into RFC4033, - RFC4034 and RFC4035 which collectively describe DNSSECbis. -

-
-
-

[RFC2065] D. Eastlake, 3rd and C. Kaufman. Domain Name System Security Extensions. January 1997.

-
-
-

[RFC2137] D. Eastlake, 3rd. Secure Domain Name System Dynamic Update. April 1997.

-
-
-

[RFC2535] D. Eastlake, 3rd. Domain Name System Security Extensions. March 1999.

-
-
-

[RFC3008] B. Wellington. Domain Name System Security (DNSSEC) - Signing Authority. November 2000.

-
-
-

[RFC3090] E. Lewis. DNS Security Extension Clarification on Zone Status. March 2001.

-
-
-

[RFC3445] D. Massey and S. Rose. Limiting the Scope of the KEY Resource Record (RR). December 2002.

-
-
-

[RFC3655] B. Wellington and O. Gudmundsson. Redefinition of DNS Authenticated Data (AD) bit. November 2003.

-
-
-

[RFC3658] O. Gudmundsson. Delegation Signer (DS) Resource Record (RR). December 2003.

-
-
-

[RFC3755] S. Weiler. Legacy Resolver Compatibility for Delegation Signer (DS). May 2004.

-
-
-

[RFC3757] O. Kolkman, J. Schlyter, and E. Lewis. Domain Name System KEY (DNSKEY) Resource Record - (RR) Secure Entry Point (SEP) Flag. April 2004.

-
-
-

[RFC3845] J. Schlyter. DNS Security (DNSSEC) NextSECure (NSEC) RDATA Format. August 2004.

-
-
-
-
-
-

-Internet Drafts

-

- Internet Drafts (IDs) are rough-draft working documents of - the Internet Engineering Task Force. They are, in essence, RFCs - in the preliminary stages of development. Implementors are - cautioned not - to regard IDs as archival, and they should not be quoted or cited - in any formal documents unless accompanied by the disclaimer that - they are "works in progress." IDs have a lifespan of six months - after which they are deleted unless updated by their authors. -

-
-
-

-Other Documents About BIND -

-

-
-

-Bibliography

-
-

Paul Albitz and Cricket Liu. DNS and BIND. Copyright © 1998 Sebastopol, CA: O'Reilly and Associates.

-
-
-
-
-
- - - diff --git a/contrib/bind9/doc/arm/Bv9ARM.ch10.html b/contrib/bind9/doc/arm/Bv9ARM.ch10.html deleted file mode 100644 index 03cce5a..0000000 --- a/contrib/bind9/doc/arm/Bv9ARM.ch10.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - - -Manual pages - - - - - - - - -
-
-

-Manual pages

-
-
-
-

Table of Contents

-
-
-dig — DNS lookup utility -
-
-host — DNS lookup utility -
-
-dnssec-keygen — DNSSEC key generation tool -
-
-dnssec-signzone — DNSSEC zone signing tool -
-
-named-checkconf — named configuration file syntax checking tool -
-
-named-checkzone — zone file validity checking or converting tool -
-
-named — Internet domain name server -
-
-rndc — name server control utility -
-
-rndc.conf — rndc configuration file -
-
-rndc-confgen — rndc key generation tool -
-
-
-
- - - diff --git a/contrib/bind9/doc/arm/Bv9ARM.html b/contrib/bind9/doc/arm/Bv9ARM.html deleted file mode 100644 index 8a33041..0000000 --- a/contrib/bind9/doc/arm/Bv9ARM.html +++ /dev/null @@ -1,262 +0,0 @@ - - - - - -BIND 9 Administrator Reference Manual - - - - - - -
-
-
-

-BIND 9 Administrator Reference Manual

-
-
-
-
-
-
-

Table of Contents

-
-
1. Introduction
-
-
Scope of Document
-
Organization of This Document
-
Conventions Used in This Document
-
The Domain Name System (DNS)
-
-
DNS Fundamentals
-
Domains and Domain Names
-
Zones
-
Authoritative Name Servers
-
Caching Name Servers
-
Name Servers in Multiple Roles
-
-
-
2. BIND Resource Requirements
-
-
Hardware requirements
-
CPU Requirements
-
Memory Requirements
-
Name Server Intensive Environment Issues
-
Supported Operating Systems
-
-
3. Name Server Configuration
-
-
Sample Configurations
-
-
A Caching-only Name Server
-
An Authoritative-only Name Server
-
-
Load Balancing
-
Name Server Operations
-
-
Tools for Use With the Name Server Daemon
-
Signals
-
-
-
4. Advanced DNS Features
-
-
Notify
-
Dynamic Update
-
The journal file
-
Incremental Zone Transfers (IXFR)
-
Split DNS
-
Example split DNS setup
-
TSIG
-
-
Generate Shared Keys for Each Pair of Hosts
-
Copying the Shared Secret to Both Machines
-
Informing the Servers of the Key's Existence
-
Instructing the Server to Use the Key
-
TSIG Key Based Access Control
-
Errors
-
-
TKEY
-
SIG(0)
-
DNSSEC
-
-
Generating Keys
-
Signing the Zone
-
Configuring Servers
-
-
IPv6 Support in BIND 9
-
-
Address Lookups Using AAAA Records
-
Address to Name Lookups Using Nibble Format
-
-
-
5. The BIND 9 Lightweight Resolver
-
-
The Lightweight Resolver Library
-
Running a Resolver Daemon
-
-
6. BIND 9 Configuration Reference
-
-
Configuration File Elements
-
-
Address Match Lists
-
Comment Syntax
-
-
Configuration File Grammar
-
-
acl Statement Grammar
-
acl Statement Definition and - Usage
-
controls Statement Grammar
-
controls Statement Definition and - Usage
-
include Statement Grammar
-
include Statement Definition and - Usage
-
key Statement Grammar
-
key Statement Definition and Usage
-
logging Statement Grammar
-
logging Statement Definition and - Usage
-
lwres Statement Grammar
-
lwres Statement Definition and Usage
-
masters Statement Grammar
-
masters Statement Definition and - Usage
-
options Statement Grammar
-
options Statement Definition and - Usage
-
server Statement Grammar
-
server Statement Definition and - Usage
-
trusted-keys Statement Grammar
-
trusted-keys Statement Definition - and Usage
-
view Statement Grammar
-
view Statement Definition and Usage
-
zone - Statement Grammar
-
zone Statement Definition and Usage
-
-
Zone File
-
-
Types of Resource Records and When to Use Them
-
Discussion of MX Records
-
Setting TTLs
-
Inverse Mapping in IPv4
-
Other Zone File Directives
-
BIND Master File Extension: the $GENERATE Directive
-
Additional File Formats
-
-
-
7. BIND 9 Security Considerations
-
-
Access Control Lists
-
Chroot and Setuid
-
-
The chroot Environment
-
Using the setuid Function
-
-
Dynamic Update Security
-
-
8. Troubleshooting
-
-
Common Problems
-
It's not working; how can I figure out what's wrong?
-
Incrementing and Changing the Serial Number
-
Where Can I Get Help?
-
-
A. Appendices
-
-
Acknowledgments
-
A Brief History of the DNS and BIND
-
General DNS Reference Information
-
IPv6 addresses (AAAA)
-
Bibliography (and Suggested Reading)
-
-
Request for Comments (RFCs)
-
Internet Drafts
-
Other Documents About BIND
-
-
-
I. Manual pages
-
-
-dig — DNS lookup utility -
-
-host — DNS lookup utility -
-
-dnssec-keygen — DNSSEC key generation tool -
-
-dnssec-signzone — DNSSEC zone signing tool -
-
-named-checkconf — named configuration file syntax checking tool -
-
-named-checkzone — zone file validity checking or converting tool -
-
-named — Internet domain name server -
-
-rndc — name server control utility -
-
-rndc.conf — rndc configuration file -
-
-rndc-confgen — rndc key generation tool -
-
-
-
-
- - - diff --git a/contrib/bind9/doc/arm/Bv9ARM.pdf b/contrib/bind9/doc/arm/Bv9ARM.pdf deleted file mode 100755 index be27aa1..0000000 --- a/contrib/bind9/doc/arm/Bv9ARM.pdf +++ /dev/null @@ -1,12885 +0,0 @@ -%PDF-1.4 -5 0 obj -<< /S /GoTo /D (chapter.1) >> -endobj -8 0 obj -(1 Introduction) -endobj -9 0 obj -<< /S /GoTo /D (section.1.1) >> -endobj -12 0 obj -(1.1 Scope of Document) -endobj -13 0 obj -<< /S /GoTo /D (section.1.2) >> -endobj -16 0 obj -(1.2 Organization of This Document) -endobj -17 0 obj -<< /S /GoTo /D (section.1.3) >> -endobj -20 0 obj -(1.3 Conventions Used in This Document) -endobj -21 0 obj -<< /S /GoTo /D (section.1.4) >> -endobj -24 0 obj -(1.4 The Domain Name System \(DNS\)) -endobj -25 0 obj -<< /S /GoTo /D (subsection.1.4.1) >> -endobj -28 0 obj -(1.4.1 DNS Fundamentals) -endobj -29 0 obj -<< /S /GoTo /D (subsection.1.4.2) >> -endobj -32 0 obj -(1.4.2 Domains and Domain Names) -endobj -33 0 obj -<< /S /GoTo /D (subsection.1.4.3) >> -endobj -36 0 obj -(1.4.3 Zones) -endobj -37 0 obj -<< /S /GoTo /D (subsection.1.4.4) >> -endobj -40 0 obj -(1.4.4 Authoritative Name Servers) -endobj -41 0 obj -<< /S /GoTo /D (subsubsection.1.4.4.1) >> -endobj -44 0 obj -(1.4.4.1 The Primary Master) -endobj -45 0 obj -<< /S /GoTo /D (subsubsection.1.4.4.2) >> -endobj -48 0 obj -(1.4.4.2 Slave Servers) -endobj -49 0 obj -<< /S /GoTo /D (subsubsection.1.4.4.3) >> -endobj -52 0 obj -(1.4.4.3 Stealth Servers) -endobj -53 0 obj -<< /S /GoTo /D (subsection.1.4.5) >> -endobj -56 0 obj -(1.4.5 Caching Name Servers) -endobj -57 0 obj -<< /S /GoTo /D (subsubsection.1.4.5.1) >> -endobj -60 0 obj -(1.4.5.1 Forwarding) -endobj -61 0 obj -<< /S /GoTo /D (subsection.1.4.6) >> -endobj -64 0 obj -(1.4.6 Name Servers in Multiple Roles) -endobj -65 0 obj -<< /S /GoTo /D (chapter.2) >> -endobj -68 0 obj -(2 BIND Resource Requirements) -endobj -69 0 obj -<< /S /GoTo /D (section.2.1) >> -endobj -72 0 obj -(2.1 Hardware requirements) -endobj -73 0 obj -<< /S /GoTo /D (section.2.2) >> -endobj -76 0 obj -(2.2 CPU Requirements) -endobj -77 0 obj -<< /S /GoTo /D (section.2.3) >> -endobj -80 0 obj -(2.3 Memory Requirements) -endobj -81 0 obj -<< /S /GoTo /D (section.2.4) >> -endobj -84 0 obj -(2.4 Name Server Intensive Environment Issues) -endobj -85 0 obj -<< /S /GoTo /D (section.2.5) >> -endobj -88 0 obj -(2.5 Supported Operating Systems) -endobj -89 0 obj -<< /S /GoTo /D (chapter.3) >> -endobj -92 0 obj -(3 Name Server Configuration) -endobj -93 0 obj -<< /S /GoTo /D (section.3.1) >> -endobj -96 0 obj -(3.1 Sample Configurations) -endobj -97 0 obj -<< /S /GoTo /D (subsection.3.1.1) >> -endobj -100 0 obj -(3.1.1 A Caching-only Name Server) -endobj -101 0 obj -<< /S /GoTo /D (subsection.3.1.2) >> -endobj -104 0 obj -(3.1.2 An Authoritative-only Name Server) -endobj -105 0 obj -<< /S /GoTo /D (section.3.2) >> -endobj -108 0 obj -(3.2 Load Balancing) -endobj -109 0 obj -<< /S /GoTo /D (section.3.3) >> -endobj -112 0 obj -(3.3 Name Server Operations) -endobj -113 0 obj -<< /S /GoTo /D (subsection.3.3.1) >> -endobj -116 0 obj -(3.3.1 Tools for Use With the Name Server Daemon) -endobj -117 0 obj -<< /S /GoTo /D (subsubsection.3.3.1.1) >> -endobj -120 0 obj -(3.3.1.1 Diagnostic Tools) -endobj -121 0 obj -<< /S /GoTo /D (subsubsection.3.3.1.2) >> -endobj -124 0 obj -(3.3.1.2 Administrative Tools) -endobj -125 0 obj -<< /S /GoTo /D (subsection.3.3.2) >> -endobj -128 0 obj -(3.3.2 Signals) -endobj -129 0 obj -<< /S /GoTo /D (chapter.4) >> -endobj -132 0 obj -(4 Advanced DNS Features) -endobj -133 0 obj -<< /S /GoTo /D (section.4.1) >> -endobj -136 0 obj -(4.1 Notify) -endobj -137 0 obj -<< /S /GoTo /D (section.4.2) >> -endobj -140 0 obj -(4.2 Dynamic Update) -endobj -141 0 obj -<< /S /GoTo /D (subsection.4.2.1) >> -endobj -144 0 obj -(4.2.1 The journal file) -endobj -145 0 obj -<< /S /GoTo /D (section.4.3) >> -endobj -148 0 obj -(4.3 Incremental Zone Transfers \(IXFR\)) -endobj -149 0 obj -<< /S /GoTo /D (section.4.4) >> -endobj -152 0 obj -(4.4 Split DNS) -endobj -153 0 obj -<< /S /GoTo /D (subsection.4.4.1) >> -endobj -156 0 obj -(4.4.1 Example split DNS setup) -endobj -157 0 obj -<< /S /GoTo /D (section.4.5) >> -endobj -160 0 obj -(4.5 TSIG) -endobj -161 0 obj -<< /S /GoTo /D (subsection.4.5.1) >> -endobj -164 0 obj -(4.5.1 Generate Shared Keys for Each Pair of Hosts) -endobj -165 0 obj -<< /S /GoTo /D (subsubsection.4.5.1.1) >> -endobj -168 0 obj -(4.5.1.1 Automatic Generation) -endobj -169 0 obj -<< /S /GoTo /D (subsubsection.4.5.1.2) >> -endobj -172 0 obj -(4.5.1.2 Manual Generation) -endobj -173 0 obj -<< /S /GoTo /D (subsection.4.5.2) >> -endobj -176 0 obj -(4.5.2 Copying the Shared Secret to Both Machines) -endobj -177 0 obj -<< /S /GoTo /D (subsection.4.5.3) >> -endobj -180 0 obj -(4.5.3 Informing the Servers of the Key's Existence) -endobj -181 0 obj -<< /S /GoTo /D (subsection.4.5.4) >> -endobj -184 0 obj -(4.5.4 Instructing the Server to Use the Key) -endobj -185 0 obj -<< /S /GoTo /D (subsection.4.5.5) >> -endobj -188 0 obj -(4.5.5 TSIG Key Based Access Control) -endobj -189 0 obj -<< /S /GoTo /D (subsection.4.5.6) >> -endobj -192 0 obj -(4.5.6 Errors) -endobj -193 0 obj -<< /S /GoTo /D (section.4.6) >> -endobj -196 0 obj -(4.6 TKEY) -endobj -197 0 obj -<< /S /GoTo /D (section.4.7) >> -endobj -200 0 obj -(4.7 SIG\(0\)) -endobj -201 0 obj -<< /S /GoTo /D (section.4.8) >> -endobj -204 0 obj -(4.8 DNSSEC) -endobj -205 0 obj -<< /S /GoTo /D (subsection.4.8.1) >> -endobj -208 0 obj -(4.8.1 Generating Keys) -endobj -209 0 obj -<< /S /GoTo /D (subsection.4.8.2) >> -endobj -212 0 obj -(4.8.2 Signing the Zone) -endobj -213 0 obj -<< /S /GoTo /D (subsection.4.8.3) >> -endobj -216 0 obj -(4.8.3 Configuring Servers) -endobj -217 0 obj -<< /S /GoTo /D (section.4.9) >> -endobj -220 0 obj -(4.9 IPv6 Support in BIND 9) -endobj -221 0 obj -<< /S /GoTo /D (subsection.4.9.1) >> -endobj -224 0 obj -(4.9.1 Address Lookups Using AAAA Records) -endobj -225 0 obj -<< /S /GoTo /D (subsection.4.9.2) >> -endobj -228 0 obj -(4.9.2 Address to Name Lookups Using Nibble Format) -endobj -229 0 obj -<< /S /GoTo /D (chapter.5) >> -endobj -232 0 obj -(5 The BIND 9 Lightweight Resolver) -endobj -233 0 obj -<< /S /GoTo /D (section.5.1) >> -endobj -236 0 obj -(5.1 The Lightweight Resolver Library) -endobj -237 0 obj -<< /S /GoTo /D (section.5.2) >> -endobj -240 0 obj -(5.2 Running a Resolver Daemon) -endobj -241 0 obj -<< /S /GoTo /D (chapter.6) >> -endobj -244 0 obj -(6 BIND 9 Configuration Reference) -endobj -245 0 obj -<< /S /GoTo /D (section.6.1) >> -endobj -248 0 obj -(6.1 Configuration File Elements) -endobj -249 0 obj -<< /S /GoTo /D (subsection.6.1.1) >> -endobj -252 0 obj -(6.1.1 Address Match Lists) -endobj -253 0 obj -<< /S /GoTo /D (subsubsection.6.1.1.1) >> -endobj -256 0 obj -(6.1.1.1 Syntax) -endobj -257 0 obj -<< /S /GoTo /D (subsubsection.6.1.1.2) >> -endobj -260 0 obj -(6.1.1.2 Definition and Usage) -endobj -261 0 obj -<< /S /GoTo /D (subsection.6.1.2) >> -endobj -264 0 obj -(6.1.2 Comment Syntax) -endobj -265 0 obj -<< /S /GoTo /D (subsubsection.6.1.2.1) >> -endobj -268 0 obj -(6.1.2.1 Syntax) -endobj -269 0 obj -<< /S /GoTo /D (subsubsection.6.1.2.2) >> -endobj -272 0 obj -(6.1.2.2 Definition and Usage) -endobj -273 0 obj -<< /S /GoTo /D (section.6.2) >> -endobj -276 0 obj -(6.2 Configuration File Grammar) -endobj -277 0 obj -<< /S /GoTo /D (subsection.6.2.1) >> -endobj -280 0 obj -(6.2.1 acl Statement Grammar) -endobj -281 0 obj -<< /S /GoTo /D (subsection.6.2.2) >> -endobj -284 0 obj -(6.2.2 acl Statement Definition and Usage) -endobj -285 0 obj -<< /S /GoTo /D (subsection.6.2.3) >> -endobj -288 0 obj -(6.2.3 controls Statement Grammar) -endobj -289 0 obj -<< /S /GoTo /D (subsection.6.2.4) >> -endobj -292 0 obj -(6.2.4 controls Statement Definition and Usage) -endobj -293 0 obj -<< /S /GoTo /D (subsection.6.2.5) >> -endobj -296 0 obj -(6.2.5 include Statement Grammar) -endobj -297 0 obj -<< /S /GoTo /D (subsection.6.2.6) >> -endobj -300 0 obj -(6.2.6 include Statement Definition and Usage) -endobj -301 0 obj -<< /S /GoTo /D (subsection.6.2.7) >> -endobj -304 0 obj -(6.2.7 key Statement Grammar) -endobj -305 0 obj -<< /S /GoTo /D (subsection.6.2.8) >> -endobj -308 0 obj -(6.2.8 key Statement Definition and Usage) -endobj -309 0 obj -<< /S /GoTo /D (subsection.6.2.9) >> -endobj -312 0 obj -(6.2.9 logging Statement Grammar) -endobj -313 0 obj -<< /S /GoTo /D (subsection.6.2.10) >> -endobj -316 0 obj -(6.2.10 logging Statement Definition and Usage) -endobj -317 0 obj -<< /S /GoTo /D (subsubsection.6.2.10.1) >> -endobj -320 0 obj -(6.2.10.1 The channel Phrase) -endobj -321 0 obj -<< /S /GoTo /D (subsubsection.6.2.10.2) >> -endobj -324 0 obj -(6.2.10.2 The category Phrase) -endobj -325 0 obj -<< /S /GoTo /D (subsection.6.2.11) >> -endobj -328 0 obj -(6.2.11 lwres Statement Grammar) -endobj -329 0 obj -<< /S /GoTo /D (subsection.6.2.12) >> -endobj -332 0 obj -(6.2.12 lwres Statement Definition and Usage) -endobj -333 0 obj -<< /S /GoTo /D (subsection.6.2.13) >> -endobj -336 0 obj -(6.2.13 masters Statement Grammar) -endobj -337 0 obj -<< /S /GoTo /D (subsection.6.2.14) >> -endobj -340 0 obj -(6.2.14 masters Statement Definition and Usage) -endobj -341 0 obj -<< /S /GoTo /D (subsection.6.2.15) >> -endobj -344 0 obj -(6.2.15 options Statement Grammar) -endobj -345 0 obj -<< /S /GoTo /D (subsection.6.2.16) >> -endobj -348 0 obj -(6.2.16 options Statement Definition and Usage) -endobj -349 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.1) >> -endobj -352 0 obj -(6.2.16.1 Boolean Options) -endobj -353 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.2) >> -endobj -356 0 obj -(6.2.16.2 Forwarding) -endobj -357 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.3) >> -endobj -360 0 obj -(6.2.16.3 Dual-stack Servers) -endobj -361 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.4) >> -endobj -364 0 obj -(6.2.16.4 Access Control) -endobj -365 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.5) >> -endobj -368 0 obj -(6.2.16.5 Interfaces) -endobj -369 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.6) >> -endobj -372 0 obj -(6.2.16.6 Query Address) -endobj -373 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.7) >> -endobj -376 0 obj -(6.2.16.7 Zone Transfers) -endobj -377 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.8) >> -endobj -380 0 obj -(6.2.16.8 Bad UDP Port Lists) -endobj -381 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.9) >> -endobj -384 0 obj -(6.2.16.9 Operating System Resource Limits) -endobj -385 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.10) >> -endobj -388 0 obj -(6.2.16.10 Server Resource Limits) -endobj -389 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.11) >> -endobj -392 0 obj -(6.2.16.11 Periodic Task Intervals) -endobj -393 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.12) >> -endobj -396 0 obj -(6.2.16.12 Topology) -endobj -397 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.13) >> -endobj -400 0 obj -(6.2.16.13 The sortlist Statement) -endobj -401 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.14) >> -endobj -404 0 obj -(6.2.16.14 RRset Ordering) -endobj -405 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.15) >> -endobj -408 0 obj -(6.2.16.15 Tuning) -endobj -409 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.16) >> -endobj -412 0 obj -(6.2.16.16 Built-in server information zones) -endobj -413 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.17) >> -endobj -416 0 obj -(6.2.16.17 Built-in Empty Zones) -endobj -417 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.18) >> -endobj -420 0 obj -(6.2.16.18 The Statistics File) -endobj -421 0 obj -<< /S /GoTo /D (subsubsection.6.2.16.19) >> -endobj -424 0 obj -(6.2.16.19 Additional Section Caching) -endobj -425 0 obj -<< /S /GoTo /D (subsection.6.2.17) >> -endobj -428 0 obj -(6.2.17 server Statement Grammar) -endobj -429 0 obj -<< /S /GoTo /D (subsection.6.2.18) >> -endobj -432 0 obj -(6.2.18 server Statement Definition and Usage) -endobj -433 0 obj -<< /S /GoTo /D (subsection.6.2.19) >> -endobj -436 0 obj -(6.2.19 trusted-keys Statement Grammar) -endobj -437 0 obj -<< /S /GoTo /D (subsection.6.2.20) >> -endobj -440 0 obj -(6.2.20 trusted-keys Statement Definition and Usage) -endobj -441 0 obj -<< /S /GoTo /D (subsection.6.2.21) >> -endobj -444 0 obj -(6.2.21 view Statement Grammar) -endobj -445 0 obj -<< /S /GoTo /D (subsection.6.2.22) >> -endobj -448 0 obj -(6.2.22 view Statement Definition and Usage) -endobj -449 0 obj -<< /S /GoTo /D (subsection.6.2.23) >> -endobj -452 0 obj -(6.2.23 zone Statement Grammar) -endobj -453 0 obj -<< /S /GoTo /D (subsection.6.2.24) >> -endobj -456 0 obj -(6.2.24 zone Statement Definition and Usage) -endobj -457 0 obj -<< /S /GoTo /D (subsubsection.6.2.24.1) >> -endobj -460 0 obj -(6.2.24.1 Zone Types) -endobj -461 0 obj -<< /S /GoTo /D (subsubsection.6.2.24.2) >> -endobj -464 0 obj -(6.2.24.2 Class) -endobj -465 0 obj -<< /S /GoTo /D (subsubsection.6.2.24.3) >> -endobj -468 0 obj -(6.2.24.3 Zone Options) -endobj -469 0 obj -<< /S /GoTo /D (subsubsection.6.2.24.4) >> -endobj -472 0 obj -(6.2.24.4 Dynamic Update Policies) -endobj -473 0 obj -<< /S /GoTo /D (section.6.3) >> -endobj -476 0 obj -(6.3 Zone File) -endobj -477 0 obj -<< /S /GoTo /D (subsection.6.3.1) >> -endobj -480 0 obj -(6.3.1 Types of Resource Records and When to Use Them) -endobj -481 0 obj -<< /S /GoTo /D (subsubsection.6.3.1.1) >> -endobj -484 0 obj -(6.3.1.1 Resource Records) -endobj -485 0 obj -<< /S /GoTo /D (subsubsection.6.3.1.2) >> -endobj -488 0 obj -(6.3.1.2 Textual expression of RRs) -endobj -489 0 obj -<< /S /GoTo /D (subsection.6.3.2) >> -endobj -492 0 obj -(6.3.2 Discussion of MX Records) -endobj -493 0 obj -<< /S /GoTo /D (subsection.6.3.3) >> -endobj -496 0 obj -(6.3.3 Setting TTLs) -endobj -497 0 obj -<< /S /GoTo /D (subsection.6.3.4) >> -endobj -500 0 obj -(6.3.4 Inverse Mapping in IPv4) -endobj -501 0 obj -<< /S /GoTo /D (subsection.6.3.5) >> -endobj -504 0 obj -(6.3.5 Other Zone File Directives) -endobj -505 0 obj -<< /S /GoTo /D (subsubsection.6.3.5.1) >> -endobj -508 0 obj -(6.3.5.1 The \044ORIGIN Directive) -endobj -509 0 obj -<< /S /GoTo /D (subsubsection.6.3.5.2) >> -endobj -512 0 obj -(6.3.5.2 The \044INCLUDE Directive) -endobj -513 0 obj -<< /S /GoTo /D (subsubsection.6.3.5.3) >> -endobj -516 0 obj -(6.3.5.3 The \044TTL Directive) -endobj -517 0 obj -<< /S /GoTo /D (subsection.6.3.6) >> -endobj -520 0 obj -(6.3.6 BIND Master File Extension: the \044GENERATE Directive) -endobj -521 0 obj -<< /S /GoTo /D (subsection.6.3.7) >> -endobj -524 0 obj -(6.3.7 Additional File Formats) -endobj -525 0 obj -<< /S /GoTo /D (chapter.7) >> -endobj -528 0 obj -(7 BIND 9 Security Considerations) -endobj -529 0 obj -<< /S /GoTo /D (section.7.1) >> -endobj -532 0 obj -(7.1 Access Control Lists) -endobj -533 0 obj -<< /S /GoTo /D (section.7.2) >> -endobj -536 0 obj -(7.2 Chroot and Setuid) -endobj -537 0 obj -<< /S /GoTo /D (subsection.7.2.1) >> -endobj -540 0 obj -(7.2.1 The chroot Environment) -endobj -541 0 obj -<< /S /GoTo /D (subsection.7.2.2) >> -endobj -544 0 obj -(7.2.2 Using the setuid Function) -endobj -545 0 obj -<< /S /GoTo /D (section.7.3) >> -endobj -548 0 obj -(7.3 Dynamic Update Security) -endobj -549 0 obj -<< /S /GoTo /D (chapter.8) >> -endobj -552 0 obj -(8 Troubleshooting) -endobj -553 0 obj -<< /S /GoTo /D (section.8.1) >> -endobj -556 0 obj -(8.1 Common Problems) -endobj -557 0 obj -<< /S /GoTo /D (subsection.8.1.1) >> -endobj -560 0 obj -(8.1.1 It's not working; how can I figure out what's wrong?) -endobj -561 0 obj -<< /S /GoTo /D (section.8.2) >> -endobj -564 0 obj -(8.2 Incrementing and Changing the Serial Number) -endobj -565 0 obj -<< /S /GoTo /D (section.8.3) >> -endobj -568 0 obj -(8.3 Where Can I Get Help?) -endobj -569 0 obj -<< /S /GoTo /D (appendix.A) >> -endobj -572 0 obj -(A Appendices) -endobj -573 0 obj -<< /S /GoTo /D (section.A.1) >> -endobj -576 0 obj -(A.1 Acknowledgments) -endobj -577 0 obj -<< /S /GoTo /D (subsection.A.1.1) >> -endobj -580 0 obj -(A.1.1 A Brief History of the DNS and BIND) -endobj -581 0 obj -<< /S /GoTo /D (section.A.2) >> -endobj -584 0 obj -(A.2 General DNS Reference Information) -endobj -585 0 obj -<< /S /GoTo /D (subsection.A.2.1) >> -endobj -588 0 obj -(A.2.1 IPv6 addresses \(AAAA\)) -endobj -589 0 obj -<< /S /GoTo /D (section.A.3) >> -endobj -592 0 obj -(A.3 Bibliography \(and Suggested Reading\)) -endobj -593 0 obj -<< /S /GoTo /D (subsection.A.3.1) >> -endobj -596 0 obj -(A.3.1 Request for Comments \(RFCs\)) -endobj -597 0 obj -<< /S /GoTo /D (subsection.A.3.2) >> -endobj -600 0 obj -(A.3.2 Internet Drafts) -endobj -601 0 obj -<< /S /GoTo /D (subsection.A.3.3) >> -endobj -604 0 obj -(A.3.3 Other Documents About BIND) -endobj -605 0 obj -<< /S /GoTo /D (appendix.B) >> -endobj -608 0 obj -(B Manual pages) -endobj -609 0 obj -<< /S /GoTo /D (section.B.1) >> -endobj -612 0 obj -(B.1 dig) -endobj -613 0 obj -<< /S /GoTo /D (section.B.2) >> -endobj -616 0 obj -(B.2 host) -endobj -617 0 obj -<< /S /GoTo /D (section.B.3) >> -endobj -620 0 obj -(B.3 dnssec-keygen) -endobj -621 0 obj -<< /S /GoTo /D (section.B.4) >> -endobj -624 0 obj -(B.4 dnssec-signzone) -endobj -625 0 obj -<< /S /GoTo /D (section.B.5) >> -endobj -628 0 obj -(B.5 named-checkconf) -endobj -629 0 obj -<< /S /GoTo /D (section.B.6) >> -endobj -632 0 obj -(B.6 named-checkzone) -endobj -633 0 obj -<< /S /GoTo /D (section.B.7) >> -endobj -636 0 obj -(B.7 named) -endobj -637 0 obj -<< /S /GoTo /D (section.B.8) >> -endobj -640 0 obj -(B.8 rndc) -endobj -641 0 obj -<< /S /GoTo /D (section.B.9) >> -endobj -644 0 obj -(B.9 rndc.conf) -endobj -645 0 obj -<< /S /GoTo /D (section.B.10) >> -endobj -648 0 obj -(B.10 rndc-confgen) -endobj -649 0 obj -<< /S /GoTo /D [650 0 R /FitH ] >> -endobj -653 0 obj << -/Length 236 -/Filter /FlateDecode ->> -stream -xÚÁJA †ïó9¶‡M'™d2s´T¥‚Beoâai·Rp·t­ïïÔÕ*êArÉÿ‘ü /A}È–ՓºsžŠvíèƒ ¨B)þP+!ÃlQ¡bJÕÂwìNì1úÈP©)&>áóÚÍ®˜€-A½bEM¦pæêÍÃd¾¼[L+V?ÉcºØt»~÷ršã~[÷í¶Ú~ÝNë a¤(±ø˘’å÷9·MÿÚ<ŸwYŸÝQ DËr;yƒ|ê~üÁÁýhÌ–ÁbïVV_§æŒlåP}&ûÿsßC+WDendstream -endobj -650 0 obj << -/Type /Page -/Contents 653 0 R -/Resources 652 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 659 0 R ->> endobj -651 0 obj << -/Type /XObject -/Subtype /Form -/FormType 1 -/PTEX.FileName (./isc-logo.pdf) -/PTEX.PageNumber 1 -/PTEX.InfoDict 660 0 R -/Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000] -/BBox [0.00000000 0.00000000 255.00000000 149.00000000] -/Resources << -/ProcSet [ /PDF /Text ] -/ColorSpace << -/R15 661 0 R -/R9 662 0 R -/R11 663 0 R -/R13 664 0 R ->>/ExtGState << -/R17 665 0 R -/R8 666 0 R ->>/Font << /R19 667 0 R >> ->> -/Length 668 0 R -/Filter /FlateDecode ->> -stream -xœu˜;“d9…ýû+®Ùe´R©— lG`XËkz#†10gwÙ~6ßÉ[53}+ˆ}tI%åóäÉT½ßs*{Ö?·¿××í'¿ûŸ?lï·¼Ÿ#5Û_7}÷n³æ3õùæóýÌ»íwû7\^ûõÃVö×oøÿ_·ÒvþmÕSéœmqöÚ¾æh)ŸÏŽ™,ײ—Zjj•ÅVÊ•ëµÍÔÆn¹§±†Ö5͵[+i6}Ÿk’¨Í–§ºØ±ÖRöÝVIƒ e´Ä¶yKfZWTp¾ÜÏç9ùÀ–ÆŒõÒý>R_­êÂJsJƒ¥.ŸËÊiôÝ×\ -û”_g'®Û_6´§ÖØËÍ“[8føƒ”œKj“È4­¹¯5Ã#6ÆJ²4·œª+ÚøاkÇä~¤ž19wR7ñm¦U%s˜,ÃT| -Û2Æ‚ŒjUçq¥K"ηbøR<™¬¨™ãŸ¹×²RU| Ñ$ÞÕZ*Š–ŒCõu«|ˆhL$,I˜–¼`¥Y|ÃNżŠLó’#pÕ‹BÖŽj9-- 9@‘ €DÌ©….¶áJ{N]Á©¥Z*zÃ3…?´T®²$À“%ÁXF°Zê%.ä’@ŽO­—€!$t\'<Ž¶*W -èj˵ãB;Žþ"%«ê;¥+ßÚ)Éú¾Œ¤IJ5yÝGN>³ʧ*=5Dt'ŸtˇÀùiQ{ - ˜‚ÚIq%˜3vH­wÁKAįr‹þq n[Uz¯!*â)ôàKG°€ÝgG-dL#¹X0¹Â“@ñ´×£^ëµ½æHÕÊ_7S41Ã,ëÀO%ê*\ç/1v¢\¨Î¡¨êG´P:‘Sœ¸1ÀÞ£q‹uc¤,¯J¶”e— '‚; F/É&N(AWÖšNfãÀŠq‚ì’htËØ“ªØOàÙ‰GÎ4óHD'ª:SÙ#Oœ™äD4Ltæª3—=Ý™pÂSè¬F$_)^"åÛ•.ªd­Ôd´ÁJŒÓ¤¨,à}‹F:IòP<Á:‚é¡û½¶H­JŒŒÀvÎ9±”8G -%S}8\Ž»Ä{!•pŸj yî8NíÖL-»Ä¼1_yk¦“ˆÔøèus‘#¸W™˜ÁAŹ{0º¤Œ4±à8pª0ŠÚž]#H ªiÓºhS”28Ú*7»Å'¤«ÎwMpíD¦9d=‹rêÀ Öd ðlÎmF1Û\ÓjÍ J$¾›ƒlHO†¯,x!Fàqê*i!ߪ ‰ ž£‘\·î"o6,âM(¨$‡^êP^Å>˜³ ÔV¬ˆ¦#Z†ª¼§?Áj¹“LÃ¥R»š¨¦VÅo€Ž –eõT¥ Ø€ùU¢ÙÜ* „2ÊNvÊ@ÈËY#E?°+êEn£±¦h“ÊFØläƒbY3Âc0CEW'ñÖÆ4€»Öm"ŒÙ©˜94A¬#—ª Áõ¢ÙëN)ÅZþÅÖ…µˆ‘ç#µxì‡Ð:Å ÑqYŠ¢ŽÞ\U¢ÜÆÕ²hb \´ÑP£’šð¢>Ô9Ž¨Ñ¸ˆùUm!‰§¢Zh!ú‹~(Ât~¿ÙA,«×>*"œD0QEuÑ|Îóî`‰ö™%„U™&2WjDó5EŠ)€®äò.º‡Õ…]Ó8¡º ú5Q«­"Y;¨¢©j%R]»nG¿'ŠAU‚s:½¯•~K“ÒÞV׋„OÒAŠI… ɪÁr2Q“°Ø¨Á>.zÎCN’¦{Õ«'^5Mã»Åûæ¡æÔÊý¹U1z6õßvãpF)ÂÏåìÊ›C£i#]bÝLkS#ˆQÁŽv–¨Ô­«•ÇcHŸ$¬Áê³DI­ÌÑptÅ73*_åª'ŽÚ¿¢ÚòQŒ×è Œ‚,É*Ñ+ôÚ™%vŽ&u߉ xœÉ-¾kz˜ Ï‡Ú Q´Pë3ÈZ§q¢Æ0¯ˆwMÍ?©=õ*_Ç£RïѪëƬ¡”’¢g!SeRâÅéz·ÝŠFLÚŸv -ÏÆ狼eÇNdæÌdï"gK2cëÉ—GoOá8GëÏϦ:B Àht[~Ðåõ—×SÒÜ£uˆQk·%È´ÔÛ†ëiATÆÌp[OU‡Ç(zßQã³* *Ñûø®á¾FÅÍ„Ï'µV‡¾;1aŠÑüËŒÜr$¿Íâ9Ë8ˆü ý‚TóþÏÍ÷_oôô¢ññCÙõ"ú*~uÊqæþéïÛ{Ç"ß~±Úú"ú…bùz+·£]OZ,SÏ¥._^·§_\^þ†56g‡3^®Ç5Z©®©¹Uý¶õòÇí÷O¿½<Ó#rYëé»Ë^~¹ÁÇ<ц®5%¥Ü~ÿñsõ\êídŽ3¼4ü~èé[iþÂÈg óžµ|¥Ïà5³m“XSô7…ÿúáò¬ä>!»Î“O÷hKYð¿þîÇ Ó3/¡úôÃgë¾4EO=öï¦üì“­‡v5”ùÜþû‚ék”ùôñR”Ì¡ÌlöÅ·ß_DÍη„Rf.{úÏåYӎͧÿ^ž©í5¬?ývýüeûMüó?Ò ƒendstream -endobj -660 0 obj -<< -/Producer (AFPL Ghostscript 8.51) -/CreationDate (D:20050606145621) -/ModDate (D:20050606145621) -/Title (Alternate-ISC-logo-v2.ai) -/Creator (Adobe Illustrator\(R\) 11) -/Author (Douglas E. Appelt) ->> -endobj -661 0 obj -[/Separation/PANTONE#201805#20C/DeviceCMYK 669 0 R] -endobj -662 0 obj -[/Separation/PANTONE#207506#20C/DeviceCMYK 670 0 R] -endobj -663 0 obj -[/Separation/PANTONE#20301#20C/DeviceCMYK 671 0 R] -endobj -664 0 obj -[/Separation/PANTONE#20871#20C/DeviceCMYK 672 0 R] -endobj -665 0 obj -<< -/Type /ExtGState -/SA true ->> -endobj -666 0 obj -<< -/Type /ExtGState -/OPM 1 ->> -endobj -667 0 obj -<< -/BaseFont /NVXWCK#2BTrajanPro-Bold -/FontDescriptor 673 0 R -/Type /Font -/FirstChar 67 -/LastChar 136 -/Widths [ 800 0 0 0 0 0 452 0 0 0 0 0 0 0 0 0 582 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 841 633 576 686 590 540 923 827 407 760] -/Encoding 674 0 R -/Subtype /Type1 ->> -endobj -668 0 obj -2362 -endobj -669 0 obj -<< -/Filter /FlateDecode -/FunctionType 4 -/Domain [ 0 1] -/Range [ 0 1 0 1 0 1 0 1] -/Length 39 ->> -stream -xœ«N)-P0PÈ-ÍQH­HÎPsõ, QE¸zFÆ`^-=1°endstream -endobj -670 0 obj -<< -/Filter /FlateDecode -/FunctionType 4 -/Domain [ 0 1] -/Range [ 0 1 0 1 0 1 0 1] -/Length 36 ->> -stream -xœ«N)-P0PÈ-ÍQH­HÎPsõ LÑE ‘D Êk8/«endstream -endobj -671 0 obj -<< -/Filter /FlateDecode -/FunctionType 4 -/Domain [ 0 1] -/Range [ 0 1 0 1 0 1 0 1] -/Length 40 ->> -stream -xœ«N)-P0TÈ-ÍQH­HÎPq ôLLÑD\=C 0¯=D³endstream -endobj -672 0 obj -<< -/Filter /FlateDecode -/FunctionType 4 -/Domain [ 0 1] -/Range [ 0 1 0 1 0 1 0 1] -/Length 50 ->> -stream -xœ«N)-P0Ð365³TÈ-ÍQH­HÎP€Š™X ‹™›#Ä ô -,ŒÀüZ&‹ˆendstream -endobj -673 0 obj -<< -/Type /FontDescriptor -/FontName /NVXWCK#2BTrajanPro-Bold -/FontBBox [ -45 -17 923 767] -/Flags 4 -/Ascent 767 -/CapHeight 767 -/Descent -17 -/ItalicAngle 0 -/StemV 138 -/MissingWidth 500 -/CharSet (/Msmall/C/Ysmall/Nsmall/Osmall/Esmall/Rsmall/S/Ssmall/I/Tsmall/Ismall/Usmall) -/FontFile3 675 0 R ->> -endobj -674 0 obj -<< -/Type /Encoding -/BaseEncoding /WinAnsiEncoding -/Differences [ 127/Nsmall/Tsmall/Esmall/Rsmall/Ysmall/Ssmall/Msmall/Osmall/Ismall/Usmall] ->> -endobj -675 0 obj -<< -/Filter /FlateDecode -/Subtype /Type1C -/Length 2657 ->> -stream -xœ}VkpUž!!i0dHÈ:=«°î"ŠÏ*QpYWÊD@p• ‘$$ç$!a2ïžé×éîéǼ’ÌäÍC Ãû)Á]^º+–B-®k)ZˆËµîÄf‹½´J«¬ýÓÕ÷ÜÛçÜïœï|§Í¦Ì1&³Ùþdš…Ãhëôõa3NO?œ™iv¤è›…$}ت?‰´±èË,Ý®³"cqC;‘µjô=©ãuVú¨ÕxÓUîÈçðÈœCæè×éÎþŒt§Óz>Tww$Õ°,'£ÛãŸBœÐ85HqL+kc6zjœ-kŠ_ô?„>M/DãQàZçÕ çɽ»Oö| -_ÀźŠþúD…PE¸EJ‹ˆZ»`»øâ€8(ÅA…‘}Bµ´>R&+åáE ÿf­YPxïÃôñð Ìܤg~ý(qe.Ê®Fw‘›¾ä<8ò§ý“?ßúzñÛW»§Z>CšÓjùè¼9üÆûzÞƒa¸ºú=}•Úî¼ÇN7Â~â}CØ,ÎÂÖêö–îz¹ -„W -©š¤õ\ o…„ TZ -ˆõjIt!†CΞ«y|×ÓhÌ£¤åËýk?^Ø^ /ç/õùmþ ÉF'™nH P¬ÏÅÛøVf1,ƒ&‰î–ÏZ†ö‡ rÓ/±©‘Ò”=†&eàÇn+Ì„¹t [r63Î˹€ð2,TÙ¹NK½°N³çàpÎÝ1MReZò¹šDÑMV‡ƒ)v33—àþ˜ hlßµäf9.jBˆ¨"j -%zÈ2(bPÏIe†§VŠ Q -'x6FöÐQ§X)®‡ZÐg¹ßÏÆwÌk6'¾¿+ãóËV¦–ªl`Ý\‚@h†¡T.Bn·¤$tÀnv§á0¡‰Z8¦(J\¤Kò*x¯Mˆ‰ío¡Oò¤¬­EGíjk´áïú”îÒ¶ú¨3Qµ®Ýè…ô$¼èF¦ÔÀùi.?Ä1,0@ËL7?È¡Û™ Q <$Q>· :È:ꥎ=‘îÉcSþH( ‚A·î»Ñ˜§ûÒ5ÞÞP8ùØNqnLOÙTúÛ¤Qh|~üÖ -n¨`×rŽ`ëF†â|¼?C3A•‹“pJê>8Åž0`ÅUI Ó²ßÛ"à$Ö‡©®ŸÛƒÐF¼› [¸M‰m;Ðd´jëöÎ^MëŒ$”Žpç] +rHô“Nxkz¨k `(¨ñG¶³a|oð1®@‹§Þ®/ô5»úôlôJë¦`œ‰‚ -ªVŶ°  --R¶5ðöU…¢Ëðå q¡Âª±v:#“TsOÕ¶U(G_¬xâm#¹#—ÙTpÃȤd{ód4åÌMóqŸé¦ižÏ4Õ2€3¿Ú*e%]_Nÿj6a©úâ!4æ®/Eñ@;ªªu’Ñô€pPmïSóc’ -.9,«”à%WÃ:Î-°R,6îâ ðAZbbñn d7¥¹„‘¹yL–'®C9‹O–¤~º]ÏC¾˜«Ý›ða2…¼N’º!ðóÙÆÆP¾—m5jA…šÒø8¹SLÃ4ÚÞ­…&bö‡ýn§ »H§âëâÎa„ïº÷§ßßg>ˆ¦¤+ÐÔŒô,·5£»Ð}hZ¡ÛÐDÝ¡wÍЋôú½ßè Q„ܱߪ?~²¡¨eý«ø­Ûk‘¹é ô¡•)eúÇ~Ô|À•Tqî¦c1[Ö5ÕÒæï¬Õ2ÇóàYf-ë 1‹Ë_|åç=>–fH| -&–ê„n>ÚÝ)D 6Á?Äx:ÆŸ+0Ô®GNªÃÐIDøX?ÀÙBþMþF9ßB]‚æû…÷a+æ›,„Ã=×9®Ã6ÀÆ<²SôOŒÈ*šWq»˜´ÉCbȄ̆¬"¡  -x¸ \3§gA34–ITž-‹R8õ-ǵÛö2ªWuÉ~Á!"(0Š*FÂ͢ùĨ¸SˆˆoÊQPˆ0¦šåiFäݸVN^_!Ô‚–bž "-Qy$ÑÎsªm ¥Ä¡@·âJ=Ŧ¿íÝëL ÍDËQÆTË?GúÓlRÎ$F*4’ƒð6–š\`Œª Ñ“Œôöd]˜é`û™ü9¸DijeI Û.q -ȼLçÇ<;— *X³«¥×ÛGâ_Y1ETïƒ4ˆÒ-U…_>´üØ¢æ}õï÷v¼ §ádù#¹rÛŸå¥@ÔÁ\5l…hð<8Ús·’?h¹†!-¶‚*JŠ»,\G/Wé9OW—×µ.Ÿ—­€&¨[”ÄIÁÚ´Ó½7ýáÐäKý¡«¨ðúš.cxQn<¼À°üÖëgöõÁúhíY8³¶+oî^÷ë°‹>9p¯“°¥!ÑÚÙ®ŠðK´¢†#©óRÄlxŽJ”ب¬Ò–àá•{ϳwÿaû’ožÇ£ëHõÅâH9”ç/.~å÷Ë -»O·Øèv61Bá5*È<6ÞÍ,‡bh‘˜¶ž\Î]Çé#¹#ØÔÍ1Oúñ°Ï¤5oÂ]цÆß4}h˜î0$å,6ü¼”A,¯?/å;Rôcy6Ò½UJ¿§Y½X^é¶ÙÉŸ‡‹º–2¸K|o½Ø”/Ȩ/ƒ( Â2Ð#žNMKðrˆ rœÛf9ËyZ¸Ú}$«Ö õ–©)  h`iÎGàAç÷´€H+Šˆ…Õ&*áX$žèìVŽhª”—›¾÷‡A1Ý£¤œÏ0‰÷—Hi éƒw~I(Áö2;à]¸L ™x4[¡OÜ,¾®ÆûÂQQ°”FdQ“ƒ¢¬„%\î¢Åâ:Ó;ÈÑ”ÌEb1ž’¡ˆÿ§=$¸¥?Iš¿CÐõ3¾C=VÐ'>·¯ôÌÒ+Ü~8 ç#;úÁ_£×á*qň+ô 8®‚ãÆpêŒ_YR”¾d%a ç¡H\eÄõãDf£Ñ¨­ŽR[kφG¸ù/WT®ò•A5”H¥ÛVoo8hnû)¼ÞÃDn…ñëqÌzfåhý&þcQbµXÇß‚çLŽúõ;{²Ðñðué¿ÊÛÙ†-©[SÄ-Û¼ÔyubÜñhüm´œ4^Ë™ ääšLÿQ‹¡endstream -endobj -654 0 obj << -/D [650 0 R /XYZ 85.0394 794.5015 null] ->> endobj -655 0 obj << -/D [650 0 R /XYZ 85.0394 769.5949 null] ->> endobj -652 0 obj << -/Font << /F21 658 0 R >> -/XObject << /Im1 651 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -678 0 obj << -/Length 994 -/Filter /FlateDecode ->> -stream -xÚµVË’¢JÝû,5¢­©¯Z҈ʂ83³°»‰hÅ+8ý÷7¡ªDÐÛ›‰.*«ò˜yòd@4 ?¢&29åšÅud`bh›ýk/à› ˆÄ`mŒãvãügðó7Ö¶ú:§ï°ÁˆpNµý@72tÆÔÉÛ |»„ºòª€ýlc3D0‹éÈvר4Á"ÔË282e5ü1|™‚É7©©¥; -Qm]»ÀÒíÏ¡[?NùËk5ú~Õ Œ,Ìr À¦v|™ý*Ô˜"ËäV£ŠÂýí´›•"("6 Š±þ0SצњfkZÂòUv:d•Ø%e•íK±q‹CYœªü¼PØ ÁÀÂÀ¿(ÕýÄ­Ø’šÔÀK/‚F‘aš¦féZÏÏÕUèñ5üŽºÌ‚¾Z¼ú_êÒÿS]ÜêHZ“¶&»«n±«Þק±‡Y_bÔ×ÏĈSÓÖ,Ê€'ŸÉ§Àãkô­z¦8¶I³.g™öyYæÅApª -±žËLÖ³yG„¡Üï‹m¾ëœ¬[aló²:åÏçJX½æršÊ›âwÅIýûCÇóéX”ÒýžW¯ÂR¸ú¤8K1w™ÄA‚ºëpßAÜ0hSÚk&ò=Ëø/§54d+Igñ'ßf[Åv])KF_?²V1eÍöPTù&ëÕßÖ{ìÉÚÙZ•Kÿúí­©ƒpšTß„ëJ wž•ÍÀàbŽ˜Îêb-ĵH:÷ä˜EÓôiÄéЉ剟ˆuGßý‰7»úæ:‰BÔ;a;áDºÂ˜€8þB‚ †Ì;aê{Òùä§saÅÞ̉'âJÂó•‘nIi­~$ é\Q¼C>tƒÕÄg½äþbøª–{L¢©X^ìÎÁ1²ô¡óè~ú£-´fg"®Û–bGvS? ½$AŠƒXCÉ×ûîAÍ:QšDP[¬˜¬‚æô¢þ4Ž²¶(iu®YaÏÅ^W‰§Êá›tùÀP‚ØɃâáÁ Ç]Ùµº©…ÝîBÙiìtd -½YàϼÐõº™¢&ró°Ðµ é¶\ d> endobj -679 0 obj << -/D [677 0 R /XYZ 56.6929 794.5015 null] ->> endobj -676 0 obj << -/Font << /F23 682 0 R /F14 685 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -688 0 obj << -/Length 2891 -/Filter /FlateDecode ->> -stream -xÚíMsÛȆïþ¼E:p2ߎ²,{•½.K®|m( -–˜•U~}Àô )ÚB¼k¯E–¢$6ºÝž™%fÜý³Ô0®2=K2Í f¶X½à³k÷»7/„6Š­”û&òÛ¹Q)3©Lfs|‘——/þøZŠ™Ô,I1»ü4ø2’I©²ÙåÕ?ŽN«²)Êf}üÏË?uˬ´íûùln%Ó©J»wŠã¹àœ—M]]mͲ*[«g—!£³\è™M3–h.ÚPú_Ö׳þŇ­ØýûçØbBÙ½nQ²ëÞ§_HØ®S…œfîeêÒn“„Y-|X—Ã.Õ]q<—îeõ©ÿúªZlV.›Çs“fGÌ}qùz–_tö%ÿ¿Qj Ó;²}Žd¸+äîõ?CO$ Š"Òy Èšö.¶ž"é)ú©>éÑu^.ÿ›wwÔP—7Ëõc´´Jö˜QR ›“IA†)X-‚”H)¤ó@Šïµô=)Ê“âFê{€cÄ#ñq]\õ¯–å8.ÊØg È(½Éd CŠ ¬AF$ Š Òy C;t"<Ú“qyS€ê«Xx—¯üO/ÖM±ê_ÿìÞÿêÝ…ûâ¦1iÓ}žl ™“AA†(X¬t”H(¤s!%K³Ä9—“:…šEwU‹tùpâ÷$¼Þ”Wy;Dä·í˜‘ª½«Bžˆ dr2&ÈÂ+E` ƒÂ„t>`"& · ˜t#‰ŸLòò*>¾¸ß+«Ÿ%£8@Æ&〠)°"‘0(HçÜ-Tåqø{Uvbsù¬W5ß`tŒOÆ R8aE œ"aP8‘ÎN&“,3:”+]ÁÒât²inªzÙ¸Ï}±S®õ}QwsR²uIÈÚT$°!Ä–*Ù(±0$hçÂh–$I63)g©1C]ÒW& -W±ïëå*¯úoÞæ®x­]Δܫ!$j2È¢ AP ƒ¢€t>P`S–˜Ä" -¤§àâ6¿<™îÏLñ9. u“¹@†X‚‹H¤ó c™5™B\(à¢)òÛææ–g‡"dm2ÈB«B  ƒB‚t>ÔZ3cÅPC_Cœæ‹›ey=Z=¨Tì]±ùX™2+¹’øDBÀnŽ #„ì\¿‰#‰ƒB„ô>ŒJ2måPS˜PS¼®êÿäÝûUÇŠþN0_aB ÚAö&³ )6¶Ô!؈ÄA±Az†É™²z¨4¬>bë ´“þvsÛ,ïný[>T·íò7Sö™®=‚X®É0 C -†-9"qP0ìxLJÇpî­³„%ÊMh­séO³_ž¿{åE.ÖÕ¦^€äÅ¿7˺XÁÙx4]ኟ9åi‘Sîëvi£i—#Ò³ë5v¸ ]ž¬Rý .Ã1÷~üôã¨OOÿºMQ÷¢OÓ?Cßk¾ - ãGyiKnSñSî,Hîä; Rw"&Eé=l»¨Œ3-¸tBûщç¦ß¼WåíC|×åÝf{EDÈÙT"°!AÄ–&±8"hïIÊ”û.F'~Çm«'€Ãhõlú™ƒ8žÉâ#CJ|œ~JüH”ø¤w˜H\éΤ𜨰1ðç*÷¥ØËü6/])–Jsè-úR˜ ß“aB†LXO¡ÇaŠÄAÁDz0Í„0P•(r™çkü®2ÑÏç‘œßh‚ÌNÆRØ`å(l"qPØÞ‡ HKÆE%‰ -%Éåq&ªêÖŸ}ªêðxEÿâ/ÇÆ-¡÷ ¹)Æ&¦®E6/VíS<*ßÙ ù™¬>2¤ÔÇù§ÔÄA©OzgÄJºŠLê‡3âWËüº¬ÖÍrá¢x0iº‡}%A1ÈÙd"!EÖD˜q""qPDÞ"DÂRÉ3Dô \­–årÝÔ¨?Qñ»8åú*@Š&€ )°‘8(HïÄÀ K¤ …DX‘\,¯Ë¼¿ýÅ¡ý•P‚dOF R(a1Åx£{, -¥ï±D™*ÆÓ¬ŸÚ´ßH<¹ºwkØl»*òfSã=ábOÝBÄÄâVb¼_ŽÈÌ®×X±.βLôC¼[ˆïªfùÉ­ïݺGÏ“|ëeacê=ˆ ‰{pKlŠ°Hi¤÷@šIÝ°®¥}$J{Ò{Ø\‰[Aq#íÃqËɦ©Vy8mñ0ôŸ|g÷åƇôLRâãôSâGâ Ä'½â[·xæ ÒVÞæåÖAXø$5û5ðû M–°£ÔGù—ã­‘ (í)×Øo8ãÐuØjg*§ÕÝChµGèÇþ‹Â/˜}YÚT¾?¨‚Ó÷·]ã`Û•o•úÎF|ÈÍdÕ‘!%;Î=¥{$JxÒû ¼JXæ*É <|tÔyéæñUD{üØ-Ìæá·® -øƒÿÝÙ/ËuS”탙‰0ß™æ•Éš#CJsœuJóH”æ¤÷AsiX -M…­æ:h¾nêãô¨ýèá·oðÐkƒh—#öùlk…lMfR,`5("qP,Þ„b‰Ðø˜Ž~]í»=Ãמ,Åzž%húg°º -ÁîGÓäm2ƒÅR…Bb7ŠÊõÌB·_K|òÂYÝ«Üý‡ü•y‚´O -RDaYåxÏN,Š)Ò;ì]¥3"ÃÂÖÕgk›uÔaëê«m‘‚S)CvdXg‚±Hb¤k ,I˜†–D·œ…Ó™ó7íÉïå4ψ}µ ™J²#HÃz¤E‚ þ åzø”¦¤ð ¥Ð¯òîââìÔ-töã)˜o•OþT¦3)$¬´ÄßxÁPáïþÌeÆÒØ'·ªïAœ+·üR#M.ŠgÎ×3ÿ¦þçñç/àJàí”s®Aendstream -endobj -687 0 obj << -/Type /Page -/Contents 688 0 R -/Resources 686 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 659 0 R -/Annots [ 691 0 R 692 0 R 693 0 R 694 0 R 695 0 R 696 0 R 697 0 R 698 0 R 699 0 R 700 0 R 701 0 R 702 0 R 703 0 R 704 0 R 705 0 R 706 0 R 707 0 R 708 0 R 709 0 R 710 0 R 711 0 R 712 0 R 713 0 R 714 0 R 715 0 R 716 0 R 717 0 R 718 0 R 719 0 R 720 0 R 721 0 R 722 0 R 723 0 R 724 0 R 725 0 R 726 0 R 727 0 R 728 0 R 729 0 R 730 0 R 731 0 R 732 0 R 733 0 R 734 0 R 735 0 R 736 0 R 737 0 R 738 0 R 739 0 R 740 0 R ] ->> endobj -691 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [532.6051 688.709 539.579 697.2967] -/Subtype /Link -/A << /S /GoTo /D (chapter.1) >> ->> endobj -692 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [532.6051 676.5858 539.579 685.4425] -/Subtype /Link -/A << /S /GoTo /D (section.1.1) >> ->> endobj -693 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [532.6051 664.4876 539.579 673.3442] -/Subtype /Link -/A << /S /GoTo /D (section.1.2) >> ->> endobj -694 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [532.6051 652.3894 539.579 661.246] -/Subtype /Link -/A << /S /GoTo /D (section.1.3) >> ->> endobj -695 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [532.6051 640.1914 539.579 649.1477] -/Subtype /Link -/A << /S /GoTo /D (section.1.4) >> ->> endobj -696 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [532.6051 628.0932 539.579 637.0495] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.4.1) >> ->> endobj -697 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [532.6051 615.995 539.579 624.9512] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.4.2) >> ->> endobj -698 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [532.6051 603.8967 539.579 612.853] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.4.3) >> ->> endobj -699 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [532.6051 591.7985 539.579 600.7547] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.4.4) >> ->> endobj -700 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [532.6051 579.7002 539.579 588.6565] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.1.4.4.1) >> ->> endobj -701 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [532.6051 567.6019 539.579 576.5582] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.1.4.4.2) >> ->> endobj -702 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [532.6051 555.5037 539.579 564.46] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.1.4.4.3) >> ->> endobj -703 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 543.4055 539.579 552.5112] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.4.5) >> ->> endobj -704 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 531.3072 539.579 540.413] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.1.4.5.1) >> ->> endobj -705 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 519.209 539.579 528.3147] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.4.6) >> ->> endobj -706 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 496.7003 539.579 505.4125] -/Subtype /Link -/A << /S /GoTo /D (chapter.2) >> ->> endobj -707 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 484.5772 539.579 493.5832] -/Subtype /Link -/A << /S /GoTo /D (section.2.1) >> ->> endobj -708 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 472.4789 539.579 481.485] -/Subtype /Link -/A << /S /GoTo /D (section.2.2) >> ->> endobj -709 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 460.3806 539.579 469.3867] -/Subtype /Link -/A << /S /GoTo /D (section.2.3) >> ->> endobj -710 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 448.2824 539.579 457.2885] -/Subtype /Link -/A << /S /GoTo /D (section.2.4) >> ->> endobj -711 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 436.1841 539.579 445.1902] -/Subtype /Link -/A << /S /GoTo /D (section.2.5) >> ->> endobj -712 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 413.4314 539.579 422.288] -/Subtype /Link -/A << /S /GoTo /D (chapter.3) >> ->> endobj -713 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 401.353 539.579 410.4588] -/Subtype /Link -/A << /S /GoTo /D (section.3.1) >> ->> endobj -714 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 389.2548 539.579 398.3605] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.1.1) >> ->> endobj -715 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 377.1565 539.579 386.2623] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.1.2) >> ->> endobj -716 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 365.1579 539.579 374.164] -/Subtype /Link -/A << /S /GoTo /D (section.3.2) >> ->> endobj -717 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 353.0597 539.579 362.0658] -/Subtype /Link -/A << /S /GoTo /D (section.3.3) >> ->> endobj -718 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 340.9614 539.579 349.9675] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.3.1) >> ->> endobj -719 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 328.7635 539.579 337.8693] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.3.1.1) >> ->> endobj -720 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 316.6653 539.579 325.771] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.3.1.2) >> ->> endobj -721 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 304.567 539.579 313.6728] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.3.2) >> ->> endobj -722 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 281.9139 539.579 290.7706] -/Subtype /Link -/A << /S /GoTo /D (chapter.4) >> ->> endobj -723 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 269.8356 539.579 278.9413] -/Subtype /Link -/A << /S /GoTo /D (section.4.1) >> ->> endobj -724 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 257.7373 539.579 266.8431] -/Subtype /Link -/A << /S /GoTo /D (section.4.2) >> ->> endobj -725 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 245.6391 539.579 254.7448] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.2.1) >> ->> endobj -726 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 233.5408 539.579 242.4971] -/Subtype /Link -/A << /S /GoTo /D (section.4.3) >> ->> endobj -727 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 221.4426 539.579 230.3988] -/Subtype /Link -/A << /S /GoTo /D (section.4.4) >> ->> endobj -728 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 209.3443 539.579 218.3006] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.4.1) >> ->> endobj -729 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 197.2461 539.579 206.2023] -/Subtype /Link -/A << /S /GoTo /D (section.4.5) >> ->> endobj -730 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 185.1478 539.579 194.1041] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.5.1) >> ->> endobj -731 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 173.0496 539.579 182.0058] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.5.1.1) >> ->> endobj -732 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 161.051 539.579 170.0571] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.5.1.2) >> ->> endobj -733 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 148.9527 539.579 157.9588] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.5.2) >> ->> endobj -734 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 136.8545 539.579 145.8606] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.5.3) >> ->> endobj -735 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 124.7562 539.579 133.7623] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.5.4) >> ->> endobj -736 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 112.658 539.579 121.6641] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.5.5) >> ->> endobj -737 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 100.4601 539.579 109.4163] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.5.6) >> ->> endobj -738 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 88.3618 539.579 97.3181] -/Subtype /Link -/A << /S /GoTo /D (section.4.6) >> ->> endobj -739 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 76.2636 539.579 85.2199] -/Subtype /Link -/A << /S /GoTo /D (section.4.7) >> ->> endobj -740 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 64.1653 539.579 73.1216] -/Subtype /Link -/A << /S /GoTo /D (section.4.8) >> ->> endobj -689 0 obj << -/D [687 0 R /XYZ 85.0394 794.5015 null] ->> endobj -690 0 obj << -/D [687 0 R /XYZ 85.0394 711.9273 null] ->> endobj -686 0 obj << -/Font << /F21 658 0 R /F23 682 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -743 0 obj << -/Length 3152 -/Filter /FlateDecode ->> -stream -xÚí[wÛÆÇßõ)ø(=p»÷Ë£¯9I[Û±Õ—¦y€)Xæ I¨$×ýô]ØݸjÛȵD&'‘la0£ùÿ¸³³XlBý¿l¢4ÑŽ»‰q’(ÊÔd¶<£“kÿ³ÎXÌ44…G=¿<ûÓka&Ž8ÍõäòÓD*E¸ÚÌj-›\^ýrþâí›ËWo.?\üzùÓÙ«ËxVè™QÑžòŸg¿üJ'W>€ŸÎ(ΪÉÿJ˜s|²<“J%…³8ûpös¦ù¶é¾¾©–5NÁ›ùÇ‹þ˜×ÍzYíF÷½ËSQ*34Dd¤‘9"ó¾w½÷­“6†0_FvÎU[|..à sPvÒί?o¿ÔíÿÃçyÓ,ü´b<{Áã~Y™¸÷λ˚Ï8–­=¯¹Jªµ"L2Ûek7¶•4æk<=ý?®«õW_N¥|Ê%s”…¾âO0Ä>IPŒ‰L¨÷Ȇ„1Ê{6xÏÆûÛUjݪ/«zÙøI—3êèfU£¤„d“ 1R X)™80Rö¼gÇ\A‰¥®ÃT÷cîÞP›:¸j;oVœOõº^ÍêñÌ…“ß{¼Øx ƒlN‡GEŸ^'R[LM²Ã ÂaÌì!ƒ¹Äpωa w™Es}Ýî$Ë*ã‡<§­ç(yT» cŠ‹Ñ†;PB1~OG.ŒÔ{À‡I¸Ói)>?÷˜èüvYýa wÈe1'Àãj…q’‰ãõ¯2IÊ §ÆRÚ둶߶¼¦¾«–aÖ;û\­VunÕÏrR)Ý÷îóºÚx´àÇ5« é-†bð@ùÄø͹80xPïá<,´Sí -àñÉu³ÎÍt$%Úš;ðHjªBÅô– xòI: -O.Ü{_¡„±„I *Ôá«U‹/ë:·ÐÇ}}Š°ŒMo¸ÒG|Ý3¦»%`ˆ¡å”ãÛzsq`(¡ÞJZ{z8(aüAP:<Ó‘Ì=¡Ñ'¤µ`ˆ!eÃÉÄ!ƒzÈ(I¨e¬eãåmµ˜n¶Õì·;Oßß-Kßbˆ©*b @)Ôxœ‹õž@ÐŽXåCv <›Íâ­Ð/Ú víxÑ,Ú¢qºï9%® `ˆa…Á°ÈÄazOX(C,7ƒÚ¡:,~\ùöSåÙ¸˜jÊN·/æñ ,Æbx@Ôx?’‹ÃõžðŠ§ÄCwxü|[·/Ú=Ð >PAs¢"æ­˜ -`ˆQuQã÷©åâÀ¨@½'*„ F»ÓQÑ=…¶…âòÂÑóuµÚ|ÚM*”a',b⊱†P ‹L¨÷„gĈabû¦´ -‹ /ßuß¼‹í¹b¹:.B¶ŠY† P 5¾c?Æê=±@1” -‡ëXx{3xÒù‡¯›m½LB»Ý•’Y|†Þr¾£CªÇµNP,/0Ää… VãK¹80yQïQ^æ ÑÚÉÁúõÅ?ö‘‡5L?ñÆ!樔hˆ0Ð! Bî=`Ñ~®7 €u¼«×óæj>‹~^múU†]Wñ{µh?ÓßÚäÃ"’TŒ0Ä€"¨ñÍ„¹80Pï #ˆ¦Ãæ€ñèÍM³h®}“`„9=Ô$OHÈa1!À#j„’‰#õžÑŒ(#‡eBô„ÜcËàÆO~z˜»º% åÌí_ÝVÇ­Á1¹ÅèC (žßlš‹CõžÐ‘Ž(ɇõEv輿©ûæámwq£/¶8ÝZ•2WÌ0ĸ€Ê¨ñ§åæâÀ¸@½'.„!jØW0k=¿íŸ¯¬öa8e°ôé,f%Ùa¨±0RöƒÀ@Á\'N¸"ÒÜéPtÊóÛùb; ¯6Ù€~e¾ú´{AÜñïfÕ®ãån™˜…b}!&ð Ëã/rq`£Þ“ÆL)ïô &§ñ«åÍökzOV{ECšã¸~“TŒ0Ĉ€ ‰Cõž ŒH¦Ø4ÁìV˜üäÐO"ç³ |vš³ü/g†„Óì0 ãëÏ™ 00ב눰R Hp Ï®®vݪEØé0K#ü‹jöy7epZ?™C6JevˆÌƒ\ï}ËÈŒº/Ÿ2D(>î‡ÕЗ÷LI=#úà}ÒÜ<å9ãèÛ¬úD¿Ì*Ùaﲂ2Žó“ {“æ:¼@ÁAó`Ÿû<çî)¬Aôù,/K0CßÊ’´RÈ;YîF°‡H|ï”;/möe$þ?FœRümpz»±lo/³#;³¸¥Äµoä~®+ú»2‘ÛZvÈÿ]CJƒendstream -endobj -742 0 obj << -/Type /Page -/Contents 743 0 R -/Resources 741 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 659 0 R -/Annots [ 748 0 R 749 0 R 750 0 R 751 0 R 752 0 R 753 0 R 754 0 R 755 0 R 756 0 R 757 0 R 758 0 R 759 0 R 760 0 R 761 0 R 762 0 R 763 0 R 764 0 R 765 0 R 766 0 R 767 0 R 768 0 R 769 0 R 770 0 R 771 0 R 772 0 R 773 0 R 774 0 R 775 0 R 776 0 R 777 0 R 778 0 R 779 0 R 780 0 R 781 0 R 782 0 R 783 0 R 784 0 R 785 0 R 786 0 R 787 0 R 788 0 R 789 0 R 790 0 R 791 0 R 792 0 R 793 0 R 794 0 R 795 0 R 796 0 R 797 0 R 798 0 R 799 0 R 800 0 R 801 0 R 802 0 R 803 0 R 804 0 R ] ->> endobj -748 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 758.4766 511.2325 767.4329] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.8.1) >> ->> endobj -749 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 746.445 511.2325 755.4012] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.8.2) >> ->> endobj -750 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 734.5129 511.2325 743.3696] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.8.3) >> ->> endobj -751 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 722.3816 511.2325 731.3379] -/Subtype /Link -/A << /S /GoTo /D (section.4.9) >> ->> endobj -752 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 710.3499 511.2325 719.3062] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.9.1) >> ->> endobj -753 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 698.3182 511.2325 707.2745] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.9.2) >> ->> endobj -754 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 675.998 511.2325 684.7301] -/Subtype /Link -/A << /S /GoTo /D (chapter.5) >> ->> endobj -755 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 663.9862 511.2325 672.9425] -/Subtype /Link -/A << /S /GoTo /D (section.5.1) >> ->> endobj -756 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 651.9545 511.2325 660.9108] -/Subtype /Link -/A << /S /GoTo /D (section.5.2) >> ->> endobj -757 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 629.6343 511.2325 638.4909] -/Subtype /Link -/A << /S /GoTo /D (chapter.6) >> ->> endobj -758 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 617.6225 511.2325 626.7282] -/Subtype /Link -/A << /S /GoTo /D (section.6.1) >> ->> endobj -759 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 605.5908 511.2325 614.5471] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.1.1) >> ->> endobj -760 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 593.5591 511.2325 602.5154] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.1.1.1) >> ->> endobj -761 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 581.5275 511.2325 590.4837] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.1.1.2) >> ->> endobj -762 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 569.4958 511.2325 578.4521] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.1.2) >> ->> endobj -763 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 557.4641 511.2325 566.4204] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.1.2.1) >> ->> endobj -764 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 545.4324 511.2325 554.3887] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.1.2.2) >> ->> endobj -765 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 533.4007 511.2325 542.5065] -/Subtype /Link -/A << /S /GoTo /D (section.6.2) >> ->> endobj -766 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 521.3691 511.2325 530.3254] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.1) >> ->> endobj -767 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 509.3374 511.2325 518.2937] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.2) >> ->> endobj -768 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 497.3057 511.2325 506.262] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.3) >> ->> endobj -769 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 485.274 511.2325 494.2303] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.4) >> ->> endobj -770 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 473.2424 511.2325 482.1986] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.5) >> ->> endobj -771 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 461.2107 511.2325 470.167] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.6) >> ->> endobj -772 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 449.179 511.2325 458.1353] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.7) >> ->> endobj -773 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 437.1473 511.2325 446.1036] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.8) >> ->> endobj -774 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 425.1157 511.2325 434.0719] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.9) >> ->> endobj -775 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 413.084 511.2325 422.0403] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.10) >> ->> endobj -776 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 401.0523 511.2325 410.0086] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.10.1) >> ->> endobj -777 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 389.0206 511.2325 398.1264] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.10.2) >> ->> endobj -778 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 377.0886 511.2325 386.0947] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.11) >> ->> endobj -779 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 365.0569 511.2325 374.063] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.12) >> ->> endobj -780 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 353.0252 511.2325 362.0313] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.13) >> ->> endobj -781 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 340.9936 511.2325 349.9997] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.14) >> ->> endobj -782 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 328.9619 511.2325 337.968] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.15) >> ->> endobj -783 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 316.9302 511.2325 325.9363] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.16) >> ->> endobj -784 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 304.7989 511.2325 313.9046] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.1) >> ->> endobj -785 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 292.7672 511.2325 301.7235] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.2) >> ->> endobj -786 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 280.7355 511.2325 289.8413] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.3) >> ->> endobj -787 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 268.7038 511.2325 277.8096] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.4) >> ->> endobj -788 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 256.6722 511.2325 265.6285] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.5) >> ->> endobj -789 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 244.6405 511.2325 253.5968] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.6) >> ->> endobj -790 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 232.6088 511.2325 241.5651] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.7) >> ->> endobj -791 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 220.5771 511.2325 229.5334] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.8) >> ->> endobj -792 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 208.5455 511.2325 217.5017] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.9) >> ->> endobj -793 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 196.5138 511.2325 205.4701] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.10) >> ->> endobj -794 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 184.4821 511.2325 193.4384] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.11) >> ->> endobj -795 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 172.4504 511.2325 181.4067] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.12) >> ->> endobj -796 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 160.4187 511.2325 169.375] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.13) >> ->> endobj -797 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 148.3871 511.2325 157.3433] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.14) >> ->> endobj -798 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 136.3554 511.2325 145.3117] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.15) >> ->> endobj -799 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 124.3237 511.2325 133.4295] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.16) >> ->> endobj -800 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 112.292 511.2325 121.3978] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.17) >> ->> endobj -801 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 100.2604 511.2325 109.2166] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.18) >> ->> endobj -802 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 88.2287 511.2325 97.3344] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.16.19) >> ->> endobj -803 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 76.197 511.2325 85.3027] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.17) >> ->> endobj -804 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [499.2773 64.1653 511.2325 73.1216] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.18) >> ->> endobj -744 0 obj << -/D [742 0 R /XYZ 56.6929 794.5015 null] ->> endobj -741 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F21 658 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -807 0 obj << -/Length 3353 -/Filter /FlateDecode ->> -stream -xÚíKs7€ïú<¤j¥ƒ°x€ÝÖ^v”rd¯$W¶6É&ÇËâPáÃŽ÷×/†`š"¦%8~ÈJ‘’¦§›Ýß4ºÌõ¨ûõŒ"TXÙÓVE™ê &;´7r{¾Ãü1ûá }xÔáåÎߟ ݳļè]¾ç2„Ãz—Ã_w^ž]žœ]^ìý~ùÓÎÉe<)T̨¨ÏøÇί¿ÓÞÐéÿi‡aê}p?P¬å½ÉŽT‚()DøÍõÎÅοã Á_W¢©¢„!Êpø$\€OÂ8'Æjg²¤îoõG)wŠëâgàpÁˆ1T:õa‹Ùr¾(‡ûïÊs0<·2ÄrSøƒ/ýE9)«ÅÞ>Wt÷ù¬?™ôg{ûFÒ]²·¯èx‘Ö~ŠÜ­€+nHÁ)k}º¡Ù¨×¼9‡1 rûPp3f›ç_Ŭذ#0²#ÕÞ#5)´f‘N¿(1Çåo”òj¼O«æ7ýjؼy=ïÊú­x˜œt\˜ ÄY H T{ ˆPDsf[@Ø€¼—`pé>Vw¤%ăI%Ÿ3¿Ü¦àîl˜€ ÓZ8˜v`0¡Ú[˜¸ º(L ÿ"0Ýe -[|ìtBÜš Ä Y ›î†&a ª½…†9+ZhÄÐüoZ•ih¨¶ú® dÌcN=wÁÜ Ä`Z §é†)aª=ÂTXKŒ*d “ü"0Ý´bgØŠnÍ… -"Ь…MÓNhRv ÐàÚ™’Dkm{…ÑÄR&4„¹¦Çó¿5«°^îYºûñ¦œ;_É^Â|ý¬]˜ Ä!ÂIØ‚joÑŠXY0o9ºîÏ‚òï ‰/ÎÉ]¸‡fã1\`À4ëÆ%a† ª½Å¥ÄZj!.âv>yyS5:|›FbÜ‚ç²¹‚02šws‘°ãÕÞr¡8¡BÈ…l¸8þXõ'㯠n†®ØhÞ¿š^ãzÔ‘J=Ú°Çd‡ba‡Ž×²;ì ;°°£Ú]ía½BRB ýKŒ®e‚gãk÷N)ûÝ º„ aÈf bŒÁ0kÕÍXÂŒ1T{Û÷83W¡ïuýÊ8]+[kÖ¦o›×ór>]Îö˜Ù”á7ƒéêÃù­†æ—«Ò÷8‹ihqBQ|UN\«£Å۶Ɏ7Äâ =ŽÅ;aoT{;”°‚0MEïUÄÅÝ¡5‚=ÉÊ"8, ˆá‚á°ÃÕÞâ@]CÂ8pƒK|·üs±ì_74”Þ¬`(çó8yÓÂùª—)í ü”MÄ(€qÐÝ3©);0 -PíqPÖ•”ÊÚH÷ƒÀñx>X&Âýó B~Óðë¹öèÃ\B  BÈZŒt÷ôhÊ„\{Kˆ¡DPi"!ÂrQ.ãjäGõË+䶾Ìç'x8› ˆñ#¨m7? ;0~Pí-?…!BÚØËÔí늟Óê}9 UáÏý››ÓØçœÓWïÝÁ܈m+½˜ÍÄQÂIØ1‚joQ +ÛVDyF^.®ÊYÃíæwµ¤2nÊ’Ábü¾nW„dOy -^ÌfbŒÀ(aŒ$ìÀAµÇzUII¤°¼e$¶/®¥L¬Ø® f2,ÆýðòüôùéYbÑNj"‰þ¸5¤öö­bu[th6.@ÃÌt¯¿¤ìÀpAµ·¸N¤‘ àÂsp9=;zñúø$µ™MZˆ.^¸x|y%¸2 ˆC…’°ÕÞ‚Â)q¦XŠÈÅU¾©1Òv@¢¿Í´ü·+^‚‹³‚@0„@ ;0€PímñB€:Tøâåðôì8T·óE¨cÚêåäÏEYÕö?\åÂèî"‰Ó…U…mm?TÌqisƒN|ᚇºð¤zßT†ÓªÙ , -ñtb'WÁóÙ\AŒ+YŒ«„W¨ö–«º'5”E®ÂRßëyœyO· ®1–…Ô7ïLkoãgËjÐlu—ú) ¶P·gC1¨`X1¨v`P¡ÚãðÊ$±\ú¥É¸Q­skb[ÞjU<ñÅÁN`‚O³‚00f0 ;0`6´§º aëù çªñ]Ðåclw6]¾¹.çWnüªóQ—{âîÛì@¤ÙY·¬{<âŽM­©ëG7z+?E{£édö]¼j†iç™I=M 嶵ɾ¢‚—s/( ‡\Ok1D¸Ù4ÃS‡tQXB­¿ Óø }«µõÅß|¯\Mýíg¦³wîºúgóÓÕôCófЋíÍK}Ú¨Ù èsötÎpÕ§ýà«ÇÑ¿\*gæ·Ñ'ÙÑ‚X¸×|ŽÄ;apT{ÌJ׫ú^zUÁÕ ã´4«‹ùXÌÅݸGWýj´VãùÁx6S’gËÉ›z†Ú™ñ -ùè¦l€ ÆÀZv`  Ú#Rfü&Ö\¿Ô;%Ú«öèÖuý¼ôWñåõ»h¥ÜŽ÷B)x;% ˆ¡´M¥„JÚ“Õ„~BüÀerÎwnnÊj8”ÝóÍQìÞ%ÀJ0hŽéÞ`O‡ù`CkòrbŒ&TãƒzÕÚyað®š~¸.‡£:¥Ö{à¹ÝV^ùWOpnöÕ±«#&aFª=–_ÜÖó½Ftjxl} 5™öp6.ý®éÇóÅtöq}+uˆÏ.nØͺPAÙãA!:+(ˆ ° …” -¸öD¸ÑDRÁ< ¼I"Ï˪œ… -+ù¼|ëGê*ÜmsZ½]-¯¦Ë -û´ÖŸ¢ï²Á‚06¶{S@Ê T{›#´"Òï½>h&óëqúê}á¯ùá0Ü[î¸ûÍÕsîŸ{u‡Bo·7f3ÒÊaˆ€ a„l‚©Ž‰£DZøMâ8¿¹OG³þÍÕlj8:\,G£²~Þ^H(ý¡ëîZçO$mÏe#1&`d0(v`T ÚÛ´¡QB‹7ÎË?–.ôMàÝ 6DL|™X9v4o€0‚?Z3º, ˆC‚‘°ÕÞ!l- "Ü$Õ¢œU¡¹?žõßÖXË·É}˜ ^ÍfbÌÀ¨Ùîµ–”3¨ö–®ë'"ŠÈŒh˜wÕOK:ÞÄÙÞ¦Qì©dà«l€ FŒFBÂŒ„ í©yNÑÔ6Öc‚Øý¹_Åû»oú#dº'Jßwº - Ó=kVÙîûßáé0WlhM\Ì -¢•lâp¸V…ÝŽG*i~?7¿Æxä^wP¹îÖâ@–² ×a3Œhk™‡7°]MëNé-m_6A -atûÒæåö¡`Š¶Ûç¯Îhw‘˜2à Uq+,1þþÌÃÕ`_§¶j>/õ“ÙGõ3y¤T[¦>LÞÝÙ,µrJ ˜Œv?w.a¦;r¤41îŸI®4ªÕãoJbËÐ_e(¸:" ˆQCÉhwÝ™2ãUA’ŠX! -’j@ªú“r¸?¸*ïÓêí^ýP¼-AŸLPðq6A@#ÆÑîê”!A¨úHÄjã;—úÖÊ[ùT¤¶9èÓ ->Î&bÁ2Úý£”!A¨úHç„r> r°UÛ²û+”Ý!Ù„AŒ0cƲ;aFª>Æ(¡… ]ži›UÃó.3Ûöî«ã’Äpƒg¬û–Æ”!n¨ú€›5„±Îü—¹ ÛyCcÍ!YÕY‰‡°úÛVôöFÄ/¡S.‚­ @€±îš~Ó>Lq@ÏÄþ¡/tyv_úL·_¶š`Ll³Úg%)x=% ‡°cÊX÷×%¬Ø )~ƒå~}«+—É'¸ÿ±ª¹¹á¯}cfû½žõC¼Œé¸_BPK§²'‘¾JPȦíÕAÀòÿÀ‘'cendstream -endobj -806 0 obj << -/Type /Page -/Contents 807 0 R -/Resources 805 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 659 0 R -/Annots [ 809 0 R 810 0 R 811 0 R 812 0 R 813 0 R 814 0 R 815 0 R 816 0 R 817 0 R 818 0 R 819 0 R 820 0 R 821 0 R 822 0 R 823 0 R 824 0 R 825 0 R 826 0 R 827 0 R 828 0 R 829 0 R 830 0 R 831 0 R 832 0 R 833 0 R 834 0 R 835 0 R 836 0 R 837 0 R 838 0 R 839 0 R 840 0 R 841 0 R 842 0 R 843 0 R 844 0 R 845 0 R 846 0 R 847 0 R 848 0 R 849 0 R 850 0 R 851 0 R 852 0 R 853 0 R 854 0 R 855 0 R 856 0 R 857 0 R 858 0 R 859 0 R 860 0 R 864 0 R 865 0 R ] ->> endobj -809 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 758.4766 539.579 767.4329] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.19) >> ->> endobj -810 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 746.5215 539.579 755.4777] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.20) >> ->> endobj -811 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 734.5663 539.579 743.5226] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.21) >> ->> endobj -812 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 722.6111 539.579 731.5674] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.22) >> ->> endobj -813 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 710.656 539.579 719.6122] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.23) >> ->> endobj -814 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 698.7008 539.579 707.6571] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.2.24) >> ->> endobj -815 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 686.7456 539.579 695.7019] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.24.1) >> ->> endobj -816 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 674.8901 539.579 683.8962] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.24.2) >> ->> endobj -817 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 662.935 539.579 671.7916] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.24.3) >> ->> endobj -818 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 650.9798 539.579 659.9859] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.2.24.4) >> ->> endobj -819 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 638.925 539.579 647.8812] -/Subtype /Link -/A << /S /GoTo /D (section.6.3) >> ->> endobj -820 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 626.9698 539.579 635.9261] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.3.1) >> ->> endobj -821 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 615.0146 539.579 623.9709] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.3.1.1) >> ->> endobj -822 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 603.1591 539.579 612.0157] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.3.1.2) >> ->> endobj -823 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 591.1043 539.579 600.0606] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.3.2) >> ->> endobj -824 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 579.1491 539.579 588.1054] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.3.3) >> ->> endobj -825 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 567.1939 539.579 576.1502] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.3.4) >> ->> endobj -826 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 555.2388 539.579 564.1951] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.3.5) >> ->> endobj -827 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 543.2836 539.579 552.2399] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.3.5.1) >> ->> endobj -828 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 531.3284 539.579 540.2847] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.3.5.2) >> ->> endobj -829 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 519.3733 539.579 528.3296] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.6.3.5.3) >> ->> endobj -830 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 507.4181 539.579 516.3744] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.3.6) >> ->> endobj -831 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 495.4629 539.579 504.5687] -/Subtype /Link -/A << /S /GoTo /D (subsection.6.3.7) >> ->> endobj -832 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 473.5253 539.579 482.2574] -/Subtype /Link -/A << /S /GoTo /D (chapter.7) >> ->> endobj -833 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 461.59 539.579 470.5462] -/Subtype /Link -/A << /S /GoTo /D (section.7.1) >> ->> endobj -834 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 449.6348 539.579 458.7405] -/Subtype /Link -/A << /S /GoTo /D (section.7.2) >> ->> endobj -835 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 437.6796 539.579 446.7854] -/Subtype /Link -/A << /S /GoTo /D (subsection.7.2.1) >> ->> endobj -836 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 425.7245 539.579 434.8302] -/Subtype /Link -/A << /S /GoTo /D (subsection.7.2.2) >> ->> endobj -837 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 413.7693 539.579 422.875] -/Subtype /Link -/A << /S /GoTo /D (section.7.3) >> ->> endobj -838 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 391.8316 539.579 400.5637] -/Subtype /Link -/A << /S /GoTo /D (chapter.8) >> ->> endobj -839 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 379.8963 539.579 388.8526] -/Subtype /Link -/A << /S /GoTo /D (section.8.1) >> ->> endobj -840 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 367.9411 539.579 376.8974] -/Subtype /Link -/A << /S /GoTo /D (subsection.8.1.1) >> ->> endobj -841 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 355.986 539.579 364.9423] -/Subtype /Link -/A << /S /GoTo /D (section.8.2) >> ->> endobj -842 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 344.0308 539.579 352.9871] -/Subtype /Link -/A << /S /GoTo /D (section.8.3) >> ->> endobj -843 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 322.0931 539.579 330.8253] -/Subtype /Link -/A << /S /GoTo /D (appendix.A) >> ->> endobj -844 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 310.1578 539.579 319.1141] -/Subtype /Link -/A << /S /GoTo /D (section.A.1) >> ->> endobj -845 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 298.2027 539.579 307.1589] -/Subtype /Link -/A << /S /GoTo /D (subsection.A.1.1) >> ->> endobj -846 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 286.2475 539.579 295.2038] -/Subtype /Link -/A << /S /GoTo /D (section.A.2) >> ->> endobj -847 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 274.2923 539.579 283.2486] -/Subtype /Link -/A << /S /GoTo /D (subsection.A.2.1) >> ->> endobj -848 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 262.3372 539.579 271.2934] -/Subtype /Link -/A << /S /GoTo /D (section.A.3) >> ->> endobj -849 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 250.382 539.579 259.3383] -/Subtype /Link -/A << /S /GoTo /D (subsection.A.3.1) >> ->> endobj -850 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 238.4268 539.579 247.5326] -/Subtype /Link -/A << /S /GoTo /D (subsection.A.3.2) >> ->> endobj -851 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 226.4717 539.579 235.5774] -/Subtype /Link -/A << /S /GoTo /D (subsection.A.3.3) >> ->> endobj -852 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 204.534 539.579 213.2661] -/Subtype /Link -/A << /S /GoTo /D (appendix.B) >> ->> endobj -853 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [527.6238 192.5987 539.579 201.555] -/Subtype /Link -/A << /S /GoTo /D (section.B.1) >> ->> endobj -854 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 180.6435 539.579 189.7493] -/Subtype /Link -/A << /S /GoTo /D (section.B.2) >> ->> endobj -855 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 168.6883 539.579 177.7941] -/Subtype /Link -/A << /S /GoTo /D (section.B.3) >> ->> endobj -856 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 156.7332 539.579 165.8389] -/Subtype /Link -/A << /S /GoTo /D (section.B.4) >> ->> endobj -857 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 144.778 539.579 153.8838] -/Subtype /Link -/A << /S /GoTo /D (section.B.5) >> ->> endobj -858 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 132.8228 539.579 141.9286] -/Subtype /Link -/A << /S /GoTo /D (section.B.6) >> ->> endobj -859 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 120.8677 539.579 129.9734] -/Subtype /Link -/A << /S /GoTo /D (section.B.7) >> ->> endobj -860 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 108.9125 539.579 118.0182] -/Subtype /Link -/A << /S /GoTo /D (section.B.8) >> ->> endobj -864 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 97.057 539.579 106.0631] -/Subtype /Link -/A << /S /GoTo /D (section.B.9) >> ->> endobj -865 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [522.6425 85.0022 539.579 94.1079] -/Subtype /Link -/A << /S /GoTo /D (section.B.10) >> ->> endobj -808 0 obj << -/D [806 0 R /XYZ 85.0394 794.5015 null] ->> endobj -805 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F21 658 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -868 0 obj << -/Length 69 -/Filter /FlateDecode ->> -stream -xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream -endobj -867 0 obj << -/Type /Page -/Contents 868 0 R -/Resources 866 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 659 0 R ->> endobj -869 0 obj << -/D [867 0 R /XYZ 56.6929 794.5015 null] ->> endobj -866 0 obj << -/ProcSet [ /PDF ] ->> endobj -872 0 obj << -/Length 2197 -/Filter /FlateDecode ->> -stream -xÚÝYÝã¶÷_áG-pfù)‘y¼»¦¸ ¸¢Ý òæA+qmádÉÑÇnœ¿¾C)˶|wé-РX`M†äpæ7¿ÚlMá­µ"T¹ÎŒ$Š2µ.ö+ºÞ»¿­XБJ%…€‡…·%4QšgëÍ|‘·«¿|ÏÙšS’¦\­ž¦½ÒL#¤Y?”?'ïvùa°Ý݆+š°»_~Ài’d:cn…-É Õ~‡fèÚr,†ªm‚ºXbRžFí 悹Nûagaiºi¶kì€OïÛ}^58þ˜ïƒÎý±ìÇÿ¦Š¾ÿxÌ ²¤h›¾ê‡_·Oø9Äõûc3ä¿ad[TOÇ Íö»XÅ6C5T(Í’êŽ% Ý$8£;cÄ(Å£Âa§‰;ˆà,ÉñqWÙ.ïî˜NŠ]Uä5J÷yÓ€›3™¼Ðh{ÓÝéd¬Ýæn‘±·%ÊŸÚ¥­í6ªfö‡]ÛU˜yDIûlƒ®?\Ø!oÂJa+Nò>;ó'ªö‡ÚîÁ¹ë†ƒ¡Ã.wáÊT’Ø×õåûüÐã(ºT¼ÏA4‹³›X–Þ¶ïmOÀ-ˆ*ª–ù£ZÕÇ•+° jœ ܳ‡ˆ[·~­v< ¢·›@ÒUãàQKñpR·ùcî­Š˜g’™ò€bI Obž!£”&÷E{°¸‚|¾o‹Ñyn9¸&ifÎ’&om÷ ‚êýiÎRƒÆtù)I¨O‡·>¾ùo§ˆõ¨‘ãG'J2‹&½í /£OüÓãö\•6¼ÏW« ÚGØ lÇ0sÖ+õp®Õ”8(0¶^Q† ÌfNÎ]8òMa|üÒvC5îñÙyüÃý»àp8÷ã\ÙChbð£oŸ†—™)49äŧ|ÐéN/rŒór_5®ùÐvDobô |Ž©ú…M#öÂ1=½ŒÚEÛ…¤;´M¦ûüüÌ)ˆüºDà!þÑmó¦ú}ŠÈɦ“É_Ÿ…RG9n® jBÐœ,³ÙdÍHÊ%¬áƒh±ùùla+°_¥™ê@0ˆF(ažsý®7 °t2ÏRN†, -ôœA)*ìaˆÔqf§†d -D Öñ›Öñ  RyEÃBÛé kÑFdœ(&ø9˜Q÷×±ÂÁÄ S¬4MƒÙ Ï 0Bš1ÉsÞUíæÙæk¿d¹äÄjž°8ùÚ‚§D -}å7A,û+£c”ú…%%”Æ8yÿiU ¢¿^OI¢0SÔƒ©C>”‚e”<÷á!8|V5T•Ëã­Wóø·áÕÓØøú*ÉsUž›vð>¯Jœ‹–D‚A Gcoƒyä¼­ÙŒ6á¹sîqA¢Ú—š…2î5ï’~<¡ÈÔuûUKÑH)´yŠ-X.DdDdYÌZ젉©ŠNƒ¼rÕ?ÀoßNl -OyùœCÖ•“¦Ï@´64* >2óNgÃŒ&ÌõÀçUlN¾.ÝR Ñ#ë›0Hõ§øn*·Ø†¤°ÝàK­{hîôËŒB/-RvÍi¢n0‚b‰ÒHUéŒ -êj»^¬ûh‚*"¸‘K4Ñ·õ3v£®tgihM2îc`ˆŠw.°Ëº >,)…¼â`7!] -> YÉàT&³ëdQ¶®ÂŠ¾QaÁô'ìL,ßN¥ÆØ…òn³%†x¾¶Ù¶˜R~*”» 0QŒåï,cš7¢“²°½Ì»k/™ŒhaÄ•“`j¶ä$¸Ç±)CÎZç°Ÿ-Fèûh†¿•ÐÛz乄Úq\µ”«,ázÉ}Ó’hø,-A?”Ïñ®,»¶õù€x“€sšês¼íl}pœ¶…öW$±­•Éc[ç¬'cŸµ ®9ΉI:bòÒÞš É—1gÔäÔÃÁ6eå*ÿB⥄i¸=£êË.ð’ô€Œ˜¬†;ÚÓXã8€^Ïp‰þ€>NëÌœûcÖî¾qnQI?º}„FÜûÏÅâ§:«Çºj·]~Ø—ªŸ FŸ ä[Xº+ ;ßâø3+äN€€.Û}—Nbª8"ÖBÿÊ â-ÅýÝ%$“!œK}žLØp]£)B£ }ù³£Ý¶ ]å}¼ÙUÍ·uœØAǹ§ŽÓ?¾„΂}Ñk#È&[Ûxð¡Òñ€QÁëkÆ'ó¿sV­þú0}ucRh5¸AiBShèŠýê×ÕÏ¿Ðu¹¢ëV”£Õú(aÆðõ~% ©ÒQR¯îWÿü/gE;fMÂM p…µÂ0‚ú|©M<Ó†¹t¢šM_F]ÀY&$,# I ·ß:…›J¬|Wn\ÐÓëùßfõ´äÌÐ6J—ÓgfÿtÇir.ýp¬¯¡\œ*õŠ‡®²~æþïàÄ ÄàLqÆM8q rcÄé»M±'×fJd›ÜµÂîáÃÎ}âèV -¸×S^ÛIÀ“ÿõ÷7¨¹kûa¦ ¼VÇêvñÍA DŠÑ úþ®ø} °ÝþüUè[o#zvÊosÜ Ñ—žƒ[Ñ¢gžû¾úÍql -ôûR•Ãî6x_ÍÞ?xc _‘ ©!RªôKàe‚PÁ#ĆSYVébÍ;ŒŸÁÏl£WcÄK㡪/ágnü @?yùáÛ¶.oCéÕLÿ¿†Ü)¨aæKH¢ZØâô­†kK"Ãç@4Ûâµ0tiõ -š[}¡[Ày5sÿ,¸áî‹®Œ¥î -ADÆåüg¿«Ÿÿ¸§` Ô ˜¯µ^ü0þô·Š¸_Ñ# §r”\²+·Ç_O+ÅÝþ-Õ«endstream -endobj -871 0 obj << -/Type /Page -/Contents 872 0 R -/Resources 870 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 886 0 R ->> endobj -873 0 obj << -/D [871 0 R /XYZ 85.0394 794.5015 null] ->> endobj -6 0 obj << -/D [871 0 R /XYZ 85.0394 769.5949 null] ->> endobj -874 0 obj << -/D [871 0 R /XYZ 85.0394 582.8476 null] ->> endobj -10 0 obj << -/D [871 0 R /XYZ 85.0394 512.9824 null] ->> endobj -875 0 obj << -/D [871 0 R /XYZ 85.0394 474.7837 null] ->> endobj -14 0 obj << -/D [871 0 R /XYZ 85.0394 399.5462 null] ->> endobj -876 0 obj << -/D [871 0 R /XYZ 85.0394 363.8828 null] ->> endobj -18 0 obj << -/D [871 0 R /XYZ 85.0394 223.0066 null] ->> endobj -880 0 obj << -/D [871 0 R /XYZ 85.0394 190.9009 null] ->> endobj -881 0 obj << -/D [871 0 R /XYZ 85.0394 170.4169 null] ->> endobj -882 0 obj << -/D [871 0 R /XYZ 85.0394 158.4617 null] ->> endobj -870 0 obj << -/Font << /F21 658 0 R /F23 682 0 R /F47 879 0 R /F39 863 0 R /F48 885 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -889 0 obj << -/Length 3125 -/Filter /FlateDecode ->> -stream -xÚÍ]“Û¶ñý~…u3‹~öíÛ3“sb«“iü*0øýt–F‹üÌ2µ8Ü„‘¢Pk7Rݼ¿ùiÜp2k—z%%E t¬<¢RÚ'ª( b S(ªõƒ!övMU5§²ÞÓÏmS?šz(›º§¼»•é’‘½)*kú¦ßve;YÐìè;¸¾ysÿrÜü!ÔþØå¸ÀÉ_¨ÊüõR¤qÄRÕa„@ÿWÉTeA"’ ™þg«bFdQô -h€½t+æ[­O«D« ’ᨯpjÚIdi²Ht ¶$bR×­”rÙLe¾™­dª´^þ|«ÄDEòï‡'|Ã, 2™á9#-ÿw(G wñ"0%‚(‚½½î$¦àö…Qh%öÑ<k»E¼ƒÿÈ&K”JèDa±_—ŸÐ²c!–?—Åðð¼´ˆìO..‡ùYqI» òyWæ›Êü¡²šPñç•Uœ Óèó²èk# -3o­»Ë+ç Ûã71Ö"Z~Xßfji> <Ç>ÑÔÛª¹òýoÇ™wÝtùö£ú_Ÿ•è”Ö?J¢çóÿp¯JdAš€ÈW€¦„J¦¡î*ä©$ ÂTCÈ‹ã$a¢ÏZ“ :„x8‰y1¸„PFczz`·cô{Ùr§ŽûüÀ£ïŸúÁ®Ó{5fæ!,݉ÌÂITMõ²=vmÓóá;µQeñ.eÝyU¹È #y]ÐvÇö£1íåa¼ŽÃ/@ÈÊ7¦ûh*óD#oêÁtµ³i¤C^XYÌB¢IeѲovÃél¹€Ñ‚áæ{óâv¥EÂtÁð‰§7foÙAð‰ö Õ¥áÔ¦ˆbvǺÈQ”Û¼zà -Ë~€Ìá8XWèE>䛼7ãêìa á~ ÐizÚ®¬wMwp¦ð“fy»ò ¿%µbÞìl ~ÉåCÓ4^c=VÔˆú#!åEÁÇ÷…l -€ÇrkëÑt}nS@FYѨ]؇ñü íYŸ÷j@û(ÚÀæ¸3ŽÈ{lØN&ü µm¶ùo0.ƒØŠÔ.û¶*AÿÖÚ¢eÕ4 :¶ôKÖЗӷÈ\[¹|"4ZqÊÊ­eÍrH…î=CÙ,ͦ™yìPk/Z2rUB êžlÆù‚Î;=Ði½© ææ·£éJ« @¡ëWµfº­…À÷À¦ä¡µ¨,‹æ¶S[“×ö°µì!| -‘(¶ -ÕVx ›–ÎC™k'HX-hÊ€®V±ŠèÊá$yI„2>zæäpd¼ŒõlGH™ % R© IRuV|uêŒOÜ!o‘©‰¼=»ÉEçÝf›²öòaZH·—×µ®T˜‘Føp±Ê¹Xë"û A\†ó¯uºZÆì´LÎÞ¯ Ü¿ƒCµW1ÑëZŒkf¬dÝð×ö.!}ÓQÆœL,¢×ÏË ŽB'«á!ÿl˜@Q»Ïëòww|΄1G¡3ùùvË•‘õ!–µ†¾4NÄ”Bb¶55Q{N>fÀ˜rtœ‡²ÆK³œ}l h€pãB‘-_åÖ“ÀTÝ晜ÅÑ‹†žIëîlÄÂCè£mdØ -¾•“Â` nç‰p€rÿ0h…‚ÈfÇ#äbpÓæ`àn ›À·h´p(©–w¾|È’@Ž©6®lꊓŠëÞÔ%DU‚O% ìÌÊ]]Ë7¿æüƒ Ï›y¼¶÷2ŸòC[ÙËD.G‹˜-R÷[ÃXœ®áÀ@dB0°mm^ûÜœ‚h¡uì®ã«Ùñoêmà‹çIÆÚ¹Æms¬ -:fc< µ".ÆnŽÒ0ŸPæ3P©ƒ( åxûÉ:#ˆ0fÚ:a^xNZæÝ̬T2Rê= @‘:Gƒ.³”D50˜WK#•yD«@ÐéÃ"6„Gi×5 Ò -Xÿ»üGAfn˜cSï]Z0—.zSá8ä]}IR™f\æD{Üœý0¸Í4 ’0Œæ^.¨‡;@øO?/`ð6zTÂ$òè Ò 8}.+7ˆ§“ 7³.j=v®ÜVøÄffáëÅÕEÔXÄ\HãNAµsÊ×KÇî<„z¨®´ùFl½ÀPb °ñÞ96‚Çc¿>gLž˜ –Ò©«~‡½| dˆRǓĉ46†[Ú¤ÄfxöÀ_Öy W%¹Lî)òDÒemÛePTp=#á&œj‚¨¦NÒîK¾#·é ¤BãŒ=™:ßcÂäz@âׂ–ôݹ1¤0ÄK?vîbÜ­÷ùyg7ÓrÚóó¥/Q¨L¸{t64®<¦š¡žå1.\†¡?aÙdLª4˜|l¸0ßß¹d÷ƒñÈŸ(0ë4=ûØç ¨Ý Í¶©|Î= -b5:”ÀyÈ,º¸+¤€$u9@yß7Û’C.üƸH«#™D³dŒfYeÀw¦ gÌÁÆÙ@Î#Í25ËWe©ÁÂ{Ð(dÖ…7‘O ó]q„í›wïzlß áeáò}㈶#A%"ˆEtqúcÛ6ÝàìËCÓ8ê²}ÖìSk|o{îUél°]h•€¿Oc0üjûCsÝ~AÀ»Y¯–ÐWSüëûÕ®¶ug¶çB¨™yI ¦üRBÕ8Ýýª_v/›øª„JÓ£¯mM‡ÅŽ lÛÖZe¶â×cú Å¬ Õ+Ö4a“ XQБä5|ÔíC2:Íñ¢Ü!;­õ–OÞ˜ád°>C$_œ E I¾Ò“”×qHHS9kí=³¡­-¡:½Åø—êw½ypv»ï¸)ü®óк7‹æØWçöhFiBº@:yÑáFBÛ”î­Çµ: -S™ýä-ç깇b뤈;=Ÿµmê®c?Ý*؇ñù »”åþèmÓ+ô‚¥ÿ±%:W€Ï$üE‰.ùȨ¾Ì\Ô>‘Zø!çC°z¬ÌÀÏ9ó.8Ló3.ˆ¬ã2ÜÍÓ©ÏÀ}W¤#›Ù¥ô´¹Ü¹g«"×Z`ä1RãË O:0‘ÓàÖt#£nÁß“zí6§š»Æ¸M9ÝšŸ4‘f„ï~[ÓòF¤¿gþÍHGþoÇ‹‰ÅÈ¿ö_Îÿ‰•‚NSõŒ;L±C¤G¢Péáî_•®)ÿå¹€Hendstream -endobj -888 0 obj << -/Type /Page -/Contents 889 0 R -/Resources 887 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 886 0 R -/Annots [ 896 0 R 897 0 R ] ->> endobj -896 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [272.8897 210.0781 329.1084 222.1378] -/Subtype /Link -/A << /S /GoTo /D (types_of_resource_records_and_when_to_use_them) >> ->> endobj -897 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [190.6691 182.1322 249.6573 191.5418] -/Subtype /Link -/A << /S /GoTo /D (rfcs) >> ->> endobj -890 0 obj << -/D [888 0 R /XYZ 56.6929 794.5015 null] ->> endobj -891 0 obj << -/D [888 0 R /XYZ 56.6929 756.8229 null] ->> endobj -892 0 obj << -/D [888 0 R /XYZ 56.6929 744.8677 null] ->> endobj -22 0 obj << -/D [888 0 R /XYZ 56.6929 649.0335 null] ->> endobj -893 0 obj << -/D [888 0 R /XYZ 56.6929 609.5205 null] ->> endobj -26 0 obj << -/D [888 0 R /XYZ 56.6929 551.1302 null] ->> endobj -894 0 obj << -/D [888 0 R /XYZ 56.6929 525.7505 null] ->> endobj -30 0 obj << -/D [888 0 R /XYZ 56.6929 422.4834 null] ->> endobj -895 0 obj << -/D [888 0 R /XYZ 56.6929 395.8284 null] ->> endobj -34 0 obj << -/D [888 0 R /XYZ 56.6929 166.2827 null] ->> endobj -898 0 obj << -/D [888 0 R /XYZ 56.6929 138.253 null] ->> endobj -887 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F47 879 0 R /F39 863 0 R /F21 658 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -903 0 obj << -/Length 3414 -/Filter /FlateDecode ->> -stream -xÚ¥ZKsã6¾ûWè¹jÍàAäÑÉÌlf«ÆÉŽ•ÚJ%9Pm±L‰ŠHÙq~ýv£ %Á3›ÚÒ` øÉYa2¡Ë|æÊ<3BšÙj{%fÐ÷Ï+Écn ›é¨ïWß~ÐnVf¥Uv¶x˜ÌUd¢(äl±þuþý·?-Þ¾¾QFÌev}c¬˜¼[|þñÝÏß/>þxw}#¥uØ—sïâ‡÷4üÝŸn?ÞQûîöSï¹_¼ÿDíß„ïîîá!¯_üëêý"r=Ý™Yþãê×ßÅl üוÈtY˜Ù ¼ˆL–¥šm¯r£3“k(íÕýÕ¿ã„“^ÿiJRF™)”KˆJ锨L™Y ](ª—M³Ú\ßh+çÕáZó_Ä|]·õc5Ôkê:zvæ>Ј¿º]݃ôl®ç·'5ÝŽFï»f7PWÓi[žÂ¤ËWžtÇ‹vÔ1+ Þo?äÓó֮Ȥ³%lÙ¿»§/hüª;¬{úèdçy™)ãÓ0w°;»É•ËrÛhEV£ü°=Ëw€ÇŽûý5YhØì7ݱ]S{YÓs[ «Mˆ¯ô¬ÿ86ÏU§CÎñ9Ç'pï‰BÇQ]Çäîá¬{rZÕÌïMÀžÊ,:÷{ú€V*ôCµ[ù i1_u»¾Y×¾ÓÁ€¥•!J©³DÅR¬ÿ¬¶û¶ÎVÝ6!që²²ŠÇ®»m…RÇ•ƒì`f·j뺧Ž]µ¥¦™÷G’Ï«>ʼn…v jN³oº~ȪªÊKtªÚÀaª½§Ç*x¶uÕs¿KÁ¶ÑOuÊ-~Çf ->øDÄ)Ày•ZNŽ/£øLeð~È¿QtœOpÈëj¨¨EçÄ#é˜,¬`ÎÊ9ntáæ‹ëRÍÑO8Xð„òuÇ ‰¢¤tm}¨|Bd®@ *4‚I îêá¥;<õ¡jÚ#GCè‰ c?ÐH¯4nã5ϯôÒQ£ã‰c†é©,é›RM•…#$΃B2Ü?Ô§ù"³Ü'ýsÝïï(áqór·[|+ÎðÊÔÏûRÁ]Cñüâ3ttý =FÜÞúÊ…ï_úxÉÏÏ JÓŠqf–³ç–ºöÕê))ªz@¸4ºW@áüù÷1Ý á•iQ ùÜ È@}!´úº^‚ã'T¯:Ø%F8<ŽŽFû8r躖©móTG˜˜]2ÏTacŽÚ<¦¬©È$˜dô Fœ—| 䎖Urˆ÷J qÜjˇÇ5>O«5aüÍôƒËjÍå¼ÈÁ}½ºá¢…†ôëLU#FêLg2»(OI­2ˆô‹Ynr\È%ëIqÔÍtØ%‡—³±Œd–7¸ÑLùÌRC²ªÁ¿DtF Ÿ¡žñ“@¸rò‰Â‰¯â2ÅÎ]çT°ûeSGp é1löªÛ¿R·tœ Ãl} 1H: -n±=*‚«wzŒÐx¢KìÏñ¸‹¨i{ק¸ïp·o‰üw ‘vHŠ+kz¾­W›jw” {ðÆìጠb3p -ÍÈ)´c‘Â|Fææ¡f63 -O=°& wœWðdcZ*…— ™¤µùiÙȸýd‰ƒ6™Ì]Ь.dJÐæ &õÅYs™©MÔ>²W˜S·ùñMš fHÁWUOA„0›î¥žèº’¬\ÒŒŒÀ'QVžþJDJK%ÅÚ¾¶Ži<(j Ð|1h d^+C§“b•Õç¤Ó‰#OìYßÈ»‡´tU ÙëWˆ›‰÷¸8J‰܇)Ëxhûš]f¤ËŠÜéÒù¤ƒô=ô+d&hVÑ*0àL„·c|¥ó·tVZ™ ‘‡ôÒ‹‚„Xô9äE/ε9`ãi×½ì8PO¤0™*Ý8 Ó:ƒ¹†Ó‰á;¯IÁ–ÿ;_žP*Ýcá1»F8-ÎëÖ ˆZÛ âh_7 2Õ7§Ç`ÈQHáö-À×XL×4@ßÓ„«ºç‚Lpú>Lq)U˜Âœ ªï’ÎÉÀ¹Ø\ŽÎÂØòÜYèPˆÂ¹ØÉ"+ã¥H)Çꫲ§>1,L#}înºá;ªõº“pÛ…P×¹èáü #cI‘³yÃx3³sÇ'Åp‚®ï›¥ÇÇetøAôÕâ!ž"vyFÀ‡4êã. Á¹ˆùK¸9⬤âTe´Ò˜Pù«)ªš¡¯[Τ!‹çF2ǽýf&Ó—¼n³CØycM^ -fD -_tÀ€ÌvØüM„ù¹…S &cÃQðføˆ‘€:úMÏ£ÎÈLÒ,ߣDƒIDOUtèðõ)xúdĸË+¼qPPdSœÜ'VðúTk„ǾŽs&Îûò’P9i74ÃqàL-e¢…ËŒÊcu}¼ŸM£—ŒW/>Ÿf˜({’¬NŒûóµ`ÅѼr_Égí(h?˜¬I"ÓR7!¤™ÓcUMNc«F'mÒu´Ë~Û~!äµN†ŠáÐíip qEò¢À¢Ìò¯Dea‚»ªöõŸéûÇs£‰ìm¡j+¹ÿâk+G¢Ó•–Õ^TD‹ß%&ú†;as7´/ÿê‹2ð> endobj -906 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [519.8432 463.1122 539.579 475.1718] -/Subtype /Link -/A << /S /GoTo /D (diagnostic_tools) >> ->> endobj -907 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [84.0431 451.8246 133.308 463.2167] -/Subtype /Link -/A << /S /GoTo /D (diagnostic_tools) >> ->> endobj -904 0 obj << -/D [902 0 R /XYZ 85.0394 794.5015 null] ->> endobj -38 0 obj << -/D [902 0 R /XYZ 85.0394 570.5252 null] ->> endobj -905 0 obj << -/D [902 0 R /XYZ 85.0394 541.3751 null] ->> endobj -42 0 obj << -/D [902 0 R /XYZ 85.0394 434.1868 null] ->> endobj -908 0 obj << -/D [902 0 R /XYZ 85.0394 406.5769 null] ->> endobj -46 0 obj << -/D [902 0 R /XYZ 85.0394 301.1559 null] ->> endobj -909 0 obj << -/D [902 0 R /XYZ 85.0394 276.6843 null] ->> endobj -50 0 obj << -/D [902 0 R /XYZ 85.0394 200.1512 null] ->> endobj -910 0 obj << -/D [902 0 R /XYZ 85.0394 175.6796 null] ->> endobj -901 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F47 879 0 R /F39 863 0 R /F21 658 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -914 0 obj << -/Length 2458 -/Filter /FlateDecode ->> -stream -xڥ˒ã¶ñ>_¡[4Ušø¬œÖÞuv\ÞÙdG9¤¼>@$4b-²Ž¢|}ºÑ ’’8Ž«R:h4~7$V!üÄ*N‚$—ù*Í£ E¼*š»põk»Œóà‘æX?lî¾ÿI¥«<È™¬6»­,³L¬6å¯kDÁ=P×›îd®ßþôîñ‰ÆOï>1ôù_Ï›Ÿhü5ŒÃ÷OÏð÷B$i¸þñ㻿o>|¡uÁ$Ÿ6_>¿ÿç›ÇÏO÷¿m~¾û°¹žßL„ -Yþýî×ßÂU üù. TžÅ«LÂ@ä¹\5wQ¬‚8RÊCê»ç»Œg«n뢤DH•ÈQIµ$ª8K(ªwp9®‹®ý†òe8j[u-O{s¼ÙÚÐÔîyp8V>žiÒèÞš÷æøêÇ•íM½ãqO_ÍhÖèÚîö0^·³†y væHƒ’Yé˜ Û <á¯RFûª,a3(¤z ò8–îªÌ6"z]_ô«âhý¹5´<ô<ØuÈ_ƒ‡·[ H‹1Ê!$2M"è(²Ùž­ÙWmI0M <€n}Òu½t#ívÄN5,¨nÔ€‡Vok;‘Ũé¦ڪЖÊŠ¶¶>äT9åÄ^å0èÛW%ONݱ.d,L¬FŽvÈŸŠ!ÂdôÃœ) Á—t7|aÔ Ózvêï™ØÜ\–Œ‚<‘£µq¬d[DßÕd6©«íQ+ÓÓôà0ºWà·$ÈöLߦë-ºƒAÍ9~`ÚŸA#Û¯5‹Ð±̓L³@dRoÈRo‡í-OKw‰ã ’Rð¾ï`S®ÖÑíÈÝkëG†ÙÕ£.aÒvÖ™ÀƒR*HÂH]šB¡¬k0 nG_¸$DC‡Læ=€A¹D<ŒW&ƒfI¦g³ßžGB ¸÷«¹†ëúÛxÚ•aárwŇì¾;V—ÆMAÜ‚~^/)HÜ‹õ±G'i<¶DJ”d&¼ÈR wls÷€¯¦Åº+tM– €cü¨ã/åÆÀ½™ÓžIh<Áݨb"àɺÞ1ŸÏC±_ô\²þñð˜ƒ:(8»a¿Ö F˜É K2ŶÄ"Ž= -ëÖòT„ -‚>a·£ßÑÉå£-}ùÞý©àÓA"U¾x¬Û\wÝ·á°dý)^Üï¤`êðIxåº2­í6ð0 -¢,‚Ì&Ò W2%ÿ¿Ïåô£’l]5ÞÇ rϸn &™òšAÜÕs¨q; -G ·{¦Â -jÛÓ -ú.Xêïè÷/Ž'·Ÿ+`cÚ¸˜‰F¿r¤rrÙ(œóíl –(ÊG¡ã™¼ ¡cp€IÕZÈ/– ?r鼿3ÎA"Á6 wÕ«€½0UohN`K½UnP*yí"¯ Æ“2çâoÒ-ÆAžÇÙ•ãÌó›¯0ÕõÞgúsÛµç¦z†€â U07'*fÒumÚªERRaò*Y+ Nûª`,M%Ü’`>…­™#Y]µ†Qª–¾Ö3À–ˆ»èüñ„IP0a×…ÑT1¥\1e¨pKFå‚Ç‚ÍmÏW)}sÇëªgä^8þeôi¬‰7›_¨&&@(Mí£SßwEfW^× F<òAspƒÂÌ¡^vS)q‘ý!Ï 1«è¡°àZâ§îxÒÇeó?놯d" ÅÜd&U˜ø€˜ÌBqº.;ç–¸ÞYôV¨2¨HJf9&,Ô««Cm,Ïn¢d„ÆT"c¦ù”Ñt‡ñY)Ÿn—ªì|ÒhŠ¯(›¥TRáX¼txs¤Š&Ž_,2 €aOù°€ßCåN¨RÁÑŒ-''÷µûÝ™&;2ɆȺX÷4öáéu|<ÐÀ2–I²’pâ”äRC"!$¤Ée¡Àšƒ,üÝTâv­¯f:ˆY9¬û·3­ˆò@¨\]Jv1ZAš•ùá8‘‰, "%¤<™<>†)02p°e@׺ALzAŒnŽO\8¿d†Ù.“”""“ÓóM¤@ÆÁäp‡#H5J:GC­°Vvø=}Í¿÷zè­'ãÙÓíRõ¦Ûþä”QeƒJßuC[bæìÂþ„7±ŒÆw>TX -iâ;.Pw…°s7¨ì@Va$ê÷´DF…Þ˜óY€GZF£éKõê‰÷•]ÌÝÎ\‰)ZˆÂÒì²ÖEC•(_=H y rZ~DŠ­áefkŠ(Å6Ýá’P£0-$æçÔ —‰µWìDh¢‰‰vh¶d¹×"oèB­#®bê <‰ &dg°¬[Ìx†ÙeÇêÞKÔØá¹}¾#Elr|¨¶uÏ«]|3–ϲ{ŠÃËÞ ¡ýQcLÖÇÂJÍý’<_±Z0F~tmŒ0Öºå’ñ+‹áE%\!¥yNb<[:·;_6I ÁÔ~Lô¥ÊO½U>Nšš÷ÿþÂÁÌ· ®CO8«Þ6åÔp…õ êâêàŸ¾tµùÓ]{®x|zO#ßzͺŸ4dq#°jà Ý*à MïD7ÃE­SzHJgoO0¦J tžþ ”b„[@X¬õ«¹ÚÀiçfG»XGM ƒ»µÙ³–K9*œæÞØ] õõì·FW5ìÇîd¦ÌI蓹õȹäW9œ6´6¬=M»Ã:·Þ¾ËÆ%Ò ŽÛªà 9=lá»~Ý[½µUÌŸR®åXw/c|ÏpÛA¡”Ä‹I¥EÆ©#Í}¥ ]¾êÖê4‚¸@’bÿ–A€aØÞ44êÚË×ëWw/ãbmž»X›…ÎÓ—bgëŸfNÎF“kÏ_’IJF³Y®ìB©ü»ÑÅwöB³i–§¾Ês—`3„£ØÍ’QVäº=MnºOX,«C6¦ˆU¤Ì.ãíÔSѦÈ/1•ÞVueÏ$SBCÅCL ÚC aå.§DãZFÎàK)I]Ù/€œ_Ñ1|žóç«£Ig8ºÐÙ‚v¯Ë÷<šé-W”Iòé] @ì®wz]ª+chft¶ýð[ -ä4 Õ’Bá nUàhjUÔWäÎÜ2÷t!8ŽŸ -e*Ѳ€Ç,EJ¡¼Mq 9jÕäå/œÆGi²5—Žøy©Ö…¯¿«vzOÖSo9¯ÞøoÒþ!²ðOH8&ºÿû—éï§( T–Éå¿TðA8Ê€3åRjxùÿƒæ–õÿ÷Å:êendstream -endobj -913 0 obj << -/Type /Page -/Contents 914 0 R -/Resources 912 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 886 0 R ->> endobj -915 0 obj << -/D [913 0 R /XYZ 56.6929 794.5015 null] ->> endobj -54 0 obj << -/D [913 0 R /XYZ 56.6929 717.7272 null] ->> endobj -916 0 obj << -/D [913 0 R /XYZ 56.6929 690.4227 null] ->> endobj -58 0 obj << -/D [913 0 R /XYZ 56.6929 550.0786 null] ->> endobj -917 0 obj << -/D [913 0 R /XYZ 56.6929 525.2967 null] ->> endobj -62 0 obj << -/D [913 0 R /XYZ 56.6929 393.0502 null] ->> endobj -918 0 obj << -/D [913 0 R /XYZ 56.6929 363.1913 null] ->> endobj -912 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F21 658 0 R /F47 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -921 0 obj << -/Length 2095 -/Filter /FlateDecode ->> -stream -xÚ•XÉ’Û6½û+täTîË1Þ§*®T<9Å9`DHD …%Ë_ŸntƒË írJ6@£ÑëƒÂ]¿pW¤~—É./? Âtwh_»Ìýò*ä5IûiÇ0ؘݧqá§E”ïöK!¯^ýô> -wQàgY”îŽÓYYžûYš»‡êoïM-ÎFwû( ¼èßh[âçEⶎÈý ËK»áõ‡oiõŸR÷ãpnôï¨ÙÊÎèIL˜øq’E,&CèØÈïöaÞ¯b¨®b`)ÃK)ñ®ôË,ÊXHøišÆVÊÛŸ`[yµîÂÂCAøEaYì-BïBOÓd-.’6›ATʨ¾Ms#Ö£”Q°Û°¸¶¯¤6þÝ>Nrï}?ЂVt¼IuÚ€¢ô=òROËá">ÒÔÂà¥ðaè—iÙk°*p}>¨³ì4È‘ û#^áHƒ£½OßÒHŒrû«Ñ܈šežåpì‡ÖIU«ñØð:¡éK¦‚5ö'EK? -JòÚC 2ã ÆÕŸÞ½!ú(…Éš8 ¬ýR¨ UÒ§7"Îtƒ ‹3=}yÌFGòÍ¡:ƒ&q[êþ*AÏ»<ñÀÔq˜{š…ôVöItê+¹‚Ïø†ñ[ñd •yµ—‘£f^¤¯©!r¤ã®¯Œ{3$®J×¼¥§ïTP¥Xæ5¡'7Ö7mdk¥¤Þ±ÜqÓYâ|nÔn‚±S -fhWü(½¾YhovçåvlŒ25©,*Yݳ÷›¦¿ªîÄqˆjØ|SüÍ‚Ø{©uÏ•cqÀ]#Xg±¬,ÕI’Êøߨ ´8͸dD\2lL|£ælV‹„Jn Ë`«.hš±š#A&Fªä=¢;I^4¥ŽTRdûC#4‹hÅ¡V|.ÓÊhMË4`šÑ_ûiÓ\Õ†+ït¿åab\rc8JK§ rgM¢ ÷Ô‘¸·~$Â&TE´´ð¬“a«ì¯nhQYdçJÉk„“âªÒZ¨xm¯v¿•|“UllÑY6HúQƒX½¾G9(©§²æ -dXõcsý.Û~¸ý¿ Šç•‰×:%<ä7IE”èÚ–Ø’ª2yÑT -hZvýxªY/ý‘áÝN6“dy 8xp]Óc~{î0¨”~‚’$¡½„3×|Ó$ý$ÈR¸2Æ/{ë³ý4±òÕc¯ÕW¹aµ¤ôó,ÎXT¦JP¶Ø¶ÖVDÙ6ßFµÊ0«æU¢íÇŽ™¶¿À×¹`-åñöl«U -^AÁ³"rÍçžü‚ÍVN²éÎ|Õ•©^Tãb6+'gäÐqQgä œÀ#Ùu£¦MÀmû¥”Ä”ˆC¬¿Ðé,õÀû¹Z@“0 ±ÙEÐól6ü˜æI4$mVn:ôsxµWï&ì˜:,F9Ü2, -DŽ49œvDü¹„šný~¹ æÒû/å¢õ>ÉÃP©_¬MËZç¹—ù3?,Ÿk&ä2@‘(Å£À9[pxZµ_.{©ãKi¨X)$5”uai `‰fAþ2sò5ÜrNñÝìÈS?/ÃüYvà©6;ðX[$€Aq[€ÃÙ$Õ„|ÎdÚbß©@åœÖôQ‚уrmýG aCˆ¨Vj@Pºµp7ñ>Z`­óBC¬SßWÄ<ˆEíƒeõôöTá€;i‡œWbé"Žp±°Å©M)Gy%â*哦tð–RW8WièÈME“Œ"­º³lââ/²Ão,Õ`ú0Ù@ç×’Kà†Ï Ïm~~ÐÁ*µf¸ºzQè¦Á‹ÇÍQh³æÀêÛÆr’.“ƒ‘?,Ñevÿ'€þ0¿]pø®»¨¡ïì{”æµå€ûèŒó‚"¨röZ^¬žH9¢Â !\: -Ÿ¤IhsÜ]W‰y-èÚ3·Øé„™„ƾt‡éQ…ë-šÇyzÚñÈ¢°äø[î%•SŸ¬cPwMß92¨6ŠÐ9ÎQ °ÄÂ~ûFbÌ‘œÎ*Î#²­.ø„XbI"èÓ -Õmíš™Q‘‚z -â~ó ¯ fÙ"‡èâ9Lt¨ž¹£j¡ mK(ÈÏbµÌ¥X2¼É6õpT!h_¥^ÁO8,uU•a¸‡àk"¿°•6ª ÇsÓ÷Oã_IZ:ä[²ÑiÉ*Np’êZÀu ‰¡‰ñìK—!Gµ&¯!cÖ`þû$8‘ôbGÊ=6ü¡ºJ¬« z¸Äã5Âr‘> endobj -927 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [519.8432 268.1131 539.579 280.1727] -/Subtype /Link -/A << /S /GoTo /D (acache) >> ->> endobj -928 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [84.0431 256.1579 143.5361 268.2175] -/Subtype /Link -/A << /S /GoTo /D (acache) >> ->> endobj -922 0 obj << -/D [920 0 R /XYZ 85.0394 794.5015 null] ->> endobj -66 0 obj << -/D [920 0 R /XYZ 85.0394 769.5949 null] ->> endobj -923 0 obj << -/D [920 0 R /XYZ 85.0394 574.3444 null] ->> endobj -70 0 obj << -/D [920 0 R /XYZ 85.0394 574.3444 null] ->> endobj -924 0 obj << -/D [920 0 R /XYZ 85.0394 540.5052 null] ->> endobj -74 0 obj << -/D [920 0 R /XYZ 85.0394 447.7637 null] ->> endobj -925 0 obj << -/D [920 0 R /XYZ 85.0394 410.3389 null] ->> endobj -78 0 obj << -/D [920 0 R /XYZ 85.0394 348.7624 null] ->> endobj -926 0 obj << -/D [920 0 R /XYZ 85.0394 311.223 null] ->> endobj -82 0 obj << -/D [920 0 R /XYZ 85.0394 189.9853 null] ->> endobj -929 0 obj << -/D [920 0 R /XYZ 85.0394 156.0037 null] ->> endobj -919 0 obj << -/Font << /F21 658 0 R /F23 682 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -933 0 obj << -/Length 611 -/Filter /FlateDecode ->> -stream -xÚ¥TMs›0½ó+t3EÕtÌI;ŽÁÓvÒ£$šbp$Í¿¯@Â&Mzêx<ˆ÷vŸvßzM6x„"AˆEˆ8&lw†»ôˆ‹ Æ `uš{Ÿ/X @þ0ÑJNòâRÄ‘o0ÌÖËåõÊg1ÌÓs? Ãëeº:ñãæ³Å¥…²ïYžÎ3?`"$ðìËÉ2OW–¢Nèt¶pù«4»^¯ÎÒñíf=[¥ót‘gþ]~å¥ù¡‡iŸ³¾_Þí…i÷Êȉ„ƒó‚‚‚r†xÈ؈”^æÝ'ìú¡o#Ê"úq”"rêˆ&1ó‚±ñ¤Ûï릕…sm/›M«ªGçØ«nåN÷]6MP 6β3“A£Ñ@Ê¡°À¶ÞíU)µ7UaáÆO`W9´®,¸±rÓø$Ò²U·»—¥ê‹­+õ;(ÕOéàIÙ†ÕCÙNÓÞx¼d‘ûœÃ z–®šg9Üôö­‚çÖ+­ê¡N,ìíùÚñµ®ZK}íEUUÔ/ÚÆènûd©>„„PùN¢¨™‹ê4Ð[%Ã|[ú„ -ˆ,}Q7c‚}vû ­ƒbÓJP*ݾ-Wfü¦=»DÖ+ýÉ\Kií“ù'çs·?0¦¥ÃUõW`[ïí¡”Ï²´ÇB >Ém[7¯ŠšæWN¸ênÈÚÊQD·ºïZ3ô¯åcõóÁª˜¯›æ/æñß*ŒKzܹénÐ8AabD\Q½Í„¾«|Üà÷¥ÿ¦œ@šendstream -endobj -932 0 obj << -/Type /Page -/Contents 933 0 R -/Resources 931 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 886 0 R ->> endobj -934 0 obj << -/D [932 0 R /XYZ 56.6929 794.5015 null] ->> endobj -86 0 obj << -/D [932 0 R /XYZ 56.6929 769.5949 null] ->> endobj -935 0 obj << -/D [932 0 R /XYZ 56.6929 744.7247 null] ->> endobj -931 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -938 0 obj << -/Length 1222 -/Filter /FlateDecode ->> -stream -xÚÍWIãD¾÷¯ˆúäH¸âZ¼©OÍ°‰Hs`8TìrbSeìrBƒæ¿ójs6sàÊÁµ¼ý}ïsŒW üðªHQBK¶ÊK†Ò§«êø”¬öp÷ýö2,¥(e”Âfá6NiÒ‚ä«øÚÈ×Û§Íw¯H‚²Œ¤«m3ûÊrP  °­Þx¯Å°ŽIšDtýÛöG§ÆP^äب%à"C¸¤Vþ'~Nø1œ‚â;%?$ ÙO×­’Þ ]•¨ÌHæ­d%yά™$(i¤íhV,EeUíñY¸Ã~Xã"R§¶îbTG5Nû½µ¨ÝEuÁGJŽî‚wJî½ÕVœò~‹]+…jŒÆB­_N£€ ´ŽfÑûuI¢Æ´M’&-ŒQ™¦Ä¦e"r± >*Éw¯Ø‰w“õëFùÒUbм•n£z_XBëVîG473DYF|9FYRbë—"¼Žq’@Wø±þîº2^ …­!ŠÉ<ÀÐlêÕ[áÕ∕ìÞÜÉÛMRƒ2W—íh…V]§Î­éˆÙŽ-T¸ó·ÕŒì¡ˆyòÞ£¡Z®ƒ=ß8+àÜÄkN¤×úó˜¥s0‡¦Ëv±óòU× -©Ç¥·†EòS€Š2Of=§&ü¡W.tÀLFXôÚyÉß'1´¦÷fÓ¸<Žn§&=Z|KÁµ½áDnãÖ [;ÑiteL-dçÞ^z@3Š Ñr0¡sSùØò¶Ð°´@EžQ/ëph‘@#†I¨„ƒÜkg+¡Û“€:cŒ£¯&L0À3LDc‚o`Â=æÕÔÕn¹ó"¦iâ$ü©ÏÍZ™Z}!W‰37µu£VDS' Ðò‡4A¤L\û6è @{{VnZ&ÜvœvR˜ò›ÍÙžÛñàVÚkÙRºåÜX³iuD·°qÅâUwñwñð—{à’ œˆ¡dCØËía~}øée ”®[³M#AJTyy+W·´@Aÿ­äóFèjc†£Þ=æ0Tè½>Ú˜ÍEq)·+\]gR½ =^Œl9¯ËσØÚ»Ç`Fvn˜ƒµsm»uð×RýŽW½ºÄè«… Ô~x)³?•ôž­ ȶ26úˆ=þbÁõ[?G¯ªa1˦킗NU¼;¨Q#Hïùe)&©tÛøBKõåš.ð=¤Á¼Î|OßûÏë¤j€©3³ý/iß’7.-Ñ[–‡Ñ}dyp‚…ge8àþ‚/Dcg*}àÚ¶÷fá -ÿ¨2ûù@[ –¤('ðVt„(þ° F —7¯€ÑK‚sTRRx;Ö›#<鹎{žëøIÜý7¸Pé´«Õqþ›ð™˜1t6Ihb–{â^Ž­(áÏ!½Žm‰CÁe -5€B=—âÿëÄæ/n¸GÂä^xÞ`W>¾QAF?°9¯ª™Ù;ë ƒû9âãòíÊwÁ®|»0«ðœIª Ÿ:½äÊ0 £•0ö1¦ÿ˜SM™^ÿ^r0m%©ßÑ1¡¨Ä ûOèøéÛíü•¾]hŠÌ—ÐÒwP‰/2î#èñ4ÉPAÊ<2yazïmþ¤zt÷7¯Ì™øendstream -endobj -937 0 obj << -/Type /Page -/Contents 938 0 R -/Resources 936 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 944 0 R ->> endobj -939 0 obj << -/D [937 0 R /XYZ 85.0394 794.5015 null] ->> endobj -90 0 obj << -/D [937 0 R /XYZ 85.0394 769.5949 null] ->> endobj -940 0 obj << -/D [937 0 R /XYZ 85.0394 575.896 null] ->> endobj -94 0 obj << -/D [937 0 R /XYZ 85.0394 529.2011 null] ->> endobj -941 0 obj << -/D [937 0 R /XYZ 85.0394 492.9468 null] ->> endobj -98 0 obj << -/D [937 0 R /XYZ 85.0394 492.9468 null] ->> endobj -942 0 obj << -/D [937 0 R /XYZ 85.0394 466.0581 null] ->> endobj -102 0 obj << -/D [937 0 R /XYZ 85.0394 237.1121 null] ->> endobj -943 0 obj << -/D [937 0 R /XYZ 85.0394 206.4074 null] ->> endobj -936 0 obj << -/Font << /F21 658 0 R /F23 682 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -947 0 obj << -/Length 1859 -/Filter /FlateDecode ->> -stream -xÚÍËrÛ6ð®¯àøDÍD0^$ÁæäÄvêL⸲RO'Í"!‹>’²êvúï]g¢Ð§¾3[ôh „… Î,ùâ2ÄÐ(`÷òäãÙxB=ì^ŸMÇžçþ ƒžº:›žŒîÎ.>]^'¹ûöÇ“«Y‹ñ4·Ÿ.Ï/Þ}ÞÒ½Í:)ú’Ì”ßG_¾b'ß0b¡ðœ L0"aH|Ä=†<ÎX»’®G?u{»úè æF”ùtHuáê¼ùŒ2­ºßËBŽ'>ÆîFÀ PZL¢$©PT­¢#³÷‡Ô¡!"€'"…žG5æ~e äQÝÈêµFÅ»H‹4koÉÊ8Ê–eÝ JÞía›ç,Ê&]Üü¢4(“ÁËÿ¼íøØœ½±wF•šå«®eu׋Òò·(_eÅe>ÄaOk=Ì—WV8JæÃÚj¥½¸²ÒÂÛɺ–µ™– +fÝɾÄv?ʲr#« ÒŽUTÔ ù”2 ¿šÂd÷È#: !EÄ<„ -Ô"xÈcÏxüçYyÜ2¢JÚ7‹â=¡¾iìbÿóÐŒ ŠÐ·Ž]úhþíèQس]ûØíŸ Ð7Xu+žz¯L_›¥ïEzïu|N‰C8b„,¸È£ˆ’Іy:ž ¤>”QbBò›(‹Š8-níqÖ xpš -ä¡ u'ã ž»ªÒ£p›¥¹Zš››³Þ5Ù¤ÍÒì²Ù”Õ7³¬ŒR6¡Kí— ³ETf‚Üdy°SjωÁ¶ËìÕ`Œ%bŒ4Ðo ãCÅ+,£t€"½Ò>),,JìÌ+Â4—ô Ø,#K;ÎRY4vy“f™].‹BÆGZ5ʨ½*WÆTØkÊh–©aÍðѲ­ø²IsùÃ~M@Ú0u˜Oó9yVQB ìBì%ÿìTËG/ŽäÀœÃ@Ë‚­t»¤&­LÆCÄqØ<;þ/ÂÜgƒ†ž¯ut ?žpÁˆ;›}PøîÛ'×ÊWy@ÝÙ/WPþqB}w*ër­õ[™v¶bæÊG§Ó­‡FM´ÿ\@Àó±çô˜ýwâ+E“êËîõ_P£,@PuŠá²S)'`®UºÙl r(w!Ì+%̽¸„%NuLò1%ÖNïâÿ±z¨‡x(üaõºL¸Ã ÉaaÝ²Õ -ß× -ÞƲƒZéÝ÷²ZyQ7$ºMñžÒ -dŠx¦VØa­ôî{)­l;¬ÿ":RL 8b ¸À¸AÛê=hùh••€¶ à? t8¶-õ€:e¦ºYJU©p¦³" 6ï–™.xÕÊ÷µ¬R•†ÕDW -€¬SËþ‘.oBff¾ï¾¹¸<5û6íµ˜e5²#’ÛÛUæîÝ¿*Û î–Ÿû–²*ÚÝùAJ§A¨k35FfH Ž]Õ®(ä¢Q%”E挄ڦR->‚‹Bá^ØÚؚȒœ—wº<Á6õ« £Ak””yvog†A©KÐÞÂ0ÇÝ¥-s•á• Ö9ô•ý—ñÚŒÝÜŽÄ®›ª©¿aGªd&ØýºYÙÊ+@ëÚ¦Dà΅˜Ví©]™úkͺ*d²ÇF’ÖqÔÇí¨Zãhº*•BÃÑ«RÁrs‘4³D6Qš¸Tzät«>]¼Ñ³ƒŠS‰Ï¡Ä_ªÇ¿ kaº+Ù:%D!â3ÚÞ*¨*'e•˜æhß1ò|Á,n½ž×Êrcrp…~æƒW h_0åöt¹jR`và检ᖣî --”ªzå¡U$äÈ×™ÀìT·Ž¦C¿æ¶Ø‡CÅQ|L§ºÞÖßúÚßã…@ŠczÌ<xΣ<ìSRL ¡¾r©ï¡~ž!_´ýhûKS$ê_€ö7€b%«¨ÿ¤Ë*¦Ûd~÷O’Xr³1!Ä-ˬÞëÃ>·Nt3fk£¾ñóqÉÌz¸á…™g‹Î–©îBB°€Xñm&‰¬ã*ëðŽìá(3{iž¸’EÍuoªÐÓ趀hÆ*ÊSÕ©åi‘ÖÒÅE2±`,mÊÊvH¾ŒÔçœRÓj]Ê=ÑëûºQ™B‡‰í­æ:B[Õ˜“eƵw⊜¯oo»õŽzÑ)¶î)6ÑŠE‡œž—36h Øy²¨zî/ß­»ñ1!¤ö®h¹Ò¿ÎøÞÛŸÃÌÿ¿y¯cendstream -endobj -946 0 obj << -/Type /Page -/Contents 947 0 R -/Resources 945 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 944 0 R -/Annots [ 952 0 R ] ->> endobj -952 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [55.6967 190.8043 126.3509 202.8639] -/Subtype /Link -/A << /S /GoTo /D (rrset_ordering) >> ->> endobj -948 0 obj << -/D [946 0 R /XYZ 56.6929 794.5015 null] ->> endobj -106 0 obj << -/D [946 0 R /XYZ 56.6929 480.2651 null] ->> endobj -949 0 obj << -/D [946 0 R /XYZ 56.6929 441.7923 null] ->> endobj -950 0 obj << -/D [946 0 R /XYZ 56.6929 373.7178 null] ->> endobj -951 0 obj << -/D [946 0 R /XYZ 56.6929 361.7627 null] ->> endobj -110 0 obj << -/D [946 0 R /XYZ 56.6929 167.4388 null] ->> endobj -953 0 obj << -/D [946 0 R /XYZ 56.6929 126.8733 null] ->> endobj -114 0 obj << -/D [946 0 R /XYZ 56.6929 126.8733 null] ->> endobj -954 0 obj << -/D [946 0 R /XYZ 56.6929 98.4089 null] ->> endobj -945 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F21 658 0 R /F23 682 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -958 0 obj << -/Length 2706 -/Filter /FlateDecode ->> -stream -xÚÕZÝsÛ¸÷_¡—NåéÅA°O—Ë%×ÜÌ%×ÄiÒÌ”– ‰w©);Îôï À$EJÎø©ãàò·ËÅ~f3 -l¦SBE.gY.IJY:[ì®èl Ï~ºbž& DI—ꇛ«¿¾Ù,'¹âjv³ê`iBµf³›å§ùË¿¿øõæÕû넧t.Èu’*:ûâ—W¸ò¥éüŸâå»·¯ßüôñý‹ëLÎoÞ¼{{d4—ðæåwßýúêñ½ןo~¾zu¿¢û¥Œ -û \}úLgKøàŸ¯(¹Ng÷0¡„å9Ÿí®d*H*…+Û«Wÿˆ€§îÕ1Í¥B“TólDuœ©.͉\8ÕÙof„]'ŒR:ÿ±,ÖUÝ´å¿öæš16¯ëmc¿ðDήHγÜ!ÝlŒ'ê2e9¡)³²Zše¹b’äRhOóÝŠ$Z$Ø€€c(9*ã%á’Í‹j9Çaw¸–ž´j¶uýûq?‚)SÐ>Ë<áþpÍô¼^Š]ðBÏ ·bì$ŸÛ-®.êÝÎ2v“mYµNŽtUp èŽðÞÎþ8šÃCY­qV;ܘÃ94ÄJ8KÏ@ëvž1’§)êÀM[–++ÕÊp^VøÛ´[ƒC”õ±Ý[ƒP»¢%'6MaÁÑ”ÎÁ¸r6(éRM›`¤êE—g¯hÁÏó D#<{vAÁ¼”LûL­µ&œfóe½+œ†¨M¡ʺ‡kÜñ½S%ÌÿMS:fäR°6ñ VH 1Ë™·A¢µo7²›Ò¸] -Ü5XÛoMëéëUhü’7h7vfqçjþÆoŠÆÛR -’S¡ú¶ÔÞ×׉  DYšæo׉d|Þ”–)®—UkÅ¢-ïÌ#!Žœi ˆ%ΰçðš³oRÀ=“øEöÉmÑ.6C¨ûMͳ8¶¦ÁYÑ…³ßAûò£{I›Ât ÀŸmÙx«wÚ³Þa@ÛÅ'ˆì)+cÕ'¿Øž>¯÷Ö\ã,¦iÊÛàt+4¦Îp»að-<·S„TÇ5xƒTD0H‡#ÞÀ  •ÂxÌU¼@Šèbœú'£0–ê‘“ÕæǦX›I™„$"ÕêY2u00ãçc2ªàb‰+ûô=ºZÚu5‘­ÒÔ»FO$ë! E8¸­'û<ŒÊû5†ŠS Ɉ–"}JIžeÊ8ëIÚ‡½Á‚äœe©ŽBáWŽÉY@pÝÃ\l‹¦U)ÉR! Aå‚ä¶r颢‰ÀfŒd¢§¿Y"¤Ëø}‡ü”\Vn¹žf4®”?]”ßú–©Ú‹[öy$^Cl̉¤ ”Š¯Ç¼žzlŽ!Z„Ȉ˦Wœ¥ÚÁ}¢G[ünAÀæ‘ÄB{¼#Ô÷Þ¤‘AH`!.¡euæ«pô×!hîênëçÄní0J‹»¢Ü1îù× K œß…ðÛQÉ©"8ªX~>ÃfD -Üx"âÂ×dU“ -¨€©¾PÕt©¦«šHÕ­R»LmÈ“T©ó\#Õ[1ŒÂ–Å=¾Óe8“ü|ÍÁiŒ‡G(<ÊÖU¦éÜìöP3”×lþÕ4¸ä¬¾\D_ñJHºÎ`ɬ€SØ JÓùžxiVÅqÛÚÍPµ¸º¨+0ë¶Á·nM{oL…6XÁ²-‹}õ"¡gR”‡Xƒ -ˆöÆ)•ñÆY,—hÖMc‚Ñ݆ҷl½u®ŽÕšeá?Ýšo°£[o¡æKkª¥Y·n7g>‰ÞÔ'{J9¡ -vòI´‹1Ø#ÕÅÄ.sP.tIÏ‘©‹1Ø#U4M ïIñr¹­ÍÍý]ˆøÉb,ð{-Cv›Ê<‡&r˜B’·ˇjY·“x±)€íEÀ‰ÄßÏ\ï_—ñÊ>î IÎC¾„¼­‰Ê¹ì'îƒi¥ižŽ½»(îj[¬Ç>‚^¦ùOÆ‘+Ðzˆµ×4‚dyD¿X¡}[ÉØ/xšð¹ÿ¯Éu:;è4ÚûÓ²«ä™=j’ç³k—j:»Fªá™M/Ãr ýlÆÏsŽTX3H¬LÃNò>=/Ò:çE¶ËNx&°Ÿ¶ƒÐO‹4ë÷Ðö!n ªºJ:OmêÔ>ué±Qvon·õ}àµñ‹…˜&UN˜à|Ðã;‘2["BVwÝ,Ìü™Œ¼ @s쩳ìÑfá™3[X+nk—JaxËÅ¡¬þ=kM~è?Pù’Õ¯"®Šíðí¸TàŠwXpNA{?&,„9ºðŒ\÷žÍßöÕŠ„^‰@ëÎa`ô¶Ä‘“ž‰`é·cãG>Û‹ 2˽OÌÑÅA³@ÌæƯœ‡c -Ø¿±C _ñXgîUú“U„È8äAö¬*¢‹1]EDª‹U„P”¤\=ëÈ¢‹1]EDªž‹úÜáÙ„ñ©†Z -"U·FNÚ:Y•á¹ßújÂhpôÿ"ŸÄ³C×ù<ž Œ¦*ï%‡¾gë<%ŒœQ¯±$Ϊ–¸p¿q•qN!Zà -ž=­¶ámºKj ðí1&Ú/L|)ŽoÌ:œ9{fغÂÈÕÀ¹+q—îsÄpÑ\£ˆ*VÆ–1å4ë¾ÀH‡.˜;ï…éæa)ŠüŸäÏþØÔÒ8gë‚7ú‡å%l$·èu$xpŽ¢«Në0b:Ä 3ãO@£A…™œ“ävNâ‘ài8ý„‘Øþb<²#T¨¹\yfvÉ»Âïc×cg=aÙª‡+·Tãï­b](°¶®dù•£Q7˜–† þ¢šað¸åöig[\G¨ý -:ºV_ Ó…ýuͤ ÜÐ?:Ÿ‘‘ÄnÒªXø7ñ«˜9ªÖ^ -!-h¢è¾Þ®ÜšMqWÖN"{ÎõüÞ#-½ UíiÏÁ–(†/‡ßÛíZG®Ì4Éd,Ï•@P2©,ôYþàüccƯá4Ð~Ù ­)–d,a"·­­²IŒ(Édç~“ûûÍË]Y*E¨žzljÝéØûáZÏÖÂÛâ!â¡ÀoÍ:^+ì‹CÛ¿ŽˆgPOCõ~T&8Vk3™ªÕ…Z»K5]kGªàËd±1‹ßÁW'%·J Ôdùy"Õˆýý¦"1ï‹0y¨ÅTìHFÄ`kN2žóÓÛ\ßJÙW›Á¾4U[|îÉi=à¬OÆëg' ™Cq•JãM åÛéK{Û«)Ï© ºÓU]¤ºXÕ1}Ž-•ž#Scºª‹Tc;ì‹»ß=}aŠ0jãÌÁ,Úo‡Ç’(ž²o½|Y•[3qðV¬9U݃1çÕÀ˜ªó®ûH3í¸žf ­¯ueNÝ6J2}Žu¤9áÝ×d.x—ù9‡Õ§:¬„OrØ"„Ѧ #èXñ~åÔŸãiIL° ¼ž¾M‰àìYwáÌí+ÒL»¡ßl‘û¯A# i¼\{ö =þc˜²Ðš  - =Ï‚PVx–%ÿªt*úÿ(_Ñendstream -endobj -957 0 obj << -/Type /Page -/Contents 958 0 R -/Resources 956 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 944 0 R ->> endobj -959 0 obj << -/D [957 0 R /XYZ 85.0394 794.5015 null] ->> endobj -118 0 obj << -/D [957 0 R /XYZ 85.0394 769.5949 null] ->> endobj -911 0 obj << -/D [957 0 R /XYZ 85.0394 749.3395 null] ->> endobj -122 0 obj << -/D [957 0 R /XYZ 85.0394 221.8894 null] ->> endobj -963 0 obj << -/D [957 0 R /XYZ 85.0394 197.4323 null] ->> endobj -956 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F39 863 0 R /F53 962 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -966 0 obj << -/Length 3396 -/Filter /FlateDecode ->> -stream -xÚå[Ý“Û¶¿¿BoáÍX>‚lŸœÄN™Ú‰ïÒ´ãø'RwŒ%R©;Ë“?¾»ø"!’’'éL;é܃Àår±X,~Ø]àØ‚Â[È„$Ï*‹‰¤L.VÛ+º¸‡wß^1˳tLË!×W·W_¾j‘‘,áÉâv=•š¦lq[¼‹ä$Ðèõ󿿸^rI£›o¯¥Œþ?úùÍ÷/Þ>¿VqtûêÍë›ë¥¢Y}ý·çßß:ŽË2¾~óúå«oìå\¿¿ýîêÅ­Åp¤Œ -¯WïÞÓEþ¥rñ”°,ã‹íU,‘±Ž²¹º¹úÁ ¼ÕŸNY.–”HËÅRÄ$…þ§¸XB2‘HhO‰P 7K94dFÁEoül`ü”™erá¹Ðøu¾-‹åê¡\}øÔÔåõ2¡4z·,~ùõñ›÷îi…–úò¥iLÁ¼¡F(eµÉÛÖ0]òŒ¤©Ê,——×LÈF/ÀæÐíÝ„ÄÍKì.J,ª}¹êšýqB¨ŒIÂ%;ú4!f 甩Œ1’IɯôUþ™JZÝ×;4¬,°ÆŒ¤±pR™ƉJTlžò}=!… ’¡«¦”u^m@+67Õéé ë?á ÇþüÓ¤£ð”(šÆ¡£ü§‡û™ŠN¬_«”áÐkÿ’˜wb$É”JœåªM‰€2!)V$åT  - —ÅX²PT¥Ôôcy–&rœMm1–irÍv -º¡»gqF“êlÿži¬@`XXï4S,Ðà¦ÚV›|‘Qgñ/Ð;–„RæL}ËÏìÃ~Ò|Á[ôÐR ¯ôo囧üØZqØîZCîJC3h¤USweÝyÝÌçæ±Ý•«êgJyY  -‹%§1á eΫ™õjÊ7¥ÙfÑûã®Zå›ÍѪÚüæ槨Ö×,ÖåL×@^7ûmÞ¡C“9÷HAÒKî1`šwÇ„ÚïëbuÚ£R„%2;Û£ã÷Ì',V"èñVÏBÊ#cmÓÙg½z Å¢"rm¨8Cš³ÙÚx‡ŒŽÆ~Q»q(Ä)A}<ü2#sgz¸ßç[C€ùkžZ£MçnmW:†b[ÕUÛísØù I»Ï”Æ(@;«Qmµ!,6»¤T8`Aã¨Y›ßÜü«*¢¶Ü?‚Û@á^¬8,¬zU®¯^½þÆ´2ŸM™'ƒ,8»`Øß©ß-ÚÃn×ì»Öê³Ù˜†¶6T¶y]´F=§·Ýë”N)”f$¦‰ƒÏi}–1ã„ŠƒºjSu¸¾ÀåÇU¹ë&:H ¶"È×üm—ﻉ®`ÿÉ’ØíÌ0¬I#BÉ“S‘ûrV(„ú™tö|†î@£§‡êšE«óñ“Eó”oZô"%¢ºé¬Âf„4½ªgœR -uÖ˜HËÌïW_´Füê!¯ërc„o›¢çàõ¯ÖÆg1æK™„ wl¸ö×it˜RI(ˆüRyÁß84…Sû©êšƒEļ¶Úìpm´MíÛ§ -½Ñj»ÛäÇdm~oy[¶ýCÞ:´ÕËû/#¨…ä­˜0J(géHG†"ÆHìÒÏ…ÃÿQ+:£’Ĭ1åòûUŠ˜Ï<—Ÿ¶3‰äxÎ:ÿà[W÷S‰KB §¡c{1@¶7)‘ó˜ŸJÜ]”ˆKi*Ø Âd/ïxQÞ‡r*íaþÊ,ùìÔ"éTì˜Î2ö¹QèA:¾¶l„÷Sp+Ò …Ž"Yšõ;ö$²ÄÇÇAÇ!*"8w#­ì46Öæ×ì²~qVõýhy:O–’â^vÁÛ{&íìq:åì–Iûz¹iòbƒ!âPï\§žiÔkÀwqœÄA·oM·zè°€0š¼?¸xÀÄ”}|‰Ö Œ`[2k sX -ÓxÞB®3&r\¡À ålöÖgTÈ M~7!E»òD]%®¿Y1nEk˜oó®+·;=7ÜçÙœžÈ\ƒ}¬ZOÕfr­z8sÑ¿…µOe=‹_°0ˆL“ô<~ ¹æñËsµò§yô -å²ÿ+àåbÔ³í#Ù‘I§#ÙÀ¦/êüN;a’öØÅ“Ìx$sóØÏ»!÷^/-–‰$ÑX†ïë¦e(•ŒXæ L¤$NéÉ©d5À2å±L9,S¡.ðì±M ± kô86làíÙRø-+W°0ÄÆ0a6Ô2;(ªöó)hÓPÉ´¹4ª!4q6Ø€¡ß@à!_k0CfÔÁÖCnàѦìôP%—Ñs÷×[üØ-x++“6²ˆS–S8à¦XÒo5<=Íð»iim\tWº£Ç›Y¬àx¤’ ±Îk+<—V½éªõñÿ*ß=kË%FÆœF‰Àšo˶tŒ×on_½üWP£mçÒ ³¹ÇÒ·˜¹šÓÏý€ëÌÜ;.“ûôõÌ "Ósz¡gÏ5î:¬ ‰˜Äxg(èÛWDâN-“‰êýöm)@£ÿ¸gÐ n†"sç¥IT4–«±„ªà¹üXµ]Uß÷2†½¶ö„€‚›Ç<„ªÒ$3YUˆåYŠã8ÊCþXš‰­4¶ÊÄa+~Óš÷k  ¦6ÔÜÖÀq]’ NâÄŸÒ KVåƒôÕŸ?==8}AOÿ™Ýp€œ›ÇÙô‰PëÃöÎ(˜b%Ó'1Ölyˆ‚n{ÑЦ÷ŽðD#lª¢=ñüº,]}ÈBdùÐÔ…S}>Øz¿[ ê†]µuŽj¬eìTί/Ê^’ µ…!×™õå¸tm¿Ë»v\ne°—+y¾[Ï5î7\\,W:þ óæ}ÕY[ø-Û züª ­î wÊ`¬7k<¼(F»°1 ¹æç¹p ¿ÊýqÓ̃ÓÙž{pu= NA߷ךû{é0etÁ&¬ \`ÁxôÃè…ù`… ©6á’Î’˜¶,Ñ~\~ÜmªUÕmŽ†^Tf®:+2uyÔ œB÷¶«J{'VLyïﮣÇùá~Ëì/‡Le!2 fOT' øúãu}3Ä^K™€1EX*]…ÄÙoB¦°ñ'a-¥±‚ ž8ņwmnt¢N`¥9Ñz[©8+þzÌúØk5Ô^q’òÔ}ª=ÄFëBé}îd»@WÖ êX¶%|Äüù¶»S3k¹8KümJ{|<-‚™‘å `NZNÆ<þËÉ ¢éŒ<x†¦’ 5ü!×xp\úJæa»+îÜ)&¤<¿-Wùê¡üm‰Èÿ~>ý…؎婃IÍL™ˆ*/Ül»JÑ õ\㑆óEìØìd¨ßÀP¯—,³ ‡èóxËIzô¶ˆŠr6¹„Dˆ¾DǶÙû+_"f'•Óm¡ÐJœžÖ#Ùá•2M@·˜ô2j’ÞA6dŒ?,› >f£—BiA–æëٙÌIz¨äÂAá€iÞÿ“ÙÚ›?’yƒŒFd*=Û¹gõîP1ÍXÐýî^ÐÔ•éÒÁÝ)ÌU¹ˆ¶ù¼…£÷šEíÁ ¹õÝlØ}F_ÓÃçA-0µuJÓÉß÷†Ðçâ4õÕ5l7{‹‚€=`Ü_ýó%^×gÃ3Áö¾íÌ›bçÂе2WO‚¯ÑEèú…Žÿ†œ¾FŠT{–¬ãYíƒÀ°Ü™wÚó°[çy`3÷FÀ/,ƒ½A·*Ûvî_ `Fñÿ&f›úëøßúÿÆÀ{i:wT§°fB¬Rh~–Œ¯^RXý ŸPýßz7endstream -endobj -965 0 obj << -/Type /Page -/Contents 966 0 R -/Resources 964 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 944 0 R ->> endobj -967 0 obj << -/D [965 0 R /XYZ 56.6929 794.5015 null] ->> endobj -964 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F53 962 0 R /F14 685 0 R /F21 658 0 R /F23 682 0 R /F48 885 0 R /F55 970 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -973 0 obj << -/Length 3750 -/Filter /FlateDecode ->> -stream -xÚ­ksã¶ñ»…¿Už9ñð$ÁöÓå’K.3½¤wîc&Éth’¶Ø£HG¤Îqû绋@R‚$OÓñx‚‹ÝÅbß ¿fðǯN˜ÌÕu–«D3®¯Ëí»~€wß^q³ö@ë9ÔW·W¯ßÉì:OòT¤×·÷3\&aÆðëÛê§ÕÛïÞüxûÍÇ›µÐl%“›µNÙêÛ?C3Ÿà•Ö«¿yˆ·?|x÷þÛ¿~|s“©Õíû>ܬ3–+Xyyí?~3­ûtóËí÷Wß܆]ÌwÊ™Ä-üzõÓ/캂 Å™}ý,áy.®·WJËD+)ýL{õéê/áì­]“œ–&ÑFdÑ 9—<1©4יΓTÂ;”]SݬejVÍ@¿»nVõ¸ßuuÒHS½ºÝø—EÛöO~ÜÑoýÛXﺢŧ|õh×÷e=8°±§ßª°mÓÕôø´©Ýú®ØÖŽ‡MQ–²ß>¶° BÃ.ל'¹ÖÂr<ŒýãcÓ=$‡ÒçLÁfUvñ,‘"Ï£â -Pë9˜—2sq1«tB†´7E;‚P[ý´~üåˆT&™Ròê˜åy¥&É„>ààìTQÈÕ¸©q VC½ûRïh²Ù‚4›b¬ÛçÎù -ŽP2¾úX—u7H¹)º‡ú†¯zÞUí1Òéí64Q=Ãé4%‘Ù?V€—^ôŽÜû¼ûhÏŽ ”‹›åQ¤MÀ׫®i0_ì‰ÃÐjW´œØÈ{ÁñÏŒ‰¶^Á“ä«»½[þÔ´-îÜ"âºm=Öû~÷D¤+BO[GÔûW¿wš;Qs4H=ðB Éå™ç©5‘;6êa,v£µ¥²Õû{z·~\ÂuÙ Iä_X3øÃ@ +B𦊑 -VŠ”ÈJñeq³æ«˜Œס±âo0Öˆ]-‰‚¯ÃÃÁß™éâ#ÉGÎtqhM“éºùvZŒûሰÉ!?OØC>°`p„9î‚ò×ÍðØ*˜ðlØqYó)" )"ˆ+ÁD@­>ô£{5nŠÑÜT·ßÞÙäP*±ú7„"‡½éÊv_ù§°ªé¦ÜØçóè¡2t@ÂéÝ]ÓU¯ß~ççû„42Å!–© ÷î»:P…ª¾/ö•SÍ``>f%¯ßˆP„§¯Цñ{"ÙÜŠ>µÓNïlZ{:²þöGX˾ÃôïaO8«3š«3p?æR53;£¹ -w»«Ëýn@ß~ª9O;2G´ã…Ì‚ø×ûíãÁQ¶ÍàäÔ;™ÿº¯w÷³tÓ ø'ùucû<xؘˢ*R40’å)°n ž”Ê¿Dß̤›³ÃmQ€‰tM¶6žÆ¯ûÆ”(ŠËP,k‚(lK Þ H!nÆ ¨(ïÏpÒ)öðºq©-lÌ®ŒT#UóÐŒXÈ ¶ÞDÛWÖwËÔ:è-† ™RbŠs£yÀÊ+P[A€Ü6m±sË{¤x„3ý}Ì•i°`Åù¬rªN9d£y™à×°×¾ô-P§€>£Þw‘i‹ûSp’§ùa÷ÔKØiv"VAÊ•3¾ðªC„U‰$¡ã”o*ó)tÜ -9dì,Ë^ŠÄ¥:^D×܃a¦±Í„¿šÍ‚0ë*Ž6M¹!}¦É‰7xØÖEçÐ{¤wž|HãÐÑòÜ%?ÙSWÜæWhÓl\0€QVr˜u…J3L›@Š0&ti°ÑÃÓyª/+e–9ð†…«\m¬kÍÃeE]ÓcÙû¡þuèYÂSáµÁ%€ë“Š˜büaçB?Àw"F‰DCñ3sŒÆ•âδmõ±ß1´*ÉŒò,$1éMH<6çY 2N³ÃËš“òÀÖMžúäe,>Ûªê‚~6½-Û`äú6\ЂT•+Düûø°w'Š3¶¦€>:x§Üw1°¾ò—.<Ô0KéŽîøå±()êã-à‘»>âØ×~w Y¬‡©jÎÌBÑ ”Ë;õ¼Ê©è AhŸÃ*[º&††Xàúû‡ 9=øvñ2 ÷ÊŒ88­ô;ðÛQ•Aõ -Í““Ô¡ÄäŽÅE‘&à8ÅäZPß4¾³æ?ƒÁÎ4ùß…JE:séê±Ø 6]S©OÒ`T”eý8ºq÷Lƒ ¶JSF¡|‰¤ÒÔQ¹* -ßxá ¨ìè:@¨²^àsÄþGËØl‹r½­tü<Œ…ƒS=ûŒ×½Î]R`ñf?‹ Zç®5guã,¼î«b¨×©CZwe_ùû ?bíÚY¤ÿøî­ûTR+ãoF°m-^¡ Þ7™KÀ¡Ô{l*¦rTMS˜†çy. ó{w“#Ù‰eo™³\ž·P“˜\Ë8G®ðžxY\˜BUæïØ…h…Í´¤ü…µ8@–†Î² \‚Ï— ®%þbàÌ•[8Ay=ŽlA¦r ?euQ6&1ƒý‹ì‰É¦´uÙ˜UkX·†ƒ³E8¤I,TO'½¨aê| h­@°Y¶ Ñ'²}> endobj -975 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [120.1376 365.8002 176.3563 375.0156] -/Subtype /Link -/A << /S /GoTo /D (controls_statement_definition_and_usage) >> ->> endobj -974 0 obj << -/D [972 0 R /XYZ 85.0394 794.5015 null] ->> endobj -971 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F48 885 0 R /F55 970 0 R /F21 658 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -979 0 obj << -/Length 1632 -/Filter /FlateDecode ->> -stream -xÚÝXmoÛ6þî_!û`Ãñmý”iêM»ÄÉÖvÅ HŠ-T–2Kn ýï;Š”,ÛLtÁ6 þ`R<ÞŸ{îŽ 0üHÀšê@êqLx,G8˜ÃÚɈ8™° -‡RÏf£ƒçLiAE0»èR+E‚Yú~ÌCЀǧ‡¯Ž'!åx|~|6á|| íüõ›ã³Ã‰ŒÆ³éëÓóI(±ŽÆG/ßÌ:‰¯ë8z}ú|zr±Ñ3ù0{9:žõ§ž”`fŽðûèý¤pà—#Œ˜V<¸… FDk,GgˆGŒuOŠÑùè§^á`µÝêEŽ`D™ >èô:BŠ”ää FY‹]\Ì«UÞ,–“P`<~²XÆI¸Lù“§æp`!„mšsÚJ×Y²Ê'š°³»+ÊËéÉåúŠ]–ñѳå›Îßž?kÞþÍß–—xzBïN.æï–únzrfwèäWešüS¿—dàåÁsr2vª™-òÚRçWŒi‘}o'ùµû/ë&.Š,µÓ¸¶ -·£†1Ò¸„[Y“ïPR•×CB¬¸3x[­‹ÎHQT·vØ,2;Hªå2.Ó<æC¢€SJpI¤•­Þï¬h¤†©‰´”Â6.ZèWYQÅ©ÇÓÐmpŠ-bM.I.•e–4vÒ=ì£h§7ÕÊ hÎìNáöÇë:s»nPÆK7ê¨1T¾š5n}5 )b£dt~iwUî)ª$.|ô…¼Zä¥Cü6³æìl5QãuYæåÜ­B>ÚÑueÂÕ/*M»±*¯€@M¶ÌʦöEo¨k\h··[7)I¤(–Û ~6;‰c§Ž=v{ûמwQÕÍS;ÿlÿ wê-¹MFY1—Y^ó_Ì,wi“Dý_ÄÃK·,¹‰F;µÉ=„¬ƒxåK;E•R2¤óN±§J Fµ -8PvH¹§H›âà-öa¯1ªÜ¯äTiĈËÆGsÀ}غ¬µç@®žQŽ'r;÷ÎzjÙÚj#ÃW€ -‹¨„¦ͳÒcZ0D¥ê„o,qç«xi-Üæ… †—Ÿ²2‡wv-±é²±/Dà bèÌ}Eú²ä½Û¶[C&ú­…»j yÏ°vÌ2F‹º²x1&PD‰ÜÎè4¯oŠØxL¨+„ÁaVÖùú¦*Sƒç>Œ„`2wþôi¹ï8SЩu'8dnk2n¬MpÞ>*³¶™À£¶¬Á“8Ý<ð`†Tv475.½D¤äªgR‹ßaÑd«2nòOÄ®Ðr,dýˆÊh;³­£¦’uYjkŸjrú˜Öî c‹šîãÜB`>s©¾¾qƒ„)DBë!™ü Å!­ a»\j «@eå .«4¿¾óXSPU5å]PD…èDã¦o㨭Gšj„ b€ G„`Ñßé$„ËÜjóy{ÙfJl„tD¢vÓQ¶jâ¼Å›Œ/N§¿ØQíöÄö}ž»ëé:¥í:¥Y®ìŽ&þØ­ÞdInLì‘?šŠæ)Á -q†£>ÛÛËÚm'Pû#%†i‰"ÍÈCº kß3øN?ù¶]ƒk˽Ø}t¹a‡óNCëÎ2ÅÕ·³-5ERIÅNC1Š,cϧ'/.Þì‚D$!ÁY0Pø÷\ì5îû¸CˆIŒ-' ûëÛô†ô¸/A®¥¾LÔ‚H~C-èêÍæêºãJC:Äu¶G¶®7„èǃ‘i†$–ãæMõ_e/}LöB_÷ öúJ¸eH¬;úÎŽÏ^ÝÏßÊG#ðž›~ý|0ƒ“"ëêdßF;þeäÍý{´“þ¿9&0R Úõ—9&"—´ãØôtv?Åb{^ú)6tó Ø£ô¿B1Ç’¸ÁMQnùÛûï©HjÌÌ2¼ÏQ‹Ä®¾ÊÚ‡~–Ü|­…k3SŠúùop;b4€«¨ÑeØ@ÔÞGÓîû¥“¸þ¸¸:‰endstream -endobj -978 0 obj << -/Type /Page -/Contents 979 0 R -/Resources 977 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 944 0 R ->> endobj -980 0 obj << -/D [978 0 R /XYZ 56.6929 794.5015 null] ->> endobj -126 0 obj << -/D [978 0 R /XYZ 56.6929 466.6686 null] ->> endobj -981 0 obj << -/D [978 0 R /XYZ 56.6929 439.3642 null] ->> endobj -982 0 obj << -/D [978 0 R /XYZ 56.6929 409.8468 null] ->> endobj -983 0 obj << -/D [978 0 R /XYZ 56.6929 397.8916 null] ->> endobj -977 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F23 682 0 R /F48 885 0 R /F21 658 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -987 0 obj << -/Length 2297 -/Filter /FlateDecode ->> -stream -xڥ˒۸ñ>_¡[¨* K<ÉiãÇ–÷0®x&‡Ôz’šáš"µ"egüõéF7(JâØ©ÚR•ØF¿r•ÂO®ŠL¤Ú™UîŒÈR™­ÊÝMºz„µ_n$ã˜L‹Ìh ƒ…ÕM¦ ‘*_mæDþyóÓ;%W*Öªlu¿Î²9lÐnu_ý–¼~òû±>¬7*K³þýþWÚeD^äw¥p‚²°6lø¹ú⻲®hÇ›Û;ÞÕ~<êa¢ ÐÆ*¦`™Í×™¦irÛÍö™·è•Î*Ë;”ʦEØNÑÚ&·îß¿ûÁÍ€ß<ñ4ÜÕå“ïšaGÃñɼ޶ýבü.‹ðP¾Ô^{Bîˆ#&Q7·õ_ê«myÒoi~¬/hy¼^EJá²L…«|ë»úo€¨t–T~ôpÓ,yßÑÔa-‹¤ö}7Ô4ƒÔðë'ÉžÄ$•Zæ‚´Y:×â4RX£sFÛ†Cú]¤>Q2Ó×¹I^áD’à’‚_›¶%¨|ªËÏçÌuä>¨¡fä[£ôšžï D!m¤Í[°Ü3aѹ`](5‚Pëø–Êã„Ö4q¢ßU¯xã–¾ á8Ó5cãG¦ã/O¾¶$1©²Zä ïz´Ž4Ov=q@£¦Ûö‡8áúãH ò‚3¸³2ùԨЩRŒöŠHQ#$‚@Uå¡ÙŸVÊKF”Š\Êxz÷’Oj@Ó“õ3úM‡è7oïO+—\€Â -ë2‡‰+>ÎBØ„¿™o vfÈWt‘—»º<1c…âÕ%KS”œŸðXú}Fb(59J“R`cÓ1'¨ŠµL&màjã ‰MΘ(ÔY' -c ß·C¿yQQ`MÖéh&×ʈ -GID濯œ 3ßp-“kºgÊÁ«²rò+– -Ìg ]©†q~ÄÄ%d!ÄØ"¹_4Èt6ÏÍÿBže´=…б/û–nâ¨pØ×eó)MdÈÙ´Í@*28²É¨•d>¾{M€tΊK±LV¦¥tã?o~û=]U ž_oR¡]‘­¾Â @@­v7F*á\fâL{swó¯‰ D°B Ë%Â2-Ú—-ãŽsR›ÈÜF›ªŽ,›+dŠâÛ•ÃðR€Ë‚y9×·3gÖ„BC¦P•¨¨‰ë•É=ü«äí¥`€¦‘ÀšÎ5¨Eɬþ\I‘ç4!Íàpד ÂÄOïwjõ¦‡­f—Š„7sÊáRPÊÌcf.RX†¬DŽ19”Fh®©Ä9L–kùh­2Ì ¸òm-!t<*}G˜èÏ4õPŸ‘˜²2LŒÒCà8,œ0 ítÒù]]Ø$ˆòL{«z»ÖëŽíȘCÝU\´Ù‹ -ln¯·Ö&MN¾q& ÈK&s’·«‡Ás1d’p^H”0¨q@܆ԙ„JKÏÄ‚XÍH߶÷U¸øo&er‡®µ}nºÇ~UjPY,Ða!‚6}×"Áç,ÜÂia -1PÞ몧LŸ—&¥?† --/HØÁÎy&å»À®”N¤Vº)ì|O¼…p©ŽEÞ$P¤>ÙG~²­Y¡Ê  †¿3y^¦kWÔÀàÜ•ÿZtÀ8”9ëVÞû—c×yÀ‘ópÖmD4( ×p×b„âžãÍ3è«))êþ{_aøãdÚd]Üàöáë鳫ǧ>ØBšlƒ’p­ªÀf±è„J’*Å}ëK´ã°ñªº­Çi–K*-+>&¤ÙqQýsÑà‡gb,T&]E4a –°Ð’på2—oi€%,Aýö¢Ó‹þYU¦!«N[ü8•Ýz²püŒ°¡>'v^ÜÏ“(—êéRIm‹òIS`É‘5¥9Aã\Ýù‡é⻲=’œpÚ/Õ`*•Â`‹k0h+7Ç— ÈBúÈòX/€— -oQÈ"ú5QÚìû¶)—ª:kE¦òXÕ•-Åä…£¹ ¼>Å‚3eSojÍkâ -}FÇ>ŒÈ E?ngʛ̺­Eñß`{Ó¤p0ú¡†.[$.d2ÐèSš¥ßbà2Éq˜öƒÍݽ} ë’–¶=÷ò¸H¶³:M󿃲<ùøñîý/´L&Ë·@‚¦®] -–ýG[¨R¹b»ðŽàK¦`ý 4ðÓmpp{ì÷J0 F¦åǺ«~ F “‘þÅÉe‘<ßéuô…$ÒtŒ{„"ù\?¯%dCv¿)#Oý¡ùæcq™Å£=ø!zVl”C·ëc©Ž>ØÕÝÅ2~FÀEKO2Àþs*€˜ÆðXZÞGBXÜ~ÆI|`Ë Í°äz˜QÈy8¥¡åí÷uÌh0;äÀǺ¦îY»³÷h2rÛø£k—b …’ÄhF -f2€ïFt-˜¢~¶åônwâ-ú¬;]àc×BλÈs¤Hz ƒúÅå©9Eª;4UUw—iwÉIÎ’iÌœæšÎž¿“²‡§þØVÓcïb¢uÕŒ1tì|w |ON~™ ˆI›ÏŠ“<>Ú<¶=õeéQylψuhFÞŒùá“R¦:îöøå|`ùÉ ²ßí¡xšFCxo´ôúu†LÆ\Ñ€•d¹v‡™&nŒ¹òÒó&ï5:‹ÞëT¿$3*nô`ivŒOávNBÒá¶NË–OŒ?E“¡IS ýØnÀ -ö}eEÁ‡¸Ø÷ (‹| ÿÒû‚Î Cú_zv9UÝ'¤…g—ÔŠB¹|"…‚’îÅG¸…ÿü^KÄendstream -endobj -986 0 obj << -/Type /Page -/Contents 987 0 R -/Resources 985 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1001 0 R -/Annots [ 991 0 R 992 0 R ] ->> endobj -984 0 obj << -/Type /XObject -/Subtype /Form -/FormType 1 -/PTEX.FileName (/usr/local/share/db2latex/xsl/figures/note.pdf) -/PTEX.PageNumber 1 -/PTEX.InfoDict 1002 0 R -/Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000] -/BBox [0.00000000 0.00000000 27.00000000 27.00000000] -/Resources << -/ProcSet [ /PDF ] -/ExtGState << -/R4 1003 0 R ->>>> -/Length 1004 0 R -/Filter /FlateDecode ->> -stream -xœeU9²,GôûeË@@Q ‡!é¡%bd(dèúʤ—÷ÿ(žÑ¯ -’$¡T¬)ÿ®ïë¯ãïãÇ_¢ýþÏaíÏc‹®½Ú¿G—=ûÌöÓ1ÄF¬lÖ]töö×ãqu‰Ý¦‹÷5š”<8Ç—ý:\;âúãñ‰üéÆ&ÞЇ h—õ:ÀÀX=&02²oÒCó eD3PMtð1CrZûbœ7³}t€mA£d«·íä'ÐWŠ!è®»½KO(°ƒÔ¤‡tÙKb•^¦Ìì »å*’ÎÕBêFåmY¸™`Uõ´™Õ -¿nÜž í½³`*TûÞ£jg“¾=Ås–A½R?Ô =}³Ú§l -¤Ï’ÃigÙ¥—ÇáC6uéíÛ&”\Ê GTœ„Méêö–KòlÜ’Fyu|?é%åiÈ¥K”êNÊq{vˆ*êèJE¢]8hÍò¤p0R±ˆ$Á(+Á nÖN¬ -qª„Ñ«ò^ÿï>‹«>÷— .13×…Óƒ!¶3¢SËAÕ”ih¥Å¨Š^…(€<Îm䦽ªšÛÆlLÊâ³ò7ÙaÆ´Ëdô 6(WðÚºK -г2"ïE9~  -n*Œ1½÷¨¾x¥Æˆpîâ‹&XîÃœ§³±è\íD¤ßä0}#XŒûž˜‹¸À>#^V°¡|2Îi‰9ÊÎr)`˜¢Xh¡Ò& „hb—H°Œe"Ãêʱ„£~Ï“a³tŒºìZDß!#Z¶ÚÂk! e'jÝ=§ _tsÙ¬ûÍ&­Nå@‚i¬ˆ3t%kÐE„\H–YZxÿ/U¥Ç™åë—Φ@±¯iW H -þrÓGçX5¾ûû8‡´ÕªOª«t–Ô³$Ây°‰—BÒ›ÀÄ5©/¨vp÷o`kA“ôr ±ñœÓ4N.4Žæ&F°ÑTÆG%V½ Î'ÌØR5¬BÔ‹`qUžv-UÍ=ëÆåQv2ë_ ”¿­qq‚~èr¯Ú5ÌJ¼ð˜°h»P¡õ‹kÜàéÚýªå>Ò¸D °o»Îi¸CrT]¿MJ¥ ÆÖ¹’°;¿ö‹ûóZ¼¬ å[Ç-œÁ¤ŸBx¿ýpü|üÈÂendstream -endobj -1002 0 obj -<< -/Producer (AFPL Ghostscript 6.50) ->> -endobj -1003 0 obj -<< -/Type /ExtGState -/Name /R4 -/TR /Identity -/OPM 1 -/SM 0.02 -/SA true ->> -endobj -1004 0 obj -1049 -endobj -991 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [470.3398 482.8902 539.579 494.9499] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> ->> endobj -992 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [316.7164 470.9351 385.3363 482.9947] -/Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> ->> endobj -988 0 obj << -/D [986 0 R /XYZ 85.0394 794.5015 null] ->> endobj -130 0 obj << -/D [986 0 R /XYZ 85.0394 769.5949 null] ->> endobj -989 0 obj << -/D [986 0 R /XYZ 85.0394 582.0558 null] ->> endobj -134 0 obj << -/D [986 0 R /XYZ 85.0394 582.0558 null] ->> endobj -990 0 obj << -/D [986 0 R /XYZ 85.0394 543.4475 null] ->> endobj -138 0 obj << -/D [986 0 R /XYZ 85.0394 324.8439 null] ->> endobj -999 0 obj << -/D [986 0 R /XYZ 85.0394 292.4184 null] ->> endobj -142 0 obj << -/D [986 0 R /XYZ 85.0394 174.5048 null] ->> endobj -1000 0 obj << -/D [986 0 R /XYZ 85.0394 146.6189 null] ->> endobj -985 0 obj << -/Font << /F21 658 0 R /F23 682 0 R /F62 995 0 R /F63 998 0 R /F39 863 0 R >> -/XObject << /Im2 984 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1009 0 obj << -/Length 3382 -/Filter /FlateDecode ->> -stream -xÚ¥ZÝsã6Ï_‘·*3k$’¢toénöšN›î%¾Ùn‰ŽÕ•%W’ãõþõ >líõfnüÀ/AàrxÀ/¼V±§Qz­Sé« T×ùî*¸~±¿]…L³rD«)Õ÷ë«¿¼ú:õÓ8Š¯×› ¯Ä’$¼^¿zÒþ p¼û‡·w?ß=¬o´ônºYE*ð>þòpGµõãíÃÓû»Ç'j~ -Tpÿï÷P†7+¡eä½ýáöÃúî‘Æ%s½}÷Ï›0 ½Û‡·wïhèÝóxw‹k­ÿñx÷tóÛúÇ«»õ°©éÆÃ@àŽþ¸úõ·àº€ýÿxø"MÔõ¦it½»’JøJ -ázª«§«¿ '£vê¢"ÃÀD-h2KšT© BMVY{&Þ‹ÍE©÷µ©¹VvTöEÖ›‚Klþ8˜º¯NVE 1DÞ}Ýõ&+Þ^¿µ\¯8ìös~…©²“ã÷|r‹PÙ7T†ŠÊ]YzÓY®Â˪ª9–õ eEQöeSgž¨b†~ªTd÷Ebwtd–-–ÙgCµ}•åÆ&j?•‘¶ÿµ55. ¼ ‹ØëLûjZê¢M(ÔÐõY˪‰½lÓ;ªŒŠn{è‹æÈÜš–èò6ë¶vCWö4v,«ŠF‰1Hw¢V¤ò~o-nÕ6>ATšA*Ñê¼i÷M »v4[& *â³mdõ‰*s­m³Þé¯ù<ÑOâ [JŽ§ŒÌÑ5ýv›Õ/—‹±n·Éæšµp›;²jù Òjg¶tßfu·1-¯A¦îį:¶ -VmeOÒ2e -*ºrW¢—ØÆ1sV¿°¡5©A D|Ru7ê,Nu¶+󑶣þ<«ë¦§îºiw Ó‰Fž™±“'1#òè-º“g‡ŽIáLxòdÛÈ·§Þ—CÚé ±hG 6’7 W«4æcNµ·kì1§Î^sÐ>µÇ­Y>0Œ|Š"MÝý¶±BBç(4šÚn(.­9YîH™²Îg³ÖyRv è0uwà…f[¤X21sgÆ£ žu:¾Á.&§8QvΕæØScN(ÜH{“x‡EÀ'€)éë8LAb´­ ^­ë›=ÓO^F¾AÂäd¢¨?HÁBÙT;x{I´wjTÙf¯(^’Xг#°L¦ç 7œõ¨èc-ØÉõÁš/:Ë›éiÂœM39ÐîÉÁsSs€nE¬5íç¿B˜I”÷®ì²çjñIDŽ@&BR4vZ°BrâСC1.UÆS“$™©§nZc¾š¡Ô4ºBNŠ'Ø.O(~Šy;¡•u¬·hÈœ¶Œr:aã[ój¦›Éä¾ëh‘NeGQÒP»U~¯«%QbÒ 'Š³s\ñÄšŽ S?I1±¸Œ¬Y"ž"8ïŽÃ_4ú§ï®  7¡u9ÆŒ2ô—} €ƒHu<÷Ë.;.ƒÔ¾Jý'ÇûaºÃ¥0±¦«&+Î&û/Î¥'Ü&®L=˜æ*ÒÒ‚ œ«nl¢þ°éŽM‚¶A@0mi÷=¤»7«øAš•·³`÷qžµõµyě廗z€e¢’B9 _ÉRTM„KÂ!ªRÿ<¥Æöç¾ÉžkffÔ$€†Ê¦a&]ÅðpºÅl‚³%ê¡6ž ƒ:³7KÈPRnŠ*QŒâ1§Š‘8ž.£\îÝ …rŒ¡Êª6Ò.ä+U@µ³íÃ||H÷&/Ñæ)æÆœi(ïñý[ꀀ²œcïɘóÛ…ŒÜT|­G Æ4ŸÆÚ—kªœF£§!ù0öQa” “œûBoJ´œV!uߛݾ§†M ¡´W&¤cÇÆ®.m¼BÙÓhÉmóe_•y‰ï¶]PJZ€Åj8'k±Ø¿k–î ¾dÏÍ¡§*ñ#3c´yC#1T![@ZÓåm¹ùØèÆ É@}¤îdZ|Èéú•µ”Ë#RÊW*uG”W|·üÓU”ö!k“<ŸO.Ù‹ÀC嬵ë_0ßẊ ø€EÄ2=Ï‹$çEOp&ýøP÷g©Î“éÙ”$ð¦†åè"öÜðJ‹Ý¯¥9"ž TÛ³µ}]ù\Â’ÃG°Z¿·ØŠ}3ÄJ··Ï&‚ßk°3t§¨0¡0_ú›ÐF´{i*ÊŠìT.AâìÒ,Ø -U, -JÎt…Gð‹œwúÞý@E‹Ó+/ëUJ?ÑQ2vØs>¿£Ÿ]kl ƒÝÐk–dY³®©;¯¦r —¬.¿:WÞcs¨ -" •âƒ!N¤g*ËN¹¨ÌwH#'¢¯í³öш­6¬ßH`ðT…ö~hŽè­.?N´Sr^£‚|•À¬¬(­ºód¶aãF"&؇­ÉOº×8èvöH­ÁmÃ=”¸¡Ó…P8_Ì·á´Ÿ•I7/$hjÈÆÙI m¿Nð*”<1)fÁ´PŒS†ùFhr¹. —Æ,õD•|ÛPV¬ùŠ åÁudT8ä…*ûôH»çíг«›án:8ƒ®ÚSF/–iC% ¢©6s†ßøB~ÐÞ 06mU,¢âmͦƒyꀌ"ž##Œ2Šx‚ŒB2º„:6.ØY-=€$†Å5]ÒlҶý0D]Ó‚`>vDƶ…K ÁºŸÍ¶¬Sû>ÕSÜ RÉ8h¯íˆNa&ŒuèudñÁxÁùaBˆ k PX4ùS G»¸Žût9"ç$C Â8xØßDF ßø x–CÙ -9ÐìsÉ3ÛásLÜC¶;e/hÕÒç›™E=žÍ?¹ êÜKüä8UàŽs’"ºÃ² žP~(¥Ë ýsÃ;B^~:_ؤÍZ¾‘3JŸFåO¦ÿÎ^À3›ûkº}h´ù=˜' hÃÅ™î’g¹U(@^ºÇL ­@|Ú󄈥¯¤žiU°ðâ+|j—Õs ñs -õç씯•P#¿DÞfno.5ÃÆä“"u%½©§Î—h¦µ»Ô¢=~Â"*•ñùg8J=x&5Že¿¥ÚÜa°Ç)ì‡ù㚦0|ÿ_µrˆUp[¡rR4^žv˜ÂgmùÕ-ÆWx[¶ï~þHwö%h䂌٨9 ³åBÊåg#Þø›óÏž.ÿ^s¾áû\¥Ì¬ë •Gë2ù¦u…~¬¥3̧íÝ"¥¼YDÉìž’NRBþZå³!R’z:2‡& O‡·ù ¯0?¾¹éH=¼áŸS¬9©ç/MÖˆD¬½½i¬¿c²;ÍYvÐaarGô~‹ÝèÂœäi÷õ%ÖƒF Z•IByy?‹é–ìÈ0Ïé=!N†ÑÜ´öÓêâó­°âg 5>VÍlföA›¿ì^XÐ@\U ì¬ó@Ü¥?ºäâ¿S^uƒœÿï?ÁŒ’ÚI-?G:ñeLX(Ôd\Hîþ-s)úOK¸Pendstream -endobj -1008 0 obj << -/Type /Page -/Contents 1009 0 R -/Resources 1007 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1001 0 R -/Annots [ 1012 0 R 1013 0 R ] ->> endobj -1012 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [464.1993 519.4233 511.2325 531.4829] -/Subtype /Link -/A << /S /GoTo /D (proposed_standards) >> ->> endobj -1013 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [55.6967 508.4843 105.4 519.5278] -/Subtype /Link -/A << /S /GoTo /D (proposed_standards) >> ->> endobj -1010 0 obj << -/D [1008 0 R /XYZ 56.6929 794.5015 null] ->> endobj -146 0 obj << -/D [1008 0 R /XYZ 56.6929 584.989 null] ->> endobj -1011 0 obj << -/D [1008 0 R /XYZ 56.6929 551.635 null] ->> endobj -150 0 obj << -/D [1008 0 R /XYZ 56.6929 396.4263 null] ->> endobj -1014 0 obj << -/D [1008 0 R /XYZ 56.6929 360.8629 null] ->> endobj -154 0 obj << -/D [1008 0 R /XYZ 56.6929 173.1662 null] ->> endobj -1015 0 obj << -/D [1008 0 R /XYZ 56.6929 145.9427 null] ->> endobj -1007 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F21 658 0 R /F55 970 0 R /F39 863 0 R /F48 885 0 R /F47 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1019 0 obj << -/Length 2880 -/Filter /FlateDecode ->> -stream -xÚå]sÛÆñ]¿‚o¡2æù¾qˆŸÜDi”‰ÇVÛLãÌ"!‘5E($Yéô¿w÷ö8€ )5Ó§NÆÁÝa±·ß_”˜pøOLœa\åz’åš.Ìd~sÂ'×ðîÏ'"ÀÌ"Ð,…úÓÅÉËoU6ÉYn¥\\%¸ãΉÉÅâ—é×ß½~wqöþt& Ÿjv:3–O_ó×S!ÄôõۯϾ¡Wß¼ý@‹oÏ^Ÿfzzñ—÷gp"œ6¾‹_~x÷ÃùE÷ůߟœ]´”¦Ü®ÌßN~ù•OÀÔ÷'œ©Ü™Él8y.'7'Ú(f´Rñd}òáä§aòÖ:&£3Nf#â‘jL<&gVÁ+Ïùæt¦ŸVÛSᦋr [žO›ŠŽ‹ù¼º¹]¯êe8_®ê°”–%!D±y¤Vë5×eCGw·áÛ‡€ÞÔtT]Ñɦ¸)ãWÛûr[ƒ´µË§?nʲ€V—áU8@z@ “™,7FzW›zµPéàšhØ~‚M–O?rÃWzáyÁ…—Bé‰XØù;zSßó¾´-6á}ûi«m€Ejñ%Q‹G—jCo.‹ºYUáúeU7(Vé²éÃr5_†;ˆÚ|”Rßúƒêó#nƘõˆÈ:›eÑÐj^lÂQ±þV=/hZ¡Â—¨|®"ª ¶á8b󌣼ù;k‰ÉXž92­ o &ƒ/šr»)Ö´ Æ‹ê„ãË<¯69—×wÄü‚N½=ÂóªÚ>X„ ˆßÿvWnW¥7N§§åçyyÛôÞ´VˆyâÊfLYk€¤¼^5¥`-Ù¾ïJŠYge1‚q¦`Ü W¦ -BÌòaΘȄìQZ~.ÀIKž8‚RpÁ¬È[”3‘ýîâ–Ž­¥bOBîØQ]ZZ² Á¢U:ž¢%omgAX$S™qQj"ZR  "ç‰-á®E‹²%\-‹ûî£WÙ”¼ °hã„ ⦠WăqûeZ8ûl©'‚ÙÅŠÁZ‰Qai@È6šÛ¾ í¹t4ÿN›+’ýMÀÉåçÈîÚ,¦ð7_ß-V›ë€ßç -¸ K{ñƒ©CºäÜé 0u›)ñE›)qã x6I{)n"•e  #Ù1UÉýä>/ß]®WsŸ”ý‰ŽdhŸ\Øc¼…kCµ7Þ S’Ù¼õä½6k3.žÉÁs€…ðÉïÕ¦ôe‡Zª>$[‚|îÖ â€T\Fv@צ¾£FL‹ºcÖ¿BáÓÉwÊÎðe¾¬º.3°s3Rë(¸ÁRn,@ª”û2ûjÄyñúœeR8ý—ž&†9ÎiË´2hÞžÎ,'ÌøœžÑR{u?qúYDÚ‹_oÑÀ”2¡/§UùH«bºUX“zqå+ï0Ëb}ÎÂ,ݧ\Ú­6-ÆxЖM°ëúwelÔ•E° “\†ªÈX.Æ\Ð×C<Ÿ~Úx®xNþÓŽ¸ëüOíë¼Wÿ¶…àL;KÇ:ý–íª‹F:¸ --Âm¹]ŸŠé£ñùÊ[wÓª0á©Ö±Î$žï› í8L=t?/§þ`%ðHiž@ù»ÇMû~D‚Ô´…yå`zÙ²w‡4×?µ•¿Sƒë…1Gáï …Yœc©0ÇÂP[?$ß<Ò³-öú»Ú]æq|Ç]ê?š¤…@ÌlL3‘ÂÑX˜D¬(÷Ëb`ÕÝ>¹·’ì ºÚ‹¢ã Z³„TX3n‰QaB;&l0k¿ªè&•°º=õU@°˜¢q·–-¥JÅ °óõªÜ4UŠ0ÑBô^LøÁ®…¶PÆ«ç‘‚œNGíPp0åÚ¦¸Ú¬ÇꟜ9«bQH²IóK)ÇzO»]Õ>Éàƒ1‡ÒÃ{u*˜=ÖõÀ-Kû ¿óh÷«"^·.çÍê>@¢lÖ@n¨F,!D×qõ‡üU1`{ƒ)êHPL°43Ơб¨ç]ù “1è`cU{F))dòóÍ|,1AOåG,FcÞíÇ™Î|úŽÊ£N€ÅeLÑMõÕ¾_ATÆ¡ô"þ¦“Bù- )HÚX:•à¢nAdÃK±ÖÎ-éà­-ÔÊÖÚö¯ý*GbšÊF NÞ‹—ƒùHK¢ 3–«ãm¾ÊœyBÛ¥ŸÙ“w¶ßæïÓ ‘Ì"ða &P4¡ŽkðЭ‰‡×Žk0½ö©Á#3A‘Y÷Œú)cF@™÷ÇŒû©4³J¨#ŠL (2BWä¡[E¯WdzíÓ¹¯Ï½LËf¿¬„eÖUt@R踠\™Èip縘’;ϺҠqŒ?ûu?öóÕg†§•榲ê~@·vÐÖuõñ^Éï«Øž”T¤ãÌæöˆzR¨ýúi¡Ž*èà­†v®UQïÚÿ¿¤"­d´á‡ØÐ_:®¾W&ÚÜ9®¼äÎãþº¬6å“ôy -ªºìIú³ÏÎ$ÿ¥þ08Kpó<ŸÞà3hóešf8™Nf8°i ìbÂ/­xN¥|Šýï°|Gÿô?ájQÖóíê’þ,®º¬îK,ú˜¾­š2¢*š¸ŠDŧïQúÍFÇoE×Ø%?¿4 ½_ŽÓp·Œµrl->VwÑï­ø^£Œ¿º,‡ö¬…cN+7‘ P…ÿCz¹½žÐâ}bÚ-ü,ý`׶wñ¢ >`¹RLìPc!âä}bv¼+£`ˆ+ùiXA¸4Æ Íy/_ ºö¾à÷Œµ`Î9* ‹ùšÆ|1 Ö´ýWfàœ–ÁÿùK©_…Ãéá¿_E›¢1 î£é´> f«Ûzv]Í–å¶ÜƒŽrFu‹à-Žt’Ùk¢cc¾sLÐ40YVô–W |GXAÀâåK:è¡AHù¦]:ÝbêQ8*½= -Ã?1>øÿÇ×%& ·srÜŒ·ÌÉ<‹D!/rÇqÚ?ØÛ%ý?mwendstream -endobj -1018 0 obj << -/Type /Page -/Contents 1019 0 R -/Resources 1017 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1001 0 R -/Annots [ 1021 0 R ] ->> endobj -1021 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [417.8476 228.9788 466.5943 241.0384] -/Subtype /Link -/A << /S /GoTo /D (sample_configuration) >> ->> endobj -1020 0 obj << -/D [1018 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1017 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F39 863 0 R /F47 879 0 R /F14 685 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1024 0 obj << -/Length 837 -/Filter /FlateDecode ->> -stream -xÚÅWKSÛ0¾ûWx8%+zÙ–Ë)…Жé0”¸½×Q 3Ž,‡W§ÿ½’_±‰œÐv˜ ÒZúöÓî§2¡üC¦íÇÞézØÙf87 y#¿}2P¹ÆªYÍU}cpB\ÓžƒÓŸ6°€Œ!ÓŸ\ö(  /`o|þõ‹ß·° {Çgã¾…µYïèóðÜ]öjéðøG!ÔžŽ[Ôàd4ì»´ç¿û×þ©1òk¦ÍÓ HÍ;ãòšy¨Sâ1Û|çasnP››RY"cl|«_ó­Úè 0q°.<^#< J(×ö€C0ÉÃóûPAY϶qn ¢(y°²4ˆÅ”§}Ë°÷«ø'1?,†r¯ÜEåh0(,"˜/"^ŒuWІqRŒ%Žœ¢n÷wKž>µ|Ï⌧q‰’lÏ!â4ø¤\dé,ÌŠY0C.DÛ7jøNy¸LÅ,‰7úWþ\Öéo¢9#`“ÙÂxÒ6¹U¶ªÏÊú,CYx<³Œ#Àó<€0™Ô@wdjˆ¬ÊPŽ¥|T¤Zþ³§EkV<ÓY|0¬ÒïIÒ‡ ðT´ž+Œ53:I*¦ó *Ó"™Ùì¾ Ž]*%ϼ6óF†’h™Õ™UŠ\a–‰+ÙÔò´^b¾Y¦ûÝ9îrZÚí¤¼¯FDÜóý$’oÙ¦1X§£ÝS®-äb€ IGhÑu½oñùßYE Â¬SúîW¹ö°ç=î,µÛ#ýöÈj‹µ%úë²K`ñu]€Íq}úÿFNþYJ'²EYu/Ò‘M•ŸZ3*o_Ñ“©*þS†(/ëÊp›ˆ,/ßíÞMðô^Sã0‰¯ Ä7 -g­Vé…³ Œ´QXK`ZyÊÈjõb«áë’Ò‚/fͺI¬[žò¸¢($ µ\l­[:×·„ØyÏ–p³.ƒø©éÚ†Í^Oƒe´[ó·Vû­0oùÞí'Âí`pƒÝÚOL÷mGwƒîCl &š ¬õöæ÷ÏêéG]@ÃõÓ¦U°Ëe¤$¥¨c¼Æ¼z(­SÿÖ8Å.endstream -endobj -1023 0 obj << -/Type /Page -/Contents 1024 0 R -/Resources 1022 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1001 0 R ->> endobj -1025 0 obj << -/D [1023 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1022 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F23 682 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1028 0 obj << -/Length 2146 -/Filter /FlateDecode ->> -stream -xÚ¥ÛrÛ¶òÝ_¡É“4 a¼">¸‰“¸—4'Ö9/M'‘ÄT$^ì¨gοŸ],@‰2ݤSkÆ‹ÅÞwA>óáÇgiÄü@†³D†,òy4ËÊ ¶½×ÜâxÉ;Åúayqù*Hf’ÉXijåú„VÊü4å³eþÛüÅ›«wËë÷ ODþ)/‰Ÿu]^&ñÕnWß{]£ªv­›]Š -.©Ô®ýŽÖúËxmÕáM2ûMº“ºú}Mþö’îøKùI•íHpUÕÝV7W°WÔÕÇmÝvKuXé±äþ˜½¢ÊIMŠM^¾'<ú'\@ðXœ›Š¢Ø&ä‘3‹¨…!n£Ûzw©Ö„㔉0ä÷ƒùuC´õ羸S;]uå«Oî5«2Z ÞB‹žO0æÉÙÊ’˜+[­šlKjaŒM)ºR¥nusç”ÌÁxÌ࿘2ñãèÁßC­¾øŒ‡,ca- †ùCNX÷ýcÊ{h8!ä’v¹-À÷DÏݨhh·uÓá4šoú"×íj»«»®¨6´è÷4.sÑûTfm@à¢R]ß,x:×ö -´ ²gíW€Ùtn¯8§Ðê¬oŠî`Ù´ÐnÞ¾d4½é¦Ô˜ë6kŠÞðhžmUµq ÃŒè6f·®>ø¾Øô¢‹ˆEPöä½ÞíÎ [ÕM\¡HbZÐü—&9A×èÙ8É‹5Â1hq»²ôÖú¨¸gS"U¶ës²ÃiìÍ¡:ÓmkÃdMcFÔTw<3Ò6þÐ{HU9Múöqô¶ØŒÍ °û¢ÛÒŒŒä8OÁmá $ðZ”ª)vZ¶ý~Ž‡”’˜|ØÀ® ‚ œoLb[ð9c0fYöU‘S‚iäü<‰­Ò ¯@‚ -‚!æò&tÏ”Š9¤áb}0-ǤþIC©oí nÚXJô¹×ͦέÇVBŸÏß›ügr>î:×Om6ƒ±Ò÷F˜"HaqSß©f) [åîÝ%C“6A3&’aZœÕ’ᮨl–­÷L\Ø&¥¨ŽhÊŸzœ†»IEC#Â÷#Ë!$â)IcûIlqر!pRPGÊQŠ&Iœ¸Î€qÛ¼Ö•nŒ§#;·[Õh+ÞOCú_;‘®UfÓù;U4cIÞ@‡Õ>ÒeDL$Ij‚bV ®µ-H[ADN -ðeÏ¢™˜…¢“Yéî^ëŠØOŸ– XøÎèØò nEȤ/ϽgL _|qzBHL÷IR9XÞžð*bS5«Š æ<\¢}Íû½±üÐ×ÕsêÉô¨>‡îy”>q<à Ã5&XHUKטpB7à¬ìÛÎ:§>kÚÉÕöUíê8ÞѲ ŸÅg@ÀÒ4G¼ìªïêŠpFD¬ÓaëðU‡!b¬ø¨±­¦< EXÜØ‹álsôgX)¸H=Ð8-°åä1ÍW‡N»ÖSÎßürõÂûåeD+Òiitm¤½S­ê;SÉâdþs íÞdAµM×âµ;i0"ª*¸cºmê_ÒÇNkÕ…:ŸÔ6*GŽd8[w¹3]©p•'¥úR”}9ÜAxOmŒ™mÁˆ#.,ÃE‡/D!15ñÚ‘¬/©á=¦:× #x\^@/Ô¹„slÉx¸µ±yŸÙ“Š†£a­“cƒf½3LÇNEÝ 9U^µq<8þBo+OѸ-Uæ•yd¡+ûò©Xô7¿Þ.í“Ø›vçӛɥ I˜UKNÏéÂ&öÑñ°~ɪÃð0þ锧ðš{êヶênº:ó4bxý19…GÙRtI´Œmd»eJWët,‡Ï°›³}‘€òU’²ˆË³O'Ø3yqh_òUVçÎÚ®ž§ÑKLjSAªHW¡d=ŸÊÅæ³k[ )z9uþ¨¿@V·\“וgéÑ=Ï^Fî”jG.zZ¢Ìz¨t“Ÿ!x’0žrì5F0ãm?«Ëëèŧ×òקuË?}ö•ø”_}ÿý·zÞ™šÑk$˜86zãN ¿F|UÕõu,?jŒ=öáºüÚ:ñ™Õú¡üQ÷ø;L NÅð½v¤‚À©ùµL¡"DpÎùðõ÷!ëÿB ,endstream -endobj -1027 0 obj << -/Type /Page -/Contents 1028 0 R -/Resources 1026 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1001 0 R ->> endobj -1029 0 obj << -/D [1027 0 R /XYZ 85.0394 794.5015 null] ->> endobj -158 0 obj << -/D [1027 0 R /XYZ 85.0394 479.27 null] ->> endobj -1030 0 obj << -/D [1027 0 R /XYZ 85.0394 444.0186 null] ->> endobj -162 0 obj << -/D [1027 0 R /XYZ 85.0394 287.5734 null] ->> endobj -1031 0 obj << -/D [1027 0 R /XYZ 85.0394 259.9325 null] ->> endobj -166 0 obj << -/D [1027 0 R /XYZ 85.0394 214.4637 null] ->> endobj -1032 0 obj << -/D [1027 0 R /XYZ 85.0394 191.8161 null] ->> endobj -1026 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F23 682 0 R /F21 658 0 R /F47 879 0 R /F48 885 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1035 0 obj << -/Length 2336 -/Filter /FlateDecode ->> -stream -xÚ¥]sÛ6òÝ¿BÓ—HsŠ‚—éƒâ8©{M.W«÷Òö!‰)E*"G×éï» H›¶“ëxÆ‹Åb¿b¢C&2™DIÀ4z²Þ_ðÉÖÞ\™{¤yëåòâÛ×*š$, e8Ynz´bÆãXL–Ù/SØÀf@O—7×ofs)d§—ß/Þ/¯~‚©æ€‚‹Wÿ !¦‹w—W¯péÕ»¼¾ZÌ¢`ºüù§«›ÙoË.®–ý;®,s/~ùO2¸Êœ©$Ö“[˜p&’DNöVLJyHqqsñŸŽ`oÕm•‰àLªPŽEŠ1¡è„…JªN(‚ÉÙ\pΧoÓ²M ¼çSšcÚäUio ´TŸ .•åÎÀ&Më]zœ‰xj2;§µYã¼Áõ¼&x¾?'„¥ø9¦eVíý¶­)×D´Ú t•7õs| -‹UæÉKÄ[¥µ™‡V‡ŠëéÛª¦C7—××D¸9æ嶦ƒ‘5œ|J‹<³7µw‚%Zã݈ªÅŠ‡û嚧uÝî„Ë—CaÊm³C`^÷îO÷mÑä‡bp·xJôA/Q<11æ€knºṉ&ìþÚÚdÀ‘ ÕÕ€¥¸¯šÁ-Ñ9Ší¯Ó+ƒß½3 Ç̶h&c±˜)ŽØ¢¨+ËF$Ü¥Ãhú{YÝ–8DâO;¾ÇYGqÔõŽF)ÌaW•†æ¦Y?®ÙéF‘n®ËMuÜhÇ?¡oÂÄ ©¿ú/sz6Ó Hœ^}ÎëÆŸ'£ëõ>Ý‚.1èç9C$¼ì â‰r2`?Z0εC™îÁ‚ÖU¹á=”L†¡—ůœËÂüs„æ<‚ÅI®¬ ½†Tí†ß ÀlÀÉznÿK†?œz cZl«cÞìö´wŸ®çûL¿x([·¶ˆßü˜~{¥/?¼Iþýª>òT~Èß}÷ nžöç‹q“êßÃéCqyfí¹UTÐñFS«‹Öx|ÌKŠ ¨nÖÁ­þ,|uBðËëw¯‚ºÓúYÆ.Œ7¸Ò%bsU}2lÌÑorW'¨0*Ž^HlÃ7µÝ;Ö^+‘Ó¼éãé)®®+›Eœ!"¹”Ð  pÄòTO"V_dyŠv#êŠx.«r~[ :I³tUÇ«r Ù¡-Ö1Û@u«¥”w²MN·iòOf˜ÃG¼,ÅO ;í³ôÒÒfè¾ ƒ¢íh¯Nc¢JT©Ñ—H -êÓ(êܵ>WP s!ã;•†c$$ÕK 9¼ÊËÆÅv_ûÀ²s[;ðX^áÛ2ÿŸK7 -r¥mÓd-Äô—…½!ª>.Ù14 sÚ˜zRunýŽ|[¢”"ç'CÖ-—¶ëx>œÉòK&;€£óÍ Çä?; m(/Ú, -%Øõæ1$¡#ÂR»^Û¶(Nçc¬òMæBBt&ƒû!¹—õ]*tM;^ÝcT?æÈþö_šƒ.CEÙ‚µ?‡öþsmîçå§S°2<¶|Ö8JÏL]\™æÖ˜'Ím…›0h·‹¤¨n°>åwfeÇû¶nþŠV›ª nwžü,5•g¿¾²‚zÊFä|yvnvfÄÉ…P„êÿÍľF8ŽÕ:‚©H$OÕ:‚é(öXTãåwk±ë÷ÝÅÈŠÏUÛý“cˆGJö«,ùd•åE½9´×LÖ*,Ô:æf¯[øí”Â{Oí‘(P^üùw«†·çÖ5JèH•¦'­hé@R5Šmuß6¸D-ŒP°ÝêþXÓº|ÉXUú¸ ˜wsàe•¡eÕ \“ºG€¦%w.Ü#‚í ª1Èßðž†Ù3/)Ó¥ËùC™òN_Œ Þõ˜u%,P±zº„Wô%7È5s—Æ,c5Ðe™¨KY=·ÀrŠSdöckj’”óæÁŽžG8)g5 θ͋G+Zîr›[um@äS0€êƒYS"¡„®XsýhJrq2üªf‡Ø´íÄg`€T‹6ÑÕ9˜Âêa€;§jîo~ÃÛE“.Þ5.ß¹ÑàrÐa€N÷VÐ3‘uÛݳ„4PCeÚàs¹eÖ}wC@^Žµx«aðdDÐg]^Zåm[ztÀ.h»±æîö# 8X]äöçöìÑ>n!p$fN ;ëÅ Á‚ðÍÈ=ù d,ÈTÅ 8Uaaqù#2c—ËÜšéž,/€6{r‡°\ÎO} ÇÐNt…Ãf„R‘( uÐññ4F%ò£+>ŒPmøö¦±¯^ß2記I‘ЙšÛ(š`{Èì äÅ€‰È‡Åíˆb# ܳ6H¡îyF+Ÿa¡Þ¥nu»+^íÈ|n¨+¶ø$ ¸DƇ­ií—ëÊèíÇÂl[°!Ø-=ì¹q-3ÉM6*Á¢DD÷J4íAÉóÀ/3а۟SF~GáËýí_mÎ?SSq,Ï?È \?ŠYbÊ^F÷8÷?ïÜgý/"óendstream -endobj -1034 0 obj << -/Type /Page -/Contents 1035 0 R -/Resources 1033 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1001 0 R ->> endobj -1036 0 obj << -/D [1034 0 R /XYZ 56.6929 794.5015 null] ->> endobj -170 0 obj << -/D [1034 0 R /XYZ 56.6929 769.5949 null] ->> endobj -1037 0 obj << -/D [1034 0 R /XYZ 56.6929 752.2692 null] ->> endobj -174 0 obj << -/D [1034 0 R /XYZ 56.6929 663.7495 null] ->> endobj -1038 0 obj << -/D [1034 0 R /XYZ 56.6929 633.2462 null] ->> endobj -178 0 obj << -/D [1034 0 R /XYZ 56.6929 587.2939 null] ->> endobj -1039 0 obj << -/D [1034 0 R /XYZ 56.6929 559.4406 null] ->> endobj -182 0 obj << -/D [1034 0 R /XYZ 56.6929 362.928 null] ->> endobj -1040 0 obj << -/D [1034 0 R /XYZ 56.6929 335.0747 null] ->> endobj -186 0 obj << -/D [1034 0 R /XYZ 56.6929 132.2109 null] ->> endobj -1041 0 obj << -/D [1034 0 R /XYZ 56.6929 104.3577 null] ->> endobj -1033 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F47 879 0 R /F39 863 0 R /F14 685 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1044 0 obj << -/Length 2916 -/Filter /FlateDecode ->> -stream -xÚ¥YYsÛÈ~ׯà[¨*žÁ`pÄO²%¯½©õndnR[ë}€HHB–h (YI忧¯ÁEÈvUŠUœ»§»§oz¡à§© ”É¢E’EUÚ.6û3µ¸ƒ±δÌYùI«á¬×ë³—oM²È‚,ãÅúv@+ TšêÅzûûòÍ»‹_ÖW×ç«Ðªeœ¯l¬–—ÿ8×Z//>¼¹ºä¡Ë¹òöêâ<‰–ë_¯¯°Ge0/ -bY¹þÛÕoç¬<»Zwü eÐÊ sŸÏ~ÿC-¶ Êg*0YjÐPβp±?‹¬ ldŒïÙ}<û{Gp0JKçtbMØ4Lf”š9¥Ø,ˆ ¡R.*–µø’ﻂõ-—¹ æ»]ý¸:¶y+3¶es®Óe±iËéz¬»-WoŠ¿¢fàP²Áþj±2a†)ï<&+µüO\¹¯]«WøÜó꿯˜ðH° áõ}é|K}ûTåûrà ÞUFÚšKwÜlŠBD¨«Ý×JQF{/‚²äŸ…kEò\(¹ò®òndyÎ …àÂOù†‘ˆ£â˜LÊÂA)g¤…Sá-¹ e2’¤Y‹UÙÀÆQ¼Ë ÒÄ°üvž…ËúÈ ìó'/AÕŽ•ÁBæÂi~SÛ‰ö5ÏáÖ¡~,šÛãnFžPk¨áU¿:Ô»ró4#O \'&–Ù®…ÉûÂsWVS‹t˜(ŒqbÀå€Ø>6w ®\œ¥›¿.8u–SºÈÎG4øZ¼"´°”Æ -u6béÄk»Yßbä„2tzFåZ8˜ºŠ” -²4´xøAñT° >_iþsÕ4uãæ](Ì‚0V‰¸«N–:ãzS8WVwÜGÑAÇËõÇ÷?pOg÷PßÃÔüŽ| Z -!0™mÅw-”•,-Š&ßq£hx»Æ¿‡Yº|Ëù³û5Ç»8¶è!;îWVuµ"·A;¡ ,C-óǼ³ghº¢Æ0ü¿ÀŽŒAÿÛŸ¯ºº¾æÆ'eÕmÝìó–Ûÿ0 ¹ë±Üí¸v#”y—öØ€(Bt»‘Qv¯ž ‘ª–­ŽÕ¶hÀ;ªm¿nF>‰Òìª[ЪQ¡¡]ú2²&‡ÝtÒPîK·©«OJ…wÇ&G@Æê·žq;`º‘ÑâË¿l)ºB»§K{o…XíiUÛ‡–Ïk$'‡µaäí-cÏ$ »C±)qCIý1žì0Z¢ý™0ÅÕX°µ˜0Z x™±.*/ 1ºÁêÅÒ -aë˜*h^Åå±ú³ª+^…‰ -hÜD)«ûå¬uå„$[ ,Ñ Q¼Z4^€|N>”¯J·çÞÛºá~`¸ ó¡ÀØ]Q˜& 0áÉè÷ù ÉÐÌF°€ícQT<Ø>ÖÜ‹ÀßQâÖˆeXL¤û{IƧköpFŽî0'Cã8UÜ(”ÒþúñŒ® \WUê'‰9EJ°·Oܸ¯‘qoeÐÃ× ¨v¡]‘N¡†äŽÜý\h‰À°_¿ÿpÉs2¡€÷U¼8^"76$RCñ«oãY:vPï0´B~ú˜­–—pñõ’w­Þ»ÝžÜÑ SŠ/hw…g±Æ¨Ä‚;ÏVHÐ﯎eg¤ZVå²wÎó,à9”¯Ã=Äh)¹W¾kïëãrg0— Xǹ%t8P²Wš9¾q˜ø6 7°‰½à'”Nb°ð7kÊCN)§r‚±¢’t½eÅo ø0æѱ>N·’ä¶à¡Í¾ô)ºC#Åv篯ðFfú™Å—|#hcø‰ú,ÛyÀ¯Hí¼S¦Y¦ö;`Žõ“'P®O–ÿ¼/ åe¬&'n±t T3eÇZñIý”½( 4:Æ·ØKmjìÁ)F[ŸAàhX³=2Áno[!ÀןD¤púð€¨=È,8±²[¸’<²šâ t’U‘¨Ð†cšÚ÷þDÿ0ç>ûi þ"µ% ÖN r‡^w<ꦕ×ÄË?^½á‘Ñ>4Ú½Öåþ=_„}À1ÿîÄÏ—±¼ÚåõÛ7ÜZc¹‹ýº`,ÌŒæÞ˜“iL‡Žk‡ãܼͮ„ ðÀÑúäØ3y«rxÓâŸÎÁÄ@É>™¦ Æ¾¶ãŽÒïU4èýtÞ)îeþM *.ßÏ^!Á+ŠE˜Ú]º¯%î•ÏÅåC¹+:”ÑîàÚî³Mã‘@Uv_br×Õ™|Ä}–™}G7ü ‘~b ÆöHFûÇG#Ï«&¾¶Ð“/Bì–§ÈÓ.L’û‹‘·Rèé/÷Bî–KæÞDÂý`#y7$n+áÎ-]ú'¤þÔS™{7£¼øj¢§îQ×ú§RZwkoÛb˜\ôwõ¦û^ܼôgã_ÚfŽ‚gNa¢tùÖÆwðÁrøº„kájô¼~ó‹¬iå³ÖÞ):A$x”§NÑÝäë`[×;8ËÃÁZ…%ä@-›âN)…‰y'¯Ú=ã3W'“aª=N«œ|\= ‹\”íîÁsŸ± ðÛóÌç+Õ}wú¿?q÷ßô£$0i΃c†Yâ™BÆC;å¼û~Êúÿ@3d¸endstream -endobj -1043 0 obj << -/Type /Page -/Contents 1044 0 R -/Resources 1042 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1050 0 R -/Annots [ 1046 0 R ] ->> endobj -1046 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [418.3461 669.297 487.0181 681.3566] -/Subtype /Link -/A << /S /GoTo /D (dynamic_update_policies) >> ->> endobj -1045 0 obj << -/D [1043 0 R /XYZ 85.0394 794.5015 null] ->> endobj -190 0 obj << -/D [1043 0 R /XYZ 85.0394 648.2128 null] ->> endobj -1047 0 obj << -/D [1043 0 R /XYZ 85.0394 619.5539 null] ->> endobj -194 0 obj << -/D [1043 0 R /XYZ 85.0394 444.3683 null] ->> endobj -1048 0 obj << -/D [1043 0 R /XYZ 85.0394 407.9434 null] ->> endobj -198 0 obj << -/D [1043 0 R /XYZ 85.0394 220.8457 null] ->> endobj -1049 0 obj << -/D [1043 0 R /XYZ 85.0394 183.187 null] ->> endobj -1042 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F39 863 0 R /F21 658 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1054 0 obj << -/Length 3094 -/Filter /FlateDecode ->> -stream -xÚ­Ërã6òî¯Ða«F®Œ<Ìžœ±'™d×Ùµ=äq DØbE"‘šÏ×o7º‘Ij·|P£ÑýnÐr&àOÎL–d…*fy‘&FH3[m/Äì æ¾¹L³D‹!Õ×_¾Õù¬HŠLe³‡ÇÁ^6ÖÊÙCõóíËݺ^HŠl^úµkúzUöuÛ®}Ä_ÃrDÝ<¶û퀢îèw×v]½Ü8õ—r¾Þ_J;oOkÆ­y2nvïV‡}Ý?Óèañí@Y¢µÍáÈ8Ýo±„sÏïr¶6—L -J$š-RÂUÆÎR‚ŒòóîcïšnÒ½t6¯Ü/B¨ÆU8TpWú½{û=O…ÖLÊ8…¸”qeSøIƨXÚÚK -véÜŠÅ•ëVûzé:’Œ€hå…çÊ#eÜýÐ1 (o'Æ· -ŽVÞÕOt€?µë’¸¢HR«ÈÞ5È"(ÛŸY¹=ͼo ݹž‡!J†ƒˆ4é9¦9< ¤¢•À+ gÊã îÔ¹}ðL<2®w;F}]v{èzB.y¿Çv³i?¸ -Äœæùüëw·×DPŒ…Cñ£[×q׺_æß»}¹ÁA·n7LѯK>lÄ4È¿"Úº „5/ّͯ\×ñõ#óùx÷q·)놶ÊâVÛvHT¹¾¬™±¥ƒ{^jîojYk°ëf3e«²sÞ®³Â[•w] œ%M•B¬"gY¬'ü ÂŽ)RÍ$펭13pѺé;‚Kúy<'ÚÔ¨%•¥?¼Ü—[×»}‡î`Ìü¶íM‘” bT4aD’>$Éü~¨ƒˆð„¸è7÷ì-atãëÈùMlªÍX<Þ¸•%3R¬Jûíñ¡ÝÿV7O„­øÈUßîŸi¾ÝŸ,8£±ónçV5òâµ 4Ëçã¢s…(k ¢&h¤šÒˆI”´j¤´´4§§°Ý™ VL ì\E²ÑB$y–çc/!×À Aî„P‘¨ä#‰på~Sc¸ðب4mOÀªÝî ˆQb€ñqkR’ö´´á5/ª‡c(Q&ã` ÀšÊM×nÉspîöÐs…£C&ÂuÕ¶nÀX÷%(­£Io²C¢]9dχù/Û=³®7‘aÈã•Ì lÛtÛºŸrO´VtäÊL©_ÿÊ'SMá”c -¡°ì<Ãw¬¿)`ê¦Âkú0ègBs¶Õcöùšyô·TIãèv€Z•»’³¹fÇëÚÍ{Ç+àŠ—ê÷—vÎJóÚǪ²/Ñí¥YgÃ$‹ bX0 -dÇ ¸fŘ6Ýrˆ|dä”oå`G™µ¡Š¸ŸŽvij {3'EÞ¹?á¬r÷m 8m!,’í¢ä’B¦Ù؆ßúÀ‘ªyë#€óH¶#¼Lø…‰$(CÂûHN:€ É–Bè3Ms¦„iW‡“Ô| u™#­ - g³y¦ñªm0T=q¯hÎ’ÈÏè¼WÝ”|ŠÊü ùj*ŠlŠ&(®a¡ŒéÊeû>ÚH°›8[7'Ä¿§›¸„u etàÕ—Ã)…Ejcc!¹„þÆ5Pô>úã>߃¯NÔ*Çh,CpŠç lªHd–lSUÓk/àâO®™Ø2CI‹P¿r1Eúvì3Tø+¶ôûD,Ëtam’É|l‚p 2Öl8fÄAFaøn ihç½N‘®^ÏÁ ’‹—ÊÄ,Aj_1(*T **˜€cWô‹åéÐqÆ°!µ ý¨©ÄŒ' tå•Þž­ŽúÝn]S9>€ëB€X9±0ýaŒ*ÉΠݳ=)òV'M®….jóÔBf]oiíXëÐJ9àQ*ÝÂ]K*æå] ~ëínã€Ñiµ $Øõ:‚ßÝ<¼ý;ƒg(YÛ^rÂxƒÏßÝ_Ý{%_ª‹ˆˆš¡¸P¢±Xcg; %ýä™…¦ºv¦‡±ü<Åjá­*Ô¦¾4JÜÇå5a^Ö?•„Þuüwÿv@µÐ"¨ÈÍøÆã@ºÈ Ò,Jú¼{ä’~ávŒ`joóñ™LÇù‘°/ &&i]@±Òï>ÏŠØtø ’6B¾Ã€_ŽæÕa媯&Ä'3‘б@¾óõ…æ ©tjÔÇDñ’gI®E>ª}¢ -‚Œ—f/Á-ÉAjl…ÇÓ¡ñ{¶3Á0 )™__ćAïvãw@aÞ¬µOù4vâ‘þ % ½"ЗOø¦“ â,YýqèIy÷˜¾p¶Òû«FŽGÁ”¢¨NíàEjlè2‘jÚΧìÇê$³™> endobj -1055 0 obj << -/D [1053 0 R /XYZ 56.6929 794.5015 null] ->> endobj -202 0 obj << -/D [1053 0 R /XYZ 56.6929 769.5949 null] ->> endobj -1056 0 obj << -/D [1053 0 R /XYZ 56.6929 747.8139 null] ->> endobj -206 0 obj << -/D [1053 0 R /XYZ 56.6929 540.916 null] ->> endobj -1057 0 obj << -/D [1053 0 R /XYZ 56.6929 511.3349 null] ->> endobj -210 0 obj << -/D [1053 0 R /XYZ 56.6929 239.6059 null] ->> endobj -1058 0 obj << -/D [1053 0 R /XYZ 56.6929 207.3747 null] ->> endobj -1052 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F47 879 0 R /F39 863 0 R /F48 885 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1061 0 obj << -/Length 2903 -/Filter /FlateDecode ->> -stream -xÚµYI“«F¾÷¯èx«§Ýˆ¢XÃ1mOûÚl @b‘-hbþûÔ´ÔÛá˜Ð¢2++óË­ -WýÀ«,0,TøWIá«῰¯6¢µ_@Æó‘3}‘­Ôš‹7@¥6j´š”ÔÍéà{«ö&ñU›µÐ P¢ur¶±Í[·ßÕÞKK-4|´°«wzùõwöÕDÆô^X*²ðzE/,…{õ_x2a>ã½Ì_¦…À*YZ†ŠeF9©”Á"(Œ9H`1ƒ8¶ŒØµƒ{XØ ´ >,“$F í…ù¯®ç!|d©¢{qHGÇè È•Ð<VF¢ƒ•ÆV’M&È3.æ~cYγâ'©7 tÏKŸ„™ÞåËBä žÕ±â|_¢ˆE7:Ç–‰ÍA°d|À 7rÄ)+qM Oð•Ä±2J&.H(àC(ºé»'‘ž„QL©W7q( 0BåF² ÏË|†#ŠŸ~k—àÍóŒ"åpÿÆ -lr݈nf„Õ->†évɆ€™òýæ%[çGÎB%"ÑøiÆhko¬'I¨H dåÊOØQÚøð…Õù‘€pŒR:<†.•°‡_–a”™LWðZl³CJ~@¬Dó§"Dyɲl¥8$ìs„¡ bæVt±¢2|‘ÙÍ!Œ±õMá*X "õ­g›?ø2¨˜€ ¨@÷ih}‘ !à g\I&ôÁQx‚«èÇ,掑«'‰sÄGù¹¬ Og+Nb:³£ëü‚— BѯŸN@¯†ç"¸ãŸKL€C.äó8ÌòÿÉòG›> ¬0Päá³Ëýsœ9p[¸û‹GS+&~Ä€‰QT—‡2ø€‹ŒÂóÒÎ3’,€À±Ð‹î¹&¿±¨®ÄW‹$)"}ˆI! -ºˆâ,\ÈüJtâX Â?‰œˆl–Ø<¹py+ɈBW™ÄLTKý!A•ùOûƒV<úeP“”ÎÃ!‰ ËüÀ¥»dwAf®(?nj‰H‚1Û%{XZ $FxñÑÉ ’°+ÛXa$Ô·2V¦ÄŒÔÑÀç`ûc{xæ-R(2åèâÞ0;:G‹6Ïf1ìp}Æ\¸res¤b’Ñ“LÒ’/ŽÕl±Ÿ/ɘ0€QœP>Ï tÚ ¾ðQzLB;ÒŽkÐòœ›ó†£ãµœˆø™Do¸?&¸ƒBX©‘–Žæ Jdä¹6:vƒ¸*‰²,ÿÉ°A%ŠÊCO£A‰„ÿØÉÈ4Á’v üúYÜЋiY~®)6èiÝ\‹˜7¨´\8UfŽ/Úí EË)ŒEã 4ÊN:ÑMÝ÷XãòRc~iby à1 -”¢4’°È8³^øÔ<óúTàì_l”©â×ÈÆ›˜VlDîö3;éÓŸ™ÝÍì÷…Ñ3sâ¸Lfhœ}Ôl˜"ɾOºjç°` VêÝ>i£“µü3~*Å ¬(”`†äPˆ&‚0¡S¨8»»”N⳪žd%&c Êç…º™‰%§SD¢Ç6LÌ|‹æHÎâ~Nœ0rTn/W–Ƙj†t -«‘w²‡Ì -¬¯ñPߣe¸8‘¿‚\DÈg¥¤•žLæçÚ’®YÛQpâCß+¶EÏ"B"AÈ‹98s¨`¼Jzt Ý£ïËÔMfF^è÷äs’ž˜@݉FÔ W2Ï ¯ˆƒ)ƒªK’S¬8zL:}PßàADŸQˆjÜñŒ”GVô5¯Obæ@%ß h愤¦ñ2º¸ùNX¯|œˆŒÏÓVàœÄäð$•jcë{ÏÂ58¤Ô­õl+­+EQ@ª@¨PÛÅ¢  Qvu„ ;÷kãzÆŠFÔPĉn#I6Gʸ˜%Ô=ã£nX_H%ˆ$új½gZæ×(ñ³$•ø˜¨{ O¬øiñùižÔ9ÈsÙÉLb§ïŸƒ/ŒÐÏÎľK³¨°¦h}mWõRç²»®;ÕºÅqí Q^äýÞŒm>½ÞÇÊÒö†i¿Ý-!´µþÅÔNÄ í4W§Ú½¾´øVzR’=;HU­ƒö®µàô7bãôýæ×› Ǻ¶êÞÜ  -Fd¯ªýa«mVKMtÏ—ïü©×Hͳku·óvøÕ°fÌÞo®ÎQƒ®6¹øÕ0]Îäú²ê,Íûø”™8o¨Ž×ÙÁ›»ö¬æ6©†`¬NY¥Æþ3÷O§ýß>½wß<¸é -¹›áþRÙ—Ð]‹“„g39]æ˜îè£ÖlÎ&5fÔRÿ(Χã`Îß‚j×kÇú¤·¡}¿·±9Òo¬@žž6Át:­QuÀpä;ô£Ã‹èÝ8m5µ°.§­{ïG½ÅÞm;…ËëH›P4Ø2‡'ñ}}Ú&ÃñíiCnÜûá~X]Ñ‡íª¥g˜¶5»úØœ³enNÇ]±nOâëûzcÞ½õPïöÚ;~È›iØï:ws“N¹ízíÓi™ü Îz Iñ0]÷;µ5»Ð'·}wºòÍ“=îµOïtŽk³biÃZ¾ƒ›½î9JÔèî´q¤Û·Á¤Í]Vj³: «÷&T¡6(3BêôÖžSÛ4… ,.ûù$Þô:V³¡¥Ëut™l¬xÓìÎ.N³Y¶¿ÀÍû—­cYjOóÅ–s¸§ÉhÄÍGŠ8ä}ÕíÊî¶ûRoþû—\2Mú'ýd_~z\Í0ÌûÇ¢P‡°ìÿ ¶H¦¿ýoÊçHH=(ËÜç%OŸñ—stÎÏ•"$}Õ¼øÛåGÕÿôtúendstream -endobj -1060 0 obj << -/Type /Page -/Contents 1061 0 R -/Resources 1059 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1050 0 R ->> endobj -1062 0 obj << -/D [1060 0 R /XYZ 85.0394 794.5015 null] ->> endobj -214 0 obj << -/D [1060 0 R /XYZ 85.0394 717.5894 null] ->> endobj -1063 0 obj << -/D [1060 0 R /XYZ 85.0394 690.1986 null] ->> endobj -1059 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1066 0 obj << -/Length 2379 -/Filter /FlateDecode ->> -stream -xÚ¥YKsã6¾ûWð°ªÊBð"H:'gÆ“8•õxmMöÉ¡1w(RCRÖz«ö¿o7¤(šv¶jì*£4~|hÐ"àð+‚È0“Ê4ˆSÍ".¢`½=ãÁ˜ûùLxžeÏ´sý´:û჊ƒ”¥Fš`µÉJO¬ò?BÍR¶ <¼¾ýÝ,–2âáý§ÛÛw ‡+¸¾¡ö§ë›÷D¥‹¥†«ðÝ/—·««;Õ^ÔåûßBˆðòæÝ•_ðþ枈W—‹X‡«OwW÷‹?W¿ž]­†“ŒO+¸Âc|;ûãOäpè_Ï8Sièp&ÒTÛ3)i¥ú‘òìþìƒÀѬ[:k=Á™TFΙ/™Op˜Êq”2£¤röË«¶µë¥­²‡Ò.–†óðÙ¶?âÉ@<‰¥Q$ǬOYYäYWÔÕ„}©c–HŸ®úï¯Y þ0hñ™IH–¦‘ž7(ƒPÍåë²hYžìWœŠ:£K4˜°·&Xl8Ø&0’©X˜ÀÄ)“*öÏê8S8š³;‹”ÍÇG0šÀ¸42¼šZdòXÆQ"qëà[ ×iªˆiD»³mà~¸ÞÊà} ' -F‡ê/Ç’Ý¡ nŽ!‰\°?xRˆ8¥3Õ†ŒÓ°Þ`›„Ý£øº<´øç¹¥©²h;›ÓlQõìEK#v¡xøïl»+-Me—ô´Qˆ¨t^W4¾ËšÅRó°+ÖûhHÀó‰M]w44RÇk൪€c& G›N¡ 85I“`ßWÁQj °Ž¹ü}QªZߪ"š)mä8£8àŒuœ€œ#p>õÀ¹ßíꦣŽsß4Ñ݇ ˜T& ’€àÄ3ó›Í¾,ÑÜ„-Ioi"+K"Öû¦Yˆ$´UGœq˜ÛÏœËÊʨ›mK2\Âר*ÛZ¢ºÚKÎsØúEY•ÏΗ…”uýu¿kÙ\¼\{Ë -§;PYÙÖDí[ëïšÁš£ÝlKCçÞf_=û·½mŠ~úðh½Ñ›E¨¾P¿öãY5Ýeíº±Ó>CúmÊÇ,U2qʨ!“¤ThÍCæËiÀóJ&½a<¥Æ»m!–êÊù ¨Kø!Šº®In‹YÌEx÷áM+eQ¹Ý$ÏžVÀ0e3dGÜeã÷0³;œŸ:ˆŠr´IÃuY@8-Û"·4Б 3N6´Ù4xÈ<‘­ûp‡;ú°d[?Y¿åÆÔ[Dœ!i`Ëeâð—ú`ŸlƒµƒC0fûî±nŠîÒ';o½+rEÒ‡)P­m@Xë;$eåDý‡`(Ì¥ÒzÞu]uYá údÞd09'&+HÈÎÚg糋"Ô^)°u{° ->1tȺ3¢ç='GžÃ_¯íÎç™?æMÛmÜvУyÊwr:è_š>&áy’ ñ(Aàrö¹eúehhKS£T1jp²+'qz„p0H1 à}^`Á”•4óYJ]¶H‚\ÖÑ<$AN£„QÄ£%ðÕãŠX%‚En ª-ŠaY³Ëf`®ýHJÏ—×[0Ò¹/ÚÀ<âÑÄîæ”áÁºÈŠÕ0âï]Öe> -ç3{œÖ/µZ0)¢t¤mQu3ÊJ,ž†Š‰´Å,Šãð£ÛÔín›¶¤Õ&²÷ P)MxŸPQ2R-ÿPTYóL|eö`Kçgslj:˜Ï`)ù& -¿Võ¡"’°Âx©]Û5ƒØ‚XÈÁç„ -ûŽFGÀÑ! ô‰%d$ªæ7x¤€ÇZ¿÷ºÆ‚ª³MÑš¢pçL‹g’ÑÙÕ]&ü{V9)2Ìv»²X»:¿¥ŠÅÁÄFöaŸ×Ô­\!ľ/µ‡ãÞè@&ÉàDcöíÛÒOm)}í¹7y/Ý]Ç3Ç"înßTx¶ÔÝØZB4Lwìj¿ -c˜,/<+”Ÿ}åI®0zy'øí†È4H¥Ôb#EˆM4nM†·K R„ßs÷ÝîóíÌÛ¾Q -Œª •æ©°ßÛxÐ}´Þ’{ÜÔâX£¬Á¾ÎΧk_©‚ÎýZk§·Š8< ˜x$”{<ÓdóÅ?oîF¯Þ9^пÓÆÀ7•‹¸‡ë¬èkªK&™xñà1¬ƒÂ,þÅÛ{àú -^JC-˜Ç>1~Wº“Å©;"<Âx<|æ¾^¿‹R ÊÿF7u>µÇ›J3 îðÞƒë|¾vÁZЋ`E5XÔ;(!Bªñ¢É%Jcî……¯(jð¹&0u]fÀ+x±ÉÆ OêpVª+.\”yj_•ÅW{"DO¯RÕ¼!¯ÝÙuydÛ¹<"ŠÆbγa|ú<ò5Z¾¯ÂOU@dü˜t–Àçä“O4è”% ¥éß>Þ]ÿŒŸ®ð+‹_ÅìÙÜë24–Àª€¶Òœ>|a·q‘?$╘@üãÿV>Ji—ØJ‘ÿ–Eµ$ËàÌn -tÒ“'--$¤ƒÞ:Û­…k"wŸÜTx½ñ¨¡ãà:wá¹™ŠZŠ œí†ÐEôz82CT¼~1ŒCÜB—×Ñ¡h±óþ½×=ÎxKoö¡N¹¸ØÀÏ…HML´•‰}q7:ñ‹²v‚µ£3ÍÃT’é(–=>˜ä>ô/Îz:¼7® õ9 ñÿ2þ鬊Ó#Ò‰ÂÎ~Gmæ'O’ -?Qù=‘ê#ÏgÙ¥XíÀÕXu¾ŸõùŠ¶€$y&zT¼çNª ÿµwQŵ³»Wdî¡!æÁûî¥ë5”ÓÂ}…×ÝlÆ`DB"zÆ^gÈŒ}Ò]„£Ã™ý÷eç-ª]™¢c$È6É©Å6uYÖ‡Á‡z_ú4ë'|S‘Ë5ƒˆ™¹§¯L!vèý3ÿ -£”òåjÎ$PšÀƒÞd·ÉD,ŽTŸllF¾É Ö~E9;ýMØË¡®'Ù‰'§+ë²/-„Ö¿fŒ¾·«;ô'#±)–Ï}‡äÖóEàà»ÿ½pü‚¨c¦°Jš­^àu‡Õ‹ê•rÎJ^hÞÿâ¥êÿWu˜endstream -endobj -1065 0 obj << -/Type /Page -/Contents 1066 0 R -/Resources 1064 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1050 0 R -/Annots [ 1069 0 R ] ->> endobj -1069 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [349.4919 384.4828 408.4801 395.2672] -/Subtype /Link -/A << /S /GoTo /D (ipv6addresses) >> ->> endobj -1067 0 obj << -/D [1065 0 R /XYZ 56.6929 794.5015 null] ->> endobj -218 0 obj << -/D [1065 0 R /XYZ 56.6929 594.1106 null] ->> endobj -1068 0 obj << -/D [1065 0 R /XYZ 56.6929 562.6395 null] ->> endobj -222 0 obj << -/D [1065 0 R /XYZ 56.6929 370.2937 null] ->> endobj -1070 0 obj << -/D [1065 0 R /XYZ 56.6929 341.714 null] ->> endobj -226 0 obj << -/D [1065 0 R /XYZ 56.6929 214.6004 null] ->> endobj -1071 0 obj << -/D [1065 0 R /XYZ 56.6929 186.0207 null] ->> endobj -1064 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F23 682 0 R /F62 995 0 R /F21 658 0 R /F47 879 0 R >> -/XObject << /Im2 984 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1075 0 obj << -/Length 1913 -/Filter /FlateDecode ->> -stream -xÚX_Û8ï§È£h\KòßÇöfoÑÅ]±èÎ>]ïA±•‰P[ÊFöäæÛ)JNœqºE€˜¦(Š"©)³M?¶©‹4M¾©š<-2VlÚá]¶y†±_ß± “"-r!àeet[ˆ:-j^m¶×J>=½ûðOÎ6ýFÓò´ª+†Ó2X¢H«&«ý„§ƒ"áOŸ¿<ÕÐã_úù0žþã«r¶åQ+ËS‘—þûØ/¯£_­v¸Üσá*qz˜úQe'Gzk¿OGµ{âWr¢æ‰ä(Ï꺰C§\ -veÒÖNϬ—ê¼g¸rÞÊ.ÎèŒÈ¢h¡Á¾¨îý<æBh%ÒËÞ:z³á˜èáhÓ»>HÅôÑhÇ L8[Ú,²j¼œ—D>Õ/…T¿—T„ ¬ñØ€0š&îm´Ù­4DÈÞY¢Bž¼è.ÈÜ&ò0§5¤RP¦†³à÷öÆ'çSʯ†í°ÓF^b ®Æû+ìY‰Óò¸ó†_Ž;oDHàJz+ÞI©!úê`Dñ:™Œ¡£ Q’â™ÞR-ÅãT!pº Û&ƒè¦H,xÀ·Üór>0“³äÏÇß·;é”ßCÍmk{È@ÁD4¤I¾qž_»ÊÏ_î9×*p -M&PÄqíèÙi7jÓŽ4¾§YyŸ"A¦͠ì‚d,"û©ì±‰kkÒ;¥)ÏR^Š:”&JÓ×9*—“²,Jן©IW؃È!6Š‚OÆ¥KaäÆ¥ÀÐU§½l†¤(.sÝ«Õ@BÃäf˜R‹eÞj1-£O.拪‚#/`h~>)×­lS€³†1Œ•ô ´ÅhmsV݈jµ75‹Êš5ß²Œ?OdoÀ7*ƈ·ö2Q¥ z¦k{WÌåU*ê*¹Ž ""!Ú–•ÐMåLÜ žqQ&ÚK¨#¾ºÔ7ÍŽÇ$%£(–qÅ‘`Wm¾œµO^˜9ÈïŠxp:¯çB£àFGBÚ/땱ˆ¡ZkÛµƒ²“íw„¼æº¨ã[½$x(ƒƒFlBLÀ{‰j8K [|ﶪ,}­UP[>é®S‘ÿº–vY•òZ\Âòâm$s–ò*/£ 6*,¬C:‹æZ¯Hy‘çAúƒÛ'†zQCz2.–¾‚Dܯ%‘H–EeACd.r‡ZÛ²¾À?ÐÐ’«Ìˆ­)²¬‰¶&ŽHäǨí=Q»i¼#³ŸÆiîP 2,àÁǯé+´'¥9¾¾z†oÔ’nÅ›9l¶,Š…;Ã1# ?bÍZ=MZ×UÔ„nçËç?j£sƒàç®ܪŒý-nñ´®Êo1<Ø èÐC`¯gFï—N‚šî-Å 9„b±K¡û@6_æúx´á&pé_–Gú¦sj½7Ù,Íó²üq‹R-êrBd:]QL¤T1/­{¨˜Û¼`É'ÕJʼŒ4Á(Õ¹ ÄÒ3îïÄSÒ§P˜ XÀ²zÖ¡ƒ‚N9ýl¨ ñêî¶aM:¦¸à~_VY(>Y2h£l—y©%«a3Ð%šÞŠ¿­6^:ꬕÛÌ[‹|pA˜ªj ?RøÃx½Í¬m­ÄÞtd¨æ.Ú%Ô­¢Z¢¨ù´+¡Ö–bíî ZÓ@BÍ`*ƒnèÜÏኻÂ;Ë züÊAŠy¤Zy”þÚhêûkdv–nwuhg‘¸ið©ø6<­ømRËi´Æpsó‰Ø‡ë®5kw"wT­ÆxªîæžRÿ4xÍË¢Ùªn@C@gçá‰à  vþjÌÖò F©›ñ3VÈj‘æ‚GÃÔèîŮĭçŽæÕûÔÞ$>1‘ÓcJç¼ZO¥=«rþ÷Ðή|u×6è€Eô×#X7±‘B\áMò‘˜¡ŒúÀ’½Rá ò,²Ð³ÈYé¶zy­@ÂÑ€¤×eOÖÜ^_¼…RQï´ Xä$òbÆêpE_I«¿¢ñâ§zRvÛ”Î×ô·A4¨Êù|ÿ0;Š&­ª¢¾îUÞýò4KŒ_E‘â÷Ƶ¯Qd{‘¡O‹“‘änGE¸onW›?\¾]îÿ§endstream -endobj -1074 0 obj << -/Type /Page -/Contents 1075 0 R -/Resources 1073 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1050 0 R ->> endobj -1076 0 obj << -/D [1074 0 R /XYZ 85.0394 794.5015 null] ->> endobj -230 0 obj << -/D [1074 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1077 0 obj << -/D [1074 0 R /XYZ 85.0394 576.7004 null] ->> endobj -234 0 obj << -/D [1074 0 R /XYZ 85.0394 576.7004 null] ->> endobj -1078 0 obj << -/D [1074 0 R /XYZ 85.0394 544.8207 null] ->> endobj -238 0 obj << -/D [1074 0 R /XYZ 85.0394 403.9445 null] ->> endobj -1079 0 obj << -/D [1074 0 R /XYZ 85.0394 368.2811 null] ->> endobj -1073 0 obj << -/Font << /F21 658 0 R /F23 682 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1082 0 obj << -/Length 69 -/Filter /FlateDecode ->> -stream -xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream -endobj -1081 0 obj << -/Type /Page -/Contents 1082 0 R -/Resources 1080 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1050 0 R ->> endobj -1083 0 obj << -/D [1081 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1080 0 obj << -/ProcSet [ /PDF ] ->> endobj -1086 0 obj << -/Length 3113 -/Filter /FlateDecode ->> -stream -xÚÍË’ã¶ñ>_¡K*šªŒ7ÍiýØd}p{o¶«Â‘8#ÖJ¤,R;ž|}ºÑEI´É(U.Fw£ŸÄ„ÃOLœa\y=)¼f† 3™¯ïøä ¾ýõNDm3Z)ø“ù:3Ê1ãd1™‘|ýñî«÷RL$gÖJ3ùø8¬e ǼÒ~òqñóô›e¹é«íýL>µ÷¿~üž¦iV¸Bà4KVx?üð-A{j¾i›_8—O»mÙ×mCƒ?VÕ¶jæUĨ&žy+mDhªÂÈ1BeBhæïÅ´¡ñº£öa{/Ü´-«èêu½*·ô§o±5#´î/Ðj1]¶ÏÕg`µÐÓ7øÅMûepUXü¡æ±z&| u¨2RÓ>æ¨nÞ ãȪÌ›Èj·›/Ú™i˜ íçºzîØýL ›(†Q‡Í%èÓ:$cøŒßVUDÔ-ÛÝjAýçvû)öê~IÀÄ®¼‚í$Æ™uCí~yâñAëSÄ°n£x2ŒÍÛõfUý€–K—±bO @´mÐ4ýeÝ2ã8- -Waƒš)m%ÂÌ ™æLZEBµL€ap~ƽ¯Wq/¿£ÍïòI:pH^”ïÛÕª}Žòâäv -©YÕ]O½`ùÐV sø·ëª¨ý’XP»ëÓXu¬,óݤÔ_´ó.>¿Eúï¾û8øoAè…žh!™å^¢óÿíîç_ùd±âû;Δwfò 8ÖwZzVðB¥‘ÕÝOwÿüg%:PˆŠyÁÕy -h\±›f¢š%žfÊÁ¾x燈v œ0“)¥ÌDsͤæEؾr¾:–‘‚9 sÀ/’dÞ9—gv6`œQfH„@ê 8€Ñ&rf€â ŠfðuEqOࡇ*§èb“±ÕB2ç´‹³ËÅb[uݱ(”ÕL ºÜJ áA([0aþi¾9µÑŽAW¹äö¢â-.À±B8q”J€;n‡‹Ïar¾ÉØx^ghùŠƒxÿ&n1ÕtöŠ‰+k(®.é¶Ð§Zí_mæ ãlŒ2C¦†=²J’™Õn›.5¬x;"ÆkD:ɤ*ì!‘g´ÛZf©æ»{¨\Œ}ØCGÚ¦Š-µã,ñx}Ð_éxÊ%ê͉ჳNÜpÿŒWD£ -ñŸ‹S5Ë~ÐhÙx“áÔ1·ÏfNùÔP”yÃííø0^áS#íXð¹ÙVõïN• 7Ä£³œªð ôcV¸}ÅéíXM¯±êa¾Gž£^äânô«‰Í™…z¯ÝfØÅ\mM:ãLÊ!!Þ©ÍÜ:èùjÆŒ³1ÊSÆe¨-šy»r@¬ÐƒE¦Dö å]UX¨)˜Ä 7&>nŸ&Ôùqt61ÀŸÒ|¤hÇx‘žŸªù>#†DRýcõ‚]0¢ôœœ PW¨8Å6T#ù; -]· -°Éä¾ešq6ÀBmã%Ħ+Ö€*È·º¾Ú^¯zÃà: ¼Z÷ž‰YP2îC† œÍÇlLé¿p0$ÒØbü --\Š_J@…eÏûuåãd~# ø. -Hy‰¨Uc‹\`e*Y; Þ7hfå*óUÌ8ëÏ;xà ”èÚÞŠçßEž w¨µzÌsÖµƒëðL;s”=—Í⫬ƒWŽi}n‹¥÷ñ<¸u­™†šâõn=aœQf¶™CyÇ´,„îvÛ_MQØ=Ø#ïr s`X¥<ïŒå+ Ñè$nÅõ€ñ -׸6VêC®ÏØ?ð —/P{Ya§u3_íþ)¦m8óÍDváøôFcE9#é1•õ ôq_Ü@ "ÆÙe&º{¨L ·_8É#w°QŹÂÕòl"^uŽ+E}ËJ\²¸È 6F›Àó¢]—usÉ”g…·ÅöÕ±,aœQ梙„”ÁQyî<ˆ[ÆñÌdˆgRÛéo»{jNáo×oé¨R›éó² 0ü\‡³] çÆ0&u¼|ÐtÅÍ·?üDãHÆ{Äxˆê÷r=ËùoÒñä/RêŒAIH×`Ç’1¾°¾êz¶ß#^Áú¬³)6!Î ê:R„?îÁ†t .õu•0Áj-¢ºö¸±çÔu€½ºŽQ^P×C*«y½.W×5öï!»¯‹—J Zí¶4R7}õ„ž5Œ.W»¤Á§ìOÏ FC_ºjSnËžàmëØ 3Ã%dG(‰‡.GO=—áYZèîï§Âß:wwpäÜó~¬‚)!ìDZ•Û¥Â÷K³ž„q6F™Ézäû²‰ì²‚dT#eµMKwgìa¤i·²‡á¾òËqSÎY„àKæk÷ajf'•‰aÏ[D¼¡EŒP^²ˆ1‰_nJt0‹=3¶píÚ%×¾å\;’醈Qr.Þ.ÜÛ·°”΂CÑQ8±¯£€ÇÑúݼÝ`BªÊtå#H2ŸC‹J„â½¾6ßðn{Ëòs…=7-×õÓ®î_è}hUo©V$àãÙ…˜vôo½ë"º‡*uGØ)pjÁCàÔBàe"µ› …ÜͶ.ñ¥IEãa¡Ðûð-Í$¯£ã½Vø´¡—4sp4Ù"KÙóðÐÊMŠÉ -1™0%ÅvQ­êuÝÓ+”7çÓ=}«# d¼ÌæiõB#$Ûy»?· öÂÈ !Cº ý7+pÄ!Žb -ÜÑ ¤X*†aج†F›ÝºÚÖs®Àn~É€*íÃk¤s¤Yv/Â{+ß*ARth‰¯‡°•ø¿|‚d™þ€²½@)º>~”Þ à ùTÑk"7ý[ûœÍÛGO  -³ÆGZP[ññk(ü[wÔ6-µ]_6 zü´ ‘5h Ésª\0Á03 -“ã…õ"GÌX€2Á K!§óÝ–(Š¯x¼‡]Ç^ 2Èíc™¨/Öìªn>EXX'»ÃîÅOÃ;"¢Ùmðx¥Z 5=J·[S­  2³¾ÍAèAøñ¡êŸ«ªÉ²œÈK’dB© ›Êó>”_>u|¶ô&2¶‡œ­Úy¹Š(FiÁ©Ï“Ã[ã’Ï{¬—=+K£z©Â©«Â&±ÂPÙ÷å|qh÷;”ñÄÖBý«ÒaMSñ\ðt¾•‘’‡ˆ¿Û@ö/RõùäÁ$w>ÊáOù• –£Îì¿÷TÝ©8Aç­‚¢‘uŽ–±< vÚÑŸñVáÿÑVUT­ÌÒR‡”«çò%¾(¢øpðzh(ÐËš2=Hkªá RKíCzJ4ŽçÓ¡qšñÊÔe”Eöþ œqƹlÈ…“ÓkçAÊ%nÕ™]! ÓØ«3¡„p6˜!O@þƒWLcòÎæAÐ/†ƒûw¹^X|Ü[ ×ú4yWx´mnÆè€ð2£™àk¡¾„уÛÈìùüa5œIm•VLr-oÆæ€ð2›J[˜þe\ÆÊáZ‘>Rï׌ւIiÁ ÔEÎÙ[Òô<¯ ñµyþ¢–[HÛ¨„¨“kÙáIúUZî?¿Ó5endstream -endobj -1085 0 obj << -/Type /Page -/Contents 1086 0 R -/Resources 1084 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1093 0 R -/Annots [ 1092 0 R ] ->> endobj -1092 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [356.2946 363.7923 412.5133 376.6291] -/Subtype /Link -/A << /S /GoTo /D (address_match_lists) >> ->> endobj -1087 0 obj << -/D [1085 0 R /XYZ 85.0394 794.5015 null] ->> endobj -242 0 obj << -/D [1085 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1088 0 obj << -/D [1085 0 R /XYZ 85.0394 576.7004 null] ->> endobj -246 0 obj << -/D [1085 0 R /XYZ 85.0394 479.565 null] ->> endobj -1089 0 obj << -/D [1085 0 R /XYZ 85.0394 441.8891 null] ->> endobj -1090 0 obj << -/D [1085 0 R /XYZ 85.0394 424.9629 null] ->> endobj -1091 0 obj << -/D [1085 0 R /XYZ 85.0394 413.0077 null] ->> endobj -1084 0 obj << -/Font << /F21 658 0 R /F23 682 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1097 0 obj << -/Length 3638 -/Filter /FlateDecode ->> -stream -xÚÍ[Ýsã¶÷_¡>EÎœ`|$Ó‡KâK/M.iâL’Ì…–h›s”¨ˆÔùœ¶ÿ{w")Jvje¦s“ÁÅb±ûÛÀlBá›(M´ãnbœ$Š25™/ÏèäÞ}yÆâ˜Y;hÖõÙÕÙÅ+a&Ž8Íõäê¦CËj-›\-~šjÂÈ9P ÓÏ¿}óêõ—?~ÿòÜÈéÕëoߜϸ¢ÓW¯¿¾ ­Ë¯/¿¹|sõü¢ÂM?ÿÛËï®.¿ït$òÙë7_„¨~ùêòûË7Ÿ_žÿrõÕÙåUZLwÁŒ -\Éog?ýB' X÷Wg”gÕä~PÂœã“å™T‚()DÛSžýpöD°óÖ:&@)Ñ\‰ÉÌjÂV‡§ SP˜66•#Æ(;˜u¦-ÑŒâžPK8ïl‰ël‰‘ÄY31@D .üŽë¡L¬!J8·ö¡p lí¸Hf-ÁY—â>wŽŇ쭫Mƒ ^¼‚ŽÝXÆ¡mN£^®PKìôõwø4¯z3HCŒ°:~´Ú.¯óÍq¡ˆÕJÅa jÜééÕ]>B‘ƒÚXù(ACœ€ï°¢̖ŲhòEษB'?ï6çÌN«íí]è~„z´'3&1œCƒ§÷T23}Ÿ•Û¼í뼬î±i§Œr:›‡u1ÏÊò!üô3åu³)æÙîí9›Öyh_ÇñëÀÚ<¯k˜9¢}V6çðájU¬nÏg‚êiVãS…‰ªª‰J›µ -¯ëj™‡ó (¾€6§ÓlÕ~Ü䛢~FüLýõãàÁÂëù]¶É€ïMü Ÿõ8 -°s(3ÝÖ¸@lyž?×e6Ïïªrá © |Öy™Ï›ÞØM¶ZTËо+nïfqßQŠ‹1y 6’¡•IJÁ¨ûÎbŸ‡lBÒBǧƒ--‘Ãí±JËGp% ;®t)Æ•{ëM~S|x²A=²¼¹¯6ïBg½ÎçÅÏ”r¯UðÖk•ðÊ»LXb¥lqe_@Â0bq'“P¢øˆˆì EÝ“Q¶XŒ¡ ¸à+Ã2Ð\ÁÃÞTeYXÜ{Q€-¼(‚dê2«ï"|Px§ußD½e_DË–(ËP’@¡¹ËW¡ Z¡-ο®nBßuÑÔ¡U¬Ò‡qxÞ,³úàŽ•vzuî(qQ"@˜ëïÁ–+ÜKÃ<5|fãÅ 'î(·”8'A®F'5{öŽ&Š³.ÉýåvÉBd“†ÛQC4ÕíŽ.³‡°â -üx›6búªÚ„îüC¶\—ù‹Hˆ Œ¼“”7vl>M”¡¬ã‘n<,¬Qjb©8¸Öòög/ ’¦I ÅcŽšÂ¶Ž8ºL•d„¶æŒ¬Ýa®ÔqÚ-iTÞñ8Q•%œB/ø˜ˆ$ƒ4½!ð9ke$aϸéÑqˆ˜ýyÇöÅu'mÅC‹GvuÄ“þ“c3h/ŒM¡Õ!§Øõ7§òŠ·ä Ù"ÝA¯áŸÖ÷ŠôÅRíWü.®ÙAÂÀŒÚ{.D´g]Š#nŒ¾Ç_±u‰ —â—c¾ix«ÙeÅj aó¥0æt+MY*7Àת¿ÖU¶ÌÇÁ ²ÖXBX·Ž1r¾j|T˽wÁ†§-é]ödáQCl£Bÿ7Ÿ1†.“bl辎°g`C”a}Ô +÷v  5ļEµ -u>ßnŠ&?bSm}ž mJœÒ¦(…äØÏ`5Ó„*µ©vÜélªCñˆMuù+‹ºyŠUA¸$Ã`ßBeBM«U;6Ṭ‚V˜!n5-F ^J¹ÓI&Q|D4ý#`_6ãxõ?¬Â'„J–¯!ÕkB|)c|‰ÝËb^•ÕªýÑó‚ F¸šž9å«E0`0›ËZ;Š¤ŽØPG;OeCm¹áé$Û/ÙðÄhqÔ„”ãà§!{:Z¹ÀRƒbÒu”Ãj5[å·YS¼GÝÔt*ø âïð¶X5ù­Ï£á†õÉ n¢5!…ÞÅï8ââº#||AC_»‰ƒÈd&6Ü)$'5L5/·5piÖ…›¾Æ4@p˜k>Ï×Mv]"\‡ºHxµ„´½ ½7Û ù&ôG(Tv…òÂþ¡1¯`½šð£ˆ|WÌ£rí«:<Ñ+Xg랧 &F+p£V»?ª`Jà 2¦ÛYs·Ò ;qølŽg]Šûü1ʉ´ÐÕãð@4À˜%”ÙŽþk;ým[‚6ÖÍ|¡K›v×±û¾(ËÐòµ'xÆÚ´|•Ÿá²ÁÙQ§™ÖÛ–FV@ü0Y÷P_,}•ìbù@š¼nÈ.þ®F3\±y4þîîð©p¼£û4ã'‡ëR’u©ŽGàJà†Ë`Ìuñ{~PÛ§ÓÄÅcšØãpÏŸ¢‰>3 @ -±ç‹,݇(!úWi»Q#Ú%ÿº]µø¶?§Ä8Û)õ å‡>a*Hʸ0m0½Èo²m9 IF¬LE7²«(ø¸§ð/GKk • - -»ͤâ£;.8d®Å}uÐ=?j)κ$G⠈…´|7ó‘=ç3ÖÏE~Û‚‰×aiƒ•ÄœûôBQá· ;SY… ôøÆôå¹Ì>ËíÆRð»ï³¢ Óÿ\VÛ–ë ¸æÑ´O:B)uƒýÅ ~TìxòeSE-l­0Ï{¢8ë’Ü»”’X𔆻!ÖÉd í1(;HñAå2Ùß‹Ö6²ØºÏê~hp¬eÞ¯nöì©Î7ïóÍàóºÉ6MŒ†N`tk@yÊ.MaI*iØ<‹qXµÆô2œáïp€âB™7Ôx±7¾õQ¸ÂyV_ˆ#!C­6ŸŒ`gñ§E²¿p™½"Ró®V›rLNU»‚w#Ô±4˜O£…•ÓwEY]?4xà´OTQ™¾ùæQÝ*þ[>™±%DÖ‘±™dnWK‚8WéèñËpxûdo‹T…bŠArǾ"EL{ÉCÓ«<ñTÒä¾ùqú-Â@;æãô¿ñG_žkÆ”¤ìTB†#ñן¶Ù4—[ŸsSÔzöª>1‹H‡™á0¾Ð2&>е]ÕÅíÊÕ) I(0)ÂL‡òpÎhͬ”ÚHIš(ÔÌ'9Lí%90núc/†•.j0`ÒOñíšXFõ®ÂvòÁÌ öž é:¯®µ‰P*»ÉˇÁš^fœ)Caì6F1‡#Òn¤÷ÌèñÏL„àêxù -|+qÆÙ>ï2V¾JãNV¾êR<\¾êñ£Ë,Â-˜ådü%Š0È' ¬Çઋ–ÁÍK%Z'sYø$E?Ó"\Ü‹a8ñ²JÇ6‡”:“n–TVµðPͲG øm ]9#€z–ΛÍ6?p†'„ž?õ=/DœÖµ\Þde=FIÔåVr±„¸„/¯°Ä=o]å ÂØÂaå%_Ä„¡ a©^´ŒlÝŒ¡ûIÇ«l„WØdmùÑE_3v(¥P—ô£9q×´ÿkBru¼2#Œ!à#Bæ±(Àî\ƒÿó¡|7öÙ&ÞRœuIŽ™¸)»>“!5s £x«¬ßb­\+Åó}MÀ™V3<ÑOôÆBCh¹tFúK¦¸yxôÚéÌÖYÁ˜±€a[ýd¾6ùÍ&—6öÂsP`å†QÂ82Êp_Æ:à!憀ƒlkúOŸ)-cù [EìÉÂ+`cka˜<ót«áÒàÈxÐǺÃrê¯éE¸>wšÁC»¤wGÄ„ˆâÔœñŠàÞ=>êҵºÌÞç¡Ë‡Õ¾¯Ù^‡–/"¾)§*Iï.Ç>zÛ¾1Ô nÛþo_¥ƒhˆ6¬±Î@E8sº{Kwï¶.7‹t\àêœb;àâ,ÙzçÂ3·’¨\xß™.SJ§/ Ð“è ¿Éšö€àëë9ûw+( £|G*ûá’’ãõáðÕîÆLúv‰ó½ §‹Xùkxì¿~›—ù2žðþSïäÛEö¬ý§Ç(|BBã—X†ê;ÄfŸÈnœó/-AÿðGLë·Y+^?ð¢ÌW·Í]òï°Œˆí½eà!©·Å¢Ö6/߆ÓýNç¿­;ôÿ'1ÅFöt–xÓÝÙZ·ö‹¯®ŠÝ0YhüXg·c¨0ØtÔ´u¸b°ŒÚÍÒk4y= ½)–Ù¦ðüŒ÷ðžC¼¦°È›|³,Vyüx>Oäñ,Ü™+CG¸«÷@²ÚÆùR] ^Të|“á -w "p ?Œ%ì&yŒ?±.&/Â_Z3©Ô9¹µÉàúóÕl4šŧ@ÿà.e’?««Msà|_HÂ…m‰ÕMÖx}ëU!òG¦£žGµ‡†¡Të¦h¶M»ø¸Ê¬¿»<în0.ˆQfHƒÌ6k÷¾È·ªSrw¥—‡R_±ºýäÐM Çálãð‰tyÌd²Bf%ôŽR(Ž03œÑ5qþ±Û1{3ö½<? þ³;c+ÿ׊¬¼þî½ìŸ@nÍ|L¾òäá#S¸tÁ÷8gè -ÍGXÿ/Õ/oendstream -endobj -1096 0 obj << -/Type /Page -/Contents 1097 0 R -/Resources 1095 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1093 0 R ->> endobj -1098 0 obj << -/D [1096 0 R /XYZ 56.6929 794.5015 null] ->> endobj -250 0 obj << -/D [1096 0 R /XYZ 56.6929 304.8746 null] ->> endobj -1094 0 obj << -/D [1096 0 R /XYZ 56.6929 277.1668 null] ->> endobj -254 0 obj << -/D [1096 0 R /XYZ 56.6929 277.1668 null] ->> endobj -1099 0 obj << -/D [1096 0 R /XYZ 56.6929 249.2319 null] ->> endobj -258 0 obj << -/D [1096 0 R /XYZ 56.6929 169.6708 null] ->> endobj -1100 0 obj << -/D [1096 0 R /XYZ 56.6929 141.5207 null] ->> endobj -1095 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F23 682 0 R /F21 658 0 R /F48 885 0 R /F14 685 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1103 0 obj << -/Length 2809 -/Filter /FlateDecode ->> -stream -xÚ­]sÛ6òÝ¿B™{¨œX4@ðóúÔ¸NÏÖí%ÎÜÍ49Š‚$Ž)R%©8þ÷·‹]€¤DÛ¹kG‹Åb¿’3?9KBO¨4˜Åià…B†³|w&fXûáL2ÎÂ"-†XoïÎ.ß©x–ziäG³»õ€Vâ‰$‘³»Õoó«|÷ëÝõûó…Šyä/ÂHÌßÞÜ~O”†«_nßÝüðñýwçq0¿»ùå–Àï¯ß]¿¿¾½º†O û%Sxbû›Ÿ®ivýÓõÏ×·wοûñìúÎ]fxa)Þä³ß~³ÜûÇ3á©4 gð!<™¦þlw„Ê ¥,¤<ûpöOGp°j¶N Ðá,Tà%Ðx^ÌaêEÊWNÌ2ˆ9…i¢à ÅüIÈøøªR°)ˆgCz'§:¬ÓcaÚ+̃h|lF¾×4¹ùþ‚&YKãJ¯ôŠ>—Œ×m5r GÈá2õ‚@"kH©ÒˆÔpÆi»¬Ó;]uOê9^€Ÿ—øë‰[¬—%þÜ©‰;-ñá±(9#Â*Ûñ¬^³Ì+W«æ\&sݲvY—oiZm7©™‡¢Û>§ß˃åžåå”nBÏ—~òÕºñ¥…⥠3ÀzF7ëe݉PüçÕ70Hôm1M²E˜ØK!YºÌÐ@[¢ö ¬'«q04b©êJ¯(ànÒKÃÐ'ÂBYçY¹­ÛŽ7>®RÙ#TºkñƒÀ‰›>öôáL’G œý\÷H(îuÝØ»ã.;vp4â»àÔˆ'K^[×ËSávêñ(®t›7Åž¥<ð\çÔèVfâ|Çs„ŒâSCèŽð#4¯Â’‹˜\hÉE6.GsÐî¡eà.[é#<K,‰–Š–fícÕeyWä´G“ÍñZ½Ó€i¬h°9#Ô]ÑV€Ð`Š6i!™·E•ë)u·:?4E‡ìÆ -ùÆÓauÌF ãÜ–ºš Ÿ³²X´šå9ùZL6_:ú •oÈ>ŽHd4 ©Ñˆ€m=ÔÆ´õås9o[°%•Èù-1ȱ„C/¦tîTÛéfG3ã /Ä2h ZkEÉÆqp¡¢Û*õaÃӪΨ+cÚ“vô¯­F‹U% üt¾)>[ÈͯqŠ (\`çB×úB+È*®äõnÏ~¸¢´!f…¾>®áõÁ\TÒU,Œ æ¢k²Ïº1‚0àÊ1‡ê£›0²C2Ù¤åÊthÎiDLhÔlDìd.*Ð߶³1ösOÉÜínZYé½®V-Á-úà ¥! )  /ñÆ_‚yiò)øb]à ¢Ô”9ƒçuÕ‘A”£,Ï.J‚ÔÕ }Ýt-£›¤Îf- °J¨È°ƒ»ÎÐæáPlÈ™è9mÓUq†ûÌÈ+öŽj|GZ´ö‚JH, —ü`­ I•eýБ5GÙ³™†Ûß;'ÂWº*8)YQã‰R5¿Y#GÉ܈ˆs |ë…±Bˆc"Œ™MŠž›Þ -c ¸2d²I\à€hªV‹°8.ƒk5¼ò¢ª»b=UP‡ÝqÌÈô"/Œý`Díƒn&‰…ž -üÿƒÖ‚ê¨ø¼$QÉØÆó,wEéð4¬IÓ(|済ÄjtDŽª]S„8¢AO˜$ÑKôÆìö&ûLPƒŽPªÿ‘;¢¶gÈS M”ÙPgKáØ0Á21¢»‹+*ýÍ´§÷’Э†…Mß«šƒ^ݤv'ñÂGájú·Ú^S¦Ä–o·ƒyÓv KÒÇN{¯ón€/9ošÅrSCYµÝaôöCJ{þ0LìŒg¶Pny7AÛòÕݘ£ nGÑ€=5ߤ ‘GI`óÌZ(YJL&‰ÂŠ×—zíªsüv—ô³•9öð©x³ô¸¼+)%–a¶÷é ->tÑÏMÚ…±ÂhÊi -â±?W[ì/Ùn_êÉ6…n{òŽá¥RÚ6Xz¾§.ýà[Ì%éüÕù"ç1POªo'<Z_»ðME¯Üüò{¡ãU^FŽÀi§ÁÍ XRÉþŠ%4›®8ªÎDè“Ü 1lÒCœê‘ü<=ðŽqp.ëúþ°GKP¦FI0àÁÆ3¥U¦TN&FÉ—Üí€2“ùǶ|£`&!Wù |¯»¥±qGûT°qì%Òå S¹[GÙ ®kë%pDKæÑ -¶Ùgª£ä@ÔCÖò(hF¶±„öô~ê嫯‰\'¸´Õ{f‹üº¯®è°×ôM -µCôž“›ãeV«/¢g -|EõÏR1¿ªw}½ö[½/rƒíGHVƒöê-~Ç…F)åvÍ‘ƒ–ÈQ‡ÅeÂ׶»bìvØŒA·ßëŒ1Àðú -Ê`‘žbôè¢Óí>˹3ÜeÇ‚'¢¶(¶ìà ŠJ´†Í¡±:‰c¥Æ>/’ó»óԟ״`(i§áF¶šM“Áš–€&øà†’±ï h 0bÅ&×<Ò25¹°lš\À!;ÍÀ‚Ù!ËÀÕoÞRþ|º3h¡--/÷ºqo -xS·BëˆÀ:â}x’-dh*}Ú(. PÑÄ1–^("÷Ú,XñîÌC$¨qÄ1£ô‚3gOfÕbW4^aŒ–"”g23ø%û«H=_BU4êD./‰îŸæëÍ›©Fço u\¬yþñöæß43º¶ô°•Á‰Qý3êê¶á{nûÐä:¾m¶Ñ/G‡«Þ«MñÃÏy¥!9rkÀ²ÎUR½[?Eà¨GíÿO:ud|paGžPÊÕÂx>øƒx¤ bm»¬éhO•}òDP÷P$ßfM–wÆçqáò5ÁñÝ´-³Û;9|D%,j7ñå•&Ã3^_ÄP€]ü~fˆ A¤‚ƒ…‰«§+.,D™ a^(Z»Ç]ñ‚‹HØŽ<=ˆ -Š^8r/(8ò¡\«ÀG]Ù³3ð‚_…LZ›ˆh%”äãÇŠŽ‹m0VöîPvžtuv…:ÏiÞiÞW扗ŠwXéÓ[* •P\Ô•†ðeßS¼®1ÝñëºO%¦² Ì“¥¥oë}%{ÀKáÜ£çoJÏüÐtòŽ³üÆþËðúòïÓa|ØüaÜo¢¹NQ¯ƒ`Çò¦ntJß>ML;¡èNÑ\ÈØK¡K“ž¸]ðÔ킧’Ter^7é½ 2önï>hD«1fðÔÕ•¼$Œâ f†Ù+f/%…—(¨‚G¾qÊ(>2áXÖÕKÉa1ï 7¾Pž­Ç×çÒ©¿õTèáݯ 'á?ý·{ÿÿ`{*Iüéÿé ’y‰ŸÆ–)d\©cÎC(ŽÃÄ'Xÿ/™Ö}Íendstream -endobj -1102 0 obj << -/Type /Page -/Contents 1103 0 R -/Resources 1101 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1093 0 R ->> endobj -1104 0 obj << -/D [1102 0 R /XYZ 85.0394 794.5015 null] ->> endobj -262 0 obj << -/D [1102 0 R /XYZ 85.0394 438.8479 null] ->> endobj -1105 0 obj << -/D [1102 0 R /XYZ 85.0394 409.9891 null] ->> endobj -266 0 obj << -/D [1102 0 R /XYZ 85.0394 349.7918 null] ->> endobj -1106 0 obj << -/D [1102 0 R /XYZ 85.0394 323.4555 null] ->> endobj -270 0 obj << -/D [1102 0 R /XYZ 85.0394 249.9022 null] ->> endobj -1107 0 obj << -/D [1102 0 R /XYZ 85.0394 222.3206 null] ->> endobj -1101 0 obj << -/Font << /F37 747 0 R /F14 685 0 R /F23 682 0 R /F21 658 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1111 0 obj << -/Length 2453 -/Filter /FlateDecode ->> -stream -xÚÍZëoÛFÿî¿B@?TB¢Í>¹Üö“ë8>—´µ}8ÚGS´E”"U>â:ý;ȕDKN¢+Œá>fgwfvf~³™`øG&"B‘¢j"G1IW'xrs'ÄÑÌ=Ñ<¤úáæäÍ;&' -©ˆF“›»€WŒp“ÉÍâ×i„(š<=ûéûˋ]Î$ŸÞ\þôa6§Oß]þóܶ.®Nß¿?½šÍI,Èôì§?ßœ_Ù©ÈñøáòÃ[;¢ìç ¦WçïίÎ?œÏ~¿ùñäü¦—%”—`¦ùóä×ßñdbÿx‚S±˜<@#¢¬N¸`HpÆüHqr}òKÏ0˜5KGõG0¢,¢# -¤lLB¡ˆÁ”VàÙ«Wó¦},2Œ«iZ­VYÙ6¶×´IÝÚæCÞ.m«]:Úö¡r‹–I¤mV»eoÞØïoXà¦HšåkÇN·aØnR.ü¦e›—g[mí“yºênkf½|læÚ ˆ9!H ATyš³9£Ñ´ÈËL[—ÅÓ›eöhÓ¤,«Ö¶o37æ±°Ý$­g$žVMcû«®hóuáˆõÆ›{4ßC;âæôzl™|t´UéEu?¬qŠ¶f”cb ›ê[g¶ymÛY’.‡QÛZuMk[]ㆬ¦ aLßu’×ú.£~;‰£Òl÷®ª÷¿’lû&/TÁ%ê—Äf‰æa ºÍÛò_³µn¸K¤›Ú€ú›ØÓ˜‡PÃí(³¿Ü#܆bÈƶ~³Ä/|ØàüÚö²YéUu÷K·¶ÝäáÌS<ŽYÂo¸Þ‘¥—s]góªk¶d3*ÜðC`MŠc© ëëeV¡j·ñ–Xgµ›s>”;x¬:Gaîiv—Õƒgòâþf„Î;blF)âãpd}ÒoF„‰Ž%Ð'/»ÕmV»óûÒ -¶Üõw­è9c)ÞT¸‰á ¶Q@XÅoÌ ÎèýÁ9IÒØo^ºhþê•mxýË ¾ù›€†»þ >@Âý¾ÈÆ’¤`¹z^–$)%øx–„ƒÆI…ùÓ¼ì: ¼\Ó¯Ød5 ÎcDU¬ÂdÚ«ÿnQÄ$‰&.B‹È¨è߇ˆˆMk„„kc]ätC§Wæ@™^öm:½ØÖì‚%\L.jt5ù´ çÌ…m#ý 3ðærÅ&o+qˆéÏCÎFLÃE¬T°¿)¨]ÿ™Ö‡ÄñLuÛ$Ý0WB7šl•§UQ•¶«#Ä¿ÿÖ.± ?3·×„ »¶rKÁgtkê˜'n?Ÿ9 M§ó ™mì÷qFÍÙFæAoTu…Nñ‚›°ÀÓ|u÷ÓŒ—¬¡÷Æ2 iô ‰uL=H¤Wçå\¦Í;Ûz2¯4ö=à¶à§yßwVì6÷Œ@Ü6›9Þ¨ñH!«xÞÓ¯»úÚÉ„Šàîhóë3ô&ˆ—Ø:¨õ&2!1Ñ›r¬¥â=¸‡¨ˆ!”œõJs -3Ð>÷Èè¢NV«¤~"×Æ(’Šyï£àfçCKÙOºÃ?bz°É“EĤø3ùì -}›Õ ŸTæŒËéõ]æé\ÖKG¡Â•£°¶OêÂ'S±‘ëaØ¢Ûq9^ßjˆè¦•Y@Ý.“ÖqIJÇ`½Î’Ú¶õI«ÎPèûœU“—÷vî@CfdÅjú>)ÿ@;#Y'þÄgãÄ~n‹*ýc3³7Ýí|`ä’ùÃ2÷wRwŠÆC…¬^å%,s@a;n«@Ñyß&ñ'¨¬¤o|{÷¦[¯«¶ünÛ?c‰0–¡ ¼ª8zŽ/1¾DÀÖ¾ôe«‚Ô'P{‹ÑøàWl9³ Ð+qÌB_RC,fdˆ€²[Ë'i1âLjpéRã"Ó>XšH)/!A”ÉÊÔd0rù³J kƒÆ‘®’6]ƒééœ. S -LY;fij©uÊ[h‹»bÌÉ’h‚ÿÔ}AÕìF` Iž29 õñuÖ¶$’ÉžÏÒ¯xÊhÐ ì²×hò<#JöîZWEó Ë¥…s‹Æ#ìAÇv` 0!+Ü´G÷·Y¯_§ôÛÇÝÛmÃc…uAâÁT].Ò‘ÃAÕ¢"æ×µy‘·3BÈt õ|·mHŽhC)”ñ‚H,âæµ»EvЂŽ®Ùˆ—íÑÙpœc©Ìú?b¬Å‘Œè,’ 7ºø#{<¨¯f¥¹ÖQY„Í"Ø -ô‚Ϊ‡ØÆ =c_e"WÂ7éà–C)œö Æ?Š¹ÉjÔù§uMŸ©n®//öX+Ðı¢ÔñS …Œ,äÔB9C\)›Z f½×*ø<“1 ˆÂ hY Äb@õGóaøìÁýË…Y’õÙXgh-ƒd™äê†ic> endobj -1108 0 obj << -/Type /XObject -/Subtype /Form -/FormType 1 -/PTEX.FileName (/usr/local/share/db2latex/xsl/figures/warning.pdf) -/PTEX.PageNumber 1 -/Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000] -/BBox [0.00000000 0.00000000 31.00000000 31.00000000] -/Resources << -/ProcSet [ /PDF ] ->> -/Length 557 -/Filter [/FlateDecode] ->> -stream -xÚm”In1 EOPw¨u€$ÅIg0²Êľÿ6¤¤êV5 oʯÅésÀóή¯ƒÖ×O²Î Ž¢‘ÿ¨#h8Çùø:„5?ùÆ [ÄIÚL’~”F Ø PÈùYÌÀ¹dˆÐzZ8å±Ýƒ²ÙËò‘–Œ€f¾Å(ÌÀE#@x˜oL Û¹[ƒ±ñðù -ä -6\>RgÈbÏWÖ¹j[†› -WŒÏ¢®{6;»²þFÃÇñ÷ø]š¨)Õ/Ô¬Mu;pk;Ì©Ëdh<åE–ñ¬AÏw³ð¬±±Nê¦ó¡Ä½t•‹ùD„™Â²]°Ä(‡;„ ·åŽ°Š­r²ÂÙÄLûˆ T¥Í¡誋ŠŽt’¹w_ =Î]ˆ‹=¦uSä÷—ä"ï±yl±‡µÃ-ËkHsŠöreOÚ³êvg›<7ºt,‡Ýe—;ãÒèЭ/I…B÷&ê(ýê³ö󻉨YÙ¹Ç,çkRÔšÚ'^ m" ^˜h±ÎW9AVªy­Â©/fýÆ"•œãûFy-Sng \Çdª¼˜©Æ¥†Í}B©•µŒÎ$âw1.¶&Øíþ²C¶O–ÃVç X×9g¹E{îÇ< •ãóP)!ÍZÜÅŸLÞª~ÑÔ'¯UâXLµüc“ÅXsЖõÚ¯½˜Ó’~òBL–§èªÆ¹O¦ºNZ_[Èü.øšŠû*]3QôçÇñ!Ö-žendstream -endobj -1112 0 obj << -/D [1110 0 R /XYZ 56.6929 794.5015 null] ->> endobj -274 0 obj << -/D [1110 0 R /XYZ 56.6929 426.5656 null] ->> endobj -1113 0 obj << -/D [1110 0 R /XYZ 56.6929 394.7216 null] ->> endobj -1114 0 obj << -/D [1110 0 R /XYZ 56.6929 335.9523 null] ->> endobj -1115 0 obj << -/D [1110 0 R /XYZ 56.6929 323.9972 null] ->> endobj -1109 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F39 863 0 R /F62 995 0 R /F21 658 0 R >> -/XObject << /Im3 1108 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1118 0 obj << -/Length 2937 -/Filter /FlateDecode ->> -stream -xÚÅZ_sÛ6÷§ÐÛÉ7ÿ $O®ãäÜiÓ\â>µ -Ñ6/驸ž»~÷ÛÅ$%Q¶çæFÀb±»Øý-(1áðgW^O2¯™áÂLæ«#>¹†¾·G"Ž™¥A³á¨ï.ŽþöFeϼ•vrq5àåwNL.¿LOÿ~òþâìÃñL>µìxf,Ÿ~wþî5Q<=Nz÷æüíÏNŽ3=½8ÿé‘?œ½9ûpöîôìx&œ0_F&¼9ÿáŒZo?œüøãɇãß.¾?:»èö2ܯà -7ò¯£_~ã“lûû#Δwfr/œ ïådu¤bF+•(Ë£GÿèzÃÔ1ýå˜q2Q !˜7FniÐxf•TAƒ¸i -àœOóù’¶÷±ÍÛbUTmÜí:_­ò5îŒâFá“™ÔÌk¡³ÀÀ§Y•¯ -zû7ÎœHÅ<*eÖ‰„3‹uÑ4ŸVy;¿ù´,›6Œí &kÿñŠDØÞÈ 3Æ­q݆ä#z]üʹ¬Ê¶¬+¢äÕ‚?7ùu—Q‡wzqSt²ôƒ„gB8ƒ“6ö ÄUiL3L›iÞ4åuÕÄz4÷«ËzYÎé´Š­¶ŽÃªøU 7u"ÁNƒN© ¾­¸›žÇ¥®‹6®S¦FÏû*pªW[‚Ü®Kð‚{zÙ4YJi&tÛf­¯¢Z·dB’ š(Só„|z2ŸwCN몥å£ñ~ÀÔü•~rúCOÁÂú`‘1¯Àÿqáwu [P -Ôs“·Ø²AAHÙ;¢0؇Âü%’I H]mšÈã2Rä9Å‚Èwe{3â2sÌóL<ìœVgqÌeqU“t´Pž'éI‹Š_¥X6ÅÝMA³^-óÓªŽçBÏÄŽY`‰»<ŒÞNs¯" -Œí–D /Ëe}W,Fõç ºªqTY]Ó+i„Õå¦\¶³²z¹9…Ð,Ë291V1§´~Jì„`*̲íØùu³’ ¼×ØA h^±™fl³šu›šAc.ór™ž ¢¼1†éÈòê~Äk¼bJ½æGôàÎhËx`nj80lWņ;¦µÕ“(ŒzþHc-ôÿOt¦`×R‹Çt¦!E -NîXÕUñç”VÕOÓÙ@˜o¥³”ãžÎ2Í8¬3 *B¹Çt¦_3AËzž/qûBq™‚øŠg:“Óó÷_4‘(‰ÉFRsÓÄ`¹+ª¢½«×Ÿé¥¬Úb}•Ï‹c1Mª.ò bY›"Osß@ -}Àt÷t–iÆAÓië`¤zÔÝyƬŽ:¦«0‘?ÙtÂëY ¡‚Ó quQ5ô¬éI6žÎ^H¾Jýw7%&SLƒ42͘õnr4®P„^„ìí0Ez7ýX,#ˆICÃ5«º¥Æ-A…/à.å"ÎÈéq—ßS£…Î8oQÀ2«’¢D/”¸”Ô‘iHõ¿eYTÀ亽iè=81ÒÑÔŒN­-§°KLÏ+êk6ÿH’ó¼)^Œað h2ð!SϺ±Û ¬ZÞPWŠxÝÁI²C3ʾ؊æÑþ`a¶Ïc¸¼Û©¡¬"Šæ¢mBF‡Oíð8<ïˆõ§¶/¢þÈBxɸ‘$L€Vs{Uâv㡪ÓÊ(⑪NyË,·}U§b4G<]/›¯(í ¬’ÚŽ=—¾¢K@pËë~¡pÄZj!f´ÛOÁ½Âˈ…€ìiŒ„,ÓŠŠ«¿Æ.b:è@ØO³ã*·õºíx÷/¿Å*!ix&$çcõ&uüA¸9ùÐV\ø\Üwû Ĺøei\5°È2–qgÑ -clk¿©ÊßãNs¨4¨ŒZÕfuYDuÖwUjÉ×ëzs»OþS;Ú‰’{¢ín%;Ñè`ñŽhTt^«Ÿâµ_Y¿Üy¼~—pªM–J²N„Ñ(&¹Ú¯á•õbæËXô`A™Å½¤Š‡Ìoòª*–± y¤† -ž±ÂƒžË{¢Ä<hùÒXj·õº¡þÄa{¡Œb}0‰åÌX¾sTkp¥<êÐf”Ó¬‹ ñ>HM±þ¾“é)¦3+QMìÛZ§õ»Ãî¾þƒ.Ú¶pki±}C`ô“\§4±®ó+Lª3צ-—e{OìÃåH¼Š ÎktÕ"JÕÆ:YIÏ”î3§ˆ¥×V}Ü®ËâK‘ê…jöúÝÇaw³Y¦û‰Á½ :eœBjD¨:Pc:Y°¾´ìI5v§d "ÙB¹K€¦rè¸Edçoøâ¦eCÄœ^/NßÓ{SÏ?ctÂ6†‚¢¢jÆ䑨õ¶˜—xÁœcÐÅ2Ãô,ow“<Ø 6­$Ã2óPUÕ'W ;tn<µÎ:Ž³!Ë}­°†„Ú¯Œ†Ä1â^‚qoÓM]8%O×A“Ðu dFjõítÐq|Dƒ€¬¶tó¸T:†•ŠHŸÒ%ô®wâJ¸³’Î…ˆ&Ÿ¦÷X*«†H±ÔOˆ1ZšÇ"™€ªð b¥Á VÛ³ŠeÞùg+¶ã8²ÜW¬4YMæû•R,”˜\§ ¡wJ­ârí°rÌAU¸ƒ“x'x]6Ÿ 3¡†ÃÁ݇R+–8mˆÇ¨þ†žäÞ0*ÙÊMïÊåbÞ_¢={[½Š÷ó Wv;ŽB ªŠ9f˜ê ² -™IS²J>Ÿ·-%<ö† -5®èÄÂ¥ÂpU›é(dà³SsY§§Ç^bá‡ýÑh­2`J^ì÷:‚Ë˼À«k.­#pÞ²ƒÞ*,„J™™‰Pž Úg{kÇq6d9r£`=„¨ºay+6šG¼5ƒS‡¼|9–¥¢"Sí7ÓüìŠÔw_o°ò÷ÉGÓ†[ñkÃÎ<}•ÉGA‚6Î ¢82$7‡ÕbŒ4¬X;£†Ü·3²¾½Ì矣µè4‹ÝA½¡øÙWÞÍdI&À~bDz8Èu_”êõ¸â5ºSü›„Èù ŒB@R6C ƒ ðR±HWúët}ð{¹Ú¬†™oÖˆ³„ÆÌœgšk›ÐLXäüjû‚•ª³á¢ƒúbwŒ7j{0"GF‹ºo)ÄÅoCRêõ@Æ‚¢#…Qs0Œæ³ÌN£ÇÀ2Ý8á7Œ¢—¨WÔˆw -&\÷ hHäõ.xø€«ŸÇÙåŽA²Êú•@AÒ‹ðrxa3Áp3Ûøõ"ÅÓü2BqŒ¶mŒÀeÓlbÅCŒGLLCoº[…ŒélàDwÃØŒgú¼K"—÷}x)-´†vÿ‘6ÜŒ„ ÖK' ‚ÑrªÞdáPS†ÎÌêtÖ¡4Ü„Eð ´g¤Øù&~:ÌšÒ(*fŒL7wjà#¡ø0lðÅM…Û‚²¥4¯—yôZI€Ö¨j‚ Â|‡OâµÉ÷–iåäà·Ìì7Àñ‰álÀqÆ{82ë–EécîÞ˘õÜ}3;† ¨¸Fæí–„éß »L3ðVßgEÖ»¸)£ñé)S4VÓ¦\Ý.£uÏߧóÈ1A‹2v÷ë{g}¼•ãr‰á3}±Ådû*]¦Ü!o 傾w÷=è­ãÜfk˜’ÏWvÇoÖ3ƒÝœyØsZ5DÛÅ8üp¾K”Å2ÜÙDͤ?,Œ€JJzñÈa°àÙ·Û}ÇïÁÝ« <Ínï~ô(ÀêÌK¯¾™x‰ßƒâiþ(œŠwèXÀ1Ö&%ÿ6P^WñÏ vè?WÊ0ü£ÔÈ?¤øäѯÓOý?Vÿg5 ØÓ¹Á}µs}.ï£P¸!eö¾u¤?ní‹þ_üägJendstream -endobj -1117 0 obj << -/Type /Page -/Contents 1118 0 R -/Resources 1116 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1093 0 R ->> endobj -1119 0 obj << -/D [1117 0 R /XYZ 85.0394 794.5015 null] ->> endobj -278 0 obj << -/D [1117 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1120 0 obj << -/D [1117 0 R /XYZ 85.0394 752.4085 null] ->> endobj -282 0 obj << -/D [1117 0 R /XYZ 85.0394 683.64 null] ->> endobj -1121 0 obj << -/D [1117 0 R /XYZ 85.0394 653.5261 null] ->> endobj -1122 0 obj << -/D [1117 0 R /XYZ 85.0394 576.1881 null] ->> endobj -1123 0 obj << -/D [1117 0 R /XYZ 85.0394 564.2329 null] ->> endobj -286 0 obj << -/D [1117 0 R /XYZ 85.0394 417.9499 null] ->> endobj -1124 0 obj << -/D [1117 0 R /XYZ 85.0394 388.7174 null] ->> endobj -290 0 obj << -/D [1117 0 R /XYZ 85.0394 267.384 null] ->> endobj -976 0 obj << -/D [1117 0 R /XYZ 85.0394 235.1866 null] ->> endobj -1116 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F39 863 0 R /F23 682 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1127 0 obj << -/Length 3451 -/Filter /FlateDecode ->> -stream -xÚ­Z_sã¶÷§Ð#=sB €äérñ]i|©íÌ´“d:´DIœ“HU¤ÎçvúÝ»‹(R¢l§—ÑA`¹X,öÏo‰ ‡Ÿ˜èŒe.uãÓ\èÉlsÁ'Kûp!Í4MûTßß_|ó^š‰c.K³Éý¢ÇË2n­˜ÜÏM2–²KàÀ“woÞ_øåöí¥QÉýõÇ›Ëiªyòþú¯WÔúpûö§ŸÞÞ^N…Õ"y÷—·?ß_ÝÒPx|}óõ8zœaz{õþêöêæÝÕåï÷?^\Ýwké¯Wp‰ ù×ů¿óÉ–ýãgÒY=y„΄séds¡´dZI{ÖwëöFý§£úœ¥2KG˜Ê1jÇ2 C¨À·¸ =BàǹCþH±¯Ê/¨Ï-M™‘" D³ºjw—Â&õT”šd¶Ê«ªð/YR6Ô™Óã—›ë¿ÓÀ¼ÞäeE½M=ûT´Ô^—M[Teµ$²ÞÑhh.%`¹`píßÕë|W6ð‘zw¨´²iʺj¨Ú1¬NsûGt}˜.÷ö¦Ì·Ûuéw©Y°>¢­Z˜—ô>këÝS`м´¯¾>EgmÐ.Û¦X/H]BBLÐBFuQ$<ˆ ª\V5½Ï™ÿˆ±cBO{ï§È\²Ý•›Ü‹/ù¾]Õ»òßy[zY kS —Í_Á¹ÔÝÆïgõfƒÛH/ËËw@zº3%w**ýSñtI¥Õ̺ÔN W,ãξ&–¦ÌYkÇ#é´ã8í³¤09ÍZé%;ÌŒ"bD1¡˜„xÚ9ê4…Dñ¸*g+ÒÆEˆpA9=¢ÇW1Nù¡lr•ƒzFŒcwçmBHËœ°âÏ[oÇñ…cÔvj¢ -jz_ŠÙÞç x $|R†<Öé æXàe‚)ÝÅ9 –Y çÁí–jÜŽ¡Ï>ýyðÔQáR½-6”þLšÜä>í™üCwE½ïòàÏ$3c?=ÕšA˜’ÙOð^Gõ‚È°%B¹Ê y -5 ؤéãH"˜°&¹]5ŸAΔ‘†„ -`²Ñ _c>:©ê±à’B0¶Ðëu3-pÖî7m9@™sá¹%8ÑÀÀuVE®ÀÆb#… -Q=–ë51oŠ0 OÿÌé1/ù~Ɔ‘;:¼/ýŠ^ Lé¦`¼®·ùìS€P€ŒÖG–Ïça•°hiU"Ràb_¥¬¾Ð5®þœÑجÞWm±$ØÒÐ·ß -ˆQFˆäº"’vU†ÏfyS¼!øÜñÌ×MMt«¢¢¾3à ê7‘éW쬂ü º\ÔÛY¿ˆXú8tS®†p²·ßX:©äaóºðåš]èZåŸ jåc&Ÿ¼w²—Ø›qžfT cÌÒ Rãö†åžŠ×‚¶AjŸR4|zVa\‹/‡RVù,í¿Z-n_R(€âYeÖ -+Ô ^PPDO7„r+zá€pœ8n’>ÀŠ^xE~S´£‘Ò¦„®Øáü8XXÇçXGk4ÎÞ †“[`sÊ?Kaõ:ZÜ£¯z€ù°H†Ž8@¶Ž­pö‚}qða_®[ŒÓX°Ãûý¥K“šÆfdŸ9e_ o 7–ÿÌf樰|^ËPšÈN=¸ko¨¤Ú]ÚdÔ®lßÖ`Ù¡8d>Eý,qa ëdšLdÄ\i†!^ ®æ™1àf,ÖF6öDsó*ÃÉœŠ1wÛw•¢µAÙÖõ:§:ýpÐÕÚp]^5eÈ“ÖQ]ýt¼ö†ÂöBË¢BÃ*éR$¾Pêy¦¥ =>¨x½ÎR¥Ž\j^.Ë6_ãQL o·0 ²œêi£`ÍÍÁ©±·sj|Ù@ÄÏ—ñÃŽ¦]íC——»¼tØ çÉÇ‚”2,SJ¼òãîÇ}ÈC\ 9àº%æ›ü‰…ëñÚ@®… =TǶnšòÁŸsÉ€µ¥IöMèÈ+z_ OR–„á°)Ðoéq@9Is8@‚2ð‰_R -û -5º,渻ґq¦óÑHãŽ+ ÀƒL!=‰  IM4øÇz÷),5F^À_L(+†y¬!T®ÀÞò§‘É}©-âŒO ¾ÆMÖŸÚûðôê€gP‡ -Ö á¢)7ÛõõùA ¢Ê‡´¯â)Š:œ¢œÆ–2¸€þÇ‚ ”lB¥qMù¢õUUOL»r¿úW{ż§H@†õzü 鮬f¤¶£JA!ª»Àó|„‚Uc -¹{ÐϺB}J.@.€zóbf¯é ’Ö<%"¾G:›ƒâ6[0kï$HµGŸ¼ô$á—–:@ÙSR•“Ìà©ÐI^ï;‹ ÎÒ ( ö/t%cÄ“.Â(IE0²*—«@],éã‚F|Ä•®ï°åºlŸ. NÀ%ÿðùr(!ÞÑDå›Ò§¤S»e˜6úúa­=Ü¢–G :âkh4P臡Å`Hº¹¥õ¾›DñäeCŠU½_Ï©#µÆR:Ø.¿Òz«B‡3+€V²ƒV¥¿  YƒðõcEnåb ™†ÏšÉØÖÁexÑ =r™N‹~áuÓ5ÁÛñØKb<“ÈñÀJÔWù ObN‚¦ÖQ¥+ŸÎq%mh Ï™u,¶°±÷ÉWc ÍC9Ù`gévalkuׂ:ûeôqä!šr‰éh´‰3žFãŒ3—viót¯E‡t)ZÉÐB SäñêÆf>ÿa'Ýùøβõ#¨Œ†Ž°ë¼­)Çé*YvØhG°n ©4¸œ§ñ©†| -BȤ†µ‡%ãâCÉåS ^Fçc6Š8’ªðÀÙÒ¤ÖÀÇkàxR`8òh&¡¥:“TÏÙnþ²FyFË€Ÿf Ë3nh2­Ž­Waæàò¯9¨‡^ûãx Íó‡ø­O©Q8ú!*r`{}.šwVÎû§ò¾?ÜšÐùæãªy¼ M<ÆghÑ^­Ä¨æe$îÏr¨-ñ…`è›N€À¿¢'«c¨%Åc$½âl ‹éñ À·cæ…Ç@™å)ÔYž ’t9ZøæȸõßY+SŽgý*ȳè6/CtÊŒ“Á -K¹Îº{}9œ#L™­÷ó ¹»Þñ^úïrÐöXQËñ ´ u`‚¨jQ® >ßIÄ£$¦“${…$?hûU¬šü&#øÅ‘Sít"ša!x|ƒËà9J0b V$jä”OjDzÅÎg £;4†U»ì]¥Ã`ÞQoë2²{Ä ¡ÎÙË08gÒì+%BU8ëßzN%Þ¶[a‡qá¬"µ|8]ÏŒˆcM²Èg˜ ¯üwÊÄù¦¬ øêÀ"Þ˜/hì´ì²QÙ QП -­qjˆ>û"»‘zG*À‹ ëäP»’x L$ð«Ã½=öl¡^ôÕ”Óü]ž1É{D‚Ø[|É¡âÁÓ¨å"׃CGŽ¦¦8Ò9 öowågŸqðáHš(K¾7Ü#õ(A€OE ÃIuýQ,÷b‡'^FÇžO7ÁÓbüÿãg§âé¶ÿã×)Üះ†×ûëe ›¶Ú%ØlÑwC]ÐÞ"ÜFˆwL6=âKÔÿ=ã4d˜ŒÛnåö…•M|³Ï¸eÊÁûÓ£[áÓûmäH„Öæ¼`þÅ#ÿhVÁœæá½+RèÝ/þv>9cƒJ lÝß] ÂÜæô.R°“¥cð)^¸Yëȧ=ú‘ ­c®ƒ{5GAr<E¥†i@¬ÇúäJ­#z^€^‡ 5œ=jŒ‚BÊÃ.ê}‘ê¡}ÙÁ`ÎhSÉR œi¸ýevÔÓùéRŽy¯(ý¤œH’€6™êIr¢ËŽæùù8EM²s×Úø/ )Çfäõß·âÊàEzæ†×X¦,0 B¡ð2;‘<þ?ñTôÿ¢8Šþendstream -endobj -1126 0 obj << -/Type /Page -/Contents 1127 0 R -/Resources 1125 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1093 0 R -/Annots [ 1129 0 R 1130 0 R 1135 0 R 1136 0 R ] ->> endobj -1129 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [55.6967 676.8938 256.3816 688.9534] -/Subtype /Link -/A << /S /GoTo /D (rndc) >> ->> endobj -1130 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [268.5158 676.8938 332.4306 688.9534] -/Subtype /Link -/A << /S /GoTo /D (admin_tools) >> ->> endobj -1135 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [378.2799 73.4705 428.5017 85.5301] -/Subtype /Link -/A << /S /GoTo /D (tsig) >> ->> endobj -1136 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [112.234 62.1828 168.4527 73.5749] -/Subtype /Link -/A << /S /GoTo /D (controls_statement_definition_and_usage) >> ->> endobj -1128 0 obj << -/D [1126 0 R /XYZ 56.6929 794.5015 null] ->> endobj -294 0 obj << -/D [1126 0 R /XYZ 56.6929 403.8784 null] ->> endobj -1131 0 obj << -/D [1126 0 R /XYZ 56.6929 377.7405 null] ->> endobj -298 0 obj << -/D [1126 0 R /XYZ 56.6929 339.6466 null] ->> endobj -1132 0 obj << -/D [1126 0 R /XYZ 56.6929 308.8302 null] ->> endobj -302 0 obj << -/D [1126 0 R /XYZ 56.6929 236.1221 null] ->> endobj -1133 0 obj << -/D [1126 0 R /XYZ 56.6929 207.0192 null] ->> endobj -306 0 obj << -/D [1126 0 R /XYZ 56.6929 125.1654 null] ->> endobj -1134 0 obj << -/D [1126 0 R /XYZ 56.6929 93.2531 null] ->> endobj -1125 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F21 658 0 R /F39 863 0 R /F48 885 0 R /F14 685 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1140 0 obj << -/Length 2602 -/Filter /FlateDecode ->> -stream -xÚ­]sÛ6òÝ¿BôLˆâƒàÇå)Mœ{WçÎqçÒL†– ‰S‰TEÊ:_¯ÿýv±ERpìNnô `±Xì.ö K1ãð³\3®Šd– Ó\èÙ|{Ág+X{!Nì‘â!Ö÷wß½SÙ¬`E*ÓÙÝr@+g<ÏÅìnñ)zû×7ÿ¸»º½Œ¥æQÊ.còèûë›RÐßÛ7ï®ßÿ|ûæ2K¢»ë7¾½zwu{uóöê2¹°_: -Olxwý÷+½¿}óÓOon/?ßýxqu×Ë2”Wp…‚üvñé3Ÿ-@ì/8SE®gG˜p&ŠBζ‰VL'JyÈæâãÅ?{‚ƒU»5¤?­r¦s™(UHº`©‚%TàÝÚ €*¨"g™à9ÐGœ_Í£ÃQcœ4Êá´]Ù™­©;ÐO¢yYÓ ™Ï{–n­ƒ#a £®ÙdcÌÆá/GH@©©á\®û²«G!‡Ð8òUÝV +2)®™–™ê¡2Ç€T..ãz*Ø…,tô7óØÒ ãîY¬ÒŒqÍÁ|…`…ÖÒnDk³\…œÑ?È“¨çÜeS Üá3/~¦ñ–¨“ÊapoèÿÐŽÐQ¹Ù…oA&’8™,ZgêmÒÑÒ*–èŒåiWfš)‘%Ž9¸µnßlÚ€`­¹ÖâÌn¬6ÁY¢µžjSóÖ˜©· ž°Tèl–)Í2) -´{Zܯf4¸8J7œ;Ê9]d⣙;´¡F²äŒ ¢%€>$æ®=Ös\œQsªÄÂöÐv4²ÿ s2;˜–n™\ Öß``‘Æ3År.Aá’3ÎÁòGQAOíÌ}l£#H ñ'Mg™°,'/ €’yž‡Ã_ÜSŒ‡$­²Æ¬IÍ’B'§“‘Åjò"gX$Å+4ižÑ60’YôkÝk–-ý“q D†AÕåÖØ2ªRI+‹f[Vn?bÑèPW¿Ìæ‘f¦ê®Z>VõŠ6BDÖ5etݘ\÷žº¶½> v(„ûË×.Qi^x÷3û³y)XƒànãEˆyÙ‡†ý¥È#2¶Ž4Pž¢wëÒAÜ©m†Q öU«>p«ní÷V.HyYõç‘R}ˆ[,ˆ—ÖáoËn¾vÁDOeáuEĦ"–óŒXÉóxƒÛq0bFU=o¶te€3Ö×僡µ{cj‚õÂÀØ ë%Èš``Yì);Qó¬·²¬k³jö@`ëç5Ý?_|kæÄXÇüòón i¦¼[÷'9w -. -†“BùüÿàÛŽ`<¤píT1^dƒƒŸvm ª©“Õ˜pêÆ¿¶Û[ã˜n5kwf^] -›°MK0¿Á@éRuß•pPðع«@,Q¯&pÕ,UÑ ÜÕÂí;ìv;s¹Oc(иàb|këm9· (ÉX.yÖ«s’ît_7XJíºRPIB鬞#•OHI™ˆ¥ˆ«’?Ë—Ôé“ÄôŸ%¦ò g5Ó¾,u~2!'`˜%zBO ù$= ï>^¿‡Ø,ÀH±/Y ƒ*•ÃÊÐb0šKÝ]âFÙà”¥í Oj•ä¼´à̈ðTtÿHàr·ƒ"¢€]rW„¦j{ØR}ØÞÛ ¶¢Ö§]ÑÀ“­lü‚õÁãP\™* AËGa½ -§ `ÿf+¶beP %§ç< íL°LùÚô–@n~"j¥ÇÒ>CAà3Ý4d)‘² -æT*DEñÍ!ËŒ‡ÏC–Ó…ÈOSµ(Xg:׃°…š¥›-Ä ¨»…ÆÝ„[wuþànÜV>LÖV%T{ÊÆÜáí¢“ØºÐ…"ç”S%„ÿ®à,[§ M äÅ…G$Y_wôÇ,ѤɸÌèP¬ áy. 9E›fµrÍ£ƒb_Úûr»-÷ÃÂä–#ç¤ÞžH -·ò -XVø0Jû‰0æë²®ñÕ9˜|¡Šm@Àí¹6¾FiYmú®ÄäŽ#K÷âÕc t8T-†–f'‚Þoqü_ú;Ô›j[Ù›p¸‚FŸCŽêè·ÕÌÙ2ÝpgÎÚ>¶ Ïáø˲œWH‡¡cý®naöû¯ Ô‡Íæ$Çë!ḃÄ`1‡öŠšÃâêf¤$8µ«íXîëÞüé ì4„g»p3)ž—ÍhÛÂÜ!Ç•ëW.G¨pýÕ|(âPã¡ãÉøMc^uâ>g ^¶ºy¼{qNi¬¸S -ðÔUÞ'ž£2µ("öÇ xËígϹ£ËMg¾ûztYO®3ƾ‘{¤@[Cæ×O„AIA&}üqðzÜW§D¶nË• ä•I€ ·úð} 2Ÿ|<Á$%UqÞ¶‰•ÊM:z{!Ô¾spñhÛr8z(÷•A›Ä Ö%ˆÕ m»Žâ"Nl -6Ÿ!.Ý!‚Ü2K°Jо•ÛPÓÞ P›øÒÑýsñ ŒË˜ÎòI¼Þ­÷%½q1 ¶Í¼¹[ê4‡nwèhmkºu³h_ћߖn¥—ȶì•©a\Ù'刯zöR‘¥¸o$(Þ¿¡…o÷Ù:Áè -N݉[»¨k ”U0®}åÜ»dàQÆÜ«´×v• VfcæÎn×Í‘xùÍÁó hÓ¸ U¨¨Ä-Ùקb˜<Ã,|˪`Y2~Ù~¨ms%I¢¦‰•G‘ô<ÅÊ3¨’<Ð÷Ò¶³ŠÜCœ'LÎtŽ@4Xüo¬wàÈÀ ÞoªÖ²Ž€£8êéâÃÕד¤ý¯KwŽm|òä®Ü·Ö„5ÏH2¡½d"r” [©­-=Xs ZÐQÛX>pD“h¾Eþ¢ìÆeà[qôgŒÄø)Ö;ØVw0>õS1÷j–H1ù–aï{ ]¹ï\ÞK¢Ãu Ý'¥Ô0-&ƒÈ¨úf늢ĢGjë®ü7± Øu[°=Šÿ.“ªÀ¥ªÓg5¯·£íLzç -9‰ s.:ØÞì0-tù×îíèÙtïÏå$¬üÒwŸÆý›T²ôÔËŠW϶ù-!bj7ˆIþ]k»€¶H9&ôMWÁm*ú¤Ãûþù{ïécx–›ç2ümHñ”å²È> endobj -1142 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [103.6195 731.9163 159.8382 743.9759] -/Subtype /Link -/A << /S /GoTo /D (controls_statement_definition_and_usage) >> ->> endobj -1141 0 obj << -/D [1139 0 R /XYZ 85.0394 794.5015 null] ->> endobj -310 0 obj << -/D [1139 0 R /XYZ 85.0394 589.1911 null] ->> endobj -1143 0 obj << -/D [1139 0 R /XYZ 85.0394 558.8491 null] ->> endobj -314 0 obj << -/D [1139 0 R /XYZ 85.0394 294.8462 null] ->> endobj -1144 0 obj << -/D [1139 0 R /XYZ 85.0394 261.6947 null] ->> endobj -1138 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F21 658 0 R /F53 962 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1148 0 obj << -/Length 4109 -/Filter /FlateDecode ->> -stream -xÚ­]sã¶ñÝ¿ÂÓ—È3'?zO—Ô—\Ú\Ò«ûÐI2J¢$ö(R)ëœNÿ{w± ”!Ûio<‚ X,ö{!y-àO^›$Jr•_§y!Íõrw%®7Ð÷Í•ä1s7h>õÕÝÕ—ouzGy¢’ë»õh®,Y&¯ïV?Í’HE70ƒ˜}ýÃû·ï¾ùû‡77i<»{÷Ãû›¹2bööÝ_n©õ͇7ßÿæÃÍ\fFξþöÍw·¨+á9¾z÷þOÉéqaÒ·oo?ܾÿúöæ—»ï®nïü^Æû•BãFþuõÓ/âzÛþîJD:ÏÌõ ^D$ó\]ï®b£#kí õÕß®þê'õÚOƒô“"R:Q*" É£D+í ßK ‹bv·-i‹ËmÑ4eM/?nEWâfaJ=šR\ÏÌà&{Sóu»¡F{ì÷ÇžÚ›¶ì¨Õ·ÜÛðjíž;hÈlÆKÅãã—I*p׸ã×Ò&&ãq¯iâ‡öÈû*^ªøÈ‹ƒ4ŒÎšñÜ–»é?Ï©hú¿~Ê#i€!¡eÈ ßÞ—œ.IG´L’ÙªüYÕT}Õ6Ô½;v=õUͲ>®Jn|×WM1 _Öű+©³ß=A»â¡#Øi[Þž»ìºbc鎃ʺ\ö圭°ny|a7*e”#ÇT†1™ó£gÏOD0Kf¸º|/y<í3³}qè«å±.ôÞ=tÄÐ^˪®ú‡)åììóÞ²!~Ðͪ°L±¢åʃ}kÝŒ=qL±ã)\GÁœd_VU·äYÊ{,Íì]O"GL¶®ìÖÛ=’¼¨ki &5u<è&÷gcm+ú6°RÑEXG…Ö›¤¥ßöãÉ PêédÎÀ·@û3  ‰Ÿ+hzÁnHäg—7…z!å¦;2i«èO«L” sˆçÙ#QD£Ÿ{ñöèƒMùÇMl¤5É°@"‰€Ò™kP;90ïôTFÚìü±±†(¨ HŠãÜ ‚ó-È_‚†sªsçücçq·° ´­¡€§[·’ôŽÁA3“.2·dWý2è`÷㥇ô/ÍY9G©ëÚeE~'âwªÐ¶Ž<£„ãÝ|†HæÂñ|ª-HöÁ…8SˆÊö"ÑfÛ¨Z+‘ «H„± ” Vº%Ï’8MaÁå§eY®º³«fU-yC0)!C§³÷-pÛc‹v%M¯ÀPkÁ4ûȯ½ûKòS…~Óæ,Y0ìgp¨» -ô>Vìag« Vû¢ÿœy#x™²ÄœsFkŠ2Ƭãà†Ÿà¬¨Û…=ÌĶi­;ºT®žú-&™¤"÷B¦.PÉû@ŒG¸åNÎ.à‚ÜÂ脼€—‘¦Éóî4~ÓÖ= å«“È€ó1=æ®o‘4°!„Ktrš3.æB€?Ahƒ2œÚ/ƒZ0 (¯¨ c¥^àH\©ä\dqÚ±¨j/ª€bÕ#‡ Cº<‡C{¤Åô8s/ÈÓ¯†XœäZèH'™š -öˆGÔ0‡–’½­kbe“Iø„èay¨¼hïù Ž®• -àÑ”'jÀF%M«@ä7Çõ`n˜©¬ó2¬¬˜Uáû6Ä)ˤ™y‘ãªr%'E -£ii…];^wUôGàÅ©8ó ÙäÙãùª·^‘  Â>·ÜKÒcÓWüe×=öóv=_Õ°+1ªº½f; nÇxþÃMS¢*ì.­èp!f¦1጑MwŧjwÜ9FÊUŽ’«“ÔÁ¢Ü÷•‹o/&œÇÀV¡g,ǺôLSÆ”™$_šÆ9mu6G êH¢b¬gU©Ìc7È{Gç*Y›T¿HÊA‘M¹®ûcÀšË4cˆ³©EðQv"ÐöüÊ1įø¿-…”ŽrÌ×OÎs]!‘pÐøSô®þ@ Aeà›¦¶”ؽñÈþP5ýœ"V÷Pv¯Cá)RX“±ó ºÿyNÐk¥v>m$MæSœ£ ˜ 0,¹¼gR£<“š¦>Àž’ç{£^X»·)wh£'{ƒöhöÎÍÂIŠãŽsTŠ}4«'ù{vÅ4ç—A]ÚD, -ò`ÀG*µéúõƺâ[_ŒøSpðã<~–`*ÿÉÅZ»‚ç܃Äa|+’ÙŸ›öÄPN‡W%GÚŸ2=®b'í%ècyhÂIAq€MÓ‘’Ò!'we»@V“T½t–]QÕa­{t/NâøoU€ªíÈz&*{)2Ålÿ%d^¼¥‹‡«²˜(}é<õ>H_=¹¡y Ì*Ð×™0+¸!… j!ÍÅS(™Œ€ãÛãq¹Í¢¢$‹³çfqnÃò<,àœ\™—¢‚g*ï>tê9úñKgZ÷ûKtò¥“Ôí²¨CQ´L„ú]óÈÿ}3žG}&|ôgš'þLû2Ÿ Ÿ$4Vf}Êê¢?'>}k§J_€Ò\%óÛ6b£ÐI`®/ÖSKÎéê-r¢ém‡7à¥;î÷ís rFÆÕŒ b,Q†Ã­Á´Ù­gßRŽÿ¼²æÊäƒëö”}Ïü9ùk€Å^Ռ޸V$}­ˆËøÜrºÜŽÌlrHú¢/xššÝxl|-¸¡gØøbéP¦FO¶-ÛfJ¿‚JTrb‚qf6ÁX£²ñ àÀ•}8Óâ¾$PAï”@û´­lÙz¹’@Çè²fuä ÁK»ix™€ËšŸ¥Õž:#•zmÈu5{“Â%IZàÇŸÚquŒÜ¦³Hœào÷1¡è`MË—!Wm/A®!¤â‘×h\Ë…7ÞYœ¤zj@Ðí£Ú4Rr¾cp8L“¿0vzÆ—yÍ"#ý¥•™ÚÃGfϺúô3ð$|TüBGá‹Ž¦ÿY©,^{°Šß^ ;J£¾6Ãò@0¾À» 6÷GOJHa_µ&3u<ÎÓ 9*n'q”§Ù™ÖêúCQm¶¸ºÊ‰[à‰Œ®Gy:2¢Ë&8lkqƒÖ±ãù¹®Y$³ôw:W6s£gߺ–p’¨òqÂÆÎåg]7m„«]” €ÑM ;’nj@sSÝ—¼—!7fÃÌ$?Si>R_¸¨œnÙ¬ž©\¿vÕj¿«Q ¾â—7ŸGóˆ$f=ZÛÝ"¹XØŒ%6±á ‡/G•.pºíþ{]âyL•Ý†ëàˆ,$õimn"z 5ˆÍOÔ°û²¢Û»}yØU ïñd -[@Ŧ?Òõ|ß*NR4p¼:/å,½Cy¼ãfkkòÒU'ãIuÒø^TæÔTØÇEÿxdñW0ttÁ¡Ë) Á†TìóFU8…¥ã—1S<ŽÏ\FRÓlª‘lb‡-ôÌšLõ›„,NŸ¾j¡y¦=Ë_ôJñŽ«p*¦Z–á Rà²éQQ ]0ú+bØýÞ›P¥Q®³lÊÙ6y,Üý! .ƒÀëiÈ) W¶BϦ\½¢ò„M³ö` -y¾!´wÀ}W€á0Äy!Ç0ŽR;F½ÌI˜ÎV>/CÉ`ãT.p¶ÝU~©Àþ8ùÓlYh[¨¢$ÏÌÅ©=Öll’õ¶SäSsà2¾œM+«{oVèlwaÛÌû^ö”Œ¯Ëvý -/X†#©X¥ÁäŸÉGžS~–üK> endobj -1149 0 obj << -/D [1147 0 R /XYZ 56.6929 794.5015 null] ->> endobj -318 0 obj << -/D [1147 0 R /XYZ 56.6929 769.5949 null] ->> endobj -1150 0 obj << -/D [1147 0 R /XYZ 56.6929 752.0323 null] ->> endobj -1146 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F47 879 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1153 0 obj << -/Length 2579 -/Filter /FlateDecode ->> -stream -xÚÅËrÛFò®¯`ùb¨J„çÇÀ>9Žd+µq²ŠrJR.’¨ÍånåßÓ==äX²k[:pÐÓ3Óï—ø‚Á_¨8d2‹i…1ãñ¢Ø^°ÅöÞ_p‹³tHË)Öw÷¯ndºÈÂ,Éâ~5¹K…L)¾¸/ Þ}xûóýõÝåRÄ,HÂËeœ°à»Ûß$£Ÿw?}¼¹}ÿëÝÛË4 -îoúHà»ë›ë»ëï®/—\ÅÎ {ÃÜÜþãšVïïÞþøãÛ»Ë?¾y™òË™DFþ¼øí¶(í.X(3/öðÁBžeb±½ˆbÆ‘”R_ürñÏñÂÉ®9ê“_,U+‘z(¸O€q&RH#À®) d) †./42ÇääX…‰Èbx ñA@R&ÁýFÓ©uÝ>ä5­Ký°[ãRµþ¬-´ÈZäÙóÜ8¨G¦I@V³ÎÍoy| ¨šÉŒ¸§Ç”#„TÑìrØ2|€]¥`G»Â}5l<ž+Ê.uÁ¨<4ù¶*|AK†œK‹vT^½ë53RèıþeO{G¢¥Ó7‚à -Á‹TO9î¶U£É ÷£›L¢ºOK¿]Õ€ƒ91N üvåCQJrË9»4ZöÈA…*•‘EÝäønÄ!kŒ?;†R€¶ :b$Q2nÛ„'Ø+óÁ®(èàž1,‘ÓÅô[·ëµ.CŸ -cä.Ž¿úm~˜>2 /Ž Ô’(TIÍ•’{ÈI!½&Ž˜þÐá¾@ÏC%™E³AçʦµÝ@éª2JMÁÀvy]øØä+¸×W͘I¦dðR’YýJBòºoé^#Æžž$Ðê,v‰@(h“¥߲xÄB¨BÒ™v -¸gÝv=I¦‰t™$@y4J€&æQ”âÇŸ;ݺDá)î, ¢ QÆÁøšù‡¿ã¶u :d Àv› ÖÆÚáw¯kŒ2R%ÁMÕݸ¬£DPùä #*ŒèS9ŒqÄ#‡(L¹šÈˆoì†M ‹÷K.¦¡ -¾\¸¥ ýœ1G9à‡M#°z°ç€Ë(£jÍã‰2 ¥H¢ÞDµìX¶CÕ6½%"?ÌŸ…àZÒÊäîòŠvûÒÇÓW6t¢ÑË8;ñRc«2vÊ…j3¯÷ù¡'¨Q4À ¹Ú¢šjJ:+ÝU[×ížj/€SÅSêî5ФqTTGss&!Õ¼8AËaIðAÛª‰´Ô˜ÚÞ³‹%|3ÁEêk_Q1lÉ«_2‰ŸÕ È/Ù©fL6R€5Dã+¥ qýcã5M8B-oôÃ2-£‡Ç¯YüZ‚?$’ kÝè.¯A–øÖÇU¡ÝW7+»å—K·û‰”9!8 ¾]GàG—ã‘ ->´{ƒ‰èT>-Ãa+*:)#, ¶L£º/ºêa7§-(O±_Ñ"f"dèÞÐ Òf·^ÐânÒ=ŽøËéê§b8¿ üEht®ÿ)BqJ¤æPbÅ;}ᬱž!äü6j¾<Îc )Ñ=ƒÕã'›qŸë¦he®·móì^¢á¿ze» WX݈9„–så…Žú#Y­se°ð\Uo4 èdKœè°q, ‘ʲ-ìæõ&«ì p¯¢²bÖ„^1µ«™˜Ù["ɵåo /J­í²ÆëÔ±¢}í‡Rq0w¬ -æ#¸ëü<Ž=§¬ß¤Ä±ó¿npnu~T’ô×ä1ÔÀjû¹âsoàO³WO°˜»þže¹"¦ïºÓ‘üÝ»!'Õ¾ Ø8)+%±MÅÿõn¦¾ÕíÔwp¯´ôÀùÅï›ìkÀCà<¶ê®MV­CfzN¹Æê8ÁØeñ.¢ŸÚôœìå8­ãq|óxÀ¤ˆ¤\E ‹=Þ®ÇY-lC–ç—ÌEa} ëéê…ÚL0=uC.Û Çõ å9Ö1 ÇÃÈe'*ºþ.·ã ¹Rï“,Of9\–Ò«b:>Ì€¶ ÇTéù&[WYYX®rÑ,œj»V{c”æàýa³Jpz;kkW/‹*É -6ÐuÙa ÚZ%Û&¢X£IS•öíhQWuWÆ®È'j® jÒl¿”çn ˜„ X ƒ'ó·˜tå^1ÿÿÍj6‚µ äê0ï€æ¹ Ë>63ú¢&í¡ ¼ŒaÍ8Úµ -½ê¼Ç{¡džÊ5´2ð_3å©/ä.iú¢S Ù!ª~5½V4%Ü¥ ¤–±á VWö%¡Æ¹!ï¾?ìê\?Dç"² ¸úÜN+ |»«7Ö8‘¸LôPˆŸ)U •ï]ÃñÉ|xˆ_¦64¨£&‹gˆlf¶Œ”qœ°¡Òçú*Ô&ÉŸf <6ñe¾œ@ÀgXårçÚ´8R-AÝšžueÊY|´ËTF@žhm´†îhÂÊVødÈ4v틉 EÚæ‹í^RÍX½¶mšµœ#Êí ö2Mì+×MåØb~B¹.œJ¸”BÒ¤JfÃd_»×mÚAÐSð!H+èÁH4UfÐTˆß -·“°§P§Ú ‘-@·=èí6ˆÉÊ>iµ1]£Q­-5tÕËÿ- µgódÞvü°¥ÃzîøZzn"ÊÓE6Ö³- ÿ¸š½H°Â¹­VmmyJÍçëµ³¼Oò=SUd Ñ$ü6©þ^+]é#°îöû2öQõ^UH±ŒN$IOr„]®4Ùä$¬ï÷ÓŽébMfï™’n;¦r«‹9ø ¸³õ×Bø+$Ï÷™F'’‡7–Ü¥°QºÌÑåO!üÃÍOãIe)™$̪é·x×+]Ï—8 ¹F› .H°÷Š5à¯h,/Ë/õZÓøš²Ãd¨BÀ"·©@­b»›/ún2Ï3jÆ»W‹É.8µšéLÏ|Pí<_7\½®c ž„8¡v(‡Â8¦´„ý•AnÈŽjþ?mÀ¯6I¡a¦Þ»IèfæbȪ]e÷Ç=«³÷o9vyÀD'2¿Ú—¾/ûÛ[Ö¯€1^G·³í×E÷uó­ActÊ~AŒŒbÊ·¶·RÉŒHÝ|œ^]þÜ úU9/ó#Ðíöô Û%CæùòDNY,¾Í©&Vž„îS/5…ÛçT(Ý}¾œÆ¤ ž#²™qN2_z'ÐŒ$‹dLù³.VØA’zzÏãÀ~ƒÀ† SRJćÄönu‘Ìre9mc–*¨éWYÑ—öÁ4sCå=jKD±Sš¯@.}QAÂÃ2Ãl´ªóõ -GMtlï‘`‡úøæqÊОî>SCW‚ÝE[&èW¥9ç´†<ºu‹8~³îæþÜÕæêÕ*1ßå„}µ—èžàæ–à Âö,âÐ5&`;~5—”‡<Á“L -ì§Á;S¼`‡ -fºÌ´ýž"Í…¡8t)„0{‡Ò¿y!Å~XšiꀒÐkS³"ÉèK`'Ÿª)UÞR{7ÛÒÀî«.bfzø›^ã°M[7 x—ËcñÜ‹Þ#ž¿s©—yé×£žÏžŠ£^„?D 8Z¨ê¡Ü|9é÷7–"(T»¦C9+;{ù–S÷ Qãá Èx.Ù`¹NÁ/N·[ˆ‰Ù¼¹DÂ9Çàêìã[†ËuYè†'.¸ë3t¿Z“¯uµ`•ñœ$NG^‹’¤&> Æ%]]ìÿÇ,5Ÿúßݯ¢|ÉDyÿéñdZ!Ð*¡,DÕwý,©ù…åêlý‚ú˜endstream -endobj -1158 0 obj << -/Type /Page -/Contents 1159 0 R -/Resources 1157 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1145 0 R ->> endobj -1160 0 obj << -/D [1158 0 R /XYZ 56.6929 794.5015 null] ->> endobj -322 0 obj << -/D [1158 0 R /XYZ 56.6929 729.6823 null] ->> endobj -1156 0 obj << -/D [1158 0 R /XYZ 56.6929 704.9004 null] ->> endobj -1161 0 obj << -/D [1158 0 R /XYZ 56.6929 387.929 null] ->> endobj -1162 0 obj << -/D [1158 0 R /XYZ 56.6929 375.9738 null] ->> endobj -1157 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F21 658 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1165 0 obj << -/Length 2770 -/Filter /FlateDecode ->> -stream -xÚ¥]oÛFòÝ¿BÀ=žî'ÉôÉ•œ‹ÄéÙ.p@´´’ˆR¤*Rv}‡ûï7³³K‘eÅqt—»³3»ó=#³QÿØ(Qa$R9ŠSªˆ©Ñtu°÷áŒ9˜±w¡~º;{ó^Ä£4L5×£»yWFIÂFw³/Á»^ür7¹9s:<+?]]_ÒJJûÏ×ï¯>üzsqËàîêó5-ßLÞOn&×ï&çc–(ç¹ÃpäÀû«š}¸¹øôéâæüëÝÏg“»ö-Ý÷²HàCþ<ûò5ÍàÙ?ŸE¡H5z„(diÊG«3©D¨¤~¥8»=ûW‹°³kñOF,d\‰¼‚…)‹“ãt‰FtÝ”)JïÓ3‡RÅ Íx¨…— -g©0)ÂD5ŠUjÁ…ËŸ[³ÉMìxÑÆÄJÆ@án×fšÏŸˆ§K³9gI`èÓã°õ²Ú3šß;€¢Z,Œ[kª‰Ú1(Å-þ‹æ| Ü ê&Û4Ûõ?à+dD5/´Û, M¦YcÕæÉÝ»÷N-C®™p?þ@Ú3îàó¢ ÜYQWöŠcñP®úW5ev_àËⱟ³`óD_øN{WüØ–…©ë¡ ò8ä’' >ÁÉ‚ÄbÉ\µnòª$ÜË ¹'ÀaSÒ]Y…i"W²:ËÀߢˆ›Ù Ûï–†Ù[Ðïb'¦lü‰{]mG¸ñ§EpwËW¿Ð³ÙŒŽÔn#+gCôãùXè8(·«{Ð*°b½Hµ=aw,)œ¸; -­ƒ2[7-2$‚»#OkBk\5}ºÄ+ã1gjïe°ÊÝ ~Ûz&LnÌt»©IðyiêœNÎhx,²…Ã9Tµi†ý[¤¢"Ÿã¨žÃ9Æ´@*(«¦…€sÌAM.¯o{Äà„»Ú¶6´€d&x†Ö«M³{švl¸'¡F›Î¥·_Äz‹XCRX‘vvˤ ‡( -Pë#øÇþ¦Áê·àÉyD¾ãéí õÇÇÐü•­Ö… §ÕŠ°\]ÓxÿÑì‡ÛÉÐé.é·o‰hüQv@´4Í1¢c"Ú ("J¬5u½ð+]»I( ‚‚'."ùœtB*IB q"ZèÜ)sì™åõ:k¦Ë“áâÒ’7<¨æ4æ%ÈÒ­²`Mÿ0Öð`«©Üh&µÙt³À_ëla¾Å¸% “]w㨭$ajyh,‚³`—Qœ¡UêÀ„Ø/xÔVv»¢‘Zv6uø2‡!£¡ÈËæÑàÿi¡MR²1DNìGrAå±1û^_qH[Ћq¥CQuH››Åˆ&7ïØ»È;vÙsˆ×6ëÌ”êXbòÓ× ’#KeáoÿžŒWŽ åR†Zéc¶Pã.Øáí±áBד€”ñnWºá…VÙMîí‚V9äP‹©O±Hò“¾£Œ–ûúSÙDIö„Ž0}¡ãJ›Ä"ücÞ,iy–ÏtîžT6.EÐàî…Ž÷_T$­Í¦Ôl×›³N8~Æl@àKý«[×;Ü<vÍ®+Xwreѹ4kîÒ¬]`•Õpj´œí›‘Òå@ÂyBÞ˜fúfc-ëX‘*ÜÌÇOP¥ø›Š½» bù̸Wf4P ÁY5'3Å<Ý+”mžì½Û2Ç,û s›­×¦œí~?ìzÇŠìg­º_E¹ÎÇËDÎÛß)õ,àÒ$eCœt¤ê Öéâ꧱ԯ¢|DÞ‰jñ~—Ä!­µWè·f9þöZ»7Q‘ ž'¿çº8؃åö~ŠÌWÛ “ÚÿÔsêá9¸bû0’rïÉ™@Qih×¥øÒûgœµ™€ì7 pÏŸËó%ÿ°d'­UõÇvMË÷Æõ¾Ž4SIU½â®³ÆÍLáÍ£ -û£HÚ%ýä°ŸzGm=÷ê?XØý5‡Ä~D÷·ƒž‡ñ}w)|µdõHB•ðxàêÿ5‘Cendstream -endobj -1164 0 obj << -/Type /Page -/Contents 1165 0 R -/Resources 1163 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1145 0 R -/Annots [ 1169 0 R 1170 0 R ] ->> endobj -1169 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [519.8432 252.798 539.579 264.8576] -/Subtype /Link -/A << /S /GoTo /D (lwresd) >> ->> endobj -1170 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [84.0431 240.8428 117.8035 252.9024] -/Subtype /Link -/A << /S /GoTo /D (lwresd) >> ->> endobj -1166 0 obj << -/D [1164 0 R /XYZ 85.0394 794.5015 null] ->> endobj -326 0 obj << -/D [1164 0 R /XYZ 85.0394 451.0558 null] ->> endobj -1167 0 obj << -/D [1164 0 R /XYZ 85.0394 423.9067 null] ->> endobj -330 0 obj << -/D [1164 0 R /XYZ 85.0394 301.4703 null] ->> endobj -1168 0 obj << -/D [1164 0 R /XYZ 85.0394 271.3564 null] ->> endobj -1163 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1173 0 obj << -/Length 1216 -/Filter /FlateDecode ->> -stream -xÚ¥XKsÛ6¾ëWðh€‚o²99Žœ:Ó8­¢œ"A c’`ЖÛô¿@Š”Õš’G£Ás?ì~X,°´-$¶å0ˆØ -cúÈö­¤˜ k-Ç>Nl3´“@Öûùä—7´bN`ͳVQÙÖ<]\З]\¹»¹ýømvuzóÛ/w—ÀñÑÅÍíïS]û8»úüùjv ìÈ·/®»úc>é¡À`¼¿½û {b]üèlz3Mﮧ—÷óO“é¼³¥o¯\eÈÉâY©4ûÓA7Ž|ëI6´ãرŠ‰ç»Ð÷\·íÉ'_'v€½ÑèQþl7pŽèØ–mÃØ÷ƒ~ ×q;mW²‚º(0¤æÚʯ RRþj\¸V&ˉ{;ƒ,à†RMï;@"–¸ º¶¨X-t•VKո׭¿uñùH× À2§ÜüìäpšÖ¯à-ȳ®ÉÊ}nëÚ;3 BhÆþy§m’%ò"è»N¼§ÉAÓò!§¤‚²R÷à2Õ•o¯I·Ö€?LJ~ä‡þôD·7Q²ìzq Ô¾dõ²d#p#6 ÜöÝçñ)Q÷J"ƒ`% [*NW!¥8oª~}©ãÎÙ ?@4¤=t§(Ÿ‘lÀ:oÈéJgyÃ7`wk)Ëù¦){*OÚ` § É© ÿüt+T |“ €oMPjŠ©G ´¤ÎAMx%¯ r†í[$ÊóÏ°¢d‚f‡N0x’m•Ó„ß‹úy#·0ÞÙ'¥ÎÇEϱO7O¾®äÍ*ÆòÓ…ÕÙòè6«Á -srÆI/9' %^ågœ#þˆsšb1–Ác9còÙ™’þeg‘®ŒËdÃêþèxó -°’!Umô‘ÎÐ' ©„Œ•|¤gDV?á:=Ì€”Ç<9£u› ©TfLüÓÈ]"f²¬Å)™”YF¦JízmÂ4âÖ—!CÆäè·5 Ü?@½!äž½[ËIåÏ\ËË€ q¶÷3F°´j5NŽ}p}¨òø# <ê¢7.ØKñd^EÎþK@?qpB™ÇDÄ(¥,ñœš·ß^ªþ/#„¹rendstream -endobj -1172 0 obj << -/Type /Page -/Contents 1173 0 R -/Resources 1171 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1145 0 R ->> endobj -1174 0 obj << -/D [1172 0 R /XYZ 56.6929 794.5015 null] ->> endobj -334 0 obj << -/D [1172 0 R /XYZ 56.6929 769.5949 null] ->> endobj -1175 0 obj << -/D [1172 0 R /XYZ 56.6929 752.2028 null] ->> endobj -338 0 obj << -/D [1172 0 R /XYZ 56.6929 693.9224 null] ->> endobj -1176 0 obj << -/D [1172 0 R /XYZ 56.6929 663.1642 null] ->> endobj -342 0 obj << -/D [1172 0 R /XYZ 56.6929 628.9495 null] ->> endobj -1177 0 obj << -/D [1172 0 R /XYZ 56.6929 601.0964 null] ->> endobj -1171 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F39 863 0 R /F23 682 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1180 0 obj << -/Length 1186 -/Filter /FlateDecode ->> -stream -xÚÕYËrÛ6Ýë+¸´:O’˜¬WNiœVUWªGC“Ìš"‚’í4ù÷Bâ[¢lRÌt¼òž{îÁpcé?lØ"*˜a 9ÂÜpç=dÌô»=œ}ò@õ«÷£ÞÏ×Ô2&1Ñ´‚eCdÛØyã‹«_/ †}@8º0ap]¼¿¹ý%íéÏÕçÛë› /û»Ý|¾M»‡ƒëÁpp{5èls¬íI†°Çàúæ·AÚú0¼üôérØ¿}ì FE,Õx1¢ë@¾ôÆwÈðtØ{RasãI? ˆ… ƼÇ8…œQš÷½?{€•·Ó&ý8µ!·‰Õ$ ¨ˆ‘ –aqMJèFÁq˜]¸Ò}¡3—*íøq”¶æŽJdœ¶¿¥?*pV²ÖKµˆB% c¼ÖÆ Šµc(8'—%ô“‡5˜©ãµFqõ]Ú¼Û ƒFøZDóçípŽô‰rgx×Ù“x®{iß‹T“(ž„Q³}Y?Lä,ö“—CæÏÀ]áŒYÅ«óúlSù÷κ«äAôÂ(ñ§™Æÿf/ªÇCueõ&RùêdÁߎûøòtc¿Š|¬Xz °ˆâ¤NvÝÓu€RDótˆë¯eòÌ—@ÙZ´˜”w'“¦p«ƒ9»çZÀéÚ¡¢eìî,ÍeË_°ÉÚK¾.¯ñ°% %×°Ðb”oPJ_e~*/Š­`Ó‚Ô"¬‘NbÕy%òÌ7ÖõŽÅpæ›íóÍJßUݾeL‡œÚœ­©¨­” d6c”¨V'˜ Ȩ0O(H -e!¶i½kO­š:EÞ6g¹«™° 1é0‚)#];SýÔ8f?F¬=ÙCZeù?Èž®Ó©möÔÆjî<åHü¹Ôemú&\ÎïeÜbíÚ…ˆ–É1¾´£_‡èN#qÀ |æ[Xkˬ–ZÉöö5öJƾd5d\”O­ýWì}©;Ûû4ÀRvä^¨®‹3½ùmgzJ ?xÚ:•Îð%ëWN¹;µÉL:EZضJÜl»Ð±†EÎUÚÞå;îê -Ë2›£ñN¡r׸"l­Þ¯ñ¬m)¯l!´aÕªRe‡Q%ˆBB-±ç“€N²VÐÎ +AÌùž3Â×7¥%Cl!óLt‰1³I#Ý¥Ò“vŸ¼oœjc”ß'ç%_ªÜ(ôT¥æ‰“!´š6eQÛ(?nÚXR&ÄÛ,ßž4å <äÁC²¹clœ4*jºTÑ€%Ë·°Öê•ï-ëÿyƒ šå•Ôÿè! õÞXš¯[µn›{³HW»–­³×sçû©äûy+ãzU‘8îã1ÞÝ@:¡Î6—ñÊ öéßt¯N9\_†7Ü‚£¢ =úνü‡Ós߶IqNhå:"ÚDX9©uŒŒn3/.çw©ÿÏ@wJendstream -endobj -1179 0 obj << -/Type /Page -/Contents 1180 0 R -/Resources 1178 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1182 0 R ->> endobj -1181 0 obj << -/D [1179 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1178 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F23 682 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1185 0 obj << -/Length 1615 -/Filter /FlateDecode ->> -stream -xÚ¥]sÓ8ð=¿"oçÎ`!ùÛÃS–+s”»žJ§§ØJâÁ±Œ¤ôëà¿ßÊ’;1% ɃV«Õîj?%“1†?‡ŠR/Çi€BLÂq¶áñÖÞˆ¥q["·Kõz2zyîÇ㥑'³¯á$!ãI~íDÈC'À;o>^ž_¼û|uzÎäâãå‰ë…Ø9¿øëÌ@ï®N?|8½:qIçÍŸ§OήÌRdy¼¾¸|k0©~ÂôêìüìêìòÍÙÉÍäýèl²>K÷¼ûú ßF×7xœÃ±ß0òÓ$ßÃ#’¦Þx9 -B…ï·˜rôiôÏšagµÙ:h?‚‘çGÞÓŽŒ" ¬â0E‘ïù¯OÜcgÁ¨PSF•[TŠ‰;Z|µZN™xe&7ú¸ Ó%¥aèu4Ûf4cÇ2ŠªBª"“p ]Š×¼äóG3ûÏ 4Ï“òvIU¶¸-A‚Áÿ¸yõœ2\¨ ío±B2år‘3ÑãÖ`neÍ23·¼~v!ÔÚ¡;üxõŒYJºd®R‡úcIÜ*£ÙâØÍìíé+‹¹ Î/òB=†BÏ"ÏjQT®à\ɵ_Iˆâ‡™ôÈä-·NnïµàwE>Ècé‚}[1©ŽÜ­„NâL¸Tº²†|<öñØ "~áªbÉŽóÄÁï3i4Qâñ dWCYô´¨¡$ØRWßêÉ{ bªà-Ý™àK—®ÔâXlójÒëfý£UJ úª™;çËsŒ×è™b”Ä8\?ÏHO.¬ï´µ®YÒ<¡>ÁuŸ-!üÌô-û‚±W5Î` C೤sfeùç ˆòà¹E<£ÏdÁÖ -mˆH‚Ò4XÓ´ì2ó“Nv”ó}.ðÒ@«ÚŒó’Ouþkxs,˜(®ÇÀ™2»A²Ü@ÓG3ê7&2àdQØm[—Ôë®H…•ÓÔzeÌx& µÚ^ß3º¨úQäP=Ĥ‚¶í|%¨±®^Ó˜’éÇD˜:3ƒT È8’8ÌlÔÊi4Å€a£%iJ~mÙ@œl[öðNC𲑵6¢8-yöÕ€÷…¾1i -Ájp†ÖÀ೬ ¯…’6hq„’0Mû¶ÉÙŒ®Jt÷EY¨qWØÜüs´ó¨'(&$‚0÷ ~„"·KÕ¼Á{fk?¬©¥ -Á2Å¡þnINcIò¼ä–h@r×{+Øë‹ÖYãú^èÜsñz›™€BM@%ŽÖ«Áò™U»ÇÖè8pô÷ˆúÓÊ’Vp7¡SÉË•²´úz©kžv±˜íòÚR@š(µþ$û8ê»ÓxÐLÂù$ ýÊ*ƒ¢ÒŒæ,%ð½k‰¸YQMjhsb}\BHs¤”XiŠ6r4ÐVMX‚¶g€%—Ê@iÀxv¯T½²KæP²„˜¡92‰Óû\³Uõñr$VÕ@Ž…>ŠÓij9fº­niÊKÜžSCƒçô¯©š€Ñõ˜U\@ßZ -}–C6{ 6ÞÔKëhä¦mÓØSDS7ößCø‘ µE ¥qY‚?^˜ˆ  oùqöCÆD\@¶ÕòÏ™5¾4÷‹¢)9ÚM^òfÝÑEM(]8Ü0 Ûˆ@º&³ü|Uæfqj÷55ÖÖ 4p1Ðé„~öõÑ‘þd8P,ðºWÿö—ÉÍgÛ F~’xÃeÇ‹$ÀÄ*¥•‚Ýk?aîªþ?aΤendstream -endobj -1184 0 obj << -/Type /Page -/Contents 1185 0 R -/Resources 1183 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1182 0 R ->> endobj -1186 0 obj << -/D [1184 0 R /XYZ 56.6929 794.5015 null] ->> endobj -346 0 obj << -/D [1184 0 R /XYZ 56.6929 215.7523 null] ->> endobj -1187 0 obj << -/D [1184 0 R /XYZ 56.6929 183.9675 null] ->> endobj -1183 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F21 658 0 R /F23 682 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1190 0 obj << -/Length 3744 -/Filter /FlateDecode ->> -stream -xÚ½]sã¶ñÝ¿Âo¥'ø"ÉSrçKœ6—ôΙN'É-Rç$R'Rçs}w±R”œ¶3‡ÐbÉ],ö`×ü±k­ÒLy]™ªŒ©ëåö*»~„¹ï¯˜ÃYx¤EŒõÝýÕ«·¢¸6©Éy~}¿Š¾¥ÓLkv}_ý–¼þáÛ_îoßß,¸Ê’<½Y¨`ÍÐ}¦²ÔdLøǺno‚eɮޯºý¶iáwf’ê¹-·Í’&»ªjw+BèëåaÃtâàÿêÚºÿÆ\&ÃÚaq…hAOë:¼Ÿ ¨»ÃÃÆÓ+Û -¥[L+¥a™ Ü2½Û7Ÿ‰nP„4ø=Ëø¦îñ‡NúuwØT4ñà0WÝ¡­Ai’fEx €—•c©uX—­¹·a±cœ§nÿ‘¤e¿¯“1– ÂË"¹÷ï1pq™_Y\¿«— .¢®È¶‡~ ®ŸÈ”}>ôÝæ08è®Öé‰Á8­ÌužjÉäeձΫnÀBvA;êjñ%7Õ[Q¤Y.ÌeÚ딸Œ½“<Í$ìüˆúýºÁ:évCÓáf‰" 0”O=ÔV*;0&åàE€ üÎÝ@o<•=}âУøÔ´ô$§‡sšCGO»a«g´û H¸(›1.N/±`9Ø."wÌŒE:á{!Š<ÍçS[@­ê÷å6ER2¹³J¢ƒ³Ö‰¥ç9KÚŽ~÷õ®Ü£rÄdžN±?Ñ‚ b”q¨#D7Ÿm]Wuõ ²À“fpÐÕ¡]âÆ•›fxŽ_{=4›ÁÚÁñìx½à¬^°±íÀÑúzÿ¸…èrÞ$Oü“ˆ°.˜„ÇB.ëλm ªsâËEÊÔ ´=Ò í‘'—:…É qr4 )Ç€—»Ý —UY¥VN•WWÜ\OCëØU‘”› úuI>˽ Ës¨u[£UôÆS3¬g”IpÁ5óê}ÿ×ÛΨ/RéR"àâ.¶]è"-2iÆÚ¿Ü4äM‘«Ÿu:A^ðT©„Dç2K‚A"¤¼¨¿,!<Ö`Eì«èëÛò™w{z:È´s,=ü ‘ÃtU÷ÍQ®0ãÜŒVô-¿?ÁðæÂI¡xr·"q° R“\ñ± Ö=Èãœñ8Ï= ÙmÎÕqj´Í0A&ž« 0²!¦~ç\’¼ÀqG[˜åà - -îæw%Ï2'‚¿?Áñ 3g\A¦eü,Kø«ËtEʵôª31¿ ‰\¥…2¢ºƒc>1g¤Y?ƒxöOM».À¯8ÿμ …K„D˜ÊÆ‚Ô5ß3,s|ž[YæF8F÷ -u[ÞºþBƒªyDG:#GpŽ9Óf,G öqqŽ&øÉÿZŽ P@Œ;.eƒLÃÔ¶ó¹Ì²ìmšÈPOM4÷Æ„_1b¥>à Oyžûh哾8e²›È’“¿ôòžÇHàlÄPêx*r1bÄXç#FÀ:Šz7›DÉˤ=Ò iqšB‰1m08¸˜7”ÛÔsñC½Ùlmži4yD¡¬A2ø·½\qÒk€ùð@ÐØ,8¹´žF6nXr½§fójn¢°¡.3`#­:ùf oR×­t&ͱîSê?™ô10á‡IjðÝ°n¤F™:@­Ú¤|ظ‘• Ìlº²rÿ _ñØÚÊ}qƒP'*­(½Ú:÷/Tš>©‹B„ -í;@¨W¬êÏÕ+Xyݹ×άcQÎõÚÝ:|û¢ÕIHÕÌÕe«‹±Î[]À²ñ©\®ëIëÄî`Óóѳ†ç±fÈ,Ô6çY1¦OÅ‹Ý$÷´qߊ ²—°I]»íÍ›ÎI­sâ³^©—¬$º`%Ë&<õ¶Ê¡s^öçÌ%—àŹÌEÀšacd0`'¹f|ֱ̌ÁhC£}¡ÍÑ`b`0>í›ÁVŠ‡ÅQ;à‡¾|ôèaÁî;#ÖÒïúK3`ÃóPÇ(“Â^N’Å“NØ1˜DlL³YuwÍ¡ö±¯›¼ïWIÞ•žÄ•oÈéTæœ$ -MèzÃBÀÈEk“l Tï 6W ãÊÄV`àfÆê4OµÙ®µºÔ)Ï\†¯lrì$7s:TnúŽ`M;PQ–³Í‘ƒÂKŸÛ ŸÒc“jÒ°&~?ß4¤hV×1šé¹hVû–ƒkeºŽÜ²îàîïlbÉVØn‚ †…(&DäÙ‘\Pe×h=Ue™™ÌÝûÜW¾¼ÝQfÒ°û\î_íí+ÒwØ„—‹Y zPwÈ}à¤Bo^ß;-V㎵³õ0°)ÿRÕôX‡ôôŠ+;l1‡ÊšPÒã—»74ˆ A_x’ôV<ë½Lá -Ÿ"ò¿øaŒÃ -ˆÞzêçËcH&Ñ»´áÒ` |Ï@¶g’I×ãÛvŸAi@ˆKÞuƒ›³{:Ócϲ´(„wEgÇUZpæ‘ì9|²¤;P3ð¥C¦#õ»-2ø §·uóÙåd!ŸÑ6;Ð7ï>Ы.úe·q´öeèÍ/1WÓ2(>;ÌÙØAD‘¤W”°wxè˜áºÇñ¼6íæ9ÜpÇÝ8ãúªÑ)ž}SõºQž"øóUøY’'Îu6¡³@º$D|Î]è96'B( yBþv,·ÛCÛ,K«ÇÄÆÿ¸éJ÷Iýyõ†l63¹~A¿#¬ -‡‘‹ªþÜ,Oã"ìc"¿L>`ÍÐg|f¥3`µ̆èîÙÒýFG‰ÏÚ7vÏ@ùâóÁ!Ruh!#|3.а_r;ý*>wûf[î›Ó [ÃlЇÛ×.åÓ›M+Ãn‡gd ÌöÒãIX®Ñx@=zzÚs);sjûÒ:V{Hf¼EfÑE½,º¨—ù‹z™-ck‡l/é¡9*ãïP!æÎ}XøûÅœBÛÈ‹X,ÜðÃÀk•ÆX©Ì:æS€0ú°ì¯§uc˨°Fy<$Ã_ñFúët™K ,ùÆ1⟥gÉ~íN胈cŸÍž\Ø„ÎhÉ<¶á6¶l܈Ò%^ø“¼" -Ë0^ãîáì–µþ².ý`ëVQÐB›\Cq’e¾Ü£o¼Ïåæà(ͦ9BPQjå»0°?¯Ü%‚™4G§Rú¬Ëíi,S©‘r’Å¡è€>ÈŒö•K㥣ñí„P›¶ê¶£Îß«HéúçýüÅ8Ž¡Žç£K‘ß™,£ÈR®ë„Ô†ò£­Þ`X»‹žË~WR‹22ƒ-¬|RŽ7m34Þñ.»wéñ@šE@w¸‹ž}{º®õ~8ìœ7o¶á6g5NäÀN»ãIyÔ¢î=ÞljÝÇ ‰ÎTþ¡Ë™âõæ ÿnOÿç[ÔÇ+æxoPë3EŽÈòTsSx¦P¨RM9WB§Jób†õŸ¶›‰endstream -endobj -1189 0 obj << -/Type /Page -/Contents 1190 0 R -/Resources 1188 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1182 0 R -/Annots [ 1192 0 R ] ->> endobj -1192 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [250.9056 208.6872 324.559 218.0968] -/Subtype /Link -/A << /S /GoTo /D (statsfile) >> ->> endobj -1191 0 obj << -/D [1189 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1188 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F47 879 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1196 0 obj << -/Length 3362 -/Filter /FlateDecode ->> -stream -xÚ¥]sÛÈíÝ¿ÂsOòLÄrÉår9yrbçêëÅnm§íÍÝ=PâJâ„"u"e'×é/°À®H™’“i2c‚K‹Å7@‰óþ‹óD*‹²ó4“AŠä|¾> Ï—ðìÇ3Á8S‡4íc½{<ûˇ8=Ï‚LEêüqÑ£¥ƒPkqþXü:QA\…pòþîöÃÍŸî//R9y¼¹»½˜FI8ùpóó5A?Þ_~üxy1:“÷½üûãõ==RLãÝÍí­dt9BôþúÃõýõíûë‹ß:»~ôgéŸW„1ä³_Ï 8öOgag:9†›0Y¯Ïd‰Œc·R=œýÃì=µ¯ŽÉO&:H"©@’Q%:—²R!)•IF^Ê‘“²ÃB)o¶fa¶[SL—ÕÎZDQ$I|Þ§üb5Â@Üc@DiÄJ 9¸Y€äu4i7f^þ†‘)ÞÀJ&&ÝÊà£xR•mg -Bë¾n A¿…IxIÍ––.á, Z}.«ŠÖgLȬËÎSš™¼'ô„6°Ó±²°‹eÍÛ:^ò¢(§('ÔNÅ) -@€r:NW6u^‘1µfŽ·tÓ,èšÓåÙ~%˜h7MÝ0×X„“G»<+Ì"ßUÝ”-]놺†®"±°üã5“fi„Òº½»½Fñ/Œ›-He*FŸ6³>Öq3óX(•mÓtÓÂTf™£D¦M]}}alID±ˆOsá±FØ[’‘ˆÔÇ‹,œì¶ ’XƒJìU€ˆIÍÆ07kSw´Ž*C¼CÆíbÉD¾j EÜ5Z®Ì“©øõf—uK†‰ y]ÐvG ÙSJÄÞž( þÙÔ†Õþ\v+§_¶©MßÜÌ—yµ+Xßè3VÏ 6ˆ‹W3"xÛtŒÒ6k†è –²÷ˆ¾íÀûZ)8³2Á’Íö·(’W×ø÷ ?ðç‹,šüó`ñÓþu§)ö>~z¸þô!o©-²žfá<\¿§‡=†í³¼ã«5@˜™ªy~b¯m(…rà#„O±Uh | cS²²T… -„„¤žç ´¢D»WÚ.ïl,󬼂C˜‚ÝæλSçâþºiÙ÷üÙæ. -Tìï3Gl³©J$vÌÈbL·ê•â¡uÂÈ–•JÝBŠ›VMó9oËâeùË 3}š5ÂÂÀÄâ xbÈÿVƒ’Òm»7#Š”*€RË+r„åC5†Òšñ)³6O€ÚÒ6ltzò”We‘w¶ö€[ŽÎåÌdz1© ·tf[ç6êªl²6ݪ)˜VãI±…B é-ÒCÅ}àõ8LÑWþvý Š ‡9%®¢%t¼Z>-`S Ût†tÁÌ(!!‘{Ïú»”„ñÀ¸ÎŽØ{‹Á}—tY¨ghðÒ¹°Œ!Ři»*„h¡ß¬À²P¿€IG&?ú;ÖÍvmS',U‚Y¯”ìo•·ô 2‹Ž–˜†œ|6|Ž]Ým/ôd‡…*ïˆH¤S)ƒ0‚X(2þ4¯ç+’iÊÎMÒeÑn6Æ– V“Õ*ÚW0Þ1¾CÎ åŠÒ/­ æØ–([ÃOw›þÖ -œŒ‘J6¦’­bV?Ð3’…iFBL¬ý ÛಷÙW¸Vžn{ÄlS[™´åº¬ò­-Ù|sàÏ9?qï?—SÑ*áF¬Ù‡mÇ€m%ï!" w0òµ)†µ»‹â{û9È!ÁiôZ ïcä«çTk4Ç™™¼Û¾Œæ Ò@æ4k„A4W2HÒ42ò€Qc>¥“Ui¶”5綴ø¼*ç+‘]‚¬ # -MöIÎ$¨‚íaØ£¹D9+YÖV+»ÎÀ -_†žO54áéAhÓµHê~ -B^K@_ÍX± Rh#Ý RdÿtD–X‡.$EˆJV„òùÜl:†ëöÙl[ºA·Ä+Pr¨î¸"S½ãÔc²%q ³ÌEкãŸepŒ®»àŠp/¸Z‘FÔ—¡:(ɨ¢AßÎ$ÕJe½Ä»x²°¡–¡£êéÒ":A žõuXœ¹‡Vb¶äJ¥ ñ¥#"ú$0Y¢92»º0Ì@>’«ãÂÖ:ôÃÝK&8ó"„sT¡"Ð*‘ßU¼$!x½ÀÒ¯ç]ùd‚‘­¦"GÔz—Qf~ ‡µ0¨/„>ç]ÓTƵŸwÜz Wqœa¿ÒÜô±Ž‡+eÍc×­¦õÖÔ‹™|”‰'·÷X#û‹NöÉ!£^“i,³ïsú8ì4q¨]ÅpXÀBE(SÁ/]^ŽÑÕA¢„C™¹œì+· -Ã6'áf j·ÿ¾ºûxysÛÏ|4‹j™AóäªC—ô9bͽ}2[¿—;"ˆR}Ð~S$ÖZà\ú+ß*±£‚*9'ËœJˆ¾4ÿ‚çûù—Ö¼ÃØDåT'êÛƒÕ['m›–awÍé2_åõÒЖ ªÿ×ô„§Èi˨âée6ùÚì˜Æ~¤˜A:·q =á¸ä“A¿#C= MUøÂgÝ3“ãÉ í‚íaÎ cmë‰}ѱŽH òZÇßa®GË’H‹š³è´Ÿ÷±Žû¹Ç²ñÎ`ìŸCž6õÔ|)»—fÈ4“§yðX#L ‡vØ¡‡\<®\ùF£&nÃmWбÓ@Éöß4¡ u7šš"ðt¾2óÏd pg›Õ­Y74†îÑäŸÝæµ›ò•Úˆ!ä  ]Ž¿t@uÃsîö`ÈÐ?¹`açÊf l­ß³Œ·ÇíuÞ+Sä>Ö {pX4…É+hH¶Õ - -É0=½­CÙ¶o™@zb¸í±¡×Ý'í•H"ô%RÆâ CDí"i*·S£ÐŠè›ãZKKñÞÕzýàâØÙÚ–{™q·P%-¸\Ä`Lñ­u¤i.W˜5Ú…5±$N441ÖÈ4N’IUÖŸ1cèÈ鸊}¡l•@—I;î–«Ž¸÷q$€W`q(<óÂw C,Ë„­g–íÖCbQ¦;KP;/>²m<+JK?– °ên¬£3Œ3GEÄÂÖÜ°dKL¸’tíŠýÜbÑm.àüM=‡=¶Ü« -@ ßÃ:¦ƒÐ¨´Ð6×N]*ùj • 0M[°ÂnùXÞB†µ¹ šà6[¨ÁßÐmc7Dȸüô¢•P'y#^™|ÛÍÀ<§ŽÒX -ÝC"op`‰&«fc;Êüp[ì¶ûÜ×5Ës8§rb™÷¼j9ˆ¶» ñ‚zØU™†ª#=h$öŸ8Üç7Äüø`ö›X{š ¶¼g¯}i¥T¤©þöâ„[Í(M œŒ#÷í†3Ñè¤:ƒj]g~RíbäÁ6qh™¹ÎÀ‡þLs1Ñ€$ K¶]€ëp° 6Çqða%Ñ@c·ÉSižG8‰’@„:éÙÇè¡tìË«ŸBPè0}1pCjr¼º‘°?Ï[>™­Ž2íRàùk ”TX* ¾ñø·o?˪™yóﳞ…T¦ß Xé¡>Xù"D](ßÎÈtÂáÙ§;Å‚Ë:‡¦s»GqH‘¹>£O—ïÚh•¾O&¥»åۻǛ¿LøÇδŒcÃ!â::ûmªü‰ýô 4áø…ˆæ,Sh<}ÐÎ0tí°0Žzb¹\Zn«–‚²i´D‡F¸Þ­gÕV+DΆÉþÛ–3‘•ý´Ÿ‚¼¢*ÚbBÌ0:z - ÿðÀ}Ýñ…·Þ¬_¬ƒôiÜ%³=Þ>åºbq_|5uÝÿ]+N]g?ŒP¾pñTÞö[ƒÃÜçüœÂûµöû¸eÅ f{Þ¨€iªÊUųѴ…Vœ†‘‹ŠaÄIÂ@(õj¨ˆ“ÔÍH0†MÒ“Y%Þ7]¬Í`©õð;¹íì”ËM°Z²’€+ö‹Jx½Â -} Š ífû·0Ûª„p@Ó9 ÂüaO óÛÁ ´¼ÜU9¿…_Ê÷œa-eñºâ“?´+úÅ ˜Žé}Á{®Ø’Uj¥B£Wåf£ð瀸A `’¡g>iz$OD-OU!ƒ0t–`¾lÊ}Oû”¼þ<‡}C¥,†ÔF4ôGV·ÂߢEc>ÜÿAŽ m#]Ž›H%þzk¤Ù}Jÿ¿$¶ÿLƒXë#k”BÞÕ@„™ÂIõ²?ß΀Ô_²þ?~ÁÞendstream -endobj -1195 0 obj << -/Type /Page -/Contents 1196 0 R -/Resources 1194 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1182 0 R ->> endobj -1197 0 obj << -/D [1195 0 R /XYZ 56.6929 794.5015 null] ->> endobj -350 0 obj << -/D [1195 0 R /XYZ 56.6929 387.6589 null] ->> endobj -1005 0 obj << -/D [1195 0 R /XYZ 56.6929 362.5676 null] ->> endobj -1194 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F39 863 0 R /F48 885 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1200 0 obj << -/Length 3390 -/Filter /FlateDecode ->> -stream -xÚÍ]sã¶ñÝ¿Bo•gŽ>Iàñrñ]éùŸ34ÍO¢,62鈔}î¯ï. H‘’®i:½ñx´\,€Åb¿I1ãð'fÖ0®œžeN3Ã…™-.øìÆÞ]ˆ@“D¢¤OõíÝÅ7oU6sÌ¥2Ý­zkYÆ­³»åÏó7~ý×»«ÛËD>OÙebR>ÿöúæ;Â8úyóáæíõ»o__fz~wýá†Ð·Wo¯n¯nÞ\]&ÂóeXáÈ„·×¹"èÝíë÷ï_ß^þr÷ýÅÕ]w–þyWxß.~þ…Ï–pìï/8SΚÙ3KÙg?±J§—„+»Ü4LÎWH´*-–}ˆùô2‘—K(‘´Kã…‡ÕXsc-ÞQᎫü×")±ä¥mÊh‘ºìôæÕÄîÃ\H1aÄp÷k¨m0 - -«çK§á¶¼äa¬~l˺¢Ñ¢ÂraIMù°Ûä-]<ûÊ©êOM½)ü½ú»›Ð!=EûòF¯øñêöRÙŸ.…p~ÌÜ…Y1´ÄA‘XAå¿ uLk˜Þzþ92YWGïVƒ1hËõé»íS¿ÛŽÊßmÑ.ÖÉýfWŒ¯–ÃÔÔžÞ»£šØ|pµÊ€áõO‚»ßÑ ¦vƒi6ïpáŽ@à*U¤€‚ÈNö0 öÔVÅFï€IÊù‘*|e°cäç,ò]ã5ö ®(•ý]"²¦ß¼m‹‡Ç–"ÒïH*hf•êñ" SSï<°`µÿÅ."Ë–~—å²úS€×ùS˜B„uÕ´ÛK;ß-‚Ö»xòå²D9{φ«åmNPΊ.êþºy>`ó–.¼†ö‹×Þ5\á3ÈO¹,h‰à óàóð ãù¾™àQ7rÒÊö¸Á€ ½ãj׬“ÕUÑ$u•4ë]»¬Ÿ«C6$Äe©¥;ÉGG4fdàþy -ñOË'ó7®” -Í0YhþPD%ÅâsÙ64´Ü„ ºU”O^9pìãõ»»«Û÷¯ˆ œ†ê°Ò²;`€ëSy%‡‚Rm9låÕK˜Eµì"%Ê çmÙ Z¶à ?jßN—Æ1Ó÷GT·üü…:a¡0ÖbŸ_MTãA«Ï„ZÈe˜æ©;­^}ªãúÕQùÞ\§Ø,“Ŧ,ªv”îApdS“ tT kR8­CȘU–v>áç< ËK1¯À9Mj}·ñ›â˜önD„™dÊaÜÖ< ½]$‰kÞWuç!ñ 6y9œî@[Rkçw—T“tOgŒ LÈûî(tÜ÷-Q`³³Z¡ÁZt)=ƒË›P6HߵË9P±Š=%t¯´žP±Œ9%㚘Êp9o‹VëC–Ûç:¶ƒómÞ4Ýˤuh컊¨¿ù®]'Õçeý—Sa-'‡â›f[Bå';»ëº¾ÃíDÑ,FÑíj!· &RbJX²}Ò5ˆßÄ.r ‘­È—ÇRÂNžñù}ªF©ü½×M›4-dhM[.ÆF©ÁŒlªO3ÐQMp04JtòY6dÁç>Fôâ¢O‚ˆI0@”ø†ÐøkQ<·+(žÃoï žhUoÃÔ'J{ÄË¡ð¾ÅGa1a©˜ ì_#ä ²°IɸÙÁÛ’²]oˤËðˆjýÞ6ä'øêàLFܧ:~ÛrŠ¶ÒÂR~¦Vvò)oÆÙ1˜ºKõi6"ј <‚‚ÜØð“*½Ï&œÚ×/¹¬e&㮋aP?‹ùuKó½G d¸¸dX:J -,ÚÃ'´ð¸„}¶%…nÉ&(Ä–rúi·yÕ€ -€ßîXÝÔ÷¤ÂHäHh„çD PUŸADúÀuµ x€Úá“U@þ’Í1ð9î¸62íÏq%HýÄ« åôy%FŒzÓègÂÓc 5>XTXýz5L})Ïy©w1AZLbë^\ÑC½kïë}Ç`t¾ArÔ†³Åwl»f굞L‡ûÛú 2iRÛ‰7r7õßìM~ĹäGB•n¤ §-¯GuÂò"•·¼²*òM² µÆØÓfÀ!åÓ,tT< q -V‹!׫ á9È9múaÝöºÉÐqzc0±Bètl[&TW ‘kz^V(7šA¯øõãšèH{Ëå»ð.ßiûî WÑ®kHÊqeHõ©SbX2b)A%£±dl¨|´ˆ‹[„&ø·]¹¯ßxìÞÛzšMqï;!^õ•³Âg_çõ@Vø†ŒMÙä¾}È_ºPC»§®ÓWÄúd»Â^_µˆ–º: —üÌÙre 8ìAq£ÿ€šC€_ÙÓfק:nv•7;8B ‘8Yø -réSNšÓ tT ›¦LeÊY7æz<€)B¸4Æ*@•a(¸z€,‘x]‡Ç|³ñ­é'd¿ž*ä/€ô±‡b:1å››×ï¯ÈX JÒø.i`,cƒ“Š¸“rþTÖÔÏ#´×(@“F‚Ú€„¬Zæa o]Š£àuÂÕs>Ø(ß<ç/M\c[R†#EµªC7©9Øu$~x;ßu™ã§º]Ó±‡ïÐ|‚[v¤]»fù’-!Z=‚ÀÚþ˜"+É2ÇÏô©ûT'9R ßxôW‰0êô¾ÕÄÆCcÍXŠM˜ÁΓACp1ÀŒR0#Œí½þ§vNÚ9ôrØ›±©2½Ï¹ÒÁgS0Òy\j ¹ ˆœ³' åÑ~Æu±‘e\nGA\0u¹30‡ä7ÅÕ|±Î+ÿm8J _ã¼Ù*– -ÈN”Vÿž†·÷3nû÷é“þ„‰{­‹|}Œ]MäM31jÓ)Žß)Ù7ã>]¤:ÃÃxµ€ëÔRÐ@6zÆ{!‡Â…qJ½q¸]wCx; =l ˆó­ (Ãé:J¼Ú?…Õ½Âp5òV”–—N«Çæòç…ÏÉ¡‰íEÝy„÷mFÝÛª-Ñ/x–ƒ©?¼&à½wAô6˨ޘTa¾?<üúâ~»†ºÃì4NÒ‚|ÓÔÉѯ" —Èt¨) ±ÂP"~šäNå‰6ËbžHK|¶6Þ/5,3]?Åw_÷`^0þ»Í¾v@ ¿ì”QOd¨˜ÕÝ }3?Ê•úˆgÂ/mñ õmÊEÙN}Ÿ—1+yöpy“¿/”|:O@ 糧] ‘—MHÜâmSÔ}3;l;Ýe&‹ß7ž¾g Quÿ’=dtÓRÒpíý×ñç*¦WñÝÇþC·(&-»lØofǾ„V†i5é‹øììÇ _ú•ôþr¸deû_b >4æP%I—E¦ð :}‡?§³þo¬@Cendstream -endobj -1199 0 obj << -/Type /Page -/Contents 1200 0 R -/Resources 1198 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1182 0 R -/Annots [ 1204 0 R ] ->> endobj -1204 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [182.6146 117.0296 231.8861 129.0892] -/Subtype /Link -/A << /S /GoTo /D (notify) >> ->> endobj -1201 0 obj << -/D [1199 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1202 0 obj << -/D [1199 0 R /XYZ 85.0394 720.9574 null] ->> endobj -1203 0 obj << -/D [1199 0 R /XYZ 85.0394 709.0022 null] ->> endobj -1198 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F48 885 0 R /F21 658 0 R /F47 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1207 0 obj << -/Length 3814 -/Filter /FlateDecode ->> -stream -xÚ­]sÛ6òÝ¿BoGÏD,@$0÷ä&N΋sç¸s½iû@K”Í Eª"Õ÷ëo» H‘’Òiã™–» `¿9ð'g: ÙYjãP ©g‹õ•˜=Ã܇+É0s4ïC}ÿxõÝ{•Îlh“(™=®z¸L(Œ‘³ÇåÏAFá5`ÁÛO÷ïï>üøpsÆÁãݧûëy¤EðþÔûðpóñãÍÃõ\-ƒ·ÿ¸ù×ãíM%Œãû»ûw4b©9ôáöýíÃíýÛÛë_¸º}ìÖÒ_¯ -òÛÕÏ¿ŠÙ–ýÕ•5z¶‡"”ÖF³õU¬U¨c¥üHyõùêßÂÞ¬ûtrÿ¤#•D©Þjkõ,Õ6LLá>¾ä¸•=ÐH„Ix„ƒ©ê¶X½2X£’&$ƒÕ›¶¨«ë¹²I°Î^©“•MM½§œÚf“/Š_„ˆò%è àoÚIVd¢Ã(•1ù_]åœD:ÔJE Ô´Y›¯óª}s=UÔQØ¿‹ê.²†ù)Zjë¯ùv[,óæ7ó(V¡ˆØv)C«uÔ[:|{z»’4LãcAôâ( îZúx_ïÊ%uëª|Åžq[ç0狼i²í+ýlkšnwÛŠ?Y]K¬xú¥`ŽüÉ pÁ³\d»&_Ò\Sf_ó¦C+˜Í‰éÁjÛ¬y G²/ÃTÊd– - ²jOˆ*ÁÌ{@$¨rJÓinóÅnÛà*ŽÈZ*¥gÉz˜1ÙþñH‡‘‰dïVtŽ±éÚPá•ã6l|Ô2 ­Š Àý «pŸ-t°‘Á»ûÏôû·]îκ[<Àš¶!(áÕ3&ΊàQL]§É· Àôɾ(K¦Ô‚”mZvòƒKn3‚’$ûzû…Ž]£9JÍðà=sup5"&´BÁòš½ãÇFèÐÒ¤”Aˆ$bÜQ71X!pâ -S)†´i0Û¡ìV -ýeíä¦Aëøƒ’PgËWšùRÕû#®˜U0ê°¡‘T¨ ¸lá×KÞ…÷12Ì-+üÎúÃ+0ٰـ5ÈC:¬GGæ–ù*Û•-ý(š É‚-•Nå7ÈVÊ0Žˆ -îë–©´/™#‘ÂFµmQ=O˜1pBo‹¶½cU=AT›0M;ÆxÛ0¯gC+ÿ -&$HiÊH«#ÛQ§:X¹oê5ýzfváG,³6›¢#„Ž—8ÿ5ôÍ"[¼äg3×QèõdòU¾?Oì)g~4á^xÖ ……V–áö) âà¤7_ *Aivã´rûmw-ƒ|[ä;¾$x è‰@:牦%D, 8#Ín+šô[Ç[¤Ð׶ù¶r -¿êM¾ÍZ2+‘²A³÷8¡Ž"Ä=÷ŸïÞÿ—úÙrɲΓe]ÙmÜ‚¤>ç9Ãa0å֓Кȋà*o/óçr7åÜcÆÒÛÒì õIç“H°Ý[œ÷>}¨Ór:²ZDJ˜yûºÉå1u *)d¢Î“ï &èô;‚­·i2dà³×%Rví®WO˜‘$Ó䂇‚Ïë÷Ÿ,"tñ€§’“tzAb‚®mr4ÌØC/†-[ôڵˆ>ÍÊÚ3½/Ú—â4øüé†À†ß’‘QÊ8µC5[Õ[¬*ÙýêÅÌYt/}draø`ráÇ´É…h8•Vv±î”ÅeúÞ⿬ÁpC<œ~SدŒËbÌtØú‡¸D¢Oã¢ïàâ®ÿbˆjî¹—.B Ó—ºngÁ'¤g›h¦ÁÔ+›º¥Þ÷6C'±¤0 BíNq?]ƒ4ðŒÒ!:9 h'DV‰Û—Ùo3ð=±µŠ`z}·ÒøïîÖÑì] ë™õ—Äxç=ÄnEõõHAž«™…i#ù¹w+5Áëu$À¥Ób½)]8N6Þ¸”[N ¡gGç'Fkfýýs‡¥à ™ãüðý9Q‚ +4µ(ŠCëø¼iŒSL·’ ‘y…; -öb^,盺.G†Q@Ø R=ë£F5¦§5„Å…È?RšúÝ¥9¤ë4öÔÔeÞN¹ضX'¦Gɉ@Vî³×Æ÷Ëzyÿôa;tïÞñX/€À¨Á­9é²â8¼t, 3§Â@>Ožc’Y@±hFæß$2=K½“ú+P³>ùyS:ùGó¦Ä§'º—ãè.ljƒE]–ü ˆ_²‹q`€c;‹¡ µœöh·G áøEh±«J -f/R@ÂFÿÎ< .NQœ£]NIŽJæ5iásW¿p#OYCNº¯Ô:ª«×é˜]‚0ÄXæ“ìLz/pFIïà -ækº¾™‚>y¡ØƒíJ °…‹‰E÷Ûð*9ÄØÖmZF<ŽôQiÁU:td ¬t¸ÝÖ X˜i ˜C€öiLµ\Ð×HtJºbƶs]ôjã‹BøËP\îÖƒ}Zs¯¦9G@ù(s,a‘ÄnJ¾CŸ*!E­¶·´AsÆ7‘|¿KtßR©.ÂNº{*$‰…EßàüÍmŸÙ»>|˜ˆúð§+ˆ¦‹ƒÙÅz¬„°ÍŒ ŽVà©Á±õ)Œ-Ž‡ºÀÈÛd`æͧJÁÁ$ZŸ·±}¨ÓF¶ƒê\ßï`ó‹RÕÈœ'ìÆ„^Ï&XÚ”CÂäôTz¨ía¿;íôl*Ùwz‰M]MF¼Ö;BPå®8›RÛeÑdO(ìøãî§÷Ã錚M¶IÞ•Ù–‚çðCw#;Þ`uVJøÅhY_0 ÑâÈ6Äþëì l¾Ö3£A2x›mýµXÎêX¿R,üé£:¶ #FõÆWŒ¢´†küg4˃ÏûðcaÖ¬‘Zù ÈìŒ$­ƒºÀÅ[/2eô>p±øæméà/q4Â;ÚˆjG9$ÎàÕ/ìJu‡1¶óÆFÁQšôB@ׇ:cl<Ô”+Ðë³Ô;¨ òÃ|fÈô;hÙu³Ø=u©WŠhSHŽâ?¤ŠÉ!X9V?ðA­`çôÏÃ_Xòï·j`,C™öÏjR=Ô6ÆØÎËš_›Ä—d­uFÖ<•„ÝÄ´¬Ï5REç©wP䇲‡©Ó®>ý¿FÖŽWq,k`í€ÍÓ²7‘FzNÖ<ü…%ñ~«¬©44òßùêclge-J1Í“‚¨>ÔiYë b»Í³v¾ ü(kæÍ&[äã„ÕBdåy6:¨ >B§âPGBáJB,!ô÷ò=i,(À‡.@ÏPãRh×Ù—œGœüÆâ»â ßPµôs‘m·EöÌ_ ®šà7¦¦¿DQL,ã¿Ž±@ìšjB! %-ôú0u‡šT{ Hó8æë%Ûf‹9_ç@¾&Ž/[ˆâèN„ïe ÷ÊÖ9 íÝ5Ý—¸©Œ~Òùº®«åÂL›=ñŽ#Ùî挢M…¹U¶(ÊÓMú]ÖÙ’ïgRºeAʯ±GÙ“v‡‰¬PóãýÝOÌî+ämë©K¾G‹a!”»çôë9¯ðÖ„d« -0œq{ÿH­[´ï>}¦ÎÚ]ñÐ¥  îÜ‹PØ7Ô>ÕX&Çs ½Sç/S*@~ãùWS JN£Þùûå,ýz¾ã%èSl€©´Kh¿U -‡+éKá_´'¶1õq™¡Ê÷eQù:^Öïq½o±È7pÒoüÃòÈ)MU‹çªæûñÓ¶œc¢ÕSz:cIÈ]-—ò“•óÕ¶^ϳ]ûò¦»­L¹ëÌ‘¿Óà—Reβ×ù&4nßå€A_²ñáÅŒr¼ŠLb—P–ïúqæ)ɾ.o´îa€k³Š[X`½E“€÷@”:š(ã½¾.{ãG"Ø»·q$ùÎÈ™œÀrn2AP®*„]à çº]¤¬-b›(§î}ì"XÕeYï;ìoïo>ÞzºË© äwÇf°¨š°ƒ2¡JÀö"Ô%#6Øsû"Ýc·¿RööÆ;Ç Þy8è©«C™âc²ó7‡2ø>†U Ü äë6r!Ž²»$”îÉ ²Å%s)˜9¾d'èÆÛZþìPNwó;vFÒÊßó |QOÀZY_ù…íD3dÿ€{\Wè"žw‡Ç,0_TTæóJûj®éÍÑL_\ŒJÝ7‹A¤ê;³A7®° ã¾ì(°ü9ቜ'+©ôl)ø°†‹¢nÈ׸MÿúÆA@¨\nŽTÅÍvåoã_&ÙÁ÷ÆÞ-½~Àâ®Öä¹`¬©×<Ûí.óàÜgÎZË7®Ç‚¾« ˜/¶XOzÃUâ+Áâ›$÷¥b=âN}¶üH†áøù–aj¾P‡§L‹zË—ÊmÅe}E'Ñ5åÆLÔŒ¢¨ú/ªü0 rïæ.9ljbøŒ=ñˆ‹;ÄÄo8Œ­ëe÷ÒÁ¾À-"rëg`WùvܸR½I’à¦lj”Nˆš²¯uÁqQâ0A‰$+à6~ã=údÔC£¡pé… fX^a¬Ùäôv0 -vj»8×ÈÃû²¥–˜€MÝ4…++âpþû&¯žrG5b#ê¬ôÄ1xÍåw)uéì)”Ã?¯D­DÁÚMÞ©ÝÕ‘`bÙÕ‡^ÿXíYÙ'Íõ{”* ªÿžá3’°î¦´îN²YÄnÖ|i¨·¢Osw8ðñ'jK8˜•§óR7-meûF[©05Öß•¬ê:dŽÂE½žº5·¨ÞM²íÄ©¸½@ºc^ñ‡c0W†ÅZÅG†­‹'¼b=\t"D µë¬(;Ö«¼ºDT2Ô¢+r#ÇTX@vzÒ -¿ˆ£·L80zÊ‚ƒèEnøZŸnày;üÅ:u¼õ‘ÀÌþRm°€SÈ•ñÕ÷D&º7úqùáå}œ†Ê˜èt¹"6€„™ÂEÄfÚò+ô1ëÿDµºendstream -endobj -1206 0 obj << -/Type /Page -/Contents 1207 0 R -/Resources 1205 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1182 0 R -/Annots [ 1209 0 R 1210 0 R 1211 0 R 1212 0 R 1213 0 R ] ->> endobj -1209 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [80.6033 407.9328 154.2566 417.1482] -/Subtype /Link -/A << /S /GoTo /D (statsfile) >> ->> endobj -1210 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [265.4578 363.0047 326.6578 375.0643] -/Subtype /Link -/A << /S /GoTo /D (server_statement_definition_and_usage) >> ->> endobj -1211 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [367.5441 363.0047 416.2908 375.0643] -/Subtype /Link -/A << /S /GoTo /D (incremental_zone_transfers) >> ->> endobj -1212 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [280.9692 332.6817 342.1692 344.7414] -/Subtype /Link -/A << /S /GoTo /D (server_statement_definition_and_usage) >> ->> endobj -1213 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [277.6219 302.3588 338.8219 314.4184] -/Subtype /Link -/A << /S /GoTo /D (server_statement_definition_and_usage) >> ->> endobj -1208 0 obj << -/D [1206 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1205 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F21 658 0 R /F48 885 0 R /F62 995 0 R /F47 879 0 R /F14 685 0 R /F39 863 0 R >> -/XObject << /Im2 984 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1217 0 obj << -/Length 3673 -/Filter /FlateDecode ->> -stream -xÚ­Ërã6òî¯ðmåª!ðuœL¾¹Iôâáî—÷þxûîöãíû··7Ë0B˜/y…3ÞÝýtK­>¾ùùç7oþxøñêöÁŸe|Þ0Px?¯~û#¸^ñ¼ -„ÊÒèú@„Y&¯wW:R"ÒJ9Hyuõ/¿àhÔNã_¤R¥2™c`6b`@[Ç×I”‰XIeX™ñí;è¨2A¬RXqEY±C½x4ôÝ77aº¨_ŠµY$oé{0eù 4e¸(6z®êCÅ0ób*‚vÛºÚb[AÛ¼ò2vaÞ¥ª;j~˜Ïùn_±ªwø«® ÜÌÒŽ麢zÂS]/ÝA–a(²(’ö<°L‹ ÅrQﻢ®öȨ™áˆ‰*æ+ªz†[¡R× e]´ùciZÚ Û¼ú£Ùæ/EÝ<¯ÖÞåÏ®!XkšÈuU¾:(qgµ¥‘ ­¥ùz]à1ò’Öy—Ó0β!E,gØ@Œ̣VÑÑ7¯ÚƒiZêlè²w®À"™ÙEˆ—J©—Øñ‰¢êLeE{–nlô­Ç/Ü~RÑ]Þ/7 ,K:<KZ#ÁV Ai¢šLf©ÅKaí@÷èðoºÎìöQFxóða—Ž[³óC§BZ$J]– -%Ò$Ô^‡Pàyõ¼l݆{³*6¯,¯3»@3á%³ê›XL‹Ìn¥"‹Ÿ*. ¯rËlÜ’®`^ÊF (žªÚ« ñ)Eæ%É”‹ƒúX¡YS£¬ŸBŸCÞTxBÛÙ™¶ÍŸÌ¬0Ý_â†NEÆmù妩wËU¾²çÒòÌm„‰ã0tÓW]Ÿ—V³`ÆHeµSChË QoŽF&»uŒT¹åH15+&2é¦åcG"KŽ4‘VÅȺú¹ß£EÙâå¡$/Ø:lÑ~â bZ¦"¸ßÐhgXFïV1Vè)Ú!*xõ¾e ÐO\›¶ X3ÞlÙÉ•[N©æÔïÜKZdOà, -#´ª‚¯º -D„€–ñ,d<‹›¹ˆŽDèúm?/a¿nÿÉÉõTùŽ}Š' Eë|GÁ¦ë)Å ²†ãÔ¨ªPŠ4ƒöE«ªÎYÕ¥Ÿ?¹½­£aÕ Ìˆut¿4kÂ-3ùÃ8äÈ#u. fÐ!Ú}Mn%%…Kõ6iaëfv[B€¸þÓýí÷‚àdùìDðÀ%/Fz@òŒsƬbëÅü†{رiI °9á=ŽxoÍÒØàñÆñÏ~0·6ت›#“Ç|¨Ë¾#ß?´C)Nry#H" EDIÈiÎÅHË1–M&âáò…ŒÙåÝj»Üåû½Y/Ab .ሠ"NÁì^¤ÃcÍ2MH"ÇØL(¹ÛLêt5 ©œ@¿aÇÁ@"2%]\…Š™Úäº֔,A”,î>¼h>' ¦!<6ÝKKÖ`@²ìa,!»â1:!QD !PL³©ð•E‹v ÑØ‘Œ«@²?A°ÛšdQ9¸P«4À8ƒFd€rèX/n+°/“’Ä„ÀŽâê˜ÌuWì9 9›¾œ³xVP»w¼4¸‰p€üTTýgj¶¯`vÓË$&õè¡nž©EzS÷OÍéólšÊ”ÔFõalöµÐ²*Ýz4µÞ~àẪ Ê°ëŒÞ;óRN _—Á 8Ó gF’-Ùj;aµ2ûŽT9$ ”¿$=8¯­WÏ6ÓhßrhŒwJ¢f' We,‡":#OîrîN>âÄÊRKMŒîž*+ÎУD,Nœ„@ËúÊ‹’!  ´k¢O{ý@Ž4á$äŒ'DÙ“ÅšìE:£ÎÅ'‹}ßìk·NÑÎ „諺o sXŸµxZgB‡ú oŒuÞây,ܼøLnžœâºØ`ÄÀ€81|!ì¤e\&ÇcÍÐ31U@䔞_½3ŸX>™¡/VMŸ …ΔϢª5Ù#²!`©|TÀ²ÎmDŒ •9P#9ºÛˆo~@Úå Ö¼©Ž%€/lØÆ"ÕRNïCAÄ@YÌqe oi$§"úyµä9$H{ËüÅÐÈxñÇW‚1Fþàåi«aûÁ8ŸPœ1À,ëw,boè*º¨uNM‰ïº3éÙ˜t -yèÑÈñHÈú–†˜œ”ïRaDS®ú2¶´}bG¶Ębje¬~&ëö< -¯9Tw2rœ3g+ë§'kÎ4Wð´«àéȲñ-ÿ ŠMÅ+è¸;Á6›b9ã>¬ «m^=^b•ó¼¾½œ]ÑuŽk«á»†l¢íˆþ|Çû H´41Ÿ5?>³<‰iýl,Óü3²Ë|‡!%Šb É™rè.êåLŽä¬ånMßG¼¦)4Õ µQ~ׯ+BÃõ¬#A±¢UŠM4¶[fÌ~aZÎÝé¡XÛü1€Ô´£/‡ja>ïMe­x@ ,ýÙrK&‚Þ~øÄ+T Ù™]mó6hƒwnûó§ûhg_¨¶¡ã 2 ÂEë -}¯’a‚Uè™ûäèZ’ÞaÃëv¨î ©€%ýK®4Ø p_šŽê‘4®Î›,°Qu48˜>4¸­§ºl·µ™ü‰*’ž$5¯“ˆ`mÎÌ•Qp’ñ ìAñ—¡TˆLå™8âò,¦!C„Ç¢¢Èd˜8¬ÈˆpÄ’q¸˜9öfž…ÞÀqÞç1ýnC±(;{¦Ê¸|‰ˆ…¯Ùíë&o -WsB[Y#HUG’°ñ”-“8}°U(ºW®0ðÚÕ³:1“LÕš¾5¹æ,h»‚1׈³„£ÊvfÃ(‘Œ\®Ãzqº°RBeq<òù3µfˆdâ^|ÈGÎD±²&9ãàXn§GºÖ,Uˆ¡SšSrû°-¬q‡&Çë§D-RBBozû_ÍØD¤‰d¢ÝíC¬] DNÂvDD¬DÙ™,E&c·KÝÌñ8ié/ñ8?-X³=)ì1w±•È0 gƒa™H§’är0<Æ: {,˾ìŠåÀ‡I쫤óizyw5³ýô]-q„Óý¹ž¶Ã×sbIVaÖ^Bƒ*åØz­{ÂÙÚÀAö ûÒõìYÚÉ«e›±Oþ¼©Þ鎒4ùò£ÖÜ*|—ÑáQÙÿȼ å)ت|µs‹Ñ˜Ê²ù"Ø -„êoT9Ò¡Ê!ÓÄ–E×´—ÚRW“JÝËM’9•Úúm‘» ýîÑÚ”êg¢‹ÿ±m¯ -¦’¾]߀±ÕÀòÌŠô°RƤ¢YîÇ#§´ÛÜ2( (\µæÚlr¸Xÿ&0SJ•HPò.½Ûñ ÊyýBö&`V.ë×ë‚~9,+HÓŠ‹&§ -– ¦úòökfÿÉQ#:H¦ÜV ¤éâû÷÷÷·o±u×=¸ØŽl@@{I‡Éhñ©rל²¦™?fª†Qø•â ~Å‹oJSVí`—œ·µÿ9€~Ád®k‡2Î/™àSTMÅn8ÈZPçkÄKk¡Ó8þŠs•¯0áˆÃì²|±ÎË—ÇÉ×K^ë܆ÙÇ2GBÆIv™5CÃô¸:SS"œŒáK‡“1l¨²ý‚¿NÌ¢T-Þ×™ñ®¶”gŽ±'jtDWœˆ(ž“é…w‚в¥fWŸbØ·ðÀéå/áREMMü™" Ö~”>ŠHYÎ {ëæÿ '!MõÿÁÄ…Ó„Äù²Ž°.ˆ ÃÝ ¶KÈ‹†Þ6§u4ü÷C¤.“á±fè˜ÖÑ20:!ä¥ËáÂ’á_¾¾òù+ÈdaÌôŸ0ßá 8ªTykëÞŒgÓä$Rç­" žŠþ!sF”¯Žÿóÿ>‡?ÅêD¨4=À© †´8& - ×Ù1åþ¢§¤ÿðDÂendstream -endobj -1216 0 obj << -/Type /Page -/Contents 1217 0 R -/Resources 1215 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1219 0 R ->> endobj -1218 0 obj << -/D [1216 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1215 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F23 682 0 R /F21 658 0 R /F48 885 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1222 0 obj << -/Length 3453 -/Filter /FlateDecode ->> -stream -xÚÅZYs#7~÷¯ðÛÊUã/>*3žY'Wvö¨$m©euÔí¨[vœ_€ûRKÎì¦jkj, Àd«s ÿÔy‰Èj{Û@„R…ç‹í™<„¶gŠy¦žiÚåúöþì›&>·ÂF::¿_uÆJ„Lu~¿üi -.`9y÷ùæÃõÇ糋8˜Ü_¾¹˜êPN>\ÿpE¥óÙ§O³ùÅT%¡š¼ûûìöþjNMñíõÍ{¢Xú92èüêÃÕüêæÝÕÅ/÷ß]Ý7séÎWIƒùõì§_äù¦ýÝ™Æ&áù T¤PÖêóíYÆxÊæìîìÍ€V×uÌ~A˜ˆPÑùÔ"ùãVV"V -˜âЊÈhÓXY«1+{.´òb-¾L‹t›UÃ+ -@ßî°Â®é¦#]i˜§6ñ÷뼺€ÉÙIùTçeeXOÛWÙ’(uI”Ý…J&YUïòEÍ-댚ët—.êlGô*«‰žK*T¯EþF­åŠ;e»:ÍYì²ÜRÈ"¤M–%HD¬ƒ§,lj7mZ‘HM~–Ro\/¨€ØoJnxsGVÿ©,*ÏG¤E–?»¹eåHå–j4?(YýRî¾8NÀpL^f«t¿©©òœîòFÅ¢t#-óâ‘Ç*ÝLd -û*}„Át,')i“‚ëÉ: ü(–ÊQÃt @lÝ7F(mcfû½,P1âf¤cÕªŽÔ¼•$B¡â1Vi¾Xå9ÕÕÕµ±=kµIŸ³‘u(¬‰’¿Pó—tWŒ 2À¤G4wBÒ¢zÉv;_™ÀŠñÒQŽì;æ¯Öy´,°óPågÊ••Ö" ËêìØOGô\ÊÒÌé¸Ö>áûD¡ xˆü±(w£Ka…1¶µ³…c‘ÈÁïa¿°ŠS -4%™ì]êÈLVÎœ@Þdé†h벪9À±Åe¤oÑÁ‰RÁQÁ-ÙŽ­ •Žµoþá‘a¸gÁŒÜd&‰V,”ß–Ë|ÚKÅf•Ú¯êÃ+ïNn((¾3bVÙ·É »ŒI›Øûyúô´qÉC+Ê·ZZ^Q ”/¦9¤yË)J£Hš]R}6›Q&-ŸþMöTÎHøº¶ÑäºföMÅOkÁÚy×¾—Ë|Ú–ñÄeré(æïi¯Ç?3jsÛ4ÝÜ]áîóŒ(´k'€„à ±upìnÈŸ -™<]Àš¶ºÝ I•èP•˜U‰&·÷óQc.ò²Î×L|ø%ªY, ¡Aˆ˜Ë|‘ÖÎ¥sZsCMÜu±žR•F~† ÄÃoÊòËþ‰%¬ˆ–RÕ1¿œÖ%+†¢åÃ5C÷¾¾™ÎÞ¿Ÿ‹ÙüöÂjr/$ßFC’‹nnº¾¹Ç\$ ã£HZØÁMrDu¹Žƒ¨†« ³íoCÁÖŠ$”ÉiÁžiDpo—“€ èÒ“ü%£ :C½v¦† -gbCñ¿}o"ÄZ–î*îQvWÍ@LNéçú–«Ë%cŒ£,§_hêä~C>EÃ&+WÂJ«¿v“iŸÝTig´±0É—=•U•?lx?zN7{—TÂãŒíÙ$‚$xmĶ>Ï„ibd'…]+ŒÍ±¹¹mžR‰DñáÛá:¾ž« ß¼¨³GXÝ×Ãø…ƒ¹ OË÷L#òûñ+…N"ÓWà6ÛmWIL¸ÎŸà„tI4ô*µZ:§zEM.îá×»¶{ÂUã,m/åá Pݧ=䄦»ùENþÉ!œˆ(‰!<„Vp8VÝÏM˜ ÈŽè¼3*Òù^!ì‘+bÏÑÑ O¯8–7ûŒzÈ"û-¯¸+¹´ÁÓkÔDsˆ`:U&„gu Þ\Žz 9ÊbóJÍy1å5r÷…¶P4¢¥"¨;‹­¼ür_OËU3LÜfônÂ!ÿÄaÇåÔ ‹]9Ia ÓÌà% ²ÎÏh4‰‰Ù¦|¡b]>1ãŠ~YA(µƒŸvbÊv&†;™‰Ê6™`i'mXݬXðI¯ñu(“ByÄFI¾þÌÉÛ@ÈÇa`ÿDšMÞ‚&€3Ø7u—ëxnk¸ºˆzºp‡†aj3Z§:-¿áQ ŸÜbg¹ ¯ÁõjÄvV„ZzÀ6’#ÇJasÀÎ9œÜͤNBÜÀ "áž -¦Háˆqø±‰­#8U¬ {@>‰hcò»›Ù§«;¾IQ&‚ÃGbú®zÔ™è’g ÊÇFÄ‘6_‡ä8•IPùÞírwª†«]°j÷|Ò«NË÷L#òG|Êô8âS&H¾Æ¥`U×¥¢„]*²Þ¥€ä]*6Þ¥€HwaIߥ [»DcùˆìWM3ùJ,‰|àW¡"çÿ·_è¦;íV-Ó ¯b¦ŽSÁYñöÁJ"”Ôú¤ì†éPxÿÅ™˜°'ý_´ÞA4y"0F ?ˆ{ˆ+à ¹º¤6¾nƒ’‡ÉA“9€è'ãȼGÙáBeص]K`ßp"8F©äkpýñ5”ÐEFol8]®«è¹VÊvå´(§U™Nëzs¦µƒÐœV áÑ ¿”1l$QÜW×RyøWïá`Ç.·@M÷õÏqi?ó}hàkjøº„$Àèî5‘ðë>Û5÷«”6Í_°Þßÿ@‚AþN8!êPX«Ñ‡N* oÚixŠ¿ßk -üœõTp¢¤‹~óÃßßé’³üz¨£c+¤‘ꯀ:°\°TqxÚóº\Ç=¯áñ¼é"… <ð¿PhŒrR†kDþ‹@À€LOò?Up @Yw-´ÖÕ°Öu5bÃÕÂfw‡tt¸W¢9wÂ[~ltîæ(Ü»³ÖÚ*Zk¤ûµvBJ ®Ž«Ñ½5RÍÒåØê+%óæêã› LÞØ<º\'Vßs¹ÎÓŽo„é§_ª/‡ €DdßРáQ¡ïë€^B9ÐöÏëY‘í`±]â1>Z¡y>¿»þXqUnàðÄwLÖ]†õÇ[~Ù¸ê>à. uËß¹ë²îÔuÙ½íóO=€y7¼¤• 'ßß}OÐùg)MúHD—DlØr½¿¹ûþê?Ä8ŸscI¿ËŒ®…2jÎW¾¯Ã&Pú’½RSµ.÷›%xd¾¨Ä­yH¶a6ÐÂYPŒýehØNÃDOkÛ’VÔPwž€ ÚžUñ‹²&j3w Îç<äCY¯©ô’S)â“)“à@ËT¢•ø:µóñÓq,!N…Fpó•›ÿ`Øu”!€<I" -À…ý7B -þ@’Ò]rD\2‘x·'TÜy-Æ÷¶•ëÓùNB†€ùÆmJȱH "?pþ,E†ü°,üÝD5€Ø¼¡™Zåé/ù2£VJôôÉRÖ){áÙà.éу`¿`E³íè&ߊcW@å³»Ï -äÝ—ŠŠtµeÐÛ»»P¤Òë–X*~iâŸ8Jfüc-–¸^P¨É²3ºcs—+Xl@‡ëôJÒY -w¢[±ŸxY’ kþHc0ËœAòé¿w¡û3Í®:áW \8Õ¬FKN}Ø×Äð’Wën—ؽrR ß:‘Ç™)w7n@õ/Ì(±xu÷ü€ŽÐVfì8p• Hq܃n¡pв›¿ëi~ÕáŸ9_Öùb=ÀPdÈþaŠB¿°~Ëkîè|øè®ÇBÇÑ›f‡éÄ7kÌäæ(Ê[á¨Ãð¤PÏs(´›)l) @yW(?…XÝ~¨ø¤¡Ñºe›¥ø°Úo¨ó4ÒÉÐÉ7äý@ÛÐÅng@ò~ dÛ§ºq±²ìŒèîE“…ó­$Ðî¡K ˆ^ÿ–™ïªzü2I®K¼*¦¯éËDÈ8@}Îù¸KG÷t؈ü) -GF|‰”Ç=¾¡-†©lçÐV´Ž©Ä_Ò(Úø¢æJèÆÅßjÏÇÞÚ•ãð,Úå±:M(ðKÌ—‘ç>>ÿç>Û¯a|±Nô¸÷é8Aƒ°Rhsz.뇘°ëÕÿQÔ2endstream -endobj -1221 0 obj << -/Type /Page -/Contents 1222 0 R -/Resources 1220 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1219 0 R ->> endobj -1223 0 obj << -/D [1221 0 R /XYZ 56.6929 794.5015 null] ->> endobj -354 0 obj << -/D [1221 0 R /XYZ 56.6929 183.6365 null] ->> endobj -1224 0 obj << -/D [1221 0 R /XYZ 56.6929 158.6249 null] ->> endobj -1220 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1227 0 obj << -/Length 3161 -/Filter /FlateDecode ->> -stream -xÚ¥]sÛ6òÝ¿Bo•g*ߧOiâôܹ:9Ç÷pÓö–(›JtE*߯¿],@‘%ç’ñŒ .ØÅb¿)1ãð'fÞ0®2=s™f† 3[n.øìæ~½g‘}¬_î.~z¯Ü,c™•vv·îíå÷^ÌîVÌßþãÍÇ»«ÛË…4|nÙåÂX>ÿåúæA2z¼ýpóþú×ß¾¹tz~wýá†À·Wï¯n¯nÞ^].„7Ö˸Éï¯ÿyE£_oßüþû›ÛË¿î~»¸ºëÎÒ?¯à -ò÷ÅñÙ -ŽýÛg*ófö /œ‰,“³Í…6Š­T‚TŸ.þÕmØ› K§äg”gÆK7!@©zÆÚΜɘU0…l 8‘7ó¦Ø})v8Öó粪 -Ó[Uuý™f×õ®›¤A¾mž‹K1ð²mŠj ¢ÔBϯ×($¸Ë¬ÇŠ†9é282Qo«Â0,-sÚêˆT6‘ѧbYþɹ,V?$S¯!ìFï—/öèl!µdÚi5[Á2cd Ç|Îw—ÂÏWÅ®aGWÍ7 …N8ƹɦU;"-úXt3bJµÖ>Ò“J3\ž%&H”BeÌ+P°íOŒQ虈"Îäüú#òÕ*Ȧhš§&”û‚Þ÷M±¢i ’LËíjˆûJ{¯Šu¾¯ZB-Ç”‹ÍSûB°ªl"ÖŸÜðm¤‹T`çE¼T8—w£;퇕‚¥ûg·P=sÂÌ÷N€4óe¾¥A^55ÂYqªÞ¢¸ö$”Aë„O§‚\Õ›¼ŒS÷yS6¨ÇŠÃ¶UýÜQ#¡Édf0x¨êû¼êfø«ŸÚ²Þ6qULJüZ5¯ÁNvåj¬Ûêy`à9=¾ä»²Ò†¹zMÀçüÌ`¡Àýýçä]ï NbĦh ò”ïÚr¹¯ò½Ó -j@P8[®ñk’N±m oh("kçA&0ù˜)†ç£x“{>Þ’¼Kßè´cÎðä]¢µÑrô?á}îšvÂ/yɬWÍ£H™ƒPñc\¿£ç¶niÐ; ò8W×4E1¶se=:9³”ÔM˜&w3ÜöL¾Ã_ôÛüñ¾Áæ‹%ªO -¥’I5fHË 37`èÈótX¯°q¼²Á&®j¡ÀC;!ÀšåI™‘Ia™‚ðÍ9Ÿ¿ÛçÕ¢ióåg:ç š‰ ¥ØÂ3Ú¦¿N)KQãDCïtq½SS -Œºé¡® ¶‚À*G…è%ë]K3¨þ®wŸûû×ûíŠÞŸB$EÐ}Ul"4P|Òvùò1¿/«M7[í#{)¦Ì¾ê„ŒÕmÿôxŠêIƒ¢„ âøúã=Tg€Ød ô$׃Ǻ‰{m€·r[œŒ—Æ8¸÷J¼ìcŽ—žqÕ]ã¢9Üü nZq>3çyè°&˜DNZk¹r1ˆœJ›(¥í|›o%ŠÏQE¬ A0å<ÃÅÐ|¾\6Aƒ.쾦Y/-lÔ &í…8ff„öCÕhw½¡* o·™Å„m¡œGWª\øGÎ ˆQ¡h?b‚4Î¥ì ç7ûpj€ÞÉA™ ¸H²ŒêKšxŒ¸‰ÒÅóz£LG'ô¼; fxQz>æx8Í]8BbÊ(“˜#~COT%©yЧ˜hò.–‰þH/AÿY†Þ‰ŸÑÈq01Lðl´$ĵ@!d5ð,b$[Ƴì·Þ¸P°x&<ªê F ZÇ8_{òA«Í#Ú}QlSälð¦V'ì|Yo6A³ð¥"ÁÁÓ°‚=Lùné¡Úpàåé€xµqùBOˆC æ¼»KÒŽ‚¿o!zO›ž ÞÖÛvWW¯ƒn–$ÖéXÖaÆJ`é#r8Žb`"Ú»W¨wXäQLƒ½X?¢?¬ÿ¤˜??–ËGÊ"´ËŒx¦Ê'Ö‚ðŒGíc×E;Š ³tT RWàþ"(Xàþ·ÞFólCT?I¼±2¨9DËŒ”zèC¼ñ)¼À€¶ÄÑÒ´TÜî%ó,ëãû tU e"ò&¡Ý©LÄÑ}¤×ë] ¤u‘·c„’ŒkmãÆï‰6‰aÚtHoÀ1@Ƀá”(ÄÄá¼R”xK— ¢hB·LEbÈA൅@<É&$BÎféø]Šk^YXëƬc&â ™‰|”q³þ!jù\áz_á{l0zôŠDCZÚoM ,ËÂñ…Ãxmåðø£S?ü:ðRŽbì%퇘Ó)?¦ÅÍI{cSoZ´„iäù‡&åÓ¨¢h+'Ý‚ )0€uC}¬Ón¨Ã:¨=žÝ„÷BŸ'ÞaMPz!áüþ€üÐ tRŠÎ ¡™u^à/ä)Ó Àæ3êÔ1É© ˜ÍßÝ|¢) -¯ ¸“ILYší»‘\F‡1žIaeßÈä Èê<ø.ÄDk®yà#\<§}„—°—Î^qÃd6á"¤ç$^AÔ[zÖ`ýpš -ç°˜y\q^n c!ı/ˆ2S¨Ç#S½^-ßj»3"{e2Ô‘y†–r,wÓ‚Ô`Gm×}Mûu{ï§ÛÿÛ·–­>½­ã°W¦í‰;› -R;øJÐ .Pf¥v¹K$}Ó»0cµ  -Ì(™nú8Y1¿ƒÿr~u$ØTIÈ.¤r,èKÆìø–eŠ°zãpÚƒà§ëœ½«áL³þ±Ò΋þÖá\vàbÀ³dÊuÐMæœÌ:K¾P_­Äºaþ²XæËK$õSî™[F­³Þ7 ¨\·´ ½Ä¾w¬tñyÈ5±®NF”Ôah^Âö:R.A~¦àHýëû>P¶Ì8äü‡¯Kߧ¯Ôu÷¡¥n!²ž‰Hpsý!äèó©Ã9Þ‰ê¨ÅDfz˦[<k‚‡a‹G1ã ?01lñ¨.9Æa K8ìµ Å!,)Åc PÌŠ6Îâ÷³]\wp9øFI+ Âqñó¤QÝ7µÀ‡’X[s£)9dÐü¡ íÄ8Žó}E×":Z-b¯_ÇžÈ17ܵ5nÀÌ®XîwMLÖGä@ÒÎólDnß•ÏåšÈ]tìZÍklU>—Ídâ/N|]¼·¡»ÌÿM+¡†2Ù¸±6x°S2Á°›†t$òPÕ˼Úmós¬BñUëç©’gž[Õë˜ Cädê(´b^ÈW*Ø>ÖKMX'n|`§D&_¡Ÿ&è¬ÔB©Ë1ˆõZ©=@0LVj{Écxé¬ÔÆ6¥Åñsœ&Ôp¢/Ô% aÅcìä?<&@§/Ö"ÖL›ðb”6vôÑò+ŒGƒOÖn”’­b5lÕ‰“¶ªÄú ¿qÊ7xˤÉĈ^Š{’,Ɖd1νb¬Ò%þÕÉ5×æ,é.Çöœ‹a+ 2„XÇЙ,ñ„± -¨šúÛ­U~›µBò!•P絇tÚVÒAàû§dÜÇedW’¥s¤;¤cÚà  -¥å€ø°Æㇻ®Æãý÷Ì‘B -Àf¿ µ -Œß½lóM¹$ªðJ'lJÝBžZ@4Æê ¿È̆_%M -%ì¸ð8¨‰Í¢ÆbÞWÅö… ’îÕ.Õ6Kµ†çùMÝmÃ'b7øUÀ;ÂTj/ÛŒúœ.)²ÍúMc<*xžâªë“_ÎǭϤ‘å¶A×æ~>ù­Z -ðAN›™Åt\¼Òmî°ôc…ïyô•Ú±£OÔÒræ¥w=>ŽôµÃ9OR%ÀVzÔÇ=fvê`Ê0üÕÖuÞÕZßýã°Ã/ç´#þÜþÕËÌ%¦ð ætƒþ˜õÿØúÎÆendstream -endobj -1226 0 obj << -/Type /Page -/Contents 1227 0 R -/Resources 1225 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1219 0 R -/Annots [ 1229 0 R 1232 0 R 1233 0 R ] ->> endobj -1229 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [367.5469 658.7781 428.747 670.6783] -/Subtype /Link -/A << /S /GoTo /D (zone_statement_grammar) >> ->> endobj -1232 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [483.4431 456.4665 539.579 468.5262] -/Subtype /Link -/A << /S /GoTo /D (address_match_lists) >> ->> endobj -1233 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [213.0783 62.7905 261.825 73.5749] -/Subtype /Link -/A << /S /GoTo /D (dynamic_update_security) >> ->> endobj -1228 0 obj << -/D [1226 0 R /XYZ 85.0394 794.5015 null] ->> endobj -358 0 obj << -/D [1226 0 R /XYZ 85.0394 642.7523 null] ->> endobj -1230 0 obj << -/D [1226 0 R /XYZ 85.0394 619.131 null] ->> endobj -362 0 obj << -/D [1226 0 R /XYZ 85.0394 502.2708 null] ->> endobj -1231 0 obj << -/D [1226 0 R /XYZ 85.0394 478.809 null] ->> endobj -1225 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F39 863 0 R /F21 658 0 R /F63 998 0 R /F62 995 0 R >> -/XObject << /Im2 984 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1238 0 obj << -/Length 3053 -/Filter /FlateDecode ->> -stream -xÚ­]sã6î=¿Â÷fÏÄ\‘ú Õ}J·I››ëv›ÍÍ=´}m%ÖÔ–\KN껹ÿ~R–íµÝéˆ!ñíÈIÿä$ND’ªt¢ÓHÄŒ'ËíU0y†½o¯$ãÌÒ¼‹õõãÕ»»POR‘&*™<>uh#'«Ÿ¦‰Pb‚é‡>ÞÝûχ›™Ž¦÷?|œÍULïîÿqK«on¾ÿþæa6—&–ÓßÝ|z¼} ­„i|}ÿñ‚¤ô8Côáöîöáöã‡ÛÙ/¿º}ô²tå•Aˆ‚üvõÓ/Ádbÿý*ajâÉ+¼B¦©šl¯¢8q†²¹ú|õ£'ØÙµŸŽé/ŠˆU”€&#h=®d)´”€££@D*j•¬ä˜’*9Ûlª×ùa·Êš|þTí_³ýª(Ÿ‡ÂK-… @êî'Œx¬NÂ'R'Bà¸ÇÊç]¾,~•×pI8}]Ë5-×UÝ04ÛϤ™æü‚ìç+zi*zևŶhhýͱ̶Œ_>~¦É[>Ûd/9 ->™§±F¡DR¤q¬,ÿ®JûIÌŸÄjºÈé‡|­,3°E(€ºfœmV7ù ,2”zúèvVùSvØ4ôRÔÈ»»Èt¦T"©XNþ3›'A0-¡÷´ü/}ÔÓ2˜ø“ûæšÈ;"CyVÖÌì:ããKf›4D» Š6'Ý( -#Uì”CÎêÄGÛ™«HO_‹ÍW†”]¾JÛ|…òéôq–ªiE8y™-6Œç†uG±@ùšk4”§ã˜žR)d¬Ë|Á¸A û—̪ÍÊ£Óìû7U‹ÂÎgbËj ƒéK¶9 Áàº3ØÓt]Ž°.Ã\™?vÅÃ¥®i„®Ié>ÙŽxcTA12Hø“‚E8ÔÐç‘^–Õ¡kÞÙ«©V‡%G(A3!Æ«®R›â%¿ÆK'+Ê%Þmê<l€ºÞUe],ŠMÑ íÎ"x‹`¶\æuMëeUÎä´!&6«×Õa³¢5nˆÊkѬ'³OÒ‡ùþ…ü“Y-«¦EG邾ÉÛxQ ¿• -hc·>VÈn¶Jž:'ãö, ØɆ뾵3,Ïšƒ y™í3#Bµ,„%°ëmväcßUuî€$n‹\÷£ë¢Ó6dɘñH|e/=3¹ÿDÏlµbe×Xd5E ½±í¦ì\(LRÓdË_ë÷ôVçù0…:À°3I¢TD&¶™ööÏZÑ÷[Ú½ÿ¯bHBϬ\ >°Ñ/‰…2QÔ÷¦Ÿ•ŠÊbAé >Ùd‹|S#”Þ‰¶ž.Š2Û»8˜'M:ý*œ62)ÓQÀ\°, ó–8ÞÆÒú5÷…ǯó’ðW9…ó| iu=º »ÖEèЉ7uåì´KË<,#Œ^V¯ x.ÙÊ9dp¨ÆHPmswʾôi %{ÎÏ;Bœ„BEi|ÙºXçÁcµŽ` ç)ߟ883ô/ñåó=Ö='P±0Ƀ^©ØÕt¸ä:9RI['#Ü×Éø‚‡O¾¡¼xa,¬p…åcZ­_ØÍ5cµ)SpÑU_Ç"Á–¯[Œq™B ™@Ò·®ŽROâ4\)“²ÉM…©38XÙ"žµWΊEION⥠-ÔÕ’ [œžH) #Õ Øô6/[ŽJ‚+­a¹Ìj[À‚i7©@QûbeˆóÜh#TlœÆÈÇj'jG}`Ðk%ýzä²úÒ@GCœ_>9dí(ñšÓôÚ' ß«´Žì“8òÈ Ö€´°†zÞ{Bî¼ì½¬ Þë°PôŪŒuµ9)/d E IçòÑkäìžã‰wÞs\Hj¶„ƒÇ¦ÀWÕo´å”ÃåBÒ®rZøzO)n·peoѺkÇëßù¾p¤Zo¶g2…ƒ­5·`ªÍKîØ¥Æ)&MY8Τ”S6ª݉xÛ¼JÆTç'u£ÃåƱk Æn…•ËMÅç=ž³ÐÓ–(wˆtàz¢ò¼ÓãœÇõx§î -Ù9„¯,7Eý [ÉDÄ3°h°î±OzÊ 9Ò+tö;{ªol_‚!ÅdûÊé°±«övKîÙSåÚé ׬Fûqýê Þð¥s+¶:xÁÍQ?”ÂÆ¡¦ük‹_tÃé í:/çU9"ùÜãö̈BÞh6=±ùÒQ(ãb]“ýJ=¸=ГÎÈ6ÔÉ¢F±á‹%i™1-Ù0í5èøôÍ6Z.¶5Ã6êÕØHCe}Bc½·æ„J¤Æ˜ñ)áÜSœwIÒ µË_¨ 6ihÛ=¥Ê’ÒÉXaËþ…L:Šo1 5AÁ­÷˜´ðmœƒ•à%ùè:cÇ_tIWŒI‡ò¦RB%íèŠl®çl.‹¹ø²8àI§K¶K<|S3z • ‹ß³É¶EŽÃaLt¡¢õjtôð=ľb·uÏ@À*ýRÂh_nùzÁ)¨Û‘²¶Xì;׶æ¿g[àâzÄ‘æ&1º2ó­ìعª ‚Z˜Þ,nØ” ¾$íá -Š»¨Gíobs("&oïdriΠûA4‡2Â9é ÞõóJí¦I,³-ƒ| (õ–¡»U€Ø[Õn¾OÁŽS`§odø é D§®Å£M2# k „dåšôqt:ÞR9–ë¢ÌÝ䇭6gËÝ9ÇÈÎY6k{ÔLÛšsÄPÁMMýa;u \(_ýÅôœÊî¬ëÔ ÝŽ¯aÛÀ!|ÿ¯5þÚÕ•ôq¼ÔO!üE'2Î_’±,”²2Œzm·ÜhÚq¥í¡§#×®éƺÐY’Lj«0"žÐØÌäÔ¹.-¯Kì}xÚßÑ%@Ÿh"=™k°_­M¿_)ÊeµõýoÝz±†`ãâœÇ¸ÿô’ŒÚÒ¿p„qgX_4ú|cÕèA)˜iƾê¬54¾Qz¹R°?‚A9QÐ,$aðç“°§8ï’> endobj -1240 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [369.8158 645.68 418.5625 657.7397] -/Subtype /Link -/A << /S /GoTo /D (dynamic_update_security) >> ->> endobj -1239 0 obj << -/D [1237 0 R /XYZ 56.6929 794.5015 null] ->> endobj -366 0 obj << -/D [1237 0 R /XYZ 56.6929 475.2364 null] ->> endobj -1241 0 obj << -/D [1237 0 R /XYZ 56.6929 451.0522 null] ->> endobj -1236 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F48 885 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1244 0 obj << -/Length 2446 -/Filter /FlateDecode ->> -stream -xÚÍ]sÛFîÝ¿Bo¥nÂÍ~“›<¹±sçꤎúÐkû@Kk‹c‰TEɾôæþû‹%EI´“Žs37š—X,ÀX#?1Ê ãÊéQæ43\˜ÑtyÂGw0÷þDDœ´EJûXßON^_¨l䘳Ҏ&·=Z9ãy.F“ٯɻ¿Ÿ~œœ_SixbÙ85–'ß_^ÄÑã݇«‹Ë÷?_ŸŽ3L.?\øúüâüúüêÝù8¹°^F -O,¸¸üÇ9Þ_Ÿþøãéõø÷É'ç“N–¾¼‚+ä“_磈ýà gÊåfô/œ çähy¢bF+ÕB'ŸN~êöfÃÒ!ý•3“Ël@R )Ð8fL¡ËÅbœ*n_7 cl枀U±Œ Æ¯üš uE°U½ÞÄ(‚ÜÖ¥¨>Óàòュ¹b6[Ežø¦ñ MþÆ ,7óˆ@À¦¬îZF€½Ù´Ëfq¶žÞû ,¯ð¢šu\Áq€NR!˜3F‰GáL"¤Ò8ÒI}Kâ G¼!Òf^Ä…e„Tu ¨èÔ„3+Züçò_4%9of7ù›7¯•$ÐNX\ÒøU±.6žæHª¸OP"B}1ÓhYl¦s?°Ç:Cµt89“BÎdìdR“é.‹{O£À>Ú³Åq‹²ÙøŠÆu|†SÅi.€vÛ¿"ȶñȸ¯ëY_ÇÙQOë*EB–óäßô¨êÊ¿¥áÞ=+: -\ÅZè\Þ¶lG\ÑÕ’å`ðüxÇcºÆ²LX‘ëÕ¦l…ÆãZZùi‰Gìg¯žQ yÔ Uɤ÷fVp -ÐŒk—N1h ËÐŽ9è짭_G§@H ëP¦ 7U+Žê‰£ (ÎjßTßmh⾪p‹ªy$\Ö´¦ ×?¶¾A5¢£fà5‘H 9„€Ìâ’F*1æt| *SÒ´ç(¥M½]Oý€Ài‡¾ç:»Åxdm”ÊîÅš¡(ƒóì<Â(êÁ Ù¢Ãâ$2Tz`=µ&K.Z„ŽØ¾Š¤jR7ÀÐP_]ˆÂ)[NÚÅ1~ë¦ âH7öŸf³,ß³}FG¶q¼ûËUD/ž43•1‹ÖÿÊf€’c™6&bümˆ5°tÓr†´WZ—Í}u©´*AÝâ3ø©…è¾,7òQRNî_$ˆvù‘föŽ¸ËP0ánhÓŠsyuzvv”îà.ÙÈÀm›Ki¾&Ìåy>œ¤Å´O’n÷>{FHf2ðè ¹<½úe@©­ÓÙN«ti¤Úp+ó}/‰þªtrƒ¦¨T°ü)‰aûÈd?¼=Öà1ƒL-³ç¬Cp¦µµÏšG¦mg¸kb3x -°¹3eLð®Á“ë%!n«Õº|(þ.x2ÌFïVº“ZE©u_êÉ|Èï$ø‘ãY“Š‡ºœ¥:ÝÎV))XåŽ)­ÍqŠ2ä? Ž Ñ’«fC*’FíoiÖO‘u`ƒ{®ŽvŸgÉ´¨h€ã“Ž0°ã3æ9!pÉ܆Xqnê߿ðÓ dr‘¶_oŠ2ÒŒ&µì4 -Q -øå~ìšùÛb»ØĘü׿ùrz±w„d¢¦Fn?#‚5`?ÊìÌkÔnÞ›híw$C?=^Çže¦¿æm -bOŽzûìen`UàÏö½}ªrÑ$™–_Uº@Èq!"E.8‘\1«á˜ž¤Eë8ЊÃvÅAìJDå t)ª¬Ú -§Sm0íL@i¨­‚{CåAÖ«ž«EŒ,FÉ6–€#S„™œjhj¬i°/Ç]Ž[þeB -æ!õÆAÖàõåRŽÎjhÔª%œö)¡àè{.áÄÑpŸ:!H(ôp ÝÙ ¼¨~ŠJ³èrøÜ´Ëö#€DÒ‚Þ{I¦‘ çXò¤Í¦ö8²ƒRJ¤Êa»ÈE„ÜŽ_nj¬~pôóÙGÂŒQ R.X¥î¾«LÞá-ë–7Hƒ {‚Ç+Š?7Èä6£XŽ!ò*lù(Á‹Õj’.œ««Åçˆ^$ð‚€Ã=0‚|`˜¢¼xDÄ…ü7ˆåÏa†yH–'Á0gW¾ãD4»{ÁìÐ!ï€cì»Â˼ ýØ8¨}Ò]—áž!6Wö›Ð‚˜d3iÿ‚¤íŠ§âˆ„‹ØeÆ~!Ž(Xdß4Ž(Hèd®þq¤Où™8¢¤`R;XþT/Šh€˜5å<[`‚†TôÀÀGp£5A°,¤Q¨rqÐlW=Ç ¿¡@e.ÖV·rØ¡^øÒÅ -|A¯èv4õ]þÿ°aÜô)éŸòË çÿßE³j­¿ i\ñ”‹€I1¶ò¼ŒeVÉoé"XjYéÄ·w‘>åg\D -…GC–OÞSP.M=p‹jª¶JÙ@ÑÜb”÷á}þ*…ŠAí*œ.Åß¿¥¡fÈÛ: ¼­¼ýÒý ¶ÂU[~=íý~™Ñ|{÷èÛ!Rv¸ìmÑöïxÌncO,‹=±ÖUìÓMÆBˆ$œ_EgŒ¾$`»e^ÄöËÒOçEU6ËøŽVè -ŠÔ°‹„m0 Q1-Ç‚æ&ôyôg`% u\ì÷— fÒ`QBùgëj¯?èËz[EDìf‡u1£]Bëz xööDmD–û]É]Gós³ñKÌ€À’'-ô¶^,êGªêpUW>bqYVìW„µ]×PƘb·`W&—¿Ðx ;w¾‰I8„éôAÿgî+”œÚ"Vû¾™tZ¯>Óˆ¬Q´¦Ê;“籃)‚¡R[&Ï£ÿ„L ¤BßÈ…zTv²ÚØOŸF»~o¿ïâNWŸ†Rqb}ZS70t"v"BÑñdî«8 – O_5ÛV­p}Dmã HNå€#ÙêyDC^â\ü,à°ë]N„åÕµyï|$RÑZ±X`½„À®X¥¦ÛPù® ̻ËûÅ%w±Ygp5årØ)ܵ¹tY˪ި£Žiûõò˜õÿÔ–F{endstream -endobj -1243 0 obj << -/Type /Page -/Contents 1244 0 R -/Resources 1242 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1219 0 R ->> endobj -1245 0 obj << -/D [1243 0 R /XYZ 85.0394 794.5015 null] ->> endobj -370 0 obj << -/D [1243 0 R /XYZ 85.0394 650.4851 null] ->> endobj -1246 0 obj << -/D [1243 0 R /XYZ 85.0394 625.2941 null] ->> endobj -374 0 obj << -/D [1243 0 R /XYZ 85.0394 171.1138 null] ->> endobj -1006 0 obj << -/D [1243 0 R /XYZ 85.0394 149.3849 null] ->> endobj -1242 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F39 863 0 R /F21 658 0 R /F62 995 0 R /F63 998 0 R >> -/XObject << /Im2 984 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1249 0 obj << -/Length 3623 -/Filter /FlateDecode ->> -stream -xÚÝ[Ýsã6Ï_á·sfÖ<~ˆù¸Ýf{é\w÷¶étîÚ>(¶œhjK®eošûë @}YvÒ¹›¹™NL‘ ?€¨¨™„?5³©H½ö³Ì'ÂJegËí•œ=ÀØ7WŠi‘hѧúêîê¯ïM6ó§:Ý­{s9!S³»ÕOóThq 3Èù»Þß~óÃç·×Y2¿»ýøáz¡­œ¿¿ýû µ¾ùüö»ïÞ~¾^(gÕüÝßÞ~º»ùLC)ÏñÕ퇯©ÇÓÏ™I?ß¼¿ù|óáÝÍõ/wß^Ýܵ{éïWIƒùíê§_älÛþöJ -ã=ÁƒÊ{=Û^%Ö›{6Wß_ý£°7^”Ÿ’B›TOP›žÖ{;ˬ©!`^á€Rõ(•Æe¸@ Ù4õ¢ªåú™iû³Z%\ -=D»)›È(Õó²Á_5(¿wño>±d¦D–¤)Oóïº*&ÖÒ UŸZ&jù¡ØÕá NkçåV|*7Z¨þRì÷媠§Ãc1¹WpJßLjÁ •´;yrZ¨ÌÚ!ä`vV< Œµ³0 Òî ²ã†d­ïnßÿ“Ú[ØAþöOëzOÃcÎĨðFÉùÝ#Oµ*ÖùqÃe_áÑb»;95åa#Êj›ÿ¾8ìóªYA½‹C¹-e5fDY)¬»ÌÓL°1€ Ú¦Ê ù¸­îëcµ±»„M[‘µÍ|íæǪ*«ÞÔÕðM¤àì¸U6ÔÚæÕ3½¹-«ã¡ànB¶îã:Å~[.T™^U6ÄT¶·z*”– ´¸dDƒ¦æc}Ü7¤íát ‹r{ÜÒ×|s,†3kÇËæϽYiF+^DRšj‘D.#©OuI-Õ$’ÊÕfII&œ’ö2'-Õ+C4Á¨WnÈK‡&Õ¢I Ѥ¿’ –Š¿»À{ý}õ¢§ ²T‹,eQè×jÎà‚g—bp©¸œqº=6ÔWz[ªÃÖÿZ"•Ô¿€¬Žè°˜è¼‡ª‡S• -¥¼ºÈGKtÊÈV)èI"H{œ|<V‡ðù ­¬ð±ï¤ðyð`?¨ƒŸ¢VŒ¢M¡Õ*¶ê(:Òð•>”‚S»¹Cõs©…´,\žá}´hš$É´ 7`=R?ôtê‡ÞVý0Ô} ÜåqOºÓ°+¢wø|SŒ÷üP,`>i\#cÀ“l6õS±¢ôƒøNMøØÀ éˆFê ÐÉ ®’áF¯XÌ,KÇ=ý¬jZÏ… -G g‡–}äõâ®qv=e·}ŽÈêY'¾!8rLqªšC‰Î×LTr¨Ö·¥×¨VITËî綂s&'¿§©¼7pw±°¼ŒÝ]‚î|]P£N<äTÙÈrÛâL·]xè\á >”71Š g* k=ÒÈœ° ’?æ³$s#œq'ÆK‘*ûBÙ§OuÞ´TA:ýx]ï·ùiø«-¼hÌe&Zª .†‘ -ŒfI:dã_!XPÞö^|\â€{']a‹•^zª©±‚èvÂjIicÍ›©³ËdÂù$ž^ÀÇx‚ & -’ (Ù¶õr°˜)»NzÍ4só|“Faá¨i‚+Êì`t[LÃ΃¿l:£Ë1î”°©;ñ±Öñ±–… „zâÛëBB ‹ÁR ¨éwU„Ä´br2Î@ÍüÐBü º\5bª@®P)®§tu;”ÍY}AP¬ñz†¦¡Ñ„m¡¦¾þð=õp-˜zC€€½ì!9ÁƲè÷.ÉI®è•(z[MíIƒýÿÉ+‘áE¢ÚÚ÷._þÊ¼ç ­²9ª}§ÙdTJ:å]«lÄ{C9ÿîê¦)ï7L -XÍãôÃ2“8ÔÂ9õZÔ;!U{ýQòêÛº‹N³yì8”ÇK¾úÑf~’ dŽ_ª«·@«9îvõR> R ²jt¦?S‚I+mòÇ›c ÿDƒœ„&e=x¢Î;°?(AÆ0{| irsâw&¦ú£ì% Kuõ”³60Ñ$cÚÔ÷à+×1ëŸFü”QL‰ßx!] ­Ö.%ßåIºÖéI5  üð—aÔ†Ôß•K*B4õš»~¼¶0´ªŸšªÊ@$Ï^Èh»àš˜˜Ø=¨3K}òòîÕK»Ï„ÌdÖw¹ãsRØÌÿaŸšx¥Zîø(Þ?ñýäªà[žxÛ“ÓÏŽ§ï*¼š71˸~e¢ÁßÛÝTÒt"B¥§×«gƒÈš…Éä ¹LŸê|ðÑRõ…ÛLÝH8ÛÌWo©&–^m&xwn‡ë¢e·¹>´Qµ¦4ËöA·÷zx ¾:ÄV[°qÏ”ƒ +$$'àƒ¤¸˜Ý¥¢F‹ÔdgQ#c¾šÑlÀ¯péLÁ®äô¥oðÑ ¤Ü·Ùs‘ÌMØ.Ò¤##‰z<½½¶¾=ÇÍ®‰4»Þe3v€x¾U<Õ’;ƒ2ðEvÐÐDU÷ ”áp¢àKaˆüðŽetÇÎ-TÙ²Ên»ÅèFwSç«¡Ñö†–ñ*·y†°h{Þ€Œ>±/\ˆô©.P¤ -~ªl ˜Ï,jŸZ°±Òì6²z• ŸA¡òpJe©½ŒÂ>Õy¶TCÆ“¬:-Li'’ĨË\´Tl˜ÑÇ< d>C>¸ŒÙ¿6€‡®2È¥!%;wŽ\¨VƒË–ðH_‚HÆ"vÝ3å öïïÙi±:=ÍÖ+!ž‚ø‰ßOùˆmJðŒ‘µøHŠâž·ìû ò¨üPél>UÑ}ë)Ÿ-|–¥½SÁÈW - -r* a1Ž8äœÄN¸Õp:°1ãç$ãºN83׃Òg†¢Z0¶A½êÎ ñ™ÕåÑÑé€=tN)=:zK*>¨®FÜô•ˆ¤ÄÀJO‰§2ð^+D8bm/<»hþªÅ Pì¯ù7§áq^¥44ùÓ@±ëLš@ZcÚ/È:s:e8Áê²”»Ç= y[ÓjÓK@¶ëD–Œ*ÿ³PW)#T¢^¸lîS]ð‘‘ê$À¬|yz¨È<²˜h©^àBixc0Ð2£Æ¶¤.ÿd[Ó1]dTÿ«@&ã;Fö™øË.¨é<ʧ/ µîÞ}¢XqU,éãLŠâœåÆÊ]*–žÖÅjMŽ,œG‡…®?µîßzN¯z5®“5¢a.WÅÈÑ e2x·_ogÞ ,ÓЛ©J=ÕßmÊ9¾…gž;›ÿðõ'êÁŒüÍ°T—Åï[ú4† ¼ê#uöŠài·&¼«q¾Õ3x¬rIãÇÝ -,óv£aSk"‰__ʱ1R¹†ë|ºÍïz - -ÓÁùàÅÎÔåèpÜl#Ð3hFèa“à­csdairxaGn q©5ß¡{¹V¡Ø¤M¸lܯó%¿ó³ÖÉrS7‹áîxER<üÊé°ÍËaçÀëÃ@î­Æ;ÖàNµ²„DÛcœ3ßíŠ|O½ámâÜ£`î¿LÖJT*¬J}ûí¦~ê>t™(Çe"‘z\ÆSg¾|7VàçêJ¶ñèýU|÷/I& F8óñƒÎ jtxAALá6lrêâùóùSÖÿ!Å^ßendstream -endobj -1248 0 obj << -/Type /Page -/Contents 1249 0 R -/Resources 1247 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1219 0 R ->> endobj -1250 0 obj << -/D [1248 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1247 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F21 658 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1253 0 obj << -/Length 2665 -/Filter /FlateDecode ->> -stream -xÚÝ]oÛ8ò=¿Âo§µ–ß»mÚËb7íeÓ‡Ãî>(¶’µ%×’ãKýÍpHY²e7Es8Ü¡@5$‡Ãáp¾>aðO22éÔÄ:•jÆõd¶ÿëæ—³‹›î.ýûr&ñ"_Îþø‹Mæpí_ÎX*]¦'[°”;'&Ë3¥eª•”qfqöûÙ?:‚½U¿uL~Zf©Î„ =r°2«]j$,¡Û‡n$eòµ>çI·EYÝ#(’vWÍ]±^Ÿó,)æ¯pÖ$å!Ö´C$eCͪ˜•2&Š9ÈR2ßC·Öæm±,ª–¶4E $ðË{üJ&R#4\Ò3ø@6¦M½YÏâžþ-Kã"칫×t@¾XЙ_áænœL¥i&Œ˜L9OÖÂï¹Ý{’ëd–WMÔ …r>/ª0ë9 W·Ç²Ø„5!Ä•¯^Z¸r›7(>RYÍ›¹;Nçcáð¼â{%ÂS&Œ -{vO@"…Õ*sClËö¡¬HÑÇŸFÙÔjÅìo|x²Pð|6r Â8¤§fFGæ¼|Fé0ëL@º]Ô³ÏÄ[ŸGÌê -Uï~³ÎÛ²«8³(Ò}Sí¬©TI0¼gت̼ëÉÆm•šÔX¡Ó¢} hv˜=RÓÈÝ$˜Zclߤ»·Bj²²ã8h>¼$Êèª'Em'ëOµQÔΧ†'7ð¿H.DD¥ÐÙÄÀ;3«>ù2MRÎIÂêÁþ¶;)ø‰Ÿ.—bò¶†;Mú׊”§}Òþ^`‡=½ÐpÅŒ૘bÖ3ý{½ÈÁ¤À:¼ñ—ˆT§œÀ¼šPœEY¬if^¿ª[šÍj…æ©@{ÂLѶd}0ðågɬè„ù|]4ÒݹdA§ñáûæsóæ#hžÍ`óì\°ä3þ‡¾˜:PCå,8c#'ý‡þ1Ý‘t}¦» ñcš=.ÅEp¡© qí0Œ³”ù—e2UÚî^v`ñ1BvXG<ÙôѨ¥1 ! Ö?á€k„‘A4Çh•Üãä&º’&_(oF—6)Ž—'6„¦J{^õâ_³bÕLñÁ{´@° ,Pð¥DˆkËbNÃMC¡ÀËæ@ÁèYøD[È$Œs'Þs‰ÖñÇë°ð"ù¢Àðõàú 'ùˆH#| ß"·ï3`ä5Æck‘¡b]AœÃ¡Ù=Ž_DæKoÔ0ÆD¿dñ€N1feÓ¢=V5¢‚ƒ›}o862n¹ËËE˜÷5g!r*:íMSLQÚ!vC²—9©‡ÎçÙi’´]Ü-ƒš <&µ„-˜{‰0™ÉÔ@ÌýWw “J/Ì2ñ­0©áÍ8ãöEäutÆÚÿ@˜ì“>&Dg]ëUš±ä ãN½¡Á¼Æ/&¶eó@©>ÞpP’`=¸š+ Sð¼•.,"FMßÛ0-Å*A23ä y¨7‹y€‹–doúZ¹G£º“J#p<ôj@Tí¡L¸H…ÖÑÍæ«Õº^…¬nµ€t[ ²7Gî¬}6´ÙDØ y±*ª0¹YÕY`wÔ€íû˜H` -‡OÕ ø¶á~î6Ù¡ý× 0m]7- ÖŤ4ø²¡g@ÖA–ÇSŠ`üÇíì¿œR(!À_9y:*uX'¢ÒXZ‘K†ò¢Èa` -H#¬ S†)™•C^00 Ëú ‡»À„£~`–S…mcq%ÄÀ„ðx`bYÊyWÃ÷TB\‰apòŒ'p•–Ù^p"³Pà”3aÕÐ,N¤ ûl€ócÞg~+8Å´Efèµ8Ûô±ŽkQ‡uè‚Nç7øôžþ$3Ö7E‡nTf†ì|jP²è%27P)œß©Tæz*ÕÐrÀ¯¥èÌ´¸‚%|HvÉ&Ì÷Ú9´ÚR7–æÅ]¾Y´aø¯C ™‚ÕXð@ªzäѹ•ºTÃýÖ BÆ[†ü¸w¢fã'‚'I­p±éðT4cgY¨øUÄù“iF"Ýof±¥°\åmy[.Êö Pùq%”¸É¿¡„=¬J±H^my÷tLíX vÉNßa}ã|®Á“+ÈOO3°_ØÈTj‹¡y*¹,+_s3•lÊ™Ï4 $¯gù‚fy8,aqíõ®i0yàY(èµ^a3'_`èÆñ§·iTðm@Þ–‹@ø¶Á5AKwSø6\ü65lrõáæòÝ?iv |ä÷EfbŒ =L\èñ07M–V+ß{@[SH34à˜EþÁbýˆ&jUò·±ÚRÅe—ƒ.sp÷ë1=ƾ¯b¯{†¢µÒÙÑ+Îù-JJEIøz6±?:F€ exì»üëí”Ta„íRˆ{Ѧè,ßLçQxp\¯쇾ŒÐx—‘+HŸ]×»|†‚ËÌú½_¤í{¿„ÞïTjº¼09ËC2bÀ\ZîuƒC6Öïýú16Ë)Þ°ÉëqÖÃj (öBû×gOôíµ‰èHX·à#µ2ÏsL4~=ý®ÅJßß-¥M…Ò|(gõhŸÑë}VÏø¥{½´Tg.{Á^¯yÁ^/Ï Øãö›E¬€¼^j/YÄ -ÅŒ€÷yù"¶OúD+0p\üÿ÷zûý?ÝëåÒ–©ÓÙL‡uà¶ÆÊ1°QÁÀoõi&4k„…Aªg@§2ž yøµü\Œ6ôRÛÅoºW­|ØÍõaÅwlW+ÐÉ]¦ê¿!xz8&±¸©Ú!.ör©]ÆùȈ§æ†§Bc'PŠTe d Íæ&…<–3™mÆ>}Bà#¤Oý -eÕ\°ƒ2‚þc]Χjº™¯¦˜n¥!;ƒ]”¯9¤†GÙ²æd»ø……ˆžã>ä:*„i¢¾£š -(è"”¡)º8t¢_mò@‚2HœóŽ§b* Š†ƒK%Eæ!€/Oš'ÈÔ–q®)ï+ÂàÃâV#°D¥GßÅ#Ï>ƒ Á -aöTPÕÇý}›@€Tâ‘ôÖª|Ù¹ókõ’fu~"è±ZîÞ»Ÿ#Bù8÷µò¬Ij´’Óg7¤HT­ ŠÜô… Ÿ¢ŸñÍ-ƒ-¤g)ýäíkÑyls…Û`"©7À†›Íìa°qȸeˆóîr (š·E¨·Ôþ öJÀ}€Û§½,dx‘Hm¾‡Uu?&ÅÜï¤_ôí¿»=лÏË*=ö§&R§ø÷!#N’uÉÃÿÊîot”Må^Ÿ½ÿào„³‘)²Öûœw¯rÈú¿ÜLº«endstream -endobj -1252 0 obj << -/Type /Page -/Contents 1253 0 R -/Resources 1251 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1256 0 R ->> endobj -1254 0 obj << -/D [1252 0 R /XYZ 85.0394 794.5015 null] ->> endobj -378 0 obj << -/D [1252 0 R /XYZ 85.0394 141.2512 null] ->> endobj -1255 0 obj << -/D [1252 0 R /XYZ 85.0394 118.94 null] ->> endobj -1251 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F21 658 0 R /F62 995 0 R /F63 998 0 R >> -/XObject << /Im2 984 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1259 0 obj << -/Length 3339 -/Filter /FlateDecode ->> -stream -xÚ­ZÝsã6Ï_á·*3µNü5÷´»Íîm§Ýí%¾¹‡^d[ItkK®%'›þõ >lÙ¹½Þd2‚HˆIà´˜%ð'fÆÆ6“Ù,Ítlaf«íU2{€¾W‚yæi>äz»¸úË{•Î²8³ÒÎ÷ƒ±\œ8'f‹õ¯‘e| #$ѻϟÞüðÛ7שŽ?ºžK“Dï?þtCÔ‡Û7?ÿüæöz.œÑ»¿½ùeqsK]–ÇxûñÓÔ’ÑãÌ ·7ïono>½»¹þmñãÕÍ¢›Ëp¾"Q8‘߯~ý-™­aÚ?^%±Êœ™=ÃK‹,“³í•6*6Z©Ð²¹º»ú{7à ×:¹~"‰¥²rb¥˜Z@“ÅVIÕ- °1ÌW$I}Þû¼-«šèÝKÓ[žtÑÔ‡ýª ·ŸÊmÙ68¢R’ôÇÆéÇ_<âÒEM±*ö×sXÈïj:4ù÷Ö÷øÌ¢m^½0 ôþZ¸È‹GbUð÷«¼"bÉ£lP©b »©Ý­òM±¦ž§|sŸå4¿l6õ3qeÑócÁ#6»bUÞ¿àBÀqRBÄ™áIëƒò$Io@¸¶6z_ï±UDÅ×|»ÛßóR 7D( #5 £ŠË {#]ª˜ÅÏe-Yæ¡AÝ‘*+X¯œ_`9'Ä%2Vifƒ¸$U©Nê ±FÆN&³¶5 Ë«B/ù`Ö4UÜD/½bíʇ|ùÒñ„6À c«––úPñ&N(¥Ó8­Y)Ú„ßa[[ÜXeßÒk«XמZZoŒ@ló¯åö°¥—ü)/7ùrÃ}ù¶>Tí”ÊÒŠØYmXuqŸ6í„¢JÇ™sôhŽäó¢Q[ÎÔsÎleån®4¸³ß}ÝY:"Û,P4:ÁÕ|·Û|Ͼ!À±‹âè£uѬöå®-knÒ† #6* SkÊ?Šc TèþJ¤3 @-œ°ÿ -J\07ónÄùpÈS€SÒÅF&¦—ìu£Ø#)c˜`á´ä£iXF¡ÕhÔ¹˜q;@áŽBÉ‘mœŒ‹òïŠU¿ò6ÇÚèÄé9=Òæ$t\¯èp:ê³Õï‹Ô°:x!0®X&x­½Áx»Õ`wmhí£¼vPô)tâ—Ažˆ6Ȭòm$°eCëÎPC4h<àëè®|½èMê€4åd´®«ï¾œˆšÃnWï[joüXHy ‡§LÈça¼~HtÀŸ&&ú\ñ‡Õ#S$°H íaŸó}åÈ¿”› ½ä!˦9xdGz ob:‡Š÷¸æÀÈ’ÃD|’¬€SØ{‹î‘àLrALó!×ùÜ¢ãòѪÞS‘©X -óŠàÀ4!xhÊhÀ™=¼ Öã<" ª Í?sz¬ê.#@ Ýõ_•+J?ûYtA^ÏùæŠ*KhÖÍ9¶Úö|xؼÐ;˜Ýý±Ûª(gžœÏ9óøxa9LæÛ==`ȶˆE¬IÀ¶ö…È3±€— ÎX>óÍ¢å“KJ7-Ÿ™€ÀÁ -"IR~9{Ÿ— wþQL7ƒ˜nƒ¿Å;Ìpm—áZ -G˜óÖ5óoso&¨Ï õ±únÑÞ'¦ùR€9[Ù =iyÍ¡%ÈÅ&o<ÐÖaLÂMhëœ qaþк|9út¼ "EÞže"?†xª²€uóU¾z,ær€%…ŒW‰…æÕzêÜæâLëpܫþ)ŸŠ9cŽS±F­{µ)‹jò|®àh\8söù6:BžIà_dp»“†\çcRÇ…Zü+Iä¦hŽå¦ÒPþ¢ÜÀ4!w8m—ÄÚ);–ËYm:<¦QuØ.)ÉLÉ\à4ô/mø¬OGS48l>záÇ;4jUW°kU à!„ˆ¼‰›^‰>^ÁËt¼JU¬1þ&¯ž• F6§^K34œFü‘öò–¸.liàòHÔæ«/“yF[ˆ™—%¦ ÉꨢaøF¢§³¿ùŸW’yœ;HÓþR.ýíé¡RIìãþ—ôð¸p¢Œµ 1¸²òD•¼»î¢t§d6<ó)¬ÕÌÀ>æC"áõvç«U±ó§UÿV­¹û¡âLŒ{|! *Ë#£†U½ÝÁv,ËMÙvXšö.8-Â;'ŽqÖõÔ¥”ˆU"‡Aûßà/`Igö‹ép˜“Ïft¨lÀ69›Ôý¡ÔwJ~®ÎÛ8»Pò€r]°¥Àun–Çf”˜WL -QÁk¬Á]áñBû%ÃG‡×øB©$Rd@¹/©ÅŠÓ Åæ@›¤)Nk’äÂ}4›KżÀÿÊÄNÇóP#¸|ZÎSp06æòêv\¯hq:%U`×sã’蟾FŒÚ"ŸYAÊ'¥ˆ!’fã|2ßq¹ “Y4ô4¤A@økçÑØ{‡ù²S\GÃFt‡ŸÕ›uѴܸϫ&_…dZ¼“ Ù;ñ…—@-¹;?´õ@aåñÿì¥Í¶~êŠàß¿E’" fÿ¿ÌKZÈÛ3{Ù¯LçÝ:0¡¸ÇºiçÖ´eKÑÌÁ¥N['qšZwQƒŽéT…‘ck§Æ‰‘qç¬ ðfÓÈ¡1¤r`( ±Ðæѧjv€[>¯Á'F½ýì¨ê}I¦t ´|#Ï/ib:2ª[²p«chfl%^Òma¬PEýÆâŸú•ƒÑëÂn®ñaop £4„.]T¡ãšÐaŒÓ6†¥Òc%¦òiÑoÒ0Ÿ†îM›WE}hˆ‹œŽ'ÁåéºþrØ5£ KŒï¬È¹êË:ÀRóµ˜ÑX„tãý[ùÕà½Øã5ÃÒY¢xnèíîL]Ò°fÑ]ÌB>=uƒ¤âL$zPLdô¶XåT#€Á)`!5XŸDvÚQ7_•Sç}^î©aY¶ÃYu5QÌz<ƺna:a"ÜD¾«„¿Åú#®²„ÇØ,zÿRnj¼¬Å‹ -.+±Ãßó÷Ô4]üsÅÄžT*ÎW#Ò)™ª$ÊŸ·P§±É_C ‚|姲¢uÍ©D†“â¥ÎCV™qCi‚µƒë’àõƒÅ=ëí˜XKuÙÙLç}=0ùmZíÎ:9Ä÷4lö’äŽéTôøÈìbëR3’½eÖAiÞö4Õ„í±‡CKgÆ@/ÞýÂuU]4Ϻ`_ÒMG%ݾZL‡¾Š”)Þ©ŒÍù‚¶•x<6½Oý¾"38M¾­…P±Ðâ•p=亰ëkºB8Úy X§!q¾(¿ãšP`4W™Å©tv¬óµ¦ß}Í;¼×#C¨JC¿÷Eí¨ŠgéáЯO~ñƒM~¦ˆ/©òÛ<æzÚÄt‰jÖ¸ç>ÃÆRÐ( Å®™ã“«ÐX¬¯èÉÙ…$±D2`pk×ûe¨Ï#¤ZÓÚY© ×´4 a|7 _!®y(JCdT|Ý•ÝÝ"¼ï8 ÍÛCw0UÆÇÏ¥ ^#Ãå—$%ñ†‡Þ¼êð¬jæÃ{œbÍ?J(“þJ~2¾Þâ_§ÆAË݆Å<•Å3)Ó±l–ç %]~Ø]¾Ï[)â•íÔŸ¼¤àÝÀÚ'ýbÈ„“P(øNúNS.Žb{çíø2´!/P™þöâ(Ú£Àœoä“ð«¤NöûB¼ìh/è—X&¢úL½ #1M›p-Á[룒}]m^&~ÒSrR´XüÄ¡«7ªøÜï`»šŒðÏ[ñ§›ØÿpS§^:9:2uXzWA)œ«±§@Ë?b> endobj -1262 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [361.118 694.3759 409.8647 706.4356] -/Subtype /Link -/A << /S /GoTo /D (configuration_file_elements) >> ->> endobj -1264 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [347.1258 314.3269 404.2417 326.3865] -/Subtype /Link -/A << /S /GoTo /D (journal) >> ->> endobj -1260 0 obj << -/D [1258 0 R /XYZ 56.6929 794.5015 null] ->> endobj -382 0 obj << -/D [1258 0 R /XYZ 56.6929 769.5949 null] ->> endobj -1261 0 obj << -/D [1258 0 R /XYZ 56.6929 749.7681 null] ->> endobj -386 0 obj << -/D [1258 0 R /XYZ 56.6929 443.842 null] ->> endobj -1263 0 obj << -/D [1258 0 R /XYZ 56.6929 420.887 null] ->> endobj -1257 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1267 0 obj << -/Length 2860 -/Filter /FlateDecode ->> -stream -xÚ­]sÛ¸ñÝ¿B}£g"ß'O¾œ“ú¦—¤®Û—ë=ÐeqB‘ŠHÛñÝô¿w P D)餓ñp±X,vý„Âg þñ™Õ)“¹še¹J5ãz¶Ø\°Ù̽¿àžfˆæ1ÕOw¯ßÉl–§¹fv·ŠxÙ”YËgwËß’·½útw}{9š%&½œkÃ’Ÿn>üL˜œ>o?~xwóþŸ·W—™Jîn>~ ôíõ»ëÛëo¯/çÜjë…çpbÁ»›¿]ôþöê×_¯n/¿ûåâúnÐ%Ö—3‰Š|¹øíw6[‚Ú¿\°TæVÏžaÀRžçb¶¹PZ¦ZI0õÅ?.þ>0ŒfÝÒ©óSÚ¦Z(3›k‘Zkìô)³”i8µy¦xj¸Ê†S|ꔞr¿ØÎëªëËfþå±|,Õæ:OyÆòYÌûH‚jB‰À žÔH†»uy9—*OH‚Iš¹„Y–Û~ ×g˜ÝÓ.ËUñX÷4(š%›ª©6ZWu„”~íÍŠÆ}àñ¹Ü5eMp÷¸Ý¶»¾£¥H'ç®RÁŒyšk-œÀÅb"¥Í’3&ê¾Üù‘jYôÅî’Û¤,–/ˆ ©~í䨨»– EÛôŽ´­ýܺ}&`S4/ݽý4P7墯ڦ , /ÅsU×Ý£nÖÒù- W5N´  Ú Î“n[,JŸ‹ª¯š¬Ú'h7~ÕCHÀV8ŠÒÌ}9¬Û]‡»#Ü·ô¥Sƒ»y–üë2peG“uÙy”j’^ §mè…©ê²éë—±Vt7»¢‚Sœ:°ÿ¹PiÎ 8“”©bÜ:zŒ ܤœC¤`Œ%ŸÊ]Õ.«ƒ»KŽ’wŸixÓÀM?ÁýEï‚FêT -#ÏûiLuÚO*sQ—EÇ;¯¼GŽjDX+Ï‹0PMÈ0vÔ,U67c!œó)i’D¸ä Z=é†"sØ´OŽP'å×mE¸eLеXx2Â.Èš–‘®È36DÒ‡½Åb¸?•»—‰›–"O™â¨õèìÈ¥¥5©¶{FvŸëÁaÈ#¾öÜ Ä<öe‡1%c>e,ŠG™<ð5Œ¾'ÖlŠ¯>ZÁà ½a¼\XÏ»xqÑF3Ťó,O½r^Ö‘§càCóíÊžç’ðe¯èÛøñvdüáÜhäÝ v±€ëƒô™žrøK•’â¼ÄT§Ý` BMÖe±ëïË¢?ã&•VÚó2 TBŒü ã©4š¥ ?€Œ‚~àœ€…ŒX8EŒBÿÑ6žxS ÌMÑ8«‡©âJGs.Î"®Lp]G¸M±ûìüÐE7eï2K%ÞB—˜ÒvÂÁ:lši›Mÿy]6¥ÓCf6ä©,ß»„Ãï]ÙÙq®ƒÛØömV“íÛØöaÍmYtmSÜ×~é“Ï!™àrP€ÄiéË ®0•ËÐ/¸R°¥ÈôØ-(‡¢¨n*¸œÈLp9Ä£ÔˆB—Ã1¹b"—›âmÈ»2ã½ HœwÂy—ä]€'SÀ™Ø&re]*Cº’@oÿ³'r¦¿áˆ{¢3~艆`¹‚’áŒJ,ðÎîhŽ÷§"¨s-GÐ}ê|ð@aöçØ…«!´¯õhÊþ¹Ý}&ÊA~šÃº“ SEHÅ:äCvFÿÁ!bpm²†”TÅR¸Î ú×æÀ!â¹q–‰_ô'üî9 (¡ÜA8t0lÕ•7ìx96~É°Š ;âë y£aãŒ3lа‘½3lLÔû“Äرeß{)è`ì‘38"e sPÐFA½õ¯EèoÌZ;ýZñJQÃŒ>Í‹Ö1àåÁ°bÌj¤›K¯JBÅ&8Ü -X&\’„kÚzŒÌ@Å%dG |È >B©Ç¡už‘\ džò"­߶`óÙ—’ÊsITì´ÝŸ‚C¼¾ÙˆÙÏ-è4‹Õ -œç1k§—±¡ƒ!ä–JAë·ãÔj]õf“—KÁ’ҪͶ.7%8ÀÒ#úú‡H€ò£ÛWy– =s|¾?vePæ&gзï_ Ì ÆVþšŸ‡$È™CáÑDøGz&i·-øÃËD˜ëÀÇh:ë+×äà -HSØøpmGóÐÚ?$!ºüòXÔà–Js_!qI”CÈźm»Ò³(èÓ¸€‰³{Jz‘BæìBE aµðu¡tEÇo¢ î–9O*l…Àø)…—+˜A„ô/0ãra -O\:Æjyý…¦5*Ö‡yOßwe½Â¶J åaºg`5:Ͻ_ö§/<É(ò;›÷ûA‘W|.½tE3±˜†2YpÿbéZ>Fèìàñt¹Ã§¾‰€©0+iÓ\èïz_àÆgÍÛqœÇ,í›s°~7¹LVô‹õ‘Š¥Æ2ñ2pü– -:%“ó±Î<ï’gi&Exü¢§q™Q­å-Ò=s#®sø5h÷8ì¶å¢r}? öE×\g<¹.à`ܘӼ†j¢¦µä,8QÖÁ|µßªèºê¡)½0~#¨…{l‚ýãUfR(ìØ^>´Í¼) -‚A¯ÀùB¤~ÀPè‚Æ%!ï‹.,s5¹põµ#Ô¶í*j,p‚àÞI­èÑÒ5'CÉ-X áä™»$«nªr.,­_ìAä]O8Œ4ˆòsv°ˆ~Ýîè7‡˜K¤ºôï0kÀþ¹t¿ªIåwñVmãã£{K€‹ÖÉá÷GÔA3Àû"SbÇ4£ûÃ6ñ“§ £}­ ¦üÏ8D±¿“ÜëKÅŽ¬¯â_|Y,—þ ËS{5`ÊRN¶Ò„rÏë -Ï!®CW;Jf¾iBWôjÊÈŒCKD7èÃ>*ØÖ)†13ϸïÂûQùµÀæE Hñ£”Ì]‹¡Ç¹an Ÿÿé”2Íñ§Î‘ꜽ¶o¦Îä/P#¦òµPo¦LþOb 4¯¹yC‰œôZ3ŸÜ‘&+ŠXüпó(çÒØgfz‰s}' ÷A0àŒ¾þa@$›Öy¾¬ÚÐ\#6×ø]ÁYŽpÐlÒÛ˜ÝÐH°DhâP`S2é<ΔŠØ*™HJiP¶_Ó4‰ @ù[£7 Ä ‚è ¨¢' œŠ8*'¨$p,&1¨¡ÏÇݽíÚÊóÞŸyx՘Щ.‹`ð­oÀ ÂIÒè6‡æox£.-˜¨÷»¿ÐKâÏêÝ7º›þõ~ÿ_T–B¥}â÷ÉLjEž¡P;J®!«k+² Ñÿ ¡4Xendstream -endobj -1266 0 obj << -/Type /Page -/Contents 1267 0 R -/Resources 1265 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1256 0 R ->> endobj -1268 0 obj << -/D [1266 0 R /XYZ 85.0394 794.5015 null] ->> endobj -390 0 obj << -/D [1266 0 R /XYZ 85.0394 690.2056 null] ->> endobj -1269 0 obj << -/D [1266 0 R /XYZ 85.0394 665.1198 null] ->> endobj -394 0 obj << -/D [1266 0 R /XYZ 85.0394 302.1184 null] ->> endobj -1270 0 obj << -/D [1266 0 R /XYZ 85.0394 278.2032 null] ->> endobj -1265 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F62 995 0 R /F39 863 0 R >> -/XObject << /Im2 984 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1273 0 obj << -/Length 2998 -/Filter /FlateDecode ->> -stream -xÚµ]sÜ6îÝ¿bßNžÉ*â—DMžÒÄIÝiÖñÍ=´}we[“]É‘´u3þ÷PKiµ±ïœNfBˆAñµ‹þ‰…Iã4—ù"Ëula«íI²¸…µ÷'‚q–ib}wuòòÊyœ§2]\Ý´lœX+Wë_£4–ñ)PH¢7.Þ¿ÿ÷åëÓLGWç.N—Ò$Ñ»óÏzùú§Ÿ^_ž.…5"zóý럯Î.i)eß_¼¥™œ†#D/ÏÞ]ž]¼9;ýýꇓ³«á.á}E¢ð"ŸO~ý=Y¬áÚ?œ$±Ê­Y<ÀG‹<—‹í‰6*6Z)?³9ùxòË@0Xu[gå'’XªTÎ 0h“8M€Tfò8UR9öÍ}³in¿œ.Ó$‰þ¢aÓ¬ŠÍ]Óõ¯‚ïºì;þþûÕÑ‹ Û$×Oº¹qž=ó®#âTÒmæiѾh1èwŒIí-,Õ ›åƒ€@ -BĹ1%”ÊXe"]d‰ŒM–“‰]à]f›T D‰%s‡ñ¤"¢+ø_F&4“Lf‹ÔØXkw™Åç…ˆçŠpØ]u/7ñò|+o¸Ð"¸“§» »+!ìuoàôÔ€ehÒùÕ]IwJU€*T†¯4˜á…$A„V ØÜ÷USóÈlTu4ÖMÏÛûM¹-ë¾\ócòC(§ÓiK›ÛE¨¬çé-Íä)Àþ=Ï:C“RqfÉâɤČÓJ“ ,F>K¤±PàŠxM¨çVº¦í7U×Ó×ǾèðûódáqH|h‰º”JGí©°QÙÝ7uçf(’V -ú|{ñ‘¾?ïÊö Ûâ -®`³Í Mnw›¾5ŽhvXfW×mü-1Éåeƒ ¬›¦ÝVõ-­ÿ =^yx©på®D>sí){<ü¸ÖŠå‹u±e¨+Û?Ê–à‡j³áu`©Øl¾ÐÛïÚš¾{"c" ïwöwÕxUGîtýZQÓÆêTDõºìK¼9¨“fù^ÀÎèbänð>×;¤—dÀuI@ïŸìغDlñn¨meÓ2á‰ÉBHÆíãräïÉ+”BÇiš›…1Yl¥t¯Û[öM—Að—áïc÷lÒEv>–+v#ÀŒú€'kâ< „G„Ãë1N¨±øÑŠdž²C«M5HÊ솬 W›5ãuwÍn³ñŠ¶-êÛ@‡@sBÍ/áÐX&à\F¦]87*¢âþÞQiîÛ -´õgS Rô´^un*‹v=+ÜSa`½fV»’é‘›Ì.¬X—ž(#ÑÑåMIc½â=Ο 1 ÒβS+}ß<”(!_Ì=_ -ÚF…{Š„‚íhjåžkNA˜EÇêü)~\—›æCSÊ+>áÝq¥¨ç8P6¶ 0e”-ÈuÎ?I%åBç"ÖV?)Ï€,ÃZ{$Ë(.C’‡i†´6–03`!—Û¢_ÝMyTàYÃ~;Šð¨@:Sé˜É#šY¬R%¼¼ë5)§‚T²e×Գªžtþ¦¦™mã½~u÷åªBs^¹HOŽj!¡•›0¸V|S©8nÑtžÍ¦È#î!%„À2köºqÏ j´Èø UZnÁ†2(7d®»Œ¿ 7ÌÅÝ)ÝqÜÆ|Ü•‡v-AsV‡GÌÄ]ÆzŒ“jAÜUZGg˜-©¡¹'`ÊÝÐ&Ò¬¾ª1¡ÁŽò¡XùºëJ{Äí®óôû®ÜÜÕhHâU¢Ó±Õ /W™t9TQùçý¦ZUý ;©Ž5 ~Ý‹¨Œ…bE§P3dPp>÷…—!ÉÃ* ($3Ùþä£nê2¨Á!~;&=ÅǘÌÈÖ¬3yÌX(’‡€€Ù;骩KRæ8Ñ?4”T°bÌL3C9 "¢iÑ($¿b’‡»jŤ]5…À5ï$»ÑùÏdEÂHÈÄõ$çÛGkˆ  -r·Íä¸Íìõ?'(¯ßüH•;¹{ÁXàyÙa ~h‘Rb'Ã<ØÔ©Vµ1q*òo3˜à2 82`1ÓñǣxÜ\eöÛ1è > Nã\¦éˆÃc¶¨c•™œ%M¹‡SÕ ¥s{9·‡»=b)éì>0ÃquW®>‘^å*«$Ÿx§â¶¨jßRè÷† àÆ,mo~4áªÿp‡ï¸«ûŠ“º‚Ò‰+&pÓìêõ$Ç£fÅWK(Í…!;JË1;ˆàdî`vù®`¤ëÒ%9~Ê5>“ŠòñfÉòÕCXq,É"|BÜ£àøx—/ãVt3‰=;:#ù1‘d€¸ë†½ ½ ÆûcŽî¯çRzR¾Ì§m%™Sã¶ùc23lº.o«º¦B’™ÖC¢®,SÑù' ö’ìǂĘ ïÆ_PC©§zIÏV/ q':ªÆ²dmÔsAß“€3/L¨÷ÈéTxÜù\rôL'ê±Â”lb4ù5S\†$çjÛ È h_)" SÔÒ|;&Š0‰A(¡ÆL/"Œ––Ž™¢ÓÒ\LâDHõ¤ÌÞ@ 0Íìñ÷#á3WgÎÅÀiäbÈA+L¯ì$òÖ&Söžu]WÝÖ®ÒOÉË°†[ÔˆÁÉz½Ï|ifäÄ‘ZM#cˆé;†%J‰FHÛª®¶»íÜ™ÆWïOoæüá6B'0VÆN`&Zœ£Ö¬åçÀM³ÒÝQT6ƒl»À^`‹CQû ±0>T®¤š«²r\;"ÔXÛÒ×°Ë…™ð°I ‰ààïdq­à`ê1#t[ös'¼yG}á}Ïû.ØIžôñ°}<4™¿ðÄ CGÚõ©6¼ -Ž­†à†-ïœdûÉ5… Øº(ÿì oëî(Ô5#„}¯ ?ÖË9Å™Ml䛺Üü´‘ȱʴ±x)5-1GèªEÊv ˆÅMO-Vë{ž€[VÜwL쾟êIJ&ÉíÁ`E +|}8ëŸíN‚êÔ|ç»»æ¡&ðèQÞ¡$rÔ1 -J„ò6FE¿ † øÃìÀ0á« -LQ ×QwÆFÒœ»‰¿®2™·I€‚‹¹oîæ"85yC:Ä%NSL6&ëR ã#¢™êÃu±ÕLB¥‰—ÏŒ9í¥eò©´Ìèïk–fÖ5Í0cùpºæÓ}4ƒb¦ Ò²¡õ9á¾2caæ,ÌeLß2:ÄzpˆUKàº5±±c¼`ì­†›üÆ?é§îQ¤_÷‘) • þmˆµ™þ¥ûqòåKZ9‡8‘°ëp t"ßÓÖÇió›´¯¾?» è¦j=³7(¢”žáŸ %|HßxúŽç fà<21§f44ßWã)µŸúûp¤&þ˜”d_¥ì¹Ì圄ý…W›#9‚o&ûç„-¾vRjgå½ëX™±xÁÒnyBN¾Õ£ÆóÏËM>SnòÉr“O•›œÊMüßrÿ˜ÜÔ3妞,7õT¹©Çä&Ÿ#7ù<¹MЇ˜ñYx]ì7¸+èÉ• ßù¾¥`A^­è¯4=¿³’8þ‡XÊÄøgc3údø‹§gÿuÚþ¯`°Ïn­<ÒñÏ@†ˆ0Sȹ±œû?c;dý¿?¿Évendstream -endobj -1272 0 obj << -/Type /Page -/Contents 1273 0 R -/Resources 1271 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1256 0 R -/Annots [ 1276 0 R 1277 0 R ] ->> endobj -1276 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [213.6732 554.0172 286.8984 566.0768] -/Subtype /Link -/A << /S /GoTo /D (rrset_ordering) >> ->> endobj -1277 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [209.702 475.7236 283.4678 487.7833] -/Subtype /Link -/A << /S /GoTo /D (topology) >> ->> endobj -1274 0 obj << -/D [1272 0 R /XYZ 56.6929 794.5015 null] ->> endobj -398 0 obj << -/D [1272 0 R /XYZ 56.6929 622.2509 null] ->> endobj -1275 0 obj << -/D [1272 0 R /XYZ 56.6929 600.0717 null] ->> endobj -1271 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F23 682 0 R /F62 995 0 R /F63 998 0 R /F21 658 0 R >> -/XObject << /Im2 984 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1280 0 obj << -/Length 2668 -/Filter /FlateDecode ->> -stream -xÚÅ]sÛ¸ñÝ¿B“'ºsÂá›@òäË9©ozNë¨Óéäò@K´Ã9ŠTD)Ž›éï P DÙÎ%7Ï °Xì.ö ± …?61ŠPaå$·’(ÊÔd¾<¡“[˜{}ÂÌ4MS¨Ÿf'?¾ùÄ«¹žÌn\†PcØd¶x—½üëÙßgçW§S®h¦ÉéTišýtqù3ŽXl^¾¹|uñúŸWg§¹Ìfo.qøêüÕùÕùåËóÓ)3ŠÁz0YðêâoçØ{}uöë¯gW§ïg¿œœÏz^R~Ž‘'ïÞÓÉØþå„ašÜÁ%ÌZ>YžH%ˆ’BÄ‘úäíÉ?z„ɬ_:&?% Q†ç#äbL€Ê-`Ê pö¡Ž´ÎnÚºnïªæ?ËÏÅrU‡¹»ª®±w[} -cëSf²²èÚ¦¸Žp×å‡âSÕ®#ÆÐÙÄ=êv^DÚnƒ½¢Yì†:ì¶ ¶‹ -·™oê{™·MŸå‰øŸ2F¬RÜ3Ó”›»vý{§(¸É.ÜJg•Ãªò¬«–U]¬qpÓ†Ö§ÄÃW{³7],HK×á@×®7ˆ·jp$êÎ$±äs âªìVmÓ•qYÙl†|Ü–ëª 4ÞøMÚå{ž!l”£ë¢]I“ÝŸn°hî±ãøqmc(Z7²­ÿL„©r²áf‘ ±Å¶gÃ}ôlôT øAãm'n#ú³7φ -löT:@ ?‚¦Ô -—ÝÄ’óó²†!܉ƒLŠ ŽtŲ`æ%ž!LË#ÇÙ÷)4A¯i7ع.±u:T.ˆÃÞÎ&ÆêpçÄ‚yÜ°®ÜQkJ³/~{­H®„Êô Bx qB}‘|O]øþï‹1¾<<ÝÛ×à$¸6¤^‚·ÉÂ8ÇÊ4a-„WW]$ñf½Q×A$bˆ„ƒ!I&=’}(½WPÙr[oªÞ9õh}»è¤ÀÑb³]7^g`ºj¢ï àMwçÏÎÍ¿´,îqà: ÙvåͶÆ1o»Ð‚.þF)¿Ý¦û§²@Sü ÷)nñ‡#¤ɪ.æžj)€j¿­” •öÊéü èªóè‡'Â#àl àwh×k8ië„?"yE‰Ê¹ °Ý¦Ø”Kt[°åª\/+o¬@ÈŽÿbSy{Ï'´=•½0¼Àº1Q@TfÄp›UÝ-õšDàkˆ'Û ‰Ñìmà‹ºk±·—›É!KeíðPhBÊù¾Ì~ØO„’Dçj¢´tiŒÏpn};ÁÎUÜ#ø4…?ŒíXoÁKâ¡øämPì$¹&B(3 è Éè¡!䛣„ày - JhµŒ¾-÷“gܵ͘KVò Î^QSÂw0`'J_J駤[œXcÌx²5í1NS”Èä€8ná¬åncä«r>¢œIU´»*Ä„EéÌý‘ÓÂ0ŒIX÷<ø[¥¥r ÞÍë¢ëp#5ØHH]Yب‡HLr8'1nç€ñ›%1NS”^bâ˜r·±O×\´‘˜ Ö%ÏÈÈ{”Ì»ÍýªáÜÓ<êIJ™æD´óßéã#Lsž-!¬ÿq®wÀC®tetÐÏí²¨šOZj•µßñã#Œ h$ 9`üÙç–“Û!ç»Ð9Â='Üú†ñ ¹z§žvèp.\.¬ Ãu™«2ÁVüPuʲÐuö\9+-?Àˆ qÝ-X”7D°¤u_p'Óy4û³Ë»meÔ]‚è8ˆƒôúHZ•ý^~ò(m6¥Í¡-Dò>¤=D›~˜6¯ÉF p—Â0=Lb†äÆ`a ×}DïøXØáÔ€¦ô6ò—²%p*x4ˆ*ZtГîwè³DP‘Õci«ËÛ"dz[öNz=Bœ1€A‰Ç•b`nûä*$ªÏ\µÈ‰Tà1%dÝ\XöãÒ²î¡ùþ±U‘—…×t”\GWèÆûÑ"25• ˆhæH|•‚È"&Ribrªð8A>ãÅO¤ "Ÿ¢H¯—I“Ë€dû—˜öù¤Œ: iÚŽã÷ˆ†!ía¡ÙÚ¦Ëèݪº$i˜Û•Ö|’ŠæÛÄínf·ÿÓQÆÇOܶȅ~ì](ÐY_ÍK_q€*•{ŸÍ÷¨h!èÚe„Áö"I.³Äžðóm2úsÅžJ2#;g„»™ßÏëjþ§I½HÚm³˜bï:Î?Uþ cßKþ»¢éÿÃs2í4 -$>…í×\žê!v¥ëy±íÊXö¹O 0»ÚžÎ“ªµçÐõÎŽšt_I -"r]'"‡)”]e»ˆUó]f38n9¨ -‹ÙþG˜´ -®ý‚é8Ö6ÝöÆQëC§K½r‹— f†P¸ñÅ_ÔwÅ}7¬R·ýü¬/³œÅÊgR=ãÓ}MpeGüʾŠ_ÜìUˆ³6iáú(Ÿ\ÓÎòö*<‘ƒÕª,<-»÷~„¹¾ ç ->2r'˜ï¥Æ QÔeq“º*;rì݉sín¦Ory’Ad¶JMûr¸½jý5i_\±çû>þÒËSÏÖ›3è4%93pcgî‚Lü29 *¢'ñ¼ËfðŸgçû’œ’¹XΘ[æ·ž|œ@t”Ö -Júž× üÀK>ù¹Ž& Sñ4Å왂`––ŠrWø ˜8Sª¿bx¶ôàÎ(óDO™ÊP!O9ÝÝ…ø|3R©…+8Þ¡õ*ç:÷Oé?Dv³­ñå£qëðí‡{{s-¾h¹žuÏ@4OG°™o×St(¹$B 3ô'kÀênr°ÕÖ;ÙÜ#€N Âu»íjå|¯Ë¡qÄy5ï¹N½N&BŒ`®{˜RXPC d’ªÛ·i°³eµýš”âaû…²4Ïè"craï)*¼§ÌN·Ù¶ Îg „*°)`Œçš?À˜itœ’ä©!èO7›ú°4 ª,AŽmÛî;(rÞ ×ƒß–øÁw/ÍvyW6ž8Xϼmð(ðÍçÅ×p%a¦Æg?¿`ý)"©šE5÷Ïáe…âø¢êÜ“wÀê°¹°ì6@¹ZÃìCÈ­À¸ > endobj -1282 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [353.6787 560.2827 427.332 572.3423] -/Subtype /Link -/A << /S /GoTo /D (the_sortlist_statement) >> ->> endobj -1281 0 obj << -/D [1279 0 R /XYZ 85.0394 794.5015 null] ->> endobj -402 0 obj << -/D [1279 0 R /XYZ 85.0394 630.8728 null] ->> endobj -955 0 obj << -/D [1279 0 R /XYZ 85.0394 603.2815 null] ->> endobj -1283 0 obj << -/D [1279 0 R /XYZ 85.0394 477.5928 null] ->> endobj -1284 0 obj << -/D [1279 0 R /XYZ 85.0394 465.6376 null] ->> endobj -406 0 obj << -/D [1279 0 R /XYZ 85.0394 128.2785 null] ->> endobj -1285 0 obj << -/D [1279 0 R /XYZ 85.0394 104.5761 null] ->> endobj -1278 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F39 863 0 R /F21 658 0 R /F53 962 0 R /F62 995 0 R /F63 998 0 R >> -/XObject << /Im2 984 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1288 0 obj << -/Length 3669 -/Filter /FlateDecode ->> -stream -xÚ¥ZIwã6¾ûWè6ô{‚•Ž´»§óf:™ng.I´D[œ–H…¤ìv~ýPÄMvfòt P(lµ|(ÄV~l¥r’[nWÚJ¢(S«Íኮ íý <ëÈ´r}w{õí;¡W–Øœç«ÛûÁX†PcØêvûK–N®aš}ÿãÇwÞÿüé͵–Ùí‡?^¯¹¢Ù»ÿ¸ÁÒûOoþùÏ7Ÿ®×Ì(–}ÿ÷7?ÝÞ|¦<Œñ݇o‘bñsaÐO7ïn>Ý|üþæú·Û®nnÓ^†ûeT¸ü~õËotµ…mÿpE‰°F­ž B ³–¯WR ¢¤‘²¿ú|õ¯4à Õw]’ŸT†(.s¤ ‚çfYÊŒhÆ€IKF˜–:I™³%)G.'åCñu]oŠÍ®\÷ý~ºiÆ(D¨ÕpäÙü‰kab°ÆA½¹4ãÜ^[ž5 }®²öš™¬Üž6¥«Ë¬.û§¦ý‚}[Ü»ö_)ål/ê-¶Uõû]‰”cÙÞ7í¡¨7å7Žb³~šº²},[¡ëìØa[]>}õ8‹º{*ÛŽ8¹L¤¹–9‘¹°}F¬Rü‚8'2È É™ 8Ç^ùYEvêÊ-–ú¿]Ùc¡ÀuÂÀÕát@®¸/ë¾jêЯ:”X‚]Ò®ì-ì+UÚã\Q±äRnšz‹;_­ãªÃ^ÑAo}¥³my_œöý‚Àjã*ìöÏÇ*ÎÎÂñ,ÂX,É r0j(]Gp"¥Ó†­àZ¥Š -,îšSÛA-©×pb©äÿßÊ7E]7=ÎR~Ý”^¹PÖA^ÅsX³_/`ÁrB`GÖôTí÷Kw%~»jZß?c­o¯Mv‚…õ8Eó¯ÆOœ‰fÕ}ÀÛÕ€³ÀÏCpŸÞ‹ý©$3 P“kIŒÍÕËx4二G‰+Jú2”¬ÍÅËÓ'®…ùÇp¢Ö:/àsÙ{‘åÁ? pö=¥¢£ -O»j³õ`ŒkjÌ3¿3,"ìl«ºhŸ‘âLóØtU_]³ì±t–‰ …Ö‚ïvÞf$Ú°±SF_D¥å7u0Ÿ§²ü‚%7ÙÀH’,*üIq£_Qö€ëeG.¯ìª^·MÓw3ES -=¢_š:q-Ì=R4UÄJ­Ç“ø2nQ½6«O‡;ԛɚ{üzM5èÐ6h¶Ã¦~WôXBYۀͿŸªp–ak°ƒîvæ*»~Â,ÈŽf5“Yd¹ –À%ÒLÀ£ØlÊ#ƒ3FãvéÌB<˜Á¡<”WNŒÒ& _À;…žƒ 3Ã1Œ( ø«Œ!:ÏÙŸ –„ñ±ŸY–(Ä0¨††‹ca? -c…bì1jW¦« 3¹ZM’ špmøJiE”Ph5ÂP¹d(/hçñLÿñz3ˆjÖ9ÏfQ¤h‚FF$eÞ`W¿¯¡ÒZLƒ²ßëYžðí‡_½m`G«á¦ÂÀëáÈ~S9až ¹`ˆ„Í㦼•i0âÃq_à„ñvë5~Cø %;Ó¶Ì-áÆšÕPžMEdŸ[ˆ²×çàø¯К[bŒ¶ÞY¤Pìe0“–¡„xÌ—3ª‡5šÕ¶êŸ×ˆ°…Ú Ø¤†Ð´3œ`l‘ka#`Sèe´ŽÏÇrS¹Ù…´‚†8Ï"¶¹²Ã6÷ÅAPªv°2êpêOˆTXÚ•5–Þ~üüùæ{,ÃÆë"2†9‹Sߊ~ø¤)1Ü݆øTmŠ½ d8=”uÙb#ËŠÉVÃÈ´Ù¯èÛçº8T$žŽ[ ÃwºMEÏári,3+i¼ùx ÀÆö!¸×§÷Cƒ üëa‡¹æãb±ÁàÜ­M>]€ë—àÃÁg†¸^YÃ|4·Œ Ü0q’)¿ÃÉç‚´ Ï/Íx.¸‹±7Dòp Ècô-–Bo¦¾L ½u‘­("˜œÜ—pvJÏ1–«øØ‹U‡_Fñû\m ùP>Ï¡[;ˆbàfFϬ3ŒY»“µUŒè†“AH 7†Ê±¥9»ÐqÀãèc¹kE Úï›8¯¹ã¼9µH¯c0‚ÊAX¾ß7OX ¡A -Õ÷Õ¡JqhNq”&Äø›}³ a^÷¥|r÷닱äpñЯÂá€ë8Œ\)¶+ïÛ²Û­Ýö¾Á¹ø~‰ì¹ûöyΉ3ÊÉi._ÞBâZØÃȃòœ(1âh·x…f„ë-¦Ã -˜GñÙ ^µ®ã~-³¿u!:3’X3 ÏîÊ]ñXyÕ -€ã¿h÷ñvUý€ô? • ‰Ç2ˆ ÛçÀ%ƒ¥ßçß`a³+ꇲ w 7Q;œ¨Oì ¸[n±Ü·pç¸wª²Ÿ»L†¾à&êÃdâ 8-8£wà˸(#[ „]@©Hî—ù±èîÔ#-æ0&cú™p¥êÝsê„…Cѹû,è"ŒûP=â~¡±Û/]ÖÜÐÛõxk<šsÕXú¦í¢ 5:ôм+>Æ{4,¦jÏ\àò݃At945‘‹³©‰\F pt<—m;XNhkðë…áy°ž.7žæÒežšÐ6ŸÙÜ„5 -Ò£'NåSV°:·O)\êÍuZ;=;W–2‘+Ä#OVh’gûæÎ[%y›3Q nÀ$W9ë*>àÂ"Ú¢b¯ÏÂ]ºC’[T¦Íà&ûâp\ÚV‚l4m(̤åQ¸Þ[ûöùŒëÝØÓˆ]ŠÓ¶ƒŒKw©D×’Û—zÀt§#“×Û¶îÖ§íqÝU”óô/nšÙçNLóÉÅ$x0pMÍ“-úœl)¶à:}ÕŜ٠„šØòóÛŸtwòyà{t1ù¥{]qÏ}é±KÐìßÎÞ‚™K‚—~;ŸÎ:SŒ‡NƒIm~N†~Ë@@§„ƒ_sê»jëSªn;˜ÚͳÖ0CJw2Hçq·õÿœ°¶!Œqq4ÞÚ¡í|k‡n!>rÅ8[ì´Ï©;a˜Çt±ŽIbíð¢w¸äÒ#ÓXó<ˆ&×þ8‚jÝÔëóÂò<-, K]rñªÑ ’’Ò¶cÑuØÜïQO;lºÃúwquç;¸¯'ÀŽÔ«è—6swŽ‰îÛâ!Ýq¡~,6_‚zOþ6Æ[ƒ>Áö&Ì1ûC‡–´K¾KÁÈh´Ð ¾Î¡À}å¹gÈuÙÛWL¯^ôv8Ž§}qöĵ0½˜d¨ùx~txad8ÌÌàeÃUÐÛ]ÉKÜ·—]W<f4EW‚«Ÿ¿.B1Ün\sYšC÷H "ky4#ÒNÞ7:Qq2 ƒHè ‡èà[Î@àØ€@É”!¯/Gy}1žÒwr˜¾É߀§‰@ÀYÊO\!ÂÜùG°u„(DXð•‘ÑxŠ| üŒqq].­Ð» @]Ê ’p ±‰ˆŽ2À%Ç ‚àjŽ -ŽˆŽêJÁ§]qˆ®ž\[ø—?ÄI´Ê)óyød3®2ÂÀW/ÅÍST Û˜¾Oßz[ÁÂËé…/ÅãÃ3†#›4Ý££“¦DÉ;¸6$,&xgAÂôõK¦m`~ñ)iN,Ó¯¼ ¹.[âB`s¡¾Sþ¾\û‡ß~†oB®µ|y‰ka#|“‚£ÇË'ßX¸ôˆðj½å°>_Æd– —¢3g+Švåüò ÑÈ@öòB2+ñ¿²«ù¸“d–Ér"ˆž­Ç@(„xY¶‰ëµUÌF;X‰ŒI+3LZ™”6bæBþŠÂ‘Dã›n_~ílŽ-ëþßLß„ã焹¿aŒ^gñÙOH†‰#ø¢¶ý}Á`š`:»®‚~y —ðçÂÉ×mÎ¥wjß[ã·ÁË•+¢ít8M”ÉF·Dhž¿²SMD|±>ã–[êó1%g¥K†4®pžgøD `ñá¹ ŽZá±õA^דŸÛ®\&‘BÇwÀ¯7ÍáòðÞ1ß‚UZè˜mì›fïÀÓ÷¢Qâœ!FƒY1{íhBB«äœŽZ™¶UḆä7DYiÇ@›kqI7Jk©~E5 h!Ìð_"0â¾)¶.E2TDÀåj(¹¥¿E€ã2ÍÒžqØæP uOCj|ÀM©lvåæKXG|ïv2mNûk–õß…Þá¿7Ñ*\Tá…ÆrJÀ,íä¡ÒÝÁÙY’£‚?-ˆÐÂÐWE(œËÒbüIgÂèÇÎÊÍi_„Ñ\®VqF /ƒµ“n·t2B•°CÞçÙ6¸+üOŠãчzèÎظ¼U÷ÅÓÛb[<-m•!ôÒN} ¾«a+ÂND(‹:Ä>¹Ì£O!éC…)qi‘®ö¹´¯-R*ªF«ÄA'|ç!#Ø€êSÕï!:"ëŠC(yAcq_>–{d,º¸à8Ë0Ý‚Æè-DM‚~´> endobj -1290 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [297.8955 476.5924 347.2449 488.6521] -/Subtype /Link -/A << /S /GoTo /D (dynamic_update) >> ->> endobj -1291 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [324.9335 169.1118 381.8296 181.1714] -/Subtype /Link -/A << /S /GoTo /D (zonefile_format) >> ->> endobj -1289 0 obj << -/D [1287 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1286 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F39 863 0 R /F48 885 0 R /F62 995 0 R >> -/XObject << /Im2 984 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1295 0 obj << -/Length 3537 -/Filter /FlateDecode ->> -stream -xÚ­Zmoã6þž_áoçk•o%ôpÀv7ÛKqÍö²¹Cqm?(m +K^KNÖýõ7Ã!eÊ–“wØ‘Cr8Î<œ!Íg þðYGLfj¦3ŌdzbsÅf+hûþŠ»> ßiöúîáê›Rϲ(KD2{X¼Òˆ¥)Ÿ=”¿ÌßýýíO7÷× ³y]/â„Í¿»½{O”Œ>ï>Þ}¸ýþ_÷o¯µš?Ü~¼#òý͇›û›»w7× žÆÆ Ç့ÿ¸¡Ò÷÷oüñíýõo?\Ý< k ×˙ą|¹úå76+aÙ?\±Hfi<{† -‹x–‰ÙæJÅ2Š•”žR_}ºúçÀ0hµC§ô§â4Š…Jf ©¢4“Zf‹Ak gQ"…´,ø”–}/ÔrQW¦é»ÅÖì®y:_|Ù›Ýá ib“]L¶ŸêF$:J¥ˆg¡gb½&䔜B‹(å2 ú°6¹X2ïL…xÞ¯¥jª¾Êk¢>åõÞÑe1Û@ãf¿"§ö¼)©Ö‡-Tiö›GX#¬l¶à Hè J<ÊâXX Ú%ª%ž[E˜b¿ëª§k>7Dí€UÝçMÕî;¤(¯Zj^¶;*äÍšWÕ“iˆFJµT”…øæ÷NHeJ£.Q”¿R—‘Út¤Uª]‡/M¾1o¾ô‡-ü_Ôy×M0M“H&±tCþöO§Áõž÷$.í.ßìžÌŽˆÏU]“"¥Ì¢”eéX‘yQ˜-2HÄüÑ fP¡T/m¥Ýn«fE”¼,asÛÆno½ZÁ¥‚mƒu–ÔÑNKCúÞlh>ï["v¦^R©ß7n¶~]uTòFƒ£Ç°XçÍÊXÍ -ÜœÜ\à$†¾u»Z™¥â •¨¥Yæ`T±stT·EC…3G´3[‹†iÓ(µrN`ååÉ /»u»¯K*×_“¦è‰´nŸ©°!ÓƒÚ[e%áñ¼h7ŽQÕЗl -9}¼¥rR÷¸3Yª¡ÉÍÜçŸ×n _×ÖOf¬V²Œ£aáD¨LÁæ·Ë‘­I殺HN)ƒ%Ñ|-Œµ -hp[ T«²7Göe`­¶+xÉÞ®ÁNF’HZ P<›Òä5'4>WýšÈù”™4m³pKÞ¶ àr—Éü÷ÖZ ÔnËäÄ’w¢Ì_{‡ºÔ²º‘Nå0ve,àHÚ;9(g÷3.{«ÓBŒ‰ËD¡ÃªnsŸ±Åi¤%×cW°&ÃC·¶£J··*È"»ÉG©H½¿å5Ävq˜Y²¡oÙÒ €ÎTÈ·Ûú@s‘*3{nw®h½œJAc£b Ú=–ÆÔÃâÑP†€$7SYuùc=âìnXÄ¥NÆ*±ó&e’Î÷Ö…•‹¼°0(Iª#Xöu&æ¶;¸ñŽèk@Ø“qƒKOì?°3ékPÃá€×ÞJ( çMZbv({"üš¯Ûº*l 5?.&ÌQê¢YÂyG:Íâña÷ržùhØgYx×Ôë!9öáäë_ˆt àâ,I_uÂ^—c¡—Õ›X¬mÎ@ cX&Ô˽&f{«ÍI=žÚEé ƒ­ôž:¸"–}æerím»ëÝè*§‚ûøŠøzw‰1ÎrØNœåI™ùƒóáç‡)8ƒ¢ô)'…¸""uâŒ1#H-^ƒu%b81ÀË„  0À5VªŽ¾½o%µç5Õ†-ÃÊå@ÙzQæ/œ°äöQ+œPC2þik -ˆCÑ1'Î'eªO¶Â̓— ç«Bd‚£PžD¡圧¹X¯€°×Ýi0—)2ŸF²ã•Ã%/T*JµÌ^ñÂ × ^è{¡¬k.½mŽÜ¢.ÉåËûNlLB꘩“™É “ä(‚­õž±qâƒøöíÔ§'" ã…±™Œ˜b'ÇÄÿífŠé—Ñ.ìuí†^A÷\Uyyq$âT¼<ýÐkbþ1è1H[!f à@OÏo߇¥§`O°—œÀž>=}{úu؃¨;S‰‡Û÷ѧ›ûßÜO%IQ¿ú£ ‘ç,ù3‘‡•øb y'DæéÉ+×=ᣠ‘ñ€zÄBàק\<À™à—²A˜pÍç @ð°°Ê‰OaëC¸â½Ë-aô’¦CtÀZ€Puèèð#/£ƒ`:øË&üÄ2» v®N!ÂŽ9ƒDŸ§Á ÃÙˆéìä´|Qv•E Þ¶MŠ.%°nJ|± #¼9â˜"§ŒS2ÿ…T{@Âwhsd<<)¡–wÔìÎ2$ÙäY¬ÝPw–-\¬d”‘$­ûä è º©WЉ ‘C•Nêg"{GcY|¼çŸz£I¸ôü.„ÆBÀ¦ “NßÇ‚`©Æ¬vâBVO^ÈÞl¶ýŠÿyíú5±üîÜæÅ’ž­$> Ñ]+‚ë=¨âŽ]üE!PQÿŸ>¾%º}¹AêÝ'úº_*еOé&h›ú€[›”6\@âËÏpë{÷}2¥ëVJÿ‰à¢Á+`r8õí{P–8ðzH©ÛÂwó?ÉêRá#uÄØYâo„ŽÌ;D:["ðó? ÂmÓ›]cú¿8>äóž5¼5RôT9± ÀŽwªLô)ƒ°HªAf -RWSPDGé¶yaÜÒC¿ß5Ô~÷óû?¾½½£ZøbÛ9^- x†ÏÀ -–Iðª¸*SOÑû:·Ù¦} +Bk¯7íã‚kt„a £—‘Ÿ§À$-‚kO¨ÝxGCxÆS7Æîö±-žKÀœˆ"qØ…ƒëVw- ­š¢Þ—æâ#€âDbÀ²Pbh'‰~ûÓSB$k‚D –AmèXGµ¨ÙU«Æ”è:oèùÜsâóºj>¿ÄÓÞâ<‘½Ä¡ ív1µºÇ¼øì®ÄF†¿WÇJûæsÓ>7g#»É·X‡BBøgy,BƒIKÄÒ€7mlR…ÕjéúÒÇâ °$÷;ìS»›’ò@óµêìK”ik…Â&ôS (ãF…zðÀ©Ç™íI¶{&ð*oSöôbÿÒ@L·³VÇClPìñU›',n5½Ó}Ns<ÜÒc§ »Qþ²Â*]zž‘q„¿ -œï៳ÿùLJÁ뎎 tÓy‚dI” -_œPö<{ʉeAÒ¡'Dÿ/ä×}endstream -endobj -1294 0 obj << -/Type /Page -/Contents 1295 0 R -/Resources 1293 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1303 0 R -/Annots [ 1301 0 R ] ->> endobj -1301 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [84.0431 462.4692 144.9365 474.5288] -/Subtype /Link -/A << /S /GoTo /D (view_statement_grammar) >> ->> endobj -1296 0 obj << -/D [1294 0 R /XYZ 85.0394 794.5015 null] ->> endobj -410 0 obj << -/D [1294 0 R /XYZ 85.0394 535.1829 null] ->> endobj -1300 0 obj << -/D [1294 0 R /XYZ 85.0394 508.8634 null] ->> endobj -414 0 obj << -/D [1294 0 R /XYZ 85.0394 198.9245 null] ->> endobj -1302 0 obj << -/D [1294 0 R /XYZ 85.0394 172.1168 null] ->> endobj -1293 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F11 1299 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1307 0 obj << -/Length 1767 -/Filter /FlateDecode ->> -stream -xÚ½š]sÚ8†ïùL¯ÌLQõaÉÖîmH—Î6íRöªí…¦x†Ø“d³¿~e$áƒ#¤x:³“É K¯õžçÈ’e bõG†\ !©&2F>\Þ ðð‡j{? F3¶¢1T½] Þ\³d(‘T kÐWŠpš’ábõ5ˆ¢‘êGï>Ý\ÏÞÿ=ŸŒ’8ZÌ>݌ƔãèzöçT—ÞÏ'?Næ£1I9‰Þý1ù¼˜Îu“0}¼Ý\é©?.t:Ÿ^OçÓ›wÓÑ÷ŇÁtqb¼³äçàëw<\)쌘LùðQ`D¤¤Ã»AÌâ1c¶f;ø2øëÔ!h=žêÌÁˆ2A ¤Ì•@.‘`ª©Iàb“k¦åý~?"i”—]±-jSªÖú3¿ÛžtñߪÌk],êß.¦)w'aªcÔ$Q'D+@_MÔß0Iº¦‰ê¤ÔojEÏMÏR•Ä¥äç¦*ͳ›ñäêjŽ&óÏ#I£ÉEpÚ IBà@å·ª ¸Ï´Á¡)¡ÉËÉ1FœÉÐL*¹UÉ}¦-y×ÔMM)WóXÈÓ‹£4&ÒOU—éOª½×ôDÿÌÔIfJ" }9¼ ˆÄq€*¼Uá}¦-|×Ô MIÒ>&(ŽE€*¼Uá}¦-|×Ô MIÚž”Äêæå‡*¼Uá}¦-|×Ô M‰ì)Âœˆð<¥ˆñÀ”¢ËèV"÷9žÀ»ŽNnè¨Æ¿¶ Hpâ*¸UÉ}¦-z×ÔÍM)íS$yXê ÊoUAxŸi ß5uÃCSÊúÁ+=„àÊoUAxŸi ß5uÃCS÷ƒÇêiD°À~ª<ðV„÷™¶ð]S7<4¥¼|œ2”ª-‚ª.ßT!x¯é þ™©þÌ”öÛÛÅ¢Ù§m=Tyà­*ï3mỦnxhJûííÔ–Å ìê¡ÊoUAxŸi ß5uÃCSÚoo«5"IX`Áƒ*¼Uá}¦-|×Ô Mi¿½]Œ9 ,xPå·ª ¼Ï´…á¡)ë··c)G,I»z¨º R…ས'øg¦Nø3SÖo‡ÇGêa8°«‡*¼Uá}¦-|×Ô MÕʇˆìAs$ÓÀœ"»Ñ=Ž-yÇÑ ÕƒM?nu[¤ièyª<äVD÷™¶ì]S7<4Åè×þfŸE8cX ž&‡¨òd̪‚ó™¶뚺3MÉÿ1š -”JXV¡êrÆNªPƼ¦§Œ=3ufìÌô -]7´/#I3wS¨ò[UÜgÚ’wMÝäÐ4EÓ>ìq‚bÉOPåa·ª »Ï´e١©ìÇ®öÛ‰LPåa·ª »Ï´e١é¤;N–2ðìUv« -²ûL[ö®©›š¾½ÈÞ\FHb!†c"U¢7SóÊðÓ+CG™~Ó¨ëëüpÈn·æ(;hÉac*ŠüQ—¶ùC¾5”+]W•[Ó}¶Ûé¢:·jO­n­›–Û¬6U³¤ WEÝø¯´"wDÌO7¤X!$9×+  ñ¨(7ù¾8{b"ZÏ©îtcµ;UYë¦b­+å)ªºÍ‹j++]¹jÃSµ6<Õ`ÃSµõ._ß0¦Öû˜Fm +L™I£Bg˜G‹füŒOõï÷ŪèçûÁ¾%n)œoˆA¬ö%ñk]~ªîÍ{æ¬<ÓꃓÎYuh{Ð¥ìР&ŒÈج«½yWýOv·ÛæÇWÓo®™<ŸN SA=Nõß3>¦w¬mÆÑ+ôêwÝÅÙäŸ÷¡o³& RT ‡SÜHTå}¤1Íj¥UÇËRUì³òGnÊËfLŽ­+]a/—×Íð%­S½©î·F“mµ&[5׉äÑ&{0fºAõY› -{ Y¯³ø×:ˆ¶9ñXÇÐîë\]U‚²hVêšÝ>[Še®›Âœ¢¦jžíÍA3Y›Ï²ó¦p{Ô›K·©Xfµ)=‡.Ýeå“.ý¼WaÛ`nó#V¬rèÀ/1åzŸÕ‡ý(î—‡ûÓ˜%j¼ò}“,} /-U(³»ÜÔ¥þT]×öœèl™×ÍKXô¥Òõ:bxÒZeÇžž™R-÷lj¼,²­#ˆÇÆWæùêxi4}T®‰{kfË*ßm«';1 d37YY×T8³šŒšŸyl«Ìœ’=f¦,kð¬KiTM†]|†à(v×£þÍHýò/iÀ×5 bé¥ïh’¢8U˜ Ž?2¢Ï"·?¹yú¢ôendstream -endobj -1306 0 obj << -/Type /Page -/Contents 1307 0 R -/Resources 1305 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1303 0 R ->> endobj -1308 0 obj << -/D [1306 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1305 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F14 685 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1311 0 obj << -/Length 2674 -/Filter /FlateDecode ->> -stream -xÚÍÙnÛHòÝ_¡·¥ˆÓ'Ù=ûä$vÖÁÄžu<À“y EÊ&–"‘ò1_¿U}‘”écã 0.VWWW×ÕU-Ót¦dL¸³T‹X*gËõ™]ÁÜÇêhžh1¤zwqðÓ1Og:Ö Kf«/¥èì"ÿ=zÿ¯Ã_/ŽÎç &I”Äó…LHôîäôƒÅh;¼?;=>ùøÛùá<ÑÅÉÙ©EŸ¾?š/¨’Ö3Çá‘Ç'¿Yèãùáçχçó?.>]„³ ÏK ǃ|;øý2ËáØŸH̵’³[ø 1ÕšÍÖBòX -Î=¦:ørðïÀp0k–Né/Ð,„Š/Ù–²Xk)¦·%``šŠ'xÙux9Я³êÍ›$,N Λ—ñ¥±–’¡}5‰S -³)ç1A˜÷lu,A‘Ž’Xr‚Š³ù"¡ÑüÏ¢£}sKúH”Š5U¸ñìÛŒÆDhÍ-Í6'í5`?¬ÙìCç™ Žäù.ŒÍ‰6pXÊÒ˜ BR’ÆJ{¤‹ë\(UѶÈ*„t´É¶EÝYl[lç N¢›9“Q±m-v5T³µäÝuÑ:ΩŒšºpdíu³«rK•—mv9g$ªmVU(Ö›îÞùõvbWçÅÖ‚°*!˜„’*5\«R³6»·sãS !Oyt¢ì&pª6Û¦é¦X€"€É[˜ÒÖ•­%²cêÎsâ]Y9&emGd íUf¤’: •NŸ·eÐY=V&ˆ¾vPãÍÙíð\2ª=ÂX­Øn甀„í˜>/Š×vY÷Z·À¶(‚|C:žðÙ0˜^Ÿ˜ ¤NôlÑç˜×e…ˆµ¢‡è°iðaÖ'å ÿ"á -vмO t"ë*´1ç<ä4¸§!*D¬¨HfC¾vTÛóa §Zêñþ_6Ų\Cq®£Û묳ÈÀu¶.ܼq"„²Í¦ÈÜ<šGcrÀKÀÍÀ‡ê"·˜/g‡Ã©ecF7¹j#çÚþ‰n7xÐÉʸö‚ëXA†‡qmÃî1ãé0¶x¢¯„°"k1 X ÿ¸ö|¹ èÒavm‘?ð\oopµXÊ„=íCªÇ"PõN±lê.[v½BÇŒ=·} šØäRÄŒì ¼‚)ἂ)y‰ Ú© ÐNm€ón°MXÒ§F±ç8eÜ¢ŸêÝ'Wc2žn!¨nîÏ.^ã_1þ÷}n*L)§Ï¸Á€ê 7ðT½˜3/0kWÅ_H“X!ž–!PM1òEc¥d:–âÈîlô`L£¹‘=2óÚò†rñ…†âp_¼s¸¼Xe;sYå;tfïX˜ÍžÐ5J1ù\È ¨žÐµ§ÂSº-z?ÔµŒ™ ÉÓ2ª !ƺ&ŸT¥øÐë•CååM™ïLAßA½b ^íÔ+†êåÁÿùP½ÜŸ2Ç¥P¸ò&šMW6µ…—Ym9^ÚÂi‘‚¨©ÜK¼ƒx²¦[ÃæåÆ;EW®QB[󵿀ój’€‚ 8¦Ô5?دÐ$¦ -úBˆ+-Ï—.ëʶ+—.ŒK{ê$–/ä…AeŠQ¿·ö"^u±Í:/ÿ¥óÇ-WÈ åº¬@ÐG¹ r¹sÞ\7(s(*ËeVùÓxwϺîªúJ.5géÓ'ÊwëOVWeÝúÖ]»ð²CUÖÅ[þ·øyÂ2aGev|óæÍ´ >„ÉW"‰N9ô³Zhø Ó&zp Ul½[_šR`SJÀ¸q^[›¡u“nÌ슨ó,€ù­.ïmw_9ÎÆ»l½ƒ F£u‘µ;Ë8¬häضpÿÔ¹ÿ(ë¥ãò)«wÙö~ª‡ À˜kQ !}›L£ã¦ªšÛ²¾‚™D:»ó$1°PˆH$È,ê­ÒœàfÕ¯h-•¹xËÚ±Müªe³«;£;Üê~S8yl%7Yµsy®aÎ/6îÖYî–OöyÀ¬ Ò±é†lgŒ¸õ¡Å ÷ÂoÜëÞ‚öQIC€cáãú.èÞÛ1¥†‚áº\^O…Gßµá"nîLNÏŽÎÏÏð¹š'Ž¨Ý4µyÎã>ö }gÇ -n_Út†su{;}Üóó‡FP¸§ t¨C«¾ÎSÐ'9Qjô¾óB–~ÅãÎGH RÒçœê^¢¤M'ÛbUl·öúzÞûeÁûFï”÷Þ†HkY:3AªGO@ \ýŒÛÛð°˜Åä=jìÜ>a ÁÉ_§Í¿Ô@Ø'œ«g D5ô&©´Ù¡¾ÛnÛ¢{avPƒ» `“\ÜÙl ”·‚cûp÷ê‹+|´= Î&ûÕíú<ë²Çí5Tĵ—ø¡ö’,N.›ÓDÅ,ñµÐ]Þàý÷2ƒ1)ƒÁFƒá †Î`Ž ÆdâËOÿóáìóáÉéTzí à Nüw$¦bõèÛVo!b.…6XeeµÛ/ $l7À. \Køb±²cK2ä:ÄïÅ’´¹ŽÛž?­¾•d<6Èx®–P@gáa¹ñóÙesSêÍþ(ø Jg™BUž iüÑ€ ÷„ºÛTФu/i>(¹+ù°Tæ"4÷52ƒß¦ E†¶v½±!ÎM=ýh²EK»,ì»Jð=tÙXÿQæ-‡âû*Óg)ÙWÓ‰¿Vûß4 ^w?‚$ÑɯS—s–ç.µø6ƒ¿7Û΀ʳÆÜSænÚôî4r_ø¦ã’V[`Yemëp•å哯S—Eh7†°Á6aâq=¸æÀæ¯s#`ÊLM4N„žü]‚„?™xõß–ô™AÝôÈ£;' ˆ«Ó—1ò2/Ï|_’«X*¨¢ÿz“»çendstream -endobj -1310 0 obj << -/Type /Page -/Contents 1311 0 R -/Resources 1309 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1303 0 R ->> endobj -1312 0 obj << -/D [1310 0 R /XYZ 85.0394 794.5015 null] ->> endobj -418 0 obj << -/D [1310 0 R /XYZ 85.0394 494.8753 null] ->> endobj -1193 0 obj << -/D [1310 0 R /XYZ 85.0394 472.5641 null] ->> endobj -1313 0 obj << -/D [1310 0 R /XYZ 85.0394 284.6288 null] ->> endobj -1314 0 obj << -/D [1310 0 R /XYZ 85.0394 272.6736 null] ->> endobj -1309 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F62 995 0 R /F21 658 0 R >> -/XObject << /Im2 984 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1317 0 obj << -/Length 3317 -/Filter /FlateDecode ->> -stream -xÚ¥ZYoä6~÷¯è·m#†‡(‰Ø§ÉÄ“8H&»y˜ ²Zm «££ÃvgÿüV±HmÙžl`À"‹W©Î¯¨b£#i6± ™æBo²êŒonaìû3áæ~R0ŸõíõÙ7ïU¼1ÌD2Ú\ïg{%Œ'‰Ø\ï>m#&Ù9ìÀ·ï~ùðþòû_¯ÞžÇáöúò—çÔ|ûþò§ j}õöçŸß^"Ñbûÿº¾¸¢¡Èíñíå‡ïˆbèñ̦Wï/®.>¼»8ÿ|ýãÙÅõø.ó÷\á‹üqöé3ßìàµ<ãL™Do Ã™0Fnª³P+¦C¥<¥<ûxöïqÃÙ¨]º&¿ &¤V À))^8–Žàp¬k†1K$ON 7LÀ?ØRÂÌ„ËQ'RÌt"„faobmX¤¤²:ÙµÍáïP60]ͦƒTbÆpλ¾ËAœa¼­‡ê&o±m›=Ñþò¶È;êì›–wEvG{¿ºËÛûÜïŠ.k°'’-qgB0£µ´‡¦çA¨að1Ë»®¸Ï±kFp9@ZþXt}q.¶õ-h×lhýºdâÇ‘Ë•‰Qn»´r­ZoÎÅõ¶?1­wÔÈÊ´ë4½}pïävnºήûò¸+f$κ!C›^q;¥@ÑZºyoV¶ŠX¨uè&´ù>oÛ´\ß)Ž@_¹Sýض]Þ¯m$@â"üúvM•õÊN¡fFÅzÜ)«Ù’'žì„*f±@ÏeŸåÐækLJoäåÖ7üorzuF -¯ÀóÝ¢’ÇB£JŽ²Û}ÑÔiY:ŠS76Ñ0V4+CïÔRÌižy{Á¹SÖ ÀJë¶~™_¶&!Å%ø8NšVc†¸$NÎùöíø:´íÇ<î˗àÄ˧ŒB„’šqÌNcìW¡žIûÚüv8˜Áv6P‚ ¤e×Д $9¦—E6J ëÊÄK#µËWx‘†%qœÌLö/:ÇPM§(IÇ–ã„ú†HEu 0{ï^¥÷3HÌÝ¡©;7tÈ[Ì@l¼¤ç‘\¦Š*­3ÔVl(&#$ŠadÛ¿Ýå5¡ì ?ÚÒ(>\‘9mØœÙQ3¯Ó›’,6‰ç'ЃâNtoÄÔí9‰Åw×´} ýZ²(c—¡1×µ”ÉŒYÌعî©C ¹³89­»‡ÜQ¯®5>4}îIûÕ©rýšI€«‹Px“@[° ;Þf/-“™Xa¨Ê³»´.ºŠôªxÌ #_èÕ*S/ðåi¸°G³nzj•iŸï–þLâ„Æw>úxâÒ|‚CÐÞµ•0ÕÜ%1©gîÈ*63Ï››Ž-ï„8H¶ÜÙqxéÛœÚd÷±9µ{4 Ø Ôêû¿sÍzú“¥WW'Ü!ä(;@V–ç ¸ÜEË'˜nnWjŒ!(b…V–ù&/›à@Øx{3ô4Y=«—Æ’µ:ui¤K{…ÅzØm]üι„1‰ !¶ŒpÞ¥;ËêfÒ¶/²¡LÛu—ïñÄ=¾‰e& ü’ãkoG@3DÌÐ!í¥vý¡-úÔï£' ar4œGcZÈëP–v—º½áeDÚåe~›¢ÝÐCÑßÑ´¢¤Ûrpv º^5ÈKk{á¤êÚx‹ä›ÑÈn¥Ç¢*ê,T‚„™>+²A î‰äÖ,òO¬Év@‘äÚ;˜LÈq´ï§ü&–ùmÝ$ƒ}ÛTÁsqGpÈô¡2ÆXIk’EÂøØT7kÛh€¦É<|)(m*xù÷¡‚$P|Œ#Ì€A“­Œõ„ÒÊ,u1f¯ƒP¨ LdâW¬b VÄ4ÍE8#Šœ€YÄ¥^ÊqJ0Öt| MO@H7!Em­`"L>~:Ú.íÓUãüÅú…‚õæ¾h†Ž:Po¦»{pöôÖ¯ I(ÎL(ÕWd! lž…Tä=Z…{’®þ -–ˆZ 6Wb««E…) -úG!W¾|Æ=§Ü=ËÙνÜ(‹@DPBħʹ¾:DO" -ŒÐ‘®ÒOr -½3ÓŠöi%BÐÜ÷T¹Ôˆ£ž$BBé†êàŒ2¢¼i' TñÙËÛû -@ŒoVÊ*ú´«_¡¬Hûâk‚XWºŒ™Ë‚o  ¡ 梖…Ò¦Ü版9KB³d" à¶ÂKÕÕ‹QD°0âúÅ("´ü.ŒÔ&®˜ð±‚‡#åÐt]üØž…'øN‡<+öGGt R a:95 ápðP¥,ªâÄÉG»Õ'z·>ݸ…éÌ{oÜì¡[—ªÔPv*y¥¥“lWü¹&W¨°¹Òñ(z¨ÎtdÔópjB(ÛO Fœ•Ï¬Š²/ô«¢&ÿ gùŸ†h§‘hBLD[&‹2ܹ#~YB$í¹sàä·s !¿¿ Öw3ô«ÊâX%µÔzºàsùü—³²ÈÖöI˜†÷pÓæŠð<ÁLH²f‚ -LÐX$|>‡½8èvzÈËrI¡õ‚uˆ´! -eÇ=]—–aNÂâ&½TÛš‡Ñ@[D'¹mnHznH0‚HóÑFí ¦œXƒ£Õñ´²íúiÏÜU‡Ú!G˜ã HÎÙf‡ “«Ö2rnæ8l¼ßt¢jv!z³ }jB -¡ðü­°e­Û^ƒfYžïü-’æi§sí6¥3ÊÜ_®Ú83ñŽáؾŠòìíVдh‰+w3 Ô”#(ÃO `tñ!¢…ƒ+S#01[s -`Ÿ¡ÜõÆ­¢AÆ¢”ÚÞ-Ì)Þ *_q‘Ó$6-€±7祵arœu<8;öï²°cÌ«öª’ûµoa!@½£^J®JÉ£¦Û~»jOOàX :¯Š‰YxRÝa÷N»ÜÍDSþšƒA¡eîOqÕß|sú¤°bÉxÖ b+é¢[Óu9G„æ¯ ½çô )’ð=Ïf½ g?k¦ç¬Ì4×·-Bîé“ÃBåQÌÉ—9g­°²xëX2¥½ä…¤,§o3ØvéGúB¦¢+!œÕ§òª©n*TÊø!ÐÞ,©í „Ž Ðõ¦»?…çOW¿ÒâÙœ´¼EðpWQ‘ÎZ™e8Â0\U7Kx¸¼à\ì,‘¯„Ì2ô9Âi\š’&Óƒ|`͈§þrÍåžF 6`úhˆÀQ,2DS´}ýE³œggy^]¥© šæ2Ñ8m`ì˲Áf»gmV0†H'/Ûì|Öó6;Îz¦ZXF'Ãb™¼ÂÀ8k…ƒ…rTÈbnNX ðÀÕìÚ :i…Ÿ}¨M UM53´)ÓU{JžŠîÔàIŸ¡áp²ò8YÞ²þ‡[EoÚ#ã>Cø%VwZá“›0ÇÂGÊ`¡½Y VQ/€e8+ç<˜Ãþˆq ײåâ¢ãÚéê{Ä:$û¢æì^º½up?èÓÇ9ؤñg¥ýÄÛ ->+Vá·ô@ØŸä;ÈC{³‰ä”ŸÒ_œµ7+6¶@ï¾Èl89îÅüÈôp(é÷vÃCÚ wîS˜NR•Ø>¹ovZ´=ùÜHº¸–><êY$€ŽÏ<Ê," -g2”¾JjËïê/AÀTb“¨Y¾TXðS °'8ùCËÅVꤣ¡slï–©ž_ôIo¸f ÔÚÁEKí§iî’+d< °Pó,XaÖ.GkU>}GWí!à~GÕL©§O©±ûŽ:ÿNó±åÑ µý¥R›"ì[‘ðÉWT¿Gû‡/€7ÚOßÚ|_<–yý™þkßN*fðþuñnŸhÆMs‹šØtó¥i¿`¤Æî?éñyÍbÜâCÛÜ»<(÷í«{¬ýV -$„?pZ‰–|éßþÕô#³âi’Èõ°ë~¢> endobj -1318 0 obj << -/D [1316 0 R /XYZ 56.6929 794.5015 null] ->> endobj -422 0 obj << -/D [1316 0 R /XYZ 56.6929 644.4755 null] ->> endobj -930 0 obj << -/D [1316 0 R /XYZ 56.6929 619.6136 null] ->> endobj -426 0 obj << -/D [1316 0 R /XYZ 56.6929 131.4228 null] ->> endobj -1319 0 obj << -/D [1316 0 R /XYZ 56.6929 107.0033 null] ->> endobj -1315 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1322 0 obj << -/Length 3405 -/Filter /FlateDecode ->> -stream -xÚµk“Û¶ñûýŠû¨ëX ñ"É''>§Î4Nê\:í8O¤N¬%R©;_Úü÷îb|ïOG,€ÅîbŸÅi ?qjM+§OS§# sºÚħW0ö݉à9Ë0i9œõÍÅÉW¯Uzê"—Èäôb=Àe£ØZqz‘¿_|û×—?]œ¿;[J/’èli’xñÍ›·¯âèïÛß¾~óÝ/ï^ž¥zqñæÇ·~wþúüÝùÛoÏÏ–Âë%c¸gÁë7;§Öwï^þðÃËwg.¾?9¿èxò+b…ŒüvòþC|šÛߟđrÖœÞ@'Ž„sòtw¢ŠŒV*@¶'?Ÿü½C8õKçäg”Œ•éœÝ@€"¶‘Ó.=M‹%•—àû³eÇ‹CñÛ±hÚeùy} ÈmÑ|¬«šº_Óßdö] -9cäG‘WÍ—¬]óý²)/Tw—Åá! bˆa—}~6‚ í!«šuqh¾hõr]vYKÀ_cS«®Š%L¸ ÿˆ®nÞtKÄxÓ‡˜þTÜòºÿÐ_ÓÊêj„àýý#Qzßþãùœ6õñ°*zN˽þ˜åyÇ!¢©‹”L `ŠR­ŒGô?d"—¦ÉéÞóþ~_X†åþ#v>ÌЇf)Xô:—×ÉÔä.©.dVK¤ê{HÕŽT«HªÔÍcU·åúöiMÒH¥Rß'PóeMU¤´s³Qù¸8û³ùœ¼‘ôNo†Ppe‡±4yi,šfjœ°Ñ”z)E$Ò8™Q†°á¬6|í×ó2Ú¬³¨Ti«õ³7ËDY™ÄèYʤ;»ç‹E9 lsÚöœ=Õ/‹yöfc±h©#[=V•?¾Æѯ^KÑÉb$xœ3Êe7k$‹fS·H%$¡Ùö&ÛtlßÔ‡Oh9IÂù!ÀöÇÞʞđ$î>wne¤•2Ovç:•!ID©Í:J£;#zÜâRçF~’ù*ùߟ´O¼?y†¬Ïº=—Ñ»y”=@™ 6“Ž³(2šjÃéA£óÊò:‡VAŽÌ*ηpÖeíï•ÆNË·Iw á½/ÍNÊoVóh§yÐ))þŠÅºf,Åçl‡©c ±dŠÈ[Õ‘ÈÇ85•^Ëåòxuu;¹á[²fJŒà¥VõápfÇ}ËXñP‹Ù‡ gâ°fK´{C¨Õ"øbÿþ6± ;}ì’zÃÔ‡N,bûŒ^XÎ…2z€u…´9OÇÚ·…útßò²šþy“tqþêíϼ‚òl׻ݱ§ç/Å 5•™„¾wÄÒ-„Q4ñø¾ñþšn¶ü·”X -ýŒ4;T`¨L<¹OªÀ’îZlüÐyw; É%ÖM"&Ôµñœ,_O"ˆe ­_^ýDcôü‰ .Û-iŽe9ˆª-éÊà—·÷·‡â3²ü`@åoé9·À¯JÆÇ4*‘„Ÿ‰À?Τ'Û2§qŸl4T°ô·0`„$(i‘[@•äò¶%5uþÑ`ˆ¢>¶tчƒí¦d0_#uÑË-¤jæ<ù¿àr|Cˆæ®f/«ŽûQn` ëëã–`,@€òm -È´l64èÙÒq Á3çà£@kàt½9x1JÏ°p0£]<ÐŒ‰#%ÑÝuF iÆÕuä 3,€rüÁÖÁ±y·º-^L}YŸvŒû<¼ž¥áÊnp¨}Ì´ËÐâ kèˆ1Ù£¬z[Ò¢«"ÿ'˜1SpWª«G:¥*˜©PÁƒbpû\îŽ;ìÈÎ*¶Y/ÿJDëÉ€¡ÌR¨ÎÙbõRù›O7±*¬Š¬TGJÅ3íLMJI¦&%¿ý€L !ljšu¦†ƒ¤o.äÔVòc@zSCèØÔ–*l\}($¿ÓÀ0.guèM&;ýTÕ7S•y¾fþyuccék9èÑÛÌ}zÞµ¿£P}Zã]6Ô75ùòʪáå&N²ëô|™†à‡`ÏVIÑL3ŒÒf˜¾ÏÚÕ&\11 ãw2Ø…ª{¼^Älÿ '¶ /‹ è}âôâ_è -}¼…ÿÔˆ ÿf»¾¥¢þÎÙÛ µ}8MC¾ - é°‘1’`›ˆƒoŸí}—#àw–á,:KÙ‡ïÂîùbP,ç¾ï‹»ï¾økÂþSKFÊZÙ}(8y¸H"+]ˆò_B˜)åÝg‡wIÿÝíúendstream -endobj -1321 0 obj << -/Type /Page -/Contents 1322 0 R -/Resources 1320 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1303 0 R ->> endobj -1323 0 obj << -/D [1321 0 R /XYZ 85.0394 794.5015 null] ->> endobj -430 0 obj << -/D [1321 0 R /XYZ 85.0394 575.952 null] ->> endobj -1214 0 obj << -/D [1321 0 R /XYZ 85.0394 545.1349 null] ->> endobj -1320 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F21 658 0 R /F23 682 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1326 0 obj << -/Length 3013 -/Filter /FlateDecode ->> -stream -xÚÅZKsÛ8¾ûWè¶r•…ŃÁš““8YÏÎ$³¶§¶¶2©%Ñ2+©ˆ”½Þ­ùïÛøåÇÌaË Ð@7º?|Ý´˜pøm˜Id2‰“ˆi.ôd±9ᓼûp"ü˜Y4ëŽzssò×÷*ž$,1ÒLnn;²,ãÖŠÉÍòóÔ0ÉNAŸ¾ýôñýå‡_¯ÎOãhzsùéãéLj>}ùÓµ>\ÿüóùÕéLX-¦oÿvþËÍŽ2^Æ›Ëï¨'¡Ÿ#B¯.Þ_\]||{qúåæÇ“‹›F—®¾‚+TäûÉç/|²µ<áL%VOà3‘$r²9‰´b:R*ô¬O®OþÑì¼uSGí'8“ÊÈJ5f@0£à°ÜÖyY€þ‘µÓË[T¦‰Î´H³Dâb8¼Þ¥Eu›íN…ÎnËÝ&­ý”îJ±„’ÒÏÉ«Ó™âÉ´(kh>­¶Ù"ÿs™-Ï GFÓú.YÙ&LƒÎ¯_Yù9…h óGÚÁøz±bŠG‘ŸL–©FQ1Ò/R§u¶ÉŠš–xÈ×kœ3™©ÍÄv2‚%ZK7|ž‘í«lÉF6Áa¸eœTOí±}D’i%mÇÌ2&ÁØÓº¤žu¾Ékj¢â®Qì7s0¦WÞRߢ,û³°Sûòb^î‹%=ü§,2/ºÙ–{që&•›Á"=ûã´*ÛÝêLàq -FÇMfAo* -P,–6xÅó(Ńyë,C¶w¦ÒCGÄÚºnmÖùŽt±(Â˼Xùye;ÿpÏRr'Épϳ­wçQ/‹#&#žô¼‘yÏÒ‚ñ$}W¹_pEË`¯oÙãØZqÃÈ©T”Ló%¸Ù¨¢žt,R‹Ú½Â"C`”Î5X0€Þ±Uæ%Ð(Yb­ÆY#qÖI¨××?1Æ´+»`YŽXAHfÛcZf¨uá #òпã'l,³J 042Gl:€ „ÀX9rëxÃSc ÀÎ/Ž“.Ш£Ê ^óSÇGr pAp 8íäüÆ5¿¹¾üp6<k™ûvo˜Å  Ò»ÝjB«ÎE†Ïºã¸‡ë,ìÛÆSð¶áV„2,6F÷örpÕ5£žÙ¡4oAx¸ËÜVÌ´N×ß\c·;üEÀa᦬3ÝïXòé?½ ¢3ãû>«jêp·Ÿ›ZÔO¯çèŠ; ÑÉZ8Øœ·¸¦NkBG•¯Š´ÞS?vYº–ÜKç`ð»ÊŠl>¸¤Ç}EfЉßLB?&½‹:î²V8@Bá»Óí6+–aPõD&ÓMVUé*óOÏr¼ï®=uTË]¾ÊA¡m;×M³»§E€íŒØqGBÚÁß÷95–}·4Z2¼C õ‚0´bÊ5:p|¾®ïÊýê¨÷›ÄÆj—n6éŽðæ oÇ®º¼X›g°[3.Œ`7JM×ëò¡¢¶llöë:ß®ý” )0g±†ózÄ~ž…¯Ñ':C©·½õöÅv^‘Ÿ -ÊŠ¤ï¨Z±öV¬öÛm¹«= oü. ²á•=FX•ûÝ"»Fáf‘I`è©£r•ñq¹³{3"ÚÉ7qܳ3ƾ|ñå þÞÉ}~ÿaÌÖ°ŸÈ2kxû]Eò—ù•Êò–ÚÐm _ñîñŒÆúÑÓŒ#Â:?<¡C‰:aR6Ÿ :UyiySÌ«èñÝÇëë‹·Ô¦"ZýHOTY(ëŠQ"Ü™WAá¹ãØ]8ÅldÕD!Æ#ÃyšS6ãgÝ cTn(·Ï)a3³»tM8$]á‡t2ŒznÒˆNº*Ày0é¬0ÉÓwöÆÞ {Ó“³0üvj¯Rq_®ÃDì ±ÝÏ×ù‚Ú®2ÑfjÊ•/ð§(‹Yº¯ïJX/Eø§nÿCñf½oEùP¸”MOç{¿À«"llî§:gqèIÙÆ1ÅM9‡ŠjÆi(©çª@ØÞtF­ ro—‡ „û…/¸ÃCî>’iª -Oeý\j´&Ã'ŸÜC«çålÓöÃN^Xi_Pµ‹Ô§ÂÝëÚø#BmOïÒŠz晫…j÷! Ïoµojkn¢—Òc½;µSÑôŠi®îíà w8«&YiÝni@˜p—.Ã~NÅ”¶$¦÷é:_v&~Ж¬yŸcZ·ÇíoÚ›~­±*×M…1­p¶µGÈ7 í×nóæ’X’õƒ}ŠÖ©¯W¡L6_–ð©ªÉ¹in¸¹›`Ò-x JjÂ×#q5 6Æ¡…©áaQîW* ÿe ºÑO*ªœãã:§Ã6ßf¬·EŠç@Û⇱PBKCQ¥/3Ào¿’Ë•à7ûwîŠÂ A[Ñ”åšr6èwRXâOýÈŽçû$ÓI<¸Òž”îUi›fñ¤Ã®Ü[,Ð9ƒBÃZu =nÈÁ¹´/6Žµ¶ùX¬›ì¶¬²áÒ­íà!$ª¦Iaƒÿ÷òc*¿øW` @²„Iúv¹ºª²zèý­IÿüÝ{°NMúäÐ+º|ü:éQÀµN^n5aÌP‰ç Ê"D!RSo[Ç'$¨æx/D€$éâ®™[ÁAûI¼Ë%árrœ]`,/ué&óŸs°jK=üNÇUº -8Lu¹(×g0Vx•ÝmÎ,«©Ñ½Iáî5Q£¶>ªA›´W»ëÏ$­=±#ÑÑð(i)¢ðñ>Ïþ(ÿ&HŒ—õmåL¥4°R=°ÔgHV«êK—§.âMZ/îf‹u;iø¼ûÁ¼Ðâ«ñuíû%æ$_í¾@á?„üYa;Äì -ØÈŒBÇ?fÕ×r÷µ(GsÑÍœyèß<åGÆÿDRÈöµ‰ƒÁœ±ÿ^“ã¿°DÞøßþϦöß¾¢˜)kå8Ý”˜ÀxUØ”ó> endobj -1328 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [87.6538 683.0228 137.7628 695.0824] -/Subtype /Link -/A << /S /GoTo /D (tsig) >> ->> endobj -1329 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [370.941 574.3534 439.613 586.4131] -/Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> ->> endobj -1332 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [432.8521 316.5051 481.8988 328.5648] -/Subtype /Link -/A << /S /GoTo /D (DNSSEC) >> ->> endobj -1327 0 obj << -/D [1325 0 R /XYZ 56.6929 794.5015 null] ->> endobj -434 0 obj << -/D [1325 0 R /XYZ 56.6929 474.1474 null] ->> endobj -1330 0 obj << -/D [1325 0 R /XYZ 56.6929 446.055 null] ->> endobj -438 0 obj << -/D [1325 0 R /XYZ 56.6929 366.5019 null] ->> endobj -1331 0 obj << -/D [1325 0 R /XYZ 56.6929 335.6 null] ->> endobj -442 0 obj << -/D [1325 0 R /XYZ 56.6929 180.4336 null] ->> endobj -1304 0 obj << -/D [1325 0 R /XYZ 56.6929 155.306 null] ->> endobj -1324 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F21 658 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1335 0 obj << -/Length 2914 -/Filter /FlateDecode ->> -stream -xÚ­ZKsÛ8¾ûW¨rYºÊb@€`sr'㩉'ëxv«vf4Y¬P¤F¤ìx·æ¿o7àC†#e6¥6¯_ ¢ƒ_4“IÈ„Šg™ŠÃ„EɬXŸ°ÙŒ½?‰ìœ¹›4Ïz}sòòÈf*T)Og7Ë/2)£ÙÍâ×àÍço.®Oçœ_Ÿþ~óãÉÅM¿—ñ~#&p#œüú;›-`Û?ž°P(™Ì ÁÂH)>[ŸÄ‰“X×S|:ùGÏp4j^õé/2L$Ï| -T>&*LF¾Â=¼|Ç£Y…*I8Ne³y,C%$7“P1œƒ–cÁ}©H Ÿº¼Ók]wÔ|«cŒ×eW65õäõ‚ˆ_ÚüNÛ…ÄH$X‡'a–ÂAã:7+ÝK3LŠ,®p»8Ç,ÿ”ÃTJi'µcÉÒ lé™ÓcÓ<èírWa+ –:ïN£`·=d ©¯YÒL‡¤””Ý*·<+ÝM¹ÖùÚ¾Ýêí½ÞÚÁº}èiz¼½úDÄ;½}$rQ.qù¥6RÌqƒp"TQ¦fóþd`k°© -_Êd°Ð]/ÊúŽšFëð|X5D˜mÃ3o?Ã$€¶P"¸ì¦ƒ›|ەŮʷŽí®Õ¤ —ÍÖN_o*£Ñ~¹vS•–íût·ÛXÆe·jvÙ -s{ «]å÷Ä Ñ5ôÜžÂÊ7ë]Õ•°µHmØs’a¬xb8]äÅÊ@ƒPÉÄ$!#bDÄAµ˺Åf„'‡½}¤ 8ÐbM‡Qö ÚM^Ø~ ReUÑ”[;Öj]uû8Y§ÝÝ‚&§+U Òæ±J‚s‹´ät!4t'³`wÅ -w ÄŸ”° €»±ah”K+;;©mÈpؾüh_^,ÈBÚ–Þœ°îœåN<Cq[# |}Ïi - ¶ËD:K “ŒÇǸM*cî>§9ï9ÎÇ,ŸzD!³0Q0ÚOC1ÍÆö…¤„,ƒ¨óÝ„ì92æQÈR8ä‰UÙv>P§a–EùÍr8C €ÿÖz BB–2g FÎ q&‰’>Œµ „€(“: Š*w‚– 0XCb¡[ð'9 ì@°™©c°aG6l<6T&ýÊÏ‚M„"|–‚úÓ(ãßl–ã|ÌÒ¶4éhá¯`- eœeßOÆžãcˆµOo"äsXË¿}\&?%G”Ïc-eªÁ8c¢Å%>Àt#%ã à0KTp‰2 ÔMGD»ÑE‰ž]/Π'‰ƒÛ¦óHD˜OD!Ÿ} -é^ª2=º'&ÁÑ@–9áx`k -_‰”}e¡—9FÚ †M|>Láè˜#ÇÆšW&ÕQc³ÒI„HƒËºë37e£² -ÀèŠÏ6V+Šû||[…ø›IÈÔžcÁøWµÀŒã$ùíI|…÷ž(w­Z»¹.ÿìË7!Md£M´øY?¶Ï$žIìà÷°*Ážáâ`cTÔÜ— 4ˆT(¬u±Êë²]SÓ¤X8N–=.€#mÎ[]éÂõ¹‰&Q<€£L¡~9§©6KAFnIÚ3R·V˜‘%Ø)¾ƒœ»ÝM ’´¿ÕÅnÛ–÷zÞÔ:zÐ eCŸ‘ŸaR˜:ýð,5@nL¤Íª3V¦f—wAÖÜvöÅ%éxm9:[0¬ÞÌ%_ý¤Ñ²Æn¬¨“ó)W°ÄÔ&s.’ 1k.LRÍ%=;oíµª„уµ úæ½D´%¾¥}¶å]m µ£®ß8ÏŠMf}æôHYÔaUÔ­Oi›êA`«‡ÍÆESwúK×oÕh RºP0¶gôäë(ä¶cmP³è=ÿW*9ž9•¹‚‹¥}ÚT€Ê9™FÑ´*øwC™;Ø„KäÔÄ¢7‰tîs3L†"fñÁÒ!‚{J‡ÄA )ckð$P{ò¢ßYÞV¶m¬<aÖtRéô˜¥NÌx–…2*. и -þ -¦nÃ>µTCWÝSV06ªë8%-úcÓú—@ SÜ:*Xä]N}äȸµCwà l— [ðô²SN½g¾š”*]8ý%ÇZ÷Ì‚bY 6°­ó -齋 ìûØ\âÖ]†ØjÖ–ÍxaBŒÊfo}û!¯Í °W™tl(ð™†Óe=Lô²ô»~e/¢ ¨Øöôà ÓŠl­Ú䎆ÚØLE/t]ؾÆÞÿ!×ÆquŽÀ¿ð½PÕÅü(ÃdÑ“tÁÆC!#Ì8â©ùçiÁÜ-Hç”÷w “†¼µýÖCTzb -(0ˆžÎ-íÓ—Gñxøòj: vk½°|¯šÎ®n͉¥¶J1‹Õs÷úý ôzg2”’’ÜoÖÉ‚ß±>!i]y[çC.À†!.¯œï¦= —ÜE³Þ”•^ÌÝðµ‹ùo'ú¼ÔÃír4R?Œj=%²€3fGxÆ8V¾¼ø’¨Î¡@h öŽZHÚ ÇIk|¼+Þ_ó÷Ù9ô W~øE¦hÈ:qU7¸ë˜]pª6Á+¸=·\*@t0÷H‘Ø‘ŠÜ1`×åUHÄyýèMÙâ"€S–ñAeA©ž~°KL¼.ßÔ4`´gˆfC#•¾×õaHMŠzï¶öN GIÓD÷'og·åÂ"cáRë,Ì>ug&«‘ŒB,<ñÊž(ºàCÅË12³!BÑ-KùœŠ2H;˜R¾o-ÀÛ–@¹+Y¿{éÄ<pQ{K#ÃAµe ¿@ÚT”·FePè+•yÊ·£c€5ô‘eöŽ½uÙ3.Ê£7ˆ¹P‚ˆŒñ¶,}faëÜÐ5Póº€øðÞN±0NŽù$æÛª‹pbSÄ<Öz¬Ò©¥ž¤ÆVÐå$¯í7hí’\Ë×}LÒ6Þµö -k¿®úr«¿¶Ï¿{.‰a×"d2ÞÛ69»÷Â%û/¨ý_£,‘@•™ì¼/_Ò”c|Hµ«fW-ˆ¶5’øEÅŽ7µjÝ=4ÛÏ£Ðñ䎥/$HóˆXh~/å+ê O¸æ[*~0dñDº[{…íp¡bäÕÛû²° ´Ñ§BN$À°é•ÖòE—‡óu{¼L¹]¨APt¶s8„™oe‡,ï}°ÃܾPn5ûÕŽ>“šõèÀn§ü§Û†¬­Û?>˜7Ae$Éa´€}h‡Œ–zå-BËjùÜÉ.n_¼²–ëãÿçƒýqˆ}Ô»öxÔðm2·'`1—î½%hkø¥srœ›­¾/›];œû7ÚĈ£ áZ/ͧ¨cíÀ©d²µcÐ_7ß ~d·-‹Îié¯Àß÷?8Aüóˆç_#¬ÿ»Çÿý•áS¢Š†=ÏõÛëÄ:+×Ř Â~nƒ«sŸÑè8 +ùr‚#ÞŸ©5`/þrÒ´¡çØö¾Éó+iµx–on¹Ò²®Y;aJGÒåþJÍÜ+¾ ,HLQúÃqŒ™Âk„„3lˆLÛ|a¨üišà¸N‚s~ײ˜ ýܱZÆ8`1¥Ù¤<¿(J—àû‚°u…«äaÈäÁNc,‚‡iD¹Priâÿî ¦`8á3ÂNE»°‹,”f}7® -d©ôé¶ÔÌTÍLÙ¢r° „ðîcð$© ³6<ͦ9ï3K™¨åù Ü¡Ü`ò†5’fÅ®³‰ƒ<‚Üã¸ü¥Ûú³d3Ã4ÚÐy’2"e¨µÓ©¯ãÕ»Â-i˜…J¶&|š²i’vV&‚Ìëi„G‹¬ùÌ<9MšÎ.Mφ¦Üýƒhúžáî=«¼Æ\–j²l käq:O8¢¡üªßöT%Õ#=]Vø˜dÔ8™E™Ér衈·7Çÿé ÁÖGA ]ÇB´XÈ0!e$iUàfX<Eu‡åÏ„åÅ›tc „ˆ;Ø[ÿ¨+p5m½wÏ#üD—ù{ÊÐÓëü“{ô1½ƒñZïÊr£Ž«÷k#TyùȯLÿï}‚ñN}¾ëÙzçw{.3ôºí>ùêd{¯${wÓóŒúVÄ0͸ázÐò$HIªhð½æÕË.õÉ@òKendstream -endobj -1340 0 obj << -/Type /Page -/Contents 1341 0 R -/Resources 1339 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1338 0 R ->> endobj -1342 0 obj << -/D [1340 0 R /XYZ 56.6929 794.5015 null] ->> endobj -450 0 obj << -/D [1340 0 R /XYZ 56.6929 672.4064 null] ->> endobj -1234 0 obj << -/D [1340 0 R /XYZ 56.6929 645.0635 null] ->> endobj -1339 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F21 658 0 R /F23 682 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1345 0 obj << -/Length 1074 -/Filter /FlateDecode ->> -stream -xÚåX]“Ú6}çWø:#­%Y¶5yÚlÙ-™†´„²ÚƒNõî·Û?ÚõV `jW]XÔµ«ïÍ_³–]î>5ï_Z·5Ï©¶ŸšYw«~_oÕ›wõ@>Ef<Îv ¸oü^ÏZ­Ûo[µnûC¥Þ^ÙR´Ù$1ä[¥Óµ­1ûCņ„ùÔz676DŒak\q(Ô!dÙV>Wþ\ž¦CËô£Ä‡ÔÇ^™€¬ ²}ÈæYeÐ%˜¤ -vjÀµíê@átRl÷â‰q”u½Ë.ÝÄ`óU€d”â"ÂP„_ǹ˜8…H^¤Èc`$è9ÄI~IQÈ<ϵ -ýëx>´eü’=3¨Tñ-žà·HÕ}M•y»f‹Ì¨ÒTéyT±M &+•458IÖÚ›pe#JåzPZŒDží¾M`ìAäø¸4 -¦Šƒò®&âaŸMàã‚Þõ ñ°³Ë;ô"ï @â0v˜åá_ÏŸ·˜ Aœf%~y‰#”´ÙE_°oØ;tpvV16é€äCÉÕSº¸Ÿ½kRÂDËù)S!6M™†Z€lË9×!/\Æ ŠM@ëð0 À2”.»4“¾äßX>Nz“ Y‡O/ -–†vúa Ô*õJל2X=Ÿä#žL:ø®L‹]æžä!IeRاOW®ÿÄû_Ab“ZÏZ“²G‹a Â…E±ä¯R¾››ìÚŒóÙOB>æ‘æ¸OgTª³s©ÎhKg¥§ûÄ Â0~ߦ\Î7çd©âJõLñÕ*$Í?ÞLÉ}3ãòZôJArJýƒ®\ÒþŒeéÏUÌ[†]­xBÿ‘:äÊ óv‚¯X‡\;YÞªCÐÿ¸¹*ݲCWBarRZrDjþ¹IÈ®O«Svø>^µbR8k%¶ }̼%©ÄD—m3_ܾ¦þ/ $þÇendstream -endobj -1344 0 obj << -/Type /Page -/Contents 1345 0 R -/Resources 1343 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1338 0 R ->> endobj -1346 0 obj << -/D [1344 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1343 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F23 682 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1349 0 obj << -/Length 1975 -/Filter /FlateDecode ->> -stream -xÚ­X_sÛ8÷§ð£ÚV6–±Ëĉ ß×!w¡×=ÎpÍŒ #dY!hõ !>ŒS­•­IV9m§í¾°¯ä‰  û¶®R­;Ïu’ögg"  –—PY9éþ —§ƒí§7æ©-Öï±H j–²à€›ŠÈ9”݆¨§¦#oþáæQè#šzp³vjIfxå´á=q´ñ±©¿z5šxp/ô÷@⬮ÅIìž&\Z8‘¼2]¿±ñ -ì¡@õ†àf8@Ó5†‡PUEª4£.#dbÄEB¯dÌ#g[Õ@¦8Î)9pælª·h  ½_{…ðq×vXŸÓZ2¿kíwØçÕG\лÐëZ6[¨2+k{$ Ëzé;›µuîøè•!vU¤Ñ¢ýŽ„¨I®®Êm9Z@k¨•î™ÇçGA Š+€01N"må¨=”«nƒ <¸m¼„¯á¾eáŠ*Õ£“ ¬6ãžIx‰÷)Î@£® ±lòg³¯]–­üÊÚÉnš½Û }–„E!©`_ìðÏ ,±øQÓÑÂ8°šžƒØ%p„ÿCѼ;4a­ˆ åßV7\2ËÞ:i×ME}ß;PØ÷‚QJ^“PèÏ£aSÛ]¥_ÚK(×}ë1°é¸ÜWùÜk„óæ',‡/×"èÏö °é&Òœ%Iù®£|ÜttÊ®RKíßíúŠˆ3™Àþ3‡ºL†º {Gï+ÎÊÚ  }F¢(¼1Á#Öˈñ,Jzë_ýÐB•Iøa£Ýûò¥æX€b)OŠG´EÐ_‚•NÆÀà»+;¿÷?öHP("@à Ûž{hˆ¨f¸kH`nóo¸Í(„ï€Ü¦ÑûÆ+kîðöXÂÔ!›·f Q ½!üÈ8ð`·$TÍ¡:·\ÓxlöDìöIÁ%‰Ã=A13n£(RÊiƒ*wÖªtå¯kàP…Ùü}î;cØÁßGŒàC/³áèØËü¥Èû¯øïþóôï.4ÚÐFýWÈ9˜²œÉ”Ä C]Œñ÷ªÿ§ÓI Lÿ;­Þendstream -endobj -1348 0 obj << -/Type /Page -/Contents 1349 0 R -/Resources 1347 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1338 0 R ->> endobj -1350 0 obj << -/D [1348 0 R /XYZ 56.6929 794.5015 null] ->> endobj -454 0 obj << -/D [1348 0 R /XYZ 56.6929 493.3884 null] ->> endobj -1351 0 obj << -/D [1348 0 R /XYZ 56.6929 463.2745 null] ->> endobj -458 0 obj << -/D [1348 0 R /XYZ 56.6929 463.2745 null] ->> endobj -1352 0 obj << -/D [1348 0 R /XYZ 56.6929 438.8631 null] ->> endobj -1353 0 obj << -/D [1348 0 R /XYZ 56.6929 438.8631 null] ->> endobj -1354 0 obj << -/D [1348 0 R /XYZ 56.6929 426.9079 null] ->> endobj -1347 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F21 658 0 R /F23 682 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1357 0 obj << -/Length 3410 -/Filter /FlateDecode ->> -stream -xÚ¥ÙnãFòÝ_¡·Ð€Åé“öÉ™x&vT¬óÜLÖÎÛØ;kfuñéâ_ý‚ƒ^š:F?g²Ø'9@&Ëc¯{}_ÞCÁ¾šÄÆJ¡÷j­ŸL¦^¹8ÏR}àJ>àŠvyl’®ìó8±Æ[Ún÷ˆ´yó‡ÁI§Îàþ8èHiS PýÑÔ%ãªVúªuµ*¶ÜÝ5Œ,¤oU<—‡‰WæQùyVn:Ñ- ªŽn/u•›U5+ºRöhêÕÏ -§‚[ǹ÷†Ž×-aukòèLž5ÔÎ[îlÜYðçºh»rË(¾b«°ÅüxF¿~Yw¯}˜‡rè’è“Ðñôl8¯tT„©F©¨n:ÁòwÛõœG̹cSl;îÃs †Îˆïî>ý£Gí7X½_tQÝnˆo7å¬úY)3;>+«(± T†÷ñCõ¬Ö›U¹†û]ÕÔñØM‰@îlfE͸ǒ»¶œ3wCL¹Ñ©Ë‚^ -P—<ÒG‹f˨§ÕN–aN»N«Âh’E«¤*M©;F 롧 €òó¦¼ÔQÝÊ7‰´ë¢:TuU?ÉLƳz ",šâ>Ûý­ÛHYGãarÙñ71ÚºX—¡kûŒ’J£çs>Û’X -.Hú{¬ìIg&KEq±y³`ع ¯fÍCÄ~¶¬V"5cHˆ`ŒØÕ$˜ªÂ1£mª¢uYV¤ŠæáýÁdÕ6(Í -=êU¨Î[™>kv«9ƒO%­v M¨—ª[†qõtì " ¤U&MøVzºjËXæ/Bx0ìdÚ"Xtštð$yÈHd°c„8Ì8p¿Ÿ Ù.iYĬ«Ï¨‚v ÜxIûÁf2âçE,qÏ:ÂW üYêèÞW(º­¼¬FÅ} ÀV¡¶ÊR –ö±&ªPØça#ö œ›žd†Í ÿ0áˆP½£DhY´ 0›FŽ(ò©Üá^~ ó´îÏ©mT¬VÜ/.Îõ1ƒ -¼lÏÌŽ<:#tÈ¡§XµÍWÙ³§·ä͆¾¯û«zAD$ßÉ«þN^Ýéϼ£Êzï {G褑ŸTYð“Ø'ƒ nX£ë8¶Âò»# ¶Yíоö³FNW ­K£§ê-‚óÝÂQ q;ô„Ž})6¡T³…}øM> 'àÑhÜ®[6Û -ƒ†ç2Œ!fŽjÛ;öó xÞã t·ˆF¬ [ÂöõòtOÃV¦l¶Õ³„0¥ì^šíoü±k§ãᮟ$Ñý»·:× Ü® À0`ÏÄ2hO倱bø’>>H’^6NçîûäPáWõÛM1âÃsƒ×ÖâÃ)´J2f˜?Pð71ÈŠÀ™r[+%$¥¤‰ 9“’ÝØì8 9æ5iK¯¸ðÁŠëUðI±ŒÅ§©™×66Ð ²™¯L‘œ²0RŸ©¶×$û‹öS^Í»ljc—q9–wÁâ—CȤ³„h´x)¶ó>¦iœ*Õç]ÎåÑÏÆ8ž"é"Q†°ƒ¿Ð‡c‹šéÄHà7©.´'²ÉÈÁš$ÕˆCýéÊ£M9Õ°Ta´‹¶¥žðY×r/=¼ˆŒ ×" }~wcãô0¢Ž2Þ€"­»ý¦[?Åp×ÊÜ×ék³8I³×’ýÅÕ<ÜMÇùú#›_ÄäN%NMœæ>=õУÀÈ9Ë2YbÝ7Áíg}œ—ßui$|mñÙÙ®$îZV3´?-zY„ŠÍ†¢d4® £~ß•Ûª”ø^kd‚ôÿHÃÑ’T¼ovÕ»÷Ü-ãÒÞ+§deHR’èv!¨f„Ä©ùWh ã,íÙO4ÌI|ì¬õÇÌYKþgIq°Ýˆ}—‘/ÂФæ¶\oº=ƒ«ª•A‹QæéD“ý_:¸‰s“…Ü+†yÕäL%¸’v`JÀÆ]éT™­K'åЭS6ã$*F»W'.Þ+ÞA;fœ‡Ådxg ^g]Ë=§1EÈp÷’¶NÆÞ€ÒŸCâsNÀ<‹Mæš©Òl(=Óæ$Î{:÷’1qâ!&ޅͼپÙ1ðRpBÆöш§dÑÍ3©v§¦JÜÙŸ©q¹$ê!ÜF“³eQ?Å“0ü±„ ³ -N0LîÃͧP¾yW<¢ p&çOjŒy¬ŒÊ{ºõÊÅ.ÍOïD1¡q2/¯Ä+;Hø0·3λìE/²m;ö<8¹kh¸A¥õÆ&b↲8ÐÏÕ¬äY*Wc’ô¸ë¸®Â|CˆÌ–N$ÂÑI¨Ú$·Ô1hÔÛ€”žVHm8“òš1$Håi° ‡Q/H%µÅþŒÄËù äÿµpgD|edrwR .õïDP2áõPGÁ—Û/”˜AÿbHOS¢8î‹%梜ÆzCÕUD:øàªìþ 3¢i+52BM\BÚ¾ÚIé v½ãBcP"é|ôbªÑ î?,ß:.ÐWî -,M¼Û ”ÏÕlDpµn8wx“œhF4ÜâÁ©H¨s>íéºýˆºô§ÂÄ…V€J2à C©)‰ÖMÛ1$Å&©R%âßâ:’nœ„Ô ¡>››ZŸ²;Çþ†ÛÀø±š8Ò‡½/¶Çœ2F²è™­ŠVÝÞ]1ÀWÀiᦠ‰ ³g6ëMµ*çSò5€˜—‹b·=‘$FZ#=¸0~ Ò!Ŭ‚'`óÞâé8•ƒ¹\B¬iÍÐíÌ¢ -bê†ÛÇ]µê¦\½=e¡U|ŽìøŠÝhäW)ùÁjd—ÄüÃŒWí†ÑY¬ûÚÓ”Nb›åÉÄ`j™©Tˆ°*Ÿ¨4< /?'&DÃÝ÷&„´‰BËE„Ø5›¨¬C¹„ u%è9ÝSìd1vÙ°x½Øm·½„¨aÖ?¯üùÓzX|KˆŸ(òuÑÛ®¸ëîæŸ.¯¸î÷ñþ=:¤˜û®ëð¸S·/\^Ô!Æ"¡¬ô·z†-Jy>Âh½Ùuã‘Çmåg|_£Ê9äŒ!ħžö@é­¢Á¬Ïû÷Œo!,”ÁY¦Ž=ÜñÉ ªËëÜ—Ö¹îþûÝÇ×·w1£™³Í›R†ÐkÍádAä2öÑáJ±8ªüL´×¼Ú˜XrUŽŸçx‡Ž»T§eÃUY ‚@VÑ×*9ú/Ê4h€ö6¸E*³Z:·‡à¿5×»|| -dü°þŒ“Žó×°ãiúú¥ˆe¨Ó_g'¦çðxþÅ×x˜ãsüÿM -Ç€Äänå IåÊSxÃ?{Ë· -_ØrÌú3ç:=üâ(x?4Ð.ÓTs¿a†ÙT ÈäFFdAaìk´î}Œ¤s–¶oZ†Ù#DI8aÂà–¿eÀ¢Y­šÖ5E):¶7ähIC9òÓ.«°+kŸzn2aFFŸk¤”ëêP¨Ç8bÐmœ¹4$:h5Çë£:seÂëæ-U1˱ Óa]H¥‡5gSFÖåæ¤.²<¸Á_L1úW½cQ}ÿ¬ÙŠŽugÕM1ÏE+}ëâW1ÃÌ^Ñf;볞Í#WPù@šeÙVÍk)`nƒKÎáKy%-=3Ø¿«‡Gú -½ã:X{@ЛÐLä6¾>Ü>|#KþÈ¿²QÄ5æ‚þ2šè¶;>Àù/Úe1ð¢SŸÅy~š­ e´xDïFý¹ØV ¹iÈ}Û•ë–{ðîQž+-þþa‡Å0š.#è“z!iã{ì6aøfKrY™ci˜ƒo5Øâ!¦ÎjI^ó[¹üáÏ}Á÷ŸÆ4RuÈõ!’G)¨ïë¦Þ¯ODŽe!~íN– -`c¿G‚¡ðWÿúéðÓ0Ð8›eæ` ¤3M9Þ1ÕgþÅf±ÏL:rôÿ^܉endstream -endobj -1356 0 obj << -/Type /Page -/Contents 1357 0 R -/Resources 1355 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1338 0 R ->> endobj -1358 0 obj << -/D [1356 0 R /XYZ 85.0394 794.5015 null] ->> endobj -462 0 obj << -/D [1356 0 R /XYZ 85.0394 167.2075 null] ->> endobj -1359 0 obj << -/D [1356 0 R /XYZ 85.0394 139.8789 null] ->> endobj -1355 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F23 682 0 R /F21 658 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1362 0 obj << -/Length 3030 -/Filter /FlateDecode ->> -stream -xÚµ[Ksã6¾ûW¨ö²rU„àI‚GgâÉ:•ØYsØMr $x̲D*$5Žóë·Á)‚¤@§â­)—@à#ú  Áa -ÿØBE$Jx²ˆIej±Ù_ÐÅghûî‚9̪­ú¨o.¾þ(âEB’ˆG‹‡Ç^_šP­ÙâaûË2"œ\BtùáîöãÍw?ß_]Ærùpsw{¹âŠ.?Þüp¥ïî¯~üñêþrÅ´bËÿºúéáú›"×Ç77·ßbM‚?g:½¿þx}}ûáúò·‡ï/®:[úö2*¬!¿_üò]lÁìï/(‰V‹x „% _ì/¤DI!ÚšÝŧ‹wöZ›W'ýÇ(á"âäbÊ*!‘€&ëÀ«¼¨ŸL viµüñæÁärk¾˜]qØ›¼Æ–¬ÂßOiQå¦þ -±L±ö‡«[|ïP^2½,êbSì°iÓÔ˜´6[×SŽPŠûl»bIL+Éäò¿EîZ¶i"ø±pfNŸMš[߃VŒ‘D)ÞX³68@ÕÁl²_)åT¨xÉê',Y¹ð&+éù&7Sm]j»rÜ}B”çAÁ‰ˆaµÙ¥(0Öƒ­WDë(Z¬DL„U¹$H)mÍîuVäÕˆKŒÄŒE‹(fDqynì´ê£pèÙÄÐw(«PºÛ/+ÿìñu(œ1A˜¤qXz‡šß÷cš0Î}ñŸŒ9HSØšjSf7°¢xœðnÊ¥vƒ04bÈyM¡¥gùÐNàá±`žØX~^`á¾gq‡Ÿ±xÜ/š¼9gùÀ""‡* e Íg¾CÍ(2îÍ*BÎ’MB ‰ &[ [‹:ÓïGSNp*dÞ¡&¤û\~°Høâß“lC®ÅD ¸&XìÙäšÃÏX<î÷í\“ ‰%ãa×w¨Eƽ…¹FXòt<õ*Àµu¦ºLóê–¶!Ý8…à ‹dP~‡šPÀ£› õÑPƒ÷¤[ߎð¬q–q‚R+™x¦×ágŒ÷ûvÆE1‘BŠ°÷;Ôœ"£Þ‚ŒS1l…ša\užqê4RÇìXÌ8¼Á ÒH†¥w¨ ñ>ß žë8öåÿ=¾%ßNV ÙƉ¦’o°‰¢TúnÅ·?cò¸ß¿°–ÂVWƒÎAßw¨Eƽ…Ù&#¢c®gØÖCØÖ¢¬D¡Õ¡Øe›‰Õ‚0lñÃâ;Ô„|Ÿnfz,|>uÛë -ýŸâϯœËOÙþ°s$„1:âþŸn·(|v0ÆÀ‹+ÁhCäá -p•†=\_ÓPkñ3¦û¤8`L+8‚Jˆ¼aw¨9EF½…iʼni2G«*@«5œþ+8q½¤å6Ë?IMápT¤CMhâ,Ž`úfýâÙÀ ‰M£JôùØ&)WžÑvøóÇý¾9¶É(#KÂãСæõ$¡Ô’]“0 û¨ó$ìP8fUqîLJI$,}AájBº?䔌¤ßå»Wð:O–{“æÀ•Ç㟳)ºÁ!¯wº<{åPTqËÊ&•=¦0Æ_ –1¿…ú©mþ³È ŠT,ž¬25€ü¨eºyÊrSµ/§®ý%Û9½1ünL'*È~ðHkî4üö¶I~€ÁG1•~Žåöîáæ㦲#pÖ–0ìØÉÞTUúÙX œ}¶€ö ªû°k¬1[Ws<à¯5ÓbSk ¾î»¬j2J¶œ§{W[™ò‹)€_©¢.·…¯¦ù “C™íS<ÊA´vÚ;[1½¸OAL =1xCrg°)Z3 ê°;VXJóW,Üüä*¶[‡ª2¾çe¨,¦ÉP)Æa×ÅUt:xÓc8‰a+Ùž@mRSÇË+§^QÖXÚ§N½µèrÉ– ºÜ ˜=ÿôÇÓhÖ»˜7¡.¬`"æêMÚ*NZm{>B uÑj¾u58pºiÈä™÷’¶’f„Ñhjs’Ž zÌ «ËczܵÐGlUb2¹«udµžcf,…€(•ììÇ‚kà£McÖÇ5–,Í*·Gz8­‰NkûÐöÚ­˜f¨_±hgËùPSEBÌ„ò*Ê[T“}2›ç•Õx“ª0pFx‡šîoR)0I Ä?`¨‘FܶA87ÙºcÕL<ë°kûê2ÛÔ®'y–¤%„ë†@vXLõiÃL(T¯yþ­ }ìK¦¬Ó̉Ý{,KŒW•Ó&ï‚OÌå Ðbð ˆ–vvîš·àÄ~]¸«›‚SÿPäU‹ëÅþ-Ö%HÀ¡…Ÿ4?3ï`axÖŸ0çç¼Ãœfüþ¡È$!ZQÙBF"½1¡Ò¦XY_æû¤ÚúšUE"©£óie!{Ö…’-:hè°Ïs‡6:™Ë„=B\Ýa‚* { -s‰%c6æ*À§uØÎn7px§rá\DYX| šïqK0"4Tyòßç :¶b <昽<›È… ÃQó4”iñ3Fû};Ób g!ÂÎïPsŠŒz òk JɾõQçùÖ¡N#•åµù\fõøj'Uaù-hB¾O8J¸Ž„¯À{Î3cÈ8F \VÁ˜D”iÏÔàÕÃÏX=î÷/0Z4aïw¨9EF½…§l~žñÆõPƵ¨ÓPUÙz7•k³ç”ó°ø5!ßß' BµP¾ï¹€öÌ^¢“$ \(ó, ^8üŒÍã~ßηˆ«™±ïP3ŠŒ{ óÍÞ+Âz4÷*À·Õlcô¨×7SNRJ"û• ó;ÔŒãÞ”ƒuAÁº4C¹*@¹e%Úo×i5ºML"¢¬‚‚[Є`ÿ8js¤2ö%7—£MvR¶)$‘4ù¬Âü=iˆíÖ®Ê姤ËZHU%æ[ºŽ%mÐÐn;lr¾´MáØwN¯<ö>ÌëaêÛE(3Åý Öoï“Áh{ -ùG¹®ÿ1}¦uwf?=–¢ýVzNþyÉ––óÔ]ªY‰ùjoöEùŠè…íj½K!v×øØjê,k.Üb—:æÞ$m`…iå5Ò(iNî‘ïö:}vNòtà-¼b½sB.¿¤»#¦Xʼn*¶áPTvgm°){ÄÚt»ÍlxOwXß(r¹-3wMO6%ÙT¯É±6êϘ––'Öº€%Ý]šýî½I ³å§b?àƆ*=}ðÑ =ÙnZÒmvÇíôçØøjfcÕúxZ° Ü^”äf¢ËÖ€>§×¯^*•œû@_("§oàÏäßþxÿô?¤ý üÜ.Û܇¶¹TÊ:5æãÓ}å?Vý…endstream -endobj -1361 0 obj << -/Type /Page -/Contents 1362 0 R -/Resources 1360 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1338 0 R -/Annots [ 1365 0 R 1366 0 R 1367 0 R 1368 0 R 1369 0 R 1370 0 R 1371 0 R 1372 0 R 1373 0 R 1374 0 R 1375 0 R 1376 0 R ] ->> endobj -1365 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [284.2769 667.7189 352.9489 679.7785] -/Subtype /Link -/A << /S /GoTo /D (access_control) >> ->> endobj -1366 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [282.0654 636.5559 350.7374 648.6156] -/Subtype /Link -/A << /S /GoTo /D (access_control) >> ->> endobj -1367 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [299.7586 605.393 368.4306 617.4526] -/Subtype /Link -/A << /S /GoTo /D (access_control) >> ->> endobj -1368 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [292.0084 574.23 360.6804 586.2897] -/Subtype /Link -/A << /S /GoTo /D (access_control) >> ->> endobj -1369 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [330.7921 543.0671 399.4641 555.1267] -/Subtype /Link -/A << /S /GoTo /D (dynamic_update_policies) >> ->> endobj -1370 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [401.5962 511.9042 470.2682 523.9638] -/Subtype /Link -/A << /S /GoTo /D (access_control) >> ->> endobj -1371 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [257.6971 346.6843 326.3691 358.744] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> ->> endobj -1372 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [310.7975 315.5214 379.4695 327.581] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> ->> endobj -1373 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [308.6055 284.3584 377.2775 296.4181] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> ->> endobj -1374 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [294.1999 253.1955 362.8719 265.2551] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> ->> endobj -1375 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [303.0862 222.0326 371.7582 234.0922] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> ->> endobj -1376 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [332.9347 190.8696 401.6067 202.9292] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> ->> endobj -1363 0 obj << -/D [1361 0 R /XYZ 56.6929 794.5015 null] ->> endobj -466 0 obj << -/D [1361 0 R /XYZ 56.6929 726.6924 null] ->> endobj -1364 0 obj << -/D [1361 0 R /XYZ 56.6929 700.1172 null] ->> endobj -1360 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F39 863 0 R /F21 658 0 R /F48 885 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1379 0 obj << -/Length 2951 -/Filter /FlateDecode ->> -stream -xÚµ[ÙrÜ6}×WôÛ´ªÒìË£ãÈ¥&vFVj¦*ÎÕÍ–SdO/R”¯Ÿ bi® h¶Ls,o…ÖSСz› ?b››)í¶è:»7jöI!V»à ³|šB»Aš‰ÈmÔ4%#ªÙjý¾m´YÝe‡|—9D. QR|DÈïÆeA€¨®ÿ¾4´YÝ,”§†¨Äð†$¶Æ!lI»Ë`ûØÐjûâŸÛÖ*{Ì]•%S« -{W™ßØYlYß»–OXàßêÓ¾ÊJ(’P‰ié{mÆÝVn^@@±öÊî6°>;vÁžY1¡ºär”dyýŸw7ÈÁžK²üÎ=÷SÜC,k(qpŽB2ÐÆUÆÞÖ@$Øèåi}ì¿àì·UÍd:7‘¥·Ðá‚u¶áîÅ ØíòÊÓ?QÊÝäb¦5ŠœR$… !…Ùåk;+ÎoU9»jĸ‰S÷&7Æ-¦æ³dzâÀ©G¨Ù‰ÓB%&N@u&Îñq·òîìOn’tF‰ˆÑ¢ã6.Q¬§Fœ>.ùPRmêõé1¯âö±nÓ -ÿ{>k '#xy‰¸™‚šIOsÍ4š§=ÝFM{:¢yâN½Q§í¤àˆ‘Ü N Q*LWô¿ëÐai -kß6;•GWëuûÛÁ=:xÞ¶¡´nö"ͯ_v7ye%Xø3´tzmVûzhµtŸ’ñ\|”1Ý985á”FÂ~ OTp‰!pHëOT(ìjÕ°æö!¬”ñ0bjëì®ÌãÌ.ç„+$%Ý?f»=M ˜óªo£àH_° Ì9”ÙS>f€ ÍÊŸ§Ø ³RK&fØÜB%ØPÎÎßWÍR´Í}ü(óÕ0ãA”¶vó´&5¢J‡ÞÀjƒ•îêòç’::ŽÜ´E=5ŒDL)5™æaZ#n4íHóDüŒùÃ~§Ò<ª¯6ì‚ÎÉqˆ¨E†½%Ó<ëš©¶P Ô蘛rœ…°k†ýZZ“ˆQ¥ËB{.µÃÐÖåë¤SõYkš`!„›‹k[“d¡ÇϘ?ì÷õ,ä°wfZ¦Ç!¢fö–d!SÙu IÂhšƒ46êÓqÀAÍ—B&õˆ ¡"]»ÓÑä/"`Ûž¾Vh"Í4=žm›S ð´õƒ^_Ï? -3C0iú=¥™Ça÷FùL"¦Jp/ ¦£Å(ùlåŒ*5¢K—~I¥zÊüEËpÛ¤~´inÅôãà4%:V'ùçñ3öûýb¤ˆJCͨ1è+MB8°2Îg¶‚mT‚„å’OG›Áœk(('XZnDîÞæ)ËLÙ•üuwÖ¿?Ìp¢•RNßæ ‰°ºcbê6/àgŒöû·yàO1çõˆšQdØ[’a—|æ:¯šfXDGhµÉËìe,;a˜aié5"¾Ÿ0Ë®ü¯É³³=ÑB#fðôÝ1ƒ©"(ÓCSÁ,àgLö;É61Übr[™v~DÍi2è-M78„-frbmT‚ne%îNwŸó‘€¯a-Òr#jDp7QÑÖFw%_[‡+UPÒß„¼M“•€š˜ƒòsæ+‹êØä2ì“ð ~¨öÙeãÅÝ·–6ýkË> oY››ªøúS¾o®<ÖÙYd“Ãô¡¸¯²•ÏØpd8ëßýžÎÉ`ê2áö÷»÷?^½ueÛG£3uzxè³»„¦ÍEá‹+/¨Myg›ðžK_ÖîiS>Û|&Á‡Pi|[¸Ë -ê ܾœ•ÉÎJ[Ãp7¦ƒß»-éæ¾Û‘ ×4‰1¬áffQnö ZŽ0l‡c±ÞÓÁÁ‰Ú£cJz Åwˆ,줅ֶüëíÈW pX³aæÿù&!|ô°j®~¡|þásžïÂ'ÞàÌ7ÕÖÞ®zòB…cvóuCq8ÞÐÒöÚwýàj×Y¿oh~7§Ç]¾qtWiŒ{Wpí´ÿÈͱB\ËÜÏ#ÓJ¹÷—8á‰øÆ&·ÀªŸÐŽ,‹®9_ÒMRŽð²Ä3q³š&]D5f÷«§¬,6Åñee#Òþi$ß­Rh•T#¢FôèžD€tX×Qäë¬×“æ ó0”‘ÌÃP -ûô¶)3y˜?cû°ß×/Üö;@p¯HBDÍh2ì-¹p˜ XÏebÚ¨Ê} Ñ:7êÓ~=¼Ì6Ïg”ˆ¨-ºÁìÅ¢§Æס߄1= FpMl¥ {Sä øˇý¾þŒ™½L@ͨ1è+I<*a<“†n¦i@µz’âIp…¤i%"h¨Ew™$HqÖUã/c7¦§ìÕ)a âIØØÈܲ$Å»O[>èõõ¬ƒÓ¼æ&éþ€IëÐï)I9)£s_ FLâ,‡iîËãê5‘N*¤…Ni  ºd£HÛ£sK…¯Ãµ„!}²hlX‚l1IXËØ$×<:iw¿Ï/`C˜1ž˜¤ -ýžÆ™rrÙûG¤Á.ûÓ?pþã -®³´qßa‰45*(eW¬¯¹`Ž¾T¨þ?탄kendstream -endobj -1378 0 obj << -/Type /Page -/Contents 1379 0 R -/Resources 1377 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1392 0 R -/Annots [ 1381 0 R 1382 0 R 1383 0 R 1384 0 R 1385 0 R 1386 0 R 1387 0 R 1388 0 R 1389 0 R 1390 0 R 1391 0 R ] ->> endobj -1381 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [259.4835 736.902 328.1555 748.9617] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> ->> endobj -1382 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [387.5019 437.0578 456.1739 449.1174] -/Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> ->> endobj -1383 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [381.9629 406.178 450.6349 418.2377] -/Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> ->> endobj -1384 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [398.5803 375.2983 467.2523 387.358] -/Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> ->> endobj -1385 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [393.0412 344.4186 461.7132 356.4782] -/Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> ->> endobj -1386 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [255.0796 313.5389 323.7516 325.5985] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> ->> endobj -1387 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [311.5276 282.6591 385.1809 294.7188] -/Subtype /Link -/A << /S /GoTo /D (tuning) >> ->> endobj -1388 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [381.2254 154.1545 454.8788 166.2141] -/Subtype /Link -/A << /S /GoTo /D (tuning) >> ->> endobj -1389 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [335.4973 123.2747 404.1693 135.3344] -/Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> ->> endobj -1390 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [363.1733 92.395 431.8453 104.4547] -/Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> ->> endobj -1391 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [365.365 61.5153 434.037 73.5749] -/Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> ->> endobj -1380 0 obj << -/D [1378 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1377 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F48 885 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1395 0 obj << -/Length 3132 -/Filter /FlateDecode ->> -stream -xÚµZÝsÛ¸÷_¡Gy&b ö)—8©¯=çêø¦ÓÉå‘(‹DêDÊŽnúÇw ‚¤H‘î\:™˜ °\ìÇo?@‘Ïüã3‘ Í,62PŒ«ÙrwÅf°öþŠ;šEM´hSýðpõ§w"ž™ÀDa4{X·xé€iÍg«Oó(ƒkàÀæo>ܽ»}ÿËýëëXÎn?Ü]/BÅæïnÿ~C£÷÷¯úéõýõ‚kÅçoþúú燛{ZŠnïÞÒŒ¡Ë¦÷7ïnîoîÞÜ\~øñêæÁëÒÖ—3Šüvõé3›­@í¯X ŒV³g¸a7&œí®¤’BÔ3Û«Wÿð [«öÑ!ûI¥Ê,š…ÃFæAÌ9ÐÄ’ƒŒ¦1rȇŒ\S¡‘“mµ¨I^®ÓÃ5×óEYËtñëÏA\!á±ö.=Y<Õ€0¢% Å„`º+ÍÇ4%/T7X¥åòí«¬Èi¢X£`gª™8`¡4 ´Ng‚p‡îÑ,?W[D -äk -úÐâáqFƒû–<ý„ú|ÉËFU ñ¹HR„ˆ‚£žðT‚ô¹¡ Aþdð'Ð8Gb‹j‰5îx,ÓÅÏõ¡à ÑvcÂxªi:PŒ², »âü1(j‡§ ¥Î%aZ¸Ž.ƒ1С:Š±¦Ÿ0AŸïËÁ(>\Œ»¢&š£Çk‰‘æ ¡ŽŒ"±Mu‰ž -wÌ‹*[Ÿ.aƒƒ§v¯‰vïø;„U‹îöß' ö”8Û;‚zÂaÇKP vBwš§ŸÐ¹Ï÷ÅPʨĸí=Õ„ }nãhƒÌ„ÒhkQ ­¦ê9j¨î -h%Ǩ‰èN¨@ %ºü7\kcÐ_ñ˘ƒlHwtKo5ý„Ú}¾/ÇœŽ¡:1n~O5%HÛ8曓)̵¨F0WSᎻ,_Òõ!-7‹*Û¥¯È»äÛà´¥®§>m=Ùïš —`‘WÁS èÐí•¢@é8î*aa˃-:°Å‰>Ä$lÉ#®;‚@ÌÓOˆØçÛ -ã ÆUÏÝÐ…Ø3Œû»¦š¤Ïmcʹ2fcmªËóT6¼¿­©ÝYŠÝb•­ñZ 4_¦e¿£ƒxˆ¥ÇS ÈÓ=\@fR*ê -ô}:ºIµÎÏq GœÄºŠ/ý„ ú|/¥<Þ ‘Ð@kÙrÔžjB>·q8Fx™8綈FÀèˆp»¯é \uí‹Ãi¨£S±ݺ¦éoÝíçÂ@)(¯í½¿ìzœ·sp†‰¹içàh!Ð £Ýœ#W¸ÇõÈú¾%ˆÅ¨Í=Ѹ =^ãø‚ì(µäkQ ¬¦²%õ¸­²Å.)+8åõ¦@ÄPŽïÁ¹úÕÎþßfçZœ£ŒcRá—Q¦MÅ‘ê(:³š~Bå>ßg3ÞjÂñ5Ñ„=^ãPc àÑ ¨µ¨F VSY'Y÷üÊX¸Mëâ°Kªþ¡AaŒImLO5 Eq’AêÖqWŒï„¸aeÎ$€#‹99˜@IHK‘Ñ“ƒ£ŸÐ¼Ï÷"ðzmJ2LLc>ðT’ô¹yðÙw!¤ —àV!ð}Ró:=”„f”16{Ê“]¶$~Ù¯’Ê9ñçb›-³Á^†AÄÊÀH.-G÷J]Fö•:\Êã~_ªïÔ¼z.h:Ù‚‡ó¤ÊžRšØ¥Õ¦X•t±×ÇC’WÙ5Ÿç4±Üfi^9* Ùã¦rsm´Oš\y½àæhõ*Ûä j†ºp8÷+E†ü½Èë“ͲÈŽGÛç¥+šýrjÀÞ·9g€€ˆiÿz[câ³#W1M}Ü›!û¤=„Äõ9F·KLÛ°µ­¬y"×(ʸÍįÇ~]× hÚ–˜L–uLȹ°ö 5u€ Á±Åɉâ'ç>ò¥Ò=gª%l—R‡e[U;p¨ùm˜9!.vÂ=š¶tk/g²„ˆƒYÁLB·ÏÙvµL|×îl¡ÁÙü_KlÝÑé=WQªA1º^él²>[ríKkÿNû2€ž¯©=ü”dE#¬(BÎÍÐYÊøV Ç­V ñ ¶õÚ®%tyøÛÍ¿h”~[n’üÑ=j£·€âMqN7gÀuI{ø-Ûr“ø³³4u„P/IÈv–Ä;{¨“¬Yî°•m¶îñÒ=2ûgèp £¤¬ çÊ0WÒñ &]ž’-䊡æGó@o:›Þú;adžßÅÑ«620š×˜`YÃäCB èOu8ŪÞË¡p5q C¿”S™n×U“ÿ PoHh)¸gä^ ­8†lî?D–¨æ¤Š½_#8¨ÀŸY h‹„yÉwËBê Æw̓ß-ã§È¿ˆQ ðÞ×Úðß…ûþLºù†4Z_ú)N R‹p&T¼(ÏIJÿã B5d-áÿ -ÄWøendstream -endobj -1394 0 obj << -/Type /Page -/Contents 1395 0 R -/Resources 1393 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1392 0 R -/Annots [ 1397 0 R 1398 0 R 1399 0 R 1400 0 R 1401 0 R 1402 0 R 1403 0 R 1404 0 R 1405 0 R ] ->> endobj -1397 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [364.6945 737.8938 433.3665 749.9535] -/Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> ->> endobj -1398 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [374.6372 708.0059 443.3092 720.0656] -/Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> ->> endobj -1399 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [292.0276 678.118 360.6996 690.1776] -/Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> ->> endobj -1400 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [319.7036 648.2301 388.3756 660.2897] -/Subtype /Link -/A << /S /GoTo /D (zone_transfers) >> ->> endobj -1401 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [460.1655 618.3422 533.2211 630.4018] -/Subtype /Link -/A << /S /GoTo /D (tuning) >> ->> endobj -1402 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [362.144 588.4542 430.816 600.5139] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> ->> endobj -1403 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [293.1435 558.5663 354.3435 570.626] -/Subtype /Link -/A << /S /GoTo /D (options) >> ->> endobj -1404 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [288.6803 528.6784 357.3523 540.738] -/Subtype /Link -/A << /S /GoTo /D (boolean_options) >> ->> endobj -1405 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [328.5503 498.7905 402.2036 510.8501] -/Subtype /Link -/A << /S /GoTo /D (tuning) >> ->> endobj -1396 0 obj << -/D [1394 0 R /XYZ 56.6929 794.5015 null] ->> endobj -470 0 obj << -/D [1394 0 R /XYZ 56.6929 484.6014 null] ->> endobj -1051 0 obj << -/D [1394 0 R /XYZ 56.6929 459.8194 null] ->> endobj -1406 0 obj << -/D [1394 0 R /XYZ 56.6929 84.3175 null] ->> endobj -1407 0 obj << -/D [1394 0 R /XYZ 56.6929 72.3624 null] ->> endobj -1393 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F39 863 0 R /F53 962 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1410 0 obj << -/Length 3082 -/Filter /FlateDecode ->> -stream -xÚÍZKsãÈ ¾ûWèH§¬^ö‹Üfg<»³µåIdm¥²%µ-f)R+Rãq~}€š¢dÉòij•”l¢Ñ/à%G1üä(³"Ö¹¥¹6–v4_]Ä£{èûîB2Ï80‡\ßN/¾y¯ÓQ.òD%£éÝ`®LÄY&GÓÅ/ÑÛïßümz=¹+G‰¸Û$Ž¾ýpóŽ(9=Þ~¼yÿở&o.SM?|¼!òäúýõäúæíõåXjcL yŠŸ?Þ\Óû?^_þ6ýáâzÚoyx,kÜï¿üpº.b¡óÌŽà%2ÏÕhua¬Öh(ÕÅíÅßû ½~è11™X -©¬µYs¼`Ym2‘Æé‰eãÑXi‘ËØœž‹ÆÅ07i„>˜ -$˜ -cST£¶"U2ß©1¨Q-2­í(µR¨TŒz¬‹•C)ó^és‹\i\™®?ón¼*ºùòr¬SµnUÔ]9oAkIGÓeÙRÏæ2‹¶•£?ÂqÏÃÒÕØ2Q·äþ°8ÊCJ‘[«üz3WÖ÷„‚ízQtnA/¸ˆ.®^TôÚ5üÄy±1oê8˜»¹Ûuû“ÚáI•Di˜ŒzB*æù5Ž•«âà™&‰ ñ:å"Œ4]À‹þªx£gR&çð¢R¡­6þìív¶hVEYŸ aBY¹Ã¾ô˜À¶Xw’à[= -ä2 -Óôð;ƒ‘ß&CàŠ›ºz„dŽÑ(óU!4ÐÍׂ 2K¬ý‚)È“JR+r“ÈsŠµ0Fû£?”Õb^l/ÐQ{…홞‘u*lj÷e .'Éò:ò‡F ü¡úCèa-ò‡Ð ì#'c‰=ö‡ŠœÅ>òévþTT%ûÌ~ãO‘ì㞆ãPϯÃÎŽ™I–¨/˜2Œ8 G›+¡l~îLÄÄ{4WݽЙIP|¯P™';…b)[^¸ØOêB+‰½B‘¾7»—C?¶óEZ¯A|÷EI.àF æAn®{b“ëC4¶Z°<@ºÉŒ>ky„~hy°ß’÷_Þׇ›[\‘ Iˆæ2œyó­·NµËfKækAŒø !v’A@«héyÂG›XX›Ù Æ ä“X³Ì®LÁh}Oce0Œ¾§[c÷¸öF-£à5VMÛeÛº»mµï1àꫪæ=òô΢©y¦ßÝ#QÖns SìH2CÎ/Ó Kpoà]q)Òó,¹AÓ÷Ò‹{ØÅšÈô`î!Ó7Åw½N¢îRF 5gLÚ®æ-„¯ãä*¥T•ÄÙ  ^$ –ñ@˜ò Â:¼f»vóÒ«Ü÷yP=Õwžˆ,NP‘"5š¼È_ŽªÜæ"¶“ŒÉ, R6.Ømç6eû;Ð$G&upÐ!Ú­;홇.ïunôO5m“›ü\¬iaoY.uoIpO¿4Ò„ìqiæQ ¶åª¬Š íG -—›ÎÔóŒñ[žâ>Ïݺ£ºeÑÑì}tÌK7wGV“2Cù©¿ “™÷È©ZN{fn/Uz*ü§%`0Âè\Ÿƒ -WÎÕ”!2/„ŠŽ‡YÌÁ<{¨àËq¨@¨o­9 •Îz?§‡ -¶šºzäE ñ=Ç@3–ʈ<µzß?ƒÕ>×è!ór  4ðµ€²+°üw¥“×\$ÄE:lHé|XéyRñÛFd*‡ ÞJ 'æPŽ2y*ÒÌJ>ôZíüw{õ\ v™i©¾<¤IWÛ¶£–¿¿îyô€ð¡zÿ±…” ¿Ù€ÌY¼o㊂b1p…`- -PyV鎮ÇÚ_ѧBÀÒ©aÒ!רÊyÙ!²®S<¿Îí¦q42îŠÐC‚à ,“îÜ-'“Ûß]ýæöŠˆ·ß0 33Oº¹½~+ˆ6½ÌãÈÏv$ -Y¡àÀ…½( çqW›¸â"D=¯¶‹¾@ñ«RæÍÍ?ñÁ¸äÀ -Ö<²?4ûã3nû*”GJ¬¸a“öà>¹M¿ß#‘[7F>pÊ£›¦Ã“™<ÜT& •hù‰¡¯è:·Zs·× úĈ½ÒÁqæ9sO -B´¡É„Bc?k.H@¯Ã·§ì“$© H+¹’)L&À]G·`ÀŽ¨´[°ÞÎÀ}/–`ß1<éÈÐGVìë‡H¯ÝM1™ðRËâO?saC”›°c9âˆz}—«uåVÀܾ냪ͻ›[Ñ `aç‹÷âCrU|ß{ÀîáDD%ÇQ¯=bCó,ØÞ ×Éú ÛœÆéP-õÌÒ,êòÇkR©Eù掽uMèu´) –5¸†Uð®Tð©Øé?6fÌþïñRJ‰c@›.9¹¦Å¡á7òØâ&.ÎiûÀ#â;yDßCu±éÊù–BP#ûr_¨ `]zµnÚ0AX¿u0²è˜@ˆ…äôxA‰­Ìmè~ æ ^hÚÈReds˜œƒZ˜Ð–÷µW&\OLò öLÎ-ØIÎy´fy¹Í'Ï#éŠõ¼ŒôTлi¯¨j$\ hMØ·<,rœQœèKcr>*Mœ Ò÷àéðNMM„·‘L£¶ÙðÕ1¹ÚV]¹®x¸—•b™ aí6«²#‹…Wº‘psë’Š3 -<çvƒ*ly±žÓ}.Ði,øý½/ä}¨7„ë\±™13‰s?è6eð0¨ÄMÛ ÒÆ­s‡É6JÈD¦#é«–™ÿrI›û5&Ã:ð‡žÆÐOçÅóÞºy×׬,Bê' ‹„\B®½==ý~¸ÎìÄÀà¦åþNøÒÙ[V[¸âcûRQôüç6ðdÞ“¢0‡{²q*4æÏŠ¢ç:³“§³áN8E0J •C„³—#Lw_ÎÀCÕO¿Ãx'¸ÉþbÄe|ýõðˆ}…@BÞ¥”úŸ%“/óò9Xóɲ‡L5Äœé ôe™Bnj!õŽü¡6ÍµÔ b›^‡9ñÙÕv÷bŠÉdÿ+û]³­Ÿ) ÷û:V“¾êŸ"¤Ìߦ礚‘åA™êñ‰Ilô¥—'‘«çŠ @sÉd<+;êøTT[GMvÇÀ°K ÛÐxüÔÈãÍbØE:¡Ù™&xí×zìf?§yFQ; |­bŽIÁ£Æ_2eqZO±V'úœ¢ 3=qZ3ý¿Ëä1C>q–+7†ÛRFãªüÄD/ë4È:µuA.iWQr ôª+H%Då÷Þè¯>­®m]v\½ðëómÕ ñ›Þ9”DÖ›rUlJªž¤>[¡Öì1ÔLA‘|ºs$ô£â +sì$†øUhH^„ؤpøºl¨„]5>Jèÿ~’0oMãe¿l¨Ÿ¸»fèrÊP®â/{ØdQ¶ásôs%Ê!\^Á?÷/6©@?é\ã‡)ò=ó -’µ6†O>t>ÙÀùä;ç“õÎ'?È°°¯ Šº›®™7Qí$„ûËÔmWÔÁï\èÃiŸù?K/ˆ×‰ÖıHU‚>"!*Q†9qѼúÿ»ÿHzt–©Al(C‡s¡ðRû$FÓ™°™ê¹[ÿÓ›endstream -endobj -1409 0 obj << -/Type /Page -/Contents 1410 0 R -/Resources 1408 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1392 0 R -/Annots [ 1414 0 R 1415 0 R ] ->> endobj -1414 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [341.1654 214.5127 414.8187 226.5723] -/Subtype /Link -/A << /S /GoTo /D (the_sortlist_statement) >> ->> endobj -1415 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [434.6742 214.5127 508.3275 226.5723] -/Subtype /Link -/A << /S /GoTo /D (rrset_ordering) >> ->> endobj -1411 0 obj << -/D [1409 0 R /XYZ 85.0394 794.5015 null] ->> endobj -474 0 obj << -/D [1409 0 R /XYZ 85.0394 424.823 null] ->> endobj -1412 0 obj << -/D [1409 0 R /XYZ 85.0394 392.7174 null] ->> endobj -478 0 obj << -/D [1409 0 R /XYZ 85.0394 392.7174 null] ->> endobj -899 0 obj << -/D [1409 0 R /XYZ 85.0394 362.8617 null] ->> endobj -482 0 obj << -/D [1409 0 R /XYZ 85.0394 306.2038 null] ->> endobj -1413 0 obj << -/D [1409 0 R /XYZ 85.0394 283.8925 null] ->> endobj -1416 0 obj << -/D [1409 0 R /XYZ 85.0394 197.5762 null] ->> endobj -1417 0 obj << -/D [1409 0 R /XYZ 85.0394 185.621 null] ->> endobj -1408 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F23 682 0 R /F53 962 0 R /F21 658 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1420 0 obj << -/Length 2921 -/Filter /FlateDecode ->> -stream -xÚÍ[[SÛH~çWøQT…ž¾_vŸ 3`Tewf„-‚*ÆòZ’ýõ{NŸ–-;Ø -ƒ©!©JŸnµÚÝß¹ŸVÄ€Ã_10–Ù ÃÀÍ f0¼ÝáƒÏðìýŽHsöÚI{ÝYo/w~:RnX°Ò.¯;kyƽƒËÑï™eŠí -<ûÏéÉáîž4<;:þ”PÚÈìàçý³ËÃsz`ÓÔ·Ç'ïh$Pspzrtüþãùþ®ÓÙåñé ŸžžîþyùËÎáå|ËÝc ®p¿ÿÝùýO>Áé~ÙáLoÐáL„ ·;Ú(f´RíÈxçbç_ó;Oã«Á¤¹`B€q¦…Xÿ«ô ~5‘R±€û\þÑ=Áð ¯5ã/—ªƒ¼†iïÎfüƒ«…@ïmR«%¶)ÁûáóÞn€¯³¯çu°Ë[ósÚ¾±>øQç­ëO&½² f%ˆþzðX¯²õyî*Ú3rÝi>kÊ|üÝ4)z§äiî®ñúš¯ ÿƒ®‹–›¬×€r2*iÝaSV¨†Ò4Uj£:1ÉoõpS$ë -]±˜‘öÖP/ºÙîK»ÇÜ=>Åñ…Øã–¦4³{€’@"‚íuu7!–TÃœ¸A_rtgÐÆFWy]Ðp]Ìî‹Y”^)¾C†ˆo¶U !À[®åB÷x¯ØÀðzAŠk\€ÔÃ%{ö<ŸQ"Û_Ök¾$þ42.ë&YÜUØFxWdkí°rÊíoË·¶‰²ÖZÛ²u V!3|Y™r?`êÀ³Ÿ«ñ(aœìæ¨ü\6­`mc¸ž7Eƒ°[lAQül›Þ´­„oÓŒhθ1=.ÎÃLpš°=Ùÿ R`e5Do#Ç]Ì„ [‹v_:ƒV»š”È1Œ“ÁÑØÀH´êЇà:¶Åë%ÔaJ™¦ 8¯µ,›#µî·eH zñ’?eÉöµ|ÐAB Ö“"ƒÑ€È‘5—Ø`¶ób:·‘Áe ÈhäУê6(XÔ.a -ÄÁÙG"(YµAFàÀ]‘*" Orêb ýFXÎqáIg˜øŒ@©{ÒíÚ§­2¢Df•ï‰”4‡õ<§s_¼;”‹‡R²P˜GQl$U- Öiª\*[ -ÁÌJÇÖ8 ñcs -Ü=é¶òE²X’î«+g™´!DP¢g¨–=»RѾcÓz¤£WˆÏ:^ûä:oEoŽÆ~ñ2Îdëvz¹¡VÍ œDGë\ü“:´½]h$ê$M‹‘´xçÕ«ëÖRùìê®y,2¬›rœ¬iÒu R¤ÔÅñ{¬‘q¬€õz¯zž‹š¥Ú HÖKׂm¯¸Êü¨ìIýäxšk -ýшPbÕö‚öÇÜß·Á"ðõë²€Ï1%€îu•ˆ&Õg}ŠkeJ©å¦l¬E/ßÀ‹Î)_q±K Éw=¦W ËtÐ$é€"‚+ÌŽ"¸`/kÐyº¯“¢ -'×U,ߪ%|aJ”ué–0 ¼³iê²=^ og߯ø¶A:aYO)QqÍŒòdHQ‡ê;QG÷…Ê !ÕÊ:õHÔÛk7|až<Ã`2ERµËK×lH'z½!MJ÷“˜w{÷§w‰DÃ6®¢Êy¯ópøªhšb–JþЧkÝ(øôµ´Yx.q(åù@ ÄÔÎCØ„P-?˜§ß<én°ÃÇmYÖH¤5Œ{ÛØJHZ­SdYOöÏ.Ï!°åŠg'„;ú›»æ4ºùÖ¦åX‰n<¡’x/‘mµ³ÝW\©7ÌÀ÷ôø+i,sªûgªóñºјÍC5û’.øŠÙ}9l±—ô -ÄéÚXÓñ ²Ý}¿âl Ì?“Rô›’u¼:"t1°>}1¢Ü\^s,HÒP2"@ÑMÑd#•O6DµÅÔè{Ì’X«ua€Xz Gçt¯¸T-¼€h‹÷ɸäÌéb‘Á·¹ŽˆÅv4S7Þ@C[CúÀ‹ªÆñ…Q‰74iÞMü² ¨óóôjJ €Útï]=LÅZ¶ÞCƒûÃÍàHN Þå4&ç³DMÛ=& -:ºÌ´JÕQ|-ëfu½Gœ–¥°ro)XG¢s6è=ÐÙ€:?§–>XÒÍ¿qŠãt–¢ÔÒÒÔÆMí=V/Ÿ5Õ·Ï.“uEc[i O1O1üíë%X -f¥îñ}Â)ÆU2ÒŸ.c«’üjO©ö­üÒ -/¶ËÂK³[Çy‘ÁHEáE‚„©|ƒ)ù;…W¾>á º^­eâ Ò•—êfö0ºÈ졳’ÙÃH 3¡%k•–yD}çëusó :ÓÆç ø‹fâÁAÈ¢uÊÅ ¸!Å`ÑXâg€ZÏCÃØ!3¯÷qF>kˆŠW}:]! Ñæ'H§o’tºÜÃZOPϹ¹Ùì—;GÅ…Q°VžëžÒ¿LiCÙãJðcŸ³¨ -Õ}9ŠÙ£w,M§ `©ÉÙCQL¨C˜á¥$‚ -N@|BÛŸÆ–«§ù+L)ì† -içÈÏCËÅr,/3åèó÷Õ/–ù 7aøÑ/òÿ+ÜŸò~MÒŸ>‘V˜ âZˆ˜³ßýÁ™TV¶³:[ÿ??2Dendstream -endobj -1419 0 obj << -/Type /Page -/Contents 1420 0 R -/Resources 1418 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1392 0 R ->> endobj -1421 0 obj << -/D [1419 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1422 0 obj << -/D [1419 0 R /XYZ 56.6929 695.8713 null] ->> endobj -1423 0 obj << -/D [1419 0 R /XYZ 56.6929 683.9162 null] ->> endobj -1418 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F47 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1426 0 obj << -/Length 3296 -/Filter /FlateDecode ->> -stream -xÚÍ]sÛÆñ]¿‚of$‡;|\óäÈRÌÔ‘]‰i2Mò(YùõݽÝAŠÝZžz4#ìí}-ö{£þÄ(ü@j5J´ò£@D£Ùâ$Íaî‡ÁkÎÝ¢óáªï''ß^Éd¤}‡ñhr78+õƒ4£Iþ›wñæÕûÉåÍéy^쟞Gqà}?¾~MM‹w×Wã~¾yuš(o2~wMè›Ë«Ë›Ëë‹ËÓs!UÂ’ø×»ëKZt5~{yúÇäÇ“ËIOòðµD ‘Þ?O~û#åðv?ž¾Ôi4z€Aà ­ÃÑâDEÒ””SŸÜžü£?p0k·îc“ -„/ÂHŽÎ£ÀWB¾•nàVCék¤sûRxéÄWQ‚œWÊt°á|(œJú©”Ñ(‰´K˜CÖß¼?=CàÚ¸¹kW‹¬«ÚX–„ž{.‹•iCƒÕ©H½Â,QMë‚°éu%còv‘U HA&‰wùŽÀ}ç(Q¢|EH¸@ ´dT‹¢é²wˆÀ{]˜Ùªš9 ¯jXÒW‘‚ˆwÄ©@žI‡£!>µR¥¾-»/)­V¦AxLZ^+š¤us;þáô\E±ô.ZàX…‚Q©ð^_ßÞ^^L+; =SÍ›¬[“¸•g]üA ŒSÈ`|"ƒ÷ˆˆŒTR=ÃôÁÛ¼ÓáÍÓ8úoäèvdzœ*_ -•c:¼x*DLL?•‰7A3IAÛuWœw¥ål»ž— ‘2ò¦U“WÍ1Ûek:C`WfAyKϦeD™ÝnQQñÖö¡9l-yE‚Á Jjï¡Ê ‚2šÈ`¤¯)º‡võ§òœ­×!u¦¹±½4IA5ÈLƒméŽA™þy‚ü²º‡+¥dœD¾V1±Åšc”j=0G06G‚wlQÎþÙ [B¶‚©{íªšWMVV:þ;ô–ûäeÍð `´7}¤vˆÂ³Õû‰3KáM×-0]U×´fíÑÒk7œú{üG]¶!b^DPÖð¢PKñŒÖ ÄñRZC.G½¤CHw$~DkTùN@åöÝ+Ð~cœƒíU¿AXØ+61ÔtÙªãP|GÏŒ–üÕ6ÅÎĺ+AkºÇS!„gãî–“Ç5ÇóNž ^5zF$ƒwýŠ#k>8ëcyP,b_$åA·7§QäýóÆXm'C2N¼lÚZC‰Sï¡°vЇ½´{O‹S¬î« -Gh)5‡™ÿËßoÙ¢Ð:Ž%Aa’†ÏˆjÀƒ—•£õÓt;Š*JS?N¤<"ªH‡~iJ‚&¿NPLà¼&§:ôŠ1„cbkŸ¹ùÔ\òYÒ÷yïüE5>ŠÐ{”‹)ܨÔ)p³ö-eÂÈ);‚e5+ŒYïÉz`¯÷¸ÂéýÙa7k<ÎFŽ ·?MÞŸŠP{g4æD WЃj ‚Íz¹lW“í›Êtàöf˜¼”à†5_±ËŠ <¤ cŒ ¸ÕJY^þF˜{D‰wS,9µÃLŽ½V*mxÀç¯>.Ehã§`°›&ÞÉ' ŸU¡ ßö¥„²©¹ñ¸' ’"þÛå±öeBƒëÉvñÿ¤ ƒØOC€Ü…„}ѹ»…Ò¤B!»?› ïÚºn°ê>{¥†mPz¡S×á–Y¡ˆiÝÖ ¡öC „Ð:›NôžÔ´”³ÎŠ½þ•Ô¥µ8˜­W4lºú‘P÷Y]í(Iç^rÑ¿íêHo -œU˜€Ëÿ?I4ø"ñNÅ ¯áÑúS%p”šŒ¯¡ö”Q¼‘ü¸éŠ˜òa ÞóRqë ”\J†iqŒ £˜{…àô4x¯‹2k 0ál“C¢öö¶!í"Øví¬­ 3ãÚ¸³^ “ºŽ&~Oa5¤¡,ªü\è$0ϸÂ6«ñBRõ닪²]Ê>`Ñx¹^-[Sà+@ýgk1DÓ{žè7f_m6]WuwÞÇIˆÄÅʙݰ±, GÛŸûg䤲>±†üœe`»]Ž=N”5‘‚×>£“aÅm©c?Ò2>¦“!wñ¥ß@.åDâ½)€Q927UPè¢j¦;Húyq_Ôí’Ê´ÔÖîø¥üÆøžTùßØï9Øž{JÛ`S! -SoŒµJ5Ö ¡ÓIÄt-aLÙ{n»p«àyWðÀÜ}¶ªÚ5ŸdÍNˆ¬ +°·1ÍL¯bOS> fåfçÜH[:ÄrU¡w3;½ÓÒ´ð ‚ %÷R -öÕ¤° ê¹OL+ dõ¶øŸM+ðn-ùŒ .¼äöè:l²#I‘`ò®+F-–u5«:ÛHJ½U -Èû ‡çE¨U¶/Š‡DÏWèq´´m:Ümç[on|®Z>¹ø˜Áµ߹ȚÇ}ÊHt£ ’#DeJ#{ïªÉjë©a‰#¨#[(hõ¶€-3SÆÀ‚Ô[Ï\Ïôðþ’·n^B±:­%k1 g%•2)öæøxk8òŽM›ÛT\ e%²ÇÓXQÃY 8 Ÿ¡e¥!Ô&/S®§6š>ZO«Ë"Ëm°QÐ=.-ÁJRÂÈðdò»´ŽëAÜ^ñM3üd@-:S`A†õ"‘çÎ"F y´]K†ß‘ö‘ôm‰»yMŸýðß+¦g«ZÄWëÌN†Ù…KT]nÛÏíOr§q™«qüž¼ÔWZ…{jEF’Àž›Uá„À=ÂØ_ÓÀšÌf¼ºZðòºZT!­'†gÙ>ð\K·P`A ÊdzŒ×Nù˜Å’O©š­›fÙ¬,@¿bH &¥#ƒnÝ#ƒ¼µ]¬DÐ× -™€/—h?ˆ³±QÜ}„ðq_ЂˆÎ:¾ÃO€ëxŽÏjÃG!'rBBü­QëQÃìÔ]LÜu2¼cQ–,á-[tMŽvÔÈ=†D§heIÃòôrâp$7Í¢B6ØÇ·Äiî°kµ9#ËÁÏ€´¾J³wÀ­[ôP}øÝ#ßÅ:ªÌÁV~)«ý†b€ùh©@ª AV%˜ôäl2%±á ^Tnà ùgSí<*<þ"rÛþ8É.«)¥¸OÎaÇ(XRP vUÁ+­EÂÓU3{@±²‰I3ãDŬçóÂpfBÖOPaxªáÅe»®9ñ™ò4%8¡ 2¡Çõ,Å®ƒ~.}äSHŽÃ-à))‡Ç~äó©6æ½=ÀÛ7ó½>œ 6ÔLò»…]bm‚±M¥î2ÍšÀ“MÄÓ|Mß}¹Ѫ9ÏÃÄ &õ@pT5½+Ÿ=*_¯8z“(÷HˆÎ=ÛI×0u凫»ŒëM³Ù^ÆY]å<7 -Û.÷Y½~ÒêØöátùaÿÆ›BTÞ¹pˆ­ B(I6åé1Ç \gcuL ³lµª¨Œä´6¦~%ε‹).Ÿ"úS»zäk:d¬ÛØðI}«va&aü}ïÛÃΨ]¾§%þñÏõ '³î%á2òßÃP-[J¼Þ–NK™Kîws|.Å Ù 0›öµæ¦øãá‡öwp¿W»µ­ˆ± ý¸\ÆôŪ Û(‚§•'Úä_ðÏ#ð}t8`v¿YtHíÛk -M¸ Œ]N¨ù{™vÚ¢1»š}(:¾ÁÒ¥ÃÍ,¼>­6Ж—öh±M×Ú¬9=L¤%c”Õ¼´[cí¹BÖ˜Ó€é‡Øø@&8ì9« qÅøŒœ³&ƒ¶`[~º4©Æ°Ÿ>ˆÚ¶¤]fnhÄL¸¯òÝK©EœØ/êlŸsDïà÷ÏGü‘ÁKÕÙŠÖy½ó\hCœM6à¹ÈÀ‹ñzL¼,]8xÈ(€Øöqwß0ôW Œ#îR& \%¦¼|š ðÄä=Ž-hCeö ÊmÛø‰¼Eklç'e z )ðÀû­]’΀±?ÃT]5ÔI‚l¤†ŒŒ~œHkÕ¬K‚m¸Ô8¸ÄÖ÷».@® y\œÈ\c­yÎãÊþËu,Ù÷¹_†€7#zsHÍÎ,מ{wÚb1ÏdtŽ;QB\œÛ` üPuå`LÖYóÙÇ.:¸¹â# ã[/v ÁÝŽÖU ;NÐ- \ë¦ByR°µßSw…¼üý©%ÐÉj׳s)Î1¶^çΩ÷?ÓปgÓªÞü6àÀ¯ eä+úιÛWFGáŸú ÉͯDUâË4=ð[›¾‘ÁD!Ë“d—òH¦~”†ÉÒÿ³Ÿk#endstream -endobj -1425 0 obj << -/Type /Page -/Contents 1426 0 R -/Resources 1424 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1392 0 R ->> endobj -1427 0 obj << -/D [1425 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1428 0 obj << -/D [1425 0 R /XYZ 85.0394 492.6335 null] ->> endobj -1429 0 obj << -/D [1425 0 R /XYZ 85.0394 480.6783 null] ->> endobj -486 0 obj << -/D [1425 0 R /XYZ 85.0394 173.0867 null] ->> endobj -1430 0 obj << -/D [1425 0 R /XYZ 85.0394 147.5597 null] ->> endobj -1424 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F47 879 0 R /F39 863 0 R /F21 658 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1433 0 obj << -/Length 2902 -/Filter /FlateDecode ->> -stream -xÚÍZÝsÛ6÷_¡Gz&Æ${s§U§urŠ{“¹¦”D[¼J¤N¤ìø¿¿]ì‚¢$Êq÷.ñLˆÅb÷‡Åb±Åð'GI*R§Ü(sF$±LF³ÕY<ºƒ¾ïÏ$Ó\¢‹>Õw7g{«³‘.Uéèæ¶ÇËŠØZ9º™ÿ¥B‹sàGÿzw}u~¡’8z;þ JR›DE¯¸|s5¡Ž”I¿_¿¡GŸ×ï®ßŽ¿ÿeryž™èfüîšš'Wo¯&Wׯ¯Î»ùñìꦹ¯–Œ5ÊûŸ³_‹GsÐîdzXhg“ÑTb!S£Õ™I´HŒÖ¡eyöáìÃ^¯:“Œ…Ò©ÀIé!œ'R ]ˆÓÛz¹¬ÊêîüB§YÔ. -*ÔU±A­_Aݥѷ/˦= ½¹ùé7=® ¦Ï«9µÍ–yÓ0ÏÛƒ‘“‰ ÂëQ7™QiÛWU±ª«rÖà -R -—$Ê«4/>űª -à£`Qói}R©Ts•J”™zˆ©*ê(«¶¸Í}ã´¸­7çÒFuúù±ƒdÃNU,稇‘ј¹Ð¨yàÓÖÔœß×ej5-ï¶eûÈbðÀu¾i`1X\?Í€†¤†6\,î ñÕ¼“*ó²ùw š![mQù!*V½ñTÙnÒ ¤uo2¬%„!r[>ä\ÁZ%†}Cã“h|Ý—zO/ÙÓ 6-îóå¶h¨¼*õm[T\\•m[ðÈ[OT¯¨V|ÎWëe`PòRÈ7´1mÚ&ð¥/ȸÁÕ‘RF¢“5N+ëe%­R1ƒzë 3nçmN¥zCßÉò"øß%55Ŭ-ëŠénéÛÆ“ }wzC宼/xÀ¶ñÛ‹¿Wõò˜ß'XÁÊ•³|ÙxÍrU›{!ììÖËÞG Õ:€#c?²ÙƒüÕxܪ¼[´TlõÃ×É„ÑŸå›M–2,WÎ,Š¦ÉïxDÞüýÐ÷‚¿Rƒ«LÓXdöYÎWišªdßùþ¹QAŽ†'% q1ðâb±Ïê¢Óé"5VX•ÙÝèz®]Æ¿3£4QÂHcüšŒ?ŒÅÕ›_`¦ÚÆÑÏÏ/2©HÆÐÇÑ?¯®¯&—¢#;Ô¤ÎÐÞÜ_§"&¸Ûõ/‰N…ÍÀR*Ö¥¨L,Lâèô;†äòcÈiwÊŒ=y¡eŠº ¯7dg¯èC!£RتŒŠOcÒ›î…0ù#§ÂË[­Ìœ°âT0 -ÄϤzúX0 ¼ÖÖ°#*›§ÝOçaz>­Ø9J\•Ã†/5̘>Ñï fᘲ©bòW§Ü;Ýyy‹RÜrÞ¡j»tûZà.»öÐ+®o"¤ŒÓ.¿©Î!rózS6³mÓP&¡7%ž•Þ¹³z3odƒ;Ü)”ñ98Í‹f¶)§þˆÃ¬gд۹]loŠÍ}±á1Mۥʰ¯¬è¢Sús¦Ë»±eÁM”Ô™ì¥Ö§Ô/‡d€û£éXÈbðÙçSÒ¯ƒö‰¶¶œmálàzYøÔ =|Zî«à‡Në-®—Ž—bwAÏ#*}Š“˜ã Ï’…Ø6Û|¹¤ìÒ+JŽM‰5 ®¹@é´Wƒ‰2PYBìS7-Ì ÁÍ—qíMé³^»€[.ÔŒÁ6´‹²úšÓ˜ƒ¥†7ÁwQ,×Ìæ±i‹UÃ".­ÊŠ‡?,Š0n1˜°ðCCðV}¥ãæ‚ ?5v AíMÉ/ ”üòjŠõ( º¤Žy±;Ý|$š-I}ÚKÍ–¨˜•>ÁÍ3øÅÔœ?‰‚”ôYoÊÚgR©±š‡Þ¡Ì}0“qðìO’Úz¼LÚ׳¡þ6öòïX%žiùC“מŠ=x¶!Ú¼…å^·Åm:“ÁLû³à-6ÙÀþ ×̶#€N†§ÑØ;Ççt³NÞb½—’·!õù -Ã>̲ÿ%‚’‡ÏÀ'K²ÑЮWËÄîÍoÁË0ãàÃýÜ-éÓy7·C~è5¢“Øv>|]Ws~ÇpŠÕ°&"Б®á€jÓR5¿££ÐâÎ]2ÍmN%¸då³ßy\ÍßÀ²*>3% rçvuB³þFÆÑû΄p­SCäózH;rÇàÔ袩”#~¤¦|ÚÔËm[PmUäeäæ“R5ƒ¤¼ -üt×Õ’ ˆxk “zÅ‘ -øm¨èÏ÷ŽUÏI`'åîýü~YŽ·×½òfSŠ7[bv›11Á{'ÝûýNIø• +8“½Oô­5}ÞÛ'ô{/ ‹¥i˜–v#ùr–iÜRìbúϾÚÃ-…¯Õ¶i"oà:“2' `šœp›°"NR{`ÒMSÏʼ{U:ºc:>lóþ’#0~ ¹„x@3Ù¾+__þ|µ$aðºõ"ºYY¶÷Ü’ÒVMw[Š´n¸ó28Èo©ÑMxE²üêi£iíOI|v¥† XjUÄÙª®@_o‚GÄ<9??¢ê‹’ñ (toȧ‡Çg•Ñ³í€Õ²§p±7ü–wU½3¸PDã -ŽíÜ;ñ8¼8Y‘‹˜ìY 5‘×q<ÞÅ;׋åuï˜ôRT<*ÌæõwVmk|˜íÍ3à‚¦ïe~•žõ w”Ú€ xšY;’Ú -›jù¬Ÿ(ÀÅ,ÉdöÇ.‰Ã£þŠÔFÐéBªT¸8sÃ7÷,nPõXgã$fõÊ¿“A ‡i ­bǹÆØúס,fÇ%ö†ÞêÜêA¾$_§Â(3­^¯ 9Âå/9ùdCÙ&ØX‘h~2;DÇt´GG=éFý™¿a|b%œ;õ„¶Ã'NEbù íÕÇG`(³]‹zs÷:½y_ù‚è8 ç¯2Oo68¤SEIÄãÍ7Ý~³>Yo½Aù<¢<‰Ooæo×x2'b{ê-ÀcPóóÚÀöÓï €ÔI€zs¿@ÏÏ)þÇ…_›€7Z¨$I‡~ ¾häÏýÝÝî·‡&ÚÚIIN^ª‘Nð"Ù£Ÿ†_貞ðÿd`®endstream -endobj -1432 0 obj << -/Type /Page -/Contents 1433 0 R -/Resources 1431 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1392 0 R ->> endobj -1434 0 obj << -/D [1432 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1435 0 obj << -/D [1432 0 R /XYZ 56.6929 673.1367 null] ->> endobj -1436 0 obj << -/D [1432 0 R /XYZ 56.6929 661.1815 null] ->> endobj -1437 0 obj << -/D [1432 0 R /XYZ 56.6929 493.0122 null] ->> endobj -1438 0 obj << -/D [1432 0 R /XYZ 56.6929 481.057 null] ->> endobj -490 0 obj << -/D [1432 0 R /XYZ 56.6929 393.3436 null] ->> endobj -1439 0 obj << -/D [1432 0 R /XYZ 56.6929 369.004 null] ->> endobj -1440 0 obj << -/D [1432 0 R /XYZ 56.6929 151.2167 null] ->> endobj -1441 0 obj << -/D [1432 0 R /XYZ 56.6929 139.2615 null] ->> endobj -1431 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F39 863 0 R /F21 658 0 R /F47 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1444 0 obj << -/Length 2798 -/Filter /FlateDecode ->> -stream -xÚÍZÝsÛ¸÷_¡‡>P3 ö-Û©o;UtÓÎåò@K°Å)E*"'ý뻋HJ¦ì\“Îu2B‹ÅXìÇo‹ ‡bb4ã*‹'i3Í…ž,7g|r}¯Ï„癦ÙëçÅÙO—*d,Kd2YÜ dÆ“ÅêCôêo/ß-.æÓ™Ô¯n®/¯^ÿ:9MãhqusMäùÅåÅüâúÕÅt&T¬%P^Äo7×ÄtyõæbúqñËÙÅ¢[òp[‚+\麟ùd»ûåŒ3•=y€œ‰,““ÍY¬Ó±RRž½?û{'pÐ놎©I*ÁR­&33“€ˆÓ#fÅfd–‚RuÆ%U§ThŽ(5,É2í”ú6/Jؼ”ÑÊ–Åg»ûŠ¿DôP”ž~ké›·­Ýl[»¢Ÿmš‚sËS-@II CáÎì—|³--[Öq°¨,eFóÄÈ«Õ˜ÔŒqØÚ@¨|F*¨ÄH?äw®yQùmT~‡õn* ìz½âÒL˜tš -P¼í -Á2­¥“SÜ‘T¶h×vG?jOl×uc©Ùì—KkW/è×@±È6ª·$cZ‰áÙm¾ü×~ËêÝý˜Ú$:zö‡Òoý -ºÃb~°˜t¹ûJÀL‚¦™€sbÐ%øç§ïïœK[®èGÑWN?•œÝ­ïªZ{OO"wpvKŸÆVd“Ž‹ì«¢m†3'Qc—uµjÜ‘Ð9¦L¢í®Ø仢üê4– À-ö'ʯ ©K8׆Hk[Q 6éÙ–ùÒmšóyáFÅÆ« H Uj¬l³Ü·ÖKZ×Ô(kwÐʃ ×Ouk­íŽLÛ÷9·Y×û²ã9ÜØUÑ,sï+\­àáPytW—eýЙD»¦9|oûuë–?ðÚÚb·ø±ÜïègÕ–Þ#œ²]‹Î“ðèßuåG¡™€³Çf!ÀütOÅY"Lö-ÑYeŠ¥<=ŠÎÿݨ°Pd Lòôô -hY¾FŠšu›ši#d@9Î…L)¥'‰” ”¤Ü¾¿y9AŠáäâ¨ÌçEjèmÊ+;>©h(RÈ)Tè‰!ÞÝç­wf26oΈ1-ÖaxZë¹.êC“FƒK4YÛSy3×:ªCTÕà¯;ï[à!¾éΣ YÕ3ˆ³ëÙª†pY ýõ?ÏoÞ¾¼ºÆ°NTï­Ûºjl3føw´Ú Û×zÏÆœ¿s…Mþ¥Øì=7»à!»zuñ¡º¸W-}À%wM0q8Â5.ú‘™kn˜L9Ä÷š³d…PƒeOâšG"ÈÓv« 3&Íž±[àe±Ì(÷üÅ…‹XEzV‰¦d -‘‰ÎpIjÅμ¥oKÜ[ê-Q09BCq[G¨>Œ•ÂÀÈ~z“6~Ö13öÑÓÞåû²= -~QØÌ=†}QïÛƒ˜×lí²Àe.5¶}Â0ÿ¾SüßÀÙ,M“ç Cs¦EF-(Ëa™LS]€G!^ÓÔ)µOˆÐXçÎí •Ó‡ô‡¿úRP“Ú#j÷~Õç|îà!Ä¡uføX£ÝéG9¶‚ïƒ;î÷âGH¯¡Q nÌ>ú‹)çó=YU+¬ª“Dÿ‰Uu8©o‡4aó'A¨†¥ð³¿yÎÆ@¨Âª:ƒÌ窓›ùÕë«ëéL Å£C‡èâø((Îö};èAY`ø‘Jì”êD>§ض‚ðF‘a:3)¨õ’@œs¾€»ºÞÏžF¬ÃY”rþokÆbÀ–OV jM3Ž·°’q#¿iÕ±,Ët|ÒeŒb&1Äeˆ#vo5"á,ƒT=„ÓŒ˜q°pŽ:IÈc®ÈF'± [y¦• —Ö7`,€­á=zu™±Àã6)‹•t…íäÓD0gP:¦AÛíµ×#ütµ‘“óv4l*ž %»M- Ž*$0Q)xÚݹm%0V¢EØVÄ7”Ç玒ŽGEÕ#H×°Sp+r Ï’ï|×vQ À£í®ž -}.(É# «QÞÐíIá½aÅÊåaÞ¨+W‚@ÛR¦ÔB/=}UÓ·ª[ß°K-€šf°¦" ‡ŠÀ"MA -ua-عlVQ{ßä÷·ƒi.¦›ç~6R4ú…º¤‡²s^jöÁ·´ÌÛ@u¥µiRHÝ•…Ú—…7ýíÆoÝ5þeQúÖy±£Ë¼SïJ T›‰Ü»Õ%hzGm/ -,À¡;P >8ìß4Ëfn¹ÝZúûq@7J†§ä1áçëÛnUËr¿²Ý…à î*°ô4cÁôÀF0˜J¡=ß‹QmŒPAÐÕõ«7¿ž_ŒÕÛàC©ì%‘¾ÂCôH 2iéÞ>Nü¹€Ò ßøG÷ùäYüö­JÐ{kœ2eN½uc~Q¸ø4{„Ê”aÚÈtdéÿŽ&bendstream -endobj -1443 0 obj << -/Type /Page -/Contents 1444 0 R -/Resources 1442 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1453 0 R ->> endobj -1445 0 obj << -/D [1443 0 R /XYZ 85.0394 794.5015 null] ->> endobj -494 0 obj << -/D [1443 0 R /XYZ 85.0394 711.7496 null] ->> endobj -1446 0 obj << -/D [1443 0 R /XYZ 85.0394 684.4451 null] ->> endobj -1447 0 obj << -/D [1443 0 R /XYZ 85.0394 642.9726 null] ->> endobj -1448 0 obj << -/D [1443 0 R /XYZ 85.0394 631.0174 null] ->> endobj -498 0 obj << -/D [1443 0 R /XYZ 85.0394 462.3028 null] ->> endobj -1449 0 obj << -/D [1443 0 R /XYZ 85.0394 432.3134 null] ->> endobj -1450 0 obj << -/D [1443 0 R /XYZ 85.0394 343.0202 null] ->> endobj -1451 0 obj << -/D [1443 0 R /XYZ 85.0394 331.065 null] ->> endobj -502 0 obj << -/D [1443 0 R /XYZ 85.0394 138.4884 null] ->> endobj -1452 0 obj << -/D [1443 0 R /XYZ 85.0394 114.5262 null] ->> endobj -1442 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F39 863 0 R /F21 658 0 R /F47 879 0 R /F62 995 0 R /F63 998 0 R >> -/XObject << /Im2 984 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1456 0 obj << -/Length 2275 -/Filter /FlateDecode ->> -stream -xÚ½YÝo7÷_¡?¬€Šáç~Ū-ç\Ør*«ÍáÒ<¬%Ê^@Ú•µ«8¾¿þ†rŵ6‰{¹Â9;œÎüfH³…l bg<$™$Š25XlNèàÖÞž0Ç3òL£ëçùÉ› ‘ 2’Å<ÌW¬”Ð4eƒùòCA† Fÿ¾™N†#®htqyRñèìŸãwóÉ bÇúóåôg2În¦—o›‡‰Œæ—7SœžM.&³Éôl2ü8ÿåd2oUÍbT}O>|¤ƒ%X÷Ë %"KÕà ~P²Œ6'R ¢¤~f}r{òk+0XµŸöº‰QÂEÌ{üÄYŸŸTFbÁEë'E¸…RÍ4Zxz3»|{éÌ=/vzÑŸ´1„Š@( ¡ K­¸Ûç²É?ÿèÃÝ…"ŠÅ ->0|^¾åS¡@™Á8w|Ëj“å¨Ì7}›Ç)áR2Çû¡Gša‰ßtQm6ºlzIFR)¼ =êXƒ—á$F ÂŒƒ“ìà/íà2q"kÝÔÆ™,jÐÅÌ™fhYûÜrÞ õT¬×HÝiäÊ·[].õÒqV8æå3ûòqŸ¯‹?(åÈãݥ‘^Tv\Ö悉èýƒvûæøåªÒm_8-]m]5ySFŒ‘L)n-BѹوÉÈ#X‡ nÚˆƒs·\l¶ëbQ4=fL‘¤Y_€°QÆ „ŸAdCB™¦ŽÁ˜„OGä`†õ¥:¢HÏ)+"Uæã³Ì\ìwè…²ÏRÅIš¤IŸ¡Ý - EOÊ0Œ»«ÖíèhTöØ„&å:çVoõ"ˆŠG£‘q¬lœ–dñ·•í¤mnÍ¿ßÛtÃ]Vnô¿kËÊMäwuµÞ7šôœ(™ÆŒ8Ì&qÒÑftéÏ9—&äV„A&´ Âû÷ï!ú ÈMÇצ¤@_/§£ÛÉìw(ýàìçuÖûâS¾nmƒS8ÖùÅ·°=™ük|ýîjBÎn® *íT‰»štÏDK“,”Î ürzvõÛùäÿŽáÒƒßàvˆƒãWøªÁÔ5ÆÄk¼Ú÷Þ/ä€fi¬T àÖæ>qÎ\%ÿKA' F¨äI·ÌE -(g‰$ÚÚ𯺮qó“xkÝ. bUI™¾Êe,má#w;Øü‚­m~Á率Õr±Þ#jžÒâF^v9oübá„o+øÄG—«žÀèÖ‹‹oŠ,Ä4B*Iª²§ñ‘Ý*àHàrlOEóÐ[hàE U¯…4¨àm¶;¼ÌÝ `Á^ÿ€te*àSQë¨Zâë%%pú‰ü³:yã÷`3q Ÿ$Цд£ -2õ'ci Wé£@f%íJÛ£íz ç“Þ9.둃œR£L˜|ÆÙ‡Üí·ÝБ}Úƒ71#I›ü]¼á/ñFJWU¹Ð±QP@R读ÒCîœy§µ«ˆ¾Å!_jó%O «WõùŒ“,S²¿ÏÎá<ξ, ¿£ Ë‘þ‹®¨ÃµI*&Šw{ƒÖ|(íj‹ë [Œ. ƒNÅÐ[›è¤DAè¼{õŠEsøŸGG I@H'ÁÒZ3xÜÌ2Lmm=øÀN¼¹ÜðÁy £¼àQ(ÙŠðžà‚ý3i ѦÙÅÙšØ,‚+™*¥äÔ¸„ÙŒ”F“ 6̬ X¦"Ì3Q?Tûõ9Mƒnævºnªv³ùª¶ ¹ø†‚“X’ê¿oÜÜB'XƒØï˜,¤)¡^ -À”*ºr€£»ŒmM0“.ÌXØ»º*‘çéAÛÞÝN¢ €8¸~x00ìV˜÷Ðùº®Üþ.ï¼rÝ«ƒs“i‚„r·n‘(sëpÑvë5NÞ¤"U­põ6îÛ¹­QfrjØ/´Ÿ*ëÏm¯—(;wì9K=àE>êë›Â¸‡'i´ÚU¤l0ÂÓHæŽÉÈÒy³ßé!ìé-ÔÁhì8B ý5O³tæê÷¥¿•Áüèðfð}àÔE¡àõÕè²I¢Tt§â¨;ϯþº×#ü¸÷ãPd{[[êU¾_7£¦YÿÍO d œvB_<&ÜÚ#ó]NGü1*Èáö¿2UH_ïYêª(É• ? êý] ,í}ù4€“¶e²Ô.™KÛM™ýæWæý@Bˆÿn¶Î×E°b(æ®}N“­Þ˜Nn9ÈË{ ÔÜaá¢-b™àL Š•æ½¢÷òÓy€išù¨}ŸšÜ|1¥0ÓaÏ TŽ¼¼š¤É!´c؇§Ã뼶¸o_ ß^L>7º¬O~4o0Acxúv2ÌÆÆ¥óÉ_—]Žƒ9†þ -_⃳Y?Ô}ý')å¯MŽþ c ÉOÿì•m×}Á].EY÷¯{'•ÛÇžæyë Üõ(á¼!ÿÿ–—EA3hIJq}|`]|â±±œ+{@Ê6Ö<Ž®‰m4Îç8ÔzWh÷‘MT‘³®ö–°-48Æ #ï>æãrýŒÔ® À²²±¿Wx#Û /ÜØgòÎ}jŸa, qr(ýæµ½/÷GÞê’|ÓU’°˜ù#X˜ÍDc—'ÎgfÆøÌŒ:‡éé{]¯ÍZ3﹆²M ,ùÉ,âäã¾@¢³O¼ÝVæe%îïxÃeø1\³j×LyC:Ö/õZßç¦SiA®^슻¯€K™dZã+¬@:>?Ÿ‘ñìqæØËóþg®¾÷pû¤—}h'8 äŽI_-p'8wOalĦ·8âëØiû<Öײ‰b> endobj -1457 0 obj << -/D [1455 0 R /XYZ 56.6929 794.5015 null] ->> endobj -506 0 obj << -/D [1455 0 R /XYZ 56.6929 769.5949 null] ->> endobj -1458 0 obj << -/D [1455 0 R /XYZ 56.6929 751.4464 null] ->> endobj -510 0 obj << -/D [1455 0 R /XYZ 56.6929 563.3947 null] ->> endobj -1459 0 obj << -/D [1455 0 R /XYZ 56.6929 537.1873 null] ->> endobj -514 0 obj << -/D [1455 0 R /XYZ 56.6929 314.9763 null] ->> endobj -1460 0 obj << -/D [1455 0 R /XYZ 56.6929 292.5697 null] ->> endobj -518 0 obj << -/D [1455 0 R /XYZ 56.6929 211.1564 null] ->> endobj -1461 0 obj << -/D [1455 0 R /XYZ 56.6929 183.865 null] ->> endobj -1454 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F53 962 0 R /F11 1299 0 R /F39 863 0 R /F62 995 0 R /F63 998 0 R >> -/XObject << /Im2 984 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1464 0 obj << -/Length 3617 -/Filter /FlateDecode ->> -stream -xÚÝZKsÛ8¾ûW誥«, ^|íM“(YOeœ¬íÝšÚL”HÙ¬P¤V¤ì(¿~»Ñe;›™Úªµ„@ ôóëńÿ˜D>ã*Ö“0ÖÌçŸ,×g|rïÞ ;fêMû£~¾=ûé­ -'1‹LnW=ZãQ$&·é'ïõßfoç×çSés/`çS?àÞÏ—Wo¨'¦ÇëWo/ßýãzvjïöòÃu_ÏßίçW¯ççS¡´/€²$þõájNƒÞ^¾ŸŸ¾ýål~Ûn¹,Áî÷ßgŸ>óI -§ûåŒ3Gþä~p&âXNÖgÚWÌ×J¹žâìæìï-ÁÞ[3uŒM¾Š˜ÉpŒOñŸü˜J*Ã'Îð_Ä’]^MgoÞ\³ÙõÇÙù4àÜ»º¡çÍüúŸókÁæ¿Í~ýø~ÎðÔ°ôTû¾|‚#$Ÿ$$ž"ôújö뜚4nlä€(iƒ|!Qù2¢´SÆÆ ×ÁŽ<±^_±„аB¨'AèƒB„ÁKTKÅŠ…<vÐ’F%M–Žz¦Y¹ÇЂÏË»ÂOÿø>°6Šb{¤Wc‡f~໿sŸ§UQ$[G÷®„>ºÏ½z¿^TEM¯óæ>/éžõxm¡ ZÚã<Óš4¦ÎÓŒÈ'tt¢OíM‘,³”^/ö†S)"ÈH µ›xæ›7Ù6iÐÄñ×CRì2ôÚ:önÏcéUÔ‡ö‡„¯ìä’ž-µj×lvÆü`î¾ÚQo™á¦Ì@KÔ%ÙdÝäcÖÈqL.h†\[¾ìPÀ@PÆfðX$Ë/u‘Ô÷4UèþTvH;·!Š eà€#»c#ÄdÀB!£bâ˜~BÅ«!ìÒ!X×_ ~Æœ?EkÀ–u²'nT›&¯Ê¤(ìoc@ð\.WF>²Sô)±Öb(„u•æèݳmM y¼Ï—÷Ø«½7ÁÉt“:hã”A-WÆ{ãï•QÓjMSÚa­"EV‡Ê‘¬Hí2yÚÜSùˆ³^$5ªmõWØä¹ðº}Æag**@iÚFº3Æ‚{z—ŒˆW„Wá”e5ÊòX‰ ç!ŠlÕÅÅL’.”¯×Yšƒ»*ìŠÀÿ©åydb yÂ1Š-µ] ˆ>¡ÃÚï|àÝ ¬CñÐ{kP 0%ûš¬7Ev1²¥ÀgÎüçN¥_zª©äê"s1Sê‰ $PïVä2 -ÀÌD8y*Ó` áÒ“Ÿªg9ØKX º—»-©vÙÐãÀÁ†¤Þf ª^Ì°±vWØ ‰Ðë4[æ뤠>¼ºwß2ÚÄt.%iJ¡‡wÆ‹? 0ƒ§5bé K â3Œ0I^$‹"³£M¡¶Á¤ÔìbLïöhÖòù¨›ä,±<‘I™s(:£v ˈ“|Bpí<’CùœX œ²U# B£bÙ[]ZHØýá=¨r{6|sb¡(fZµóuÔiÝZ3ʈÁKu4~ƒ/y õV!Àžv› ©ÁìarSæIž?òÀ ñ >n­H«V7NzÝó8¾´‰Ž>á…;‡ŸEr~ìvGYšöʪ¡F²¨«b×óí*=0ò1I‚ dìNóêÃõå»Ë«±3…°º VO@ž%Z.)<È3 »dÁbE–A;‚bùQ¸m¼²’¾·¬Ö›¤Éy‘7qh‡ée–l‹Ü¨t?@”dR9p†,Šã6¶7¡ êŸ -W¨›C¤ïÒˆ»2ÿF0Ç7NŸy™æ.úBâq †çYÂLôED ë}^ÑÃ8Ê>ƒÈNûÙ¦y]îø')´•_òL樅qÌjKS<›9ÞlÀÏÇ€j¨m.hù:›6Õ´€Ô›zLÁ7€êܨ»¬DÈhŽ>J-D¸´ÉÀ Q·«¦nUrH‡ÁìÑh -r‘9 ßgÛ¼qÎfC£€påôyП—”K;j{y»"«Ùó9Ï’—17"5ã~ìà¦Eć¢@â‡ÎÕŒ‹b€ÖÊ$*õŽ î†<½;´Óò 9ÛZE'–g»?¡ï==ú£J%†ºsÎü0z®P¢%¤ÔàퟔÒS -ï;@æ+;ßôTê½ë«9ô¨¹]½†Û’Œ\'Íòž:-1é}Ãê߈Ïn7¶X-·,·ý=ÃyRoÅÿÞöâÒ[ ¾òÉ‹’#’nÆI½U€Sƒ ÒÏè- O&·nz¿y¾–!…Þñ~ŒeºkÁÿÅeâÄ(~CrÈt$dÿ~òèžRñ€EpÞTAŒP”­ ÕÈ=%¨?–÷B[^ÏÆ=$@Á¶^ýn~5¿6‰ôí|,ÉUŒsåtšÛÒºê ܪGw]œ}m²‘ùÑšBI¶Í0Åo¡P €'%«·³¾ÑÕ“-¸l3ü„`òdI&@W°Æb%‰Ý~"§¿Y}°ëx!¸-xÒ¯ÛÛ÷çxý~vs3¨Wô0YMpSšùq͆ðZ<<Ÿ -ι7KÓ¼¿ÈÛÜì­9ؘq9ˆƒ–µ!w‰tÛ²¤è—)“+{l j^|v¦P Ñ}¶"ÄîØN&þÔ4“69ë­h¯Sì"&›ƒgº[o†ãHžØ"yÖcÈÂ\@šUQÜÅ&í¡‹¯üN×öÀ[Æu[ß&c`B ¶tÕ  js:›Ûõ²fªyCÚ×ÕšúY`b·™ôÄÙíÕnõò€|BE^&Û}¼M'aR„rÃì-MLÛ,¢÷™Æ_CÓêVš4‰3.“C,›]Wã=Ó†Ó -!¼‹ÖèÅbïüµN¶_€¶/_[ÿpœÖU’v½y?ñ7vu‰¿Œ©V›ÚãÚ0FÆweÛ‡¬­îóvu -ÐjBl«Žq¯Ú=TŽPúk£Û åààk[¤é´Ã¯é™}ô#¼%ak\­¢çÂág¯þ -²ûompô0¶¬ ™Œ„:¸®@ƀƌ—’°˜¬Û²5étŠõð.ÃF| XG:/c×à.ñš$#µÙ4–F @_²w?lL»²ÏÕÁ”t›È—ô·€º¥lš`m ß5€.š|i®™¬è箎¡Ç\@¦Î‰©¶M–oŒ ~´v m×7Hâ±ÃÜÝœ¼G„Žß…í}X VEšv{Ž'óÈÍ¡Hb ¶°à#~¨0rÛ€éúb! ±$¡»,DÇjÏeïPu—§MU„wÓ‡7B >ˆÌ‹Û«Æå4]Œm¶IY¯z¹Uàé œ´ÙûÖ¨ÁVÝÝüŒ-Nt&N¡Ø”S8)×n5®;ã…6]´ƒœ{Ävk†ÐÆášš ªdCضåb,»U¥¹ÆP¤ev™mmØT—0+cű|ÝÉ(ÁT¥Ššv;ÁÚýXû±èuBŸ„Áwg¯&Ý3N° ú|Å!µ‰W~xÀê«ï«]ª„Þßá¡óÖ¡9!µH*& -DG†¬Î évttðƒ”yëÛƒþmŒhÅl1íÝwÃÆ k†\~''ñû”'­FßAVÃÜ­ZÄ"_…Cõ œüKÐJœ.dQ¬ÄsÀ|Ÿ:D@sW›„W¹/[ QfÍcµýB?ûÆvwÕó“n€°ñPå©¥AhoyŸ7Yê§ifªõ¥]‘@]äw¥-eGš ˜xwOW„Zzuån“Û“»§)Æ*º„ßëQh!~´—tZ¶ï7U]ç R2­È8 ¡)äÚx«m¼Õ6ÞÂsW»7yi¿qÑ®[ªÍ×Cfûí‡<‡‚z¾}÷QA@Àš>^kYÄö”7cRìK¨ËBZèp {é—ø„€oa¾ÏjLÀõ‘ÆQúì&ø%ì¥ã7vâ—,»=ϪÛéhí2Y#|kËÚ•C&ðã€.¸:âzMW?£¶¶~`áý¬íÈüÓ½ÎѶˆ³‡zSc§>$V>ïG>ûå“g+0/ýȸûÐZ›»y9ž—·ù»Ýr/Gå÷5òñÖÿÛWëendstream -endobj -1463 0 obj << -/Type /Page -/Contents 1464 0 R -/Resources 1462 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1453 0 R ->> endobj -1465 0 obj << -/D [1463 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1466 0 obj << -/D [1463 0 R /XYZ 85.0394 687.9013 null] ->> endobj -1467 0 obj << -/D [1463 0 R /XYZ 85.0394 675.9461 null] ->> endobj -522 0 obj << -/D [1463 0 R /XYZ 85.0394 283.5376 null] ->> endobj -1292 0 obj << -/D [1463 0 R /XYZ 85.0394 259.198 null] ->> endobj -1462 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F21 658 0 R /F23 682 0 R /F14 685 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1470 0 obj << -/Length 69 -/Filter /FlateDecode ->> -stream -xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream -endobj -1469 0 obj << -/Type /Page -/Contents 1470 0 R -/Resources 1468 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1453 0 R ->> endobj -1471 0 obj << -/D [1469 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1468 0 obj << -/ProcSet [ /PDF ] ->> endobj -1474 0 obj << -/Length 1368 -/Filter /FlateDecode ->> -stream -xÚ•]oÛ6ð=¿ÂÈ“ Ä )ês}jÓvëP Cã>­{ eÚ*‰šD%͆þ÷ñx¤,Ǫ·À0t<ïŽ÷M¶ æÇYL(Ï£EšG$¦,^õ]ìÍÞÏWÌÑD1'qĹYÌì®bž‘8 ÓÅjÊäÍúêö}È!%IÆ‹õn”•¤)ÉÒ8_¬·wÑjÙ-WaLƒtùçúW<‘4K£FDB²(Ïì7~{‹Ô9~îe1t¥~ÂÕjúr+;¡KüXDx”„Ž_‘Œå¨@JØrÅ(¥Áë¢}?²Ñªpñ±ìµgÅ9É“0qœ8%!Óñ|Œç—, Gäxؽ/4¦¯ï>öæËn•ÂÒJÜÛ-.‘YÔBÜ«ŽlôAhÜR¢ -Ñ ÐK·5´Žg³E )‹¯¨¨ên7èaªÃÐ; lFž\œ1’Çqh/.ªJ=®¥ËÝÓŒ™Œ÷¢(MÍ) ¾™á‘G\ú}u[ÉSê›RãU+»Êõ%Ѷçþ„1Áó³v’G ¶“Û[ã/ -ýM#I_P¾†c[¯7j?ôÔý5"°KôXVB›J_üôþŽ™‹ã¢oE!OÓ¨bc)d5@´æÜN8Ü8y‡º€`Døª®Uv°÷éý±²ñÇ•ÚÙдÒЗd® ˆÂßÅß—ÿXâÈ !MNPb·Ù+$eÏÖáóý0æFžÄŒ%HÄ_ÍÙ‰ÉHM‰N,Š…¾,É™ ŸÕ¬ÆßG!!'9£ü…qQ˜²ïMl¢f"Îï²­ÀÙ.F¼ƒ°t"nt°p¦†‚iÃm¨7²û¿xyÞ-öóØßÑ #‚9Ä÷Ws\U‹ÓÜÄÅÞì'ö'dV© §ƒÆTK¯úTb³ƒÅ \Tê8_L9ŽQ~Q'ÏrõÌ8—¢éoÕ8Q×®´“¥×LÜôSëÎÕ¢7{öŽ»Òß㺾²¿`ÒsˆæéôÚ—î7;¢5um#3>NDc½·ž„IP …ía°€2ÏY„9ˆ±-x‡¥¾ÆÕH2vDX M…MöT„  Âím¤lP”ï‘% aC%ÐÛ²_͆òÆ$úììò^¹®W«“¶Ö˜Ñ¿¶$×Êš´2÷§Éó.§eq¡ÇÞx„c:ŸxÈ̃/Ý@ôúóýÝ»OKóþXÏ O¦XæÔObûPöªó}VÛÖzõn=¾Pý»“Ç^±soXO²:Òàv*–Só óÔ3á.m|Ÿ‹û“˜ô´endstream -endobj -1473 0 obj << -/Type /Page -/Contents 1474 0 R -/Resources 1472 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1453 0 R ->> endobj -1475 0 obj << -/D [1473 0 R /XYZ 85.0394 794.5015 null] ->> endobj -526 0 obj << -/D [1473 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1476 0 obj << -/D [1473 0 R /XYZ 85.0394 574.5824 null] ->> endobj -530 0 obj << -/D [1473 0 R /XYZ 85.0394 574.5824 null] ->> endobj -1477 0 obj << -/D [1473 0 R /XYZ 85.0394 544.7049 null] ->> endobj -1472 0 obj << -/Font << /F21 658 0 R /F23 682 0 R /F47 879 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1480 0 obj << -/Length 3343 -/Filter /FlateDecode ->> -stream -xÚ¥Z[oÛV~÷¯ÐÛÒ€Eñ\x+ ¸Óº»Hº‰ŒÝ¢íEKÜP¤BRVÕ_¿3gæP”D7Š æáp8ç2·o†³þ‰YùQ*ÓYœj? D8Ë·7Ál Ͼ¿Ì3wLó1×·Ë›Å[ÏR?d4[>d%~$b¶,~ñb_ú·¿-\¼Æ¼2ðC©@<ò|÷Ç÷ï—Äu&Q'¾‰d¶ûwo¦$E¾TB3ÏLJåÓã› QBÀ¢´Š†)ïZ>|¸Ë0€5ÞÂïÛG˜ÁRRº||øîéÃãògºûîý»o>ÜßÆÚ[>ÂÎsó°Nj|š"PxLŸo~ù-˜p¨?Þ¾J“pv€›Ài*gÛ*?ÔJ9Juóñæ߃ÀÑSûê¤vD'É õ1¥ž0õ#‡çð÷Ë-DÚ×ZÄ'.;%=ý4s£ž¦w/ÌÇoq¤£Ù¯äâìÏýî›ÅþúÙ¾ËMÛûM»†ñb·_-˜´ÈŠ—²kÚãâþ_sÐSàÁ9¥~h¿¨»Ëåkçòlý_ÒôÓ$I¦50$~aƒ %_„Ç[4×+ …¤W'|¡ÔëzÖ3¥^KÃiÿA ÅLh_i° `+0Ø|‚{òµ Bç ·s`ß›¶iz²õ¬.ØL¿/ –§F3 0ðƒ(Œ¬˜÷5ð'¡÷ôîñ¿8Š¼Î´/¦íîà.Õ^Ùµìˆo×t]¹ª Qû†¨ímâík¢±7µdÙ-CŸ¹¿ˆ}Ô¹u¾ioEâÁ6ÌÔšUä‡iì˜MýR{½5uOsü„Á¾+ë5/lc†³“ ò=įܾ ÿÅÔ¼‰/£ eöç}÷eS[f;éêˆ/¡†R_RÏæBøiJËßíL^>íš”RvM0Þ¯RjucKŒ?‘±‹tó~bA$^0‹•cE7;\†Ã0ñ–TN”g5=ߘjG£r»£³{1DèŽ]o¶Äß™|ß–ý‘ž¬øº«²œ7!Y»VËÎN›êÀüVÍï8¼£“I¤æÜÁPn9lÊ|Cfz(«ŠFU¹-ÙˆíAá È¶ÙÚ›šGå3Û:]È^ùQG×¼qÛÜ–)l&Cˇd’Ä9Ð}ÝÀDø¢¼}gž÷¸-¼g“õ{û¶¡‡ÖŽá­ ì,@™…×ÁáÓ}óLì@±KÒnS@ÈVeeÏØRº4ž¦ÈÌÖ ÎXLÆ÷ûz×–/eeÖä1vw#ムñ™ }OX›„¢âÐYÛžXÂ3kÃØ:ó·¯Mò¸‹×+T"ðþs›J5Öí×kÓ±vi«5¹*ª±s¡‹®g;#Ê°—ÃÆ8®n0íë2!=ˆäÌק|\ø2–‡Œtï³oƒ¥’ȶ|?g J¤VÇxµîWó{¶ÝUülqkÃ2ÞTeÍdÔ¼¥4?c×±%Ëɦö¥ a¤Z}žÒ0uúeϼ›I%“·xÉÚEm'ã0(W&±c½CǼaonGlË×3’ “Ľ>LyMJ€Ki|?_Ka¿â² ɱ.tf%2ßpÊIF¯ÍÝ{gš\ì»vQ5yV-VeÍ[ŸGWÁ'ìÄ1¡§ëÕ‰Ù°nJ°˜7b5iÁ™zé[>JÙ˜Î8•M¦kð0%ãØJ{ËÐ2ök~îXËÈ{nZ¢OYLC^â‹v †Üx•dQ:5NwhÚODá(»3mu¤geíVB YÛ—ù¾Êx¥I5yÐX0@ `×¹›ˆX -¬$ ƒU‚3åGax‘~_3b™úI§£ˆ…†Kï؀•N8)á¨6h 8²Æ W0Jì1¡ê˜|î¯̾µÉxTÖyµ/LÇÌ7Žý†²*ܳëƒ8œ±;Ÿ’üÉGÛÓÞ[Nk´s·—³ôŠÂþ†A5M®•v-`|65é¥4ŒÍSG 8&NRñ5± ‚ÌÆ.n–<aœ£<á9"»¹)µÁà× •!ì;Ó[~ÆE¡ -ð9«‘ -ìË ]³âû®¿˜ï%«ö¦f³§#" +îÏì‚°RçPÇ'3];O Û”‘;°^¶ÜëApŽ“'FÅ šúêth»²˜ÓAL¹cèGItã²'Î21¼ÂÚ©¶ ±ßQ¡Czê6;7ŸcbÁå2´Ì&ÌÝ`>õº»ô‚óÒRˆp wQ˜—Ŧm¦‚òãtèüL…¨LEµà+Ð.CL!Fé/ ScaU³žòMLA|.®VžÀÅšàË4}Nè /·Snš(tS·a -€M)_ÄQr \ ÿtŽf¹®±ðÇŽßréùgêùŸÚ²iÇn$Ï7××.•>¤Âèk\*uŽGŠ -ñÍ7-?†bBÊS@ÛC 8‘œAQQà‚è¾J%aa‚ÛR¾ÉêµqtA-â£é:®˜l+ˆÛ¦(‘)Ïú¡NCmv®ê‡”`jJ_fŠöO Œ”ªTÕ¦´£¤ŸÊH]í‡ë2ן´B³Î`? ·¢5çÁeÁ= 7µo3,‹m\ý4TÞ8–¹„rê£ümÙS!4Õ.U?"¬¾¦_*à$RÀh“Ý:0b1aE¯Ë¢÷ÅC÷ÆEãoèzËPúA YÂuà@3#·p b0x% ‚Õ’°Ó»‘ÃH êù¡*Ä÷€Ã„·„¿Ò{¸êÂâŒ23áA"pêÙç™ð¦Š˜Fc»×ÓXÂâq+goØÑl´)'x>–l7±gäÄ  ( ƒA ‘T3¼kz ’´ƒ£0 -QØ´£³À›ÐÉ^Å‚³É¡H—g±€¥wtká{’Ù'ŠP3Üc±o™N¿%£õƒýÝQ/¡äU;T¨- °ƒ•aà@æQJ{p¶º•ÔЧbÔx…:¯8§@Q|ºiM×ó¢òÞ0çÎ(àÝÛ&JØ°pë¯ -€è­ =B Áb+Ë|nDu•£àÔ±±þ5ûGO:8ÀéãÃ_óαK ‚lƒKµªŸ ÀJ­9Ï)ÎroŽ`JeN¡åiWd½qÍjî;~±]}Ï^ Åý×WÒ+œ|¤îY>ŽŸ³œ/Þu›f_4^ñ« qPvŶ‰Úšƒ«Úš©`ÆN€!`Æ+æѪàY]§pØÁ¶Tq]£½¢áû US`ï¶7¤UÖQ¤(¾§Ú•RÊ{ü‰YQFíø%*º”ãÔÞ¦¡²I&5Ÿ¡bbX9f£“»cÿâEVåÀª©U÷ÊÔ;¥¬…^ÖSç@†P™Þ -\Tü·”Ã'ºm¶†É«üØ×qêðÀöæ0gUOÖ¨I2ı?¸ƒœœÚåJ…Ü.GòÖô›¦àe0 Š4N×  -@µÜœÖh¹»†X܃s]àŒ®$Áý"pó³Šå$ƒÑâøé žnˆ-”üáƒdX–ɺÒ20~¦fÐÚ,väï«®áoúa©™ñ|¶ø˜´x¾hÃÓØó¥6lB¦ðªfTª|)høÍÌö‰Ú¦±$Û1¡Z, ÎOÖÊñ]º*{aÖáÃv¬ø`G -ìÍ´phÛŽ0[4A™=ÔÇ]–³cDøµi]_):bÂbbùññ{þƒlKòxxXZ“ôk15µ8úꘚŠÁ͇…i\^ÅÉ1]Õ¦?Z¬hŸÌ‘5ø"8®ð¶è”´ÌÐu‹n¤-/¿«NØ–«s\}4Ê4÷¨Í1¦ãÏS÷cùb`}B×l8UŸN(פcšïšªÌÓ-Œ0~½2œ–u¬N_ñz©úøs’‰ŸCMó—µrÂy@[’Èqå4®Ñ_' „…;KôÕÊÝÏ[®—þìÕJMendstream -endobj -1479 0 obj << -/Type /Page -/Contents 1480 0 R -/Resources 1478 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1453 0 R -/Annots [ 1485 0 R ] ->> endobj -1485 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[0 1 1] -/Rect [63.4454 757.0719 452.088 767.2337] -/Subtype/Link/A<
> ->> endobj -1481 0 obj << -/D [1479 0 R /XYZ 56.6929 794.5015 null] ->> endobj -534 0 obj << -/D [1479 0 R /XYZ 56.6929 739.5018 null] ->> endobj -1486 0 obj << -/D [1479 0 R /XYZ 56.6929 704.7645 null] ->> endobj -538 0 obj << -/D [1479 0 R /XYZ 56.6929 563.5308 null] ->> endobj -1487 0 obj << -/D [1479 0 R /XYZ 56.6929 535.7626 null] ->> endobj -542 0 obj << -/D [1479 0 R /XYZ 56.6929 418.2412 null] ->> endobj -1488 0 obj << -/D [1479 0 R /XYZ 56.6929 389.5504 null] ->> endobj -546 0 obj << -/D [1479 0 R /XYZ 56.6929 228.1296 null] ->> endobj -1235 0 obj << -/D [1479 0 R /XYZ 56.6929 194.8993 null] ->> endobj -1478 0 obj << -/Font << /F37 747 0 R /F67 1484 0 R /F11 1299 0 R /F39 863 0 R /F21 658 0 R /F23 682 0 R /F47 879 0 R /F53 962 0 R /F48 885 0 R /F62 995 0 R /F63 998 0 R >> -/XObject << /Im2 984 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1491 0 obj << -/Length 533 -/Filter /FlateDecode ->> -stream -xÚ¥TM›0½ó+|©¸6Æ`³IÚ²RÓ4a«ÕxT‚Ó@6Úýõµ3·¶ôTEóÆoÞ|x€"b~ Ž “1JeŒ9¡•[ µ9ûêQÇ Ï¤ð–u—{Ÿ¿°I,“(AùË–ÀDŠòêÉÍóé"#Nü!Oˆ—Í&à‘ðXNÇ‹,4þ1[f“éb¤±Ÿga,ˆ0ñÌ)Lg£ïÙøó P§Ôžó{oš_¹m–f»øí==T™žï=‚™ ˜J¡­s†yÌØÙÓxKïçEðæô:4<Îæ"J¦±¡éq‰fŽìô–z«lO‰ßÕ½êÀ,7ZwÎÝkûäþ/¥và)šŒê­-¶uið[xØUE¯*8˜ØyžE_€U· ã`wXUz[€×H¶.²RZ!—{Sô7üÐŽÛôRŠ%çÑ©'ÂTÊä)…Ú{2è]·ÊÜ,#‰Ÿoê˜Çâ- ”úŸ Œ‰I§Àßë]بWÕ\cÁ*uÛ›|u»vx_÷v溵¹å¬Â¥rÚÂÏæî ªö¾ê:å8úe¨ÁÝaÕÔ%ìÝQ­Àp#¶ý¬Ní_Õ¾Ð*å­î]HÓè#˜îâÀÍ9Ε‹ÿµÛŒc»›hþ®îÿÞûë!6¯¤ÑðJ›ëÄ"’é¹(;/Á?V~yAþ.ýÑÍendstream -endobj -1490 0 obj << -/Type /Page -/Contents 1491 0 R -/Resources 1489 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1493 0 R ->> endobj -1492 0 obj << -/D [1490 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1489 0 obj << -/Font << /F37 747 0 R /F23 682 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1496 0 obj << -/Length 69 -/Filter /FlateDecode ->> -stream -xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream -endobj -1495 0 obj << -/Type /Page -/Contents 1496 0 R -/Resources 1494 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1493 0 R ->> endobj -1497 0 obj << -/D [1495 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1494 0 obj << -/ProcSet [ /PDF ] ->> endobj -1500 0 obj << -/Length 1964 -/Filter /FlateDecode ->> -stream -xÚ¥X[ë¶~?¿ÂoѱV”D]Ò¢i³§I¶EÒ g¢íé-imõH¢#Rv7¿¾3œ¡,ÛJS »&çÎá7äˆbÁ¿Ø2Œ’2ÝäeÊHÈMÕ¿‹6{à}óN°L*“P¦I“îV&E(‹8ßl—F¾zy÷øu,6qfY,7/¯³¯,/Â2IËÍKýàé Ž¶¶±Œ‚âáŸ/"µ4Ì‹\ Z.d˜—Qá^„Á¨§]טƒÖ¶ö³šHÃ$ÍbVË’0Ï"òS„âa+¢( -žtßëþ0j0Ó›‹–Rz Ÿ‹Â˜M<ÛϤ ´¥ÁYŸ šßÐì Ï4¨{{¦ŸQ隣¡™ž¼öA]™=zØÉ‘%›2,³8ãÀ =e*RJÈ,%©v±42º›l‹‹Ä™Õ3õ„Ér“va¨®SI5Ô4¨ôÀQ.¸­1ScüøÚ¶UŸ8Šãø Š 95ƒÝSûF™‰8¬¹{Ã¥ábæœÃbLc݆nã<¦#þfA§÷û™ˆquh9»æU“ÕÄ‚å2¢„°ÞNÎêS[³˜"ºÑ`ÅdýJôC;Xvçòƒ´v¿=ç96X´Û0Ø5× n“ijÚ_LÝn+à¤ÓÃÂ…ïÒS -i ·¥Ý3éÀ–yíˆùðŠ&Â8K<æcø¡›‚hïCû™<»úÐŒ­êhüýÔï Æס\@•‰ó÷w= vVXƃÓÆ-ÈÊ@͉ο&DüL|Œãœ¤!š7¢±Þð+Ôʲb@4@™ þ@ŒN³¬CX;6úØÍ2\ô<Ò스‡yÑ· g°È”}sɘ†€G€"6ù93À͵úFtür²e€h$Òßàï»ïÞ¿ÿñÇ©*e§^[ú¤ïÜvzW¿ ×}kì…{½^¬0‘p‘ÒyE?°)e™í0‹Óàu² |d ‡Æ‹o<ÐĪôHÒÕßO'2ŸëaÍžÑ_5±¹Á’FŠ ÈœŒðiÍZ W -ŠØmT¹,(¾ÊÞñ‰}q´€¨\Â&|&d¾vKÈTÝVŒÐhÆKI›S?s@Õ+6¸k0mHšŽµÇrRϯÄ'¨›CZÙN,HÉÀk™ôjY`:ujˆN^®5ôÛé³'A´é°²\¤A®xYöÊ`3§Áçs³‰uÿŒ`°¡¬mú£]­7>)34n-_³•>¾ñ±ûzs„ašÃÙ`M t9hðÃ|K>xÌ«,«DM¿Š~|ª`x‘â\,Íq.¼éÓlŽò{½$çF.ÝÁÌJö¢´VËlo>ͱýãÓh®o›ÿ+Ÿtc‹lѸÄ"'ÛCv0 -ýf3GÕ51b‘æi‘diNŒ‘Œâ±ˆ±0·"ð0àâÄßZÕ7’\sÂw"ó‡&0ÍåþF—?$cRÍZº”í(õåŠ:éH^04g¢°û(½À ÙWáÓ7˜¿S,[>°úŒ¹…;î3`ô¦'bÕÀ¤Ö^ ïöEy˜]¹œ­Þv‹íçÞa¯Úák@n@þzh|ÇütÓOÓ0J¿mºã—¿ÞeÚâš(°ÁiÇEðá êÍâÀz҃ѣm§žæˆ§çOŒ$ ¸aѯt ÇtéùL]%ŒFèŠâ¹Bˆ%Ç#¥ e/v­Î©­XKí)™®×âX°Åu’_=ÿ~-ÃÔ¶GYðþÛ§päÏH—@ -­è×ØÚ:‰óÎÐÃBYn?z·XdÌqâd¾©Üä¤ÚNí:ørðï»QÕaáƒL·CÕMucVìâªV.Wª4 Û8Hü»Uoy)”@»Zìo+B)ˆ×­©ôD9ƒ©;B.ÊõTyåvÂ)Î6™îZds§¡ÁÓÏMí­µ°r=¶öä&vÓž®é^/yr€¡¶¯ÓP;«y Â1{9B€FãŸà{ËוÂM>p\×-ž‘7>å èWˆÌ¨WKÐÆ 5m"û¿À¥–€ã6WUŸÔž9ZØוå,¶VHbžþ‹'¯´=Í\¦pÀŸ'8TÃ[WyÌ#‰6Éyè5µÒÇî:4 ßál 3,•ßbÏ[œ+ªë/WF".ƒ›ËÊ?@”€/jŒu“1Ô¢+l',{_¼2ãâ•sä®ÏñÛªÊ ¿&–Bú–åç !G˜ -¥Ìrcø-Š¼ûãËü -“¤%œ¡i±Iæ² —â~ÚøÑŸ/¯6³Âv¡ám’rá÷Î.zïá°ú‹EØûÛxà8KQ”×ñܼÍBw1\­ýÎÆð»•s^ÀÍQŠ’säjMkç/Ú,ÜÚmR¡ÈEzís³ã¾‡êÁaWvEÊPæâ—öD¤p}ÉqQüë›2kl—*÷»roÙõÖ¿x|<ŸÏ!ïÊ£/ËGFßãn²pÇ71ÞlÔ,u×U>î­ý·­Â·ÀèªA§jW\†=?í„·Aû‡ÄD†ø,¹±Ù^dèEr\Ca—¹7ä:ŽüÖÛü¾yïî?ÃEŒùendstream -endobj -1499 0 obj << -/Type /Page -/Contents 1500 0 R -/Resources 1498 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1493 0 R -/Annots [ 1507 0 R 1508 0 R ] ->> endobj -1507 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[0 1 1] -/Rect [348.3486 128.9523 463.9152 141.0119] -/Subtype/Link/A<
> ->> endobj -1508 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[0 1 1] -/Rect [147.3629 116.9971 364.5484 129.0567] -/Subtype/Link/A<> ->> endobj -1501 0 obj << -/D [1499 0 R /XYZ 85.0394 794.5015 null] ->> endobj -550 0 obj << -/D [1499 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1502 0 obj << -/D [1499 0 R /XYZ 85.0394 576.7004 null] ->> endobj -554 0 obj << -/D [1499 0 R /XYZ 85.0394 576.7004 null] ->> endobj -1503 0 obj << -/D [1499 0 R /XYZ 85.0394 548.3785 null] ->> endobj -558 0 obj << -/D [1499 0 R /XYZ 85.0394 548.3785 null] ->> endobj -1504 0 obj << -/D [1499 0 R /XYZ 85.0394 518.5228 null] ->> endobj -562 0 obj << -/D [1499 0 R /XYZ 85.0394 460.6968 null] ->> endobj -1505 0 obj << -/D [1499 0 R /XYZ 85.0394 425.0333 null] ->> endobj -566 0 obj << -/D [1499 0 R /XYZ 85.0394 260.2468 null] ->> endobj -1506 0 obj << -/D [1499 0 R /XYZ 85.0394 224.698 null] ->> endobj -1498 0 obj << -/Font << /F21 658 0 R /F23 682 0 R /F11 1299 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1511 0 obj << -/Length 69 -/Filter /FlateDecode ->> -stream -xÚ3T0BCS3=3K#KsK=SCS…ä\.…t œ;—!T‰©±ž©‰±1ƒEV.­knj©g`fA‚!ÂVŒendstream -endobj -1510 0 obj << -/Type /Page -/Contents 1511 0 R -/Resources 1509 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1493 0 R ->> endobj -1512 0 obj << -/D [1510 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1509 0 obj << -/ProcSet [ /PDF ] ->> endobj -1515 0 obj << -/Length 2543 -/Filter /FlateDecode ->> -stream -xÚuYYsÛ8~ϯð[誑ÂûØ7[ÎádìrYÎNÕnö"! k’`ÒŠæ×O7ºyØéTJ@£hôñuƒö.\øç]¤ÑÚ ²ð"ÉÂuäzÑE^½s/°öùÇ•²8T²îf²Þ:‹¢A6Ö^yƒì$Mú]·JîiøE™N·gšh&vGIƒ›û- D]°èíý \dë,öc>Ӈ˹!ë[vGÝŽ d¼ ~ø~gx©óÃuý\‰)´¶»ôyPu­êQ¬6sñ] UÓø^TLÝžM'+Éó¾mñ‰ú©3ð{YÊT÷V¯¦ß•*Òõx4ÜoEv%K>~Ú B'óÝßhÄ– -\Ó±8 ØãràÔòD3h Ä“0D,¤É[µ³:Ýê dÐ9 QÔ€EÒÔ'{)Áúrø®óɪ¢«q—µÑ$”ÄêY_ÝÔ'ÿ=>\f¾sUË"' Á_‘k/ƒ“†® -¦6pkK­é·ç÷'‘s[w²…-@Ø£åÌ­ßp,XBšÎÞ'h7ü•¿Ù*Œpv -÷Ãa…|‘¥nl Ø-H±ÈZyá6µ¨€÷ƒ( -RÜŠ1ÏuL~”6`l ¿‚~ZѨ¢<ÓCƒÚ̓ý¬j¢$¸æI·ÏÌ]¿(òAw·øYìÜÛ€eö¢ç9'ÉQ³m§Vu´:Åìe/¡P5G*@'ëR¢tGÑ­Ò…Â<x)aA· -’ r”OœBç=Á 1j"«¢ºÑpQɧUäzý"GöÄÙ G,ØÝfS6ä ÐBdz˜€z²Ó„Q™DÏ B0q¶Ah3>£Œ7«®sÙØ£FfÁ'‘«RuJãÆÕùö‘]ôçÛ/¨N‡ÝVM)gQø|$¶Ì­} 8Épat*ÌÒ¹Ã^‰©€ck ˜Ö…/ ‘úf8ùtTù‘w)Ë¥áZ½RÜ0†Oå:»^•˜Ã&Ù:v3*LO„Y‰ÅèÖt4™\a¼°[`\ÃÈÈö®ž„Ž—ÌÉAM´Ěû«„Ä„ €É,Ö£ÄvFø[vAé÷Aô´QêÜéüY4²³Álˆ†±ˆC¶ýB=ù¸!‚nÌÊw‰P‰ü¨jiˆ¯ÔàbºHêØ슆 Â÷ZÁµêμûž¶ºž–Ï܈RvµïY×ÛæÕ¨äjµ¤½¬s«I˜ŒéT×wìDDåïÛÍêv{K‹<õ0Ø>Þá0(î9±Þs@ܘe·ž«„D±é Ønu»ÁƒÖÄqE?cÔq,¦…îÀ³ÆúE£ÁĘŽAÄ)ôkÙ>ËRži6”šQÑÇÑ í%"Û2R¡q¼µ2$Q†£5ÄÞÞ3Xßñ±bɾ¾Ûºù~­(z‚Hׇ î †FX³Á¿,0x,ã&þ,<^ NÖÀY_Ö# ÆÃkfÝOUÿÕ‰[¸‘{Y›åj_¼ˆ1î𥑈6Hy ÿ/óŽ#窀Š -ã”U#7Cã@Q²€.ÿ¾ô™Ñ„K ÷yIJ­¥¥tG6µí a)\§ë€Ö&tÅŒ‚þ[år Òéú@Øèªé)ŽL½"Ÿûæ¢@ù<ópBµÙ>~æÜpËBtG‰ãÉYxEìÅbè á¥…9`°8#Û–8Ϲ6aù/3!(¬ÝˆUÐâ£:J¼TœpŠq«ëÄLM³ÿ@ÏM •($Ñì]€B‰±c€2i ?P‡nþmD4“Ç v;)*¼Q¾Ý3,$¶×`(‡æJý× éz`ê„Þw§Y1J†|%\‹B¡kùüEÙi¸U³“eÉJ}“/Ë…ü¦¯KÑX%=›4øªQÕ‘¢®óñg¯,•Ä²áŽg k ¥TŸ%#.Q=( ‚ש©ö¦7F ŸgàÑ[¦Ã–è@±¸ˆ$ŸægH@Ä%²ZI(Ž":ž( 6SaUŸiQc¢õFêƆEiX*×5ÔÏ]OÕ-ãÖXXE p³Í‚¥¢o¹‡›MÔºõÁùˆ4òK®øbðج–S€¼V(Ø&ˆ0ð[P£ ÄNg[iÝÑÒF´åêNuЧ—%KÞ©gI«w}o }U¯K­yHÝ2Ž"ÛüÁ×ý ÆŠýô3À‹¬ÉC–Påú‘?{°GÉÏæ#Sð¹c"ˆ£oë¥yó–þ®‚¸åé·žøqsˆ™Ìy™Àfá:ã¤m,ßû¶¿š°f¬…´íº¥®ÙÀoçÁâgþe5ñÐ7þùçìÀשŸ%ÃF¨gš½=mü‹Áßû jh¢Yendstream -endobj -1514 0 obj << -/Type /Page -/Contents 1515 0 R -/Resources 1513 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1493 0 R ->> endobj -1516 0 obj << -/D [1514 0 R /XYZ 85.0394 794.5015 null] ->> endobj -570 0 obj << -/D [1514 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1517 0 obj << -/D [1514 0 R /XYZ 85.0394 573.5449 null] ->> endobj -574 0 obj << -/D [1514 0 R /XYZ 85.0394 573.5449 null] ->> endobj -1518 0 obj << -/D [1514 0 R /XYZ 85.0394 539.0037 null] ->> endobj -578 0 obj << -/D [1514 0 R /XYZ 85.0394 539.0037 null] ->> endobj -1519 0 obj << -/D [1514 0 R /XYZ 85.0394 510.2426 null] ->> endobj -1513 0 obj << -/Font << /F21 658 0 R /F23 682 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1522 0 obj << -/Length 2893 -/Filter /FlateDecode ->> -stream -xÚ­ksã¸í{~…¿Õ™‰IÔ3ÛéL.›ls×Ë¥‰;íÌíÍ”–h[]Yò‰r²¹__€õ°•½›i“&Ê›¹ðïÍÂȉR?Åià„®βݙ;ÛîÓ™Ç4 K´R}·<»¼ñ,uÒÈfËõ€Wâ¸IâÍ–ùÏókÇw΃;ÿtûpûtý·ó…ºóÏ4xº½»}º}¸¹¥éýÃÝOO?^ŸÇÁ|yÿÓÃù"‰Óp~ýøxûðñþ_Ds ]×BonŸÏY~v»ì$žÊsŠûëÙÏ¿¸³÷ý™ëˆ4 g¯0q/MýÙî,…BXHyö|ö÷Žák–NjÉs_Dþ„š|1¥¦0u"(TÓw÷át~2Q.ê -'é<%Ø«Ô4hνd®J%µÊ‰¢¨ó¬ö­Ú­TCSßu]"UN ‚yH‚ïäêfÈõµ)ZE¸zMˆJɦ|ãeeÉ õ^e-3³”í–—ª\~ 4 -hfáyN†¾9fùVT²"ŸFÒÐg[Ø>k$ŒÓ­%ya4P’~¯$œø#Ìùp -"‡Ï®ëgýFÐ\í‰s&[ÔÂŒjp`‹1ãÄ.}Qe½ß©ª%€Ý)«+]ðq‰§µU«*YejRueêd9ø]ËcmzÂê ½7À$Ç÷ÓdþPÓ\æyÑV–4 j¶ÐŒ¨+Eœ-«wvXŽæ=ª‰%dÅ\ ¡a»•Ö5ƒ´Êà_o ö`2bö²Í¶JÃà>¨u|4Ì_ëæ ¡Ì!æsE¸}­u±*ÁÛ:—o4\½y+ôLX7z[ì c,€د1z…IV7ûº‘¨j} ˜oÕË‘r(üµ…½²ZÓyYp)㨠¢–Qfsø­;rªúÀ˜¢Ê‹—"?È’!Å›y#ˆ7S`× t’Tؘ{¾ð Ì?©Š1Š¹j­Ê1·væx=ok`Ã[Ç DÚtÙß?¾D|‡ó¼#*–÷³º×ð¿ó†@`éÇNà‰Ð°d6IlØ}1«$áè ïùÉbU´„«WµÅ¹gî:ø'AÉå€ïa³–YÇȘ Z…ÃÈ(9Hãùë¶È¶¬(z`ÖúÏéQè„žðŽv¨r;˜ -±AiÏK:·úCÛÅÂñCa×R¾_~à‰-³¤üœö -É‘9R P)0¦†Œi‚4`(M§6ó'óÃ^S(Wr7dg51™hïŸÏ=¨m/̹?5YŽ¥ÚlË7“ìÌ(Ø… ¾È5o]÷"L¸6xc0¡q²m -©—´¦5õÃD œ$ŒlH„r«å&Âçݳ5º?¾·hdµÁk+ §/-UçI0> -è¾ÏÝG$”uf,Õ­DC¡Æüx¾;˜t -(–"—ÜYi4¹B™º¦qfèY'ÉíŽÑ–\z ¬nÌ\³&ÊKŸ ‰•v(Äð1“‘㣓Æ|ÒØŠž«Ëˆp}µ6eè£[SWöj›ŸMñ¢Âú`K@®Ö j]¼©VP%Ûc4ºãê#‘œ*Õ-õNB'V½S“ÖÂxl˜gr/WXÖà= #’qcYaç 8êò®• õ•Ëö0î$3£–F®ÁØÑ‚𪕲€¦)¨Ùˆ1|L7eX¥s*-qPC+a©÷Ö> XúØö±°ž  WÓgÀÀ´ëð{SJ­¹ô‡©©í>ÖØ"à© g0Áhrsÿñ ÃÈó1‘¦ß,°Õd0\>M„4Ê‘Qƒ+KŽ\”c.¬ŠhÙdEÛ¤Ašäèe<à‹uÝ«²ä~É°?Òì¿A{É ”Ôøø¾ÿˆ8"UÐ%1t\éÁî`ªŒ˜ ‰HÒ¿˜Þtè£}VÕÐ_àrÉhÓ±#}à'nLsD¯€“‡¶Æº$ë) kL蘌‘¦Ö¹aTìö¥ÚYu›ºÊ£²Ýbf`’–5ýv¢àdб¦œ)à·7En¡vÛ\­%””4é-„¼×ô[)¸ìZ6oçÈõX˜Ì¯'ûÓ·}‘ÙeÜÎJ©]±ÙrUQÖ57°eñE]u-ã "‰„“aë_ßu½«|•\ùð›^I×…õ¾Wk•xWþJø)mÑñ™*ÛÒã@ ;L/ʨY'²zÝššbb™Û—¢ÏÞ’9” Cfb‚ ã\sÂ]¨ ÏvHÆïV¼×V¾("+ª¬ÛÀ8«KsÕaˆWýßWW¢K =ÉIøô¥;^4@%(SÚÂdà†¸¿ÑʸSî”bÙH^šÉÉÇ!4F{\Zf6ç¬8€´} âç13êêʪ«Hó›!¾}°ü\ñœ­¨7Üoßú؉õ|Ø *¬(OJæpþÁÆä³H`7é^EžÄ)Û-t/`7õÄàÚýÇHžÇ~ , KÌëì`9B»EœLçsyÛÖà&Ñð\´Md½•ÌÙ|4o.hÔ¿4~^Wè­QâX†½lx7ã/Ñ»ÏbŠ„rS ƒ^E8©È@´ÂŒLcÓ’Ã/ܽmE! §UÝš&7!'\×JÌæ(ÎËñ.iU¾XvÝép’›ž¢2‰¦Ø;ðšÉ½W3ÜðÛjÕ“jº˜¼ÒÙ¿Ñy‘7Vĉ#EhîQÿ¾YúÅ`Á©s5eBÛûj×NÝl.›uvâ:¾;©+ŽD:òœŽèDŽ‘Nx½ç7±I<|à9NÍࢠDš4§è~ïK®üü:q -·KÊÿóWÞþCw;"Iüé¸~œ8Ô¥V(> endobj -1526 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[0 1 1] -/Rect [253.7995 146.8976 417.685 158.9572] -/Subtype/Link/A<> ->> endobj -1527 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[0 1 1] -/Rect [63.4454 108.9117 208.8999 119.0735] -/Subtype/Link/A<> ->> endobj -1523 0 obj << -/D [1521 0 R /XYZ 56.6929 794.5015 null] ->> endobj -582 0 obj << -/D [1521 0 R /XYZ 56.6929 652.1213 null] ->> endobj -1524 0 obj << -/D [1521 0 R /XYZ 56.6929 614.8935 null] ->> endobj -586 0 obj << -/D [1521 0 R /XYZ 56.6929 614.8935 null] ->> endobj -1072 0 obj << -/D [1521 0 R /XYZ 56.6929 584.5024 null] ->> endobj -590 0 obj << -/D [1521 0 R /XYZ 56.6929 289.5256 null] ->> endobj -1525 0 obj << -/D [1521 0 R /XYZ 56.6929 251.3901 null] ->> endobj -594 0 obj << -/D [1521 0 R /XYZ 56.6929 251.3901 null] ->> endobj -900 0 obj << -/D [1521 0 R /XYZ 56.6929 222.7156 null] ->> endobj -1528 0 obj << -/D [1521 0 R /XYZ 56.6929 53.7852 null] ->> endobj -1529 0 obj << -/D [1521 0 R /XYZ 56.6929 53.7852 null] ->> endobj -1520 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F21 658 0 R /F47 879 0 R /F53 962 0 R /F11 1299 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1532 0 obj << -/Length 2825 -/Filter /FlateDecode ->> -stream -xÚµZ]{£6¾Ï¯ð¥ý<-’ KÇö¤É4™4v·Ûα›g0¸g&ýõ{„>äζûä" ôâóžO <òà"†<ÊýQÈ}Ä<ÌFëý•7ÚÂÜíV2×ZèÚ–ºY]ýó Gñ€£Õgk­yQ„G«ÍÇñôéiñ8¿û÷äš0oŠ(½@‘-5L‘‘ÒñÐá3N䆡3è~†ZØqš©Xœª4ßv8¨v‰¼°©\¾•U²ïs1Òç¼ÍÇLiÿ)>‚æ7ÛDßÇù)>¾ÕH-ÙŠpׄøˆG Z*~€O꥟ŽÅ¡(m)—^@Eäw–”ƒ;-eÜ‹s‡{9¡-òºØäÙàwùú8ÁÑXzâñ?E®([M0Æãcœ—ŸµkçË>ú|ŒpªnÑ÷ èû°«b54=mOe¥‰ãÁ°Ïà…äR=`K9ô®¥,½½» -½w±ônƒO•b’õ.ÎÓr/o?JÉO5)ÅþPéSÙa¬+>wÙšÁZÛÞDAAHœAŽ±qú-M¾›Od7ï?–”ƒ-¥ù!˜ºøqA[üt±ø±Áçoy¼Oדk„㟛¸™‡Qmÿb°kâB‡5q-2”p;CŒƒ† ÊÆ ±ŠÍ…˜\ªñծؗE®F­}SM='_v¸hèëëø+¦îkê@!øÚ„FÀ¿)NùFs~8êP”§1ïûÔM¹-5L¹‘j(ð0åNè†ò3ì~Ê[à³,>ZN¦ -ªèf1ˆ{²¶À,@^C-·{FæBþ¿9•;yµÈþЉ픽ý&A$¢ä–”ƒ -e˜ ^ä`Âm1ÑÅ`ÂL¶ ÒWÕâõÎT:è~:%Dz›r„I@úSÑ4ßÈÄ÷U×qq=°Þ½GÃz‡¦CP½ wKÊ¡w-eô„.pA[zïbèÝ_|«’¼4 Æ$§²“ŒòE?¼€;Ow½gF¡€ùŸóŽÃô1|‰KÊA–²(  -\Ð]ì -lðÇ"¿–EWrܧ¹®ÈŒÆe‚©£G²I¥¯ÃC$d´ßfÇø«`VØôëžêÞ^"ˆ|nÝÛRú7RF÷‘洞ÐîÏ°ûuß_&ª* lü>y“M¯UýEÐ䄼JMM’ÒEàBÂEVË»Û!„"/bØâj<nÀCüq:Ácå$”?¨©ÛÓfé»”E¡Ñx®fqY]˼o Zy?‹¿h—£-#0}Û2”_&œŒ“,ƒ\Iœ:XªôD<(›í$QQ~ÁN,)‡h)c'œz;qA[vÒÅ°¼e' i'"}—Uü’¥åN4S®˜¹z¿P;ŠÏÏC¡3âÈçAgÓh®8ô2¸L•µ#áfÈçˆr‰!KÊÁ–²r$2'´ÅP{€!Ü(û9ùý”èf,»ÇŸ…ÚÒmW'ImÙ%׫s\9äÆÔ”ðÿ7[#àKlYR¶´”f‹z^è`Ëm±ÕÅ`ËRZ?ß'jòj¨ -ÀqM†|D·kâF¶k½Á#ƃ6IÎ0×ÞÛssƒ)è7–”ƒ-e¸ œ9ÑmqÓÅàÆ¿Mr¨¯…bÃP•V"Ú…Ü_Óu"§¦Ù¶€©Ý^ÎÉ°'ib%ÜËX =>(–éæT{-éÕp!è¿].e~ót^“§<®\ËÏüN9´Tô¿ÿç}õé­ì -¶º/ÓÃi&·hÞêß¡fÔ_¦/Å«=sß²²~e|–pu?øCœejîú*ló£ýû›<€æ©»¿Ù4ª mõÖÒwm{RßCKqšµ-5lÖFʘ5!³vB7f}†ÝoÖ-ð»|SÛ˜n+Ÿ“²È^µ¢—§Ã¡8Vgçr1ëËԃرþØ?+ò£¡zž¬Ûᆠ-±ŠSzIï–”CïZÊè=¢Ô¡w´¥÷.ö€ÞmðÕNFƒ” /]xœ½•i)Źµfk ®ÕÖ\éL ®íLÐð©p’f¯M¬Šxõ%Í´Ü-ƒ‹g= P’Šàã@wFªžV‹¶êi Ó$“pŒ"^Ø#µ¥†É4RšLßs‘é„nÈ<Ãî'³^Ìí¼€y¾UÉ|\lN*²‹ÑZÁBX”disæлsùбØÅ”ÕĈç§òYèzº†11ú FŒª;òdw$^æ!.ËDGn¹9ª [œ6LjHp•IÿnÐφé0 -=|a¿Ô–rЯ¥,ú1Ô mÑßÅ ßWgU±.Ä.øÌC±él FD¥oíÕbD&&áÈMb‚;¹û}nýlŸ3C¯îs;s,“&,Ú6 3a;²}PâÚ,”G«•[ìëÞ2–Îñò_´ ¨‚™èÌÝvaI9ìBK5vá;΃Ж]t±ì¹TÖó¢8„È#ëB”õMm”F*ÊSU׉‹ÆÄÙì5,>}ñ­}ʸ Þ´#š‰È21ú ÄMŒƒsu\bZFñ÷ÃY‚©À² ¸ ¡£ùÈ -’Xï*½ªA¾§ª³ÃÐù"bÀø0‹^h%-¡aÓÓBæP•¹"’ ·1¼.p¿ÝÙÈÓÉ5#¾eCâNŨ—LÔ b fËšQ¥°™G{?µûeB¼1´5öÝ&ÉÔêóäoúùZÿõ+Ÿ«¯’ùõØ.…‚1¤•ß‡ð§ìÎ̶ìî6~•/œ÷u˜s:e0‰ ×&S[ÊAµ–²¸vÐ:¡-²»ØlÛà³b¿—»®Xo¶ö| “ Éjq,¥ŒôW˜Xž¶[èÄêNÆߥßúÎiˆBŽíc$êןŠEÞŸö±>uû®uŸ«=°r¦gjð1i“tôº-ž[½ç<ÎÿH·Cqæ!Í2sâû}&Á#Dü p[„%4lZ¨ù "rœ¸psè÷[ƒ¼LŽ©>*y<5Ö´Þ’HªtÝWeB0fþùé¬9ŠhÏÅqí÷~$yb þBýo +\ 5iÞõÙ— ·Qx¸_á6²ñ>¨óÒò%Ùů©Èú0Yv ][­˜–Î ú¤¶‘U!ŒÞ=½òjºQ'²a{1 (€æÃâ‹°æ+ˆúUŠcZîÒ*– ’:_ /Q2÷i¾ORí„zÍÖ’}¸1\½AªŸàö¨Ö3¹ý/ék톈FÑÀaõê—¿‚Ÿ}‡l> >õÿ:`bŒendstream -endobj -1531 0 obj << -/Type /Page -/Contents 1532 0 R -/Resources 1530 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1589 0 R ->> endobj -1533 0 obj << -/D [1531 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1534 0 obj << -/D [1531 0 R /XYZ 85.0394 752.3015 null] ->> endobj -1535 0 obj << -/D [1531 0 R /XYZ 85.0394 752.3015 null] ->> endobj -1536 0 obj << -/D [1531 0 R /XYZ 85.0394 752.3015 null] ->> endobj -1537 0 obj << -/D [1531 0 R /XYZ 85.0394 746.3107 null] ->> endobj -1538 0 obj << -/D [1531 0 R /XYZ 85.0394 731.5461 null] ->> endobj -1539 0 obj << -/D [1531 0 R /XYZ 85.0394 728.1497 null] ->> endobj -1540 0 obj << -/D [1531 0 R /XYZ 85.0394 713.3851 null] ->> endobj -1541 0 obj << -/D [1531 0 R /XYZ 85.0394 709.9887 null] ->> endobj -1542 0 obj << -/D [1531 0 R /XYZ 85.0394 651.9592 null] ->> endobj -1016 0 obj << -/D [1531 0 R /XYZ 85.0394 651.9592 null] ->> endobj -1543 0 obj << -/D [1531 0 R /XYZ 85.0394 651.9592 null] ->> endobj -1544 0 obj << -/D [1531 0 R /XYZ 85.0394 648.8377 null] ->> endobj -1545 0 obj << -/D [1531 0 R /XYZ 85.0394 634.0731 null] ->> endobj -1546 0 obj << -/D [1531 0 R /XYZ 85.0394 630.6767 null] ->> endobj -1547 0 obj << -/D [1531 0 R /XYZ 85.0394 615.9121 null] ->> endobj -1548 0 obj << -/D [1531 0 R /XYZ 85.0394 612.5156 null] ->> endobj -1549 0 obj << -/D [1531 0 R /XYZ 85.0394 585.7959 null] ->> endobj -1550 0 obj << -/D [1531 0 R /XYZ 85.0394 582.3994 null] ->> endobj -1551 0 obj << -/D [1531 0 R /XYZ 85.0394 567.6349 null] ->> endobj -1552 0 obj << -/D [1531 0 R /XYZ 85.0394 564.2384 null] ->> endobj -1553 0 obj << -/D [1531 0 R /XYZ 85.0394 549.5337 null] ->> endobj -1554 0 obj << -/D [1531 0 R /XYZ 85.0394 546.0774 null] ->> endobj -1555 0 obj << -/D [1531 0 R /XYZ 85.0394 531.3128 null] ->> endobj -1556 0 obj << -/D [1531 0 R /XYZ 85.0394 527.9163 null] ->> endobj -1557 0 obj << -/D [1531 0 R /XYZ 85.0394 513.1518 null] ->> endobj -1558 0 obj << -/D [1531 0 R /XYZ 85.0394 509.7553 null] ->> endobj -1559 0 obj << -/D [1531 0 R /XYZ 85.0394 483.0356 null] ->> endobj -1560 0 obj << -/D [1531 0 R /XYZ 85.0394 479.6391 null] ->> endobj -1561 0 obj << -/D [1531 0 R /XYZ 85.0394 464.8745 null] ->> endobj -1562 0 obj << -/D [1531 0 R /XYZ 85.0394 461.4781 null] ->> endobj -1563 0 obj << -/D [1531 0 R /XYZ 85.0394 446.7135 null] ->> endobj -1564 0 obj << -/D [1531 0 R /XYZ 85.0394 443.3171 null] ->> endobj -1565 0 obj << -/D [1531 0 R /XYZ 85.0394 428.5525 null] ->> endobj -1566 0 obj << -/D [1531 0 R /XYZ 85.0394 425.156 null] ->> endobj -1567 0 obj << -/D [1531 0 R /XYZ 85.0394 355.0758 null] ->> endobj -1568 0 obj << -/D [1531 0 R /XYZ 85.0394 355.0758 null] ->> endobj -1569 0 obj << -/D [1531 0 R /XYZ 85.0394 355.0758 null] ->> endobj -1570 0 obj << -/D [1531 0 R /XYZ 85.0394 352.0499 null] ->> endobj -1571 0 obj << -/D [1531 0 R /XYZ 85.0394 337.3452 null] ->> endobj -1572 0 obj << -/D [1531 0 R /XYZ 85.0394 333.8889 null] ->> endobj -1573 0 obj << -/D [1531 0 R /XYZ 85.0394 309.8192 null] ->> endobj -1574 0 obj << -/D [1531 0 R /XYZ 85.0394 303.7727 null] ->> endobj -1575 0 obj << -/D [1531 0 R /XYZ 85.0394 278.3282 null] ->> endobj -1576 0 obj << -/D [1531 0 R /XYZ 85.0394 273.6565 null] ->> endobj -1577 0 obj << -/D [1531 0 R /XYZ 85.0394 246.9367 null] ->> endobj -1578 0 obj << -/D [1531 0 R /XYZ 85.0394 243.5403 null] ->> endobj -1579 0 obj << -/D [1531 0 R /XYZ 85.0394 173.5556 null] ->> endobj -1580 0 obj << -/D [1531 0 R /XYZ 85.0394 173.5556 null] ->> endobj -1581 0 obj << -/D [1531 0 R /XYZ 85.0394 173.5556 null] ->> endobj -1582 0 obj << -/D [1531 0 R /XYZ 85.0394 170.4341 null] ->> endobj -1583 0 obj << -/D [1531 0 R /XYZ 85.0394 144.9896 null] ->> endobj -1584 0 obj << -/D [1531 0 R /XYZ 85.0394 140.3179 null] ->> endobj -1585 0 obj << -/D [1531 0 R /XYZ 85.0394 113.5982 null] ->> endobj -1586 0 obj << -/D [1531 0 R /XYZ 85.0394 110.2017 null] ->> endobj -1587 0 obj << -/D [1531 0 R /XYZ 85.0394 95.4372 null] ->> endobj -1588 0 obj << -/D [1531 0 R /XYZ 85.0394 92.0407 null] ->> endobj -1530 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F47 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1592 0 obj << -/Length 2889 -/Filter /FlateDecode ->> -stream -xÚµšÝw›:ÀßóWøÑ>§ÑEŸ$v·‰›µ“·ÄVN0¤·Í¿#ôÀ zwÏž<¤AƒõÓŒfFà‰xâùÈH4 "yö&Ûý™3ù}WgXÊœ+¡sSêâþì÷4˜D(ò‰?¹2Æ -‘†xr¿û2E3Á™^,/n–Ÿ®ÖñÝõ_³sâ9Ó¿ωWsq³y¸ºZlîòv½ˆçËÕˆàÙyàGÎ4¾»[¬æË?EÌGutëåb3ûzÿálq¯_ÛüiØ¡ü¿Ÿ}ùêLvð ?œ9ˆF¡7ù 7ÂQD&û3×£Ès)U-ÙÙæì_z@£·~´wª°ƒõIÏ\<ÁEžGZ“åEȧ„Ö“µfeq€JŠ¿Ó—õûKŒCúµ«ÓávÕZêT·k.Lä‘ ­{Å~ÂÏÇt:_mÄÅz-ØߎCò´J‹¼ž“ÎOÁŽ ÓJ}x >Ð;xŠ8ÓKô~‘)c,~°Ã ‡ÓçäPÕxz#»âú?™Þ&ûä¥(eïZö>dÙ>És9h’ïDóÝ “H ~[l_’WVRxÞfB½Ò¹XÂ>>m«âÞ£¦ ‹ÎAC„ý(B¡ïŽ6¥† k)M8püaÂVÕ áݽ„[ºXøé«M|§–=7¦m½˜Aw‘ä/ø Òü›¸˜øh²÷²ÈX–%ò™.w˜Cú)F8RJJs›jƒCWw?SwÌ×r0½e ˜\úÓ§â Ú¿^k¬,ÅdBçM±M¸é ‰eÂ{ÝàOSÙQ=3q1/öI*;WÉ^¶nÞÊŠí{°R#{Ñ+Å`½r°äGZʶÆæ ãóÌó¦é¯”I‹ÓÃœkÇ £ÝÏwŠÞuVÅR®Šyº}Ió²È¥À‡$?&‡7½.üáuá¶çÒ1û4¤,ëBI©uAXÖ…Mµ±.ººû×…©ÖÅž0SŠÝÚÿò†zuð‹Í+Û¦OoõÊà÷5r.Ù,Þ\—¼¾rå=FïFÈÅ.5ð»"ΫÊÎ¥Q+±ìØnŸÓbÀhÃA¼^è"⮯)5ŒWKxÃa¼VÕ Þݽx[ºùš¥;¦~m|„Ó‡<å Dcg›…–åŽåUÊã*v(EÓQº|ª|9´i_Nµ/§V_NQzÔôå‘Ø„ù`Iž²L !|14Þ"å¿å£-Ô°Ge¼–b}Ì™ ƒö¢ADG@RÐJJƒ&Ô±€¶©6@wu÷ƒ6udr/~mŸ“ü›œˆ9ËØ7µw ±­Ã…àÉ¥W›¾È*ô ‘¡íÀJ…NqÕÚ#»±“…%Èuý1 -†”…‚’Ò`¯·P°©6(tu÷S0uÏ7±øé•°b³¼’MiÞweG<úvÄv¤óc SçÀ=Û%uQømBsIh‘”U–¼0ÙLkCß½Sq±°ûgM,&†af0s†”…˜’2ˆb6Õ±®î~b¦îõ&þãvîÁÎ(j4À2¢5~Åñÿb›E7 -jõ’¿¡æG(pÐØån`s¿k°‰`FÔÊ'­0ÝÐA>Lº¦)5 SK0-»UuóDw/Ì–îMUê] -GtzÉb ƒà“•¼Í­ò¾š!oP y£`ȯC.1ÂP„!ílòç9Cþ¬izŽ§ -™z…ñ‹ORøê¸Û!¨•Á¹Å´ñ´ÿÄr]ˆã؆”¶’2`GØ6Õì®î~ئn;û\(â/‚Øô©ŽZίY]™½°9–¢?•-Òõ††ë´ë ×-€ÀEÄÒ†ë ¥ëZüý–ëõñ‰ Ëþ CºÑUCÊBUI5T]KcUmPíêî§jêž³*Ù>³Ý³1Šìݨ@ôà‚Ù¥ÔõþÏ[%…42ÂþSj–Òh‚ÐR°ªnÐœèîEÓÒ]‡6ªÓ…¢ 2Ž §¥QàÒÈž’éTÙj0-e@´J¢k³æ•™ÏC6çÈ…Þ„ˆB- dTš’g”„n¤à¢L•¯U¶²‹ÇâÇ c¬É{öx˜…Ó&›$Ž3\¢¥¾‡â‘`HYV€’Ò+ žeØT+ «»˜ºï9P×u¹-Ö”]—Nãcõ Ûnõ&ºîŠ”—D‡ºŠïî×Â>y͘÷µ³NÞ%““~'ë{nüO ë§T¸Fb\‘G¾k¼*²åU7ìü‡NSì)lÃ#!o#ca(dAŠ±Å½Z”üÚZûé5Zy »¹ŽÏ±8ÀÙ‘¡.!„Kˆ™¼À•(ÔbU½%Fõëê-n2\l—!ðp(6c°ð¿¤óò"®áyA:y“LÕ-¨@S„>â¹ãFÈÂQ -5 ‰¥ngÓkì(îGi(Ž›t]$ãk}4HøÑ`'¿¿IËJ¦žÂ÷:íbo¸·8`ù,ä8Έ6¥†™k©æË3·ªn˜ŸèîeÞÒ­çc‘o‹Ý ü«~‡—&‡éÖ?Áô~²"âø¡ÅÍ~6oZ_ˆñzH3•¼„ÃÉ ö"â±j)e¡¤¤J¶ýÒªÚ ÔÕÝOÉÔ½fß©Øãö,WÛ¡Þ"›#/~w]è ó\ÍÝk–nBzSÖ•ž»Ï,HžÜNáüâìØ@¹Ü… ݑz)e¢¤4/²™ŽMµ¥«»Š©{<½ßT‡ã¶n’ufÞ8ÛèÙ#ùuÛ“ÿAÇæ9Â@b?üÅÆ ÂKL) %¥Ó:Š-»–Uµ¡«»ƒ©û2KÊ2Ó¡àruÏçk¯…w‰gºáGɾVU•t—3å„®dãNÒ¼ªç¾(ªîWÏÖå÷#>×ÅÝ989¶7¥,È””FK4iUm ëêîGfê^ÆjËà% -¶}ÎÁ=eês¦=÷qrê6=äé÷#ë#@ wÓ!(ôü  ¶í,c‰ÂÊŽ¥^I§‚ö;•“~f8ö•…!4LK 5eb©TÛô6¬ºŠ{Q™ŠµsCåã܈û¸¤Õµ›s£N$—ñ*W—+¤;vH†¾oä%MŸ´Nÿ`Ä:¥†ÇÍ”š”šwJ¡‹º°•çâ#Èó×Ö–ei²W_,j%­Ø_kç3»Á@ÓRgñÿž¶gò“þÏŸíUñÑ0^H"7„AäKñŸ‘“7Wß÷ž¾ú5Oendstream -endobj -1591 0 obj << -/Type /Page -/Contents 1592 0 R -/Resources 1590 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1589 0 R ->> endobj -1593 0 obj << -/D [1591 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1594 0 obj << -/D [1591 0 R /XYZ 56.6929 748.5056 null] ->> endobj -1595 0 obj << -/D [1591 0 R /XYZ 56.6929 748.5056 null] ->> endobj -1596 0 obj << -/D [1591 0 R /XYZ 56.6929 748.5056 null] ->> endobj -1597 0 obj << -/D [1591 0 R /XYZ 56.6929 743.7078 null] ->> endobj -1598 0 obj << -/D [1591 0 R /XYZ 56.6929 719.6381 null] ->> endobj -1599 0 obj << -/D [1591 0 R /XYZ 56.6929 711.8197 null] ->> endobj -1600 0 obj << -/D [1591 0 R /XYZ 56.6929 697.0552 null] ->> endobj -1601 0 obj << -/D [1591 0 R /XYZ 56.6929 691.8868 null] ->> endobj -1602 0 obj << -/D [1591 0 R /XYZ 56.6929 665.1671 null] ->> endobj -1603 0 obj << -/D [1591 0 R /XYZ 56.6929 659.9987 null] ->> endobj -1604 0 obj << -/D [1591 0 R /XYZ 56.6929 635.929 null] ->> endobj -1605 0 obj << -/D [1591 0 R /XYZ 56.6929 628.1106 null] ->> endobj -1606 0 obj << -/D [1591 0 R /XYZ 56.6929 601.3909 null] ->> endobj -1607 0 obj << -/D [1591 0 R /XYZ 56.6929 596.2225 null] ->> endobj -1608 0 obj << -/D [1591 0 R /XYZ 56.6929 569.5028 null] ->> endobj -1609 0 obj << -/D [1591 0 R /XYZ 56.6929 564.3344 null] ->> endobj -1610 0 obj << -/D [1591 0 R /XYZ 56.6929 549.6297 null] ->> endobj -1611 0 obj << -/D [1591 0 R /XYZ 56.6929 544.4015 null] ->> endobj -1612 0 obj << -/D [1591 0 R /XYZ 56.6929 529.6968 null] ->> endobj -1613 0 obj << -/D [1591 0 R /XYZ 56.6929 524.4686 null] ->> endobj -1614 0 obj << -/D [1591 0 R /XYZ 56.6929 500.3989 null] ->> endobj -1615 0 obj << -/D [1591 0 R /XYZ 56.6929 492.5805 null] ->> endobj -1616 0 obj << -/D [1591 0 R /XYZ 56.6929 467.136 null] ->> endobj -1617 0 obj << -/D [1591 0 R /XYZ 56.6929 460.6924 null] ->> endobj -1618 0 obj << -/D [1591 0 R /XYZ 56.6929 436.6227 null] ->> endobj -1619 0 obj << -/D [1591 0 R /XYZ 56.6929 428.8043 null] ->> endobj -1620 0 obj << -/D [1591 0 R /XYZ 56.6929 414.0996 null] ->> endobj -1621 0 obj << -/D [1591 0 R /XYZ 56.6929 408.8714 null] ->> endobj -1622 0 obj << -/D [1591 0 R /XYZ 56.6929 382.1516 null] ->> endobj -1623 0 obj << -/D [1591 0 R /XYZ 56.6929 376.9833 null] ->> endobj -1624 0 obj << -/D [1591 0 R /XYZ 56.6929 350.2636 null] ->> endobj -1625 0 obj << -/D [1591 0 R /XYZ 56.6929 345.0952 null] ->> endobj -1626 0 obj << -/D [1591 0 R /XYZ 56.6929 321.0255 null] ->> endobj -1627 0 obj << -/D [1591 0 R /XYZ 56.6929 313.2071 null] ->> endobj -1628 0 obj << -/D [1591 0 R /XYZ 56.6929 298.5024 null] ->> endobj -1629 0 obj << -/D [1591 0 R /XYZ 56.6929 293.2742 null] ->> endobj -1630 0 obj << -/D [1591 0 R /XYZ 56.6929 267.8297 null] ->> endobj -1631 0 obj << -/D [1591 0 R /XYZ 56.6929 261.3861 null] ->> endobj -1632 0 obj << -/D [1591 0 R /XYZ 56.6929 199.468 null] ->> endobj -1633 0 obj << -/D [1591 0 R /XYZ 56.6929 199.468 null] ->> endobj -1634 0 obj << -/D [1591 0 R /XYZ 56.6929 199.468 null] ->> endobj -1635 0 obj << -/D [1591 0 R /XYZ 56.6929 191.7053 null] ->> endobj -1636 0 obj << -/D [1591 0 R /XYZ 56.6929 176.9408 null] ->> endobj -1637 0 obj << -/D [1591 0 R /XYZ 56.6929 171.7724 null] ->> endobj -1638 0 obj << -/D [1591 0 R /XYZ 56.6929 157.0677 null] ->> endobj -1639 0 obj << -/D [1591 0 R /XYZ 56.6929 151.8395 null] ->> endobj -1640 0 obj << -/D [1591 0 R /XYZ 56.6929 137.1348 null] ->> endobj -1641 0 obj << -/D [1591 0 R /XYZ 56.6929 131.9066 null] ->> endobj -1642 0 obj << -/D [1591 0 R /XYZ 56.6929 117.2018 null] ->> endobj -1643 0 obj << -/D [1591 0 R /XYZ 56.6929 111.9736 null] ->> endobj -1644 0 obj << -/D [1591 0 R /XYZ 56.6929 97.2091 null] ->> endobj -1645 0 obj << -/D [1591 0 R /XYZ 56.6929 92.0407 null] ->> endobj -1590 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F47 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1648 0 obj << -/Length 2544 -/Filter /FlateDecode ->> -stream -xÚ¥ZKs㸾ûWè(U€ øÈM¶l&3¶#y²IÍî–`™ŠTHʳ³¿> âA" É¦|0 4ñýu7º›ÂxS‘$˜DIàQ„éd{¸B“=ÌÝ_a)3WBsSêúùê/w$š$^úáäùÕX+öPãÉóîÛtñôtû°\ýs6÷)š.¼Ùœ"¤Fon7³y&|‚ð©M¯WןW÷ëÅÓlj‡~E-–âfóõþþvó|+o×·‹åêáDðì·çOW·ÏúµÍ­aDø;ÿçêÛoh²ƒ~ºBIb:ù7ÈÃIâOW% Q#ùÕæêïzAc¶}tLU”ÄýhDW>ž`ì%”ú=eÑÄ ‰OZe-6b[GV¥MVµuWÃ[\ Kˈ cd Žþm}wŠ"¿ 11E^œÀû;@µÌ50MSêÅ¡&ì²<¤Y!öîY‘Õ l¾¬j1Vvºhï÷§lÇ<þŽƒ-ázAÆðB|ÝBü‹'þ.Xsjâ¡|g‡V‰;œÄ‘gU6çKr¨Ûr(\Ii•S9Tî‚6”>Ķ¨Ý¿)‡R*^[Þ2mRqu—åL\ݔůùû“àA ÞVÕ ÇSNÓ Ì HŸŠ§ö“©äãš±ªa‡TÎ=n›Ò #!V2ÂúªL);ZJ“‘`ßN†º#ã {œŒø(: ¤¹ôb÷g)ñ1õÂ8öû”,ieúÆ{©fñô”V?4#¡‘vNQ|CÊÁˆ’RŒø##.hƒ‘!¶…üLù7UÖ°*“îñZJc]—e##Jz³aÕ;«êÑ(Åà‚qØçáZòð%-Š¬ØØî9Î?f”N³ß3fñO 0Âhê„,I!M’I\ƒ£°…"ùk-Õ]¾g‘giÍêS¬ù^Vÿî(ʶlœ£0ö"?ÆO’é!Ëåtš¤µœþ…ûQ•íß A‘‚ì%sŸ$¥WÌ߃V¸*Àæ -i‡ÙL‚™‡&7;kž@£Ä‹¾)˜RvÖµ”¦=ö©v'tÇûö8ñ=ðì< §Ï3Œ10°Ï[½„(ßGSöò×ÙœþtU×§Ö -`¦µxf…ã‡âR+¦[%òñHQ -ͳpUÉç[BX#îŽ"â6å¶ÌÇ¢.ñ¡Ä<`µ¸ëj¤uk“¹–Ÿ Ó†¾L3Ø¢2ÃTÆd!dõuD^FhK!E: G@vᜀ-”È?1’ÐŽCHGh‡Å.ŽÇ<ÛêôFx5±Z>,TÉ0<& `&„ÁC]†›»4o Em‰?´Q_à#ØL¾Ò¢Ž%Ïü}$Ïf®C@›Ô ËóR3Ý‚lß4ßö¬ˆÂñN‰!¸›RÆ•”A9vPî‚68b[H7Á9£ÂÅØ|šÒ„»>»i*°5ÇÇ€%Á OŒxêÊÅÚØÏçFâ(ŸWæÃEtšDœÀ‰múp€ÂŽq¾ŒÁ¸X«%œÏ|Q„«Ez„_çi±}cÍŸ <ˆ TP—NsSÊN¸–2w¤ÁNèŽð3ìqÂ{àO§âǶÜ1ÀiÔÆùˆL¯!Ū[Âù}0eÈÈ;"";Œ~-2þ¨‡>ŒŽ 0¯ãFÔÅ VC2nÌ[òP?µè…`[D¡õÓˆ…§RøŸrö³<û ¸Ò™'ˆQP" šW,O•,¡Öü €3„Fþ…üÀ”r˜‘’ÒÕÔ€3rAf4Ķ˜‘ þµn­ƒ @œáPeu®Ž™©óÑÍ`á FE:QÊ Þ-àÁEÌ-ª—¬©ÚzHÌVaÑÀÍË©±ÈCfÕE`Mž*òUÖeÍŠ—ôtãüh—ÑB<Õ Ϊ˜@Ê %˜!dgQ i#ìh ¹p;‡ÀãšÈ’ žUõ“ø®SÁ^Nû=ga$G°™x˜À+Ï[ƒ%”–.PØU@åF·Ž )‡’•T§åÄá*NhCÍCl‹žMp­ÏÍéx,«f îÏeºS-~XYôM/ŒÉ ßóÌ+!Õ`¨²z«”¾8VY®5Ní÷cEñ…V)åи’êjÖÀ‘Ç:¡ ±-7ÁR³l¯: ×iÙù ÂS…m^Štv´µ@àšöIxÔmƒÄŸ¦§ý›HJÇLßÞ%(‚ ÇÊ SÊA„’ÒDÀQE:¡ "†Ø"Lp}"„:à—"wƒ‹›òpL‹€¸Z3ˆ÷ìÈ¡ ñ½ 6»;$!ÓOžxòo9+àdjG}í|æÎN™¿Êô+ÜËùG¨ÿê—mP”ëÃBcO‹ØʧQ/ -/¦”O-ÕñIÉ£ºãó {œÏøB÷FßYѵEï”Kɬ`à|*û㽜ÚÑ]9+áU}ŒÖÛtÙî&6Fãà/ƒ)¤Sz9j8®AÊ؉¼fP¶5rfE‹h®ˆýƒNT¥Žh‚? [ÞÐîKð¼zÐôkÉ¥ˆ/ƒAþýIRÔ9ãhÇpl§‰P/@Á…TÀ”r¥¤4Sp6;˜rAT ±-\™àKþåg²­›$œ.Nͨ¼ç‰!ù•lró›húÎûâíè›(dxñÁïyU–Ö\o·“u=êTt„GT‡:Pò>ŠÕwmû›OŠ\B4ÏÔÓ½@Dúv"¡Ê‚ê—=SÊA¤’ÒD&Èår.hƒÈ!¶…H\çt«§÷Påbüè¨Ò¢î’¼³/÷üÓjžlü›ò~tŽæÔËS¥=U_(W[½ Ö•³mر1R`(°ôÄ)öbHžú=ñÇ—ºÌYÃh`i‡cÎûUå{û;l1ã#j‹<ÄXl8GÁXܶ`JÙmAKU”ãPtBw¶p†=n =pa ~8½íš&p×FOøÏÊ}•ßÀIs1òÙ‘`†¾Sš˜ÍQ<½ñăw©øþÈò\δ_L|¨–·o§ü&G7Rþ)gYS0ýÝ‘`É%Ì-¥ »²È>ÈLGá÷ú1ÿC ‡/¡ÜÝ”rP¬¤tÞFŽBÙ mP<ĶPl‚_g…>¶>§/LÕÌÙÙI;ZSȈ¥žH‚dü3ØM•~=’ -§ý©n4‰•%ˆtÓ`ÙYPBÝ'©ÈQG»p;†Àã˜ÈÂÉb §áY…Hvà¾)ù³¸†A•áÊ8åÀ~/öê»~¬¼VY³âÄ-}¼'`(ŠÌ¦Gœºâ>]ݲòÜ”öÜêF}îòŸùüÄÓ -2jëHøÿûYF2òHlë¹B¦žDê¥øæ2|sýË­óWÿ/§÷Áendstream -endobj -1647 0 obj << -/Type /Page -/Contents 1648 0 R -/Resources 1646 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1589 0 R ->> endobj -1649 0 obj << -/D [1647 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1650 0 obj << -/D [1647 0 R /XYZ 85.0394 748.4854 null] ->> endobj -1651 0 obj << -/D [1647 0 R /XYZ 85.0394 748.4854 null] ->> endobj -1652 0 obj << -/D [1647 0 R /XYZ 85.0394 748.4854 null] ->> endobj -1653 0 obj << -/D [1647 0 R /XYZ 85.0394 743.3452 null] ->> endobj -1654 0 obj << -/D [1647 0 R /XYZ 85.0394 728.6405 null] ->> endobj -1655 0 obj << -/D [1647 0 R /XYZ 85.0394 723.1655 null] ->> endobj -1656 0 obj << -/D [1647 0 R /XYZ 85.0394 708.4607 null] ->> endobj -1657 0 obj << -/D [1647 0 R /XYZ 85.0394 702.9857 null] ->> endobj -1658 0 obj << -/D [1647 0 R /XYZ 85.0394 688.2211 null] ->> endobj -1659 0 obj << -/D [1647 0 R /XYZ 85.0394 682.8059 null] ->> endobj -1660 0 obj << -/D [1647 0 R /XYZ 85.0394 668.0414 null] ->> endobj -1661 0 obj << -/D [1647 0 R /XYZ 85.0394 662.6262 null] ->> endobj -1662 0 obj << -/D [1647 0 R /XYZ 85.0394 599.7666 null] ->> endobj -1663 0 obj << -/D [1647 0 R /XYZ 85.0394 599.7666 null] ->> endobj -1664 0 obj << -/D [1647 0 R /XYZ 85.0394 599.7666 null] ->> endobj -1665 0 obj << -/D [1647 0 R /XYZ 85.0394 591.7571 null] ->> endobj -1666 0 obj << -/D [1647 0 R /XYZ 85.0394 565.0374 null] ->> endobj -1667 0 obj << -/D [1647 0 R /XYZ 85.0394 559.6222 null] ->> endobj -1668 0 obj << -/D [1647 0 R /XYZ 85.0394 534.1777 null] ->> endobj -1669 0 obj << -/D [1647 0 R /XYZ 85.0394 527.4872 null] ->> endobj -1670 0 obj << -/D [1647 0 R /XYZ 85.0394 502.0427 null] ->> endobj -1671 0 obj << -/D [1647 0 R /XYZ 85.0394 495.3523 null] ->> endobj -1672 0 obj << -/D [1647 0 R /XYZ 85.0394 420.5376 null] ->> endobj -1673 0 obj << -/D [1647 0 R /XYZ 85.0394 420.5376 null] ->> endobj -1674 0 obj << -/D [1647 0 R /XYZ 85.0394 420.5376 null] ->> endobj -1675 0 obj << -/D [1647 0 R /XYZ 85.0394 412.5281 null] ->> endobj -1676 0 obj << -/D [1647 0 R /XYZ 85.0394 388.4584 null] ->> endobj -1677 0 obj << -/D [1647 0 R /XYZ 85.0394 380.3932 null] ->> endobj -1678 0 obj << -/D [1647 0 R /XYZ 85.0394 365.6884 null] ->> endobj -1679 0 obj << -/D [1647 0 R /XYZ 85.0394 360.2134 null] ->> endobj -1680 0 obj << -/D [1647 0 R /XYZ 85.0394 345.4488 null] ->> endobj -1681 0 obj << -/D [1647 0 R /XYZ 85.0394 340.0336 null] ->> endobj -1682 0 obj << -/D [1647 0 R /XYZ 85.0394 325.269 null] ->> endobj -1683 0 obj << -/D [1647 0 R /XYZ 85.0394 319.8539 null] ->> endobj -1684 0 obj << -/D [1647 0 R /XYZ 85.0394 295.7842 null] ->> endobj -1685 0 obj << -/D [1647 0 R /XYZ 85.0394 287.7189 null] ->> endobj -1686 0 obj << -/D [1647 0 R /XYZ 85.0394 272.9543 null] ->> endobj -1687 0 obj << -/D [1647 0 R /XYZ 85.0394 267.5392 null] ->> endobj -1688 0 obj << -/D [1647 0 R /XYZ 85.0394 252.7746 null] ->> endobj -1689 0 obj << -/D [1647 0 R /XYZ 85.0394 247.3594 null] ->> endobj -1690 0 obj << -/D [1647 0 R /XYZ 85.0394 223.2897 null] ->> endobj -1691 0 obj << -/D [1647 0 R /XYZ 85.0394 215.2245 null] ->> endobj -1692 0 obj << -/D [1647 0 R /XYZ 85.0394 149.4956 null] ->> endobj -1693 0 obj << -/D [1647 0 R /XYZ 85.0394 149.4956 null] ->> endobj -1694 0 obj << -/D [1647 0 R /XYZ 85.0394 149.4956 null] ->> endobj -1695 0 obj << -/D [1647 0 R /XYZ 85.0394 144.3554 null] ->> endobj -1696 0 obj << -/D [1647 0 R /XYZ 85.0394 120.2857 null] ->> endobj -1697 0 obj << -/D [1647 0 R /XYZ 85.0394 112.2205 null] ->> endobj -1698 0 obj << -/D [1647 0 R /XYZ 85.0394 97.4559 null] ->> endobj -1699 0 obj << -/D [1647 0 R /XYZ 85.0394 92.0407 null] ->> endobj -1646 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F47 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1702 0 obj << -/Length 2122 -/Filter /FlateDecode ->> -stream -xÚ¥YKs㸾ûWèª*Bðà37ÙÒ8žñÚŽå­d33š‚%–)R+RžÑþú4Ð J$µ•”n ?ôQø±‘ç?âÑ(ˆ\âQæ’Í­`ìöŠžIÍ4±¹®_®þöI£ˆD>÷G/o–¬Ð0d£—åWgJƒê\ß]ßß=Þ>OŸþñÛxÂ=ê|£>Ì°³øõöv¾x™›îó|:»{¸6ž~DéÓÓüav÷oŸ*©´¡ÞÌãï/Ÿ¯æ/Ͳí­1*Ôš¿úúŽ–°ÃÏW”ˆ(ôF? C ‹">Ú\¹ž ž+DMÉ®WÿlZ£zj§©%\ø¼ÃVœ#‘çñ–±¼ˆø‚ m¬ÇײÈd%—¸ÇÙÃÂØF&û]ZŒi>Ý”½›.4htG‹ ×&ºp¬¹ÔÒ¾‚VN}ïû©fÆ9XÅ †U7\çº]û 1mݳb§ùxârê<Ä©ZÌYÊJnz4™ÿ¬d^¦E®Ít²;R„ëR²ÿ -S|á̈™—U¿Ë1Ã×»1 %ê‰sÓ¸1ü_âýÛ&ΔÏq¾w¥¶\+š4°ƒ>8WéEº$Ä£:Þ‘i;ÃÔ@ÇD0Ý€^ ¹ÅÝÀYŠ5*ÊzÒœgƒ£j#Žúp5Ç!7i‚_·Ë¸’]FŒ¸<² Ôs ~k ÙàgzÓí.Í°9ˆ„ú$ (†ÂæêÇ¢ájÀðÄ€ ª>¢q¦»Ž–îËöoša? -‰"ïÀà—Xw“uƒCÔƒ’Hò’Í5€CÍUã ( pRmápª»[wƒCƒƒjÕ8èvƒƒ'!,æ7˜5GºÊÓ|…é¾Zšÿ'î3HW‘î8w® Nü×8âŽÌ2T:Šqá<ró*wÆêù­(Æ)¥ý˜‰ˆP7º„™Å5€YÍuÄ,¢˜ ©¶0;ÕÝ™­»'7.‚Ý›,Þ¥ß(åI\5ÄúûŸ"¯]®Š«}—Sqð°íUsãU÷òGZv;ÂúáŒ0懱¸©¹@\w(˜ ©¶9ÕÝ ˆ­û>ݤzdéj­¼Rð")¶iÅ’̘ë|™ÿ†”gY˜™3ô,“b·Ä¶r·çgíjÁ¢€[qOMQqO þ%.Ky@š®ô’ˆÑQ”* -p¹™Ll«ežúï…ÔƒÈyx¡Î³¹ú!m¸H}oÒAÕGHÏtwBÚÒý,—R9Ož¢óˆ€!ˆðÕþ'ªcÌ«ù³BëB®øZ\ϳéØóœå™S$}*v›¸3ú°ò»mçÀqº_íËê«Ó‡±‰€á2ª!áA¹Gýæ‘' .Î]rsi$Ívñ[ÕULSHÊ.Dæj ֬ЫgA ¾»Yi¬ƒqc$èèv±_­'K5‰?ŠÝ».>Õüe‘ì7P“”8¦JõÕu§okžç«4—rg¦cÇå;2ƒ¹Ñ…Õ ƒÑµÄ%Úö"³F]¼„Ž¾N#¡þ̤FøRt¿ÇZ[œžA«'+M,«x%Klcáå;Kù!³b«ö+ò#æÜm¶™Týbg¤7öR“x¯g“•Q]´·eÎ\Åõ+‡ãX`#Ö_áÔwô#ÎÔY -ë˜èÊÿ€\åºØg†ªµªÆ«ÄïïûßUQg5 %©!¹Ú>Zcn„½©SŸ!Ñƺû<3þ$)6“.|¶qžjéŒ:¯ü≀Æ2-“,N7:‡ê¸jX óñBçç®:s%võrá‹(+d-K¢øpuüa„ÄøÉÒ7YÂò°§O+|Ëô'66E^­Í\8ïõ¬S¸lvlԬسW ¥´^²“©¶~Ö3¯f*IM=ëÇŒ²38Ðó  LPxuµbá¥ÂÎk±7±âúîav”ëB±ê7r)‰X}y“;åF½Ïì<„RïÂõËæ:O&° lâ(LgÖŸGµóÈ™ÚÎ<ÒÒŠy„zÆ­¨o[Ê^´5Vć9Oñ>ÃIÓ .\œHºSá¤É»ŽпO÷j"s¡âÜvéj­“ˈ!lÀ Õß+Ô¼ '¸ˆàÇ%L8 üöiñ}£ÌëºpØbXWŸ,ŠB\ÛB¾ÆeUl M ÈÞLÿŽ#y†‚43OøÜSºN®tM52…kE’ÂY.{‹8¬ê£¼hs¬ÿïÿ¥¬ê% "컊p°¯‚³(µ—È=[yýÖùÒÿ š`£endstream -endobj -1701 0 obj << -/Type /Page -/Contents 1702 0 R -/Resources 1700 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1589 0 R ->> endobj -1703 0 obj << -/D [1701 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1704 0 obj << -/D [1701 0 R /XYZ 56.6929 749.4437 null] ->> endobj -1705 0 obj << -/D [1701 0 R /XYZ 56.6929 749.4437 null] ->> endobj -1706 0 obj << -/D [1701 0 R /XYZ 56.6929 749.4437 null] ->> endobj -1707 0 obj << -/D [1701 0 R /XYZ 56.6929 746.6461 null] ->> endobj -1708 0 obj << -/D [1701 0 R /XYZ 56.6929 722.5763 null] ->> endobj -1709 0 obj << -/D [1701 0 R /XYZ 56.6929 716.7581 null] ->> endobj -1710 0 obj << -/D [1701 0 R /XYZ 56.6929 701.9936 null] ->> endobj -1711 0 obj << -/D [1701 0 R /XYZ 56.6929 698.8254 null] ->> endobj -1712 0 obj << -/D [1701 0 R /XYZ 56.6929 684.1207 null] ->> endobj -1713 0 obj << -/D [1701 0 R /XYZ 56.6929 680.8926 null] ->> endobj -1714 0 obj << -/D [1701 0 R /XYZ 56.6929 656.8229 null] ->> endobj -1715 0 obj << -/D [1701 0 R /XYZ 56.6929 651.0047 null] ->> endobj -1716 0 obj << -/D [1701 0 R /XYZ 56.6929 636.3 null] ->> endobj -1717 0 obj << -/D [1701 0 R /XYZ 56.6929 633.072 null] ->> endobj -1718 0 obj << -/D [1701 0 R /XYZ 56.6929 609.0023 null] ->> endobj -1719 0 obj << -/D [1701 0 R /XYZ 56.6929 603.184 null] ->> endobj -1720 0 obj << -/D [1701 0 R /XYZ 56.6929 579.1143 null] ->> endobj -1721 0 obj << -/D [1701 0 R /XYZ 56.6929 573.2961 null] ->> endobj -1722 0 obj << -/D [1701 0 R /XYZ 56.6929 558.5914 null] ->> endobj -1723 0 obj << -/D [1701 0 R /XYZ 56.6929 555.3634 null] ->> endobj -1724 0 obj << -/D [1701 0 R /XYZ 56.6929 540.5988 null] ->> endobj -1725 0 obj << -/D [1701 0 R /XYZ 56.6929 537.4306 null] ->> endobj -1726 0 obj << -/D [1701 0 R /XYZ 56.6929 510.7109 null] ->> endobj -1727 0 obj << -/D [1701 0 R /XYZ 56.6929 507.5427 null] ->> endobj -598 0 obj << -/D [1701 0 R /XYZ 56.6929 477.5928 null] ->> endobj -1728 0 obj << -/D [1701 0 R /XYZ 56.6929 453.2532 null] ->> endobj -602 0 obj << -/D [1701 0 R /XYZ 56.6929 369.7201 null] ->> endobj -1729 0 obj << -/D [1701 0 R /XYZ 56.6929 345.3805 null] ->> endobj -1730 0 obj << -/D [1701 0 R /XYZ 56.6929 310.6805 null] ->> endobj -1731 0 obj << -/D [1701 0 R /XYZ 56.6929 310.6805 null] ->> endobj -1732 0 obj << -/D [1701 0 R /XYZ 56.6929 310.6805 null] ->> endobj -1733 0 obj << -/D [1701 0 R /XYZ 56.6929 310.6805 null] ->> endobj -1700 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F47 879 0 R /F14 685 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1736 0 obj << -/Length 1917 -/Filter /FlateDecode ->> -stream -xÚµX[Ûº~ϯ0Ð>hˆáE¤¤óÔÜÚì²)š-úìƒÖ¦m!²¤#É»1Šþ÷ÎpHÙòÊÇ(ŠÖäpøq8wJ,8ü‰E¦Wy²Hó„i.ôb¹{ÅXûÛ+áy­˜N”‚ÉÌj¬UÆt&ÓE| -òîþÕ›¿J±œ#õâ~=žeÒ”ñ|q¿ú½m[[¯ÊŸ7±ÔÌÐJ»‚+k˜}nú!”ùÓk9])# ¿ìʺ¼Q?tÅÐ8á¼ïíŒK€0ùXg.¸ô@Ê„?48Ð%÷`×~Û4(ºáG1ZZ†Õ]OKvY n¹YÓo9øÕà%Ô^€\ÑkXÈ@ ÅùÂõÈЊ3 RP‰µµC0׸àf÷»Úý€þ#xôlÓ½lrÐC{?´è!D¤ßmñdýìÜh½¯—E5žÖ¬g®0›hþ¾Â–'*Ô>²s²<×pÇœ¥iJÿ¶¶Í~³9*ÑÐg*uÍ´2¥çÁÀUJF5ÆxUpæÔ½"ús9l‰¶lv;Ð~\•µ¥5 -‰Í~gë¡GÓi Æ%î¢êâÚ½'Ñü±–r׬<”³3þBXSªq -0 ¤PžLÝ~L!1ÅŠ’GrbPÈ´Ô>GCgÇL%+ër‹‰ÞíboMÃ~—î4i<Ñ90ž1U‰C=U‰'9oÂí-^¬æLD·¦Eä7Iô¼µ50¼,òi΄0‰7d¼÷*™Ðé6ünÊ'[ãõµŠþYWåKt[tUé&˜~Qô×8M)»I££w·wˆ#÷¨»‚î^OjÖ³1o01vÏë’NuðfðÎæ™´'ø ÊE2 þݾʶ²§ÑÝO#ùÑ/–}¿·>ÊOü±gñÆõ``a6Zì$Ag”ù¾TÊC ‡V+¢¸ãâ -;‘ -¢ô­]–è„Kš‡²§|Á¸IÈŠ/(yÎàõ!¯)PÂ[Æó<—Uå BØCQút’ºë£`Tu‰Z•=¹%Þ²žñE¡5R„õ–oàÝÔTO!•eð\ ÝÄß—M½ž‘{Úh{„@œ¨ÿ_#`¡º¹`6&–_Žq9òùM.8^ÓØkŸéÔyx~|x8 ëÐêÐû:aøÏO¡½Œ|¯°'˜u0×ï˜Ìl -o§¾÷Pcµ·ž­¥>"† ÞÑÒÊ® ŒžÖQ¨™ž 5P~DrÍ› ÏC‰z*‹9?€ww¼àÏÿþôåóÇÿ¼a€×-g3ÅLfähg¨ð*ºß†«Rn>½~6æ|â C¹¨D97ù2"ó„%BžÕ®ç&/ÚòÞ*d T×qñrn˜q²YkÞ»ÆJÍíýR7 -ƒ÷Ÿè—¾¸VsAOÔb±*Zšøš £á*ÜдVÙ'[º{ìÕ'i},©9B:u\þŒ™ðw}HàáQ=1oì™Î^—¾…;÷¨fFóÕLBјT3— |~‡ŽÂ¥ÓõÁ)— zÏ; »R3Ò\˜*ßc†}3¯uï99>ÂÃg‰ ƒCûóù©TâHY@ iFL·w!`Z`é–<›VAd|ÿé$ß<9K"5KøY¯ºþÝ´¡Íu΂Cï,ìü}|Ý2ü–:ûNö,ñ‘‡>£N>mpÃ2™§¯ëóÓƲ/û/Œ¦endstream -endobj -1735 0 obj << -/Type /Page -/Contents 1736 0 R -/Resources 1734 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1589 0 R ->> endobj -1737 0 obj << -/D [1735 0 R /XYZ 85.0394 794.5015 null] ->> endobj -606 0 obj << -/D [1735 0 R /XYZ 85.0394 769.5949 null] ->> endobj -1738 0 obj << -/D [1735 0 R /XYZ 85.0394 573.0107 null] ->> endobj -610 0 obj << -/D [1735 0 R /XYZ 85.0394 573.0107 null] ->> endobj -1739 0 obj << -/D [1735 0 R /XYZ 85.0394 538.4209 null] ->> endobj -1740 0 obj << -/D [1735 0 R /XYZ 85.0394 504.6118 null] ->> endobj -1741 0 obj << -/D [1735 0 R /XYZ 85.0394 432.7569 null] ->> endobj -1742 0 obj << -/D [1735 0 R /XYZ 85.0394 303.3232 null] ->> endobj -1734 0 obj << -/Font << /F21 658 0 R /F23 682 0 R /F39 863 0 R /F53 962 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1745 0 obj << -/Length 3971 -/Filter /FlateDecode ->> -stream -xÚÍZÝsÛ6÷_á™>T™‰X€  ÷1ç|4q§qs±;×NÛZ¢-N$R)»î_»ØDJTÔ̽\<B X,öã· Êsò<Ë“Ü¥îÜ8dBfç³Õ™8¿‡¾7g’ÇLàiÔ‹›³o¾SæÜ%.Oóó›»Þ\6ÖÊó›ù¯“‰LžÁ bòêòͳišg"\¼ÿúêÕåÏð;01ywqõÓÅD{ÿÌÁ°7¯¯Ÿý~óýÙë›ÈLŸa)ròéì×ßÅùøþþL$ÊÙìü~ˆD:—ž¯Ît¦’L+(˳ë³Ç {½þÕQH‘¤*OG$Ês)—eé@™Kr•*/‚ëËwïxMûúé6…{‚7UOv⺕çÆ¿rA£»§u5+–ô£ªšYÑUMM¿›;žGöæ‘$BÀÔÂÏ3¯îG“&ÑJg4o\꯸a Ø[:u’A-äÀE¬8G]¬M¬¶ò pæcµd$».7‹Vƒ°ˆÚ¾]³ËjØ u/Æì(‰\õø4’ ÒSy"Œu~íßß\þxuý9àG/z¤ø/ odz;¶WÌ \'Í:àôükçåi‚›ÒÀAÂy@" ƒé½”šÝh–*±yXÅ q²C~5„HQjVa!,¸Ú¶-sË+Ôtö[3 ;nê’#øQ éÒP•qSJe´)¥r‰¾n‰X—Ýc³ùHUݪ³’;Q/­Eâÿ°ÙïÌ|ç·ßâÿ>ñ4“‹šøCA4Šs¬›MGôUñD[æ§]lý Ò(ô ¾ã‰:ŠõºU{eGÕéo WüŠ$-–‚­p 9 -“mÃÏÖá$*V`øÏS³x©¦Ò`ÃT‹‚H^Þz0+wQ³€>[þH¡ù›ÈÄåµÉ,a¨?8(è”ÔUñðĦšÏ=‡ß(8|£5+‘8™†]Mgãv•ëthWcžYéÄY`%í`|B¾f²à™×äÍ ÜA L~p¶`ßœ)ðÿÒ O¾`ùözϽ-Ûª™9/~# |ùvïÍ—‹¢iAÄ£ï&QýöNuÔs9£C8˜ŽÁUp˜iq{ð\a€a|,Ûߟ+@î„ïÖt<\>Duš¶âéo‹äJ+5sî$S ¡¼ðÆæ >„ÆD 7"cäؽªÜv-QUá“S†™wVHˆ¸˜²WˆUÒæj/è’¥è :ƒe9¦v)¨]ÐλjYˆºïn!ÏL…é¹[«ƒ!Æé½²ARѤkuK„‚õv峸 ýô‘ž°W$BbÊj¥w¾¾gMU "«K^ñuG"{2÷ŒÒk ñn³;zÒ.šírNô[vëð¬ÈÍ0å%å¼/êêO¼Ò”&†'M –sª&ès¹[¼4oyüšã 0æô¶ì²)œ¤ÑÒÔ" S'³@™™à¶-%Ä}žgÍj9Ü¥¶ÅQ‰ó1%™ˆ-ªú!JSŸÀZ=m;˜¨YvrÂ~<Þ QÑ/áÓë.ôù¸$2Þ3À1€ö˜OU2É” †7]ûTç"þ‹WÖ ˆr>æeÁa+ÑU_;Y—¦¶çdýf|´‡¹Ãž³Þž5åC‡‡8UÚ%&³{Êvô0S»7!|ƒþÌ©Uy(¦²žú µ†d»à!Þ°:IXÀàÔ°ëÕÕ55h+Ø -[Á6ÄÚé=¨ôœ>QܼjÃOð`ì™xSÈó×’øEˆL·eÉPÜ š÷ýv—"õrO_v¨÷bÑNV±êl?TkðI.ØOrñ5¤/ ZÆÅsœêñ %Lší«°T¡Ê5\8Lô×G#—Èe°oƒ0mScA[pXÔ  -)¶;) ~cSÔ-î둾Ò:ºC“b<ˆÈ'ÿÿÝbÎN¾rv¨‡1ýÉA+#¯Óîþ;Ì«Œy•‘!p‰†õ#Æó$@ À‰S‰<8v¼dÚEm˜ù²£¸rÎòz D)û¨zÇÑ㢢0,#ÅTdWòkOýâòê» ~ ßGžÎód’H{Þ¨Ýâi\<å•O.ð?ríd[/)‘3é‘Ð"]ùüNiÿ8r\¹=<®Ýº±O+5ÜËuS‘\E™w‚z¼ç ûç.Û”:·ç*½^Þù0ƒÑM~ð15MûˆÑg{ØõD]> ¼£9Ò "“(‘à(P.~þîCB$º~@bX¨ªg´ÖW|ò žiß=dϧ[0eVþõv˜kÊ^ÕWèz>V RIžŠì„†ƒVíÊcã¶ì"z)ˆ`$^RTÜmþq52¬Dd=ã o1 Ø Y,*í‹èʱE蘈.L6[õ}Ù†¬%ä„ý£:ƒ5z³§!´ª¢ÀU¹WÒ…ÈZ…+Øå3¾ëÄi¾æ(yýãÅñÒïcѹ?d8ŘDùÞ4””>1;‘þEw °=ø¼é§qûU:Û‡†Éw«ÃŽõÎݪÝ5Æ1w ˜Q@ŽG’¤Cw+LQ0óöjæÝvI?ç ?³€n«v±ãoŒ YkÆÇXÈÏÈBïîæmüEŒoök¦mH2¯\zx‚ÿÂpJþ õTj.K#yU¬×äeäàöÓk4(@kÏ3“v/áRG´Õ -œk,]IvfRqé`%ýK»q—Ž8$ÏNW`rªi¿ò8îoÄ®’Zñn¼¯ö=¢¢²•p‰–j¯r8¬8¾†'ßDï®›!X„‹áçt‹íÑ, zãð.ÙÄ;h38nl¸X6(ÊËÆâby^2^Ü• )5ÀÄŸ%åŠsÝ¿å$Âņ°gµü"Û‰Íâ‡#Ÿ) ¥Ò¨ÞÝæC.‘.—'¯ Rü$âð¢MFPm–‚m¾n€º\l»f -0+–þ*J÷,ø‚¤/€D)ïãúµI$‚éAðe_'œÿ^fĪ0ÊĪ&¼)ÓDªŽ©ª§¨XI±Y£Î7K2mÌàæ–a×+ƒë»j-4ÚI±{!p}ïo>!òe]¹»é-g]õP.Ãw"0ä{¨ó®lm›þÊÌÄ8̾ áÑKa¼Ù„/z …Ò êêövÉCñ¼|6‹Cë¹÷¿6\Ÿ[\4O.>Ð×bÌœzå¿šñV#Nú+ãý íÁúS©X¥v<°ÒîN"-fáó%ë¹/:®¢ðx”öÍõåõsÞdÔ46ª\%jïz_ÃAù䣯‡‚jÇ*,#'ù±ÜLpsYÌÍ>Ž+’Q×¢"ié&¿øsÙÒ -”Ø¢/Û†H½m„ËH Ž0]um¹¼#"‰*ß+—R‰ÊõÔ¸9.Ã;ÈGtzX†«¡à ±Jôtäj£ ;þ۱ˣ,DŽÅª˜C¹—)‰‚ˆ˜:¾—èuÝÐgØŒé9|ûîâåôÝ«l,§ÌÒw"¨#KñÐx¢@u”'jáÑñwÞFÔÐ ñ`ìA<Å>s"Q2ïC=LbòÆ´õ>ˆ8Aø:Qä\Í€1ñ{ÍÒ"NPÐã¶hËi®©¯¬gÍœàSð…hZ†/h—<É}YãEN;'Ê-'0ó‚Õl -œÀ4d‹V ½K²Üì]½„Á…s¯I°Måz°“âcÉÝ‹ÐbKöýãjmÁL­8¥×BªÃ>]ÁãsZVM!äm˜¿§ürK?ŠvÇ€oxóEÉSy¤·‡‡ª­|0ÆØ8È9÷]Wáo»õ¶£ë£^=ë%+ý1 -ê­yŽvQ.—_3¤¼Ý5TÉ -weþ>Kô@yðÐd·cá„`bÀ€ÓÕä±ê#QD¹4ÑÊž¸-?ŸïP>Í<öuZø²JaéL}.%âç+ÿó§ì»õµI”µéø‡W©±‰¶0 3å ‰ùá÷eüÍû!ëÿƒî5äendstream -endobj -1744 0 obj << -/Type /Page -/Contents 1745 0 R -/Resources 1743 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1589 0 R ->> endobj -1746 0 obj << -/D [1744 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1747 0 obj << -/D [1744 0 R /XYZ 56.6929 752.2728 null] ->> endobj -1748 0 obj << -/D [1744 0 R /XYZ 56.6929 504.0748 null] ->> endobj -1743 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F39 863 0 R /F48 885 0 R /F53 962 0 R /F11 1299 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1751 0 obj << -/Length 2762 -/Filter /FlateDecode ->> -stream -xÚ­ZßoÛ8~Ï_áG»QI‘”Äö!m²EÝ6»I=´yP,9jKYKNÎÿý 9Cê‡%åpw(PKÃ!gøñãÌ -_0ølj -˜Ðrk(ÆÕbµ;c‹'hûxÆIçÂ)]tµÞߟ½ûUÄ è(Œ÷ëÎXIÀ’„/î³oËËÛÛëÏW7_„Š-ß犱åï—Ÿ¿^~BÙí¹——¯ïà5R,%nÔ"¶¼ºùxþpÿÛÙõ½w¦ë0gÂxò÷Ù·¶ÈÀïßÎX t¢¯ð®u¸ØI%%…p’íÙÝÙ~ÀN«í:€I ’0A c(Dš u¾É÷f®zÙlÒÆ<%Ë¢FÉ߇|_ä¾”yžÕØÞT(úQV¯®oŽM?ò#JÒ’ú¥Û§j_4›õ%+Ú[yÌ‹ò už¼BDË›[ßß|¾úÙ)꾃YUæ4ÈÑ, rÁy • -íôž÷çݸŶ×M^¢ÈBkÙiû¤;K`Ó´ åër -ê<æ@ˆÂìcóf¢–Q±”C³øðõê–¨ Žk5Øчr›×nåJü½üë×?)&Sì¾ñ3Éb~¡¡n£zAC¹Ä«´¦(žâ…öTe‰Y¥?0ÖzS4 -EÀB½A£ŽÖ œ–§ÑËê„E!,wªyÃ^ëÔò€EØ&’¾id‘ô,bÄ"éY$=‹˜c‘ä=1Ç"Ùe‘J ã9 °…SÚPiÕŽe“þ ŸŠ¶ªWÊ$‰/@»m˜’x2ÍI±  )C(.T?jt*ðVB -™+î`…†€TãøÅ}«Ÿó•¯¼my•Ž./„Ђ’§O†®¯ýÓtÈH»`–Tª6…­®">~ VB pGõwy³z·Ïëjû2u¬Ö°*¦Nh'šÐIÑLàyÜ’½þÊðÎÊPˆ\AŠÆð­}¬¸;z „ë$€³€ó÷'cÆ?uÜ‚ZQ‹h¬Ò§$žw÷ÕàTNî)±%†0¿§ºZÓ{Êkù0ÙÎb4LÎoÃä‰õñ0Ù3oS³ I65ƒS³‘`j6Otæн5 ¸¢¦%Ë ­K<2:Žö¤>œª0ø%Fã8}ÚšæQÚBN‡g¥ˆDY:ã®ü¡°‘Œ·‡Mfø‡Uã‘Ξ½l܃@y:åHuåý£;ÿÛ,0Í2uZÄñ,ëhÍ°Ìiµ,ÛT¯L‹e3ñ†^ëÔƒÁ…—†/Uß…[Ì[²­ ¥µ‡^)=ÛÌÀßgÚó$äÁÏƾb··SÓ3sC­ß‚¸£5±ÓòÃ&FŒŒ™œ·îµNÍ÷ñx+÷í_åîr"mÏ+ ŠŒ„€­û˪<îÚbr$âšó`ên‘<Î"‡^‡Ô0o@ÜÕš†ØkyÛiZ•Ûãd¬œ5ÞÆÊëã±²gjzpqgJë4mksYÙ9+zeCiï9Í‹%‚ýJfIïÌfªQ By%üœ‡Íñòñ@Í81xHéøÒ --Ø»ãžή3®o¡ë#ëXÝÿbð楀¹ØæM^B5<Éa®Â Iâ7Ît]­i{-ÏáÕ<‡g·>±>ÎážyËa`Uð€A‰Ãæ #(<|¸Â_ÃáÕ&_ýÀb$YQ›ƒG†46»XæÁÆáî(=K&èÉ4uîü¬$l{ùÆf¨j”Âœ.öû% ¾\}¾»»þ€Ï/é¶ÈÒö R­{õ ryš -LCÖ ç©ÐÑš¡‚Ój©°¼!œ5ÜÞžX¿!왾Â/†SÅ!}P|$ÔŸ.ïîÜ…l^v>Ãù"ÑëRmä?‰L€ÇAGo`ÛQš†Ö)µ7‹ ¬ú ¸R ìˆYÃ^éÄrZ ;8õLÿwÈÞßú?áêJe˜¿æ™óäÿç?iÿ$FÆ6Žãd?A†P6“S&=÷]rêú¿ü£®uendstream -endobj -1750 0 obj << -/Type /Page -/Contents 1751 0 R -/Resources 1749 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1754 0 R ->> endobj -1752 0 obj << -/D [1750 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1753 0 obj << -/D [1750 0 R /XYZ 85.0394 695.9587 null] ->> endobj -1749 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F21 658 0 R /F39 863 0 R /F48 885 0 R /F53 962 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1757 0 obj << -/Length 2840 -/Filter /FlateDecode ->> -stream -xÚ¥Z[oܺ~÷¯ØGITR¤(©@$=ÈA{êž8hÄòŠ¶…h¥ÍJÃùõrHŠÔmO[ìƒ(qÄÎ|s£–îüè.±(’b—Ü:a|)aJ’ïW_îÈ®¹½"1+òt÷ 7$¦E‘ìW~HœU¬e»PE¿{Êzµ3ETž‡îPõWUSUÝ—÷¬p§³X)Øêó“lÑ}”>µÔ©/5Ëg"5R¿jû^–'PÇ|€Ñ$ÏíþºÓÂbÀ8NM¯†S¹— +±Ø¿^€-%EL“,ÝÆmAÓ£y8fÙ¡ÃëWB’¶²‚H ŸºS=&˜GmyV Óy2Ë<XÜ»ˆÕ< D'‹UÌ ?»V™›Ѿk‡²nu„±ØÕÈAmºîx~|>âµTòªIp’cS¾àS·Î§¼Åi㎾V–ªpV–:2Œqk8ÿTêhÊ œNox”jk«ø< ƶáë­£×9ð: ‘‚‹<ßdìˆfœCô$4æÿÖAæ(Àî f‹B`¶(,`PÉF>–Ô@p,‡'œyÐVéÁ mÖu>6 +|Ðt@íøŒ„ˆDp»<%ih? (…ÙóQ•"”©M\ìFœóåcÖOï_ÌSÌ1úåÄ9rîéÂ[B¶z…%f$‹$¹ìÃ.÷ÊoÒ¸^=È“sÐÜf³õ$…ê ¥¡jŸO˜qŒ¾kô» 7z„£GT³NeðUÆHôqÀÉçÊ…¦Á›‡®iºgŸÉƒ<ʦ7Ó£ÍÀ1õlDÆÒ*sHúOݳÄƘ‰KB^¶^;²ð|F¾g1à¹ìÇd&;?xþ®Ô¡Ô°âñiNcQ~Ûå}ªuŸwTÎé÷‡jæòUÄ8;ª9ënWxÁ'¼G¯W -1‰`ÑñT·†kx¬€7Í¡â«…²Áû}w8Èv°““źóp<ÛÉ -èꇷ¶£RðÐÅp\p,!bFT‘¿]Ô¥µ4*©h×á­,›8ŽµýZA3Bê©´€¹—¶<+ǦVE8*1%®z>*#5Å \µB-ï 3qÖ@uWÂX~tÕè,•8áiXÍ4›¼ÇT3c¾œkî7èÍ? F“FÝRõMø?ã‘S¯ tj׺·Öòıý8R·C€Ü}gYBú9¬[‚ˆšÕô‚%<ª KX*g ë«ë&û±`ñ_.X>=éÐøEç_p¾ªÃ­Þð@…ë;|†áop®¬*T{œÐuœš9*xáBçý<ÙJ»ê(X˜[{a/˜ÅYÎ$–òµ)S.\Oã`>íi@¥¶;²5:,«s<\MŽŠ„Fð)®§‡ -28B¡Í{®R78†Óª\€V×`“¥l³ÏÕ®¶×¡ruZ6©xzm·é}wÖÜöù¾iÐLBÓ¨‘5Ž}ÓÓëqtßjÙ×´Û®x‡ç‰6=ɧZ÷$G5&RŒ½ýª'm²=iÆÙ“ü:ÐÊØÐxJ²DS·²C”{³çÿ­BÖ푘ôB+îSmØÃR9šÍ~5ÇlòsÌŒùrŽ ¸›tÌr—Üah\W÷¨­Vxu¢À«ÚEÝõ¾ÿ³:Çá*AõÓN^ö8a -ƒCYÉת ¥#]_ÿ”ŽÁzOã€N|l^&^Üswí&:î%T/µmpÿHÊôê¡që«b˜ŸB$ÝDOµŽ Gåôý4å[äqÊ.°54s®“ª˜Aõœ±íͨ‘/•Ñ’ŽÉN]wëú²­G=qÍœÐXé]Xý½^_̾rß8WcûhF/Œ>Õ†),Õh -•Ä”­×Möcpñ_®Ö(ªNÑF±õ‰ëV”QD2öNZ}×Ëýxƒý Óe RjÃоÂ:¥¡uå#Œµ=„m‚‡ó©ÅòŸÚõÖK–ÿºhõ„×àÙ7aeà×!ATã“ñ ð¨6 a©$Æb-üÖ‘@Zl›¹£šsŸø,æ 4oû÷~Rû©É¹wÍ@ U›–ËiÈ5_1þxò ²}½n˜$#1tD¦OµnG5ÆœõÎ{ -¤YA·ù;ª¹¡mÀG™ <”`´ ·¶áÖ6<° w'Å$EÖ·£yXæáh¾d’ópß<ܘ‡óðàtyÛ<бæE~!”úTæ±T£yªªV»+›¹}„úÖ’m à¨æ„öIUÛHà™GXók˜'³æ‘'²¾íÃ…±@ûˆ%ûÖ>·0öÆ>™³¦¢ˆ3–Oê¢ £Ñz?Â/ÌûTëFsT£Ñšfõ”n“óxJ7c½|Jðþ$M¤±%ܾ‘¥*‘æQç+!¬|\¯Ø¨à13<¢ %"üzXä_nWʵ-ž¶Z›²\.Ö|ž ›÷Õ¤€â¼Ó'ŽpŸv`PâÅf{EÚ-}…:%K3{|»ptC⾆‚tmÕ‡A(ñAŽ2¨A|¥x ßÛañ³ž“Ó ƒÚRPMÂÓÍeÁ¡£²g£6a5î|z|“©9I¯-¾ÌA˜õ“4¯h÷ê¥UêRng»ïs ;I]Ã+tv"#zTŸj±–Ê|ð®e?ÇìèÖ[œ=·ž²^qkŸ·®ýÞ¥î0Æ|tÓ“ NK×™«V5 >¿¿ÁýJ¹Ó|6N’²¸ 4ÝDz‘¤¹!¨Û~e5‘Ï -ïýEpÌÔ#x®NÍ\ Zö<½È×~«Íç/¯}ûŸþàk#¥ü~.›°<û)ñøjÚv-„¥ú}\Ý@µm[q\êܺ“0ý1ÛãF×ÿ‘ÅI&.TÑÆ ‘ôI:6½ÅvÄó”ï2œ}ÆÍÌsÐQ£0Æ“êЬ†^M3…''Ô`#¦=b‡i|¶„i.Æ‹Ml%Y1ƒ´/¤Ýס³4Jb<üù¬Ž~šúÛÒÙ3x‰s^°0cœY:„NÕÿo¬'8LZ´UœÔí¾9WÓ#FýAÎBÝÿûÕÊï€/_þÙYçú¿ÿ”7þåg1×¾M&¤%Õ2¡”&Š|î7$Ndݹèÿ3=ýØendstream -endobj -1756 0 obj << -/Type /Page -/Contents 1757 0 R -/Resources 1755 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1754 0 R ->> endobj -1758 0 obj << -/D [1756 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1755 0 obj << -/Font << /F37 747 0 R /F48 885 0 R /F23 682 0 R /F21 658 0 R /F53 962 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1761 0 obj << -/Length 3318 -/Filter /FlateDecode ->> -stream -xÚ­ZÝsÛ6÷_¡™¾ÐÓ -!¾HâfòàÔNÎmš¸µÓ»›¶”HÛœJ¤*RNÜ¿þvDŠ”|Ó^2 p]¿ý¤ø,†¿|–iK£f©QLÇ\Ï–ë³xöïÞq¢™{¢yŸêÍÝÙ«·2f‘Ìîî{ke,Î2>»+~‰.nn®>\^ÿû|.t½açsÇÑ>]¼wc7çFDï®n¡›èXG²$Ž.¯ßÿv÷ÝÙÕ]¦/0%JòÇÙ/¿Å³äþî,fÒdzö:1ãƈÙúLiÉ´’Ò¬ÎnÏ~ öÞÚ©S tÆ´PÉl®‘k’LSÌb Ûž§ -×R&“ʦŽÉSá1}]M×¾¾<Ü.—‚eIÌgý5GœÕ˜µ=Ö\¦,Sü€÷mÙÏ¥L£î±tz·^”[l'QsïÆP>O–Ó„Çü‰ft{æ›MyΣ|ëºUzõV÷¥±aI¦ÈŽìë|]:ª¬"e"I8Áúã…¸`±’Dq9±†aR -E÷ªëËœD Úò©Ûª€}ó,* ÚÏ¢mV»®d¸úl.²„ ÁñÈ93Z »ò=7 gTÞç»Uç:OùjGãUëžtr–ò×8µeÝ][Á©ÕžŒæÕtèÐl»¼+×eMóýÁJÓ?²L1Ø¢ ¿*»å«m xb°·û©Ò,QÜá7°v¦"{NÀƒ+€N¢ºqg S ‚­΀DF[Qa7$-ŽTôfÃp¼i„iá5è¹R*ú ’ÏU÷ˆ-Ý—Ÿƒ8è×V,¼Z¶îÊíÆtx”–‚r뼫žJ÷¦ÞsÉk¢þ\­VnhaA'AÛræ«-Çå£]Ì•…6à -ìÓÞ6ŠfWuë:«ªíü”>åøÖxš±Œ§¦Èqù8qW2cp ^k@Š‰¥8˜íWrò]É«VQ¹£ZÒI9Ç‹kÁx"“¿ -.6²äd.“T‚š&Ùi›Ú§:nS•µ©‹Ý}[ýY¾~3²ªJÁ‘rOòTcæC«ª KM¢‡Ü­U^›±ñéòÆ5†mþ@£ $ÿ½Å:*:HŒ­$Ê‹§rÛU­ƒ‘5h!°yuùá6¦å§,£HRtÁ,o&n<šL=Áâ¹+[†&;kfÅÌ¿TëÝÚuPcœúsÍTªÍPý×UM´©±[h]½>»ÇŠFû…þ^£¡“h-5[…F쎬Ý8œ®žÏ9çŠlÒèg !ÐÜz®»-ù€uGÛÎ[^Ð0¶ífWe1ev§^÷‹æ3é48<7w³­ÀB÷äâñP.œXØz[Ó -:Ó¸$h-ó]Kú˜»Þºký±+·Ï´M\­3«ÇtgLHi^еÕ ]óTV×Ê¢n_5R4‘0€¡>Í8P9„/hßd6d} ¨îíid^Ù²pVYJÔVMMï÷ ˜Yc¡¯ü}UÍ W—õÐx¸˜Ðš¥ïHIOÊâ‚ ÿ¡"ýÿîÿÐ7hô6>8øºnðÊ& X=)áÝrþ¨=ðtî,Ö¥)Z -H= -DŠ2ðA'ا:Ä@e÷õKÝü¶† ¬ZUu9Âc’±lëiþj,À`ïÓ81C n¶Æ=JdtNËÆ>‹Ö ®ªßKײç‰ÛØH§'`ø€ÏÜ=àhMK3íNçv«¶ÑÉ:'î.”ÂÖãn×s‡ºdNb3´oŽo^ä‹.s†×¿¡SH휎‡;hXdlˆAìohë0TæËG78Ü“CuDªÜuѱ9Æ"½@ ª¤ ËÞçK¸M €ÉÖ¦ËÝj§>+)`ìœO?î¼w{pŠC.룠‡ ]à)SRyp+›Ýqãª9L̤xÓ=ª˜öTÓ÷yµg‡:Ê49Í:PyÄ1â3ä}‰I’‚T¤é\£CÃ#¡×¾*¿Ð»¶Ü>Ù¼QQÚÏçfçè ¥2ñMî·W?kýüö÷±B°ÚÈwÚÔ¡9+‡ ªQÓÈT·ÝnÑ'ǨØ/¾(!K®ý°»£ÐQ)x@©õièô©ŽC'Pè,JÈEîÁ4t#¥ -,˜|A€@5–à@[lb¯‡"\t¸n0Nœ¥ ˜‘ªÝ¬òg´‡ H$:4:ŽÆž4ŒR¸Üºž¿¬„÷|2Rå+4~eañC _ü`§jÉ -BÈ.3=Ä„w¥T6Ì RB'0 Ÿ\·Ÿ¶Ç¯P—diú•ö¨N\©§ -W -®»-—£ëÔ1d"";Í4s×z‹‡‰‚§TL›P:ûº¯òk{!¨ Ũ¹€e¯lŠ Íß_ýÇ8áZ2s0†±Ö%À6†Ù—7UçS~_(À¸–…Õ@þJgx6ÅP(#ÀšµáP‹©°Õ`Z¾¶ú<Ï8ÓhÕ4¿;÷“ÅCBò>[ßëAŒÁ¿)NB0§~ØÅÉÂ4¥ÂËüòªF°„‡TÕšhã i ÿÒYJh$(o -.a*£©ƒ#÷5Φo®¯âÀNÙ‰à îÙ){;­I;%R4¡ÊÌ@jÜœüÛ–*¬8ï/9VW¦%å2ÝsþŸ¬•HÀå'æ… ¥OuÜZªà±ºfc g£¨%8#V§¹ª1û·ÅYªy:äÿ/æ\ØJ~N"7{'/÷N̵7åÃ?×ÉÝtØÐœJÜ–‹ª"ïlٮǠ&ºb&ƲX§Có×0Ʊ®ƒ7­1}Súïc̯8ï/91Tk%ôžócÖv…-Þc.š‚½6äaàEÜíüðé=¦Gw×7ï¯ÜVütõÓõÕí„mˆ,Ó©Ù{î½¹þp‰-7P­7+û *§øMÙrôØ¢b~¬Á_¬pãëåín³tªuœZWt¨.¶(³Y‘`"V(@í-ƒ¬³¸R·Ê"WÇÁFº )Ù: ÉMÆåÐÖ¹ýÉXº´8V^>+‘ŸþòsÐèØ»ÏùÔG®˜I?›EÞ¡ÇDè Îy„»Än³A)04Çoz)'ߊÌíd émÙ -‡Â™àø2'éå^úUe¿Â¨Ã?Ž[§jWü\¥ýtíx¸â ‹…9Hì@V™?´ßK¶¢¶>+F%U"˜öÖx)Rú¯ -ÐZBÀ+ËĽÆ_cR ˜÷Ο‰r‚‰8óíRÛ‡}C6ÎŽÐ×Î6 ç$OUÕSUìlÚ"EØŽ}åE.Ib‡9*âHû jòŵ‹²]n«}™ó<WŸ¼óEóTâ¯4À¨ÑM‹Ø}A·¹!öì½sü’óÜ”=a£í@ŒÜGTHî_Û»ÁÆþþö?S€aûË·bã¦/¨±NI“wšga&üõæ«©=ýÂúó¦<ÀÈr•·‡¸±»›PøÒCQHûØìVÅ0žÈ=Ôûµüý”ƒüòw«fá.>u*!è‡ø HH¼\­&TRp’—Œ~Ͻdô[ ;h£IZ4˜–Z:âû¶q3ü2^™m*hË26ƒ -’z¢ŠK"K¬@`á×ÆÛÒVš©šX”A»´ud0ºÛ¬hÜY!aAƒ€àÊ]'µñ¶mS÷N _ô°=ÉX¶;Ÿ,LÓY*E>@{ ú>@SžkeÑ……„û…÷þ:•êÁL¹ÚHùeYÚJ›RGL¾È ‹yøMŒ Ë–ëb*aŠ™Ð‰'Ü›w9§M,h`¶Ûª(ÊÚ×\¦I– Õkñ<ø e÷2ùÎÒW\ºaµeÊ4Ûï«oý÷ØòKŽÞþÇ~-&!s—r*®ŒCxò·I¶ÿœJ™Ä¯ï“a“Œ!||Æ …çb̡䃒L¤¢ÿJZÓ endstream -endobj -1760 0 obj << -/Type /Page -/Contents 1761 0 R -/Resources 1759 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1754 0 R ->> endobj -1762 0 obj << -/D [1760 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1763 0 obj << -/D [1760 0 R /XYZ 85.0394 204.5196 null] ->> endobj -1759 0 obj << -/Font << /F37 747 0 R /F48 885 0 R /F23 682 0 R /F53 962 0 R /F39 863 0 R /F21 658 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1766 0 obj << -/Length 2180 -/Filter /FlateDecode ->> -stream -xÚ¥ÛrÛÊíÝ_¡‡Î”š­÷Æ[ßœØÉљ۔9í$y IÊâ„E¤ì£vúï»4%Ñ£t:| ‹Åb,.+&>1ñÄ2ž„±f>þ$­.øäæ>\K3sD³!ÕÛåÅå{Nb2˜,W^ãQ$&Ëì‹÷–I6Üûõn±œÎ¤Hî]ÝßßÜ^Ïÿc4@Á¹÷ûÕíç«„»ŸÆÒ»úp³˜~[þvq³ì¥J,¸BQ~\|ùÆ'þÛg*ŽüÉ3 8q,'Õ…öóµRS^,.þÞ3Ìš¥£œIÈ1Äc*Ð! ÂTÓYçûåÇ–€ççgV´)k¶v&©÷Ìþ¤¿!ãð ×­eW7ÀÔsù^ª|2S°RÆ¡Ù¾]7Ï°B†ÚÈÒ‹¡ÐŠqÎ#Xç¤=å)ð<Ê·4i³+3bùÓ×æ³ÚNEä5ºµ%H›ªJjKSµEw ý«ä»Ã¬ ƒÜ˦ù¾Û´›Î”¢{uûO~ìòíÞnÜXm˜V±ØB+:ª©&3-c€ÙgB/Í´Sô©´`‘V²yâ¡—ÀO+~Ê·mNaí5+ LŠC£ œ·<ìAă˜)£<ÄÜ.†¥ùgm¿Áé±e¬X±•÷gÏ…71†ûIÛ=–ÍCRÒ.$ŸÑœ -C¦#Xs ºfÓ ˜Gñ¨É?Ø $âÎ…~u])ÀE/31K6›²È3T¹”^Û¶['݈3G’ùQœWœâ“ŽÆÞâ™PÔEW˜“ÃÀYñý«$³”d+ò$]DÆMêH{Kbz_9—õ!K£LøL8N™3Ö ^Ye¼e“âZÇèTnà1• sTåtþJÀP’IñrCÖžyVyR[9^S7x4†s±®gàØ¥=HÝtl¶Eݹmrz ùy›+c RMóÝ - WÎèTBøõC:(ñ†Ü‚· ÿ'· ‘ãQÜJk.ÿçÛä4Ö˱™¤f2ÂÈ£|‹XÚùõ- °ø|÷iêûÞr<¸KŸÉ8hÕjÄ(1ÿóñ\E±39y›¼‡©€À[ÛÁ®(QÇÚ£ukB’˜€úÊ}fË·u‚N˜”Å¿Lš¬©’¢&²:©r 4Óî6›fÛ½¡‘± üÓÄ'išo,’r ³¢Ý”Éž°uSϬYÙ?4ñÕâÝ|ŽWLõB(.-Ñ”à.ÀsÎé*¸óqˆF”àÀk“./÷´]ÚÔÿ»–6L×É6IA94™×i“õ#LB‘°ùŠÒŽÛ¼6K)XHŽ‘7< #‚غ3Ü•¶#„É­Aä]‡D›oŸP&„û·êA„÷H¨~?46…^) %åAr ‘“¶©1[(8]nânÞ%ò?½ÜP*1J—špSr¸²±OüP²@ƒ?QvJGQ4^tÎzŽ³!ËÓŠRrˆž‘_vF¯ç‹«·oÆϸÖ.PåõSAf««c,*á)Ï}(sÌõÒe(PžÑ¹Ñ§Õ¹˜, ³à'¸(³Øa­BÁ0±ÕÔQÄu;Q`+l„móŽËGr -ÔeBž_Zig±í4òvuûJ¸ r…Û÷óÔ[éû(¾^æ]z¹ÍÛ¦|bpÅW½FL„°?Òüåß¿Þý~óŸK¢nÓ1¸Û›,nnHWwçcüºi;Œ¶ãèZ‰ñ"Cd4@fuÛæéì{¾ÌëÁ¤ÙA[5@-¦{ý}zÿZ)¬4ˆXè÷tã -–Duê÷íç‹óGßs± 6Ì>€í Ó5 •é—r•€T @3¥gÈÌpÇ×”NÁ/ ‡BÝ:›‚ø¦,DŠ[ŒÇãâC¬PÖòfµÙü«”!A×®ºp=»®(‹nÿ3¾±¯›M Wå()ÁÂ(PCÆ‚›7Ö¦ -Tú˜¨Æ{X -7tÀâõ¶§z9(6_fÉ»¬¬·íòùé›C¥c¥§Â&A»Ôš–IÛŽö)ÌICÔ3¼aZŠß¹b5Ý«üÂø˜á§ó wÕC>Ú@LJ-Ž9vg9vûÍX¶‘ -¬Íõ1¿?Îò{NŠîU~ªçG-Z zŽË£/³jd—CVeò8¶‹f:ŒN´ {(°U2G¥Á·Ñ *Lâ0h\ß,Þ}šß/çw·#ya$,Ž·JGÃÒ/–4øk‹jƒéHÄQ'Í„©%Øä[€+S¬áØ\gì;$MC®ìëø×°&)KËCÂzÿ¶<¤M9z8?¿·rfÅ@ˆä­-tí,IÕ1”OOEj 1|~HL ¦¼?¨Klmk@ -­;,Z[ymíŸçΰ ½Çâ)¯ßŒ˜BB”àÚw>óš)$„Jß]nÓå¹]lí¸6e†wU•˜Pû6¶„,½{<"…„ø¾xÜ1Û'¥>‹¼QF]'IÂ?Ší”Õɽêñ mï1LE#¸-[è;!ìE é¤#¨_Ð̓¥@ç2ÝÀæé@Æ¡ñ1DP{@R¶Gë·m×åÙ,ËÓ¢2=3àæ÷Ošˆ>ESÆð/«Ó¦vUü%jØ÷˼,ª¢3¥Ÿq€?dlÊmèÉkš±oHž&m>ÖyA9«e|Ö|!_çÞ¶ÉòU²Ã‘öæÒ !‚Ç9À÷sSÿÙçèD쵇gXøZ<’byáþïGé—7wzô’¬BôŒ¶B¡š ®9Ý=_ŸÊþ_&øûÒendstream -endobj -1765 0 obj << -/Type /Page -/Contents 1766 0 R -/Resources 1764 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1754 0 R ->> endobj -1767 0 obj << -/D [1765 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1768 0 obj << -/D [1765 0 R /XYZ 56.6929 626.4701 null] ->> endobj -1769 0 obj << -/D [1765 0 R /XYZ 56.6929 517.4334 null] ->> endobj -1770 0 obj << -/D [1765 0 R /XYZ 56.6929 438.0429 null] ->> endobj -1771 0 obj << -/D [1765 0 R /XYZ 56.6929 376.8269 null] ->> endobj -614 0 obj << -/D [1765 0 R /XYZ 56.6929 339.1376 null] ->> endobj -1772 0 obj << -/D [1765 0 R /XYZ 56.6929 306.6767 null] ->> endobj -1773 0 obj << -/D [1765 0 R /XYZ 56.6929 271.6646 null] ->> endobj -1774 0 obj << -/D [1765 0 R /XYZ 56.6929 207.5268 null] ->> endobj -1775 0 obj << -/D [1765 0 R /XYZ 56.6929 137.3205 null] ->> endobj -1764 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F23 682 0 R /F21 658 0 R /F53 962 0 R /F47 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1778 0 obj << -/Length 4061 -/Filter /FlateDecode ->> -stream -xÚÍ[[wã¶~÷¯ð[åsV\\ì9}pö’ºMœíÚIÛ“ô’h‹'©);ίï fŠµÚm^ºû@hƒÁ\¾ÀòRÀyéL"tž^Ú¼»}{󯫩2bòMr55BL¾¿¾ýñú;¢}¸ÊÕäúÛwwø3SØIa·LLþúÃÝýÕîÿvñî>r³Ï±YùtñóÄåÿÛ…HtîÌå3ü‰Ìsu¹¾HNLªu ¬.î.þÜ{ë?“€Ñ.1NÙ=&“'™VÚ‹ -·Oå×ñú½Úï­óDJ«` -ìVµWS­²IQãÓNšMW5u±bêöJºÉãn]ÖQž—Õ|I]çeÕ-a&OƒëbÍ­†_Ý|à1 ?jÙò÷ÍÃÉoyüºèx9r°X½q9¯gÙ´ÝÈ¢§©†³HUÊ$7F‘–Ínµ ø´+·/Ô¬ê¶+ ¦#{øôìa#0å_n÷i-ýXUðù" EÜè|¥³Äê<ìÁë²›¿Þ–m³zJæMý0Â?,2K¥æìq9ÕZ%Ú s9Uа–tÿø<žR®g6HiZŒÌ!Ó$Mã.¿#ŠÕ -’—ê5ƒWÅ+-?íª§båµÃ˨ â躪~ì7ÂPÊ*â’¦Og9Úg ¨Y¾Eû+Nt¬N%RKõyµP2qƆ ÷ëâWÞêâH5¢6¼l¸Ïõí¿¯¤”qS`Ì,ÍÝpSþ¹,ÑÀ¤>!4ƒT‘é›1a€ž[™‡ô†Ï][.^ˆ$-”–gD¡’Ô¥¡ÓsµZÑ EוëMÇÌ7øT“EÕnVÅK¿"߸ûášdßóÆ?Ì݃wÐø½©YfÈ€L@Å-sàÀ›Ö½×ƒŸ¡Y3«g–1X½€1aíÁêi3‚}j•NŠ]·l¶UWtÕSI¤à~LoÕH&þ¡á‘oáJ0hhí­ÎÓppúšüZ?^:ܧ™,Ê_„Pu`höfánï¨ß¡PqbèΈ3¯¸Ô›~<4»`.ÁaEoFkàÁ¾Èä6hÉt>®§*ÍÕTKïU·Wn²›w¸tMîßÁ!¥ Â[¿hh å]ÉÉ ýò…ç|U´í˜ -I‘XÜnš|¯ÛP‡òĹè q‚åVÌÕ¼`†g%=Ñ®† ¯šæ×݆h-ÛªY0ƒ[Ò;eMâ¤PÃíy³,š¶.y‹ˆ;ßäxØì|c^îSã†'¨Û‚ _/ʇb·:,øæ›[z¢#¿©»r 3£7?ØlÏÙOÞƒ•ÛYÓúÑìºÍ®£6h'e]n m5õØ×H€ÆXyÖïæÊEgã#yÂ9ê$ƒp”n1)ŒÌ‚ÒmǦÔ&;n`ynz  &$´Õ¼ÀósÃ"ópÏ=´{a’ƒ„/2 ûúCb”IídY 3R©ô²Ú†|ÝSµð2fìTÌ}.¢·Åwóf½Ÿ6«VU÷ÂñiªE>¹ W>UÍ®¥QÐ5U`l°†WDßmRV™>³©Œ'ŠæmŸ«n¾¤%ÀrjŽš™Kɘ¡@ål÷ø؉m1/Û³–[Е9¦(ëb¶ -Xí©7ÁÀû%¥Bi‡ò;ïê`Óu³(©å5žm¹*çd*Ê›Šž€B8¨Çl¯ÆÙV2B!¿£Ásy6À¶cX(웧gm2SGoÊ-¨×šÆ-èá7­c[ÔíƒÁ*èaèpì–%°ٙȮ“\Š´÷Ê~mW98BžŒB:(ˆË²lÒ)œY2ÐÚl«šA(zfïÌ {ÞÞ¡–ƒÿpÿ‘(*±±Ÿ¢ áÐ ëõëkøGnÕoè ö7«|PÇ_ óË1K²¨Œ*;ƒÊ•1a[<Ä9É‘GmdOÎ%æ•{š±n{Ñ 'ûò°Ùްª1Faÿ´8ë2w“vSÎ+9h¼ 3NÁWì„Àó”D ÈÚÒŒ÷ØÿæÃSF”½)¹SÈá°ã. ãw7²äæöž~,šuQÕÔµàÏ{øÅðRn¡íª8ëøøþt`LŸ‹Ä!ü†db -rrý‘ê_!y%‘G³œÞŽ#.mÍäJ5æajÒ'TïÖ3ŸRÑã) -š¾›Ç¶@£äi¨9ãABV{àM’ju¿ë؇ 5Ž×ñT ýžñÔ ·ïhËô®˜A¢¼ë<ðÎeˆT^Þ†°7 wˆÁ;Ü øÌo2Ck‡c‡]K¾Ã÷)©Q“ °ÙBÆPRYÄ7šæ›¤V™ÿ5ÍE>Ð{W˜RÒ£z )ëfœ©)+²Ñ‰46ÔdæX9T.à€Öƒ˜OOnaçø¥÷[¾õP>“»w¬-ØêAˆ“GãÀGV†/‰¼â, )u? ù]?woÊ‘§‚g[ÒŒ‘fæ£)B²w ‘­Wdë9aŽaM'x ß®ØáòNVvÀœöVv0NÕ± PhÂW˜lé'Y±šüø+liˆ ݶ*["°)Ÿ^Ác…Í ü¤„dv¼–EýHö¦X<Ž^Tˆ_ö…œ'<”9B/Ç.DÛDªˆÀÙU–0UÓ‡ª^TsP|^ì²yf!æºõÉ?韨ŒåzÒUëQ´ðÖ9§Ï–K”ÓÙ \‚ƒ’ì7eð*‘C §eƒn·dí&=–ÜÈóüØeªÇünߧŽ/|q*2Á -€„àí$uó0"ü©é[yà1No‚Ã=•{ud´Šº|,z ¦ô;-¥yu`z‘ù½ÊÚy °pm°2Ø ó3°™Û¦ž²åî »yâøõiw…é.ˆ-YpקŠævϳÄZ+wÛÚ Ýs“»P'¥ *f§á`œ+pOLï‚øø–¿ê&ÊÞ"CN¥ i‘ivÛ*ÆS%$¡„˜Ì0 #É{=öIȨ¾Ð¤€‘Ä@¾uçë­:‹É—OW7çiHb`ÒX“‡ÉÖeY)˜9fJp] I±"/"0.«'ŠßÇË Œ.3 ë†ÊÎeOaÉ"±Ñ×?á‡Ç'ð ›ÕÓh¾ËT©N¿$ßéÿ4uò´‰Ñ#Ò1ÑO£¯”âŽ9ºÌ‚£KÓóua2{%rt]­«9ËÄ+%4f%`Æʇø壒𹣗'A…Ý;˜Â: ¤Ü¨¨/ÚõƒŒÚõˆ!w”¬~x¡˜”¿m0R‡o=ÓðìU£  “m‡½º¥¯ÎÐØíW‘¼kw”½ŒAê™ë¶Xd ™yHjÜ"&ß L„‹.ðx7Ó<Yv~3µ >{çs(• l•âüáÃk–ƒ×Q}*C´EÄDåþ”’ºtDI©rá'ó¹<}â5Âßæ€TÛKß:â™ÔÉdƒféШ½ÕÓZ¤êš”ñ@Ϧd…y˜*Ç ‚PŠ]°°À›ÎŸ‡Rvàc±§<2¸/|OJñiWE%‚×U÷ŠOvþtU -œñj*Gµþ¾ÃEÞë½ÿØ×…yʶk¿®¾¯mLЦéxE"3ò¨¶g gúö¨·‰ÔÙùS(‘Åé½µX¬H¢¬• Ù4n><¥D -± ˆ^&›fë3«N-ÑŸ‡ÅrØ4û?^c°ÂkÙˆbÇÒhXù×lµI]ðìÓn\ NeG°ŽÓGçølD9òŸH!s 6E^ç"«H{Ù”cØ_Ú,6VAýëˆðn9¼ŒÇm8èŒç!poëêwâðˆ‰?£7·“7·×ß¿{Ed¬ ’'LpQ>´¹»®}G5¹»ù–[GÇ¿þ§œ òÈýПç¿HóI;<#+*œ$;®I¥¯—ç‚j@îáλziӀܖŸÅïSKSÌ_±ác†Í¶‚”Š…‘ë$ÍT>®}yÆ[:MSëã”ÊÍ~Ž’y—ŽD,îµD¢4×ôê žùŠ!Å.ŒðÀ3ã£Ôby2ýìñyšäBîÀ˜Ï¾H<<0¨yæè½}Nï2Ò3èJùAXI)S (Š9RªâŒ,P†,ÂWuŽMX!RsGBÌëÁ¡O!eúðX4_Ó(ÔÚ_ê¹Nßip‡KMZ`õzxkQ®æqdS\…=ønTA!'R:7gT[3¸p@~%FÛt(ÇèåCT¸·nì¤R -_Š‡·=öF`“³TaÆç ˜-µ¼Z¬ ¬¹ÿ’»·]±å3ü*‚BÅvÌdñÓ‚¿›…Ïzƒæx‘, -Œ¯¬ñ¸«¨ã%›bŽïW«æ9T²f/‡•¬ž=‚“Uøp?ÑF¬P&\Åžr:ø‹T:5™u#çÄ{5(èä‹'Üjèù\x3×|S=¸&âü$ñhª&{BSwäuVt§1Õ%ÊîqÉÓŒ[¾Q‰Íb3ýç‰ן Œâõ¨Üƃ˜çSÃdÿá5 üûx|561Y´‚/`-:%Xî©£¼LBü‹ùën»Ñi­ƒÓ:¬¾9eo‘Ø{´€¯Tt7-X]í-Θ|¼¬d4 ­xÆõE£ÒM =Y‘còê@—24à¤}§ G@ê×åkÐOÞÑi‡iK~M×7üá ²ÏÜó-­O:M¢Sí>§$ebðêÀ²{ä”q”·§ok¹Df™=_~T+q|‚ÁË´šªSS¤·Á2]ÀkIÕ°£#^øÝ›*_HeÎFØ衽á}£ 7 6`%üMàÒ2ZËüÆxŸŸ‹ ØÁu™+¶ZÈ -H?|?á—|?‚ïI”jÃe¿ßªõnÍ7ø€hÿ¦Tpè[azpÉu×߬øšÓ<•ÆÛQÓv> endobj -1779 0 obj << -/D [1777 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1776 0 obj << -/Font << /F37 747 0 R /F53 962 0 R /F23 682 0 R /F21 658 0 R /F39 863 0 R /F47 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1782 0 obj << -/Length 2136 -/Filter /FlateDecode ->> -stream -xÚ¥X_sÛ8ϧðÛ)3Ë?¢$î›Û¸­÷Ú4Wygî&ÛE¦MeÉkÉîæ>ý¥H“tæÆ) àÀlFáÇf2&±âj–¨ˆHÊä¬Ø]ÐÙÞ}¼`Ž'ì™Â1×»ÕÅÛ"™)¢bÏV›‘¬”Ð4e³Õú6xG¹ 4¸ºÎ²ÅûðŸ‹ÿ|\\_†L¥Ró››ÅõÕòß—!—˜•ÒàËüúùgÜ»¹T<˜\d—ßW¿_,VƒZcÕF§¿.n¿ÓÙ,øý‚7Ì~‚¦Ÿí.")ˆŒ„èwª‹ìâ_ƒÀÑ[{Ôë -F 1÷ø‚³cDIÉ'ΊĂ ëŒåÕ5•ýqsóõÛ¥”Áʘ‡ÅÈ‘tò˜¤Œ)<µq~mã§PppQcœ'8w*çmSCŒ ÖAôQ^ë9|û!rFaÀ¡ —î ›»Ïà„Óˆp%Õ,V1(©_NTš¦~8 ‰áX$âæX7NÂÓ(y¼Ù¨xµÌæï>/<ÁIB£ˆ;St}*ñ³Õ;]wè„S‘{Wiƒ§†«{ç<ësëOçs»([| qb­ÝîwCáÃ( PO¿Pâš‘dž­îøyXãA/EÆ_‡¯T&Ê1.ÓàXr|¶ #QB ED¬R{äÃò3–3‡Ÿáë[Ýoºmªßøn SÉÙböÍ?g__Gðu¹5`Ê L¾Áƒ Öf35›#«""¢¸¿3‚ãjR(šªãºn[]„?ôÃkµ‹3‰,ëµA¯R©_hÃTŒUêOΤ°X# HŸ>ØZ€ë®iª…Ögu³o!4Î2N0’¤±˜‰$‚ _Áe >—P’Ÿ©Æ$a "r,âi‚õµxàò˜ƒcí‘bR@ÄjÚ‡a^m›ÔÊ'®¤U¶OÌðÎ'-!J —·PT=¢¢„¤œÆ½¨úUQ&žº‡½O´5Ð’õj݆…GÅhäxŠ*o[$Ñ42ò;zí6ÔµñˆŽ%I¤èEoª|ë“Aþ:~GÀ‰XJ˜déqnÃí«¸H…êáq´‹2~bÄý@ý¨½ç"‚îøþÐtMѧç&ç÷<2…$i,ûât€Æ¨Ù­õɯ|L%?Ú¾*´íºÞB÷ËŠv™×`~³iwòLàá7ç‚O¯*[é“®~5þêG´;/ -€ž ÄÄ®ÙûoË›Õò뵧0÷9ÔžAj¬u•˜F¶E0µÙ”mc ñ«©m¯3]‡Nß5šew¼ïpÖ¸´ %<¿}p’ ¥;Q¯ÏÞETD¦k2Xv¸ešq›_½öÓN³j› Üë¡ -¸âÁ±uïÜðÔ*[~tµÌ[]*j¹…Fy¨Y¹…™ݎJbîäOÌ¥Î\Ú›Dè•$ù…ºóÕ~ä§s£+ ¸8¡üåÊ2æêǼ§•eà²hÝ—9)#Pì”ôU‘±r šžB2¾¨ÝÀåQoR" –94õ2]éÂN1Qäºq ŠÃþk¶‡|_¸5(i⇦ØEòHBÏWÁ$qt«fãËT€n%b毚%Á‡\ £ìîhG¸þÎiÖÔ=±Á ¿eó/WÒ͈Р¤£FMì—›JiŒ“¤8,Š¼g)küÚ²+Oš Ã"ð -3ñº±¹—¨€ýfæ.3;åî`ˆbÔJio¾±½x‚£<À€µ©ˆÈj§4õÛWËÜ(+±ŸÑÍ=Ù|$ ME³ §ƒê×zm‡ÑàC\²÷ž›Î JBG¼äƒ¿¡ø©(¿©Ù8v0…we‘WÕÃÙx‚áDø£G-*ò-y3 dP¨^ÁŒ× ˜ÑsMšÅ fÀ¤¤xÚ,N%м¨ÛÀåQn‚L’ˆñdª]¶×Ei¢E—[¿¢>îîÌß †6ùižweçØ t øÀž`všÀFPV½¤â¾) =•d'CXÃ-µÖ{-'¿éå÷B&8è  ” 6¨Z&0#A{$Ü¥Á[|<¦jP–€²°dŸÝOü# ’q$0ú€€á?uŒàwß´ÀK-Þë<ÿ‡ &ªÑå°€AÚ}õ‡ˆªØ1âåÆ7˜Á°ç®=Ø*¿`´ -'8 åÑ£àÉKCàSÿ åÉݱêJDX8‡”‹#âËãÇ~Ãi)ïåØ÷°`gyZËÞñÏük §ù«×“+th)þï”ÿ9‡[¤é3eš'’Àá¸WÊx<ý„ÜÏOuÿSnÏûendstream -endobj -1781 0 obj << -/Type /Page -/Contents 1782 0 R -/Resources 1780 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1754 0 R ->> endobj -1783 0 obj << -/D [1781 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1784 0 obj << -/D [1781 0 R /XYZ 56.6929 751.8114 null] ->> endobj -1785 0 obj << -/D [1781 0 R /XYZ 56.6929 637.809 null] ->> endobj -1786 0 obj << -/D [1781 0 R /XYZ 56.6929 571.6272 null] ->> endobj -618 0 obj << -/D [1781 0 R /XYZ 56.6929 530.4875 null] ->> endobj -1787 0 obj << -/D [1781 0 R /XYZ 56.6929 492.9536 null] ->> endobj -1788 0 obj << -/D [1781 0 R /XYZ 56.6929 459.984 null] ->> endobj -1789 0 obj << -/D [1781 0 R /XYZ 56.6929 390.8804 null] ->> endobj -1790 0 obj << -/D [1781 0 R /XYZ 56.6929 303.7532 null] ->> endobj -1791 0 obj << -/D [1781 0 R /XYZ 56.6929 225.6163 null] ->> endobj -1780 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F39 863 0 R /F53 962 0 R /F55 970 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1794 0 obj << -/Length 2915 -/Filter /FlateDecode ->> -stream -xÚ¥Z[sÛ6~÷¯Ð£<\y™}rçÒ´v6Rf·Ûö–(›ŠTEÊÞô×ï98J¤Ô™u&øˆspp® Ä„Ã?1I ã*Õ“8ÕÌpa&ËÍŸ<ÂÜû+á03š…¨W¯ß©x’²4’Ñd±ÖJO1Y¬~›Þ|þ|{÷ö㿯gÒðéìzf8Ÿþrs÷õægû|ÊéÍûÛùõL¤‰I¤ñéÛ»ùüöÍìÓí¯ïoï®ÿXütu»èØ -Y\!O^ýöŸ¬`?]q¦`µÉ o«U±„ÃC™jF˜µ¾—SŽ;rJâ^Ö¶]Ñä²®Ú¬¨Šêñè-Rè4Oõ¾tè§ì9ïáä´éœ…_%¦Ï“éÇ5UµcÊ¢élg=´ý#¦•^QØ ¡ÚîÇ;j ÷ :¹W%™L’KŠ Î(‚GYE8ñÇ©bJ%òñ9£æm±Æƒ²:@#ò²Ü õâC`©JK²ToŸÐÑëÂÖb•QI—eý‚‡ŽQ-QQñAº±Ê{ûãš4C&%$Õ=ͨj+µÄMZ²L>ß*È ©»Ý›œºkËO½¡—¿¼{CÃÒ¨”z/EYRïÁ½‚ŽàÅÚ­W7MñPæÿ@[àÓS¼—¢qx4¤Ta•¯³}Ùöƒ†W^®Yªõ…ˆ¢Î(¯GYå}:‰ši­/ô ’½ˆ‘2-ÍÉÏ»¢j›žÇ‡¾s²hö›M¶s_»àBÞ¶mQWþeÔÛ¡x±ßäÝÂmíÒòPÊ )eì¬rU5M¾œŽƒ6 dñQç•xW?z6ÒmÄÇ¢ÆϦCÙ³ù6v6gIvgsJrèlz$ß“Y9i“Ó‡Nßé;ŽŠ{@>Þw±âôµq j…’Ž.H0@‘ GY n/²Û]ÝÖ˺-dÏ2w(dO¹,d{ìAG¿%RRp%Ñ9YD,Ù)W•â¤-‘zpç­K‚ñ ²5°Ìb|Ur˜äá±Úoð,qè!o_ò¼¢ î``jTÂ>R÷™4Æ&ÔÜ%Rþ ¬ƒVaÃ} ¬¯Á`îÞ)t½C¥§®"óÀAŠ?Ø m?Éé²h¨pD6*j­ŸÇøyãÞqû;ªP ïNšýr™CºWb•¤Ì˜KYhˆWâe•xw) Ýûõf•?Ÿ*1^ yž¹5À]?ÁPÌpiúìõncw©£âPzÕ{{Ëœ&ЛcKìV¹-Ãtd(G9¼ Èí!WÁ…¾Ã!nhjU{:¶hÃi§ÝÏÅʽž \Þ(ÌŽRéÍþ5HëµWé„ÅëÛP§‰É¨ÀUìcY$¨ÛŸû4Õ*!Ú ,_,sÌA”qû²£Î*ð•žxÝS!è /šÎ¸êÌÇv¦Úî©,:Þ¬2,á<Ò£í@΢Y¢0½ì]eôOUû³QöÚ‹†è<)•„fù”í²ekÝàH¹£,ÝXXÙ#Þ Üέ²Ö-ÚÖÔ>8ê.ý‚‘¢¥ÈV}VN²-f[褄wRhոɬ¤ò³§²Â0ÒÉÒÂjøÖO á5¬.>(B¶]õœ£Íÿð»Lˆn3 ¥œïÔ‡"Å· Î¸²n§¹x©Ô´»¼zlŸNÝŽb<Ñyæ:ÔwýØ™0Ë´ÏÞ‘Ûá^A9re€åÌŽøʹS”„L9Ý^¥p„2jºÉà ÜÁl]aÐ Ñ„ ¥}‹[îwŽb[ºô÷)sʃU¶«w\åNA¶ûÄÊÜ+Q—€AdÕ X§ô%DëK‡²úÒ†)!÷•ƒß ®ÑçùêPŒ_–piV³ð -Rúb‚>Ý;IWffB¥ðR2•èähSGœÈˆ nú¤3i‰÷$G¤o¾.>¼¹¿{‡¢^ÑÐÝýÉ pƒA÷ žH°ˆsÓwzw÷þ]›bE>9‹Âä,rÉYÔ〆°g\&¿ÎwŒnÙ¶~Éì¡(‹ö{6ÛÃ|ÕZá;ÊàØ‘y%\õc–è@‰Ü}‡µ©°£[Áj¹û¾u^—×x8 ¥/茾;U÷ç‹·>eþœŸÖ°†Œa‘slu S¾ú7î‚Iõø¢š¢W4¯ò‡ýãcwsfÙb]y܉r dE„9fBiÒ£÷·w·_nP-·o»Âp> ôp€*óÿõÔÕ½\‚žÿf å†öò\Ö›m™“Ç©ÏÉ×û²<\''1$íØÚ{ºlFCàÔI 0d-/ñb‚(.6C_ý‡~ê¿ú}ªàýeÙþ 0 ù$TÖ©w5-ïS“™– œšŠúÖÚ´`½¬ Þ·6½s9‹¿$*šþ;d½`bÀÌŠÚv;5¾j -5⛿R-Ú£HÓ”lì[·P’%ÉXñŸéC”U\¡ûwi¢‚µèÓŠˆO¬/Ž"Ÿ§Ú¡NÉö]7‡>ØI,žç°ÇoY.—kƈÙ𸨄fÊ\úECˆ:#*º,ªsTQ“UH”~HRÔ½ûØ}"*È“ò]± o„¨`ËPÜ@eO.û²ò±ÞíÓfTÀ)x¡’óò @ãâõ ‹Ò=Gò Ücšƒ² iŽùÐT'ÑE=> endobj -1795 0 obj << -/D [1793 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1796 0 obj << -/D [1793 0 R /XYZ 85.0394 181.7045 null] ->> endobj -1792 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F55 970 0 R /F23 682 0 R /F39 863 0 R /F14 685 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1800 0 obj << -/Length 1931 -/Filter /FlateDecode ->> -stream -xÚ¥XKsã6¾ëWè°¹2DâAbo[3Q2–½–¦*Ùh’˜ð¡ˆ”g•_¿  E²&•ÒA@£Ùh|ÝèÈà ¹@B†rI†8&|¸,x¸†µbyÇs½_ ~ü@£¡DR„b¸XÉŠŽc2\¤_FïCW nfóùä:˜O?Îþ{7›\$ŽH4ßßOf7Ó_¯‚c`fŒG·ãÙçñ'C»¿’áhüq2¿z\ü<˜,:ÅŽ•'˜j­þ|yÄÃÎðó#*c>üŒˆ”á°0Ng”:J>˜þÓ ÇÌN|ÅU 4Òå’l™gI¡üª³†4ò:QêkFfdº3~Y×Ü]¬kª*ÿŽ<8?”Õ¶ÎêÓn”‰bA!!qÄb¸Bžê^ßo0Œý¥?Š*àX„郤§ò︼Ç×™âK<ºÑÒ÷®“ˆÑ®ZæIí {¡DP;»¨ÔIL=)x—à.BB©ezµ;x„r†DØ9k'T]ªÊ4h²ÂW³².ŽNe®<2ƈËè¤%¨öÍvß«,÷Éï—üu7Út£?<{ÂÕ¬»Í]šèg€¶è,Ò‰Ë/c}T õ$öÙ:‰ÙE‰™¾ìÏ.®~ÐS/Ð •G¤+n‰Þâ ÕDÒø3mD_9Çïuþ=k@i -…! O%Î.J¬«$€N5KòóÚ¨A‰_Ýê¢thÖÇjw^„9E˜ž6kΕÏB¡ǯ«´“ŸC7•”ûëÑV_±„l&edkÛ`a¸áN#„½™Z<‰¡é%“›Éüúaz¿˜ÞÍ<õíÛu•''‚MiÈܽԌ:; Ö–öÐþëÏT¹œŒ¦!¹öÖ2ÎL–„Ó,éáa>ýhhý7'Û0Rh%4¹J÷KÕßV+¢¬´gµ«Û&Y/T+ûÚ`õîakz;­¶‘Ò=t@cy°„&iô+ˆþ íZ€–ª\­Ý“Û…•Ñ°0ËÝ~@´ÅPuÝj°4=kŸPt‚î OãôYn²¶£²êÖ†êÚm÷rÛ5㮼-«ö ÊL2[\¥ªÑ¯*FI˜?NŸŒ¨ú¥&vò’§câÊuzÿ‡%„Üó’žjÕx|ŒÆˆrž¼dÙÞÐ>,$KûFá`±U:÷Ä -!@¿‹zª"Ü]¢üüúòÐ ù‹ÆqèYL£h•ÒÇ$˜½RÝ=Ô¾Öýÿ~·endstream -endobj -1799 0 obj << -/Type /Page -/Contents 1800 0 R -/Resources 1798 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1797 0 R ->> endobj -1801 0 obj << -/D [1799 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1802 0 obj << -/D [1799 0 R /XYZ 56.6929 635.5323 null] ->> endobj -1803 0 obj << -/D [1799 0 R /XYZ 56.6929 476.3563 null] ->> endobj -1804 0 obj << -/D [1799 0 R /XYZ 56.6929 407.9215 null] ->> endobj -622 0 obj << -/D [1799 0 R /XYZ 56.6929 365.2162 null] ->> endobj -1805 0 obj << -/D [1799 0 R /XYZ 56.6929 326.9947 null] ->> endobj -1806 0 obj << -/D [1799 0 R /XYZ 56.6929 293.3376 null] ->> endobj -1807 0 obj << -/D [1799 0 R /XYZ 56.6929 221.9809 null] ->> endobj -1808 0 obj << -/D [1799 0 R /XYZ 56.6929 108.6903 null] ->> endobj -1798 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F39 863 0 R /F21 658 0 R /F48 885 0 R /F47 879 0 R /F53 962 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1811 0 obj << -/Length 3191 -/Filter /FlateDecode ->> -stream -xÚ¥Z[wÛ6~÷¯ð#}Z±¸’D÷)mÜ4mâdk·»Ý¦´DÛl$Ò©8Þ_¿3˜o¢¤œ³öƒÀÁÌåà Hy.à_žg6Ú™ó絛 -iÏ—›3q~}¯Î$ó,ÓbÈõÝÍÙ7?èôÜÅ.QÉùÍÝ`®,Y&ÏoVD/Þ¿¿¼zùúß eEô]|±°BDo_\ýúâ ÑÞ_8½xuy}±Y*S`2È–ˆèåÕõõå÷‹ëׯ®þóîêòâÏ›ŸÎ.o:Á†ÂK¡Qª¿ÏþøSœ¯`?‰X»Ìž?Áƒˆ¥sê|sf¬Ž­Ñ:PÖg×gÿì&ôú¡sÊ°:‹m¦Òm(y.eì¬U#uX'Zi¯Žwïo^¿»ºÞÛ‰ˆ…¥JÄN¥jÞ Ì´r……g̸pÝE>]ÒéXëL_20Í,©K‚Áµtv¼äoRʨؖwÏdè|½¦Æ}QÛ¼-VôØ”÷UÞî¶2‹Š&>¤›$sq& qT7C®Ãºé¸¼n–¸ä7?X;à”"Vl+<Ër7ÍT0©l,m–—¬ãšm¨C©Á%cÙ®‹eùAU4¤¬ö¡ Ä5H6߬ï&Lÿ­«â°BmÃb§:à:¢ÐÀåúqN¡2ΜլÐÅóž:¥‰³$µÇåê¸f©S‚ g(ÙÍ…9ZÞ^,´’QÓixEÍ7ò†Gtåýµ¬î'Ü@¬·9¯ž'ý°„ÎïD6¥£›‡’g¯Û²®¨½Éy‰Ûb_8Pdì„ÊP Œ3°©ÍnÝ–k6y[nŽ‘´q";aó×›.oóõŒÍ] ÞŸ²ÉWõ&/«=«ƒÛ -’ã’u\3¢ƒdÓe{Åx -J šS%6zùÏ߈Ö-QA@bZ­J² RÛš¨WÐðVÅž -ˆÄŸ/‡–ä±ÕŠ—¸îfG»k‹v/¨µáûÑ–?>Õ*˜pC$Ömí%Fx•oŠÁO~¾¬ýïê°OØTÁ©'Òã>1ä:ì—÷‰ÕIX•ÛbÙÖÛ}4°"Ná$>*\`šnäÖÆ©4z,Ý›ºþHŠºyAµŒ2€Ç©ëñ -}Äsæ†l@ÛD2†ê:@59ûdV-ã=Õˆ_I ÿò T -ÔÜ7o°á¡Ÿòu †Y(gù0FŽe^Va‘)@˜²ˆ¢ ÐÂ=ÿÞ6õzçÅW6ª¹—ÄXçmù© -îÝKÈèEEÌá†ìÒóRË˧ðxZ•Ĥ=åö™×§Ÿj·¹ ¢•<ÿïð÷öíË…ß‘Ÿ'/üñíÛëkô÷4ªê6ÇCïxVÉH ø³ ©1P³! ¨²&Œ#ä—æ[c¿ ]¿‚`7ßSÛ'4ÀñÖ'4@Т}øšÚøi1 ’Põ×XKÈNJ˜‘7¨$c•d^%>2ÖG}uõ56¸M¹|¹¢ŸÜ¡Z1m€ ðDånKÒU-÷ûéèõ‘ªzç-‡|£m"‰‚HÊBž¤ä~_“3ê4­M“±7v'ÂXVN©µ)«#•¤Ÿ‡z· ˜gEH+ D«Ÿ¦º®—|P6‹'Îsð|ãw͈3pàéRÖ£7ä: q—‡¸bâRÈ.X“LÍœÑqb€í¨p׌t#€3P`háÆâu'ÚØ €Ã–8ßç„-¸ÿàð‘Nº™S‰ÅçGÎ -<²‰èw<bÍ9©†-&&ù'µ.NS›1+{¤Ñ -S|=R‰ `³ªóFÉŽ#G¡ %c¼ê  išüÉl8ÚO9Z\®fžf ÀD¡‹ìCÏ™‘`N“ö|¡ -’Uc3®è±G  PÅ…s ÈA×Æ¿)ס¾œ€¬´/ì®'“Ã>L0ƒ¾â4j¸;m$ï;ªúé««˜ÚnØ; n*n&Φ^#c8ŠìÚpò´-4”@ZPÏ*fž^u(†ß­Jªó4¯(¿#ƒHD}9SròSéLl2kÆ -Yw9ÔαK[é§>qA2ä:Œ]—Ç®»Ùb9ÉtÐT½kwíâ®\ï£$T&Môqñ:®ùÆé™MÓ±€¾LÕ2‰ª ÿ!£ 4˜†…&þ’M IX"ú ºç…Xh¡Î¥{`mÃÄx‰âDº¥‚\+ífÛƒ·/®XÓ3Ês€–¤±4P9cF)¥b¨¤åØú,Á¡’Nñ{wYùÍöå–à‡}H¸X›ìÄ…Ëëˆ.ïC{ø¸1'– L3KŽ*0Î`'K¾ß–Uˇ~ÎÁC½ee4»Í&ß>¸Œ k®0¸â¢,÷A~¿ÛÝÄ-ÎHÊ8ÀÕ]%U Àì-ˆ¾3cÃÔĉs#?˜³ŽJ3˜×ÈN†\‡­Óqy딧®Ã@•Åªýä|4¶£²u\3““Ú©K÷¯.ÓÈéç‘NOe½kÖÏ‹œØåì[%'yÓ„Þœi>(ðlj>5ñW›Ø¸-† ­ÄÙ -ÿLLƒí2fFo“Í.t»5 óQ ‡ÖqRÝL3ýçå:”a ÿ”3gÎS€kƒäwtg0©\„g5Méæ‹jaÒ]V£:k_Y¨®²ÈižP×e¬Û¹¦ÏQî àû®õar!h„Íf²Û,/ƒ½·LæÑ4b¸7“ºçV¿OeS»iÊUA#W¼rM¿·¼ª—’®Và©©ëÊOæ<4Ìå.íñ{–Çu¾ä*Ä…PK´ëÏ2 ‰Rw¤H§‚Þ›Û?5ÄÀn¯£¿wq ñq {ÛnÒ’Ü·[-™~[´OEÙ€{ôª‹H*T]vˆÍþ2ªk% âÞÑrÅ—ûñc- …Ô_« <B†?{'Š¸/.jCÈæa¿(ð´¬ ©O[Œür Oc­º´)ÔK ¯5z³îðó–Ëi …›R“rºV§tK„Í„ëa aªŠLUÑisâ ñ”˜@‡? -…<põ :*¯-ýjØäJæ_+á°¢¿šrÎ\|1ìiÆV»¢;wýoÝ-¶ÿ]Mw3v—Ѭ :ñ9xªwáòõ`°ÎÊo¾¥=‘2 ¹Ê—?”_ŸJ»ý1¶åoÈIÆyw™2„ÃQù:®Gs*c9÷X›R³Ð6œoÛ>ßæ ûètF"å¢>6ÑûºiÊÛuAL4Yùsï {IV§‰‰ï(ÜÚâs‹¿3§@qÎö/>¬`|¥ "¿TÈÑÇ.c‘i3Xe›?ZÒy™©i:Ÿ@’ŸLÒy¾Äu¶?ïíq[BrZ®Ÿ™ Aéß´ù'*©òRx¦2[ôÐX=C–_.é!¤Gد\ótˆ0ÜâW»Í#H¢dÓH$b¼§t†àÄàÅlµ@SÐSð lë+°{\1üa§ShÜò´àÀÙ¿?¥à—…¿¡fÐ5Šò  [}öF籃üû×å]G8Âw>Òz8S`Ôþ™ýeÓì´ÞÆïÇ“è&Þy¿Íî·’ºiâŠßá— yUø¢¤óQ—Q~œ…êÆòþ3¾”JY-ù dß°©g"Sø\¶û«|ç¼® ÷@„óîGme¨U_õŽt7Øô7*Üc)úè Ü(5‘-’‘Ⱨ×O7Íbé!ÿTŒg¾ågb\{‰XŒü¶î$zߘäû7äý­UŒŸÃÍ8³è>uû¿¿ºë¿/4ÌeÙÌ´0±ÖN¡PûRØ©èÝ÷yû²ÿ•¡endstream -endobj -1810 0 obj << -/Type /Page -/Contents 1811 0 R -/Resources 1809 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1797 0 R ->> endobj -1812 0 obj << -/D [1810 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1813 0 obj << -/D [1810 0 R /XYZ 85.0394 751.8312 null] ->> endobj -1809 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F55 970 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1816 0 obj << -/Length 2975 -/Filter /FlateDecode ->> -stream -xÚ¥ZÝsÛ6÷_¡·ÊÓÁINãvÒ´I.vfz×ö)›W‰TEÊŽó×ß. HŠ¤§sãBÀÀbw±_°Xpø‹8a‰•v¡mÄb.âÅzwÁ÷0öÓ…ð˜U­º¨7·¯Tza™Md²¸ÝtÖ2Œ#·ÙïË7,b—°_¾ýpssýÃêæÝOþóñÃõåJ-ôòêÓ§ëoßýv¹’18€9_þzõáËÕ/Ô÷éÒÊåÕO×7—Þþ|q}ÛÖ%^p…Tý}ñûŸ|‘Á~¾àLY/žàgÂZ¹Ø]D±bq¤TèÙ^Ü\ü«]°3ꦎ2Cp&U"G¸!U‡F°ØÚx¡cËCȦØåpÂÈÆËÛ‡Ï<´YQ¬T¶Bø‹¦Éë-® ³ZDV훢*/WJÈe½Ï×Ŝ˼ƱL©ß/åÚOE™UOÔnÒ†€OÅvK}w9}užyTE˜C -3wÅ·I´Ù·è´<ìÇû̇ßeŽÊí&U]塯ü܆¾»ªn¶ÏaOD8jG©z¶I0-D²Ht̤6É„-!Ъ‹"S"F k‹Bf¬J² qÜA·àÒ)oÊõîÔ€00Αó5KXÖ5C`tYë¸OÙMÏE±7Qäu:QÕh0¨yM gk`¬:-ß<ÓH–oÒã¶ÍV \†Ò¯zZ&~ÛºI³`ÚT~ßÅ$0jÞQuQÓŽªE9GU‡ *Òmjr(î‹òL7X›yÒZÔmý(Ä0¹dŸ¸ÛÀÈo.Ppltĸp˜/ßm¶ã”9e¯†²hc½ ‰æ|uœºõíÂË(­ëãng†0¶]#Ð5!?¸»Œ+#çå×EM˯E9ù}|)Ѐ„cl¦‚ŒÈà‰ç lQ#ö¤¹7Ü$Ó'ÑIQiîÝ?¶…ŽÚ3D&µƒ·¥I‹²€èÍvµsBÐmt$0~ -:N»Ö4u&èÐwsut4N8oiDã1‡×žÑ(!¶LÛÓDXü>Mí¡™@C: ´8“ˆè ë f4, œ†í‡[& ãV¿°elÙ=pk3ØòK²ƒ¬a_çǬZQÉ» âO›”Ÿò’úPœ3ÃnÒè ah¤@]Ba}b¨MZ7;€¡ˆ”XÞ9åe¦ˆSí« C©)yç‰xŸ¸P¶+8‹å0r äK-ùh½´öDI­Úâvé35œ‰AÈ¡6GÐþ-ý¤S# =5þèV…g¯i“&ü†‰!Õ‡.ˆ(±ßû=늼öËõX¿-vä\“ª¨´bZÚT±‹šVÅåTñ0bì,•*ñ׃Xåg†Nr&t¤ç‰kQ#Ôõ Œ™ˆ“>uýœ™;ÅûlÅgüx(Ťj,(&±sh™€Ü»*˜Ó5\è´vGCYöqÚT=™ŸžŽ”'U ´[R”×À¬×”>+k˜Ž ÓÞ‘Œ Œèq%P‰*ÿûX<¦[*a!C,Öx” -U×ëì$Mé±°!Љ=¾úUSÿ_ùó]Eúžù‘|;¬r©¤SÁq@ä3 -½\÷øýb,ö…+Q`É3ruZø¬ÒCº¦R-àˆy oëáî= YµæǼµã¾¤ß;¿»/ìBOQ‚R¤YŸ”fX[¤«ëùîã§6¾r‡LOU¶ãX][ˆ˜Å"žÈK!Ïid…X”Y±N›¼në{>ZëË‘jÄ.p$=TÇmÖ¶ðÌÓV‡k–Dò…«‹š±:å¬ÎYÔ”(¦¤¶ó[ÐÈ–]^%†)nUËO‡"$tu÷¿Æ<¬_Ð\W»ý6G¿1ɉ5ÉãyŽtQÓiQŽ#/& Ûü1ßžÕ-5–\äÆájíƒdxý@º -¿öˆÖšÑX9ø*øåfCbDk7•ùGÅuSž/…ËSæ4¹öÓ=[®ZÄ?G€NÖæÏ-Ï7hÁú'¨'LJM_ÿvõë§_®G"8„ìÃ%kœà“Òv[=7 þ§º#&Âî_S³ ý‘”;$oŸP À%³õh´Œ~Þ$4 ²Ø¢y Í›@ÔÛ›+jQ†† §ãóòÈËú -c­ß!+kÈ_W°L wáŽÆ&¼–aã}ç$ì{pß ž‹˜OCN%C7å; Œj!K}ö?vǺ!ȇ¢áHæî(wí6’0ÊkfâÉgwlžßFA^˜tÞƒN´û¬vIÁâ(}åcµöÿy€OŒÛªúË¿F¢jžfñA-¶§°¸Î›ñt ®³n Â×þ´({¯¬qÿ~©(¿_8µ®ÂTWZƒÖÛúžÙ·pê·rb…;ªåŽ^ú‡°„a)±g€Ê]ð‚AT=U”"2Ê[«û1ñ€,Ý“ÎÄ)¼·jÌ+ñÖ"üßÿ5túÿ(ˆ ”™*pJC<mO/xrîÆýÿÓþ?v—*Õendstream -endobj -1815 0 obj << -/Type /Page -/Contents 1816 0 R -/Resources 1814 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1797 0 R ->> endobj -1817 0 obj << -/D [1815 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1818 0 obj << -/D [1815 0 R /XYZ 56.6929 119.3275 null] ->> endobj -1814 0 obj << -/Font << /F37 747 0 R /F23 682 0 R /F39 863 0 R /F21 658 0 R /F55 970 0 R /F48 885 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1821 0 obj << -/Length 1544 -/Filter /FlateDecode ->> -stream -xÚ¥XmsÚ8þίàËÍÀ´VõbÉöGJH›¶!¹@çn¦Í ¸5rÎ6´ô×ßÚ’ŒmÍÍMf‚-¯wWÏ>û"“>†?Ò÷9Â,pû^à"Ž ï/¶=Ü_ów=¢e#ä4¥ÞÎ{o®™×P ¨èÏW ]>¾Oúóå—Áèþ~2½ºù{èPŽoÑÐánGÓÏ£Ojí~ÐÁèÝd6tˆ'˜ B¼x0ÝN®œñûÉøãønz=|œèMæµcMç f¥Wÿô¾<âþö𡇠|Þÿ7‘  ýmÏå q—1³’ôf½?k…§Õ«608ó÷©gC#°¡Á$e Û_Ê<N¯å¯TFjÑYëßTýF?Ãís¡EºÕo=¡“µ¯„¹%,à›C -8§•¡ Iô -cöŠxÔõl¢mµ¨t*Z¶‰vß\ÃVŽ»,E|$|W"7RÅ´ØDå„Oé~HúNÛy­‘†¢ @„ø.(¬|êtjØó €%¿È†ÄDaå- Œi¢´â#8HŒ‚³ tÌʧӯO!ƒù&Î[æªë|“î’¥ÚùSåBßaÂC˜0Òò~©_¹ˆ–JC¬á ÕâJ¥º€­n#YtåN÷I81¾öX†Ûh {”+ËîET®EÕ^rœ1©ÑŠ·ÙxÚò†êýTáÓCõàY=ÙÇé.Oê‘ƺº6;¤ƒq±QkËhî’B+3Ø@ey½ hn=gñ@Qbߣƒ1¬,ªå0ÏwÛ.¹UŠTAøµ!­‰´Øe:<ôe¬îEš†h€,ðwD€Å³-¥ ílÙnqùb1ya±¤ù êmÕÒ¯W«ý2 -Wo6™(´FŸfwöúAÂPF›yá[Gò+,ûðèzᶚ A.6åâíÍôJ™ ´µå6–q^d!G-=4óK-݆r&¶,~™B«·ÙwQàS®ÇJ#åŒ[ô¹Q—“ºhXpshÀ‘xmøFŸçïï~Û„”‘fæìCuÐiœÊ<ÍŠx·=šus… —K‘çCå­€Dº0žTuÂYl¢ÅwS,ªØrä îUÂS9ãZPª<Ö›†U%)õÔUõX'X*ËŠ³ÞAÐâTZêéAáO-\*ŒåZ'iš&/!ãA¦Ï9T¬Î!``Ð -†ÖÎRKß'°AÊKÂY'$ ±€‰Çiª8?ÔRV„Ê4ýâìÍÕ·úªP›ä-®zçMцª¤+Òi-â.´¦¡ÖºŠ“¨tÁØøõh§'cpzZˆ^Mf㇛ûùÍÝÔÒÓ;$µPªC¨Ha*ÓM½”ìösE‚׺Xï4ãeZtå¢m(‹x‘kÑtÕj¥/ã=S—-$î*f'#ª&¢Ø¥—ÙÓ”ªØÓ‚Ó°§–*íÖœàÍa -ÁœâÙÑô¸¼-ý¢sµ”Å»9E늶{ãMUsÓ2> e›=å¥ 3•/<;ƒ[F¸@ÐIdžj¥›P«å"Ù-#uslÐñ¾œ +F¥yKË \4…§¼®gˆòF0é"‚N¥Ú"@Ä‘+:3]¨™kâeC°Óìz:´È˜ÇÛ8 ³ä`j›ÁÌPT mg¹I&°`¿áVCê·ŒTÅ­}×dÀ G‰ß˜4B“ÍXÂ)Ñ÷¼ŽÉû,–ÝTÞôW'¦ÉãòéiÅS r],šÃî¨8:¶k˜1u€¤Ž@ô3.Î:7dˆ¸ŒCè<üF¨Bÿ—}Æ|zÑž‘9µ×Áž‘€·ìÝGÙ*Ͷ-fÂyJG#IÃe§’&‰ºØ†0ndÇ#Š&þ*ÝÉã9æ4ë)d 悽ä`ghÒÍÊ8Ó1J.Çá(s> Z¦ŠÂ·“($<×½d̈œkÅhÏ¡–5Œýµ‰äîz¼iÿšó>ó.;éò-Ýe2LÚÕ'.jçEŽÎ}Iñ®üüaÙ®[àÿþÊrüž­…ùþ™†Â0Œ©, Æ© ‚½®ëõ÷˜Sßÿìœ/endstream -endobj -1820 0 obj << -/Type /Page -/Contents 1821 0 R -/Resources 1819 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1797 0 R ->> endobj -1822 0 obj << -/D [1820 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1823 0 obj << -/D [1820 0 R /XYZ 85.0394 562.7154 null] ->> endobj -1824 0 obj << -/D [1820 0 R /XYZ 85.0394 499.03 null] ->> endobj -626 0 obj << -/D [1820 0 R /XYZ 85.0394 459.6249 null] ->> endobj -1825 0 obj << -/D [1820 0 R /XYZ 85.0394 426.4105 null] ->> endobj -1826 0 obj << -/D [1820 0 R /XYZ 85.0394 390.6449 null] ->> endobj -1827 0 obj << -/D [1820 0 R /XYZ 85.0394 324.0377 null] ->> endobj -1828 0 obj << -/D [1820 0 R /XYZ 85.0394 263.3171 null] ->> endobj -1829 0 obj << -/D [1820 0 R /XYZ 85.0394 199.6317 null] ->> endobj -1819 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F23 682 0 R /F21 658 0 R /F47 879 0 R /F53 962 0 R /F55 970 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1832 0 obj << -/Length 1880 -/Filter /FlateDecode ->> -stream -xÚíY[sÛ¶~ׯÐ#5S!¸’à£b«­{;µ•¶Ó$´Ù<¡HE¤âª¿¾‹ER”LÜNÏÌϘ °Ü;>`WdŒáŒEˆÂ˜Æã(æH`"ÆËõï`í‡q4SO4mS½\Œ^|Ï¢qŒâ†ãŪÅK",%/ÒwÁK¢ pÀÁåìõü|zöãüì?¿_]Î'S…”³7oæ—ç¿M¦T` bŒƒ×³Ë·³WvîÍ$¦Áì‡ùÍäÃâ§Ñ|Ñ(ÖVž`¦µú4z÷S°á§F,–bü/‘8¦ãõˆ †gÌÏ䣛ÑÏ ÃÖªùtÈ\H$(Á-ÉD‚ ˆ ‰8A! £dÈcžJ{ì=Æ4WE²V}{c@+>n3=í‰D³–h‚1ŒÃ¨+{q¯Àç, -ŒxÉ \Ù™úÞM,ËB«x·Û&uVvÕ*m êÒÎÝúîÕò£J!² ‹àbeg‹²¶dÕF-3ý½J¿ƒŽƒ¬¶$©Z%»¼®œ¥öä\Ü2ƒqˆ µõZÿª^¾Ðºƒ4 OY¨ƒ‚b!¨!V–YÇ'”¡˜`îx!GAÆͧ+¿D’DÀX Œ åõ|ñöúÒ&ë/Bã`öê­M×^Àñˆ™ýÐh:5þ9¡’¤(¢§V¥í„È@Õ»mQYiIaŸêã3UuRïܪ <‰}dîUm ŸrëÈ”åkßRU«e­R/À °c i°}È*5ì¯nÇ=7ó¹ýxöêæjÀÆ!§¼ÇKøG¾³Ÿ¶<õgY¨Ö²áÇÛ8D '#>Ž//.Ï-“Ø©‘®³"«jÈßrk§®ÕÊ9¡X:?¼NŠ]’¨KB‰h†¦ ƒË®#fo?^]?í‹¢VÛB¹ˆÞì«Z­]¬ÎÊ¢*·u¶[ÄrÄxHŽÁˆðØ (‹ñ‘ûÌÞbÆQIiˆ/à ¨)ÉQÆjFÝè”ëM–+#ÀL¿§4²£Öœ -Nò,Íê½}3L³âÎ%š‹ ì‹Ï - öóuYæCÇÞÕv‡ßì‹rSeUB³ Ù˜I†"Æø„°ž -8‡ö6 {ÆÐÞP xo2 !6ï¦é?úo3úÔŒ>7£¥5\t1+ÖgŸOöežTÕNÒ`0ŠUÃq5ÀÜ(C!éªÜ®“zy;d ÇïŸc6ÀœAžÃñÕÁõu™ª!ã;¸Þ0þø¤ªòc}~ëoãw¤ßëgÖ¯xf~åӡΙO!IqÔçY=ɳª÷¹ú‚ 7Ç?'Á¥®9þíôÝôfp'µ­üºPÕOªf[8VËí~€©à(¤‚ô™>üLϛѯìC"Ñ€É×ø@㙵>þ$â¡èmÏv: ‚²Ž¡ ô[@¹ÅâPöT-Pn^ÏË R| ,Ë~ŒÎžy£þ3(“Ÿî¿Eÿí(ÿ¿ŠÊpÝ’H3íDûKÑùÿ¸ÙÇMóÖ M¿¦€³8ìÞtÏç7g×oW—_Upú: _prÄiä³ÊPšÒƒ¹€àAµ/êä;éêCdP³ÜmÝež¹ÒÖíª¿ÿ3wÿ×½J‚‹ÚNnÔVÃÄ‘ Û„€©ƒª!•H$ô¡$Û*=åz(žýÙUjµË­Ü•©†`Ъ‘@²ó*Ì[¯:n•¦w½þÈ5l¦öl¦!Fœ“ž vÛC‰u¯Ö®cP˜^Žî -=×gP[¨Ë&oÀ´ƒ&p>b­¢‡FŽu.ˆÉÖYžëIÓêöÐ8@¿ÜË`4¦ t+ep»«­<ÓFQIþìén½qC›š°î]o -ÔZµ'(Ý÷NýZz·Ã-'欇—®ñe[c¾6f8×۹ľ¶šdvÞ«:£(˜¥PFge‘äù~BÑf1k “Í&ÏtzVõ6[Ö;³d\erõY啾ÝÛ§kÁi~TGôGô‚ñ„þJ{Ç÷Ú–•»z£½Êìª,ÏíH÷õ²;µ£¤rÏÂ=—µî»˜±õ²5®!vgú¯o÷)A)Ä`À0ŠcvèãL¦Á¯4ëµiå{ûÖ L40ífSÃí¯Q.I·æp~Ö[ÇûY׻ʵy’Ú¯&~êÖíµ¤ò½=¹î\}_V~K¶U´Û·ÙÐC^ -cØ¡Qø”—â’7ÂQó·ééœh„aª2ˆ»°+s^7ôÝ5^cA ß> endobj -1833 0 obj << -/D [1831 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1834 0 obj << -/D [1831 0 R /XYZ 56.6929 687.0104 null] ->> endobj -1835 0 obj << -/D [1831 0 R /XYZ 56.6929 626.5588 null] ->> endobj -1836 0 obj << -/D [1831 0 R /XYZ 56.6929 566.1072 null] ->> endobj -630 0 obj << -/D [1831 0 R /XYZ 56.6929 528.949 null] ->> endobj -1837 0 obj << -/D [1831 0 R /XYZ 56.6929 496.7215 null] ->> endobj -1838 0 obj << -/D [1831 0 R /XYZ 56.6929 461.9427 null] ->> endobj -1839 0 obj << -/D [1831 0 R /XYZ 56.6929 398.5692 null] ->> endobj -1840 0 obj << -/D [1831 0 R /XYZ 56.6929 263.2909 null] ->> endobj -1841 0 obj << -/D [1831 0 R /XYZ 56.6929 125.0477 null] ->> endobj -1830 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F39 863 0 R /F47 879 0 R /F53 962 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1844 0 obj << -/Length 2946 -/Filter /FlateDecode ->> -stream -xÚÝZY“·~ß_ÁGn•ˆà>ײìȉÖr´‰U±ý0KÎ.Ç&9kÎP²òëÓ8çr#U*m•ˆÁôî¯Ý †?²ÐaføBŽ&b±Þ_áÅ#¼ûöŠšU$Zµ©¾º»úÓ7L- 2’ÊÅÝCk,°Ödq·ùiyóöí«Û¯_¿¿^Q—_¡ë•Àxùææöï7õ}o¯ ]Þ|ûêÝõŠ(I IK&ñòöæÍ«¯W/ÿüêå_þùýí«ë_î¾»zu—k3O0³\ý~õÓ/x±5|w…3Z,>ÂFĺØ_qÁàŒÅžÝÕ»«Ò€­·îÓ1ap¡‘ \.Vf…UŽJ #,àÝJqŠâFb”ŒI,RY‰­>ô×iÒF’E{°Á”‘hdJÖšt£•êMùöXj¯z›ûƇüXåÁ?”Í[`®· =âK`ÄŽvÈöùfµÞæëßþUâm&4ù2蟎×D/ËÇc¶÷³d‡oä5h=ÈVa &Ï( E5£€Håðë@IÅùü”‘hdÊŽ$’B¨î”?nó é]™mŠÃcONŽ®õ3ÆtÚNny¶éÿZžŽ‡l犠¹¢N"­êjR¨R)¤´TóBmSM 5Q9¡®=„èQîÄã`½ËªªÏ¡¡õ«=–Þ¼÷=GëÒýnªvçC~ô´ué»oücy ðolOe±t_Ö[OQVñÂïˆn¤S½*Vq_… Ä.“°.¶`9v®,&ƒŸš“ÛŠ©î«{J-€eF£PËÃ.8Í(1Û~ó¾½;µäd;?n‹õ¶ýÞ‰ÌùÖ2xǸnûÞ…Sq4è4ç Y_ýTGõCëÝß®…XþÃ? 1@MöÓÒÿÞøŸ2t ñc´0 àÁcÀŽ4ÀÄt°þa ë¿}TJ}1 œU=(P=r¹ÉwùcV‡èX,oßùß‘…ŠîêdXó ö§ ÝÃA|_ƒ -ûÔŒŒ±²p¨pPˆ),"|8 lpÖ¯kÿ.ÛU¥o%;€v°h=îNa”l³ñÌVhhÐYâî3ºlØØgµÅ€[ViXH=ê¢ÊÝ&ŠèÀú~¦m‹Ýæ ¾R\‘gá›ÌâÛkü C;Äš‘6À ÊrŸGÔ¤¤­‘øI~?¾¢N¯§&äѶHìÆÜ#ÉÔ±“?D¾#i³–èÛqÔ×EÎs¬žqD5çç¢ ¢9y~øBeŠ~7E•¹’2¶ Ú…ÊXƒè½?Õ¾3Ƙ®ì5?~,ªð®„ë)²j,®#ÚC†n†qݼÛ¡Ÿ€]î惡CjSr0 –|±¦6ûç—ê’Kc@Èé¸&]¥Tó÷ÁÿDÅaŒÏ¤P-¢é *¹êa4’šÅÀÚf1`hý -ÒOÈRù,[‰hÈW7•HH£:Œg²™éT¶]Z®´É£šbÞ:IA®ÃqǬëüz³f<“j*AÃi æ… ¬Ú³S“(DHÑ4N0ƒ=‚œ©æµ©f©T¾«{ĸbg°B`€³¬%ªÞºhQœè2—àÂ4´f .¶ÓÂÅö…—.y:Õ¾3Ö¢l«êRàZ™x´òÄÓ‚1FÌeKašL"ÈM5Š H`4ý¼é(Ñ%g'ßÀ~=b’höŒ‚(0)OYy0ѸïnÊè÷R•iª<I0øüÁŠõ|t >vy¬aÅàæ´ª&}Àº<Ôùa¦@È$¶åšy;iM›I$rVòÛ¸•h#Ø\IŠb¤¹˜e*Ò ™ê–£äP²ËU¬FÔH`¥„¶÷1§Ý•ªÇá£`›$ƒƒ&Ë…Ë÷4VFº5DÛñ»SŒ.l‡‡54Ì;†FRÉ †›+yq¤•î”¼`† Îoä÷­¥±·´KŒyk°hˆ$º¶P]>a $E›|t¢®‘„Ñí¬îcvÏt. ÒÈóÎÏÜ:.¬ø™€¾M5 ðDåþf à21<pŽ”=Fe,QpÖ8 ÃîÓaí¥E¥?Äp´‡ö'‡ÕdÖ”Âù‡/I‡OÙò¥=[G~˜ö™ »ðÌÄ&}LËç ’Í R"ˆPÅ…ˆ”H¦úÌ0è³|O}«‘ ïKø^ -ѨôÌÑi›jš‘ÊAóðYÁÑ,_):ò5uk²MÆœç½&Kç|í³+‘16R"c49_Kpª!ÉùºjIóP5qçØŒç;(¶ô/â²è|;_Ž_`ÚÕ2úµ—t+d¸øÁÅ— -ŠÌ3<»0ÿÿQÑ -I†ÏÜiSM[f¢r–YžOîA£VJëäQpñóÌ%ªî:öÉmÙS«.{?^+¾<õ Ë‹I|¨I»50ӳǯbd ½‰¹¿nþ„œø.%®ñwêÎêòøiZö1ÿ¹MLë_HÄ$;ã™ÛT3úTNÿÕÙK-Uýi—O^j™å¬¹Ô2dmôRK‡·Æ9k2}ƒ;®ÏUÛïleÀù_è XѦ© -rnW€—÷^5ŽWyʹt“øKO—Áñ, #N;Ó¨ó°™»2íä˜ï2[¯ž˜È—b²{É \«èîw.1gziÙ­X%ƒ¶…¹ýÝ—Uè©NEíÏ­o„«nkئܙ‚íËNu #ëlgšl×}øÍÂ`ùSvÌê0Xµ>Oµ½î¢Äòûƒï¬#ƒîÔ¡{pæk}[Ú  ñ(ŽÅã)/#ßÓ¬Š„Uñ–)ÍÞí Œy¯žÅ5†K{íÏêí©ò=Õ ÓȃDyàe¾)ê V§vy‚NT×zG‚Ý7”GÏêjÊĺ´|]MéTWS&ÔÕ Ñ­«AGª«A»ƺšŠ¥’A«©«­˜‘î°ÕMá[+þ8%0Û]c¬ûm³ý²ß>ÏéÊ`ѯï·}}û  èWmuú²%$ÜJž»ìÚÍ\µ Dξû¬ÈvŽ©Ø˜kÛ\Å|K„”~3ÿÓ܇AÒ%zI褫ù>%]¢“t‰:Ú™¤KÚ²ãLº¨`—']Š¤{ìË2>u1Â{÷>;¶‹U*X%ccÀ‹h@Ÿ}/¼¹ñÓšŽ£‰aŽ3$2e'ØôYL#¡!‡òþo.óendstream -endobj -1843 0 obj << -/Type /Page -/Contents 1844 0 R -/Resources 1842 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1846 0 R ->> endobj -1845 0 obj << -/D [1843 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1842 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F55 970 0 R /F39 863 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1849 0 obj << -/Length 2037 -/Filter /FlateDecode ->> -stream -xÚ¥YKsÛ8¾ûW¨j÷ UYž$pt,eÖS‰âµä­Jr )Jb… öx~ý6"%HJÕ–l‚­îF÷×Àd„ጄ‡1¤ò¨7Zmz²$ÂR’Ñjýmüùhðxq÷e>›L)çÌß=>γ‡ÿ»ÀÀ,¿Ü-žï>›µÇ‰¢ã»ßæËÉÕï7óUgNßd‚™¶åÏ›o?ðh –ÿ~ƒSRŒÞà#¢¥7\0$8cíJr³¼ùw'°÷µù©Ë\H$(÷À 1ß;ã(‚|B€Éçzð%.?Y&í¦i¥·ùá“=F¥?û Zs¬ã" -«¼x?ö! -yÄ;ÈsYÖ1šÆz …+I¶ÝïŠ ‘ã<¯&S†Õ¸Ê­Lõ~ÉÒó\Æé€íK_HËYæVè.°âã,Lêud^@Ö Ââר´ 2ÎÚ_Y¾0ϾcL·uTqn¿ê•Ä2FŽyÙ› …QYFkm"86À½ÆSH Aã‚Ò`1Þ˜g1‘ã:3ôË»yæQÆiœEbWÃÎg  YÉ‚4Z£0[Äx3>öùeXõ¹Îãªãj€õæÑ™sX-.×q9¬BK!á+14/ÜéO9åg`…Ù¿€*¨9”Óª™ ª4eŸGfÅ C‡¥Ô €g>¤AYEEŸÉÐÿ|XÜ~žÍÍÛ2-ˆ<0×£C½åÅO(pŒàñj·*¸1/àóÔ°ÖÄA‰ÞµAVÔ¥ý ŸºŒbˆ.m=a`é±q9M!ÿŠçÁ)ô¶”¼Î×p¶\ 8gÇ*=‰ AÙe•-“Cew>CTao¨rV§{㼿ó̺± ²u©qsåY‰yÝäETg£$oÁ»¥R/I›õð;ë÷¾3¨;`ºãb4 ót'QcÖi¨EœÒë¡¢Iê³+¡êq]UËÕ„êW€Ü•æëèØ.åA·ää²]-“îAÁ1!øаå> -ã $SÞømAîæEg“~†»(ü©I¿ G³ÁB’§q¦#Üü4NÖ¡éëís9^\æ2K‡Î -‚$ÍËÊVÈ.Ùe‹™‡:¤pjÓ#¡¬“ʼçó ÌcÄIÝji~˜›g­£¢¬‚l}$°o¦Yô†»8ÛZÁÉ6/âj—š×ïXà§O÷æf* DƒËñc^–1ºÙV6ñ6¬}§`ç>’s ’ï”ò· ÈôÓs&{í¡ÍZG›ü¢ ²Š²µC‰®dJž’x›åEtN‚ -BÙµl>A\ÀÔw1›ú\糩ãÒu’ë¬?i¹˜!"%¿¬¹ãr¨&ŒD0óùCÝ«®¹äiЖ»Æ˜†Ê7G=èP'_" f¾œº0ÏhÜ0i“+žëq]ð\Ëe0Ñví“R#Lïü²ê–É¡zè9øêyþPwç¹_ò–±u`ígÇ Ž ~Ai`>ÂŒšYèi¾z~Z˜ÿgóÒøîó³9ÿyÒJ /ë÷’3ÝCr8Ú°6=LªVu‘µÉkQýWv,©‚ª.‡{$Ãa8*̈[X¶·¨+Q\QSKÛM…[‘ºJ¿Åå÷´æܳœÏÍï>/¿:öèrŠ® R׎ÛÞn<¥G¢ÞçF÷C2´"•uš©Ú ˜ ‡z়«@. GÚšóña13ò”ÝÕÚL\Vp€Éí8øm¬O³ÐºõKÕЋNÕŠ¨×ÀÜ~…î µ˜¨¡cïžWÿúútÉ£†ï!ƒ^˜E!Ëw˜’Sûû<+ó¢Šëô bÈ=jåp -KˆöJ`5 Ûp´J¿ÀX5, ›ßƒàAY/Ä6Ù(õ 5´Ò]ãʨx -—‹ðæÞ³|_Æåq­aPÁ¤ÇFDR$ˆûÚÚ¿¢BÇûb ì‹0w*ÊQ;®Þ¾=ðà·)ÿÑR^G…vVì!¤=õiøÇÛé&N"ǃ° ÖöìNîÚ!Â&=ˆ¬=¢E/õvšD¯Qòëb7µí¨Ô¡ -Š·ÇIûóMl]ÇŽ¸/ɱŽÌ!oÊÀ«„é[‘þTóp_—.É -Ié«cÉû«NÙCj¸ä1¤ƒQ'¯ì¨Ê!yè£ñ:Á |âˆúª¹p¼,ÜŽ¥ÞÉî_;꯫ֆTÞsžE¸Û&ÅÈ#À?HÒÙ|yÿôð¸zøºøÅ^éš6¼»Ñç:¨^z×™­"šnJSC™ -hhÝIf‹¥Sõ‚-1>‡VÖâñ>(*óI÷Sý4—W@˜^ )ekÝâ—Ú^eÁÊÆôZ«íay õ©9Бæ‡Ücw3Àuœ™Sl#´éÂÙÑð;¸m+¤]‚¶Wv}Ýv$¿=êìº-¢î ¡–ÛÚ»¨Ñ£oö^óŸ¦bK8¢T»¼®ÌszØÖi”Uå­#ŠDøˆIß럘]QdHø¸)œ‚#ßø&°ªí~ÕØ.ÌËÉ¢fµW§p%>FœuÙû!ªÂïZ¤BžÇd>Ð×ÊaAýá±o­öð{{5Wq{!±ªà8 À&Ê ñgqT¢s×è5}÷íèQ¸Ë½ÿûŠýð/®ã(©{즾ÐӶץA>=d`Ḑ¶ÿ Ðøendstream -endobj -1848 0 obj << -/Type /Page -/Contents 1849 0 R -/Resources 1847 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1846 0 R ->> endobj -1850 0 obj << -/D [1848 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1851 0 obj << -/D [1848 0 R /XYZ 56.6929 496.4666 null] ->> endobj -1852 0 obj << -/D [1848 0 R /XYZ 56.6929 433.6488 null] ->> endobj -1853 0 obj << -/D [1848 0 R /XYZ 56.6929 370.8311 null] ->> endobj -634 0 obj << -/D [1848 0 R /XYZ 56.6929 332.0288 null] ->> endobj -1854 0 obj << -/D [1848 0 R /XYZ 56.6929 299.0792 null] ->> endobj -1855 0 obj << -/D [1848 0 R /XYZ 56.6929 263.5784 null] ->> endobj -1856 0 obj << -/D [1848 0 R /XYZ 56.6929 197.8388 null] ->> endobj -1857 0 obj << -/D [1848 0 R /XYZ 56.6929 126.0307 null] ->> endobj -1847 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F55 970 0 R /F23 682 0 R /F39 863 0 R /F47 879 0 R /F53 962 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1860 0 obj << -/Length 2811 -/Filter /FlateDecode ->> -stream -xÚÝZÝoÛF÷_!àJáf¿—D8±/pÑ8¾ÆA ´} ©•ÄV"‘t’þõ7ûE‘%ùôå Z.ggggg~óA“†d–„YÊg*åH`"fùæÏ–ðîÍñ4q ŠûT¯.^þ›©YŠRIåìaÑã• œ$dö0ÿ5ºº¿¿¹»¾ýå2¦G¯Ðe,0ŽÞ^Ý}¸úÑÍÝ_¦4ºzsó9gˆ”!“8º»z{s}ùûÃ78}‘ fF–¿þŽgsü‡ ŒXšˆÙ'xÀˆ¤)m.¸`HpÆÂÌúâýÅ:†½·vé” -KH¨šÐ%3BP*(A¤H2ʬÞÝ?ܾ»{pŒ°=)’"ÁˆšV¾'ŠûTaã å*³oÌÇ[¦ 1–ÐÓ[¢‰-YoK¸fFR1ÜòC­ÝµÞÞ?q7ªÊõ7ÒOºt£bá~›•'_UuãF›,_¥Ÿ.j÷›gÛìqí'«E·…Dæ„`ˆiO0*Jeγ×ÂHxÂç"ñ$Y9ŸàçbBñÀFžg³»$Iä¥Ü´M›­»£Î×m]Ìâß0¦Ëv—5EUº·ff­Ý¸(ëFgsGmìk°|®Y»n^LÙ‘ˆ‹4HùR7ùË2Ûè¹½çYÌ$EI!&v¡‚t‡™8e(5Íñ‚P˜H=˜(Y]Æœ‰H—ulÌ<7«¬1#¹Ùu•Í‹r^zªƒÓ›Épz³š¢luíúÝ>U»?A¶hônĵֻ§0¹Ûã†Ä]`4§]eåRå²4*šÚ w+«y˜îySí¾ø©V»§ÿ›¹ŸmU×Åc°†á¥0ŒRŒ¥W$0÷ŒU."J?¨¶Þ<Œ þ×Y &_L˜oLȆ”$#eœ¶ãA*«^UízîäÑÃJæ4{¬«uÛøÙmÖ¬ŒÙEa@Z@t]úTÇÑ¥£²è2ŸB‚’TCžëÇv¯ýׇèBÁqÏÉ×QM8D…¤„4ð½6‘%õ7ióLoªò»Ú?ñÜÐÉ3HTÁÚï”pƒZdú\ã«H Æ÷ÎÌ…Š®Í’¥5{+Ñ.Ë×™ ÖªgEꤾÊo_&vdà|Š…`ô¨cç“œ˜{Sé‚6!PUý°>ýX… žÕ£0tC¯+¥ËܱÈj]7A΀9c‚=ª&¨¬ .Ò -Ñ tsrË@4±å ÍQˆ&‡[þÔ–#Í8tú½\x/Ý·¥wêß°À¯åVn¶¬|*äì´øK9®W¸V&å9½ö¨Nè5PY½.'ÒÇ$•g¶ D[ŽÒÇD©Ñ–ßH¯Yx‚<ØóÚ[ìº -^(ö®>J"!£‘]d¨›¹Þí¦œN dOvô’¸JMÕ™KêS¿¤ŽÊ^Òf -9à H°Xg7I RKÂåiÁ:ª ɸH¡HNE: 2µ;)9‹lÄä<Ú€MÛsm-µÎ÷Èh¨ ®²lY›v0¹±Þ’úwî!äÜù#$…Âx®Ó‚Ûk"éJ!AttTS‘\"Â;6²±IžË’j7?kNgùÔGIÞçWHÍÒq>Ò•>Ã@7(}6yóù9骱‡•ÑŽè.§ÞVÁ!›jä·ï_m“& a.ÀÐ!ž3NŸÓè¡PñõOµyâŽaÜãxhÅ4âļ TæXooÞŽåc ?!“o'_Çð´| ÜZ5”ïúæÕ‡7¿À!¢xßpѺÎwÅ£žwð9QäBXÑ‚Aý³¨ó—à¢hõ¯gä4ÇÀ¬˜*vëöD' ÎY¤+ÏfšÿÈ·m}u%ÈO‰ÕÊ5ð ûá¡\¯}îÓLÐ+ÂÕX¾ÃÌ ò;S™Ç?ñÜçïwUy‘ý©ÝL6ÊÊÆ)¼°Õ+ün b-¶kOôúþCí[°·žÀ¦æ]½Õya -=1‘}ëÄŸË>¡R†ì›³¾|*l̤n êÛAe¾`žPUn\¯ÇL¯ü l76äswCkäw3[)ºlÜ„ ö0È÷a×T{ÎA‰žEà\‘£½]¸™Â3-ünméûNœû<Ô08`ÿ}`ëNÑëX™S¼ð©ˆOo â…¾V¸wǦ'²yW„Ô%‚ûÓÎ:"³á¢ÅIOìSwÅŽÊúâö¬/n«]sèŠ%\œ–+MÈ5Ì9 TR9ìÇ¢nB“Ñ$vð±Õ»BסéKf/ß8òÈÒ½/î©Î‡¾ÛÅ(8Ö¸²-¥a—ÓnfG‚¿S åçî´GuâN•½Óz¢ŒR ¨âä–hbËQ¥$‘Ã-¾T<Ú¡‹RC3ö©¡Uc“5p­E^ŸÈ×Mi.9ݧëU;uq,ÄF† ->Ø‚þ\4 -'– €• :NŸæYb¿€ ô€Êt(Àhòrë0ðòC·‚s† ]Ld-)}µ÷>K¨þ%…Ä0F‚aa~×Sœø–°`4÷w—±$ÂÇ’F7ª¦ŒŠª$ ’K»ùìã OSæ¨zc{Ú½ìÄËÛ ]Wp¦YÿXsÜgmÏ%iÿº¡ -¼DrD¡¾ ð¦ ñ„§ÿƒK„Ç€Wa¤0 ÐÜ%èêãÝìBí§h¨¿®,àþdÿg!ø¶ÓèÍQ †Œ’¦„{ ÆžpîÀ·?>Äì÷YŸbB!§I‡Ó§rÿ9æ-DÂo[k?Sx*°”?Ú2ˤ¾ÍÊŒ5Mtê(dli§Á¸u4C)9(ðÁgž¦ïN\˜ç«xegÏ”AV96çÌUNÛõ,÷`Ü–¥ë]ÁLÞT®Â¢Ñ¼Òuù]ã¦u XŸûj­Öyë8Í_À•¾€³ŸÄ-ÑHj7õ÷æ“ZØG×mûdb‚BJDÅ*¤GûLMkyBa€,‚ã'ÙÛT qÙÒÅ)aÚ©6¾}²¯¥‹Wb¯óàoFNŽÀø©Xë¥ö‹mì…—ºÎ³­;a¬ŒŠ\‚‹˜aý‘ëãá°ç¨_çúG4ÃÄRšì%rúûž…{þê¿xÚÿED1íX§ sÄ̇.&ðrF«¸ûã¨@דþ¿ñùjendstream -endobj -1859 0 obj << -/Type /Page -/Contents 1860 0 R -/Resources 1858 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1846 0 R ->> endobj -1861 0 obj << -/D [1859 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1862 0 obj << -/D [1859 0 R /XYZ 85.0394 751.3856 null] ->> endobj -1858 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F39 863 0 R /F55 970 0 R /F53 962 0 R /F62 995 0 R >> -/XObject << /Im2 984 0 R /Im3 1108 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1865 0 obj << -/Length 2226 -/Filter /FlateDecode ->> -stream -xÚµY_oÛ8ϧÐÛÉ@Íð¿DìSzMr^´n/q±ìîƒbщP[òZR’~û›!)G²e÷½C‹¤†3ÃáÌüfQøc‘ÒDn¢ÄH¢(SÑrsA£Gxw{ÁÍ´#šö©Þ/..oDb4×ÑbÕã•š¦,Zä¿ÇïIB&ÀÆó«O×&S.¥ÐñÕ—/×ó³Á\Q JãOWó¯WýÚ—‰áñÕíõýäÏů׋½:}•¨Ë_¿ÿI£4ÿõ‚aR½À„f 6R ¢¤ÝÊúâþâŸ{†½·në˜ ¤J‰âRƒ1$‘ܘqC1’0D‰¤„&0ê ÅÙ˜¡:*4ԴŃ^Þ(Õ£dŒ¤FfŽ¤­íîІiRõ%éÕè%zÒLBdbôº·M[äp'pMtìï’œ$Àý@ÇÖ\“”™$e«¨ËeµÙ®mS”~¾ÝÏÅÚ>Ú ²ÚÚ]ÖUY¿›LåqÝ.Ÿü«¬Æ§ˆ—» Kc›5>"®«å7 M jžà½Û¶.êÆ–{‰ºFÓT)áäS0¸QŠ;-ª€Gn«]S“à HQƨHE8Uéâ"u’Žû#E54©b§™ù˜…á~ËÙ´Óoª’”¤œ&ý»ßw¥ áIÊ# L^ˆ&˜÷®RiÉœOR¢—á*?O¦šÅ øåñõ‘m4°22ÒœCÞp‘ý1BÁÖÂÓôÆî¬oFp —³ >Tp ¨¦ÀwÚc쎤y?x¸ ZHiÞTjㆫRÇ‹rÂhܾ¾ógÔŸwºóé2Û€xª¾¡ˆRIòæùµgÝeþU”ñ‰›0Öy‡;pÎüc¨[îU€°šL%ƒjY™ûAm›nW5õf)楇qº´5QegëªÝ--ÎôMá^ ûÄ_ËÚ¡“×–Yc×ßÁ h ÉE& -ìRÔ~óÆfeàêS‡Ù q A!½ÒA"ú"'å,T[ÌhžgU‚ -ît<Á$ :8Ý ziå ÷ ¯“›øåÉ–#^ ¸"™‘?öZ‘òη‹ÀÒ h18xŠyÑ­8°É ',õ¨®­3ÌèÊœe¿>ÂÀAŒ™nwVø“€9ÊùБ ʆ¬i×E‰7ŒXðBŸ‹ª­=ñ¼°š#€á†²jü -DS…žñâ§ÇA‹ÎyaÓƒõóm²¢tn‹†{^_íàó\Ä@õS‡ñGøy‹ð𵟿${m vš¾•ú€œÛCõÐË•=§ï’¥À#)ãûšûÙíüêãýH.¡X‡µ‹#œ¡ý8T–.OµÐ§Z¿°ïK¡*á‚AUòXfXoàËú©j×x<8.>„èT~äò<—UÙxk¿Ç''xƒ54Ô€9¿]û8 @Ó„§]Á·+óåXë 53¤Ç@ô¦Ú±FèÃÐgùIô`i°vz½úT§ÑkO.ä_¿}ÜH5ŒÛˆ€å„&зäÞTÎðË–ü…õ°Ž@ÃßÉ$‘ñISq,׌:o©ÑiCuDÁN³ù!ê××wŸŽú0“NScOt¬ÇÀr -Ò­†0(òÔÌÌ«—ò¼yàŽ$ Âï+24 )ÙöÍ]ïQ¸3wmËÜÐqåÕ÷ðÄ„’ë-èPz5®…¨-sû¥¼´Þɳ„¿„RPùo_ÿ<¿™Ý~½»Bƒ/fŸç?N‹®E\%[3ò=aÀJHB™î:mÈ -¨écëó v"Æ•µëG¤‡"XkªÊü·´Wÿ¶ ‹¹­—»â¡ÛSv«Ðˬý͉@°¦÷H>ÌÙ>—í›"^¸ÄÎ Whб—aíùs‘w_Њž£¸ãËÁ÷cE¤f]#ä©\团,êÌQ…[½³« {ÙEð§¬l³õˆq™N±JÔý>ëðö!Â8¶1Þ |åz3û8ò:Ä°«•šŸó‘‹/(JŽã¼#B‘—¶Y^:?!à«ãð†ÆNéä¬ô=Ñ‘øƒð†"]¤ñ‹ÑêøÈ#qÑ{äÉ4Vgà'çÍÓ#:mžŽÈ™ç9Û]îÚ2˜h[äGÒ+yV=Ñ‘®¥CˆÑWaÜD!ð“Ô´ÈÏ[¨ÃAp{1Ú/Ó½oþôÿ8Þþ‡#!Y¥é _€$M`³î”ƒ2Æ/ -.¾r¬û¿IË!endstream -endobj -1864 0 obj << -/Type /Page -/Contents 1865 0 R -/Resources 1863 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1846 0 R ->> endobj -1866 0 obj << -/D [1864 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1867 0 obj << -/D [1864 0 R /XYZ 56.6929 361.2723 null] ->> endobj -1868 0 obj << -/D [1864 0 R /XYZ 56.6929 210.791 null] ->> endobj -1869 0 obj << -/D [1864 0 R /XYZ 56.6929 130.947 null] ->> endobj -1863 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F55 970 0 R /F23 682 0 R /F53 962 0 R /F62 995 0 R /F63 998 0 R /F39 863 0 R /F47 879 0 R /F48 885 0 R >> -/XObject << /Im2 984 0 R /Im3 1108 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1872 0 obj << -/Length 2455 -/Filter /FlateDecode ->> -stream -xÚ­YYoÛH~÷¯ÐÛÊÀ°Ó÷ñè8Nƃ±ãÅIŠ²S¤F¤ìõþú­¾(’¢ä³0`6«‹ÕÕÕ_]-2ÃðGfZ Ì Ÿ)ÑÀD̲õž=Âܧ3x’È”ô¹Þ?œ½ûÈÔÌ #©œ=,{²4ÂZ“ÙÃâÛüâîîêöÃõ¿Ï*ðü=:OÆó›‹Û¯zÚݹ¡ó‹OW÷ö¾&mÙ$ž¹ýpyþãᳫ‡N›¾Æ3«Ê_gß~àÙÿã #f´˜½À FÄ:[ŸqÁàŒEJyvöÏN`oÖ}:eÁ4šª P2#!èÀ É(s6¸¿ºò[½øóþ³ÝÏ»¼o8<ƒY¤ QŽýËÇËó„<‡í1Ï‚öì#É¥†Ï,÷o­ŠŒ†¾8þÿ'~A\B1Wé:_$Ù*Ïž²ºZ~ÇkøG§ÿ[Wùxz[-²1­|Ùž=ϛŤ0—~æpS a.%ŒÜùy¼¾¿¾ýàË„3[¬‹ªhÚmÚÖ[Oú’/s¿z•åžt“V»´œ0‘Q «x{ À2MÒ1%L!ª¸ð®óõá÷Ï_&dvx‘Žïºjóm•·^“ûצÍ×¹¬«¦Þ¶Ån½_—#Æ% r8Eœ*/üNƒ{ZƒÛ,Hbås ¦=¢À/Ç}í–ÿN©ò#{(~ÔäÛç<©u†¬KOصEY´¯SFÂÑ8ÜûÔkUoš¢‡ >ÎÀQ¹VHi3åÍ4§‚Ãx2Øa„¯¤'ÁÇ:3ë"Ó~ßì÷-ùé· úf‚8¡‘$4õn›åIºXló¦ñìÃ%’ZFöQr6!ÎHK!«…~ñ˜,‹2Ÿ+R‚ñ±Ø§7Å>å¯Çdr…4Åj,³ySfáD&¥œŒ%n&$&L‹¢bèÈÀý„`ʱic$ø_Ýèub‰¡ÍÀcÔQ¢á –+ØcæWÒEFk=”’NbÒé€8PR‚5d¿²U±XLlPÄ“ígõzV‹é°Ä5â63<ïÃÕýå—뻇ëÏ·ÝWGcSŒ$£ˆA) }ØlÜÂbÞ®r?¨79Þ¢®ÂëÒ?SÿQFHŠC„…`Äç×m˜Ø„&_ä=ɇZSnà€¢i¦u†‘Öå=OŒTAh–{IÃ:¿¡çb‘/<¥ˆ{(Á¥eAaŒ„À4"˜zÛ¹Sæi“7°+Îôüz9¡¼ÀHs•?fq†˜Ž/¬’†JÏõ“ÓJ°—¢]yrU{JĆ#–E•{r½±D¸œÏÔiû¸[çUÛ@&fÄ·þƒÍ¶bàófeÝÓÍ6;XeûÄ-½EG”a94ˆG…Í!»uo§¹è0rž×{úœeú³ ¯{ýGÜEHKƒ½ i„2§A{ „u _¯wU‘¥­…"S"ÜŽœ¦LÉhKŠiÒŽën”úÇÃåçÏ©ò¬-Îɼ®Àê+ø²ZÕ£çÜ›Æ}¾ƒ•ªÖ)±Ð J ¡Àç‹â±hS› èTlدö_»¼iƒŒ8ÓñÐKÕÂø?šþ÷Íð“[ýa‡e9XhRõÆÃϺ{Wnv![¥`“Ps®wMàüà à<Æ–Ÿ¯!&øÇTî‡Ò™1j¬¢?÷G‰I_¤ï6þiÃ`nö+‡ÜïU­ê—*l¼ Ÿ.}Èf'_¥ýR˜³{1±Tóç•ú`ìý°™¤úŽ1}ÜuÉæ,ÅÇd4dóE½ÌÚ§ ¯êO÷óNP›fm ®[ì.X¯» 1´[¡ Ü_|ª¶Ó—zWÛ ¨ËöÜÝ X¶+ÃäÎBóí–峫™î.4BÃA‰D -zº+ésÅû‡Ã¶¤ã²ëv͈èÇIEš`G›‘¾†V—›Ó*v\:ë(ÛQR:Tòk“OÞC*ʼn–i ü†iûÔe=³+uß[xf¹Ÿ°‚|x œ>–gø„ô‚gUFždÍYJk>ÒÍ®l‹M¬@ŠªiÓ*Ë›~½æ6ÿmWÛD×MËÒû‚uÞ¶u ÞE·eˆSµKÙ}'¿¾{æ£"H2éÙ±ìm‘ûšg -£D¹rá Œö¹Žc´ãrͦ0Š¡$GÚÚ@%A˜rvZ¿ŽkBÁá•DŒNÔ60¤óÈ• -xï¡“˜€$b&b¤%ÆiÇ5Yý‹=wbØþóE¾Ld¿Mõ¼NF‘¨å»¼ÍÞÙ`î.ɦÜhpóp øm§ÁÐã:†ÈåÀðôfÀê_F À9´ê‚ŸV®ãšÐnpºÐ*(L†êE‚QœN^– „B»†¹2=PËgÊB¦J—)Û½p.Ocú‰£'B#M>8úPÈŒtS -"²Þ_VBiL ^ ëÕ¬:K è0’ý•|D„ê)‰Ã"ù„`u£IÔù¥°õ%Ê×gð„|»ð#áÙol,Eö{B¢b5ØûÂìkN;.–ûɉd¤CäW}ÝCע΃"UÝF£Ä¥5^ùŠ¦=êpÚØxÈNû[鸻E&çmÍ›¡wM7ð5F–ã¤^ÓbCïa¢Ô@³þíà°ƒPóÎ×üm†‰-œ‰å Œüí„fz7±}ÓÁÆ¡3³ÃuÚf«<|”²Boóuhu¿ãé‹”$þÀ%˜ž3<ïaÀgzð™öåÈau® „¢7e(›Û{±ÂÂ^9¡örÇ.Ô]0Íõƒ–oY¸¦Þ¼J±~Ò½û Kµ÷AöÆÄë  ­j×åéð#Œ'ÚÊ’‚S0E„zæÃ’ÁÏe -®K¦Qu3¸ÅéC¯(:rÙÇ #ãì B; ™Ú;û¸Á½þÇ Õk"mBÇ~¼dÙ{Õ ‡Á]ñ·ØÜÿnËm]¬”; sÄ E¥ì~ acÕ»Ÿ@uÿ‚D|Õendstream -endobj -1871 0 obj << -/Type /Page -/Contents 1872 0 R -/Resources 1870 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1846 0 R ->> endobj -1873 0 obj << -/D [1871 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1874 0 obj << -/D [1871 0 R /XYZ 85.0394 752.1052 null] ->> endobj -1875 0 obj << -/D [1871 0 R /XYZ 85.0394 676.9839 null] ->> endobj -638 0 obj << -/D [1871 0 R /XYZ 85.0394 637.9396 null] ->> endobj -1876 0 obj << -/D [1871 0 R /XYZ 85.0394 604.8838 null] ->> endobj -1877 0 obj << -/D [1871 0 R /XYZ 85.0394 569.2766 null] ->> endobj -1878 0 obj << -/D [1871 0 R /XYZ 85.0394 503.1887 null] ->> endobj -1879 0 obj << -/D [1871 0 R /XYZ 85.0394 431.0324 null] ->> endobj -1880 0 obj << -/D [1871 0 R /XYZ 85.0394 247.0209 null] ->> endobj -1870 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F47 879 0 R /F23 682 0 R /F39 863 0 R /F53 962 0 R /F55 970 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1883 0 obj << -/Length 2194 -/Filter /FlateDecode ->> -stream -xÚ­ÛrÛ6öÝ_¡·¥ÚÆDß\Ç麓8n¤tv¦é-R§é%){õ÷{p£H -²§ÓLf"ðàààÜ/0™aøGfB"©¨šÅŠ#‰˜­wxö{¿\‡³ðH‹!ÖÏ«‹Ë,ž)¤$•³Õf@+A8IÈl•ýýŒšÿ¹úõòƒ`\J¤‰úéËÝûktýùîƒÅQ¥ ²‚:Ô«ûû›»÷·ÿ™/¨À@}¾GŸ®î¾^}´°û¹¢ÑÕ/7KMìâfÕË1”•`¦…øïÅâY"ÿzS‰˜½ÀFD):Û]pÁàŒyHy±¼ø­'8Ø5GCºã"A‚r Zdˆb‡5LPL Åœ ªDÒk˜’†=–ÖÈâÉéW 0 A‰[¥=ÕM7Õ†¢ˆ«DΆ7žðå‘| ­©bÄc5ák™W™µÈºÞíÒ*kíWWÛßÕõ½]xî&.B¨B,fr"Ãäj*ÇÄáUÛå©»µÞ8¹½{oWê_Ž…,ߤû²óÜU]3'IT—°M«*/̽sÇÁ‚'>å ÿ!Œ9}ú¬W¬ë±ŒuŸ^)cKÂ^¿Ò#®j/¦(æTŽ¯¼©Ò‡2·2?çÍCݺ²~|,ªÇ³J †{U C¬óJ豌ag<æÎôå‡)[‰D"Æñˆ­·ž"•$I8Üžà©#Æ…„Pr,B‘MÙ#˜ AxüºÚz¬€ÞFÑ‚!”$ã[¿ÓIu[·pzšÄšà K,Îë’ÄŒò;êÒ èr$dÚ )sª¨MJú’²±!½›ˆÁþ cú¸oÒ®¨+ Ô2GÁןW c1J ˜|7Åx‚o(Ì…bE’¿­˜Ý¾í¬ØÞ%ªúÅiâá eT¥»<³ —¢Û•Ôg 3'J[‘ %„M-œÑyBDiùX7plç>mQ›¯UòÎ}w ¤».4‚GµÁÈòÆ‚7µ[L²´ˆvyÛ¦îÆç´,2oQø¶5nد×yžA—À¨ˆn7ZÕS3%‘”ž75 ª@µR&(zþ©­{Š‹!ÉScC F4!äxóYc/8 š@æŒcÛ°*ƒF©}Ê×…ö÷<{çN“qPÚ—¬š*[‡J.C\2/EYZÚšl£K”uý—^0áœD]§vS+×,Öeº×)J¯µè_«¹Í›ç¼q|wi—ïòÊQ×µ}€‹G¸¹ñ*Mˆ[9¡&ÐMH6öYã]ŠG…ö e<Ã|{r6¸Ú ¶üd]¹í7¬«*'©mëV7 KÍie6ÁÂu! £ }ÐkCoÖOÌž´{·žF0<–H3Š4’ŒîêNŸÅÊs„G@§‰vm"캴0ÂN»M­¼™Ý=†²CxÙë­Ýs˜®-à˜¨)ÛjĽÖJW¬A˜l,ŒõÚÓÖ,ØIV.óx7hu¼ݺ¯ÝÖûÒu…p£eoS÷ljµÃݦÏô˜Wy“º‹-nßZ6ö÷²œÃN!Ñ´-r ÂëâFÀé˜F˜æ ¸ÔÒ<•¹¡àÖ¤EÓ` ,@Ûý“îE6aóá_J´q‚¼¿ºu?¼ó—çæ\Û eWÙ®¨ -ÈÙiç%ù’oœ6«µ;ö)­ö 4«&঄Œê•×ÌÁ;ª€ #Lbú†Xe?è"Uï ­ÿ=îu(L<ÅŠ ‹ÂïlóòÉ®\AA=G}XAV:ãÊ3´YÒ -òñöÓíÊ ›ú¿Õíç»e@pi*`œ¿-ŽÏ©Y·¿<äÞ™­8Q˲wëP„ø¨ß>CIÈ@:h¾½ÿ„Y%JO÷Þö]QÝaN‰¼÷CªUºZ9÷·‚¯|àÁõTÙ4 -¿ë}ã<¨+d’0ü¾¤Ð9€M¹õs‘">›ÁÎ(=Q5î4àÛæfX¤î…A ¥ -ÅXÈך<®õƒ”xÂøwhò,ÁÅ¢}Qr¦{AEâäxñkM „ˆ¼om“¥éõušý8hƒgºÊ€£c56â2>æÄÜZÎdz‹ŸÖûaŸr¼k–¹³R3y 4<Š°åÍ=zõqù9 t ¶ˆ¶ù†ðyw,™&S`=[͵|ô$³V,˜ÏPƒÇí$Shš)tÌ”SSB“M¸7f8!±R=Q>#¡ÌëØ×Õ¿?y[S·U—7•O)ËC Ž3Ü54_Šýîx¯ž¥·'HÞ¿î9ý$C,ðnóaiô"¸ð¸ (”++Ǯ觑ª¥PˆÆ Zˆ0¿#Ф`üFi쪎NjþÝgû(XÅ‘ƒªú©…\6M$h6!öQ"xðÑò¨¢æ‰îÕç’!‰Ó áŸKz¬3 -?aïo–×_nïuñ:£ïP|…ôÃ$ƒ½¾Í¸!ˆëÏCÊÖ»¾ÝÔ:CŸ$ƒöùï54Ðço¶Ñ©¯S`»E 臆é+ Þ¶…$Pâ·V.<àœ@Ç耩˜˜"¬ødk‹]Q¦D!5èægÝí}IÔP3'›í´Þÿ³ë®Ø…ÀðŸpéß¾Ž™,d(n±Húd²LDK?Ó´îê!¢ÊÚ´íŒr;–ô¡I×y;Ფ:Ó¾›oóXà´€LÓt<¤z2ÑŠß‹u]ÖðîÍäc†jŸñ£=N`­Ý8ú£lk‡ÖSuç{æÜ-+OpßîM$Ý/¹øê¥çÂ_˜±úVü§~wP#¯]Ÿ¦iýd‘Ë,ì‡Ëà ¹w®ýcºoéÊ¢ÊÏý…C÷ÝŒ…ò -îSÁ?þëÇñÏB> endobj -1884 0 obj << -/D [1882 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1885 0 obj << -/D [1882 0 R /XYZ 56.6929 546.7712 null] ->> endobj -1886 0 obj << -/D [1882 0 R /XYZ 56.6929 448.103 null] ->> endobj -1887 0 obj << -/D [1882 0 R /XYZ 56.6929 386.1077 null] ->> endobj -642 0 obj << -/D [1882 0 R /XYZ 56.6929 347.8768 null] ->> endobj -1888 0 obj << -/D [1882 0 R /XYZ 56.6929 315.1782 null] ->> endobj -1889 0 obj << -/D [1882 0 R /XYZ 56.6929 279.9283 null] ->> endobj -1890 0 obj << -/D [1882 0 R /XYZ 56.6929 215.0111 null] ->> endobj -1891 0 obj << -/D [1882 0 R /XYZ 56.6929 155.9807 null] ->> endobj -1881 0 obj << -/Font << /F37 747 0 R /F53 962 0 R /F21 658 0 R /F55 970 0 R /F23 682 0 R /F39 863 0 R /F47 879 0 R /F48 885 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1894 0 obj << -/Length 2682 -/Filter /FlateDecode ->> -stream -xÚ­YÝsÛ6÷_¡é=”ž‹P| ˜<9‰Ós¦ù¸‹;Ó™^h‰²x¡HU¤ìsnú¿ß.€(šŠÓ¹=\€‹Å~þ3?1³šq•§³,O™æBÏ›3>»…¹Ï„_3‹æÃU/¯Ï~x£²YÎr#Íìz5àe·VÌ®—¿&?^¾}õËù\jž¼dçsÍyòîâýÏ?íãy.“‹/?Á«Ì3‹rvþÛõÛÞh5`¯òœe©F©ñ?Þ¿~Å^}xÿ—ž]^Gq‡G\¡¬¿ŸýúŸ-ádoÏ8S¹Õ³{xáL乜mÎR­˜N• -”úìÓÙß#ÃÁ¬ûtJEZY¦­Ì&t$Õ”ŽtÎŒ‚)<ÊÏMõoÒE×?Ôåóó¹<ù ‘ú–že³¤A»¢g]5%©Iåƒøl.,Ë…&Þ»f¹`‹¶YÑÒ#a´a2S^ŸUlS›lö‹5Žò¤«6ۺܹ_ÍÄn¹fÊFM±)—'wóeÚú¥àŠçÉõº¤Íþɹ¬KÚkß•Qûõî\ؤô]_ôå¦lúî9}2¹uí¶¯Ú¦­zF“ -3›K!Xª  ¹ÖÒÉÑ•»;wF§}ÿ!½Aã=>—£uÎMÇÇ#=V”€Ó+ä}¬¥4e9—ÁÉ)ž% Ù¾¨ðœø†*»+ýL] Ö@«©§D0)ãÚhÏ{Y®Š}ÝϽ‹b Æ›ôËiÚ­ò¬ÚºnïË%½Ý<г_ûeè¤{%4KS>Ò} zWR$ÅrIfî:" ‹» z8>nˆÄ‰›¥èBZ*8lå?[·]O£ûª®itã¿Ù—~n]6žo‹O~ÄŸ¼Çëmu>(<©ïNìÛ½·P ZI‘b’ƒccHN¨[r–ÆH³¥ú„!eÆl&íÈŽèž¹šœq©Í؈ÒúóåC#ÕQæÞˆ@ÊɽU,YÅR8 ý~]aÊò¬– ‘ -tÌ·˜:O.˜ÈLrú R0ÉÓ|sr®TBli™-Sá¡øœc’+ÜX´÷ãÍ! BÊW‡½«åÄî -J€Îõ W*“'[gÿö®¯\º“±mèI„m½iÑn6.« ó7d(()‰§åÓJ‘±Œëì)õžª±' kÁÎû°MÕ© ×MÑ/Ö^™`#f°Ç.[5·S 꼌9•FT:me48z*hÉÉgEðcz!ç²”2Jð$çgr¹'*øy®"P¢Ýïåë9ÖòÇ'JÂ!>Ð6j”Æ Öƒ#µLo2¿3SûhÉ„ÑÇéá!xµ/W€|“…Ã@C… ‚»Ò•½'8¤ -ƒ«w)Í@$’ñËA8tÚ…_<€6eçÃ)ÈvO~Õ"ðFýp.„H&ñåŪ?€ò)㤂e˜¼žÊË–)eÓCU¹oËg{Ô ò[ÓkÕ,êý²ôÀ»ð}C¿Cw¤ ìÔÆ#òE¸FiÇAx¿ÃDªݑâ,tgRëc¯((ÊJQGé ð¡¡ÃÍ À4|²&4'‡M¾nÛ®«njÿ‘wçSA€U"dº.CíÎUÄjϦƒ^Y?‘€28º_ ÀÊIXCáQNE!ô³Ð£ËÔ”YP“ ¸NổÐÓŽ[§Íá¶4Šr ɺ&õA’kXáYЃÚ(sdüó怃ò-!6ŠšûF¨”ÏpÔì77Î/‘áÍnÄ%¬÷! ”X ݺÖopµŠÁ6ËɦW(Æ Ï¿EÓl’+¼”„ÊðÙí·ÛºrY‡PwXpœ9‰8Žnü"Ÿ¯_Óõeá_œÆˆw»„†1Æuß*¹,œÙŽw#“Cß R> -6Ê—TY|.iDõª”ð¢&êÝm#Vðk§”iüË€nŸ,!VC*Œ*mwS, Gÿþ¦zÁ³:v­xhWš8"3i² ‰Ê <Ërv–Ò¡Ô/tœË®ü•Y -ݪËðúÁWüdX]pÉÈG4ÿuäDeçÐK¥ò뽆dœçöñEÊÑ5oÝ Žï«~0Ÿ;7A -5†«W @Å!L(9H¥ä#42ˆS(ižYKy‰á²;úû6´‰,3éȡõÉcE ز*¸eQ߶;8Íf*È!9 ïÑ­/ÖåS‘R2)›Åî!à\˜80u¯«àÌG—"ÈdcÿtêòRúa‘CsÊÁ™ˆëÒd±ß‘g4}ý@“mC#™üíÝÅ«ù»×Úß“åЗ’ljª·q!‘].ãÍdqÅ¡gA*ö,H-èµ+$GOä˜a±Âð¢ '” -ÀÌË«÷¯iqNß‘ÝîŠÍ„«ú‹;pÕã+šQnÄ‹bºÓáA¡nÒ5¯¥d -¶õÉ4%-àó g{"î …¶û>£WB›ÙAÇ\n™ä±+Ülœ¯•S±/™´<€èzü>EÝy ?7í}ãÅë¦öä–¥* ¬6ÕW6UL¨¸é3¯b-×øÄ0lIuÆ#†Øò!…àP>T]Fwݸ<º½z˜_Ñ74åûžMLÍt,Ø_×e -ãÐS¶åðR¬§½»uµ%‘‹âlî%ß÷áÎÙ2žK9ºÉòa[ÜU]Ä i`S4á’ÿÕ¦óùàSYŽ -õå/ï>þtéc¹ <\„9j Ð8^O„¿nºÑâ°ØA}Qdw{Œ­ZžQÊûNT,è$ öG®³Ëó£æ†óä?N3÷twí‘¢°¾nEmÚ‹)l<¼x†ìÀÃáý…ou§vú#2ƒŠl¡‰:úÆ ·ýŠÔ"â€ÿ¿­!Q÷Ã÷§ö–©ÿ(î<ª3‡îÀó›:!õ(8ÒJ«4üãÏœÄD2Cm> endobj -1895 0 obj << -/D [1893 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1896 0 obj << -/D [1893 0 R /XYZ 85.0394 368.0049 null] ->> endobj -1892 0 obj << -/Font << /F37 747 0 R /F53 962 0 R /F23 682 0 R /F39 863 0 R /F21 658 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1900 0 obj << -/Length 1897 -/Filter /FlateDecode ->> -stream -xÚ¥X_sÛ6 ÷§ðåeò]ÅŠ¤(ŠÛíÁMÒ6[㶉»Û­íƒ"1±®²äYòÜìÏwHP²l+Kz;?˜A@Ñq?:‰Sc©B"*ÆérŒï`íÕˆ:¿eòû\/æ£ç/¹+¢"ç·=Y1 ☎çÙGï¡™€ˆÀ»šú§og/_Ï&>U¡ ½é»wç³³‹_'>0gx—Óه餽›(æM__O>ÏÏ;µúªÓ€~}üŒ3°à§Q@¸ŠÅx “€P¥Øx9 -'"ä¼¥£ëÑûN`oÕntXÃxĆ|¡z¾PŒ‡cJI‰¾ø¢ï'~ö5ºnºÉ_Æ°1¥D rÛÙwÕ:oKä\,“Ô_fâ»#hyQx­ÓµnÀg!pž\ñ×ñ»èÅÏ[õÛö×íŒÿòÛÏ›÷?þx‚{ýÁãþ±‹Ï_2Þ³Äç‚Ä‘0VE•e½(íI^³Ð0àÊKnª?4Òô×d¹*ô3'ŒöÝIiº!ë2KNdŒÄB Ç´Í‹åÞÜãQ™¾M6šêmj§j”Z¯ÿÐk§•ã*ª4)UÝ ùS7Ç$ àGaB‘+)³Yö’ ¶:s$Kßy‘Q"d öݶ›}”Râ™ÃuœVË%¯a?c^S¹{ -£{Ú½3–œõ@ECûÛjëfTèí™ÏÌTzÛEž.pe¹AѪv‡ß8!™þ¬´¶9/w‡ ª™û±FJ/­J#án³Nš¼2ÛeìJ¡‘a Œ#Ô–As·Xv#t¾Y„@žÐØÓñ$ÿ|áXÐTÃÒ$^ê²Az^fy -”º=Æ^;žã<´g ^8ÔlãöºcïõåôÔ¿<8KŠ õº´«# òÆmÝ)‹ó´Hð¢Ì¸*›$/-§Ür“ÔÚBœè2­²¼¼ÃYuûBúï @ ¢Šª¶ 3{‘ðŸU›{0þ}S“H+ŒAøóHb>ßdkL \?Y!¨ç‹8³(æâ8‰eL⻽y;7¨·ñUœ(B"Cþ8>H)𤃿K6î€ -‰;4 žN¾ŸoÀºªÖ ..x«)^ -oó h hߘሑ ÜÔŽ=¯ÎMíªÐùwºÔ"î*ü[CDUKާ͛cÑ<¬ç#,¿½ëÚ÷Uµ ŒpÌß#G÷ñŠÐœîTŸ"÷ |¦©P²2ùÖhÜ°W… Q¸‡üÄH-$`ª Ž‘0-gçâLsœ½;7B².‹{$´ÎαF †ŒY0(hþ·ä Šb«¾xÜ”Yb/'kË'' î|?#«M³ÚXÔ¢ˆù€P:ó<à -„Tm†8Œ:Œô€„¬Kƒ>ráB¶<sÖUQùBôvŒ„Öm·Õz@xè„ÚT3`=tm#,ŠZVôVìXu`´ZçÆ%.i8‹ åÐ}[Òìô[²&""Ž¥SÏ\ ¯°#T$¦,þ¯Œ¡*"¡iýöôÖé¢Â>íäKYmK¯ŠÄ˜üµÁ©q³$ø‡]Û NþÆ¿åh×bÞ…Œ„öÌÙôòí¾>¿š@UþþìÜôÙ¯>\M7çog$1´êœaq·u–ÓÈeNE‡ž†Š]„ݸÕ]é·7áªMøOÒT¯äÄâa¨¤¡S¨[™!O»…¥Õ]™ÿéÂL Á†R¯tš›ÃÛSór¨Fº6æ0e"¢x¤ž‚EÀIåq¦Ú -Á)oÕã˜}F}“–ÒëTÌ4/ÕÌñS’L((}¢Õ&TÊ»Öú@ºçanË^»<„C”HÊÇÄA$ƒÉ~ÒkÆz–M󨻘áHáß4[æe^7Ø& éJßj¼÷2uÛ.“r“;pÂnFCGU` ó`jp«Öõ¹ËŒé›ë·¿‰ó,ˆÍsà™«Î½x¸Ö&©}J ‘¢ÿ"¦ÒÔ2Ö‚âÿóı 4Š æF]8 xÅç!¼ß ÞŽé‡ùë·W»å°k]¶àz}_ÃU»Šq -S¾YîÎ ¡ ŠºÛ„4ê>À›?‚£Î°r }ŸDÖ™AŸAÅà*åqwbµùožÝ­á¶]Á牉ͪ*ž€®×÷eµªóúð˃Ñ#Ž¸éq¹dCß  (+&L­þˆ`^ÁF;Ç_ºÏÈslµ)ýäs;ºA‹Ä^„€ª"è RP=Fšv½ºNf: ³ýЉ¼Í‹o¹èF_„C-E×ñ€ð²‹†§_=ª¯möå1@ðCyëyð&åD°ðàã ¶òøq;>_?ªn’ek]×O÷@ó¨Èt±®ª&ˇú=xQÑ…K'tó¨PxÙ Éc!ÔNÜ_ð@”y: ¤JÐeçÿþº·ûŠip)Žwi·ßrKA`sÔ*e‡\=R½ýx¬û¿d×endstream -endobj -1899 0 obj << -/Type /Page -/Contents 1900 0 R -/Resources 1898 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1897 0 R ->> endobj -1901 0 obj << -/D [1899 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1902 0 obj << -/D [1899 0 R /XYZ 56.6929 449.4646 null] ->> endobj -1903 0 obj << -/D [1899 0 R /XYZ 56.6929 355.3738 null] ->> endobj -1904 0 obj << -/D [1899 0 R /XYZ 56.6929 285.1933 null] ->> endobj -646 0 obj << -/D [1899 0 R /XYZ 56.6929 241.275 null] ->> endobj -1905 0 obj << -/D [1899 0 R /XYZ 56.6929 202.5209 null] ->> endobj -1906 0 obj << -/D [1899 0 R /XYZ 56.6929 168.3311 null] ->> endobj -1907 0 obj << -/D [1899 0 R /XYZ 56.6929 95.2288 null] ->> endobj -1898 0 obj << -/Font << /F37 747 0 R /F39 863 0 R /F23 682 0 R /F21 658 0 R /F48 885 0 R /F47 879 0 R /F53 962 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1910 0 obj << -/Length 3181 -/Filter /FlateDecode ->> -stream -xÚ¥ZKã6¾÷¯ðÑ Ä>%{šd&A›™ÙLX ›ƒÚ’»…Ø’cÉÝéüúTñeI¦ì>ˆ¦Jd©ê«'Å~l¡¡ÂÈEn$Q”©ÅzwCpï‡æiVh5¤úöþæÝ÷"_b2ž-î7ƒµ4¡Z³Å}ùëòý—/?}¸ûïíŠ+ºü–Ü®¥ËŸÞúåý¿ÝÜ—[×ïøøõvÅŒÌ%1Št]þüéÃw«ï>úþ‡Ÿn»ÿñæã}dkÈ:£yúãæ×ß袄7øñ†a´Z¼ÀJ˜1|±»‘J%…3Û›¯7ÿ‰ îÚGS¢PB¥yžg ƈQŠ„¡ ÉV>~ýîç»/÷wŸíÛØgNò£‹7„K–YâCS®Wë¶ÙºbT)`±•” wî¼âgë=¿žJ¨gøW:Ç<ÑjH|÷y‹T'\ ·4‚¡ùå-QbË¡° b -fÔxËÖÿï9öíÌgP˜¤ÎÁ^ö×Àç/4Œ è¿ÁÝ?ÕÛníÜZ&™ó×Y€HRA<Èø›ì"Ë©ò„IwP2bû]Õ¯ÓÐͳvµöL¾<ßÏÕ!±2b-TB÷Ú¡]”õ!±þJdšhPÆØ‘½`5-»}µ®Qh¯8n¼}ðsáæñÞöÀ,s{`Õ¦<ËÚxÁû5Ñ¿Úk ð\ó\)gWTωdÑóÍxWªÍ0¤ì™s_ë_ìúÐ÷C¥ð²äYvî® Ë‚x«õØ]ÍF6“E&£»¢rYVø¯±h¥Ê¢ÕÎnŠã¶wÖín缬!`5ÕÖ݉³`d·l ê; 9L#3Žp»m_ÒQ^0E´4êª&5A]6îxÎŽ nYy™@8¶£UÚcdNt³³u¿Ž‰Y¬û±Îfò›×PøÆêÔ6, ÒéÉØ8Û¿ÆBïz$sÈ…i{g3ªZB‰/²ËªRÍ«>RY1=•±’@ -yeË@”ØrTƬ^'[~9Ô>¢6‚£ÔŸÚƒ7„î©ùÁ+ ÝL2§²nÚ—°®òñ3+«Ïtøæœço YïØ°˜Wbࢴ¼¢šÕÕ*«šßßâƒ1´Ìúà‹¼|ð9sI<ânäƒ1—õ:Ê|‰Ëš9=h\Æ‚£©[+`^B\Øö­¸±;ºz$‹©wá.ÏÅÖvÏ`X¶»¢nN¤ vQþ>àjê‹E+”kZË„Õ%‹Î®Â†fÄè+}©ÑÐx"‹™ýUÌìÑÔ¦€Áì^îSæœ)1éEBq?æj¯}_Þb!.Ì Ç;–M;zÁ*Óæ÷ ‹¦¼ñL\«x%1"VH[¨bªÆ³bómÇ -l¾öîÙÙ¸n—ª¸%ŒÆBûÇ"¹Ô¡#±B´ãLŽ™Ì @w³0â˜=²\]ÆÑjH‘Ê"é@’!™Ñ@qí.™(¨ü‹ÜEª{#H)ˆ"š²1cL)ìŒÃE-»öhõ¶®Ü´Íáê¸u4eÑnÖi¾ú³Å-’8„â²àŸÚCýWèf\Øúïy"a)<ìtkˆrâkºW@ÝÎyek½fÆ ðîÝÔÞ¡í¹.+7‘ìô3MD<>zWVÏïü{%Âf±·j«JX Np–®ñûÃõº²µg8x@þ" d(Q¼i9\ÝÎMÕuî­™Î0N¨IÚEŸþк@íuÝì=I¼¥Æc×S#Ón|¦+1!óØ Iç‘ÈÇ p9‡J,[s+/ Oyp×ÓIˆõ=ßÉ–'ác85àf'æl†B´ùeF]Ü‚ÿ¾e3u¸(J7íd«« ⊠¯2Ÿ¦Ú.Ѐ>©>+—*Ëa -(Ó}xɲءhJÛ€ô=µH&:„{V‡¾Sc4ÔÑZLPï[ èÇ|°ÅwŸuhL3ìt\Ét‡Tó-RY‡Ö]-rŠ²^B>D¸ÿ,^úÌŒ°éùþlÚ6md·û‡bý»/F´¥vNO„ÍcQdxÄή`q@u‹Êb±OWHž‚ÎÖO‡¶íýiÔŒ_š JË‹ÌEªwãØʉ‘ ß{¾æ6&ÔÜÆÌÕÜí ­®4êxžÉiÍmü÷p=ÕÜÆõt´¿Úƒ¿sñ -O—%»Žx“ÇO&^êíÖ-¿/€1HÞ⸵·•7ÿÞß*JÿÙ‰`¬xzPUÖønÎ+ °ýë0`Š™¯Q4¸M¿í°TŠh®žyXÖ…a?‹¹wm{Ñðß k> AÚÀˆµ ô1ÃÍ.9·/Üg¸A½…õ'»nÚ£u8õzŠ„ ­GFÍr(àTã7ÇcÌ«¾‹cÄÕ* ¯Z]ÉŽDóöˆ,ÎW«,ˆq‡¹*ëS±Ê:c*Ye ¹òVke­6“ó²<›Å‹mÞrp²ïÏc1¹§flúm³}DŸá4õôŒõdÃVåÛaOá í¬ ÚxD—H b‰àÇm pÑø9ÍÿýiäéPi{µ> endobj -1911 0 obj << -/D [1909 0 R /XYZ 85.0394 794.5015 null] ->> endobj -1912 0 obj << -/D [1909 0 R /XYZ 85.0394 751.0357 null] ->> endobj -1913 0 obj << -/D [1909 0 R /XYZ 85.0394 641.026 null] ->> endobj -1908 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F39 863 0 R /F55 970 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1916 0 obj << -/Length 733 -/Filter /FlateDecode ->> -stream -xÚ¥UßO£@~ç¯à’co³ûˆZ=/Z{¶&&êì‘+‹4Æÿþ†(.MÚaùæ›™of§Ì§ða¾ÒD[nýØJ¢(Sþºô¨¿wgë1ъƨ£•÷ýTľ%Vsí¯žF\†Pc˜¿Êî‚#Â( ‚×ó“ãèøj~z6›‡³2–A²XÌæ'ç·aÄ0 ) .“ùMrg‹Ðò 9›-ÇÕOo¶zKkœ:£¢Ëé¯w÷@ý *øéQ"¬Qþ osdvÄbpð® é"O„ƒFH]‘@‡\†Æºªë™ ož+—n3Ñ @b˜=ÄjëjÛLÄ–¨NØ™`“iÕcþä¯<€Ñ*6mÚæeîÚsn{Åûb°™ÛW|*\Ô1ú‘àŒ0©5H>ŒnG–×í0 x5!¯´DÒ!¸KË<ûT_Kb¸=ôËÉaÔ[{8£3è5ºm03BÆ(—³ÆI.–W__¶Žýž*jà‹ #Ó½P£ûbGh¬a¼™ä„5ÌÔÑùü]mŸTV®hZ¸KUG×ùSŽ3æÖýÕ¼Äë7Ñxm×Ð3¤'SzDö”T\ºè=6¹Yý¸ºþZs×æµË[ÌdùÚÀl5øp\¹¦ªÛbW~¶!`·D'¶'}Kñ¿wõû’Œ‰0†¿¯áƒí+ÎzHª+Ž1ó!õa«Ìý ˳Øendstream -endobj -1915 0 obj << -/Type /Page -/Contents 1916 0 R -/Resources 1914 0 R -/MediaBox [0 0 595.2756 841.8898] -/Parent 1897 0 R ->> endobj -1917 0 obj << -/D [1915 0 R /XYZ 56.6929 794.5015 null] ->> endobj -1918 0 obj << -/D [1915 0 R /XYZ 56.6929 752.4085 null] ->> endobj -1919 0 obj << -/D [1915 0 R /XYZ 56.6929 626.6031 null] ->> endobj -1920 0 obj << -/D [1915 0 R /XYZ 56.6929 566.5511 null] ->> endobj -1914 0 obj << -/Font << /F37 747 0 R /F21 658 0 R /F23 682 0 R /F48 885 0 R /F39 863 0 R /F47 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1137 0 obj -[650 0 R /Fit] -endobj -1921 0 obj << -/Type /Encoding -/Differences [ 0 /.notdef 1/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash/ogonek/ring 10/.notdef 11/breve/minus 13/.notdef 14/Zcaron/zcaron/caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity/lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde 127/.notdef 128/Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal 144/.notdef 147/quotedblleft/quotedblright/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis 160/.notdef 161/exclamdown/cent/sterling/currency/yen/brokenbar/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis] ->> endobj -1483 0 obj << -/Length1 1628 -/Length2 8040 -/Length3 532 -/Length 8905 -/Filter /FlateDecode ->> -stream -xÚíte\Ôí¶6Ò ˆtÃÐÝÝÝÝ¡Ä0 00Ì ÝÝÝÝ’‚R"‚´t ÒÈ‹>ïÞûüž³?³?½¿w¾Ìÿ^×Z׺î7¶‡Œ5Ü -¬‡¹rðpr‹ t´P(ÐWç…C­fL9g0ЇÉ]Á¢#°5@ ðòxDDD0rp'/gˆ­+€ù‘ƒ…ý_–ß.+¯ ‘.[€ññà …;9‚a®ÿã@=0àjØ@ `€œ–¶‰Š¦€YIÓ †P€¶›¨C@`˜ ˜`w@ÿ:@p˜5ä÷Õ\8¹d\@€‹y {‚ÀN¿!v€ØÙââòø €¸l0×ǸÂêfý[À£ÝþG“3üÑÃñ{$Ó†»¸º€œ!N®€Ç¬ÚòŠétµºþÎíy„p›GOk8Èí÷•þ`4¨+s¸‚=]粬!.NP ×cîG2'gÈn.˜í¿°œÁ¶@gk(ØÅå‘æ‘ûwuþuOÀ¹=ÐÉ êõ'þÇëŸ ®.`¨ '&ïcNëcn[ “ë÷¨¨Àlàî¿ìÖnNÿÀÜÁÎ -Äü{fXE­á0¨ÀlƒÉ¥ w}L `þŸu™ó?×äÿ@‹ÿ# þ´÷×Ü¿÷è¿,ñÿvŸÿN­è…jÁ‚ÿxcê€ßÌs:B ^ÿÎýïžFà¿4þ;Wàc!d`¶Íàáäæù €¸(B<ÁÖÚWÀ}¬Ô»Ìì …ÀÀýSL7÷ß0};Èö»ôA`˜õßå?6éx.M}U]u¶ÿöªrèA§Ë‚GPè¯íÇ9pÕ÷rþo:# ¸õ?¿ùdeáž^7Ïãú=*áðû7¹ÿñüë¬tu†x^psr?Fr~ÿsÿÎýOÀìo4 -0Üú÷äè¹aÖÃöOÃoäæìüØã?ûÿxýœÿŒ=ì a.ÌÁAb¡ö™9Y® Ä£ò/z{xÂœ*Þè—ÖÁ»2#×Dj,ïêÃ8›ÇEµyÍî;Ýoª²n öA™ºÓÁß‹(üèX>ã.3v±ms™W`gÅúϨ¯"› -rn­êèš—ß¡RŽwð9£_²Ò¹Ð_8=óe4%v>oFÀk(Ù?`LÙ½¼`êú4ð±ûåÃ&9[~ƒ˜;26cLà«|r)Sƒj…×Íl(ßÛ -b¬Å7ÎßÊçÏVð™h9Žù,¢I‚°RÊ• e®äß·RÆ%=²ìÙ êt›œ(†Ì%³LÇî)®Ž>1Ù¥‘„µ…^Ñ2¼éˆO£Ý %õ‰>•pjÕr{2–ÂwÍ<–g¬™-j—!3cäáakIè,AŒ$ÁLˆÇÆ‹J¯³nöùU»Ïm›Þ‰D3 -~"ÅVöè=”Žòíí`õ§ï3t;k‡–Bf?õ[¼„Y®¤¾ša£„+gl’ft]ÎB‚²w3ë‹,£ªˆôkêyô’­úÅ>¡ï„móW¯µrÅý¼0Ï”dË#»§BŠ¸ÝUJàžuÕñÆIÍôaòÔã·×¸§ ™ žL¦€Ädô<­cË-8àÒ—£t‰Äº4ú£|©D„¡¹šŒ]¸ãÏßE¯¡>ÓR·9xyôöŽ[Ìï`º~ͲûDœ¨'ˆº5e[-0GMÓ=KÊÊJþ&â&’PøS¤8ëãin,õ 2PU«r`ZÅÄí¢v8Q—ÁèÍ ×ë¯oã»o[2ÝO2Ó¾Ðm/Ÿß×Y¿üìvV¹"_=5Ó›é¶è áaÖ™7þv|g “y×&"YæЖ(¾+ÐMoûÁ|°>›à¦± vZÎI ÏW´Ä%^‘›üˆ¯­Ú]Ö%½ZÆÁ_Ï@ÄRdçÒÄ9è©‚†õ‘kãC¾¥HzõOlnÕžÝÍà™>{óbÙ7U^|ä-)G? -8òÞ¼x“mì¾%ÿjã=!•š[žž;[#ÆŠ™ éJ©/A%Ñv–µû`éióöí؜njP~^z•çQ•7˜¿\扯â ÈÛ.|âùúÁèéᙪ9 x°¶`÷V¶v™öÉÝçñ–%®¨eßùbU€|;0}õd¯ºGŠŸ¡*ºS{…Oi,ÚŸ‹í–0M¾U_jL¬@qª?Ôªuo›`ö@è­Åû-€›-0Múp_ðà*Kþ*š´ll´8ðc©ïÑJ+cCôcr÷®4$G¡ŒÕ<;i¨Wi Ùªµ‡ý^gµ£¾ÕN!Î*{¶£ô…ÆW5'xs ^ÅÍ&o`Cð¸OïŠPÑ©4e¼BÃ9jÝ’N7t’2_M´Ô¢äÔ¸/\ä_‰¢{\”ñw“Ï‘qú\®û7«X­”ƒÞAÁ¥}Æ -¸È÷»Œq„z`²\F棖ûEœ!~õT¦¾\Ž'4/ýCîe– 7,î9tãÒ¾Â1 ¦’·IM^y/¢˜kIm;˜¨½}O«•oÐHâ•¡Ç6—]í7ôh`† J­TÂcweófœkÔ­—ÕRÐÓ(9%Ö¯c -Ó·_Ü€¡èüêr_7ýGmÔ&œÐ‰lÞÆŽ -Kê#TðÖ†§øñÞ ¿šûDE&ñžËœ^QH¶!’Þ»¸>àáÉà̹ç$ÚxþF`Š×Í4IŽ@N@ÒÖ>_9²J¾ÃEúOêá˜/kIÉu~~¦r–æw0§øF¼Öë!ÅÞÍ<-Ñ:yLj]óC&üwÏö䟃!•“®²h!¶‘6òÕÝýOÒÑéÃVwc1Ì{õX/MHÕ¼“øÍT(¯m­)5~Þ÷ú?É6nðýYº³`æj¶]`.Ò’·Ã‹imzdëøjXJ[”˜OX8wâê^ÞÔGÓö†^& ÌèWZGÅï] ðÍ}Ù ¦L5«ûrkÎw¯C3íñTS‡n‡a†’Í|­ïDÔR”ˆŸÆþÚgòý·¯0,‚…þ«dñ6›ô@‡Úò ‹6~ƒ -uÿ'¢µ?s_¯Ð‡öÿŠ˜'u -BêH—‚?ý -$OíœàÅ€DÈåìصö„÷¥½O%©4žñ­¢¯‘ÔðQ±¡8M”¬|â ãhƒÂ!ãëaž!ÉÇ86e}YÐ7IÏWë]¶Ž`…ÏÜ&ÂcD×rZ‹î”…µöíòj—«§ÐŒô6ZÑóÉÎõ»§ ÉDdßÆçxãT  4ã¥éÐ|ùw%h± V–¾tf°‹ðÃ/ùäanЇhµ•]ªU•²ÆfÑhª¥Hm9Ôaêëô¦É’T›À…á/‰¡øOõ£èî.êš;{?W›¥~#ÂÝGÂÚM†ÑÐuEh 7m[E†lûÌì’ãÍcT±ˆU,ͧ˜¤÷Ö„½wú°aV.¯4žg®r ¯R«©*˜"‚¶±ºž¾<«0ÛÍÊõòÂh„Û‚†½z«Ã÷îîÛ²±žˆ©Ë_>)FMÁ¿EIÕú®´ËRÉs¡bÌo™ç-:ƒÒìXÖS¢ªÈœ‡(2³Ü{Y¥1³$Ê&?ÎIX>µWÑЃšÍçnPÊÉLÇ@¼¦‡2—­eýS¬+‹†^WD£gu¦í÷ùBü]8¸ïOÔ5mVl³Õé”VË(¼ÛmN^nml ÷’ s ÊõÙ±…- ™x³àiΛ*µ a1ןáu«+@Nñsâ),#Gu-/JÕ¥[òmš¬»º_ä>TÂåg?âD"gCó5®™,ý’ «gº%q\Éw&áÙ¤Û‡ø=rM±‰©þAÓǯ{Êò¾fņWÛ²%§›s¶J¡üêí;7¥ÒÂ"¡äÉU’wlQ-OfÌÚSá\Ð*¡BI:àà¬e’,Ï—¨xF)f‘ý\0l±÷„½Ý…ÇvãûÁ‚„@>:ûY´ÈÃ÷µ[e|&.$UÎ;M“íj¹ª_¸=*Þ äSó«—M¾¾rµøds‚ïP‚Ò*’÷Öåß `2¬„ šêÁT^£„J’¢¶¦ž¦Ÿ+õ¦ÐÛc8ÎÍ(¢•ÉÆOûX™rZu"Â&U =oöE±êPy*2ßî"VåÖTú•¼Ðc&úø¼-ÿ{ÄAÊ+jV•f³þ¥œÃš°8ãö©Ÿ· \b,>ÆÜ—(hwÌ©¹û†}ÞwW#3?¸šn/fƒ´ÛÇœ¥Ÿ— ˆ¯¼ø–HÕ‹ ÷S+AL—£vÊÑQ†¿«l0v^£žÁJIL”½}ÓÎß>ÏØ&é(üôãIßv0Ûu îò'+¢gôô÷Fvˆû§BôYO ­g©qq¯Ë+ä(ÖGb›‚±›Ì¿xê!±ùÒ‹§G ->C{(©¼Ê°nwð,K ?EÚ7þBq&‚´”jɸˆ·?è¦ú-ŸCØüƒ%¥uXcýøââBïÅ ´;ÁµÜ3höŬ ¶÷Ét(‡„šœì :î´cØ¢>:ƒ‚¯úò‚#ÑǤ_VItSÏ$ëŽ`ø~"ÔܲÜr$ŒU–Y7÷“ø?¢ê¹iâ¯ÉqÅõãÏØISª5ñ4Â…èÑb“EÝêÑÑn›p³ú†-.ä‰ìošå•Hû~B»ÎÂî‚T§Z§Ï_)©OqÓzèß÷>ë˜Ê;­dpI¡rr1ÛA -öÝPî2Pw]¶u¢èúä»(£ý/Ž¾ªˆ§þßÜ¿~&æ[1¸Aé-KžÚEО5JÃ÷.føzßwi°h“bLñB³ß6ˆ^ñ*£–—qº'À°´TÈ8‰ÂWÏõ—„ãŽly&V¬AÕ²Kò^ˆâ½þÅY;/Vwúí}<÷Gc…R“#]›gùDÏ råV¥k¿½p¾Õ¼¥}ÃvGšAÐg•†7PöŠ²S -ÃÐÙ²¶©HÈ  9^©;¢Ìœp»Ãm%{r7E•€ÏŒµÂE±…ʨ*o,„ó QÞúʭ䦀(ô$íªy{Çgk9©‘5Â1ª0Û˜F3ŒÛ!s0¸4XàŠú#r¥Æ2á\8nqå°Ãs}䮀„s–è5)q…i¹C9ad¼¿`u ^<‰2@´ÄR­×$âƳ—xº>áÈïž¡wdª‡}Té†×ÎÂËõ€Èøt\1Ü~‚9 ÿ½8ia D9©ì"Ð!gÑßqÝ ùA“ׯøŠ‰§j_dI*¡ -»]‚ÄÙªAÓ8ﯙÎd@Iî?_ɽŽbÎJÊ8&1ß’bçy·ÌJü®J_ƒ|¡iïÂC®¡L;¡Æ–=x8"ÆÝù\šGd'—®®ðÖ/B¿ÝÞpRÆ'µsñX'MÂÁd;ŸäÕEûtGmý«†g¾ ¿¨öùWí},¾Ï†Ä›tÓk„fªõžÑ »›&oô/L¿ÇGìü²•âBZmÎOw݉Úñ¼>–¶ü^ÝvšÉŽHk6Œ´­¶DM0¦›}Öda'¨šßo·é˾xWp¼311ïçdϘ9óÅ­Ô§?¯jò>*§¨¦‰Ð:’-+X}7¿$ÏL\œö¦nD™ðì¡ÉX˜vWŠñ=mç¡|'M}„ç‹çÄ_’øÏ£÷rci%Åës܃ ¨ÄÏ,n±±ˆ" 5Ù½6ìÉ6úQèÒõmŽ¬öó–à+q®Æ¾ùÃ$ô|Òî]¾öÒñÕäË&æèñ²€Õ„KfVº”DfƒŒåZóbúä`#öZ·<Ò_Ç÷-¦ªÏôª -_˜lg˜¨Î>«ŠTÂ70¡ðW~—ÛC!_ŽÎr¦x‰|„ŠúNx‡<7M–/&×gaÅj[²Ë±‹4—À¤ÀÖO–|¾1_JSw{ðÐıDÃP~ÜFY­Yy³]ˆ:¬aÔ_|žjÓM+ý­‚0@îhÅtÙl¿Êgšê…µAbDå·Ôw¿þ}ûYÕ×iîBÕ*jòýZö˦ÏN’FéT/Hn±úÁÖ“4ÑOEìØœz~Ÿ Þ88‡á ‹w|q£ªšîFªãÆÇ -TT>/5—䬽%‰”dðqÚnCÃ%Î4ÃXDmeß:#ƒU¹Ø•l1~à 4±GL§%ÕëEЈ®ìÒ\;ãÛ8Å+§êJZdº×d¡K©¡ZÅIŽf3zV#W•c[Û¡*_-߈¯Þ­—¶5k ª€º—,ìd¿»Ìë÷S/úò¢×Ž Nâ)uóÒY~ ]ßjÑ×Ù˜fšuž²K,tÊ÷“\'gy¿÷5­<TÏ4CUMà£Ægÿ3Q£8Nð²Ã‰ËzN5\/MØr®]SÝé}pæ§VD@™:]¬ÔË7>1ÌÈéC•'ÛEÆŒ!…Ù7aVì:ASQ×µ{|ãÇj9YÈ4Ö|m Î·*_íw4ø!D1 ñX¿Ù¤X•³ç -t‡Í=žÝbóÆÃwî6ß"£“˵?”JËOP2RÐ oQo+†â1)©w†¦ÜèådîI½ÈZ¿VÍ­(e÷åû È"QÔüFØs(úF$'‘qL ®/¶!õÔ ¤HvkÖ‰Œh¼È‰¬ê؉á¶o?Ùa:Šÿ±qêcŒ° gã!_QÇ~ÏWê¡1üaœ¯UÝGmã§Yñmn%ìRãr9÷¬ß0qˆ5†/‚E…(êÚ“†,W‚˜$Ù½ï¶åçLxËÎÔ|ú奕£w†Z|ÂV€ãž÷,éOd -ÞyŠGÝ ŽÎ¨Ý3lÍ4©¿Î\×T2Zª½Ag—.7Ù#ÏPæï™v¼eŦQLÞ»±Oþ¼Ô\’ ¬ÿĵJÅñ¾(š3Ç].Å*,MÎ>ÛBx(ÃSÃó|D³uû‚Þ¡ï†{:Ò‘Á¨2G9¡Cê{É•<|?ÒK áéá@F)Ø,êw÷ó?È ¸¢Ëa„Çh%Ù±o^Œñ{‹6™Ý @¥-«ä%Å~jÉwXjz1îi´·î¬%uÕ3^¿±g¸`d+ÎK[ŽDe—„]âò†YèÖýÇ?Ï>£³HjË,èkѸÍhÔ8Š” ™v_Å [ªJÖ®²9m=·âú?\‹k>¼à¬‡¤*³Ñ³ž,Y ê<‹ý¹uÓ Z/ZV$S·é#ƒmNOš¨5M@¿§rãÝ0Hõ7¬&7[àçŽAØñêOõƧÈêÚ5±pE6~d»Ž^.x¨T1¬µ¤$£Í7¿ÿ4òÆêüj§‹G1¬èípoóÌ3³QýÐZ:œNÍÆéç,0½‹Š‡Zg‹ðâ£à)‹Q©¯³‹X""œÛÆ0ÏÁ¾äBvFA‚)Y9(ÎYÖý…ì¬S…|¸Ôü¾“qbæÇN.LÔX§…_ï‚¿œ%%½¥åŒìé|°D>W²7}C–Í#—ZR¸­$º`bÛGο…a¿9gÝS%\”Á/œîñhC|?s§ Ø…šg¯ÎÙÈ)ª¬m}ÐvÖËk†Ÿ.bÉ&O -üõí+uqfº`Îa‡„°£â,I§ã¯½/‘˜÷ÇÝ›Á¤'P6ߢH‚Ú?÷›½šÙ¹˜Žà9¦ŠmHr7:pMRYŸ#£ 'æW¥¿ðKCß|-¡mWÝ躖nᲶË0–«ÞÐ3äÛÙ=j’¸Ë-,n–³e±€¢üb½iÙ;‘˜Hâ°l<)žL.ßÐYÖÿ°Ú·)wL=(‚Œ£± L|)=å'ÀÆ-Å@²öò¾µ<ÃNrä³6îµEôʃ3±d¶kÓ»¬ÿ‹%ôµøü·(kD~ô(¬_yñ‡Í; ¯åä²fùOî{&*‰äyÒ¯9ÛB±T¨d>è.òY[a-³ZyÏ•px9ÝØÜ>穾„»*|,4°ç Žð=Ï añŽ©{ZwLVqžCÅo, H;ç_7Gg[åGx d½DŽ…*~ÂJSÛ/ *ûÎÔF‹µëújQ‹jw Ý]_-Òq;Œ,1t³õ2ߥÆíËòê{:Ö§Ùo$<×ð¬žôôJ©Àëóüλì„b›F=ÍçåcT”u;ÐuË›÷#³»Z1q“ÒYÖgHŠ^fiyv|‰¢,PkŠA±¢FH£s^…EËRôƇnQWEÛt%Ú·y3™{æÈŒõFbKã<%Æ)â"-L+{墒zS'“#é²ÊòZÃ+•÷U­Á׎#Ç©ÃCcæHŸ,êä;÷=íÏô .óYäg:¯jÔn¹¶Æô×êS:c¤¬UºW¹Þ/Ëf¹ŠšcO¥ÛøŒM¯lD‰Á¦9²ú:­ÈùÈßÛ˜ìÑËr6½õx§ç±2ú]úS¹‘ p7O¼,j1îöÐËÚ{ž$ªS7O–xYŽróæs÷â»ì(è˜Ýš‹ÏD‚@§­Y#žC²L%¯íáž›1A•Ã¸©3¾~M+ÖAîDí>¤¶¯cãµã-Nˆ¥”ûÚÔß ÄÖtzâ"¹tãØ'>(˜“”hSðÕœM]ˆÎÛ…0ìŽ ñâSPÓKD³—dOj nÌó®|KHtÞ‘Ñ+㢟S'÷@6„iõ“¨C,÷ág3B½žpÖáΡÄêφÖÑn‰Ü;ɦc“ _7T,Q1çTiHøBÕWL8­¡¾  ,œ²£.±ß u2†)¶=–Oš ¹ÿêÚ´­Ùê², Aq¨¿râ^T!1í¢ëç2)áN\§‹¬‚)æÄËR…Ëbž÷ž6Cb5ü´çêÞ›Ô;ð¶¹mH“üÅL¸^Ȭü¤Ý¸Ê {>«m@Ë›ðzéN‹›´×»ÔÌÃBÿ]¬—š@)õp[jÊâá…6붡²BSHQøר.öØ«N÷Ž`ðG¿§zŽ^n)?ìû±«892ÉÿxÈÌÄ÷Ù%¼­Ø3ÕÎZJðô]\ÿ^¸Äé„SXA㣅¸r}[(â0Ò@¥elöÉmi¶ö­EWÕ9úQѲ´ˆC¶Û¯µAñ=°g>MF{Q’= †*Ëk¨+™×Øõµk¤i@ïħÕW:x<›ó"Í}<=<²šC½Q¤4Æð÷i©UµSöA-ÒiMÛk×qnñÔÆèO“¦R<)D¾€÷/ÇT#î¡ÍM© Æ$ÖžåÔ3³Ð¿Á¢\ç{Uª÷Þ<UW=ˆ$®&<ƒªZ€0óØÒgÒR*¹ÉÒO¦1‘'£ùŽŠj*5wË-·‰ûùT j4ÝióÍu``òh߯µ“K…ݻʔÑk‡‡A›”ôÈÔDôìtk¯ö2ÅÛö÷ú—¨§$ÌöZ¥ï@Î^ùÝêõ^E~§”Üúí¨u4߉<*ôŽ±§¸KJßùy/žn•C*}…ÃåLgI£J·8jŽ[“Þ³ ”ØT7%JÈOïä,Á!ØžÈ+ÌÁ¯f—ÉȘs‡h`Úq¢O”1£<ƒ3(©dØOfBOŸ º'"p=Q£B¿âäpJ}ÝØü™ŸZ®¤!p{òëÈa}÷qÑ¥³äƒ£DKXôžòxÇ(žÏÑã ©¨“{ÏçÉšj¿dqX·ã·ŸP¦Üv£ä£Ï€³i¬¾AÕ;³@øyŠ*œoLœOœÕøë…ú¾›ºxOÛÝËc -@YšUʳªø;žBiäMÖð.•\rž;ùU´¾Rø'î…ç)眄š˜ …@ƒi/_ A®ÉéÙêr«0áFx<×Er;¾zÇ´UÏšøSÂö²Ù„.¥mô÷Œhâæ¨É2Ø’ç/{I;õŠjÑm÷¬ -*s"}Y ;Ò‰¢ú{YÌÝÇí]p¶Òݯ€Ž¶Xo³êÙ}U¹ôZø: hÁ‚)8f÷EµÔëÛDäµsüð¢ qTMŠ:ù‘ɸX!±l®ûÔ”Ëû ΄,ñº17ýbŸgûŸ&fܽ×Y'jeAt ]ôÛïwV^þ%ÑåµÛR¼”tμ‡Ël¥¿é˜¦j¹„‚øϸ3èm>YjŸÖCƒÕ¸ÄžÄÈÊjbÆn“ªŒUý©?ô‹ïðu«ÈÃWøìý#ë,M€¾ߥJBQlŽ‰âXè-ebtxÃ]€s<—ÿ¢:XÝQ…¸w¶²-N;N¾?Vl¤‘vG‰…,Å%ë9êçöË'bìη9|1.…±!]¹¶DšÏó=RԌݬ¤Iˆg‰=Åh_ìŸ5rÿ/˜ÿŸàÿ  tv…;0ÿFdõ·endstream -endobj -1484 0 obj << -/Type /Font -/Subtype /Type1 -/Encoding 1921 0 R -/FirstChar 67 -/LastChar 85 -/Widths 1922 0 R -/BaseFont /NTJURL+URWPalladioL-Bold-Slant_167 -/FontDescriptor 1482 0 R ->> endobj -1482 0 obj << -/Ascent 708 -/CapHeight 672 -/Descent -266 -/FontName /NTJURL+URWPalladioL-Bold-Slant_167 -/ItalicAngle -9 -/StemV 123 -/XHeight 471 -/FontBBox [-152 -301 1000 935] -/Flags 4 -/CharSet (/C/D/E/H/I/O/R/S/T/U) -/FontFile 1483 0 R ->> endobj -1922 0 obj -[722 833 611 0 0 833 389 0 0 0 0 0 833 0 0 722 611 667 778 ] -endobj -1298 0 obj << -/Length1 771 -/Length2 1151 -/Length3 532 -/Length 1711 -/Filter /FlateDecode ->> -stream -xÚíRiTSבª¡¬2©¤j=,Œyn4„„1d%æÞ[’{éå’2ˆ8PIU–EltÉ(*J…UE (µÄ*¼N¤U„,ŸEªVEÀ©¬««ôgûë­wΟ³¿ý½¿óÍp g‰a|ˆc$ bC"à/“I!. Î\.Áð'9‰âX€œDD -=Àj­ðV®@Ä_!â h à§é 4EE7æ$IÄ„@r Èä¤ -ÑP5r5Ç(BêÙ@¬Vƒu“7ÒÁ:$!2˜Mƒ £ -l@RPŒÆ™Ô$Å”8¼amÚÛTB¤S¢€Û”L& DÂ8¦ÖQÒ8kqªBiù'dM/¨U«×Ê5“姜úK^®AÕú߸&MK"á0B`Ó©ÑÈq2FµšéY))W£ -1–¢F ZÉæ®|ƒ£é¨CQR¡J¹:™Â ž®„òoJGåþû×N%Cå(FFèÓÀýƒ=CÄ”Iªñ\6— QDj¿=%Nk&Á8Œb)€Ç÷r‚ëiÔQdAÅ`D¥˜ÃÆp’º(gr€'h“ÿêÁ5’ž>‰¾x€“29{”{“Ø_Ÿæç‡ë²X+x€ÅãS­¸+=€ÏÍùQ¡%#§Æ‡2èm¬D)OD‡(hæ¸ÂkËÇ{Om«É•Tuµf¦/4ÞÒ~nëI£{¸×ËáÑøCòÁ¯ö[í?FÙ•Œ„|Å•ü>ú)q¶)+œ³µÇÞdëĬØ>ëb8!iÆ¥²¶Ö÷4¶ß5/Lktð£ëÓ;ç¬ëÖ܃•ô‘™57o¼|œ›º±£Ïló%ì:TBK,;½fõß;EW&îáU¸¹úÒü„}O_™é­·»SoÙ…†2™Õu£÷‹9\¦NÙßAƒö§.6Ç” -W‡‹f/ô¸Unï{»c|š›Bd¿Ìèb -\ŒïvKósJ‚£¥‘£ ŽV8(j¨½ƒªé–H}k\‹Æ»P0X–ïZßÉó.†Ò÷0Ö%¿düºdÇÌ'‰ÏŸ÷>{m ·ì¯|øóÅÃ~^R |oò™ˆ›î—jÎW8ÖÌL45V-iš÷ øÍwñq\è5×Nœ0T;ͺuE÷Ug³øã‹Ž‰<t¿ðú¡$ÒÔ8rØcQ®õÐæ©;Ù÷#–gyþbu.¤6YßéY{Âôý¼e{áˆlVØÞÔc5!5Û4úGÂ9{Ž -ëBVåÙgŸˆ›¾S–E Î-dãÓåÌ6Æú˵H»¢Ðç•Él"Ö÷LK+F`ƒÇdz2xg>ZÏ÷JHyÕísxÝÁê¬]<º¹rÑöõ4‘MÏ€ž&ù´$÷õ–Ñž ­½¤©=ÞŒÝ=j¼ý}*Ø|ö ½ÖÕ;æ«¥>-ôºóÿ[ÆâÙ+#²¸êX÷BËþ Ü\©©ubÀNƒ—üä)nfg“Ìñ[égÌÔœfØH2½çùQgù}¾s¾u]\¤"ᤜCE’ê)w%=ÁÙÏ|¿{~Ç:`tÉãè3Æ‚烪ÞÓžåÅÒáËâ›­»µ]ê¦ê҂ݲ¹5ëß ²;Ô~YtÕÎ{W{q;ÿ“¶qú2òÅ«ø“˾Ö'A݆‡A-k2aìp `»¶·Ñ¡Í——'.õ뺾sD•ÔÐq­,ï',2¼>ÑVµo™Çñi›E,Zͺ÷Á•ØO¿I® Œ—´$^íù|4l‡à…9‘ÃL,bÉÉUÝüyæ O2CåWÑkû¹sÑþ_ࢀBÈ ×ȉTÚoU팯endstream -endobj -1299 0 obj << -/Type /Font -/Subtype /Type1 -/Encoding 1923 0 R -/FirstChar 60 -/LastChar 62 -/Widths 1924 0 R -/BaseFont /AUHQZV+CMMI10 -/FontDescriptor 1297 0 R ->> endobj -1297 0 obj << -/Ascent 694 -/CapHeight 683 -/Descent -194 -/FontName /AUHQZV+CMMI10 -/ItalicAngle -14.04 -/StemV 72 -/XHeight 431 -/FontBBox [-32 -250 1048 750] -/Flags 4 -/CharSet (/less/greater) -/FontFile 1298 0 R ->> endobj -1924 0 obj -[778 0 778 ] -endobj -1923 0 obj << -/Type /Encoding -/Differences [ 0 /.notdef 60/less 61/.notdef 62/greater 63/.notdef] ->> endobj -997 0 obj << -/Length1 1608 -/Length2 7939 -/Length3 532 -/Length 8790 -/Filter /FlateDecode ->> -stream -xÚívgPTݶ-HPPÉIhrM‘œirNlèZº›,Q@¢ 9G%#A2HÎ9ƒäŒd âC¿{ιõ½óëÞóëÕÛU»j¯9çsÌ9æZµY´tyd K¨"ÂÍäåЀÙ[:£tÁj<²8pk&`a‘CBÁhÂAŒ†>B!y¨@@%`È!Ý‘0[4€]_ǃ‹‹û_–ß!K÷xnw¢`6ÖÛ(áhu@ßBü7êB¡´-` ƒCršZÆ %»’†>@ êE‚á-gK8Ì - ³‚:  kÿk°B8@`¿KCñÞbÉ `Êj»Ýu³‚:þvq¡H{ -uû €¡6H°ú¶hæ`w†ü&pk·Fü!äˆDÜFØßúnÁ´(4Ê - sDn³jÉ+þÅm Fÿ΂ݺëÛHÂÊùwI|·0·^4怠¡nèß¹,¡ å»ßæ¾sDÂþÐpFÁlþÅ€€„Ú€‘8…º…¹ÅþÝÕ øoÕƒáîv#þDý“ ‚­y €·9­Ð·¹m`|¿ä`ùÿ²Cœÿás"ÿ4ˆý÷ÌpÜ’CpwjMÀ§@ߦ°ÿÏTæýωüø?"ðDÞÿ¸×è¿âÿíyþ;´¢3®¶¿€¿.Àí ƒ¨~ß1ÿW,Øwÿ7Ñ4„þÅð߀ÐàÛ6È8ØÜJÁÏËÿ—†R„¹A!Z0´•-À ¿íÑ»¾Š„à·Zþi#€(,ü7Ÿž-ÌÊÎáwÓŸˆþqA g~+ÏÞ|êzz*Æš\¿MÿDiݪŽÖsw¼%ö_u¨# ÿ\üÆ•E¸jDâ~çðerÉö%e>w$ò¶J¨ˆ$k|X‰A\–³³Ëóõû9[GowWgó1Në: Wz$>‹˜ 6!k˜¯S:”‰~‘g„e.0¦ãclKP«>»àÂÌ1yÕ’ Àd ÿS¡Õ¬çn9´éçï©|e>·'ëC‹›f§—ЛÙq€úYšµ«„8ë$fÚõSëÁ·RÞoÛ@*¾« ʹAÔguG…*|«eB‰;}ƒv©¢]ùßÖÒï6”‡yÛ}sx/Gj¢T«$Jñ£•H âQ–®‹B~RlEÛ1w.ì*Çbr|¬½}$nÖ‡·Gs]> Ã?V1òx£+w¿³\õ9’e‡Ð†ŠØ¥ÍäÊv””7œœ¸äN­Ñ÷«/ùŠö.‹ú…&Ð)âá0äPùÝÚ…k¥ èé¹éÛR§ö -^8³÷&sݱ­|&éŸî#6cÕ¯‡‹úœ‚ œEë=öÚÊÔïƒ.Œ}(pÚéc8hXÔêëeM±¸ÄÈpefI­|š -8xÏŽo‚¹ Lœ¸Uˆ–¤¹ŸjñÝq*½ºÏáÃ'äy•JâêA@"]1\j-L¢3wØ°¥`”µÇ,–>aZ¦¶où¿-Ž~æÚ n‹åãQQNq—5% zh±)è#*õò¸”l\ÌÕ/(YfÿY½wç½Jt½o­QêÅTHú{ò=Ó™5Ú -R!ß1Âr<;Þâ$ûg2³£§Ä¯Cǥs‹©Ï¹å‹E#‡„2‰ó9[ª«eÖb äBñÇ›;qäë4‹¦y,'XÈ.ó¹^Ûû¾çm}l3S@+'éY“W[ZTç¤ay þR#ÁWeôùì¯w<Ààø!ËêHô‘ªÝ°a2Y'ŸxVc[ЃÖ̺«P‘|m÷L¨3X´•¢|FSp õ6!wˆ¥qi­ÍÖ)/)y4ž^ÉdÏ—“¦'»À+Oð+Wë³Ã/HŽõ°8³:̨%¾0€°nô™¦RºNSX)šÄ©wo¸Vá"n®¡U®uë.ýe‡°ƒ5­†âÁ„v0äÓ=Ì­²Ðµ”ž²­ÔÂtwï‡tKy…‰ ö €À›Á²Ãí/hÆnfÔÛYÏß35|\Ã)͹b€½^s$QÛ<.'DÑ -(^‹òp߬h7š” ~Ý¢ñí‚…Ë.^,°‰ðzÈî§D€×û3ÊZú’|JRA.KÞ&[å/0õî¼2³–ÛOy«óCúÒB«e€öžt‹:¹ïäCA2µÅËV‘ÀP½'Ûz”êÅŒ~,ÁÑ’ØAkQèoL¹>3a…\Ôô‘¯&û‡EÂË"g>1doµÖ‰g·s<î÷‚Ž!4ž„…ÊÚ% ôi®ä%-#£`‚h-GwX8n^]>ÃÇWÅîió¦p•ÞUÚåâãÎäIdØxÓ„LµvˆNÀî8‡Ä|x©îóÊØÆ|çBSP߮ଗ–g Ô¢Jšóú¹mî9}Þ/@êcõH/š®JäÓü‚h_ÿܧ^à¼n‚K¼?71$ÕŽb¡’êRm:î^5c ¨íÇðêZDQ%qÞ©39ˆ;–*XgEvb»Ä#ªi.ƒRÍãÓLëŠ÷j;Už½À9ñû’šeÕôlëbZÊq5Sv‰¿P ÅùC»¬ÄÅYÚd42Ê¥¯XÜÿÑHC{€T óT½{bÕÞjÝ´?¦Ðàk)øeXïÙr™ÐWTbé£ÜlÝGN‹…1ß^¬ßNdVZ½”¤«ÔÀç,ZãˆÍaþgD¼äî-ç -Çö7=s`[šzþáÞ•MåME÷¿€uG–h‰+÷ÜKI•9º¶Z¶ý3h#`+]¥J¢æ·šõ¬¥¸¦4 G‹Æä5ÍɦŸñ ¨/„~ 2…°ëIš%ƒR*µÈ¹ï¥‚CSž[çm•&ê,œ^ˆ®ül™ò‰0¼3F£!âù2°gáȺÝYzñ‚Ä^˜X@°æ¨Í›#díQ¿¸ ˜ßÈ?'ty…Š,ÿˆbx_¸Âæ••ÌDC«½¬}F0j|{¯Õ\þ˜ßsžù¬—}8$QŒáinúAµ$o<½öR•eµ#"Uòe¥rÞ‰Kÿ ñÃ=Û`GS"“H®bʘ#6W?³æ—å‰ÖÎ+ëíø ·¯ô– -ÝI{ˆQeY:BøÂb¢÷‘>:_/!€ÐéË@íáÞÑȬýu¢‡3èµ+òLn¯óqŠq`Uúmò'ÄaeG-3¿rk ³o=m[¾Íbõ« ¢Ä"îE;A{°<¹æôþÊ1gŠº `F;¹Ex÷”‹S>EG‡t 62j"hkùýI5IëUÑ:ƒMn"A˜W¸Í(Î -òÎqE„¹¯øç*+nû…Æ—²;OeŸöY:«*š“ïgœò'\Ý7"µkûl‡ÉqèËÑÌ'ð9‘Tgeix¿qVV^­ÐÅnOiêlÄ&Àh1ÿ¥n† Šo-R’È!î±~x“ýè‘·ÞøyoÏõÏ4íÙ{¦Å\4X ²‰¤÷•Ï´±ÝÈ/åµ½¸N%{’;4u)Ç!‹=íè¡ç"Â3¬¶Ðœš®`¬õ0¼f»åæ6ç -#vƒl|¯göÕšŽùí:qÄÔyN¿3-y„¨Å–UÇâ${Læ6¬ÆÚRøÉ™¼ó¥?"áZ¾þþË\øQ>È” §{õîû7l]¢ÍK*;”]Rï¼Eú4à[·NhÀƒµŒÆëÍö—¹|j"œl‰\ö#Ã$,¼¡û4”Ÿµc2"S%öÍOZ5éê˜-=_~/•˜ñøˆLreá’ŽÙ7/Ý4w„_3ìƒý-Æ_õg$¨L&{[äã¤.¸4Ë<±I ½U€QrW(aRë*­ª)}¤{öÜùóš×Õ}ÿSM#¶ú¹”è>ž6ʈ~1ô–r¢„tBÖPÒ—µD 7S£á±iþ1N­@¤s‘e¸ö{‹>“õèÆw -™mÜtW?e‡ÌŠØÇRXÝŸ¶« qÐNøb%2t)( æß-Ö§9¢A¸‰Éš2žŠŸ±;Njf:¯ƒ9NÃïÊœT)š…ùïš=l“'v!V‚»ú7?êÑš\“Äk=ò†º¦ù^š-2~ë‰Uïs‘.»o¨ËªüaMfsÍ%W2b+¯ø¾ -(Ì°?ø6|Kú‘œ™µÁ86<6zlDÌ)®VésF¢¹¦GfôZ¸èøJü P!HlÆ<¼H›8ºîeg©õ/¶D-¾ú‰¤÷ ã›UêYœqáÕ±Ç øË -*Ïp›Â¤A wÓ'v•ù7Vš4¶¨ž+jÙÚN9dB<ï·NZN,±$íŽÝ\ë|.ʳ4 -Úu&IFlµPÈ‹˜<>ê¼çO}ö•>ݧ·ðgžF±;YuQTˆ §ÿæ‡ ¬ßôtD¤ûfP˜{s“cÞ·+J .>xi¾’²È¦{¹3Åš®Þ~—ÛãŒd@ãa‚äÄ·Ž„kï887Kp¥ôRXŠCãóÑ°áTîEQæü^w~@³ßG±¸½Kë3rÎN¡ÀK’jùÚˆYi†Fý€ðF®ÒQG÷QÜKV1Wñ-ˆÄ]uÓ£¦¦Ç¦—D'Å4Žs^ï¥%͇aT{¦®ŒL7“ù—Šð¾äá®^8¡cññçî6S½¤(¸ZÉ€û`2$éß=ŸÝ›·4Žânâ%ÝÄ5Ì&¨¦ȇrŸšÉPjÔj©VÝ J%ž8#/Ô+¶tt:WšœÁcÓ0¤¾öíjMö“¼úŒº£èZ×aóŽÛÆýCØÛÉ7Û¾!-6‹Ú¯¿˜6œ6ÛÛj~ÁSis?ÛíS`¡°è%«èëÆ6¢™hSSÄrþû¤N¹’QëÔ_’­÷êsucÛUi¦¡G1ÞÔ‡´é <Õ ,¡7%ç”b>×Èê/7ÑÀdú^ÉÀŽ‹½ì±/ߤžâ:»özÝoW7…~Äf¥:7âTWÊxû¤¸1RTùã¢öƒ¿°ò}‘<}wD>‰ß­+=ó¦ºf7µ½îÓã'Z׫@='´EþMÅ)TÀSwú‹-Ñl:m‘Ÿ“¡ä÷ËG¡;r­ÒÐ/Ã*Ž¤fŠÞó-xz -}~ÏLcÄçt>í ÔN$c÷¬¤úœ ú=nÆ©ngþõžå ÆIE^ÕÖŠdÙh›•™&|Œ݃Ûtmðp6ðQYMã©©SÝ;h†.¯ÚÉ/Švö˜ È6èDz‹~¾:ûK¸Æ&†Æ$€±sfƒr®©X¨Õ‡ìÝåö©6¸ÒY|CÈœ‘ÄHRÊ=›Ð<Ž3 S=ÍêU%6?Q<ÇÛSOújÞò5®+òr+׎™s[VŠ"ƒ¹ˆÛ­R@BLȼô½øóÉ*ùOx<‚Ýr”†a¯@$ñjKSMƒï”Øvª*8¬rŸâ¼Y¼ˆ5æ‡ßr¿™”‹ïÔØ žÓâ8»­KÔ°§Ý;…§—?\—§Fä»j8‚\šO“§•×†øžŽu8a”öÖömÐú»«MÌø©rÛvÙjÐC;L‰C`„>Vx­iôALí+©Å[ƒ~þº†KIoä&žá2j4+»,~£7RQÅV$èÃL|‰<ÉœÄÐÖzÜÒýÁÏßo„˜0»T 2chÊ›îà -!dÌF æö/¨˜õpŽI^ø©Ý©²‰µ([|«Fv/f»H/>_!üËê¹ocG¥%ÅÉ s5“•ŽnÇ5¾Z‚ÏÝŸ¤±ðJ©ýšžÇÝ\UËúö¡ î[Ÿ2Êíß2û²Qx„úûs‘½¯Ø«PU XäxŠnO -IÇäœ÷îÍóÍè v ó4ýð CihTðÞ²° ÇÒf%’2Žãl}Þç×^#ò†-¼hC¤ó|7Äïçiжr àÕýŠQÉH‚d.à–ŒñÆld„1(_¾wiNŽ3ªÖO^U·s5@p».ú0}¼ƒµ³W -Oyâ|g܇;Òðh¬Ù#1|éôë6Ög²›œ·UëáÇ rk_‹öw€º«¹j!:/œ*¼È_Ô¦ ¶S+³(#>û­pKÕs%ìÛø“hj£ê·ßN -\O–ˆuõ–.½½h8¤Ëµ[%-n&í—o{Ø,OJ‹ä k ƒ$4Œsz!¼¢‡bÃ7Ú‡vçˆemÝÊ5Hcý™’W¤uÊTãO³‰³7 †³Ê;B¥È†“ŸÌõáõý"¡dËUŒtúÀóñ[í¹0!Ã<Ú—(U½›È>ä9íÁ;˜Ö€7¤ÊÞ­:À¤Õ²y £7À­ÔÁT}I”C¶–‘Qîì¹È\·ÞWõ3›Ã½ZÆ™&ÝhÄlÊÞK\o`~~çt!•†ó(à'¤§tq Y†¶bëÑ4r3ÛDZëòa[ö_ó> (ÁÔE7 bO;8<0¹8Ô4;Õª>*ËVëu?+«h–H½~šq»x/·}$ãºÊá+¡V8|ýƒ!Ù‘`Ç©³Mò×ÎàåÇøQÝ'ï³eò^JYõžâ7:¯?¾kñs”ÛqWç®fa Š’Œý4>§ ÇZ'úy]Ü;_GdRÁú È•†bn¥æf§çƒ\Qù²1³7›^voŸØ4Ò-מyþ«wýE’ñ$-¤;k3¡j¹õ½³"í§¬kEŸÄ¼ÕSíÇ»õ7ó´ÎˆÏÖ1ªÉœÛü¤¦Ð#,õ÷9ïÓ¬æ1Om—’÷Ÿ»uÄËnP“ÒZ}7LÎ$·*1e¥PÈ mêõ¶ÇC gùVGŠñGÈÚ=Êïà9’"ðfÙ°ÙèRÒxªú;ø®^í,‚£åzOirŠ>׳wÈÍcÅ¥˜?!wÏÇFNyÆ/^€Â(Œ’‰‚SÌ—òñy`LÿâÅ”ÎàQwѳˆ.ýÌéììç ²7L‡²m³‚Ô-Ôc—†\Âý îãE>`­X|úZ-‡ŒØ3!lüqÆ׃팚ˆfrMºîôaúKãŠÌˆxè¯Rnºí®{ɼD£?ø&´ÌFóŸ´T%ɘZ8­U6 -3ú·<Ȉ› h¥=¯`·C-ãZ*¾•‘Û3ØJ`+>…p˜;w cÁ¿ù\åµdf؆:îÉVÂÊ£QÏ -Ló¶Ú±{i C¤üD8þúñ7.4ß=£Nƒ~ØA·™Y¼ŸíQíì -;dÕÚÞùYÌú.ëÅ3¬m -Œ·Ò'OܧZM•ÈkÚEä»óÔAøV¿F+áÖØ\7H”ÕÁ¬–ÞÙ‹s± -A7µ¢¿ï?å151"yUF„I×íòÏfwÊ*Q;1WG¬ä‡üÖWG9 -dòú“¢Ï¡ã6–±hò¶þ|áç RÖ/?‚jïVÈttf=]«­mîXCh-»E²`?|(“躃Øçw¹©”]“RÉÆè·¸¿½ú‚[O÷^Üä'^m[ñ™4]aÄ‘þÖ9ö5QºÄ”ÔbcÅ‘n"¾ÿ]½GF&<ç ¤3dRµ°%‘ ”Ê.Óµ­ÉÂÆWòQmw)‡GÒDa™e¹ÔÖlNA|¦Z–ýÒ½‹Lýƒ÷ÛE}b\ÝîL» &épƒ·gr[‹÷šßžz÷ìòdÈÄ º‚íüë£-« ‡Z‹ÎîpnöŒ´Ð|˨) 2xqô¦S=w¶Æß jIž6a›6Ä.OSy]ÆñþS§oa¶Ô«ˆÌ±â£Š51r»%ob2üpȈEÐ&â§ÜÈÕöIòÊp¤ì‚è¯ôV²í­NæçiX¯Ô²»Í æá‡A$­Ñe$D{òD¾Ÿû‡‡';,Ög¦•k\Ü Gái3¼q¸Qþ¥L‚¨99ö]/9(C쯆IV-u—ß $#ô?(Ð%¤<×~ü^nsÑÔpPpmªJÛ7'êüyô,YEj–lw‹hÓ> ;Ko·ˆíŲ"ƒÞhÆðÇû­uÔÌm:n=¦ÇŠX—N7ŒÐä£Ïà‘Çžßi®1zUL-íµf½+OGÅŽF÷Ù*v|­FO]ÆvGÓÙŸ¥¥>Š?$¡$ï.ÇpHSî 4ó¢1Ž‹,V‰Æ;…Š¥"mLôWµOËétoÕÛu_Ý„fhJ#ʯ\ü¦CÀ¹÷)O!òiç¸SÔD3ŸJ6IÐëYåÍW«;Õ9#%“UÔ…ò@KÁÝDFjðc¾®=ésË‹¯N|½Ý‘m*ú‰¯—œœR–Ph< ßûÒøºà;wíöÐ5Ÿ÷ãyí]³õ–èÏáÊ͇# -Xæ"¢Úbò3¸ý]ub7¾‚夨õù-ÅsÅK>ˆ<– !!’=j‰Á bê÷](åÏi·t9ù -KÆ.Ha½+-Ε[åòÿÑÒñx Ciif|-is \‹¦ÿ€|6±m¦ÍñŠ =“1ä`K^!y9ÊÌßIjX÷žXHO~ûLýì«œÈF7v—")òï@µW™[zb™®ÕÚ4“*ý÷L´ªŽœ0–¯z$¹Š/‚„à{>UiO³ýE©²5êæ÷”t¦=Ä;î -€¯À4?œt€sTeù›!4J%h¹‰¸—ŽQÏ:µ¿yÓ´(kY¸³½M>X‹– sôqÀirÐÀ³8!ÂùÕÏS€¤Sì$óÅ­$R÷Ñ•amPÍ$?çÔg•ËŸ˜Vd[ƒ1ËiÇO°<Ø_¥¶%yÐœáZ.›eˆô¤Xþ*Iò{()õŠ_¼¾êW÷ºÛ £x}kã¾ããVÔ³Ö–I͵'EÜöGi‚õÂV;áåÏ¿Ø×6™+Ý$Éž {ýTö"1Ðœä5v-V$ÍlÂÞ¯«ª›bݦ´³ã)º§ÊoS6”hLGñ…îÇ,v%¹u©I~®]%¾)Ñ}ú‚¸2¸  âoJ°]^¯ÿRÓ HmØ;Âúž³d¶ù핈`)ÑÑëùÄÚ”°•dv -8>ÔfN-öÓ¥]¥rÆp4’ w0N¼‚+à.ƒÅf4¢Îf Œý˜¬ê/7r¦ÀCêOÝpñ%\ï‚©.úÌ•â{šÞ‚§mÝ’ó³éÁm÷µp7ßßçŽÆQ}⥜ñMÃècFn°ãH¶ÈH¿­D^{D ^HÒœð.xØ´Yæ^¥$ÃNèR¾äK'^é’²td?õ’¸I}²ß©fxaúÁ(‹Œ™K‹ ŠÖâ€MÓÞ*ôSæ›iô‘ h šŒ%–ýb¢¨¦—úˆ*äÝ*Wæò(#]V’Ü<ši#ÒY²•Š‚DÁ°¡ÃÕFFV鹕6ÁóÑÕ+3ÙøÛM~o£¼ Wö¥Ø…Ú ©5QÐ8ÿµ;¼³Óæ?¾z¤á ½³0MñÇ€nZ_:¾ª"‰4Oñ÷ ™Ë±NGÕÛØW,vÕxF™GM2Îzä}ézÚZç=¯‘ZO+Itš_¿Êk÷ïMj ëgàÒk/^R\LsG‰ -²© -3ã½+ôÞÊ•÷aˆlª Ïn×–OBw:ëÌDöƒ^ቃ€¸Rn¹šd¢¯ÅÓò;SÓtd®ÌA~z M“èRVt}õÚ+'˜ †4~}µ÷°}³íÚš[T:áµ%|Å’Q"èXê³ÚÎÝ9"áòç0Tw³È‹d·¿Pô@åÉ@ÅìÓEâòxOæî¹à åÏIXUb_4²üQ ¨:ù©^\õ47ãÇU¸µ& ²ðc óŒA«`á0Ôýµ˜—™žÌ‘¥ˆß·%¢y†.Sz¾M²hàž·ãý°óg #$SÿçÅOÁëÏàBø[yã¦5åž Šq(OÜâƒL#‘'Þ/ãØ«*ûü©¯ð5X1œæ)ol×Ós[2L&³d´/øÿ—ÁÿøÀ -#Ñ{0ÒŽàÿÊn*endstream -endobj -998 0 obj << -/Type /Font -/Subtype /Type1 -/Encoding 1921 0 R -/FirstChar 36 -/LastChar 121 -/Widths 1925 0 R -/BaseFont /MTTJYO+NimbusSanL-Bold -/FontDescriptor 996 0 R ->> endobj -996 0 obj << -/Ascent 722 -/CapHeight 722 -/Descent -217 -/FontName /MTTJYO+NimbusSanL-Bold -/ItalicAngle 0 -/StemV 141 -/XHeight 532 -/FontBBox [-173 -307 1003 949] -/Flags 4 -/CharSet (/dollar/hyphen/semicolon/C/D/E/F/G/I/L/N/O/R/T/U/Y/a/c/d/e/f/g/h/i/l/m/n/o/p/q/r/s/t/u/w/y) -/FontFile 997 0 R ->> endobj -1925 0 obj -[556 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 722 722 667 611 778 0 278 0 0 611 0 722 778 0 0 722 0 611 722 0 0 0 667 0 0 0 0 0 0 0 556 0 556 611 556 333 611 611 278 0 0 278 889 611 611 611 611 389 556 333 611 0 778 0 556 ] -endobj -994 0 obj << -/Length1 1166 -/Length2 8264 -/Length3 544 -/Length 9079 -/Filter /FlateDecode ->> -stream -xÚízUX\[Ö-4Á½p'hpw×*(¤€*Ü!‚»înÁ]ƒ»kÜÝ/çôºoŸîûtßîw«öZcÌ=æœcÍýíz(*r%U&3[ÐG[¨+3 ±1q„«Cå˜T@掀'Ó“ŠJ â` úú‰ƒŒ ¶Pqc‡'^Í o °¬@> 'ëÓÈþW -Œ ƒØغ”@ ˜5úD‰Ûš:Ú€ ªŽvvÖ™ -në3Áùà§Êþ3+@ÌÖÎ1·pЪ«hÒ100þ aåå嘸þÅÄApˆ9@ý´pYÛÚý‘éIBÁžŠ6û#V l,aqø£]­…ƒƒ ‹Øô„1ÃÁÌP ÝS¡P31[›?à˜x&LŸšreù»oVP[g¨ûÀ`ÔìÏ–ÌíXÔ¡{G´øÿ?A˜ÿÂÌAN ÈÙ@.¦,¤TsµýI²þCÍ<Ýílí`ck8È=]0ÝáÆN €Ìäéþ¿ÿ¾Ãde˜AL& ó§cø—ú ÿc/o샸tÌ@ +øÇ÷Ÿ+ý§5³…Z»þ+\ÁØ`—‘cø{ïÿŒµ}’dbåæ0±ñp>MÊ“"/'ûßÿéÅ_>ü‰*Cþ§Nà¿$¥¡`[ï?Úyòñ¯–œ@0øÓlhÿc:À¿ë+Ø:@LAÚŽø45OÖÿ:RÿÆÿ×Áú{ŽŽÖÖºBû;O~Àr€?±6†ýG¸± ÄÚõ¿Üð÷@MÐ?¦ÿÿ #í`l 1š[ÿÓ&ü#Äd¦q0µøǸüå²ÙŸÏ!HÉùãI0±r²þS³€˜ZAApøÓYüI fK)5µ5ƒ@ͪOSi 3û'ðmêƒ=Ùóç=Ýû× y*r™bÎMÛšòû[Vú7]•‹83ýfïäR¿xt|Çf¸ÁŒÔ¡ðÚª€„#ãœ'Ò ¡R]dydÄ€H‰0ng+^Ñff4|‚ÏøHRAÄ{ÌU -|ØGè´£ÇÀNâ¨Ð× éÛb®=R‡äEÚTBbCøª¶DÞ¤W:›[öŠ¨$dEY%Š[Ót¼/oü¥¬½”ùP'û[Ä–~ X2­µc×42:Xµ{—%ÍøFSÓ]¢8œÞ“’˜•G&$ÚÜ|-C­l7…à›ò~»,Nv}»Æî,@HíŒÅfMè\ƒ•jLw~˜,rÿMüF]_©!Ìçªu¶KD]ÅîÅÑO¹÷šÕæ%SSJd2N„ì1«Uòêm!fÕá†ïÆ /ëÍ•‰×Ô8ê.Õ›O4E¢6:UB 5 ž Í..7’M%¼Ì¶#M´-Û\¶1êh߉PÕ;þSB%•N’ek!_>”þl€ýHåQ·8ÐmÕRëp9Þ”Ô3áØš`— ùÅ‚ÁZdžÇÑTæw÷RüÂR#Ö\¸å%u± œÝ{WܘòÃ`rRç&ƒæ°ÅPýþ‚9Ú=q…« yì†,ÝŸ÷4^¾ÿ*»Hg½ kt”PØLrœîZ`n#úíÌÁë5&×Å놄ØS~¡RÎyïþyœkô²Aªl–O#ZÏ6±ÚÄ®Z8JH’ð>â.¤}Þ<•Y8R¹j­år"e¡“@nª2i‰6r–·EnX$:ФBLÅw3[Y©]Ê’TɽÈ|ØZoóY*˜1N1.5"Ÿq}|Ã7ÇDaq*áüqdŸ«AåRkD6–*u!óÔ¸$&³^´ È -ýÍ8¶öOáÏoëÓ‚úïLîÓ¼¿œ+è¶kÎ6ÙAÝ$=43Žºoô°Jü¨rOwVsr¶Ê¬ðšz¾Ž~ÿ²ºþëÁ‹êËõ-!蔄Wd=R9‹ò”l:VŽhÔïÀ³¼LôÃaìtþ8QIVæyU&Á¡û«ü\ žj_E‘{<óéYàôDËæúløa½ê£D–Îîç„xô?¹é$Ì|’"Xûü"rø—Xu[ÊÚ6·èNâ÷AŒ»®qmƒ½Éý¢¹Hx7žMxÃ_Õ[±½z -¼*K«™Zú¹úÕ°×Wý¢Øø¹.ÔR¯æES úLkéDÐ?«áäv%.;#•ûc~¨¹i -šI-b´zŸŒU íÑ—þDÅyMß\…‹ÙCó«ïÓÖSätRR˜…$ ùÛˆFy/Áê}äYeOÈZñ¸ÕÏ«¥¬øïc}͹ü< ÂåŠ^úRX¿T[ÅgÝñF/yo\ky“Wb“Ë·Ú{že”Ã_¥b1‰¯ç(17•®LsT/“ks¸àýÄR–Ê8à׆h0ƒÄcsâð]€¡í"Z°p¬Ì¥`ÓTÚÕ¼V£ˆ™×Þš¥”¾Îé;»WžÄi%(¶ØÄ5œ™,—»ì>N*Yƒ?åïyÚóíʈfüλ» ²ɽø7ãáFWqÊZS>M…ùdT„Ǫ;£Qס3˱_‹§ÙL_¥Ÿ€(U}Üh-²CöF;5 œ} ó.T²¶/0žyÖ]±!3f\CÕ1WR|#¯o‚Ǧ?}Fq?¯ÓfÏ ‰²¾RŒ2Á œðäÞ"#±ÒŽuXéKS‚ºãµãõðÄ{¯¶©F -hŠÚ?åðP‘­||èuæsSQ2¨•PbHRóŠêÐ8ꎜ¹MS^MýÜÝ´ Ó›û¶ÈnØU´]IÜl(óš–ªÉô˜ÔpXò,Î%0Œ1µky„Òæ®qú§°Ä ßÉ`hˆ Y›½ goû[rð`jϾªN¸tÇ\®»–ü»bIBj¬÷¯Âµ^‘•HÝ{”é·ÄÞê>µê9ÙY•Ó¯BšË‘!õõ詃W/lë²(»óT²œEÄ$ ^î·lý"Ÿ»É¼µ÷/µ³ÃÚ…/ò½ŠBº¹Ë)E†…å(xˆ¬%ð©»O:Ä$¸]g¤Õ ¾JÑóæÞö…ÕѨ¶EŠŽH¹ïØϹÈGgÔgΨyîDŒg.uøò¤å…MeÕ.…î8ã ÃCK±(Ö.f5i@«v]Q„ƒ¯Å=@Ûp»CDlë£5e…„° 8óMù½€KöVò¯½hŸ’•±¨cÎÔlÊû%±È™‹•3V°°‚`÷b,ˆu®mvÎA“&­ÝTY–vÛ:ìL$cØÜxcšÊï• £\\ª^æû@Ä›xBÐeøü;ÃDÐéÿ˜ Ž*‹ÃA‚¥¼MJ$ˆ¯;ÌPïý47Ø0HïÞ#XýÑôš>ÃêÙ©8„2È^Ï|Pø¦~Œ@ÎtÐCvÅY ÷º÷±ÇØœŽ¸ÍÈëš…^¤Pù]¶B¶š)3iy=-;¤ßÿ¨çÙK%¿ûÉï÷£K}P^å—]èë$Ã;4׺´ˆy¿8¤×[)4±ÆÜ ²T§‘^±"©* -Ô +¸'º]÷ñ@f̼ÀÜGgìdô—éËùêÛðFÔ!k£«Ã*.$|™/mßFàŽùyAO&—2Ö…Õªõ¾1Ù«<Žø+vˆý–­Dce”­µEx`Iµ5úÐçK:™¢¦ïÝOÜtó‡ž.erƧbÛ,H/«äíuåí™RrŠò–WW“OF3³gÃ)‡¬Då"\ßžâjèßÓ”võVسïuÔt2C «Æh]W*é„g̯%ä"‡È@Šr¤Bqf„•4†Fóó<ÐP+]°¹Ng…8à„q/•ãȼ¹b–Òdù&Ê´ºdVN šùÞÕç6bÎNé?ï…çPÒZWïn›vÊ -bší‘v\aۺΤ:×}¸½øÚ"¤#"tl~–ŠÂó5‚ws¬@ö|KéêyÏ’4%Óù|ô}É=ƒ-RK¨Ö{Öˆ“¤‹xwwa@­â©Ûæí‰ûÂŽKˆ0oýwËŠµºÕ6©M8³q¡ºïˆoâ³·àßYF¤i{#ØHjî˜/„†HP,9;]D»¢ôc¢bÓ* ÃzøüÆísüe¹ÔÊâ°?»ÔÎTùw}ãΗÊâÜšTÆýjy¡1(`ãóŸ©3;çó~•…jffl¯©È{>ë²SÕ†¬[ZÆ€ñí^m5 -îlúôü4  }ª9Ã¥jj:ÕÂŒ ÐåÏG‡®ù<Г¾ TÄ.ê…H›Ÿ¼IôhÔ?±·!—,ssÝÒ ´6¡Ø_KiYˆ÷)|“Ûú£a¬>S±I"(.‡±ÇŽ’¶®îîCî>`™ïñ´Ö³=gL”Ä0·mþƒÝ®•@ !á¬ÃYf‚bÂRò=ñT®Î鈶×Æp·ô6/­¼Ï•ñQfÚð^…|_äb õm;à×]1Lð–ùæˆùFóYKïÍh¿µS [ÍÚ«²þÒ`’ùQ­ "ƒž‹£ÈñʽÊ¢@ÃqØâÐ.Qô™óÊÞÐÖW³_~È‹Q5)Ãæh¥_ç• ÒI¸tò±‰ð¾ØÇ(ŽÊE([~ ×ØÚísqÓÛ9êŸ٢Œ™4¤D£l̾½¦Û²úµ9EŽ6Bp,¢Êòé²êG;òƒâ¨¸²µðÆ&;Ì™µ¥ íKk4[ß#½_mú]–T¯ÙFÇÖÃÿPò.€;4'.úU~ëwÐGA9Aá±Õ*§¬ÇAWö 'Æ4RIîHkˆÎZ+{Ö iùay±3_¼ ø’ƒ‡ÇêÉÁ]£¶ÎGBˆÓ -¸iÛ¬[tÁA°Âü™©÷‡¾ú€µÕÚ…i‰È>íï—{Óût{‹s¹"”C/Óçš²†Vn¥‰2$ò v’+X™gh tò‡ê’ž0䶷KW0N¬e"HNY9úóÌŒ¨hA®¼Öô‰óÏß_ÈßHã› §ˆ(X#;B×ý‰Œ\%°üÄ炶zÖÉ7(™öJÇgÄýb-¶ÕÀ$ÉÖ3¡ùzAÎåùv…s¼÷[Jêâ½QÜ<ãF¦=Ç&ÿœl¤rPΧWV€ntBcÈs%¿)œ¬ Žß™(ö׬%¥,R<†H—¢¤‰y]rÉá MèŸÙªž'b¦§¼±¦æ-o½‹”ÍòË›’Ö¿¶g( >Žó–õM6!ÔX¿JdÏÙ=‘¬ðÜÙðM‰-¨u7¡F#]Ê Htæ@¢î{éÂ^¥‚ÜY”1(öó¢ÙHaè¸zÜÛ™ ììÎΕ›!ócÅWH™¶²ny ÈxtƲ‹5‘mtEîúÍ ´¨ ûØ­bñÔŨA÷ -AEÂiæ·Ü¾^Ápš¡¶²S‹q”)ä—®}ÀÈ™’X¦‘Ñê ½ž¹I|&åYöd§œçI»Á~hÜ%i}ºZùñfǤXÂx,¯ðçÝÀŠÆTÀ;=ÝJi×î^‡É¦Öèz,€h?R9Ìó;@Öÿj—þY) Ƀp9:•Iß­¸ùG« -gwoÔЇ¼V}ŽCsg@ˆÑÕ†šÒm ^©‰iÙ;4 -ú‹®fºÐ61^Ô˜±õƒøåiBž•1•ƒ—ÛÉŽ¸ïõ+üèªicöe 3+âòÖÛ'˜–ÍN¥ê“7ðÉi˜ì§ï´½~2¤bêó²ãò½õþ•`×Êê¯áÞØC?¹ÕÔÌ=u¤ÛˆU¸…Í"â#øŽ\f£N2ú-aäÀoŒâÕþÙ`S6¼T z¿Êqˆêëà5À¬³DÕÓÙ÷“G‹sRç\êõ/0+A¬£6àÄZ{Xv#¾K,,Wx§[~ð윲‹T\Æ…Ñѱ1n“w  -wŸè’¡µ¸§¶”¬Õ¾Ï®HÁ=ˆÒT“³šÌ6X’>3¡6º­1•üVŽ mjƒ3/7¯=Íôþ &!nIy<`e%aŠ{ƒ#0SÌ=²\:×Ñòz¤ØGàU%˜YMçËá.žÜÃ_bÔõ~¬›ÖwŸXöçÏ×{7¨‡¬MÅ6ê£BÊæz‘×´‡ïÝpä÷¹QØì‡G2n2ªDö.×hE#£“ Z½¼Y‘ñ&ÐëE\(ÃES¥cùlgK„ŽT@â91D±èc™×Àj…¤ÐiÞÚDÅëÁ»ÂЯ0Tµµ£bÅ$㪌íéyÑdö¸Ì„ýn&¢›\ ‹Hè^¶ÙôX\JÆÇH?!Ê¢ñ*zTD#Äßǧš¿¦3\UƒX¤~d«mNl›oåbã-ÙÜùUÅRù³ž’¹JÖj/3i‡Z+¸V=˜5¶1Jmt•÷êŽ'o›IT/Ãöí©Z'\?¦=0"÷Ñ4¥HíøeA(2½Ø$B¼?ƒíϪE†³FÑ|¾_DÀžûºAqeˆæŒœüµX\K9§†µkÞúšs»¿JÛViS°N}¶²»$ |}Ôˆ<4­œ]Z¼´BdHØüˆ^œÝ¬$À½=N² [¬žgr9Í~[$·*È$#\8GÖiËŽ’'BÃW3Þá*yÛ&ÝôS‡‹p=˜vPbyB^ Ûœ;¬·§G¹ª3vipº";ªÚ§TáF8€Ì'HÔ÷«Žee`h>|7x gZ–ÅÒËÔ©}?‘[^æóN^Ö6“/ÇÄ+Ƕ³©…¥>3ÆùR¶¥L@¦ëû1µèÄþÔôe㛚 -F‘PÖçhé!ÍFµù„複ì‚4ãE¢Q¢ªÈŒ êË¿$Æ£}IÅD0I>àÅlPól&ÕFXÞáÅâ‹×Ž^ì÷êÑ!W‹ é·qV`ç¥Óz"!׌_j¯Ñò«E’µeä —QúŸŠGÌå«P•['ïkÈôZðÛ5%K…š†Â¸ª¾àÛ㼿°è/©äG Z­Ö¸µ²¤Ë›w f§þĺ#7^•Ÿ?<Žàa¶Úñ9" ç*‹æz]à•Öˆ·Ñôv–ý £-ÉTqÿ.åó%‚8Þkeÿ3¿[M£6ò¢@Gò‰ƒXúÞ¥çˆS&2ØŸjF[fzØ.½„ø'eCL`KI -g.£Êù5õ\Ïc¯ªO]ffå,§m¾¼@+¬—q[¹ ,<¸¡ÎIPŸ©if8§”MIe({—Jœ~À$:­`š‘ -éé;±‘¬y~`²ŸâÑjr+Ö-±˜…>IEƒfçl±¢ZV­®ô ÛûUM½5 ßOÇRòˆœN@Èd£èF_ó³òÌu³Gö–l0êYiQ¶ˆrœÔÑeY$î9Ùq+SÊbÁ9+²ÀYƒŒá— )mdA( Å”µˆm;ÞUÓ ŠÊˆm-Œ/=ŠÉ?ˆ)CH ÙrS¶Ô-“×ìª0Kƒk}öW­jõ‰9‡ý@F#iÍKû½D;¦$*µ±¯ˆ:vÍuš - ¢6G4ÚWó÷mq£Mo’¾íü0zt™ žà[ΛÙóïÄ3ÕÝZsÆÈP:dVÔ/fyŨV³Œ§²· ÞŽ%Ÿð G5¤ÆA«ÀÞ«§hÏ}Kœ¤=ª4¢a3¨˜– xMPn”ªÇ#qp´ų́çxk lƒ<¶ä¥ùÁãÊ¿aLÆòË+&ç0qwl$^dnÜðy(ÙBÓ¶ûo‘#@¹×M±®@S#8±CjQðç} ékŠ»*lí,¡µ =êïΘexí¬„¢h‹®•ëö¥°gЇ™N¬/U tùM-w*Û¼¿<ý\ɽ~,($ۥDzÁÏ5dèrР®Ê º=¸’+•"‹~tó%Ê"â…,iãä, -û -àÑè.šoÏx­g6åëÚ†ÇËVDU±N…;ZÆÒ5oùOhú­—Ð>IîÌ:h^$¼Ôlz×ÚÁÓT @ÿ}&YƒHõEŒ(=‹qåö6õÙ¨ôW=wš’xsDs‰¼:ŒëöÊ-¶¿{´1öFi”"}±FêÃLf_ÜÅÅ;FO5æøþ|y~U¦Î ‡ëÄCš¢Õ„’+ê´Èø–u{Ó&d¹¿*¯’E牊ô‡Mâ‰t/&%Ï©H6ÛÒ¥Š‡¬GJ×:Ìøö•¿ÒÒ•ß:–”eˆº —ýq«É(LdOÅ"^$·u1§&j¶ÀZ¬ -Ú=;ˆðá:ØÓÏäÁÏ/én¼¡,*¢`\ÜäK}["ÊHTÆÞˆo`ÝÙýz„N¢ &j¸'µ2ó‹|K×c6Qén)' üÖœëv?.ßüê´–®PÌ£§åZ]GOŸIªvIbŒµ³ÉЄH\Ô‡óÉ}vÆé¾°å1ù{'¾ógâ݇ûmœ‡½*œ‰VákÑJÃÙ9ÿ¾<§µÈi¥ßgCL‚¶áX±rX¯=Gó‹Ûìö.BÒÓ oû~o‡´~8:_ª˜WzåHTº{‚,×d?u-ôR,ýá²ÍþcQk®‰î•üâŒ'ÄݹQ쪡³¾§Æç‰g\&ÚQ„#J©Yð#Õ²á[ƒËEßE(@˵¸x†üœ³/ö®:g]!$…US ](%v¨ åÑÜ팼`‰jî&^Ûœ?-ó@öùàjÙ÷<³ïlY?XRr$Š™£-ÑTù†~ŠÇ/0‰ÌB¯7Ù×ìYSB{@&A^UE s $DH@ -٦ϭÓ%"Òð9ÓPëñÞç}ž¡œb --ý¸Bçhµ0ÊnnL¿ñE~„éMÇv¡“LYd< gñÕ¾ìQ±íÅ EþoÉ|Ľ„\cvê´ -Y É4j"¼ÒÜçÞ»6ð¯ø»(~7qBËb“½L*&=¤ö4P'©ð·@Xáѧ†÷§€R§ ÙiîÌ#k]3§&M<~èêÆŽ¬y×–=¶÷.Ö}ìh"rr²Ë«À±æ <³$wt•°CnEÕ@¸*ùwN.߆Z r™LŽ:øõŒªOâTãPêŽ".!ÉMù?dð<Ÿ½h·Õð¯=B­›B] oº×dûJèoÛ°Æ°­TFØQêP¢úC@qSÁÅùÖ÷¥7_±¸Ôˆ ²»ÞÌ3å³_Ž¾«š’ñ #¼Ì‚ ¸~sOsÔ|ùƱ-J?§>8_@1.æXIg5ßRic¹RcÔŠª¨Ûý*GÆKVJ°îŠ<íãÞÐèHïñúa˜ô0ÂAYêÎÈÈ¿Ô-U@®—‘ì»Be×âwª\ò“C’.US>˜ôÓ»,Ø "mY)×ÿ» %´Å§o_)5ݘñÊÇNÑ÷`AG‰Ÿ9PÙ6R‚stñ¥³e›è©ü[Ueï¬ÐÆ9ÆWúÞ¿ë­QW!'M(gÖG}ú1ö%dyÓõz¹þm¤)9adz/°jE/5Ϧ`†€wƹc:…@Å“|_9,ÑçpSþ˼ËËg;VˆÁÆvÓ[¨™5–`Ú¢!¸(횈݆jª¾¯Òº@–î¤û ðÛ`¶ª&ÂU\ôqŸaá |\+.oø."—Þlˆ“Íèô‹qQõ»6Z7ZíBÏ‚$¿Y휅xÁ¬„×ez¹¦b ¼`<¤tI¥å}Y:½¼ù¼ØÅ„ÝB¹ÞVõ-¦»ƒ¹-†p¸•÷IŠËÔíò»Dmä¼CB˸hB®ºåD™¤L.ŠXG]GbK/aµT”Ú¼_¯‘p (5w»0|2¿}¶ºÊ5i¤™Ø×ùîIJŒ*D-dtš?Ý£üO<*$çŒ7}_Ø´·{MF~F~Aµüž è‚Ú;nU•nÚ—sûZ˜7ûÎKø§Ÿ‚%g¼À¢Œ[Fð}‰X]Â¥2ý¢–ä•z‹8ŽÄ¤5üµòDoÅ2µ_¯âÔ¤°mÿ¢šüj Ýîå]¼@¤FÝÎktdÇjJ×yÇ8x­öàvËÕ’í&jÏõžÇQL6¬w=ÄŸÂËUdçHßÌÜn t¿”è®þÝüÖv—ü³)¦h ?„K¤AØñì¶,á:  á®ããÛ Nàÿåóÿ ü?!`j 2†9ØÚì0Ýa ¸ƒ-ì>aþ/J€endstream -endobj -995 0 obj << -/Type /Font -/Subtype /Type1 -/Encoding 1921 0 R -/FirstChar 2 -/LastChar 151 -/Widths 1926 0 R -/BaseFont /DHCAHC+NimbusSanL-Regu -/FontDescriptor 993 0 R ->> endobj -993 0 obj << -/Ascent 712 -/CapHeight 712 -/Descent -213 -/FontName /DHCAHC+NimbusSanL-Regu -/ItalicAngle 0 -/StemV 85 -/XHeight 523 -/FontBBox [-174 -285 1001 953] -/Flags 4 -/CharSet (/fi/quoteright/parenleft/parenright/comma/hyphen/period/zero/one/two/three/five/eight/nine/semicolon/A/B/C/D/F/I/L/N/O/P/R/S/T/U/Y/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/quotedblright/emdash) -/FontFile 994 0 R ->> endobj -1926 0 obj -[500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 222 333 333 0 0 278 333 278 0 556 556 556 556 0 556 0 0 556 556 0 278 0 0 0 0 0 667 667 722 722 0 611 0 0 278 0 0 556 0 722 778 667 0 722 667 611 722 0 0 0 667 0 0 0 0 0 0 222 556 556 500 556 556 278 556 556 222 222 500 222 833 556 556 556 556 333 500 278 556 500 722 500 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 1000 ] -endobj -969 0 obj << -/Length1 1624 -/Length2 8351 -/Length3 532 -/Length 9216 -/Filter /FlateDecode ->> -stream -xÚíweT›ë¶.R´¸;A‹»Cq-î‡ H!P¼x‘Bq)-îîPZ(VÜÝݵ-íº{ï3ÖÝ¿ÎÙ¿î¸#ß;Ÿ9Ÿ©ï_˜è´t9el Ö E(ÎÉËÅ#Ð;[»»©C!jœ²P'Mk'0àÄdb’ƒ¬à`(DÞ -‚lò €À+**ŠÉƒºxÁÀvöp‹¾Ž!+;;Ç¿$¿UÖ^ÿ@-ÝÀvóãƒÈ êâ ‚À)þdžº nØ‚@9M­—*J% }€‚Y9´ÜSÔÀ@Ä Ä -°…ÂN@(Äü;57®G.7€ÀÍ?š< —ßÀs»¹=>Àn;˜þX8†Üm~ð(·…þ È}Ôp~ÄÉ´ np7 ìjÚ@î¿Súƒ=Ò<¢p+0Ä yÂû²lÀn.NV^¾É\`à?a¸»!vÿŠ€ÙYÁlœ@nn4Ü¿«ó¯<ÿ-{+'¯?ÖÐ?ZÿŒ w9Ùraòò=úÂ}Û!˜Ü¿‡Eb ðòü%·qwùæ‚ý)Ëï™a} ÂÊ -qòØ€l1¹5 ðG—–ÿY—¹þsMþ´ø?ÒàÿH{ÿwÍý{þÛ%þßÞç¿S+º;9iX9?À_Kð¸e 5Àï=ø½h\ÝAÿ—•3ØÉëßXý]ÑôW¤¿ÉþŽ©À­Ë!±{l '/Ï_b°›"Ød£†í¶VNÕú#ׇ؀`N`豫 -úhÄÃó7LÏ t„ü.¿à_bó÷Øõ'rn cE…*ìÿn·þÑÔzœ¸ž— ðܪCmþyøÍ#+ õøp -ñ8ù„E"<a^¿ãñ ï¿ÎêVpØ`ÂÃÅÃà xüýÇ÷_'³¿Ñ(@€P›ß3£ ·‚Ø<ŽÙ?¿a ; öØÝ?7ÿ1éœÿ <ä bÎMCâ!©éið*ÒìÞ!y“î.^äÞP—ÂZ½yÐÎש᫢¥–¿*C¹ê†Å¦ö]î6_°mõu‘8=ëLçRù1°~ÊÃ_bnfß -â6/ÄN;0|ës2©¶òÄXˆÇ`kmH[Ǽà*õp+? ýä†5€Á#/€ˆñÚǘRóŽ¸ ¯ *ÿ€9a÷æúÙ—þ¯½=g(Ÿ6)Ù³Þa0‰{<ÁfŽ -pÍ¢”2Ö/õ‰`”TèÄjš 3L¿àƒíá!ŠH»  s…?VLãT‘¹Jˆ&‰g: ÉÒѧLy‰À¸Šge0å+÷&|ÂýÀê~sóTšù‡²©ttÔRmñIëëd°9:6+¶@›ÿ䧗%«ŠA~ªÎA ý¨£±bíè0TóYòs¢1…Ðg{Ü™ü_8X—Áx!Öy4´Ê3æmü,qÕ¡Fôž¸Uœ1”=Ê™gÊ™gÆȲüwâEÉw#A¯òøJàú•BþS›•¤ònë®”{w‘?ßW#·TæJZ…å˜>}‡Ñ•ÁJJù‹”ºŠÑäÊj¿¸°[f"­u¬x^Ø( HHŠ}Q¡‚ßaŽRz8Œ¶¦µ“;jÇÐ:šÈƒÏó%^%QÓ±¬­v˜iŒ¼Æ¤|hÉÊUq”J÷¹ù »Ìã:aẖ²Åà2]½Rô¶°÷\xT; µ7L4T3FÁ°.ÌkÛ4ä»Ïuä‰qÑÅÓÅŠ ›c´ã¨ˆ“Ÿ¾Ú:‰Á˃NG!òç»EŽfµ4ƒvZi•M –Þc’þÆXÓ"Ã-­íêÆáP‡³ÕÌ$’_?Nˆyéå…ÓÕ½mÞ+à„_½‘sãÙ ’I%pazÏl›€ÿ¶uçU« ·\Û×Ðbjêìb>U¸)}{QŸNßà—¨ªw%=Ák±äfZ%Åêos[1øÉ]·êñZ¬w¹­fsƒ\û¾cx‰¾¾‰ŽµMÌ(}–"Ú\ñ|1wNkõTƒh,.Wèçh7)m|°Íü'gˆ5’S¯ŠJ2ÇM<'sÖ+ ±UÇR·¬§ëÁµ&I"AkËðÖíƒÜc»Êþª'ºø®¾bÒ^XÛÒV¶ãž‹c&jžü õ«{Aî.5ûÛd -Ž{âA‚ݧL3bü J?ÙnÁ›C#ŒGÖ:ÂûSÅŸ†¸XJ½·5^9%4•Õó’‚Ò¨î_Zúäu¼AÁÜ݇€,23sËÛZÉzÎgIÞf­35TìQ›Ã_ ?Ôn¹)-ödÙ­¤!á-æÔ‡$J›½Àzö‚õ˜»‹Š)Nü‹:¸¶’{ý[}ð|ͯÍ*Úe™à€\‡v,­:j±ªÖÙH’R<[ݧ¹}I¡ÊíÐRò´hst4ý¯3¥{Þë— à e¶A¥ÆÈ)f!ÁîÎÈWn];FuéÅTK&|Õ‹æ¾\c…GîàèE9#½‘lý¤z‡X,¾t8íèëàvO¿šåj›@’ò»²·1Z1–ÈÈWc7Ü^q7÷õÛHm®#Í4š‹9.é"घ»Ž;ʆW=™PNïÞmMj§%·™Gô(àØ/õ]-÷'?E4œ¥ºŸê ЗBáNIV}f…×–Ÿý•‰ÓBýó®aˈÖ[ i´ü%ïÎ¥”uºÄ±‹·•¢ÄÙµâŒ%Ä53ÅŸJÔ‘ñŹgu®mj:7¹1“Æ•™ãw¿(ûÓ^]š¼×ÀÔú˜¢|p©Ö¬kŸ `ìj•óOÉ9¨# ¸iZM˜`¡lÇPa´Cùç_Õª˜ -ÝìËI–Ø+¥®kª+…k{p¶MÍÍ$]Lj&”?M(ìzŽh¾ÏöÄÝá6è g*⪈}Æôš.lÄÕÉ^wïkæXÏ7eKxvù»‡ù5QÁ°Ç•Ê.ܥ˯ŒZKòQóÂsÅhã˜\«l>[êß Ý“Ñ"bÇ -idguÊ ÛáÜ‚Ñ 9¤ëË‘'jM.~×ÿfêKÃÔŸ’ SêkÉ'ë,Fèø.JìíÜÎXѶ%Ænvâš’¤¼ò\¤ëVù¹r >guΆɩ,hè‡ÓbѤÏ_9¶¯Ë`ÔT •#ÅW}gƒ|³f<×­ð8²ÿ5È âõm`cÚ—}çêã[ÿoöþ-ΣÆgLÊôµF&Žzê_Ùºœ['Xæ tqu“G.¢/­bŸºâi$g¿Ð ÿ¥ð¡^df­Ümù!gÞ²Ã3Üú3a|ê0/Àd)°FyQ­unÅ(€?v Ú<$J˜ÿžZªè–ioQÞPëP‘¼“%ÞäØ5r•°ÝZ(J¼æÔLñ{ ‰œßÍuu"@M›ÒŽxˆñE(3'_pTÜS½ù¨æpæ=*½\yíwÈ^aöÚ-6åblEcjÓry† :ÅH±Eè"I„t…39ìî씀-ÜYlZêf©^¿ÓAj÷½Ê»ŒrvŸ5ºZ­X΀9KÓîl±@žñhá½U½ê$–Ï–coXœ•À9$JŸ­4ýÕ‚“ÈŸ $i‘åqHÝy‚ê~ée—ôTG¼n²÷*³‹ß%¥ g­Sšêm²'Xk°•9¢Çõ…Ä’nïø½À©ÚAèuqf]¹IK2|—Y·k‰TK[užXbEƒD8ÆïÇSJüZâ =ÆôÒºµi3íü”‡ùµ^Ф9Ýö@»Àø†Ð­á÷˜ò.ø wœô/[¡ÄŒ\~Á‘¯>3=Ó”£½—©Àé¤YEp¢` ‰¡QÙ¨’ºa®zżžÊ*Þœzgç}¼;Ð#U’ýé -#ÄÎÝSDº“l ¹ügTù®„B'æ|pÙž2SXÁÖ =‹ç~õÎK–DÛ+Ïk¢·­ÀICÇCÜ0SApðäcZ:³ísž÷½Z÷•âKíÀDÙl”osúòÖ'+˜EŒ;úØÏb ]RN;-¿Œº(·]({5ׄX’³øö÷ô~™Ÿ=ÇŒpy¾7rB>Ý#ÛÁr{Yƒ©3ßrƒlšê¼õ~±Y¬Ø)Õ`qyûT±ŸIJ\^Òº2¶5ù¶…ŒÂ¨ÆÙ½C+âa¹ÜmyüÊ€=YÙGzm’ÕŸ>ÖÃI)ª~•¢•¾·wZ䥗QyyŒRÂfff8û“‚ -¸ÜÏ„e) ªÔ5‡Ðz}Í=1¶à‡v‰ÓG<˜'}îpÂ/òʨ^ärÁÍ)¤ƒÇ¼V²YYÍsSsôaÛA ŽPWôÔ /U®øGÎ8G”„X×ö¥ïôgd” ŸŸËÀ¿ÚrsŸc¡W8DN0|’t&sõ™9©~ }Y%ÛZˆÝñ4Ã@hÁwKÇÊ0º7ñ¤‡>–"OhIåà"5àÊtþ]ÛŸe»ÝÁ†UyåÞå¼ë\_¹j†œO" o‰¾é~iŒµb âÔwyu«•¾Ö:&[PŒÑhøvw;}V»\3¿”ÍYÍ>ìk·K¶•°Cã{Ç£¹-wd¦»ÏóQ½ødȹç>UQ\}Ó Ï à 2ÍìšsI°Œ?Á/¸™dâð[6Î…eíÖŠ¥£±J;¤àœ1NcùT)À:[êg³dSÇ·"-ûÍ· Ú£ÝRgÖ–²ØA/‡¿„aavàn–¾„ í0î®èT=:ÇÐÈKg1‹OŽœ8ð[<™+è½õJ퓶Qô»Uæû½žsl ø\]ó%»¬üîúr²0»Ñíû‘¡¯u:ÿlˆZª¥äú‘7ko |OtZc½ÜH$Z¢Zà =ˆ#j ¿ 1¢¼M ÁD§à5Yõ‡íïcE30J)R¢êö³c©Vƒý§¤Ï® KÕ{“z$ïŠàPJ°Ýë—Å£‹‘Þpí쩉nÏïKßÖÌײ«ŸêÇ+F©*Fß9Ç6]|»+(½VEãÚœ± b(N·®åäiÚܪþ -ÓEWº?Kûß“IœñáÕtÍ{Be-ë Uu£tië9ÙVåøë_onw®YH°íy‚Þ|˯©KâÉ'zÙuLÔ‚™I…¾?Cfà.mQn%¥Ÿ•I\zQ[°³D]Yí7öT¬$&+ázªŠÜ^„§P•àÇ´ômÖSXS„α¿çd±³Á¡Y>RêÑ™½²†ò…*Ÿ~ûzr”46:bŒ*Ç´H]ÅúÉ êXË—P/f Îëîw¸ÑV%.Ð-HÙ¤œùÍØÁ°ù¦µŸÏ™¿Ï³Ú/€V>ÖG—ç™~]I§ÐRúå”ù5ÝÙo<…zÅ•—Ã!rÀÜC)4ÜKÿªdÞÌ5YG¨Ò!ŠUa dV¦Ä`ȆՃ¶å|þFĹšÆ#\XZ­•c…–exÍØ⻫‹ -ðŠâÅI´ÁAM8îe¹åÌ 4+Ÿ`,NÍ| -‘†“uÞµ¡ÞEL0ÀsUÆŨ O?’t>ÕÕd(×cpÁ@‘¶DùüÊzƱ±º”u²l(èGC™þVƒa%¡³_¯Òã‰z«£+Sñú€ÏZ·öRÊä»îÛ¡MŒXsPX”èóPÿ8:í©N1–Ž[ ˜š#´â;ëRœ -jT­C©i–Tu #s¥§Ú'¨jzÇ¢’‡‘]ž>û Ó›ãé4ý}AB1ö‰pvs!œÀZý¶Ù0¸øÖ5 =YÙ‘Õ®¨=×`«²Š©«åU:¯ -$¨éå,3£¨{Q¾Qê5¨§6µh¸‰Üüß <ü‡ŸP1[½;džFoU—%÷UÒÞ,²Éš5Vo1ÀfÞ2TÝ9'szÀ´{w¢R“XáÐ㌺EæoTúRf;CHñØž;>áẨßæÞzeZ{ 碭-ÝpzÆç@r3‚ÖÚîPá8å“™ŸôU€ôGj%’vrL>íŽ9ŠúK -=JƒË¬À<2Í¢îÿ¸£»|µºÂmïÝa²‡kv¼@ˆw÷ÎÖý¢AŸyÆ«ïÌvÒDYœ32² -©òc¦Y +«Æ€§Qùsýò:ŽrM£ÅÈ*iÀ· Kö î0ÐÇkøÄ<æçó|;€^QÞâÝ@öE -ăڙ~»À?(Ç«Ì_aè3µœÌÀq•Ò·'ZÍMÈòqZ£¹§ËSÅv8à‚¼Ô[=Ä2MV*ÇE¸ì¬Ömpx†“‘ò°Œ¢Ç¸ +4a¯ã§À!¾Â2J ’¯Ôc2Ä»îú£ GЙÓØQö(„ªž0ôéÊ ÕZÅÅ`¹‰ÞÍ>QqÜY·TÓlFrÙ9Ä>‚$s™| -cúÝå99¯ vµI÷ðJÐ?½›ÉÇÎlâ—2ãÁ¯Ú÷ýŒ€%Í4ïÚ]zôMy\U¯_éCùÅ‘Oaðáׯ™I m>jzX P’·ž¿Á©Øô©:Ïûô.)¿¨h^iyˆpdÎ<öL#ÑÆ¥{¨Òܺ¾E¨ózÛ'¦îIÐÔñ`Ïõ®±G‘ß霈tYD0¸À” 0[þ´rD›X[˜Ê˜ïë‘͵¤?5Í<„»9%WÀÙ!.ÿ:ÈÝ*úœhR*C3›"Lq¹JYžC<+yîõ°mÂOSÌÖ“ç8DºVãL¸ˆ+“„¸×[9µQ|…|¨yžâ rÕÓ¨×ê±Â”ùÓxczb:¸ Æ&= -F¸lqF÷wã!ïlgVc8Agbf–FLD¿¦x9Š|s ý5þi.ñ½5ò.–so–¾¨ìû4§e5CÚ±CŠH›zrŒøòx³÷ÛÅ»+Vˆ-j¼pÎén J™m–›Ñs°pЭ@úEƒsFÚ-V^@6êI]§gIëEJ‚J[eƒÏ%K\ñ¸\%kÕבÊ}½Ï±ª·—´Æs‡2ßwýÕk“Òhý€×U%'ˆW(“ûh?œGØâˆÏlíä7+#ÐÖO'›Þÿ²ºéúÅç78' K*ûTâàÃF\Úÿq$qƒqê¦tMŠ+éM4Îâ§7·!… û9B²cr˜xÔ©*ÑEö¬!ü¯¹Š G_á¹É³Ìkñ¹ïEãA GþHŸ#ÑÙfÓT¼äû<û˜}!gÆÁ¥¬…X Wϲlq*¿ˆé©°MWfüp]ýÕST”i;Çéyù>.¯GxfœÕÛ[$« LTmç¨m–fîîe¬¢¦§P*†tÑ5[=ÑTQ3<“)u k¥ }²ùbâŽ4¯w -E,˜µ´´&¾Þ6º„¢ï¨Í$¹°ÁÜ<ÊÅ|˜oÏLŽ8ßx'%ì-ià_~±úáÚuY߉•ü]<ócÉÞ„Ä:g}ä­A™l=iÜ’Ù›Añþèuúéצ<Û­O˜àmæ5 ÜT… ò‘êÕkjÕ‹IG ¦X%-úú\¶qŸt§D Љ64>–_ÚÒâ[Nlòí3«KRÁp²–Âb]ÌJ—^»6m4×Ë'rÕÏ"d^D›y!!o<¥fN¸È%PZQ¯÷nœ•7Je( æ%.ÜÆÐFœ—Q Ú›v¢î*ï&Q_Ç1éÇ»OµMí÷S]Ðê—âO -,öŠú"Erq‰3×{1NÛZ2ú ©ôeeE?qx -‡N$ÝE¾ã!Nz(Ý}Xn×ü½aב´˜S€¯q=! ÆUwŽÛ-ÁWá‚}Ø\dæ”Qf¨ÛÁsZY THƒ-´/â«Î-k×ÖôïÒÉRZ¤™2ûx°.[ÿªt8HÕ«XE¥2‡U-äbO¶’g×Vs£I5üŒõ¤JÒ´Ù¼ëâ#LAôfvñͳýn™ÖM6H·Þî,ÙŒšípŸBIN"±Š…:2 íÀlÇV=+èw9fš ÷˜±ÁÕ"ÙÛ½ìøù<´ÓÇ™R]Y4B²,LˆéIL ׶—=™ùôÜ3BÍ]²'ÿÔ¨ ’]döŽ -ÝݦDJ)ÙŒáÉ¡fl°«Sa¬c€²cý×Øh}ë –7‘:©„ÑÅeƒ+"Ï ^Œæ?õl^}âï.<œEÖöþÒë’QzM‚iDÓÂÂLTª¬õºÒk=mùP©ú'·UŒ´/€›0òû -ä–“Tf0kˆ¯¨éÞ6¡"¸FÂéq$îDY7Êôµíª‡æ¢_Ä+ùXDLI¨#%ò8ß[”: ¨ËA|’z,¯ -ø¿BówÚ]ŒßxÅ®ª ÙÒš›¼Ï"ÌbYÓ’j=KãðÍ_€FàüÀx•ÓÕ¤'“¶?z˲ˆl®ºn~^ÃÆ/ßc1Òn6i"ø¼å!ÕBuŽÐ#PÁ€ÄÑ£ù±¨óËÏŒPÍVJ8d/¼?­H|ÀDêŸYE|ETÛÐ+MV«ô{8ê§t"'2/<Å“Õû›ÕŽÕ#qX(-an럷?æÞ)¦êÞ…s´ù:™&pRf· nn×c3ò{<ç {î1fJ=‘gq¬qQ’ƒw“¾Ò{+æNkcŠÐ°˜W¬kc+$Ó UÁ#/´®¾òËñfØô}’‡3ðKµù>MÁKÚR‰ûDû­˜ ¼ðM]eËÛuô¯‹ÙŒDÔ6A-Æw¢Á¾êÉöSÛ2•8H¬ó9NS‹²õ"ö• ›ˆhÉôD,,»O&stÃÕZ<1›pxÍ6L½â«c÷Ë섉Λä7ÛǸ{Ò0ÀÍÎ\vÙsùÕw’qò¸%‚‹c4©ŒÆ7ïF#å:¦ÚÐÛ*Ší ò• -rÒÛdê9ñb÷Cæ½óG„á·|9]°Qˆí3ˆ¥8ö•'|2 jK¢´”6¾Y¦·ü–ū؆Mì{"¶¶¤~lú…W²ÌÅ£¥ZI¼ýÇCLTb¼Ø¨ñÉ®-üGOdfEæ—ôk'Ì,³q½Š°ÊšBa›=As_|û¢Õå|šEñ ¦Ùá`uͶ‰:ïp0nÚ”Û+•¥`¯|,_x*¦«;"“T+Bò%Þ}êΈ†õ<õÐMþÙË1Å¢~aEê#0k’Å{¯)QOr­à´¢.ôÄJ¹UâzU_0K‘E³¤ïB=÷eôP–ÃÜÍôC>QR‰øÁÆ“Úå{òë#>Ĥ¯”¤BÄœ“m§EÅÕé³:¸·Â¾ËmŽŠÞ:òpzÝÚ>iŸ÷gc_³wgÓñ¶H|¾âÅèzïÚq÷E)”×[‚¢ñS?ü¦ã4ûÁÀ[<\ÍÕ`ö&“i -Q^ ±ëkB˶ÉÝÏW)´XI6°,}¥¬>Ñ­ -ff|óéæîDÈ[(-’°1MXü’µÌǨæ¹Ð1½æÄCÍ`SN¡‡ÒÅ»ïaÏB±³7,PÄ_ˆ•Žp²Ï‰çó×CG®t¹=6Jøwº‡P×±f×öËÌŸ õò–ÙÍ·¿)—UôÑþN¶Õ2¤C.®;—ÿÔvcƒ‹&çî¼Ð›íø¡¢ ?’!sÛ yvØ·ïœÒÎkYiÌçhbÏ0¾IDê.¶Y_^¤+<@<«Nk¿±eopô³…+¥ºêhC‹0Hó³cŒÆÜHf Õ»uÎTÉ "[1ò™8ÍQ áMBšHiô*ó]ƽ ¨Y©ipá8i­Þñó°žÇª<FßèÍNa¼°ã¹Q[£ðbd Yfwp“—µ©Â·{äBŽT.‡)çN¨5# Ü\8£ ¦oåc—j9^ ÐbYHËoùIà3Ò"¾œ½OÒU›7œëí Ú£xÖ°´ =|MÆË•’ëé÷\Êã®›½›ÊLs (iï*{–2w}À ‚Sq¤”œz¬4XBc°ˆ/­ùšNߧ}‹ÆO"¼¸ò^µ¯Å•m¹•÷h„‰rd,ŒÛà½ûJtF ˆÛÑW¤\ʯ¡q—9-1;Š ’‡Vû·U¢“Äç ½—»ÁD“™A72<öO• ‘6üVCRð³U$· $„Tyl-™üÏ;é4Ðì±ÓÈ„C퉊{ì7–·êë—Ó§è~HË”¼}™+e¦œu1Ïß‘ØU)Ô:·@ïRQuÜ|¯žìÀ·=´6¦òµ”£Iï3VNîôĹÏÃ|)nðËÛ—[®,—èr¶Lß­âØʼnÐ?¾çy1·ãmõé–:”ˆDÈsQuMÀ4‘eÖ*d›K ¿hwŸZÉa…Í“éœcg¸»EXïŠÅ÷‰OÙ#Åî~ý¨bõ*Ú¼W5¤ýXÿ!à%Kìë•(À - a¤)•Y°žeDÿ­ö‡Ú—«~‰ÕofØB8ûzIÅ‹‹—ç"ç6ZŠõæ ï?|ÙÊËûêÞVÓjˆóý ª¾$ù…è¾™A_%ãè -½=7c…ÙG¬èÎ35µmªâÊÉmqZ†\B‘[›¸46ÊÎõÉé1‹äp#T‹ÀY̼†Ü¼²µ8c1@Ìõb$ýZÃ>ËA‡ýÿ Z*9/‹[ qM%ÛZîÔ3Ÿ"Å÷OÙýklT¢HFkmºYüéA3—¾OpkÄ·\;±©ô‰ãìµêOX.š²ÃÙZ|©9K>ø -[L-‘×_ÎlrÉÁ~Õ?·åSç& ‰Å¬}+ž¾†¸WfÊ5na­¸À®ª|êkS=öê[¢8ˆžºÐ(ú°Oæ*ÔØ…ª\LêÊ°_PÄê:‚܆Ÿ0 -o¶d©Wr‘ÓÕ$EŠÚÜÍyÆokjÄÀ”*€Ò¤'ñË']Çåú®8šŸªBžß%[Ž1FôõU~zË7†Ÿ¿Ñ&¤”D·=.Eå°¹úiˆH× |v`—þ /õ«”WÕw°õ‚I ¾ª@+a®ó(©±ãA5¡=y=£­ñxç>USåD»<çÆÍMUÔ›€ÙlE— û†wRŽ{ÞÉíkGo-îçDq±¯R®¾  …ù ¤í€‹p¼ ìoB:04B»Ëß *pº¤¯O*=¾oFäÉ°ïCÀIüŠkú$ÛÆò wLv'1W—8w. -OêX¡gŠÛm9#Êó2Ôq -ÓRLvÏÍŒÆ/Ï7Xy!r8Ë!MÔ4ócK v&½›Ä4á”UO-EyÂTóT­âÑÕì}3Þ5ªV¡H·>”œ³"M*œjnøÏ3°ï|Ú÷×’4²{óÝéL¬!àW”¬Pfœ«ÙýFGó¼Õ‰}j™j컓íRÜAñÓ5Ý«rà)vw º'-¢ßGrËpnvÙ1AÛõ ·ºó\1sNñ&b®]?Mr)smWÅ€ÑûäÌ uQØÉ«N•ä"l•âaLGEí,¯Â·[Á×ì<2±?®¸k´.5ó÷Õ–»ïĉìðOµ2¹ŠqBÂ/1¡3oÌò¬²P¢t?r>qŒ>Øçg(Ò6#ï0õLy¯Gûaš”GêÓ`ì>!úáJ(µ°îÿ,FØ™@xæWÙÔF,7tDƒ—st¡•= ¬'Ïèê©SÅp}K%Áîx\5DGËM®LT¡Cà¿H¦:ØF¯ßÛx‹:ÂukÆÂu“K›` ;üxÐŽ»Z -aàùÚîjäßÜš¨SÞ‚{ÈTvø…ùî)x“›”Vˆc†šçùÁüÿÿO@V08ÔÙ -æˆù_Â:ÐEendstream -endobj -970 0 obj << -/Type /Font -/Subtype /Type1 -/Encoding 1921 0 R -/FirstChar 35 -/LastChar 122 -/Widths 1927 0 R -/BaseFont /NZFEJI+NimbusMonL-BoldObli -/FontDescriptor 968 0 R ->> endobj -968 0 obj << -/Ascent 624 -/CapHeight 552 -/Descent -126 -/FontName /NZFEJI+NimbusMonL-BoldObli -/ItalicAngle -12 -/StemV 103 -/XHeight 439 -/FontBBox [-61 -278 840 871] -/Flags 4 -/CharSet (/numbersign/hyphen/period/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/r/s/t/u/v/w/y/z) -/FontFile 969 0 R ->> endobj -1927 0 obj -[600 0 0 0 0 0 0 0 0 0 600 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 0 600 600 ] -endobj -961 0 obj << -/Length1 1630 -/Length2 10420 -/Length3 532 -/Length 11286 -/Filter /FlateDecode ->> -stream -xÚíteTœí’-î\›à.ÁÝÜ]h ‘Æww—à.!$@ð Á=¸[p· Á!—|ßœ9³Î_3ç×]·×z{½Oíª]UÏ®·è¨Õ4Ù$-ÍArŽ(;§@ì`îæªìQbÓY»©šÛƒ//´ ;Bd€P@d Y¸¹\‚‚‚htiG'/°µ À¨­¡ËÄÂÂúOË€¹×?—HW°5@ÿòâ²wtrA /ÿã@Mµ¬Àö €´ªš¾¼Ê[ã[mÀ[ä´¨¹½´bP[€ ® &€•£ ÀþïÀÂb þÓš+û —¤+puY€_Â@ž §?+À äâvu}y€]Ö.@ôå Ž0ÄÂÞÍòO/v+Ç¿ -rrq|ñpxÁ^ÈÔ]¡®.`'(à%«šŒÜßuBm€Ð?¹]Á/0ÀÑêÅÓÒÑÂíOKa/4/(†¸  OèŸ\æ €%ØÕÉèõ’û…ÌÉüWn®`ˆõ?+`¸€¬.–ö Wךî?·óÏ>ÿ¥{ ““½×_ÑŽyýg `¨+ÈÞŠ‹û%§ô%·5‚ÆñgXä!VŽ.οí–nNÿÀÜA.]㟙az)hé±÷X‚¬Ð8T¡/)Œÿ3•Ùÿ}"ÿ$þ·üo‘÷'î¿jô_>âÿí÷ü¯Ôrnöö*@‡—ø{É^¶Œ#@ ðgÏØ]v³èÿ -:€í½þ›ÀuÔý]ìðý+,¾\Š$ÄúE6.nvοÍ`W9°'ÈR µ°Xí_îì/»6Ääb†€^´ýëZ_‚89ÿÓ²[ØAþˆÀû7‚Xþkù/rýU<‡¦–š†”Ë·aÿòT{™¨–—ðit•-ÿóð‡GJÊÑàÃÆÇ`ã~Ãàççpqùý7ÿ¢áúçYu{ 9Ù99¹/ÿÿxþy2þYˆ…£åŸÉÑ„!–/ÃöŸ†?°…›‹Ë‹Æ}ÿ/Mÿãü×؃@ž ´Å9G áPÛŒìLh Q~ÿwÃîN.øþ0§ò:­’¢À*ÇŽ€ŒÈuÁJ³Çê0öú1¡ç¯^³‡NOÛ -Ì;ƒ„ö é ÓBr?¦®"ÜUúV~–`“rÌÌ#ÝXŸ³¥5>Nïê&eHc­o\PÎn˜iÜ‹ñi¯°ü-Þ×&´áÔÃàÕѧìß\3ô ô÷uœ#vm“±ä% Ò »#`ÒÇ:瑉hWúD±lÁ}Ù¡ŠïJÎçâYÊÝ¥…ŽeÌ|,PwÐÖºàóoËóÍQä‡/Kk×ØC)3ù•kKКM,y]íÝ»IWàCn‹ÿ³ÑžŸEbg¬BY¶â EœÞïýoÕÍ%¢_¹ p¿ž²Ÿ¬?BûZ·bŒ“ˆ·d*RˆÈÕÝÆø÷@÷¯¾òðgŸoÒÙÌ2ô!í¤ Øô‡~‰±ùÁpÕ}ØK³ ç¸ûC׫F%=ʾü+Þxè7§Á½€Ö4šçBé÷e©mÔ×q¨%Ù®ñF¥Ëª/4DÀxá‹dÍÛÌss¡¢¬Ù¯?¼eh%Z+r•ØÖ•,s„Q|p\6“¦«Óò·—]=¦LéB˜®ê*‡ð^á„H¢[„%)ÔhÓλÿÔnýBõ¥Ãë8yÆŽTf@F.õ5Ó¶UWbË‘Ã`î“” ‚²Ã2š&·äåêÜ+V ¢,éx”©›ÝmUØ#ÖâI±j†ð¤/]^{˽èभˢzÝŸóS¨ˆ—=¨¯ÆùN0¨®×|ï¢oäB¸F¿æÞŒþn"·3wBaÀBp®6à½ð´á›X¢1mS¯–G–èf9 et­çÞ®‹œÈCöê(1árkÝØ‹úÍâûR9/O RŸÉ/Œ®[–K‹†)5;ô‡Q¯ ¬puâi—╉Xüø’›öùÓvö®Ax-ÈEʸÄÜóãÍûÓûñ»úÅyR(qr4<³ÎJw9™Ш¥=Yì«ÂÎä÷~0fY²ÒãNªDí]÷qvqª%%›•ZLl4Ë’‹F|viˆbt0©á=e¨_h.eJÔ¦·a)PýYó‡Ýz›w„&ºÑÚàÖÂËØX©¯àÏ -µå7„ùŸ{D/kÅ:NŠº3©1fæÁª®ÖÌ>›ˆ0œÊ-~ýdžR¨X<™6Ú4’ÑzVÆ„öO”ðµaÕ= åƒd!?Õ–¦.OB)»OÞ8:eõ4 ±ÎÌYÉzM—I[Øù\ó‰i·Ó¯‡‚¶j×ÍX‰õ­æáBJ÷[ØE¾RS×ß½c&È1Om +bi¬NÈŸ -"¿ ¹V6Õ›dJ VOÆýräªÕpê9£åLV±Bï÷Õ&JÀà»<ëÈdRs΄5Ãc6âšþ=ó×½Ó#|õ‰2Ìu÷Ñà 7$tD;³Ì/>ä…¦+²Ø˜±%œýD@X;…1OžK(„ØfAH̦Ê"m… `²­èF5óRX¯.èÝÀ1_|qãŸ2 -òâ¸ÚqÍ\ó°aTúËî3ìlŸBØ0UmËç:<¢Lµp. «ŒHa>7÷ ¡$é$aLŽW*æ—ôZÇÝඔ‚ªÖß.«UŸHeYê¦äñ 4’5¡ö|Ž¥ò ïm´ÑË­çŠß“Trו?äÖÏä‹wJf–h÷3»7P¸bF»`œ/[ŸLÏ>¿¦td#ø5‡ÍPÝ®gÊ |Ô«ÕCY…#4WÚ*€¿0Z^oÖ,F±ãƒiôŽ¬÷“Ön4 ‘EMI;h!ŸQ5r²©äÂÏ †uVrŒyq ò…f~IØA¼þ8«+ö}¤&ØõÃu"ažyº-¡Íß*à ɹü#Líj)¸|›t¿Wu‹ü4°s!MRmYŒ5 0ÉWýŽƒýÝGiÅGÝD¥å²VŽ>5ºöæw&‚ß3F\Ü~'²Ý»µIËO™ù™õ¯âÑG÷4•ÌËX¥+© ¬ŠD¾I_åhkˆÀ/ÀŠr2ûHïíæ÷¹Õè9D¾ÏÔK1Íœõ.ÂÖf:¥©_ˆú™4LT™M7(¥o3iså—ò»ºö½_ÚC'¿{drmcN~µG§;ÝÚq´ ÓCLs:l ‚DFLS¤ÁrÚ'»HíÚGtH”ÁòaÀÉ©ZʼÎ÷h96åË—¤õÆ3ψ%6Ëpx¢OÚe.OSåÐœ©<³Œ)˾ F‹´®7}Ë”#)_Z¥¢Ê -7ÂÃD R ‚¿è±¡~HYÑ+RÝ,=Ä-*Òÿ‚´-°?MVC˜$™œiĵ5˜Ãù–…Z¶a8W‘OYE«Pj5úïNhŸüˆ×KÈÜœƒ[—ÝËŒÇÓ]ûʲj¿æ2^*î_5—ð߸-Ýg…û®Æ¢…û#¢žö¿ô¾¹ë0ÖÌò·h'‡Œ²Æ2—ñeMÔ´!ƒ-ËŸŒ`Êz"ýÑ`¼ŒøñÉUÅæï~Q¨’:Ü&1:Äú7'â/é|ªÖOÅ¨Ô ,‚ Qp˜¥ÒÝ5Çþ0-jŠ×Ñf‘ –šã#ƒ®fZBÕdeWYÉQ”y1°Ãgè¼*Ýy‹…ñP¹MIm]V¥‰Œ„=¸2Jc_ÞY¼itP³¬æC´KcƒHÕZ~¸=›þœ F‚Y}üR>ôa&Úø è=-—þé:êèžXA<¤k­ÍûÛÖT@"7§½Ù2†;™áRÓŸºº3û;ÓׄÎøR®¼ ¨ò;ûçVó€(§Ío –·ˆ8oMÅktöEáú‹Œ+6ì‹‚çØ{=ðEº8~꓾#‘šhl­,>õ]i^_ÇçDÁ Qê&ó¾~¸ÁkÚûïßš£BGIÁѧ´Äóé]•¬ÞOà#>+#¼‹¼ÞV·Q 9ßi¡öò}ø¨‰yF0ýäüÁä5ÇE†ˆø=V¢l%œ‚¥4è5f·ÖBОJÅÆÄ´WòÜŠVöÆêC«Wº§ê"MÞƒ@0ih”´í2ÿçE|d‘ó>s™×Æ,QáËŪ±qJr=­¡ïn<µ Å0ë’3²ë¶ª¶Þ4˜2cæ8›n½R^1][­#ÜÁZ* E#1 -eÕÔ×Ì:8}L¸Õ÷aÈN˜üŠûÔªÌéjb¾ú©;¯ ·»ñÐA¨1ÆE“¦{øc”’³l -¶§£âŠîZ<3ýrãrö, ˜ú¡ü´sÛ£¦üÇçt™-’,ÊÁš2šv^I4{|ãfg£!Æ-’ßÏ -l ,vßgª[™GV©SÓÄu rbðW„_±}\7Œ]Kö ÜÏŸŸ=8RÄC&)Ãù13S³à™ÜˆzÖó &Ü{ Òâ®;›{ºw/L=®¹>Îi%Â+06wIœ¢¸/óÆ1qx≓–^½Û‚ŸVæø aF©kH£ ¸p”6œB¨EAb¶¼4ƒ"Ògå#ß–ß]ßÙ¬’ÛžâÀÓÇQ´ÝKçãëA”œ˜jô¾ð‚p ?Ѓú'[yõ |#—Qb9rȾÃFNw®Å^™Ý~¹6”Ô™ÓEŠïábä߬í#Áæ#ÚWŒ¯*È•:ëè$4×hÔË×öÂnD¹ïÜšÇS×¢FD¸}¸ÐXëÏI¢U1Øθ3o8ú8J)u£e<Ô…Þóh|¬"=–gfíÎ1 `[u˜ÅQAØÇyïóÎp%oZ’øqa’…aÜýËC5¿‘ˆó^ÐŒ -ûôÐÓ]2Žá×ðÂŽk•|½Ç7X>럾·Ù(´Í¾o÷ŸÔÌJmˆ•oXGUç²7w&¿#7¶Ù>E"]$H&íÍĦ^û0„“•¶}™–ŠŽÓQ¬W7ó,žWïG²ó©O]k®<ž‰Ý™mH¾ uÉ%—œ)09ÅÁŠ§ŸÚšaQºÍ³~aµÝ°ó¨cw˜[K¦;ÿ -ê(O“ùRtS63ZÞ0CFv߲ͳZ -|C·r®ÿµ?Øô¼©F¨$ @¯ÍrjB/áH $=@"¿ƒ£ÓžíW'$êp+}“'!€ëeGUú!‹cI„Œ‚Ì‘JE#‹ï~üª_ò‘#’‡Ž‚æ\ÖèÍòîDñLîôx@ÚPqÈ&É@ýê4‘UªÏ0+ œeˆ×”¨ê÷]ïÔ¬ÎþÍÚ¶ûÜÂû)V¡²çOs凜åEj¨KØô„Ãzã¥ÈÖt3zÀZÁJË<ü›tBlš´7Éw1ÑD;ÓàWb´ÆhfX8h-´Ö6´kێג™ð±0vÐÕ8$Œgt¬Âzä"nÙ+¬FZ»ÏÛ ýP‚ïŽl”zß19„DkrrЈ0ÖnœËâ{ÔäÎuõu ƒÂ2éV¶KŒ -€ñLœ #Ž|DøÓú$LP÷f(.€RC¿7é@ -ÿ³±Ž“ˆ¸*„e³VtØø®Ï`Áz)£`j|S’»§²×¨?È4·¼-ó5W¾”8˜ ‰¨WÑ÷Òh òµÈ~à&JYÈ)0­ê¶D©:Ç4Á¬Ãšž“<Á$ ŽFô!uæýÔK~Smò¡z­2 ;zëJŠfÕiu°„j–ó¼ÍÏ}ÃGL0tW’e³Þ‚å»0\èœCå™xà¶}½©âV<=Xeys¯”òLV²º3#†–¡ØNs‡Nɶ¢»H*åÀ›õ³?òБ´¥Ôo0͉L ´ 0[„SS÷Ñz}k ,œOÅffáL¤ßzMÞõ‹® Q½ [ßy]£=ÇÒÔ„‰ÈPmC v¬M£F ½\áÃÎ ³‘“½›I¹Fålºs=˜•ø¨ žÕêiêÀádùY‹z±¸úž)fë’\ä14؛8æÖÑ–áB½d*ãó¬¿ÎNô®¦sËÖG–.‰£qÕÄErÓõxš1'6á2ì<›¼”gÔ*ÚP~’l¥ð±Ö 3gØr"¶*¦Ë÷Õ+ YŽ(ÓJ aûM±)ø7qùkâá•ÞŠº †µd ÷çíÌ«K^Gˆ¶J0 ‘d_áZ¨¿¢<“ÄeB¡xR¹¢¾Mœ^™Y²é)âÛ¶iÀ¿PòÅÜ¢¸‰j2ªñ¤Äœ³…nÎjÖá+Ÿ±U‹L(9 ¶ä,ÔYóÜøµÚ6ò:Æ>{Wµã1¡ò:›ýÚßípõ“DùËDÐ2V†Iq0³’Œ™}&Ïéz/–¤‰—¥¬cžÐÑ‹Å3?5¸œ´º¸ë§8ËÑs|#øq"‹åìüv÷U4Ç7%úÜÄäçÑõÕÓßÒ“³¬OèÚ-f53¨™côçìcJªÊêƒÍj[…2œC¢gŠ+§•tùÇÁŒ*°y¨AÇiÎ(JmßRÔÉtýmk¿0²n¿.UU;î質ÅÈV--q!½ôñžL MÖ³<·@[êÑaÃËBÔṆï[W¡tÌp§¨ýp 2<¾Kì-r ±ü7>ogoÝ ëO?V'ÖäôÃ7üÀ f*,ÃýÙ ê©¢eáV§#SšˆNÒ[ÚæóÛ"zʯÁ7ñ„—çÜÓw‡ñ!~h~Röb®ùÆH÷¶øV"ûàù\AÕ½Bl¤‡•-€gèƒSõ'¦Çñj“(ýŮ,gë4Zh’¨„à:“~9Ðëæû -ÉÈصM"-!J$Th ¸þ`1/ù†ñ\âîô­ÜTQ‡ÐŒÈ[ÖNåÝW…ˆãíñò Φ·9íïCÆ?öaô|ºé´Ó2gz µÚ|펋0T§ÃLÒº2ÖËàÃÍÄEßþ:–@A,™Š`k­û úm«§”G6Š+Š9gÃÀº‚r~I÷Où­è·DÊ¢[ {­‚¯´rÁ\CPÉ#†|m\¶}äh;¢µ…ÿ´fB­Ã0=­7ÍRô‡/œÀÐÀÝÔk¢1fR´^¤ÛºÙCñ®Çäß>0c(¤‚e(Ö.×ÈîJêùô -Q9!™¨‘™y0‹½zÞ½iº˜^Ì /D—Ó|eæèù>JB»!|A¿,S`&ǽï.÷L5ü±ï÷÷ˆCX æçÞŽ¬ å©aÜó‡Û /}WRèŠ"µ±gÚѾ­øÿ;.¾‹œ2Q‹)3–+À#'[¼„ì×jéXÜö¤êáEIkÀò YBUµ<ÀòÝÉÛ‹QË¢Ÿ¹Ù¨ƒ-*›žP¹KG}Ãýºm<þ@h9á¹5+3WgÁ¸g×TÅÓ_¦P ¿PØG’ž³>QîFÛ_DþÇÎP\òýò¶Þúº2ª‚á\¸+WÝÚtBVÂv±7×â«5ÒnáL ªùµGˆ´³¾i•ñ™p&û¬Ý†˜"§©NÝ›Mu}äφð<þúˆÜ¡ì«–¦É•dRþ*D²WÒ~ïözjq¡6Än¿ç,àíd#%üîç& Vç xœRðÕJ²,v~ó½="„))™ëÞ•‘-rt£gc®Áy7˜œn»’ՃĪwhN—&um6 njþ¬$)ˆ’f‚ÏF¤”d/¨4Ч2ábukÙL%‘v¼} eAhÎê{µD(”ª˜[Gݯö> ‹¤LI’MFÖí‘ðÉAëU”¤Šz9EóÖk1"ŸNM¦ÄÈÊOÙ5ÞzKYRC,Õ`Ž¢ÊSt:Ãd1Iuu“bWê×7ØßâRÕi)‘«H”ïŽù±ÒV½QÏšÒŽ%Æ“©Ö›.ªOr½ÐvéŽZÑfá])Ù?ÓzúÆä`ËÊÚÀB»ìÝNr¿ÿ ^˃ô»‹s™!"ë¢ýpWD©åYËò¬ZÆÍû 蜯 ÌrC™9OÇÖ©u¼M¦¢Q3vv0OB®ù—ùå”Í/ÐivÏÞZÀAIW„· é•ëžÜVÚ8q` Œ•¼:œz”Hn5 Ts)Ÿä t‡«·ŒÖàÊ>»Î¬‚ìŒPFùÖ„£?Îg¬šV+±¼ I›réh¢²þNâkíVHD‚ƒÓq§¡vey6’6³Õ>¼ò&f’Ù¯Þs¸µqž÷Æ<ÍÞ¡åFÂ'lÓjÃDšË ׋†™p‹Î‚ÉLbÐs*}L 6÷=AÄž+0 L^þrøV“¨XÌ“/(° Î8UBÝ‘~úóü+~‰"•jñ¯®îoÙR( jˆ‚ò.©)Å=^•aæ°›%“DBQ =#ÍéBt[­r¡ [&e‡œ 9¢¤¦ÐƒcàΛug%¯ÜæpLyTÆIX‘š£,Prb«îSàúæ„ÄZôâÕ·e\Ýt$võª¢[aZJtã!å(WcÇb†ŸyÓ(´¤4‘éÍ£ôe m'ÂWÃωPq¸ýßrÄ»÷qŽU‘²jjÓÄv‘AÈV’ÒœœsöSšXŒÚ#‹~[*LýDºûY>à†ÌK’³¹i-úá‹chåõç!ØÝ©ú«Î¶g“°:Ï2|pÄÆCׄ÷¥/šlBÿã©Ò›àÌâ7¡¿J¢Z ¡}ðÍãrçH†ÎFTõT˜<Í>Dä÷Ï19="ÒíFØCc´nlS “#‹&›Sô7ËÚ¶¦žO™èªÜsqƒµË×0>_u¿MTyÀsylîdI J•¶1Ãy÷þ¢áĸ¸á™{mÕ´ÅT±š“´÷ÞGïÁ±ÄÏ‘ÌZ ­P‘ªM ÿ#~ç¬õªOp ÀíÈ„ŠŒ0aËãÏWK†'‚äwè¼cèª=äÊPð5×€êþ@%`pCo N^³9)üÎ\›Iž·“S«ÁßR‘-‰ñÞ° YŠ §ã6'0#è–±”Ô›¤H«Ì¹½ì kIKRå‚iìÍQ¦Ù Óp]Ë¿µ“”Tû¢ —­~š…¢«îlô~â†õàØü-³er@ÜYŒÖäžîj«ýT"ŠÒãÛ¨×KÜð%ì_í[~«¶¬ƒxRåøž&'q.kýØ®ƒ”ÞÑ‘ccšÀs1\ÖEÔõŠbº<&zò¹d£}‘l—¾¢@ ¢¯uR$î-±ÌM3ñÆö΋ÇV"¸3<›6@2dm¨YežqT÷5¢2ÝA?ÒîYÎ7 ½C ”BU*uE9VA~w¢}½Y¬Ÿ#•pþ$¡-È6;ÐL Ÿ¼û»Õ…ƒõôí°zÝûgžgbAúi«á´ÅˆnÚbH›+À Ç§$X?å£ìW‹!j¬8ô3lËhß7§ÍUÔlîès5Ã¥i‹H'Î^á¦_|Zžo í l:ÕyjÔσ{]ñäS¼ d2B”ÞHg~´ê#n‡Ö7Æ -ñ,(Zà …G!½½,‹8yKæ;~ã)_Çzá8´‹öÑÊXÐ/â&_5º(Ƀ|s5š)ˆÒá+>úÏ°c²±lj×ú²ˆ%¯ñQ eÃü²†‚w¾ÙÁÜUú7|Þ–ýö‹ç4Ï‘³·¾hB²’Œh'à¨]NåD¡·T±TÎ$nñõ½Cm¼:1 S’•ÄéEÔ¨“¯Q/nHbç A( ¯öÌ'rÀ/V±¼.p:F‹ Ö“»aûÏÕwïl0yß]Žˆ”.z2“ÖŸ~ÝÊü”— ³z^¢ä&Ÿ›ÚÕ_BXÌ].ùÞ,y4DñÓY=õN[“ou1~KM“éýeülÝQЃ$¾®QJÖ\â3¢¼ÛÚ7²_ÞU2æ°(²89j¢è‘X(ÍàRêôâ&*ÔÞ—«ÿ½—R„Kó(P -ïÝåJÂYsD,~ ‹j%ûÏ.Ÿ(gªbç7ú[([7™>"Ä«1íKIkJ°rÚ(t~¨,{|†xáïÒ…CWá §­›ƒpK¾}AµþÖoX4šÝØœÙ5)köa³ŠGöfeÌƦ¦»#%ÝÅM'zŠX³¸·®ËÂV‹ïÞ,]0.Ùìëî9¡ß‡'¼Ó+}ÅNw§s»çoXçð:¥r•Çu’Ÿ¨óUºÊ‡˜BsûîsŽ1ðô]¸ÑÊágE>èé6±: ËÖªbCÀÙ‘Pý\rËÿñfóªÙL[1Ë@í×õˆL -Æý¾> X¿ ãŒ0ÛÙêpµ~è~ñnrÆÀf·*zW–Wµ8ÁˆåX“7`i vXìq|¹*ÚÓÝ;É} …ºÛKå×B@ÅSCÂHØjIúœº3NøÎOm‡êuHÎ&¯õHì{ÃNIv-%ó2þb*BÁÁˆµ.Ú¿ÉË(-0ÆÃ.™ bÉJßÒú×קínjiF^Aƒ½x”®8¤á- …Ž! `ܯ¥ LÑËëû.íS@&Ÿ$ 1~G„¡é!nó[‡:sHæÏÄzŠê÷ ÜPÒõöoaÇ"Û£]¡{;XÎ Fb úzÛçŽw¯ëö‚ôƒ ¹’Ey­ -v{Â~[ Y퉷kë[ÊF.Ëë®R2:|µ&˶ ù&~t±³íšá–kAYÆ-Ò’Qíç^Ü—³AÆPR˜R†ŸAÅ%®’+Âã9ÔR´¹«{  Ó’!ŒUW2i÷ø¹ó› oO7BÁ._«¬ëyŠ D(aá]k~®u– ®Ý‘»ÌF%ïýÐ×ÙÐdf»qÅ£ˆ=#ã j)Š¸)…ào}Ú|(¤»ó$5÷)ê:×eÝ–\KÒ|ý`S';ZU©ÜóÑâs—5žm¤_|à»Ïö˜iJTR#ŠéFeðnH©á$uv•Íž"¢òÌŽà–' ýÛ³&B#çS5ïg#Ö´¤ñÖñ?œ a™C ‚a?|¸ügz|8xÉãÅ1Ž2,ëÐœ^ˆeQ–ÂDi«ÿªè¬0½¿8ÿ÷„ ÃD‡Ž-…6Lj@t}…xO{=œéª3ñSÒ¿€u÷Õ4¼”UÆÓ'¾zlaË®ÃàvÙŠ`GÒœW^Ã#"©´5ëSèË$ÝÌ9ôÁéžpß~dêúý0Þ‚}$d_ÆJÙ˲Ën -Ÿü._¯ 7#°  ôcö›ÐB¥×¢ fÜÈ =°ŽÏÚÜÙê?½zêý0íCÊ‘!´æûtÍç«1žu?K+.®o–/þRi†-zSÇ6ÊüdrhŽtFš(eL³‚/umDðN”Vï}º3,RÖŽXí;m?´oZ92íã“Á‚?†}æ]*ý|ðÊI¡¯W•’­Ké6¤,È5ßsx˜ ™ßV$$öøu"ÛºîŒw£¸Ôf ÚÏëö-´*MŒ¹Ÿtù Þ÷š^þò9CËt¼Ìþp€ŠÚ}{¯Ò¶>ÍëýH/[óÕFI=`k9!«n¨«Š.ôÊ$s(­y4ùrðÙâV€ªáÝ·Šm.ÛŠ}Ö/¸°•åoâä£h!ðv\wþó.¡}Ó‘R#îÌÝjœeÚ5¦.)þ0—Œ¥SMœgcE²MÑ¡ç÷Öb3Ší±ªì§Eºý3¼8ÝFа)hÜ”äŒ=¸—"ëë]l䳃!Zj»©n<%Lèl›œÿËÚÿ'ø‚ÀÂt::]ìÐþ«Ë–xendstream -endobj -962 0 obj << -/Type /Font -/Subtype /Type1 -/Encoding 1921 0 R -/FirstChar 34 -/LastChar 122 -/Widths 1928 0 R -/BaseFont /STPRBR+NimbusMonL-ReguObli -/FontDescriptor 960 0 R ->> endobj -960 0 obj << -/Ascent 625 -/CapHeight 557 -/Descent -147 -/FontName /STPRBR+NimbusMonL-ReguObli -/ItalicAngle -12 -/StemV 43 -/XHeight 426 -/FontBBox [-61 -237 774 811] -/Flags 4 -/CharSet (/quotedbl/numbersign/parenleft/parenright/plus/hyphen/period/colon/B/C/D/F/N/O/R/T/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z) -/FontFile 961 0 R ->> endobj -1928 0 obj -[600 600 0 0 0 0 600 600 0 600 0 600 600 0 0 0 0 0 0 0 0 0 0 0 600 0 0 0 0 0 0 0 600 600 600 0 600 0 0 0 0 0 0 0 600 600 0 0 600 0 600 0 0 0 0 0 0 600 0 600 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ] -endobj -884 0 obj << -/Length1 1606 -/Length2 16237 -/Length3 532 -/Length 17113 -/Filter /FlateDecode ->> -stream -xÚ¬¶ct§_Ó%œ¤cÛøŶmÛ¶mÛ¶Ží¤£N:¶mÛvòöÿ¾gæ™u¿óiæùp­uª:»vÕ®sÖ!%TP¦4±72³·s¡e¤càÈYÚ¹:ËÚÛÉÐ -ÙÛ˜þY¡II…L ],ííD ]L¹ê¦&Sc€‘““š lïàédiná PUR§¤¦¦ù/Ë?!#Ïÿéù»ÓÙÒÜ@ö÷ÇÍÔÆÞÁÖÔÎå/ÄÿõFeSS€‹…)ÀÌÒÆ ,¯ ))' —Sˆ›Ú™:Ú\l,2–ƦvΦ”3{'€Í¿c{;ËJs¦û‹%è 08;˜[þÝfêalêð‹à`êdkéìü÷`é 0w2´sùÛ{€¥±«É?þÚÍìÿEÈÁÉþo„í_ß_0{ggc'KÀ߬ -"bÿæébaèòOngË¿n€½ÙßH{c×Jú—ï/Ì_¯‹¡¥3ÀÅÔÃåŸ\F¦KgCÏ¿¹ÿ‚98Yþ‹†«³¥ù1 8™š:™Ø˜:;ÿ…ù‹ýOwþ«NÀÿV½¡ƒƒç¿vÛÿ+êq°tq6µ1£ƒfdú›ÓØåonsK;húEÒÎÌÀÈðo»‰«Ãÿô¹™:ý«AÿÌ å_†&öv6žS3hz9{—¿)ÿw*Óý÷‰üß ñ‹Àÿ-òþ¿‰ûŸýo‡øÿõ<ÿ'´˜«œ¡íßø÷ø{ÃØdÿÜ1ÿ¿XC[KÏÿCôª›þ›áÿ DÒÅðoíÌÿJÁ@Çðo£¥³˜¥‡©‰‚¥‹±ÀÌÐæoþeWµ31u²±´3ý«å¿Ú ed`øŸŠ…¥±µÝ?Mgý·ËÔÎä?™ÿ•ç_¼éåe´DD¨ÿó6ýW”Â_Õ]T<þûuÈÚ›ü¯Å?BBöoZf-;€ƒÀÁÎèûÈö/ÆÿZ˺8Yz´ÿ–ÌÀø¯ÂÿÇ÷_+Ýÿ€µ3¶7ùgJ”] íLþÖÿ2üã6vurú«ç¿Îúß‚ÿçú_#njêaj ½ºdoÌb•‘éR‘?4!¢Ý÷‡ñÇP¨CY“Jqa@­}FÄg•ÁG](]ó×W»çâ™ÃçÕáÈtòž4Ó«Ÿ¸¾Ä”½…H›dìÔ‡Aôzep™çê1Þ× 2Û Zl j‡»ŠJz¥àxSÌN×Ï”Än…¨$Oð~Æéñh]ˆÍ@ÈõEgçdÉ'ÏOä£ÃCƒ=·`½8ÔyñP¤Ün pdÑŽy8üZªUÞ‘T‹GYc6èç æ=C’èlëŒÜ›UCî¾Ww'òxÊ0ÃöŠC„®ÖN^A½É³°’:÷›ÍÈ~ÞÕt~¢Š'_»Jéã®1#žðzd Ãš-ÕÅJºEÆæöÄ»@÷?Åòì”íB! -IŒ‡1†ýºŽ”ûÌIQ;uP¥°A•åû˜3RD¼­u#AôìîÍä¬N£ƒ)GaÍA«÷qY< ‹#4?CÊœÃ-òÙ¼íV'Ù§óü*íWu| - í:Œ}V -T§:jâV6ðë>z1ZVª=àšì™ÓvÓFÑÐ54½ú!§¶å9A6P0ð®+MG¼bê¢Y‘ßçGaƒæ¶Ë V­c3çY?â!_¸Ù þZkbl¸bnWç¢Ã2ü5ÔQLàÃw ñ¿¥®VçÍ}SˆãÃ󀘡YÒ{§žæ¾òfƒ†/’€môú¤»AËý`˜âa^>Ñ;^™éu]Í;ñ!O>Z6Ú¬?^{êRE¿Xüä¨:.B³ª·uâ*ˆõdÈûwøÔïc>w-ü¦‘)W; ÍGö+±sSí»ÏrœÎßÊ:"9æÈʬñò7Íúd”%17!Ý-.DÊ“Ë®ÆmSûµÛ| Û{Vë2ýE|m²UzTß¿þ¤›Ì¡åPBH['²ùÍeiùwÊ5 -q;w¾æûD"'š0@=÷a#èQÏ÷ ç«î³¿k^G6ÊP ó'9TʤŽ!è§ËéסT;éîŠjè¦~C OÃúHm~Ë.!H!§[8=f÷‹âƒ|Ýt۲Ȁú!"L7wðÍV¦Jq˜œT#pÊw„áËàçýÚ@ZRÏÇ&—~¿w -bÛŸ=ÆMF"PÆ‹C×™‰X1±ÏÔhE 'z˜™òR##¢á݆ӮŸ}ü;\°„ ¢YÕ¸' þ*iêð‡$“9ù#›«1Q°ïäú*¬÷›‰8»xM°s@MT!}>*Ä3—YoÑôxå“Õy^/g¢8cÜů̌d¡å`ó~ÊÆ—êªÌêÔVï˜#J¥DEÉÚ—ØÅ¢-]»îvLó;6÷ñ€ŠÎ!;l‚é•AÔ¨zœjPxye'¼©j]e0_ÛŒÌeªå\´©Éí ¸2å%çþðÊí,UÛ—ÊÌi¹è[S1Ù÷OúyŸ÷Úl˜€|õÈÔÜ’ÍøyØ㢵Æh¨i?IÂŽcW¼¦3,¯0(çße°œšNvÞ1˜£Îü°Bþë3Cp…<.M À¤ò.Ÿ.TÓGI ‡f¡õ2eÝàä¼8jÜàú®A»½Òï.]GÄíW`²=a¹Ÿ9Hæ}Uw†IÙ†&öæNé@Sßø\¨hŸô<Šp”R%á™í®R1ìPxV߃IÀ íÇXtÔÇߣLµµ*ùØ yieF3¢˜Ý~˜,¯ž3A¯í ÐmVée…êMI–èd—ZˆU -AUä]<·õ—™ñÉ*1EQðÎ!A&åÔ@x*aÛ 99¬®ž8H”ó’Pv@^Kµ¥|Fû"gRÖç,KǨÈ%ô±6®eÄÓ•ØÇš Š§Óç ™'¹Óš„$‘óòè‰(aì LG×_u™“¼3”Þ-äX]IÕ - 8"T¾ «¥Ìˬx"-Ô¦[ð=@%ê⨹µAÇ!øÑ=wàûàÄÔ‹î3ížl4íõ¾s3&êš)\l^ÒÌÄšÍQõlëŒoúÞƒ´m9EMé`:Áóñ8ÕÇ7d@8‚f¸Òá` -쟖éÞÆIúcÃ@W—¹;ȯ~j ƒkj§wÁü‘Ï~*žŸR³žª¿d%>Á­g,e± Œæ*û²o®êž´t ÍÏwx^Î$òn2*´5Ï[X™ßþsß -Z€«¬_Žˆ9¶Nž9l Ú:Î\zäÏYÑŽ>}8êÕ:¬ÆJywkPÃíñÖ¸ÛJtÇlɬº‘;H•"@ë]P•½ƒ¼+æ%0)¨–úKÎ3á¯>KAÍHjú…L’Ÿ[ŸÞ KI-?<š ØQAŸ@éÛ™ -be2d5ÚÜÃ%Ìœ&Ø9«a7\Ô¦ï†F#Â#ÂìÑò#f¸E庲¨NÈ<ê¤yÈ(¢õœjŸZ^á&#Ø-•¤§q^Ñ+!d®g¬~3ûužíNO=³“Øý.E²ª%Uâ Ê1Ô¬}+lF†b ~ö°®–V¥Þ;ç£]£ÕKï o-K‡_JO«×ë‡ß|Šk£,¯±Q O|4õh|ñ>d@…ÈÐö}«á«YQ1ó–K€‰Pj£ÐËôéÐw8"%âqJA\f>ÇAÞ‚f+|%‡jU ÏØB¾þ–ÀíÉó½Ä/ÂA$­)^U“~úÀ¥ ÑÏ•²%e3{‡¦.Ê1+³_SL· ẽÑdø$É’»u£9Üh(3¾H¼÷Û×%I¨L›Ö<›õ"E;Ì䱆v&ŽŠ Š¸Äùl•ÙtÓ êWQ–¤Ã‘OÚ㡶ë:°Ì”Þ“®ì‡C·-à™¡©\òÁlËý¢XJ¥!n:"ö0&aô14©zÎV…ÉóÐüF¿ÖpÀƒ¤(»ß°×u$èxððCAdh‚½ Ñw>*ÁÛô£BX£éñMý~VØŒEz Õ±ºRÉ…¢É?qåpGÊe"þÐ'zr&Ô•b&ú<Ši™‚)!¯W“k'ÁkIH§³ ðõêyì$×ø%ë’9p}˜©dQǸ¢ø.éÚ7Ü(akØ=¯Cµ#Qϳçr}<18ƶˆÖÔ&+Jã8‘®Yw-Ô˜âÓ®$ß©†ŸµuCbRâ û§L!œ‡9ŸeJ´í5h·ÀÂÒáV&ËÀ_îÌjÐÊã—o{½Ižøîê5¡¹Zµë8tºœœ_z++ª£â»ÉYÒ3CM5¤œMkh–zyW¹•” I׉„§ÛÆwÛEƽW ÿ¾„|ˆŸÏÉ—É&kë†x¨ ñœÔ0Á¹—go2·?¤¡÷º`†T†€òǾé{ `n¨ÑBÚœUÇ® Žc!\"J÷¹âPÒÂ*Ù{XÄ$ìÛmÏxXWY?غ©\‚;BÜÈy®XÊgn «L_ö¡áu] ¡“|­„r諒/ö!!3Aj/Oi_^b,ÿ2u™ÍUìšãó â+æy”¹j)ðÇ!ýýŸ9=ð ñŸ®™á—ß´ŠYý$¨òœ- -ƒ+”{¾ÊôóóÜ–oãb¿À8ÜJ•‚¡ˆLRåVeË pˬ¦Z9ÂL0˜41üR–&ͳ -àLÿCîCÒê¸wCŠYøqxþ:Üzø65|Yúö ½uYN²Æp¿ ý"SëPy!W8½¤¡ÐWzFµ?¢V¢²ŠËHí’qn1Ux` º(9žì7¿P…óU@U¦6—zÚØÄ8 ë[ûrS#žaÃZ½Ñ¤/(ÀÓEã¦'¸²Oiüü`3Àú¶÷›ˆ÷îú`´Ç#;•,›zaòŽ™ü nNfè‰Ë£<æ”9€uݧt†C„}·T®ºSmrp4ÄÜ!¾re.¾ b”½ÞvÙ•Ó'DÌ##'`~(3Ásíß; _®G•‹¹¶s9ajI)v"£–ƒ‰ÉÃÒÒ7Äú‘õ²9˜äghî\Hªá¸HÚïH&j’‡ûí®ÃtО$;MzzöŒnuoRKÌ} -xa™ëi†µ'°'cÏæ͆ђÃxt }EjR—ᔚöc ’ËÎ(ë‡Ñ#ÔI]†kÑ›(‘…,·:®þ&q{iIÿHR[”ÅO—ÛÒßc,n7!Úhœè”>}yä¥GöЛ¿ŠÑäzõl ³†©Û^ÿ¥¯Î·Ùyø©ø–¸ã\öYŠ{ªm±r'Šü6ä¯áµ1W8·ðaø4ÃÿFE ×{rˆ †!ˆ¿`ÈÌ–ÂDO‡ÂõcÊôÅƼ®=þ÷æ…ãZ8{¹t ¥Cetݽ⣦ÅW(DØÇ/°Î«ZŸ}.0¯z¹V06 öeÊY’Zš¥±õÑŠŠ‡iô%PšÄ¹[ÀW'Ù™¢#ÝŸ›m)4».?uѹ yà2ô-‹Ø^2¦d´t=öª°M³‡çæøÂÒ% 3ç6¹Á0x@xœŸ,M Û™ê$Ì"*7 aý°¿…à0ÜŸç”–¦ˆòôð–ÌHÌ<µ0 Äó:3_´ë⡳ ÜñȃV: ?¸iˆwý)M„ÌþSŒŽ’³CÆßjþIö‡!Ím¹3ëU¾; ËŠV®¤››CÉü×L +ýwåѵ#;©UúR®yÉ/ÌŽ,Wþ–æá3ôÞrÒ$¥élr:Jët ÖÜþ¤é[Þ×4s•á?x+÷HX00SËjöüŽ·6Š†Q¥×ŒàmQrb‚Û w Áb-?‘Ûüú¿sB‹’+î¥äUcàë?Ò'l¨^檻% BïnÄÍ®1ã§Nj3àv½¬êE®Á€¸›ô…ê]‘å®ar¤ÀgÕ1‡ Kë|1&H<>ÓEü$Û€ yëéÓ©œÝ E6¸î¶O{Ϻ¨ u%çE?‚#Ý&DT-`ró)COêߤ÷´âA'ä÷[\hõ:–p")4©×G‡€§ÑeL -Â=ŠÚÅ׉_ó/7——1»—¬û¦£K`«¨àrøY±|Gõ`È=ÃÖápDÏŇ`™ Ý’(ÌZ“ Röâ.¨ñ”“¬Ù’ŒZ  eR:Ž™Ÿñs͉æ„DuaïkÕOSA`«ÑóuÎÝU'VAŸý^RõÂlyÄspèÈ^4ô—Ó$¥?ÝÛõ„$x¼@§åËÇÅÛoÔ$Z\—¬O„Z]È\(‚u™pvI½ç)Fó÷]iÉ~ñ­Ô‘•OyªÚh†˜:¥²'±€393šz€FðÏsä- ›Éj¤Ðk³R%šã3zý‚ú¸‹€S)#š?%€ª3ì¡|Aþ5ÔÕƒ‘û™¬ÿ#ÄêðAf—9¯¶^£Ývª²æ$ñ+úu#œBX)Ñ ›‰ó*]lV_fÐW†.˜©ì(“aÎúã`d`°ñõ&CðÕÑ*7^ß'ò@‰Ҍ¸˜Ä)Dô†?Ãõµ7Ó©¶ÄspcEŸA.¢9mòÏ´…!<Ép‚sdÌͨ´G%}ŒÎÍžŒwŒ'BE’c™…:ÚØTªÔñH+.„©ìd×õU-@V¼½VÌ{'ž«om¶ìGm—ÕEËÉ`·H©ãYâ÷”ZÕˆ$àtÏ꣋7-ݾ€Qfe×Zåûô $br·Üµšaxâ_‡ý=‹\ÉòÔ¥j±¬ ƒv¶vúó{üc -8-y¨u'ö8÷ó\9b€Btï1³‰+/áu?ÌeóBjŸ(³ÂMEAé¬%»…> :þˆù»ù5RÝôTIJú±Æ–-£œûƤEW†bCÜxFÖðh r 8J´ ®è«W¯çaŸÉ !#4ðWª1¦+­>Ûeñ6aLh4Ç5›·^;n¹Îm8¯uQ»DHÅQƒqÊ@Iñ©ªMI± lÿ7ž1ɇ,ªíùl†“=¼ò¯ír‘ã6+ý'‘ÌD.6F¿{hÖsµ%SJ} â⧮„ùmÁ1úž >9Œ.½QäO”u—&LÇ$“ø<䃰¿€[e2-ã‰ñ`„îÜ×2! ÔÂê3t‘ÖËs&—Ù‚TÑÀ•êmN=K×dB ¦b²-Ñ;|T·efJ2FþFße=p†8›@PÐ"?tï÷ëy ëΓ $´?1OûwÅ¥3K":¿Q:gÌ Æ ï¨Û6Vê¶ZÈÕ #Í9‚TGHcz2ý¢ÌÌ3Ǭƒ`:^Ì ³ÃŽ§¸P¯Å|ÂaËÕ:[ZäŸKÅU3ŒÃOL¿c»YÅäg[u¾ž«+‰G-UQ´]TM"EÕ«ºA wÍîÁøÆŽ·A7ýp1Eî‘p:×”:ÉEFt4`{$ö›;«1¥³Õs•ÎÒ»É.·¥bÈð+¨ÓÏ=SNÃñ)=Ñ ZŠžRÒ¹Ig–7<$ýzÔCâB¶Z‘éWñsÒ1;@iI”éAr£è†‚}§½ôç˜õZ4Zñn¹ËÒŒÆJ.‹"« øRÒý#¾œÙ1ôâ.´‰Ì-΋ª|,w ?¥:Àþ:ÈFÁšåÍ¡n8‰hÛ Ã-ÏŠcl/òHÚ;i^&P÷„<˜Cúì*Ðcò—f‡M°ÇÉÙùuqîQ¨žî5ž„%æœ,ùóR‚ ø].ót$‚°HñOh²Â–I)™i’¹$êÖ‘ýáv+ê\9 z0àzã½Ñf(Ìz¾ 1MsmÇ{.ŽÙô %|¡³âÏú¹c¬B‰"F›•Z"ÎQç{“ߊÛiƒY&iÄd 1][¬sÛÕþ§ˆ¥xªWÅÏ‘-ùTû?Àý× R{ÆZFzØ×ʾ{›çl]¿BZ®v­9z©TÄ>öT»¶ëlqF%óð²×æé×üíí¢³!RÑ`$Åæú(%ˆizÔ¦ yLy€«é.%t‡¡Qñß -aÍ×#êT/ãÜp·$3x»f' Óc;‚“ZàCq‹4:-žørf›B!èè‰<2©ÄP¶¿°wFôŽ.¨S:=ØܹDñF-M0î’s% d×AF*öm\;’Q±eÞ Î`e}…±‹÷~7E_œtB††ùÚx¿¦þPPÙZéâ@fðXQ½zËä+òƒ-\íÞ©’*×HDÒ¥*¡ûæµíh0Ÿ_|Ý's~Æ‚R¹ çô³Ðb¸"xW!ìê^ -ÑÁQ|®gšnîòøÃ>_adÿæþ©£ñ!Îò¦_ 'Á™Œž$\­ ÌÓ ÞbHz¹×szrP'ðÌïã];7wÿ]@Ë/c™&ïÑj©ØMËùgº ˆàRŠ*6?áÑÝ?­ jî«ž*ûbúdNOÇÔ°*]LqäˆKgˆŽ`ÿD ØpÛÍÛŽd ~}¶Ã#ŽT—Óì¯Ãˆí)'MÚ÷w¿“WL7DÚ»ê:üÖ£¾ÙÜjœèÉ:ÊAM+ï.y¦ž%^ ¼kÈ>ÆÙ ˜ñœ‚æƒg NAPRâÐ+:É0Ä©)Ù)­‘˜±ß2ooùFU©öUyÌÑMшnt1ÀÝ͈ú€gFYsvm¾Ahž«¤•®?*ÔÖeå ñEZ^svR|ŸiDF>F@Øxfl÷¸ýÀ)¼ÄäVg±û3;šh[Ù[ñ|â»U ë¬[ kx×cU[ôf¹óT ®¹€ŽFØcΉ‚]àÍ]9Q °«z<Âký…]ÜÀ0¸4xtÛ'¿U߶È9ãù±¡vÚ%  ›ë³y~¤$OUˆ*_¼¢­ùe}°ºÎAJ°­÷ɹæ-Ž¾ë™ÆL“†4%ÃOˆâŽÈ_î?vο1Uq£›º©xÙôéîŽ#3qû€Š>*ÛÆöó`þZZ‘³7U1±^Ìâ½Aãƒ~fô. -ª¹¬ÒNª¶¾E”¦PÆæÇ·ùÄÿÑZ׿R6‚|³ª°6wç'Yq'lx&á,fB™hØÐ@;&swW€nõÉz?¶¢‡çªM‡mh3ŽÅ»ñ‰. -ˆ¤ÅúÀÌ^wrËMbvÖºQv¸”ÀÕM€’û•}«9»\û®­µñ¶hý(t =Ð!yØôѼèãL[±I–ºîîfÖ ÷k6«6Ü´‚W· -ú4.Q¶É;X¸%ÝC³‹£w1¹G[è£ëWc/hl·÷­-Ò 2[Ÿï«+Çë9?èAaOc·to1b.y°i¤¾ÛÇ6%/] ä9©_ í1¹ù£APÃzGo‘W?ÐG'.îï,4žKÑ÷%þËÍVB°3»¥d¯>Gß™·¥_Æ™ë ~dM»ÒÝÉ’²Õ(ýcßÒ’þÚ (›w6y»l1úi»Ì¬=ÉúVV%|Ú{ƪó\ðé ´þŠÑ—ºÌ@®< œÔÔ’Õ´õ°û(qŒ]+D_ Usm?î>µÔÀ%w3üºñmõZ›±î9[£àl£GVì|ä×å×Ü,Àf(!½Åô`.A"펆n3ÿ8:Ðîã\ C±v®DW'–ÛA4´+£‰ÑP„ÛEÌÌD%;N^`°@^²N†¡Û3jùcN½¡3$påqF>”dìô É·«7Á Öê{›•ÌöÐQn¶íÓ™¤ÄÊòj®e#—³ýƒ!Ê®ú.WQ…øsîrž,TÁ‚£äÕ#ÂjÛ~1dÚ°ˆšŽ¨ù»–c½!|È× ¶ Éîg(ºîvRO¸ $8OG9ÛêDó¢a;P«oØpŒ$ æã”ÇóIìðB)ð·‹UDOœT×5ö-­(m†÷ÕëîOG“‹b«Æ¬ÆÀPd9•åÛÒ¨±yáÞluÇDÎÌð¸²ß ;ÕyÂ19½)içíö q€ú#ó¸adã|-‘³÷ $ç¹%@»µÒó³gx«ÖŽ¾—©ý$œ.¹gL<§ÍòÕõñ7bƒS¢£éj%;"Á2k)à"ÿx×9=FY‡ŸwjçJ’Rö‹$›¿a,~LoÇôÚ«Ñäå³8Y}òç¢I6EÁÑ«ÿ¨œUX¬ÍÂ\>HnŠNß–YÁ ðV -t /˜~ü;™nCÌ’}8êÂ)(Û8·ñËq]>\=n;‘:NœÞãË2hk]yt5Ï2NŠºœ¹ìI*œšuÚ D.²QQD‹°•6c8r…*Øê Í -ÉJ2kç¤%o72mÝIËKèo5šn$éÒŠY~èp™î/íy\mT§ë4çN²j ÆjKSO}Óé†6Ñ gô]æÉ•\Gu²Ô2%LzI|’µ–ʽ۳:½TÇÔõöãOA©! ·\x,{"ÌF‘Ýwz§ÇY2­Îž•OdçÊúÎ`/â•<Á³Û9ˆÖˆH!‹¾Ó„ˆvŽ–,ÕõMÄ[ñ«Ïõ^‘9¹Õ3Nr‘17'rùJÒ¢î•"bPŒÆ(#é˜ÛSˆËZZƒ•õuÄþà35<¥¥½::ãÞ‡ ®™!‚oš”,~"‚\ÕU¿{’áYAäÌ(q«Í€Šµf­Ágß‘ãÓÅ:%§££ð¨±ræ'ô*" -Sdü=zÔýKò*wEšyŒ“¼+±%]B>äÚ]½»=}ÁbÄ5Üm†5Á';ç5·øŽÙùñUI¥Ùnx5S”«DÃé袧ÎG«•dBG2’{nœ‹U‘æ[ü>9WíÞµ‘³t#Öf 2ñ’ø ›ÏsHæÜfbÏ^KÆo O|òQX>Š Ìà…×oDývΆ¨1 #V„°³\óM-­Vì.ó»u±á#ÝÐ2â!OK°vÈé²û±4wbäίɳ˜Æ5‡+,‹UtZ²ž®Ië8ºg*H·r29ñÃì¼Ã´ùöªõýyˆ?îÅ;'ta\ÖSúÝ óÆ>ôîœåáX½ÌàƳzœR©õªÇ5}Æ ú°DL b´Ũsü5 ¾ÎI­è&,) OB#-z) «ozM¶-:Ÿ mré‹í‚ƒQmIi€¦g´>L9ÿ¤å?èÊ`0ùµGÔJõÅ›Oc7yÏ¿8ÂÀ³#e­À”z¯» (¡ò›MœõðEQèö`‡ÔDftã,;1Ä·*„Z&ë~Ù “˨ÓõIUˆ7ÿ†‰ðyÇ(éûî6+¯sÁ!GH­#EëSÚ²ŠÙ¯,ãѺi§‰G íÄ´AAë·Ršýyy„ÐÚ[^kúZ‰yKî‚®þi 3r¸ØJÃaª²›ØbÃ^}±¢&¼¶¢ÞÎy¼r;|Û:#ÚO$pÒ2Ñ…è¦ãPD‡¯èxü²½oø’‘R`*îšý Î{bÆzœ"üiͱôPr¯!³!¶lº²kÇt÷Vk¨®PÌ<ªÖ9K¢låÿÛ{m&±ûîêyä·Ã³‘xtdâñFwXýdøXî“åOå³9€æÞ~`‘ ¬iJï+ÄSåÜV´‹(E˜Žk²ªuHlsÌ{+ò8Mw–^¸ñÙŸRÌêxf{ -tmQbà¯mq™‹Ó™Ãþ<}~µ[$ ÌE(-$Â÷p¯¦Ãk"†½®"ÂÔÑóM¯r=PUÏ£Œäç(–©N'Ù¦7ÍÌu™é¢Òœkv.È'ôEeü~ʦÌV°‰> -CÎTºMj8IÍEÐ#ë7¥´J™vòÔÛÚ)¡ºÎ,ÐÏ‹ Á“µV¸`Ç—öAÑEì ($¬-,=C÷_"þ1P³ž*?,c9âN™¨ýº:„Þ¤V•áíƒyÏA,ð‰'§n‘IV•fö;68ñ²ìµImüZÂÍ0A—6 &Ö@KY§6î/r¾Ò]ærG¹Eºd«É ~3*T¯­í,ëH€»‘¦žýRT.…}XÁOûÜn̳ÇPÍÿà>É&¦hGâ9žÄ¯ÐpRò…½4ÍHÞœÄk’-ŽÉS‰¶!-ƒ_IŒd3W{2ÅX)D̞π¯òjzV]E9FV¶“O8TÒHIºoADО8¶ž‹3Jì€j­¦ëp\°ÑSJ¾úÈM£wJè«>‹Uâ1ŸìÈIëc pØ’%æú&2,PÝ>™ˆPàR¶ærhÓh±¬ƒb4Yü3+\8=…à ä1óì)Àäk¶Á§`VâWÑCp+ºB#d~/ð·øbe#W›Ÿcs§Rñ$ -ñ¥ØDˆƒ¥™Pþh÷ioi1ÂÿðïîÅíº”a¬M(añêâiùà êÌ‹þîÜ0Æ«ŠÉ,zÃĵ:ûc -‡ÓÕà¦^=µ®ãF–:%)Wmqf`чÃyÜ©˜¯*Ò2|í~ðµÜæf˜wÔªóŽ6‚ê¶SÖÞ¹†öJya×ÀõÏ/4ÐF@÷š#÷ðzè&÷\(‡_zH>/pü’yŒ¸x&KNå< ö~Kr>!â­шÑs„yßrnèe½:‰×<QC”Öß°¡6äŸ>Cù Ü2,^Ö%a1Ò¼äJºÙ=ßH§Ž  Wà¹pß×(yAkâ“×püº%øE)pÕ]ÎÚ"L™~_/'þs¶iSG &0IÉúç[ðôúSMÿlò7µÄOOªMžO öÃèV@Äa®A†‚Meg©Ë°Ù>Êf«e@ëvò§g~lBÖ¶òú»ì`„~€!´Á÷¹gÌ’¥™ß#d¿Ï§4(ÌY,›éF&Ê‘”.]þjFÑ(˜;-QQPFjƒ,qx¢RâÝ'¨ë 6'JsÍV`ñ#°É…Pǽp ס=ÌO§9¯ÒÏSCŠPú#™x1‚ýÍt¡ÀÓÓ™øð`˜Š4¾À2¶Ž×j…ììø9¬–eÛYÈ´©m¶âïx -§[ªhÃàz\^-B }‹,Kþý×nc ]O;EÎÁm±dé¹cxá˜g¸=%T]ãë÷\†ƒ»jïÑÅðdêÅâºì´Z>»M4–‹ÎUìé´wâ; 0eÑ©€©KE*Ѽ—`0‘Êêk6_í „.‹6wVv>OÜ€@w¿‹Ê«ˆüŽnËé(Õä^…õšjóFkƒ^Ù*® cJ#,ÆÆß“Û§FõçÆÅ¢Ê ôó¶‡aÞx’)ïB'ƒ=Z°?éuÊiŽ% 1~fÌ3Aù/A€NÖß  Bl‡wÜB+<{ÔÄŠ €£iÝìG{K¿/è~¶ïõÄøìϥʰq˜X†bÝ>tÇ^hÜBÆ´½¾[â.1óÿb´$&ÄæEU¢láa/ëÔ tï˜Åpç7/îEbØ…> åÅ`YךŸ"3^›r¿ê‰Š;ÚQ€µScÚï|Ö%Æûêæ%ÎÖ@äR›„L19ÒíQa[ˆb}[2"¨œIÍžï š‰MÅîùÐÛ Ïü.ùœ©e‡2yÇœóé(-å5Óü´õö ´6¬±ÃþÚ™D;Ùäþºˆ_4×}‘ZQ%“›½™·]+ŒO‹àZâÃì&äÉ›Ã.²]ÝHŠöç˜ÉuÜPè95ÿ 뢗ÁfDZbŠDl~r’nü%n†MmÂ7áC¢†æ‰‰b Msû¹(ŽãŒ¬--¿ò^Žö垌½ª»1”Ék^-ý•‹Dúft^t,¦£®ud˜'½ã0"©1oQòŠýAÕؽ6$-0,µy±ZdR3cÛ^„OKoÿ(r¯”Šµß‚¢ùe :3ĆԱhº¡³Œº: -¤öΠ"¦ýŽ :B;«ø&&c€'I”…Òn|]ãh¥ƒµ• -%‘åwÕkïvm—wàpÇJ¹¾U œ÷&“³oP1‘\œfr;Š|Y[âéÂn†ö¹ë °¾LTÁ¸Ÿ£d«ãÇ­!5ñ樹õS^¤X#Ûwô¨$c#Õp×RqE.84A•„#ËPÆ4UÄ«SÚíÉ°ª\bÚô„ÑÑ`“ÇH­0åɹr,_QwæÖB“VŸ4 O=“½´†?â;ežÞ¿(‡½ -7©¨—.q `~K± -¯3}â ›ÛÉAj¸*óbŽ$k3VgzØOÜæ*PÛ=Idi)~*0vyÊî©àÝk–.Zsù+žÐ´YÍ„R£÷oÎáA<–ÊКäÞ]˜®žqÙÀœŠ‡é65–¹£e=ÌpŠO0°ÎeÞ ?ŒÅP‰¬¼Ïª1°¬{üê<ñÜ{Çš'÷uFŒÌŃÎ’8\PËHáäçŒRàñŠsŽŽ9ÞFOÎ* SˆºTé&A÷нðÃûn=ŸÑgœƒÔ i–”Ú|÷;–÷3W™µŽ'÷ø®I—¹õ­¾íÏÿˆ!!(šÐ (ì Í^÷H®²€Â#½7§”dËO €š>Äá}¿½8$ 4ûÝJ—ó^wÅý $-Z Ç;¯'ÉÔï{œU¡f -Rs2$Ñ%º‹ë!nß%BÛ»C)uv÷'\ó&6Éu¨ë=Ôä:Æ k‡z½ÌèœýU9S/ƒœþÀϨŠïw1~µ0D6Y+e»øݼF‚z—P÷«údoÀ· “T”,û«ðrJvº™‡ô¦ä‰_q ¸‰¸Oñ>Ëz0å™ð3ü™&UK&g&¥Ä²è÷˜‘[zÄ KR"áš…ÊŽ®è/¶ß~+˜àÔó†pJ§ã•<êw­òöViåhúyufRµÕ–4êåp\W a ‚Ó\—B -':o´ù]9>áÉ¡-Ö™)yãXp<âo_jð½äÂUZ帥þ06_VnO¨nórzcúî×Õ:L“5uþ¨8Ýi÷™¦»‚w®P€RJaa¨êé4 ¯a²¿{LÑ™B”³è\@oE…Ð;çA‰ Èø,È+”qËájŒÂ¹’dV8G³}cÖÀdâæî‚^.ìÍûÚ˜ÿà>*Õk …ÇÄx>2øµ•_&9¯!Æx˜ÙG"¼ï*“¹±ÌÝ»á‰V0D)É¢‚k‹÷ž:å ¯P4û -Œ›?yUGáõcç’£Ä %³¤™š€î°®÷šTYØô DšÉaNEn6Œß“ eoŽ%¤Kß»,cöâNeî idšÓF[í±fáoLò´ž«ïã–$ÆæèébhžÔé]ç}Æ9Å‹°ý~+T‹r]„–Y;·úÐ}eEvtU÷™TR³]OJ¹8Ë…ì×è¹Ën·¿#“£n- #v=MM×IF;Íä˜)v܉«¼£ªÀÓ™m]WO[JfÔwâò ²ª«ŠÜpòƒFc.îÒ¬÷OjGÔ£…W9=ì¶Ä±^µpŠCá§âáÄØ(eOi"3©%ÖsÃÌa«;MSìÇ82¹Jô@(¥6?3>¼r BS&O³ç÷MH 2Èwgƒ§ÕŠ«˜ÜîÕk♕Hp(Í[P›C^ÄY…IÚ‘Xà" ·Íƒó”Øšt×´¯hÏËB#4Z=\´3ÙA½Ëçhc¿@a~8]›/Ì·?Ãad>=0/Àcn,•Å\†ËL0¤ÙðX¤ÍÎV¬"»@½ZµFû%òùÕǺ—´FœXTX¥œ9|ò}Lí;h,¼ODf<ˆš»øÉÊËå˜Ì`/Bw -®V´:cMG  ÏÌR\Y^( [#¶æÉù´*Ž|J¾¿µ°æêÇߎR/ð÷hïšý®dèÍß!HŨ¦µ—`èHÜ Ù•õiÒ¥8Ÿ¢—"ƿ첈ïæÇ`é"¹º’à †Sð’ÞÈÏ–<$¸Îâ‰ã -y#K×2ª®q1g¬›“‘-öæÙú݃ÓIÝFÍ×½Mx°O cׇK2ºëAÆö¹Ì,b šO)Ù˜•䪎ۖÜå×ïLlˆ¨¯Ø: -:^fËër¡ó5‘ª‹ê(foC;a'¥'Ô'pq84«Åq†‚iµ‡„ðŽG~éÚ#>š;\Þî>í?I/;¤ z©Õ -¤¬™·yæN¡ÒÍ=Ñxhwí‡Ð¦-LêÅoR„µ ”3'ÅžŽ7vF£¼êb•r1uºÄ…›Ùaml³§W·áFIöõ»_ìß±#EÂp¯Î\R8úrî ,¸©n²o‰¨¡2V;ëÃrÁÿßþî [gƶé¾ï—OžBË&í)Ü\ù#ûÌÿ7õ|®æov·E|’ïÙ}…I%\ÜrŸø¥ 7K¢ì´v,_Zµ¢e¥ÐŠÒyÛÕíŽ%_ÿœ÷ãyìÍ2#íO¯Ö8_^{ñšÃÿ9ÊçC'±2]ØÓÔyÕáùÍ)Óç©X÷\â~¡æô}Ù’—§Ëøby³Äó{K9ì™ül“íÙtß9³äí2Ë~ŸÏMÖYYzࢄ°TƒÎŸ8ë6‰B9ûdIF†Æ{úáª:OãÊ.,|©–u‰•Énãk“9u³3zX&jîû7WD‹ý î9“fGÝÏòTNo½ª÷À’Ñž3(È'Pôè§b/©ˆóy§?nIËy¶ÚH©îš©ÖšÖæ-×¾$êMS|á*¹áö±k¬«¼+§Yå–óŸ}˜á·ÓÂ;œ¬ëönüÍ¢°iòüêÕþ™6íŸLÂ6/èžµý±æc‰][K8–¾‰KQùiš¾ZnrKb]Ÿ:ß˃ü—ü¬²´o\gl­V“Üèãë]šwó¹KÿM“? ÌÉ{EÝf3Ë…¼×Q©‘éÏÙ¼‚ýCÒR¥Èk_g-äM·´ÊQüµõ­öf -רÀäœÔÄ¢’üÜÄ¢l.Õ#‡endstream -endobj -885 0 obj << -/Type /Font -/Subtype /Type1 -/Encoding 1921 0 R -/FirstChar 34 -/LastChar 125 -/Widths 1929 0 R -/BaseFont /NQLZDD+NimbusMonL-Bold -/FontDescriptor 883 0 R ->> endobj -883 0 obj << -/Ascent 624 -/CapHeight 552 -/Descent -126 -/FontName /NQLZDD+NimbusMonL-Bold -/ItalicAngle 0 -/StemV 101 -/XHeight 439 -/FontBBox [-43 -278 681 871] -/Flags 4 -/CharSet (/quotedbl/numbersign/plus/hyphen/period/slash/zero/one/two/three/five/six/seven/eight/semicolon/equal/A/B/D/E/F/G/H/K/M/N/O/R/S/T/W/Z/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright) -/FontFile 884 0 R ->> endobj -1929 0 obj -[600 600 0 0 0 0 0 0 0 600 0 600 600 600 600 600 600 600 0 600 600 600 600 0 0 600 0 600 0 0 0 600 600 0 600 600 600 600 600 0 0 600 0 600 600 600 0 0 600 600 600 0 0 600 0 0 600 600 0 600 0 0 0 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ] -endobj -878 0 obj << -/Length1 1620 -/Length2 20127 -/Length3 532 -/Length 21036 -/Filter /FlateDecode ->> -stream -xÚ¬ºct¤]·.Ûv*I§cul'[£b§bÛ¶mÛ¶­Ží¤cwý¼ï·÷>cŸóëœý£jÜk^s^×Zë5FQ’)ª0›Ø%ìlA ,ŒÌ<5e ECkkC ;Y)¡5௙’RÔh²°³3y@€Ðð퀅›› jgïîhafPÿå ¡££ÿ/Ë?.#÷ÿ@þF:Y˜Ù¾þ}pZÛÙÛmA)þ¯U€@È0µ°Dµ¤ä%Ô’òjI -ÐñoŠÎFÖÆY c ­`jç°þ÷`lgkbñOkNŒ¹„†'{ ±Åß0 ›1Ðþˆ`t´±prúû °p˜9Ú‚þÎd°°5¶v6ù§€¿vS»dïh÷×Ãæ/ö—LÑÎ ädìhaüͪ(&ñï:A憠r;Yü…v¦=MìŒÿié_Ø_š¿(ÈÐÂÖ ºþÉe˜X8Ù[ºÿÍý—ÌÞÑâ_e8;YØšýWôG ™¡£‰5ÐÉé/Í_î¦ó_}þ—î íí­Ýÿm÷/¯ÿ¬Áä´6eD`ùö7§1èon3 [¦¶Š”­©€…ùßvgûÿÀ\€Žÿõ?{†æo†&v¶Öî )“¼èoJõÿÊŒÿs"ÿHü?"ðÿˆ¼ÿoâþwþ—Cüÿzžÿ;µ„³µµ¼¡ ð_A€ÿ¸c²€. ãÿÍÝÐÆÂÚýÿðß=5€ÿ®RhælmèøßáÓ ÛšýU„›‘ýßV ' 7 ‰¢ÈØ`jhýwVÿ²«Ùš­-l5ý×8 ,ÌÌÿ S5·0¶²ýgøìÿ†€¶&ÿ½ü¿2ý«x¦ïêêš*jtÿû½ú/?Å¿úƒTÝí€ÿ?‰†œÉ.þa±sx2°p2X™Ùÿ»¿›Åûÿñ_D,ÿµ–39Z¸´™™™Y¿ÿãó_+ÝÿF#nklgòÏŽQÚšüÝdÿiø6vvtü«í¿Îýߦÿcý¯íºÖWìŒyƒ,Ó2ÓAu¸¹#SbÚ},#Áö¥ªE~5v½¾ia»Ü•µÁŒM3<¿ÛÝ—Ïí?¥iÆúp¬©zS€×ùDÞ4ýè[_;9鎘ôJ‘Ó/4¢:2Ü{ ÝHH— OÉë…ü5ÒÏ!‡Pð‡Z…xUó«Óö”ê&BÏØ>ŸŸÙ‡PvE‘Ŧ—µ‚ÏÕàO͘ƒá†€l¬„ÔÈW"æþx²À £ŽïIx%Q¼Kâ¦No¿­ùWcwúŸò‚ßÄÎ׊ü;L§V‘;fT° £Ö.ãG¶íúÌÓÎõ=®>ÕÎ7èX¬JÌ[ÃZUýùbªÜîA+_®›xF»Íc¨À( ¥ã©ƒv¸\Å$L Ò…õ)_,Ò ¡Ã4ŒR4r-Ø“©¾ˆ3ø‚2Ž‰Œ€$¿ d-ô~“„}¼Dä9&G9?á¬;Ô6®£ÛB‘œ´Xsÿó/w†ßöèWŸ.S?649ú0|‘ßãš@΀ƒëì˜ç3¾>9È%æú!.à—¼Áô/mH‚Þ¹U'g7¬«T¨y㨒Cº4œÖ)7%Š_0iôGàìáä}²›„ ƒåÔ›xêÙÄ6\/ÓÁ¹Ô¢ÑCnoãÐ5-Ûu. ê24|jþb'U//g7~u®›œ÷äkƒÓ—8•†n¤3€j}_R:âàÎ>)[kÛAP++Ïú;iw9¶»¼ª½ ·c¸A{÷¿Y‰ü j¿3à aÉ»ðSr°Ñœ¨t2ýV å -o(:¨Ñ_‚ä¤ñOFuØI)Q’¬¥®‰Í:T\+kÀ2ñ´Ò(ÏË2+­Ô»Ð]é¾çAM¾×Q­?A"tto¯$ÏÊAœÇÛwÎB¼ã¢ü1lþUxq¨eÝÒäöt¼d"$ÀÇŒ‡™M ,tEÃ2g§ö“0ACª•ƒÇ“IyàbLżê|cÔd€&ó­Ðƒ}7ÆÐJVóJfŒ!`/—ö©Ä~iCB2l´–¼â¸¡Å·Û‘ÜÁøÈÆ - )/úh½0HéZ=`|K›@?ôî3Ob¨cËLádÍíìÉQûcz‹þú7¾cèü¹$ Æ>2Í%—¹ß°%F ->@í£dJî'¾T¨WÝ– ’ÆÑë«úþ®@Zl—,P* ï™7o6x©bäÀ×ZëíùOרc ‰^à°HY¹ê¶]¼„qGÝx- $v·úyüJŠÑ‹lüwÝ„ze|5lÇ¢‰Û&^^Y†¯d¤å¸=眫Ø'ZðþžQ.,°#p¯ü°Éøù¨~j‡|i¯ÖÍ_)¢é<-ëqHb_Ò»S3‚4~«Ò/²Jú -ó»kœAUyÑ® D‰ˆ„’"µpVk_í+t·—$ïÒBhtçß’¼`ª-‘C†Èù}îÒôƒ¡OQN¢¾hÉlÙ‚¦X©ÍÉÃÚ-ðÝ󜚮Ӳå‰f]D–„]fp`ÝLWý£ÄÄEäÑOT¢ÿ«0ûž†zܾòïþ׬M -‘ו‡ošDƒŒ ¾”¹yÙÚ<1Þö÷Š3 -9à Ù÷:Å„Ÿ\ÉFlý¹ŽNÁçµ±½F¥1¢{1I#ù#gÐM!Å&Ð!ùf¸¸<:â‘[Ç‚êÞ—dx²UÃü9‰Åm³{¦¨F®Aº/b›ƒÞŸ&ŽiÊù0ÆÊ<É{ –3Á—)t;¾ -I…ÆÄ8á J’«2ðÚÁF–û†t÷+àK‘D:rtËSα£³ÒFX°Y¿ƒw0¢ºãÎo‰Õ"Ú-P¼L>Vš˜ñפ2 Ynîë|CVÞZsZú Ó†x9„ĶU&bNž\@š'üýlNÔÞû1ãWÎèjöE¡¬¨ÿI1©~´Ç)¨¥P#çP&¦B5ãrEò¬é&ÜìPÿgÖ©‘ŽrÏ3ä5ë(h“‹£66q¨ JÄ·­ ï|à·Ë Ç#·û:[‘úìƒîi0žì­ÎÚoœ*3ö8¡|SgrJ_ˆ·¬»TáZ‡%{ÍbË„pøTþÃiK¢`È$Ñò-ž— r38‘nü9jNÒúzzç÷˜ °î¸×ÃÈm‚t ßk–ßnŒ.ƒjÅâGr Ÿ¶~Ýòz^o -g}%ž¿<ÿš¦¢§y>ÕdsŸZˆ—ŸäØt‘ùB<*Cuù­ Xò4RWJY¾?Ôse4¿¦öÁGGøË=1nI6ö>â¶dxøÛzÀÛö§úø÷^`K­™u ÒZ¹$gMÍÍE®Ý§R‰³› |~Π;âIךÚCXFçÔ[ "9Û\(:Ô/œê4Ùè´G÷b^LG9DyÈ‚6ú+ìÖ?óÍv_æÜ@Úz¬ºy4r ²ÕEëæfNfS\ý(„w!Ð+`'èìõö½Ãºk0Ê1pI?ص€ÝK?lÜT›åœ¼lîSè’›šæC`-ëJœª{K'éͺ¯ÊÕ Çƒ„¶õÄ&]_\ãN*Ž²ýÈ˜Í ¶q™â?tâ‹>Ú»ª¿[h]ØÎDi‹Ø?•ƒ] q‚ŒêH¿(OßM Þýa›kP …Ìùj†§lL_Iª3e#9_zÇ…q»¢«¾I¤DKi‹KÂ|Áô-ïì¾æãEP+ëÂû; KOã%; EýkêÂJþþ‰ò{¢M; -%Všy¯Žç½wd`õ\¥Sd˜4¬Å¥øïhj-Ó)¢1Ù¯tê…hE‘¼Æ’§@c]ŒQº,ÃÙPJ±Zõjæ¨u¯žYuÉÔÅ›òÊqzú‘Ÿc¸×µ#Gr<’çâØP|Â~Rq‚a?–Ôà?ÌÕ…¢ò-›ðå&•ZëCnŽ‹¨H鬄™NN~g’±ÜLwgz̹{Q\CÂàkîËãMN®-Ø\ÝmbdDÀ!pŒ,*-eG¾v²M×<Ÿ»)¦Õî°ÚQ ¬Ìô²Åc¬ÇáÓ7/ZÓÀ¥¢–ôæ!ùOInWþþXÞ€8ä„áU„4ƒÜ42ôgYzY,lsûtˈSòî’üZQ”²8 !Êó@¨`úžnLnï¬?'@‰R§³ÓÔcz’jýzçÑGD”ÖlþhkUé.ÁôÅ0…{)ÿûŒ<Ë) ÔCçÆŒ¿v—f6„øzÒ˜êïUì³^¯È€žžs<Œ¨+ (œ× -?>Lîw\_¼__º‚+úˆ—Ï*×5²,Üâ~‡ -ËGBÐ×4$<]q…x\6_ÌI_ϱȸtÓ<< ±ã[ôV(“K—ê£hAÑLÿžƒ«±î«k”“Á™-H¼~„ÈëRtàÆ;ê¬ԧОSŸ«,Ä>x›ºQmMΠà¸ÀöH|’MÇD-2:s»ÁK¾jÍ)yu$–©Ó:ž•([mq!+GŒ™SÞz‚PùÒ†ÞjLñpö«Ys%²Ý¶p¬z.M[›t]Þ§ÀŽKxÀKPų½×ÕêL•ªçLý=à'd{ì-¥?Ö­#†‚­¢E^+#6#– ñ/–“õ­ñ¼ÍTñÖ<ínÀZ‰/”Ú8Y2ÓØ/gÓAÓ›øæ±,dx -v]šÑØ}a(ôÉ:eÝX!±«AÏ[–Ž×ÊÜ’ÀæƹƣÞ3a‘^£ãxR°šË\ì2ª<2€ÿŒÍmxÕîQžæ‘QáE‚žÈ¿¼=±HF,ÃØðªÊжÌ>Èü]¼¾Ø¨ÍqZ\Q0³“×-|/SS´æ;ª? [B«˜jÜë&BØ’ÆIRòu“$€„ƒƒj°i&ÝY³$——½å£-B’ -ç¨÷i ¼%0¸)xëõdïIG•&Ž¿œÃtɳ6†ž7|¸.&õ - -ΈŸçf™ÕÈPMC°3p§î¸eÚìq²áBÞæh‡~ò¨,þ¶¢Æ®¹ÿã -¥;Kƒ{jPÌCÛf¯¨“Ø£_:©Ãb*¬Ž–Ôº°AïhµûÞÈq‚F΃a¹¦Ô9›X´Öò€)t‘ÚQPAng©§âÏíÿ4»š†ü˜©>¹I¡Îúîá”JO¼AÌ°#­úEñÛÅŽÉ<æT»;×ý.Fíô«déÝj¸bÙ«k“ú§V«,þ|D—æ‘,4‡Ûj·vÝ–²ºyAñ—‘ùþP´›ç€8îf3A|æž{a­ --5ù\;³½2>V®±*T# +sê«®0V—0p ÒÀPô4¹7®“Þ¾Ê܃#›}Là®Ižß˜ä•¾9h_ê3ú 76¤Z&!‡Ÿ†‰Y‚Aý±Â;¥§!ûÅóë\š[S±eG»tö™€JË ¾qWp‡þ¬ÎˆN7ÝId¸1c[9H©èMu„hžä?ø³Ùo°‡T2­„Œåm¬ÔæZ5·}Oîͺ!bîÛÉ$<~éø::¥½½ž„2Ž €O1W© -@0‡cz´ëðcL"¸¶©ˆ1tQ mhž7OyÙK/=mŽ1Ü´iüŒÇŠ··ôŒÄŒ%¥”v= \lB­×9Ɔ½‰ü‘“WŽÄõÝ©s;Ú¾†øðýa_ 7,Z±jg[À6¾bV¤ÊY—qá=›TLÀTæù4¸©ŒZä¹xæÇ©D S7Aof„ûoŽ¦¹¶†d¬Å(?# Í”¡4÷Ú7©¯;˜Ác%$P„P|¹Ú“k½T˜dpR(áæÓþ; @UÂŽåo.P -·?å?«ì:º;rº¶;(œåÒHBÐUQ%Wy¯ÇûcEàÝÚóÌãÁÏbמgo@¦ð­q´ÔDÖèÈ' )øóÁ«ÄhåHø*²ï›#™·ZÏYHá( %Òïg!›µ ß¿ûW{|êõhñGÆq¡ÄL»»o–DTèd·ºãú±‚e6D²]}~Ç¢jé‰fÙ1HD,zÉDx¤[®'tC,ôC“2ßíÓ[+'aæ%¬vâ×òAµƒŒc;ÎC:e›sÓ’/ŠVÿ¸lÞ+ã,¬zïpÂ%¿ìg.#C‰ž4¥ì#,þà¦ÉÃý\¬Á—¤&‹öðcç[5—&b†ì~wcÖͳQy•†øÀWœ±k´Ô¨ÿ ³6QÃÁ»kÓÞW´ÌvŽËËf³í®Ào×>¥‹;ùk/E'’r×i'4hözUZj -S(xÚ#oÓÜõç ç‚͘©ØÔäs½6º~ï6?\$Ý“ Ûp¿øæ ´wÅ@¸º·ÑG´=/á1^ØûûWM€Õ}ýÐ駋–Ê{ÅóZˆÔ(sï[6ìÂO ‘züñÉ'ý1(¸MáCªš˜ãôº)–æD8ŸåÏ=’´ŽMæ2_Úû+ࢊ.hmËÞycÀ‹0w¯ƒ&¬í9r7µqB´!KRëhlo:®SZrEýñž:™%ÓF¤ûX¬ö@fÔ3™Ö`¶ÉbcгûË€yŠ|{¸ ¡ïì¹Fn§È…çA™kÙYÔëÚ½ |â­±ôÈìÓDáw E)³*j³sý«‹Û–]vŠSl|œ¦ÆEÔô5L‘–Ñ – :Z™ÜŠ2Mù…%–Ð`ß¿1¹¤²¿‡T@@jL¨Ph˘Ԩs*ô½§ Ëâå®è‚ -I³ÙêéÇ–T©-˜R§5߇›‡þÚ@ÂÇŒçoT§÷uf‘‚‚Ÿ£;?®IÖB,$ÊqªG¶vÚâ¯PIJ •£Æ»¨(¡àœ•SÕ`RHáRp·É/i¼™É6rƳ¬È»ÚôÊvökU;]äW¸é­ysV†$Z k›oÀëãõK„ö Î£ æe*|LÞ¹*p¼§}¸ò× }an²éÜ¥ºÏ¡öÚò´Ú7dîyˆg9ÏÅõð¤éFOdtã’ý‰,5FYrè¼c}í¤Ná§à:†KÐe fŸvE#Ÿ?Íю˪̘ í‘0S(Ó¿£ME J+dL©¬¼I­ð^>|$½g'IàŠ´?"týy0ïù4=:9W8ùÉÝ1ÕØ”D…—ÒšòÒ»³/Ã1ðý¥C¬£ù#öŽi÷é1Dr‘ ?ÇBì6R6VdÒkšÙâ” \šž¯ÀßgÐ>ç¼u]'6ªû©$c6!Çác¢Ä£Ü¢Ãvƒ -6AdQ›¹Í,>N)¥Ò©ðOã’ÛÍ·o}ŠÓ3U¢ªõ3“ÏŠC…}àp)Æó¿a™FK›ó+ •W1{‘¨íœiNŒZ?¿~Ô<îZÛ×Áˆô~ô}“IU?û -^ºö*ÕÊ;â˜<\éæjB† :æ‹ãk‡o™ùžËýtaA=« ÓÔ'ŸÔÐH•ÄN!z^“«ÿw¢ëKËÌ´«vߪý'ZÎØS³_-Ÿ!¡ÑÐ9†˜­yƒ±<`–ìÜkÚìƒ8˹‚®UF¡èýÒ¿äâôëO‹¦3xª©‡ì†°b$pãÀfN2rI[ ÷Ð`-IêѸ\\AIëÇz£AÅ ;²;»¬·Ó@sûÑ’Ðë"ø ,méG(;vø™Ùd×"|‘"¦ŠÄ`྅Óé‘«¬óõlýÖ!|t]Œjø0Š–¬¿Ö¾ª0Z )ˆM&çEî+É÷Éœ GÌ7kʱ—Ed`X]ŒÚE•ÀQd¸À'D5õüDU°p¯)+7sZz Ce´– -Ý)k=g< -ýÀ”å•LâàÛìàwD#XY«yû¸é ‰zp£^àž¡°óRÈÒˆþ‰B˜D²¼¾Ý_v|˜÷ÕìÆ”¡v’S|*B‰ã˜D#ÑŒ¹N7uˆ'ôx’ÎvïNEy-‡UI 9̽Ç|iýB[}¥­ Ó¨ÜE>T ”;pf4_·Ñ%ÙøN} T…—Äï÷uĘ¿”õ‰¦ûñ,Ri.ï -„y„ÑŠ<¦ªòÐYtÍþz`Õ4ŠMÇ>f·ÅH3¯ð(±…¼]¨!9‡çߤ–šà›cà -è°ƒXC#Ä1ž7róѧƒ†1÷‹þØ*:½Ý -¾¬üš"¨ùᶓ°P ¾¢®tþkºô¡ßs˜8ÁºÌÈ8õc°ã9­•Qæ3EåŠü±¹ÙΆq«¿tÔöÙËCCY^"fDzJ -ÛnÂ÷Ù'Î{ü®ÒÿŒŒ®AiD–Xg‰¸N8T£lõß Ý¼ùõšâq’Þ¸+U‹í7›™Z¨ Á©Þ¼{U ìôtœ&ñ6»=¹3gT’>Ë€ijév¦r‚Kºr‚ÞDƒœR7$ál^é•4mtn$êEÒÙeÜã8½¹ƒVã=R¶W…C8.Œ.'~Všë[²­:fÉHn‚™MÂû¯®2P8¼Ï`@¹G´=qHw¾•Ø[_û7*²C™r³ŸºkÞ²¬Ã1‚¤Á7ú>< -Ã2k}„‡Œ°±hd7,=½åÒp3{9 uN4Òœ°T—£b ؆F–i$ïó‹'p‘}¾Ÿt¥™´ð^ɨ"3±Ut¢¡zx²ØÆx4D K¬ZógÜ–z‘xC6‹]äÂØý9&yóï³t6?ðÌ"% -‘¼FøCAÌÑð}>€¶6‡¢ÓVÛþ\ý di B´«ÙQ¯è.Ç~Þ‚´ÈÌ=ìäm’6yS$ý-Ñ¥ª¶™)P‚´)keÅÃvM¡Gã¶Ëe·5%¬_ØYûMŠKÒ}ƒ†Œ8 îÕŸÃl5wìóµ Ô<öÅ·£„²3dz’œVÉ ÷ - žóø.Ñ°\éd¥(š˜>¯–LãPÊ  Ôš3,¿Ô16še¤³Û²˜BG»OåÔÏæ¦_ƵW‚®e oÎP×½'”@ç×Ò KLýº-/ÞJ[ýŒxw]öG8förˆVƒÉcvÄþh;Ìšé£è‡µŸõ!qîL¾Â mÕBÇïã@håR}ºûür†¢'rû⣖í5qq!Š¥¥¾Üt¿°wô¯µžQ8É@Œ‹«}Hë%‚Õ›E1TâìGäìï¢vF9Õ´½Öœþó«õ‚y¦¹ØÍYG$RXs³ ¢ÖÌÄxŒÕ}èÔ²®å†ˆ¶DR¢$GG0!°Ýº˜ÇêQàQv‡{ÎúlÀf×rh`>-¸O×HÿËtÈG¾è¤Â³8˜RG#zÛƒ–´N–˜0NGéìl%¡§¢Ë.læ¦äyð»R×|~e@!ŽŽÔGê`ª0棋«å=,–v_æyN¸À(:¶óÌ¥kÔ/˜´@ÚщÝ2Ï$4;ô™d1Sží±B;·šjü“ < Iiß\ÿ ê™™Î9£<È;ôÈypckÜl"ºÇdcß]ªPí’›öĪ®Ê™x³}YÚð²UöWÓÖ°Å÷ê êy´NpY¨Jý°ÐKöd¢_Ì|¶jUM‰Üßíùº=B78b5í9S]âh?7 ØD) ƒšƧ̗ÌÛgäX‚ǵx–!6YßÃÛ.R8WÐ^õØ!žÃüJ½:±³tñÀ{›lnZú|£€xÎÈ›Éú¾¹[ÄÇÍ U7NÑoÁ/¼\€ZëôJ(šøºa™Ùi¤•?€üa/J£ˆEÿýý"«€ev×!€Ã?ü‡¦1áå©Qá<>ÝZ¬|¥“hà]12fʸ™§ž(Cj‘ÃS¦™úêûW%W%N_ììÉÕÈiü‡Ÿg='tÖ¾Íö¤â„6ùWÊÕfKd2žÊ]'Á±†[–àÎGÂÑ%Zu$o[fìÀ(ÿ÷KŸml>H×ýá<ňe~Òußɯ,gVi®ÔŒ¼³¶FUjé‚YKò–eŸ¨?ŽD‡.^– åª$y6àj)¼¹è 'Ç"äMï{fÅ´cäì²Üz+¢1 -°YN0ÛæxôÞù¾•·Z1#‘pÐG)œïò±ž{+¿ÝªjwÒ±E©áš=P´Þ7±ÙÑ[7û¦“¸NYYÇU¸ydyÀ3yzdC|`×¾„CBݤ0âF½Æ&nœÐ~,‰ÄÖº ô"µðóo›Á·¶±zÚŠ7¡t<=›¯z`é†Fx¿¯!­„OL¥ó¼‰cä¹àåOsLÊ…©V-Ľaw^ß -¢ˆÉd)$± ¶Š¸[a# :‘ÁÜ.‹ÍÉü7LÓ„(èòGÚyö é안øžwbMŽÓüÇÞNËe?ZÎÂfRc¯PÌeš²ªéQÚ"äI8 -4Æg÷ÎüôL¬¾¾Ò?Âlœá6_±Â؈u‡ëî$àÝÌ;ÇDpBÝu¢Cbî›#13º;Ï -*‡Kò·¶‡;¼-’"+ܦ˳-ý<ÎÈt_üöYëÎ’áBÁ‚¡$üé©Ò.&>Ùe¸R¸¡3›Áÿ]u7üaÌõñ.R8‹zAµÓãvnXLûçpYTÓôª['ÒøUÒà=|¹üº*ÚÜOAŒ/–*CØ ¿?CÞêh67÷ Wáïx,V½ªŽ_RÆò^/H–}èÈ;‡¨=+mä káÕÊuS®ÉẇNbnN’²‹Y)êctž-yá¬JHw‡d`‹£Mó®úí}KÕ4¬«–!øWù…sYÚá•MS |•Ð§D Nß"æµdYDéÖáÄúÑ¥õÇ*1öEÒ.úMµü–r±ÀÒüØ -Á4õ5’KÄó}†#‘.§­¤‹R‹« -õS—¸­oïV‚•¦x{ì—?]Ž{øjA}øé{¶$õ†BÇÃh>/o†"U¹»ý´P‡SkwUçn0þ€8âàB¶ü¾F;u¶pL)#–àa–é†EI!ù+hâJXÓP%*;fÑðáCyê¬ã}ÝoÒ¼¿¡ɧR,çÇ?’˜Sl9Ò«W¶ä'j˜¸¬UÆ)šµæ•Ïˆ°gí®œÙ­cø•XÞ|‚qbÈ£!1{¼ùelÇgÅ™0Ù—^už…ÒÊç„D_ºö¡l*·ðd¾Flú`‹Í,¨X KTŒŠf­—;û²#q~hŸ7¡¤Y'ÕynÚsëÙ¤…Ϭâ¾Ü{äcÍ2–ô-ÙþŒÜ×’QîPt®ÄóðZs‡’„¼Å·Q·œêŬÇàâr´iÔhKEF<ýçn|Ñ ;ÃÎ*½½Æ¢¨O~TÍËiƒ„½• ñÑrQ˜šÂ\QxöórÅs]‰‡ÉK‰×Öt©RŒ{±þÄTq>°/í¯ èÀYˆ8~'}j+U¤5]¦tj7ѳø6²ÉOŒô%òœíüØe¡ ÿýkFÁÍÄI÷-IƒZÚ[fã犴Šˆï;£À»¹{ý£›¨æÜ 6pÂédʬ ÊL -}c6!„L¹âP’{ƒá;D¾dçqí¨ˆz`Ë2«f§µ­])ÊFDŠÜ›/˜[öÃð"§Ê^wHZÁ‘³"¯oD{¼_7züä5àb«;ýS@$ú¡W °²ZðDò¢òuÙÙ‡W{fMÞ2ó ¥I*,~…Ä©¹#xÖÖŠìz‰KkVßL™E›)¹‚¢ÞIXbÄSóùÈ»´[N[lº3íLX¬˜üçw^@dqór®©aœ€ÿˆÈ«^œ©úQÔëèŽ0¼KÔÎs?Å$#ÅEA‰i×&ɇݻÁ‘$Ò©ü¥Sy‡1;HèWuP)½N® ‚’¯W¹s×![PÛwÚä” ïÜiCéW.䦄NMb‹Õžçáâ—¢ VTOþNÂ^K_çÛ.€ m†uÅÎåÏ0úvaiÞAœ,g5YaØ‘â×Ái¡Þø\¥œÑÖž-©* -G%vA)ÁÃG¬³¤f‹o¥¿ñ`Ý­LF™óVõ‹ÔK‰óÔÝwø`ø?qŸàÁ¨Í tj@®ÈÎê3cçÈEÑØK×O»Õò:;?I ¡ ýÅ!˜t¿£dæ[)¹¨øLIÃ-…Í6mïÄ;ðëjoà'ø|Q¸>ElŠ§Ôþ"$+Ä/ÊÑótb/w6ŠäƒôÝ~pióÁ …§Î`ÕÊgŠ²g²:¡;÷Y2&Ô%ó -ž(—NÑÄåi¾%¦Še¿€Ù?ó‡ Ÿ›o†`ƒbîª0Ø– õÚ MR¾Ýmc,ÛtóÓÇ@6UÓ -Xá…<§õ0ØC"ôñŸjè(–ŸÚŠeÂÑ_{Ú#‹p7ƒLìÙ5`:ì¥~Áì4«¼„?ãL®Ý8Qó\‡,OÇ™ÒÀ;ŒmhT Î§µVÄ! ¿h¥¦ž;t*ê¿ôŸçq !·Ë,·*¤Z…ΟÐWŸ¼T‘*”„6C‰:(ç›ø9ÖɵQçQÈÔGæǦߑ_<Â9ç×YÛ­ÐÚºMîƒ3u"JL üüÒ¦Q#ÆV_©©…vYTóVKYðçæÄÞU™gÔ»ð¼ òù‘Ïz‘Z(ßC?¢1Ý=žâD®jŠR8€‘%öøg×Èži2v»n›„¸MM¢t QdÂ*l%–¿‡RS7ÌÖgj¿¤‚<ÿWßÊ}#ó9¼ˆ¯†eç^™êgÞÀ Ïõ#²z:Ý¢ -Ha\»¤ÿEH Ü„Ôçì¾f• %bA¯üIÃvÊ¥lPsw‰8º8Ö­æŽÚz1IÝûQgÜûØÍMw­©•—#ŠC$=ꤡ ºí=ŒjâwÔŸD*/ÜÒdêÅÎVÇ ,M¹·KÎ?ß´—GM‹-ø’S,‡rYŠãÙ§¢](?*¢/GØRèÌõݲOR毙(š:4 ú™æÒøxÝ`£BÎ ´;á0dˆåÍvøÈnç”j¶ÐŸôwoå*ra|&£p8`ƒ1ÕªJs‡!ùåækz‡Fíãeo—É1.ƒ&xªMC1b¤‚Ïæ·x±Z8~"xOkËÄ¢¯×¼lT²”XQ  Mo¸cRt¡Þ aY7_.äNéT±JëñM2AJéŸÃ=k§Í"Ž‘Zíë%a]¶•æsð¡|jËNèNÙ Ùcš|GXŽÈc|G¸[«‰5G¶,€/œR\n‹l_`m>üTO‰+©b0é³lG¾u8ÂfÓºÞC#ÏzÆ?/Ùel\‘´ˆW°‡Ý×ôøüº±Bì¯7z%ÀÀ·Ú(»w)ûV§â‚›î»vM†›»ó¨7Õ5K#;ù -ž‘õ÷¦ÝÔÆ.3±õƒ¤9ù]v\_17OnS{‡71¼ôtÝêÅËCgû!Ìõ’+Ì\\j·Äž¸,1Èßß62–e€Æ§¥ì¶£þ&kL¿ÜêWÎc½aàJÚQà&AY¸Úãt¼Å+«8•õàZõг…V|Òœ½ÅÆú¡/½99tsDõbÛ_ÇÜÛWp vµe>‡ÿö²fßé(!‡°~i0bkzì¾ÕIä­ÖÙ²¥©@ œæ‰R&ï…Ãi$|i ׶Π³ùòR¥ñ-f —ºŸ æžæœby,I꾟pXðØ©»›¦Æ)bF°¡K·b¬H‰ÌçubØJŽ%Yô¶yX}<¹ƒùÂ3éîe›i0Û~4f$­z6n/¾˜z¤ðvÀÓx$×ÂìÀˆæÑnmeõaàtçTŠEð­*>÷ËMÉCJÁ0Ýg¿WæWk¡0[(ÃL(”ÂÁÒ/;í:1J ÛÙÞ¯£ùþŽŠ'sÙìYœÑ$l“E! ÿŠ’úë}ÈѸ/áK#¨ÅA­Ž^Uë“Ø~L¿  Š‚±XYC§»¬þÄÜ¥¹¾a.áM\…ætrQ×üÀjq"Üm £ÏÖ¶î½-‡Tâ‚Û%JÅX›M³z¦¹7SÖ¨úf ï0´ô³V˜q7´2AÚ€úË»X®Õ’t•Ö3çfÚÌ3C’{Äc6 b€¸Pek8ÆÉ@G•«EWf¶rˆO»iuw‚xÜÒqÌÿ8ihø©à¬j›—UCÅH»Ê¹b?,£LrE =ƒ¹ôñ5Ý&*~ê%ÐÕc¾îÏòX¿,Û qBN)óYþÁµe¤*±~å`r|"ýç4[ØŒ¢¤¤€í·Ã|­íü·‚PžéÉ+Qu|¸ÃH:^R8MÿÅ›ª¾â,FU-°ràQ„³sœð §gVì5qï¢< êÎŽ -d9ÊÉ„™Ö´š1ìÏ¢ì¶1CZVXÉbןJÐA¹ÒKMöS–GõºwÑ×í‚cþ` È1aeÿñG©n¼õ÷Ñ™7çïŸÊœFŸînŸT‡êO÷6ήpMëgW7a=_ëŽ1T^¶Õo&Œ¦ßÓÔ‡\œ"ÚË •×)-E.eÃîi¨¨Ý·ŸsÿS„/ ü†š(Aæø+ÇŠI*ÎÓüúÆjÚˆšµmiäXý…EŸç¤9q/¥%p¯ëç As=ÜÙ}Ú•;Qlir®©ù“ ÿw-db&Ñ = ¡.b¸ÝÀ¹P¿¤àÅЭÑ#m„ɲ]¶ÇeÕù-÷uÆÇ9—ydrwÙxm£ ]Ô(IÇéÓÂQ„V‹I/öVxÞж[óVmyc~|´‹ÎññF-]£ÇõF$ô{Ç•þò"‡‹Èu*'¥æ/Tw)þñ/ ‰_bbèø†èh³H‚y5(Ô23^K~xɱVÊ+˜H©·1›)¿h¤GP~,”é;¸0ÇPÝîDÀ³Ø2y(ï³³RTkÂì¢þ•KÒíÛ/ Ôkz2,ƒÄUHH,[¤÷žÆ—ù­gÜBþîÕLM*g,ØG‰³Vî«LµÎ¸NÆ›þÜþ$î¯Di$uôìØ‚´)# 1%}>Ò-2¸ßL1­ø¿²s5ûvTëð$‡.2XPPù8ú¹ãsµïõîrRÎÁõ„¡Ï¸¨›â•þI=¹“ NOCÕ4rʷ鯲›lYõéjÀ‹¯>T1w=/&6‹ü9ìæ·äŽui]¹%3ÁÐ.{~Sé…*5s›3:Ô„Ù“ü*·ÂÖ5pFÍšm*sÚ»°©’aÅ:kïÃõb–^4M"s2Ë®EÑ8Õh¿]œ·R´Ɇ¥ŠÚh6lXq¦!JpAW©!lx’YŒ¡›=’ÍÓtúñPJ—ép —Ý@ÿÁ$]C2R7qlnOÊ—*k”(Ú…V¯{­²ÏRw#XLÀ#btJ—Ç-N‰zØÞ)VMÐS“Æ£<^É™¯ŒuK ¥¤‘îdçÖMø³[×ÐÁ÷ÛÞóÞkSÙèðËÄÚÎÍÞÕßßLØUÄ Ô:L}× ¤å°6a@/æ{н6X6ÿ]„Ë1_µ8.·$ñúëý2h¤ñ³O:þÉããhIU½”²·–2 Ÿð3”1®.øºò"îf/’’u.3éªZšœ˜­9µÀµ˜…”Û±†mùlË—‡Ï³'´8/Éu×µF±‹gKŽ‚Ç;`†øç:í·úGj¹ÃÊH‡õi¤ö@É÷²ÇÖiFèÅžo:Ë… õXWzŒ†˜g =çÇ$¥6¸i\üh¸Ôè¢ë9ÃËñüwÑ¿nÊm#p¯=7Ö8wK -†‚˜!Y5ª¬h›Âø IŸsëâÏç ùÕu8᱇¶QøFt“M$Ž×Óå“y'ž‘qŽ²ñÐEW fáx:„˜û;W7·H þ”ãWŽª—g=p.Ä"®¯·4š©øZKGœòÍ£¾O‡¯ wŽù¦Ú&þ¼­ÓØb½êÇý3ËÌ@1"†r=qoÃEó”ä×™v0™ºpݳ³Ë„ƒ"´Å¡‚’¶Éà#’¨¡Ü‹BÕÝkñ:FñHí ç絬¦æÐì âyPÞÛúóÐn#Z\›É72L‹Šã°-*CÌÚº§´á—µ'摃ì“Ùðú”ø>mã fË©¤7i0?˜ûû/‘ªªÚÜAñ‡®¸»¤ß3¶îew´°éÜÐ fL9QqØ]P ×·²¿èýöФ¤5BéÂKÖÔ( ÿRÂM«bd¦ñbÏJ®¿Ü>å#cãv“¯Š1‰«¹Ñrjºé×M —U;hKË’ºDÐWRIÔ®@$š@ì<‘ÍA´¨ÄDú&„IU©¦"ŸöÐ9~D”eùÖÔ ôTê¬ãœé(¤Çn.”.kðÿ´ ¥®ogï=ƒþ½»þsuFÝÏåþ¢‹·cËáäÖ„þ²÷‡ôŒÃ¢§gÖ™EBdeìºf|íö˜ Œ³Zw4Vçvž&Ê=®ÝÂ¥H‡,d|LÀâ3N‹'¹²7,šsL„Ô]øm³ n-@ܤ¬N&…¬$ÿÈûÃõKÐt|]Øl‡¢óJ>h– -’9„©²Íºi=ÿ¨nuþò©­'h¾N«˜4Õ 7<±–¹ûIíÓö†÷Õ=Î)iÇN{À$dQñãTË0¿‡h¹KÝçµÙÚÒ9äóÌèÍï@¢ËG¢ $éðfKvHÀÑ:ÓÝ&îûAoà `žŽ“DGO?Ìd¨ö3ìŒ Â̪i¢ì'Y"-°ö-¸™¸O-õÂ5¾4¡Ã­š6rMŸ4Éì’‰üË¢¸U9F4Ò±SÑU-ÚÆ -¡à£"Ð,‘gÏKîD~^ººÓÜÉ/Zn\Æ$ÿM­Œù–1ÄŒ)Á×BoÅ£E[âcQóh¨X*úêÊÒO>0”ëw+ÇœðaÚ¨F~¶zñyþþ{ ‡gS(êá9‡&IdÑX2)Fžb¡8ÚËp¤‹PX,Gæ(xõš2œS`º faje‰ªh.,w¤á«7 -cLÇý2 Ža®_š²HÎh2+ƒZj@¥üAnÆÝܧúœt`;æßgŒõµzê×îòx¤áï¹Ñ%–ž{æVp¨XU‘Ãí`ß Üv«%¸‰ø×îDß=pNÞßà`å7—Ò‡Rtó ž5•C{ -L­ysŽ>!qÓ±ôm«¢É‰Èåîãéoª#ÙÎÐ^?ï8–y_å¨õOÇ€«j;‚U㌠-¸Kþ­Óp’¹«³>ú±ägWüD³É÷?æKåÖôm#|žZ¡£ ¢Ieí "b0G`½t¢n¢J¯q¨ÜÜPé¢G08mÜ8Ùªç µÝ¯Ýã¤ßRf§2e±;$D/Æ&.mÈ—(Ân¹\çU"S#Ð!=7±æ -’Š±à÷+ÐáËú­qJ®lHsIw¹eòª zDëÞªÔ• NÚšO%ÒçÕñr‰½¯=W¸Ë„TF%:uÀ䀙2º,~u‘\ıáýú”oC}xù‘Žq"4{‰ -@ûÅ#\t£¼ó¿º™/K®Ÿ±UgR¯H€d~È -a«Ç|…Á|e¿g½¯ }ð”uT©ûa3s+³Ì¥•¿½ã1KÇ×1¼tþ~¸O`Ë’tyQ[ýÈ—M!›ªo®J¿¦½Á'‚K›ð⊿Sî|ÿ˜û\WAƒ#‰Å9Žê2]2Z³lp‰Fûû–†ÜûO¯†O &¤ ÜDpªV¦8ï…ñ™÷óìº è™zgØùÝg¢‚5¹’-É}P«†öž/£y+¢rC*î‹#&ï]:x"v˜rNµ4¥‹|ÓWíJû`føZ1mü-msFYîÐ:8[Ž–?[¯+v~ôðá²› ó&pÀs–K‘v£y¨¤}Üšÿˆ÷[â01%¸.cœY‰]j˜ª:Ç¿ùö:Qqæ!åµ¾©ÏÁÈégƒ¡¾{£6jÊÑõ({ö;¯`ôô«î½A$äÆä¥=ÿ7<‰†ÐZLLSXëFŠ}Db62×,èÿv;=›#˜‡Ãc(íˆFrEƒÎUA7Á¾ºñ°¤‘ïμ Ÿ³ËØ 0 - ·‘—Vh/†¸MƒD:•ÄÇNñü°†•:#Þþ>PLÇÒwïÿQ5GbÄñ Òû¦ªð@` Ìz(iVþÉOëµ6 ‘–`.¿ô#°Ý;Uº-AnGûnxf³lTÆíØHºcÍõ7<²q3)‘‘Ç~*Ún¥ ÑB«R‹Ï+K¥È›!®)w™øÄ•™þîêñþœCåaIyƒÎ³<–äxŸs²)¬•¢×®8zÅJäó £n©ÌsÌ™æEHœX-z/è=!s_å™B?Êóíwö;µŒ›ô7M»Õöî‚Œ“˜:¨’PGKÐ'¨MÖí éżAJN{QbÆu:V7^Ð(*mké«s櫬é)7,"[›CÓXåºñªÌq…»¡„GÂmb(GXT€,ùÅbo©ðp²‰Ï÷ÖnròΡÕ`‡ü'íÌI êÁ¤Ë­,,ÿ7üëlþ\K -³ãÆ Y§u ïèœÙ+èï°9¤- ˆíRUöMxöOþúíú¡ÅsC¨3‚Džú›„àyEà·£¸q ›—Rôd}ŽO± æé[ÞÄ™G`c·§;[‰^L–çÎ(Ön^v轈î½—’‚IA?‡Zdߦx¶ë‡0Þê5/„·ï0iñUE°—,¿"7ZE"Y÷­à ŒçÂëáÂBG¾8˜¯§µ#êÂ^ êa¹bÙø´­b÷VîæלuHmzæî -P̪è¥Ôqõ D·Š@ÞDzˆ‹òuçöÿäüfN?ag>-šŒÊM©a7šµjª)Ð¥0c1å˜Åêž&¶Á0®ï¸‚«n9¯ÀMæW )õêP&°C˜Ù‹÷¥J@eôOqðȾÿçx˜¡ù3ÜÏú\åušà$å·=„þ’»:0¥äí ¬ {]Û7°PPÎþm1ˆ’=pËvÑ18Zµ±ˆÀºrG»%±6.«ßÌ¢8Î8П«woZKÉ9'çêí#úG—ïj²X+§ÃšP8†»Œݸ¼0J…®D“-ýf¸=_U0óA­ú¤‰Lÿé-àK‘ú¥Ïã&zŽ^Lqêm²ù›_º´~æ9ö$ |òÔ«*9k+ôûÒ—eL€<•Ëu¼É]ý v¨Œº_rœ!¬ß§Ìèèn"X[,#ѬR;Ry\³¥»VXÀƒ±AA+w -©õŠÊ»üyž+¾û™%’I†2£mÞá­¥\÷¤uçó:µš¥WbÕ‘¹éˆ×h'¢IµCŒºÛ ¯uJ*ÓÉ<¸S!ÙÖdNPÂD)­çcÅkø2æòò›9b«Ë#¸ö••v² û›T“Z#¿FýŒcÄ̦ë»Éz,³ý‹ù¦Š{ªÖœÿV¦(Z‰šavQÖK>T«:œcn -JÎtŒa½µ~öB¿çn 8b¦”W»VŽn$èÍñ)4Üê¤÷VûËÌŒ;µ•èN ‰R£ËÐŪ§ýÿ×>Y¶5( QD‰!%ÝHîfà¨Ñ9º‘n i’"]Ò-Ý1ºKÝݵ÷þ‡÷Û}îùçÃyžã•”4|œ"ïñ`Ûý]_€ßÿ¼Ý²í\£$«:ê¯{¶F†Æ»lìÏ3¢?ÑL$G@Öóå×vmôãŠ#Žª×°tή4ËFIñê\é±¹†òã–ÊcLÏBÙðn¶²e™i¤ÿs;<¶ ¼ÿñÏ7JŸ¨ie/þ5÷“FàEZUuç!í¯îðœJMþ•³ŽôÓ }Ëß–~¸ -Âòé€z{JE‰FªM Û„u–æG0i ž³ÍÀ†^µYkúzþ'ôÍòH¬n“È([ÒKFR}ÿ^÷ôdk -±5b$ßì}Cd%#vﱓ*š°ßÉ ‘ú°»­¥8hñÀÜ_Œ»Ð7¥U½2f -b›oÒm÷ãÅY…½jãnQŒ˜fýÊm½­ªm&*þ8”Èç1|ñ˜a¬~– F‘«•¢ûÎòXQ;( _ÆSI0ü+p˜ý&á¸$BF -ý1ì_v#ZâÍ,µgªìVØ -*‹š@i‰úû¿ž8ëäCî3luRŽn£ÒsbX‰É ýÚNã0Lb£?yrK—Søƒ=ÕˆáÜá@Æ žÀlþ ¦Ã<˜'•AÅ87gñU˜ -Üxäø›Š•XGŠyº'üá9vµ,Õ½OÓà¬KÏýØIC`­” ¿¸9Âò§é¸ˆ ßcZ”Âh.RÕŒI8¬_$òfIKmÌXró–€àÇêŸ%Ŭg”ÆÂüˆßY'ºVR, ¨B~ ÐÔAQäϲ¯u£s¢€Ý_˜Œ\@øt-ò©Ÿ’>ö‡Q÷FÉÎUŽ«l$Ô.ËW(¦8*³Ÿ{>B7@ -7쑘ôy™Ù7º!„³¶ QèÌL}*Ÿ$‚WVÉÉ®š±Èñ×´//2ZA$¼§¥ªb;>~T6EÕ<Õ¿¿Vj3ps[‡Ú[ë #.JìñåY¯ª0ûì©'™„±ŸµQÖ8}Q¥ÞÒš½.HÒý¤ñ‘õ$=¨â¯oñöaZ]‹#6ž/¿¦Ðô¹e¸ÞZ‹ÇM{ªh= Hp¿œ¦-Õôš£åežÂúz‚€ÛÆ«ì(Onû÷söQY²æ‰Ï&¡I(Ja]U›-fø´Û[ˆÿÞóݦ6vº%š.[Íá§KpyJÖˆàêh2nösjJ,©VŽ&EͯU¨•x9øW+0éOžÜX‰3„\´å‚]:aFïz”* ^Ô¿Žààˆ¥A -‚¾¡ÉzŒ:s[­+ž:[´‚r 7À«_ó熈ÑFÂ2Õ:¨Ù˜-Aè -œÆâO­Œ,Eß÷;XM«âU†æüìeçÎ&¾¸cë2“.D£T«h8&Ëe7nV"ÎCøpÁ¨Ö# }&_ot-ç2ÃæXL¦ºŠðï"’‚Áf&ѭ탔w¤éʼŽE9Ãê¶Y|t\dà=_©Ÿiµª¯9ÅÝU5½<}âoCʬe±É·mQJ_”–õx-ºDïä»3¦Ÿëï"‚_ -{8þFÑÇæ–éì é–sEcø ôc/ ¥Xne­£ß Ip’XÌ,X§x©oÞC§C7}yñ8㟑KÓ•F<Ø—¶cÚùc§>É÷"ÊåæÔYxVì#³í³9y«bTjýé‰NÜáù„…ªjŽ\«WÍX!Ì[Ê뺧b'ÞŒÆ)<$1ôÊÚ[,ৠƒ@ŽWÃc3/—°WnY"¬Æ4áé[_Šüå–#xÎöf3I¹[V¦;ñ²è2f’a_ÏãX;q)ö&Öö4FØ…È÷Ÿ ˆMóK¶Ñõ‡ºé€‚œ»&nˆ°¤ý‹ëžÜ[}·R½™Ú¾Nò -=X¤9ƒ:Ø•ñÒ¤áiÁáß”×ëù pj2ã¬#C÷€ù=  Ë#; .§Yº°xB±}!ÝA®í×›< ûFÔ9OµX¥|½D;-^Èê-Èñ(õ8¶ºÞsžj‘ÿû_„1Ìo^}$å©ZR‚„ÒE! -†*Nñ(ßc“À“ -ÎQÓp/6è~E”ª:Ý?ªúÚ Oæ˜%3=/4X ýÄÐuƒä–ŠžØ¨ûáá]°ÄDóÏí¼ G‹Æ˜; sL‘yø‹laÚTKcøþÙÒ5Ìg+Ÿû{Dü±Í9­M9îŒu.ÍÁGBLK¬O%¹ŒÔLM…•“–`Ov’T EíûÐÖ[ï21Êsd©Jéšp•˜éø#ÃYÝEö‰¨õrnâ芻‰…ë°¬&âè݃é3N^Árÿœð•ó+fd-9¸U0Ód‘ ´U¥A}ù®º"äöÔÝ© -ê™ã2ú»‚îY$óµÉ•­ßª2^IÑPYm3ïÜÚ×Juý¼=ÕùÌ~9Äÿ 2©”pmPkDÉ Ç¥)DcX¨Ù콘ûk*+ÇMCÆ{Ù´~­Íµ)²è5¿¯ÅL|yÿ1ª5u‡Êëñ÷Òc9„ÍrU ¶óBDøò3TyÈ嘙 SzH1ß+`Îð¶+§`½°W5Ó㎎²ÁÑÃiÁ™,÷ò}cýö3!§ïÒƒŒ‘Pu aÛ›”Ë tòÍ|T\ÅL,pÈBHðì9çÑô)8H-úäjj*ê=êOŽ<™â:õY9­ªÓ=iƒ‚h¾!‡¶ïh­ðç¼×îöÎWc?|8na|qží+¬A}~é{âV+gê7L7,ðt>ÓSÉr¢$˜@ZýaQ»²L=4›Eb ”¶¼ú¨•ËÅ›å/Dj {h>UVÇêúÓ·×!JÞ£ëp‚FL¦DE8"¸FKËyŠRŠàïQ¶ÖÿcFö,nc$õCèÛn^ºËø}ÃÞ‰ÔÕÃìm{ebèÅß5|:¼ê6ÙÑÑçd®‡ÄŽæùƆ ^Ý+÷/Ø:!\Ø°meCkn+? äm –ùK'S| j&¹qýÉÆJ²¤µúže•xz2ÙÌBwÛÝ:‘C¤·¸:¥½`RÛˆë1ïN^‹r+Ú©:/cm1+Wã¤àûðó·ê÷$â{‘™à‰¾m©¡¯ÈlXCšyÆïÓ»,P°&Ä•–¤–6Aí³è¼XË4ì¢Ljn¢ ér:S#7v°£˜¬dd÷—“dZ«¼rQK¨ý>¯õ®lH}™‰Óüzôßa­ªëµjÈî`ê†÷Vš¬ŠÖôžÕŽopõÄh€— âc—mNá»’E…¡/—¯ñ­(À»¾£ÐgñKÂ¥K_}dÀç²çšøWNy´bJºœñýÎ^y{D¹¿ áöø ȯ×Íó WV?S¢6y‚ D\ë †µÆ†ûÿ -Œ†<\a/r¼ˆvÈxµfíÉCvP€ÕóuóföÈy§Åm4ÍÛÆajùlW¤JÕ4pñûZ¢Aÿ6Ñ®–B][¢µš×´B©®¦Ö{?q£Q4¢«]*ê f1 ¬Œ*w5#Ò”HðŠ¼ª¡–©ÖËCšŒñÌ®¾”ëÓj¯¼Ã'gE¸FŽ:í·²ˆ¯%u0Aü¼$°aXÂ/ ÷ߵƪÂú¬(ß™uklê..Úá¨etV‡rÓ*$ß;>wYp®Ûr¡£îdʈ†éñÇVéÃhKñ«¸óWCÞ.ïò$.¢oÂÞQ#»Å¹* q¦ûÀ6¸JÔ àÇæOŒù[ôÏQ7óeø^ðÏa:iÄçºb¢&ÙgAÑV£ç\tj†yçר™<£È„ì3tçV(ôßÌh©×OѬEf›½ éÝK•X?`Ãþ7ØokÓÈh_y,Ü÷í½?á¬{®Mpóßù‚z¯–ž§ûëeò eÌtÞøa‚s{ú(5J<iKfÙý6ZilX'Å¢ã6ÉñÃëÓÛ)'´Y¬¼ó4a ³Ô4ǸÔ;ÁñUÁÑu]h‡ÎlŽÑJqz$KЪ@ÊÛ3§Üo%ù˜CS÷.õ„ŠuáDâ°YkÊ5N-¸àî )¦uóñ×RÒŽ»—,â,Öò‘ù;²eõ'h=ö:©aCDcjÏç¾µg"ÁÌû'…@ä¡e;éL7FK@»,ƒýëdE’¹¿eÊu]þ¦&ãñ*çXê R\×|ç>¤}Ð8ûÅò´†ïZúI–-ÄŽwp­íô |Mª›…ÞTõèË¥{E-5uyЪ(Cˆ­ÞF‡ÒogçüÚ3‚Æ?Sh`Õæ²2­£=‚II¥ñ“ÆñÎhÆz[ùP.ÍgN#w£é_á£ãäbJýè ¦3eçø1Î?­úw–û’ ë zT4{… BfA]qpeóD=>ö$”z‹Ñ”H"s›eª+è–ÆŽµz lSvöñ©…ï–YöWñǘÛFÆÉð& ëB¼´söÓn>³•Æ¨»VjÔŒw¥¿·x¬ I’ERH· |MÄãzÅsz{o ß–ž›ŒD3e'lÁb=âßç95K7ÁœÃ'ç k+'ÂæxAS5#]¡~ Ú§¾wÅäoV¬1¿AÃÍÝ4šïOFG,j‹`Ý8ðE¡4™üøìi–¢L-C^+ÔÜF«Uݱǭ„ŽŠ(û89Aû[¡÷Ó­f)­Æa|é]l©ì™ùÀ`§ª¶p«B8Lúño@}þÐ’F³’Ùa8 -åUÔwUMõ»gÕ"&ÛQ=Q¿Á²p,æŽ ðrÎfœÝ‡Qã³éîtÜt6.§>ôÙêð97›“¡ÞnW‡•‚ø«Ñ¿}‹!®N‡éi…@lã -C•Á&ûA×"4ÂÌ]iÅ Î|,›ž(mÍ…pêÖ.‰ý³oRŽÕ] ¸kŽ¬¢PÖ¡ZÛZŒŽT2Ê©‚pC¯–dô.Rn®f™7£žØærðk®–-!OõŽž1t¿9~‚ó–‰æ·q¼mxYæó”9gK’}ÃÜÕè×å HéÏAf™\pCÊˬM‚._óBâÚjq À¶]qL÷‡ Âa¯¡n—ˆ›´¢('â¥&Cv­pñf–¿‡OFÙ2ö -# ð:øF(‰¥YäsäLèÆùxÂJßÓ%ÌgæÂîˆñe:‡¯#0®ÿëÊ»3¯‡óíLM¤\“wŒgßRkHäŽÅ_KØwÓªÂìni–ŠØ± ¨wŠlNþj sßÑ8v> endobj -877 0 obj << -/Ascent 722 -/CapHeight 693 -/Descent -261 -/FontName /HVVXSU+URWPalladioL-Ital -/ItalicAngle -9.5 -/StemV 78 -/XHeight 482 -/FontBBox [-170 -305 1010 941] -/Flags 4 -/CharSet (/fi/fl/parenleft/parenright/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/a/b/c/d/e/f/g/h/i/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/emdash) -/FontFile 878 0 R ->> endobj -1930 0 obj -[528 545 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 333 0 0 250 333 250 296 500 500 500 500 500 500 500 500 500 500 250 0 0 0 0 0 0 722 611 667 778 611 556 722 778 333 0 667 556 944 778 778 611 778 667 556 611 778 722 944 722 667 667 0 0 0 0 0 0 444 463 407 500 389 278 500 500 278 0 444 278 778 556 444 500 463 389 389 333 556 500 722 500 500 444 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1000 ] -endobj -862 0 obj << -/Length1 1612 -/Length2 18760 -/Length3 532 -/Length 19672 -/Filter /FlateDecode ->> -stream -xÚ¬·ctåßÖ&›£’Û¶mWœT²cÛ¶m§bÛ¶]±*¶­[ÿsºûíqnß/}ß{Œßšxæ3ç3×c“)ªÐ ÛþŠÛÚ8Ñ1Ñ3räÍ­:;ÊÙÚÈÒ)Mlpdd"@C's[QC' 7@h ˜™L\\\pd[;wsS3'¥š² íYþ ütÿŸž¿™Žæ¦6ò¿.@+[;k Ó_ˆÿëD àd˜˜[" -ŠšRòJ y5€Ðè`hPtþien57Ú8©&¶«F¶6Ææÿ´æHÿKÈ`p´™ÿMºíþqÑì€Ö掎¿æŽSC§¿3p²˜ÛY9ÿCà¯ÝÄö_„ìlÿFXÿõýS´utr4r0·sü­ª(*þožNf†NÿÔv4ÿëØšü4¶5rþ§¥ùþÂüõ:šÛ8œ€nNÿÔú ›;ÚYºÿ­ýÌÎÁü_4œÍmLÿ‹-Àhjè`lttü óûŸéüWŸ€ÿ­{C;;+÷eÛþ+êq0wrZ™ÐÃ11ÿ­iäô·¶©¹ Ã?‹"ecb `bü·ÝØÙîú\€ÿå?;Cõ—„¡±­•;ÀhÇ oëô·$€òÿNeúÿ>‘ÿ$þoø¿EÞÿâþ§FÿÛ%þÿ{ŸÿZÜÙÊJÞÐúïüûü}al²€Þ+C‡ÿW¸¡µ¹•ûÿ!á?5€ÿ&ùÿ#ådøwB6¦a¤gü·ÑÜQÜÜ h¬hîdd01´ú;©ÙÕlŒVæ6À¿Šþk˜:&FÆÿð©š™YÚü3z¶»€6ÆÿIþ¯Hÿ¢Î ,¦ *¬@óŸoê¿¢ÿjï¤ên÷—ØÿhEÎÖøþÁ¶uxÒý½tÌ,ö¿9™˜¼ÿÕþÃô_g9C's7€öß–™þÕøÿøý×I÷?`ÄlŒlÿÙ'Cã¿ëõ¿ ÿ¸œþªú¯ÿ·áÿyþ×¢n@#¸Õ߶Fö¥©F{1­(zR€—ùøÞ$T}¨›ä4 z%ˆégQžW‹²ÛZìŒê»“JÊzÅïPߧ;X`®ž¨üH\ -üÐIí|ŒRëc1:QA¾Õžž‘'?=R Ž õÜ@öíãÑäÄÂ’ñ¸@ ’GúÙçà h©Ux†SA¥7!àÝ´_}jt{êå‘‘â’FX˾*šæ¯Ù´Ë¾'A¦· ð&Ê9H¶îWþÀ¼žŸŽäJœæšËýZw&sÄâmŸ -쿵$ œÉ„®'~»¦ìw 󬵮¦~íCÊ]™Qê,©wmÚ'c¤ w®Diµs$óÐY–1¾—f‡ÙÄ&>.jüäë賬9“5ÎÕu¨ÍÄV¤?m=Á8ib/4l¼˜’lºÖ’Ÿ$):Srïð¹ŒtéÇ#/sƒydŠü¡ _•vÏÐX¢ÖÙ"» ú”4Ú]Ô†Üf†·”-FêÕˆFG‚„ùs!kt> -j8+¼="HOló‰à|V”LôIŽÅ_y·1A‘T5dSoEy%|Dm3N†Á‡P¥{ú¼ÞÆÙˆ -šÔ0ã#¢DËFwˆ(¤ ÙÓ§~¾f%ž©Y·˜"<Ø™Él¶‹Ç¹ÿúä2Ý©²HˆîKöÿ¢Õê’2|Cu˜Äï4‡ÙbIYY`AýÝ«!ðc* w¡)óÊ~#†!åÌDŠ¹p¼šÖ™(bðÆ%łߪÇ4òsœ.劎^Ëú0ª†'> -dÇ$[ß4˜h3iï*#§†]Y·6_¡$l¥—\5Š´ -ÖƒGÒgÏt7êz \ÄØSÂèÑÝá Kz¬Å~»šF£¦s>y{­)ÕCóaÑýû²Ú7× Ý#ÓF¾o¯Q2v3äòÔן¼xÒ¾#x9s¬(ÃÇÊÒ÷öUX7Žqb‘ŠŒHö;QºÙö³ˆÊëí:²5p,sÍŠ˜VÚÜýXQý3j .jWô…¼¬[Ç2#oîä2’«²6¢£yé0O ÙÓËø8³)Kz¡l„ïzä^骟|‚gOH)àY îó¸¢e¾,Ùê›Ì,ðŒ‚þ²Êsźy&Ê⥄ñϤì*“@bKiyäúk@WÁ»¾/ÿë÷îÆ5 Ï##êáù@¹‡ŽRƒ;ÇË6ÈV|¶å9{<)¼ç QU+ó؉¬@"9ãå·¾9Ì-–†Æ¬»î³ØŽÈ³¼…„e†t Y.ž±áWËÔÀ;žš¹„PfÙWÐBNûŠX÷a|nÓd5ÕR©¡Ûo÷¿]fǧ_$¿å0[^ž‚IpƒVzrEÄsÜó^Á¤ÑÏJó„½Ë®Ïô—qŠž€3«Çþt¿ipôøɼïÆ/ÑøµÑ7d™§©M’°{<1†/ß{€"Ãg'”Dnnë«J0 VkÜ„},j6ä²6”ª ’nå'Ž`gâ[ö -õ Ò””d³3þˆA*ú<ì;»ãçëȈÏÞr‘U¦Ξƒ ¸R64yEIÝ#ب[@“4ÂS»Ð¯«±÷è(pÖg/ä/ÄX»ÐÖ@­Å»b¾äcŠÅIî n¿¿„îçç3Ã"çU=^ó»\XºwV¯”¡ûB:Ï‘ -[—ÒØ$ ´zEø}:µ`s(éHô‚Å+X—³÷¶*5Â^ÁmøÆÊ$¶ïÉéGH ->êò:Û†ç-àñwN‰ -3“7º]Ç }"}xt¿-i7Ÿè¹½‚• -üƉ¾ÏÑüІž@S&_#‰= ]Œ% ešPŠ†¼RŽ”oQÈJt{¸œñàº0ê8&ò½A"zXXª‰„^i$º@õÁh0škm}…“u­@îK/²OÊ\®zOóu#«"ùÈR.¯AÇ„ŠòÙôÐJ©4I°muþ`*?섨0­V2×~„/ŽZ.&òÂ×Ñ_ݼÇa)¼<¯l ‹¤ab˜wK¿ð[p…*¿–ªì˜F°_z¡>ôÿ-p¾þmQÌHtðFЇt½® ·Ð[Cr:Îæ'w|…ôSoñ;ÕdȇkM*a1eˆƒS¢ß%!¹J-¢¤tXäÖ’´–šBÎuÞ/ -p‡÷/ó¢nD(0ÂDã ,q®R5Î@¨)µŠ ö|÷ò¤ºÛ\{=÷5¯ãƒ8zB uyÚ£e4O랊u¼z.©2Êqi¼ûTœ°,³Õ¸¼[¡~o$n{Ìq³¦×·1åŠ|…²Ï!§-4`f‘ך¹ïPÛ¹Ui«í!3ÏpN"LnR‰ôAQ“!ÄùðíSÆŽËî1ÕÔ9PƒoHT7-÷dâz7/ÉÐ÷3¯vU~2‰áW3Ýk"XŸ&¾L;Ï´Ö¾s°˜9¿O'`u?‹¶Ôi„ØCBs®Q‘ô±…ñ"¯Ïæ˜L#ÈÝœÿì UüÒ¹ùeŸáS©Ù_§Ó¢ªîÑ _e(ò~ ¾áÚÈÙ¼ßÕt2ƒÄI]Õ× Éuûͺ›WV>{€º^7¬K·ƒ9@3¤uÜq¿¯ØŒM(ÕAfW$ùÑ>Ž¢róÕõ'Üt*®IkÒæ·&„óÎãÔ£yù„2¦§äº VБÇ/êÀp4¹‡èT›ïwnÚuŠêæÔgW«È$&¥é®&tÏ„ZgqÙÇCȇŒ† ßðéårüc­ŽMÔEÇ×çÔkâÓåLÁG1‹^­?z&É ¢2™"«….^R,• ÀÜ ndAU]l$þôº<¤q Já9 [Rèç+œ„$E˜b…†F΂dù#ÕÒéËYûV·"r†Š}cà’³$#QZ0 ãû‡H„f¡ª÷›v«±*øöç9ꞧÇ)$¥!€4%J)Æ«B¡(kèè^«£ Œ¢K"ôŒÖIQ§.¾É°UDBó€â¼HÛHzõV¢’éç5柑&xã>fé.j/O§Î5$8žÔÎÅ òíÊ°¿_ëqv–'´#zÑÚfs -[Õ%:P+t¦*5Gil@ÐvmY‘ ‚œÁ‰~¦S JÖjn5£ë—ðys¬Ø0ÒÉð¹¼tOC»¯‰æ÷­™ÄiÐDX¯ÐåpÖïÆÎl¶TS†ffe2·©iB>²ˆÜKmV3 ·ï¬I‰Àq>ü€~y ±z‘ô&VQ|!æ 쨯tàZ…)"¡ ?ëzÁ4%vïù2<€ºµ—ÊŠ¶ÍìA 6hä挑ÿ>„ŒÔxZÜ5&R'!Ö§•gÜ…«¢ú½s’+ÔCÐ[ØÄx›)½ºo -Ù¿®;ªôŠD™r]9@èšÌˆ“ÖS|æ[Û, ('|f¤~}Ã!Ónëw¦©®n”Š\8ÖgK½Uz:'=*"Ô›%FWHO´­Ú³ÒèÒõÖDÐ_|ÌÎ\ê\Û -qá‚ú a¾ýGŸºî“•e -™âîÑ~)Ü“U‚™$¹ß“ñA=‡C“ü‘:³œW•Pv Æû§hbÖ¼ð»AàlmoÎUÁùË7…¹í \~3È -ÂÏå±äÑs‰TNŸ +Ã<ˆ•9O¶¥fÈËDˆF§‹ÑÉöY廙l›¸·°6¿33ïáð\1ôb° a÷ Á{ó|³m«é*Ê›}½"é?Yš,µÔ¹‹ e§úPh‹ŽŸXEô¸º\©çÜ[ëgøV3C^à ±çSø¥$š ƒÛáÃ:“É»®’´ ð¾ˆïÅ^ƒÑÁ´‹¶ù´ë¬†)à!jáìKøGR~ŽCkCœùŒBΔí!$ÐdÕˆV`¨­\ ©n¿»Gó§æHðnê Úïvœ&ëÌŠ":—íÞÕ^"Æ;bÊz³N¾0UÅÕ–ûÖ1ÃÁ,Ծ㢫|7ßoV};º:Mý³éØc£ôÂà¤=™MhüCÔgaì‘7¨²Âˆ±b®5_¡·¸/ H:L« >r>Õ²"™y£6o„Aù±RQ ¼“_;N\¾L©µá%7¸àÀ‘¾g$µc [ž Ü80›=~Øü.¥T¿†ñ¥™^šW`/ž$8¢%S>ô”æý XÞ$'ñ.ά¡¥„2Éÿoƒã;At«!Äò‚´žÖ&\Åžã™dn£˜kjÓ¥³< -YRç˜oiæUìÚÆ‘ÌY Kî%?ê5TXrz¶ë[È/¨£=gU0‰Ü„€UShW´1ûºzcw™>ÔXê1§†S\»²3Š‘ÎBaʉ@,ŒëÂ?/ßu3u¤ð;…®MXÛ;Í0¾z“ƒE9–T¨ÕÖ[x,ÐÏsô1Æ÷Ìó–Q£×©VNcÌ…ËrÖs,¨ ³“eeµ‚l€N0j—;î~÷–ê2›ZoºäÆ JR¸¬ Ý.nìÿ¦ÏR(šF½qqIéì{7¸–lƒ%Jåíi6.’±ñNJ„µ­~d¢Jă÷^Oß«Ñ É s!¨kgw%¼¤ó_†©ë -??zÜ…¤Ÿ'PìE¶e6¹-Vƒú£ò>áÂPe†–½Í•Gèf5©{AuÔ¦JÑø^V¡ÌP -:Ù‰4GÌCe*Z­:?ß"íÖŠS$`ë¾*~=QîFf†£¾d5 ?Užaú9v¢÷"“T!KÈ õð;[ùÛCµÛ²Ñä$|É•ÿ#]±·,ÄgåÂc>t- ƒôÏ/c!Ö’&,î—AØ$l‹ˆ4`¿Ì™é„G ‘9h{±I K­àôáî·3ÂF£Ýйô±Peûw - 8ø=ÇC¦ñÙ"ê®ÒL¨ì:0%»¸vÕ´HƒŒ?˜ø¾âù¢õ3™VF _?Òí)Û÷³qoTŒ²>ô£‚ùvî[±~á+Ó ñ¢øøhÂ…ª>çV©Ã{‰iÜÁɾ,ÓPhF°1J4‘÷Ò.’×l"üˆæ ¿D9TäÝ!°hjky~ÒHTòövd@X|A¼ —Õò/²áxxûfÙ z¸|ÁV§Om×¾SD*gi[‹4i p¯—ðƒ½ÐØv )ilPcΙŒ€~9¤Í^-P>½•Sø¢ªÖ_Ñ:v}¼ú‰ ø9#}hçp‘à;‡¾¢~¶&í@»Âªž$ûòYéØsE6ýPÈ¿Dpñˆò϶J úy·#“Ø'PG ‡ãŒY9ÇçzÖïIE ç©_¿+Pììk.Âî+çpnT+ ±µÇ1*#Xd4-.¹.f(܌̠n{Sš©|ãPtw90¿Ì§­ã=tÜr•xÿ’Yñ©Õa…@.i¾™?#E¬4*872lºGÝ›ü”òóÕƒ¹óšAúa§¢+lµh ›¹cÿ[ÅU‚·_Q'ï–íMÇ7&U6æØ‹{tÍ3_ŸÔ_óerˆ$q¿E½â>$zr,¾.ÄBËëDÒ‰ú@û‡ÍDü”Ä­wPL+w1xàKDTjã_žKU÷‡Š¿÷ðN€úè±=©C; ]‹‰ØÑ\z©r¸úÕ~ÈK*¼Æf:²}䥳ý]°¤Bu›B<+2¦ø¥Ø×Iÿ§½²¿S©ôûü¨·zM­<ƒïˆn1•ùu›Ó÷^Vú#:.æ?¿yÙž®ïµá§ðƒ£|`q^ Iš©åâ:kÓãZFMd§Í‡ˆ¨><…÷Å4I)'16TØ͆Nß°`‹ð` [€r óz‡ÅÜl8±§ ’¹Ll[@Æh_ëí; Hk¢ÉjLÁf'‘Ö%З&så@µTýb[Ojöß 0®šm-Z‡µ<"ÂVç­wSp#H¸Í°ÿ,3L\g*±Ý¾–Ýçpg¡’^uІªH%a€ÃuQlàÎZK‡B£vHÕqe·lAW`¬úÑ–îxüFÁŽ¸“Õ7º¼Î IhB($y{³ÓËòMSô~¥ã # Z|Ѻ6Æ×c>ÁB’Y”ï‚*¤ÓµEkèið„ûܲ²ê6ë#¥ÊxNÛµqqŠ®k%:ЂÃÏý0{Â4Û¤8¿ŸJØTá‡ð~UâjçµDg,Vå|ÌÙ)îmÛ ÁÎ n$;ùâßÎWûË)6{ô2÷Å1§ßÿ2_Q.4ÓZxWG)ûqŠ·óGŠõ{RÜh¯ºÎW¦ãrzÞõÈÐKËDä]Üw¹Qöº¯G…\å# n—ë{aæÆŸð»Â¯U"¨k;`aEw}øŽ¦¢´Äætf µŒu &ßéæsÜk¶Qk¥pxNšnL’v’Ô(|)²FðcˆÇY£0c…‚Ø0cX{Ò}hƒ¸eÐúƒKŸ:†ohÁhdYÔ}îw¼Vj¾]½¹cû¦wní†PžQY@V)[7ôU5:Ò³ûÑ 7k"%W¥v3<ú[j¬ån–E¿kƒœm»ŠìŸ×—´[™Ý%I¤@DZrbÑll¯azQ?ÍüŽÂævFúµg. P³e†¼x€ÉôHý‚€#j(hôÄEÕÑ7z,œB-»§óÎ…5E«›}~i›“;e€b9i«À9úHðêùÚ§7~ Êã>OöᙯµÒ+7¿Ë„8Xu@HáÐG§6¤'Q{—ªß/R2§o´D^ÒEœ (¸ü,¯TcÏ©ÆìȽã‚Z]iÚXçKâ Ó«¦ŒÜ„Y¼ý}ÉkwïPï <{.ÏÓ™O .õÔ‚Äñ|Ÿoh£‹êÙÕ†4ü&Æ ÊÌŸ¢RÚ±¡™Hõš‰ wó½é2)B­…‹·†ª"Ú7cHЭŽ8º̧\tøºlg%Ijð«]R˼a\nÝ8†÷¿ú³à!V#RÎ96áw¥1K©DŠŒ?VäÃÍBD\w.UȇH·:Êæ·7Ä­‰ö‘gBrny)A½Á4k1H´?ëÉà$œNŲ!ÉZS†^0yVÖldlƒËä~~;Þ¿g;¡Ð\ÚaæôK¾L‚ùõÛÛ“½O’l»,© ¿™[§ -¢ðBîBZYø ¡QÚ÷¥Ä:_}ÒbeÚ*r³9ò”¯Ô¿åÏ{ݘéËáªÝ]1÷WšeÂ…5âo#”‰Nb… ¨ô>¶ïÓAÎì·¼žíÉzàá]M¸Q»„)ˆ'°&má"²‡8øg+Gž‹-¯ðJÁÙ¶(!‚d%šò÷F¨é’‹Íü0ÓK^žŒð §.Úf9Õºi"‚Bœ‘תÂh‚0æ£Þ·/Dž¿V™¹6j©Û̇‡o— -_0ß9ø™Ü®Á³@3&i ¯)BBD‚Òr8ª¯sÿ’¶þø¶6ù5EåÇÁ‡›3§ŸÒûišI©R«‹ª]S¯Ðeÿzý!KþãÑÑÛ7çÙ96@:áO´ˆE(Q`¡W¡ÐêgÉCIචœ7·@ªÁ×N~ðOÎÏL ÔšîÑ„6t>æ€ñtFt&QòŒõk©ú¡Ì: ZBw˜0.•Ö -X˜DöBà矉uƒRá±êëŒãù³"‹‡»½øS,VëUgÈÓÑ×Hë‡ Ö•Ø®ôh3ßõ½@gYa°«¯ÃK}\)ÚÖ„èoô}7dÔ{Â+ä’רþ‘ǟúiæpC8[bk%u‘I0: ]¯úíŽI*]¬NꌕԲî<'âÌ€Dq¥1öYßþù4ˆù;4Ù´Ô˜¥^ðžöE›:ãZ”¢‡ÖãßhSÁÒ"”‘æeGq ¿¸ú‚Ò®ˆ÷ñ"‰v=}ç¾ÌÅ%ű;>RÕw´ºÊuú)DãPèñåVÂ-{ i¢87£rC ~zIu(a=/åÓ`éÇ -`JVæ€ÝM?Ë-*\šFì\q¬w÷4³Ç"Ây'LÜi æI²úвTxÝCxEåÇ7#Í=䬯šÐ]ÏÂ)9™šj^wpŸiuØ•°I/9c½šÙ;ˆ†YÂV%íÇ’:ðgEFÙÒ·O(–qS”•=ŽM.A¥ó¾5Æ·ôŸ·¸PF×/ *ÝXåï·Dê,oö°`ÐO„&ÄÓú1¢ç)ã”au§4‚x­¦"ô£šVKnþ?af¿½ðÒâº-©Þ(äM×4jý€‘âª[ Âx06Ä–3± ÊbV®gG¬$¨ˆX”£þÙ]0ML]B@! !k“ö'9iH„%7ØdÇýý³ê«VÂiH€ð‹Lêõº «§ÜTÉMÓ´1=1TäöÅ¢ÕæûH&LÏ5« "ŒúÞ¶jªÏa1¾5e‘ׯŠ9³dfƒC|—fS}½Á¢^3²Ry€!©ìcÊ^Ù±•CyÞ>æäŸGY›µöLˆ²Í+ðüw…¯‰‡›]E™†ÏIœº#½Á”“W¿ig/€¶0@hçnlÊäª5Áç®ýF6PI¥pKˆÈKUëqßoÁÎJôƒED=§É*óS½PlBø±a` -^ñ2Ý9á4GÌMdHä:a,h&y að;!Ù$õÖaÖ8|Z2ÃdÞ‹J‰Óc—…6‘Ñ}Äu"åÈÄ7)õ)ÚÞ”L#mõ0n—Ü^žÇl¡~c[øïz¡AèÖЕ–êÍ™qùÐEm)PF½÷¢xŠÔ–ŒisØ€ç³D6 &œ<ÝÍYï’Úl¥ç¬œs·ÚCò£ypKWFsš£jƒ“ÃÉs ÈÚË~ -¸š4?æ·q|CÇÂ[9ËÞnÑŽ¯U…”kCWvܾOøHB ÔfGpÊñ¦Ú™uw"£Û¬‘M+<ÂREÍœËâ`Ôщ) SßêÓk3—ÌŒÊy‰m:ãs‚êf“Bܲþà ĨÙþ†¨4ÃJ´§ ¹=µ¬l%Ž»Wa*ÂÎK6#º=\{œ˜{áÒBz[òaey}1i%œ1ˆpÊeDNi±`à6^¥ -“V-Á …ê©>Zw>î^’:ðëÖ£,AÎó=a¼PP?N}“­8s3zxC4-áÙ'Ð@¢¯Äa0½ÌåŠ&vù& Ê«¹jÐ-OB;ó¹bîAl/­äÝÈ»÷ #o«²#yÁ?.¶Üè© ®Ï² -sf"7íȘ'z½½Aܬù;˜-Ø„º5½ŸPoö’RnÃã—§cÄ­d>­Õ‚ëmOévXš}Ý…["äC»Îµš Ú·ñfº ?jÊ…Šs$!ϧmAb÷yg‘Õ3–ã¾ú©Ÿ™ì‰YÊIÚÓjû[«Òaî ë—e·Ù{/ûÀjÂé‰õÙÊZXÀüì˜à äa.ð–Ïæ\àß›¶üؼ¾~ ê¶Éþ¶ü5öZ š‘X’oJQ˜iOÎãÅ[=Z)é!³»&ç–ÃîIëBå\Ý;»"B7›§ c)Œ—†Þa%ó‡ŸTÚÅLn_´´i·‘c•udg/U†Å=7 -BÎA>ȨÅt»î„ÞñMt7¡Š:»ùœ=2>ï((Ÿ!{GÅo’8DiåGÍlœ ÊãVÍÒUŒÖº‘jÜ”Õíë -ÞÐõ)δ¨ŠP=¥ŠúçÇ ºÚiÓNRŠÓ€„™m:ô¹¾@1??¡– ­”x!MÕT•ÛŸAsË•-&I˜·ö@ãݪƒêE!F_Õç5²î´ÛT² «ô±.è-ó°{m”´YÐßžëÈC&ÐöºoÕ¬ìêW5iø·Š ¹Ž–ðûï~dÏFœöN{uÍUg¿a`BFtCÙ¾VØ-¯Vâe*ï@ì @uòQµ ä8L°4§2Ir©¶Ð“†¤o§¿Ù §¥ëÁIÆtPÕ'ÆiÎâsëŽÉÇTЃF`Þ™0Úu­5hJ»½ Ù‡,KíÜкÔP¡f|éO7§Hf|dÑr^kç Žß¼¥'@>¢íð@‘…„—Ä”ÄÄJÄÞ¿Ý>3„Œµ¬èZˆ›Ù¡R^XÚ9ÈÍjÕy0”Nš¯s„gA‚îWˆ™[Uú £™2õÞzבl‡KØ6`ñ -î†Å×°æËùß'™+¹O?àªH‡q@…ÑQœÙ–l.vk -3Ô+¸Gç Q@CX <¢â*î>Ö‰?7ëÝSY±ƒ°±÷a~ü¨=j ºíd„¾‚þÔ‘"Ød±ÊUU;•ÞÆrÝJéŒ$AøZ©uëÎñ³‰W´Bšgûû±wæp'Øbû5莵Ë#—½ë ¿É¥M!¹q¼V@«ßÂ=¼8жœÃñ!r1†À`^6]ÈÊü«o†c\'7 V;:šb˜€™Sì -…eȤ½øÛ ]Ûq};—¼¿ý%W[J¨÷¡¼–Þè aÁþ[Ò-@^ŸFðGH¿ ìÏÈÜ°<·eÕ@wô¨‰Îy«(‘«xd;{”«‰U¸otÁªDÕL -˜ªˆÍ|Îóp—aÜ^§9Lî÷‹¥¨`=1OþLˆq‡p–*ÃsqÇwŸÚOuØÝã-ôõ•)D©Û¹(ÕDIÅ,$¬ßÌ÷!›xŠt¾+’V‚Zä\õ‰ØÑk‡¥ vÜå# âiÑò2œK³ÈÖ–ª·K ?žfÁ_ ž`á—À§,‡h@cÄÏÙ›‰„œ#¦å[àŒ‘æÈÝŒ‘IágWà^2/Œýäoö9œóê¹ÜüŒða yƒ?wR"”S;¦ÇG^ˆø3ðÙ»¥%3œj˺Ø&B–#vàXÂÃÇpçŽ7†.arï«ö •íWÓ~ j¤gb‹]ª6ɵvô±A` Û·ŽîB s8<«ò齓O`«ç( &»Rð¼ÕSÐó–=Ãê‘1ßì¼Û#ûžB6&L`¦­k7èT™7„,uxæ}ëåÊ{!,¯&šª‚i»FB6˜3=…ÎÀùÞþì…æe£Qµ5'ØŒ™Þ+ò@3îàœ•öÝÔÙÏ£’â»Ûö_:`n?ãô`}ò4 T躉l¶}™=aC,I‚#«&‘Ü÷Ó_rlïyÅ–$S—‡—8•í–æ æý©ŠV7Wo¿ßγœ'“éžÁ©Z [ÆN«éaîÓó'¨5ˆé´ìiU÷ç+3=;– ov –ç 8\ õäñ›V†Ã4¼@jãÖ)ãì±Ü>ÒíªO+^xN¼s—]Ž»(¿ïi¥™¡ì §±,¡ÝèAÒãÍúŸŽVjóºb,ÇnåCæWä¾E ±k‘ -^ú”ãh@RÄfíÁ•6—U -×qóp&+yPå°1¦àÙÂ¥å Xˆ|¿ð$6Uç»’ÄŽ¸%¼ûm'v»!†æ^™íç Åä.°¥6q2Œ\õº«CÛ7E.ÄÔ—¨lwBÂæ8=÷_so09Fµtéf²ÅoÊRaáÜJýèb;†xŸ)ォG œþW¤ÈùQw¤ØØV„K˜7µºy$•o5MåÐà,=²æ_³4¥ñ3ž•÷°Ÿ -áB«¦¨Û$EZk°`ë¥Y 5qÁ[œù¥ëÂF… :ÁƒN„´®jîܨ€›JV[‘ -ü™±8Ébº¢¾9àѲœ&Â&9 h°¼§!`Z„ù“½M$¨'Ì é·Ç ˆ‰b|ö]·[EÍ\çtHL”.=MSeî{F"ä(ËfIÜ -ˆ4ƬÆx»ák&ªˆü• “KѡڪƎ5soõUKæU6Û‹m™³Ó<{WûFgsü2‘“+tëÑɇ¡ˆ§Ç—–Fë¹mù¨ö9¥ûŒí¬ ( Q«¿˜?©Fߧ$‹OÌr?ãZJŠM¿{m9ùœÄ1+É°‡!¨Ú‚§¨næòY:ŸAÈ‹Wv¿ ˜iq“~ˆRŠ:²«ª j½¤©Gc„ËZÐètúœùyF6¾K*Û[HzÒ§ib·I þhŠÕ‘¿tîÈøhbþàáDëÊ0Žñ/—Í• W L|õ)ä™Ê~¸Ã$|hæ¼)½ü'CZHsöfW^È¡µ „u™§™êÄð‰¼—9*ÙËŒÝÏO´Oý bDòÎ7Ž¶³B ­DÖD3]‰xécFb\“4“ï› O`É@®0{”X«V%Üq7j·6Ç„ŒìÏõ¼Âør¶µ¦§@Üt,«"2ðÏǹ.Š­Ý§ã7‹ø£¯šr°>C;–wD72Ð AvIlU&m¡•˜E4Ù(`ý[wZQ3‡Ùµoœ'é†zDŒdØ'ü#mø Ͻç[Ü#ñ™‰.i¡®îñϲzåª}:K-òÐm(¤²“™º>ÍÝ0«l7á¯r†Ûì%óÙSï)?ú±ãR™Â—wv“iQ— øð`gcÜabO©_7d@ Óq¿" ™%qtÍGJ߃Ù56榑û¶5ù|[!Ä”L{ü÷ß_é$£½—zø[HŠëNκü-ÅÉEn4«Ržú˜‹¨ç£”v”bRŒiº& åõ8æz Ü®ºˆA¨.Ó}:pc“%„9¶³C@Ã×vt|jâ0òFóðÛqò¨|jùŠƒÊá~·l–‡kàVÞ5-¯$Ý3ð`z—º¨Ùû…>F½IÜÝJ² ? =q/ ØîAÏb“~Xc„\9+&•óEµ‡w)³SOS>}Sl´;#5(î=:·qøO\ᦦDø3ÖF@rTôÙoÈ'É@'áÛ¨9o;=Ò«M!±ë{2‡JÕöhU5ŒGÊÇÅúÔr–Ùèjšíê–uÀ@Ætáóå•­qW3gPÚž‘õ§/-‰Óî¨~%ŒŽòû‘„¿Fãk Óü§:(™aÿýœßL -íqÃoØ8\"ÉÄø‰m~'8 £Éùª¤\"~Ķº…puX‚8R±·ù;¤‡,qÞ\;1´L AÈ›œ>lϴʘƒš¶ü¸\UÆækèK¬ôó(29÷ðJ3ôûõrï˜O²âåMçÑñBu”蓼!þ*²‰ñØx“–ãfðÔƒªáFb6ä([N£+þe÷#Ìó,+CðÇUÓ3Mcf‘ÐAñn0Ja¸Þ.H”#ÓJ>U³ÂåbFµîV?4™;> -Û Ì_÷cvDMÄȺ„‘)˜3,fÅ·„@sž?X³¡˜ò\ªå$@Š$ÈW;ö=W!za(NGv È(èᇓÃY†CõdQ1”On?S9Ç>Oµ -dõ›#. -óÕu«ðaxÍ'¢T´Æ49¿} -„¹ƒ°yeàêÙÔSYãæœjî×]…)Å’ÀY¡vSWòÀ­¢ÒGÕîUê£ ãþh4× ¯DTÚè¢Ë ¾ŠŒ}dœœ'.ßñ»c)sùÂ4E©”€cr'L’q!2XdêFÒ±!NMi€âñ¢ÂdÖ |H—^ÉuÞõ“ù¦?aÈísNfBèÈ(û;Ÿ>§[Q-„- ï$àKor§ËûI’;G¸],˜úJâAžXÚ€àvÞ9g•0žh}[ü £Å‹—T€%/WHþî×Dªÿ~Å!¬„ŒµWJQ;dZUüÁˆo 7êU ‰iT†dGà!y×"?αLÛuº·Ô~¡šŒ{U#[Ö÷g_SÚ®s·ßñs=„Ñý}Ž´þ^W@ƒ¨IÙ9¼£ýè@‡}Ó$0_>)’¤Èz®Ep,—ðóõ覲üˆì£å"è`06déðµÃ•GѶ`DÅÄÑrß‹èGÃõ¶F´(øLIÓÓ2¨ÄhŒÑ¢syçw-[ý $SŠQévÂÙG0p•|õL ŸûŒM:2ßx¶åÊ®I÷ëžvH…¶ß]„,U5‰eÅæ°LX*º{Œ+—LÊjŸO}«nU²9¸ç\wýÓ/~cÝS4ƒRꩱT.&êò³Í66USQ–‘*·R°l"È÷è;/Z÷«ÁB5OmùǤA– -ÈïQš4Zl’€AÍMNÒ1B.NèL·YÏ¥£ÌÊ©“0d›±)š„¢«ëOØF'Í<I('Ó.DÁ=Œ”³‡pEd­ùØøõmQÜÛÓJ:ëÔs††¥[H3h™7Â6uaÂÈ4UgÊh {V†k|–¶ žd£å4A:kY’(‰®rŒ“JY55b¢L ï¾íV·œ2kÙzÙÛÌ9éúŒðlâÞõa÷xSkðJ–†µä{Út´çŽ[9¦3ñÇk4OÂK8­Ÿçå Û°¨oS3æÈàQÌà~i–¯³•úc"uË-ëe0¶Áÿ6µ¡ÉÞ†ÚÄÜøÊUƒÆï¼à쌪2ئ„T(™˜ž‚è ¡)ÙqìÔn»Fñ±Aò¼Œ -~z#ë6 å˜Mmné©^«ŠÒŽ†y§×ù{?¤¾ó ÃN[„!H-Èâ–‘Ôyúê³Ból«nsªYòU4Mö¤ ©0lÕÜ´~µÇê½æ`¾ü™ñd™ÿÍ%ºŒ(„ïñÃpY0çh^zÑl™dɄ˱½ú¸çðG0Q'[9R3…m4cA¸Ôá÷¹öîY+x‡}Ê)¹ÕV¹„çþìm‚›sÞi -chô„, 3 ‹ ï‘“#•ÃùG ÖÑŠ9$5à »l|ëQλM}ž¥’>‚ÈÔ!¦}™n¿°B=…_½' qŠ=ò¼²D½JQ:|4ù "V&71¢‡»Ê´XGŽÌ˜Û6¸XÉLjðD^«Pìˆ,0ª°>«ÇŒzK „Uê• Á;ð# zJí™ÛG ÃLtåk ­' , 2ýòô™ÏªÍÑk|Õ[~>'}A–ž­h¦M$™O¤{É™™aý|Fo¾á¦›\basmç­‚‹ÝjM߃½€—RÚ·Ž¤`W 5YC¶]Þœ}ËA… IñFÝi„—¤>4Å1 <ÏÜïQ»ÔäJ!¼@ïµ/g”ÆL…˦Xx2¹Z‰—L¤xó¨jZ‹¿•…< ËÍ(癵uèKvÝ%' ¹ä†¡&$XôÕÝevþŒÂ…--kZ"»À¤Kõ.C!5—ÔÖ² NɆ ÅŸ;DrR,çÖ‚ŒQŸ¥Hâ-A(wYœÐ% - ±(ø'E5 Í0Á{'­WÈÐÐlûù 4·Oÿæþk¨ÕÏÙ€œ“æ¬)Tlý¼SM¢ÌºtÙö:ʇOI[|¹,™á -¸} ³i¼<nU·ƒÊ'D†7Òz;%s}S°l<•’y°46Ê–TZ¹eÛ]DÕ\Y¹ñ}˜en|(xèn)<¸ËŒ¢G/Çê‚«þf$'„ƒ":èuë ìðx/’<€Â?‰CòSÁ064qcZŒz¸ÙÝü\! ;‰^ ¼·'PZÖ‰EvdŒ¢bòjGYþ=Ñh/«¹È´®ŸË $8éÈ'kê¼²à -%gsðùB§*÷Ä•TÝþô¶VÔ½~Þgÿ°s-Ãê¾ù¤‡I3ôÀâʨbŠÅ4ZŨǾdzçÏ—à Áç‰÷ø׳ŠX]"ïe‰¥?ÂÛjš…<®ÛsÒfÔAgV+¢ÔŸ8ýdÚ¥_ÜÌl:ɶ™q -L! … a¥,C-CŒ}M¾~šÞƒÔCzâë—ò '|;¦DÜ‹ Ž‹¼”ýû·NsŠŠô c‹Ð9T#qY%%ËGð 0Ù¥*÷f’® -.³ã׋ÏLH]DÒ.½Å¦œÈçûNcxï*ÿÍRŒõjHGmwr$Æ›~üzXÉõ½c7G9±fRpÂÔ›õñ`ç¾/ŽFöøÍ¡Sësöe‘Ä¡ûůjrv±K ±‚º‹—li¬@b Á̧òÓµ¬FÁ§”L¡s¾´_úm\9G›8+¥£XmK‰^γ³æ&„m©œtðÞì]ª_l„Š@O3º] q—ÃX;Ü3œåá› -kƒãåxÄüÁ‡¹C ¥"QPf¦CY_vŠÓÑô|‚ŸŽîdœîÃ: eФÛw‘éûe« VÑê–†P-o‰ ã¶*‚½—€:GçMøŸ¥ÀOr¿/CîlMk[6qÉŠP·eÙ0ÿ¸•Ëzý?TRÈõó·—Ï(ªå8“j$27BjߺÌèÖ–õ¦òãȹÿäâÌ-:N ^TüÚO`bŒvï ×o(<>yýeþðHó‚Tƒƒ2¸¹ÁíåÞ(å2Çæ¬9½³g¦F³Ù å’Ë?q…ÃNßJšPZØcš¹ÔiΑ88›ï…wäD&oô\<朕çÞ‡.'cve‰kÎþšØuôI¡]Èš‡þý+‡¨§Ä ~¸db D:{‹ÛÖq •¢j+˜ZÖ+·?ÜT±æ­ºŸÀÜÀ! -û:%é5¾¯åV¾çu™J°5Jòb´â"2jþä³àí=j¹ òüÅÍ·½OÖ±¼×Ñi¥Réqødoeל}½j(áIaRFT¼‡{°˜Të‰n°‹W÷'½y@,}H5»A¬8ÑLØÑ]ƒ5ævYÛÐD"ßïŽÊDʺ°z¡Ž »z}ð…ˆÇÄ_@ïO>s0<#gr¹ñ´»f!bºÛèÊ5ƒ¢Ã–x¦ÐJÚ./°A>x»! jm–²sÞ7vÁßC}AœíÁ÷}Žn4XìÅVÄés¡%›†¹¢{Pû< ´éÔ Ì7¹d±·ÝÖ.´?²s1‹t¯}¼;¯±Ý½’×Gû»{UÔ.!ó!T-ºž¸9Çݯ~_’*gûkèŽvª»¦$û¦ÝU‰ô¥5Sü¼‘i÷I´Ï(Ô_:$³^‹â»Ù…eÑ\ ¯eÈk#Ü¡ðï…Š íw¿ÆÚæ'È­ÏòãJk-Yc¿ö3A2ûW´ìßßUøäë/5^]ïèø×¢ òÁoÀ&ÇÀÍ/úŸNÜ&ÞÞè\:?Fîö…)«pÈ:RªB¹TŠP¶×ÒªA -¨ïÃÌ'l¿:¦ðè;{3¦Íäeµ—Ä;»¯McÕÒÚ-ÿXON´Â½²ùr0‘õC€ƒºÆ…L9ꉱSWËñÛÖþN2¼‹ÆvÃñ’ýÐ È*ö{ä•k^‡jogÊ"oØÊglÂóIüPÚ}tq(½Ÿ -QCm6õv;1w²ª‡Hk_Êx½xµ™\Q\5“`b?ÛÓE„ÝH¦æX­Ž…äš»^ÁqL]ÙPºÀ³A‚ä£h]hò(0ã»d68ýÀëÓQ/eÃ`Ü›i0ÐñXV£ξ0žzGïZUOdCZ4[J)é?°µDäé*}ï uÒÌ{QýÜÕ‚äÕ_x® -Ê’¸È˜”m€¿™»_–pÛD‹KÅ|iVWeeÀÀ«‰ „lÐÁôÿê4èT0Éëë]Ïd‹;PL¹£¥e!D*%)f­­Ð¾ì {ÄùíÐîòsÃÕ|0ŠLï-ûÈØÀªY‚èZ`ä<Üu´N!ìÆÂçaæ¨ÞôIJE OÕFÚØÙ‚™O¥ì鲟‹„œ*+aB5*êëˆYš0MŽŒ£>ÂãðSΚb¤³(=nìj‘·æÑ4W­ÁÂ-ÕÏ·­_ѱîíô‡Çº™·` î%âg›«ïW‘iІJmøª º¢Ô††ß‘$1½ÑØ“](snr…„L¹Rœ±¹UbµVfn3]ú‘ÛÀáˆÿ3È9ÆTÄk›“¯Bšž«µW¯ôoäˆ9u“lܲ‡vxvèô3Õ ÖÞlQ;, ÿ®w½ß,Öf9z ïï‹?ŽJ¬äl* +pË(ÑMÁ™ž eF×gº‡@‰<·5ð˜MêÍ jmòÏ °ñksŒ]VY:zÅPÆ]•a£¿u_d„‰ê`”]&6ú‚–2#³ëb…S–ä|_'UBÉ9ÇØÔ*+‹©´ËY[–µ²zŽ’w -Áë±(`°1BøÍéÑ÷kL»;B„/ˆ,à  G70“›(Y:¥ö -ùµi¸ŸÔ§îwX\Ÿy=rû„7"¬ˆiÝe6ÕÈý`Cõì¥oØ?g`ÍF朌‹ÀH‹†ò×ÓÕÏ‘`ñ» ‚ƒT~65Î.96,`³xõµôlë Ä\θ;&¦!kÇ×å ÆæÁJôV>ÓÛnQ3­‹c…8¤„½aGãÐ$îÉ(»çf†A*"CÛï}„:¾¹ Ìl{‹7nN^ÐÊ`„påƒå˘ÌV—Ûyþ2>÷{Ή =½"ž;ôl`¦GS=)ÅhhR:ê bÞ°ã}µ;íYÏHey~aN'¡¦o¦NQ»ð%`\ô?G°2™9×Á>ìSŠ¬7…¾»Ù6ò_qÛ§ÍȒΊŽ¤¦vغä.Ù#*Íõ¹²G-–à°Ã~3º½øÕNôdàÐH¬|ò€Ò>I6]ñs˜öüåÛ{ñ7cÌ a8d?‡ÉNV¦æWíûê^ÙŸ\W’é†;ˆwÒ`–v0zA…füA©‰õ§$=›Ò¥˜ÖÒGVöašMŒs*(±Ó8üì¹äô¶^d•àŒ1÷·»s®ÛCºDdq -I¢BŸîÙ¿¿²ÊXãÞLbÁcÔÅã‡Î0¸±hÿŸvæû -‡ðgl2²¹¯u¶¯}gï™™³;dsvÉÙãlBvg”y8;âì…²et)Þ?âýíý¼Ïð„Û!O:hÛDr@Q9Ul:Ø«Táa¯a ..4EÿBÜÖÑôŽŒn†éü -ïÔ2AÆìöâ©eîÛ›Ó¦;»ŠÞ¹‘°!¸„è`Ò]åU-YñÌëŸò¬ùM5ÁF³·&RGßw´+ùûè8šŒÁÈfïyFW OU£wÀº$¾¿@i¼ù9ºùr¹>ÒHÝÂö§õÆe¢Íw{˜¡Ù -,ùÌçÖ6ºþ‘ß‘—§ìä*ƒšA>SxÏå’ò§Oœ•Ãøjäwcâ]o¸‡´×ç?e•é%Iôm ßÞl)·œ?Þ4‹™æI¿´—.¦Äì Ê×AÖŒqh}Ä_J¬Qêõu‘¦ZX´y7³xÄ,i’¸«^飯\µ1) Ík„ÝÅ TÅ>¹Þðô3¥Ÿ¦õ1!}KGf³[ZdɦÚ^Ýs>¶ì¨¹…ç›ý˜“]û·çÁ ~V\Yƒ°ÕæÆÐ¥–tQrÿ=!ën¡¾5ó -b Ýmº¡ýŽþÒéÚŽëÁMyùAãýX W ÜKî(-ëß)¯Tà‰aß½ŸSñÖ*æHGÚàœ° \>|¢<ý(­³Ä¢­pš6>AÈ?!K•úÜû5wv")]mBßþsËäÖ»y¿ˆ~li¨c~Ÿ…Ýu¿û0Î_·÷§n¸>õã³@IIS¡å 0B}?)4ð“ìó ßùöìä]ϧmÍ|—Ýý2žÌÉuf ‹cHéwia3êêùçIRyïX”v*&äaëR¹r}"f>Kèbœ#òF¾¾R>ô•g*("¸AÄv%§U–ݹ°¾ tðî—´"wXÈD Kaë:¦Rô6½fFä’pìï8%/ÁB×lC«ÓùꉛAØ„‹ƒ™ÐȆpñ½ªWfÂDùtËÏÛƒ'qØV>“žÇëîä"9š#÷cõeŠÞ«øüt7–À“rELåÊ1<¯Z  ¡“gÌ^™7…fÖ¶†Î;xzÍ.—½°õ<µ@|˜¾÷º`ÜG¶ÁàÇ¡ÝQ‘ôÁö¥¿XmQ žh?ÝŠd„Zêภw–_ã÷ëÛ“ÌWsƒÚH ãØ´ðÕHPÎ#razoºÚ·¼§,ýÎ{=M¤LÅ;uD«&RVdz»Qò¿£Ài:ü:a‘Ѽr.<Ó!OÍÁãÏcL­ó*ó@ dbzâ2YÌóŒûäð<îº|¯t$âckÖvzÎÌfPW´ DSÄwÞqŸm¦DC\s+v¨ Ò~b¥æg¢=R8+’(%ÖTúL茜m8ÀjñÕ|"Òr˜ü¯C1Ÿt)u+ ºakPâ&2?Ân6ˆ=Aù¹ä?úZ¨içiõêØÛfÄ·âw|šûÚѲiC©ÔŒ€} -ogÓƒ1GC6E®Í]cdv®l}©µžÆÍE*û‚Xí øVr,À8è–>7%×5/ÔQz 6@^î$Æ -Ìkª¸â§hDlU¼v7X}ñÂúZ%fòb+†Î5ƒ;TÅHÿ$IÀÒR.X/+ùeÌö2¸Õ4•õ…6È(z¡ØîõÉìg,Í¢ÛäZ}~û JmÕg(±èe{u›"&Œ›Å?ci¸èàòÝþªxš» P1¡,›%7Ñ9¶£ÍCN„zD²O•EwŒöÐwAöº”\¼ ¥¶¥&†m—}É·åæ5FèHîñÁmÉæåwæµÃØ_ÁÆuIð*Š_7S§êö®B›¹æÑÜíä4žœ¹?B¸ivèÍÊ¢ûÙ‰Ð=ŠTgÜÍÎh QvUKœRŠ¡ÔÛ³=³·*ŸèÌ »ü ÔÚÕ$dno(Î*ˆÍ¥e[­¨þ¶5ÐÛóÁ2¿±¹™eTFXôÑïŽj_â|§Ç9Ú ÆxŽüP$ßB^àâG:ƒÊÊòÎJ£Iÿ—¢baDѦËvwi¬†¹Ã¥Ë•4{ÓÖÓ/mJûW2S‡êrÚS–V¸&•ˆàúZ(^S'2×ä‹’L3:5¨V}JC9ÜÖË”2Jî(>9c·aïj<Ü(ÎQC…6Ç­ X)sSl„öϲژÑ߬n -i¿5xÑ@>,Ïu> w?tiÓ¶0ûôIÏä#%(ù‰ö -©«ˆ|LO†D¨Å÷¦gîÑå¼Þ8vÉC÷I~®O–ÙÍ>mŒáõÞ¢‰‘}‚ -^hâŒð·¹ œ£“hZ™Í/øÅ_à7œÀ+P¸¸&&êåî$+Nȶp®Ô ~I(–»c¹ÚŸYªÓÅg¶%ø¥p%ö>­’H¾iL¿\ÚõÐß(¦µâ_«8Cƒ—R{‹ -Žµrð¦ëØíû‹0Ê{‡˜ÊQê¸2‰«Zœa‰ƒ†*7Äc¹äJî„I›ÏüìÒ]©æÁ 1=Š¡å©òñS€MX¡¥GMøªéþP¢‹:*½ÙOT9†ÜD¨*ÀzÞÃ*Úž“¬ÿ°Ë_hg -‚œ«ê9ŸjˆŠ"J7Þ®(ðhT(ìâ ª¦¼ÜðÊ™§Ä‹V¬áÝq -oò]ç }£¯9B‘7õ· öœH{È­’ëæi`T&éVÇãs"¹‡‡ªÃßÛçVMo¼iá÷׈â{C„^×;¿_g¿`,·÷þ2 Ún“ R ɫǶ]ÅjÍuib°ƒãÏV!QÏÆ>²¦aO<ö”ñOÁxƒªH²$áófe°§Åû›ê¥úКxÇÑiêÅà>ò$­–Ìy"-Ú-ŵ ôý‰¤Ëq ¸ŠÖˆÕ"™[Ø m¥cA¸¶¹"t8Q+PK¥ìó÷Ñ”¶ëÛãh_“ ®$+ƒº‡¼S¾ÎúÜþµ$áØ™éezv~7EhÅZÞ‚¥ÓªãHÝåûm®Ý‘(ãŸÄ"Þïòwnúê›»ÉÕ”^«¦y$3î3i=+iÿWuÈæÔmâ’<£Ⱥ][±÷QgShSÝ»¤SñºïX±wû@`z>ÍÛòÈëB¶"Æ®.(ñôAàN¥Ã|³w®3¬ín1eqÞ¸XäL%­1;¹MÊ®¦*Åÿ^OìU©‘yo•½§ìRùùÑ© lå™Õº©RéÓåú’ØyšQÝÅêØÌ·XçY2‹†¸Ä¾ŒPñ+«Ö$ßo¼7SæDEÏ–GÙËËGªvË.¼–Õ£ª¾PH^ ÍuòñjzZ+3àÆ´¤Nc<ÃÃe™åGKB.þ/Qü?øŸÜ|Ý]ƒà~.>ÿžßendstream -endobj -863 0 obj << -/Type /Font -/Subtype /Type1 -/Encoding 1921 0 R -/FirstChar 33 -/LastChar 125 -/Widths 1931 0 R -/BaseFont /REOTBO+NimbusMonL-Regu -/FontDescriptor 861 0 R ->> endobj -861 0 obj << -/Ascent 625 -/CapHeight 557 -/Descent -147 -/FontName /REOTBO+NimbusMonL-Regu -/ItalicAngle 0 -/StemV 41 -/XHeight 426 -/FontBBox [-12 -237 650 811] -/Flags 4 -/CharSet (/exclam/quotedbl/numbersign/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/underscore/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright) -/FontFile 862 0 R ->> endobj -1931 0 obj -[600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ] -endobj -746 0 obj << -/Length1 1630 -/Length2 15892 -/Length3 532 -/Length 16775 -/Filter /FlateDecode ->> -stream -xÚ¬¹cx¥]³-Ûv¯ØfǶm¯$+6:ìض“Žm;éØè°culãëç}ÏÞû\ûœ_çÛ¿Ö=kTªY£æ¼îûZ”¤ÊjŒ"æ¦@I{WFV&^€†ª–²‰­­‰9ÈAžQÕÁÎð×̉@I)æ 4q9Ø‹›¸yZ@s€8Ð ÀÆ`ýúõ+%@ÌÁÑËdiå - ùËAKOÏð_–\¦^ÿütYÚ¨þ>¸mí€ö®)þŸÕ€@€«`²Ä””ud¥4RŠ) =ÐÙÄ ìfj 2ȃ̀ö.@Z€…ƒ3Àöß €™ƒ½9蟭¹0ýåq˜\f ¿a@O3 ã?Àèlrqùû ¹,Mì]ÿöÀÕ²7³u3ÿ§€¿v ‡äèìð×Ãî/ö—LÙÁÅÕÅÌäè -ø›UY\òßuºZ™¸þ“Ûô8Xüõ4w0sûgKÿÂþÒüE]M@ö.W §ë?¹Ls‹£­‰×ßÜÉAÿ*ÃÍdoù_0œ–&Îæ¶@—¿4¹ÿéÎíð¿íÞÄÑÑÖë_ÑÿòúÏ@®.@[ &V¶¿9Í\ÿæ¶Ù#0ÿ3*2öV–ÛÍÝÿs:ÿ«A4ÿÌ íß"LÌìm½æ@ fE׿)4ÿo*3ýωü? ñÿˆÀÿ#òþÿ÷¿kô¿âÿ¿çù¿SKºÙÚ*šØÿø; øç’±ÿ?¼Mì@¶^ÿ7ÿÿî©üw‘ÿWW“¿­±·ü+ãW&–¯ÿ@.’ O ¹2ÈÕÌ -`abû·Wÿ²kØ›mAöÀ¿šþ«FV–ÿ†©[Ìlìÿi>ç¿! ½ù¯ÿ¯LÿªžYMV\^L”þÿ¸WÕlÿΗ+÷¿#”ÿN‚«º—#ð¿Òi)8˜ÿçâ>QQO€7#+€‘‡ýïdc|å`÷ý¿äþë­L\Až=&Ö¿¤ÿü²ü“û? ƒÿF#aoæ`þÏ쨹šØ›ÿ·ÿ4ü›¹9;ÿUù_7ÀßíÿÇú_ƒzÍV9˜ñ[§ge¸Öáæ OŠë ô±B‡8–6ªÔ8ôú§‡o­4~« ajšæýh÷Z:q|ß—¥;íñ¥îM^ù’Óö¢ÿ¦êä¦?d6,EÎ8ÕŠö¾\”ß‚ÒåbÑ<Ø™TQ5,yƒ!žîdw†»|¤ w/ À¢xpDñ3KkˆÃîBkèûqrJ•tüø@=462ü³÷ºŸ>7ž’Ï -™**À)—PHW£B¢ªU³m·WÛÔOrí]VÉ• $«ùqyĤ"õÂzŒf<0ëûë£Îðf}/Ÿí¤>bêFè,VØUd‹ÕƒæÔJlNÍo’©+¬OXÏ1Ï-¼§c-NÂ1ipÝ›í\AÖµ?ªª…¹{G.ž'Þ½µ$5õü^oDÌÒ’j8Á¬R/ë‰yÝ࣑<Ì`½^ -úêì`uvdé,RHžê$žkK‚>&Y ¤ºÛ”OØ&â„o™kâÆœm§Ù WëÙÉ -¨œ/û«Ð[BÒó´`Ûtä¯äÍN¿GfáĈHªýmVéDÇÏ“Ÿ”Ä÷¦Y_kÉóÍ+èü1pÇÒ¨åÁ³ñÂjD•jÊ -Ga1Ã8‘¯YÛ«Ÿãн>½l•ê!¾™Ç”œ±Rš¶?àW'‡Ù_NÄåƒÆY4!aÔ„ø‰¥– -/ÓLòFºVÕa¥¹òÞ+sTe˜1‘G·G]<ÖlI¯7E³±+’Ò=‚,Cš«OÒØor.¹kÕ /ÁÓŒ’ÍU±Hi~|ŒÖwÚkµqš‡~ƒ¸Ö£7ö³"ÄÇYæ…ÅO k_ã1fo4,ëIoböm5¹‹²O½k‚uÒ¥2ƒÞ¡úd‹j¨7W})“Þ‹¤ÐϾÑdT¥wÇ„{•ü¦ÒfËç«Ø™#K˜€Nƒh çuÏÏ%¢>ÞØXñÿàÛñÝ%rá§_&ωbksà£uÂÑj£«ÓEŸ -ö:çkØ¥»ãÆðòvÏ5ÅΰÂÜ0p!.ZÍ2§.•`Õé;ûòÒŸ¾´E 'ôòL‹~­'"Bδ •RÛ…ê뚀ÄÌË1ú€Þ‚`0ýzл»-õ®‰ÑÆöø$·«|Â9˜ ühˆô`´6GÞ£h‹º¢:"ÎÙ;¾M¯_­µJ%îo%ÒÌnck—ý'y¾‘ýαšm¡‹¦ƒ”õíÞ*{ iwQ[™¤kžç Ë tîF!cö8äÞŠNßãÇx´ ’Ü!Ä’¥¼Ö¢¦¥Š—Î~_ó©àH¶ýÛ±1%Š–±Ú¹ Ͼº¦á¢Õ>ÝMÐAŸdZ˜Ê51Ýb1ܤɬUð/ -‡ØRŠ#ÿ>w@ÿyXõCulŽ+Œ†ÌA馹°\¾ç­ÚÔ¢bjdT9äú¶’¥«×zbzÎK÷÷§©¿”fí*õ }æiEÔAž[ÙI ßý¹+¬C ƒœí4IX¹˜z²rw}ô‰öRj÷yÉX@È[ªiË fó„zyuôtT5åú4B›I—”ÉK0Ë>oIqÖÛoß™KØgv † -Š…â!^ÊÄ,õˆ¨òæ–áë,…â­X˜È(q"=Ã/šëø4ßß2ku¢Ã§oÈ\ɘPTø$á9¶#=¼.ª…ªI$¹ Å“‹Îšø©™ˆûz·Êp^‹T6ÞmyD¨g=_¤.Ó Ê—ÜÌOcVP‡¤.â³ù{:²|GÂT˜Žë¿·Bo¦w·øÐõï:j‘´åêÿ€Z uHT©—btcý½B.÷IØÒå~¨2Ò7*Qõ>;³2û ÃP“\³uŸ;k¦«Œ¥3b@òÑ©6­ZKî#C\òËT2ÜhŒµ`{ÕÅAîK岦G«³_ÄZ¥öc¤Ü>ÜÈÀâ¤k÷égq}2Ïþ=¬«E(Š¿'Ž - օݧ{ÌæßÖRáï›I“¬ïØÃ4†ºéd`ðe'¢ò›KþÈé•ëÀ0 xö¯´ØQ¤Î]åhÓJ;ZL½"7Ò–ñà|êTñÌãço2R°×%‚¬Xs­üòc–>`pȸÔ¢D…Üo½I[«4uÉG ‡äÇ]F?bo÷ ¦"1I[#– x%‡x‹¹žÆɬ²×Á>Эs*´Ïühd&Cîx3Ôà9‹œkMŒ™"SàÈÕÍŠL€''ƒ™C¦eòœÿ@ËÞÀ4:%½BÔ‡?Ö´OH6c{h¦5/çÕ -5’QÄ„Qƒœqó™0=l­\αç -¥×$á_~Т:ò›l -Û…úMÚ„m>ô‹'Á†ž§MýO³qÎCÄ]´5CXá*\•MN£dtWî -BJ!•l!~X‡’Õ É•aó’1Ë"/°E©ø!Jü÷™oó§KDMk§Èéw“F±§Ûˆ{¹g,˜6Q4²«lía¤WÈw©4q’7_úU0"¾B` Ï"ø?(±*ë2­³G€ ¡fÓêQXŽŠJ5úºîÚ ñ%èÐäíb¡Ê¡ÓYÉ_c¸p'vÿЮ/]·mÐøD‘ /³îwòŸÙ|&æ>¡®GSÜ° ¯d9{¶£IóJŠK÷9fã¢éŠ ©þäÁõ@ñ¼9xŒi,P¾*=cùüà‰µNm6O—^ E› ªÖž©ÁôЮº -M2tÉ»bqJCgª`AjI@vr]Ú@Ö *Ó ä½è¼‰_‰ä”/ú¼æ/ -¨á"R’´‰öÆ$ä ÚU W=ŽgY·'æýÕ ±M‘‚‡{}•ÜÿöA®ô5±ò½UKмÎf6ÞÎ'2¦g¯,5ƒŽh­óçü¨6à«ÈÇ -g!ò)#îLI•eÇO~,EbÛà ¢.ÈÁî=íõÙL(Bćơ=²a~¡Ž LÌjSȤk²5ž€ŸH½ºFŒ§WiWམXøwÖýï… \#A†%ñ³‘Ë2‘j Ç´½Û¡õ´„P2’åíC¶²‹’³o K,\QÛ²ÔŽ‹¼Ü3WÚ ‰SÁ™Û3èF#ëšlËñ°ÁºÌ¬§T{ô?êu5DZ—b!⺂Æn9Š#M‘y^Qi$ë\Êo#£ :“ÐÇÏq`{‹!ˆC%oÝË|°¢’N½`^¾VÄ:z´ßÂØÚ˜Å,Žž”\uyFÌOàø6ëÞÀ…?z†t+A×ÜéEî>VµÝ´çröt'ˇÅ<Ë9¶]ÄöýÞCðò—|fŒK¨ª£µ®ß( ­Â‹%SrÜ3ÀðYÙ%ŸTu3×dhtéõn&ƒà)pMþ¬'Ö]ÛPB4ÿA÷ÃID€à·GPDŠ¸U\%%2à!¬ÂúKÄÖ£Ée”Ø“ê6,Ù:'Û((í,ïÌ»DÜBó¦úƒˆ®õI›™½a'=I˼\ùKrå.;_ ŠRP,¦èÜ J¥0Ÿ(„Ï ÂmÃ*¨ù}‹ZP¼>iI*ëz¦á-µŽdy áäQ‡~zò,!Ÿ«ËöHéqŠûˆ\óD#k4I6ðsÝö:ïBéã Îö'è$Ë/©ŸìöU]€’’ƒLWF: KEÑx.A?C;ù'CvãR§S=ËÀÝ•jX( “ûµÏ~&/H«¼‚‡6œÀ#Žz„˜»»Jýx0ëÖ0MÞu J£ Ä’¹)AË©GOûØ+VôývŸsÉŠJǾYNaú»È[sûË#…ù«YñÙ/%AœrºWó¾B¬ÕDTi;þä$wÐy.×oöiÉÕÙªne\½þ„1Xï§Áõˆ_°ˆÔ‹ i‰}]hœ‘DÉF•X8)RŒ(êe+QBöìøYýú$ø𙨗wš4ÉAÑåFç[/Ìï(=Š|ú11ǹÌYfFã–s»Ø'ú[þµwù|¼ŽÇÛ,ë¢39i¯æ¼Žõšm!¸«uEÖê†î .>Pr˜áËóOªbeå£/Ï”£à?cÛ^0ô²³Ë«Lâ9}IÍv#VSgzºŽÙÑ‘ðîàê)˜¶©£p.´ÊI*ðwgÚË&)ƒâ²oUÌäšH€+ßÞÉ¥al‘BéiWŽÎG^ç˜ÀØl8„¬~ÇH/«æ5Àc/ý -q,‘ô¡ÇúGåKco IÛ³ø©‚Ž Nv#j»£)Ÿ—“Ì·‘¶ý¤C±Œmm§ -ÄáÛì‡VJ@ÂyÜ4A“ß(9,”÷-mZË)é‹ò8ÕªÇ+“lvÕcÊž|:"Ú!ý XjñÕ,NÛO¤y|¯aëŸÚaƒ™zßÀæÚ:µfm¦M?3r»’~°OƒïäɈö…‡«Ê2´Xñ#L9¡!&ySzDØõvÿæIp o<Èk`Ð S“˜ó¬º=âp¬ Y1'&ŒDŸpªT„¥‡˜VôëÿD·Xø}ÓË%0“{ Üò<‡·Ë|¬ôùØ8¯¿¦‘‰ÿ¨Ý.‚hƒÍ¢Ij9ì¤AææÕþpƒjFÓ›¯ +ôhЗ$™-ëM š:ËpYÒRYýæQ®îCš¯pc[`÷ÜñYÎþ^b}oï¿-æ‡qTBäò÷ÎõÀ”¸x•½ªµÏÜ«i HL›´,H÷RQf.úYaáVx þ&ѼzkK.|×{ih—W¦ˆvJwÂmà@Ãt i» ß–ü¸Ç.ö• £ˆ¢&ExìÓªúp6î#_8?¥œÕ”#ȹFøØËò4xITëèŸU¤l&€rùÞc—ßÜ°ÕÝ«C°*¿÷›Ãq(E–ðŸ2㾿Gµ:Í>‘ùÎâ>ỹ†o÷S¨æ÷yoúšíUCôM-&7qD¥jüãR…ñKs30¿¾»eçψѦ[óÚâ/×ÓI–<÷ÉgÓAiÐfþÃ.|ùž÷F?—$àvGQyuº‡ÚwòÄ@ÕTˆ•MU‰ѵEf|ähÝÖ̘®8 äiÌ‘D=_ND¹½aŸˆ?Æ)þVELK‹ÎR—èp-´ÇhÆÓDºøZXFÛ!¹àºYû,£ùðŒtó×ìX·¿Ñ¬7$ Ž»¤©„,óYch÷Ç›#—s³™&úÞ Ä¯Ã4~Œ•5-ò~Çc½ëweAdð)9Æ’6Éò‘Ðo¿Ý¥Ä3'ÄjhD(ÅêÁëi¾­!ÕrßÙÃpp¹g¼pä¹&<¸$LÎ}’²OÏÆ1™3Ñi Ê®0®©Ü•.;Y£34wçP×äU%± ` 6=ñfÛ8ÅT…Gç+\TÔ³7½ú¿üš«²ò³k“eNµLXQt0‡îÀÕÒ:_‡YšÉéxOmY|AÀ×^ÙZY Ò|4’ø†â·à:Ê>²Å)ZaYñ7¬Ö›ÅìiYyG×ì—'R>PìÕÕ™ùòrÖ¹š°[}Vì Ãr1¨ £É¢iÔUi©D¯ lu2CR.’ÉQtUÌä¡8ÆÍm+½Dø"‚Tq_…„p/×Ù^$Àw,säÞÚÁ­Á„¬±Ð%çͧÇŠŒÚ·7Öaeýì³^›)ô,ˆò]tïéÍþ²IäúœH¨õ4öM‚…QˆŽ+¶”/ #lífä±³Ëb!^sKQ5UúL0tŒØ…=0ØæåkZŒÜ‚û°ðâ>õ™^éÐÍJD&kÅkL=úïˆãÔá?OdG’’Ž“" æ™·?à37Î[-‰ç¤˜ô6ÀŒi,ÌÃ#‰ Ä‘£2¦‚ìDM(ª­ÂbYäGGÑw²Î¤‡ ¾Ó€v|uËÛ³aŒþÖÝF>d’çJy½þTf'X3i2]JÞé‘N»P¹ SwE©º3‹Pfèáüq9èºñ#kñ|?öèØô"’ÙY0(Æf·%‹ µòÂÐÇÎs>SŸE¢ö&*Âßš ²mÌIy’&ϾxÇÜ€~™~V XxDÑ:ÏbŒÕ©ê¥Ä4ávü\è<‰BÕ„0ÙTÄQ)9BÙHq9ætñÊê`í86[vƒ¡×\ø‹×«/…'YqZX«ÇSüýŠja axäa° ¨'m6q¬§Ï¢óÌzÉODB<ïô{†Ð/ºa#²Ü ªÐ©¦õ‰ô& ПÏL%ýÒÏmØ’NMQ_æ]¤Êåà‡~–zÞóÙ8Ñ\ë W@¿íÜ®¹pá]±ú¶}”òŠTGjf&ÓâÉèÃúVìûÙÄÕaɆ’¨5n 'Å4E“Œ¤CàÌùVˆw¤Ów"ýúx{Ê*X2&~䯯QP.Ì×ðRÚ•{kccÐe˜7ñÀ:¸‡_Va%±©â5G+£\÷t(§@évx©Jø™îñví,·WG Û KbýœÉ¢ðj:lêò‚.Gwé"oœúäÆL¬5“íÜÕÊï0CCŒú¿OéSyÌ!¨Þö&ü/=MÔ‹m?Ú|;uÓPö¥Zž°j[¿ÄU ;=aµ¯a`®îÈß}\ßöœ¯ç·xÂÚHÒ¶E‚ IDQ¸¿çÍõ‡Y­¤)„t®=°^Ùd•†{ 媒Sΰ];S ]“[^&PÁÙAÔ›qcàÊÞækt5ñt -"q‚x”Ad€Äœˆ®wÒ4°ÈJÙ¼­Ì8ø¿Wöwm B\ëê ìáQïÞÌæºÙ2çŠ'=|J¸^Ö{~ %ÒffÞ2*„ÿ¹UU£î[œRnÖûÎ ç äà/︊»æÕµ±úøÖ[²@“¬½¡Í—5NCCOQ~Ù/N»ùÞq¾!ê ‚„ÙHÔÚä5Ôû3õíya÷UTE‡3BŒýóGN½Ü‡ÄlXþÔGõ“) Âå§aow;é5’-Vy3Å„§J%™èvsQ¾ó\¥Æ0wW˜jS4ÂÒlêWbØ9z%ò¶;,_*EéÃŒ¯ïw1wÙ=ò^D%IßïÿèÀ ‘´ÃΉ™ûÆk¸ß‰y(@ÞqH·DêÇÊQsfT+Û©Õ©s>ÁK@BªB¥¦¤¹já»AÙSg(c¯Ì^¹ŸˆˆÄ>Ò k]5¾`®³ŸFU÷ÚI4û†˜0–—ûcw~¸øTàëö÷Kìµ/ØÐS ^¶KÃðàø¶úN†.é*fQÃïÊÛ…¸SÚK>2 -«°;‡5Î9ø%ÏçL¿ôw_†hÝ¥‰’ 6°V… -^”ØD>#û|ïzïÔ>Œ_ƈP‰ÌäFY„“ðÉQ[ÜȾo £zsT¸8ŽZv?=ªÅHAÓB[LÒÒâvl.èÆí“ÚGÆv‹7"E‰†O¥Ojn(`²¯—½Wb°¡vs÷;îù+®{¿ÈýÀX°«§º½[ŽÓì1˜'½Û6ˆUÊYø“÷dÌe`3ºæç³¼6àHÅ©ÜÁ­ ¾ØÅú(n°ƒù‹"uY»¦·[F’¼3  J -ÓdŠ®ÂlÀZ(”ŸRO¹Œ»“69Û€Ìà†ûŽDQäìUJE5ý*rÍ@¥”Ê~2ÉèeS2N˜ôBÔéø½S[©P°öÐ}—Ìjùjª¨Ÿ´ôÛíýc‚I‰ží õëš(ñÍß>‰/ÜagªœÁáµãº¸›þƒàà出ÅÛó,TúG–-N­ê½Pó5ø¯­ 4hi!Öøß|tÄ:/tô—nx•²åÕüÇßC)7µd|%çC§/;üÿœ/zm’.ØD×ÿa•¸·†iýAæØÚPƒ1.<-¿å¯ö”¶Ð¢›ÉWVž@£ÄUGà†áûÔËÍÖ* -(§[$$Òè,ŠÕ%%yÔ »´Æ”V°ß{Ó(±3· Z„Ö= (0ÜHnƒ«%1œÍBz;¦ßŽÚsÌ9û=u›UÛþígàÑv±Ú9Ž{â’®0ÝùÙ7ý#÷í¡J ÐF¦pß.Ð4·HóRØ°hÀ+;™ëŠÿjHj´JìÛ}Œ¹Úã /x|fðÙµcs|“úúa SNwX¨ÁCWú±Î~\ƒ6›Ðpr;h±8R÷>by;yÛÍálÈ0#e©Ðu?¼¥tMÕ€ž^g¯ªòn$Nß_ävSìêõíX?áûL•†ä³s«¡¡÷ Wþ¤Rââ5G5ºŸ~–²@í—OöŒ¬vË1¤ Š@ ÈÅÎt·»·¾Ãþߺš£pÊjUˆÂØÙ©®¼ú€5ëïžþôè+ -ø%IÆãа¬"£H_|B -DÈôZ¨K~¡ºy±'§«š—˜Â2ZSŸÄ*_Žs°¬¿áüy­•4á’DˆìG„V!3ÆÓä.¦ŸõÒÀ~Yx²ÚQ3æ0ËÉ*À‚äêJÛnïPýúúx ëW11u‚:Ow aA” ^†’ÃÆ„fÚÒRW—Ø(˜¾àBß|d9™eŸÇì x¹|nzç¥üí’]áÍOúåð;={É—êž/Ý„x_ ?à^ÊÃxVòWû‚¼%uÅ ºs+§iTO˜²ýôˆí^êÓqFÆï;ëá[1IÑÇ@ÑIÍEÃÎXq{tUå½ÊZ$ÊÈ/.·Ë3¨-Î ï_ßa?›@ñÅPlTÁLþŒ?iy1s•ÂyK°€[å>su ñ-UXr§m;¨:ª•Kó£*gò¤Åú‰᪠Y&–Ì1Z°ÏÚ¬½ÙQ‘~r"¬JÅÌ`\Š}‰rí&–¡[@²¦Ú»Eû($:¥ºøeÖÌÈ|½C¾Ö(ß~™„¡0¹ª‘ÉË]ô¢/áÉÈÂÜmúüpxQ[kñPÝVÙE·T+†L|­¢D©¦hèGR †.QÎ^Ïs)P>¸õ”.y•y=Oª\î­Ê¹¥ÕȤèGµÓà8þp·—¢®*7”:^&-fVl®ª¬.è<€:T`c…’`'×+mi£HÄÁÏÊ™³9E”ÓNÄJù>ÉVŽu“”=ÜÓ‡“Äòq|1,¬évÅDÒžZä-û4X…»´üÒhÓ%…¥!1ÑÙ:ՠãz&çkÙ> GžŸsêEL¢yeiªlŒþ[Mà Ô({§>¨)âNäþXP¤¨¯owÜô¼.⯠Š–4ãÞEUmVÏ“bD‰;Yª¿TÂíG¹=6ä’-Œ¿Ç@^» ‡¹OSä™aä]Çeiˆ)Vª´û~†Î•¢‡¡j¹×¦Ð;ûvÓ~$ÂV”¸ÃeEÛE³.£2§|Õ_ƒ ‰€G­™uè‘1—ñ½‰æ—DV‡„+j -ö99'(ÜÛG(#?‚iÎä²qßÇɲZ®[ÛÂääßýIbËw‚Õi™£KÝQSûž)VøÒŸ6+Ηݓà Æ8,LýA娒¤ÈåàãÍP9?¬CÚ+|…ëÍÁ^óøúÒ¼²Í·rôjÅ6À¹Ž‹ßuæ -[(†ºÍ öt bÚ[·ö- -HÉU -’7ø“’ðüÅšŽ,<ëÀ¢ Ò½è ¥;KY±7¨n’7qÍþL3Œ8Œ@×SÿCŠtv‰jáY²Ž¶bb»¸iS -ÕL;&ÜÚ社Q²;»UjNN{)òèÈù¥@Ã:è0>nOG"ýya,.ÉàÙ zi™TÄë:q!$*nK\Â)÷.¬’í8>‹ –Éîu¾J~&Õ†»M[oȳ©žJ´2Ëxy˜3Ÿ‰“ýÖ.¿”©tü.ó–5”Ï8Až «Z¦´´òÏn‘Kœ'‘[àõ•úV‡54›»Ü,eW~o§5X9mó‹jœkÑ$'<àYœ@ªùA-G-_ÚmVó ` «ú„£ù”Ó¹×”Šó“$È»²™©CÕr1¹"ÄÃ$AŠíŽ)й¦?¤Í0HÝÅŸàcËÉ&kžm,¡¿j%‘z´Üt/DÅ2—ð£xD*íÒú`s1VKó߉wAwcuÇ$aD_Û*_? -.g4“Mâ'M¦ï(ŠMÑ|éÖˆð…õ²›ÓĘ#5Ç´=È•ò~u¦5Vê£R¯/®£­óHÄ®f§ŒŠN¿:¿lŒTmoú_ ˆ[O»1Â̤§ké&èIN†‹v@‹þH,€tŒt¦á>Õ'R¥•K.zgóJ˜ë(+Á5¯2ìkÚ Ý϶¨Â[ú3Änè^ þ^×ÌæQ¡T d`v+f<ñ'yжj~›q)ž\k,°ý”škQí—½`µ‰OÒ«cìÔ\,& šîJ -íiW‡ fÈ“$#Ò±"÷qHÀŠJ\èWxZ'dô•ÿŽç[œÀþ‰Rèyý©ƒäHñ'þŽŸr9Ø®cpøÝ…uÑ{cBíÙ‹Ü$Ÿâë ŽX -'î»ìØ•Ë#>¼ºê£Z*¶ ?fôÑ1sm%$¥ž -aþ2rž¯Y"`¿/Éü -E¢Ì®_Q²HL‰@Zá~fNS^ÿœí^®<+9;ÚyÜúMtéÔtßæN9ïJAñÀئ{½ùMÌJXQ—DÎ+vûÔÕ†|bs”F-Ë•§EJ òó8}]ÕzÙeRéÀd.Ly’ö|ÿDl>Åõ]Ãh­W[®!ûÄT‡‡ÞuýÝ!"ƒgúˆ.’FHD•‘õÝÖÚšgì$Ð6MNâjpx#2ì,y]®“ê™ _ŽwrÀ% Oqp¶,Ô†´}–úy.Ì0ØÖ³pßãOS*³ã‡ïwâE †ó0m‘¨ü…YiEµ ‹X‚EiyÂ’“ F/ɪô¶­‚´J´ž—‡@%aHøèÕ?7ôÝŽ¨Â'’J‡ˆ2LäÍÝDœŒŸh¸Ì¢±·,Žh¶è„CYö]Ñß´­úgmkôfÆ#ÔíÈä¡J¸Umßý¶ªæö1ãïÕâ•Æ»Å†-eQCÕsoŸ½Ø‰ Í™ªLlmwÓšÞ—Jš¶9¾!&5#é»~kÃÓ•±9wX§Mk‘ŠHg¥éÌÐ6ÓÂx̱Ùõr>%Cçñ#ñ“(ž¢Rm|™$×B\µÉ AvV7Áû¯…00À(ä1˵ÕÝÝK¦Ü¹Ù~éo»T9z˜~Yã{òÑ=Mq0ûJA «ø}/£1Äí«e—Ѧn/*ómF¿Äxù q¬äyJS*\€d­-†:¯Ø]yÜÔåTƒ‡¿øƒØE@ÍfvTü6íÁ2~lW=_xãSeþ<ùBÐÊÒm"¿‹g|£žŽ/>¡„ïn‡œ0'OK_5b«F¾ìؽ°`‚ýÔš´ú&¯Ï¸?`;ãõð æzâŠ×=k-"c ª)k¡@2×Ül SÕs'tÜ«f€p!Ó«‡¢¤H|ö‘¾×Á[ú 4ô‹ê9_¹ªÒSGUPâI%¸5– -¯ò\†¦ U¥ÙˆŠ G (Õc˜Ã -qQ)[‡ŸäW=Òлe~ÙŒB‘»ëó´#âý mω;y»Š%üŽ@D$zfªéA%OÕtØ9ø»«óu 6’RáÞŠxƒ„ï”…íãÄg“Aý; Ã^ËŸæ‹ÜlÏÀc¸_!. ¹À2ÇŒaj¸ Öl§i»fâ^Ù'µÓ<3`¡. `oØNÖ˜©4kÄ®+ÉϺþô.×Zá4ñk Ãi‚" ·æÃDÙ»úˆ›§7æ¹í„ Ó³WæÃW¹i±1àüS ë™ §yBžÖ'ö^2V“j7¶Åˆºi³õ _“¹5·pDÆâwŽK/h,WÐU›4Ä:Ó~¸\+HÂÜ­$”¸ÃˆC»…ŽMŽ­ù•e–â.¥pzÝ?$f‚Y¦ &º2>4ÿ~j‡}áW(í ˜‹·¢ÓÕŠ£‘(kC°JS!ÛšgjäÈ&Em½õDeÏQz›ñ„ûá^–öŽ‘ámªºú$‹ª/ù^T@n®XEò´i#9äšÅ0x»M›×õio‚qÆ;aà̓µ!( ~ÚÀz,˜;ß@å3=7ƒ8L‰¸²±=_òóÏr~“ì”{÷Þ5#©7ûôÄU”Y]ôÇÚØû“ÂV¤íb‰; —Ëæ¨Iæ—‘ª@àQâü)ý4"«Šöâv=<èy9ãÀ+q Q® ð>-ÕOÆ©®@A¤K® m²v$i0KƒÏÛg•m‡D•g<’o9iTÎ’cÕ&™Û¤2)¢'ap¸—È–7 E›§kw†ÚSçšò¶8&drM )I% -2:RÒ]š¡¸\•´²DÊ™º´^-;nðÇY~þ0Ÿ1Í»PÒø¤0«¬}¦“?f0­úÙq†cŒ¶[ú¾;¶96Ø/çCð¶ aF nð¦Å;gF—´þàøåÒçNŸ†UçæÆ»ÚÜŸúDíÌꇺÿįõi›nWƒ¤Å…ß ËY»³»¶v»:ûBXW9aÇá‘ïíYÞ·+Kþ%ýY&ÕûÌÚ3.û×ö€4‚0åe3Â_C¸{½n™rn*6Âܒįì–ž?d&Æ å3²Èp]Í"å™:jW"w…¤ýÈò›ù;Õ+†éY/¯RËB ? -P„ é*Ë~fûiöðÐÁ± y;§‹¸Ãà’ßÐpù<3A, -HG€BÊ!´q<6õûœp—-HM¶Ýu'¯ýôhË)&)|àÞšÙbÎÇU$¨™4ªC‹äCQW -Ûs'&ÞHË¥Á§õŒñ¾QNç—‰Ÿ8[/»'ÚýtÐMs¾Z!Å7ÃFjA¡;Pì;ÎÓ<Ø:ô‹hX[ÇñxWÓ·MéxWÕòћӼaç~ݯJürÎÇû®³`ù²ÏÉF™m¨1£áú§U, Å€ÎÌ÷;:ÖÇ9½èyÄÂ1žìPUºÝS‹QRUib3íWëA(W×â“ÙÅ€µ†„äõ6ú¡Q{I–àÆ/Š†#¿I¨ -RW¥Ï -Òd<—ñ*õ/^›žˆu“ ”Ö†´06f¾Dx>É3ÓÐ6 $cºŽ~{V -´.ÎlTÖ±ð`­çÐÖátžë¾±ÉŸÜÖR)z’ºª^ Å}bû»Îd7 -Á~‡+Ò«‡´¬©Bcá#šUQˆµ»ž2ßÓ5:a]C>+×­ 7ø×B -lwÏÍ ¤Á;e£“/~Å©ô6€bDPö€Àì5 ßhàdÓ'±1ãŽÔH®—äI¯Ãz£íFR… R꿧ù‰´Ôö~ZB‹µü|†šïs>vŽ(B¯)ˆä<µ¢+þ‰>wÓ*>‰v»P°ÈÒÕìn݇32B‰;¾}0ñ\d3í•©Þlýöu>Ø5¹¿ å'Všµ«7ŽìòÂn@ÐŒ_÷ u,c!Üy&iÏ6I¿ÓpǾ -I3qn»#q.¢+j¨lx¥šÏw$àmE8L/ëÄŸ4Æ‹ jìhz:¼‡“nÚé(åw‚ -i}ü8c©+V\‚ØH}Hȧ¿`$¾³O4Waˆ©þ«ùůµbâbõê¿Þ™þz[›aó¬^QÅç¿o¹59ô>Ÿ%{q‡óx§òêÕ/ ìŸ)¨1£7i-ɉ<ô–Îy×`áÌ~)/B,ÔŒÄ ’$¯üÈà‡Š} Ðqƒq\­¸Ôä9XÇÊ&Y Ä~ÛÙ?FÑ«âÖ7AhnzräÍç$"wÅ:XÞ#uq^ß>\xb1Ò»Ïtá6J•ßOõ;‹ŽÉ–a¨Ûß„f {âe# zP$ü®)И'´³ýyòÓûÕn&såÚd´‘ôòh0×Qš>™ÒsA”>2Ì„8¹º—£q}ªé·Lm¯‚Ódx¯N›GQðLÚþ‡Yô2V÷«½ 1±ÅµXè*ýõ ÷q¦69+ÛÞ¥Ÿá0ë8õ¯Ü§Xî´ÏÚæs>Þ¡v5js+¹¢ˆ´Qaïe÷|* û½*$!ÿ½ËI ̽n(9Jºd`t=:™bڃĞ€»¡môÅñNqÖr¾¶Ù¿LÌ¿öåÊ`T0ÐElbiâPŠélº¤Ã¨:îi…wZ’„A[ž–áÇõVm#Ù®©ÂãôCÐÉ/‰ïF6r¨.]ª^|\¤†ÕḔ ¦k)–:õקàX9LÈí¾)b[ôŸSÕG¯Ê"2ƱµJѸRMxÝ]ÙrÿÅ:K¥ÓS%œx&Á¥€¢[bÜlñ™]Œ ·ðØ&T¡Tœ(j!Í'^‰1ýž¸Žƒû7îIÕäÁzes P©.—6Lb"Ž£“k2áKøvxxo¾ô Î@èô*sJc†*¢Zr»“”€—l§^c‹ÓœÌ¤¥øÅú2ÉÒq™ÍŸ8Ð 3?9Fõ<}UíçUr\°V -æ¨5-lçÖwŠ?v¹Í“!‰P£C´é¹2üÇ6$í.ªM¬—¿òÔöž8ü¨=Cî<:6¤Ò*À8€Ëi¾‚’¬ˆ§eœxÁ7gSL¥]ü÷MÁl϶É_LÎ[¯>7‘~KÔC¿ bÖ¡ùMÙDSG„l,Ô±ÿ…ô4¨·ÕõvOój˜ývXÚ‹>N]'#èØÌ×!óþÇ7îð*xîG™õñÌþÀ!%aóЦ_èõ\{¸®qf__ÌjävU“j3ùêEo/ž4 16ìž-AXðIŸsþã¹ßZI‚–>ÛýNA¸­s´Kp‹²ê˜"ÏGx ™?þ³Kl\jß»¬“aÒۗ샜+€uÊtC—hÇîá• -¿n$rÝ XðD˜t ÎõÓ…”2§—n„sÞmOÆ„ ˆ;²ÃßshuåU9ñÖ&;y-sõP~K*ªÅz4rnp´}ª÷œõ)RB—+«å—>¢cI£Ž¹w× éhz€Ì\mm £MúHþ×<×|Ìï­&‰ Ÿw³s£Üë+\?VË´<=yò‹ØH»M'²ñÑ67Cøoí+A5x5½·x¯'_Ë -c!vÜ~óÓ4¶bIpµP]ãH^ŒúÀnkLßYßÙ„æÀ,•‰)tCœrÀ‘ Çi†Ï±m$hýÈn.ÿ¶»öO¿ªWÂ[–{OFChÓ'žWùÆ*6L‡1±’g^H]u Ââa3ð¸g@—TÕL_1@d7¾ùÁ“†µ‹Œ:…‘XF.ÿ§Òfb1\ÄñSÙ£Ö®TÁIS ÒŽã{9.´ v´ôPš_$ ƒºÃ™.T€Áj”¤RÚ.zàÂiXÎ^;-”ûkwå0HMKyÃûSc-‘tkâôk'a.*bí Û¶4ŠdÇ&ž*qÉŸX‡ÒÝÓä"c°4 *+9‚3£ -cáE¢Lg%ãŸïÁó§KíÚï©=ëg‡~Q)œu‘Še7@ô`­¥¡c˜„s2¬ìe/ï´Ã÷5ØI*·[ÔrHîD4;"«hntRÉ´c¬¥ŸýÝ„u å{ÿÁØ }hë …x;³°çlqf—š “d79˜R€2õ¨)iµ†–Gö»€ê&‚—ÜÞ¨CšùŸeVò]ÏÓ~„ð¡T}îY¸dë`XÕìéÎ<òe JË»1ÒXê¤QáÀ#÷gX¹;«ÜÉà{}¤* ½lÈ»€~.ž©kÜõVÅÇ®þÒ€§ú‘7ã$o—#€àkص <Éâ{ -¯41¶{ºQµÚâl·Pãg;‹($@QQ~:ú4¥ /麞e„¼æª't“Ê>~œÍÆTÂ={š÷ÈcW ä­ë6Å͆ÇIjË‚¶{Al ¸¸ ²œís è¹”Lª £ÈàýÞùqœöÇ=*Y€þKTØ&§Ð9æ2ös³Ìü±×îªÊ›õäõ§=ìÌÉIx=ãç7åv[¿Céhw›«Ó(îl*ø®Ÿq ‰Ëb“ÛfÜèY àûYÚÿßRŸåÆ |)¶U-*ª[rᇻ……øw8me-PÍsóQîñúW™N‡vé¸î²”š{e³ã=öEëe>*­xQÿuò_­Rñ„çÒ˜ ¢þ«Iïç?d¯Y¹Æa½/Kz†Âc™›gZ6qæåØöì—3 p0, HÎIM,*ÉÏM,Êæ8f‚endstream -endobj -747 0 obj << -/Type /Font -/Subtype /Type1 -/Encoding 1921 0 R -/FirstChar 40 -/LastChar 90 -/Widths 1932 0 R -/BaseFont /SJDLCB+URWPalladioL-Roma-Slant_167 -/FontDescriptor 745 0 R ->> endobj -745 0 obj << -/Ascent 715 -/CapHeight 680 -/Descent -282 -/FontName /SJDLCB+URWPalladioL-Roma-Slant_167 -/ItalicAngle -9 -/StemV 84 -/XHeight 469 -/FontBBox [-166 -283 1021 943] -/Flags 4 -/CharSet (/parenleft/parenright/hyphen/period/zero/one/two/three/four/five/six/seven/eight/nine/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/X/Y/Z) -/FontFile 746 0 R ->> endobj -1932 0 obj -[333 333 0 0 0 333 250 0 500 500 500 500 500 500 500 500 500 500 0 0 0 0 0 0 0 778 611 709 774 611 556 763 832 337 0 726 611 946 831 786 604 786 668 525 613 778 722 0 667 667 667 ] -endobj -684 0 obj << -/Length1 862 -/Length2 1251 -/Length3 532 -/Length 1861 -/Filter /FlateDecode ->> -stream -xÚíUkTgnõJÀ+Å€€¸ -æ2%X4© É„’ L P -A@0¨P¹TZ)­`åb°¢àY#BAn¬\uÝôØ¥?wíÙ™?ó>Ïó½ß3ÏûóY˜yúœ9H슈$ÒwŸƒ ‰dœ…… -C>"ÚI`::8€€³4©™F§éTÎpAÂ"Q~0OX¹|¶ ¢ÎBå³!àIx°ëÁ†€ÂæÃ’H"à,Þ +Ä€7,†Ñ˜CÄ Àá³%@ÌáH Ž˜".Ж`Ž4ì£bÌ`…™ü À,r‘ àÀ\ÉÁö‚1'ÿ SË›»JH¸Ð~1¥?ñ/ˆ|«@„aR ŒîFEË¥¾ð’9w˜Ã— -—³L $à³EÁ €vD²-u‰à‹]ù2˜ãÉ—°yˆáEq–[Áâ[4BÚ»ÅØëjóv®‹¤'ÄIöE†Áù½z±ß×XJ(_ø“‰d2ˆ ±÷ÝWÀ²Í¾±_ P¨ö„¢P$;AXE¢A€/âÀ2–aŽID"Á–X4Ç.‚âÆ -Ú$6e `öÂÔ$ ìAHAXæð 2ÃPˆ `îaÛ·ðÒÐßãö¡ï, `‡Š˜·ÿ98‘E(ÁÁû´h4ê±²¥( -‹$‹g‹ÿ]Íåc#ƒaÌÆõt!lÇÄܪ¤ò˜/Îßùá#’ÎËÖ -Mv“_MLŸṡzÎË,XR2R¤ºzBUîe;žÒG¯¥{¤}5U¬ñjja™_fµ‘ØíƒLH•¯zmc9ÂT„8ÿʘވ>:ûí–­=S[b[õÎqÔŒCçfºt×[{Ÿ´6ßHë¹ Ýÿá|dÿ“ŽÍ5±¹7¶³ÇoßwczâÅ®©–J®“nÐ4óÀP*m¼†›ï©UG 9skYiþ²§¦)æÉÏ[|ÊdÓ©1ÆÑ¿Ý -ÓÆßMM/šþš¥ƒk4e\ï¿£H¼¡"eÄín0u3i}dË{µ±ÕÆCþI0yÀvť᣶Çû©“ߨµ7–Ƽ(ƒBó«sLw= -ÿ¾nûì~|ú1â—U§>+©SèvÕ€ú;îõ¸d¼,Ðñh×J¥¸K¯ÎÈkx'FIø¡1»ö®;»KÅ ?Ð3úîk¯€j\: r}­•Þ<4püzEÇ\ÞI3±üêÀ+æʲÕâb« ââKq£ ô¾£`åÍŽNðz,ýpv s‚™j|-Æ‘ã*­›ÖËk º«Ïʽz¦Ú}ªÌ(¥™¼BÈçžÑÉHK÷ ððòûR+öpSnb+à¹FÓû¢üY)rvÛè¦øQ_MóDËËq›Iñ˜.ýRg‰_²±e$|©ÞÉn:_Û¹ììZ5S‰d·Ýdø]Ü×É+HÊâEM¦œû‡ùËØß'¾__Bø)Úzp\ ¹µ'k:vØÝèd)﹊UëXUjjFìq£%v‡DàœPyb›jÕSüMÛÀŽC{PLÃc3„šyjé³ÊäWuãã…žÛ&Ê|FWèxhö?+”S¢꧞éઞÍÛvM|¬{9ß{øÔ¶Ÿ4kiËwÕû8¦ªöox“qày;Ã0ç“пéÏøi^…çÎÒW³ä½ŠË¸ód?ÿË`ÉDøÚ¼k·×DWBËxKß­B{ªòèà ÕõŠ£Òú›Ž–r’ê6eü™LŽI®ïÅ5¬HöµÕãÊƆîÚ¹äÀñ|tOYù)}å>s+wœ¨(ñ§î³ç×Xª„{ÒùÅßO‘Þ$t½Ðªm‘™”ú2*“'§ŠuZÞlöÌld Ègm¬”ªUÒ=M ÕagŸñ¶]ÜÙ ¿Éš×Œù*¢ô¼ƒ\pÖë=ýùnÓÎ×¼¼gǵ¢“C… |ÂÿûêjÍi“0ú}E@ù(±¶ õ¯; -TÉIs›ò¯7”ï8Ëlòi~H;¾n¦ñU‚•úÛŒJOó•¦E½óÅcËP‘&¿ÿ#’dki¿{¸!a„Îÿ¼0¾¾=ܳ¶Sš]ŸŸí¡¸EÎxR‚ùµØé•á‹º£/‹»ÖÁQ&­Õõwþšât´sÍôÝ{pJ]|ÔM½"Z»×Hÿn‡kéˆ~Ë| ggóí§Açk:Ò A«öÏóòC áonšö´ÝºÄ,;-`¬+«¡ñš,“Ý$®ÀÖ8‡B}8³ÙkÀ~l2‹îœ×x˜)T> Ž>oöã7QGÔÃþ«ÃG~ém6T×Ö9ÝÑ™äãf>Û&K>£š\¿½­‹pbGë1ódï^†Û­¾Y…ÎÊIJN{H{PÚ},Ë[«GÎË_Ø“SÎý@ü>¸ÿ7øŸh€]Ý*A„Šûì;þTendstream -endobj -685 0 obj << -/Type /Font -/Subtype /Type1 -/Encoding 1933 0 R -/FirstChar 13 -/LastChar 110 -/Widths 1934 0 R -/BaseFont /JTOBJF+CMSY10 -/FontDescriptor 683 0 R ->> endobj -683 0 obj << -/Ascent 750 -/CapHeight 683 -/Descent -194 -/FontName /JTOBJF+CMSY10 -/ItalicAngle -14.035 -/StemV 85 -/XHeight 431 -/FontBBox [-29 -960 1116 775] -/Flags 4 -/CharSet (/circlecopyrt/bullet/braceleft/braceright/bar/backslash) -/FontFile 684 0 R ->> endobj -1934 0 obj -[1000 0 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 500 0 0 278 0 0 0 500 ] -endobj -1933 0 obj << -/Type /Encoding -/Differences [ 0 /.notdef 13/circlecopyrt 14/.notdef 15/bullet 16/.notdef 102/braceleft/braceright 104/.notdef 106/bar 107/.notdef 110/backslash 111/.notdef] ->> endobj -681 0 obj << -/Length1 1616 -/Length2 25291 -/Length3 532 -/Length 26183 -/Filter /FlateDecode ->> -stream -xÚ¬ºc”¤]°%\]èª.uÙȲmÛ¶]YV—mÛ¶mtÙ¶ºlÛÖ×ï{çÎug~Í7?r­çDÄÙ±#ö9±Ö“™$òJ4ƶ†@Q[GZzN€Š¢š¼••±¹­4¢­µ௙š„DÈhàhnk#làä¨Â@###€ƒƒš dkçfonjæ ÿ‹AAEEý_–B†nÿéù»ÓÁÜÔ@ú÷Áhekg ´qü ñ½Q 8š&æV@€œ¼†„¬€\LV ´ÚXä ­ÌÒæF@ ÀÄÖ`õ €‘­±ù?¥9ÐþÅpì€Fæ·]€vÿ¸¨v@{ks‡¿Ïs€©½ãß8ÚÌmŒ¬œŒÿ!ð×nbû/!;{Û¿Ö}ÁämŒìÍí³Ê ‹þOG3Çr;˜ÿulMþFÛ9ýSÒ¿¾¿0½Žæ6G «ã?¹ cs;+·¿¹ÿ‚ÙÙ›ÿKÃÉÁÜÆô¿Pì¦öÆV@‡¿0±ÿéÎÕ ø_ª7°³³rûw·í¿Qÿ“ƒ¹£ÐÊ„šñoN#Ç¿¹MÍm éþ9*6&¶úÿ°;Ùý§ÏhÿoƒÈÿ93IÛÚX¹Œ&Ðt²¶ŽSÈÿïT¦ý'òÿ‰ÿŸüÿDÞÿâþwþ—Küÿ÷>ÿwhQ'++Ykà¿›ÿ9cÒ€†ŒÍÿm`mnåöŠÿï‘jÀÿ ù„‘p4øÛ -Ó¿rÐÓÒÿ‡ÑÜAÔÜh,oîhd01°úÛ§í*6Æ@{+sà_=ÿm%€†žþ¿ù”ÍÌ,mþi<˸€6Æÿû_‰þeN'!§ ¯.Fõ¿ÏÔãäÿjï¨ìf÷—Úÿ(EÆÖø.þA´uxÐ0°²hÙ™þ^9F3“×ÿ!ã¿@ ÿµ–1p´7whý-›žáßâÿÇç¿V:ÿ FÄÆÈÖøŸÓ¢äh`cü÷€ýOÃ?n#'{û¿ºþ{çÿýŸë:è -4‚^ùckÄh‘š‘æX‹ž34!¬Õ×Ã6dWÒ \˜ï[mÛ퓺ÍQ¡ÿ^DÛ8ÅùÙê¶xj÷±/Iy0ÒƒfEÖ ¼ÌÃñ"¢èÍGÜ mg£:ð§Ó-K;S‹ô¸ZÞ×d¥W=Ø™PPÔ-~ÿŽ;ÕÎduõDáKäœï‹Bühïm”RƒÚЂT[pzFšpüôH60:<4Ø}Ñ»M•óƒ„ËŽ4Â÷W66Ÿ¦J¹He‹êïÝn-6CoÑÕI9G¬ Œ¦§¥aŸáòäK‹Qîïcþ~Ÿ {4C›uÝ\VÚÜñÉëÁ3(!×áÍfª“ËѿѪ7ð^Å®Q¾4¢]G]·0žõÕX°G-Å¿iÞngó2ø*(žTñ³u_¾Œxô«‰ªjy¿Ý -¥$T³ØÄ^×âs:‰¿„³Ót»©È i+3«0€Ö~Z¦Ò‹Áº*ã¹®.òzbdÄhn“<£c¿§¯ -ë³ü>Ëä1os´˜™(ÏÂß_Ø⟣٦$z#zlúµ1R?m%„ƒWåc¹BI-8v‘øòKNxoŠá­†(׸œÒùÏ[4¹RÈFNH•ƒˆUIþj¢ïö…D«6Êh”oϯ[%Z0ïÆQ:Åç $؆­˜U‰ú!6Wã1YDæcô*þ`ß•ø¸qÅó¯R rú†};V”¡ý!ÅYs>*²%èa¡ûG¶G\V­n63QËR]BlõõLƒšªNS±o³®Xãk”t¯Ž¿¥è%+Ú£|ŽÔuœÙ¨ýf4 l˜³®En>îg„ 1 æ„ÄNò]¨ß`Ф­×/i‰û5Òyµ˜7:ê 2M~¨‚´S&Ò>À{y$ «É6W¼H?ŠÅÏÝÉÓ*S;£BÝŠ ÄIÕÓ¤¹ª|wf ãÆ!â…@[|…9s³qÈŽ××—}>¹v¼¶±Ä¸©–ˆ2CÌQÕ™15Bj"«RŸóöÚ窙Ä;cF1rv/T…ÎeBPBœÐA/[ŒÒ'}¯ä •©Ú{rRŸñ[±p†âºÙ§9êppàÒ-ƒÅ”vÁ{:Æð"çd€BnRâtïn‹}¨Â‡‡5„P‡<ùáew”McÛb… L™¯ÎýŽ’µú¹¬<,ÌÒ=¶I¥]¥¶‚•!ìk ÎÔÄdùÝÊ:ó$q®éÞ®Šq¾ƒ¼Æ<ÃýÊ,svwA]¯cŽŸ™¾"{=Ÿ&u lc ^£çDÿ)a/{¦8N.§% §q±ü5¥×KÇx20œqK;ÈjtTŽ¸y´&H*À͵§¶q¨p¥GsÓü G4%Dá—rnì$áD_f!º>Èø`k‹æógúCÞŽsNU¸ÁŸ2û¥çüUÔÎ7Ú-/3аÉt=ÂœZžZ÷öešElòÉåi³Ø!š±ýKŽœ—DíØûø½u×"ƒq”‚d¯²Ôšª 9僄U1ðêpbDþ±kWaGÚ”ªø5ÁÐ ç#Ç~ÞŸú§j Çÿ½B7$Åšš’”6ìG†g€y†µWÿÚ›¨¸ð‹Êö|Ÿ¹^qHcOG_ùÎ}ŒÝËîNÓPb¥j„úiQR}D™CTµ u( Õ]ú·ð»è·¸{§¢e%‚ÓòåO™ Ú¡Þ=’Gf0ýa½<ŒjZ80P߬j…'¿Ú_/ü„ÑêaÍ·LšÖz‹€f1ÏÍRpÿß&áì88g=§u©Îc“ñÖ›í²!»GYº7ù:1’‚¾3¼rž.5»W¹"j> •Š2¦Õ?Ê{®!¹ ªô&(žì$¾^ºêX¦ŠÓÂø Â} >‡ii3^ >ÑÇÞè‹›.7ùLå# +ºÈ!¼®MëŽkX¿ &î‡O÷•ÎקvŽß÷›/á)]—¼<.Õ_‚jÁŒó(e÷¿OÀœÎ”!9¼¹¬Õ)jh‚r¾8®i® ö%»@æB‡›GïÊ.PÔœ–~1+D²¨€*Ûšq¨²×`ÕäÀ½`ñfŒÜ~{éSšØ.7§ÂÑV,¼sqÆÇ\ów/Lrå¼æ¸-6a¨oIÀuêˆËîÕ¨@¬EÒß­“K-۱择á.ÀäA]ÏB²ßb:ƒšor…‡@_×ð—ù L'¾RHüÅýϪà­yZAQnƳo ôSóŒà%à¹WœA€\ArKñðÜÍÕ%ô¿æneDáš÷9(ËMŸ·œÔ2ç¤Ç5Á2?PFÏ𢧷I^ß÷4#äD}ÏügIJÒ›]RaßÍQ×|™=ê*à¿j›¸­¢½Ø®Pbû&À„K¦1!>7µ‚Á’¾ÒºTkÃp¦Ô"•Cy¤CAx$u‰WÊHµXu™ªÔæuz×ðœàÅÜf˜6‚Š&´Tçð.ÄÆÕŸ¢œ3…—ì’~¼.¬¨ñÒ°(—H cð]€g R+…Ó©®:¤ zœ§ó×p–†?'Y¿´|gƒ~·xæg˜-ËÓK̸֡wî?3Â[¬­=`â(*ËpèUÌø®Â.ÃE=Yâöå8#ÉH©”7äÊ>S»Á–Þ«Ò1â‚„Ñíf'åÿàz#ªZ:A^ªë·¯ìœü|ð˜+ª¨¶^48i¸Cº¹,xŸÝ3ëK&ƒ ‚ -Ý}ÈâJK3î„ÕžÖõlµüÁçÓDÓRfd‚ICÖFJ$GKó¾¯D˜ü‘·vŽ+À$kPSöc«¶U|R·Æ ‹‡hX'œQýSÁàØœ¸5£ -•LŒ{Œ›h1X+ðaÃ1©GÌ$“ñ¥l&HÝoÿÃ5Ÿ©qΧ©uAÑÇÁÛ9+.ÅÌAK¯lrD‡2||ÀÞW™òqo ÅU{´@ÎÜ^ËÜqøHΧ6U½SN0} ì Šz,sE¬˜¶a;eŽE/Í:P–ÒÝH“OïQ\ÉŒm–Õ›ÝèIY湪 F'}P¡Éô”ÆiR¤ÞÑî •¼Æ-D1dšMZa·ø»ooÄPe0™ù{à3X|ªÕ(Æ5rcˆí“ªCch³Áó€n']íõ%®$Á÷pÙC$äg´ž/qº–Q„¬{kÐÝy¡ »ä(örïZÔ”*"ILÎÑŒè¹ÐbG. /“!C¡U†RmÊfB,@²¼NïÊ;ÉE–•@’O}64jÂ(æcŠ¤½k#Ï÷éWOm½·þ'Ãœ¬2ƒ÷¦œ¸ìuzí‘tÓ^% vÅ©§{“F'Mj•åçKÐk>ó/Y`íe¦ÊKdëÑžvÜàlG8h(ìü2«ä¥1(_t“K¯cdOc?$øí?JÓßù35![3ìú‘÷ -M J9‚®»˜=¾EMì¥Ç§SëøüªæÊgg æ·g˜èô\ %#B9%´®©b]c A=Ô'‘B˜1É2ׄ١·]CbLX Bîo’›Ð{ü)EÌ~É–½ó‡¢½§‘E»©z! &‘e»ÊÁ»*7Èç_"mœe優t_8!ð¦[rФNC+PÖª=i -‹“Û,o2ˆC½³Ò=ÙÖk•/ØØK‘ÕœƒjŸQªÊ„·¨Ãy -@†Ä¿ØÜôH ¢ì’×Z²øPAçGÆKX•©Èë7ÿŒQŒ±f´ý1ÜF-Ùw|¤$»\ÃD¿‰x¼ È€Ñ"õ†t?oånŒFÖÙ»s¤‡V@•RÈ2Sx p]½ùö]¼¦ÊCRë ".zî¼å§ð©PGŠŠ Ôƒ H>öé%WÀD|rÀ©ñËE`…zôGfìí¢t•„9—šÏ¶3Í7„  ir6s¼ŸÏ‹¼Á†(»µ›œM•_Ï^–8%ÃÒÌh§Üs: žlwÇjèQ›–óž…-á’æØŽ¬£öI:(i>·QÄJé|]ˆgZC—º’¢0'¡Üœó7Á¿†pyfãÎCûâtˆí&ž?¨Ó[åÏ蘚ç>÷bE‰ÌiòK)¿Oµ…µËÃmžÒÃúÔˆÒÒ³ü}'ð– ixiªûÂcá‰|^"íÆÅ>p&ÄñâüGÚ:[>´ŠX>µlºZ‹ÿZ9Ð[:ž}€Àe‡Fk;èpO ©¿=–õySɱ¤T‰‚í)Üsm%¾äËï¨OZ¥8!'Ú76 ÅuþöÍqCS) (Ág-˜¾"Ÿmå:ºWV¶õÇ/ã|ÅÂY¿,F}ØÛu/Ÿˤ°¨570]ç 4eCØ¢Yøí–² ó—Z -Jë Ø -{Œ¥«KqHM+~ÏBO¨Ÿ?oiµxÍ+«7g7[*‰F]4HxD½I·È-÷€ðÚѦîº-v€á*hûT°ž½ g$+ªíá?t"+<äµ +zÒ´ÊßÇKÙ’«fÍ¡Ù”ø…È^fx—wÝ¡×Ú‘Q!·úwxm$, ãûùyïìC8@„S+®dtóWÚ³æѶ9ÊN-*h³ÞºE¨‹@­åðòuAIÒØždé°&#t›ÿ xªÅæQ§„ óãUÆ)3ªçèeœUýaìFÊ7iyªÅ+; c ,Uïלq,0úv~D5¡§Ü”+pùˆeÂí<Þsm=ûÌWôÃÉS{ö’'4ñ§±¶Tmon“º×d5 -9µÝ.Ý0{Z[Cdiî×É!âOø^)kUIÑhäëºCiµá{¾ç&KÚéçýoû›ÆîZ—‰ÜËlÓîÔù—6lÂKR:¶;y>ñuj u¶ M¯²á3Ú©*cð!¼cpäï ½¿§$+7æ,ÌŸ; o&ÁÈbÓZlÑ~ËwÔ»¤¶”Y¶ˆ~ÂÞÉ)X‡[u­çÌSX‰&©ìÈ-D rÄ-‘7Œ¿îV5Û—nþÙÓž­ÍÔÞš£÷âËì›tŽƒ‚õGQbEˆD>¤*꯴Â[@ÁÖ5Ƥö*>›9%§úýDHÔy µff3@h?L;¬îFÂð¡Íϸ/;*s ˆ¯cOåU®BÚ½/âAñ.kþÚ sHFC®Ü¨¬J½¯1þFn^×áöƒ¿¢WW)ËNV¹ŸQO‘Âömœi}Ü8åÑñ¶;áî=Ÿ8;2{¶†^ÜóJE9£n(tòx~˜Jþká)5þ–ÞBʨnŽ8Ʋ>>•m‹jS#®YR«—Í´…Á­‰Ù\ñGkï¬1_d:mN;ªž‚˜"a’žq€‹©°Ê?ÌÐÄ#ìÕãÙ{½=#Ç™‰¢Òò¢äè{¶Êl¯=¨çPÒDZÒ‹Ýlļ÷Ù-:ñeD8å=ü*$YTÔO½xÑÜúÜ]µ©ÑÚˆ”I5ãþ±×©_)ºNÈ3¨6«äµõ«‰Nó"äD1¬ù „®ê0ö°7®<4ö(Ìuæ´SˆQÁ“pR/Á®E©`SŒ^ôÈÅÙ@D‚±ñ–§æxÌä}ú”:»º¶¥uÒpp—§QÿÐšÓ -ÒÎ&rs¿:Ÿ°ôåÌÄÜÏVèy.<Ó!f•ÛËiQØg:0ÖáéãÍs_E©3dΑ¹Ÿ:A=Ë×8‹´dÍAƒʽïêÛRØ-À×SÄÂ'ãBØ\eá~›"›ÙRrD|©}Ýÿd¯qyIÇð1ó6§µ(‹‚hQCÀÛ#÷œ—é[6ED€ó‹%±˜úÍ<ZL9ÉAÒê“sõ“7\wêm’’¹Ù·—¬˜9ðwב0Êpø¢Ày&NߧBm4D”SD"«4*Èwît£&ˆÞWÄŠWÈžèHÌËKv3†;a4¥QoÚ®ÓA.óÎ`L›&•q‘óýÁµÚi¦týL6OcG!,çj§eD­=G83˜ø®eÁ鯑´^4ÒršXýŽ2Nä@È“mï†óD¼ <ÔýÙíŠÎ±6øpv\èÚž”%¦3+è¢W,K…êÙœçEÛhÃï`vÐyù'5‰$ع$rñ‹’ŸÅ[ -Ý(~®$"·jJZ«ö0V;XÁÖ9àL[ö÷ŽÃ=ú\µ$ÔeKE²¦ë•*VÃ% TÚÓì—£ácÒ㢎¯ô­1 6`hÒÀ7>œm¸>/ÿge–‰—sªè²àÔ2Vú¤ yîpwí¡úÜkÆƱg¬¯Ð·ˆ½P…ÊÔÆöÐGWð%!Žl sŒÒe £•;‹8Ù1Ëk²àÚ>Ø?Fõ$é;wͺn­æœÌ^Ü”/˜÷RºñTš„ŽzÇWÒU~WW›G0a– @8§OQvˆk?UJ_xJ”³&ûˆ#p;'+ÍUv˜á#9¾}¶Qý•þÇ%ë<"w9>O“d°FT´pü;í&w°nð-gùo …ÁŸÒ3íâDã»­;ÖC+Ò¸ïÅf@Ô -Æ°çe=âT“¥j-”_.¾Ø?0Šy!éâ}tF_0ØçÅæü¹oet¯IFeaa‚+œ:%N»YÎH”¿ÅÜÍSýÙ^7DžÀ“b}‹7kÄð*¹ÑùÕ|Aþ£Iæ·fuêEÛÛÜõî¼½bÁÈ:®Ô;I¢A9ÙP -á[xœŒ†÷\KQ}Þ£{ânUÃ{¨ƒÁÅð(¸ixJ -/ÀÅÜÍôx¢Pt|‚£»ŽPûβJÿ´ÌΧ•Í[…† %®§íßW´¦ú‡Ñá´L±ŒZLys)5œb[vb§¦ÖKÃB¬ÐüŽÛ|Å2Þ>‚µ¡XÉK©o[rHÔ\ñíq˜²? ßyæ ùíoædÏfN/Ê ÎMB-£ÁPˆ,÷#”|¬7a•´“YE8n¤ Hõ¥ ¨ùIHÿD}ž†‘#×Àä:>ƒŒlØ)_Æ1}N šLŠýö]ùNp’›±=’“j †/Gîr¶Ò£1,Â;c|6Ž 4Õ‘a 'ýq*v¥Ú³§ '|iú‚â®ìL5³ÇI"wè{À,•|XÐì¯/û(3Âö-4Ø—•0dT@N&‚†E|ð4þç.ùiÛÑœÈ1àü[Ò pJÓT †šžs;ícñU\ÂKÁ/m¨@‘§M=ò]“’Jí‚% ë_JXñÒ¹Žìhuó{¨øy¬–z­¼ÍAWô{iaz¢˜š–mŽÜ󺳘;¨2¨/ˆþ/»ÄcÆѶˆäó?™Nû¸°Ü F`® ^å±Z§ôv»ÜÃR4êI¯d¸'|ß|ºÐzëÔ%†=-ÉjÅÐÕï¡ó-‡Õ´;ÌXåpMž8Ìæ-< -QPÓ-áê“&eÃÜÓªŠ^" q\SVÁkøD÷>©Ìp8ð=·[5<‚K‹ “óç/=¨^ï{"~jhõ^Z ×çþ¸š[Œ ä{˜ÿEƒlqt3HðGRÃÞ¨î|¤]e1ݼqì&vÈúÍ’ðfôŽ•žŽý³ð¨•¯ëåu!šQ³ú¬€#yìížJ}ð`¦æÛ6YÒdvF§{KxôDl¬ -TSõ÷Ò‘òÍ?¡n¢‡ Ì>bO³3ÙØÈ#wÈVßÊ[½6´Éû‰V˜5xy`ï’ÙFC±èëŠY &³»ïÙXºÜR>Ñí.Ž ù’Bpe­Œ ¹Ž•®¶ºÁ¼ž¾ÖM‡çÃ{‰(Lv¹%Û<ÃDì¼Ù ÑÄ@^m„ï}(}屩 A?N'´89}¡ãÕ°àahg›ò…NyF=Ø,¨E$ª=ˆ -‡?wÔ]™{†]°á³Í4jÕâŠ”P)ssW;RëË„‘#•m“>®~Fí&û[¾F>«¹MÖ`5`¬M«,>NÛÈà/ÁnJ¾V¦Œ뵞ÑïyÀÞÀù؃7¨–Qa‘5¦CäÑÓƸÅCOƒ­r§Þ—س–ÕNæÉg%…•æþ²RZÔ€ªf1 -Êçx™>]ù‘³±”íìÕÄõ3OSF}óÞn+QýíPR»Š¦½Ý5­¨VÅÅ ç„þªeh—‡ÇŠûFe]mÿ‚e¤e¤RÕƒÓI¤MQÈ›.·—~#v‰XÇJ€Ë¦ïu»wgß´»Ù²‹Ð·‹mèΩˆU¦Î\ÂÜI!&ÅÅÁ -^>íª$¡‚ªN³°jQtˆâ ¡'§"»BKº-¯”¬ØfOUÎ51½D:e;…"YE­"^gŽLÖIÜ)Éæ#S|^o´¨/‘feý •á€•‰¶ 4ê|¶%ýý .–î´0¶&Û$LèÐÛýÏk¨MLèOöc«¨ðæ[›L3xÒZsýZ”Óîd42)wàÐ!É5³ ­%aû+|ã=Ê.ÜÓ¹3ÜÙ8Þ- pˆh’•™ž^¿W¯ïEvÃhdBdwü¨øPy>h†L r%@÷CøÆ#œ(|HD‰ñÝ ¾W6ÀG~ùç+¢m+ç®_#É€'[.ÕF­ ö Ô9”f÷iõD -ÇEE‹S9WM3×!ídòÔmAfoçõÄmî¦Ð[Òd‘F$ØíRUJt·äýÀ ÷ ä{v@8üªÍÁpU×°h7(Ë4l^b¬ç/«*ŽS<ÎÞÀ$l:®NléÓÉÙé)ŸÖ%¯¥Ÿ8ƒ‹U5ã=çøŸ>áŸKö…(W$#,•üZ°QTÀ1š¸ÊS¾í>Fj^*Œùnur8øÒ”¥tgá†EÑ\£±kâVružâ„õ#=Ü>?+ÉF[M¤&Ä7ë&%?×çRí¨¦E!3óÛvtˆ´S²–•¨GÛ\˜&w¬bÑØPÏLý,ýò¤ -0êæz©/`¸2ídž©Ä[@GÊÁn‚½‰Ô«þE9"*‚G*þ½Îbé”(F†C}†™W¹–^.~-죦ª îêê>. ó¾_þAC鈮ëø:%cý6{L™n&¾[™˜â¨†énC–rMÌÒ( ¿Zv›ptúˆ c2{d„q¡D|ýü¢ó䊇•©|„¦3Ì‹ÀŒ¶¹S(·’ ÖÿÎV‰Ò‡CýîδÐCM*y]?œeàq1œ®=à¨Ì>xÞd?O-G¼®·²µñ¤ç¿òºáåÞ¿ï¯ý _ŠS߃Ø#”ÍÝÈÞc³7—½û9˜X'!yf¿ÑìfÝ;ˆg3³Œ0¬`ÛemrG¨^²üzë ÓãÓÉ×eI’ÚuÓV¨™Wk))5ü÷pÝ3`ÜŠŽâf~€)`â¸ÒÉê ¦GñF¬&ÐœíçMÃD@«UJ¾ k¶¦» Öê^ŠdÔ«©ÒmÞ~9OºðQ†4Â>…£”ÈX>®è8#c -ÿ^÷É’^³õR™aÉC¼ÇJ®ÂZúí!ŽHÑwØÌÒ—þÅÍ7ÜÂĶ6Ú™¬žÛôäAkyýægT8 @.tß ——™³?â¥ÂËÀÖZ:WŽÞžEö~îþ¯6ñ߸lëóÈj*Ò Õñ¤ã×EHŒK˜âS5TAœåçÕ1œ(˾…µW+1ä„ÜrzEC - ŽM·«*T$à&N_Òò,j5% -œì_ØË\ŸŽdµíY|ï—ô(®iÙ˜ï÷_ <{‚ßnSéÓ7T³®lpá/Å=[ü][Ë6S[ÑM¹–3$`êMIuÀØR{,ÅWþ¤”µΖg-ÿqjòIý˜=ßôY÷idᜒÑtR˜)¸z éôªóe;úOt+%«Àã†Ù²ÇÙWË7pž>\¦ ÅxÑÍŸ*L³bæüQÄ'QÛ\˜èõžx˜:S,Q@²úIyîÛIÿAË)i^í·’ê#\>¡²ˆ×k¸ôpÀ/ðânoMe™3²ÌB¤ÿÆ]Ò§F¿"Ûà5~·±µÐÇVS´Öþ,&Tqx`•GYú®F/Í âå=TЉ¦ê&Ô%³S¬À#¯]âëI–7•„GKPj%?‡Vo ÔR6Ôõ+¯0X¤Vo€\Àå)s—X‚càÉRû{c‡Õ=µ\…=!ýûÚ\'<&~j~®èHü‹£l”ã7C0YœiÛɺß>¥¯:\»á84±tÊÒw6ò°á¤ëv­6hÕ·ØYYŽž[¨d%8ôc#œŸ+a&"Fš:ÄrU•Î­›‰@zSßÜ®s'"YÉNePtí«¬·÷?›;Ej“Í&>ò‚ßk@)oœ¡”ŸÀ¹f3% (¾«-K~u0`²¡`«Ã/ÿŠVÔXײaURè+)(™êéûÙß WHœ;tLçñçà’« ç·ò™‚< -öšûDG¹_× óæÕõôðªØtx˜†&ÍRueŠÖï:FŸ‚sy.!À\Ùs‡‡k¯EÁ€Ó•sö«x×CíÕ<©t¹KrgÆ/Y4Žö•V«‹§K¯€Kb1¸Ž†¤”,M1}}A­ÖW2Œ…á¤ÊùÛ8x¼3tã×Ã3Ï<º›©¼U³GüÖ†¤|D‘‚ZÚD…ûú÷÷>Ìâ’¾ÃÁÊ:ºŸømõA‘ÚõØ'º\ÝöH+Ì»tô¤H¿€áÖNÛstàmœŽ'1LÞd˜Í8¿Ê!©£lÄö'`•,áO›>Ö SÃâ<Ú…Ì¢î±D»Lôyº*mpÐœŸUžâ™Jš:‘¢`6Í؈÷+ÒÜ\ñ2¬aÃUÃ?wéöÛ<ÚÊë4'ž’!lž¾T§brÖœ-1_/&âXcb®ÓiÇD8ûæþŽu†åfmk7ÔõvüZ­ÏÅ¢ã|$b ŒAnÕ·Íê…¸bQ&¢½ÁRîX[ÂÅѸ¶ ¿øE·Ë¬[oÙ¶žÚ[£Ê«ïÌw>w¦{3ÿD)¯Iÿ#Ó)°Ó'×J‡£ÀŒÏF™¡ã×ö£M÷ß4ÙËáZuT»Ø²n“€9DDt”¾ôb5Û1g8õ!2õ¬j<­è+Íy" $¬ï¡1!‰ùœ«l_.‰‰´—k3q,7’•ˆ³F÷F¹¡ï_z=F¨ïœ:Gß¿q€*F yDÓ³–R3¡ÞPaZ¥~CRœúsF]ñµ«†, -áŠD(A~«ÌiðÔ–Eó—1+¥^¨„iyÖ¡dõgVs¥Ý_Çë t\û¥[Vƒ‹¢ ãŸž4Ž«EUwS¦€˜”ÍƵßT÷Ün¯ °"@æs÷‚Ù¡h B^#ÓÞ€Ý~aG>a­LÉ uò§p€ºf¦Î -ë`H“@$ÕflÕ=nUúÕ5îÙù-2?—+{žj•ð¡Òj›W b>H°ÿØ…9ŠÌïh‹æv =f÷{fÕüVì:Ç1["rù”SêƒoÑõ¾Ç’€šlOÕ‘äÌ]ªãuƒ0êôXPðkµ»9Ð…Ø:ÿÖ‹\þ±Öãà–{áÍÜÒ#ú}B*Q½‘W¢¢´ž…tZ…xœêÆ/*ÖV’^oá?Z‘F ‰Ô7” :ã øcj¿?‰zz1ÿÍ^yãývÍð¿\û0Æò±ŒÄ†]dqá=¤¿@‚Öº›3IoÝûÂ"Ãp™çMLò"–Îw»h=y|+Õ(¹2#g‰DÛkœþUhÉ«ýƒh+V2™¹,ÈÎ*MYcœ´ð¬äOæ~‚ gï.ícfÛèMM““!TêÕ6ƒ8 .ƒ)¡ éU¾ïmS‹"Œ§Ô°5” L4ûöã¾:‘Oìc³5hFWG8 sË›æs-¡ëûç";÷\¬ã2•„ys8‹×ªlºP²XÎL|¹©‰ü4ÍÞ̯v9êNvsr‰…Â+xCü>c¯Xç§Ë'­}ֲ߱ß1TÝçu#ß2çÓ -+¦É¿ìÚÖŠ^Ú®/\—sjÇOŒ¤+G4Õ–¬¨9 -,Ù°U× g­·ù;ŸÐôl"•R’uEc°VÁ2^ºBRA4MæÀQ‰ç‰¶·#ÂÊ€ó#Šh­5¾;•b‡§XæD ””gX]åF¥"yM…Y@ÅZéxaxÕ49ìÍ|ÑÞŒ>‹ŠçââD’ü2¼C%4öÿ/ô»ènÙt§ÄŠeýú2nš±t =_~ ¼}RÉ~>Ë »a0¬n.¿Î¥µ#M HöíTiCÕNjŽØÃsûÖ‘ýaç_ÒÈ£ÑxF‰“Ô EG^Èn Ý=†¨Œr&ª‡C0ŒwCÀ“`>ÒUÜFæœØXîØ}6ø[·ìfÇ·fíŒz¼–ç‡ñVÉSçä‘¿Ôìi€ÐgoLúº¨6UtY–S ýS´,ãþXppjIíWÀž8›‘ÊsÇÞwZ„EyB¦È˜Ê}°w9zÌ^Ù®(ÿ÷ôÈЩÛ<KäVÕø>Q/ÚÜ#ï×Ø·¢yû!«oø~Aòô­%“#¹ö÷ƒ¼BzÁ˜»ªŒï?_"’ ë‘Úë?w0ºŠüvˆ_…¡"=%_U[Œˆ|ð <"á6ìZƒ UcèzA²¿¯5`¢\î~ê×Sù©å¡ïÕšPÄëŠó+™ë´Z,kB¦§F ŸñÁêÚàT‰Ò~–á^Wíl¹PÖÓáÛ](R¶=$Ÿ‚$|-È°hˆÌñ„ÂÓU¡ãÆ.ùƒ-ë¾)=+µÏPDóÕÌÔÅ-öÇe~àï ëþ½ÙêÖ;fx\sYc2¿ÞðànóyRYƆYõä>n½3Œ=yF@NÓCBÒ ŠPœà€5¦+úÇ[rG¹h‰ºÁ™NÀUÏ ›ãö0ÛÖÖwé߯f3œEñšaJ†ºxüèEÈ ¯ÄUt6q-èa¥‡z5 þCg¿šÁ´˜Ù[Yˆ”œúéüü™Å<¦ÿÄúŸPÙ×(:þ†r<+ ll"¯‡-‡6ë‰ðÅdÒîÛÖ²D,vºÑÖq­ Ch"'ýc‚$^´5ð¾»D_H‡”Ò_ˆ¯¸®ÀŸ`¾í¤þlØYF)×op9Öh¼â«äz%ÓŒžËÐe7‹õ}fFîSª¬Pîdœú‹À¼·âŒgU´ú4L1˜ê'‡5ƒ„‡cDˆžáhÁŸ¥Ï HP ðñHK¯z›lîD‰õ“—z¿[š«ŽÁ/húKØÌZäjyù[\5CŠœG#ÀîcEU½o‡ë`1òd1v'QeºŠÞÆ­¯!Íâ¹IXÛ4+¼\zˆdÏ'sŸK ¦²R)¯l“€‘?‡ud¾9öˆ©jmMé‰*—‹| )„Ü©¹úºâúÐ(" çVð(è<˜¬öóPĹÆÏàϱþÔCL`E¿rKÖ}¥ÌÆÉe¸yZÓÚ̶OÑÎ~âŸ7ïã9•Ò&œkq¸F¶F#¾Ê Õ»ci€kzÆh²"”œf¥²T¼ âœóÌáæÕ¨`Vv÷ùø»ÛÔ#GäDz»`Íõ¸ëØò6ÃIM~ -1·ð€š2åªvÙz¥›Ž³AfW­æ› îs÷óK—i&ê¯Ózy¿ðƒþ#t°ZÚ)þƒÝ6Ö¼˜ëþ¥ØwÌ ãZ5ãRa Hl[:VBJí3¹ÓÌ/*m“eâ…Âé;á°¼¥e4˜ìÔRéà©êý_†Í|P"w9B FF¯Ý,€z]WñóRAJúۈ멧ÍͪŽI{9ð‡,Îo²#â«*¡pŸ¤Š†^YRnTȘqÛG…{í~ý©J,!à‘¼RçÌÁ’0ör¤A[AÌ ‹áé$¢$’JQßGó½i·˜åÌôiÄ«õUÆ ô¼òàÝõ[P¹BsüÔü.¼†³».y‰ù¨†œ÷·? -kÈä+>x‡ÅôŸåÞ„PÁ EEo-B1ЦL¥ŠñãÝÖ›²Ö›ï{ƒÎûZq"Cöá±âši¨èbyÇû[&Èïd_†/ -ÁÑ™i-j´ã/¾fXØü€ßÙ(‡.V’+®¿ ² -½JTàÇÊcŒ†úJ$1³Ù«B«“HûS•° î{ƒ)E˜ï@Ä|èÈö,›G|8fäUÜêg¾dÊÊSð õÀPÒ”¬^Ÿ¢õ±ûJ#„ÉòvÖœ¶2W¡ýâ­Vø~-…3RüzÌýÝ÷ -3Üdc ×›+°É'©z8údÆÕùÛüÌ[Tòw@ÿŽ¦žÍ…gM/Ù›ƒéFŽ]á,ˆø½Åžlx+d±‹ 9²ðä~OêÌKC†«hMŒú%ÎvkøæþÒ(„¼MW{B %8T ØdaèÒ…`[Ô¥Ýy¬CCtt?èhîÑâðïä÷`ãß1>ëÕÙu•î$= ›gSg¸W‚Åw‚¾H. Þ¬¬_ÕLz£x­÷þç…«ˆ9ú¼Q³:²sðÖ9v®A%ý˲ùïß¡ãë’!CÒ¶è‰)YXP›Äî­é•1*A‹EöRSîŸùÆš¦ÿ8L?#ºOYI(¬c,F‡n¿ô¤@É«ïE6ÊPdw9^Öäv] ô%cND·y§;£ÙP™äµQFaØ®›qF?Æh¿µÚëè-Å×›ÞË#ôý<ë)%™<åàiÙFÏ -{@[s0Ÿ"¥²ŽÌdbÔǘ–´EVðMh^±i5q×B2¯^JO ^Ìê£oÜ'‹âØL¥ÆdýT<“ø­ê²fjí7Dµ• 1­X}2†7›€¤c½Bbá/?ãÒIxPp%‡Œ©SíCÖ…“La2ì‹i½I[«E8Ššå½¸çÌ Þ@Âî\ǸŸ29SQTw*ÑB1ï¼Ðå+Uïh®¼Ä¡Ê/þ­‘Cå y[üAôŒŸ#2‰oLú *ÇÇUqQ½ -ó|,šZŠK§ -J˜UÀ·~SsÜ1Á¥Ã3ûtâ’”§ ¿ømƒQDf"x~ˆîd÷ôM”prB!4¥”N½Ëïb«@äÒë³q §àάAÃêÕµhÛ„Œ°Ç³8vˆti¤E¥ÌU$ÕƒF#ãlˆè‹2Ž55JÁÆû -W—‰ÊGo#Jܤ±ÐLê yNב]IïðÔfñ+ZMv‡ï7{ä¶Ãê‚øíXºžXäó½Ý‹`*‹Ò‚jpj÷´?+› -|B@†-›&±í ä5‰tkfÏ?B~½b:%Yñóà6uέ£þ˜”£LA®ªˆðÁëX‹ÀÌWÿªïÏ,Ñoðö»¶ƒ1´†Ö®ûM")ûŠ’8H_Q@)­ÃûÌßj”Yã*Fô&ù2ÙüB‘çÇ.Œ%nåÁ\Û†_ØO˜Aê;)çÓjÙ7 ÊíåÛsoÒ쪰1¯3Yjè@á³fæåE#ÚQÔYï”zpÒáš×,£»e‹\nÆnCþÙPÛöXC­ƒ -Û .]¿1èf‹Þ$‰V™ÇŒ[óN<š?ÜY ætLçN¢“v} «˜&…yncú(Å:ÉZ£Ÿœî,Õ„wJo ØŸq”é»»2ÛÔŒR⩽(Òue†·¦³‰Â€D…%ô¿Á„Ä a÷uZG“9ì4éÓ¤uy Ù¡]&PžàfÌeAÔ>X õ®pøN·¶±R`ÿläC‰ÚHlÐ$ðô²NæPh7»˜ è›LfŒ¨“a h¿Ïy8 ¨ã q˜ác )ÿ_~1iSÕˆC¢aH ”Ó‰k0zÉæ.@ÉÕ—Rû“µl‚‘¿R §´ù½Lý¥tû(Iðd˜î |ëm´ ØÿSáB÷ÈVG:ý†®§DÚƒ?s¼Úö˜ ÎTëýô?ÿ?ˆ ¹×”-.ûdÜ7”ˆì¾.îÐ -q·–-bÔqŠŒë—âNòA?£,(T|Ý·ž¬ ¯[{5º MÚ56¸ñ+å-x «ìŒ즘¢Ð Óž‘¡Ï/Ì^;Ÿ -<Š´yçö{e¯(×6鈔I»îbyö„•ZA„I³ªÙÆç`¼ÏÎS¼^™AáRup:ÓäGW@-!Äø«ƒèÕßèËs=aË‹Ü'vÉRýl+}¦Á_¾u0ûÅF/¬D—5u«œ?Ë”ëñè TÐaöÑ»ZÂ]6A-k•gjtfÞñkLbn€£‚VáÊœ¨ºŽà.yÞvÚ…};”kÐ÷ñY 8{ùÑïB%}Œa‚~óE,lÔ³J0œ¸â_ÍõÐÁöÉgaá+!Z"U”¿ýK2š§¡¡¨¶,sìSƒ"&2ÙEgõË–}5ìK Ve -Öÿ“^)~ƒpàÕ²ô*²ÿ‰sY:ûyé×6Å€$ŒÝº½Å{‡êÑi×rL#¯(T‹PÆvœ·Qr†¤óVJôkH0¥rÔIV€«´*$ã®/ -ëÙO³!õxÉRdíhÜ!] úãUK+<7Öœjã«/ªM;Ë>ú‘ÕÃ}„ý甂ÜZV훺¤¶&mgëlf1nM¥þÏ»{I¢íAµiŠoL6Qca2Ì'ÚVŽa±„Éü6¶Y(¨=¯/-ô 4Šëfræ˜Ø„‰¤ÚÒÉW9ÇÃ7ÐR~AÉÀ‹GŠßJ2´XÇdI<Œ¾î•ìM°ð*©óÔÌäÃÍוE–Ѷëñ›Æù˜#ÿàÅx]j{$8@ÑöœÏÈÅR¡Z¸ÓAŽ¤4AÊA°TMáЗˆbZbq2Ê¡²†m€9häxÒµ2#@n[@´<ò±íG%åSz‡Kñ/w¬ó§RÌï¾æ˜q Íî‚GâKF/¹%ÆÅEw•®dýª,Tè!0Ï+? -bù‰æ1²y†#Ö6yéRØÙ`sßUJ öà‚Hø.ß°›GßôýMŒek½„¾Û º¦¥CŽšËž…l^§¿\<…‡6ÂK̹çø$‡’vçÏ %hf¥Ëm°¥sô |G'Æ[fûý/Ša¥¬3µrž®gS¬Ê~9^éÈŠSìꦘÏéNÐó á¢M>À]àpÀ -䀚Œ5åèÓíöRŠÙRÒ¶>ù;¹Ý>Z׺Oמڢ5RBd$j«C ûJïeù˜äÔwÝX})ZϬ&fäXÛXIƒ^±®.<Ó¾Û+ç­ƒ…Œ{dÕ!¹\™˜ïÅQ’‰EªgBnëø]~©ŸHJ£ãßQ Jì㉨K$ewqá0œ²F§_ñÈR7p‚ÆL˜»‹ZîFë‰c‹”%»• >¦{+e•VÊÝVˆÍê]¼ó–ÓÒLäÝ‘h&$¹./€Ô è¤ÐàÞà€y&c_ž0/‘D*#ûÛ਌‡¦uõÁaÔ<‘’Ž«kW’g&8>Ÿ§Ç¹úã{ n K?ñVݧˆv¢eÿ–YdÙëûv*e¡»âbƒä³Œ‘PeëÈ¡¨ø3€æ7¨G=61ØyvrˆèÌ/oë¯Px=Õçö–‰f$úÛP8BaZ¦tð²]6F4ºî:'ù H&0¸˜/’w+–é{>)ZÜÞÁ F &–¬%ÏS-l—¯‹àöIŸc†Wˆ=Ô¡8œO[âb׫ÖLÕ‹´¯8¤¸î59ó øc’k!±y´dXFü>xn2HÍ¥@ -Ì‚StRóùa¼âæøïŸm+ŽÞ¾µ¬¼/†m@”«†fDä)”y â­XDl_`p ˜3‰Õé"p£ ùÓ½r§à‡¬i3N€‚_ø+iÝ‚WQô¥ˆlò÷ÅK¯Ë.XÐ :îîÐ0 ûvפ¹, aÑ;‰x{N:ëLÕoÓ„4ÃÉ€«ñ)í/9Æïã¾KÒåöþÜT.7±¢¢ANÕÉg=Ω¶>Ñßq:u¥ÅÿµÅì𡼠6p܈é3£¡²“®+è^ÉehÆUÚ¬B}¯\u¥™&+ÐÇB_¥²Ê¥e?‹)„¹Ýá×oÞ,ñ#6ǧ§ËEô7u@ƒÒý§å˜MïD;ÏÏÏ;\Má Ç­ l|~l‡š[¶lB¯ï¥á1g<`LV+ .ò‰xo샥 $(éÚ?J’_ÂäRŸ2¨!û×ImgYwŒÊÝêû“ÅÿúžÃÝq•£-³d/RXÓ€óý¦÷ºÛûJÀ[#t>D™dXò§`K³µ£¸¾»—J\&g“9éx!+D•éD¯+ï‚ö‚#u‡PãhŽj\~búiôïq[€Äß‘yO(³ÿ®™3hwr粂ˆ¢†;D¾J#Hù]øÝ/˜[>@çÆŒt.<‘I×S=RÌZ`Ï3Uó%ÖÑõ,Á>!ßÀÄt$9·žÒ›Q6óâ‚:ÕEðµ$î£?u&ÌIßIUŒûÍÛÜ¡½Àý—#û&y- -tkR¦ ÍûÀVùŒ -+Eª0»¹§“Í 3M‡rN?ZeÜÔhSžK½c#B¯š`”Ž+ÞÁ?í@žâM¹ÓØ%qndzF¯ðIÏE8ú£ÖÚ¥dó½ëH’›Tz]¾7]37Ô—ãß?2œœÕ˜`‹Óý5ŒVY7Žâv‡ ébŸ -2ã$5nµD錥öI …5;£·‘³â¥œš½œ¹ÎœI—¼ŠP¶–z ¬{çÙÏšÐQÅhÆ- [/µ/þ%Á4¾Ù^—a‚ªßvè¨1 ¡x™6LÚëI –œ©n¾4âzEÍçõ3ù¬ßÇÖ%r—±(×Ù[!yŒk»¬Fy›˜µ›e5kWâìŒ(¯(j¶Y9›oæÔjCBçO›ƒ±æä9?}0‹ÀÃÒéstQ Óútƒy QÆä*¥[ ~R¨[E†¼Íx#è{¬=6OKâ#s‚{oq“7ë­[›¹D(r]¢&†·­)eî5:_ÙÂÆ7D‹”C˜TɧµÇ~K˜’±TŸVåJ"ð_àö!¡ü@ŒàÆ›Üppm¯ÄHš÷k-‹H¾©—se•`jš ·”õµeæ^±üad‡DuÅB\CÅs~Õzß<éUÍk•V^?ÝÂø1 7dAíî]žWŽ¾0 º¯èP¿MÄÇßÓÉ„k‚Š67Ÿ7õæ¥ÑìJ4.Š“±!­ó[¤£æ_7ò&²œkGd8+0cë³®¿ƒ+ÅSÑ•ˆ@i¶òÚGîÏäÀ”ð´øÐ?Œ=—ž½\ŠÕÔ­Þìr ×Œâ³/Ÿ6`OC\h1ȸ˜K öD°ïŽ @ÅÙø1d­)w`0a=Jç)!Ë2ÁŒoŸk×ñ±ÔЊzLw! ¦Ï?‡Sw3øò GG -iâwˆ]SwC''/ˆŽ‰~ðs¼Í¥PC4³DuE~A}=Ó T¯}ÁuÇttôÉNx`kWãê«Ÿ"QDúnÓÓÈcàßvß :Kð°T|)ÊüNm7p·ìlƒlvqºÕòJ‚k”[ª± T§j|H,‘k² +µ¿]¦³sÍ׈㚺¾Ë¡97håʸéþV=ºk‚ä¼àH¶²èS}‰´ñ;ñYØh}np‡£`¢|YÚãÌvb2ò°#ßv 4õ©ÍóÚ”‡UŸÙŠM>Äôö¼C´™Ó”ê…?|ÙÜuh:”A.l]Âb}Žažû»Õ̶Ќ ŽåuGL7pkò¨óT\‰áºM+‡¡²ÛéDÒãL@h‡•^Kå l»*¯YÚ-_EP÷Ž« Ô¼²;CbÒNseà‡„±.BûÎ ó þ4¦ý)½òA*þ”’arð0é¤ìP ãQuRš0¡ëÎY5§@©çn)¢‚taFœ<ÏÔ&Md§4€îW´ - -ñ 8þ~|²oßÅ3ôv<*gÅײî_ÈŠZœëÁf—ì¹ÍF‡Gâ¥\¡^ÌtפZf¾7Ët!Ûí|qC³M¿¤œìß+†£Þ-Ú_,0^µk£54u+¬Ç’5Ëz×Éy~¿C³‚f§ÖQâtš÷brÒ€5ñ3Að¸i$ŸbŒç[‡ÙØ'Ùexðh‰*q¢‡Ã:–¦r"³gz€_à3jé¤ý"Õ¸dÕS‰åY)5dSO#s­.Ê•¶yà‹bw¹åiUa›Ï&ðrȳsúúj{Ö^Œ]$êö8g•6 Ôu.ºG¥àe{aØÂ^ "ÇR‡¿#-¦±§f@!„-hÿÌŠó ÛvDç1ptõ-¨ö¥Ü à_D²–È4ý®›šØ9s†Ãñ ˜ >“Tú&>,œu…êG¢¶4¥ -jf«Õ Iˆ7ÛÑt":¤Ê˜f÷ºá|¥Ýn«8ËiòÙºi=7"*ÆZ÷T…½ƒ Jœ[É©L~¯ä÷úxô|×ôjƒsm #ƒYmèu#Œì .¨lÝPXUòÑ,‹÷âÐysËÓJàläy¨›Èß¾gVmè|Yɺ™IÎoÆÙ¥Ã}xªhx R§ªœØD"áíñmóC/·Û]Ë#ìß’œ|rÝB>ý†›Ýe‚gظ%ÛâÂ¥FK#¼Ü -VKëÏ°@öMêhµÕ{íÓ«kª‰þ®W=õ€[xŒ¡èûÞÚ) ÿöx0RaU6 )ûËöñ^óîʦ=£É2XÜØ{?ÍÜ”â$¹v’˜g„×;• œþ8Ëà#ÓTˆ­½ytÑžgÖØ£üd?,Ïö+«¶[{‚æÞÅM·¾YY¹·ûž’ÿÃ7‡ZЫ¡×ôWÁI熃83ZúeIºSÌa-Ó«dzå!£Ñ­þüÛ*\Ò'µ¦ý6W Cí|Hª«&XW´Øeê›àâ*üd÷gÔºñ= €ø¸J³ëRì4”íaN¢<1cœÕ²iHÈ_ÊOml¡FŽý -ýñWÖ͸uòóɃɋ,In“„È ÷úÏh¬Záßrž×wç3÷¡nã)8FÕ°=ÀËÈS¬‡5÷*ÎoÕ`!Ú\:âÀÉGàb¸ØÖ:*™°Wɬ)÷Ðõáñµ.Åzxï¶Q+u -ßoÕüŠèg|)¢Ý”+媀B}lzr}/LŸè×ZýxeÌÖ{po6Ñ1–—Û€úuê-Í„Éuß) kê8ñüJ[q=Õ’tÕ|F ´ŽoWÓ‹ÁÅ'üÉ;Í‹ŸA-߉~çYqP”$uöëå±´Úê8ÛšOŒ%¯0䑱§i»ZÊPÕÀú˜ß µ¶2Ùmß~ýœ÷PßE¢Ó(÷rëÞüÛ=ã;輸E-~ag|^f]pŸQ÷± NÅÁóO‡\áä—$LŒa›~z“À˱F;"GÍLÅ|õÞ·TúrœB˜êtŽd’žœ ½ç(¹’_Ó GÕBkMD\h±²Íl·Äèý/A$%a³Æ–ˆSUM/‡Ì¨(ÿfŒ¢Cµx†x|˜WÄÈ{WZ׎rÒŒ»ôW~ç4‹o,£)×â‰öûU¸µèá¥k8æl!2"gvéº(m–´§=O øZÕG‰IlZýòØ¡µ­mò‰Ù{ªhd¥\B§l+‹z†KŒð«ž ¹§(O¾ÃGÇm›TXê) - ¸Ä¦~Vyg²åŒ¡°uÆJ°Ê×´fM-€8 ¥K¬Ÿ«äCËš, J½| šj_6R#/&]ääæ|e@¸(óã#š' ò{Ì¿’˜qå »|ð¹L¹¹j«²Ë/Ù¯ñ³»Û$wqià5šÜÛ2‰t d{ÞTçÚ·­cEU¤¡óôÀÁKKe¶rÄTê"r\=¢¾e÷Š dÂàþù•9O·Ä‚Ë¥»~ÒÝWë§A?&™µ>Ò˜Ç9§Ö…Äd·{‰ˆŽ™Ü‡ôÚÊ7SFä3¢Ö¡ÅoB8‘º¾#%Âí{üÁºkÐF_Û÷€êZu²}ªÂ9«Ê=‹Ny Ñ,âb¼â ãi\ZÀ™Ø¨ù(¡þL ¯6‚œ­?~ãØ•Sþ/L‹ý$ªt~P›sUºÎ€¥Meæt"“[¤¢‰ãDö -çŽ|" Å¥®2‡Y÷¨ Ù#µ:¯út\]Ñq Ï{Ðeë˱2: r¿ø1ט…ùò û+£DÈx\üÛB:Ú}[Nâì_è׿1ÜÈÍáÇa Œ }g)ý^4’çý í0)Ñòd}Ó%4H šËã¿yÎápJ&2Ð*E}oÁyæ+8%‚6X_Iƒ#DŽƒïðSΞ~È£Pw6÷­,pzº~öÀëîÏÙªßêK%^™–ÞRÉ/ÉÐ}êÏÐæ ä-áfQ3Q¿Ê¾ÚðO°J'@…‚dQÏƽ¸â¤Ø*Ü…ñû¨$¬k3:@ ä> Ð"’;{æ<ß߬}\ç²dRŒ;ö’u{x^û¼³³LmP~gWº™ªU¾Ï_ƒU)ÝZ‰>hœÀødäï¾ ¹–"Â÷ÚÝ)Í2Ê‘rès*H„ -0ís ¬¦¬×&0/¾Ét‹ÕŸóëå;”Û9t;ÎÑÛ¶niaóÀvñ~¶"‘_ŒNëÁÚGM] Ñ#·8-z;aaZJpÙ ½kš -²°׳^Kè„…žåÖ#Ö »*0N” u ^8~=“²BÑóCŒüÛr/CÎà-À;0|ûÇ£‡gÊÒMNÄéa`œËßwª@É#—0ñŸ}Åà¦Åÿ“[Ž5^3H¸>x«0Ò"†„TÛp» -ÓhÙ$ål$zQœ€ì=´ö‚1d–®ÓÃû"sx(Ú*1¨ø¶z,ˆÒ'݇v!²§ðI1Õ΃ñ¦©»g [ÞC¡ç1Q1SÑÄl»Iz_TŸÊé–Éü¢Í«¹>Ð¥Gâ­È…¬oa¦Ý—ÞëZ¼êɬÿDW•¸¼‹Uô‰ ù;VtWí½ªŒä´p€4oUû¤I67Â]¯KÃ%µôN”ph»ÈØ O{ViÂÔFìË¿ú°È‹!”éH8-“¨š -:B‡ŒlŽgú‚2ºaÒ"¦¹?|  ÿ¢ t+ë+ˆùR–~h ,“Ø‚_s -h<…È™¸gß W ¯@Wç™áÜ;_y"ÙCü :mM`¢= ã;òtçÊXÈê ~Ô“'–6Ç3mœÄAÛ÷1­Á¦±ÙMæŽW‰¡Þ®jjÚÔ2ä,Êb¡¦³ÿÊ<)yh+oÕ QÑv‘j—3¦‘„å&‰£nµ‰ø©íEÑC›¸CÄù|ü2醙+ßÆ„mK€`‡4¿Tƽ–b´7lT›½rB´¹Áø&œH&@RÈMŒx­c&û¦¸x,=˜B>Õ¿Ö’`tàœÑK–ž›És®h%ºùÔ~ÐõÔ&­Ø`Y£Í˜¡cç?›2¡e‰ð D/Ô(–+ÉP×½L-Íaž -Z¦Ûæûa„Ék6kUqèL£%hp—´rÛ° ÍèE–r:-ÃdÆÊHP:ì‡2;P®…ÓêF{ƯДÏ@ÏœüO©ªtºG©÷Ž’4Å%ü’Y×ÞöPðüid‘˃8LÖU/p„h[×ÿ1õ˜åô×îE¥JP(òCˆ¤‚§t¢8ꜧÝÎQ‹‚j%U×¼±†ÙŸJXµ¿LF-.=5†Oí~Ñ -\jË9gWØÅ."FˆmßÝÔÇ‘ÓßAÌõ|ˆWj p7MÐ"Kc20ȧåOh]9J°F®×Ò‡õíTNì)mC\Rà‰æ8èÄЗ|- µÂ¸ÅæßËlÏB@\ë®4Ʋó˜•k™_̦CÍö˜T!Ô½\!ƒÂD×$×&m iÀ槻ÁLÝ¢»?a|ÿ¤þë™ ú*$÷¼66ÛëðÞºR¨p`N‹8¹Îs©2õóŸÉ×®aLç%¢)K–9CJN¼·ดÇÃ6ôqx~ë“;à@È÷<þ]ÍCļؽyùI©Ž6xóm·Lº¥—Óê©.Chøƒ‹ÿ<™a-^õÄÞU\u´úé,R8ô0V‰ƒÖ=iï$……ní±ª—Æ„®h„¸çM«KÈÅcóÇŒqØÌ8wƒZÃÊf;Íhi3‚{~„Ý($ -iÿót:ùÃûxxñÍš6ïÛ÷ÄKZ·ÏlŽ¸ŠŒbd|Oá±–kË¥þÎÏB™E‹¤» -èlLäšOnRZ~‡î&I°=w¦}æ‰l§b””Î÷g ÅTÍ‘ûûÁ{Ë1LxméÌ­?b†‘Ü€±%Öé]¶çÛ'$5ˆç }~Ü‹{Á47 ŒCS®¯çÏgá·!v(°Z^cß—"|ÏÉUÛëUÛ„³¾Éêºêo6–I‰®óì¢;ɬ ‹a6²ôÍEê—'ÅKÜv–Ý«kî]¥’*€Þÿ<þSÍ?´.õÞ>|»ùו{šV8IÉ€¸@²`!Cr}Ùu3MVÅ ògè¿<*4ËëαÁŸ%… Ò9zS7ú‘Ÿœ’âó:·©Ž6Z3_C¯h¬Q½ÉŒff]1.ärÔõ„ÀݺgŒ6 hnO+(HuXíY]dOUÝ&°†9&/×á!^cnȯ(«eHü€SdClvÌf‹•”ØME?ÛÔ³ÐZ›N˜´BfG1d>QÚj\¼È”Ï·îPΊŸ¿æà;j:Œáo2çI­`þ÷?Á…ÀÌÞÂÄÅÕÑÁÄÅîÿØ0¹´endstream -endobj -682 0 obj << -/Type /Font -/Subtype /Type1 -/Encoding 1921 0 R -/FirstChar 2 -/LastChar 216 -/Widths 1935 0 R -/BaseFont /IOQPXG+URWPalladioL-Roma -/FontDescriptor 680 0 R ->> endobj -680 0 obj << -/Ascent 715 -/CapHeight 680 -/Descent -282 -/FontName /IOQPXG+URWPalladioL-Roma -/ItalicAngle 0 -/StemV 84 -/XHeight 469 -/FontBBox [-166 -283 1021 943] -/Flags 4 -/CharSet (/fi/fl/exclam/numbersign/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/equal/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/bracketright/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/circumflex/quotedblright/emdash/Oslash) -/FontFile 681 0 R ->> endobj -1935 0 obj -[605 608 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 278 0 500 500 840 0 278 333 333 389 606 250 333 250 606 500 500 500 500 500 500 500 500 500 500 250 250 0 606 0 444 747 778 611 709 774 611 556 763 832 337 333 726 611 946 831 786 604 786 668 525 613 778 722 1000 667 667 667 333 0 333 0 0 278 500 553 444 611 479 333 556 582 291 234 556 291 883 582 546 601 560 395 424 326 603 565 834 516 556 500 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 0 0 0 0 500 0 0 1000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 833 ] -endobj -657 0 obj << -/Length1 1614 -/Length2 24766 -/Length3 532 -/Length 25647 -/Filter /FlateDecode ->> -stream -xÚ¬zSm]³eÙ¶]uʶmÛ¶mÛö)Û¶mÛæ)ó”«ëû¯:n÷S÷}Xkfæ92GÎ{G,RBy%c;CQ;[gZzNE5ykkc ;iA;kc‚3 )©£‰³…­°³ 'š‰1°‰##)½‡£…™¹3ùõYþ !0ôøÏÏN' 3[²ŸWk;{[çˆÿçJ&&Îæ&¦Ö&Brò²bäb²*b&¶&ŽÖò.†ÖFÒF&¶N&¦vŽÖÿ¶ 0²³5¶ø§4'Ú,''{#‹Ÿm&îF&öÿ¸¨ ìMm,œœ~Þ ,œÌ lzàlG`akdíbü»©Ý¿Ù;ÚýDØüø~Àä휜Œ-ì ~²Ê ‹þOgsçr;Yü¸ ìL"íŒ\þ)é_¾˜¯³…­³‰»ó?¹ MŒ-œì­ <~rÿ€Ù;Zü‹†‹“…­Ù1 &p413p4¶6qrúùÁþ§;ÿU'ÁÿV½½½µÇ¿vÛý+ê?9X8;™X›ÒB10þä4rþÉmfa E÷ϨHØšÚ0Ðÿ›ÝØÅþ?|®&Žÿjù?3CñCÂÀØÎÖÚƒÀØÄŠNÖÎù'%ùÿ›Ê´ÿs"ÿHü?"ðÿˆ¼ÿâþwþ·Cüÿ{žÿ;´¨‹µµ¬É¿6üÇC MðÏ%óØXX{üßÂÿ{¤šÉ¿qü¿¡H8ü4BÀÖìG zZú3Z8‰Z¸›Ë[8™˜Xÿté_v[cGk [“5ÿÕHzúÿæS6·0²²ý§í,ÿæ2±5þïÔúq:qU ªÿóFýWœüòÎÊö?Ôþ½;ãÿ\üƒ"(hçNàEÃÀÂH@ÃDÏðsà~øp0±øü_2þ ˆá¿Ö2ÎŽîZ?eÿìü§øþk¥óß`DlìŒÿ™%g[ãŸñúOÃ?n#GÇUÿuâŠþõ¿ÝÄÄÝÄj}ÅΈ+Ø2ýw†szîÈ”°Ö@ðHˆ}i£rQ]¯_zøG¥þGmmÓ çW»ÇòûÏ#IÊã±>4ë_½©&×ù8>ÄýˆÛdlTÇtº¥°jÑ^7KÒ» š¬ôªÇûS -Šº%`¸3LŽ7)ü‰] üQHžíá|ÒâP»šê -ÿ\%ý}þ54>:2Ü{Ú„M•IÊå -KåïƒÍ§©R!RÕDzÝžeÌ}øØ"œ³\ʤ!g?5íµ Îk“T $f}QìŒ}}œ7Ãë–aI­zQ£Ø`{1®ËÊ›¡9sõ‰ór5úË<#¤=ø…ˆ´±36…è4Ó+òŽÇ¾a‘Ïp:‰é"“|:[5P6“Ó½«D¡;MMM¬:NNIˆ0þŒÞû+âÝzzÜðà\ -Š—€’»qt‰ÿß)âxô0EBå)¦d4Ôà,Y=2€Ä„ÖÈ=ðK86iÓ·½µS(ç óQôx;”ˆwMÒÝ\]°Ň„ŒŒÄŽ¸¼'Ž‚ŒHè¬|Ûd@I¹²‘E —çê‰xERµÆ[ºª–ØÞ÷6µt×Ûô”Uâ£ÀíÇÏcí—‡²áŠù¥t/ëE½N r…5õƒ‡À}[ÖvÞbO¿öxî3–^üX³~ݱÚtX”·úbÛ»Ze¦B}Dþ¡¥±{dyÉÞâþÝbæZR4ŠR`s§Ú1w p˜aºÃVÒ}ŽÔŠ'X7zÉ(S†Å£À¥AKÝÁÆçr&ì椫û\šì‘F­ÆLu×c¶X‡YÈnT<)—l%WªzÈ -Ì0Lo”2´“4c×±¢»ò“÷é·%¶œìÔr÷«rOxRæ@oÑ[#OóÐY„ý‹UՈʼn%?¼H»@yÖÞãLùbùÛq÷›c}DNCýŸoì sÑr?áƒÔÝÛóŠJx>æ?¤å‘]ò;ÔHbÓ‘¾tTï¨)Âm"È|Ó\¹¢óCÁ†e`ç'(Ël-zÝÇ.æf ì„©ƒ5 /Â/‘˜ÅÓSþÃEÞW;mdu‘ýêØ®=)À6li»ÙæüÖEÍX»Æn–ç]6 -Ȇ§yð»Ô™6üÏ2Röv•ŽQvvåôTÂ*¦(?ç)m¶5”OVÀ#8”¦Ú•4áîPñ"!Ýa¶é]\yc™··sãAZPU6gbß+:*(¥Þ'V­PÜ…¥Û)+#®¦.ráýô[yÞ]²ÅÕ¦<×µAÅÊ|…ø Ý&Û¦ÖŒß,`ÄÆ -\w­wñ0‹²R§ËJ†H®oQSÓâ(b½,íµ‚9¹/#Ýýo ¹|Êq3d›p+¯º>2£~ìîšzµ´[=1#„ãW*Ža†Æ4õzð­âü¦`E'K‡vU?Ê ±lyZ¨ö©­O›iÁ&6xDÏ/ -8øªˆž!/ˆalÁæG¼¸PIQÔ'âf΂ÏÈs%ÔÊbÞ)r1X#Þm@i°c€B  x›¦çë}4ÕU _ÚI ߪÒ­gë–i“êÞ* ]pÕ~éÆ)‘¾ùB½Çµ6úþD+.|qŒæê²^”¥1=XXOV°kØ2å<’*«9°ŽxòH ´›ñû]·ñ8l35Çï>oøeD-ª ï(cÛ¶.ûK@!¨ õ¾5üE³DP:[ÞŽ3ÆôŠˆ}ÕFŒPˆ¡‰„Ü6t±ä͉ -|\4YÍùô\VŽAò¡iÙœÐV•1ë#~Ú¦c®IhòT3S–ÎÎÛÞc|³!6½ñà †ã;–iòྲྀ\{ê€ ß„†EødAØÆ(éžDô öè"Oï?órš"µkñ㥡} põCÛ|TŠ°jö·1.+îq æš½ÕÖÓ¨0A" BZ8Okaƒ¦Ø;oHÇóô$Dœì@_æ‚y:hã0 ›š®Ï/óÞš~½dç"¤ªÛ•E¹ž(ÓmÅlQ$uÑU/Ã| b·8œߺ©17Ñ€2‚èe¾z@ypO2Mé—”Ý÷n‚pnA'¿1ٷل‘ñSoˆ*[¤.€ jÔ=R`>oQ³‰voqÜÕ€,ì;ÕùoƒÂUp…ø<Þ¼nd‹*Θ`Ð…²2€·½OÛ§²|#ün”5¸•õ²ùœ×¼¬³Õ²¬0'MSh%.é4îVáÏlx -'Œ†Ý¥ýrˆøœ]E ‚ˆó(‚ƒ+c[€Éj‹®¦Qíä¼_Þâgˆí44U÷“É;2–×LC -JOÉÒ4WÑœž:óû\™Ñ™ïÞ! ×yÖ\3Ûø=«/Τ€çÞ¸ ¯æŸ/8ˆÇîc+Š GI1(yBª5ŠÝ¾^ºk½“»¿Btœ'Ïá‚<ÚÂÓè¸Gù‰4E–'m$âÖ…;©ßÈ€,ÌH©ÈªÎØuW7ðÅ}Qgg.UÜ€‹öË„¯Ô—+D+K.j’™pìlîw>k»«áª‚˜NYK/ >œ$¢/Ü×ë°R -ˆÐ÷™êq¥@ûÏ|åRøíçÒ¨Zqé1#.²[Â^%â”(:^ŒD”ÚPØ•/ð -ÐJºN$†¦ædœÆak¯n¡mk5¼{n -©.׬nà'' 2‘î3ˆ2?g‚Ó<ûeZ‘™a÷­6™'zOÁt­:ñÕBzÚFÑ£AjÅ6©²}Ôq”‹ðü¬fŠ™ðaNõRäm€É€e‰aS—š=ø„PD‹ Å©?Κ-Év“Ü*.ºå„í_óÄpçÂ’EJ-Mn’†´#Îó¿?JýjÌàUàTƒ* - dªÑ‹ï­M1–7°¤*’±¹+DÞÄZ·íøjâ?å½Ü ðûLÃ+“:öýÇÈç?·Œ=¹>y.ž¡Qvãà…Ï™\Tz‚ëv<Štbèû°Ú¥€gÒgñ] ÃÊ JÛv§¬µë-èÀ\Õé)Ñ&ë!d9¯!(MX0Ý?Tpï.mêßýßVýÔÅJ/Qq“êå5„ -”;çÙßëÀÓùÙ—8Ç!‚Kùz.Áøò¯Xñ€¯ÈHêKŠ\M(€Á½µBO8 çXE_æsÃYZ·èp6aaLÞ5f(wS;áKéªOÙÓzôx -Õ§µ÷YÍÛž—™®Î燸-f: sôqó957ì>\Ç´¶ ¬C½}8$;DPì…eªì¢V¼'­ØíÄ<È“½Ü¾NO(߈]øé¦ÛÅr_[Þ*ʇ¡ÆËÆ<Òx ç˜î®l!™(Gζt Ë¡J6Úöž¡Z|û±¹¥Ø¦‹±<)”ávs"¯ÿB77ù>±9 -Ä’£×¬÷°zJmp¤0ZgôìuáÜí™ô!F…ªä Œb“Ð.ƒ ‰¢9wØhQÝ+âGùTjx­~wtñ».^jËð‘g&rÖ̹V§#KÚý®Œ¿çqÑHºö”Å~àlsLÓfH9áNjn£W4`oÑ£:»Øš^ÀÅK¥ŽÒúƒòL9ôlÊ0Û‰B˜ÚÔ#k|yË¢\Ÿ=*XˆÕÄ óRi× à¦H~&¸·—ϲSz…€ÕhßÝ0Ö/äH—Ì-Z‘m®Ûû <€úQ³Õ0zÒבß8r¨tIÏ'Õ`™@*ØÆ®@fÃ&€IѪ¥v%QÏ:®Á:.s&ŸëF­¤ƒQüʸúW ›_!Ò0sI"A4ªØ¼D×Ä÷¨C!n†Ñðú;+‘Öº{ýŠ÷ÊdÒ”üÝz/176ßÆÊê0l®«ßCヤb£s0 N­÷ä?‰ X! ¦œ´Î`ÿ¾‰$ý:Š¾]‘µß«kw#+‡üåj$P®¶½¬6>žæØñ^70•öKú€ø$ˆ]ïï­óÝo¸@g\³°Gé_›_¯›ÓŒÉeeXY¿³}ôiºiG(Œ·´‚&*ú~ŽÇzªF`4&šš8+‘o""7÷Ý3ƯU¡³ß-Aöêxáªî]2ÌÀçpÛdJ˜ -9ÅùbW<-—Ô9âEjRœáÖÚîö©ÝRËâG^ì sJ¬¾bíÇAÂxÙýeØ­ÒæÊ>•¸jÀ ,WÐs -ñÝ‹¼I2ˆô|ß{1¦[y#²š‹9ö_ÀSƒæŸ’™fyf+(ý -K#Îø/÷2ž;¼£§Zç$Êò^Mú½0)íN(ïó‘µ<‘Š6lþ;9ÅуŸ)Ðæ¦óF}»ºÐ=À¸¶V Û˜Å/éGŽIÌYW¯µ=·ŒìŶÑ;˜vìbs¯+YÈý/âwåáNV­&Þ÷¥0óŸ7¯Â$6/ ÈÉa…Ø藺¢ z|£>†²ª=–û&‘*hGTщÌ÷]š‚ëœ1Õ­šƒ”éYr}Ë!Øŧ¿åÈ<œ#ëý«Y)‡òöx~¿˜æ}{rÑ\¨®ÚK±ÈýZFÅ>V;H4®WV<^»óF†â„íÔ—î²\ƒj4Õ!š¼2¯6Gp?“‹Zi_<ÎnnŽiµ)Xg¬N~_@–GÑI; ñöa±»ùu: øàý‡—¶ËÙloOµŒ…6÷¼V¹1 ‚*ÞÕÀ³Ü2 ŽOÚy‚³OÀBwFÆSwß× Må·>æ"ng,Ÿ¬$¤€w;ÌEÞf7âúe-¥nXe€žªpºLa :¡…ÏÃŒ^^r¸ØˆÁOäÓ· XF“ã®qœø±NÈ…!-# -«Mˆí&/·}Î I Ø%΄%0W¦É·¤¬´{âI\5d§1ÖÙA)£7½¡TDƒÖcÆãM~ÉÛ0l4ÚÔÕÝ„ùäˆ÷)—h7¿d~aùruÖ[l¡F÷è\)ãƒ|9Ù¦'ýŒÓoX™!Ï·²6…ñCìÿDapï“AVá ösò߬!»eÅX#}°;©JƒaíJÁ,;ÏÊó-%•6¹“ÉÓ1­Ù7Ó.QŽMœé`èð!s™ãÆÒb¢Vyz×¾Ï@ä[ RÒ…¸•°¡½oºì=Å0Î/˜ƒíÃ݆ÛÝ4uCaåïæT{!¤$šb-»™5– 4³dtõTÁP ­»ž:0ÛªÍÜ|njŽëéY Žž0“|1&‰•rœR»)ÂPåø2SÙà Là ÔÍD›ñØ•¼ƒe¸Ñ¸üñ§fžÚ£ƒrÿCâ"Ci°Õz(¾7ª‡V6c·µ^_ŽõÝX±–Ú¿ÿ¶ƒ,ºx@#f×ÍÉ—ÔÐt<­µÑÞ¯SwE[Øx-Í­.¸éOÞ¥f¹xpõº¼›ÅÅ?¬’ágI!Ó~lñ¿ö]>i}aÙ£™ÚØåƵ3.žÇ,>Fa´—ìy‹”li‡ WMq9WÍ!.iÒwy, -‰¾É%|¾Uůx¯¸;%ÒŠƒ}5]åD„¢J›œ)h#?yºâþ-^ø*#G„ Ú”¢‘üÀÄi;IÑÉ2çŽÌ/~é)Ñu 죯ã3noዯ78]P³]nÃ|¾g -6ψ6o‘PBšP'̧AFæêdf?P0dGC×´rW›çB¼¼6&³SÊr¥Ü •¬SS‰ÓòñÞõT9Žú¼K)Œ\û)°bç¶Õ†3´$ZÞ#&†×ææjsmÂCf‰àS4XäHF Z”ÔzϘ(Pt -|ÿÖc2›#á¦$'j‡ß|c›xß3ÃlÞ“”3Bm€Ü9ºš?¨ -LÈJ„5(µ -S|ØHˆGð—Ã=>ôԑʇÞw1®V®Áç€R=äŽK‚uW—e“ 4¤µZ^ öçý†Ï#ÃÎDžâØmwp#ŸT-Œä{Mô§SqêßÑZ!¯È¥û;Åcï¤ág´SƒqÑq/V1aŶõrR€ñùòdfN51©é‹å=túúöp›˜Ùøfqû— áoœOwÖÚu»a?Oƒ=ûàÃ<´ç{±Yúk}Wy†C†³Änµ›à’v€­âfI‰Ïì•Öˆ 5À×¥µ#t }¿ÍÓËx¹¯W–Éw \[^ü©®¢¾ÛèßWñ{‰³èGªAÁ”9•¦Ð˜¥H®!’¾¬²²Üc§c‡-Pâ©P¤!A¸öÕO“L¾S¸p¼²pàx]øŒ©cYÑF6ÚÖdòmýqJ•·àØM¸Ø[?§€YJ2”µ„,,º›]£/oŒÉcQ`»Îßr¢_ÒG[‚e5ÞÖ'·Ù€@®­·;úÚFºñ(êÒÝM#4{èÄ ¶o+¶Ê^\¸g9–À ™«„!pÔ÷Ào¬99Æ"ŠâÜùüçÜ[êJG“DÝñ±h0D´«U? ©$-p®IOŒæ·­-–Ò¨#­l6±…šå$Þ<÷š©^AåyŽ·±TðºÇIæ±k¯Ì{gþ2Ð'‚S»iï:+£Ö0NAr=”kˆ¡j+¥)¸’d¼ñeKpÓÿþKô^MËQŸØøjiíD$bÙbQ>}W"йÝÍÆa]ptYˆQèxwU?X`Ù*5wi|­`ÿT{o¢”¥TÕAñÛ÷=ø9½‘ß@šÖ}¼"D–˜G®ê“[­Op¸Ì¯¤E.€Tä”?Wç+:±B¤Ýê/ýµ»Ôt0¦æ<¨ökºíúðƒ–Ë$N‰öWÏ:^åßm -#‘%‘Ï+0{—¹Vx³½û³IÏßç@ ›AÖå]d˜± ÜšfÓ 3.ˆ•Lçû^«ªwkFOpªÍm“é éâKL§.ã¬f0æµ2x‘$âGÈÛ~Í…†ÙgpèÙzœlŸTêŸß'Ah7‹#m¢(´â'Z %åÝa&˜P[&W)íýyÝaHÄrÇxg+Ešê»ÎÑû ^äŽ(úÖß `–ºr¶jºù7Yþsß›ûPDS"äÊ"pqšQ¦Mê´šsËÚ‰ÉöR'  )Ú0çöÌzlšºð•`^•¼ßÖ ——úq2‹ãqÙ•ÚüŒmÄàðr²ÉEhÈဘÏ˽ÇEFá}y:%rÜ€ŠíÀƒ -¤á¾}˜D'N+nš~¯Ðß0’ƒo™¬WOÜs:¡ðwaz;A³cJ©ÚäA çÖûÈ<’+UȯÉCvL¥ºøPô‚Û²sùô* ze-£Šü;2 «ù«#_š¤£s¾þ vêÄ‹úñe‡Î‡CØ“¨Ï>¼»,æñ’peàùhôm2’ÏÝ°MÍ[®¼¬Ý’‹÷ €"_o UÅôh£ ÖB57„ý^æÛT'kiWCEÏr§ó•vOƒ*åµA´™Ç94\Ò»`´—ͯ{Ø­²ÈÈÛáåúX&¾øoä¦0ÔØðk> HøöŸ+åªØ=âø†M¼·‘vk[|º$»öð¦»tâ—@m ÇÂ:°€Ë8WùŠ7Š²ZƒÝ3Sq4@ÄtWð‘)6ýî D0ø)×ï)5ë¦xÅ"YÖQ¡-Yz»²4û&X³ZþË¥FßJÙU§Õ1l…ìDô¶¿+GÊȵ|Æ¥4>Û"ð Dz»}ªkÄCV­¿•îá•a‡ÁuìSÅÚFpÚý¡ôú=Þ O«‘NM/-: 7‰Ï”;É)6V©ìenìRvNì‚ ‘è“íƒr—#Go“ô¦ŠFWÔl™ŠQe¸ß(„ضêKIÚ-™š”…5(žÛ—Dî;Ϫ" äÈUºÉª¿kY›#ìÏaFÎϬ0>"_ø6ð"§XÂ[]ób -©ØWÚ¿\N[Ž”ÀöŒÍ&nâáµ9vdµÍ¢–£¡!Šã5iAÅ@ñ/*w.¸Ã(:³›Åå×Î6îu1Ü3î᪾ûõW¤®48ð“ã‹KÓ^¥3Tòte:ëù`Ë"‰‹º‚p­,»iAX/†HÛ˜?äµÞ)RR«Y?êxjÒ/½)‚P8ñ“—»C>Är–BŒ!†¬gÝ@¯kîÚ“èNü½?DÆF¹U<þ5”I.:´s¾Ÿj-p“Ã䊰"ŸªcÂ#Œ:B +?/P— wég&åoï²û×!æ9œa pñ|Š®¥Þ²K5lïøŠÑ9„CF †ºž/õ¬;¿G@!íxc|ȹD¤.׎n^H$ßÄÛÂÓq]Èõ+É{¸i™’ -“*ÅûÖ€H-eëpg,eƒ|ÍaJtžŒ/dŒú*Λ¢ 6ºK2;”‹x'.QŸ[å ÌñÚ:ŸÄTß $$¯µ“Í¥¤·4UA -~:Š0NÇŽŸÂy¨r“Ñ$85¿Aš«`!¨WÄF'*nNÁbt*Ú*¼ëëÂæ;ŠEôû”ÕaÇòõT~ÔÖ“S4Ÿò3<5×Ø\ÛJ´Æß&æ–“O=P©[¨P$“Óµãñ€ èiªš_`Ž.Šó{h/"•"v¥¯CŸ)-FßE¶ÛA<Ýï KF‡é9 ‚'ýøa¢4*$'=ÝèO áequGf0[éÒ´ò¢ïÑÞ7™Ë©4€ÐóØxâ%%Ì:¼ã/º.@ªã#)NˆÈÌaÀSt–k ’»´jˆ5b;¦¿J;÷Ò±C°7·ä°ƒÂKŒwA¹5S‚é%8.nN`ºê9_Žû¡ôÓ;Sæüê\g|¢Häae#§û×çÛu¦;¯ºÖÈÊXšŠäo+7×m4”°‹ª0Ýë#4åâ8hù‚˜RË9«»åì{°S©ã£›ªˆ¿z rª“ÊûýÎœ•VØÖi!z_)õ¸¨VS[i²sõq£Ë%®µe?åw«ìbØ-…97Á |Êš aü’Þ[ -4%Å5k£½02ƒÁw¿b¶8y<•«ápÁÒ*Á–Èp«¯,”&«‚rÃæG€Tëƒç¦£¤å¿”X{Š”ùH;_ÕZ ¼ë/i)ï1Èû£.5n仯ðå9 =)ÂéÌW%^}@|Ѧ{P`Áíea°,pS L§Ü”üÚ®Û7CÖÄbÀtÝzÏ3$rX§5Ø¢Pü–„˜jW~\\{ 7NìySE¼9 ]ºž½"„i5¿ÓúÅXôxBää\„“y”\á¼¼!‡k(MÂÖL]*/öðéžä§FJ{Y<Á&eš¯lõ‰Ïƒï…Ì‚+üŽŠ<Ù@9vOŽ’¤ä[RY·ZßUMZûp4–DagPcZ‚%V_©Þ\;=MåWÛ¾ÖG -›¶ƒ¯ñ¦¯<¢—h¸E“;Ukê ñÏCX ™¹&]U;Ûh VýÛ›ˆ‰±È“pc‚Ûùí tTÚ½JŸzõE™ ’O›IG©ÎWð€A\~a OÄãö!!Š×K+˜eè-£¢~½'‘Þ$i²º„‚&ᩯ† þï8^%:'†Æ¨HÆè cYòÝEMÆä˜éb§™å>à&©/8!¹ ½¦e -J±&éù雈‹˜9›âÆæZue)äG $ LË#[|íÕϬ4ÈÝÕbO -€£AÚ¤x8mw›þÖµÔ„±ßxèÍ#ºaýªU!˜ù´TßN.ÓÙÇ-É™Q‚«iy@ŒWc²8qá/øç ‹ïåqYw'`:ÓN·ˆ=óC$?Œ¸m¦÷öÕû—ÂhÀSx/JÌ.Ló±˜× -*¥6©!bÆ¥$ž)ÈFå¨3Çx=H3/xR ÎWGzÊt¡Dc€Ê'ÒHD´öXM-®ÁöpáØîÐÌ’!#ŠÅø*ÒÕ Íè/<Ô¢8>§Ð†ó÷‰rŠeÀìåtѦ’ ¾Lñp m… U?ˆ+Ã:N¤5ûÕt'°‡¡†µÐuî¸_‘ßçêZÚÃ黲s™x¸ÅâÉÚ¿dŽ «K²/gº†™xÆÄᇤ'Õ¼bpb4C¢êš×²ë”€¹j6‘oÑ¿š…JŽi8É—©ßNN1˜ëÑ]l€c²ŸHFç¶îv/qt¤ª½ :[¥§ÌOýýÞ6ä éè­áF2“¶ÿ™ ÷•æÙy+àäjLã,Æ«J5ïr{òZÄ÷ ݆̃§cè‰áÕÏÝAj¿©U¥ÚÖ­c¿jdO×h=ö–®¸H*í%„Sb¡Î¦Ö”2+½22Êç(&ƒCWœdQ÷ßCÅ_%;Ù*Ô ^õj'Dx÷tÈ6 -½ŽîÏ>¿ÇrøKKíùƒrÍAfjxy‘ ^W_ª^ø‘UŠäNGReÈ\®v/ÖVö†¶Rú׌hÉýy3˜Œßc¼b'óÑl«ð‘Ä›k,¢°§ƒ.ˆkx„Kªý( 9×^ÅÈüsk%áIÔ5fð÷ mV:Bô— óütÑ×LmÇIL£F¤ê\@ñþ¬d<?©Ÿ¸ü*Yáv°8/æ6²¬çYF|±¼Û(=<èÝ`[AbÝdƒ#´zäè|œüK÷ŽUŸF¡Öt õÒyŪ)è´rSSd}ë"`!ê÷”Æìê×ÑúŒïÅõ -…d«…œ#£}þÂÀÑÜÂG( ÑhQ/Um+‹|“·^±OI$ѸÙ0ãÆVèþ )ÆJ3ÍLJ_ñ·ÿÑLÖ÷¥Ÿn­Þo”vÒJáØêqmìíçâ%Á­Ãcœ~ªzVÈ‘søqÕ g%ŽQÌ4³æ`£E–/T““?§púyÂå[uïлJ÷ödhºHÐÈÜlM~MTüpÜ„Ÿ[,1|-iÈÀ…´²"ùÄûø„pÐ ŠCCà ˜ÒFŸÃ^'ŽI…42ñÉ…Éš¥†¼*sjx'-ž¯ÿÌ`”Ú¿Èk¯‡?£ID9/ø†h wÍ_lÿ’Z²T,Úy(Â5ù ¡õŒê}ûÈÃ9'¹õ_dÐ]ôAGò¤¬J\YL¶ÈÛ×ÙøǦÀ©‹cÝ›øõNÀ9nÌ;­Åyç¨ÚðV‡., HYÁä{»[úœ„8!\V\¡üè<‰'bÜšDÏgw—ì£;ÞüÒéYÀõ¥"²AL$ý,ÇÉIÃÊrôH™i3>¨¶‡¾sÍnAR~§Þ…vXI³eÙM4.ñT §ÅÔ—³­:×÷öZëœnžŠÖ¥a£ð¬øyHi:štú•YŽÝ’-h¹Ò7‹NQNÅ"$:í»›{fžòO›©¡‰¦œ×µK‚7“½au@J$k-Ç8ÿÅœ*G£uÐð‘ÂF³c|&É}UëVÄNlƒÚ÷‰x^±EJ“9[k<S]óØÝîDÎæ¨ê.Ê~PÓž­üömÍnOõ)-àW…kÖ“~(>@¨o­*ˆ[eF¡Õ…•I@XgL¡Mdæ3•Ï\ÒúÚÓ!™JÕãÁuÃQš„ˆ¸q{sÍÆ£‡µ&7š}ÀKUL»_¿øŒ@ÎÄGƘÅy -Å s?Òr&Fd¿Ä6ë&>N´.Š ¦¾1:¹rP1ûØ——k¡f)ØdQmŸèÄI BÐä5Mþ¦1T¿`m[;­z!î_µ±=ñp)ä5^Išõ@ÑðÈ š¢žAò'tG<ÞÊÁæa¯šm-mn(ØdxDØ‹o=€ôœr‚Ãl( µÔžÀ¥V´êä¼ ‚ØyÒØ% -‰|¿"]ˆnŸ†GhS”C£ãžä.%^=‰Â žš| È%ÿÅ%Ÿ/†5¥ntnt I-¿ÊÍÈ.-ÚŠ -˜4ƒ¿à†tæ-ws(›¢ü À.}!Ë•™ª^‘ 805D|~ØfÌWŸ½æ°›ã‰Å9ãqÀy[eN ù~TÒ€J…gD›¼à%HõŽN´W¤Vê Ü©&QXS²;^Æ#~o ÄSÙÄòQ¯¹Omº¿kÊ–»{.ŽwC«§Y¯[Ý›H¤Î©:¦1BQäcÕùV‹jzˆý“#:^£[~ŒŸ¬Ï¿7ûKWÙ­\ÕèþbÔÔ™î=ùµ„ÔNÎÎ4i¦Èö1häêZ:H÷ÈñÌ«ñ 0¦DR>BÒâ2'BIζ:Mˆë¯ÆZg­tí´š“I:ŽÝA_¹ÂXÿ ¾09¨‘©RI¿b»Ún¹bÕ]¶4 ê¬=/û(ª¢ïŒçÄ„F;–#ã1±¢ÊC»;*æÀ‰®ëÍ­ÔÃÅmQ I’TaYXÉßñ–#OÞÑÓÃÅÓ%”3<¯)>ÿ¸³ÜM`®C;mãð%ÿ?Äél“•òAҬ̊X ÏróüÏXâWàË’Y¤Äi0ƒŒ¦¶zšãÔøª~MÒò¦ôW”¨¡½ ƒ.W³t~ß Xx7 ÷Çý¦8•fÜ®‚’ aø÷¤¢X”dŸ›¿]c5l†i¬ro¼!Q@:Ö1«¥Ä1ûa4±µx”^pj´9KTë‹}¢6[}ßO"ÝJVÕôʼn»ÐŸ|†ö©R<3±CáBÖ°ADæG.îcZ{ÃM,—ž•Ÿ/à ËT@À¥B®Å=‡êêDY–¸Ìén^uÂ]_ö¨€·GÀ›fNPÄ„¡æ}ì[ÊÀž¤/Rø`Ð4I]]õØ Óû¡{%=àÂüc2‰ó‚êì4Ÿ -àé%.@”ØÀÄZPÑ}ú¥ÄÝØÇ<†,2xˆá+„P À:І¢€XH‚9É2¯!I‰¥“–mõ놀)ÓLvÒÀªÊŠ‘¤®­‰ŠI¾ž´ÀJ€-um~5SµÏ?¼‘ÞËxXkDZÎS§ꊿʥ'ÿâA“EÈz©Ltª=ø½¿ˆÀ¯’ëÊ›2{@?ï5ºûšõ¨N …&øºòȨŽ3HKãGš‹6hXle¡ïÿ–kMžÍMxßqhìàV…Ú¤ki1IƒË‹ë°ª¶ƒÊ9UFmwY¥YññW>èYM Ð7u -Ç:êhפ­ߛ֙C9߇¬o“‚/¶z>‡”8Õ"¬pÔ"8f@xk©óí…f¸®söšË‚ý(†'ï »Úƒ½pLjt:1[ɘú‚ËHâûŠK¥Q¹ÞAH)†3W.‡å¬ÉüÖÀU7¹þ"ݨ²_mz$(®$åÔ^ÕìÊÆŸ‡EÄÆvPºÄ¤7/' ìl\du#vتç¾½ììÄ“QP‹qH{Ä$5ƒlíÛóyïd? 2$yá9MLºG%[!/J™Í2an¶ÁœÞOz~ØŠ9@5ꎥ;V7ÎF FsÕàd—ûãת?siÜ5$$éD_j(¯Ü‡ËOÒðBO¿šq€îôN»#.Æ/8ZëùkVŒè‚¹ép›ÆjÕGpéÎØzÇöÛI9´HÓ®"!ÕJˆá«OY¢Úîµ5¤=.J×ø2yØPK0úÍÙÃPI¼ ÌIñ$GÈ^˜ÆºÌ‚cý%úE˜òï„cijñ¼•9‹ž9Ñ’l{ˆ‰$ 0¢w¯¡&jjia>’4\¸ KDÃ{pÊŒ#?ÓA þ0›9 °ñ-D>"ª:c?ܺÚ~†‡^e55¸l -:kb¾ÉLQÒcèâåSŠÛ€ …l±Ã{Y14¯ŸË#Y‘·IUHš6‰·'&:,q[ÞÀÑçºËÔg+ñA¼dÖ/LŒn”•ÿRÔ›”È€ ñ²4ˆŽ7åÚƒRÃoíئS[›IÍqÉÛ³å±FÞéÛv´.19÷Ï.í¥+åh¨>ÌíŸs”q×0u\—…Ãt|<ú§´ä ÞœJSiën@-ø;`®=ô!·þö»$¯ u#îò>(5~¯ìÕ{ âeÎÈmPHXÊ¥í‚_Þ…‡ý”ä¨H*ùÈ*ÖPÓT¼žÚ´_¨­ËÓ9¼×0ÍäúRóyÂò”ë¥k#šLkF@D,}œÐ -ˇ—ÕøêMCEýŒw·òÞPðÃ]ï-¼5L-§Ô²%\ðd*]®K¬qtmpMó¹{Â6Dm1Ð[2m¢ºûw*QÝd‹Q“÷\ÒBq¶˜™2<ôÜå `ve¹¿*9GiÐÍ - .ÓÐ']ÒÀ^Od°â®D—üå„,?#ÞWÖ³bRªv×èSž¼˜Î§ÁØ$ôÊ`mñ 2D=ón“þ´ÁžD㔹=õk½IPïÅvƒJ<¨±ÏÞtݘÍZ´G U^W0äõ¬’”¤¡ÌšÙ=JéSQŠT#’åOµŸ>]žAß÷åʇȆ³Z!“Œ®Íïå>÷Ô‹fÜ.å¾Ó;ö§h gXUãÿ‚yXÛ%…6,˜Ä™T¸«úÊ*1²ö°Ò”"‚ï3Y¶m"ˆ†s¸µÌ· Rþ;ÕõµU§é±8fŠ•ì0A¾Ç¤‘oxZ¼ÒÀá¸+ÊNVkú÷#$ Ë£6\4Štó V·‘D^2'lRw‚ fÈ2Ñ[£Ø߇`Ÿk5Ñs kÜË·g¤Ãs© ÛÂÍÝÍŸ¬B?1 |k6*yf¡3ñÚP‘|Büu+ÁËNõ8XÄôÈä‘¡ù EUQÊFÿµð¥¸ËôiÔ2¼ð`Næ}ïT´?AËÒiÎâ ú[¼5¿«-ŠCLÓÇUY$ÐÀéëh¤®WNÉJB-þ¾ÜaìÚvvÚT¤‡dŽò[µ>Æ–ø|sÔrèCd `¦Ÿü^†ÕÁÊãDÃ*ã%­ã»òýÏŸ‚«ˆ›óñÚ àfX¡6øvçŽÒ]©Â—ñV¤M"BÝèù£=&w>8Kºä*¯+– ¡ oèKᣵ4æx( =¾$h%H -£VâRÑ -ï82Ö&)°"¶E;Ü´”ŤUYvƒÜìVZ9M*­µjQSJ­)‡Ÿï@LH§Ò5Èþ¥ -½~ÒoÍdW)(Ö€çÜÀæP»€Zø¦ÂP³¢½OU®æ’mèß´¨§raäÓw@„&7ìVÛÌyå\çøiÃH47+ù׉L%wÃ8vZq‡#¨¿S·,È_N ŽÅG ÚÅ•},%šc)dù…t1Z’bw' Ý–ˆQÞ’5p4#19B¹Ô/‚ÒÖPº¥}ⱡu±âv† ×àk讌z´?O «¢kês*A„1Øb÷F–o(Êf +^e`˜Ö«ç˜Yªó[c"VÌ{ƒÝŸæDDùÛ„@†€Q"é&º±s±tÞ¤cð>ÄÜÚ.èíÊHÁçÛJ¢b^ûY­&è×`}»'бTZ}¹ë&½ÑÞæa^бŒj7Y¥0ßbªÐDý¨ªN1„á3G¾_²Þý&1UF·b üÂO|=ÇΙדnj‡üGÀ´Çδ.Œè1§ÚÖ%t|šx¨@gzM†ª)dï2^G!¥nÿ¬¡Rý•QE‰)ÖÒ•*Ñÿ}úÖ€ÚûçRTWˆ¾Ü’ŽØ¿¶eŠ-(ÒØQDñ -µQu-W€»×4~Q.£ÎÐ)ÅÈLHQ-Û(èÖü¥> ø|kúÜ„X`Ž×¾®º] #.ëwx+«;.ñml3ÁѪ۰çµsߟ֚ÝÑ­ÍÃà³ -:Ê(׸B®Ó'=êû’ýeÅ9,†`óÙ‡{ß%€ª ¢0<ý}õ¬YâÁ}‹­i@âËÂTÃEóEÎRYöõžN Gö¼ =ã4,4…B™Øi:ò 1tüʼnW¡©Ç½?PÓîºövVÓ'õœ±éÞ"Øì ‚´ñïÀñµý¹• ©JÂzùíž,JøÄUw5ç«Ø«âu«”›<k1%zQ1‚¥[f15À“¤'¦’Â3÷ ÙÇWuùµÐÐ%ßï7iåœG¥Þ@ñ¿’|ÅÇåý©G—lFê¾LŠ Ñîᄹ,¼‹ Ë°—š‚„³³’%MC+–:ôSŸO±ös£]ƒ6&#r´K—è˜#kD—·¥KØ¥ý1ù›Y|£¶0› Ö!ꇫ“tnÞ€ðžUéBN“Y£æ›Ni70R2ÝžC¾«Ü-{*ý“-Ž“˜Ñ -ˆ¬BÙp:©Ñx”Mî§?ó}¢Ø×4¹„“ùïüGßßaWGÄð«àøêÖ -«1,u6AS£áx\|czíR¢€oÀbÐ.P³¦‹Ý=Öö+<µU ZäÍ&zÐÑÅReu–«ŠŽÈ*Yìü”-RGû>çHHn;åSÃêFR"Ìf‡Åfðq¦-#†©cE/NX[\VC`“e’UWYþ¶&ãLÿîC‹Ü8Ëw°šhÁÄ‹£¥±‰¶¬j‚RÂôœ½â¶÷Ñ!/¡àÀˆ´7D­'b ß½¿ë™ÝRȧ/5ÈáqL ÝéõäírâŸÏKªú~sµÀÔ«)ôh'¢Ù`ñ:~­(IÃÕmc+Õ‚Wo¿ZåX˜§™†öŠ9£›à„V×U©%-½˜‹c현Tü’uC|ºõÛ$Y~ˆ^(c­/êE)^Ì>,­¬ˆ•Â‹Ùý¤µ†ò\Ù9Ï—›éu¬#~«ùn_©38ŒàÍ^PCÑ€dp_:»’óÆŸÌ·qÙ¿H(Yï7çüX{yÊïŸw[€°5zf[7 "¯sÅvÅô̳‡Óá2 -[5ÖðÆê_ka‘¢Þ÷£ø‘*q¥=¡R4Ð/@™jÂHµ0M’$Ùþz„ -˜É¦p8çˆC¡·š•òÏq0ÞSGD¼ÆSâT2J¹Ôi­¸É½°½äA iÎáDµ9)î“>oâÚàЂ,®DOͺ؀¢À¨&¯¬±ßŸ“ãùí„í½O Ä[¢:&ßQC—Ýåy˜1ŸÜ¨^Nò`ϯȌ)†¬!îÍÓ¤~»,˜7Õ$á/°Ûº¤zé5"™4¾bø–ˆÛM]üè»o~E®5p‰ñðJÌs¨{•moœäÜ%Ö¡A;›<Ñíô¦óñÜý¦¦@=®Ð@ZR¸ôGv Ö}¬ÇàƒO³þ›§—ÙA´|:÷©‡ž™Ï @pmðïÑçñ€R Àw<—a°Ý½7#øSBG8-(v> Û žq<]ùÞÚÖÁPdöÙò @JÞâõ•WÑ2|¥ —Ê„s’¨Ê‘i% Ìî3² °6“NP&0ž>>ÀI2åOø®¾Ój¬ŠÛ¯)ÒÀŠÜÚJ8¯Öß*fzU;.ÏZÜ$ÚùdL±’Ïëì·~‡ˆ‘#_Úq@ï1ÓÝ)§/f V¤Â†~’ŠÕ.-e`Yë1†ˆÅ&ÉÜyS¬S<Í„c)fœs Ò†fÇßyã·=%±ÒD=°©lø” ⦱Wèz©ßš!ÁÁ™ÔÊçÓ_[éŒÌ|œÐÕzÂõlkÜo[Ö>ððã²æe×ÕX¤ñîÎ×þ_¢;ë#7Õ ?q2Þ|~€\áÄðPëÁ'i]°Ñ®(”Ç¢:îšÆx7I£ -×D½í¤»a £ªâ*¶‰ÂÀÜÙš*û(Œõ¤qÁÃåäÌ°[¨.xÔŒHhý {§ú·–æýy澡:ÔuÓçg¦¨÷œ4k ÜÀ=ñïElD+Ž9Ó{û¤Î=£n„ÉÐE:xª»n½†í·ô^j>³ÎÄpbH4_de›Ó^S.t¾¤™_l¿ 3)VÐñ,ÿ²8Änd2€ø»Ì@צÍ*€]ÉãhsÀž”nä¦(ºÎõ§ÕŸW‘ÉÒî#ÐósD–&ôؤžm<[ã Xp.7ôâ(5%ö‘ì>B8‘'ÇÏÉÄ-ŽM%f+ùo0à8}¤{+Ãþ/®ò ¡‹pp… ‚óìô½ÙW¬ÒCF8fÎÞßòä6ŽÓ‘æBVÎÒP,-{DÞBЪðß“úé,¢îN`:¹ ¾ÔŒ/™t>¯‘¾ÀýÝ«9Ñ>á…‡]`5TæÑ’zûvyWX2FüºþbfO–f§>}al÷¨\ÔMê—´ìù¥ìâVPÇsp¥²oøâÇШ›x¨³N O_Ž»N=𣳧ND˜ÿ«ýzZ¯@(5Ic{Çv³cÛ¶mÛ¶m۶ƶm»Ñ™w8wóÍz€ÿ~eŸYçÞ*D+_—‚#ioÛçT¢{?Ø Ï|Xž!ÃS)Ëb×ß[ñ_ˆqM`Õ|)é)vÉEåN”ŸmÝ­ÔâÑÜêCrçéú¡]¶é -ï%,3”1•äœJñÙwG¯üûñšøoeüªyDhéNÁÁϹݎÓRþ ~¯›GßB‚\ÌŽ™;؆r•R-ŸEGT±ùø°ãѶ÷Žz ‡¤/z”Þ‰…3 ¿µf!KÜt[¢áqQ‰(¤Õþˆg§þ¬EÒudV;~_€dr‡çI;17 a £ƒžq”„)b±¿²‡s(…0 -IfLt´& -¸Õ‰]ª¼ÖÀ·ü´¨ˆúWÓž•N€ÓáÚ îËè ¥·I­Ñ—Øü:k b-F”ÛÈØyŒÔLúcÙY># S·ÿý¢žæãþx5¥ÁõëU­N)r×&O¼ë‡hÛ‚$‡Øöñ1j2Ç< up& )æDÓ˜‹Ô9TÌИϦ]ÛûÑ)Z‹HAJ›0ø¼vøg^V}o2Qâ -ŽsU ? ë{x[òq=4£øŠÉTññbEK'òmç±v§9ˆçì‘È$“CXcþ©\“±>ÊG˜m@>¥¼lX1 ©ô¸dwO AþŠEÒÖ’±Sc¸I/cK+–5>¶V‘+"zg1´:Ë™T¤þÎ -*»åMì•¡p_ÐV—+}¤ªÞTžY!æĹ(K§i"üÇ(*wOzŒF®¯’«X`Ž¡ÿ­Š¢ÉÂ9•ûóV[h#´$$£¸ -™*r[¶Â—n³î+ˆm•€Î êËÜun2qÄi"P6h£.ü·T”•OdÉ_ùüånµ~ ‡q#$i5’2ÍçšuÛOÖL[˱ÙE¶IkQñßå:¢_é²w«®º!É·Õ7ˬÞýóÌlÒλª> ^ØH•€ þfuĶgŽÍÆm4N}ÒY‡‰Fð/þM(zK¦COåúë·½Ì\?½c<'}ÚÞu*gi·êhôQ´•Vhš»7ª&º=è8?NI@ý ·Axgz¯fckp5[ü>À¦ÉÍ—>ý®ÂóKÓL†™f EÚ³:â£]åÕN³Äèx÷ú9,Ѓô^¾Æ´m=WäÔ>x ÷"9N‘Øyw#DZ.‰ÞÌi*„¸úR/ÝsF©ÚPS.çYŠÈòŽfb-?F|…í-¬{ÝOžà»ÛTháÜ=ªK8[9öMâ™ÍÃßv\©«ù P$€Ë~*À^ÄçÝTŽ]ÝLyî O¬!±KÔŸÒ`ä÷þ;ËQyC¬¿k¦ÂËᬩ£Ž” Â_Ñ#ý:{;„YSý5§È9N€˜gyä¶~ ËsÐ^Üûlœ'Q -žº²Üà9UwgÒBkÙãƒËÚž½Gr˜u)ÔëÛß°û„{¢T?,Ì’xýà‘Ò$b¿ªép×Å°·‰©È{ÃXá¤,#½ÜPÝ"QL$*/éÆù£ˆ:ÿxrG­Ñömi´Ã. DêBU%ÔEñï˜Aàâ»ÿü V¾£¥Úö°±]àÚøÖfâ¹›rƾÏcÁ¬FšF"¾7+ZÍ4´ˆ'|Áaèp›“GLÍptmL0°Ëd™Ò§l³CÙÊ5ç²k·›™²u•†(¢^§Ì€SÀóþtJ̦ îÒù<‰Ó¿`—+ƒéíÀ~Ûf&°üØ̱iZž\|¾ÙV?P¥QüèçÍ6GTqÔQ—m¡’>Ú߈3ßþ'{ãËDˆ/Ñ`ˆÚbNŠ"{YL¬ÇY‘Ô¿†•†´É»ž8 UÅt"gæ´LþÊÝ»åE´;aw#"‚Æ`l1naO)º -èòÔAé›ðöÖ_ß5Xuïwo%~’KG`4÷B9MXÄ—›Ý*¬â=cÉwú¦¶­r±¼§˜½ïÙ ÌèÀXmgsÌ{ná>³.ëÀS±¾ü¾ºÈÙ”¦ŠQ®Ÿ6È4ȤÍzÚ9Ú—¦Å÷K\ ìkCì«›!ê;àú¸èy¢Å - -"¿‘©ÜŒ˜%(–PL•„àà}çô—ìd¸A4HVs_™c‚Ò„µÜÅ‘nÜŠ¡Vz*-‰To­”â 7*úï #{y‚íl¤â:n\Æ>‡áos.ø¨ŠsýE×õ©É¡Ã<äm¶ E±¸@ˆx²îkrŸËÁ}G=1ôƒNl.&·´Mf‰2À4îۯ0ö€6Ñð G¥í¤B§R“Bt•¯º%õĪÜ~ç$`XÞ(ÿ¶ˆphíÒ[, ²·wÄ.„ˆØeæÒ$HÃù”±åá<€;]vÛàr Öù›–ÞpuU“J¯ÐœA£½<ÚÓ¤ïõV1r¿Â¥“e8Õè7Þ)h(²¼Eð¥GðЖ„ñ˜WÒMæ _Y£õ‡æÒËfcØŠ¡ÌõCÒ0—£Û²u—§§äùp3¦~ùÌ[yÔ5!Áy˜Ý Ð-¹9¨ÉŠ%Q-} /DšC¦—jn¦%>HLgùh:âî…¶Bldš½üuô݈°½‹IÖ#o½¿ùði9žìtå‰ò2¯̉ê³æÖ®Ê2VÂ^­.îÔ -ëÿ8±² -òo·Ä‰è8²{ãqÍED§G×æë±ÆöåÜbùÜß°”\&Ü‘ù­òÏ2qsÈÆ°Ûy¾>bò´ÌOX(oÁYÓ‹Þ"4Ù†w7 «~Lé'ƒ]‰v }Oä8ÝMª)Ž–X’EÀ,3bQ*ÞWAš 0 N5<_8%)FľJVßr”[‰=Wÿ:¯&,o/ÑQƒ+"%N†êémü‡*VtŸ_-’È°”´sPàkX‹'ÙÊ‘FâbMüzyixûŸGG1SÝ(&¦F›Å8'Ç9qr«E™Lôð‹ÜÒ{î}pJ‡ç"3„žœ®NÔ1 `2SÚ;{{ÿÚ«”ìŠ÷ ÿŽ¦Ï˜ 1a|67¥œtؽ_”½áFÜ•g/š:EšR˜3²F (´†»nDM†ÀÒUœÁÌVÕåq–¹4òBä£à?;±¿®Uy7-Ò¿£;©©D'eaè;Å:ÎCÂ)n.fï&#–œ¸ˆ2?\Î2 -mÁR!/¤ïmYz'Úò”¦ÀÀh'¨1I ÌѨõéI¹;b ’@\Öq×Ü[¤µ*ýôF£½™ÃØ»ÚRqõ¶›0ý×nD%ŒãßÉ€¦ ]:bĨvÿŽ“U®ïqî{ĤgÑ5Àee4ê}ââsë?†'Jïg/žÄ1àÞ¼–'=ÌNŠ³)—NcëULtbðÏ$ mw?:ji½Í€E4Èê6öʺµÉm>·’ºS î¸£”=~ø$ÄV9N·€ø.Ü.®z;…•ý37Uxõò~Z–¥]5ä´Ñ<ÒZµn•}—Vo)I -Èù#†ð÷†(£ÃÐw¾áR¼­ñ¿ø; h@À‘Ä8~©Lp©™¦¿RÒtª3ª5/0Ò¡S0±nÍ&9=Ó ÷-Áz;¢IrH©3©Òpdl²l[‹}B¿p“šÌN2ùòw Д˜…¥UhpO·  -FÖ—bowÖç'<{†Ëe/>w¤ìºO Óyf4,%[n‹¦ó<ÑȲ’Dø¯7XQ`õì¹;ðkgýÑt{D¯VC|n$è_ -5±)Ä;À†íkPAs~6wD¦l¹Y²˜'À&>)Ž:•„ΊÙtAʘxñI…Å©Ñ’"Vï·´—Á}“Ôl—Üœ2Ê?«RÙª¦» Ñ2ø¡†LŠ¶Ð*¥ÕùÏ•Õz¢W¯íPO!Zñšâ:¡••3ìv{´3:9¨;8 ~†»Gcã–XÇ*ؾƔrõFÉ×<ͤŸ”WSs¤ù€ûñúóRXÙlN|PLò4ŠÒñ£l8¯´Àøî[ë†4 Àñɽ.zšcF­{ý†ÄT¢¸ˆŽ¾‘Ð[™()ä ‡¦f¾ÆF£ðÝ´Z"gº…´>Ôæ5âµlÏâ,¥÷y”¦Ä“1Êe]#¾{Gš!ÓK±¾„OÍ÷¢ü¤ïï!Œ^{ßðÉ‘F'U0BBo÷LÉ7„ob¨AÏqØ5ƒ£&ÜçîYd5K­ÜeíO%:Ó 6™zD-߹̫\šM07œÄûga\)³?ÎÍØU>Yë7“ÚNÿM³ƒ†yŒµ¿_asáL³í|¿Œ‚Ñi(¡Ñ›à¬ìz™XHGªáO\DzŠ~o9EÁNº>¨¢r4!Öî€1/;{k=¾·¥ïTRëö îì½:¹c‹GÃáÐÙaí¿[ò!É­©Ð†Ꭰ—fÝ}†c¢³R[#ð:wAò»p@‚Ò@NÞ†ÓDùNËöî”yRbÒ%y™ÔÌњǡã0-KdiÛBqÁ+a`½£é6!ÆìÂÖ÷šóø53"%)k(h0OGµž32Š!¯‘¼ù_“Û’¸6fÜYײ#–=MBùBo)QI¶ÍE3Aè¢öh(‘‰±9ŸmûÜLH©*q2:ã¿}45«1Û¶*…Ë; õq4—ÉFeÈ»r-daº’õ¿×X}ÜÁÈ'ö ‚TjÙTûõ®Bç’¡X5>¤hŸ`Ÿ" ¤pñ5Ѽb\*]–Ù“»$BößÓžøãÊL½bð¨Æ@¶x}€×)j¹ïÀËŠh4HÄlªA§k7÷¥ßjMó*ùf“VlÜ%´þ¢.’£uXà}{ÁoT˜ ’ÓK7ú‰Éñ-5?»™ýuª¦ý5G¢M9|¬à+´¡ï˜I¯qRÒOÖÛ‘ñ0Dç"fb×a²ØtÿV¤Ÿ@-¿«¤ÆÐ$u².~@baæ|*¾ê3©%…îG÷ïã´‡N‡ ‰49‡˜"Xˆ¡|S¸ßÌFÉW壓ô?eÃýåL£Ø&tb^Ué.¸2N%æ’äMÖOw”¯çe/Öʹsê"›Y #•|mËMsßÒÉYàœÑLLz™63<>9ŸšwßEBèˆU¾D¿îÁö{'÷·n‰æŒLžkp±磚‘rôCÖP€³rúgœ§câˆE$kš¿Ÿ,­×©à>€ü3ªŸ2ÈÛ=cuT¤ `+š«6E@éú*ẳ~5¿¬'Z>t %š=:þ¤RŽeìþ«nO»ý’y0HÈë4ÚµüÍ‹;ô¨K‹iþzª -¯'l­Õ_‡2›.vèKâÔ€fïø¯âˆÚ\ŸÙÊ¡òËà.¶¸iAìU„‹Åss*’ñªÛ -ó Ë.ºÞJy'k<¬¾T¨u®rï p¦±2Äéyš˜¾Á0^øÓí ›H v,¥wó!éùž1ÄVûr#Âp_JI´¿4ŽÎ¸6ú˘ì{2{ã• <[—)¾Íj°xÔo~y‘S¿mäó¼—¯ùh§NWp¡Q2¬ð‚‰>÷ËgCX ÀõVUé³½æ·ÝbM†Ðñù6 kh*†4¬† ·ÚTã’#­Ò<÷òwHÜ2ÈAœS¼WR¬v"«¡™Ô1í2•¢¨¡;ŽÞuE@L ±Âà‘Œ”ª^4þÕŒl«áÇü̺-€¾¨“\Z™Òçtä %p´§”î–©ÚËjKûr¦ä¦¥Æ¢[~ÕÇÆêþÕ&÷»6øxŽÔߤÐ3òÛøñøíp…ò¯Ý@åjCŒ,:°”v—Vj¶ ’/—4â3Vÿ¢§öžÛuá<¤ÓÄø -Z¬Å…Fv˜fU*¬ê&'°áÚÑÌÖÿ«&45¸h+Ë Ch/äΖãoýÓ(…§A]]fçþ$ni6ñ–ÖaöqRÜ:¹µÓa¯yÌ]¿jñïšëté¤ÜK…ïÚNÝR/RàÚ¯{|Ý+î8|H@bÛr®fEéÊl.°_½€ZNe‚œæ>>îI”¢kf 5ùùª‚Ÿ»ßÈy˜Ë{2LC6þ¸ôØÅ~Û5 7Çíí=E4ÅÑjè!¹A=Ï·tg åƒ&%§ƒ—!~T‡ºÀ–¾U§/T1ìåoù¾—±Ú¨¿L—7ÛÎ…B»ñúð©JIª‘Èã¬B6ÂÀŸØ2¥7j•C†Ðâ.ü”3"OBv U‹C9jEm{‰ü6ºJÀ¶¦Gáà•PŸ… Ù(úV…yÄfö·› ²–“mTèÁ’½ú‰L9--ö´»¿sµx#¢ª}«q‹“Y*ÔV·ôZwa§:Tu$~ËÇ!5‰íåBòdô’µÀåŠWü©æºÍ”þ†ëÞ­ËêJ‘kíOµUEÉ0µ³ât¿yÎhÂRUO©x ç&<)O±\b:EÛôØ$Jpÿ‰–ÎÍS|Ût 9–dtþq6 QˆÙéDÐIÛß0âFò'¸JÌìY7¯»°:}…çqy¹•·ÜçüŒaÊ~oà韪Àæâ6°c5Œ#MóbðAÖHa5E18G:*ï }Ù5âìħϪ•Ü<—,$l]ղؗô ümn]78TÓKrº -eÁ½õiÐGÓ8¿ÙñCÊI´‚¥º]u¯˜Ôjù -JtáBÊk(WI)Í’ˆÇ ¨kFîÈJi…Õ FS„Éãâ…—¹l;£—¬(¯cgHÖ5§ýUj®¦›¤ÞNX*1a"˜…J[å?x¯5Mï@ 7‰íɳ't"Mrmc §Õnœ€rÍÖÔ<.ïo°öÝヲk¶åÎM¾×ÅŸ“p40¶Y¤ÉçŠÀ^s ëµ¬d>Rõ~YîZ_Ä둹v0§Gm‡‡N®3çï7G$*›½th•ëùý¹¡Òg)ˆ, &ƒM€¶ïÎ3«yÔ&o¹Ù›ïu–ž4«ô,öZÎOkÜ÷ªÔD%«†Déz¡v?ò‡/óÀ; Š'?§îºËcšý‹Üè~Ü÷.ïs -µ(à\èaª -E‰7jŨi¥oòƒŒ:½úþ·cêSJo*>»u+Æ#@Ä«áb\[k!s&D “‹Ãd`È´Êëš”ïhc{·5?ú¡iiîÅbx[РƒÜ¸²à‹™÷̾`_rª»“ž!R4>‚K]J…wvýqL\¶Š– þ AÓ!÷¯Kÿüê@7¿-ü'²ØAAضӃÖe ¢Þߺö;ˆsôÍxyÈDUE…ýøsÙæp£/kït6ÎîX/Ûžua·Q‘\/œ;^tøÊIø&dÖC+ƒT&a“ļMØ{$UT‘«ø.ÙN '”ýBþTŽiÔ|us)î³”n2s2tLn”Óš`$}ÂlŠx`j6#Ô—Vn3DÅBƒ¾Üâ")47#UtùÖRÓ“³8‹û‡mÂq¸ÀVôYÅshž£ºí¨ûöàÂÏÏûºyžkkÒ;ÔJÙ/c¯º6ï,ø4ë$ä[Ff&—8ãÔOø0€#›ì'L¨âJá0äï‚ž=Äï y¢z¯ëmjMU(0i´ÓòÁB­úg”GX¿‚rë•{µ)ùºà  ×·f"Õõ®‹‘†­,``ª“}BT]ºˆ»Y®ì}Þ´¶Ì‚i•Æ´A„]|(ìÓQÍííê—ÉH8ï -j!H·îà3ÁE. - ø!{mž/ƒòZú+p%Œ«u–}Fcí¿ èýˆ/ì…Ƶ1>§ÌM)ÔÐ O%Sýù8½î×Çâõ‰;‹¸¡Û#;üe,ã ’ÆÄ\õ0þ#tÎȾ³k훯"’ÃÅÆ{Ã÷âJÉt¿R4ú‡£da`{ó‚ŵ_Â÷ú¼*S½ŽµÁ˜¢eŒñ'»2òãTÊÀhÜD7Ð š^BðàF°²•B„z@jø­z„…Ä÷z‡=éYU¬×:sB®gæ#²ÁÛÔE·Ù"-‘ -dˆür4îŠ$#œ™/à·Ñw $–+3¸]Ì„5¼T87Å]ý—‰Ø¥–…ZPŽü¢ X¥Ì[šÿ8™XpÉþCi€ó`KpmMƒ*­y¨À&ÕÇ*é\—l¹ïˆü° xr#L?)¨ù¹kvü¯â|V{þ–aÀB$ÇÉÎàj`ñh›Îëæîõ­QUdj5Ë$k>7¦|©™¬âÃöõÚ¾¤,ˆÇSÎbÎ=¯ 6¢ŽIÛž‚2üúð?÷ò)CÎ|æ¡î0)ukt ùþîo#‘Æ$÷s‡³Wgª~„ŸÙñôÀԥ;ºaâlèQÌãæƒhË›ƒÌð`¾ªD`;˜ßl)Zþ¸+‚´öœ¸"nƒbî…•Wãìˆý2@4Jn²k‰Àüš>,¶èŒo¯×ý½cSò¬‚~NDD«TNo,ŠYv£ÐƒÒ˜÷-R¢%d¬ò™êe‰»CÀ÷ûú”Īoà/ŽâÈüo%×ÄR’1Ãó—G$TW~}Úæ¾Ó¬r' i kI -Z®§Ñœ8Îeä¾ÏFþ±Ã,ô\5ˆI.èÑaM 4Ž´mÇÕ‹èqWM‘±•î·egcØøí «\[þT -¿Á…æËU¨—xÙLDÞsäÓš¨Iÿµíe¬ âæN™V¸åJ‘ÑÏn§Y ÎY½–\fÐN€¨ ¡B‚?&{¬D·š‘zµÝ¥å -Iö×~pºóE¦f}^!˜tQ°Ù’‹ƒEäì>‰ n|'ÆV²5D9_äå‹7â̬FJvõ˜2È­ÛŒ’ý;Û£K¿>Z&ú‰Àš¤þØɉ,-¯,Yت–=–ÏÞáÆX8?¸#…m èÓð¥žçßèðž–u¤<5åÑwÒ6¨´ÍÔ™­×#0±q“²Qý‰±ÀåÙëã=¥—;1Â&<ˆ2’¨ਛ4ÿ1=´ˆñ¯”uà t jlÔ»<$¼³lt‡7¶Â~ølRh¸¤Â…ò^JÁuò‘{{#Xè -| f Ég¬,=‘¥vp‘·xMŒé‰_b¬5 -µœóû¿ µ§öÈ4¿À#è¸?§ß7LíXʳŒ”ñkÌ€Zî»vSLR‡û 4 ƒ?&4 =cwÓ™7mÿ­8 ‡L¡ž~šËmé0Rƒù]N9ÄO:;e0vÈ(©6‘÷ôŒ÷ÃæÓ=ÔèÖ‡7œŠ?­)Í'á ž àÇ38ƬpYBà³Â|ƾC¬D?ÖD‡§-QÊ(6ò˜¤>Œö)€*#£˜òDUdùªé³ÓvU‹ùaaæ6#÷7M‡jƒ8K §ZøP‹øÕ‰ãw© 3ê±,ÄaAÅÃÒO¦Í•Ç½,R!®(e¡|ÉÒj£_µ3b: ö[Ï㥻w©{Î u\öAøo†êm¶¿ïÆñ’8ÁX˜ž‰’ÍèQR^ÈåkP’AÛa—ËÚwÄ*ù™ü óñ»v̽–ÆÍKy ¯_È„&ÕýÜý|ÚòK6ã¥L§ñîÏ}¬O?2Y‹gl$mÓ¢ÛÏb»\feþ]'ái¬}n¦s+.Û¤TíD•6s²rý ´ ·†döNQH瘊Ø3Âs%´‰ ƒQ”Ìæç(©mIÊé`1‘rCÓ)NòÒB‘,›÷4JÓ‹d—W]M„=beÞºe(Ë ÄE&›fg¬esÅ ×"tO†2ÄÎБ.Õ(îõâwwÓú¨e¡Ž Úà"šm°Çó" -¥í’bWWž^¿§M?¼ªßªéë;ëš<™áh ±Kñŵž¢¨ÚÆóV1îcÖOÏ "ž³x4tÅ:l¼t@i×uÅ«»‡‹Á0“öë]RϺM'Ü>Á™?#ÉABlž=fÌì…ïé ÚiózõÔ¨¿!…+°2Ô’Ýzôµ¥Îb—B -y‘üP'càÜ^M#R°·ñÃ4 {LJ B«œ»×ën¾HïŸMc–9|þ*S5ïV®ñKãÁ“üvÚJ¦‰‡’à°áR‹ÁPKw©ä;ÉͳðåH-ºOÖ²ÉâØÉ*Wü—¼éýšö•p…+èó®a7AÔºº;˜âR·~4ÿÕ|S®‘mƒ®W•~ ©Ãâ‡}DL×WF5J‰åéØ|¨i÷>#\2®˜Æíß»OÍß 6.â'¢ÿp$iÊíù2ŸÒ;LÛ–Oòá ±Fóyº)‘ùµ©ãà~ ¥ŸC¡ë­„aø ÅÑ«¨ÙûGæhg [&óâ<1—Xû²Âø{iª_“¸bf)¦Œ²§T˜ ÜÓ»GAe!ógF玦àUa!*ÚZ0Ÿðç/è a0¼€ž~£œ†äwÝo âïfŸJ³xÛw® ÞaÇL¿õ0 è^š `8¿Ú Ù4Ùç÷ Ï©4†V×"”]BÝ3pþà·½_) èIÞ\H$séåXŒ{Òb^Z,ÃÛ6ö©ÉÁ ¬–R2µCÇŠ‰t(£ˆOܲÓ7‚9òó`e€² ä@y%0júAÈëRÿ˜à˜~xƒ4wÖ5çíÂàÖ±åmÝÓ×â}=Ð’tRX[>͔ҞÐRÔ "çH³l/é•_r> endobj -656 0 obj << -/Ascent 708 -/CapHeight 672 -/Descent -266 -/FontName /HVUUYY+URWPalladioL-Bold -/ItalicAngle 0 -/StemV 123 -/XHeight 471 -/FontBBox [-152 -301 1000 935] -/Flags 4 -/CharSet (/fi/fl/exclam/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/question/at/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/quotedblright/emdash) -/FontFile 657 0 R ->> endobj -1936 0 obj -[611 611 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 278 0 0 500 889 0 278 333 333 444 606 250 333 250 296 500 500 500 500 500 500 500 500 500 500 250 250 0 0 0 444 747 778 667 722 833 611 556 833 833 389 0 778 611 1000 833 833 611 833 722 611 667 778 778 1000 667 667 667 333 0 333 0 0 0 500 611 444 611 500 389 556 611 333 333 611 333 889 611 556 611 611 389 444 333 611 556 833 500 556 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0 0 1000 ] -endobj -659 0 obj << -/Type /Pages -/Count 6 -/Parent 1937 0 R -/Kids [650 0 R 677 0 R 687 0 R 742 0 R 806 0 R 867 0 R] ->> endobj -886 0 obj << -/Type /Pages -/Count 6 -/Parent 1937 0 R -/Kids [871 0 R 888 0 R 902 0 R 913 0 R 920 0 R 932 0 R] ->> endobj -944 0 obj << -/Type /Pages -/Count 6 -/Parent 1937 0 R -/Kids [937 0 R 946 0 R 957 0 R 965 0 R 972 0 R 978 0 R] ->> endobj -1001 0 obj << -/Type /Pages -/Count 6 -/Parent 1937 0 R -/Kids [986 0 R 1008 0 R 1018 0 R 1023 0 R 1027 0 R 1034 0 R] ->> endobj -1050 0 obj << -/Type /Pages -/Count 6 -/Parent 1937 0 R -/Kids [1043 0 R 1053 0 R 1060 0 R 1065 0 R 1074 0 R 1081 0 R] ->> endobj -1093 0 obj << -/Type /Pages -/Count 6 -/Parent 1937 0 R -/Kids [1085 0 R 1096 0 R 1102 0 R 1110 0 R 1117 0 R 1126 0 R] ->> endobj -1145 0 obj << -/Type /Pages -/Count 6 -/Parent 1938 0 R -/Kids [1139 0 R 1147 0 R 1152 0 R 1158 0 R 1164 0 R 1172 0 R] ->> endobj -1182 0 obj << -/Type /Pages -/Count 6 -/Parent 1938 0 R -/Kids [1179 0 R 1184 0 R 1189 0 R 1195 0 R 1199 0 R 1206 0 R] ->> endobj -1219 0 obj << -/Type /Pages -/Count 6 -/Parent 1938 0 R -/Kids [1216 0 R 1221 0 R 1226 0 R 1237 0 R 1243 0 R 1248 0 R] ->> endobj -1256 0 obj << -/Type /Pages -/Count 6 -/Parent 1938 0 R -/Kids [1252 0 R 1258 0 R 1266 0 R 1272 0 R 1279 0 R 1287 0 R] ->> endobj -1303 0 obj << -/Type /Pages -/Count 6 -/Parent 1938 0 R -/Kids [1294 0 R 1306 0 R 1310 0 R 1316 0 R 1321 0 R 1325 0 R] ->> endobj -1338 0 obj << -/Type /Pages -/Count 6 -/Parent 1938 0 R -/Kids [1334 0 R 1340 0 R 1344 0 R 1348 0 R 1356 0 R 1361 0 R] ->> endobj -1392 0 obj << -/Type /Pages -/Count 6 -/Parent 1939 0 R -/Kids [1378 0 R 1394 0 R 1409 0 R 1419 0 R 1425 0 R 1432 0 R] ->> endobj -1453 0 obj << -/Type /Pages -/Count 6 -/Parent 1939 0 R -/Kids [1443 0 R 1455 0 R 1463 0 R 1469 0 R 1473 0 R 1479 0 R] ->> endobj -1493 0 obj << -/Type /Pages -/Count 6 -/Parent 1939 0 R -/Kids [1490 0 R 1495 0 R 1499 0 R 1510 0 R 1514 0 R 1521 0 R] ->> endobj -1589 0 obj << -/Type /Pages -/Count 6 -/Parent 1939 0 R -/Kids [1531 0 R 1591 0 R 1647 0 R 1701 0 R 1735 0 R 1744 0 R] ->> endobj -1754 0 obj << -/Type /Pages -/Count 6 -/Parent 1939 0 R -/Kids [1750 0 R 1756 0 R 1760 0 R 1765 0 R 1777 0 R 1781 0 R] ->> endobj -1797 0 obj << -/Type /Pages -/Count 6 -/Parent 1939 0 R -/Kids [1793 0 R 1799 0 R 1810 0 R 1815 0 R 1820 0 R 1831 0 R] ->> endobj -1846 0 obj << -/Type /Pages -/Count 6 -/Parent 1940 0 R -/Kids [1843 0 R 1848 0 R 1859 0 R 1864 0 R 1871 0 R 1882 0 R] ->> endobj -1897 0 obj << -/Type /Pages -/Count 4 -/Parent 1940 0 R -/Kids [1893 0 R 1899 0 R 1909 0 R 1915 0 R] ->> endobj -1937 0 obj << -/Type /Pages -/Count 36 -/Parent 1941 0 R -/Kids [659 0 R 886 0 R 944 0 R 1001 0 R 1050 0 R 1093 0 R] ->> endobj -1938 0 obj << -/Type /Pages -/Count 36 -/Parent 1941 0 R -/Kids [1145 0 R 1182 0 R 1219 0 R 1256 0 R 1303 0 R 1338 0 R] ->> endobj -1939 0 obj << -/Type /Pages -/Count 36 -/Parent 1941 0 R -/Kids [1392 0 R 1453 0 R 1493 0 R 1589 0 R 1754 0 R 1797 0 R] ->> endobj -1940 0 obj << -/Type /Pages -/Count 10 -/Parent 1941 0 R -/Kids [1846 0 R 1897 0 R] ->> endobj -1941 0 obj << -/Type /Pages -/Count 118 -/Kids [1937 0 R 1938 0 R 1939 0 R 1940 0 R] ->> endobj -1942 0 obj << -/Type /Outlines -/First 7 0 R -/Last 607 0 R -/Count 10 ->> endobj -647 0 obj << -/Title 648 0 R -/A 645 0 R -/Parent 607 0 R -/Prev 643 0 R ->> endobj -643 0 obj << -/Title 644 0 R -/A 641 0 R -/Parent 607 0 R -/Prev 639 0 R -/Next 647 0 R ->> endobj -639 0 obj << -/Title 640 0 R -/A 637 0 R -/Parent 607 0 R -/Prev 635 0 R -/Next 643 0 R ->> endobj -635 0 obj << -/Title 636 0 R -/A 633 0 R -/Parent 607 0 R -/Prev 631 0 R -/Next 639 0 R ->> endobj -631 0 obj << -/Title 632 0 R -/A 629 0 R -/Parent 607 0 R -/Prev 627 0 R -/Next 635 0 R ->> endobj -627 0 obj << -/Title 628 0 R -/A 625 0 R -/Parent 607 0 R -/Prev 623 0 R -/Next 631 0 R ->> endobj -623 0 obj << -/Title 624 0 R -/A 621 0 R -/Parent 607 0 R -/Prev 619 0 R -/Next 627 0 R ->> endobj -619 0 obj << -/Title 620 0 R -/A 617 0 R -/Parent 607 0 R -/Prev 615 0 R -/Next 623 0 R ->> endobj -615 0 obj << -/Title 616 0 R -/A 613 0 R -/Parent 607 0 R -/Prev 611 0 R -/Next 619 0 R ->> endobj -611 0 obj << -/Title 612 0 R -/A 609 0 R -/Parent 607 0 R -/Next 615 0 R ->> endobj -607 0 obj << -/Title 608 0 R -/A 605 0 R -/Parent 1942 0 R -/Prev 571 0 R -/First 611 0 R -/Last 647 0 R -/Count -10 ->> endobj -603 0 obj << -/Title 604 0 R -/A 601 0 R -/Parent 591 0 R -/Prev 599 0 R ->> endobj -599 0 obj << -/Title 600 0 R -/A 597 0 R -/Parent 591 0 R -/Prev 595 0 R -/Next 603 0 R ->> endobj -595 0 obj << -/Title 596 0 R -/A 593 0 R -/Parent 591 0 R -/Next 599 0 R ->> endobj -591 0 obj << -/Title 592 0 R -/A 589 0 R -/Parent 571 0 R -/Prev 583 0 R -/First 595 0 R -/Last 603 0 R -/Count -3 ->> endobj -587 0 obj << -/Title 588 0 R -/A 585 0 R -/Parent 583 0 R ->> endobj -583 0 obj << -/Title 584 0 R -/A 581 0 R -/Parent 571 0 R -/Prev 575 0 R -/Next 591 0 R -/First 587 0 R -/Last 587 0 R -/Count -1 ->> endobj -579 0 obj << -/Title 580 0 R -/A 577 0 R -/Parent 575 0 R ->> endobj -575 0 obj << -/Title 576 0 R -/A 573 0 R -/Parent 571 0 R -/Next 583 0 R -/First 579 0 R -/Last 579 0 R -/Count -1 ->> endobj -571 0 obj << -/Title 572 0 R -/A 569 0 R -/Parent 1942 0 R -/Prev 551 0 R -/Next 607 0 R -/First 575 0 R -/Last 591 0 R -/Count -3 ->> endobj -567 0 obj << -/Title 568 0 R -/A 565 0 R -/Parent 551 0 R -/Prev 563 0 R ->> endobj -563 0 obj << -/Title 564 0 R -/A 561 0 R -/Parent 551 0 R -/Prev 555 0 R -/Next 567 0 R ->> endobj -559 0 obj << -/Title 560 0 R -/A 557 0 R -/Parent 555 0 R ->> endobj -555 0 obj << -/Title 556 0 R -/A 553 0 R -/Parent 551 0 R -/Next 563 0 R -/First 559 0 R -/Last 559 0 R -/Count -1 ->> endobj -551 0 obj << -/Title 552 0 R -/A 549 0 R -/Parent 1942 0 R -/Prev 527 0 R -/Next 571 0 R -/First 555 0 R -/Last 567 0 R -/Count -3 ->> endobj -547 0 obj << -/Title 548 0 R -/A 545 0 R -/Parent 527 0 R -/Prev 535 0 R ->> endobj -543 0 obj << -/Title 544 0 R -/A 541 0 R -/Parent 535 0 R -/Prev 539 0 R ->> endobj -539 0 obj << -/Title 540 0 R -/A 537 0 R -/Parent 535 0 R -/Next 543 0 R ->> endobj -535 0 obj << -/Title 536 0 R -/A 533 0 R -/Parent 527 0 R -/Prev 531 0 R -/Next 547 0 R -/First 539 0 R -/Last 543 0 R -/Count -2 ->> endobj -531 0 obj << -/Title 532 0 R -/A 529 0 R -/Parent 527 0 R -/Next 535 0 R ->> endobj -527 0 obj << -/Title 528 0 R -/A 525 0 R -/Parent 1942 0 R -/Prev 243 0 R -/Next 551 0 R -/First 531 0 R -/Last 547 0 R -/Count -3 ->> endobj -523 0 obj << -/Title 524 0 R -/A 521 0 R -/Parent 475 0 R -/Prev 519 0 R ->> endobj -519 0 obj << -/Title 520 0 R -/A 517 0 R -/Parent 475 0 R -/Prev 503 0 R -/Next 523 0 R ->> endobj -515 0 obj << -/Title 516 0 R -/A 513 0 R -/Parent 503 0 R -/Prev 511 0 R ->> endobj -511 0 obj << -/Title 512 0 R -/A 509 0 R -/Parent 503 0 R -/Prev 507 0 R -/Next 515 0 R ->> endobj -507 0 obj << -/Title 508 0 R -/A 505 0 R -/Parent 503 0 R -/Next 511 0 R ->> endobj -503 0 obj << -/Title 504 0 R -/A 501 0 R -/Parent 475 0 R -/Prev 499 0 R -/Next 519 0 R -/First 507 0 R -/Last 515 0 R -/Count -3 ->> endobj -499 0 obj << -/Title 500 0 R -/A 497 0 R -/Parent 475 0 R -/Prev 495 0 R -/Next 503 0 R ->> endobj -495 0 obj << -/Title 496 0 R -/A 493 0 R -/Parent 475 0 R -/Prev 491 0 R -/Next 499 0 R ->> endobj -491 0 obj << -/Title 492 0 R -/A 489 0 R -/Parent 475 0 R -/Prev 479 0 R -/Next 495 0 R ->> endobj -487 0 obj << -/Title 488 0 R -/A 485 0 R -/Parent 479 0 R -/Prev 483 0 R ->> endobj -483 0 obj << -/Title 484 0 R -/A 481 0 R -/Parent 479 0 R -/Next 487 0 R ->> endobj -479 0 obj << -/Title 480 0 R -/A 477 0 R -/Parent 475 0 R -/Next 491 0 R -/First 483 0 R -/Last 487 0 R -/Count -2 ->> endobj -475 0 obj << -/Title 476 0 R -/A 473 0 R -/Parent 243 0 R -/Prev 275 0 R -/First 479 0 R -/Last 523 0 R -/Count -7 ->> endobj -471 0 obj << -/Title 472 0 R -/A 469 0 R -/Parent 455 0 R -/Prev 467 0 R ->> endobj -467 0 obj << -/Title 468 0 R -/A 465 0 R -/Parent 455 0 R -/Prev 463 0 R -/Next 471 0 R ->> endobj -463 0 obj << -/Title 464 0 R -/A 461 0 R -/Parent 455 0 R -/Prev 459 0 R -/Next 467 0 R ->> endobj -459 0 obj << -/Title 460 0 R -/A 457 0 R -/Parent 455 0 R -/Next 463 0 R ->> endobj -455 0 obj << -/Title 456 0 R -/A 453 0 R -/Parent 275 0 R -/Prev 451 0 R -/First 459 0 R -/Last 471 0 R -/Count -4 ->> endobj -451 0 obj << -/Title 452 0 R -/A 449 0 R -/Parent 275 0 R -/Prev 447 0 R -/Next 455 0 R ->> endobj -447 0 obj << -/Title 448 0 R -/A 445 0 R -/Parent 275 0 R -/Prev 443 0 R -/Next 451 0 R ->> endobj -443 0 obj << -/Title 444 0 R -/A 441 0 R -/Parent 275 0 R -/Prev 439 0 R -/Next 447 0 R ->> endobj -439 0 obj << -/Title 440 0 R -/A 437 0 R -/Parent 275 0 R -/Prev 435 0 R -/Next 443 0 R ->> endobj -435 0 obj << -/Title 436 0 R -/A 433 0 R -/Parent 275 0 R -/Prev 431 0 R -/Next 439 0 R ->> endobj -431 0 obj << -/Title 432 0 R -/A 429 0 R -/Parent 275 0 R -/Prev 427 0 R -/Next 435 0 R ->> endobj -427 0 obj << -/Title 428 0 R -/A 425 0 R -/Parent 275 0 R -/Prev 347 0 R -/Next 431 0 R ->> endobj -423 0 obj << -/Title 424 0 R -/A 421 0 R -/Parent 347 0 R -/Prev 419 0 R ->> endobj -419 0 obj << -/Title 420 0 R -/A 417 0 R -/Parent 347 0 R -/Prev 415 0 R -/Next 423 0 R ->> endobj -415 0 obj << -/Title 416 0 R -/A 413 0 R -/Parent 347 0 R -/Prev 411 0 R -/Next 419 0 R ->> endobj -411 0 obj << -/Title 412 0 R -/A 409 0 R -/Parent 347 0 R -/Prev 407 0 R -/Next 415 0 R ->> endobj -407 0 obj << -/Title 408 0 R -/A 405 0 R -/Parent 347 0 R -/Prev 403 0 R -/Next 411 0 R ->> endobj -403 0 obj << -/Title 404 0 R -/A 401 0 R -/Parent 347 0 R -/Prev 399 0 R -/Next 407 0 R ->> endobj -399 0 obj << -/Title 400 0 R -/A 397 0 R -/Parent 347 0 R -/Prev 395 0 R -/Next 403 0 R ->> endobj -395 0 obj << -/Title 396 0 R -/A 393 0 R -/Parent 347 0 R -/Prev 391 0 R -/Next 399 0 R ->> endobj -391 0 obj << -/Title 392 0 R -/A 389 0 R -/Parent 347 0 R -/Prev 387 0 R -/Next 395 0 R ->> endobj -387 0 obj << -/Title 388 0 R -/A 385 0 R -/Parent 347 0 R -/Prev 383 0 R -/Next 391 0 R ->> endobj -383 0 obj << -/Title 384 0 R -/A 381 0 R -/Parent 347 0 R -/Prev 379 0 R -/Next 387 0 R ->> endobj -379 0 obj << -/Title 380 0 R -/A 377 0 R -/Parent 347 0 R -/Prev 375 0 R -/Next 383 0 R ->> endobj -375 0 obj << -/Title 376 0 R -/A 373 0 R -/Parent 347 0 R -/Prev 371 0 R -/Next 379 0 R ->> endobj -371 0 obj << -/Title 372 0 R -/A 369 0 R -/Parent 347 0 R -/Prev 367 0 R -/Next 375 0 R ->> endobj -367 0 obj << -/Title 368 0 R -/A 365 0 R -/Parent 347 0 R -/Prev 363 0 R -/Next 371 0 R ->> endobj -363 0 obj << -/Title 364 0 R -/A 361 0 R -/Parent 347 0 R -/Prev 359 0 R -/Next 367 0 R ->> endobj -359 0 obj << -/Title 360 0 R -/A 357 0 R -/Parent 347 0 R -/Prev 355 0 R -/Next 363 0 R ->> endobj -355 0 obj << -/Title 356 0 R -/A 353 0 R -/Parent 347 0 R -/Prev 351 0 R -/Next 359 0 R ->> endobj -351 0 obj << -/Title 352 0 R -/A 349 0 R -/Parent 347 0 R -/Next 355 0 R ->> endobj -347 0 obj << -/Title 348 0 R -/A 345 0 R -/Parent 275 0 R -/Prev 343 0 R -/Next 427 0 R -/First 351 0 R -/Last 423 0 R -/Count -19 ->> endobj -343 0 obj << -/Title 344 0 R -/A 341 0 R -/Parent 275 0 R -/Prev 339 0 R -/Next 347 0 R ->> endobj -339 0 obj << -/Title 340 0 R -/A 337 0 R -/Parent 275 0 R -/Prev 335 0 R -/Next 343 0 R ->> endobj -335 0 obj << -/Title 336 0 R -/A 333 0 R -/Parent 275 0 R -/Prev 331 0 R -/Next 339 0 R ->> endobj -331 0 obj << -/Title 332 0 R -/A 329 0 R -/Parent 275 0 R -/Prev 327 0 R -/Next 335 0 R ->> endobj -327 0 obj << -/Title 328 0 R -/A 325 0 R -/Parent 275 0 R -/Prev 315 0 R -/Next 331 0 R ->> endobj -323 0 obj << -/Title 324 0 R -/A 321 0 R -/Parent 315 0 R -/Prev 319 0 R ->> endobj -319 0 obj << -/Title 320 0 R -/A 317 0 R -/Parent 315 0 R -/Next 323 0 R ->> endobj -315 0 obj << -/Title 316 0 R -/A 313 0 R -/Parent 275 0 R -/Prev 311 0 R -/Next 327 0 R -/First 319 0 R -/Last 323 0 R -/Count -2 ->> endobj -311 0 obj << -/Title 312 0 R -/A 309 0 R -/Parent 275 0 R -/Prev 307 0 R -/Next 315 0 R ->> endobj -307 0 obj << -/Title 308 0 R -/A 305 0 R -/Parent 275 0 R -/Prev 303 0 R -/Next 311 0 R ->> endobj -303 0 obj << -/Title 304 0 R -/A 301 0 R -/Parent 275 0 R -/Prev 299 0 R -/Next 307 0 R ->> endobj -299 0 obj << -/Title 300 0 R -/A 297 0 R -/Parent 275 0 R -/Prev 295 0 R -/Next 303 0 R ->> endobj -295 0 obj << -/Title 296 0 R -/A 293 0 R -/Parent 275 0 R -/Prev 291 0 R -/Next 299 0 R ->> endobj -291 0 obj << -/Title 292 0 R -/A 289 0 R -/Parent 275 0 R -/Prev 287 0 R -/Next 295 0 R ->> endobj -287 0 obj << -/Title 288 0 R -/A 285 0 R -/Parent 275 0 R -/Prev 283 0 R -/Next 291 0 R ->> endobj -283 0 obj << -/Title 284 0 R -/A 281 0 R -/Parent 275 0 R -/Prev 279 0 R -/Next 287 0 R ->> endobj -279 0 obj << -/Title 280 0 R -/A 277 0 R -/Parent 275 0 R -/Next 283 0 R ->> endobj -275 0 obj << -/Title 276 0 R -/A 273 0 R -/Parent 243 0 R -/Prev 247 0 R -/Next 475 0 R -/First 279 0 R -/Last 455 0 R -/Count -24 ->> endobj -271 0 obj << -/Title 272 0 R -/A 269 0 R -/Parent 263 0 R -/Prev 267 0 R ->> endobj -267 0 obj << -/Title 268 0 R -/A 265 0 R -/Parent 263 0 R -/Next 271 0 R ->> endobj -263 0 obj << -/Title 264 0 R -/A 261 0 R -/Parent 247 0 R -/Prev 251 0 R -/First 267 0 R -/Last 271 0 R -/Count -2 ->> endobj -259 0 obj << -/Title 260 0 R -/A 257 0 R -/Parent 251 0 R -/Prev 255 0 R ->> endobj -255 0 obj << -/Title 256 0 R -/A 253 0 R -/Parent 251 0 R -/Next 259 0 R ->> endobj -251 0 obj << -/Title 252 0 R -/A 249 0 R -/Parent 247 0 R -/Next 263 0 R -/First 255 0 R -/Last 259 0 R -/Count -2 ->> endobj -247 0 obj << -/Title 248 0 R -/A 245 0 R -/Parent 243 0 R -/Next 275 0 R -/First 251 0 R -/Last 263 0 R -/Count -2 ->> endobj -243 0 obj << -/Title 244 0 R -/A 241 0 R -/Parent 1942 0 R -/Prev 231 0 R -/Next 527 0 R -/First 247 0 R -/Last 475 0 R -/Count -3 ->> endobj -239 0 obj << -/Title 240 0 R -/A 237 0 R -/Parent 231 0 R -/Prev 235 0 R ->> endobj -235 0 obj << -/Title 236 0 R -/A 233 0 R -/Parent 231 0 R -/Next 239 0 R ->> endobj -231 0 obj << -/Title 232 0 R -/A 229 0 R -/Parent 1942 0 R -/Prev 131 0 R -/Next 243 0 R -/First 235 0 R -/Last 239 0 R -/Count -2 ->> endobj -227 0 obj << -/Title 228 0 R -/A 225 0 R -/Parent 219 0 R -/Prev 223 0 R ->> endobj -223 0 obj << -/Title 224 0 R -/A 221 0 R -/Parent 219 0 R -/Next 227 0 R ->> endobj -219 0 obj << -/Title 220 0 R -/A 217 0 R -/Parent 131 0 R -/Prev 203 0 R -/First 223 0 R -/Last 227 0 R -/Count -2 ->> endobj -215 0 obj << -/Title 216 0 R -/A 213 0 R -/Parent 203 0 R -/Prev 211 0 R ->> endobj -211 0 obj << -/Title 212 0 R -/A 209 0 R -/Parent 203 0 R -/Prev 207 0 R -/Next 215 0 R ->> endobj -207 0 obj << -/Title 208 0 R -/A 205 0 R -/Parent 203 0 R -/Next 211 0 R ->> endobj -203 0 obj << -/Title 204 0 R -/A 201 0 R -/Parent 131 0 R -/Prev 199 0 R -/Next 219 0 R -/First 207 0 R -/Last 215 0 R -/Count -3 ->> endobj -199 0 obj << -/Title 200 0 R -/A 197 0 R -/Parent 131 0 R -/Prev 195 0 R -/Next 203 0 R ->> endobj -195 0 obj << -/Title 196 0 R -/A 193 0 R -/Parent 131 0 R -/Prev 159 0 R -/Next 199 0 R ->> endobj -191 0 obj << -/Title 192 0 R -/A 189 0 R -/Parent 159 0 R -/Prev 187 0 R ->> endobj -187 0 obj << -/Title 188 0 R -/A 185 0 R -/Parent 159 0 R -/Prev 183 0 R -/Next 191 0 R ->> endobj -183 0 obj << -/Title 184 0 R -/A 181 0 R -/Parent 159 0 R -/Prev 179 0 R -/Next 187 0 R ->> endobj -179 0 obj << -/Title 180 0 R -/A 177 0 R -/Parent 159 0 R -/Prev 175 0 R -/Next 183 0 R ->> endobj -175 0 obj << -/Title 176 0 R -/A 173 0 R -/Parent 159 0 R -/Prev 163 0 R -/Next 179 0 R ->> endobj -171 0 obj << -/Title 172 0 R -/A 169 0 R -/Parent 163 0 R -/Prev 167 0 R ->> endobj -167 0 obj << -/Title 168 0 R -/A 165 0 R -/Parent 163 0 R -/Next 171 0 R ->> endobj -163 0 obj << -/Title 164 0 R -/A 161 0 R -/Parent 159 0 R -/Next 175 0 R -/First 167 0 R -/Last 171 0 R -/Count -2 ->> endobj -159 0 obj << -/Title 160 0 R -/A 157 0 R -/Parent 131 0 R -/Prev 151 0 R -/Next 195 0 R -/First 163 0 R -/Last 191 0 R -/Count -6 ->> endobj -155 0 obj << -/Title 156 0 R -/A 153 0 R -/Parent 151 0 R ->> endobj -151 0 obj << -/Title 152 0 R -/A 149 0 R -/Parent 131 0 R -/Prev 147 0 R -/Next 159 0 R -/First 155 0 R -/Last 155 0 R -/Count -1 ->> endobj -147 0 obj << -/Title 148 0 R -/A 145 0 R -/Parent 131 0 R -/Prev 139 0 R -/Next 151 0 R ->> endobj -143 0 obj << -/Title 144 0 R -/A 141 0 R -/Parent 139 0 R ->> endobj -139 0 obj << -/Title 140 0 R -/A 137 0 R -/Parent 131 0 R -/Prev 135 0 R -/Next 147 0 R -/First 143 0 R -/Last 143 0 R -/Count -1 ->> endobj -135 0 obj << -/Title 136 0 R -/A 133 0 R -/Parent 131 0 R -/Next 139 0 R ->> endobj -131 0 obj << -/Title 132 0 R -/A 129 0 R -/Parent 1942 0 R -/Prev 91 0 R -/Next 231 0 R -/First 135 0 R -/Last 219 0 R -/Count -9 ->> endobj -127 0 obj << -/Title 128 0 R -/A 125 0 R -/Parent 111 0 R -/Prev 115 0 R ->> endobj -123 0 obj << -/Title 124 0 R -/A 121 0 R -/Parent 115 0 R -/Prev 119 0 R ->> endobj -119 0 obj << -/Title 120 0 R -/A 117 0 R -/Parent 115 0 R -/Next 123 0 R ->> endobj -115 0 obj << -/Title 116 0 R -/A 113 0 R -/Parent 111 0 R -/Next 127 0 R -/First 119 0 R -/Last 123 0 R -/Count -2 ->> endobj -111 0 obj << -/Title 112 0 R -/A 109 0 R -/Parent 91 0 R -/Prev 107 0 R -/First 115 0 R -/Last 127 0 R -/Count -2 ->> endobj -107 0 obj << -/Title 108 0 R -/A 105 0 R -/Parent 91 0 R -/Prev 95 0 R -/Next 111 0 R ->> endobj -103 0 obj << -/Title 104 0 R -/A 101 0 R -/Parent 95 0 R -/Prev 99 0 R ->> endobj -99 0 obj << -/Title 100 0 R -/A 97 0 R -/Parent 95 0 R -/Next 103 0 R ->> endobj -95 0 obj << -/Title 96 0 R -/A 93 0 R -/Parent 91 0 R -/Next 107 0 R -/First 99 0 R -/Last 103 0 R -/Count -2 ->> endobj -91 0 obj << -/Title 92 0 R -/A 89 0 R -/Parent 1942 0 R -/Prev 67 0 R -/Next 131 0 R -/First 95 0 R -/Last 111 0 R -/Count -3 ->> endobj -87 0 obj << -/Title 88 0 R -/A 85 0 R -/Parent 67 0 R -/Prev 83 0 R ->> endobj -83 0 obj << -/Title 84 0 R -/A 81 0 R -/Parent 67 0 R -/Prev 79 0 R -/Next 87 0 R ->> endobj -79 0 obj << -/Title 80 0 R -/A 77 0 R -/Parent 67 0 R -/Prev 75 0 R -/Next 83 0 R ->> endobj -75 0 obj << -/Title 76 0 R -/A 73 0 R -/Parent 67 0 R -/Prev 71 0 R -/Next 79 0 R ->> endobj -71 0 obj << -/Title 72 0 R -/A 69 0 R -/Parent 67 0 R -/Next 75 0 R ->> endobj -67 0 obj << -/Title 68 0 R -/A 65 0 R -/Parent 1942 0 R -/Prev 7 0 R -/Next 91 0 R -/First 71 0 R -/Last 87 0 R -/Count -5 ->> endobj -63 0 obj << -/Title 64 0 R -/A 61 0 R -/Parent 23 0 R -/Prev 55 0 R ->> endobj -59 0 obj << -/Title 60 0 R -/A 57 0 R -/Parent 55 0 R ->> endobj -55 0 obj << -/Title 56 0 R -/A 53 0 R -/Parent 23 0 R -/Prev 39 0 R -/Next 63 0 R -/First 59 0 R -/Last 59 0 R -/Count -1 ->> endobj -51 0 obj << -/Title 52 0 R -/A 49 0 R -/Parent 39 0 R -/Prev 47 0 R ->> endobj -47 0 obj << -/Title 48 0 R -/A 45 0 R -/Parent 39 0 R -/Prev 43 0 R -/Next 51 0 R ->> endobj -43 0 obj << -/Title 44 0 R -/A 41 0 R -/Parent 39 0 R -/Next 47 0 R ->> endobj -39 0 obj << -/Title 40 0 R -/A 37 0 R -/Parent 23 0 R -/Prev 35 0 R -/Next 55 0 R -/First 43 0 R -/Last 51 0 R -/Count -3 ->> endobj -35 0 obj << -/Title 36 0 R -/A 33 0 R -/Parent 23 0 R -/Prev 31 0 R -/Next 39 0 R ->> endobj -31 0 obj << -/Title 32 0 R -/A 29 0 R -/Parent 23 0 R -/Prev 27 0 R -/Next 35 0 R ->> endobj -27 0 obj << -/Title 28 0 R -/A 25 0 R -/Parent 23 0 R -/Next 31 0 R ->> endobj -23 0 obj << -/Title 24 0 R -/A 21 0 R -/Parent 7 0 R -/Prev 19 0 R -/First 27 0 R -/Last 63 0 R -/Count -6 ->> endobj -19 0 obj << -/Title 20 0 R -/A 17 0 R -/Parent 7 0 R -/Prev 15 0 R -/Next 23 0 R ->> endobj -15 0 obj << -/Title 16 0 R -/A 13 0 R -/Parent 7 0 R -/Prev 11 0 R -/Next 19 0 R ->> endobj -11 0 obj << -/Title 12 0 R -/A 9 0 R -/Parent 7 0 R -/Next 15 0 R ->> endobj -7 0 obj << -/Title 8 0 R -/A 5 0 R -/Parent 1942 0 R -/Next 67 0 R -/First 11 0 R -/Last 23 0 R -/Count -4 ->> endobj -1943 0 obj << -/Names [(Access_Control_Lists) 1477 0 R (Bv9ARM.ch01) 874 0 R (Bv9ARM.ch02) 923 0 R (Bv9ARM.ch03) 940 0 R (Bv9ARM.ch04) 989 0 R (Bv9ARM.ch05) 1077 0 R (Bv9ARM.ch06) 1088 0 R (Bv9ARM.ch07) 1476 0 R (Bv9ARM.ch08) 1502 0 R (Bv9ARM.ch09) 1517 0 R (Bv9ARM.ch10) 1738 0 R (Configuration_File_Grammar) 1113 0 R (DNSSEC) 1056 0 R (Doc-Start) 655 0 R (Setting_TTLs) 1446 0 R (acache) 930 0 R (access_control) 1231 0 R (acl) 1121 0 R (address_match_lists) 1094 0 R (admin_tools) 963 0 R (appendix.A) 570 0 R (appendix.B) 606 0 R (bibliography) 1525 0 R (boolean_options) 1005 0 R (builtin) 1300 0 R (chapter*.1) 690 0 R (chapter.1) 6 0 R (chapter.2) 66 0 R (chapter.3) 90 0 R (chapter.4) 130 0 R (chapter.5) 230 0 R (chapter.6) 242 0 R (chapter.7) 526 0 R (chapter.8) 550 0 R (cite.RFC1033) 1653 0 R (cite.RFC1034) 1537 0 R (cite.RFC1035) 1539 0 R (cite.RFC1101) 1635 0 R (cite.RFC1123) 1637 0 R (cite.RFC1183) 1597 0 R (cite.RFC1464) 1675 0 R (cite.RFC1535) 1582 0 R (cite.RFC1536) 1584 0 R (cite.RFC1537) 1655 0 R (cite.RFC1591) 1639 0 R (cite.RFC1706) 1599 0 R (cite.RFC1712) 1695 0 R (cite.RFC1713) 1677 0 R (cite.RFC1794) 1679 0 R (cite.RFC1876) 1601 0 R (cite.RFC1912) 1657 0 R (cite.RFC1982) 1586 0 R (cite.RFC1995) 1544 0 R (cite.RFC1996) 1546 0 R (cite.RFC2010) 1659 0 R (cite.RFC2052) 1603 0 R (cite.RFC2065) 1707 0 R (cite.RFC2136) 1548 0 R (cite.RFC2137) 1709 0 R (cite.RFC2163) 1605 0 R (cite.RFC2168) 1607 0 R (cite.RFC2181) 1550 0 R (cite.RFC2219) 1661 0 R (cite.RFC2230) 1609 0 R (cite.RFC2240) 1681 0 R (cite.RFC2308) 1552 0 R (cite.RFC2317) 1641 0 R (cite.RFC2345) 1683 0 R (cite.RFC2352) 1685 0 R (cite.RFC2535) 1711 0 R (cite.RFC2536) 1611 0 R (cite.RFC2537) 1613 0 R (cite.RFC2538) 1615 0 R (cite.RFC2539) 1617 0 R (cite.RFC2540) 1619 0 R (cite.RFC2671) 1554 0 R (cite.RFC2672) 1556 0 R (cite.RFC2673) 1697 0 R (cite.RFC2782) 1621 0 R (cite.RFC2825) 1665 0 R (cite.RFC2826) 1643 0 R (cite.RFC2845) 1558 0 R (cite.RFC2874) 1699 0 R (cite.RFC2915) 1623 0 R (cite.RFC2929) 1645 0 R (cite.RFC2930) 1560 0 R (cite.RFC2931) 1562 0 R (cite.RFC3007) 1564 0 R (cite.RFC3008) 1713 0 R (cite.RFC3071) 1687 0 R (cite.RFC3090) 1715 0 R (cite.RFC3110) 1625 0 R (cite.RFC3123) 1627 0 R (cite.RFC3225) 1570 0 R (cite.RFC3258) 1689 0 R (cite.RFC3445) 1717 0 R (cite.RFC3490) 1667 0 R (cite.RFC3491) 1669 0 R (cite.RFC3492) 1671 0 R (cite.RFC3596) 1629 0 R (cite.RFC3597) 1631 0 R (cite.RFC3645) 1566 0 R (cite.RFC3655) 1719 0 R (cite.RFC3658) 1721 0 R (cite.RFC3755) 1723 0 R (cite.RFC3757) 1725 0 R (cite.RFC3833) 1572 0 R (cite.RFC3845) 1727 0 R (cite.RFC3901) 1691 0 R (cite.RFC4033) 1574 0 R (cite.RFC4035) 1576 0 R (cite.RFC4044) 1578 0 R (cite.RFC4074) 1588 0 R (cite.RFC974) 1541 0 R (cite.id2499701) 1732 0 R (configuration_file_elements) 1089 0 R (controls_statement_definition_and_usage) 976 0 R (diagnostic_tools) 911 0 R (dynamic_update) 999 0 R (dynamic_update_policies) 1051 0 R (dynamic_update_security) 1235 0 R (empty) 1302 0 R (historical_dns_information) 1519 0 R (id2465026) 875 0 R (id2466484) 876 0 R (id2467305) 880 0 R (id2467506) 881 0 R (id2467714) 891 0 R (id2467891) 893 0 R (id2467912) 894 0 R (id2467946) 895 0 R (id2468030) 898 0 R (id2470292) 905 0 R (id2470315) 908 0 R (id2470345) 909 0 R (id2470435) 910 0 R (id2470465) 916 0 R (id2470500) 917 0 R (id2470595) 918 0 R (id2470629) 924 0 R (id2470656) 925 0 R (id2470668) 926 0 R (id2470694) 929 0 R (id2470705) 935 0 R (id2470805) 942 0 R (id2470821) 943 0 R (id2470843) 949 0 R (id2470860) 950 0 R (id2471334) 953 0 R (id2471339) 954 0 R (id2473122) 981 0 R (id2473133) 982 0 R (id2473511) 1014 0 R (id2473529) 1015 0 R (id2473964) 1031 0 R (id2473981) 1032 0 R (id2474020) 1037 0 R (id2474038) 1038 0 R (id2474049) 1039 0 R (id2474156) 1040 0 R (id2474282) 1041 0 R (id2474327) 1047 0 R (id2474341) 1048 0 R (id2474390) 1049 0 R (id2474595) 1057 0 R (id2474732) 1058 0 R (id2474811) 1063 0 R (id2474954) 1068 0 R (id2475084) 1070 0 R (id2475106) 1071 0 R (id2475139) 1078 0 R (id2475354) 1090 0 R (id2476147) 1099 0 R (id2476174) 1100 0 R (id2476281) 1105 0 R (id2476296) 1106 0 R (id2476394) 1107 0 R (id2476477) 1114 0 R (id2476893) 1120 0 R (id2476936) 1122 0 R (id2477152) 1124 0 R (id2477512) 1131 0 R (id2477527) 1132 0 R (id2477550) 1133 0 R (id2477572) 1134 0 R (id2477662) 1143 0 R (id2477857) 1144 0 R (id2477909) 1150 0 R (id2478602) 1161 0 R (id2479412) 1167 0 R (id2479485) 1168 0 R (id2479549) 1175 0 R (id2479593) 1176 0 R (id2479608) 1177 0 R (id2481708) 1202 0 R (id2483474) 1224 0 R (id2483532) 1230 0 R (id2483954) 1241 0 R (id2484042) 1246 0 R (id2484857) 1255 0 R (id2484872) 1261 0 R (id2485056) 1263 0 R (id2485257) 1269 0 R (id2485688) 1283 0 R (id2486990) 1313 0 R (id2488093) 1330 0 R (id2488142) 1331 0 R (id2488222) 1337 0 R (id2489668) 1351 0 R (id2489675) 1352 0 R (id2489681) 1353 0 R (id2490299) 1359 0 R (id2490332) 1364 0 R (id2491624) 1406 0 R (id2491881) 1412 0 R (id2491899) 1413 0 R (id2491920) 1416 0 R (id2492156) 1422 0 R (id2493254) 1428 0 R (id2493382) 1430 0 R (id2493403) 1435 0 R (id2493834) 1437 0 R (id2493971) 1439 0 R (id2494061) 1440 0 R (id2494466) 1447 0 R (id2494590) 1449 0 R (id2494605) 1450 0 R (id2494717) 1452 0 R (id2494876) 1458 0 R (id2494937) 1459 0 R (id2495006) 1460 0 R (id2495043) 1461 0 R (id2495105) 1466 0 R (id2495584) 1486 0 R (id2495729) 1487 0 R (id2495788) 1488 0 R (id2495868) 1503 0 R (id2495874) 1504 0 R (id2495885) 1505 0 R (id2496039) 1506 0 R (id2496101) 1518 0 R (id2496273) 1524 0 R (id2496529) 1529 0 R (id2496531) 1535 0 R (id2496539) 1540 0 R (id2496563) 1536 0 R (id2496586) 1538 0 R (id2496622) 1549 0 R (id2496649) 1551 0 R (id2496675) 1543 0 R (id2496699) 1545 0 R (id2496791) 1547 0 R (id2496846) 1553 0 R (id2496873) 1555 0 R (id2496900) 1557 0 R (id2496962) 1559 0 R (id2496992) 1561 0 R (id2497021) 1563 0 R (id2497048) 1565 0 R (id2497123) 1568 0 R (id2497198) 1569 0 R (id2497225) 1571 0 R (id2497261) 1573 0 R (id2497326) 1577 0 R (id2497392) 1575 0 R (id2497457) 1580 0 R (id2497465) 1581 0 R (id2497559) 1583 0 R (id2497627) 1585 0 R (id2497662) 1587 0 R (id2497703) 1595 0 R (id2497708) 1596 0 R (id2497766) 1598 0 R (id2497803) 1606 0 R (id2497838) 1600 0 R (id2497893) 1602 0 R (id2497931) 1604 0 R (id2497957) 1608 0 R (id2497982) 1610 0 R (id2498009) 1612 0 R (id2498036) 1614 0 R (id2498075) 1616 0 R (id2498105) 1618 0 R (id2498135) 1620 0 R (id2498178) 1622 0 R (id2498211) 1624 0 R (id2498237) 1626 0 R (id2498261) 1628 0 R (id2498318) 1630 0 R (id2498343) 1633 0 R (id2498350) 1634 0 R (id2498376) 1636 0 R (id2498398) 1638 0 R (id2498422) 1640 0 R (id2498468) 1642 0 R (id2498491) 1644 0 R (id2498541) 1651 0 R (id2498549) 1652 0 R (id2498572) 1654 0 R (id2498599) 1656 0 R (id2498626) 1658 0 R (id2498662) 1660 0 R (id2498702) 1663 0 R (id2498708) 1664 0 R (id2498740) 1666 0 R (id2498854) 1668 0 R (id2498889) 1670 0 R (id2498916) 1673 0 R (id2498934) 1674 0 R (id2498956) 1676 0 R (id2498982) 1678 0 R (id2499008) 1680 0 R (id2499031) 1682 0 R (id2499077) 1684 0 R (id2499100) 1686 0 R (id2499127) 1688 0 R (id2499153) 1690 0 R (id2499190) 1693 0 R (id2499196) 1694 0 R (id2499254) 1696 0 R (id2499281) 1698 0 R (id2499317) 1705 0 R (id2499329) 1706 0 R (id2499368) 1708 0 R (id2499395) 1710 0 R (id2499425) 1712 0 R (id2499450) 1714 0 R (id2499477) 1716 0 R (id2499513) 1718 0 R (id2499549) 1720 0 R (id2499576) 1722 0 R (id2499603) 1724 0 R (id2499648) 1726 0 R (id2499689) 1729 0 R (id2499699) 1731 0 R (id2499701) 1733 0 R (incremental_zone_transfers) 1011 0 R (internet_drafts) 1728 0 R (ipv6addresses) 1072 0 R (journal) 1000 0 R (lwresd) 1079 0 R (man.dig) 1739 0 R (man.dnssec-keygen) 1787 0 R (man.dnssec-signzone) 1805 0 R (man.host) 1772 0 R (man.named) 1854 0 R (man.named-checkconf) 1825 0 R (man.named-checkzone) 1837 0 R (man.rndc) 1876 0 R (man.rndc-confgen) 1905 0 R (man.rndc.conf) 1888 0 R (notify) 990 0 R (options) 1187 0 R (page.1) 654 0 R (page.10) 915 0 R (page.100) 1767 0 R (page.101) 1779 0 R (page.102) 1783 0 R (page.103) 1795 0 R (page.104) 1801 0 R (page.105) 1812 0 R (page.106) 1817 0 R (page.107) 1822 0 R (page.108) 1833 0 R (page.109) 1845 0 R (page.11) 922 0 R (page.110) 1850 0 R (page.111) 1861 0 R (page.112) 1866 0 R (page.113) 1873 0 R (page.114) 1884 0 R (page.115) 1895 0 R (page.116) 1901 0 R (page.117) 1911 0 R (page.118) 1917 0 R (page.12) 934 0 R (page.13) 939 0 R (page.14) 948 0 R (page.15) 959 0 R (page.16) 967 0 R (page.17) 974 0 R (page.18) 980 0 R (page.19) 988 0 R (page.2) 679 0 R (page.20) 1010 0 R (page.21) 1020 0 R (page.22) 1025 0 R (page.23) 1029 0 R (page.24) 1036 0 R (page.25) 1045 0 R (page.26) 1055 0 R (page.27) 1062 0 R (page.28) 1067 0 R (page.29) 1076 0 R (page.3) 689 0 R (page.30) 1083 0 R (page.31) 1087 0 R (page.32) 1098 0 R (page.33) 1104 0 R (page.34) 1112 0 R (page.35) 1119 0 R (page.36) 1128 0 R (page.37) 1141 0 R (page.38) 1149 0 R (page.39) 1154 0 R (page.4) 744 0 R (page.40) 1160 0 R (page.41) 1166 0 R (page.42) 1174 0 R (page.43) 1181 0 R (page.44) 1186 0 R (page.45) 1191 0 R (page.46) 1197 0 R (page.47) 1201 0 R (page.48) 1208 0 R (page.49) 1218 0 R (page.5) 808 0 R (page.50) 1223 0 R (page.51) 1228 0 R (page.52) 1239 0 R (page.53) 1245 0 R (page.54) 1250 0 R (page.55) 1254 0 R (page.56) 1260 0 R (page.57) 1268 0 R (page.58) 1274 0 R (page.59) 1281 0 R (page.6) 869 0 R (page.60) 1289 0 R (page.61) 1296 0 R (page.62) 1308 0 R (page.63) 1312 0 R (page.64) 1318 0 R (page.65) 1323 0 R (page.66) 1327 0 R (page.67) 1336 0 R (page.68) 1342 0 R (page.69) 1346 0 R (page.7) 873 0 R (page.70) 1350 0 R (page.71) 1358 0 R (page.72) 1363 0 R (page.73) 1380 0 R (page.74) 1396 0 R (page.75) 1411 0 R (page.76) 1421 0 R (page.77) 1427 0 R (page.78) 1434 0 R (page.79) 1445 0 R (page.8) 890 0 R (page.80) 1457 0 R (page.81) 1465 0 R (page.82) 1471 0 R (page.83) 1475 0 R (page.84) 1481 0 R (page.85) 1492 0 R (page.86) 1497 0 R (page.87) 1501 0 R (page.88) 1512 0 R (page.89) 1516 0 R (page.9) 904 0 R (page.90) 1523 0 R (page.91) 1533 0 R (page.92) 1593 0 R (page.93) 1649 0 R (page.94) 1703 0 R (page.95) 1737 0 R (page.96) 1746 0 R (page.97) 1752 0 R (page.98) 1758 0 R (page.99) 1762 0 R (proposed_standards) 1016 0 R (rfcs) 900 0 R (rndc) 1137 0 R (rrset_ordering) 955 0 R (sample_configuration) 941 0 R (section*.10) 1662 0 R (section*.11) 1672 0 R (section*.12) 1692 0 R (section*.13) 1704 0 R (section*.14) 1730 0 R (section*.15) 1740 0 R (section*.16) 1741 0 R (section*.17) 1742 0 R (section*.18) 1747 0 R (section*.19) 1748 0 R (section*.2) 1528 0 R (section*.20) 1753 0 R (section*.21) 1763 0 R (section*.22) 1768 0 R (section*.23) 1769 0 R (section*.24) 1770 0 R (section*.25) 1771 0 R (section*.26) 1773 0 R (section*.27) 1774 0 R (section*.28) 1775 0 R (section*.29) 1784 0 R (section*.3) 1534 0 R (section*.30) 1785 0 R (section*.31) 1786 0 R (section*.32) 1788 0 R (section*.33) 1789 0 R (section*.34) 1790 0 R (section*.35) 1791 0 R (section*.36) 1796 0 R (section*.37) 1802 0 R (section*.38) 1803 0 R (section*.39) 1804 0 R (section*.4) 1542 0 R (section*.40) 1806 0 R (section*.41) 1807 0 R (section*.42) 1808 0 R (section*.43) 1813 0 R (section*.44) 1818 0 R (section*.45) 1823 0 R (section*.46) 1824 0 R (section*.47) 1826 0 R (section*.48) 1827 0 R (section*.49) 1828 0 R (section*.5) 1567 0 R (section*.50) 1829 0 R (section*.51) 1834 0 R (section*.52) 1835 0 R (section*.53) 1836 0 R (section*.54) 1838 0 R (section*.55) 1839 0 R (section*.56) 1840 0 R (section*.57) 1841 0 R (section*.58) 1851 0 R (section*.59) 1852 0 R (section*.6) 1579 0 R (section*.60) 1853 0 R (section*.61) 1855 0 R (section*.62) 1856 0 R (section*.63) 1857 0 R (section*.64) 1862 0 R (section*.65) 1867 0 R (section*.66) 1868 0 R (section*.67) 1869 0 R (section*.68) 1874 0 R (section*.69) 1875 0 R (section*.7) 1594 0 R (section*.70) 1877 0 R (section*.71) 1878 0 R (section*.72) 1879 0 R (section*.73) 1880 0 R (section*.74) 1885 0 R (section*.75) 1886 0 R (section*.76) 1887 0 R (section*.77) 1889 0 R (section*.78) 1890 0 R (section*.79) 1891 0 R (section*.8) 1632 0 R (section*.80) 1896 0 R (section*.81) 1902 0 R (section*.82) 1903 0 R (section*.83) 1904 0 R (section*.84) 1906 0 R (section*.85) 1907 0 R (section*.86) 1912 0 R (section*.87) 1913 0 R (section*.88) 1918 0 R (section*.89) 1919 0 R (section*.9) 1650 0 R (section*.90) 1920 0 R (section.1.1) 10 0 R (section.1.2) 14 0 R (section.1.3) 18 0 R (section.1.4) 22 0 R (section.2.1) 70 0 R (section.2.2) 74 0 R (section.2.3) 78 0 R (section.2.4) 82 0 R (section.2.5) 86 0 R (section.3.1) 94 0 R (section.3.2) 106 0 R (section.3.3) 110 0 R (section.4.1) 134 0 R (section.4.2) 138 0 R (section.4.3) 146 0 R (section.4.4) 150 0 R (section.4.5) 158 0 R (section.4.6) 194 0 R (section.4.7) 198 0 R (section.4.8) 202 0 R (section.4.9) 218 0 R (section.5.1) 234 0 R (section.5.2) 238 0 R (section.6.1) 246 0 R (section.6.2) 274 0 R (section.6.3) 474 0 R (section.7.1) 530 0 R (section.7.2) 534 0 R (section.7.3) 546 0 R (section.8.1) 554 0 R (section.8.2) 562 0 R (section.8.3) 566 0 R (section.A.1) 574 0 R (section.A.2) 582 0 R (section.A.3) 590 0 R (section.B.1) 610 0 R (section.B.10) 646 0 R (section.B.2) 614 0 R (section.B.3) 618 0 R (section.B.4) 622 0 R (section.B.5) 626 0 R (section.B.6) 630 0 R (section.B.7) 634 0 R (section.B.8) 638 0 R (section.B.9) 642 0 R (server_statement_definition_and_usage) 1214 0 R (server_statement_grammar) 1319 0 R (statsfile) 1193 0 R (subsection.1.4.1) 26 0 R (subsection.1.4.2) 30 0 R (subsection.1.4.3) 34 0 R (subsection.1.4.4) 38 0 R (subsection.1.4.5) 54 0 R (subsection.1.4.6) 62 0 R (subsection.3.1.1) 98 0 R (subsection.3.1.2) 102 0 R (subsection.3.3.1) 114 0 R (subsection.3.3.2) 126 0 R (subsection.4.2.1) 142 0 R (subsection.4.4.1) 154 0 R (subsection.4.5.1) 162 0 R (subsection.4.5.2) 174 0 R (subsection.4.5.3) 178 0 R (subsection.4.5.4) 182 0 R (subsection.4.5.5) 186 0 R (subsection.4.5.6) 190 0 R (subsection.4.8.1) 206 0 R (subsection.4.8.2) 210 0 R (subsection.4.8.3) 214 0 R (subsection.4.9.1) 222 0 R (subsection.4.9.2) 226 0 R (subsection.6.1.1) 250 0 R (subsection.6.1.2) 262 0 R (subsection.6.2.1) 278 0 R (subsection.6.2.10) 314 0 R (subsection.6.2.11) 326 0 R (subsection.6.2.12) 330 0 R (subsection.6.2.13) 334 0 R (subsection.6.2.14) 338 0 R (subsection.6.2.15) 342 0 R (subsection.6.2.16) 346 0 R (subsection.6.2.17) 426 0 R (subsection.6.2.18) 430 0 R (subsection.6.2.19) 434 0 R (subsection.6.2.2) 282 0 R (subsection.6.2.20) 438 0 R (subsection.6.2.21) 442 0 R (subsection.6.2.22) 446 0 R (subsection.6.2.23) 450 0 R (subsection.6.2.24) 454 0 R (subsection.6.2.3) 286 0 R (subsection.6.2.4) 290 0 R (subsection.6.2.5) 294 0 R (subsection.6.2.6) 298 0 R (subsection.6.2.7) 302 0 R (subsection.6.2.8) 306 0 R (subsection.6.2.9) 310 0 R (subsection.6.3.1) 478 0 R (subsection.6.3.2) 490 0 R (subsection.6.3.3) 494 0 R (subsection.6.3.4) 498 0 R (subsection.6.3.5) 502 0 R (subsection.6.3.6) 518 0 R (subsection.6.3.7) 522 0 R (subsection.7.2.1) 538 0 R (subsection.7.2.2) 542 0 R (subsection.8.1.1) 558 0 R (subsection.A.1.1) 578 0 R (subsection.A.2.1) 586 0 R (subsection.A.3.1) 594 0 R (subsection.A.3.2) 598 0 R (subsection.A.3.3) 602 0 R (subsubsection.1.4.4.1) 42 0 R (subsubsection.1.4.4.2) 46 0 R (subsubsection.1.4.4.3) 50 0 R (subsubsection.1.4.5.1) 58 0 R (subsubsection.3.3.1.1) 118 0 R (subsubsection.3.3.1.2) 122 0 R (subsubsection.4.5.1.1) 166 0 R (subsubsection.4.5.1.2) 170 0 R (subsubsection.6.1.1.1) 254 0 R (subsubsection.6.1.1.2) 258 0 R (subsubsection.6.1.2.1) 266 0 R (subsubsection.6.1.2.2) 270 0 R (subsubsection.6.2.10.1) 318 0 R (subsubsection.6.2.10.2) 322 0 R (subsubsection.6.2.16.1) 350 0 R (subsubsection.6.2.16.10) 386 0 R (subsubsection.6.2.16.11) 390 0 R (subsubsection.6.2.16.12) 394 0 R (subsubsection.6.2.16.13) 398 0 R (subsubsection.6.2.16.14) 402 0 R (subsubsection.6.2.16.15) 406 0 R (subsubsection.6.2.16.16) 410 0 R (subsubsection.6.2.16.17) 414 0 R (subsubsection.6.2.16.18) 418 0 R (subsubsection.6.2.16.19) 422 0 R (subsubsection.6.2.16.2) 354 0 R (subsubsection.6.2.16.3) 358 0 R (subsubsection.6.2.16.4) 362 0 R (subsubsection.6.2.16.5) 366 0 R (subsubsection.6.2.16.6) 370 0 R (subsubsection.6.2.16.7) 374 0 R (subsubsection.6.2.16.8) 378 0 R (subsubsection.6.2.16.9) 382 0 R (subsubsection.6.2.24.1) 458 0 R (subsubsection.6.2.24.2) 462 0 R (subsubsection.6.2.24.3) 466 0 R (subsubsection.6.2.24.4) 470 0 R (subsubsection.6.3.1.1) 482 0 R (subsubsection.6.3.1.2) 486 0 R (subsubsection.6.3.5.1) 506 0 R (subsubsection.6.3.5.2) 510 0 R (subsubsection.6.3.5.3) 514 0 R (table.1.1) 882 0 R (table.1.2) 892 0 R (table.3.1) 951 0 R (table.3.2) 983 0 R (table.6.1) 1091 0 R (table.6.10) 1417 0 R (table.6.11) 1423 0 R (table.6.12) 1429 0 R (table.6.13) 1436 0 R (table.6.14) 1438 0 R (table.6.15) 1441 0 R (table.6.16) 1448 0 R (table.6.17) 1451 0 R (table.6.18) 1467 0 R (table.6.2) 1115 0 R (table.6.3) 1123 0 R (table.6.4) 1162 0 R (table.6.5) 1203 0 R (table.6.6) 1284 0 R (table.6.7) 1314 0 R (table.6.8) 1354 0 R (table.6.9) 1407 0 R (the_category_phrase) 1156 0 R (the_sortlist_statement) 1275 0 R (topology) 1270 0 R (tsig) 1030 0 R (tuning) 1285 0 R (types_of_resource_records_and_when_to_use_them) 899 0 R (view_statement_grammar) 1304 0 R (zone_statement_grammar) 1234 0 R (zone_transfers) 1006 0 R (zonefile_format) 1292 0 R] -/Limits [(Access_Control_Lists) (zonefile_format)] ->> endobj -1944 0 obj << -/Kids [1943 0 R] ->> endobj -1945 0 obj << -/Dests 1944 0 R ->> endobj -1946 0 obj << -/Type /Catalog -/Pages 1941 0 R -/Outlines 1942 0 R -/Names 1945 0 R -/PageMode /UseOutlines -/OpenAction 649 0 R ->> endobj -1947 0 obj << -/Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfeTeX-1.21a)/Keywords() -/CreationDate (D:20071031135044+11'00') -/PTEX.Fullbanner (This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) kpathsea version 3.5.4) ->> endobj -xref -0 1948 -0000000001 65535 f -0000000002 00000 f -0000000003 00000 f -0000000004 00000 f -0000000000 00000 f -0000000009 00000 n -0000066898 00000 n -0000664779 00000 n -0000000054 00000 n -0000000086 00000 n -0000067022 00000 n -0000664707 00000 n -0000000133 00000 n -0000000173 00000 n -0000067147 00000 n -0000664621 00000 n -0000000221 00000 n -0000000273 00000 n -0000067272 00000 n -0000664535 00000 n -0000000321 00000 n -0000000377 00000 n -0000071535 00000 n -0000664425 00000 n -0000000425 00000 n -0000000478 00000 n -0000071660 00000 n -0000664351 00000 n -0000000531 00000 n -0000000572 00000 n -0000071785 00000 n -0000664264 00000 n -0000000625 00000 n -0000000674 00000 n -0000071910 00000 n -0000664177 00000 n -0000000727 00000 n -0000000757 00000 n -0000076188 00000 n -0000664053 00000 n -0000000810 00000 n -0000000861 00000 n -0000076313 00000 n -0000663979 00000 n -0000000919 00000 n -0000000964 00000 n -0000076438 00000 n -0000663892 00000 n -0000001022 00000 n -0000001062 00000 n -0000076563 00000 n -0000663818 00000 n -0000001120 00000 n -0000001162 00000 n -0000079535 00000 n -0000663694 00000 n -0000001215 00000 n -0000001260 00000 n -0000079660 00000 n -0000663633 00000 n -0000001318 00000 n -0000001355 00000 n -0000079785 00000 n -0000663559 00000 n -0000001408 00000 n -0000001463 00000 n -0000082713 00000 n -0000663434 00000 n -0000001509 00000 n -0000001556 00000 n -0000082838 00000 n -0000663360 00000 n -0000001604 00000 n -0000001648 00000 n -0000082963 00000 n -0000663273 00000 n -0000001696 00000 n -0000001735 00000 n -0000083088 00000 n -0000663186 00000 n -0000001783 00000 n -0000001825 00000 n -0000083212 00000 n -0000663099 00000 n -0000001873 00000 n -0000001936 00000 n -0000084298 00000 n -0000663025 00000 n -0000001984 00000 n -0000002034 00000 n -0000086008 00000 n -0000662897 00000 n -0000002080 00000 n -0000002126 00000 n -0000086132 00000 n -0000662784 00000 n -0000002174 00000 n -0000002218 00000 n -0000086257 00000 n -0000662708 00000 n -0000002271 00000 n -0000002323 00000 n -0000086382 00000 n -0000662631 00000 n -0000002377 00000 n -0000002436 00000 n -0000088910 00000 n -0000662540 00000 n -0000002485 00000 n -0000002523 00000 n -0000089162 00000 n -0000662423 00000 n -0000002572 00000 n -0000002618 00000 n -0000089288 00000 n -0000662305 00000 n -0000002672 00000 n -0000002739 00000 n -0000092495 00000 n -0000662226 00000 n -0000002798 00000 n -0000002842 00000 n -0000092621 00000 n -0000662147 00000 n -0000002901 00000 n -0000002949 00000 n -0000102950 00000 n -0000662068 00000 n -0000003003 00000 n -0000003036 00000 n -0000107881 00000 n -0000661936 00000 n -0000003083 00000 n -0000003126 00000 n -0000108007 00000 n -0000661857 00000 n -0000003175 00000 n -0000003205 00000 n -0000108133 00000 n -0000661725 00000 n -0000003254 00000 n -0000003292 00000 n -0000108259 00000 n -0000661660 00000 n -0000003346 00000 n -0000003388 00000 n -0000112550 00000 n -0000661567 00000 n -0000003437 00000 n -0000003496 00000 n -0000112677 00000 n -0000661435 00000 n -0000003545 00000 n -0000003578 00000 n -0000112806 00000 n -0000661370 00000 n -0000003632 00000 n -0000003681 00000 n -0000120178 00000 n -0000661238 00000 n -0000003730 00000 n -0000003758 00000 n -0000120305 00000 n -0000661120 00000 n -0000003812 00000 n -0000003881 00000 n -0000120434 00000 n -0000661041 00000 n -0000003940 00000 n -0000003988 00000 n -0000123309 00000 n -0000660962 00000 n -0000004047 00000 n -0000004092 00000 n -0000123438 00000 n -0000660869 00000 n -0000004146 00000 n -0000004214 00000 n -0000123567 00000 n -0000660776 00000 n -0000004268 00000 n -0000004338 00000 n -0000123696 00000 n -0000660683 00000 n -0000004392 00000 n -0000004455 00000 n -0000123824 00000 n -0000660590 00000 n -0000004509 00000 n -0000004564 00000 n -0000127470 00000 n -0000660511 00000 n -0000004618 00000 n -0000004650 00000 n -0000127599 00000 n -0000660418 00000 n -0000004699 00000 n -0000004727 00000 n -0000127728 00000 n -0000660325 00000 n -0000004776 00000 n -0000004808 00000 n -0000131334 00000 n -0000660193 00000 n -0000004857 00000 n -0000004887 00000 n -0000131463 00000 n -0000660114 00000 n -0000004941 00000 n -0000004982 00000 n -0000131591 00000 n -0000660021 00000 n -0000005036 00000 n -0000005078 00000 n -0000135033 00000 n -0000659942 00000 n -0000005132 00000 n -0000005177 00000 n -0000138107 00000 n -0000659824 00000 n -0000005226 00000 n -0000005272 00000 n -0000138236 00000 n -0000659745 00000 n -0000005326 00000 n -0000005386 00000 n -0000138364 00000 n -0000659666 00000 n -0000005440 00000 n -0000005509 00000 n -0000140844 00000 n -0000659533 00000 n -0000005556 00000 n -0000005609 00000 n -0000140973 00000 n -0000659454 00000 n -0000005658 00000 n -0000005714 00000 n -0000141102 00000 n -0000659375 00000 n -0000005763 00000 n -0000005812 00000 n -0000145286 00000 n -0000659242 00000 n -0000005859 00000 n -0000005911 00000 n -0000145415 00000 n -0000659124 00000 n -0000005960 00000 n -0000006011 00000 n -0000149682 00000 n -0000659006 00000 n -0000006065 00000 n -0000006110 00000 n -0000149811 00000 n -0000658927 00000 n -0000006169 00000 n -0000006203 00000 n -0000149940 00000 n -0000658848 00000 n -0000006262 00000 n -0000006310 00000 n -0000153288 00000 n -0000658730 00000 n -0000006364 00000 n -0000006404 00000 n -0000153417 00000 n -0000658651 00000 n -0000006463 00000 n -0000006497 00000 n -0000153546 00000 n -0000658572 00000 n -0000006556 00000 n -0000006604 00000 n -0000157451 00000 n -0000658439 00000 n -0000006653 00000 n -0000006703 00000 n -0000161073 00000 n -0000658360 00000 n -0000006757 00000 n -0000006804 00000 n -0000161202 00000 n -0000658267 00000 n -0000006858 00000 n -0000006918 00000 n -0000161459 00000 n -0000658174 00000 n -0000006972 00000 n -0000007024 00000 n -0000161588 00000 n -0000658081 00000 n -0000007078 00000 n -0000007143 00000 n -0000166242 00000 n -0000657988 00000 n -0000007197 00000 n -0000007248 00000 n -0000166371 00000 n -0000657895 00000 n -0000007302 00000 n -0000007366 00000 n -0000166500 00000 n -0000657802 00000 n -0000007420 00000 n -0000007467 00000 n -0000166629 00000 n -0000657709 00000 n -0000007521 00000 n -0000007581 00000 n -0000169977 00000 n -0000657616 00000 n -0000007635 00000 n -0000007686 00000 n -0000170106 00000 n -0000657484 00000 n -0000007741 00000 n -0000007806 00000 n -0000174741 00000 n -0000657405 00000 n -0000007866 00000 n -0000007913 00000 n -0000180920 00000 n -0000657326 00000 n -0000007973 00000 n -0000008021 00000 n -0000184667 00000 n -0000657233 00000 n -0000008076 00000 n -0000008126 00000 n -0000184796 00000 n -0000657140 00000 n -0000008181 00000 n -0000008244 00000 n -0000186525 00000 n -0000657047 00000 n -0000008299 00000 n -0000008351 00000 n -0000186654 00000 n -0000656954 00000 n -0000008406 00000 n -0000008471 00000 n -0000186783 00000 n -0000656861 00000 n -0000008526 00000 n -0000008578 00000 n -0000190468 00000 n -0000656728 00000 n -0000008633 00000 n -0000008698 00000 n -0000198661 00000 n -0000656649 00000 n -0000008758 00000 n -0000008802 00000 n -0000216022 00000 n -0000656556 00000 n -0000008862 00000 n -0000008901 00000 n -0000220238 00000 n -0000656463 00000 n -0000008961 00000 n -0000009008 00000 n -0000220366 00000 n -0000656370 00000 n -0000009068 00000 n -0000009111 00000 n -0000224175 00000 n -0000656277 00000 n -0000009171 00000 n -0000009210 00000 n -0000227147 00000 n -0000656184 00000 n -0000009270 00000 n -0000009312 00000 n -0000227276 00000 n -0000656091 00000 n -0000009372 00000 n -0000009415 00000 n -0000234515 00000 n -0000655998 00000 n -0000009475 00000 n -0000009522 00000 n -0000238765 00000 n -0000655905 00000 n -0000009582 00000 n -0000009643 00000 n -0000238894 00000 n -0000655812 00000 n -0000009704 00000 n -0000009756 00000 n -0000242265 00000 n -0000655719 00000 n -0000009817 00000 n -0000009870 00000 n -0000242394 00000 n -0000655626 00000 n -0000009931 00000 n -0000009969 00000 n -0000246293 00000 n -0000655533 00000 n -0000010030 00000 n -0000010082 00000 n -0000249718 00000 n -0000655440 00000 n -0000010143 00000 n -0000010187 00000 n -0000249976 00000 n -0000655347 00000 n -0000010248 00000 n -0000010284 00000 n -0000258745 00000 n -0000655254 00000 n -0000010345 00000 n -0000010408 00000 n -0000258874 00000 n -0000655161 00000 n -0000010469 00000 n -0000010519 00000 n -0000264226 00000 n -0000655068 00000 n -0000010580 00000 n -0000010629 00000 n -0000268214 00000 n -0000654989 00000 n -0000010690 00000 n -0000010746 00000 n -0000268342 00000 n -0000654896 00000 n -0000010801 00000 n -0000010852 00000 n -0000272260 00000 n -0000654803 00000 n -0000010907 00000 n -0000010971 00000 n -0000276289 00000 n -0000654710 00000 n -0000011026 00000 n -0000011083 00000 n -0000276417 00000 n -0000654617 00000 n -0000011138 00000 n -0000011208 00000 n -0000276543 00000 n -0000654524 00000 n -0000011263 00000 n -0000011312 00000 n -0000279969 00000 n -0000654431 00000 n -0000011367 00000 n -0000011429 00000 n -0000281613 00000 n -0000654338 00000 n -0000011484 00000 n -0000011533 00000 n -0000285546 00000 n -0000654220 00000 n -0000011588 00000 n -0000011650 00000 n -0000285675 00000 n -0000654141 00000 n -0000011710 00000 n -0000011749 00000 n -0000289728 00000 n -0000654048 00000 n -0000011809 00000 n -0000011843 00000 n -0000295345 00000 n -0000653955 00000 n -0000011903 00000 n -0000011944 00000 n -0000305746 00000 n -0000653876 00000 n -0000012004 00000 n -0000012056 00000 n -0000309844 00000 n -0000653758 00000 n -0000012105 00000 n -0000012138 00000 n -0000309972 00000 n -0000653640 00000 n -0000012192 00000 n -0000012264 00000 n -0000310100 00000 n -0000653561 00000 n -0000012323 00000 n -0000012367 00000 n -0000317603 00000 n -0000653482 00000 n -0000012426 00000 n -0000012479 00000 n -0000321290 00000 n -0000653389 00000 n -0000012533 00000 n -0000012583 00000 n -0000324743 00000 n -0000653296 00000 n -0000012637 00000 n -0000012675 00000 n -0000325002 00000 n -0000653203 00000 n -0000012729 00000 n -0000012778 00000 n -0000325260 00000 n -0000653071 00000 n -0000012832 00000 n -0000012884 00000 n -0000328115 00000 n -0000652992 00000 n -0000012943 00000 n -0000012995 00000 n -0000328244 00000 n -0000652899 00000 n -0000013054 00000 n -0000013107 00000 n -0000328373 00000 n -0000652820 00000 n -0000013166 00000 n -0000013215 00000 n -0000328502 00000 n -0000652727 00000 n -0000013269 00000 n -0000013349 00000 n -0000332842 00000 n -0000652648 00000 n -0000013403 00000 n -0000013452 00000 n -0000335118 00000 n -0000652515 00000 n -0000013499 00000 n -0000013551 00000 n -0000335247 00000 n -0000652436 00000 n -0000013600 00000 n -0000013644 00000 n -0000339340 00000 n -0000652304 00000 n -0000013693 00000 n -0000013734 00000 n -0000339469 00000 n -0000652225 00000 n -0000013788 00000 n -0000013836 00000 n -0000339598 00000 n -0000652146 00000 n -0000013890 00000 n -0000013941 00000 n -0000339727 00000 n -0000652067 00000 n -0000013990 00000 n -0000014037 00000 n -0000343990 00000 n -0000651934 00000 n -0000014084 00000 n -0000014121 00000 n -0000344119 00000 n -0000651816 00000 n -0000014170 00000 n -0000014209 00000 n -0000344248 00000 n -0000651751 00000 n -0000014263 00000 n -0000014341 00000 n -0000344377 00000 n -0000651658 00000 n -0000014390 00000 n -0000014457 00000 n -0000344506 00000 n -0000651579 00000 n -0000014506 00000 n -0000014551 00000 n -0000347945 00000 n -0000651446 00000 n -0000014599 00000 n -0000014631 00000 n -0000348074 00000 n -0000651328 00000 n -0000014680 00000 n -0000014719 00000 n -0000348203 00000 n -0000651263 00000 n -0000014773 00000 n -0000014834 00000 n -0000351968 00000 n -0000651131 00000 n -0000014883 00000 n -0000014940 00000 n -0000352097 00000 n -0000651066 00000 n -0000014994 00000 n -0000015043 00000 n -0000352226 00000 n -0000650948 00000 n -0000015092 00000 n -0000015154 00000 n -0000352355 00000 n -0000650869 00000 n -0000015208 00000 n -0000015263 00000 n -0000376379 00000 n -0000650776 00000 n -0000015317 00000 n -0000015358 00000 n -0000376508 00000 n -0000650697 00000 n -0000015412 00000 n -0000015464 00000 n -0000379211 00000 n -0000650577 00000 n -0000015512 00000 n -0000015546 00000 n -0000379340 00000 n -0000650498 00000 n -0000015595 00000 n -0000015622 00000 n -0000397280 00000 n -0000650405 00000 n -0000015671 00000 n -0000015699 00000 n -0000404815 00000 n -0000650312 00000 n -0000015748 00000 n -0000015785 00000 n -0000411129 00000 n -0000650219 00000 n -0000015834 00000 n -0000015873 00000 n -0000420651 00000 n -0000650126 00000 n -0000015922 00000 n -0000015961 00000 n -0000423538 00000 n -0000650033 00000 n -0000016010 00000 n -0000016049 00000 n -0000429911 00000 n -0000649940 00000 n -0000016098 00000 n -0000016127 00000 n -0000439507 00000 n -0000649847 00000 n -0000016176 00000 n -0000016204 00000 n -0000442707 00000 n -0000649754 00000 n -0000016253 00000 n -0000016286 00000 n -0000448703 00000 n -0000649675 00000 n -0000016336 00000 n -0000016373 00000 n -0000016742 00000 n -0000016864 00000 n -0000024693 00000 n -0000016426 00000 n -0000024567 00000 n -0000024630 00000 n -0000645556 00000 n -0000619613 00000 n -0000645382 00000 n -0000646581 00000 n -0000019727 00000 n -0000019944 00000 n -0000020013 00000 n -0000020082 00000 n -0000020150 00000 n -0000020218 00000 n -0000020267 00000 n -0000020314 00000 n -0000020647 00000 n -0000020669 00000 n -0000020837 00000 n -0000021002 00000 n -0000021171 00000 n -0000021350 00000 n -0000021659 00000 n -0000021819 00000 n -0000026052 00000 n -0000025867 00000 n -0000024793 00000 n -0000025989 00000 n -0000618401 00000 n -0000591922 00000 n -0000618227 00000 n -0000591237 00000 n -0000589092 00000 n -0000591073 00000 n -0000037758 00000 n -0000029108 00000 n -0000026137 00000 n -0000037632 00000 n -0000037695 00000 n -0000029642 00000 n -0000029796 00000 n -0000029953 00000 n -0000030110 00000 n -0000030266 00000 n -0000030423 00000 n -0000030585 00000 n -0000030746 00000 n -0000030907 00000 n -0000031069 00000 n -0000031236 00000 n -0000031403 00000 n -0000031568 00000 n -0000031730 00000 n -0000031896 00000 n -0000032057 00000 n -0000032212 00000 n -0000032369 00000 n -0000032525 00000 n -0000032682 00000 n -0000032839 00000 n -0000032996 00000 n -0000033150 00000 n -0000033306 00000 n -0000033468 00000 n -0000033630 00000 n -0000033786 00000 n -0000033943 00000 n -0000034105 00000 n -0000034272 00000 n -0000034438 00000 n -0000034599 00000 n -0000034754 00000 n -0000034911 00000 n -0000035068 00000 n -0000035230 00000 n -0000035387 00000 n -0000035544 00000 n -0000035706 00000 n -0000035863 00000 n -0000036025 00000 n -0000036192 00000 n -0000036358 00000 n -0000036520 00000 n -0000036682 00000 n -0000036844 00000 n -0000037005 00000 n -0000037167 00000 n -0000037322 00000 n -0000037477 00000 n -0000051127 00000 n -0000041075 00000 n -0000037843 00000 n -0000051064 00000 n -0000588541 00000 n -0000571460 00000 n -0000588357 00000 n -0000041665 00000 n -0000041828 00000 n -0000041990 00000 n -0000042153 00000 n -0000042311 00000 n -0000042474 00000 n -0000042637 00000 n -0000042792 00000 n -0000042950 00000 n -0000043108 00000 n -0000043264 00000 n -0000043422 00000 n -0000043585 00000 n -0000043753 00000 n -0000043921 00000 n -0000044084 00000 n -0000044252 00000 n -0000044420 00000 n -0000044578 00000 n -0000044741 00000 n -0000044904 00000 n -0000045066 00000 n -0000045228 00000 n -0000045391 00000 n -0000045553 00000 n -0000045715 00000 n -0000045878 00000 n -0000046041 00000 n -0000046204 00000 n -0000046373 00000 n -0000046542 00000 n -0000046706 00000 n -0000046869 00000 n -0000047033 00000 n -0000047197 00000 n -0000047360 00000 n -0000047524 00000 n -0000047693 00000 n -0000047862 00000 n -0000048031 00000 n -0000048200 00000 n -0000048369 00000 n -0000048538 00000 n -0000048707 00000 n -0000048876 00000 n -0000049045 00000 n -0000049215 00000 n -0000049385 00000 n -0000049555 00000 n -0000049724 00000 n -0000049894 00000 n -0000050064 00000 n -0000050234 00000 n -0000050403 00000 n -0000050573 00000 n -0000050741 00000 n -0000050902 00000 n -0000063950 00000 n -0000054658 00000 n -0000051225 00000 n -0000063887 00000 n -0000055224 00000 n -0000055387 00000 n -0000055550 00000 n -0000055713 00000 n -0000055876 00000 n -0000056038 00000 n -0000056201 00000 n -0000056369 00000 n -0000056537 00000 n -0000056704 00000 n -0000056872 00000 n -0000057028 00000 n -0000057190 00000 n -0000057357 00000 n -0000057524 00000 n -0000057686 00000 n -0000057848 00000 n -0000058010 00000 n -0000058172 00000 n -0000058339 00000 n -0000058506 00000 n -0000058673 00000 n -0000058835 00000 n -0000058997 00000 n -0000059152 00000 n -0000059307 00000 n -0000059464 00000 n -0000059626 00000 n -0000059788 00000 n -0000059944 00000 n -0000060099 00000 n -0000060256 00000 n -0000060418 00000 n -0000060574 00000 n -0000060731 00000 n -0000060887 00000 n -0000061044 00000 n -0000061206 00000 n -0000061363 00000 n -0000061525 00000 n -0000061682 00000 n -0000061843 00000 n -0000062005 00000 n -0000062167 00000 n -0000062322 00000 n -0000062478 00000 n -0000062635 00000 n -0000062792 00000 n -0000062949 00000 n -0000063105 00000 n -0000063262 00000 n -0000063419 00000 n -0000570494 00000 n -0000550527 00000 n -0000570321 00000 n -0000063576 00000 n -0000063731 00000 n -0000064395 00000 n -0000064210 00000 n -0000064061 00000 n -0000064332 00000 n -0000067523 00000 n -0000066713 00000 n -0000064436 00000 n -0000066835 00000 n -0000066959 00000 n -0000067084 00000 n -0000067209 00000 n -0000549638 00000 n -0000528306 00000 n -0000549464 00000 n -0000067334 00000 n -0000067397 00000 n -0000067460 00000 n -0000527539 00000 n -0000510131 00000 n -0000527366 00000 n -0000646699 00000 n -0000072034 00000 n -0000070852 00000 n -0000067647 00000 n -0000071346 00000 n -0000071409 00000 n -0000071472 00000 n -0000071597 00000 n -0000071722 00000 n -0000071847 00000 n -0000071002 00000 n -0000071195 00000 n -0000071972 00000 n -0000310036 00000 n -0000352419 00000 n -0000076688 00000 n -0000075652 00000 n -0000072158 00000 n -0000076125 00000 n -0000076250 00000 n -0000075802 00000 n -0000075964 00000 n -0000076375 00000 n -0000076500 00000 n -0000076625 00000 n -0000092558 00000 n -0000079910 00000 n -0000079350 00000 n -0000076812 00000 n -0000079472 00000 n -0000079597 00000 n -0000079722 00000 n -0000079847 00000 n -0000083337 00000 n -0000082196 00000 n -0000080021 00000 n -0000082650 00000 n -0000082775 00000 n -0000082900 00000 n -0000083025 00000 n -0000083150 00000 n -0000082346 00000 n -0000082498 00000 n -0000083274 00000 n -0000268278 00000 n -0000084423 00000 n -0000084113 00000 n -0000083422 00000 n -0000084235 00000 n -0000084360 00000 n -0000086508 00000 n -0000085823 00000 n -0000084521 00000 n -0000085945 00000 n -0000086070 00000 n -0000086194 00000 n -0000086319 00000 n -0000086445 00000 n -0000646817 00000 n -0000089413 00000 n -0000088545 00000 n -0000086606 00000 n -0000088847 00000 n -0000088973 00000 n -0000089036 00000 n -0000089099 00000 n -0000088687 00000 n -0000089225 00000 n -0000089351 00000 n -0000249782 00000 n -0000092747 00000 n -0000092310 00000 n -0000089524 00000 n -0000092432 00000 n -0000509475 00000 n -0000497890 00000 n -0000509298 00000 n -0000092684 00000 n -0000096532 00000 n -0000096347 00000 n -0000092871 00000 n -0000096469 00000 n -0000497355 00000 n -0000487841 00000 n -0000497178 00000 n -0000100916 00000 n -0000100525 00000 n -0000096695 00000 n -0000100853 00000 n -0000100667 00000 n -0000161651 00000 n -0000103202 00000 n -0000102765 00000 n -0000101053 00000 n -0000102887 00000 n -0000103013 00000 n -0000103076 00000 n -0000103139 00000 n -0000105854 00000 n -0000108386 00000 n -0000105703 00000 n -0000103326 00000 n -0000107818 00000 n -0000107944 00000 n -0000108070 00000 n -0000107496 00000 n -0000107657 00000 n -0000486982 00000 n -0000477610 00000 n -0000486810 00000 n -0000477048 00000 n -0000467964 00000 n -0000476875 00000 n -0000108196 00000 n -0000108322 00000 n -0000646935 00000 n -0000107325 00000 n -0000107383 00000 n -0000107473 00000 n -0000198725 00000 n -0000227340 00000 n -0000112935 00000 n -0000112001 00000 n -0000108538 00000 n -0000112485 00000 n -0000112613 00000 n -0000112157 00000 n -0000112323 00000 n -0000112741 00000 n -0000112870 00000 n -0000356445 00000 n -0000116427 00000 n -0000116047 00000 n -0000113086 00000 n -0000116362 00000 n -0000116194 00000 n -0000117661 00000 n -0000117470 00000 n -0000116552 00000 n -0000117596 00000 n -0000120563 00000 n -0000119987 00000 n -0000117760 00000 n -0000120113 00000 n -0000120240 00000 n -0000120369 00000 n -0000120498 00000 n -0000123953 00000 n -0000123118 00000 n -0000120701 00000 n -0000123244 00000 n -0000123373 00000 n -0000123502 00000 n -0000123631 00000 n -0000123759 00000 n -0000123888 00000 n -0000127856 00000 n -0000127088 00000 n -0000124091 00000 n -0000127405 00000 n -0000127235 00000 n -0000127534 00000 n -0000127663 00000 n -0000127792 00000 n -0000647059 00000 n -0000305810 00000 n -0000131720 00000 n -0000131143 00000 n -0000127968 00000 n -0000131269 00000 n -0000131398 00000 n -0000131526 00000 n -0000131655 00000 n -0000135162 00000 n -0000134842 00000 n -0000131858 00000 n -0000134968 00000 n -0000135097 00000 n -0000138493 00000 n -0000137734 00000 n -0000135274 00000 n -0000138042 00000 n -0000138171 00000 n -0000137881 00000 n -0000138300 00000 n -0000138428 00000 n -0000352161 00000 n -0000141231 00000 n -0000140653 00000 n -0000138659 00000 n -0000140779 00000 n -0000140908 00000 n -0000141037 00000 n -0000141166 00000 n -0000141671 00000 n -0000141480 00000 n -0000141330 00000 n -0000141606 00000 n -0000145673 00000 n -0000144907 00000 n -0000141713 00000 n -0000145221 00000 n -0000145350 00000 n -0000145478 00000 n -0000145543 00000 n -0000145608 00000 n -0000145054 00000 n -0000647184 00000 n -0000149746 00000 n -0000150069 00000 n -0000149491 00000 n -0000145772 00000 n -0000149617 00000 n -0000149875 00000 n -0000150004 00000 n -0000153675 00000 n -0000153097 00000 n -0000150207 00000 n -0000153223 00000 n -0000153352 00000 n -0000153481 00000 n -0000153610 00000 n -0000156460 00000 n -0000157710 00000 n -0000156334 00000 n -0000153800 00000 n -0000157386 00000 n -0000157515 00000 n -0000157580 00000 n -0000157645 00000 n -0000161715 00000 n -0000160882 00000 n -0000157864 00000 n -0000161008 00000 n -0000161137 00000 n -0000161264 00000 n -0000161329 00000 n -0000161394 00000 n -0000161523 00000 n -0000166757 00000 n -0000165359 00000 n -0000161827 00000 n -0000166177 00000 n -0000165533 00000 n -0000165684 00000 n -0000166306 00000 n -0000166435 00000 n -0000166564 00000 n -0000166693 00000 n -0000165843 00000 n -0000165993 00000 n -0000454156 00000 n -0000170235 00000 n -0000169578 00000 n -0000166895 00000 n -0000169912 00000 n -0000169725 00000 n -0000170041 00000 n -0000170170 00000 n -0000647309 00000 n -0000174870 00000 n -0000174550 00000 n -0000170360 00000 n -0000174676 00000 n -0000174805 00000 n -0000178034 00000 n -0000177655 00000 n -0000174995 00000 n -0000177969 00000 n -0000177802 00000 n -0000180984 00000 n -0000181178 00000 n -0000180729 00000 n -0000178146 00000 n -0000180855 00000 n -0000181049 00000 n -0000181113 00000 n -0000184925 00000 n -0000184141 00000 n -0000181290 00000 n -0000184602 00000 n -0000184731 00000 n -0000184860 00000 n -0000184297 00000 n -0000184449 00000 n -0000186912 00000 n -0000186334 00000 n -0000185037 00000 n -0000186460 00000 n -0000186589 00000 n -0000186718 00000 n -0000186847 00000 n -0000188482 00000 n -0000188291 00000 n -0000187024 00000 n -0000188417 00000 n -0000647434 00000 n -0000190597 00000 n -0000190277 00000 n -0000188581 00000 n -0000190403 00000 n -0000190532 00000 n -0000194902 00000 n -0000194534 00000 n -0000190709 00000 n -0000194837 00000 n -0000194681 00000 n -0000264290 00000 n -0000198790 00000 n -0000198470 00000 n -0000195027 00000 n -0000198596 00000 n -0000202882 00000 n -0000202386 00000 n -0000198915 00000 n -0000202687 00000 n -0000202752 00000 n -0000202817 00000 n -0000202533 00000 n -0000208035 00000 n -0000206902 00000 n -0000203007 00000 n -0000207970 00000 n -0000207085 00000 n -0000207241 00000 n -0000207426 00000 n -0000207600 00000 n -0000207785 00000 n -0000272323 00000 n -0000212172 00000 n -0000211981 00000 n -0000208227 00000 n -0000212107 00000 n -0000647559 00000 n -0000216151 00000 n -0000215831 00000 n -0000212297 00000 n -0000215957 00000 n -0000216086 00000 n -0000220494 00000 n -0000219505 00000 n -0000216263 00000 n -0000220173 00000 n -0000219670 00000 n -0000220302 00000 n -0000220430 00000 n -0000219839 00000 n -0000220005 00000 n -0000281677 00000 n -0000339791 00000 n -0000224304 00000 n -0000223794 00000 n -0000220660 00000 n -0000224110 00000 n -0000223941 00000 n -0000224239 00000 n -0000227405 00000 n -0000226956 00000 n -0000224429 00000 n -0000227082 00000 n -0000227211 00000 n -0000231466 00000 n -0000231275 00000 n -0000227571 00000 n -0000231401 00000 n -0000234642 00000 n -0000234324 00000 n -0000231578 00000 n -0000234450 00000 n -0000234579 00000 n -0000647684 00000 n -0000239021 00000 n -0000238215 00000 n -0000234795 00000 n -0000238700 00000 n -0000238829 00000 n -0000238371 00000 n -0000238957 00000 n -0000238545 00000 n -0000242523 00000 n -0000242074 00000 n -0000239133 00000 n -0000242200 00000 n -0000242329 00000 n -0000242458 00000 n -0000246422 00000 n -0000245755 00000 n -0000242676 00000 n -0000246228 00000 n -0000246357 00000 n -0000245911 00000 n -0000246073 00000 n -0000250105 00000 n -0000249337 00000 n -0000246588 00000 n -0000249653 00000 n -0000249484 00000 n -0000249846 00000 n -0000249911 00000 n -0000250040 00000 n -0000254580 00000 n -0000254034 00000 n -0000250284 00000 n -0000254515 00000 n -0000254190 00000 n -0000254352 00000 n -0000332906 00000 n -0000259003 00000 n -0000258364 00000 n -0000254746 00000 n -0000258680 00000 n -0000467609 00000 n -0000465612 00000 n -0000467444 00000 n -0000258809 00000 n -0000258511 00000 n -0000258938 00000 n -0000647809 00000 n -0000276607 00000 n -0000261168 00000 n -0000260977 00000 n -0000259129 00000 n -0000261103 00000 n -0000264485 00000 n -0000264035 00000 n -0000261280 00000 n -0000264161 00000 n -0000264355 00000 n -0000264420 00000 n -0000268471 00000 n -0000268023 00000 n -0000264625 00000 n -0000268149 00000 n -0000268406 00000 n -0000272388 00000 n -0000272069 00000 n -0000268583 00000 n -0000272195 00000 n -0000276671 00000 n -0000275594 00000 n -0000272500 00000 n -0000276224 00000 n -0000275759 00000 n -0000275910 00000 n -0000276353 00000 n -0000276481 00000 n -0000276070 00000 n -0000280097 00000 n -0000279778 00000 n -0000276783 00000 n -0000279904 00000 n -0000280033 00000 n -0000647934 00000 n -0000281742 00000 n -0000281422 00000 n -0000280209 00000 n -0000281548 00000 n -0000283200 00000 n -0000283009 00000 n -0000281854 00000 n -0000283135 00000 n -0000285934 00000 n -0000285355 00000 n -0000283299 00000 n -0000285481 00000 n -0000285610 00000 n -0000285739 00000 n -0000285804 00000 n -0000285869 00000 n -0000289857 00000 n -0000289537 00000 n -0000286046 00000 n -0000289663 00000 n -0000289792 00000 n -0000295474 00000 n -0000293080 00000 n -0000289969 00000 n -0000295280 00000 n -0000295409 00000 n -0000293326 00000 n -0000293488 00000 n -0000293650 00000 n -0000293811 00000 n -0000293971 00000 n -0000294142 00000 n -0000294304 00000 n -0000294466 00000 n -0000294628 00000 n -0000294791 00000 n -0000294954 00000 n -0000295117 00000 n -0000300692 00000 n -0000298631 00000 n -0000295599 00000 n -0000300627 00000 n -0000298868 00000 n -0000299030 00000 n -0000299192 00000 n -0000299353 00000 n -0000299514 00000 n -0000299676 00000 n -0000299839 00000 n -0000299993 00000 n -0000300147 00000 n -0000300309 00000 n -0000300469 00000 n -0000648059 00000 n -0000306003 00000 n -0000304030 00000 n -0000300817 00000 n -0000305681 00000 n -0000304249 00000 n -0000304411 00000 n -0000304573 00000 n -0000304734 00000 n -0000304896 00000 n -0000305050 00000 n -0000305211 00000 n -0000305365 00000 n -0000305527 00000 n -0000305875 00000 n -0000305939 00000 n -0000310358 00000 n -0000309291 00000 n -0000306128 00000 n -0000309779 00000 n -0000309907 00000 n -0000310164 00000 n -0000309447 00000 n -0000309617 00000 n -0000310229 00000 n -0000310294 00000 n -0000313806 00000 n -0000313485 00000 n -0000310483 00000 n -0000313611 00000 n -0000313676 00000 n -0000313741 00000 n -0000317732 00000 n -0000317282 00000 n -0000313905 00000 n -0000317408 00000 n -0000317473 00000 n -0000317538 00000 n -0000317667 00000 n -0000321548 00000 n -0000320840 00000 n -0000317857 00000 n -0000320966 00000 n -0000321031 00000 n -0000321096 00000 n -0000321161 00000 n -0000321226 00000 n -0000321354 00000 n -0000321418 00000 n -0000321483 00000 n -0000325389 00000 n -0000324552 00000 n -0000321673 00000 n -0000324678 00000 n -0000324807 00000 n -0000324872 00000 n -0000324937 00000 n -0000325066 00000 n -0000325131 00000 n -0000325196 00000 n -0000325324 00000 n -0000648184 00000 n -0000328630 00000 n -0000327924 00000 n -0000325568 00000 n -0000328050 00000 n -0000328179 00000 n -0000328308 00000 n -0000328437 00000 n -0000328566 00000 n -0000332970 00000 n -0000332521 00000 n -0000328823 00000 n -0000332647 00000 n -0000332712 00000 n -0000332777 00000 n -0000333436 00000 n -0000333245 00000 n -0000333095 00000 n -0000333371 00000 n -0000335376 00000 n -0000334927 00000 n -0000333478 00000 n -0000335053 00000 n -0000335182 00000 n -0000335311 00000 n -0000339856 00000 n -0000338912 00000 n -0000335488 00000 n -0000339275 00000 n -0000465291 00000 n -0000456078 00000 n -0000465105 00000 n -0000339059 00000 n -0000339404 00000 n -0000339533 00000 n -0000339662 00000 n -0000340894 00000 n -0000340703 00000 n -0000340089 00000 n -0000340829 00000 n -0000648309 00000 n -0000341321 00000 n -0000341130 00000 n -0000340980 00000 n -0000341256 00000 n -0000344634 00000 n -0000343408 00000 n -0000341363 00000 n -0000343925 00000 n -0000344054 00000 n -0000344183 00000 n -0000344312 00000 n -0000344441 00000 n -0000344570 00000 n -0000343564 00000 n -0000343736 00000 n -0000345088 00000 n -0000344897 00000 n -0000344747 00000 n -0000345023 00000 n -0000348332 00000 n -0000347754 00000 n -0000345130 00000 n -0000347880 00000 n -0000348009 00000 n -0000348138 00000 n -0000348267 00000 n -0000352611 00000 n -0000351392 00000 n -0000348418 00000 n -0000351903 00000 n -0000352032 00000 n -0000352290 00000 n -0000351548 00000 n -0000351727 00000 n -0000352483 00000 n -0000352547 00000 n -0000359497 00000 n -0000355669 00000 n -0000352763 00000 n -0000355795 00000 n -0000355860 00000 n -0000355925 00000 n -0000355990 00000 n -0000356055 00000 n -0000356120 00000 n -0000356185 00000 n -0000356250 00000 n -0000356315 00000 n -0000356380 00000 n -0000356510 00000 n -0000356575 00000 n -0000356640 00000 n -0000356705 00000 n -0000356770 00000 n -0000356835 00000 n -0000356900 00000 n -0000356965 00000 n -0000357030 00000 n -0000357095 00000 n -0000357160 00000 n -0000357225 00000 n -0000357290 00000 n -0000357355 00000 n -0000357420 00000 n -0000357485 00000 n -0000357550 00000 n -0000357615 00000 n -0000357680 00000 n -0000357745 00000 n -0000357810 00000 n -0000357875 00000 n -0000357940 00000 n -0000358005 00000 n -0000358069 00000 n -0000358134 00000 n -0000358199 00000 n -0000358264 00000 n -0000358329 00000 n -0000358394 00000 n -0000358459 00000 n -0000358524 00000 n -0000358589 00000 n -0000358654 00000 n -0000358719 00000 n -0000358784 00000 n -0000358849 00000 n -0000358914 00000 n -0000358979 00000 n -0000359044 00000 n -0000359109 00000 n -0000359174 00000 n -0000359239 00000 n -0000359304 00000 n -0000359369 00000 n -0000359433 00000 n -0000648434 00000 n -0000366143 00000 n -0000362579 00000 n -0000359609 00000 n -0000362705 00000 n -0000362770 00000 n -0000362835 00000 n -0000362900 00000 n -0000362965 00000 n -0000363030 00000 n -0000363095 00000 n -0000363160 00000 n -0000363225 00000 n -0000363290 00000 n -0000363355 00000 n -0000363420 00000 n -0000363484 00000 n -0000363549 00000 n -0000363614 00000 n -0000363679 00000 n -0000363744 00000 n -0000363809 00000 n -0000363874 00000 n -0000363939 00000 n -0000364004 00000 n -0000364069 00000 n -0000364134 00000 n -0000364199 00000 n -0000364263 00000 n -0000364328 00000 n -0000364393 00000 n -0000364458 00000 n -0000364523 00000 n -0000364588 00000 n -0000364653 00000 n -0000364718 00000 n -0000364783 00000 n -0000364848 00000 n -0000364913 00000 n -0000364978 00000 n -0000365043 00000 n -0000365108 00000 n -0000365173 00000 n -0000365238 00000 n -0000365302 00000 n -0000365366 00000 n -0000365430 00000 n -0000365495 00000 n -0000365560 00000 n -0000365625 00000 n -0000365690 00000 n -0000365755 00000 n -0000365820 00000 n -0000365885 00000 n -0000365950 00000 n -0000366015 00000 n -0000366079 00000 n -0000372318 00000 n -0000368880 00000 n -0000366255 00000 n -0000369006 00000 n -0000369071 00000 n -0000369136 00000 n -0000369201 00000 n -0000369266 00000 n -0000369331 00000 n -0000369396 00000 n -0000369461 00000 n -0000369526 00000 n -0000369591 00000 n -0000369656 00000 n -0000369721 00000 n -0000369786 00000 n -0000369851 00000 n -0000369916 00000 n -0000369981 00000 n -0000370046 00000 n -0000370111 00000 n -0000370176 00000 n -0000370241 00000 n -0000370306 00000 n -0000370371 00000 n -0000370436 00000 n -0000370501 00000 n -0000370566 00000 n -0000370631 00000 n -0000370696 00000 n -0000370761 00000 n -0000370826 00000 n -0000370891 00000 n -0000370956 00000 n -0000371021 00000 n -0000371086 00000 n -0000371151 00000 n -0000371215 00000 n -0000371280 00000 n -0000371345 00000 n -0000371410 00000 n -0000371475 00000 n -0000371540 00000 n -0000371605 00000 n -0000371670 00000 n -0000371735 00000 n -0000371800 00000 n -0000371865 00000 n -0000371930 00000 n -0000371995 00000 n -0000372060 00000 n -0000372125 00000 n -0000372190 00000 n -0000372254 00000 n -0000376897 00000 n -0000374633 00000 n -0000372430 00000 n -0000374759 00000 n -0000374824 00000 n -0000374889 00000 n -0000374954 00000 n -0000375019 00000 n -0000375084 00000 n -0000375149 00000 n -0000375214 00000 n -0000375279 00000 n -0000375344 00000 n -0000375409 00000 n -0000375474 00000 n -0000375539 00000 n -0000375604 00000 n -0000375666 00000 n -0000375730 00000 n -0000375795 00000 n -0000375859 00000 n -0000375924 00000 n -0000375989 00000 n -0000376054 00000 n -0000376119 00000 n -0000376184 00000 n -0000376249 00000 n -0000376314 00000 n -0000376443 00000 n -0000376572 00000 n -0000376637 00000 n -0000376702 00000 n -0000376767 00000 n -0000376832 00000 n -0000379664 00000 n -0000379020 00000 n -0000377022 00000 n -0000379146 00000 n -0000379275 00000 n -0000379404 00000 n -0000379469 00000 n -0000379534 00000 n -0000379599 00000 n -0000384149 00000 n -0000383828 00000 n -0000379776 00000 n -0000383954 00000 n -0000384019 00000 n -0000384084 00000 n -0000387400 00000 n -0000387144 00000 n -0000384301 00000 n -0000387270 00000 n -0000387335 00000 n -0000648559 00000 n -0000390650 00000 n -0000390459 00000 n -0000387538 00000 n -0000390585 00000 n -0000394430 00000 n -0000394174 00000 n -0000390775 00000 n -0000394300 00000 n -0000394365 00000 n -0000397604 00000 n -0000396829 00000 n -0000394568 00000 n -0000396955 00000 n -0000397020 00000 n -0000397085 00000 n -0000397150 00000 n -0000397215 00000 n -0000397344 00000 n -0000397409 00000 n -0000397474 00000 n -0000397539 00000 n -0000402075 00000 n -0000401884 00000 n -0000397742 00000 n -0000402010 00000 n -0000405203 00000 n -0000404430 00000 n -0000402213 00000 n -0000404556 00000 n -0000404621 00000 n -0000404686 00000 n -0000404750 00000 n -0000404879 00000 n -0000404944 00000 n -0000405008 00000 n -0000405073 00000 n -0000405138 00000 n -0000408593 00000 n -0000408337 00000 n -0000405341 00000 n -0000408463 00000 n -0000408528 00000 n -0000648684 00000 n -0000411453 00000 n -0000410743 00000 n -0000408731 00000 n -0000410869 00000 n -0000410934 00000 n -0000410999 00000 n -0000411064 00000 n -0000411193 00000 n -0000411258 00000 n -0000411323 00000 n -0000411388 00000 n -0000415132 00000 n -0000414876 00000 n -0000411604 00000 n -0000415002 00000 n -0000415067 00000 n -0000418569 00000 n -0000418313 00000 n -0000415257 00000 n -0000418439 00000 n -0000418504 00000 n -0000421040 00000 n -0000420332 00000 n -0000418707 00000 n -0000420458 00000 n -0000420523 00000 n -0000420588 00000 n -0000420715 00000 n -0000420780 00000 n -0000420845 00000 n -0000420910 00000 n -0000420975 00000 n -0000423926 00000 n -0000423152 00000 n -0000421191 00000 n -0000423278 00000 n -0000423343 00000 n -0000423408 00000 n -0000423473 00000 n -0000423601 00000 n -0000423666 00000 n -0000423731 00000 n -0000423796 00000 n -0000423861 00000 n -0000427282 00000 n -0000427091 00000 n -0000424064 00000 n -0000427217 00000 n -0000648809 00000 n -0000430235 00000 n -0000429525 00000 n -0000427407 00000 n -0000429651 00000 n -0000429716 00000 n -0000429781 00000 n -0000429846 00000 n -0000429975 00000 n -0000430040 00000 n -0000430105 00000 n -0000430170 00000 n -0000433534 00000 n -0000433278 00000 n -0000430386 00000 n -0000433404 00000 n -0000433469 00000 n -0000436418 00000 n -0000436034 00000 n -0000433727 00000 n -0000436160 00000 n -0000436225 00000 n -0000436290 00000 n -0000436354 00000 n -0000439896 00000 n -0000439186 00000 n -0000436650 00000 n -0000439312 00000 n -0000439377 00000 n -0000439442 00000 n -0000439571 00000 n -0000439636 00000 n -0000439701 00000 n -0000439766 00000 n -0000439831 00000 n -0000443031 00000 n -0000442322 00000 n -0000440047 00000 n -0000442448 00000 n -0000442513 00000 n -0000442578 00000 n -0000442642 00000 n -0000442771 00000 n -0000442836 00000 n -0000442901 00000 n -0000442966 00000 n -0000446214 00000 n -0000445958 00000 n -0000443195 00000 n -0000446084 00000 n -0000446149 00000 n -0000648934 00000 n -0000448960 00000 n -0000448317 00000 n -0000446339 00000 n -0000448443 00000 n -0000448508 00000 n -0000448573 00000 n -0000448638 00000 n -0000448766 00000 n -0000448831 00000 n -0000448896 00000 n -0000452693 00000 n -0000452373 00000 n -0000449111 00000 n -0000452499 00000 n -0000452564 00000 n -0000452629 00000 n -0000454018 00000 n -0000453632 00000 n -0000452818 00000 n -0000453758 00000 n -0000453823 00000 n -0000453888 00000 n -0000453953 00000 n -0000454189 00000 n -0000465533 00000 n -0000467856 00000 n -0000467825 00000 n -0000477345 00000 n -0000487401 00000 n -0000497639 00000 n -0000509844 00000 n -0000527977 00000 n -0000550065 00000 n -0000571075 00000 n -0000588893 00000 n -0000591724 00000 n -0000591494 00000 n -0000618982 00000 n -0000646091 00000 n -0000649041 00000 n -0000649164 00000 n -0000649290 00000 n -0000649416 00000 n -0000649506 00000 n -0000649598 00000 n -0000664889 00000 n -0000682155 00000 n -0000682196 00000 n -0000682236 00000 n -0000682370 00000 n -trailer -<< -/Size 1948 -/Root 1946 0 R -/Info 1947 0 R -/ID [ ] ->> -startxref -682634 -%%EOF diff --git a/contrib/bind9/doc/arm/Makefile.in b/contrib/bind9/doc/arm/Makefile.in deleted file mode 100644 index 85f318d..0000000 --- a/contrib/bind9/doc/arm/Makefile.in +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 2001, 2002 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: Makefile.in,v 1.12.18.8 2007/08/28 07:20:03 tbox Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -@BIND9_MAKE_RULES@ - -@BIND9_VERSION@ - -MANOBJS = Bv9ARM.html - -PDFOBJS = Bv9ARM.pdf - -doc man:: ${MANOBJS} ${PDFOBJS} - -clean:: - rm -f Bv9ARM.aux Bv9ARM.brf Bv9ARM.glo Bv9ARM.idx Bv9ARM.toc - rm -f Bv9ARM.log Bv9ARM.out Bv9ARM.tex Bv9ARM.tex.tmp - -docclean manclean maintainer-clean:: clean - rm -f *.html ${PDFOBJS} - -docclean manclean maintainer-clean distclean:: - rm -f releaseinfo.xml - -Bv9ARM.html: Bv9ARM-book.xml releaseinfo.xml - expand Bv9ARM-book.xml | \ - ${XSLTPROC} --stringparam root.filename Bv9ARM \ - ${top_srcdir}/doc/xsl/isc-docbook-chunk.xsl - - -Bv9ARM.tex: Bv9ARM-book.xml releaseinfo.xml - expand Bv9ARM-book.xml | \ - ${XSLTPROC} ${top_srcdir}/doc/xsl/pre-latex.xsl - | \ - ${XSLTPROC} ${top_srcdir}/doc/xsl/isc-docbook-latex.xsl - | \ - @PERL@ latex-fixup.pl >$@.tmp - if test -s $@.tmp; then mv $@.tmp $@; else rm -f $@.tmp; exit 1; fi - -Bv9ARM.dvi: Bv9ARM.tex releaseinfo.xml - rm -f Bv9ARM-book.aux Bv9ARM-book.dvi Bv9ARM-book.log - ${LATEX} '\batchmode\input Bv9ARM.tex' || (rm -f $@ ; exit 1) - ${LATEX} '\batchmode\input Bv9ARM.tex' || (rm -f $@ ; exit 1) - ${LATEX} '\batchmode\input Bv9ARM.tex' || (rm -f $@ ; exit 1) - -Bv9ARM.pdf: Bv9ARM.tex releaseinfo.xml - rm -f Bv9ARM-book.aux Bv9ARM-book.pdf Bv9ARM-book.log - ${PDFLATEX} '\batchmode\input Bv9ARM.tex' || (rm -f $@ ; exit 1) - ${PDFLATEX} '\batchmode\input Bv9ARM.tex' || (rm -f $@ ; exit 1) - ${PDFLATEX} '\batchmode\input Bv9ARM.tex' || (rm -f $@ ; exit 1) - -releaseinfo.xml: - echo >$@ 'BIND Version ${VERSION}' diff --git a/contrib/bind9/doc/arm/README-SGML b/contrib/bind9/doc/arm/README-SGML deleted file mode 100644 index e33c937..0000000 --- a/contrib/bind9/doc/arm/README-SGML +++ /dev/null @@ -1,329 +0,0 @@ -Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -Copyright (C) 2000, 2001 Internet Software Consortium. -See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. - -The BIND v9 ARM master document is now kept in DocBook XML format. - -Version: $Id: README-SGML,v 1.17 2004/03/05 05:04:43 marka Exp $ - -The entire ARM is in the single file: - - Bv9ARM-book.xml - -All of the other documents - HTML, PDF, etc - are generated from this -master source. - -This file attempts to describe what tools are necessary for the -maintenance of this document as well as the generation of the -alternate formats of this document. - -This file will also spend a very little time describing the XML and -SGML headers so you can understand a bit what you may need to do to be -able to work with this document in any fashion other than simply -editing it. - -We will spend almost no time on the actual tags and how to write an -XML DocBook compliant document. If you are at all familiar with SGML -or HTML it will be very evident. You only need to know what the tags -are and how to use them. You can find a good resource either for this -either online or in printed form: - - DocBook: The Definitive Guide - By Norman Walsh and Leonard Muellner - ISBN: 156592-580-7 - 1st Edition, October 1999 - Copyright (C) 1999 by O'Reilly & Associates, Inc. All rights reserved. - -The book is available online in HTML format: - - http://docbook.org/ - -and buried in: - - http://www.nwalsh.com/docbook/defguide/index.html - -A lot of useful stuff is at NWalsh's site in general. You may also -want to look at: - - http://www.xml.com/ - -The BIND v9 ARM is based on the XML 4.0 DocBook DTD. Every XML and -SGML document begins with a prefix that tells where to find the file -that describes the meaning and structure of the tags used in the rest -of the document. - -For our XML DocBook 4.0 based document this prefix looks like this: - - - -This "DOCTYPE" statement has three parts, of which we are only using -two: - -o The highest level term that represents this document (in this case - it is "book" - -o The identifier that tells us which DTD to use. This identifier has - two parts, the "Formal Public Identifier" (or FPI) and the system - identifier. In SGML you can have either a FPI or a SYSTEM identifier - but you have to have at least one of them. In XML you have to have a - SYSTEM identifier. - -FP & SYSTEM identifiers - These are names/lookups for the actual -DTD. The FPI is a globally unique name that should, on a properly -configured system, tell you exactly what DTD to use. The SYSTEM -identifier gives an absolute location for the DTD. In XML these are -supposed to be properly formatted URL's. - -SGML has these things called "catalogs" that are files that map FPI's -in to actual files. A "catalog" can also be used to remap a SYSTEM -identifier so you can say something like: "http://www.oasis.org/foo" -is actually "/usr/local/share/xml/foo.dtd" - -When you use various SGML/XML tools they need to be configured to look -at the same "catalog" files so that as you move from tool to tool they -all refer to the same DTD for the same document. - -We will be spending most of our configuration time making sure our -tools use the same "catalog" files and that we have the same DTD's -installed on our machines. XML's requirement of the SYSTEM identifier -over the FPI will probably lead to more problems as it does not -guarantee that everyone is using the same DTD. - -I did my initial work with the "sgmltools" the XML 4.0 DocBook DTD and -"jade" or "openjade." - -You can get the 4.0 XML DocBook DTD from: - - http://www.docbook.org/xml/4.0/ - -(download the .zip file.) NOTE: We will eventually be changing the -SYSTEM identifier to the recommended value of: - - http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd - -NOTE: Under FreeBSD this is the package: - - /usr/ports/textproc/docbook-xml - -NetBSD instructions are coming soon. - -With packages listed below installed under FreeBSD the "catalog" file -that all the tools refer to at least one is in: - - /usr/local/share/sgml/catalog - -In order for our SYSTEM identifier for the XML DocBook dtd to be found -I create a new catalog file at the top of the XML directory created on -FreeBSD: - - /usr/local/share/xml/catalog - -This file has one line: - - SYSTEM "http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd" "/usr/local/share/xml/dtd/docbook/docbookx.dtd" - -Then in the main "catalog" I have it include this XML catalog: - - CATALOG "/usr/local/share/xml/catalog" - - -On your systems you need to replace "/usr/local/share" with your -prefix root (probably /usr/pkg under NetBSD.) - -NOTE: The URL used above is supposed to the be the proper one for this -XML DocBook DTD... but there is nothing at that URL so you really do -need the "SYSTEM" identifier mapping in your catalog (or make the -SYSTEM identifier in your document refer to the real location of the -file on your local system.) - -HOW TO VALIDATE A DOCUMENT: - -I use the sgmltools "nsgmls" document validator. Since we are using -XML we need to use the XML declarations, which are installed as part -of the modular DSSL style sheets: - - nsgmls -sv /usr/local/share/sgml/docbook/dsssl/modular/dtds/decls/xml.dcl \ - Bv9ARM-book.xml - -A convenient shell script "validate.sh" is now generated by configure -to invoke the above command with the correct system-dependent paths. - -The SGML tools can be found at: - - ftp://ftp.us.sgmltools.org/pub/SGMLtools/v2.0/source/ \ - ftp://ftp.nllgg.nl/pub/SGMLtools/v2.0/source/ - -FreeBSD package for these is: - - /usr/ports/textproc/sgmltools - -HOW TO RENDER A DOCUMENT AS HTML or TeX: - -o Generate html doc with: - - openjade -v -d ./nominum-docbook-html.dsl \ - -t sgml \ - /usr/local/share/sgml/docbook/dsssl/modular/dtds/decls/xml.dcl \ - Bv9ARM-book.xml - -A convenient shell script "genhtml.sh" is now generated by configure to -invoke the above command with the correct system-dependent paths. - -On NetBSD there is no port for "openjade" however "jade" does still -work. However you need to specify the "catalog" file to use for style -sheets on the command line AND you need to have a default "catalog" -mapping where to find various DTDs. It seems that "jade" installed out -of the box on NetBSD does not use a globally defined "catalog" file -for mapping PUBLIC identifiers in to SYSTEM identifiers. - -So you need to have a "catalog" file in your current working directory -that has in it this: (these are probably more entries than you need!) - - CATALOG "/usr/pkg/share/sgml/iso8879/catalog" - CATALOG "/usr/pkg/share/sgml/docbook/2.4.1/catalog" - CATALOG "/usr/pkg/share/sgml/docbook/3.0/catalog" - CATALOG "/usr/pkg/share/sgml/docbook/3.1/catalog" - CATALOG "/usr/pkg/share/sgml/jade/catalog" - CATALOG "/usr/local/share/xml/catalog" - -(These would all be "/usr/local" on FreeBSD) - -So the command for jade on NetBSD will look like this: - -jade -v -c /usr/pkg/share/sgml/catalog -t sgml \ - -d ./nominum-docbook-html.dsl \ - /usr/pkg/share/sgml/docbook/dsssl/modular/dtds/decls/xml.dcl \ - ./Bv9ARM-book.xml - -Furthermore, since the style sheet subset we define has in it a hard -coded path to the style sheet is based, it is actually generated by -configure from a .in file so that it will contain the correct -system-dependent path: where on FreeBSD the second line reads: - - - -On NetBSD it needs to read: - - - -NOTE: This is usually solved by having this style sheet modification -be installed in a system directory and have it reference the style -sheet it is based on via a relative path. - -o Generate TeX documentation: - -openjade -d ./nominum-docbook-print.dsl -t tex -v \ - /usr/local/share/sgml/docbook/dsssl/modular/dtds/decls/xml.dcl \ - Bv9ARM-book.xml - -If you have "jade" installed instead of "openjade" then use that as -the command. There is little difference, openjade has some bug fixes -and is in more active development. - -To convert the resulting TeX file in to a DVI file you need to do: - - tex "&jadetex" Bv9ARM-book.tex - -You can also directly generate the pdf file via: - - pdftex "&pdfjadetex" Bv9ARM-book.tex - -The scripts "genpdf.sh" and "gendvi." have been added to simply -generating the PDF and DVI output. These substitute the correct paths -of NetBSD & FreeBSD. You still need to have TeX, jadeTeX, and pdfTeX -installed and configured properly for these to work. - -You will need to up both the "pool_size" and "hash_extra" variables in -your texmf.cnf file and regenerate them. See below. - -You can see that I am using a DSSSL style sheet for DocBook. Actually -two different ones - one for rendering html, and one for 'print' -media. - -NOTE: For HTML we are using a Nominum DSSSL style instead of the -default one (all it does is change the chunking to the chapter level -and makes the files end with ".html" instead of ".htm" so far.) If you -want to use the plain jane DSSSL style sheet replace the: - - -d ./nominum-docbook-html.dsl - -with - - -d /usr/local/share/sgml/docbook/dsssl/modular/html/docbook.dsl - -This style sheet will attempt to reference the one above. - -I am currently working on fixing these up so that it works the same on -our various systems. The main trick is knowing which DTD's and DSSSL -stylesheets you have installed, installing the right ones, and -configuring a CATALOG that refers to them in the same way. We will -probably end up putting our CATALOG's in the same place and then we -should be able to generate and validate our documents with a minimal -number of command line arguments. - -When running these commands you will get a lot of messages about a -bunch of general entities not being defined and having no default -entity. You can ignore those for now. - -Also with the style sheets we have and jade as it is you will get -messages about "xref to title" being unsupported. You can ignore these -for now as well. - -=== Getting the various tools installed on FreeBSD -(NetBSD coming soon..) - -o On freebsd you need to install the following packages: - o print/teTeX - o textproc/openjade - o textproc/docbook - o textproc/docbook-xml - o textproc/dsssl-docbook-modular - o textproc/dtd-catalogs - -o on freebsd you need to make some entities visible to the docbook xml - dtd by making a symlink (can probably be done with a catalog too) - ln -s /usr/local/share/xml/entity /usr/local/share/xml/dtd/docbook/ent - -o you may need to edit /usr/local/share/sgml/catalog and add the line: - - CATALOG "/usr/local/share/sgml/openjade/catalog" - -o add "hugelatex," Enlarge pool sizes, install the jadetex TeX driver - file. - - cd /usr/local/share/texmf/web2c/ - sudo cp texmf.cnf texmf.cnf.bak - - o edit the lines in texmf.cnf with these keys to these values: - - main_memory = 1100000 - hash_extra = 15000 - pool_size = 500000 - string_vacancies = 45000 - max_strings = 55000 - pool_free = 47500 - nest_size = 500 - param_size = 1500 - save_size = 5000 - stack_size = 1500 - - sudo tex -ini -progname=hugelatex -fmt=hugelatex latex.ltx - sudo texconfig init - sudo texhash - - o For the jadetex macros you will need I recommend you get a more - current version than what is packaged with openjade or jade. - - Checkout http://www.tug.org/applications/jadetex/ - - Unzip the file you get from there (should be jadetex-2.20 or - newer.) - - In the directory you unzip: - - sudo make install - sudo texhash - - NOTE: In the most uptodate "ports" for FreeBSD, jadetext is 2.20+ - so on this platform you should be set as of 2001.01.08. diff --git a/contrib/bind9/doc/arm/isc-logo.eps b/contrib/bind9/doc/arm/isc-logo.eps deleted file mode 100644 index c6a1d7a..0000000 --- a/contrib/bind9/doc/arm/isc-logo.eps +++ /dev/null @@ -1,12253 +0,0 @@ -%!PS-Adobe-3.1 EPSF-3.0 -%%Title: Alternate-ISC-logo-v2.ai -%%Creator: Adobe Illustrator(R) 11 -%%AI8_CreatorVersion: 11.0.0 -%AI9_PrintingDataBegin -%%For: Douglas E. Appelt -%%CreationDate: 10/22/04 -%%BoundingBox: 0 0 255 149 -%%HiResBoundingBox: 0 0 254.8672 148.7520 -%%CropBox: 0 0 254.8672 148.7520 -%%LanguageLevel: 2 -%%DocumentData: Clean7Bit -%%Pages: 1 -%%DocumentNeededResources: -%%DocumentSuppliedResources: procset Adobe_AGM_Image (1.0 0) -%%+ procset Adobe_CoolType_Utility_T42 (1.0 0) -%%+ procset Adobe_CoolType_Utility_MAKEOCF (1.19 0) -%%+ procset Adobe_CoolType_Core (2.23 0) -%%+ procset Adobe_AGM_Core (2.0 0) -%%+ procset Adobe_AGM_Utils (1.0 0) -%%DocumentFonts: -%%DocumentNeededFonts: -%%DocumentNeededFeatures: -%%DocumentSuppliedFeatures: -%%DocumentProcessColors: Cyan Magenta Yellow Black -%%DocumentCustomColors: (PANTONE 1805 C) -%%+ (PANTONE 871 C) -%%+ (PANTONE 301 C) -%%+ (PANTONE 7506 C) -%%CMYKCustomColor: 0 0.9100 1 0.2300 (PANTONE 1805 C) -%%+ 0.3569 0.3608 0.6353 0.1882 (PANTONE 871 C) -%%+ 1 0.4500 0 0.1800 (PANTONE 301 C) -%%+ 0 0.0500 0.1500 0 (PANTONE 7506 C) -%%RGBCustomColor: -%ADO_ContainsXMP: MainFirst -%AI7_Thumbnail: 128 76 8 -%%BeginData: 10692 Hex Bytes -%0000330000660000990000CC0033000033330033660033990033CC0033FF -%0066000066330066660066990066CC0066FF009900009933009966009999 -%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 -%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 -%3333663333993333CC3333FF3366003366333366663366993366CC3366FF -%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 -%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 -%6600666600996600CC6600FF6633006633336633666633996633CC6633FF -%6666006666336666666666996666CC6666FF669900669933669966669999 -%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 -%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF -%9933009933339933669933999933CC9933FF996600996633996666996699 -%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 -%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF -%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 -%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 -%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF -%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC -%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 -%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 -%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 -%000011111111220000002200000022222222440000004400000044444444 -%550000005500000055555555770000007700000077777777880000008800 -%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB -%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF -%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF -%524C45FD1CF852FD63FFF820272726272727264B27272627272726272727 -%26272727264B20F827FD63FFF827FFFFFFCFFF84365AFFFFFFCFFFFFFFCF -%FFFFFFCFFD04FFCAF852FD63FFF827CFCFCACFCA2F0607A8CFCACFCACFCA -%CFCACFCACFCACFCACF7CF827FD63FFF800FFCFFFA8A8070D06A8CFFFCFFF -%CFFFCFFFCFFFCFFFCFFFCFA7F852FD63FFF800077E2F0D060D060706537D -%CF7D2FA8CFCACFCACFCACFCAFF7CF827FD63FFF8000D062F070D062F070D -%062F2F0D062FCACFCFFFCFCFCFFFCFA1F852FD63FFF8050707062E517651 -%522807060706072ECFCACFCACFCACFCAFF7CF827FD63FFF8002F067C757B -%757C757B512F072F2FFFCFCFCFFFCFFFCFFFCFA1F852FD63FFF805075251 -%75517551755175512F062FCACFCACFCACFCACFCAFF7CF827FD63FFF8F859 -%75765176757C517C757B2E2F07A8CFFFCFCFCFFFCFCFCFA1F852FD63FFF8 -%00517551757CCFCAA751755175060753CFCACFCACFCACFCACF7CF827FD63 -%FFF8F87C75757CFFCFFFCFA7517C752F072F59A8CFCFCFFFCFFFCFA7F852 -%FD04FFA87D527DA8FD5AFFF827757551A1CFCFCAFFA0755175280D060706 -%A8CFCFCACFCAFF7CF827FD05FF27F827FD5BFFF8F87C51767CFFCFFFCFA0 -%517C752F062F060D84FFCFFFCFFFCFA1F852FD05FF7DF87DFD5BFFF80552 -%7551757CC9A7A05175517606072F7E7DCFCACFC9CFCAFF6FF827FD05FF52 -%F852FD27FFA8FD33FFF80059757C7575517C517C517C2E2F06CFCFFFCFCF -%9293CAFFCF6FF852FD05FF7DF87DFD04FFA8FD05FF7D7DA8FF527D7D7D52 -%7D52A8FFA8527D527DA8FF7D7D527D52FD05FFA8FD05FFA87D7DFFFFA852 -%7D527DA8FF527D7D7D527D52A8FD19FFF805075275755175517551752D0D -%0653CFFFCFFFA78C6899939344F827FD05FF52F852FFFFFFA8F87DFD04FF -%7D27FFA87D7DA8F827A87D7DFFA8F827A8527DFFA8F852A827F8A8FFFFFF -%7DF8FD05FF2752FFFFA8F827A8527DA87D7DA8F827A87D7DFD19FFF8F82F -%0752517C757B757C2E0D062FA8C999CFCFC28C928C8C8C6EF852FD05FF7D -%F87DFD04FFF8F87DFFFFFF7D52FD05FFF852FD05FFF87DFD05FFF852FFFF -%F852FFFFFF7DF8F8FD04FF7D52FFFFFFF87DFD07FFF852FD1CFFF8000607 -%062F2852282E060D0607067D928C9293688C6892688C44F827FD05FF52F8 -%52FFFFFFA85252F852FFFF7D27FD05FFF87DFD04FFA8F852FD05FFF852FF -%FFF8A8FFFFFF7D5227F8A8FFFF527DFFFFA8F852FD07FFF87DFD1CFFF800 -%852F2F062F070D062F072F062F0D9A8C928C928C928C928C6EF852FD05FF -%7DF87DFD04FF27FF52F852FF7D52FD05FFF852FD05FFF82752527DFFFFF8 -%52FF527DFD04FF527DFF27F8A8FF7D7DFFFFFFF82752527DFD04FFF852FD -%1CFFF827CFCF7D2F060D062F2F7EA82F062F938C68928C8C68926E994AF8 -%27FD05FF52F852FFFFFFA827FFFF52F852A852FD05FFF87DFD04FFA8F852 -%FF7DA8FFFFF82752F8A8FD04FF7D52FFA827F8A87D7DFFFFA8F852FF7DA8 -%FD04FFF87DFD1CFFF827FFCFFFA80D062FA8CFCFCA927693928C928C9292 -%75517C7B51F852FD05FF7DF87DFFFFFFA827FFFFFF52F8F87DFD05FFF852 -%FD05FFF87DFD05FFF852FF52F8A8FFFFFF5252FFFFFF27F8277DFFFFFFF8 -%7DFD07FFF852FD1CFFF827CFCFCACF06062ECFCAFF928C688C6892688C6E -%765175517C26F827FD05FF52F852FFFFFFA827FD04FF52F852FD05FFF852 -%FD04FFA8F852FFFFA8A8FFF87DFFFFF8F8A8FFFF5227FD04FF27F8A8FFFF -%A8F852FFFFA8A8FFFFFFF852FD1CFFF827FFCFFFCF7E53A8CFFFCFC99292 -%8C928C92757C757C517C7551F852FD04FFA852F852A8FFFFA8F8A8FD04FF -%527DFD04FF7DF827FD04FFA8F827525252FF7DF827FFFFFF2727A8FF5227 -%A8FD04FF52A8FFFFA8F827525252FFFFFF7DF827FD1CFFF827CFCFCACFCF -%CFCAFD04CF93688C688C6F7651755175517C4BF827FD05FFA8FFA8FFFFFF -%A8FFA8FD0BFFA8FFA8FFFFFFA8FFA8A8A8FFFFFFA8FFA8FFFFFFA8FFA8FF -%A8FD09FFA8FFA8A8A8FD05FFA8FFA8FD1BFFF827FFCFCFCFFFCFCFCFFFCF -%C38C928C8C6E7C7576517C75767551F852FD63FFF827CFCFCACFCACFCACF -%92928C8C688C6875517551755175517526F827FD63FFF827FFCFFFCFFFCF -%FFCA938C928C928C99517C757C517C757C7551F852FD63FFF827CFCFCACF -%CACFCACFA093688C6892757551755175517551754BF827FD63FFF827FFCF -%FFCFCFCFFFCFFF998C8C926E7C7576517C7576517CA7A1F852FD06FFA87D -%527DA8FD58FFF827CFCFCACFCACFCAFFCF996892686F5175517551755175 -%7CFF7CF827FD05FF7D2752A82727A8FD57FFF827FFCFFFCFFFCFFFC2BB8C -%928C8C6E7C757C517C757C51CFFFA1F852FD05FF2752FFFFFF52FD58FFF8 -%27CFCFCACFCACFCF99688C68928C6F5175517551755175CAFF7CF827FD04 -%FFA8F852FD5CFFF827FFCFCFCFFFCFFFA0998C928C926E7C517C7576517C -%51CACFA1F852FD04FFA827F87DFFFFFFA8527DFD04FF527DFFFFA87D52A8 -%FF7D527D527D527D7DFF7D7D527D527DFFFFFFA8FD06FFA8FD04FFA87D7D -%7DFD26FFF827CFCFCACFCACFCACFCF99688C6893517551755175517575FF -%7CF827FD05FF52F8F852FFFFFF52F8A8FFFF7D27A8FF5252A8A852A852A8 -%7DF827A87D7DFFA8F852A87D52FFFFFFF8A8FD04FF5227FFFFFF7D27A8A8 -%52A8FD25FFF827FFCFFFCFFFCFFFCFFFA08C8C92927C517C757C517C7575 -%7C7CF852FD06FF52F8F852FFFFFF27F8FFFF52A8FFFFF87DFD07FFF87DFD -%05FFF852FD06FFF827FD04FF2727FFFFFF2752FD29FFF827CFCFCACFCACF -%CACFA799688C68927575517551755175517526F84BFD07FF52F8F87DFFFF -%A8F87D7D52FFFFFFF8F87DFD05FFA8F852FD05FFF87DFD05FFA8F8F8A8FF -%FF7DF8F8A8FFFF52F852A8FD27FFF827FFCFFFCFCFCFFFCF9368928C928C -%995176517C7576517C7551F852FD08FF7DF8F8FFFFFF52F827FD05FFF8F8 -%27FD05FFF87DFD05FFF8277D527DFFFF7D52F852FFFF277DF8A8FFFFFF52 -%F8F87DFD26FFF827CFCFCACFCACFCAFF938C688C688C6875517551755175 -%517C26F827FD09FF27F8A8FFFFFFF852FD06FF52F827FFFFFFA8F852FD05 -%FFF852A8A87DFFFF527D7DF8FF7D52A8F87DFD04FF7DF8F8A8FD25FFF827 -%FFCFFFCFFFCFFFCFCFCFC98C928C92927C517C757C517C7551F852FD04FF -%7DFD04FF7DF8FD04FFF852FD07FF7DF8A8FFFFFFF87DFD05FFF852FD05FF -%52A8FF272752A8FFF87DFD06FFF8A8FD25FFF827CFCFCACFCACFCAFD04CF -%99688C688C6E7651755175517C4BF827FD04FF5227FFFFA8F852FD04FFF8 -%7DFFFFFF7D7DFFFF7D27FD04FFF852FD05FFF852FFFFA8FFFF27A8FF7DF8 -%52FFFFF852FFA852FFFF7D27A8FD25FFF827FFCFCFCFFFCFCFCFFFCFCF92 -%928C928C926E7C517C75767551F852FD04FF7D272752277DFD04FF7DF827 -%FFFFFF7D27525227FD04FFA8F852A8FFFFFF7D2727525252FFA8F8A8FFFF -%52FFFFFF2727A8FF275252527DFD26FFF827CFCFCACFCACFCACFCAFF998C -%688C688C688C68755176517526F827FD07FFA8FD07FFA8FFA8FFFFFFA8A8 -%A8FD05FFA8FFA8FD05FFA8FFA8A8A8FFA8FFA8FD07FFA8FFFFFFA8A8FD28 -%FFF827FFCFFFCFFFCFFFCFFFCFCF92C29A928C928C928C99757C7551F852 -%FD63FFF827CFCFCACFCACFCACFCAFD04CFFF998C68928C8C6892689344F8 -%27FD63FFF827FFCFFFCFCFCFFFCFCFCFFFCFCFCFC98C928C928C928C928C -%68F852FD63FFF827CFCFCACFCACFCAA8537ECACFCAFF938C6899688C688C -%689244F827FD63FFF827FFCFFFCFFFCFA8072F07FFCFFFCFCF992F0D5992 -%928C928C68F852FD08FF7D7D527D52A8A8FD54FFF827CFCFCACFCACFA70D -%060753A87DA8CA5A0607069368929AC244F827FD06FF7DF8527D7D7D52F8 -%27FD54FFF827FFCFCFCFFFCFCF2F2F070D062F072F062F07539993C2FFFF -%76F852FD05FF7DF87DFD06FF27FD54FFF827CFCFCACFCACF7D0D060D0607 -%060D0607060753FFCACFCAFF76F827FD04FFA8F827FD07FFA8A8FD15FFA8 -%FD3DFFF827FFCFFFCFFF592F062F072F2852282F072F072F7DFFCFFFCFA7 -%F852FD04FF52F87DFD0CFFA87D7D7DFD05FFA8FD05FF7D7DA8FFFFA87D7D -%7DFFFFFFA87D527D7DFD04FFA8527D527DA8FFFF7D527D527D527D7DFF7D -%7D7DFFFFA8527DA8FFFFA8527DFFFFFFA8FD06FFA8FFFFF827CF5959CA53 -%07060D066F688C6892684B060D06077DCFCFCF7CF827FD04FF27F8A8FD0A -%FFA82752A87D52F852FFFFA8F87DFD04FF7D27FFFF7D27A87D52FFFF5227 -%7DA87D27F8A8FFFFA8F827A827F8A8A852A87DF827A87D7DFFA8F852FFFF -%A8F827FD04FF2727FFFFFFF8A8FD04FF5227FFFFF827A9062F070D062F28 -%928C928C928C928C92282F072F847E5953F852FD04FFF8F8A8FD0AFF2752 -%FD04FF7DF87DFFFFF8F852FFFFFF7D52FFFFF8A8FFFFA8FF7DF8A8FD04FF -%27F8FFFFFFF87DFFFFF87DFD04FFF87DFD05FFF852FFFFFFF87DFD04FF27 -%52FFFFFFF827FD04FF2727FFFFF8272F07060D060D278C688C68928C8C68 -%8C688C060D0607060D06F827FFFFFFA827F87DFD09FF7DF8FD06FF27F8FF -%A85252F852FFFF7D27FFFF27F87DFFFFFF2727FD05FF7DF852FFA8F852FF -%A8F87DFFFFFFA8F852FD05FFF852FFFFA8F852FD04FF5252FFFFA8F8F8A8 -%FFFF7DF827A8FFF827FF2F2F070D06938C928CBCC9CFC9BB8C928C6F070D -%062F0706F852FD04FF27F852FD09FF52F8FD06FF52F8FFFF27FF52F852FF -%7D52FFFFA827F827A8FFF852FD06FFF852FFFFF852FF7D7DFD05FFF87DFD -%05FFF852FFFFFFF87DFD04FF2752FFFF7D52F852FFFF277DF8A8FFF827CF -%CF2F0D064C689268C2CFFFCFFFCFC2688C682E0607062F52F827FD04FF7D -%F8F8A8FD08FF52F8A8FD05FF52F8FFA827FFFF52F852A852FD04FF7DF827 -%FF2727FD05FFA8F852FFA8F82752F8A8FD04FFA8F852FD05FFF852FFFFA8 -%F852FD04FF5252FFFF7D7D7DF8FF7D52A8F87DFFF827FFCF59062F6F8C8C -%99CFFFCFFFCFFFCF938C8C4B2F0759CFA7F852FD05FF52F827FD06FF7DFF -%A8F852FD05FFF852FFA827FFFFFF52F8F87DFD05FF7DF8FF52F8A8FD04FF -%A8F8A8FFFFF87DFF52F8FD05FFF87DFD05FFF852FFFFFFF852FD04FF277D -%FFFF27A8FF272752FFFFF87DFFF827CFCF2F070693688C99FFCACFCACFCA -%FF998C686F060759CF7CF827FD05FFA852F8F87DFFFFFF5227FFFF52F87D -%FFFFFF5227A8FFA827FD04FF52F852FF527DFFFF5227FFFFF827A8FFFFFF -%2752FFFFFFF852FFFF27F8FFFFFFA8F852FD05FFF87DFFFFFF52F8A8FFFF -%7D27A8FFFF27A8FF7DF852FFFFF827FFF827FFCF53062F6E928CC2FFFFCF -%FFCFFFCFC28C926F2F077ECFA7F852FD07FFA8FD06277DFFFFFF7D27277D -%527DFFFFFF7DF8A8FD04FF527DFFA827525252A8FFFFFF5227527D52A8FF -%FFFFA8F852A8FFA82727A8FFA8F852A8FFFFFF7DF827FD04FF52277D5252 -%A8FFFFA8F8A8FFFF52FFFFFF2727A8F827CFCF2F07066F8C8C92FFCFCFCA -%CFCFCF8C8C8C4B060D59CF7CF827FD0BFFA8FD09FFA8FD05FFA8FFA8FD09 -%FFA8A8FD07FFA8A8FD05FFA8FFA8FD05FFA8FFA8FFA8FD05FFA8FFA8FD05 -%FFA8FD05FFA8FFA8FD07FFA8FFF827AF2F2F070D4B928C8CA0FFCFFFCFFF -%998C8C92280D067ECFA1F852FD63FFF8270707060D0607688C688C99C9CA -%C9938C688C680D0607065A76F827FD63FFF8275A062F070D07528C928C92 -%8C928C928C928C2F070D062F072EF852FD63FFF84B842F597E0607064C8C -%8C68928C8C688C6828060D0607060D52F827FD63FFF827FFCFCFCF7E060D -%062F6F928C928C934B2F070D0684A85A59A1F852FD63FFF827CFCFCACFCA -%590607060D06282728060D0607067ECACFCFCF7CF827FD63FFF827FFCFFF -%CFFFCF59062F070D072F070D062F2FA8CFFFCFFFCFA7F852FD63FFF827CF -%CFCACFCACF2F07060D0607060D06070653CFCFCACFCAFF7CF827FD63FFF8 -%27FFCFFFCFCFA82F070D59CFA8A8A859060D07FD04CFFFCFA1F852FD63FF -%F827CFCFCACFCFA82F0D2FCFCACFCFCFA80D060DA8CFCACFCAFF7CF827FD -%63FFF827FFCFFFCFFFCFFFA8FFCFFFCFFFCFFF7E7EA8FFCFFFCFFFFFA7F8 -%52FD63FFFD09F820FD07F820FD07F820F8F827FD63FF27F827F820F827F8 -%20F827F820F827F820F827F820F827F820F827F87CFDE2FFFF -%%EndData -%%EndComments -%%BeginDefaults -%%ViewingOrientation: 1 0 0 1 -%%EndDefaults -%%BeginProlog -%%BeginResource: procset Adobe_AGM_Utils 1.0 0 -%%Version: 1.0 0 -%%Copyright: Copyright (C) 2000-2003 Adobe Systems, Inc. All Rights Reserved. -systemdict /setpacking known -{ - currentpacking - true setpacking -} if -userdict /Adobe_AGM_Utils 68 dict dup begin put -/bdf -{ - bind def -} bind def -/nd{ - null def -}bdf -/xdf -{ - exch def -}bdf -/ldf -{ - load def -}bdf -/ddf -{ - put -}bdf -/xddf -{ - 3 -1 roll put -}bdf -/xpt -{ - exch put -}bdf -/ndf -{ - exch dup where{ - pop pop pop - }{ - xdf - }ifelse -}def -/cdndf -{ - exch dup currentdict exch known{ - pop pop - }{ - exch def - }ifelse -}def -/bdict -{ - mark -}bdf -/edict -{ - counttomark 2 idiv dup dict begin {def} repeat pop currentdict end -}def -/ps_level - /languagelevel where{ - pop systemdict /languagelevel get exec - }{ - 1 - }ifelse -def -/level2 - ps_level 2 ge -def -/level3 - ps_level 3 ge -def -/ps_version - {version cvr} stopped { - -1 - }if -def -/makereadonlyarray -{ - /packedarray where{ - pop packedarray - }{ - array astore readonly - }ifelse -}bdf -/map_reserved_ink_name -{ - dup type /stringtype eq{ - dup /Red eq{ - pop (_Red_) - }{ - dup /Green eq{ - pop (_Green_) - }{ - dup /Blue eq{ - pop (_Blue_) - }{ - dup () cvn eq{ - pop (Process) - }if - }ifelse - }ifelse - }ifelse - }if -}bdf -/AGMUTIL_GSTATE 22 dict def -/get_gstate -{ - AGMUTIL_GSTATE begin - /AGMUTIL_GSTATE_clr_spc currentcolorspace def - /AGMUTIL_GSTATE_clr_indx 0 def - /AGMUTIL_GSTATE_clr_comps 12 array def - mark currentcolor counttomark - {AGMUTIL_GSTATE_clr_comps AGMUTIL_GSTATE_clr_indx 3 -1 roll put - /AGMUTIL_GSTATE_clr_indx AGMUTIL_GSTATE_clr_indx 1 add def} repeat pop - /AGMUTIL_GSTATE_fnt rootfont def - /AGMUTIL_GSTATE_lw currentlinewidth def - /AGMUTIL_GSTATE_lc currentlinecap def - /AGMUTIL_GSTATE_lj currentlinejoin def - /AGMUTIL_GSTATE_ml currentmiterlimit def - currentdash /AGMUTIL_GSTATE_do xdf /AGMUTIL_GSTATE_da xdf - /AGMUTIL_GSTATE_sa currentstrokeadjust def - /AGMUTIL_GSTATE_clr_rnd currentcolorrendering def - /AGMUTIL_GSTATE_op currentoverprint def - /AGMUTIL_GSTATE_bg currentblackgeneration cvlit def - /AGMUTIL_GSTATE_ucr currentundercolorremoval cvlit def - currentcolortransfer cvlit /AGMUTIL_GSTATE_gy_xfer xdf cvlit /AGMUTIL_GSTATE_b_xfer xdf - cvlit /AGMUTIL_GSTATE_g_xfer xdf cvlit /AGMUTIL_GSTATE_r_xfer xdf - /AGMUTIL_GSTATE_ht currenthalftone def - /AGMUTIL_GSTATE_flt currentflat def - end -}def -/set_gstate -{ - AGMUTIL_GSTATE begin - AGMUTIL_GSTATE_clr_spc setcolorspace - AGMUTIL_GSTATE_clr_indx {AGMUTIL_GSTATE_clr_comps AGMUTIL_GSTATE_clr_indx 1 sub get - /AGMUTIL_GSTATE_clr_indx AGMUTIL_GSTATE_clr_indx 1 sub def} repeat setcolor - AGMUTIL_GSTATE_fnt setfont - AGMUTIL_GSTATE_lw setlinewidth - AGMUTIL_GSTATE_lc setlinecap - AGMUTIL_GSTATE_lj setlinejoin - AGMUTIL_GSTATE_ml setmiterlimit - AGMUTIL_GSTATE_da AGMUTIL_GSTATE_do setdash - AGMUTIL_GSTATE_sa setstrokeadjust - AGMUTIL_GSTATE_clr_rnd setcolorrendering - AGMUTIL_GSTATE_op setoverprint - AGMUTIL_GSTATE_bg cvx setblackgeneration - AGMUTIL_GSTATE_ucr cvx setundercolorremoval - AGMUTIL_GSTATE_r_xfer cvx AGMUTIL_GSTATE_g_xfer cvx AGMUTIL_GSTATE_b_xfer cvx - AGMUTIL_GSTATE_gy_xfer cvx setcolortransfer - AGMUTIL_GSTATE_ht /HalftoneType get dup 9 eq exch 100 eq or - { - currenthalftone /HalftoneType get AGMUTIL_GSTATE_ht /HalftoneType get ne - { - mark AGMUTIL_GSTATE_ht {sethalftone} stopped cleartomark - } if - }{ - AGMUTIL_GSTATE_ht sethalftone - } ifelse - AGMUTIL_GSTATE_flt setflat - end -}def -/get_gstate_and_matrix -{ - AGMUTIL_GSTATE begin - /AGMUTIL_GSTATE_ctm matrix currentmatrix def - end - get_gstate -}def -/set_gstate_and_matrix -{ - set_gstate - AGMUTIL_GSTATE begin - AGMUTIL_GSTATE_ctm setmatrix - end -}def -/AGMUTIL_str256 256 string def -/AGMUTIL_src256 256 string def -/AGMUTIL_dst64 64 string def -/AGMUTIL_srcLen nd -/AGMUTIL_ndx nd -/agm_sethalftone -{ - dup - begin - /_Data load - /Thresholds xdf - end - level3 - { sethalftone }{ - dup /HalftoneType get 3 eq { - sethalftone - } {pop} ifelse - }ifelse -} def -/rdcmntline -{ - currentfile AGMUTIL_str256 readline pop - (%) anchorsearch {pop} if -} bdf -/filter_cmyk -{ - dup type /filetype ne{ - exch () /SubFileDecode filter - } - { - exch pop - } - ifelse - [ - exch - { - AGMUTIL_src256 readstring pop - dup length /AGMUTIL_srcLen exch def - /AGMUTIL_ndx 0 def - AGMCORE_plate_ndx 4 AGMUTIL_srcLen 1 sub{ - 1 index exch get - AGMUTIL_dst64 AGMUTIL_ndx 3 -1 roll put - /AGMUTIL_ndx AGMUTIL_ndx 1 add def - }for - pop - AGMUTIL_dst64 0 AGMUTIL_ndx getinterval - } - bind - /exec cvx - ] cvx -} bdf -/filter_indexed_devn -{ - cvi Names length mul names_index add Lookup exch get -} bdf -/filter_devn -{ - 4 dict begin - /srcStr xdf - /dstStr xdf - dup type /filetype ne{ - 0 () /SubFileDecode filter - }if - [ - exch - [ - /devicen_colorspace_dict /AGMCORE_gget cvx /begin cvx - currentdict /srcStr get /readstring cvx /pop cvx - /dup cvx /length cvx 0 /gt cvx [ - Adobe_AGM_Utils /AGMUTIL_ndx 0 /ddf cvx - names_index Names length currentdict /srcStr get length 1 sub { - 1 /index cvx /exch cvx /get cvx - currentdict /dstStr get /AGMUTIL_ndx /load cvx 3 -1 /roll cvx /put cvx - Adobe_AGM_Utils /AGMUTIL_ndx /AGMUTIL_ndx /load cvx 1 /add cvx /ddf cvx - } for - currentdict /dstStr get 0 /AGMUTIL_ndx /load cvx /getinterval cvx - ] cvx /if cvx - /end cvx - ] cvx - bind - /exec cvx - ] cvx - end -} bdf -/AGMUTIL_imagefile nd -/read_image_file -{ - AGMUTIL_imagefile 0 setfileposition - 10 dict begin - /imageDict xdf - /imbufLen Width BitsPerComponent mul 7 add 8 idiv def - /imbufIdx 0 def - /origDataSource imageDict /DataSource get def - /origMultipleDataSources imageDict /MultipleDataSources get def - /origDecode imageDict /Decode get def - /dstDataStr imageDict /Width get colorSpaceElemCnt mul string def - /srcDataStrs [ imageDict begin - currentdict /MultipleDataSources known {MultipleDataSources {DataSource length}{1}ifelse}{1} ifelse - { - Width Decode length 2 div mul cvi string - } repeat - end ] def - imageDict /MultipleDataSources known {MultipleDataSources}{false} ifelse - { - /imbufCnt imageDict /DataSource get length def - /imbufs imbufCnt array def - 0 1 imbufCnt 1 sub { - /imbufIdx xdf - imbufs imbufIdx imbufLen string put - imageDict /DataSource get imbufIdx [ AGMUTIL_imagefile imbufs imbufIdx get /readstring cvx /pop cvx ] cvx put - } for - DeviceN_PS2 { - imageDict begin - /DataSource [ DataSource /devn_sep_datasource cvx ] cvx def - /MultipleDataSources false def - /Decode [0 1] def - end - } if - }{ - /imbuf imbufLen string def - Indexed_DeviceN level3 not and DeviceN_NoneName or { - imageDict begin - /DataSource [AGMUTIL_imagefile Decode BitsPerComponent false 1 /filter_indexed_devn load dstDataStr srcDataStrs devn_alt_datasource /exec cvx] cvx def - /Decode [0 1] def - end - }{ - imageDict /DataSource {AGMUTIL_imagefile imbuf readstring pop} put - } ifelse - } ifelse - imageDict exch - load exec - imageDict /DataSource origDataSource put - imageDict /MultipleDataSources origMultipleDataSources put - imageDict /Decode origDecode put - end -} bdf -/write_image_file -{ - begin - { (AGMUTIL_imagefile) (w+) file } stopped{ - false - }{ - Adobe_AGM_Utils/AGMUTIL_imagefile xddf - 2 dict begin - /imbufLen Width BitsPerComponent mul 7 add 8 idiv def - MultipleDataSources {DataSource 0 get}{DataSource}ifelse type /filetype eq { - /imbuf imbufLen string def - }if - 1 1 Height { - pop - MultipleDataSources { - 0 1 DataSource length 1 sub { - DataSource type dup - /arraytype eq { - pop DataSource exch get exec - }{ - /filetype eq { - DataSource exch get imbuf readstring pop - }{ - DataSource exch get - } ifelse - } ifelse - AGMUTIL_imagefile exch writestring - } for - }{ - DataSource type dup - /arraytype eq { - pop DataSource exec - }{ - /filetype eq { - DataSource imbuf readstring pop - }{ - DataSource - } ifelse - } ifelse - AGMUTIL_imagefile exch writestring - } ifelse - }for - end - true - }ifelse - end -} bdf -/close_image_file -{ - AGMUTIL_imagefile closefile (AGMUTIL_imagefile) deletefile -}def -statusdict /product known userdict /AGMP_current_show known not and{ - /pstr statusdict /product get def - pstr (HP LaserJet 2200) eq - pstr (HP LaserJet 4000 Series) eq or - pstr (HP LaserJet 4050 Series ) eq or - pstr (HP LaserJet 8000 Series) eq or - pstr (HP LaserJet 8100 Series) eq or - pstr (HP LaserJet 8150 Series) eq or - pstr (HP LaserJet 5000 Series) eq or - pstr (HP LaserJet 5100 Series) eq or - pstr (HP Color LaserJet 4500) eq or - pstr (HP Color LaserJet 4600) eq or - pstr (HP LaserJet 5Si) eq or - pstr (HP LaserJet 1200 Series) eq or - pstr (HP LaserJet 1300 Series) eq or - pstr (HP LaserJet 4100 Series) eq or - { - userdict /AGMP_current_show /show load put - userdict /show { - currentcolorspace 0 get - /Pattern eq - {false charpath f} - {AGMP_current_show} ifelse - } put - }if - currentdict /pstr undef -} if -/consumeimagedata -{ - begin - currentdict /MultipleDataSources known not - {/MultipleDataSources false def} if - MultipleDataSources - { - 1 dict begin - /flushbuffer Width cvi string def - 1 1 Height cvi - { - pop - 0 1 DataSource length 1 sub - { - DataSource exch get - dup type dup - /filetype eq - { - exch flushbuffer readstring pop pop - }if - /arraytype eq - { - exec pop - }if - }for - }for - end - } - { - /DataSource load type dup - /filetype eq - { - 1 dict begin - /flushbuffer Width Decode length 2 div mul cvi string def - 1 1 Height { pop DataSource flushbuffer readstring pop pop} for - end - }if - /arraytype eq - { - 1 1 Height { pop DataSource pop } for - }if - }ifelse - end -}bdf -/addprocs -{ - 2{/exec load}repeat - 3 1 roll - [ 5 1 roll ] bind cvx -}def -/modify_halftone_xfer -{ - currenthalftone dup length dict copy begin - currentdict 2 index known{ - 1 index load dup length dict copy begin - currentdict/TransferFunction known{ - /TransferFunction load - }{ - currenttransfer - }ifelse - addprocs /TransferFunction xdf - currentdict end def - currentdict end sethalftone - }{ - currentdict/TransferFunction known{ - /TransferFunction load - }{ - currenttransfer - }ifelse - addprocs /TransferFunction xdf - currentdict end sethalftone - pop - }ifelse -}def -/clonearray -{ - dup xcheck exch - dup length array exch - Adobe_AGM_Core/AGMCORE_tmp -1 ddf - { - Adobe_AGM_Core/AGMCORE_tmp AGMCORE_tmp 1 add ddf - dup type /dicttype eq - { - AGMCORE_tmp - exch - clonedict - Adobe_AGM_Core/AGMCORE_tmp 4 -1 roll ddf - } if - dup type /arraytype eq - { - AGMCORE_tmp exch - clonearray - Adobe_AGM_Core/AGMCORE_tmp 4 -1 roll ddf - } if - exch dup - AGMCORE_tmp 4 -1 roll put - }forall - exch {cvx} if -}bdf -/clonedict -{ - dup length dict - begin - { - dup type /dicttype eq - { - clonedict - } if - dup type /arraytype eq - { - clonearray - } if - def - }forall - currentdict - end -}bdf -/DeviceN_PS2 -{ - /currentcolorspace AGMCORE_gget 0 get /DeviceN eq level3 not and -} bdf -/Indexed_DeviceN -{ - /indexed_colorspace_dict AGMCORE_gget dup null ne { - /CSD known - }{ - pop false - } ifelse -} bdf -/DeviceN_NoneName -{ - /Names where { - pop - false Names - { - (None) eq or - } forall - }{ - false - }ifelse -} bdf -/DeviceN_PS2_inRip_seps -{ - /AGMCORE_in_rip_sep where - { - pop dup type dup /arraytype eq exch /packedarraytype eq or - { - dup 0 get /DeviceN eq level3 not and AGMCORE_in_rip_sep and - { - /currentcolorspace exch AGMCORE_gput - false - } - { - true - }ifelse - } - { - true - } ifelse - } - { - true - } ifelse -} bdf -/base_colorspace_type -{ - dup type /arraytype eq {0 get} if -} bdf -/doc_setup{ - Adobe_AGM_Utils begin -}bdf -/doc_trailer{ - currentdict Adobe_AGM_Utils eq{ - end - }if -}bdf -systemdict /setpacking known -{ - setpacking -} if -%%EndResource -%%BeginResource: procset Adobe_AGM_Core 2.0 0 -%%Version: 2.0 0 -%%Copyright: Copyright (C) 1997-2003 Adobe Systems, Inc. All Rights Reserved. -systemdict /setpacking known -{ - currentpacking - true setpacking -} if -userdict /Adobe_AGM_Core 216 dict dup begin put -/nd{ - null def -}bind def -/Adobe_AGM_Core_Id /Adobe_AGM_Core_2.0_0 def -/AGMCORE_str256 256 string def -/AGMCORE_save nd -/AGMCORE_graphicsave nd -/AGMCORE_c 0 def -/AGMCORE_m 0 def -/AGMCORE_y 0 def -/AGMCORE_k 0 def -/AGMCORE_cmykbuf 4 array def -/AGMCORE_screen [currentscreen] cvx def -/AGMCORE_tmp 0 def -/AGMCORE_&setgray nd -/AGMCORE_&setcolor nd -/AGMCORE_&setcolorspace nd -/AGMCORE_&setcmykcolor nd -/AGMCORE_cyan_plate nd -/AGMCORE_magenta_plate nd -/AGMCORE_yellow_plate nd -/AGMCORE_black_plate nd -/AGMCORE_plate_ndx nd -/AGMCORE_get_ink_data nd -/AGMCORE_is_cmyk_sep nd -/AGMCORE_host_sep nd -/AGMCORE_avoid_L2_sep_space nd -/AGMCORE_distilling nd -/AGMCORE_composite_job nd -/AGMCORE_producing_seps nd -/AGMCORE_ps_level -1 def -/AGMCORE_ps_version -1 def -/AGMCORE_environ_ok nd -/AGMCORE_CSA_cache 0 dict def -/AGMCORE_CSD_cache 0 dict def -/AGMCORE_pattern_cache 0 dict def -/AGMCORE_currentoverprint false def -/AGMCORE_deltaX nd -/AGMCORE_deltaY nd -/AGMCORE_name nd -/AGMCORE_sep_special nd -/AGMCORE_err_strings 4 dict def -/AGMCORE_cur_err nd -/AGMCORE_ovp nd -/AGMCORE_current_spot_alias false def -/AGMCORE_inverting false def -/AGMCORE_feature_dictCount nd -/AGMCORE_feature_opCount nd -/AGMCORE_feature_ctm nd -/AGMCORE_ConvertToProcess false def -/AGMCORE_Default_CTM matrix def -/AGMCORE_Default_PageSize nd -/AGMCORE_currentbg nd -/AGMCORE_currentucr nd -/AGMCORE_gradientcache 32 dict def -/AGMCORE_in_pattern false def -/knockout_unitsq nd -/AGMCORE_CRD_cache where{ - pop -}{ - /AGMCORE_CRD_cache 0 dict def -}ifelse -/AGMCORE_key_known -{ - where{ - /Adobe_AGM_Core_Id known - }{ - false - }ifelse -}ndf -/flushinput -{ - save - 2 dict begin - /CompareBuffer 3 -1 roll def - /readbuffer 256 string def - mark - { - currentfile readbuffer {readline} stopped - {cleartomark mark} - { - not - {pop exit} - if - CompareBuffer eq - {exit} - if - }ifelse - }loop - cleartomark - end - restore -}bdf -/getspotfunction -{ - AGMCORE_screen exch pop exch pop - dup type /dicttype eq{ - dup /HalftoneType get 1 eq{ - /SpotFunction get - }{ - dup /HalftoneType get 2 eq{ - /GraySpotFunction get - }{ - pop - { - abs exch abs 2 copy add 1 gt{ - 1 sub dup mul exch 1 sub dup mul add 1 sub - }{ - dup mul exch dup mul add 1 exch sub - }ifelse - }bind - }ifelse - }ifelse - }if -} def -/clp_npth -{ - clip newpath -} def -/eoclp_npth -{ - eoclip newpath -} def -/npth_clp -{ - newpath clip -} def -/add_grad -{ - AGMCORE_gradientcache 3 1 roll put -}bdf -/exec_grad -{ - AGMCORE_gradientcache exch get exec -}bdf -/graphic_setup -{ - /AGMCORE_graphicsave save def - concat - 0 setgray - 0 setlinecap - 0 setlinejoin - 1 setlinewidth - [] 0 setdash - 10 setmiterlimit - newpath - false setoverprint - false setstrokeadjust - Adobe_AGM_Core/spot_alias get exec - /Adobe_AGM_Image where { - pop - Adobe_AGM_Image/spot_alias 2 copy known{ - get exec - }{ - pop pop - }ifelse - } if - 100 dict begin - /dictstackcount countdictstack def - /showpage {} def - mark -} def -/graphic_cleanup -{ - cleartomark - dictstackcount 1 countdictstack 1 sub {end}for - end - AGMCORE_graphicsave restore -} def -/compose_error_msg -{ - grestoreall initgraphics - /Helvetica findfont 10 scalefont setfont - /AGMCORE_deltaY 100 def - /AGMCORE_deltaX 310 def - clippath pathbbox newpath pop pop 36 add exch 36 add exch moveto - 0 AGMCORE_deltaY rlineto AGMCORE_deltaX 0 rlineto - 0 AGMCORE_deltaY neg rlineto AGMCORE_deltaX neg 0 rlineto closepath - 0 AGMCORE_&setgray - gsave 1 AGMCORE_&setgray fill grestore - 1 setlinewidth gsave stroke grestore - currentpoint AGMCORE_deltaY 15 sub add exch 8 add exch moveto - /AGMCORE_deltaY 12 def - /AGMCORE_tmp 0 def - AGMCORE_err_strings exch get - { - dup 32 eq - { - pop - AGMCORE_str256 0 AGMCORE_tmp getinterval - stringwidth pop currentpoint pop add AGMCORE_deltaX 28 add gt - { - currentpoint AGMCORE_deltaY sub exch pop - clippath pathbbox pop pop pop 44 add exch moveto - } if - AGMCORE_str256 0 AGMCORE_tmp getinterval show ( ) show - 0 1 AGMCORE_str256 length 1 sub - { - AGMCORE_str256 exch 0 put - }for - /AGMCORE_tmp 0 def - } - { - AGMCORE_str256 exch AGMCORE_tmp xpt - /AGMCORE_tmp AGMCORE_tmp 1 add def - } ifelse - } forall -} bdf -/doc_setup{ - Adobe_AGM_Core begin - /AGMCORE_ps_version xdf - /AGMCORE_ps_level xdf - errordict /AGM_handleerror known not{ - errordict /AGM_handleerror errordict /handleerror get put - errordict /handleerror { - Adobe_AGM_Core begin - $error /newerror get AGMCORE_cur_err null ne and{ - $error /newerror false put - AGMCORE_cur_err compose_error_msg - }if - $error /newerror true put - end - errordict /AGM_handleerror get exec - } bind put - }if - /AGMCORE_environ_ok - ps_level AGMCORE_ps_level ge - ps_version AGMCORE_ps_version ge and - AGMCORE_ps_level -1 eq or - def - AGMCORE_environ_ok not - {/AGMCORE_cur_err /AGMCORE_bad_environ def} if - /AGMCORE_&setgray systemdict/setgray get def - level2{ - /AGMCORE_&setcolor systemdict/setcolor get def - /AGMCORE_&setcolorspace systemdict/setcolorspace get def - }if - /AGMCORE_currentbg currentblackgeneration def - /AGMCORE_currentucr currentundercolorremoval def - /AGMCORE_distilling - /product where{ - pop systemdict/setdistillerparams known product (Adobe PostScript Parser) ne and - }{ - false - }ifelse - def - level2 not{ - /xput{ - dup load dup length exch maxlength eq{ - dup dup load dup - length dup 0 eq {pop 1} if 2 mul dict copy def - }if - load begin - def - end - }def - }{ - /xput{ - load 3 1 roll put - }def - }ifelse - /AGMCORE_GSTATE AGMCORE_key_known not{ - /AGMCORE_GSTATE 21 dict def - /AGMCORE_tmpmatrix matrix def - /AGMCORE_gstack 32 array def - /AGMCORE_gstackptr 0 def - /AGMCORE_gstacksaveptr 0 def - /AGMCORE_gstackframekeys 10 def - /AGMCORE_&gsave /gsave ldf - /AGMCORE_&grestore /grestore ldf - /AGMCORE_&grestoreall /grestoreall ldf - /AGMCORE_&save /save ldf - /AGMCORE_gdictcopy { - begin - { def } forall - end - }def - /AGMCORE_gput { - AGMCORE_gstack AGMCORE_gstackptr get - 3 1 roll - put - }def - /AGMCORE_gget { - AGMCORE_gstack AGMCORE_gstackptr get - exch - get - }def - /gsave { - AGMCORE_&gsave - AGMCORE_gstack AGMCORE_gstackptr get - AGMCORE_gstackptr 1 add - dup 32 ge {limitcheck} if - Adobe_AGM_Core exch - /AGMCORE_gstackptr xpt - AGMCORE_gstack AGMCORE_gstackptr get - AGMCORE_gdictcopy - }def - /grestore { - AGMCORE_&grestore - AGMCORE_gstackptr 1 sub - dup AGMCORE_gstacksaveptr lt {1 add} if - Adobe_AGM_Core exch - /AGMCORE_gstackptr xpt - }def - /grestoreall { - AGMCORE_&grestoreall - Adobe_AGM_Core - /AGMCORE_gstackptr AGMCORE_gstacksaveptr put - }def - /save { - AGMCORE_&save - AGMCORE_gstack AGMCORE_gstackptr get - AGMCORE_gstackptr 1 add - dup 32 ge {limitcheck} if - Adobe_AGM_Core begin - /AGMCORE_gstackptr exch def - /AGMCORE_gstacksaveptr AGMCORE_gstackptr def - end - AGMCORE_gstack AGMCORE_gstackptr get - AGMCORE_gdictcopy - }def - 0 1 AGMCORE_gstack length 1 sub { - AGMCORE_gstack exch AGMCORE_gstackframekeys dict put - } for - }if - level3 /AGMCORE_&sysshfill AGMCORE_key_known not and - { - /AGMCORE_&sysshfill systemdict/shfill get def - /AGMCORE_&usrshfill /shfill load def - /AGMCORE_&sysmakepattern systemdict/makepattern get def - /AGMCORE_&usrmakepattern /makepattern load def - }if - /currentcmykcolor [0 0 0 0] AGMCORE_gput - /currentstrokeadjust false AGMCORE_gput - /currentcolorspace [/DeviceGray] AGMCORE_gput - /sep_tint 0 AGMCORE_gput - /devicen_tints [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] AGMCORE_gput - /sep_colorspace_dict null AGMCORE_gput - /devicen_colorspace_dict null AGMCORE_gput - /indexed_colorspace_dict null AGMCORE_gput - /currentcolor_intent () AGMCORE_gput - /customcolor_tint 1 AGMCORE_gput - << - /MaxPatternItem currentsystemparams /MaxPatternCache get - >> - setuserparams - end -}def -/page_setup -{ - /setcmykcolor where{ - pop - Adobe_AGM_Core/AGMCORE_&setcmykcolor /setcmykcolor load put - }if - Adobe_AGM_Core begin - /setcmykcolor - { - 4 copy AGMCORE_cmykbuf astore /currentcmykcolor exch AGMCORE_gput - 1 sub 4 1 roll - 3 { - 3 index add neg dup 0 lt { - pop 0 - } if - 3 1 roll - } repeat - setrgbcolor pop - }ndf - /currentcmykcolor - { - /currentcmykcolor AGMCORE_gget aload pop - }ndf - /setoverprint - { - pop - }ndf - /currentoverprint - { - false - }ndf - /AGMCORE_deviceDPI 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt def - /AGMCORE_cyan_plate 1 0 0 0 test_cmyk_color_plate def - /AGMCORE_magenta_plate 0 1 0 0 test_cmyk_color_plate def - /AGMCORE_yellow_plate 0 0 1 0 test_cmyk_color_plate def - /AGMCORE_black_plate 0 0 0 1 test_cmyk_color_plate def - /AGMCORE_plate_ndx - AGMCORE_cyan_plate{ - 0 - }{ - AGMCORE_magenta_plate{ - 1 - }{ - AGMCORE_yellow_plate{ - 2 - }{ - AGMCORE_black_plate{ - 3 - }{ - 4 - }ifelse - }ifelse - }ifelse - }ifelse - def - /AGMCORE_have_reported_unsupported_color_space false def - /AGMCORE_report_unsupported_color_space - { - AGMCORE_have_reported_unsupported_color_space false eq - { - (Warning: Job contains content that cannot be separated with on-host methods. This content appears on the black plate, and knocks out all other plates.) == - Adobe_AGM_Core /AGMCORE_have_reported_unsupported_color_space true ddf - } if - }def - /AGMCORE_composite_job - AGMCORE_cyan_plate AGMCORE_magenta_plate and AGMCORE_yellow_plate and AGMCORE_black_plate and def - /AGMCORE_in_rip_sep - /AGMCORE_in_rip_sep where{ - pop AGMCORE_in_rip_sep - }{ - AGMCORE_distilling - { - false - }{ - userdict/Adobe_AGM_OnHost_Seps known{ - false - }{ - level2{ - currentpagedevice/Separations 2 copy known{ - get - }{ - pop pop false - }ifelse - }{ - false - }ifelse - }ifelse - }ifelse - }ifelse - def - /AGMCORE_producing_seps AGMCORE_composite_job not AGMCORE_in_rip_sep or def - /AGMCORE_host_sep AGMCORE_producing_seps AGMCORE_in_rip_sep not and def - /AGM_preserve_spots - /AGM_preserve_spots where{ - pop AGM_preserve_spots - }{ - AGMCORE_distilling AGMCORE_producing_seps or - }ifelse - def - /AGM_is_distiller_preserving_spotimages - { - currentdistillerparams/PreserveOverprintSettings known - { - currentdistillerparams/PreserveOverprintSettings get - { - currentdistillerparams/ColorConversionStrategy known - { - currentdistillerparams/ColorConversionStrategy get - /LeaveColorUnchanged eq - }{ - true - }ifelse - }{ - false - }ifelse - }{ - false - }ifelse - }def - /convert_spot_to_process where {pop}{ - /convert_spot_to_process - { - dup map_alias { - /Name get exch pop - } if - dup dup (None) eq exch (All) eq or - { - pop false - }{ - AGMCORE_host_sep - { - gsave - 1 0 0 0 setcmykcolor currentgray 1 exch sub - 0 1 0 0 setcmykcolor currentgray 1 exch sub - 0 0 1 0 setcmykcolor currentgray 1 exch sub - 0 0 0 1 setcmykcolor currentgray 1 exch sub - add add add 0 eq - { - pop false - }{ - false setoverprint - 1 1 1 1 5 -1 roll findcmykcustomcolor 1 setcustomcolor - currentgray 0 eq - }ifelse - grestore - }{ - AGMCORE_distilling - { - pop AGM_is_distiller_preserving_spotimages not - }{ - Adobe_AGM_Core/AGMCORE_name xddf - false - Adobe_AGM_Core/AGMCORE_in_pattern known {Adobe_AGM_Core/AGMCORE_in_pattern get}{false} ifelse - not currentpagedevice/OverrideSeparations known and - { - currentpagedevice/OverrideSeparations get - { - /HqnSpots /ProcSet resourcestatus - { - pop pop pop true - }if - }if - }if - { - AGMCORE_name /HqnSpots /ProcSet findresource /TestSpot get exec not - }{ - gsave - [/Separation AGMCORE_name /DeviceGray {}]setcolorspace - false - currentpagedevice/SeparationColorNames 2 copy known - { - get - { AGMCORE_name eq or}forall - not - }{ - pop pop pop true - }ifelse - grestore - }ifelse - }ifelse - }ifelse - }ifelse - }def - }ifelse - /convert_to_process where {pop}{ - /convert_to_process - { - dup length 0 eq - { - pop false - }{ - AGMCORE_host_sep - { - dup true exch - { - dup (Cyan) eq exch - dup (Magenta) eq 3 -1 roll or exch - dup (Yellow) eq 3 -1 roll or exch - dup (Black) eq 3 -1 roll or - {pop} - {convert_spot_to_process and}ifelse - } - forall - { - true exch - { - dup (Cyan) eq exch - dup (Magenta) eq 3 -1 roll or exch - dup (Yellow) eq 3 -1 roll or exch - (Black) eq or and - }forall - not - }{pop false}ifelse - }{ - false exch - { - dup (Cyan) eq exch - dup (Magenta) eq 3 -1 roll or exch - dup (Yellow) eq 3 -1 roll or exch - dup (Black) eq 3 -1 roll or - {pop} - {convert_spot_to_process or}ifelse - } - forall - }ifelse - }ifelse - }def - }ifelse - /AGMCORE_avoid_L2_sep_space - version cvr 2012 lt - level2 and - AGMCORE_producing_seps not and - def - /AGMCORE_is_cmyk_sep - AGMCORE_cyan_plate AGMCORE_magenta_plate or AGMCORE_yellow_plate or AGMCORE_black_plate or - def - /AGM_avoid_0_cmyk where{ - pop AGM_avoid_0_cmyk - }{ - AGM_preserve_spots - userdict/Adobe_AGM_OnHost_Seps known - userdict/Adobe_AGM_InRip_Seps known or - not and - }ifelse - { - /setcmykcolor[ - { - 4 copy add add add 0 eq currentoverprint and{ - pop 0.0005 - }if - }/exec cvx - /AGMCORE_&setcmykcolor load dup type/operatortype ne{ - /exec cvx - }if - ]cvx def - }if - AGMCORE_host_sep{ - /setcolortransfer - { - AGMCORE_cyan_plate{ - pop pop pop - }{ - AGMCORE_magenta_plate{ - 4 3 roll pop pop pop - }{ - AGMCORE_yellow_plate{ - 4 2 roll pop pop pop - }{ - 4 1 roll pop pop pop - }ifelse - }ifelse - }ifelse - settransfer - } - def - /AGMCORE_get_ink_data - AGMCORE_cyan_plate{ - {pop pop pop} - }{ - AGMCORE_magenta_plate{ - {4 3 roll pop pop pop} - }{ - AGMCORE_yellow_plate{ - {4 2 roll pop pop pop} - }{ - {4 1 roll pop pop pop} - }ifelse - }ifelse - }ifelse - def - /AGMCORE_RemoveProcessColorNames - { - 1 dict begin - /filtername - { - dup /Cyan eq 1 index (Cyan) eq or - {pop (_cyan_)}if - dup /Magenta eq 1 index (Magenta) eq or - {pop (_magenta_)}if - dup /Yellow eq 1 index (Yellow) eq or - {pop (_yellow_)}if - dup /Black eq 1 index (Black) eq or - {pop (_black_)}if - }def - dup type /arraytype eq - {[exch {filtername}forall]} - {filtername}ifelse - end - }def - /AGMCORE_IsSeparationAProcessColor - { - dup (Cyan) eq exch dup (Magenta) eq exch dup (Yellow) eq exch (Black) eq or or or - }def - level3 { - /AGMCORE_IsCurrentColor - { - gsave - false setoverprint - 1 1 1 1 5 -1 roll findcmykcustomcolor 1 setcustomcolor - currentgray 0 eq - grestore - }def - /AGMCORE_filter_functiondatasource - { - 5 dict begin - /data_in xdf - data_in type /stringtype eq - { - /ncomp xdf - /comp xdf - /string_out data_in length ncomp idiv string def - 0 ncomp data_in length 1 sub - { - string_out exch dup ncomp idiv exch data_in exch ncomp getinterval comp get 255 exch sub put - }for - string_out - }{ - string /string_in xdf - /string_out 1 string def - /component xdf - [ - data_in string_in /readstring cvx - [component /get cvx 255 /exch cvx /sub cvx string_out /exch cvx 0 /exch cvx /put cvx string_out]cvx - [/pop cvx ()]cvx /ifelse cvx - ]cvx /ReusableStreamDecode filter - }ifelse - end - }def - /AGMCORE_separateShadingFunction - { - 2 dict begin - /paint? xdf - /channel xdf - begin - FunctionType 0 eq - { - /DataSource channel Range length 2 idiv DataSource AGMCORE_filter_functiondatasource def - currentdict /Decode known - {/Decode Decode channel 2 mul 2 getinterval def}if - paint? not - {/Decode [1 1]def}if - }if - FunctionType 2 eq - { - paint? - { - /C0 [C0 channel get 1 exch sub] def - /C1 [C1 channel get 1 exch sub] def - }{ - /C0 [1] def - /C1 [1] def - }ifelse - }if - FunctionType 3 eq - { - /Functions [Functions {channel paint? AGMCORE_separateShadingFunction} forall] def - }if - currentdict /Range known - {/Range [0 1] def}if - currentdict - end - end - }def - /AGMCORE_separateShading - { - 3 -1 roll begin - currentdict /Function known - { - currentdict /Background known - {[1 index{Background 3 index get 1 exch sub}{1}ifelse]/Background xdf}if - Function 3 1 roll AGMCORE_separateShadingFunction /Function xdf - /ColorSpace [/DeviceGray] def - }{ - ColorSpace dup type /arraytype eq {0 get}if /DeviceCMYK eq - { - /ColorSpace [/DeviceN [/_cyan_ /_magenta_ /_yellow_ /_black_] /DeviceCMYK {}] def - }{ - ColorSpace dup 1 get AGMCORE_RemoveProcessColorNames 1 exch put - }ifelse - ColorSpace 0 get /Separation eq - { - { - [1 /exch cvx /sub cvx]cvx - }{ - [/pop cvx 1]cvx - }ifelse - ColorSpace 3 3 -1 roll put - pop - }{ - { - [exch ColorSpace 1 get length 1 sub exch sub /index cvx 1 /exch cvx /sub cvx ColorSpace 1 get length 1 add 1 /roll cvx ColorSpace 1 get length{/pop cvx} repeat]cvx - }{ - pop [ColorSpace 1 get length {/pop cvx} repeat cvx 1]cvx - }ifelse - ColorSpace 3 3 -1 roll bind put - }ifelse - ColorSpace 2 /DeviceGray put - }ifelse - end - }def - /AGMCORE_separateShadingDict - { - dup /ColorSpace get - dup type /arraytype ne - {[exch]}if - dup 0 get /DeviceCMYK eq - { - exch begin - currentdict - AGMCORE_cyan_plate - {0 true}if - AGMCORE_magenta_plate - {1 true}if - AGMCORE_yellow_plate - {2 true}if - AGMCORE_black_plate - {3 true}if - AGMCORE_plate_ndx 4 eq - {0 false}if - dup not currentoverprint and - {/AGMCORE_ignoreshade true def}if - AGMCORE_separateShading - currentdict - end exch - }if - dup 0 get /Separation eq - { - exch begin - ColorSpace 1 get dup /None ne exch /All ne and - { - ColorSpace 1 get AGMCORE_IsCurrentColor AGMCORE_plate_ndx 4 lt and ColorSpace 1 get AGMCORE_IsSeparationAProcessColor not and - { - ColorSpace 2 get dup type /arraytype eq {0 get}if /DeviceCMYK eq - { - /ColorSpace - [ - /Separation - ColorSpace 1 get - /DeviceGray - [ - ColorSpace 3 get /exec cvx - 4 AGMCORE_plate_ndx sub -1 /roll cvx - 4 1 /roll cvx - 3 [/pop cvx]cvx /repeat cvx - 1 /exch cvx /sub cvx - ]cvx - ]def - }{ - AGMCORE_report_unsupported_color_space - AGMCORE_black_plate not - { - currentdict 0 false AGMCORE_separateShading - }if - }ifelse - }{ - currentdict ColorSpace 1 get AGMCORE_IsCurrentColor - 0 exch - dup not currentoverprint and - {/AGMCORE_ignoreshade true def}if - AGMCORE_separateShading - }ifelse - }if - currentdict - end exch - }if - dup 0 get /DeviceN eq - { - exch begin - ColorSpace 1 get convert_to_process - { - ColorSpace 2 get dup type /arraytype eq {0 get}if /DeviceCMYK eq - { - /ColorSpace - [ - /DeviceN - ColorSpace 1 get - /DeviceGray - [ - ColorSpace 3 get /exec cvx - 4 AGMCORE_plate_ndx sub -1 /roll cvx - 4 1 /roll cvx - 3 [/pop cvx]cvx /repeat cvx - 1 /exch cvx /sub cvx - ]cvx - ]def - }{ - AGMCORE_report_unsupported_color_space - AGMCORE_black_plate not - { - currentdict 0 false AGMCORE_separateShading - /ColorSpace [/DeviceGray] def - }if - }ifelse - }{ - currentdict - false -1 ColorSpace 1 get - { - AGMCORE_IsCurrentColor - { - 1 add - exch pop true exch exit - }if - 1 add - }forall - exch - dup not currentoverprint and - {/AGMCORE_ignoreshade true def}if - AGMCORE_separateShading - }ifelse - currentdict - end exch - }if - dup 0 get dup /DeviceCMYK eq exch dup /Separation eq exch /DeviceN eq or or not - { - exch begin - ColorSpace dup type /arraytype eq - {0 get}if - /DeviceGray ne - { - AGMCORE_report_unsupported_color_space - AGMCORE_black_plate not - { - ColorSpace 0 get /CIEBasedA eq - { - /ColorSpace [/Separation /_ciebaseda_ /DeviceGray {}] def - }if - ColorSpace 0 get dup /CIEBasedABC eq exch dup /CIEBasedDEF eq exch /DeviceRGB eq or or - { - /ColorSpace [/DeviceN [/_red_ /_green_ /_blue_] /DeviceRGB {}] def - }if - ColorSpace 0 get /CIEBasedDEFG eq - { - /ColorSpace [/DeviceN [/_cyan_ /_magenta_ /_yellow_ /_black_] /DeviceCMYK {}] - }if - currentdict 0 false AGMCORE_separateShading - }if - }if - currentdict - end exch - }if - pop - dup /AGMCORE_ignoreshade known - { - begin - /ColorSpace [/Separation (None) /DeviceGray {}] def - currentdict end - }if - }def - /shfill - { - clonedict - AGMCORE_separateShadingDict - dup /AGMCORE_ignoreshade known - {pop} - {AGMCORE_&sysshfill}ifelse - }def - /makepattern - { - exch - dup /PatternType get 2 eq - { - clonedict - begin - /Shading Shading AGMCORE_separateShadingDict def - currentdict end - exch AGMCORE_&sysmakepattern - }{ - exch AGMCORE_&usrmakepattern - }ifelse - }def - }if - }if - AGMCORE_in_rip_sep{ - /setcustomcolor - { - exch aload pop - dup 7 1 roll inRip_spot_has_ink not { - 4 {4 index mul 4 1 roll} - repeat - /DeviceCMYK setcolorspace - 6 -2 roll pop pop - }{ - Adobe_AGM_Core begin - /AGMCORE_k xdf /AGMCORE_y xdf /AGMCORE_m xdf /AGMCORE_c xdf - end - [/Separation 4 -1 roll /DeviceCMYK - {dup AGMCORE_c mul exch dup AGMCORE_m mul exch dup AGMCORE_y mul exch AGMCORE_k mul} - ] - setcolorspace - }ifelse - setcolor - }ndf - /setseparationgray - { - [/Separation (All) /DeviceGray {}] setcolorspace_opt - 1 exch sub setcolor - }ndf - }{ - /setseparationgray - { - AGMCORE_&setgray - }ndf - }ifelse - /findcmykcustomcolor - { - 5 makereadonlyarray - }ndf - /setcustomcolor - { - exch aload pop pop - 4 {4 index mul 4 1 roll} repeat - setcmykcolor pop - }ndf - /has_color - /colorimage where{ - AGMCORE_producing_seps{ - pop true - }{ - systemdict eq - }ifelse - }{ - false - }ifelse - def - /map_index - { - 1 index mul exch getinterval {255 div} forall - } bdf - /map_indexed_devn - { - Lookup Names length 3 -1 roll cvi map_index - } bdf - /n_color_components - { - base_colorspace_type - dup /DeviceGray eq{ - pop 1 - }{ - /DeviceCMYK eq{ - 4 - }{ - 3 - }ifelse - }ifelse - }bdf - level2{ - /mo /moveto ldf - /li /lineto ldf - /cv /curveto ldf - /knockout_unitsq - { - 1 setgray - 0 0 1 1 rectfill - }def - /level2ScreenFreq{ - begin - 60 - HalftoneType 1 eq{ - pop Frequency - }if - HalftoneType 2 eq{ - pop GrayFrequency - }if - HalftoneType 5 eq{ - pop Default level2ScreenFreq - }if - end - }def - /currentScreenFreq{ - currenthalftone level2ScreenFreq - }def - level2 /setcolorspace AGMCORE_key_known not and{ - /AGMCORE_&&&setcolorspace /setcolorspace ldf - /AGMCORE_ReplaceMappedColor - { - dup type dup /arraytype eq exch /packedarraytype eq or - { - dup 0 get dup /Separation eq - { - pop - dup length array copy - dup dup 1 get - current_spot_alias - { - dup map_alias - { - begin - /sep_colorspace_dict currentdict AGMCORE_gput - pop pop pop - [ - /Separation Name - CSA map_csa - dup /MappedCSA xdf - /sep_colorspace_proc load - ] - dup Name - end - }if - }if - map_reserved_ink_name 1 xpt - }{ - /DeviceN eq - { - dup length array copy - dup dup 1 get [ - exch { - current_spot_alias{ - dup map_alias{ - /Name get exch pop - }if - }if - map_reserved_ink_name - } forall - ] 1 xpt - }if - }ifelse - }if - }def - /setcolorspace - { - dup type dup /arraytype eq exch /packedarraytype eq or - { - dup 0 get /Indexed eq - { - AGMCORE_distilling - { - /PhotoshopDuotoneList where - { - pop false - }{ - true - }ifelse - }{ - true - }ifelse - { - aload pop 3 -1 roll - AGMCORE_ReplaceMappedColor - 3 1 roll 4 array astore - }if - }{ - AGMCORE_ReplaceMappedColor - }ifelse - }if - DeviceN_PS2_inRip_seps {AGMCORE_&&&setcolorspace} if - }def - }if - }{ - /adj - { - currentstrokeadjust{ - transform - 0.25 sub round 0.25 add exch - 0.25 sub round 0.25 add exch - itransform - }if - }def - /mo{ - adj moveto - }def - /li{ - adj lineto - }def - /cv{ - 6 2 roll adj - 6 2 roll adj - 6 2 roll adj curveto - }def - /knockout_unitsq - { - 1 setgray - 8 8 1 [8 0 0 8 0 0] {} image - }def - /currentstrokeadjust{ - /currentstrokeadjust AGMCORE_gget - }def - /setstrokeadjust{ - /currentstrokeadjust exch AGMCORE_gput - }def - /currentScreenFreq{ - currentscreen pop pop - }def - /setcolorspace - { - /currentcolorspace exch AGMCORE_gput - } def - /currentcolorspace - { - /currentcolorspace AGMCORE_gget - } def - /setcolor_devicecolor - { - base_colorspace_type - dup /DeviceGray eq{ - pop setgray - }{ - /DeviceCMYK eq{ - setcmykcolor - }{ - setrgbcolor - }ifelse - }ifelse - }def - /setcolor - { - currentcolorspace 0 get - dup /DeviceGray ne{ - dup /DeviceCMYK ne{ - dup /DeviceRGB ne{ - dup /Separation eq{ - pop - currentcolorspace 3 get exec - currentcolorspace 2 get - }{ - dup /Indexed eq{ - pop - currentcolorspace 3 get dup type /stringtype eq{ - currentcolorspace 1 get n_color_components - 3 -1 roll map_index - }{ - exec - }ifelse - currentcolorspace 1 get - }{ - /AGMCORE_cur_err /AGMCORE_invalid_color_space def - AGMCORE_invalid_color_space - }ifelse - }ifelse - }if - }if - }if - setcolor_devicecolor - } def - }ifelse - /sop /setoverprint ldf - /lw /setlinewidth ldf - /lc /setlinecap ldf - /lj /setlinejoin ldf - /ml /setmiterlimit ldf - /dsh /setdash ldf - /sadj /setstrokeadjust ldf - /gry /setgray ldf - /rgb /setrgbcolor ldf - /cmyk /setcmykcolor ldf - /sep /setsepcolor ldf - /devn /setdevicencolor ldf - /idx /setindexedcolor ldf - /colr /setcolor ldf - /csacrd /set_csa_crd ldf - /sepcs /setsepcolorspace ldf - /devncs /setdevicencolorspace ldf - /idxcs /setindexedcolorspace ldf - /cp /closepath ldf - /clp /clp_npth ldf - /eclp /eoclp_npth ldf - /f /fill ldf - /ef /eofill ldf - /@ /stroke ldf - /nclp /npth_clp ldf - /gset /graphic_setup ldf - /gcln /graphic_cleanup ldf - currentdict{ - dup xcheck 1 index type dup /arraytype eq exch /packedarraytype eq or and { - bind - }if - def - }forall - /currentpagedevice currentpagedevice def -/getrampcolor { -/indx exch def -0 1 NumComp 1 sub { -dup -Samples exch get -dup type /stringtype eq { indx get } if -exch -Scaling exch get aload pop -3 1 roll -mul add -} for -ColorSpaceFamily /Separation eq - { - sep - } - { - ColorSpaceFamily /DeviceN eq - { - devn - } - { - setcolor - }ifelse - }ifelse -} bind def -/sssetbackground { aload pop setcolor } bind def -/RadialShade { -40 dict begin -/ColorSpaceFamily exch def -/background exch def -/ext1 exch def -/ext0 exch def -/BBox exch def -/r2 exch def -/c2y exch def -/c2x exch def -/r1 exch def -/c1y exch def -/c1x exch def -/rampdict exch def -/setinkoverprint where {pop /setinkoverprint{pop}def}if -gsave -BBox length 0 gt { -newpath -BBox 0 get BBox 1 get moveto -BBox 2 get BBox 0 get sub 0 rlineto -0 BBox 3 get BBox 1 get sub rlineto -BBox 2 get BBox 0 get sub neg 0 rlineto -closepath -clip -newpath -} if -c1x c2x eq -{ -c1y c2y lt {/theta 90 def}{/theta 270 def} ifelse -} -{ -/slope c2y c1y sub c2x c1x sub div def -/theta slope 1 atan def -c2x c1x lt c2y c1y ge and { /theta theta 180 sub def} if -c2x c1x lt c2y c1y lt and { /theta theta 180 add def} if -} -ifelse -gsave -clippath -c1x c1y translate -theta rotate --90 rotate -{ pathbbox } stopped -{ 0 0 0 0 } if -/yMax exch def -/xMax exch def -/yMin exch def -/xMin exch def -grestore -xMax xMin eq yMax yMin eq or -{ -grestore -end -} -{ -/max { 2 copy gt { pop } {exch pop} ifelse } bind def -/min { 2 copy lt { pop } {exch pop} ifelse } bind def -rampdict begin -40 dict begin -background length 0 gt { background sssetbackground gsave clippath fill grestore } if -gsave -c1x c1y translate -theta rotate --90 rotate -/c2y c1x c2x sub dup mul c1y c2y sub dup mul add sqrt def -/c1y 0 def -/c1x 0 def -/c2x 0 def -ext0 { -0 getrampcolor -c2y r2 add r1 sub 0.0001 lt -{ -c1x c1y r1 360 0 arcn -pathbbox -/aymax exch def -/axmax exch def -/aymin exch def -/axmin exch def -/bxMin xMin axmin min def -/byMin yMin aymin min def -/bxMax xMax axmax max def -/byMax yMax aymax max def -bxMin byMin moveto -bxMax byMin lineto -bxMax byMax lineto -bxMin byMax lineto -bxMin byMin lineto -eofill -} -{ -c2y r1 add r2 le -{ -c1x c1y r1 0 360 arc -fill -} -{ -c2x c2y r2 0 360 arc fill -r1 r2 eq -{ -/p1x r1 neg def -/p1y c1y def -/p2x r1 def -/p2y c1y def -p1x p1y moveto p2x p2y lineto p2x yMin lineto p1x yMin lineto -fill -} -{ -/AA r2 r1 sub c2y div def -/theta AA 1 AA dup mul sub sqrt div 1 atan def -/SS1 90 theta add dup sin exch cos div def -/p1x r1 SS1 SS1 mul SS1 SS1 mul 1 add div sqrt mul neg def -/p1y p1x SS1 div neg def -/SS2 90 theta sub dup sin exch cos div def -/p2x r1 SS2 SS2 mul SS2 SS2 mul 1 add div sqrt mul def -/p2y p2x SS2 div neg def -r1 r2 gt -{ -/L1maxX p1x yMin p1y sub SS1 div add def -/L2maxX p2x yMin p2y sub SS2 div add def -} -{ -/L1maxX 0 def -/L2maxX 0 def -}ifelse -p1x p1y moveto p2x p2y lineto L2maxX L2maxX p2x sub SS2 mul p2y add lineto -L1maxX L1maxX p1x sub SS1 mul p1y add lineto -fill -} -ifelse -} -ifelse -} ifelse -} if -c1x c2x sub dup mul -c1y c2y sub dup mul -add 0.5 exp -0 dtransform -dup mul exch dup mul add 0.5 exp 72 div -0 72 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt -72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt -1 index 1 index lt { exch } if pop -/hires exch def -hires mul -/numpix exch def -/numsteps NumSamples def -/rampIndxInc 1 def -/subsampling false def -numpix 0 ne -{ -NumSamples numpix div 0.5 gt -{ -/numsteps numpix 2 div round cvi dup 1 le { pop 2 } if def -/rampIndxInc NumSamples 1 sub numsteps div def -/subsampling true def -} if -} if -/xInc c2x c1x sub numsteps div def -/yInc c2y c1y sub numsteps div def -/rInc r2 r1 sub numsteps div def -/cx c1x def -/cy c1y def -/radius r1 def -newpath -xInc 0 eq yInc 0 eq rInc 0 eq and and -{ -0 getrampcolor -cx cy radius 0 360 arc -stroke -NumSamples 1 sub getrampcolor -cx cy radius 72 hires div add 0 360 arc -0 setlinewidth -stroke -} -{ -0 -numsteps -{ -dup -subsampling { round cvi } if -getrampcolor -cx cy radius 0 360 arc -/cx cx xInc add def -/cy cy yInc add def -/radius radius rInc add def -cx cy radius 360 0 arcn -eofill -rampIndxInc add -} -repeat -pop -} ifelse -ext1 { -c2y r2 add r1 lt -{ -c2x c2y r2 0 360 arc -fill -} -{ -c2y r1 add r2 sub 0.0001 le -{ -c2x c2y r2 360 0 arcn -pathbbox -/aymax exch def -/axmax exch def -/aymin exch def -/axmin exch def -/bxMin xMin axmin min def -/byMin yMin aymin min def -/bxMax xMax axmax max def -/byMax yMax aymax max def -bxMin byMin moveto -bxMax byMin lineto -bxMax byMax lineto -bxMin byMax lineto -bxMin byMin lineto -eofill -} -{ -c2x c2y r2 0 360 arc fill -r1 r2 eq -{ -/p1x r2 neg def -/p1y c2y def -/p2x r2 def -/p2y c2y def -p1x p1y moveto p2x p2y lineto p2x yMax lineto p1x yMax lineto -fill -} -{ -/AA r2 r1 sub c2y div def -/theta AA 1 AA dup mul sub sqrt div 1 atan def -/SS1 90 theta add dup sin exch cos div def -/p1x r2 SS1 SS1 mul SS1 SS1 mul 1 add div sqrt mul neg def -/p1y c2y p1x SS1 div sub def -/SS2 90 theta sub dup sin exch cos div def -/p2x r2 SS2 SS2 mul SS2 SS2 mul 1 add div sqrt mul def -/p2y c2y p2x SS2 div sub def -r1 r2 lt -{ -/L1maxX p1x yMax p1y sub SS1 div add def -/L2maxX p2x yMax p2y sub SS2 div add def -} -{ -/L1maxX 0 def -/L2maxX 0 def -}ifelse -p1x p1y moveto p2x p2y lineto L2maxX L2maxX p2x sub SS2 mul p2y add lineto -L1maxX L1maxX p1x sub SS1 mul p1y add lineto -fill -} -ifelse -} -ifelse -} ifelse -} if -grestore -grestore -end -end -end -} ifelse -} bind def -/GenStrips { -40 dict begin -/ColorSpaceFamily exch def -/background exch def -/ext1 exch def -/ext0 exch def -/BBox exch def -/y2 exch def -/x2 exch def -/y1 exch def -/x1 exch def -/rampdict exch def -/setinkoverprint where {pop /setinkoverprint{pop}def}if -gsave -BBox length 0 gt { -newpath -BBox 0 get BBox 1 get moveto -BBox 2 get BBox 0 get sub 0 rlineto -0 BBox 3 get BBox 1 get sub rlineto -BBox 2 get BBox 0 get sub neg 0 rlineto -closepath -clip -newpath -} if -x1 x2 eq -{ -y1 y2 lt {/theta 90 def}{/theta 270 def} ifelse -} -{ -/slope y2 y1 sub x2 x1 sub div def -/theta slope 1 atan def -x2 x1 lt y2 y1 ge and { /theta theta 180 sub def} if -x2 x1 lt y2 y1 lt and { /theta theta 180 add def} if -} -ifelse -gsave -clippath -x1 y1 translate -theta rotate -{ pathbbox } stopped -{ 0 0 0 0 } if -/yMax exch def -/xMax exch def -/yMin exch def -/xMin exch def -grestore -xMax xMin eq yMax yMin eq or -{ -grestore -end -} -{ -rampdict begin -20 dict begin -background length 0 gt { background sssetbackground gsave clippath fill grestore } if -gsave -x1 y1 translate -theta rotate -/xStart 0 def -/xEnd x2 x1 sub dup mul y2 y1 sub dup mul add 0.5 exp def -/ySpan yMax yMin sub def -/numsteps NumSamples def -/rampIndxInc 1 def -/subsampling false def -xStart 0 transform -xEnd 0 transform -3 -1 roll -sub dup mul -3 1 roll -sub dup mul -add 0.5 exp 72 div -0 72 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt -72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt -1 index 1 index lt { exch } if pop -mul -/numpix exch def -numpix 0 ne -{ -NumSamples numpix div 0.5 gt -{ -/numsteps numpix 2 div round cvi dup 1 le { pop 2 } if def -/rampIndxInc NumSamples 1 sub numsteps div def -/subsampling true def -} if -} if -ext0 { -0 getrampcolor -xMin xStart lt -{ xMin yMin xMin neg ySpan rectfill } if -} if -/xInc xEnd xStart sub numsteps div def -/x xStart def -0 -numsteps -{ -dup -subsampling { round cvi } if -getrampcolor -x yMin xInc ySpan rectfill -/x x xInc add def -rampIndxInc add -} -repeat -pop -ext1 { -xMax xEnd gt -{ xEnd yMin xMax xEnd sub ySpan rectfill } if -} if -grestore -grestore -end -end -end -} ifelse -} bind def -}def -/page_trailer -{ - end -}def -/doc_trailer{ -}def -systemdict /findcolorrendering known{ - /findcolorrendering systemdict /findcolorrendering get def -}if -systemdict /setcolorrendering known{ - /setcolorrendering systemdict /setcolorrendering get def -}if -/test_cmyk_color_plate -{ - gsave - setcmykcolor currentgray 1 ne - grestore -}def -/inRip_spot_has_ink -{ - dup Adobe_AGM_Core/AGMCORE_name xddf - convert_spot_to_process not -}def -/map255_to_range -{ - 1 index sub - 3 -1 roll 255 div mul add -}def -/set_csa_crd -{ - /sep_colorspace_dict null AGMCORE_gput - begin - CSA map_csa setcolorspace_opt - set_crd - end -} -def -/setsepcolor -{ - /sep_colorspace_dict AGMCORE_gget begin - dup /sep_tint exch AGMCORE_gput - TintProc - end -} def -/setdevicencolor -{ - /devicen_colorspace_dict AGMCORE_gget begin - Names length copy - Names length 1 sub -1 0 - { - /devicen_tints AGMCORE_gget 3 1 roll xpt - } for - TintProc - end -} def -/sep_colorspace_proc -{ - Adobe_AGM_Core/AGMCORE_tmp xddf - /sep_colorspace_dict AGMCORE_gget begin - currentdict/Components known{ - Components aload pop - TintMethod/Lab eq{ - 2 {AGMCORE_tmp mul NComponents 1 roll} repeat - LMax sub AGMCORE_tmp mul LMax add NComponents 1 roll - }{ - TintMethod/Subtractive eq{ - NComponents{ - AGMCORE_tmp mul NComponents 1 roll - }repeat - }{ - NComponents{ - 1 sub AGMCORE_tmp mul 1 add NComponents 1 roll - } repeat - }ifelse - }ifelse - }{ - ColorLookup AGMCORE_tmp ColorLookup length 1 sub mul round cvi get - aload pop - }ifelse - end -} def -/sep_colorspace_gray_proc -{ - Adobe_AGM_Core/AGMCORE_tmp xddf - /sep_colorspace_dict AGMCORE_gget begin - GrayLookup AGMCORE_tmp GrayLookup length 1 sub mul round cvi get - end -} def -/sep_proc_name -{ - dup 0 get - dup /DeviceRGB eq exch /DeviceCMYK eq or level2 not and has_color not and{ - pop [/DeviceGray] - /sep_colorspace_gray_proc - }{ - /sep_colorspace_proc - }ifelse -} def -/setsepcolorspace -{ - current_spot_alias{ - dup begin - Name map_alias{ - exch pop - }if - end - }if - dup /sep_colorspace_dict exch AGMCORE_gput - begin - /MappedCSA CSA map_csa def - Adobe_AGM_Core/AGMCORE_sep_special Name dup () eq exch (All) eq or ddf - AGMCORE_avoid_L2_sep_space{ - [/Indexed MappedCSA sep_proc_name 255 exch - { 255 div } /exec cvx 3 -1 roll [ 4 1 roll load /exec cvx ] cvx - ] setcolorspace_opt - /TintProc { - 255 mul round cvi setcolor - }bdf - }{ - MappedCSA 0 get /DeviceCMYK eq - currentdict/Components known and - AGMCORE_sep_special not and{ - /TintProc [ - Components aload pop Name findcmykcustomcolor - /exch cvx /setcustomcolor cvx - ] cvx bdf - }{ - AGMCORE_host_sep Name (All) eq and{ - /TintProc { - 1 exch sub setseparationgray - }bdf - }{ - AGMCORE_in_rip_sep MappedCSA 0 get /DeviceCMYK eq and - AGMCORE_host_sep or - Name () eq and{ - /TintProc [ - MappedCSA sep_proc_name exch 0 get /DeviceCMYK eq{ - cvx /setcmykcolor cvx - }{ - cvx /setgray cvx - }ifelse - ] cvx bdf - }{ - AGMCORE_producing_seps MappedCSA 0 get dup /DeviceCMYK eq exch /DeviceGray eq or and AGMCORE_sep_special not and{ - /TintProc [ - /dup cvx - MappedCSA sep_proc_name cvx exch - 0 get /DeviceGray eq{ - 1 /exch cvx /sub cvx 0 0 0 4 -1 /roll cvx - }if - /Name cvx /findcmykcustomcolor cvx /exch cvx - AGMCORE_host_sep{ - AGMCORE_is_cmyk_sep - /Name cvx - /AGMCORE_IsSeparationAProcessColor load /exec cvx - /not cvx /and cvx - }{ - Name inRip_spot_has_ink not - }ifelse - [ - /pop cvx 1 - ] cvx /if cvx - /setcustomcolor cvx - ] cvx bdf - }{ - /TintProc /setcolor ldf - [/Separation Name MappedCSA sep_proc_name load ] setcolorspace_opt - }ifelse - }ifelse - }ifelse - }ifelse - }ifelse - set_crd - setsepcolor - end -} def -/additive_blend -{ - 3 dict begin - /numarrays xdf - /numcolors xdf - 0 1 numcolors 1 sub - { - /c1 xdf - 1 - 0 1 numarrays 1 sub - { - 1 exch add /index cvx - c1 /get cvx /mul cvx - }for - numarrays 1 add 1 /roll cvx - }for - numarrays [/pop cvx] cvx /repeat cvx - end -}def -/subtractive_blend -{ - 3 dict begin - /numarrays xdf - /numcolors xdf - 0 1 numcolors 1 sub - { - /c1 xdf - 1 1 - 0 1 numarrays 1 sub - { - 1 3 3 -1 roll add /index cvx - c1 /get cvx /sub cvx /mul cvx - }for - /sub cvx - numarrays 1 add 1 /roll cvx - }for - numarrays [/pop cvx] cvx /repeat cvx - end -}def -/exec_tint_transform -{ - /TintProc [ - /TintTransform cvx /setcolor cvx - ] cvx bdf - MappedCSA setcolorspace_opt -} bdf -/devn_makecustomcolor -{ - 2 dict begin - /names_index xdf - /Names xdf - 1 1 1 1 Names names_index get findcmykcustomcolor - /devicen_tints AGMCORE_gget names_index get setcustomcolor - Names length {pop} repeat - end -} bdf -/setdevicencolorspace -{ - dup /AliasedColorants known {false}{true}ifelse - current_spot_alias and { - 6 dict begin - /names_index 0 def - dup /names_len exch /Names get length def - /new_names names_len array def - /new_LookupTables names_len array def - /alias_cnt 0 def - dup /Names get - { - dup map_alias { - exch pop - dup /ColorLookup known { - dup begin - new_LookupTables names_index ColorLookup put - end - }{ - dup /Components known { - dup begin - new_LookupTables names_index Components put - end - }{ - dup begin - new_LookupTables names_index [null null null null] put - end - } ifelse - } ifelse - new_names names_index 3 -1 roll /Name get put - /alias_cnt alias_cnt 1 add def - }{ - /name xdf - new_names names_index name put - dup /LookupTables known { - dup begin - new_LookupTables names_index LookupTables names_index get put - end - }{ - dup begin - new_LookupTables names_index [null null null null] put - end - } ifelse - } ifelse - /names_index names_index 1 add def - } forall - alias_cnt 0 gt { - /AliasedColorants true def - 0 1 names_len 1 sub { - /names_index xdf - new_LookupTables names_index get 0 get null eq { - dup /Names get names_index get /name xdf - name (Cyan) eq name (Magenta) eq name (Yellow) eq name (Black) eq - or or or not { - /AliasedColorants false def - exit - } if - } if - } for - AliasedColorants { - dup begin - /Names new_names def - /AliasedColorants true def - /LookupTables new_LookupTables def - currentdict /TTTablesIdx known not { - /TTTablesIdx -1 def - } if - currentdict /NComponents known not { - /NComponents TintMethod /Subtractive eq {4}{3}ifelse def - } if - end - } if - }if - end - } if - dup /devicen_colorspace_dict exch AGMCORE_gput - begin - /MappedCSA CSA map_csa def - currentdict /AliasedColorants known { - AliasedColorants - }{ - false - } ifelse - /TintTransform load type /nulltype eq or { - /TintTransform [ - 0 1 Names length 1 sub - { - /TTTablesIdx TTTablesIdx 1 add def - dup LookupTables exch get dup 0 get null eq - { - 1 index - Names exch get - dup (Cyan) eq - { - pop exch - LookupTables length exch sub - /index cvx - 0 0 0 - } - { - dup (Magenta) eq - { - pop exch - LookupTables length exch sub - /index cvx - 0 /exch cvx 0 0 - } - { - (Yellow) eq - { - exch - LookupTables length exch sub - /index cvx - 0 0 3 -1 /roll cvx 0 - } - { - exch - LookupTables length exch sub - /index cvx - 0 0 0 4 -1 /roll cvx - } ifelse - } ifelse - } ifelse - 5 -1 /roll cvx /astore cvx - } - { - dup length 1 sub - LookupTables length 4 -1 roll sub 1 add - /index cvx /mul cvx /round cvx /cvi cvx /get cvx - } ifelse - Names length TTTablesIdx add 1 add 1 /roll cvx - } for - Names length [/pop cvx] cvx /repeat cvx - NComponents Names length - TintMethod /Subtractive eq - { - subtractive_blend - } - { - additive_blend - } ifelse - ] cvx bdf - } if - AGMCORE_host_sep { - Names convert_to_process { - exec_tint_transform - } - { - currentdict /AliasedColorants known { - AliasedColorants not - }{ - false - } ifelse - 5 dict begin - /AvoidAliasedColorants xdf - /painted? false def - /names_index 0 def - /names_len Names length def - Names { - AvoidAliasedColorants { - /currentspotalias current_spot_alias def - false set_spot_alias - } if - AGMCORE_is_cmyk_sep { - dup (Cyan) eq AGMCORE_cyan_plate and exch - dup (Magenta) eq AGMCORE_magenta_plate and exch - dup (Yellow) eq AGMCORE_yellow_plate and exch - (Black) eq AGMCORE_black_plate and or or or { - /devicen_colorspace_dict AGMCORE_gget /TintProc [ - Names names_index /devn_makecustomcolor cvx - ] cvx ddf - /painted? true def - } if - painted? {exit} if - }{ - 0 0 0 0 5 -1 roll findcmykcustomcolor 1 setcustomcolor currentgray 0 eq { - /devicen_colorspace_dict AGMCORE_gget /TintProc [ - Names names_index /devn_makecustomcolor cvx - ] cvx ddf - /painted? true def - exit - } if - } ifelse - AvoidAliasedColorants { - currentspotalias set_spot_alias - } if - /names_index names_index 1 add def - } forall - painted? { - /devicen_colorspace_dict AGMCORE_gget /names_index names_index put - }{ - /devicen_colorspace_dict AGMCORE_gget /TintProc [ - names_len [/pop cvx] cvx /repeat cvx 1 /setseparationgray cvx - 0 0 0 0 () /findcmykcustomcolor cvx 0 /setcustomcolor cvx - ] cvx ddf - } ifelse - end - } ifelse - } - { - AGMCORE_in_rip_sep { - Names convert_to_process not - }{ - level3 - } ifelse - { - [/DeviceN Names MappedCSA /TintTransform load] setcolorspace_opt - /TintProc level3 not AGMCORE_in_rip_sep and { - [ - Names /length cvx [/pop cvx] cvx /repeat cvx - ] cvx bdf - }{ - /setcolor ldf - } ifelse - }{ - exec_tint_transform - } ifelse - } ifelse - set_crd - /AliasedColorants false def - end -} def -/setindexedcolorspace -{ - dup /indexed_colorspace_dict exch AGMCORE_gput - begin - currentdict /CSD known { - CSD get_csd /Names known { - CSD get_csd begin - currentdict devncs - AGMCORE_host_sep{ - 4 dict begin - /devnCompCnt Names length def - /NewLookup HiVal 1 add string def - 0 1 HiVal { - /tableIndex xdf - Lookup dup type /stringtype eq { - devnCompCnt tableIndex map_index - }{ - exec - } ifelse - setdevicencolor - currentgray - tableIndex exch - HiVal mul cvi - NewLookup 3 1 roll put - } for - [/Indexed currentcolorspace HiVal NewLookup] setcolorspace_opt - end - }{ - level3 - { - [/Indexed [/DeviceN Names MappedCSA /TintTransform load] HiVal Lookup] setcolorspace_opt - }{ - [/Indexed MappedCSA HiVal - [ - Lookup dup type /stringtype eq - {/exch cvx CSD get_csd /Names get length dup /mul cvx exch /getinterval cvx {255 div} /forall cvx} - {/exec cvx}ifelse - /TintTransform load /exec cvx - ]cvx - ]setcolorspace_opt - }ifelse - } ifelse - end - }{ - } ifelse - set_crd - } - { - /MappedCSA CSA map_csa def - AGMCORE_host_sep level2 not and{ - 0 0 0 0 setcmykcolor - }{ - [/Indexed MappedCSA - level2 not has_color not and{ - dup 0 get dup /DeviceRGB eq exch /DeviceCMYK eq or{ - pop [/DeviceGray] - }if - HiVal GrayLookup - }{ - HiVal - currentdict/RangeArray known{ - { - /indexed_colorspace_dict AGMCORE_gget begin - Lookup exch - dup HiVal gt{ - pop HiVal - }if - NComponents mul NComponents getinterval {} forall - NComponents 1 sub -1 0{ - RangeArray exch 2 mul 2 getinterval aload pop map255_to_range - NComponents 1 roll - }for - end - } bind - }{ - Lookup - }ifelse - }ifelse - ] setcolorspace_opt - set_crd - }ifelse - }ifelse - end -}def -/setindexedcolor -{ - AGMCORE_host_sep { - /indexed_colorspace_dict AGMCORE_gget dup /CSD known { - begin - CSD get_csd begin - map_indexed_devn - devn - end - end - }{ - AGMCORE_gget/Lookup get 4 3 -1 roll map_index - pop setcmykcolor - } ifelse - }{ - level3 not AGMCORE_in_rip_sep and /indexed_colorspace_dict AGMCORE_gget /CSD known and { - /indexed_colorspace_dict AGMCORE_gget /CSD get get_csd begin - map_indexed_devn - devn - end - } - { - setcolor - } ifelse - }ifelse -} def -/ignoreimagedata -{ - currentoverprint not{ - gsave - dup clonedict begin - 1 setgray - /Decode [0 1] def - /DataSource def - /MultipleDataSources false def - /BitsPerComponent 8 def - currentdict end - systemdict /image get exec - grestore - }if - consumeimagedata -}def -/add_csa -{ - Adobe_AGM_Core begin - /AGMCORE_CSA_cache xput - end -}def -/get_csa_by_name -{ - dup type dup /nametype eq exch /stringtype eq or{ - Adobe_AGM_Core begin - 1 dict begin - /name xdf - AGMCORE_CSA_cache - { - 0 get name eq { - exit - }{ - pop - } ifelse - }forall - end - end - }{ - pop - } ifelse -}def -/map_csa -{ - dup type /nametype eq{ - Adobe_AGM_Core/AGMCORE_CSA_cache get exch get - }if -}def -/add_csd -{ - Adobe_AGM_Core begin - /AGMCORE_CSD_cache xput - end -}def -/get_csd -{ - dup type /nametype eq{ - Adobe_AGM_Core/AGMCORE_CSD_cache get exch get - }if -}def -/pattern_buf_init -{ - /count get 0 0 put -} def -/pattern_buf_next -{ - dup /count get dup 0 get - dup 3 1 roll - 1 add 0 xpt - get -} def -/cachepattern_compress -{ - 5 dict begin - currentfile exch 0 exch /SubFileDecode filter /ReadFilter exch def - /patarray 20 dict def - /string_size 16000 def - /readbuffer string_size string def - currentglobal true setglobal - patarray 1 array dup 0 1 put /count xpt - setglobal - /LZWFilter - { - exch - dup length 0 eq { - pop - }{ - patarray dup length 1 sub 3 -1 roll put - } ifelse - {string_size}{0}ifelse string - } /LZWEncode filter def - { - ReadFilter readbuffer readstring - exch LZWFilter exch writestring - not {exit} if - } loop - LZWFilter closefile - patarray - end -}def -/cachepattern -{ - 2 dict begin - currentfile exch 0 exch /SubFileDecode filter /ReadFilter exch def - /patarray 20 dict def - currentglobal true setglobal - patarray 1 array dup 0 1 put /count xpt - setglobal - { - ReadFilter 16000 string readstring exch - patarray dup length 1 sub 3 -1 roll put - not {exit} if - } loop - patarray dup dup length 1 sub () put - end -}def -/add_pattern -{ - Adobe_AGM_Core begin - /AGMCORE_pattern_cache xput - end -}def -/get_pattern -{ - dup type /nametype eq{ - Adobe_AGM_Core/AGMCORE_pattern_cache get exch get - dup wrap_paintproc - }if -}def -/wrap_paintproc -{ - statusdict /currentfilenameextend known{ - begin - /OldPaintProc /PaintProc load def - /PaintProc - { - mark exch - dup /OldPaintProc get stopped - {closefile restore end} if - cleartomark - } def - end - } {pop} ifelse -} def -/make_pattern -{ - dup matrix currentmatrix matrix concatmatrix 0 0 3 2 roll itransform - exch 3 index /XStep get 1 index exch 2 copy div cvi mul sub sub - exch 3 index /YStep get 1 index exch 2 copy div cvi mul sub sub - matrix translate exch matrix concatmatrix - 1 index begin - BBox 0 get XStep div cvi XStep mul /xshift exch neg def - BBox 1 get YStep div cvi YStep mul /yshift exch neg def - BBox 0 get xshift add - BBox 1 get yshift add - BBox 2 get xshift add - BBox 3 get yshift add - 4 array astore - /BBox exch def - [ xshift yshift /translate load null /exec load ] dup - 3 /PaintProc load put cvx /PaintProc exch def - end - gsave 0 setgray - makepattern - grestore -}def -/set_pattern -{ - dup /PatternType get 1 eq{ - dup /PaintType get 1 eq{ - currentoverprint sop [/DeviceGray] setcolorspace 0 setgray - }if - }if - setpattern -}def -/setcolorspace_opt -{ - dup currentcolorspace eq{ - pop - }{ - setcolorspace - }ifelse -}def -/updatecolorrendering -{ - currentcolorrendering/Intent known{ - currentcolorrendering/Intent get - }{ - null - }ifelse - Intent ne{ - false - Intent - AGMCORE_CRD_cache { - exch pop - begin - dup Intent eq{ - currentdict setcolorrendering_opt - end - exch pop true exch - exit - }if - end - } forall - pop - not{ - systemdict /findcolorrendering known{ - Intent findcolorrendering pop - /ColorRendering findresource - dup length dict copy - setcolorrendering_opt - }if - }if - }if -} def -/add_crd -{ - AGMCORE_CRD_cache 3 1 roll put -}def -/set_crd -{ - AGMCORE_host_sep not level2 and{ - currentdict/CRD known{ - AGMCORE_CRD_cache CRD get dup null ne{ - setcolorrendering_opt - }{ - pop - }ifelse - }{ - currentdict/Intent known{ - updatecolorrendering - }if - }ifelse - currentcolorspace dup type /arraytype eq - {0 get}if - /DeviceRGB eq - { - currentdict/UCR known - {/UCR}{/AGMCORE_currentucr}ifelse - load setundercolorremoval - currentdict/BG known - {/BG}{/AGMCORE_currentbg}ifelse - load setblackgeneration - }if - }if -}def -/setcolorrendering_opt -{ - dup currentcolorrendering eq{ - pop - }{ - begin - /Intent Intent def - currentdict - end - setcolorrendering - }ifelse -}def -/cpaint_gcomp -{ - convert_to_process Adobe_AGM_Core/AGMCORE_ConvertToProcess xddf - Adobe_AGM_Core/AGMCORE_ConvertToProcess get not - { - (%end_cpaint_gcomp) flushinput - }if -}def -/cpaint_gsep -{ - Adobe_AGM_Core/AGMCORE_ConvertToProcess get - { - (%end_cpaint_gsep) flushinput - }if -}def -/cpaint_gend -{ - newpath -}def -/path_rez -{ - dup 0 ne{ - AGMCORE_deviceDPI exch div - dup 1 lt{ - pop 1 - }if - setflat - }{ - pop - }ifelse -}def -/set_spot_alias_ary -{ - /AGMCORE_SpotAliasAry where{ - pop pop - }{ - Adobe_AGM_Core/AGMCORE_SpotAliasAry xddf - true set_spot_alias - }ifelse -}def -/set_spot_alias -{ - /AGMCORE_SpotAliasAry where{ - /AGMCORE_current_spot_alias 3 -1 roll put - }{ - pop - }ifelse -}def -/current_spot_alias -{ - /AGMCORE_SpotAliasAry where{ - /AGMCORE_current_spot_alias get - }{ - false - }ifelse -}def -/map_alias -{ - /AGMCORE_SpotAliasAry where{ - begin - /AGMCORE_name xdf - false - AGMCORE_SpotAliasAry{ - dup/Name get AGMCORE_name eq{ - save exch - /Adobe_AGM_Core currentdict def - /CSD get get_csd - exch restore - exch pop true - exit - }{ - pop - }ifelse - }forall - end - }{ - pop false - }ifelse -}bdf -/spot_alias -{ - true set_spot_alias - /AGMCORE_&setcustomcolor AGMCORE_key_known not { - Adobe_AGM_Core/AGMCORE_&setcustomcolor /setcustomcolor load put - } if - /customcolor_tint 1 AGMCORE_gput - Adobe_AGM_Core begin - /setcustomcolor - { - dup /customcolor_tint exch AGMCORE_gput - current_spot_alias{ - 1 index 4 get map_alias{ - mark 3 1 roll - setsepcolorspace - counttomark 0 ne{ - setsepcolor - }if - pop - pop - }{ - AGMCORE_&setcustomcolor - }ifelse - }{ - AGMCORE_&setcustomcolor - }ifelse - }bdf - end -}def -/begin_feature -{ - Adobe_AGM_Core/AGMCORE_feature_dictCount countdictstack put - count Adobe_AGM_Core/AGMCORE_feature_opCount 3 -1 roll put - {Adobe_AGM_Core/AGMCORE_feature_ctm matrix currentmatrix put}if -}def -/end_feature -{ - 2 dict begin - /spd /setpagedevice load def - /setpagedevice { get_gstate spd set_gstate } def - stopped{$error/newerror false put}if - end - count Adobe_AGM_Core/AGMCORE_feature_opCount get sub dup 0 gt{{pop}repeat}{pop}ifelse - countdictstack Adobe_AGM_Core/AGMCORE_feature_dictCount get sub dup 0 gt{{end}repeat}{pop}ifelse - {Adobe_AGM_Core/AGMCORE_feature_ctm get setmatrix}if -}def -/set_negative -{ - Adobe_AGM_Core begin - /AGMCORE_inverting exch def - level2{ - currentpagedevice/NegativePrint known{ - currentpagedevice/NegativePrint get Adobe_AGM_Core/AGMCORE_inverting get ne{ - true begin_feature true{ - bdict /NegativePrint Adobe_AGM_Core/AGMCORE_inverting get edict setpagedevice - }end_feature - }if - /AGMCORE_inverting false def - }if - }if - AGMCORE_inverting{ - [{1 exch sub}/exec load dup currenttransfer exch]cvx bind settransfer - gsave newpath clippath 1 /setseparationgray where{pop setseparationgray}{setgray}ifelse - /AGMIRS_&fill where {pop AGMIRS_&fill}{fill} ifelse grestore - }if - end -}def -/lw_save_restore_override { - /md where { - pop - md begin - initializepage - /initializepage{}def - /pmSVsetup{} def - /endp{}def - /pse{}def - /psb{}def - /orig_showpage where - {pop} - {/orig_showpage /showpage load def} - ifelse - /showpage {orig_showpage gR} def - end - }if -}def -/pscript_showpage_override { - /NTPSOct95 where - { - begin - showpage - save - /showpage /restore load def - /restore {exch pop}def - end - }if -}def -/driver_media_override -{ - /md where { - pop - md /initializepage known { - md /initializepage {} put - } if - md /rC known { - md /rC {4{pop}repeat} put - } if - }if - /mysetup where { - /mysetup [1 0 0 1 0 0] put - }if - Adobe_AGM_Core /AGMCORE_Default_CTM matrix currentmatrix put - level2 - {Adobe_AGM_Core /AGMCORE_Default_PageSize currentpagedevice/PageSize get put}if -}def -/driver_check_media_override -{ - /PrepsDict where - {pop} - { - Adobe_AGM_Core /AGMCORE_Default_CTM get matrix currentmatrix ne - Adobe_AGM_Core /AGMCORE_Default_PageSize get type /arraytype eq - { - Adobe_AGM_Core /AGMCORE_Default_PageSize get 0 get currentpagedevice/PageSize get 0 get eq and - Adobe_AGM_Core /AGMCORE_Default_PageSize get 1 get currentpagedevice/PageSize get 1 get eq and - }if - { - Adobe_AGM_Core /AGMCORE_Default_CTM get setmatrix - }if - }ifelse -}def -AGMCORE_err_strings begin - /AGMCORE_bad_environ (Environment not satisfactory for this job. Ensure that the PPD is correct or that the PostScript level requested is supported by this printer. ) def - /AGMCORE_color_space_onhost_seps (This job contains colors that will not separate with on-host methods. ) def - /AGMCORE_invalid_color_space (This job contains an invalid color space. ) def -end -end -systemdict /setpacking known -{ - setpacking -} if -%%EndResource -%%BeginResource: procset Adobe_CoolType_Core 2.23 0 -%%Copyright: Copyright 1997-2003 Adobe Systems Incorporated. All Rights Reserved. -%%Version: 2.23 0 -10 dict begin -/Adobe_CoolType_Passthru currentdict def -/Adobe_CoolType_Core_Defined userdict /Adobe_CoolType_Core known def -Adobe_CoolType_Core_Defined - { /Adobe_CoolType_Core userdict /Adobe_CoolType_Core get def } -if -userdict /Adobe_CoolType_Core 60 dict dup begin put -/Adobe_CoolType_Version 2.23 def -/Level2? - systemdict /languagelevel known dup - { pop systemdict /languagelevel get 2 ge } - if def -Level2? not - { - /currentglobal false def - /setglobal /pop load def - /gcheck { pop false } bind def - /currentpacking false def - /setpacking /pop load def - /SharedFontDirectory 0 dict def - } -if -currentpacking -true setpacking -/@_SaveStackLevels - { - Adobe_CoolType_Data - begin - @opStackCountByLevel @opStackLevel - 2 copy known not - { 2 copy 3 dict dup /args 7 index 5 add array put put get } - { - get dup /args get dup length 3 index lt - { - dup length 5 add array exch - 1 index exch 0 exch putinterval - 1 index exch /args exch put - } - { pop } - ifelse - } - ifelse - begin - count 2 sub 1 index lt - { pop count 1 sub } - if - dup /argCount exch def - dup 0 gt - { - exch 1 index 2 add 1 roll - args exch 0 exch getinterval - astore pop - } - { pop } - ifelse - count 1 sub /restCount exch def - end - /@opStackLevel @opStackLevel 1 add def - countdictstack 1 sub - @dictStackCountByLevel exch @dictStackLevel exch put - /@dictStackLevel @dictStackLevel 1 add def - end - } bind def -/@_RestoreStackLevels - { - Adobe_CoolType_Data - begin - /@opStackLevel @opStackLevel 1 sub def - @opStackCountByLevel @opStackLevel get - begin - count restCount sub dup 0 gt - { { pop } repeat } - { pop } - ifelse - args 0 argCount getinterval {} forall - end - /@dictStackLevel @dictStackLevel 1 sub def - @dictStackCountByLevel @dictStackLevel get - end - countdictstack exch sub dup 0 gt - { { end } repeat } - { pop } - ifelse - } bind def -/@_PopStackLevels - { - Adobe_CoolType_Data - begin - /@opStackLevel @opStackLevel 1 sub def - /@dictStackLevel @dictStackLevel 1 sub def - end - } bind def -/@Raise - { - exch cvx exch errordict exch get exec - stop - } bind def -/@ReRaise - { - cvx $error /errorname get errordict exch get exec - stop - } bind def -/@Stopped - { - 0 @#Stopped - } bind def -/@#Stopped - { - @_SaveStackLevels - stopped - { @_RestoreStackLevels true } - { @_PopStackLevels false } - ifelse - } bind def -/@Arg - { - Adobe_CoolType_Data - begin - @opStackCountByLevel @opStackLevel 1 sub get /args get exch get - end - } bind def -currentglobal true setglobal -/CTHasResourceForAllBug - Level2? - { - 1 dict dup begin - mark - { - (*) { pop stop } 128 string /Category - resourceforall - } - stopped - cleartomark - currentdict eq dup - { end } - if - not - } - { false } - ifelse - def -/CTHasResourceStatusBug - Level2? - { - mark - { /steveamerige /Category resourcestatus } - stopped - { cleartomark true } - { cleartomark currentglobal not } - ifelse - } - { false } - ifelse - def -setglobal -/CTResourceStatus - { - mark 3 1 roll - /Category findresource - begin - ({ResourceStatus} stopped) 0 () /SubFileDecode filter cvx exec - { cleartomark false } - { { 3 2 roll pop true } { cleartomark false } ifelse } - ifelse - end - } bind def -/CTWorkAroundBugs - { - Level2? - { - /cid_PreLoad /ProcSet resourcestatus - { - pop pop - currentglobal - mark - { - (*) - { - dup /CMap CTHasResourceStatusBug - { CTResourceStatus } - { resourcestatus } - ifelse - { - pop dup 0 eq exch 1 eq or - { - dup /CMap findresource gcheck setglobal - /CMap undefineresource - } - { - pop CTHasResourceForAllBug - { exit } - { stop } - ifelse - } - ifelse - } - { pop } - ifelse - } - 128 string /CMap resourceforall - } - stopped - { cleartomark } - stopped pop - setglobal - } - if - } - if - } bind def -/doc_setup - { - Adobe_CoolType_Core - begin - CTWorkAroundBugs - /mov /moveto load def - /nfnt /newencodedfont load def - /mfnt /makefont load def - /sfnt /setfont load def - /ufnt /undefinefont load def - /chp /charpath load def - /awsh /awidthshow load def - /wsh /widthshow load def - /ash /ashow load def - /sh /show load def - end - userdict /Adobe_CoolType_Data 10 dict dup - begin - /AddWidths? false def - /CC 0 def - /charcode 2 string def - /@opStackCountByLevel 32 dict def - /@opStackLevel 0 def - /@dictStackCountByLevel 32 dict def - /@dictStackLevel 0 def - /InVMFontsByCMap 10 dict def - /InVMDeepCopiedFonts 10 dict def - end put - } bind def -/doc_trailer - { - currentdict Adobe_CoolType_Core eq - { end } - if - } bind def -/page_setup - { - Adobe_CoolType_Core begin - } bind def -/page_trailer - { - end - } bind def -/unload - { - systemdict /languagelevel known - { - systemdict/languagelevel get 2 ge - { - userdict/Adobe_CoolType_Core 2 copy known - { undef } - { pop pop } - ifelse - } - if - } - if - } bind def -/ndf - { - 1 index where - { pop pop pop } - { dup xcheck { bind } if def } - ifelse - } def -/findfont systemdict - begin - userdict - begin - /globaldict where { /globaldict get begin } if - dup where pop exch get - /globaldict where { pop end } if - end - end -Adobe_CoolType_Core_Defined - { /systemfindfont exch def } - { - /findfont 1 index def - /systemfindfont exch def - } -ifelse -/undefinefont - { pop } ndf -/copyfont - { - currentglobal 3 1 roll - 1 index gcheck setglobal - dup null eq { 0 } { dup length } ifelse - 2 index length add 1 add dict - begin - exch - { - 1 index /FID eq - { pop pop } - { def } - ifelse - } - forall - dup null eq - { pop } - { { def } forall } - ifelse - currentdict - end - exch setglobal - } bind def -/copyarray - { - currentglobal exch - dup gcheck setglobal - dup length array copy - exch setglobal - } bind def -/newencodedfont - { - currentglobal - { - SharedFontDirectory 3 index known - { SharedFontDirectory 3 index get /FontReferenced known } - { false } - ifelse - } - { - FontDirectory 3 index known - { FontDirectory 3 index get /FontReferenced known } - { - SharedFontDirectory 3 index known - { SharedFontDirectory 3 index get /FontReferenced known } - { false } - ifelse - } - ifelse - } - ifelse - dup - { - 3 index findfont /FontReferenced get - 2 index dup type /nametype eq - {findfont} - if ne - { pop false } - if - } - if - { - pop - 1 index findfont - /Encoding get exch - 0 1 255 - { 2 copy get 3 index 3 1 roll put } - for - pop pop pop - } - { - dup type /nametype eq - { findfont } - if - dup dup maxlength 2 add dict - begin - exch - { - 1 index /FID ne - {def} - {pop pop} - ifelse - } - forall - /FontReferenced exch def - /Encoding exch dup length array copy def - /FontName 1 index dup type /stringtype eq { cvn } if def dup - currentdict - end - definefont def - } - ifelse - } bind def -/SetSubstituteStrategy - { - $SubstituteFont - begin - dup type /dicttype ne - { 0 dict } - if - currentdict /$Strategies known - { - exch $Strategies exch - 2 copy known - { - get - 2 copy maxlength exch maxlength add dict - begin - { def } forall - { def } forall - currentdict - dup /$Init known - { dup /$Init get exec } - if - end - /$Strategy exch def - } - { pop pop pop } - ifelse - } - { pop pop } - ifelse - end - } bind def -/scff - { - $SubstituteFont - begin - dup type /stringtype eq - { dup length exch } - { null } - ifelse - /$sname exch def - /$slen exch def - /$inVMIndex - $sname null eq - { - 1 index $str cvs - dup length $slen sub $slen getinterval cvn - } - { $sname } - ifelse def - end - { findfont } - @Stopped - { - dup length 8 add string exch - 1 index 0 (BadFont:) putinterval - 1 index exch 8 exch dup length string cvs putinterval cvn - { findfont } - @Stopped - { pop /Courier findfont } - if - } - if - $SubstituteFont - begin - /$sname null def - /$slen 0 def - /$inVMIndex null def - end - } bind def -/isWidthsOnlyFont - { - dup /WidthsOnly known - { pop pop true } - { - dup /FDepVector known - { /FDepVector get { isWidthsOnlyFont dup { exit } if } forall } - { - dup /FDArray known - { /FDArray get { isWidthsOnlyFont dup { exit } if } forall } - { pop } - ifelse - } - ifelse - } - ifelse - } bind def -/?str1 256 string def -/?set - { - $SubstituteFont - begin - /$substituteFound false def - /$fontname 4 index def - /$doSmartSub false def - end - 3 index - currentglobal false setglobal exch - /CompatibleFonts /ProcSet resourcestatus - { - pop pop - /CompatibleFonts /ProcSet findresource - begin - dup /CompatibleFont currentexception - 1 index /CompatibleFont true setexception - 1 index /Font resourcestatus - { - pop pop - 3 2 roll setglobal - end - exch - dup findfont - /CompatibleFonts /ProcSet findresource - begin - 3 1 roll exch /CompatibleFont exch setexception - end - } - { - 3 2 roll setglobal - 1 index exch /CompatibleFont exch setexception - end - findfont - $SubstituteFont /$substituteFound true put - } - ifelse - } - { exch setglobal findfont } - ifelse - $SubstituteFont - begin - $substituteFound - { - false - (%%[Using embedded font ) print - 5 index ?str1 cvs print - ( to avoid the font substitution problem noted earlier.]%%\n) print - } - { - dup /FontName known - { - dup /FontName get $fontname eq - 1 index /DistillerFauxFont known not and - /currentdistillerparams where - { pop false 2 index isWidthsOnlyFont not and } - if - } - { false } - ifelse - } - ifelse - exch pop - /$doSmartSub true def - end - { - exch pop exch pop exch - 2 dict dup /Found 3 index put - exch findfont exch - } - { - exch exec - exch dup findfont - dup /FontType get 3 eq - { - exch ?str1 cvs - dup length 1 sub - -1 0 - { - exch dup 2 index get 42 eq - { - exch 0 exch getinterval cvn 4 1 roll 3 2 roll pop - exit - } - {exch pop} ifelse - }for - } - { - exch pop - } ifelse - 2 dict dup /Downloaded 6 5 roll put - } - ifelse - dup /FontName 4 index put copyfont definefont pop - } bind def -/?str2 256 string def -/?add - { - 1 index type /integertype eq - { exch true 4 2 } - { false 3 1 } - ifelse - roll - 1 index findfont - dup /Widths known - { - Adobe_CoolType_Data /AddWidths? true put - gsave dup 1000 scalefont setfont - } - if - /Downloaded known - { - exec - exch - { - exch ?str2 cvs exch - findfont /Downloaded get 1 dict begin /Downloaded 1 index def ?str1 cvs length - ?str1 1 index 1 add 3 index putinterval - exch length 1 add 1 index add - ?str1 2 index (*) putinterval - ?str1 0 2 index getinterval cvn findfont - ?str1 3 index (+) putinterval - 2 dict dup /FontName ?str1 0 6 index getinterval cvn put - dup /Downloaded Downloaded put end copyfont - dup /FontName get exch definefont pop pop pop - } - { - pop - } - ifelse - } - { - pop - exch - { - findfont - dup /Found get - dup length exch ?str1 cvs pop - ?str1 1 index (+) putinterval - ?str1 1 index 1 add 4 index ?str2 cvs putinterval - ?str1 exch 0 exch 5 4 roll ?str2 cvs length 1 add add getinterval cvn - 1 dict exch 1 index exch /FontName exch put copyfont - dup /FontName get exch definefont pop - } - { - pop - } - ifelse - } - ifelse - Adobe_CoolType_Data /AddWidths? get - { grestore Adobe_CoolType_Data /AddWidths? false put } - if - } bind def -/?sh - { - currentfont /Downloaded known { exch } if pop - } bind def -/?chp - { - currentfont /Downloaded known { pop } { false chp } ifelse - } bind def -/?mv - { - currentfont /Downloaded known { moveto pop pop } { pop pop moveto } ifelse - } bind def -setpacking -userdict /$SubstituteFont 25 dict put -1 dict - begin - /SubstituteFont - dup $error exch 2 copy known - { get } - { pop pop { pop /Courier } bind } - ifelse def - /currentdistillerparams where dup - { - pop pop - currentdistillerparams /CannotEmbedFontPolicy 2 copy known - { get /Error eq } - { pop pop false } - ifelse - } - if not - { - countdictstack array dictstack 0 get - begin - userdict - begin - $SubstituteFont - begin - /$str 128 string def - /$fontpat 128 string def - /$slen 0 def - /$sname null def - /$match false def - /$fontname null def - /$substituteFound false def - /$inVMIndex null def - /$doSmartSub true def - /$depth 0 def - /$fontname null def - /$italicangle 26.5 def - /$dstack null def - /$Strategies 10 dict dup - begin - /$Type3Underprint - { - currentglobal exch false setglobal - 11 dict - begin - /UseFont exch - $WMode 0 ne - { - dup length dict copy - dup /WMode $WMode put - /UseFont exch definefont - } - if def - /FontName $fontname dup type /stringtype eq { cvn } if def - /FontType 3 def - /FontMatrix [ .001 0 0 .001 0 0 ] def - /Encoding 256 array dup 0 1 255 { /.notdef put dup } for pop def - /FontBBox [ 0 0 0 0 ] def - /CCInfo 7 dict dup - begin - /cc null def - /x 0 def - /y 0 def - end def - /BuildChar - { - exch - begin - CCInfo - begin - 1 string dup 0 3 index put exch pop - /cc exch def - UseFont 1000 scalefont setfont - cc stringwidth /y exch def /x exch def - x y setcharwidth - $SubstituteFont /$Strategy get /$Underprint get exec - 0 0 moveto cc show - x y moveto - end - end - } bind def - currentdict - end - exch setglobal - } bind def - /$GetaTint - 2 dict dup - begin - /$BuildFont - { - dup /WMode known - { dup /WMode get } - { 0 } - ifelse - /$WMode exch def - $fontname exch - dup /FontName known - { - dup /FontName get - dup type /stringtype eq { cvn } if - } - { /unnamedfont } - ifelse - exch - Adobe_CoolType_Data /InVMDeepCopiedFonts get - 1 index /FontName get known - { - pop - Adobe_CoolType_Data /InVMDeepCopiedFonts get - 1 index get - null copyfont - } - { $deepcopyfont } - ifelse - exch 1 index exch /FontBasedOn exch put - dup /FontName $fontname dup type /stringtype eq { cvn } if put - definefont - Adobe_CoolType_Data /InVMDeepCopiedFonts get - begin - dup /FontBasedOn get 1 index def - end - } bind def - /$Underprint - { - gsave - x abs y abs gt - { /y 1000 def } - { /x -1000 def 500 120 translate } - ifelse - Level2? - { - [ /Separation (All) /DeviceCMYK { 0 0 0 1 pop } ] - setcolorspace - } - { 0 setgray } - ifelse - 10 setlinewidth - x .8 mul - [ 7 3 ] - { - y mul 8 div 120 sub x 10 div exch moveto - 0 y 4 div neg rlineto - dup 0 rlineto - 0 y 4 div rlineto - closepath - gsave - Level2? - { .2 setcolor } - { .8 setgray } - ifelse - fill grestore - stroke - } - forall - pop - grestore - } bind def - end def - /$Oblique - 1 dict dup - begin - /$BuildFont - { - currentglobal exch dup gcheck setglobal - null copyfont - begin - /FontBasedOn - currentdict /FontName known - { - FontName - dup type /stringtype eq { cvn } if - } - { /unnamedfont } - ifelse - def - /FontName $fontname dup type /stringtype eq { cvn } if def - /currentdistillerparams where - { pop } - { - /FontInfo currentdict /FontInfo known - { FontInfo null copyfont } - { 2 dict } - ifelse - dup - begin - /ItalicAngle $italicangle def - /FontMatrix FontMatrix - [ 1 0 ItalicAngle dup sin exch cos div 1 0 0 ] - matrix concatmatrix readonly - end - 4 2 roll def - def - } - ifelse - FontName currentdict - end - definefont - exch setglobal - } bind def - end def - /$None - 1 dict dup - begin - /$BuildFont {} bind def - end def - end def - /$Oblique SetSubstituteStrategy - /$findfontByEnum - { - dup type /stringtype eq { cvn } if - dup /$fontname exch def - $sname null eq - { $str cvs dup length $slen sub $slen getinterval } - { pop $sname } - ifelse - $fontpat dup 0 (fonts/*) putinterval exch 7 exch putinterval - /$match false def - $SubstituteFont /$dstack countdictstack array dictstack put - mark - { - $fontpat 0 $slen 7 add getinterval - { /$match exch def exit } - $str filenameforall - } - stopped - { - cleardictstack - currentdict - true - $SubstituteFont /$dstack get - { - exch - { - 1 index eq - { pop false } - { true } - ifelse - } - { begin false } - ifelse - } - forall - pop - } - if - cleartomark - /$slen 0 def - $match false ne - { $match (fonts/) anchorsearch pop pop cvn } - { /Courier } - ifelse - } bind def - /$ROS 1 dict dup - begin - /Adobe 4 dict dup - begin - /Japan1 [ /Ryumin-Light /HeiseiMin-W3 - /GothicBBB-Medium /HeiseiKakuGo-W5 - /HeiseiMaruGo-W4 /Jun101-Light ] def - /Korea1 [ /HYSMyeongJo-Medium /HYGoThic-Medium ] def - /GB1 [ /STSong-Light /STHeiti-Regular ] def - /CNS1 [ /MKai-Medium /MHei-Medium ] def - end def - end def - /$cmapname null def - /$deepcopyfont - { - dup /FontType get 0 eq - { - 1 dict dup /FontName /copied put copyfont - begin - /FDepVector FDepVector copyarray - 0 1 2 index length 1 sub - { - 2 copy get $deepcopyfont - dup /FontName /copied put - /copied exch definefont - 3 copy put pop pop - } - for - def - currentdict - end - } - { $Strategies /$Type3Underprint get exec } - ifelse - } bind def - /$buildfontname - { - dup /CIDFont findresource /CIDSystemInfo get - begin - Registry length Ordering length Supplement 8 string cvs - 3 copy length 2 add add add string - dup 5 1 roll dup 0 Registry putinterval - dup 4 index (-) putinterval - dup 4 index 1 add Ordering putinterval - 4 2 roll add 1 add 2 copy (-) putinterval - end - 1 add 2 copy 0 exch getinterval $cmapname $fontpat cvs exch - anchorsearch - { pop pop 3 2 roll putinterval cvn /$cmapname exch def } - { pop pop pop pop pop } - ifelse - length - $str 1 index (-) putinterval 1 add - $str 1 index $cmapname $fontpat cvs putinterval - $cmapname length add - $str exch 0 exch getinterval cvn - } bind def - /$findfontByROS - { - /$fontname exch def - $ROS Registry 2 copy known - { - get Ordering 2 copy known - { get } - { pop pop [] } - ifelse - } - { pop pop [] } - ifelse - false exch - { - dup /CIDFont resourcestatus - { - pop pop - save - 1 index /CIDFont findresource - dup /WidthsOnly known - { dup /WidthsOnly get } - { false } - ifelse - exch pop - exch restore - { pop } - { exch pop true exit } - ifelse - } - { pop } - ifelse - } - forall - { $str cvs $buildfontname } - { - false (*) - { - save exch - dup /CIDFont findresource - dup /WidthsOnly known - { dup /WidthsOnly get not } - { true } - ifelse - exch /CIDSystemInfo get - dup /Registry get Registry eq - exch /Ordering get Ordering eq and and - { exch restore exch pop true exit } - { pop restore } - ifelse - } - $str /CIDFont resourceforall - { $buildfontname } - { $fontname $findfontByEnum } - ifelse - } - ifelse - } bind def - end - end - currentdict /$error known currentdict /languagelevel known and dup - { pop $error /SubstituteFont known } - if - dup - { $error } - { Adobe_CoolType_Core } - ifelse - begin - { - /SubstituteFont - /CMap /Category resourcestatus - { - pop pop - { - $SubstituteFont - begin - /$substituteFound true def - dup length $slen gt - $sname null ne or - $slen 0 gt and - { - $sname null eq - { dup $str cvs dup length $slen sub $slen getinterval cvn } - { $sname } - ifelse - Adobe_CoolType_Data /InVMFontsByCMap get - 1 index 2 copy known - { - get - false exch - { - pop - currentglobal - { - GlobalFontDirectory 1 index known - { exch pop true exit } - { pop } - ifelse - } - { - FontDirectory 1 index known - { exch pop true exit } - { - GlobalFontDirectory 1 index known - { exch pop true exit } - { pop } - ifelse - } - ifelse - } - ifelse - } - forall - } - { pop pop false } - ifelse - { - exch pop exch pop - } - { - dup /CMap resourcestatus - { - pop pop - dup /$cmapname exch def - /CMap findresource /CIDSystemInfo get { def } forall - $findfontByROS - } - { - 128 string cvs - dup (-) search - { - 3 1 roll search - { - 3 1 roll pop - { dup cvi } - stopped - { pop pop pop pop pop $findfontByEnum } - { - 4 2 roll pop pop - exch length - exch - 2 index length - 2 index - sub - exch 1 sub -1 0 - { - $str cvs dup length - 4 index - 0 - 4 index - 4 3 roll add - getinterval - exch 1 index exch 3 index exch - putinterval - dup /CMap resourcestatus - { - pop pop - 4 1 roll pop pop pop - dup /$cmapname exch def - /CMap findresource /CIDSystemInfo get { def } forall - $findfontByROS - true exit - } - { pop } - ifelse - } - for - dup type /booleantype eq - { pop } - { pop pop pop $findfontByEnum } - ifelse - } - ifelse - } - { pop pop pop $findfontByEnum } - ifelse - } - { pop pop $findfontByEnum } - ifelse - } - ifelse - } - ifelse - } - { //SubstituteFont exec } - ifelse - /$slen 0 def - end - } - } - { - { - $SubstituteFont - begin - /$substituteFound true def - dup length $slen gt - $sname null ne or - $slen 0 gt and - { $findfontByEnum } - { //SubstituteFont exec } - ifelse - end - } - } - ifelse - bind readonly def - Adobe_CoolType_Core /scfindfont /systemfindfont load put - } - { - /scfindfont - { - $SubstituteFont - begin - dup systemfindfont - dup /FontName known - { dup /FontName get dup 3 index ne } - { /noname true } - ifelse - dup - { - /$origfontnamefound 2 index def - /$origfontname 4 index def /$substituteFound true def - } - if - exch pop - { - $slen 0 gt - $sname null ne - 3 index length $slen gt or and - { - pop dup $findfontByEnum findfont - dup maxlength 1 add dict - begin - { 1 index /FID eq { pop pop } { def } ifelse } - forall - currentdict - end - definefont - dup /FontName known { dup /FontName get } { null } ifelse - $origfontnamefound ne - { - $origfontname $str cvs print - ( substitution revised, using ) print - dup /FontName known - { dup /FontName get } { (unspecified font) } - ifelse - $str cvs print (.\n) print - } - if - } - { exch pop } - ifelse - } - { exch pop } - ifelse - end - } bind def - } - ifelse - end - end - Adobe_CoolType_Core_Defined not - { - Adobe_CoolType_Core /findfont - { - $SubstituteFont - begin - $depth 0 eq - { - /$fontname 1 index dup type /stringtype ne { $str cvs } if def - /$substituteFound false def - } - if - /$depth $depth 1 add def - end - scfindfont - $SubstituteFont - begin - /$depth $depth 1 sub def - $substituteFound $depth 0 eq and - { - $inVMIndex null ne - { dup $inVMIndex $AddInVMFont } - if - $doSmartSub - { - currentdict /$Strategy known - { $Strategy /$BuildFont get exec } - if - } - if - } - if - end - } bind put - } - if - } - if - end -/$AddInVMFont - { - exch /FontName 2 copy known - { - get - 1 dict dup begin exch 1 index gcheck def end exch - Adobe_CoolType_Data /InVMFontsByCMap get exch - $DictAdd - } - { pop pop pop } - ifelse - } bind def -/$DictAdd - { - 2 copy known not - { 2 copy 4 index length dict put } - if - Level2? not - { - 2 copy get dup maxlength exch length 4 index length add lt - 2 copy get dup length 4 index length add exch maxlength 1 index lt - { - 2 mul dict - begin - 2 copy get { forall } def - 2 copy currentdict put - end - } - { pop } - ifelse - } - if - get - begin - { def } - forall - end - } bind def -end -end -%%EndResource -%%BeginResource: procset Adobe_CoolType_Utility_MAKEOCF 1.19 0 -%%Copyright: Copyright 1987-2003 Adobe Systems Incorporated. -%%Version: 1.19 0 -systemdict /languagelevel known dup - { currentglobal false setglobal } - { false } -ifelse -exch -userdict /Adobe_CoolType_Utility 2 copy known - { 2 copy get dup maxlength 25 add dict copy } - { 25 dict } -ifelse put -Adobe_CoolType_Utility - begin - /ct_Level2? exch def - /ct_Clone? 1183615869 internaldict dup - /CCRun known not - exch /eCCRun known not - ct_Level2? and or def -ct_Level2? - { globaldict begin currentglobal true setglobal } -if - /ct_AddStdCIDMap - ct_Level2? - { { - ((Hex) 57 StartData - 0615 1e27 2c39 1c60 d8a8 cc31 fe2b f6e0 - 7aa3 e541 e21c 60d8 a8c9 c3d0 6d9e 1c60 - d8a8 c9c2 02d7 9a1c 60d8 a849 1c60 d8a8 - cc36 74f4 1144 b13b 77) 0 () /SubFileDecode filter cvx exec - } } - { { - eexec - } } - ifelse bind def -userdict /cid_extensions known -dup { cid_extensions /cid_UpdateDB known and } if - { - cid_extensions - begin - /cid_GetCIDSystemInfo - { - 1 index type /stringtype eq - { exch cvn exch } - if - cid_extensions - begin - dup load 2 index known - { - 2 copy - cid_GetStatusInfo - dup null ne - { - 1 index load - 3 index get - dup null eq - { pop pop cid_UpdateDB } - { - exch - 1 index /Created get eq - { exch pop exch pop } - { pop cid_UpdateDB } - ifelse - } - ifelse - } - { pop cid_UpdateDB } - ifelse - } - { cid_UpdateDB } - ifelse - end - } bind def - end - } -if -ct_Level2? - { end setglobal } -if - /ct_UseNativeCapability? systemdict /composefont known def - /ct_MakeOCF 35 dict def - /ct_Vars 25 dict def - /ct_GlyphDirProcs 6 dict def - /ct_BuildCharDict 15 dict dup - begin - /charcode 2 string def - /dst_string 1500 string def - /nullstring () def - /usewidths? true def - end def - ct_Level2? { setglobal } { pop } ifelse - ct_GlyphDirProcs - begin - /GetGlyphDirectory - { - systemdict /languagelevel known - { pop /CIDFont findresource /GlyphDirectory get } - { - 1 index /CIDFont findresource /GlyphDirectory - get dup type /dicttype eq - { - dup dup maxlength exch length sub 2 index lt - { - dup length 2 index add dict copy 2 index - /CIDFont findresource/GlyphDirectory 2 index put - } - if - } - if - exch pop exch pop - } - ifelse - + - } def - /+ - { - systemdict /languagelevel known - { - currentglobal false setglobal - 3 dict begin - /vm exch def - } - { 1 dict begin } - ifelse - /$ exch def - systemdict /languagelevel known - { - vm setglobal - /gvm currentglobal def - $ gcheck setglobal - } - if - ? { $ begin } if - } def - /? { $ type /dicttype eq } def - /| { - userdict /Adobe_CoolType_Data known - { - Adobe_CoolType_Data /AddWidths? known - { - currentdict Adobe_CoolType_Data - begin - begin - AddWidths? - { - Adobe_CoolType_Data /CC 3 index put - ? { def } { $ 3 1 roll put } ifelse - CC charcode exch 1 index 0 2 index 256 idiv put - 1 index exch 1 exch 256 mod put - stringwidth 2 array astore - currentfont /Widths get exch CC exch put - } - { ? { def } { $ 3 1 roll put } ifelse } - ifelse - end - end - } - { ? { def } { $ 3 1 roll put } ifelse } ifelse - } - { ? { def } { $ 3 1 roll put } ifelse } - ifelse - } def - /! - { - ? { end } if - systemdict /languagelevel known - { gvm setglobal } - if - end - } def - /: { string currentfile exch readstring pop } executeonly def - end - ct_MakeOCF - begin - /ct_cHexEncoding - [/c00/c01/c02/c03/c04/c05/c06/c07/c08/c09/c0A/c0B/c0C/c0D/c0E/c0F/c10/c11/c12 - /c13/c14/c15/c16/c17/c18/c19/c1A/c1B/c1C/c1D/c1E/c1F/c20/c21/c22/c23/c24/c25 - /c26/c27/c28/c29/c2A/c2B/c2C/c2D/c2E/c2F/c30/c31/c32/c33/c34/c35/c36/c37/c38 - /c39/c3A/c3B/c3C/c3D/c3E/c3F/c40/c41/c42/c43/c44/c45/c46/c47/c48/c49/c4A/c4B - /c4C/c4D/c4E/c4F/c50/c51/c52/c53/c54/c55/c56/c57/c58/c59/c5A/c5B/c5C/c5D/c5E - /c5F/c60/c61/c62/c63/c64/c65/c66/c67/c68/c69/c6A/c6B/c6C/c6D/c6E/c6F/c70/c71 - /c72/c73/c74/c75/c76/c77/c78/c79/c7A/c7B/c7C/c7D/c7E/c7F/c80/c81/c82/c83/c84 - /c85/c86/c87/c88/c89/c8A/c8B/c8C/c8D/c8E/c8F/c90/c91/c92/c93/c94/c95/c96/c97 - /c98/c99/c9A/c9B/c9C/c9D/c9E/c9F/cA0/cA1/cA2/cA3/cA4/cA5/cA6/cA7/cA8/cA9/cAA - /cAB/cAC/cAD/cAE/cAF/cB0/cB1/cB2/cB3/cB4/cB5/cB6/cB7/cB8/cB9/cBA/cBB/cBC/cBD - /cBE/cBF/cC0/cC1/cC2/cC3/cC4/cC5/cC6/cC7/cC8/cC9/cCA/cCB/cCC/cCD/cCE/cCF/cD0 - /cD1/cD2/cD3/cD4/cD5/cD6/cD7/cD8/cD9/cDA/cDB/cDC/cDD/cDE/cDF/cE0/cE1/cE2/cE3 - /cE4/cE5/cE6/cE7/cE8/cE9/cEA/cEB/cEC/cED/cEE/cEF/cF0/cF1/cF2/cF3/cF4/cF5/cF6 - /cF7/cF8/cF9/cFA/cFB/cFC/cFD/cFE/cFF] def - /ct_CID_STR_SIZE 8000 def - /ct_mkocfStr100 100 string def - /ct_defaultFontMtx [.001 0 0 .001 0 0] def - /ct_1000Mtx [1000 0 0 1000 0 0] def - /ct_raise {exch cvx exch errordict exch get exec stop} bind def - /ct_reraise - { cvx $error /errorname get (Error: ) print dup ( ) cvs print - errordict exch get exec stop - } bind def - /ct_cvnsi - { - 1 index add 1 sub 1 exch 0 4 1 roll - { - 2 index exch get - exch 8 bitshift - add - } - for - exch pop - } bind def - /ct_GetInterval - { - Adobe_CoolType_Utility /ct_BuildCharDict get - begin - /dst_index 0 def - dup dst_string length gt - { dup string /dst_string exch def } - if - 1 index ct_CID_STR_SIZE idiv - /arrayIndex exch def - 2 index arrayIndex get - 2 index - arrayIndex ct_CID_STR_SIZE mul - sub - { - dup 3 index add 2 index length le - { - 2 index getinterval - dst_string dst_index 2 index putinterval - length dst_index add /dst_index exch def - exit - } - { - 1 index length 1 index sub - dup 4 1 roll - getinterval - dst_string dst_index 2 index putinterval - pop dup dst_index add /dst_index exch def - sub - /arrayIndex arrayIndex 1 add def - 2 index dup length arrayIndex gt - { arrayIndex get } - { - pop - exit - } - ifelse - 0 - } - ifelse - } - loop - pop pop pop - dst_string 0 dst_index getinterval - end - } bind def - ct_Level2? - { - /ct_resourcestatus - currentglobal mark true setglobal - { /unknowninstancename /Category resourcestatus } - stopped - { cleartomark setglobal true } - { cleartomark currentglobal not exch setglobal } - ifelse - { - { - mark 3 1 roll /Category findresource - begin - ct_Vars /vm currentglobal put - ({ResourceStatus} stopped) 0 () /SubFileDecode filter cvx exec - { cleartomark false } - { { 3 2 roll pop true } { cleartomark false } ifelse } - ifelse - ct_Vars /vm get setglobal - end - } - } - { { resourcestatus } } - ifelse bind def - /CIDFont /Category ct_resourcestatus - { pop pop } - { - currentglobal true setglobal - /Generic /Category findresource - dup length dict copy - dup /InstanceType /dicttype put - /CIDFont exch /Category defineresource pop - setglobal - } - ifelse - ct_UseNativeCapability? - { - /CIDInit /ProcSet findresource begin - 12 dict begin - begincmap - /CIDSystemInfo 3 dict dup begin - /Registry (Adobe) def - /Ordering (Identity) def - /Supplement 0 def - end def - /CMapName /Identity-H def - /CMapVersion 1.000 def - /CMapType 1 def - 1 begincodespacerange - <0000> - endcodespacerange - 1 begincidrange - <0000> 0 - endcidrange - endcmap - CMapName currentdict /CMap defineresource pop - end - end - } - if - } - { - /ct_Category 2 dict begin - /CIDFont 10 dict def - /ProcSet 2 dict def - currentdict - end - def - /defineresource - { - ct_Category 1 index 2 copy known - { - get - dup dup maxlength exch length eq - { - dup length 10 add dict copy - ct_Category 2 index 2 index put - } - if - 3 index 3 index put - pop exch pop - } - { pop pop /defineresource /undefined ct_raise } - ifelse - } bind def - /findresource - { - ct_Category 1 index 2 copy known - { - get - 2 index 2 copy known - { get 3 1 roll pop pop} - { pop pop /findresource /undefinedresource ct_raise } - ifelse - } - { pop pop /findresource /undefined ct_raise } - ifelse - } bind def - /resourcestatus - { - ct_Category 1 index 2 copy known - { - get - 2 index known - exch pop exch pop - { - 0 -1 true - } - { - false - } - ifelse - } - { pop pop /findresource /undefined ct_raise } - ifelse - } bind def - /ct_resourcestatus /resourcestatus load def - } - ifelse - /ct_CIDInit 2 dict - begin - /ct_cidfont_stream_init - { - { - dup (Binary) eq - { - pop - null - currentfile - ct_Level2? - { - { cid_BYTE_COUNT () /SubFileDecode filter } - stopped - { pop pop pop } - if - } - if - /readstring load - exit - } - if - dup (Hex) eq - { - pop - currentfile - ct_Level2? - { - { null exch /ASCIIHexDecode filter /readstring } - stopped - { pop exch pop (>) exch /readhexstring } - if - } - { (>) exch /readhexstring } - ifelse - load - exit - } - if - /StartData /typecheck ct_raise - } - loop - cid_BYTE_COUNT ct_CID_STR_SIZE le - { - 2 copy cid_BYTE_COUNT string exch exec - pop - 1 array dup - 3 -1 roll - 0 exch put - } - { - cid_BYTE_COUNT ct_CID_STR_SIZE div ceiling cvi - dup array exch 2 sub 0 exch 1 exch - { - 2 copy - 5 index - ct_CID_STR_SIZE - string - 6 index exec - pop - put - pop - } - for - 2 index - cid_BYTE_COUNT ct_CID_STR_SIZE mod string - 3 index exec - pop - 1 index exch - 1 index length 1 sub - exch put - } - ifelse - cid_CIDFONT exch /GlyphData exch put - 2 index null eq - { - pop pop pop - } - { - pop /readstring load - 1 string exch - { - 3 copy exec - pop - dup length 0 eq - { - pop pop pop pop pop - true exit - } - if - 4 index - eq - { - pop pop pop pop - false exit - } - if - } - loop - pop - } - ifelse - } bind def - /StartData - { - mark - { - currentdict - dup /FDArray get 0 get /FontMatrix get - 0 get 0.001 eq - { - dup /CDevProc known not - { - /CDevProc 1183615869 internaldict /stdCDevProc 2 copy known - { get } - { - pop pop - { pop pop pop pop pop 0 -1000 7 index 2 div 880 } - } - ifelse - def - } - if - } - { - /CDevProc - { - pop pop pop pop pop - 0 - 1 cid_temp /cid_CIDFONT get - /FDArray get 0 get - /FontMatrix get 0 get div - 7 index 2 div - 1 index 0.88 mul - } def - } - ifelse - /cid_temp 15 dict def - cid_temp - begin - /cid_CIDFONT exch def - 3 copy pop - dup /cid_BYTE_COUNT exch def 0 gt - { - ct_cidfont_stream_init - FDArray - { - /Private get - dup /SubrMapOffset known - { - begin - /Subrs SubrCount array def - Subrs - SubrMapOffset - SubrCount - SDBytes - ct_Level2? - { - currentdict dup /SubrMapOffset undef - dup /SubrCount undef - /SDBytes undef - } - if - end - /cid_SD_BYTES exch def - /cid_SUBR_COUNT exch def - /cid_SUBR_MAP_OFFSET exch def - /cid_SUBRS exch def - cid_SUBR_COUNT 0 gt - { - GlyphData cid_SUBR_MAP_OFFSET cid_SD_BYTES ct_GetInterval - 0 cid_SD_BYTES ct_cvnsi - 0 1 cid_SUBR_COUNT 1 sub - { - exch 1 index - 1 add - cid_SD_BYTES mul cid_SUBR_MAP_OFFSET add - GlyphData exch cid_SD_BYTES ct_GetInterval - 0 cid_SD_BYTES ct_cvnsi - cid_SUBRS 4 2 roll - GlyphData exch - 4 index - 1 index - sub - ct_GetInterval - dup length string copy put - } - for - pop - } - if - } - { pop } - ifelse - } - forall - } - if - cleartomark pop pop - end - CIDFontName currentdict /CIDFont defineresource pop - end end - } - stopped - { cleartomark /StartData ct_reraise } - if - } bind def - currentdict - end def - /ct_saveCIDInit - { - /CIDInit /ProcSet ct_resourcestatus - { true } - { /CIDInitC /ProcSet ct_resourcestatus } - ifelse - { - pop pop - /CIDInit /ProcSet findresource - ct_UseNativeCapability? - { pop null } - { /CIDInit ct_CIDInit /ProcSet defineresource pop } - ifelse - } - { /CIDInit ct_CIDInit /ProcSet defineresource pop null } - ifelse - ct_Vars exch /ct_oldCIDInit exch put - } bind def - /ct_restoreCIDInit - { - ct_Vars /ct_oldCIDInit get dup null ne - { /CIDInit exch /ProcSet defineresource pop } - { pop } - ifelse - } bind def - /ct_BuildCharSetUp - { - 1 index - begin - CIDFont - begin - Adobe_CoolType_Utility /ct_BuildCharDict get - begin - /ct_dfCharCode exch def - /ct_dfDict exch def - CIDFirstByte ct_dfCharCode add - dup CIDCount ge - { pop 0 } - if - /cid exch def - { - GlyphDirectory cid 2 copy known - { get } - { pop pop nullstring } - ifelse - dup length FDBytes sub 0 gt - { - dup - FDBytes 0 ne - { 0 FDBytes ct_cvnsi } - { pop 0 } - ifelse - /fdIndex exch def - dup length FDBytes sub FDBytes exch getinterval - /charstring exch def - exit - } - { - pop - cid 0 eq - { /charstring nullstring def exit } - if - /cid 0 def - } - ifelse - } - loop - } def - /ct_SetCacheDevice - { - 0 0 moveto - dup stringwidth - 3 -1 roll - true charpath - pathbbox - 0 -1000 - 7 index 2 div 880 - setcachedevice2 - 0 0 moveto - } def - /ct_CloneSetCacheProc - { - 1 eq - { - stringwidth - pop -2 div -880 - 0 -1000 setcharwidth - moveto - } - { - usewidths? - { - currentfont /Widths get cid - 2 copy known - { get exch pop aload pop } - { pop pop stringwidth } - ifelse - } - { stringwidth } - ifelse - setcharwidth - 0 0 moveto - } - ifelse - } def - /ct_Type3ShowCharString - { - ct_FDDict fdIndex 2 copy known - { get } - { - currentglobal 3 1 roll - 1 index gcheck setglobal - ct_Type1FontTemplate dup maxlength dict copy - begin - FDArray fdIndex get - dup /FontMatrix 2 copy known - { get } - { pop pop ct_defaultFontMtx } - ifelse - /FontMatrix exch dup length array copy def - /Private get - /Private exch def - /Widths rootfont /Widths get def - /CharStrings 1 dict dup /.notdef - dup length string copy put def - currentdict - end - /ct_Type1Font exch definefont - dup 5 1 roll put - setglobal - } - ifelse - dup /CharStrings get 1 index /Encoding get - ct_dfCharCode get charstring put - rootfont /WMode 2 copy known - { get } - { pop pop 0 } - ifelse - exch - 1000 scalefont setfont - ct_str1 0 ct_dfCharCode put - ct_str1 exch ct_dfSetCacheProc - ct_SyntheticBold - { - currentpoint - ct_str1 show - newpath - moveto - ct_str1 true charpath - ct_StrokeWidth setlinewidth - stroke - } - { ct_str1 show } - ifelse - } def - /ct_Type4ShowCharString - { - ct_dfDict ct_dfCharCode charstring - FDArray fdIndex get - dup /FontMatrix get dup ct_defaultFontMtx ct_matrixeq not - { ct_1000Mtx matrix concatmatrix concat } - { pop } - ifelse - /Private get - Adobe_CoolType_Utility /ct_Level2? get not - { - ct_dfDict /Private - 3 -1 roll - { put } - 1183615869 internaldict /superexec get exec - } - if - 1183615869 internaldict - Adobe_CoolType_Utility /ct_Level2? get - { 1 index } - { 3 index /Private get mark 6 1 roll } - ifelse - dup /RunInt known - { /RunInt get } - { pop /CCRun } - ifelse - get exec - Adobe_CoolType_Utility /ct_Level2? get not - { cleartomark } - if - } bind def - /ct_BuildCharIncremental - { - { - Adobe_CoolType_Utility /ct_MakeOCF get begin - ct_BuildCharSetUp - ct_ShowCharString - } - stopped - { stop } - if - end - end - end - end - } bind def - /BaseFontNameStr (BF00) def - /ct_Type1FontTemplate 14 dict - begin - /FontType 1 def - /FontMatrix [0.001 0 0 0.001 0 0] def - /FontBBox [-250 -250 1250 1250] def - /Encoding ct_cHexEncoding def - /PaintType 0 def - currentdict - end def - /BaseFontTemplate 11 dict - begin - /FontMatrix [0.001 0 0 0.001 0 0] def - /FontBBox [-250 -250 1250 1250] def - /Encoding ct_cHexEncoding def - /BuildChar /ct_BuildCharIncremental load def - ct_Clone? - { - /FontType 3 def - /ct_ShowCharString /ct_Type3ShowCharString load def - /ct_dfSetCacheProc /ct_CloneSetCacheProc load def - /ct_SyntheticBold false def - /ct_StrokeWidth 1 def - } - { - /FontType 4 def - /Private 1 dict dup /lenIV 4 put def - /CharStrings 1 dict dup /.notdef put def - /PaintType 0 def - /ct_ShowCharString /ct_Type4ShowCharString load def - } - ifelse - /ct_str1 1 string def - currentdict - end def - /BaseFontDictSize BaseFontTemplate length 5 add def - /ct_matrixeq - { - true 0 1 5 - { - dup 4 index exch get exch 3 index exch get eq and - dup not - { exit } - if - } - for - exch pop exch pop - } bind def - /ct_makeocf - { - 15 dict - begin - exch /WMode exch def - exch /FontName exch def - /FontType 0 def - /FMapType 2 def - dup /FontMatrix known - { dup /FontMatrix get /FontMatrix exch def } - { /FontMatrix matrix def } - ifelse - /bfCount 1 index /CIDCount get 256 idiv 1 add - dup 256 gt { pop 256} if def - /Encoding - 256 array 0 1 bfCount 1 sub { 2 copy dup put pop } for - bfCount 1 255 { 2 copy bfCount put pop } for - def - /FDepVector bfCount dup 256 lt { 1 add } if array def - BaseFontTemplate BaseFontDictSize dict copy - begin - /CIDFont exch def - CIDFont /FontBBox known - { CIDFont /FontBBox get /FontBBox exch def } - if - CIDFont /CDevProc known - { CIDFont /CDevProc get /CDevProc exch def } - if - currentdict - end - BaseFontNameStr 3 (0) putinterval - 0 1 bfCount dup 256 eq { 1 sub } if - { - FDepVector exch - 2 index BaseFontDictSize dict copy - begin - dup /CIDFirstByte exch 256 mul def - FontType 3 eq - { /ct_FDDict 2 dict def } - if - currentdict - end - 1 index 16 - BaseFontNameStr 2 2 getinterval cvrs pop - BaseFontNameStr exch definefont - put - } - for - ct_Clone? - { /Widths 1 index /CIDFont get /GlyphDirectory get length dict def } - if - FontName - currentdict - end - definefont - ct_Clone? - { - gsave - dup 1000 scalefont setfont - ct_BuildCharDict - begin - /usewidths? false def - currentfont /Widths get - begin - exch /CIDFont get /GlyphDirectory get - { - pop - dup charcode exch 1 index 0 2 index 256 idiv put - 1 index exch 1 exch 256 mod put - stringwidth 2 array astore def - } - forall - end - /usewidths? true def - end - grestore - } - { exch pop } - ifelse - } bind def - /ct_ComposeFont - { - ct_UseNativeCapability? - { - 2 index /CMap ct_resourcestatus - { pop pop exch pop } - { - /CIDInit /ProcSet findresource - begin - 12 dict - begin - begincmap - /CMapName 3 index def - /CMapVersion 1.000 def - /CMapType 1 def - exch /WMode exch def - /CIDSystemInfo 3 dict dup - begin - /Registry (Adobe) def - /Ordering - CMapName ct_mkocfStr100 cvs - (Adobe-) search - { - pop pop - (-) search - { - dup length string copy - exch pop exch pop - } - { pop (Identity)} - ifelse - } - { pop (Identity) } - ifelse - def - /Supplement 0 def - end def - 1 begincodespacerange - <0000> - endcodespacerange - 1 begincidrange - <0000> 0 - endcidrange - endcmap - CMapName currentdict /CMap defineresource pop - end - end - } - ifelse - composefont - } - { - 3 2 roll pop - 0 get /CIDFont findresource - ct_makeocf - } - ifelse - } bind def - /ct_MakeIdentity - { - ct_UseNativeCapability? - { - 1 index /CMap ct_resourcestatus - { pop pop } - { - /CIDInit /ProcSet findresource begin - 12 dict begin - begincmap - /CMapName 2 index def - /CMapVersion 1.000 def - /CMapType 1 def - /CIDSystemInfo 3 dict dup - begin - /Registry (Adobe) def - /Ordering - CMapName ct_mkocfStr100 cvs - (Adobe-) search - { - pop pop - (-) search - { dup length string copy exch pop exch pop } - { pop (Identity) } - ifelse - } - { pop (Identity) } - ifelse - def - /Supplement 0 def - end def - 1 begincodespacerange - <0000> - endcodespacerange - 1 begincidrange - <0000> 0 - endcidrange - endcmap - CMapName currentdict /CMap defineresource pop - end - end - } - ifelse - composefont - } - { - exch pop - 0 get /CIDFont findresource - ct_makeocf - } - ifelse - } bind def - currentdict readonly pop - end - end -%%EndResource -%%BeginResource: procset Adobe_CoolType_Utility_T42 1.0 0 -%%Copyright: Copyright 1987-2003 Adobe Systems Incorporated. -%%Version: 1.0 0 -userdict /ct_T42Dict 15 dict put -ct_T42Dict begin -/Is2015? -{ - version - cvi - 2015 - ge -} bind def -/AllocGlyphStorage -{ - Is2015? - { - pop - } - { - {string} forall - } ifelse -} bind def -/Type42DictBegin -{ - 25 dict begin - /FontName exch def - /CharStrings 256 dict - begin - /.notdef 0 def - currentdict - end def - /Encoding exch def - /PaintType 0 def - /FontType 42 def - /FontMatrix [1 0 0 1 0 0] def - 4 array astore cvx /FontBBox exch def - /sfnts -} bind def -/Type42DictEnd -{ - currentdict dup /FontName get exch definefont end - ct_T42Dict exch - dup /FontName get exch put -} bind def -/RD {string currentfile exch readstring pop} executeonly def -/PrepFor2015 -{ - Is2015? - { - /GlyphDirectory - 16 - dict def - sfnts 0 get - dup - 2 index - (glyx) - putinterval - 2 index - (locx) - putinterval - pop - pop - } - { - pop - pop - } ifelse -} bind def -/AddT42Char -{ - Is2015? - { - /GlyphDirectory get - begin - def - end - pop - pop - } - { - /sfnts get - 4 index - get - 3 index - 2 index - putinterval - pop - pop - pop - pop - } ifelse -} bind def -end -%%EndResource -Adobe_CoolType_Core begin /$Oblique SetSubstituteStrategy end -%%BeginResource: procset Adobe_AGM_Image 1.0 0 -%%Version: 1.0 0 -%%Copyright: Copyright (C) 2000-2003 Adobe Systems, Inc. All Rights Reserved. -systemdict /setpacking known -{ - currentpacking - true setpacking -} if -userdict /Adobe_AGM_Image 75 dict dup begin put -/Adobe_AGM_Image_Id /Adobe_AGM_Image_1.0_0 def -/nd{ - null def -}bind def -/AGMIMG_&image nd -/AGMIMG_&colorimage nd -/AGMIMG_&imagemask nd -/AGMIMG_mbuf () def -/AGMIMG_ybuf () def -/AGMIMG_kbuf () def -/AGMIMG_c 0 def -/AGMIMG_m 0 def -/AGMIMG_y 0 def -/AGMIMG_k 0 def -/AGMIMG_tmp nd -/AGMIMG_imagestring0 nd -/AGMIMG_imagestring1 nd -/AGMIMG_imagestring2 nd -/AGMIMG_imagestring3 nd -/AGMIMG_imagestring4 nd -/AGMIMG_imagestring5 nd -/AGMIMG_cnt nd -/AGMIMG_fsave nd -/AGMIMG_colorAry nd -/AGMIMG_override nd -/AGMIMG_name nd -/AGMIMG_maskSource nd -/invert_image_samples nd -/knockout_image_samples nd -/img nd -/sepimg nd -/devnimg nd -/idximg nd -/doc_setup -{ - Adobe_AGM_Core begin - Adobe_AGM_Image begin - /AGMIMG_&image systemdict/image get def - /AGMIMG_&imagemask systemdict/imagemask get def - /colorimage where{ - pop - /AGMIMG_&colorimage /colorimage ldf - }if - end - end -}def -/page_setup -{ - Adobe_AGM_Image begin - /AGMIMG_ccimage_exists {/customcolorimage where - { - pop - /Adobe_AGM_OnHost_Seps where - { - pop false - }{ - /Adobe_AGM_InRip_Seps where - { - pop false - }{ - true - }ifelse - }ifelse - }{ - false - }ifelse - }bdf - level2{ - /invert_image_samples - { - Adobe_AGM_Image/AGMIMG_tmp Decode length ddf - /Decode [ Decode 1 get Decode 0 get] def - }def - /knockout_image_samples - { - Operator/imagemask ne{ - /Decode [1 1] def - }if - }def - }{ - /invert_image_samples - { - {1 exch sub} currenttransfer addprocs settransfer - }def - /knockout_image_samples - { - { pop 1 } currenttransfer addprocs settransfer - }def - }ifelse - /img /imageormask ldf - /sepimg /sep_imageormask ldf - /devnimg /devn_imageormask ldf - /idximg /indexed_imageormask ldf - /_ctype 7 def - currentdict{ - dup xcheck 1 index type dup /arraytype eq exch /packedarraytype eq or and{ - bind - }if - def - }forall -}def -/page_trailer -{ - end -}def -/doc_trailer -{ -}def -/imageormask_sys -{ - begin - save mark - level2{ - currentdict - Operator /imagemask eq{ - AGMIMG_&imagemask - }{ - use_mask { - level3 {process_mask_L3 AGMIMG_&image}{masked_image_simulation}ifelse - }{ - AGMIMG_&image - }ifelse - }ifelse - }{ - Width Height - Operator /imagemask eq{ - Decode 0 get 1 eq Decode 1 get 0 eq and - ImageMatrix /DataSource load - AGMIMG_&imagemask - }{ - BitsPerComponent ImageMatrix /DataSource load - AGMIMG_&image - }ifelse - }ifelse - cleartomark restore - end -}def -/overprint_plate -{ - currentoverprint { - 0 get dup type /nametype eq { - dup /DeviceGray eq{ - pop AGMCORE_black_plate not - }{ - /DeviceCMYK eq{ - AGMCORE_is_cmyk_sep not - }if - }ifelse - }{ - false exch - { - AGMOHS_sepink eq or - } forall - not - } ifelse - }{ - pop false - }ifelse -}def -/process_mask_L3 -{ - dup begin - /ImageType 1 def - end - 4 dict begin - /DataDict exch def - /ImageType 3 def - /InterleaveType 3 def - /MaskDict 9 dict begin - /ImageType 1 def - /Width DataDict dup /MaskWidth known {/MaskWidth}{/Width} ifelse get def - /Height DataDict dup /MaskHeight known {/MaskHeight}{/Height} ifelse get def - /ImageMatrix [Width 0 0 Height neg 0 Height] def - /NComponents 1 def - /BitsPerComponent 1 def - /Decode [0 1] def - /DataSource AGMIMG_maskSource def - currentdict end def - currentdict end -}def -/use_mask -{ - dup type /dicttype eq - { - dup /Mask known { - dup /Mask get { - level3 - {true} - { - dup /MaskWidth known {dup /MaskWidth get 1 index /Width get eq}{true}ifelse exch - dup /MaskHeight known {dup /MaskHeight get 1 index /Height get eq}{true}ifelse - 3 -1 roll and - } ifelse - } - {false} ifelse - } - {false} ifelse - } - {false} ifelse -}def -/make_line_source -{ - begin - MultipleDataSources { - [ - Decode length 2 div cvi {Width string} repeat - ] - }{ - Width Decode length 2 div mul cvi string - }ifelse - end -}def -/datasource_to_str -{ - exch dup type - dup /filetype eq { - pop exch readstring - }{ - /arraytype eq { - exec exch copy - }{ - pop - }ifelse - }ifelse - pop -}def -/masked_image_simulation -{ - 3 dict begin - dup make_line_source /line_source xdf - /mask_source AGMIMG_maskSource /LZWDecode filter def - dup /Width get 8 div ceiling cvi string /mask_str xdf - begin - gsave - 0 1 translate 1 -1 Height div scale - 1 1 Height { - pop - gsave - MultipleDataSources { - 0 1 DataSource length 1 sub { - dup DataSource exch get - exch line_source exch get - datasource_to_str - } for - }{ - DataSource line_source datasource_to_str - } ifelse - << - /PatternType 1 - /PaintProc [ - /pop cvx - << - /ImageType 1 - /Width Width - /Height 1 - /ImageMatrix Width 1.0 sub 1 matrix scale 0.5 0 matrix translate matrix concatmatrix - /MultipleDataSources MultipleDataSources - /DataSource line_source - /BitsPerComponent BitsPerComponent - /Decode Decode - >> - /image cvx - ] cvx - /BBox [0 0 Width 1] - /XStep Width - /YStep 1 - /PaintType 1 - /TilingType 2 - >> - matrix makepattern set_pattern - << - /ImageType 1 - /Width Width - /Height 1 - /ImageMatrix Width 1 matrix scale - /MultipleDataSources false - /DataSource mask_source mask_str readstring pop - /BitsPerComponent 1 - /Decode [0 1] - >> - imagemask - grestore - 0 1 translate - } for - grestore - end - end -}def -/imageormask -{ - begin - SkipImageProc { - currentdict consumeimagedata - } - { - save mark - level2 AGMCORE_host_sep not and{ - currentdict - Operator /imagemask eq DeviceN_PS2 not and { - imagemask - }{ - AGMCORE_in_rip_sep currentoverprint and currentcolorspace 0 get /DeviceGray eq and{ - [/Separation /Black /DeviceGray {}] setcolorspace - /Decode [ Decode 1 get Decode 0 get ] def - }if - use_mask { - level3 {process_mask_L3 image}{masked_image_simulation}ifelse - }{ - DeviceN_NoneName DeviceN_PS2 Indexed_DeviceN level3 not and or or AGMCORE_in_rip_sep and - { - Names convert_to_process not { - 2 dict begin - /imageDict xdf - /names_index 0 def - gsave - imageDict write_image_file { - Names { - dup (None) ne { - [/Separation 3 -1 roll /DeviceGray {1 exch sub}] setcolorspace - Operator imageDict read_image_file - names_index 0 eq {true setoverprint} if - /names_index names_index 1 add def - }{ - pop - } ifelse - } forall - close_image_file - } if - grestore - end - }{ - Operator /imagemask eq { - imagemask - }{ - image - } ifelse - } ifelse - }{ - Operator /imagemask eq { - imagemask - }{ - image - } ifelse - } ifelse - }ifelse - }ifelse - }{ - Width Height - Operator /imagemask eq{ - Decode 0 get 1 eq Decode 1 get 0 eq and - ImageMatrix /DataSource load - /Adobe_AGM_OnHost_Seps where { - pop imagemask - }{ - currentgray 1 ne{ - currentdict imageormask_sys - }{ - currentoverprint not{ - 1 AGMCORE_&setgray - currentdict imageormask_sys - }{ - currentdict ignoreimagedata - }ifelse - }ifelse - }ifelse - }{ - BitsPerComponent ImageMatrix - MultipleDataSources{ - 0 1 NComponents 1 sub{ - DataSource exch get - }for - }{ - /DataSource load - }ifelse - Operator /colorimage eq{ - AGMCORE_host_sep{ - MultipleDataSources level2 or NComponents 4 eq and{ - AGMCORE_is_cmyk_sep{ - MultipleDataSources{ - /DataSource [ - DataSource 0 get /exec cvx - DataSource 1 get /exec cvx - DataSource 2 get /exec cvx - DataSource 3 get /exec cvx - /AGMCORE_get_ink_data cvx - ] cvx def - }{ - /DataSource - Width BitsPerComponent mul 7 add 8 idiv Height mul 4 mul - /DataSource load - filter_cmyk 0 () /SubFileDecode filter def - }ifelse - /Decode [ Decode 0 get Decode 1 get ] def - /MultipleDataSources false def - /NComponents 1 def - /Operator /image def - invert_image_samples - 1 AGMCORE_&setgray - currentdict imageormask_sys - }{ - currentoverprint not Operator/imagemask eq and{ - 1 AGMCORE_&setgray - currentdict imageormask_sys - }{ - currentdict ignoreimagedata - }ifelse - }ifelse - }{ - MultipleDataSources NComponents AGMIMG_&colorimage - }ifelse - }{ - true NComponents colorimage - }ifelse - }{ - Operator /image eq{ - AGMCORE_host_sep{ - /DoImage true def - HostSepColorImage{ - invert_image_samples - }{ - AGMCORE_black_plate not Operator/imagemask ne and{ - /DoImage false def - currentdict ignoreimagedata - }if - }ifelse - 1 AGMCORE_&setgray - DoImage - {currentdict imageormask_sys} if - }{ - use_mask { - level3 {process_mask_L3 image}{masked_image_simulation}ifelse - }{ - image - }ifelse - }ifelse - }{ - Operator/knockout eq{ - pop pop pop pop pop - currentcolorspace overprint_plate not{ - knockout_unitsq - }if - }if - }ifelse - }ifelse - }ifelse - }ifelse - cleartomark restore - }ifelse - end -}def -/sep_imageormask -{ - /sep_colorspace_dict AGMCORE_gget begin - /MappedCSA CSA map_csa def - begin - SkipImageProc { - currentdict consumeimagedata - } - { - save mark - AGMCORE_avoid_L2_sep_space{ - /Decode [ Decode 0 get 255 mul Decode 1 get 255 mul ] def - }if - AGMIMG_ccimage_exists - MappedCSA 0 get /DeviceCMYK eq and - currentdict/Components known and - Name () ne and - Name (All) ne and - Operator /image eq and - AGMCORE_producing_seps not and - level2 not and - { - Width Height BitsPerComponent ImageMatrix - [ - /DataSource load /exec cvx - { - 0 1 2 index length 1 sub{ - 1 index exch - 2 copy get 255 xor put - }for - } /exec cvx - ] cvx bind - MappedCSA 0 get /DeviceCMYK eq{ - Components aload pop - }{ - 0 0 0 Components aload pop 1 exch sub - }ifelse - Name findcmykcustomcolor - customcolorimage - }{ - AGMCORE_producing_seps not{ - level2{ - AGMCORE_avoid_L2_sep_space not currentcolorspace 0 get /Separation ne and{ - [/Separation Name MappedCSA sep_proc_name exch 0 get exch load ] setcolorspace_opt - /sep_tint AGMCORE_gget setcolor - }if - currentdict imageormask - }{ - currentdict - Operator /imagemask eq{ - imageormask - }{ - sep_imageormask_lev1 - }ifelse - }ifelse - }{ - AGMCORE_host_sep{ - Operator/knockout eq{ - currentdict/ImageMatrix get concat - knockout_unitsq - }{ - currentgray 1 ne{ - AGMCORE_is_cmyk_sep Name (All) ne and{ - level2{ - [ /Separation Name [/DeviceGray] - { - sep_colorspace_proc AGMCORE_get_ink_data - 1 exch sub - } bind - ] AGMCORE_&setcolorspace - /sep_tint AGMCORE_gget AGMCORE_&setcolor - currentdict imageormask_sys - }{ - currentdict - Operator /imagemask eq{ - imageormask_sys - }{ - sep_image_lev1_sep - }ifelse - }ifelse - }{ - Operator/imagemask ne{ - invert_image_samples - }if - currentdict imageormask_sys - }ifelse - }{ - currentoverprint not Name (All) eq or Operator/imagemask eq and{ - currentdict imageormask_sys - }{ - currentoverprint not - { - gsave - knockout_unitsq - grestore - }if - currentdict consumeimagedata - }ifelse - }ifelse - }ifelse - }{ - currentcolorspace 0 get /Separation ne{ - [/Separation Name MappedCSA sep_proc_name exch 0 get exch load ] setcolorspace_opt - /sep_tint AGMCORE_gget setcolor - }if - currentoverprint - MappedCSA 0 get /DeviceCMYK eq and - Name inRip_spot_has_ink not and - Name (All) ne and { - imageormask_l2_overprint - }{ - currentdict imageormask - }ifelse - }ifelse - }ifelse - }ifelse - cleartomark restore - }ifelse - end - end -}def -/decode_image_sample -{ - 4 1 roll exch dup 5 1 roll - sub 2 4 -1 roll exp 1 sub div mul add -} bdf -/colorSpaceElemCnt -{ - currentcolorspace 0 get dup /DeviceCMYK eq { - pop 4 - } - { - /DeviceRGB eq { - pop 3 - }{ - 1 - } ifelse - } ifelse -} bdf -/devn_sep_datasource -{ - 1 dict begin - /dataSource xdf - [ - 0 1 dataSource length 1 sub { - dup currentdict /dataSource get /exch cvx /get cvx /exec cvx - /exch cvx names_index /ne cvx [ /pop cvx ] cvx /if cvx - } for - ] cvx bind - end -} bdf -/devn_alt_datasource -{ - 11 dict begin - /srcDataStrs xdf - /dstDataStr xdf - /convProc xdf - /origcolorSpaceElemCnt xdf - /origMultipleDataSources xdf - /origBitsPerComponent xdf - /origDecode xdf - /origDataSource xdf - /dsCnt origMultipleDataSources {origDataSource length}{1}ifelse def - /samplesNeedDecoding - 0 0 1 origDecode length 1 sub { - origDecode exch get add - } for - origDecode length 2 div div - dup 1 eq { - /decodeDivisor 2 origBitsPerComponent exp 1 sub def - } if - 2 origBitsPerComponent exp 1 sub ne - def - [ - 0 1 dsCnt 1 sub [ - currentdict /origMultipleDataSources get { - dup currentdict /origDataSource get exch get dup type - }{ - currentdict /origDataSource get dup type - } ifelse - dup /filetype eq { - pop currentdict /srcDataStrs get 3 -1 /roll cvx /get cvx /readstring cvx /pop cvx - }{ - /stringtype ne { - /exec cvx - } if - currentdict /srcDataStrs get /exch cvx 3 -1 /roll cvx /xpt cvx - } ifelse - ] cvx /for cvx - currentdict /srcDataStrs get 0 /get cvx /length cvx 0 /ne cvx [ - 0 1 Width 1 sub [ - Adobe_AGM_Utils /AGMUTIL_ndx /xddf cvx - currentdict /origMultipleDataSources get { - 0 1 dsCnt 1 sub [ - Adobe_AGM_Utils /AGMUTIL_ndx1 /xddf cvx - currentdict /srcDataStrs get /AGMUTIL_ndx1 /load cvx /get cvx /AGMUTIL_ndx /load cvx /get cvx - samplesNeedDecoding { - currentdict /decodeDivisor known { - currentdict /decodeDivisor get /div cvx - }{ - currentdict /origDecode get /AGMUTIL_ndx1 /load cvx 2 /mul cvx 2 /getinterval cvx /aload cvx /pop cvxs - BitsPerComponent /decode_image_sample load /exec cvx - } ifelse - } if - ] cvx /for cvx - }{ - Adobe_AGM_Utils /AGMUTIL_ndx1 0 /ddf cvx - currentdict /srcDataStrs get 0 /get cvx /AGMUTIL_ndx /load cvx - currentdict /origDecode get length 2 idiv dup 3 1 /roll cvx /mul cvx /exch cvx /getinterval cvx - [ - samplesNeedDecoding { - currentdict /decodeDivisor known { - currentdict /decodeDivisor get /div cvx - }{ - currentdict /origDecode get /AGMUTIL_ndx1 /load cvx 2 /mul cvx 2 /getinterval cvx /aload cvx /pop cvx - BitsPerComponent /decode_image_sample load /exec cvx - Adobe_AGM_Utils /AGMUTIL_ndx1 /AGMUTIL_ndx1 /load cvx 1 /add cvx /ddf cvx - } ifelse - } if - ] cvx /forall cvx - } ifelse - currentdict /convProc get /exec cvx - currentdict /origcolorSpaceElemCnt get 1 sub -1 0 [ - currentdict /dstDataStr get 3 1 /roll cvx /AGMUTIL_ndx /load cvx currentdict /origcolorSpaceElemCnt get /mul cvx /add cvx /exch cvx - currentdict /convProc get /filter_indexed_devn load ne { - 255 /mul cvx /cvi cvx - } if - /put cvx - ] cvx /for cvx - ] cvx /for cvx - currentdict /dstDataStr get - ] cvx /if cvx - ] cvx bind - end -} bdf -/devn_imageormask -{ - /devicen_colorspace_dict AGMCORE_gget begin - /MappedCSA CSA map_csa def - 2 dict begin - dup dup - /dstDataStr exch /Width get colorSpaceElemCnt mul string def - /srcDataStrs [ 3 -1 roll begin - currentdict /MultipleDataSources known {MultipleDataSources {DataSource length}{1}ifelse}{1} ifelse - { - Width Decode length 2 div mul cvi string - } repeat - end ] def - begin - SkipImageProc { - currentdict consumeimagedata - } - { - save mark - AGMCORE_producing_seps not { - level3 not { - Operator /imagemask ne { - /DataSource [ - DataSource Decode BitsPerComponent currentdict /MultipleDataSources known {MultipleDataSources}{false} ifelse - colorSpaceElemCnt /devicen_colorspace_dict AGMCORE_gget /TintTransform get - dstDataStr srcDataStrs devn_alt_datasource /exec cvx - ] cvx 0 () /SubFileDecode filter def - /MultipleDataSources false def - /Decode colorSpaceElemCnt [ exch {0 1} repeat ] def - } if - }if - currentdict imageormask - }{ - AGMCORE_host_sep{ - Names convert_to_process { - CSA map_csa 0 get /DeviceCMYK eq { - /DataSource - Width BitsPerComponent mul 7 add 8 idiv Height mul 4 mul - [ - DataSource Decode BitsPerComponent currentdict /MultipleDataSources known {MultipleDataSources}{false} ifelse - 4 /devicen_colorspace_dict AGMCORE_gget /TintTransform get - dstDataStr srcDataStrs devn_alt_datasource /exec cvx - ] cvx - filter_cmyk 0 () /SubFileDecode filter def - /MultipleDataSources false def - /Decode [1 0] def - /DeviceGray setcolorspace - currentdict imageormask_sys - }{ - AGMCORE_report_unsupported_color_space - AGMCORE_black_plate { - /DataSource [ - DataSource Decode BitsPerComponent currentdict /MultipleDataSources known {MultipleDataSources}{false} ifelse - CSA map_csa 0 get /DeviceRGB eq{3}{1}ifelse /devicen_colorspace_dict AGMCORE_gget /TintTransform get - dstDataStr srcDataStrs devn_alt_datasource /exec cvx - ] cvx 0 () /SubFileDecode filter def - /MultipleDataSources false def - /Decode colorSpaceElemCnt [ exch {0 1} repeat ] def - currentdict imageormask_sys - } - { - gsave - knockout_unitsq - grestore - currentdict consumeimagedata - } ifelse - } ifelse - } - { - /devicen_colorspace_dict AGMCORE_gget /names_index known { - Operator/imagemask ne{ - MultipleDataSources { - /DataSource [ DataSource devn_sep_datasource /exec cvx ] cvx def - /MultipleDataSources false def - }{ - /DataSource /DataSource load dstDataStr srcDataStrs 0 get filter_devn def - } ifelse - invert_image_samples - } if - currentdict imageormask_sys - }{ - currentoverprint not Operator/imagemask eq and{ - currentdict imageormask_sys - }{ - currentoverprint not - { - gsave - knockout_unitsq - grestore - }if - currentdict consumeimagedata - }ifelse - }ifelse - }ifelse - }{ - currentdict imageormask - }ifelse - }ifelse - cleartomark restore - }ifelse - end - end - end -}def -/imageormask_l2_overprint -{ - currentdict - currentcmykcolor add add add 0 eq{ - currentdict consumeimagedata - }{ - level3{ - currentcmykcolor - /AGMIMG_k xdf - /AGMIMG_y xdf - /AGMIMG_m xdf - /AGMIMG_c xdf - Operator/imagemask eq{ - [/DeviceN [ - AGMIMG_c 0 ne {/Cyan} if - AGMIMG_m 0 ne {/Magenta} if - AGMIMG_y 0 ne {/Yellow} if - AGMIMG_k 0 ne {/Black} if - ] /DeviceCMYK {}] setcolorspace - AGMIMG_c 0 ne {AGMIMG_c} if - AGMIMG_m 0 ne {AGMIMG_m} if - AGMIMG_y 0 ne {AGMIMG_y} if - AGMIMG_k 0 ne {AGMIMG_k} if - setcolor - }{ - /Decode [ Decode 0 get 255 mul Decode 1 get 255 mul ] def - [/Indexed - [ - /DeviceN [ - AGMIMG_c 0 ne {/Cyan} if - AGMIMG_m 0 ne {/Magenta} if - AGMIMG_y 0 ne {/Yellow} if - AGMIMG_k 0 ne {/Black} if - ] - /DeviceCMYK { - AGMIMG_k 0 eq {0} if - AGMIMG_y 0 eq {0 exch} if - AGMIMG_m 0 eq {0 3 1 roll} if - AGMIMG_c 0 eq {0 4 1 roll} if - } - ] - 255 - { - 255 div - mark exch - dup dup dup - AGMIMG_k 0 ne{ - /sep_tint AGMCORE_gget mul MappedCSA sep_proc_name exch pop load exec 4 1 roll pop pop pop - counttomark 1 roll - }{ - pop - }ifelse - AGMIMG_y 0 ne{ - /sep_tint AGMCORE_gget mul MappedCSA sep_proc_name exch pop load exec 4 2 roll pop pop pop - counttomark 1 roll - }{ - pop - }ifelse - AGMIMG_m 0 ne{ - /sep_tint AGMCORE_gget mul MappedCSA sep_proc_name exch pop load exec 4 3 roll pop pop pop - counttomark 1 roll - }{ - pop - }ifelse - AGMIMG_c 0 ne{ - /sep_tint AGMCORE_gget mul MappedCSA sep_proc_name exch pop load exec pop pop pop - counttomark 1 roll - }{ - pop - }ifelse - counttomark 1 add -1 roll pop - } - ] setcolorspace - }ifelse - imageormask_sys - }{ - write_image_file{ - currentcmykcolor - 0 ne{ - [/Separation /Black /DeviceGray {}] setcolorspace - gsave - /Black - [{1 exch sub /sep_tint AGMCORE_gget mul} /exec cvx MappedCSA sep_proc_name cvx exch pop {4 1 roll pop pop pop 1 exch sub} /exec cvx] - cvx modify_halftone_xfer - Operator currentdict read_image_file - grestore - }if - 0 ne{ - [/Separation /Yellow /DeviceGray {}] setcolorspace - gsave - /Yellow - [{1 exch sub /sep_tint AGMCORE_gget mul} /exec cvx MappedCSA sep_proc_name cvx exch pop {4 2 roll pop pop pop 1 exch sub} /exec cvx] - cvx modify_halftone_xfer - Operator currentdict read_image_file - grestore - }if - 0 ne{ - [/Separation /Magenta /DeviceGray {}] setcolorspace - gsave - /Magenta - [{1 exch sub /sep_tint AGMCORE_gget mul} /exec cvx MappedCSA sep_proc_name cvx exch pop {4 3 roll pop pop pop 1 exch sub} /exec cvx] - cvx modify_halftone_xfer - Operator currentdict read_image_file - grestore - }if - 0 ne{ - [/Separation /Cyan /DeviceGray {}] setcolorspace - gsave - /Cyan - [{1 exch sub /sep_tint AGMCORE_gget mul} /exec cvx MappedCSA sep_proc_name cvx exch pop {pop pop pop 1 exch sub} /exec cvx] - cvx modify_halftone_xfer - Operator currentdict read_image_file - grestore - } if - close_image_file - }{ - imageormask - }ifelse - }ifelse - }ifelse -} def -/indexed_imageormask -{ - begin - save mark - currentdict - AGMCORE_host_sep{ - Operator/knockout eq{ - /indexed_colorspace_dict AGMCORE_gget dup /CSA known { - /CSA get map_csa - }{ - /CSD get get_csd /Names get - } ifelse - overprint_plate not{ - knockout_unitsq - }if - }{ - Indexed_DeviceN { - /devicen_colorspace_dict AGMCORE_gget /names_index known { - indexed_image_lev2_sep - }{ - currentoverprint not{ - knockout_unitsq - }if - currentdict consumeimagedata - } ifelse - }{ - AGMCORE_is_cmyk_sep{ - Operator /imagemask eq{ - imageormask_sys - }{ - level2{ - indexed_image_lev2_sep - }{ - indexed_image_lev1_sep - }ifelse - }ifelse - }{ - currentoverprint not{ - knockout_unitsq - }if - currentdict consumeimagedata - }ifelse - }ifelse - }ifelse - }{ - level2{ - Indexed_DeviceN { - /indexed_colorspace_dict AGMCORE_gget begin - CSD get_csd begin - }{ - /indexed_colorspace_dict AGMCORE_gget begin - CSA map_csa 0 get /DeviceCMYK eq ps_level 3 ge and ps_version 3015.007 lt and { - [/Indexed [/DeviceN [/Cyan /Magenta /Yellow /Black] /DeviceCMYK {}] HiVal Lookup] - setcolorspace - } if - end - } ifelse - imageormask - Indexed_DeviceN { - end - end - } if - }{ - Operator /imagemask eq{ - imageormask - }{ - indexed_imageormask_lev1 - }ifelse - }ifelse - }ifelse - cleartomark restore - end -}def -/indexed_image_lev2_sep -{ - /indexed_colorspace_dict AGMCORE_gget begin - begin - Indexed_DeviceN not { - currentcolorspace - dup 1 /DeviceGray put - dup 3 - currentcolorspace 2 get 1 add string - 0 1 2 3 AGMCORE_get_ink_data 4 currentcolorspace 3 get length 1 sub - { - dup 4 idiv exch currentcolorspace 3 get exch get 255 exch sub 2 index 3 1 roll put - }for - put setcolorspace - } if - currentdict - Operator /imagemask eq{ - AGMIMG_&imagemask - }{ - use_mask { - level3 {process_mask_L3 AGMIMG_&image}{masked_image_simulation}ifelse - }{ - AGMIMG_&image - }ifelse - }ifelse - end end -}def - /OPIimage - { - dup type /dicttype ne{ - 10 dict begin - /DataSource xdf - /ImageMatrix xdf - /BitsPerComponent xdf - /Height xdf - /Width xdf - /ImageType 1 def - /Decode [0 1 def] - currentdict - end - }if - dup begin - /NComponents 1 cdndf - /MultipleDataSources false cdndf - /SkipImageProc {false} cdndf - /HostSepColorImage false cdndf - /Decode [ - 0 - currentcolorspace 0 get /Indexed eq{ - 2 BitsPerComponent exp 1 sub - }{ - 1 - }ifelse - ] cdndf - /Operator /image cdndf - end - /sep_colorspace_dict AGMCORE_gget null eq{ - imageormask - }{ - gsave - dup begin invert_image_samples end - sep_imageormask - grestore - }ifelse - }def -/cachemask_level2 -{ - 3 dict begin - /LZWEncode filter /WriteFilter xdf - /readBuffer 256 string def - /ReadFilter - currentfile - 0 (%EndMask) /SubFileDecode filter - /ASCII85Decode filter - /RunLengthDecode filter - def - { - ReadFilter readBuffer readstring exch - WriteFilter exch writestring - not {exit} if - }loop - WriteFilter closefile - end -}def -/cachemask_level3 -{ - currentfile - << - /Filter [ /SubFileDecode /ASCII85Decode /RunLengthDecode ] - /DecodeParms [ << /EODCount 0 /EODString (%EndMask) >> null null ] - /Intent 1 - >> - /ReusableStreamDecode filter -}def -/spot_alias -{ - /mapto_sep_imageormask - { - dup type /dicttype ne{ - 12 dict begin - /ImageType 1 def - /DataSource xdf - /ImageMatrix xdf - /BitsPerComponent xdf - /Height xdf - /Width xdf - /MultipleDataSources false def - }{ - begin - }ifelse - /Decode [/customcolor_tint AGMCORE_gget 0] def - /Operator /image def - /HostSepColorImage false def - /SkipImageProc {false} def - currentdict - end - sep_imageormask - }bdf - /customcolorimage - { - Adobe_AGM_Image/AGMIMG_colorAry xddf - /customcolor_tint AGMCORE_gget - bdict - /Name AGMIMG_colorAry 4 get - /CSA [ /DeviceCMYK ] - /TintMethod /Subtractive - /TintProc null - /MappedCSA null - /NComponents 4 - /Components [ AGMIMG_colorAry aload pop pop ] - edict - setsepcolorspace - mapto_sep_imageormask - }ndf - Adobe_AGM_Image/AGMIMG_&customcolorimage /customcolorimage load put - /customcolorimage - { - Adobe_AGM_Image/AGMIMG_override false put - dup 4 get map_alias{ - /customcolor_tint AGMCORE_gget exch setsepcolorspace - pop - mapto_sep_imageormask - }{ - AGMIMG_&customcolorimage - }ifelse - }bdf -}def -/snap_to_device -{ - 6 dict begin - matrix currentmatrix - dup 0 get 0 eq 1 index 3 get 0 eq and - 1 index 1 get 0 eq 2 index 2 get 0 eq and or exch pop - { - 1 1 dtransform 0 gt exch 0 gt /AGMIMG_xSign? exch def /AGMIMG_ySign? exch def - 0 0 transform - AGMIMG_ySign? {floor 0.1 sub}{ceiling 0.1 add} ifelse exch - AGMIMG_xSign? {floor 0.1 sub}{ceiling 0.1 add} ifelse exch - itransform /AGMIMG_llY exch def /AGMIMG_llX exch def - 1 1 transform - AGMIMG_ySign? {ceiling 0.1 add}{floor 0.1 sub} ifelse exch - AGMIMG_xSign? {ceiling 0.1 add}{floor 0.1 sub} ifelse exch - itransform /AGMIMG_urY exch def /AGMIMG_urX exch def - [AGMIMG_urX AGMIMG_llX sub 0 0 AGMIMG_urY AGMIMG_llY sub AGMIMG_llX AGMIMG_llY] concat - }{ - }ifelse - end -} def -level2 not{ - /colorbuf - { - 0 1 2 index length 1 sub{ - dup 2 index exch get - 255 exch sub - 2 index - 3 1 roll - put - }for - }def - /tint_image_to_color - { - begin - Width Height BitsPerComponent ImageMatrix - /DataSource load - end - Adobe_AGM_Image begin - /AGMIMG_mbuf 0 string def - /AGMIMG_ybuf 0 string def - /AGMIMG_kbuf 0 string def - { - colorbuf dup length AGMIMG_mbuf length ne - { - dup length dup dup - /AGMIMG_mbuf exch string def - /AGMIMG_ybuf exch string def - /AGMIMG_kbuf exch string def - } if - dup AGMIMG_mbuf copy AGMIMG_ybuf copy AGMIMG_kbuf copy pop - } - addprocs - {AGMIMG_mbuf}{AGMIMG_ybuf}{AGMIMG_kbuf} true 4 colorimage - end - } def - /sep_imageormask_lev1 - { - begin - MappedCSA 0 get dup /DeviceRGB eq exch /DeviceCMYK eq or has_color not and{ - { - 255 mul round cvi GrayLookup exch get - } currenttransfer addprocs settransfer - currentdict imageormask - }{ - /sep_colorspace_dict AGMCORE_gget/Components known{ - MappedCSA 0 get /DeviceCMYK eq{ - Components aload pop - }{ - 0 0 0 Components aload pop 1 exch sub - }ifelse - Adobe_AGM_Image/AGMIMG_k xddf - Adobe_AGM_Image/AGMIMG_y xddf - Adobe_AGM_Image/AGMIMG_m xddf - Adobe_AGM_Image/AGMIMG_c xddf - AGMIMG_y 0.0 eq AGMIMG_m 0.0 eq and AGMIMG_c 0.0 eq and{ - {AGMIMG_k mul 1 exch sub} currenttransfer addprocs settransfer - currentdict imageormask - }{ - currentcolortransfer - {AGMIMG_k mul 1 exch sub} exch addprocs 4 1 roll - {AGMIMG_y mul 1 exch sub} exch addprocs 4 1 roll - {AGMIMG_m mul 1 exch sub} exch addprocs 4 1 roll - {AGMIMG_c mul 1 exch sub} exch addprocs 4 1 roll - setcolortransfer - currentdict tint_image_to_color - }ifelse - }{ - MappedCSA 0 get /DeviceGray eq { - {255 mul round cvi ColorLookup exch get 0 get} currenttransfer addprocs settransfer - currentdict imageormask - }{ - MappedCSA 0 get /DeviceCMYK eq { - currentcolortransfer - {255 mul round cvi ColorLookup exch get 3 get 1 exch sub} exch addprocs 4 1 roll - {255 mul round cvi ColorLookup exch get 2 get 1 exch sub} exch addprocs 4 1 roll - {255 mul round cvi ColorLookup exch get 1 get 1 exch sub} exch addprocs 4 1 roll - {255 mul round cvi ColorLookup exch get 0 get 1 exch sub} exch addprocs 4 1 roll - setcolortransfer - currentdict tint_image_to_color - }{ - currentcolortransfer - {pop 1} exch addprocs 4 1 roll - {255 mul round cvi ColorLookup exch get 2 get} exch addprocs 4 1 roll - {255 mul round cvi ColorLookup exch get 1 get} exch addprocs 4 1 roll - {255 mul round cvi ColorLookup exch get 0 get} exch addprocs 4 1 roll - setcolortransfer - currentdict tint_image_to_color - }ifelse - }ifelse - }ifelse - }ifelse - end - }def - /sep_image_lev1_sep - { - begin - /sep_colorspace_dict AGMCORE_gget/Components known{ - Components aload pop - Adobe_AGM_Image/AGMIMG_k xddf - Adobe_AGM_Image/AGMIMG_y xddf - Adobe_AGM_Image/AGMIMG_m xddf - Adobe_AGM_Image/AGMIMG_c xddf - {AGMIMG_c mul 1 exch sub} - {AGMIMG_m mul 1 exch sub} - {AGMIMG_y mul 1 exch sub} - {AGMIMG_k mul 1 exch sub} - }{ - {255 mul round cvi ColorLookup exch get 0 get 1 exch sub} - {255 mul round cvi ColorLookup exch get 1 get 1 exch sub} - {255 mul round cvi ColorLookup exch get 2 get 1 exch sub} - {255 mul round cvi ColorLookup exch get 3 get 1 exch sub} - }ifelse - AGMCORE_get_ink_data currenttransfer addprocs settransfer - currentdict imageormask_sys - end - }def - /indexed_imageormask_lev1 - { - /indexed_colorspace_dict AGMCORE_gget begin - begin - currentdict - MappedCSA 0 get dup /DeviceRGB eq exch /DeviceCMYK eq or has_color not and{ - {HiVal mul round cvi GrayLookup exch get HiVal div} currenttransfer addprocs settransfer - imageormask - }{ - MappedCSA 0 get /DeviceGray eq { - {HiVal mul round cvi Lookup exch get HiVal div} currenttransfer addprocs settransfer - imageormask - }{ - MappedCSA 0 get /DeviceCMYK eq { - currentcolortransfer - {4 mul HiVal mul round cvi 3 add Lookup exch get HiVal div 1 exch sub} exch addprocs 4 1 roll - {4 mul HiVal mul round cvi 2 add Lookup exch get HiVal div 1 exch sub} exch addprocs 4 1 roll - {4 mul HiVal mul round cvi 1 add Lookup exch get HiVal div 1 exch sub} exch addprocs 4 1 roll - {4 mul HiVal mul round cvi Lookup exch get HiVal div 1 exch sub} exch addprocs 4 1 roll - setcolortransfer - tint_image_to_color - }{ - currentcolortransfer - {pop 1} exch addprocs 4 1 roll - {3 mul HiVal mul round cvi 2 add Lookup exch get HiVal div} exch addprocs 4 1 roll - {3 mul HiVal mul round cvi 1 add Lookup exch get HiVal div} exch addprocs 4 1 roll - {3 mul HiVal mul round cvi Lookup exch get HiVal div} exch addprocs 4 1 roll - setcolortransfer - tint_image_to_color - }ifelse - }ifelse - }ifelse - end end - }def - /indexed_image_lev1_sep - { - /indexed_colorspace_dict AGMCORE_gget begin - begin - {4 mul HiVal mul round cvi Lookup exch get HiVal div 1 exch sub} - {4 mul HiVal mul round cvi 1 add Lookup exch get HiVal div 1 exch sub} - {4 mul HiVal mul round cvi 2 add Lookup exch get HiVal div 1 exch sub} - {4 mul HiVal mul round cvi 3 add Lookup exch get HiVal div 1 exch sub} - AGMCORE_get_ink_data currenttransfer addprocs settransfer - currentdict imageormask_sys - end end - }def -}if -end -systemdict /setpacking known -{ - setpacking -} if -%%EndResource -currentdict Adobe_AGM_Utils eq {end} if -%%EndProlog -%%BeginSetup -Adobe_AGM_Utils begin -2 2010 Adobe_AGM_Core/doc_setup get exec -Adobe_CoolType_Core/doc_setup get exec -Adobe_AGM_Image/doc_setup get exec -currentdict Adobe_AGM_Utils eq {end} if -%%EndSetup -%%Page: Alternate-ISC-logo-v2.ai 1 -%%EndPageComments -%%BeginPageSetup -/currentdistillerparams where -{pop currentdistillerparams /CoreDistVersion get 5000 lt} {true} ifelse -{ userdict /AI11_PDFMark5 /cleartomark load put -userdict /AI11_ReadMetadata_PDFMark5 {flushfile cleartomark } bind put} -{ userdict /AI11_PDFMark5 /pdfmark load put -userdict /AI11_ReadMetadata_PDFMark5 {/PUT pdfmark} bind put } ifelse -[/NamespacePush AI11_PDFMark5 -[/_objdef {ai_metadata_stream_123} /type /stream /OBJ AI11_PDFMark5 -[{ai_metadata_stream_123} -currentfile 0 (% &&end XMP packet marker&&) -/SubFileDecode filter AI11_ReadMetadata_PDFMark5 - - - - - Adobe PDF library 6.66 - - - - - - - 2004-10-06T16:15:40-07:00 - 2004-10-22T21:51:43Z - Illustrator - 2004-10-06T16:15:40-07:00 - - - - JPEG - 256 - 152 - /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAmAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8AiX5AfkB5O/MTydea1rV5 qNvdW+oyWSJZSQJGY0ghlBIlhmblymPfMfLlMTQbIQBDOPM//OKX5U6B5e1DWZ9R1uSOxhaX0hcW il2H2U5G0NOTUFcOCcskxAVuWOaoQMj0Y1+Wf5EflJ56N+kUuvWEtgImZHu7OTmJS4+Glmv2eG+3 fMvXYJ6etwb8v2uPpNRHNdCqZz/0Jp+WH/V01v8A5H2n/ZLmv/MSczww7/oTT8sP+rprf/I+0/7J cfzEl8MO/wChNPyw/wCrprf/ACPtP+yXH8xJfDDAfzv/AOcc/JHkPyHN5g0i+1Oe9juIYVju5bd4 uMrUYkRwRNXw+LJ48xkaRKAAfT/5V/8AksPKH/bE07/qEjzJaiynFXYq7FXYq7FXYq7FXYq7FXYq 7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq+BfyU/MTzH5Nhnn0yUPbSzt9ZsZqtBJ8CAMVBFGHZ hv8ARtmz0uihnwkS58XPryDrdVqp4sorlXL5st1/z/8AmP5whlgu7p20+b7VnCqwW9AwYL250YD7 TE5eI6TSncgS+Zccy1OoGwPD8ggfLXmTzl5HvJLzTD9X9YKtwroksUiqSVVjvTc9iDlkp6bVjhsS +wsIxz6Y3Vfc9B1b/nJjWZ9Hhh03TYrPVmH+lXTt6sQp/vqM/wA3+UTT365iY+w4CVyNx7v1uTPt eRjsKk9s8j+YrjzH5W0/Wbm0aymu4wzwtsCRsXTcng1KrXemaHV4RiyGAN07jT5TkgJEVae5jNzx v/nLL/yT91/zG2v/ABM5dg+pjPk9M/Kv/wAlh5Q/7Ymnf9QkeZzjllOKuxV2KuxV2KuxV2KuxV2K uxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV+eX5W6Yl7aztLvBDMSy/zEqtB8tsyJ644NP6fr lI18hZcX8oMuf1fTGP6S9h0Ly3rGtzm20q1M7RgF6UVEXtyZiFHTbOa3ke8u52Adr3lvWNEnFtqt qYWkUlCSGRx3oykqeu+DeJ7iuxDANasU07UIriJFaF29RYmAK8kILKVPVc7bsjWnUYiJfVHY/oLy /aOlGHIDH6S+zNB1K31TRNP1K2UJb3lvFPEg6KsiBgu38taZzGaBhMxPMF6DHMSiCOoR2VM3jf8A zll/5J+6/wCY21/4mcuwfUxnyemflX/5LDyh/wBsTTv+oSPM5xyynFXYq7FXYq7FXYq7FXYq7FXY q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq+A/yedP0NepT4xccie5BRR+FMxNfE8ET0uX+9bNP IcZHWh+l9K/kxr2kW1neaZcSxwXskwmjaQhfUUqF4qT1Kla098wMUg5Mgq/nNrujzada6XDKk9+s 4mbgQ3pIEZaMR0Lcht9PhjlIWIeCebnQQ26U+MszA+AAAP31zoPZyJ4pnps6ftqQqI67s3/KGD81 YPMejRFNVh8ts6tKJ0mFp6HAsOPqDgFYUoVzYdonTGEvp4/hduJoRnE4/VwfY+lCyggEgE9B45yr 0Lxb/nLe8tYvyoe2kkCz3N7bmCM9W9NqtT5A5bhI4wFlAmBI5B6l+Vf/AJLDyh/2xNO/6hI8z3EL y3/nLq+1nQPJem69oWsalpWoyapHZytZX11BG8UltM5BijkVK8oFoaePjir0v8ooJB+W/lq8nu7u 9vNR0uyvLy5vbme6keaeBZXPKZ34jk52XbFWYYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7F XYq7FXYq7FXYq7FX5z/l3fy2Nq88Y5D1mDodgylE2zaafSR1GnMJfztvI0HWanUSw5xIfzf0l6Zb a3plwnITrGe6SkIR9+x+jOdz9k6jGa4TId43dti7QwzF8Ve/Zq61zTLdORmWU9kiIcn7th9Jw6fs nUZD9PCO+W37Vzdo4YDnfu3S3y5bW3mjzpptlqVwtnZ3U6xO5JoEFTwBAPxP9kH+Y+GdXDCNJpyI CyBfvPf+Ojz5ynU5xxbAvozTPzt/L2W4vbT60bO109R6E8qFY5kX4SIVUF9uylakduucN+aiSbfQ Z9gamMYkC+LoOnveJeYvzDnP5kTeatBmlMUUoayS7qRxMYSRCgbZHPLYHp4HMKWT18Qet03Zo/Kj DkA5b179vixD84/zA8y+btFi/TEsbJaSVt44o1jVTIRy6bn7I6nMzRZJSyi+4un7Y7OxabSS8Mcz G32N+Vf/AJLDyh/2xNO/6hI83jwxeUf85q/+Ss0r/tuW/wD1CXeKvVfyn/8AJWeTf+2Hpv8A1CR4 q8j8x/nX5n8ifnH5nGr28+o/l4tzp9rNKnxtp082nwSckAqQklWYp0Y1K/FUFV7F5gutN1/yJe6h pmoSNaT2M1xY6jp1zJC1fRfi6SwMh2PY9+o2xVjP5faLe+ZPyb8tx3WtanDPqNraXmo6jHeXBvpD QSMqXLSGSIOwAbifs1HeuKvOfzm0m/8ALHnz8tdI0fzJ5hhsfMmqG01aNta1GQyRC4tI6KzTEp8M 77rir2bQfIEWia5+kbXWtYurZ7SW2msNQ1G7voS7yROkyC4kk4OgjZajs2KvH9Is9R1n/nJrzd5Q utf12Py9p+mRXtnZQavqEQjmaOxJIZZg1K3D7Vpvir2Xy/5JTSdO1PTZdW1PUbS9ujcW8l3fXUlz bxmGKMwpcmT1uIkjZx8X7WKvB/8AnH/RPMX5gflhrGqaj5x8wQa/BqE9rYagNWvfTjEdtBLH6kLS NG685TyqtaYq9K/5xr86+aPOH5Yw6n5kJlvYbqa1hvWADXMMQUrK3EAVDM0ZPfjirHPzm/M7zt5G /M6wvNIt5NV8u22jC78waSrbCD620RuUG5R0LKC4FKfa23Cr1fyr5t8s+ePLcWraHeG5066HFzG7 RTROAC0UnAq8ci13FfwOKsS/JBbuS183fXNQv9Qaz8y6rp1s97eXFyUtbaVUijX1XYLxA6jfFWA6 RZ6jrP8Azk15u8oXWv67H5e0/TIr2zsoNX1CIRzNHYkkMswalbh9q03xV6vB+XE8Oi3+ijzJrJs7 2/S8W5e+uJL6GBI4gbWK8eQzIjSxFiQfssy964q8i/ObSb/yx58/LXSNH8yeYYbHzJqhtNWjbWtR kMkQuLSOis0xKfDO+64q9n0DyDFoWvDU7XWtXurdrWW2m0/UdRur+Eu8kTpMq3MknF0EbLUdmxVl WKuxV2KuxV2KuxV8tf8AOKPkvyrr35Z6zJq+mQ3k02qy2zTSL+8WJLa3dVRxRk+JyaqQcqnqsmMj hkR1T4EJg8QtKPzn/LXS/JV9pzaXNNJaakJisc5VijQlKqGULUfvO4zoezNdLODxAXGnR6/SRwkc PIsk/Ln8gtN17QNP17V9RnSO9VpPqMCKhCh2VaysXryVQ32B1+nMXW9ryxzMIgbdf2ORpezIziJS PPownzdp3kO384XUWjyXMOkWbMrRg82kkiFCsEjVKhn25PWg+LfZc1uP2mIgRKPFLoeh9/7Ofk9P H2GyT4JxkIxl9Q6x93f+hj2oXjXt9cXjIsbXEjStGleILmpArU985ORs2+nYcfhwEbJ4RW/PZG2X l+4mAec+ih6LSrn6O2TjiJdNre38WI8MPXL7Pn+Pek/5j6Pa2nliWWMuW9WMfEQep9gM2GhxgZHm O0u2cuoxGEhER8v7X2j+Vf8A5LDyh/2xNO/6hI83LzpeUf8AOapH/KrdKWu51yAgd6C0uv64q9V/ KYg/lZ5Np/1Y9N/6hI8VYb5Q0/SvMf5j/nBpWq2yXNhdzaVbXVq+4ZBp/p12oQTwqCNwehqMVea6 5Yeb/wAgZ9Tgtlm1r8qtdWWJVrym0+edCq1rQA1NK/ZkHg2Kvevyiiji/KrycqDip0TT2I93tY2Y /STiryz/AJyO/wDJp/kv/wBtw/8AUXp+KvoDFXzXp/lvSfMH/OXnney1P6x6CaPbzJ9VurmyfmsG nKKyWskLkUY/CWp3psMVe6+U/LmkeW0vdK064llV5hfGK5nluZo1nURqGlneSRlLQNxLH27Yq+XP yK8n+e9f/IrzOPKfmS5025fULiJdIRLcQ3LLa2zOPXaP6xE8qNwqkqjYV74q93/Ij8xPLvmnyhBp tjaR6Pq2hItnqnl9FMZtnj+CqI3xemxB3O4NQ2+KqFxLDN/zkwllKitGfJMpYPQhxLqiqUKkb7R4 q8984/l15r/JzzNP+YP5axNd+WZjy8w+WBXikIqzMgFf3a7lSByj90qMVehf8476tZ635O1fXrON ooNZ8watqCJJTmFuLkugehI5BKA0xV57p/lvSfMH/OXnney1P6x6CaPbzJ9VurmyfmsGnKKyWskL kUY/CWp3psMVe6+U/LmkeW0vdK064llV5hfGK5nluZo1nURqGlneSRlLQNxLH27Yq8e/5yO/8mn+ S/8A23D/ANRen4q+gMVdirsVdirsVdirsVfOv/OGn/ksNU/7bc//AFCWuYeo+pux8ntWreX9C1hE TVtOttQWLl6X1mFJeHOnLhzB41oOmQx5pw+kke5M8UZ/UAUFq3mDyp5P0+zhv7iLTLI0t7KMIxUB F+yqxq1AB36ZTlzC7kdy5ek0OTN6cUb4Q+XvzM13S9c866lqGmRJHZO4SOSMcfWKDi0xG28h36dO u+arLIGRIfRey9PPDp4xmfV93l8EHoGmqVF5KtTX9yD2p+1/TJ4odXS9vdpkHwYH+t+r9f8AanuZ DyTEPzS/5RKX/jNF/wASzJ0f1teb6X2H+Vf/AJLDyh/2xNO/6hI82zhlb51/K3yR52EK+aLGXUYr ducMBvLyGJXpx5CKGaNOVO9MVTHy15Q0Ly1p0em6MlxBYQp6UFvJd3VwkaDosYnll4AduOKoTRfy 68p6Lr1/r2m29xDq2qFG1G4a9vZfXMYIT1ElmeNuAYhart2xVPNS03T9TsJ9P1G3ju7G6QxXFtMo eN0bYqynYjFWtK0yx0rTLPS9Pi9CwsII7W0hBZgkMKBI1qxZjxVQNzXFWO+avys8j+a9VstV16xm u7/TW9TT5heXkIgcFTyiSGaNENY1NQOoxVlFvAkEKQoXKIKAyO8jfS7lmP0nFWDXn5Gflnd69P5g n066Ot3NPW1FNT1KOZqKEHxpcqacVAxVO9F8g+WdFsr6z02K5ij1Fle8le+vZZ3ZAFWlxLM8y0Ap RXGKqPkr8s/JfkmGWDyxZSafbzuZZbf63dzRNIVCl/TmlkTlxUCtMVWXX5XeRbjzT/ir9Gm28wkF ZNRs7i5s5JAQAfVFtJEslaCvMHFVWb8ufKU3mtfNklvcnzAkRt0vhfXqlYCxcxCMTCMR8mJ4caYq yUgEUO4PUYql2g+W9D8v2cllotlHYWck0lw1vCCsYklNXKrWignstBirFLz8jPyzu9en8wT6ddHW 7mnraimp6lHM1FCD40uVNOKgYqyLyx5N8v8AllLpNHhmjN66y3Ulxc3N5I7KvFayXUkz0A7A0xVL vNX5WeR/Neq2Wq69YzXd/prepp8wvLyEQOCp5RJDNGiGsamoHUYqyi3gSCFIULlEFAZHeRvpdyzH 6TiqpirsVdirsVdirsVfOv8Azhp/5LDVP+23P/1CWuYeo+pux8nvOY7Y8/8Azo8q6Nq/lK61O/eW O40aCaayeJqLzYCiupqCGZVB75j6mAMbPR3XYeryYs4hGqmQC+XIYmlmjiX7UjBR82NM1z3+XIIR MjyAtmqIqIqIKKoCqPADYZmgU+X5MhnIyPMm12Fghvzc8i6jZ/lNJ5hvHEKS3FsLe1pV2SRtnY1+ HboMy9JH1W1ZTs+nfyr/APJYeUP+2Jp3/UJHm0cQph5t84eXfKWjSaxr94tnZIwRWILvJI32Y441 DO7t2Cj8MVYZqX57aRpCQXOs+V/Mel6ZcOkUep3ViiwBpCAgfjM0sfIttzQYq9MxV2KuxV2KuxV2 KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KvnX/nDT/wAlhqn/AG25/wDqEtcw9R9Tdj5P ecx2x4p+e3lfzteTXGr2dy7eXLa1Q3NoJ2ChkY839H7J6jf2zC1MJXfR6z2f1eniBCQ/emWxr9Lw yw/3utv+Mqf8SGYkeYen1wvBP+pL7mZZmvmTsVZ7/wA5N6hZ6h+Rn12zINtNc2bRhabDkfh27r0O bDTm5Boyci9X/Kv/AMlh5Q/7Ymnf9QkeZ7jF43/zl1Lrmk3vkTzVBAbvSNC1Fp7m3IPpfWFeGWES 0rtIsLqK9PpxV6v5X84+R/zX8mXB06cXFleRGDULJqLc27Ov2ZENeLKd0bcGlQTiqF1P85dE0r8w NN8j6ppGp2OpauwXTr6ZLX6lKDWhWVbhm+0OPHhyrTbcYqnfn7z3pvkrRYtWv7S7vo5rmGyhtbBY pLiSa4PGNUjlkh5knspJ9sVa1vz9pOg6TZX2t29zY3WozJbWGjlY576a4k+zFHHbPOrN40eg7nFV C2/MOI6rHp2p6DqujGaGa5hur2O2Nu0cCeo/7y3nuOLcd+D0b2xVj+t/njDofl6TzFq/kvzJZaPC sby3M0OnrxEzrGnKP676gq7qKccVRNp+cf1rSrPWU8meYho97HDPFf8Ao2DRiC4CskzLHePIE4sG Y8dh1xVW8+/nFpHknXNH0bUtG1S7u9flNvpDWS2jpPMGjTgPUuYmU8p0HxAdcVR+kfmFNfa7a6Pe eV9a0aW9SV7e6v47P6uTCvJkL29zcEMR0FMVTTW/OGiaLrWiaPqEpiu/MEssGnGg4GSGP1CrGu3I bLtudsVTvFUj8u+cdD8w3utWelymWTQb06ffNQcfXWNXbgQTUKX4GtPiU/MqobzF5/0XRdZtNBEV zqfmC+jae30iwjEs/oKeLTSF2jiij5bcpHUE9MVVPLXnBNb1HUdNl0nUNH1DTEgkuLfUY4V5JcmV Y3ikt5biKRawOCVfFWQ4q7FXYq7FXYq7FXYq7FXYq+df+cNP/JYap/225/8AqEtcw9R9Tdj5Pecx 2x51+eHmy/0HysLa2sUuYdZE1jPPIW4xCSOlAi05MyluPxbU6HMfUzMRXe7zsHRxzZrMqMKlXfu+ YCHR6EFXU7g7EEZrn0AgEeTMrO5W5to5l/bHxAdj3H35mRlYfNNbpjgyygenL3dFbJOIxj80NQvk 8i3Fis7izluIXe35HgWVtm49K++ZWj+trzfS+u/yr/8AJYeUP+2Jp3/UJHm1cMpxrekaHr2nXeh6 vbxX1lcxgXdlLQ1jcnixA+JfiQ8WHcbbjFXx/wCefJXmT/nHvz/p3mzy1cyXHli9mMSo7fEU+1JZ XIFA1UFUf2rsVxV9Efnb+XUf5geRuWnEx6/ptNR8vXa1WRZlAb0ww+IeqAB7NxPbFWLfk35j1D83 LrTPOOsxenY+VIhaW9r+xNrTxA3N5xB+ykLqIlP2S7HFU7/Pv8vvN/mO20LzF5MuBH5o8p3El3YW zlQswlCc1Bf4OX7paB/hIqD1xVA/lD+ek/mzXn8necdGOh+drBWlELIyxSlFIdo1kq8T8GJpUgrU hqbYqmH/ADlH/wCSJ8zf9GP/AHULfFWVflQA35VeTlYVB0LTQQehH1OPFXkn/OTk89v+Y35Pz29u 95PFrEjw2kbIjyut1YFY1aRkQFzsCzAeJxV61onm/wAwahr0Ol6n5SvdFR4JrlLy6uLKaP8AcsiF V+qzXB5H1h1ptirxr/nJzRvMHmLzXZRaFM8eoeTNDm8ywrGKuXN7DH8BrXmEt3kX4TulO+Ks6i/O car+TVj5q0dFk8x6z6el6fp43/3MzH0fTof2Uesu/wDusVxVhn/OMdldeWPP/wCYvkq8uWu5rOe3 uVuXJ5SGsgkkIPd/UQ4qmv5xeUPzP0Pz/b/mj+XcS6ldrZDT9X0dl9RpIUfn8EYKtIrUWqoeYK1F a7Ksv/Jv839H/MewvZVsW0rzDphSDWNOloXQ1fgVchWZOQfZgCpqCO5VejYq7FXYq7FXYq7FXYq7 FXYq+df+cNP/ACWGqf8Abbn/AOoS1zD1H1N2Pk95zHbGiqkgkAlTUHwNKfxxS+UPzkutEufzA1KT SkdOLCO+5rwU3UfwylFNDTYVr1apzV5iOI0+jdiQyR00RP4f1ejGNK1RrOQq9Wgf7Sjsf5hkYTpe 1ezBqY2Nsg5H9BZRDNFNGJImDoejDMoEF4TNgnilwzFFif5pf8olL/xmi/4lmVo/rcXN9L7D/Kv/ AMlh5Q/7Ymnf9QkebZwykHm1PzQ0f8w18xeWdIh8w6BeaZBYajpf1uO0uVnt7i4lSaJp6RfZuaHf f2oDirH/ADj5I89/mxe6Rp3mfSI/K/k3TLpb+8tXuoru/u5kVkRF+r8ook4uwJ5k71xV7DdzSW1o 8kFs908Y/d2sJjV27UUytGg+lhirx7/nGDyX5z8keT7/AEHzPo0thcz6lLexTie0miMb28MYH7ma R+XKE/s4qzXzNqX5haV5piutG0L/ABB5euLRIrq2huoLa5guY5Xb1Y1uWjidWRwGHMHb23VY/pvk zzH5j/NnTvzB1/SU0CDQbGSz0ywaaK4vJpZxIjyTvbs8KIkcrBUDtua1xVGf85AeXvMnmb8r9V8u eXtNk1HUtSNuIwstvCiCC6hnYu08kXVYzTjXFU9/LC11iw8haBpGr6bLpt/pWnWllcRyyW8oaS3h WJijQSSgiqV3p1xV5z+fXlHz/r/nbyHq/lny9JqsHlO+a/umN1Z26y1mtZljT1plf/j3YElcVZ/p 3mfz3qGr6fay+TrrRtPeR21HULy70+ZUjWJyqpHbXE0jM8vBelAN8VSnyzpHmVvzd8z+YNU0S4tN Jv7KxsNKuZJbSRSluJHnMkcVxI68pHAX4DXvTFWOflr+Q0vlP8ytZ1R5eflS3ma78q6dyDJFc3iB LiUx/stCiekh7qcVdZ+TPO2hf85H635ztNElvfK+uWEdrNPBPaKVlWKD4/Rlmhf7dvStD9onFWXX ut/mbpHmnWI4/K7+YfLtzJFNpNzZ3tpDNCBbRRywyxXckAoZkd1Kt3xVB/lr5C1ew84eavPWu28O nap5nkhWLSbdxKttb26BAZJFCq8spHJ+OwPc1xV6RirsVdirsVdirsVdirsVdir51/5w0/8AJYap /wBtuf8A6hLXMPUfU3Y+T3nMdsQGoa9omnT29vf30FrcXTrHbQyyKryO7cVCKTU1O2WwwzkCYgkB hLJGJomrQd15K8p3eoXWo3WlW897ex+jczyIGZkC8e+wPHao3zGOKJNkOdDXZoxEYzIjE2Hyf5k0 uzj81alp2hRTzWkFxLHbRspaXhETy2ArQUPUVp1zWGO5p9G0+c+DGWUgSIHuspTBc3Fu/OFzG3en eniO+AGm7Pp8eWNTAkEr896vd3Plp4JuLD1IzzpRtj7Gn4ZsNBMnJReT7d7Jw4cByQsGx12/Hxfb v5V/+Sw8of8AbE07/qEjzePFFlOKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV 2KuxV2KuxV86/wDOGn/ksNU/7bc//UJa5h6j6m7Hye85jtj5B/OE2S/mVrEun3KTwvKkglicOFkM amReQJ3WSvyztuzb8CIkKeW19eMSCzGx/wCcmfMNvaWsM+k29zJDGqTztI6tKyinPYUUnqeuYM+w 4EkiRDlR7XkALDBvzG8+t5y1tNSXT49NVIkQxxkO7utfjkkCoXO9FqNhmZoezoaeyN5Hr+hp1naW TOBAkiEeUb2vvZjpf5M+bNeg8vanNJHLYX8UL3tz6oNwkUjGQu4YDkwjYKtGY9K0zi+1cHFqZcIA jfT7ftfRewO2oYNCIzMjkAJF7+4Wln/ORn5QaL5T8irq+k3F1KGvIYJobgo6qrh25hkRKfEoXfxy OlwCGQENGt7ZyanBKExEcjt7w+kPyr/8lh5Q/wC2Jp3/AFCR5tnnCxj88Pzoi/LzTrSz061Gpeat YPDSrA1KD4gvqyhSGK8moqjdjtUbnFXaF+WHnPUrGO988+dNYfV5xzmsNGuf0bZ25bf0k+rKkknD pyL7+GKpJ5+/Lfz15b0afzB5N89a4X04fWbvTNUufr8UluhDS+m8ysyssYLDlyrSm2Kva8VdirsV dirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVfHH5K/mFceTPyPvZrD021W98wzR2qyg soSO0tGlYgUqKUXr+1lul0Yz5al9IH9jRqtUcWOx9RKa+aP+cgPNGu+XW0lLaLTZ5zS7vLV3BeKm 8aK1SnLueZ22za4Ox8eOfFfF3AutzdpznDhqnmkUApyfv0X+uYHavb/gyOPFRkOZ6D9r1Hs97HnU wGbOTHGeURzkO/yH2nyVQqAEBVofYE/ed85qXbOqJvjP2Pcx9l+z4x4fCj9pPzu1jwIw+H4W/A5t tB7RzEhHNvH+d1H4/FvOdsew+MxM9L6ZD+AmwfcTuD7yR7no/wCT/wCbcnlK4k0vWZJJNAkDsigF 3gmAJ+AdeLnYr47+Ob3tHs8ZwJwri+8PBaLWHCTCd19xX/n5+cXlzzh+Xt/pGm29zC8c1vOs1yEQ OElClVVWc/t1zUz7MyYQJSI+Ds8WvhlJiL5Poj8q/wDyWHlD/tiad/1CR5BtL5u8+3Bv/wDnMzSL bURW1srrTYrMP9mgt0uEpX/l4kP04q+usVaIBFDuD1GKvMPzU/MTW7LzT5d/L3yq6QeZvMzGR9Rk QSrZWUfIyTLEdncrE/Hl8PwmuKprc/lSs9sKebPMkeohaDUE1OZfiofiNsKWp3PT0sVYX+Vv5k+d NP8AzL1L8qfPk6alqVtGZ9F1xEETXMKp6gEqr8JJiPIECoKsGJ64qk/mP86/M/kT84/M41e3n1H8 vFudPtZpU+NtOnm0+CTkgFSEkqzFOjGpX4qgqvYvMF1puv8AkS91DTNQka0nsZrix1HTrmSFq+i/ F0lgZDsex79Rtirz6383eYPLf/OMsHm2ykn1PXhpNvdtPezS3bmacokkzGZnNIw5k49NsVVfI9jo /nfybZavoHnbVbvzAkcMt7cDUp1CXNFd4LmwRhBGjMrLQRV4/ZJGKorzz588wal+Zenflf5Uuf0b dzW5v9f1wIkstraAEiO3SQMnqybfEynjyFB4Kpxqn5TyT2kh07zd5isNVKn0b46lPOgfqC9rITbs teoVF9qYqxj8kvzR806t5j1/8u/PHpyeafLvJhfwKI1urdHWMyFV4gNWRGBUCqsNgQaqsa0qz1HW v+cmfN/k+58wa7F5fsNLjvLOzt9Xv4hHM8diSVZZq0rcOaHbfFU5/KrV/PVl+avnj8ur3WLjWtI0 i2juNN1i9P1ie3kuFjeGKSQ8WkJSY1qesZpSuKqX52eTpvJv5R6vrmkeZ/Mn6Y09bQRXk2tag9TL dwwuzR+sI/iSRv2cVT3yT+Xh1n8v/LesnzL5ii1m+0ywv5Lg6zfyRtcSQRzNzheVozGzn4lp02FM VY//AM5AX+sad+Zf5X22m6tqVha6/qv1XVra0vrqCKaFbmzjCmOORUX4ZnBKgVrirJv+cj5b3Sfy d1fVdK1C+0/UdNFoLS6tby5hkAkvIYW5tHIvqVRyKvXFWUflR6z/AJa+WLu4uLi7u77S7K7urm6n luJXmnto3kYvMztuxrQGmKsJsDej/nJi80U6lqLaPF5bXU49Oe/vGtxdC8ii9T0mlKH4CRxI4+2K oX8/fzcvPIHm/wAivDK/6PknuZddtkJo9n+6hqyjqV9RnT/KXFXsFzrGmW2kSaxNcoumQ25u3u61 jECp6hkqP2eG+KvJf+cd/wAz9U8+XnnafUGkQQanHNY2cvW2tJ4jHDEFJ+Ha3JbsWJPc4qwz/nFD QdH138oNY0/VrWO7tJNbn5RyDofqlrRlI3Vh2INcx55pY5iUTRZ+HGcakLDyTU7a1j1y9t7RWW0i uJlgSQ1YRI7cQxHU8RnU6zUyxaaWT+IR+0/tdN2Xo46jWwxfwyn/ALEbn7GWflb5Oh82+bodPuiR Ywo11ehTRmijKjgDsRyZ1Wo7Z5tihxy3fae1dZ+VwcUef0x/Hk+p7Py/oVlYiwtdPt4bMLxMCxIE I/yhT4vpzZDHECqfPZ6nJKXFKRMu+3g357/l3pegyWuu6PCLazvZDBdWqCkaTcS6NGP2Q6q1V6Cm 2YOoxCO45PY+z/aU8wOOZuURYPk8buFHIMB1G/zGdr7O6g5NPwn+A18HgfbbRRw63ijyyR4vjyP3 X8WX/mR+VFlon5Kx+a57trnUL9rKW3iQcIoormj0Nfid+JG+w9u+U63tE5JnEBUQfudfo9EIR8Qm yR976m/Kv/yWHlD/ALYmnf8AUJHmI5heIf8AOUv5ZeY013TfzQ8qxPNeaV6LalHEC0kbWr+pBdKg 3YL0enQAHpUhV6z+U/5y+VPzE0aGayuY7fW1QfX9HdwJo5AKsUU0Mkfg4+mhxVkHnfzlpXlPQZtT vpYxMR6en2jtxe5uX+GKGMAMxLuQDQGg3O2KvEvzwFx5K/PPyX+Z1xE7+XkjGm6jOoLiAsJomYge MNyWXxKnFX0LZXtnfWkV5ZTx3NpOokguIWDxujbhlZSQQfbFXhOlab/i7/nKm58z6YPV0XyhYfUr m/XeKS9khkiMKMNmZBcNy8OPyqqyDyhp+leY/wAx/wA4NK1W2S5sLubSra6tX3DINP8ATrtQgnhU Ebg9DUYq811yw83/AJAz6nBbLNrX5Va6ssSrXlNp886FVrWgBqaV+zIPBsVe0/l3e6Lp/wCVHkSz 1Dgtvq+l6dZRxygGOSW4sRIY2DbH1OLCncmmKvHPze/Ke0/K7U9L8/8A5cXMumajLqMFmdAVyYrl rhifSiqeXF+NGiNVp0pTFUx84T/8q9/5yis/OOsAxeWvNdqti+pN/dQyiFIOLtSi0aCNmr+yxPY4 q+jY54ZIVnjkV4HUOkqkFSpFQwYbUp3xV4P+VWlN5k/5yB88fmNZrXy6iLpOn3Y/u7meKOCGV4mG zov1U7jb4hiqS2Wk6vqn/OXXniDStauNBuk0eCT65bRW87Mog05fTZLqOZOJLBthXbriqffkj5qf yz5r1v8ALfzoEg85zXcl7DrT1H6YSUkpJzcmrhBRFFBxHEAFWxVkX/OUf/kifM3/AEY/91C3xVlX 5T/+Ss8m/wDbD03/AKhI8VeVf85Hf+TT/Jf/ALbh/wCovT8VZv8A85HaVeap+Snmi1s4zLOsENxw UEnha3MVxIaDwSJjiqY/kjrFhqv5S+U57KVZUt9LtbObiQSs1rCsEqNToQ6HFWN+Xok1T/nJTzLr Fk/rWej6Bb6PeSrui3c1wtx6XIbFkSP4h2OxxVCeavK+n+f/AM1vNXl6+/3ktPKtvp4f7XpXF7dt dJMFr9pTbxMNv2cVYD+WeqeavNGi235IazBLDcaBfNH5mujXidFs3V47cPt8U0pWJaf7qFcVZL+W PDRP+coPzD0FVEUOo2kOoQqo4oSBDJRen/LU3TwOKsC/5x7/ADR0byR+VF8LqGW71C61m5a0tYxx Vgtpagl5SOKip7VPtksWglnnsaiObVm1kcMd9yWBTXZn1Ca6ICGeR3I6hfUJr91c6DXabxNPLGOf Dt7xydZ2TrRg1mPMeQnv7jz+xmf5V+cYPKfm+HULsH6jPG1relRVljkKtyA/yXRSfbPNcU+CVvtf a2jOpwGMfq5j8e59U2etaPe2Iv7S9gmsqBvrKSKYwD4tWg+nNkJgi7fO54JxlwyiRLup4D+fP5ga ZrtxaaJpE4ubSwdpbq4jNYnmI4qEYbMEUt8Q23zB1GUSNDkHs/Z/s6eEHJMVKXIda/a8duGqwUGo A3HgTna+zmnMNPxH+M38HgvbbWxzazgibGOPCf63M/oHves/m/5m0DV/+cb7S10y8WebTjpltdQH 4ZY3iURnkh3oSux6HNbqcE4ZyZD6iSGjTZYSxARPIB75+Vf/AJLDyh/2xNO/6hI8LIspxVg+v/kl +VOvXbXupeWrRrx25vc2/O0lZ615F7ZomLe9a4qoaR+Q35S6TqUGp2nl6Nr+2dZbe4uZ7m7ZHQhk ZfrMsoBUio8MVZvf6fYajZzWOoW0V3ZXC8J7adFkjdT2ZGBUj54qwy1/JD8s7MsLPS5bWByS9pBf X8Vq1a15WyTrCRv0KYqy7StG0nSNOi03SrSKwsIV4xW1sgiRR7BKUPviqT6L+XXlPRdev9e023uI dW1Qo2o3DXt7L65jBCeokszxtwDELVdu2Kp5qWm6fqdhPp+o28d3Y3SGK4tplDxujbFWU7EYqk+p +QPJ+qeV7XytqGmR3Og2McMVnZOzkRLbJ6cPF+XqAouwblX3xVB6P+VPkTSdSt9TttPkmv7Ov1O4 vru7v2gqKfufrcs/pmn8tMVT/WtD0bXNOl03WLKHULCYUltrhFkQ+BowO47HqMVYnbfkj+WltEbe HS5VsmrXTzfX7WdD1H1VpzBT24YqzOysrKxtYrOyt47W0gUJDbwoscaKOiqigKo+WKsXsvyo8jWX mqfzZbWdxH5iul4XOo/X79pJEAUcHDTlWWka7EU2GKovzf8Alz5L84NaP5h0xLyexYPZ3SvLBcRM CG/dzwPFKvxAGgbrirfmL8v/ACt5k0BdA1yC4vtJWnK3kvbwF+Lh19WRZhJLxZQRzY0xVHeXPLOj +XNMh0vSI5YbC3RYreCW4uLgRxpsqoZ5JSoAPQYqlPmn8rfJHmnVrHV9dsprvUNMcSafMLy8hEDg q3KJIZo0U1jU1A6jFWTRW0UVuLccniA40lZpWIP8zSFmb6TirCh+SP5ZJczXNrpD6e9weU8en3l7 YxOf8qG1mhiP/A4qyjy/5c0Ly7pqaZodjDp9ihLCCBQoLN9p2PVmPdjviqA0nyH5Z0nX77X7GG4T VtT9P9IXEl7eTCb0UKRc45ZnjPpqxC/Dt2xVMLPy/otlq+oaxa2ccOp6qIRqN2oo8wt1KRcz/kKa DFUmvPyw8k3fm7/GEljKnmQoIjqMF3d27lAnphSsMsaEcRTdcVfOX/OO/wCXGled/wApJ7e+mktm svMFzJHPCFL8XsrUOnxVA5UU/Rjj1stPMkC7DDLpY5ogHoU9/M/8hodE0RNU8r/WLtLQMdRgmZZJ TH19VOCp9n9oAdN+xzZ6Dtc5J8OShfL9TrtZ2aIR4oWa5vHIphTi/wBDf1zF7V7A8WRyYtpHmO/3 eb0vs97Yfl4DDqAZYx9MhzA7j3j7R5qoZCvLktPmK/d1znD2Nqga4D9n38nuI+1HZ5jxeLH7b+VW sedR9j4j49vxzcdn+zkuISz7D+b+s/qeX7Z9uIcJhpbMj/Gdq9w5376rzZn+Xv5ReYPOkFzeRyCw sYgRDdzozLNNX7C0INB+029OmdDq+0MenqNWe4dA8Dp9HPPcifiepQv5oflBrHlD8vdZ1PWJYZJP XtLayNuxdGV5eUjnkEYEcFA27nNZrO0o5hGML7zbsdJoZYiZS+D6p/Kv/wAlh5Q/7Ymnf9QkeYbm FlOKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV86/wDOGn/ksNU/ 7bc//UJa5h6j6m7Hye63Mxht5ZgjSmNGcRoKs3EV4qO5PbKYizTMmg+NNH8sa75q85nSVga31C7u He8EiFfQBYtK7qeJASvT6O+dzlzww4uK7iBt5vJwwyy5OHkSfk9Lk/5xf1YT0j16BoN/jaB1f2+A Mw/4bNUO3o19Jv3uw/kc/wA77Hk+q6PdeW/M8um6nCJJdOuAs0RFVkRWDAivVZEoR7HNxjyDLj4o /wAQdZPGcc6l0L7Wso7SO0hSzRI7RUUW8cahECU+EKoAAFM4ORNm+b18QK25PIf+csv/ACT91/zG 2v8AxM5Zg+pE+T0z8q//ACWHlD/tiad/1CR5nOOWU4q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX Yq7FXYq7FXYq7FXYq7FXYq7FXyD5H/Lj/nLDyRpMuk+XLW1tbGedrqSN5dPlJldEjLcpGY/ZiXbK 5YxI7s4ypkX1b/nNfws/v0vI+BHuZcZUv0Z/zmb9Z+tehYfWuHp+vx0r1OFa8OXXjXemHwhVb0ji 3vZV+rf85r+Fn9+l4PAj3J4yl0nlT/nLmXVv0vLp2lyaoEWMXjx6S0oVCStGIqKV6jLBYjw2eHut rIjxcVC0x+rf85r+Fn9+l5X4Ee5s4ykfnHyH/wA5becdEfRdftrW5055ElaJZNOiPOM1U8oyrYY4 gDYQZW+m/IelXuj+R/Luk3yhL3TtMs7S6RSGCywW6RuAw2NGU7jLWsp7irsVdirsVdirsVdirsVd irsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVf/9k= - - - - - - - uuid:c63b31d6-45fe-11d8-8e7c-000393cd9a96 - - - - application/postscript - - - - - -% &&end XMP packet marker&& -[{ai_metadata_stream_123} -<> -/PUT AI11_PDFMark5 -[/Document -1 dict begin /Metadata {ai_metadata_stream_123} def -currentdict end /BDC AI11_PDFMark5 -Adobe_AGM_Utils begin -Adobe_AGM_Core/page_setup get exec -Adobe_CoolType_Core/page_setup get exec -Adobe_AGM_Image/page_setup get exec -%%EndPageSetup -Adobe_AGM_Core/AGMCORE_save save ddf -1 -1 scale 0 -148.752 translate -[1 0 0 1 0 0 ] concat -% page clip -gsave -newpath -gsave % PSGState -0 0 mo -0 148.752 li -254.868 148.752 li -254.868 0 li -clp -[1 0 0 1 0 0 ] concat -54.9161 147.252 mo -1.5 147.252 li -1.5 1.5 li -54.9161 1.5 li -54.9161 147.252 li -false sop -/0 -<< -/Name (PANTONE 7506 C) -/0 -[/DeviceCMYK] add_csa -/CSA /0 -/TintMethod /Subtractive -/TintProc null -/MappedCSA null -/NComponents 4 -/Components [ 0 0.05 0.15 0 ] ->> -add_csd -1 /0 get_csd -sepcs -1 sep -f -7.82032 17.3956 mo -12.9034 12.8946 20.6797 13.3624 25.1856 18.4405 cv -29.4395 23.2481 29.1768 31.1573 24.5225 35.4014 cv -19.4395 39.9131 11.2784 39.8477 6.76954 34.7637 cv -2.26661 29.6758 2.73926 21.9004 7.82032 17.3956 cv -cp -11.7549 43.3096 mo -12.2579 48.5938 li -16.7979 48.8663 li -17.9268 43.7178 li -20.3682 43.4747 22.7608 42.7344 24.8936 41.4756 cv -28.8946 44.7803 li -32.2999 41.7657 li -29.4512 37.3243 li -30.8975 35.3721 31.9356 33.1631 32.5196 30.8428 cv -37.9678 30.3233 li -38.2413 25.7842 li -33.0137 24.6417 li -32.794 22.21 32.0909 19.837 30.8458 17.6924 cv -34.1573 13.6866 li -31.1416 10.2813 li -26.8135 13.0518 li -24.8252 11.46 22.5674 10.3506 20.1846 9.75684 cv -19.6973 4.61329 li -15.1592 4.34083 li -14.0616 9.35645 li -11.6202 9.62598 9.22754 10.4092 7.04786 11.7168 cv -3.06153 8.42383 li -2 9.36426 li -2 15.0967 li -2.42969 15.7667 li -2.27442 15.96 2.14551 16.167 2 16.3663 cv -2 42.168 li -5.16114 40.1416 li -7.12208 41.6631 9.37012 42.7315 11.7549 43.3096 cv -/1 -<< -/Name (PANTONE 301 C) -/CSA /0 -/TintMethod /Subtractive -/TintProc null -/MappedCSA null -/NComponents 4 -/Components [ 1 0.45 0 0.18 ] ->> -add_csd -1 /1 get_csd -sepcs -1 sep -f -19.8682 23.167 mo -21.6221 25.1495 21.9336 28.1055 19.6426 30.2452 cv -17.7315 32.5264 13.9385 32.1124 12.1084 30.046 cv -10.2051 27.9034 10.4053 24.626 12.5489 22.7256 cv -14.6924 20.8213 17.9698 21.0293 19.8682 23.167 cv -cp -24.5225 35.4014 mo -29.1768 31.1573 29.4395 23.2481 25.1856 18.4405 cv -20.6797 13.3624 12.9034 12.8946 7.82032 17.3956 cv -2.73926 21.9004 2.26661 29.6758 6.76954 34.7637 cv -11.2784 39.8477 19.4395 39.9131 24.5225 35.4014 cv -/2 -<< -/Name (PANTONE 871 C) -/CSA /0 -/TintMethod /Subtractive -/TintProc null -/MappedCSA null -/NComponents 4 -/Components [ 0.3569 0.3608 0.6353 0.1882 ] ->> -add_csd -1 /2 get_csd -sepcs -1 sep -f -42.0054 124.904 mo -38.6949 132.106 29.9537 135.87 22.7505 132.561 cv -15.5523 129.245 12.4058 120.72 15.7144 113.527 cv -19.0259 106.334 27.5503 103.179 34.7427 106.488 cv -41.5435 109.62 44.98 118.187 42.0054 124.904 cv -cp -52.1324 108.189 mo -46.0132 109.425 li -44.6382 106.935 42.775 104.731 40.4371 103.029 cv -42.0914 97.1954 li -37.271 94.9756 li -33.9527 99.9629 li -31.0816 99.1973 28.1519 99.0762 25.3277 99.5635 cv -22.3921 94.2989 li -17.4175 96.1416 li -18.6011 102.011 li -16.1207 103.443 13.9351 105.404 12.2232 107.825 cv -6.41944 106.179 li -4.2046 111.001 li -9.19288 114.318 li -8.42237 117.192 8.30616 120.126 8.78467 122.94 cv -3.52295 125.882 li -5.36475 130.86 li -11.2349 129.672 li -12.6656 132.151 14.6226 134.34 17.0562 136.049 cv -15.4068 141.854 li -20.23 144.069 li -23.5582 139.057 li -26.3648 139.764 29.271 139.844 32.0865 139.344 cv -35.1089 144.747 li -40.0816 142.907 li -38.8687 136.883 li -41.3609 135.473 43.5679 133.563 45.2554 131.213 cv -51.0806 132.864 li -53.2984 128.045 li -48.1685 124.64 li -48.7964 121.878 48.8687 119.031 48.4048 116.281 cv -53.9722 113.169 li -52.1324 108.189 li -1 /1 get_csd -sepcs -1 sep -f -25.3804 126.851 mo -21.3306 124.99 19.5601 120.199 21.4234 116.152 cv -23.2847 112.103 28.0757 110.342 32.1226 112.198 cv -35.8609 113.921 38.1509 117.934 36.23 122.414 cv -34.9371 126.865 29.2769 128.645 25.3804 126.851 cv -cp -34.7427 106.488 mo -27.5503 103.179 19.0259 106.334 15.7144 113.527 cv -12.4058 120.72 15.5523 129.245 22.7505 132.561 cv -29.9537 135.87 38.6949 132.106 42.0054 124.904 cv -44.98 118.187 41.5435 109.62 34.7427 106.488 cv -/3 -<< -/Name (PANTONE 1805 C) -/CSA /0 -/TintMethod /Subtractive -/TintProc null -/MappedCSA null -/NComponents 4 -/Components [ 0 0.91 1 0.23 ] ->> -add_csd -1 /3 get_csd -sepcs -1 sep -f -51.919 34.2159 mo -50.1553 34.3702 48.4336 34.6612 46.7647 35.085 cv -45.0293 31.7598 li -41.462 32.9639 li -42.0958 36.6563 li -40.4815 37.3428 38.9317 38.1573 37.4639 39.085 cv -34.7881 36.46 li -31.7666 38.7081 li -33.5157 42.0323 li -32.1993 43.1778 30.9776 44.4268 29.8624 45.7686 cv -26.5 44.0938 li -24.3194 47.1651 li -27.0049 49.7813 li -26.1094 51.2696 25.3331 52.837 24.6817 54.4659 cv -20.9756 53.917 li -19.8526 57.5108 li -23.2159 59.169 li -22.8292 60.8477 22.5831 62.5772 22.4659 64.3418 cv -18.7579 64.9659 li -18.7999 68.7315 li -22.5225 69.2696 li -22.6778 71.0323 22.9639 72.7549 23.3868 74.4249 cv -20.0635 76.1573 li -21.2667 79.7266 li -24.959 79.0928 li -25.6456 80.709 26.46 82.2569 27.3887 83.7256 cv -24.7627 86.4004 li -27.0127 89.4219 li -30.336 87.6729 li -31.4795 88.9883 32.7305 90.21 34.0713 91.3243 cv -32.3975 94.6895 li -35.4698 96.8663 li -38.085 94.1827 li -39.5743 95.0782 41.1387 95.8555 42.7725 96.5069 cv -42.2208 100.211 li -45.8155 101.335 li -47.4737 97.9708 li -49.1524 98.3584 50.8799 98.6104 52.6456 98.7227 cv -53.2696 102.43 li -54.8282 102.401 li -54.8282 90.2071 li -50.5508 90.4063 47.168 89.4581 43.1543 87.2188 cv -31.6788 80.8194 27.5655 66.3292 33.9717 54.8516 cv -38.3282 47.044 45.9112 42.2872 54.8282 42.667 cv -54.8282 30.4581 li -52.4581 30.4971 li -51.919 34.2159 li -1 /3 get_csd -sepcs -1 sep -f -33.9717 54.8516 mo -27.5655 66.3292 31.6788 80.8194 43.1543 87.2188 cv -47.168 89.4581 50.5508 90.4063 54.8282 90.2071 cv -54.8282 73.5127 li -54.4903 73.5616 55.1485 73.5948 54.7969 73.5948 cv -50.8213 73.5948 47.5987 70.3731 47.5987 66.3975 cv -47.5987 62.419 50.8213 59.1944 54.7969 59.1944 cv -55.1485 59.1944 54.4903 59.2286 54.8282 59.2764 cv -54.8282 42.667 li -45.9112 42.2872 38.3282 47.044 33.9717 54.8516 cv -1 /2 get_csd -sepcs -1 sep -f -3 lw -0 lc -0 lj -4 ml -[] 0 dsh -true sadj -54.9161 147.252 mo -1.5 147.252 li -1.5 1.5 li -54.9161 1.5 li -54.9161 147.252 li -cp -0.99 0.99 0.99 1 cmyk -@ -0 0 0 1 cmyk -%ADOBeginSubsetFont: TrajanPro-Bold Initial -%ADOt1write: (1.0.21) -13 dict dup begin -/FontType 1 def -/FontName /TrajanPro-Bold def -/FontInfo 7 dict dup begin -/Notice (Copyright 2000 Adobe Systems Incorporated. All Rights Reserved.Trajan is either a registered trademark or a trademark of Adobe Systems Incorporated in the United States and/or other countries.) def -/Weight (Bold) def -/ItalicAngle 0 def -/FSType 8 def -end def -/PaintType 0 def -/FontMatrix [0.001 0 0 0.001 0 0] def -/Encoding 256 array -0 1 255 {1 index exch /.notdef put} for -dup 67 /C put -dup 73 /I put -dup 83 /S put -dup 127 /Nsmall put -dup 128 /Tsmall put -dup 129 /Esmall put -dup 130 /Rsmall put -dup 131 /Ysmall put -dup 132 /Ssmall put -dup 133 /Msmall put -dup 134 /Osmall put -dup 135 /Ismall put -dup 136 /Usmall put -def -/UniqueID 45714 def -/FontBBox {-248 -284 1528 985} def -end -systemdict begin -dup /Private -15 dict dup begin -/|- {def} def -/| {put} def -/BlueValues [-17 0 750 775 638 660] def -/OtherBlues [301 305 405 408 -261 -256 -222 -209] def -/FamilyBlues [-17 0 750 767 638 656] def -/FamilyOtherBlues [301 305 405 408 -273 -255 -214 -209 -252 -239] def -/StdHW [47] def -/StdVW [118] def -/StemSnapH [47 55] def -/StemSnapV [118 126] def -/ForceBold true def -/password 5839 def -/MinFeature {16 16} def -/OtherSubrs[{}{}{}{systemdict/internaldict known not{pop 3}{1183615869 -systemdict/internaldict get exec dup/startlock known{/startlock get exec}{dup -/strtlck known{/strtlck get exec}{pop 3}ifelse}ifelse}ifelse}executeonly]def -/Subrs 5 array -dup 0 <1C60D8A8CC31FE2BF6E07AA3E541E2> | -dup 1 <1C60D8A8C9C3D06D9E> | -dup 2 <1C60D8A8C9C202D79A> | -dup 3 <1C60D8A849> | -dup 4 <1C60D8A8CC3674F41144B13B77> | -def -put -dup /CharStrings -14 dict dup begin -/C <1C60D8A8C9B6D5A0DEDEC57B918D61DDFA401F5A49FEA3B89C6864173301 -6BDC674395116B42D2387AF24DF2F1DC60C61A5B6585CC0DA86F050A110B506B -B65171C092F0636620BAA275DBDEA04B3E655EC58BDFB8B9B535650BF4DE0E82 -1C2ADFD8C9F649E0C395722C228833505318AA21D61F3D55D035246FCF9BC983 -692D83F8C9AF492468B91F4CB872C7D1953185BF38A8E7A5B72C7F51E36572D3 -718D9C26EEF5DDFAB02F3E79248875F4CA6CC06F7C289C017B388B2CFE4B85A5 -1B0090> |- -/I <1C60D8A8C9B77771C05B04C6A1CDBDED73825D1016AD1A9F739BE3AE28A3 -2F89A16FA0ADB365C478020BF11BB9ADC332932373DC2832A2FD54E961E2B084 -4B0EB81447C317CA2A36F9297140F653C6CF38B651D9BF313FA9254650245A3A -6E604D8E9EFFEAAF12423E3B4CFD19A9AFAFF5FC58BD3FF4189B6F8AF938C510 -BD91FB49103F7E5C2AE8440096A8B2CFB59E1B448BD934D6C96663C7ECAD3789 -1B4FEEBF9172B6A7CCC0965D9AA12297E39BBF30EB7B8F6243DD70D9185FBD81 -8CFC74B60F41E69C4533165A53D5C2FC5A9B44BA5F12F31CB79A71FA4F70F551 -E84E63E5837361F7B7736F91> |- -/S <1C60D8A8C9B7F51B95A0DFD92CF0B9552EA2D8DB80CD668D35E3A70F4576 -D4238E8EEA2F046EF8BC16C7785D1607E04A62100A5AFF084F37B544AFC2004C -0BC4AE1356D2B0EC8700AB99117F620401AEDDDFA69D53F0F4E5314303A9C779 -D85053ADE7DEA169C445735EBAC333F65F31A077498B479248885315A58C9DAE -7AD6ABA3F9562E1A36EA3EA3274E191D557F04A6CB9FA3B240660C95B31FD1EC -ACE3874E2F240022DE09CA2256274ED580EE94FBAA5793BD5F9D37682BE7C541 -ACC5EE4D95FB35149493D2CCA9BEA729ABD0DCEC9C95E902EA9DD124CA919CBA -F3364C7699DDBE268B46D54393CC359D98EA67700B83CEF348489F1F90A16D> |- -/Nsmall <1C60D8A8C9B6BC88BD85FE8659C453EEEB8E1BD03325A00213B3F3D -4D450DC128DD37CC24C857B6D60D557A08CD43D812DF35B5BD6760576A63576C -506A238602F1E6EA5D2CF18DAD28B193AFC0FA899C7F243B47EAB7B8460C0CB0 -4242476B1602C4D8E3342E27EB421C00D297126C6E43889F0137C7A1C441FC72 -2BE08EFEBABED7A59A7395971A284A820995BDAAE7D9478AB8745D9C9402C363 -B7514AFE9E3D0AF6A39663E1D555B5F7BDA2CE94F32DDC1E19216692DC849907 -7A3E6206E838004DD8DB4A986C8F31EDCAB6E6B82F722A0EF26221ADD2189144 -83D5E5F90B6CEB939F64EF523B4531C4C0B4ED4F521923EBA94C1FE7AE3B2648 -AB7B1D48BCD570F1DED35E03DBB412CF55B5989A09E378971DDF42BBC4FD1669 -7B92AE130992922E13408AB712F27D256F7305A6C6B07A0AD7C13FE23EFB63CE -65111A1A787D3875B8B8D9507C694904CE3BA8114CCE10FF99A55> |- -/Tsmall <1C60D8A8C9B66C0E1D18F4614EAB544F0CEC538C8C01A016933AA12 -429EBE5390D596C5F67CFF90C2108DEC0E3557EFE47A84AD0A504C83D7E8F287 -5DCBB9233950E37680119C5422B9BA74EB5E3A2AE4E2F090670CEE3CC015972E -6CE8DF50DCD73A5ECEE824E6627364F3B83B1B73833AA7E396445D318F119C4C -5EA2429D5B49B0EDBDDF4808A5790BF8CDC63B184CD3A9CE7C22C4D23ACC081C -FF7BCA42342880880724EDF5A0F6F9059ADD736C441B65FC95D81D78B14BCAE7 -32E0959A4FEDBBA605D7DB559BC1CFFED39160EF11111F189C967E86115A679A -21BB269B7452490D7C600719A2B02BE0A92DC8D7E101DFFE6011D579AD666FD2 -6352E7C3F88546D427880A3ED55A53668B9B911F227F478005846196CB2A821D -9436A361DD997E24624546B193AD16A013BF60C83D456FEFAB524A4C3C4DAF51 -640204EE51B9A6B98D186E77DE45F4BD3696405A93E6DE14A3A251AC1EF6440B -3F074B20C4913F3447DE56969C6BBDB2354148031166D8E9781263F94442062C -991765ADD918972AAE466DE6B9C6E0991428CD75BCCEE> |- -/Esmall <1C60D8A8C9B7FBE1B006E95A68A3EFE857D335EDE0BE9AEA4BE7F95 -2FA0109C6CB803A7F2B985E7BDE818880C9FD186C7136A63CCA57CEDB6AF2828 -DE38E8685BB8771E2988A810F73E0345E8908310C31FD0F7C222F54500389519 -240356E338A96366351A20F484B5651422D1A0FDAE927D548045766A19F6150D -CC390EA0D98D6C0EC5E1C97E0B4512533CA015299550D65A6EA9A741DBD81A7F -575EC26534A2210CD8BC3335B163A776277B6F29843653C092C384FA226EA0E5 -F40EBE1799B10828B444468B3DA053A6ABB46879088C5CDBC46D899C794B325A -A3C97D044BB760BC39839995FB64819C682832A40321F78B99C09513B805CEC3 -996F9F6C14C0DA278CFDCC8EE83409A0C9BCAE8289E42BA209582E05976E48A0 -66222F364CA72855AA1A8DD971B9E012D88EC883F11B6B8DD1F7A3A1A193533F -B42207516FD3B0F5443A7865F511A1795EBD587D37DBDF03F04386AD8496835A -76A8A2EA2B1821C0A26A3284A32DDD223178AF712B0015CA9C866D881702FB56 -88AFCD83EBB5B8B70C983ADB28C933F563180B2F5D693852DE904FE07D55275B -BF14C6F4184BD1B4A9AECA29C644CB5A0BE9622ABA21F24CFE079641418F3570 -3415A4A73F296C050FA68AD25A13C7E948BFB4A1F5816B4ED0207AE7F70F6A21 -CEF402873ACC39E699949E03BE7A042549D2AB51127EAC04572696553A61D3AD -7A50684611A83B8CC45B07DFB59CE66FF4633DDD79F> |- -/Rsmall <1C60D8A8C9B6232B67C2503515E3E19A361BD6B49811E165A598B41 -3BB79166E3FDF489EB666983D5C7D39CD639562A5B5DFFD54539B03730F39196 -01122BFF4EFD30EC733326ACD5E99E075E6AD0B22300446FDA3039558CE7D82F -A6C33C70F1D07536B16D4B1DC2398D650AD9DE1FE1EEF9FC8801CF7C62691F3D -44ABC62967E1B752BCC2F000EEC07286667F57839EF2E6B9C04C2DA9F22FCE01 -4B7A5598EA7A603107AC2DBC5AB39CAF9666BA8BD1E17DD88F1B0183C4C1C3F1 -1214AD45BA4F39EED6AE5D1943AADDA9D1EC079FB2B1E8FDACACF0141DE87287 -5FA936F561AD9761380B6FCDEE2C83C4F292D6BC0EFBBEBA1571BC78DB7E53A3 -C2355971E9941081B36BC438EEEB16D9D4B14BD1644AC5E58981D2AC452FD6A5 -580957C704505040E5A864423A1DEC798AD589C92753FF4E99FE4D12AC55E99D -5F0AB1E5E4B10AE2F480F509E7AF89EE8CEFA0BA716FB8CEAE96307008D32070 -D365B7F6583B829884DD2FE6EB7D95965527303A93BC3BED5A9AD904DA3DA> |- -/Ysmall <1C60D8A8C9B7CDD8BD7DBD65E184B9680768C945EF501FFBAF34DB2 -EB89B7C35DCB2E8CDE46F9D37FB471E35DF335DEED86CBC9BD25ACBBBE505717 -85D55C56B45ACC3A263ED736CAA051A570F787892A1CB6821A2FFAD018F8067C -A681AE9EC8078E3C7AFE94C42C7FD5A558E11749ACDE333C8BDC9884D4FA3DAC -AE8A34DD32D0843E9B8D09766739B4ABA55282A00532DD1F8B6DE1183006D340 -67C1700BABA7CDD73E0CDB5BE2DDAE32FBEED1C6D7EEEA3B5CEB4C4205571F0D -CF1A506D8FC5DC8499A45715F34A9B98FE00C59CEE5F28BBF36D76480FA97A6C -7DA2BD1F5844A8385287554D6A25D036C1B44B3D155C43934FF8AA5F5EFA8691 -C8A756E6E6312D494BA1468BA6D0686CD0C8B3FDB8C0351FA65E6040F976F25D -799285A835570C29A2FB34B27E1A794353E610FC2C4A30406992C247A28AA7F6 -E944BDFAB0BBA11598F8F567A868E003F8F3944F74A873C0B590A5CBD543024C -D6E3B83887E8B4201> |- -/Ssmall <1C60D8A8C9B79FB048C852057885B7FB39D71FC3016435158EC7538 -3A43C835122312509B1BFED76A61F209ED65A42B34BB62984E18488BC60B5218 -01752FF5C2563FA0352A4574582BF27E08DA350B6E25230194888F1FA389A5D9 -3FBF39576DDF170A31E4F9A79349B244BDF70FC82577F5D740926CBB4F2ACA8D -2425F341518CF5F38A11D5613BD07DDED6A6C9CC2A89D2BA18004761AD9B9FC3 -4EDA3D0BA2574B07F9B17535C3DFBDB872ECFEEFC15F4D3F7BCA04E0B730A15B -DD0D5BCB061E10476825BE14CC3CD57D1B8CD428D2118BB782F85F1A67B39448 -980A962927A8E8DBBBF65E6278D0AFECB529564B170722C87DEFBDB> |- -/Msmall <1C60D8A8C9B5BDB4869BB7396C2BCC7E2D035A8DDF69463A769AD1A -A49DB431BF0660A482C35C477875AA9502C9E16D281765C1FE89158C85EF4F3E -57125A0E615EF95AE1B7077390D7D5D6DDBA63FCBAB687625D16C58A812887A3 -BF8B333347AF25B78756DD80DFD049480BBC5CC2E60C8AAAAAEC52485278ACB4 -CB64431DB98372ED33A1281E6970D65A9DEE7B405CB6932D27F2DFA40B98C2E6 -9A163099093F74C6495CCB4C78B91CF36A00F110217924E037A2F56731347A29 -95E8AFF22D6698D628918F5A55716FEBDE556231C95D2821D1B0DE3CCFA65E60 -C9DDB56BAFC7C7328AEA86A4824D8004029A0A0834D297E9E2EE5DAE0DFFB8A2 -CC6F17A3EDC65> |- -/Osmall <1C60D8A8C9B6AE36D8AFC06EF7691CEA7388408CB5711A90AA9C8BB -7DF107C83E9F4C9D93C2707EED4FFD917928C910BF7966EA41381731C2EDBAD2 -707004603AE29A600E85B2D80CC1F8253013508BECCA2FDAB8779E3B7D43916A -0E2CE1B80BB3DF3> |- -/Ismall <1C60D8A8C9B704CCC403F91AADD9CB2F76DB90BC6EC90EF3D45C6A9 -10C33779B027A5893F399469312EDD288FF0EA2B3848F5A530D7C0162C275993 -6728784ECB91933A5B31FC0120544923268E389858466EE39EB2181D57CD3BF7 -07FB3669BB94B89A418CD729CFF5FBF8DC7045D58C25F7CB07F19116123D927E -59434BBF93B4FE5DBF40C126B117E6B60590BBF45DA98B6DE8B19144213326F9 -87495E510476E3585AE1A21D73828E47A902A177877DAAAB4C0EE1255BEF7F14 -75F7B919B37EA781F4D15EE851B6A63CFE7192BA2E00BB3BF61621837B8C6E3E -7AB8CE9EC58E9FFE71C29175C76E5> |- -/Usmall <1C60D8A8C9B6ED055F5BB1EE84E1A93ADDC8E7C125E88D8FF53587C -17D959293900B8FD46371B21619962E4E05301A5E3EA5963AEEE83B21393A2AB -3695359695D60CA9917C3B4C055638C566E55787F9201E25FB6F1ED940BE5C4D -321EC5E70BC368233DBA0CBD12DA827A229D0CC8A349901F7F6297A8D2B5EE1C -32919F009B7DEC73D0710E8891AA9A0D36238E9E944FAFD91D10D63C6B88D5BD -C3A7985808BE85B22B832353DB0C8315F69AE576B8073207A5E9FE25F5A1E4F5 -9C748E9F7D4D5B9763098CB580B40B6CD00897D0384713B624EAD8EE1E24E326 -A2BE8083CCA899DE1FAB4FB90AF9AEB63CFCC24D405FB6596CE1D598C7EFABAD -D016781F1785ACBA6641462356572572D87FF66C89B7A4AFB38B24B24E1E7B07 -44FD561E659DB89FDAA3D90E0980DCB66> |- -/.notdef <1C60D8A8C9B7A73DC56ED86593A26411A239A9F576A4BB06AD4079 -CBD73625AFEDCD129CE8B573E3C4C05A38ADB9D43C2E751D7FE69FF5F6F4BCAD -D50244964753D5C819FE275F32A27920BE3EA3D1AFD957ADA922B28CD2CD8E15 -58DDDC89C143A1> |- -end put -end -dup /FontName get exch definefont pop -end -%ADOEndSubsetFont -/FDJFDP+TrajanPro-Bold /TrajanPro-Bold findfont def -/FDJFDP+TrajanPro-Bold*1 -[ -67{/.notdef}repeat /C 5{/.notdef}repeat /I 9{/.notdef}repeat /S 43{/.notdef}repeat /Nsmall -/Tsmall /Esmall /Rsmall /Ysmall /Ssmall /Msmall /Osmall /Ismall -/Usmall 119{/.notdef}repeat -] FDJFDP+TrajanPro-Bold nfnt -FDJFDP+TrajanPro-Bold*1 [32 0 -0 -32 0 0 ]mfnt sfnt -63.709 49.9312 mov -(I) sh -FDJFDP+TrajanPro-Bold*1 [26 0 -0 -26 0 0 ]mfnt sfnt -78.333 49.9312 mov -0.080658 0 128 0.288605 0 (\177\200\201) awsh -131.874 49.9312 mov --1.83563 0 127 1.73947 0 (\202\177\201) awsh -188.218 49.9312 mov -(\200) sh -FDJFDP+TrajanPro-Bold*1 [32 0 -0 -32 0 0 ]mfnt sfnt -63.709 85.9316 mov -(S) sh -FDJFDP+TrajanPro-Bold*1 [26 0 -0 -26 0 0 ]mfnt sfnt -81.7983 85.9316 mov -0.213654 0 132 -0.177307 0 (\203\204\200) awsh -127.864 85.9316 mov --0.0141907 0 133 0.276245 0 (\201\205\204) awsh -FDJFDP+TrajanPro-Bold*1 [32 0 -0 -32 0 0 ]mfnt sfnt -63.709 121.932 mov -(C) sh -FDJFDP+TrajanPro-Bold*1 [26 0 -0 -26 0 0 ]mfnt sfnt -88.9883 121.932 mov -(\206) sh -109.841 121.932 mov -(\177) sh -130.882 121.932 mov -(\204) sh -144.271 121.932 mov -(\206) sh -165.124 121.932 mov -(\202) sh -182.77 121.932 mov -(\200) sh -199.487 121.932 mov -(\207) sh -210.59 121.932 mov -(\210) sh -230.869 121.932 mov -(\205) sh -%ADOBeginClientInjection: EndPageContent "AI11EPS" -userdict /annotatepage 2 copy known {get exec}{pop pop} ifelse - -%ADOEndClientInjection: EndPageContent "AI11EPS" -% page clip -grestore -grestore % PSGState -/FDJFDP+TrajanPro-Bold*1 ufnt -Adobe_AGM_Core/AGMCORE_save get restore -%%PageTrailer -[/EMC AI11_PDFMark5 -[/NamespacePop AI11_PDFMark5 -Adobe_AGM_Image/page_trailer get exec -Adobe_CoolType_Core/page_trailer get exec -Adobe_AGM_Core/page_trailer get exec -currentdict Adobe_AGM_Utils eq {end} if -%%Trailer -Adobe_AGM_Image/doc_trailer get exec -Adobe_CoolType_Core/doc_trailer get exec -Adobe_AGM_Core/doc_trailer get exec -%%EOF -%AI9_PrintingDataEnd - -userdict /AI9_read_buffer 256 string put -userdict begin -/ai9_skip_data -{ - mark - { - currentfile AI9_read_buffer { readline } stopped - { - } - { - not - { - exit - } if - (%AI9_PrivateDataEnd) eq - { - exit - } if - } ifelse - } loop - cleartomark -} def -end -userdict /ai9_skip_data get exec -%AI9_PrivateDataBegin -%!PS-Adobe-3.0 EPSF-3.0 -%%Creator: Adobe Illustrator(R) 11.0 -%%AI8_CreatorVersion: 11.0.0 -%%For: (Douglas E. Appelt) (Mad Doug Software) -%%Title: (Alternate-ISC-logo-v2.eps) -%%CreationDate: 10/22/04 2:51 PM -%AI9_DataStream -%Gb"-6CMtIYE[^blnitWj!HrIdV0lorEFGN3p=d2AK:U\*q_!hY[_$iT*gP5UX1]SSqSRQ?_'$)V>TY%qP`SMZ@PZ&5]GQS5IeD7R -%m`Y!QleGQ7K.p&6?3aPlR\_,pU'rp&CDDZ00VZam^DTYCI"bGS,pf>eC0p"$ku^->l[*"R8fVlPU'FAYD. -%pH<]YO.ZB_I5g)6.fSi&qjT5\No0V,*'aApjM1[&?VKA;s5+k>*rNhPC\4:.?Tp^0SRbF/qI]^'n%Sf"Iau[8YhK*1=8[PW@95Bj -%feh2gC0m5p>Dk5X:Z"Oie -%_>('6rT`ihmf%TV6aJF?pEP/0^\r2;05#YbIeS'\a5_%#Z`D -%M#tCQSj(t84WKTq]6a,!Z/=Ac38STd5'sfM!j\oF_"j]3hd,(Bg28!D:rMsrhk/^7$3khgXInb)kR&(e;*iD*,)s5!YHLWE;hFu@_jloh"cpiZ.#*V2om4is<'4&SdBk2#Kl=D(W,jr6[thj\_UF8BI"+-&1Xoq"0D1+W8Dh:JnpT+i -%?bp*J"_3/!:^b8g,Gjj:7.;#X^kgo%N*@Djcbc(-0AOC"i%MH*E2&Y,7.;#4%A-H(@tJn;2!Os8$cW@"U!DTsAMQKsF+Q,4Oe;i, -%kt)dRoq)"TIA=8=cXi-4#5pe=(a&[0Q=pJ:eFXd+(jnY%(n]#+6%tnan\JSBK@/*E_dD[hPe^Y)"lk6M1lI#5"BTn6]MWVJH7nt; -%F%6*QW'`.gS%s_I:;)FS;nqP0e?[:7eW:lO"/?ORK[IWb1huk&`Wq!e(?%32O'k<#_I'5DUT;*AbSJnUaO(q4]*3rnOg5*b&bcUD"n*]8_:'!OK[Sm3$^B[6 -%5`Z&2n8s>%6#pdm^#=2R9LnWSF!M=0COrQI(Rca192k+D=8^58KSZe<]Rr1otMX5/e. -%i[=]kpN.KAl),"U`6Vl[i%N>*h9-geqXLul[N?!kAp]o#p95J:So\,F?=@Y?r9HTE9mTU-eQ5>%g-7NM(++>09[hd@j04RP-UK1TF%c8k1lR(l6i1KQ.D>/ZiP77uF=:=.,l*oJ5h?SSg[%2rnj-9S%rs]G0#5Y%NI9>jRd)*Dm_=p:p6Ha4( -%%s]7ECC]5b_C2&frY,1V!dlA`)%DM2%tN!shJ!Ad=ANrJE#?0-pjfm:H\(YXcc>jYILn%7LGPCXK7=doF?NF3Tq-Amq6356p8p]/ -%6aLY9>CE'2qW-gq0ue!MF2[/GR -%ID^&7gH`q9k)StGE/[64elI6>-HA)u?IH9bK3#J6Y3dN$<6>cP#CnF3fQ7'/b18A51>EE4/c=%\dK7XPDtQBgl"Sm!\%$3Y`+g>^ -%phb4CTn#q_5Gi]fcCeRTY4"5qE(gL_B,hStRio_GnkVgFj:;#QGL.SM!pD(QA:T_K#IUb-.^[@YnKl!DO]%%E@$]M0nJRC?TJaO/ -%[/OG4$eMo?o)eM8UH$VVn0^Oaf&iE!L-:Ue^bO'_&jB#SoZSTJ1gB+)*ZLLtcG87`T*)j!Fq4E8\oG`8B]7Fc")p\s#s\DC1H6&Z -%^V)m8VOV"`D@n-.9Ri:D?2".%s#oN+DNk$.ZdGU'mT6QL,4qBY+@H[MF!OkpI7,gZ#I6AsAq1^9,N+OLJ_ -%0Uc_EnIin#3eBHQ$c%8\>ec#;QRRJ25F&?&^'+35b_\N[GM$P^0gZ\=Xp$HD=ZE^Y$$\,Fqge4XF^7(gSot56ST)P"8AU6<-)7,Q -%UpuHR/l2P/J=dI!&;Q>Z5h'uT%#cI\]flh6U9K+%qklsH<82S$i^Hu'LXNQmOTH#g)t?H/7.Z$'dRL#8OCRF`K,oY:V.i/9 -%6)H_q\\OhK#AX7.#W%%uFnAA(PN@jK0cnHeo(4+86'6O_)EI+eS)ToS`:0W?-MjmcVDF>)bc3-+I\o]2!?0a6sf"DnFd0hfJ5) -%\rN<5l"eD!!=b>g:hX64>lD -%i`;cm+I."DJKlOj`I80gcMO&DUHLk:Uti3!YmPSWJ0`AeoMEF;oMh?aKV!aA7%S/TP\ARfcOZbDd4]kh[C4_BbZ!$4@E+trFtD[Y -%JjO)n0TcLpVOTL6d`BmG(5\YKJ(H7+f#5moL'QgDl\XCe\.c9Y7emMN[R1WS&E\YX*rEF$ILt,.D8b;n1#3d.J)-X@/Vp+ZtJ<>D"11Z@q@ATG6L%WhJZTRLR+L/Zi,iT\cg0.(BXI7/.T$`VXDO5J0!,;0gilp_l^?ft$cOeN8]rFHV4KH5c.$C>L'c39Qq9D?s5N.7UUD!7#`V>hS`R7pP.&nB&VgH0O'61pfquQW9(N(dBXOB*5Nth7HqL%'4duc(9>$L^\o$7a=ck_HMh$i# -%U_*o&d28')d7gtLiXT!2b3)f(:Ab9oS^Y\CrcHUQjV/<9iG$odb.+72JK5HUV@"4Oeu45M\0cX&'5ItAGNeXIXkBQX2E9VG?LM53 -%CKeCbhf\7%kSMSsi+KF>#h5[;'N2HH[]=0C-EtO,g$UPR"maTmgp,MlBbrA4f^kY9;[:sA&NeecGlt/b"Q*&E7Z7Idl#mijK9L`g -%M[&hpCi6ju>86t'XOXQ4>L@2Mge2HoM:Qa0HfjEu*>RsKA^(RRNqTd2E`(FL#Rgqs3'Y"qfU3"_iutR%qi/B(m>?\$dOp0Rg=9ue -%1l7Q7BphR9il8ne78KT,**L+Plk=.OQ)n-gb-a"AQ8"Y^VGkjii-D6&3l"rNc+5U@F732Dc=;s!*\q3aT!J>rQ3O1h"^NO:8gGY) -%:snJ:C;h5G3n>@M^BLRTdVSQ[2EAj;efM-EmQ_a%g;"`1_J$=kpM+*KnI7)=&]%"8ViA:^+gp6j'fs3%H4VrOXW9fech-gF2?f+09bSrjX;81`e2)5b>9sNr -%Sj\lFfNjA\DD.;``k4=5K&ZX*Cun;HO#WaeO(*0e(gW`VPUjmI$^thg\cYj0T;!oOpSlAl)4nO=LN:;O4['aCP"O-AV>@Q0$`*dc -%n^,a"[3bTF[$M"kk\9_r;ao:Flh`A6P(k/\BA*_pqk9aLN4<(!,Lu*`ZE6PV&hZ[p7s%0J?-E.\)e)pS-epH/\=ti)io;3GAS*e9 -%?n%PAXKAnm/>LfI\tR#eh?/1hlk`mP+ma!'#U?N!`H`4nF,Y9EdX&m`,@t$_OOOi42m2)37!>F5C/LT52P*U_:0/>&4@k+Cc:K]M -%&/;@6ABkLn]ja:]&ab)FMtV-]ng8FliDD\;5slM]i2Apple@,k#IY>CV4reK?3L8]Db,J]lU[.'TemP=,K72KG!OdQ-o/QsJFs.$Jb'Q0XfDq'AX5Ds'oGR3d,LaU%1F78@74ZEh)W3pqF -%F]%_t66M/\_\F#Yef+'r0JfDs>b>N>8L>oW4@]\cZV -%U,PR.JR9'*ej4tgqL7/9ITO0H+;@XbU/:n2c#&GbY!;)/;VoThfae;,?)JuAT>%eH4_ps&m;G4>HRJd$]fUe7m:UG:r9""Hk3`KN -%0)UdfI!^89nu;Iae[`kQs)RjQr-Wqi_p*2_`lfIlYQ!Pf/u4j"&(ejKs39`MotCD%Er5k2iVM^!l>hCIrl`4Lo(N[H2]n'H?V@fl -%nrMad/#mWDX^,8H^V53tjn/**pn*mSYmrpHKoNj6`fKn*Fa9cQO6Y,&Gk@Gn^SX'DWm5acF,S:EQZlF'Np>K#\p'k9*HgHO;KS??`or;"?"koTf*I;9oWhqrkYq&]IT -%0-BVc4rd@"pHMq]+2[=rDXSW1*'[c4pQo6:^:F+<@hjkbh0f$G]"\+U/'6u#a4ned(L(-Up#P`4rkldODsI2m#lgO"5/7,<"#j-: -%b*V_Ss8C.21CWilh-Y%QO8o%Tk3@X"HL/4lIs'cn#Z#l]\au#SGN4H3I]AI,]8)m9a+nn0O>u+P>^q?fJ,XQ_rckuNa]L@)n]1Y" -%%WLM&KC@7MnUr!?a<&:PW8(4=GSeQ&nAFpK>Q]Q\TEU__9DIu9r>!T@rlb6\p(Sr%oGd8'\a&bG[3%)tLO\pW-i]dM%tGc^f9+AX -%I.d:P3f#`/lGJ[,?TrfNW@ld07JH*I2.=KgFDamIq(7m3T.U?Ln5a"Ond>hslih->ARn8ro!Hi3.!rKVl8qJMANo#!\>s4uikVrM\r^\;)5bQ+rJrU'JD#Vu8$lMEE6a%#k% -%l-`P@2"esZs1A<')Ya/+RU3*\h#7'Dh9V^ReXr;8@Cfc&;g7KbF8Ybc=#U]IFEr<3dF6.Rc\guf-GjRg]6kiid\JP -%](p=Dn`-Gfg^3!k/jJ1LIJEBiZ\E8QiWCkphu)gn^HNZf\6;ml)_O9$!('jHDS!LWj<+.mmY.,`GK62.X&[pHN4khJrp+h+_f=6# -%2,q<[q#(*"5G.q&GOtbZI<#l%%=KA/Idc7nNLqI%4/dW.$,2hBs5rI%s6B(@n%O2GmHqs+l;n7ZeMe%PE.@cXXoIS)e`QkSk9!d_ -%h;-obHBhOhYG`32o):r,55PgsGId\)d#6W7??q9W>kn/DWVOF*iB9i[SpfSVk3Dp_gVDS5H1o?uh]jOB]hH0JN>J0GrrtlJld)K] -%YUYM05DBc!U2E*fr>_9"gXrcTfDd"Jk8W.r5Mk4geC7slrq8R:2g:l.(dj/COfNuC])T.e/G.5Ol3@ibDnfOA*90HESN]?dip,8? -%YYT3EVF+7k/g?`BesV(S_%*WF$2I2.FQK>4NuhJc1C;7 -%@_M5E:fiaFd$G?3;:m*.i39sY[JL>4LGZfa`a;q`'C'&YEPa)nh&^48_7>3og>_b7IdX+_oMaW@?/Kt0Y.I'1 -%pO1qB)\2r#c/$l8aDUH$ZE660ep`arpB\D(W4N8;/e$_V4F22md36I"i/rNP!OhNkFe1KE$X:dl<78\cmSt3 -%GK_;HJ%Dd?aqonV6mA2J&8?bbg*)Rg8>Hn3WN1!TJOm7@UjFB8)Mtgi,$cPE*KoY1,uYpa:So1&UPG(HS/jS5Y0@HrRACLkFpt4%g"=(kbV<4C%$H@]JY8qQ -%&o34'0rftq'FoQ.@BXstHQI'_6QLE=:Qg5JQ+gtY-Hikt81cTH9eAgS#(EnD?g\A:Y.=_JYT"#aLfY/.0X -%pN625*ng%=Qa"[P(nVJI-+l^I-.E^A,m7;6 -%)qeF)g>,ndS+,/[ESKau]3X@'ou5kdU,nR`WLd*QYBFONh!3Sco36nT(06C<=O"+>j^atM9_2LjJMh3`MC1M?B[NVdcLn:)H1s+% -%l)BH[s+QL8+.X!,U,_jmcGoGikPA57m`7S!( -%$i"C3Hqt@m&i>%aZ"3i -%VVKeZm"/5'N!!X<_=+NkI(9#up$GO>s16W;^9p`&"L8U298N5/bVbm5/=UV;iNGlQfl*$hCTa5=m*@u#MEVMmE])uoc./5_O&s\VUF."[_05&L?rO.$PJh+8J<%pVG4J5=">)Q,J>*FrRfMp7/_qZ[HPG^sqk6T;sjV(RaQg3ZG;kB?@ -%jV(RaQg3ZG;`:IPes8dOckpjhdJr@%"hL?7ME\NV>+oVa]:^8*<<_Bc_\M`WKW>J^cW@>kBX+/8l4fqnt -%]#Uu=nLE[9cX544'ae#`m]+Q^]m)..<*@&pVCJ%(CWNb>A$3A8+DC^iYm)Ws%TK>aI\YGnd[0`.4cb\NY&6fLJf<0)L1I_:P7@>\Z.,hpPQ0*RETcDbQGpA&J(mE^heM0Amsm8am3Yrh^iD-UcUH<+E=MG_ -%9dC[]jT?Xb3_'ifktCp'7Fr5%I&Xu(M!UW.j+j[j]DL.XkG'E3jOUfm$aBk)PVTHW+]B_hH$h)2]OE#[J^tF7VN>O#>%=d_K1D[d -%-kE9YOXLfNDGj,aF?o,h8e_Z8>%mTG.N)F;8CS)H34-i%eW-/BS7o<5[W$mq]<5bM2S*AK;XmZJVMKDfgK+OiYLFg_u6)A6fC20 -%bPCSU]P:^Xql8b'.=eS`tR# -%>2Ql:Hgi'3^"bYRQ-I3"[glJNoC0r*_c>APr,V+B[CFQS6L/T%c,4iL4kW)gPMMF>@;Gbf]s:7IDl9(9D:gBYQnQ]m[ql_$bNp9o -%>:&%Z7.g:E2j1plFYaEhO9:Z>ib^iT1^@1G+4%7,SAZX(qW2)MEHk229Jm\W_oo?WZYJ6 -%\46!,"Dl_@NAiN>&ZE)62^4l7S9J3g?cZ&<:(_VpN9E:j9. -%Y7sX%;jJIeF+pC@JTW%.Cq>4RYVp63@qdO.)h51P@b -%HC\tSDVD'rk?F4@L9&r%ll?0g@\Oj;W?8u2(o9V!]mM4>PfYj9NSc9A)pA^(nH&W)(RIa(RLtdjr0/2Qj?FI[k,2u0qp$>2o -%8M#?kO&^Gm71EE2h'ZRJR(Ki@r^So'bJ),8iP56cT@P,&P[:VB.]o;B[u'("X/G6"@QE9>:#^`&BiQf^4L!n.qj=1/<)7dE5C-!l;k@'UEQ$#UYtEVkq5TPY[Vj9dE1BV#n;7CVL(:D&L8Q1['m%Q.[YM2'=Mh4?9YhW63T[[X4JBl]>G+&V$37bF8Tpn&@krCh(h]?]#6W1Q]*'aA49($)^.tjGV?.^0m -%F`^NKPE"2(kuom/bB@Z?SZ17[-Mkr.N:t)++`+sQ)@h=Cp]Xj="?eBjZ*Y\HWRV:SA:M^(31$5>7Q=5Pm"?<./]OYe&(e8Y^-)VlYZT" -%A-;Z;%H/#.pP+Fl@BSJ<&3e^r>8k@-qe,7shDDAT:r.tlUr*#/auT[7<:XRJr=`N3T[i9jek+/%6W0OBim6? -%)=)f)kB'dmYJH?R-SO(7j?!"P<-bekY=],2-j'Q!JoGQ/.rEMUO9M=B?Bpi;/`t_)LW6LMMc.TiNZ6/?b4Mp:NgIUp-lh+=?]"_k(P>$sjr -%ahC)/CkpEj%@^iJT[,QYMS-P])nQK-Y,QFt)n^,-=JGTMe^MX_6cq%EkJ>)]X`\\73jKVQ\_3"Z+UUP^6gZ>(QLfZ7iN!X]S)J<759pRkX/%'4K/]FSAQa3oi<3+B"6gdr1_)t6 -%eBGUl/AR)O\6=^$=bs]KYa\PK%>We>@N=Oo)i:EHF%-F1&AaJgRuiunKkj`@7#P!S`cG4O8D"083!(AYp!ADge;RAb)R.`WW"\b+ -%et+k"`*H'#(]1Jj[%):i?peKF0)u;[UUpMS?gUaU^87nl/N#GF(K94i<'L!`MTk$\pVV]W5#p?d6)3Q#GJf+R[(_ilA)/1FQnCK] -%\lEN9>l9nP3c;"c]Pc4n8qf'.@-u?-]$FD-DDm)pV&$$e^a=C.k;;ns!% -%nXOASG?&:i*+*_d`T$.D=+u.*Hf'GRjI+UU4j9N9@J,?]+*2(`=(Z2p/2uTe#"J=)H\3%#dBlldV.'j:>4jd&guJ7=HHB#$k8#Z" -%o5^,;U.(QCB=57=_@fY1H$%056D=q.FJt?>c-KY6)&Zt/0Q)KbcSf#I^=M8+,D0UB4J\tt*=Y4''i%`^amhi+\0Ope9_ZVoA@6]n -%YBYt+\e0EMI'(:4k8MV(&l'(M;;cb_8IC4fIN4b8Z[4m56ZJeb=f))nIGqJW/U+2$W)RpLHeAOj0m[&2BbnCm$DH;L)@P.n\-ftE -%V9jdV_e83]j"b2$e<1>XamV*Rad]6D2"B.["jZNr]]c0.?VXc"mlP+BnPcK!a&nsMF>*qb -%`j=cgcDkNJ=nMp\K<"9dY]sVWaZh.E_,hr.3BP@!a*p%nOIoSh'C\G_SEQ*a<,-'.W&Z+^92Bm/;`oa;r+HIBBZ4ocoG653RcnjZ -%DRf2OlbJnI3E<7%3*5JZ:Y&sa(n4[s<]s?EX@_(+?KG\cq[;#"3krjIQ,5O9f'695p,,kl&(H3)#>4qV>*U''\K^1;OK$)_MRf+" -%9)cM'fO/aS[DLk3I#9+<$_8\hU>RbOpaS*-D'f40Z5YDh.To`-+@8p>KM`]6$,dJYX,q+'P0*./Tn%/%?p"a7@N":Eq1%Ai5M7Qj -%_O5n+g+f5qUq_0"hgQTlpqu_%eDYlQ?p@_lF8b*dIUYO9ZVJWP,F01OL!:k>Hp3@cn5C'Z?Dpop%^QA4D,lZCAnKd-G=TZ22U?g/Z-Tcu>IYAYGbKe75qou6jBB#-L-n7L7l\83n,?8Kpai%F=JE:,k#HkdJXS`\D@fV:D'q("AuZL]QPl_Ohn5/"cX -%8kRjk[A@0`g@J-**UK[5mbV?ecLF(dGN$,VbZ]Fr4uo0#0k?!Y/JEoU3#=G7R:e^/6JY_B&8cD[U,?-fY>7a^f1r"2P\SP6WdB0>W.bGJS(fFe -%kQ"bCr"D\_5j'-\n=#@KGU2\Nf;#^Xln!d@,1/?WrU2=A"TDRI"$V.10_At?QHb2kKu[@@U]1dEtlc[\;I!t'+0>C?!IPDN^HUb -%Po&HN;&48l_["I%(j5ZJU@%WA:J\'qA,\W4E@Nh2W11qma6UH7TF=8?1-k&+&1G]ahYQ*$]*_=!FB,lprpj(3o4BXqniq?cSoBCU -%C:j,EH,?u7YK@Qh-X?8RX%M@bcQXkoE^%ir]q9u8c>ms5`.0[a>:*Dhkf9a"gHP3d+KUIQh.e_>hj -%&,YYZ&qSEHZ?j^\%j9)r\'4gOiiIJ%b#4_hrd*_bs#CND_,Sa@:OM7"T@@8CbWb8Bm=]#r&oA@YMI.^b`sDFeoNI:hmht\Ub2sSj -%d%_kfLq"p4nRG2U'?ocsQ:WrWI(]'pRp3PEa2X[A%t(6;L6hQOE3B:pM.i6&c_:%2W`YLl&VddO*:H8=S:b>2NB2s2+*[mK`*UWT -%3H1#\ZBs+OMcg@n;5S/hS=*CTf@&9rlB*VP#%pX3/pAM@JgRgo&BfO^e%T#*7hl7m:$`hiK^0_*=orp?6pb7&f.AI -%j'%HlN59KH+K%Tf-qKBEl'4e"F]pH#cRP`Wkn^^L%4sC -%duChn1@!It2SgS[B\eR;p#@7H\Vo;hZcYK'[/(K/6OVh41@s%FASjBV\uA_7HV^_=$h9pG2oCg40A-/t'7(+:[b@dJhc"7^4lsC> -%A5nl[ba/j(`*9an#&^_pgSml]ajr&=]qG(jo3jD#$NB]OU[1LHB1CQ4!I@t.5EtknML.ltbcMO-V6ZUm8m'WC)jPT?SV/lBuS8=g1j5:c`eSce/Ea98E4'oba;F[-`E#kH;ZI -%Pc)Klm!Pt6:5Lb -%5SG[WB9,&64,@'Vj^1l:?$%mllTtM.bO`JJ5p'u(UG3tR6HRP2bUVh#4*55LB\5Nmp^g5H0@!PYi21fD\1&kVcI29UI_:+hrkEnJ -%H1h.a^Ud*VIB11#g%3e.T9?=KRPcS$'.U4>5")c(NE*K!'X$<\\,\8k=)W:f!#^Kkf3!`"7cEVic2I>&_tEC-J+GT+\+LQfmm"WI*I[P(e\f;prmi=m -%qYk`IqSSXA4Jmm`=&!a5:L1"bPCJ>LkIZ*c4 -%r<_BZ2'ib8JVqkerU/Ci:SINboKMY70E"PenrE@]53JcIn7-tip$i+X+rp:gCrFSSh.n#o3k>\p%Pr:+SM+0M4,1%a]'u0P%/6@Y -%go;AJ`hDd#':_oV\CD@dJ[2kbZ50Kch%4M&\Y8nOmsP`:Om/TWC'W#7DOTK@j4o]rEV9`-^M;`&*oIk9#9,*rl<3;_^,&M#FZ5@X -%B7_]T\;+\6B__S?J#7!7I+9[1FT^7[ICXiE\8TkQ>W,7ldocK.gr;%DmudMAe2Q_eW5F&VpR\hRGi4#j"Tg[CTa*ic"<^'UiMh89 -%5T+2Jd`M5Kk1AL7cJq2-%GrB53]cCqauV`pc?H[?(Of(4YC0_nCeH..`OT_lT\oWOj#FngM.`JoPoR^.8#T[2s^$Z]`$,Ho3n^T#m\?^o]V=N^^)#__7^75*BGXqu283Y2pS( -%05]]cPFrd&ecVk=h'/YKC&Ki8+#PY=p^P7!ESc=m+@h_N(Vt>SB'6tru"7_h>kJSCI -%<>StFc`W?'C19LIlqKPE.^h&kjre4tZacC^C&sr*N47kETGWD;$;=PZp*_d'KQ%$+Y07mp'^S[B-(XKaLa>jjd-j"P3=fu%n)N'd -%0_X'^]94LgYIr`TOW#64^uqAYMR18ojt:B3O`G`"gT+1&#Q)KX."9L$q%Bfl.6Y>dmYhQZ")F>VhCa; -%.Rp(7H!?HR4P15MmsMGM%0&pqR+'4'b;RWj4$BsW@]Wj1-eUa:+Nc7ZE&l)FEt%aEQj=d>/41qK(@[=grq@<_:lHcY#"Z\-qZJ1n\A2<6$h9V]h5?-'K*jHBg:)M\JX?YfKdHfjd)UJL!@DA6 -%kW"+iT_!DG2hMSsN'Z?jB;P'JmcIi!0*+d+Pb8&merBm,P+'.c-R[e4YdVAcfFs`S]b+b/6#aU9DG5mRjGoj4ZDk\#+='S$M=iZmh,bc -%HVHiTDmkDE"+p]J"!,aLFTdD9kQ&6,ejC.;I$ -%+>O]TdO!*t!Mfa;@4'9u&b`%K@N]C*Cra_O9::`M6AA?S$h&N\\dCqo?=5[\Bo3*P44QG*4g(X>^&8@akrbMhL=IO/.]BIM[EV\. -%P'U@U0ggL0Oa805cm+R;.;ig<0)IpO;i)0abf]K3MmsP51ZU2#a>q43=B*lcM`NT25kjb@r<>6SkU)jeTqg5ijhC2(rM9a1']]@q -%5^i+?Y$Vu#:XrJkiV$A321aN";4h:\Gj]2p8epnB32iPBcsWI+Du6e^JJ*8GaQO7J^ip+p6mCj2psaO<;YQS7coJC_LbdEuDI@&V>'N?,&#P-8+IHZ`?<'0jnR7DnsXZmjtK?r%k-[hT3R;_OWN*ESur$q>Tp,7=e8 -%0!$NF7B?jgT%3mC9-e.PUu@sm-HkDFT.V#^UkfiecCk8N@#"E3/nG6\f.am9"%3=WN=+Z,3`#DMqG0* -%(8ASR%4(i9MS+Rl>Z30k881c[fHe(%ZU`*@=jUC^n>qjsn-O61h")Stf*gtB2PUH[\#=\8ZWC2dXr1(+##*$B19[O^Ng9Z!`XWj< -%J;^ga*9Zn46TNK*6Wp^09sjLO_fm?mFj5A<55T>C['A/. -%S-P-6@hXg-ZU^)p2\XTK3(9LpM2>sK*q'0-74TOo6t*:&>Y>uKo'h*0Y_d^_P:"1+hB:Qf9NR\tM$B!CDV!?\SHe41)1Z3ilgdT^lZr8c^m*n-tK+t4Em;*Z1nZ9(RJjUVR -%`)*A3Y[87C!BHQ@^FgFh%g>]ePXSRhmPMZ!]k2%X7Vp>e'5=BN.go,\n+*!EIYGf1YiM;K;6_B@'rh\?8,*eESrfu?Z7$gCAPkXe -%b6;CCZ!\@Vgl"X@0pGm0q@Xqt`+Fk25d/DbI2UZl!]\!V3CZc9@r"Yi9Mt#LfKm;.MhNHNc&HDf`g5<:=<[7=l1uPQ7,TL$#+J%s -%UU$hUSC&q4[L0Ad:Y=^5HXJ/35D*M1]jRnk^6i7LG[==#aA\b'CrP)p#I?Kh_J+r&O3inVWn?ob -%@#MX1AL@r=?"E7-#C7d!'[%K[WV$tV'+U8"^.G[g//t(_`JXCBm'&P!U@aJ,K<7Jm"_*72#@!%E'8LePMQCjXFrfh_&r-P6WQjcr -%N(FkEMF3dtDt[F5b2t.'%p]b-?F,Vf`c3ETL;]J#HZU6boL7)$' -%Xk<9`=HqWkju%mXJIrfj-H5C;pR+$a@b29M\XJ6Q,)jX4$K40H-F$k)L;\Q2CUD594cuS4oJBsU_*_^@J7Cs%":5e4bMloiUDY+W>gI*B%(ue41,N(,b6%(.[(Sa(I`N/> -%+Wuma%KW%/0He/'%$H-(bcR<4Lb@e^/N`bU<@7KLYc$uF68-bNQ:B7q*r$?p&LNOU,f4tn]L@np_^)#e$'SIVZ4ma"P3.R:E8=>W -%JQU3PCt0Z94=ASbVW2n6EO'\j\1plDNDlNo0W7;LMNg[<&jIu\81!WI`*4_i$3H@q.P;;7Lu8mhcq78p -%R^Je"T2rE%=X\eP'PNJ2'p>RJm>.o]V^1SnCVS`6M -%%'^(;5dE0u6FKf?2>GO<40UMn%fim8/9;-@8M$cBk!kJC=cSdKq5i;mWfHFq1Of"iE/4C15Zr1ZOUZ7Y8:jW(TfmMkc,aJ.,f,bL5FX,iU25#haJ#ETor_2;nTFANE-1\!HeL?.mKnSr'RlA5XbN'8_G+.:b6>]\GgUt)`sZ'$F7 -%@Wk)t">9Hhf5o[+P:i(jTULOKN!1[6"(d+Xrn=(.^c2QS%G2*]q>?2I["KQ^Re]:+ii!`uP=UIt7=L&X$8@TM.17E?'c,Sd9;,W, -%MA_WdD^kG"p9lY%a&F2?)\#XA1og>1@K8nAk3WbYA@pPUWE#m'&1,Mr_L`,cqBQs]mlac5)?Xln9i-1@kXWDr7_Jru%n_baO'9CI -%_,*RtOgC;co)Ua!hCE:@Mf/[/o(ereg*&k<:kha,6BjCs"FX)cM(#i+W6r[bi>0;;6G,a,apWHV@88_V_S@a:b#*D;TIJ9h6A/DW4bn8b&3X0C -%9;9Lb;&mIQ65YLI^C\F_#'E*OfmMm(ZbnQ9/k#k+U:Y!T'pYJO";;+od]dt5oIf\i$-rmi9Y2n[F\/)ddXhY^s/;`H%X/L6+lP$t -%-7%BCAD5.K8+OogdKYU;DD:o5"3VnEZ"GS).<&(/XW"aKA[>sZ6tJ\/TgY72Xo@4Eo`'$*O4D1Qd3jf^f]a'SQu)GP=:?oJ+r3Q, -%=TO`3BPh@G-b\Mt/1P.=$hT3(:l+*D'r\Sk:g[+OP)-d[YSlNnff:"dDr)I5pS<<7#`@ZLgaM2ajiGq#V?H*s@][&"$5X4EOMe,\]m<_Bs7FZ/c%6&#\>hUE#[sMm[AUSh0&&r/)Bk\2%??c1^%BulHG^1D"AFc\2Bg1:fBu+Q6Jt$4'["ukp9.oJ0KOg(2sk" -%$gtqKP>6uc"DkEs=Mi_7?>%N.\]Jcaa!JODJL`f;2dK7GTb(F]sT3Oe!a4M8@j$p"J_ -%$#mmRO;SXfO?;W.CpE=@q+6el8@@rh`B-)2/+10@!#!S%_^s0-5[2:\k3*(M9=->(7T3H^t-0IZIU5s -%buqF4i$B_2*LB=g=2DLo^PI&ZM!$!K-c(\F4G^'dn$q;YDg]"Od:pU*rRbL+!BAekpHTl]V#`dJq,hW9uG^;$,06c]isf!!!b`-MgiC -%_to`'`YGV1/-.'Z7jOnKr5`,X+*j_qM9HN?(V&51H)bU.OU*>R5bs?Gah\;3.IF]!*LBSG)46'a'l>5I;:R_5(>K"o$Xr1,=S+pR -%0uRNt$-S.h8jJ.c>m68lAlc=hVbWA(,fZQ/)aimUDAVXGg;7I68X@X8r,rVi!).YoG0A=1*^FL"Z<^n;>VW/9[l64-X/Jk5,)9HR'k-H@dPF0>Dhg)l"P,skB'?i -%[jSTMNWR/AQXq&QEluP0&jIu;>f2^t>T9NH6oG2ad\I59[]kU?-"WfY8Jk?^F$2t(e.As'B(%;D9?R*1l]oho,2lW9@KfHF:bC-R -%4F(Z1(AK8bYSEaF=`T)hPSdB:]eV&Ze(?]YjdlUr-<9.AP%9C@"9gTL?d#)n""V]_SPM?)q,$Es/N=([3u;15h-NlKTlQ1#k+o0*(8lJ0u9CYrB,+ -%A]K\Pr??=0=S.>S5ec5IL#(%s2S@2s)iJ-Y2Csdl)WJW":&R`V;!N)PD"c`61b@[8TV!EnfmT?+@qTdTAXAU3FjjA/C-rjX9F"U" -%>ILIWaZJ0F2t0:Zb>*@T@`+W%d4n#!h$grag9SoT5^TI^];,nC=k>.2G,RfQEm!hpcVKbSX7/Z'Xc!h@8fq15^.*$H3l/ -%9KoNk<63@/`2V/V`IS/_1ZOg8;mQI&)SM_Ogi?5?u)'>[`6WQ")2asjsi%!+Ir-WPo!0/\/uhNC?r&JH(!qYW8PD4#GM]u>SZ2,MZS\l.@+L8<-Uj2)lB,#:tUu)A\ZNQ*=8NIkuoj3/Z/W63h54gZr+]I!]F4u?,GfUop.'7 -%P]P+tB4,`1.-KiGFTbBD0Mn^XPOo*+r3bf+k_8[HlX58@&DQ+[nODb*kb'tYS9J$S=Qr3U2]$bGjkgr*0+fS.8T*51GbdIDD.a(% -%,tNZ+/lFU3Q]![t+rMV/XlM'*B6KQ%nV37^(`[^6U8Ce.)7&9^0s^#:)F0NqPqkGE$qk8mBqefmHje@[E16!61_:]CK\=C9b//^8 -%gd[DW/Jk]tWi44='5&Z#2#1e^Q#*X+P,1<#,:ea;K91dp)9OBqYmdPKPRQTXN3*6EF1Q269BKiD37`.I[?U?sl-QY*m+K&+W%cDd -%j&-hnhOXgJ)igIhq6*2Yn&Z3rE`c&^hMWrhh1uuuW]g*J%J($UP4WRXDqL6t$q=kO7Pf+eK6Cof855>T5#_F,W03EM>\k&<+l<_s -%\G%W8:uB8sKc\ZVNQeD=*nhd+MHH\ofP]+c4&k[cWAguO>&sY5poFR!6CMI[`X_;[9LUb/S2'+.`c:*ZN!5g54U,rC#n6QsWON"L -%)_c"4(M;Tara=W.dUgiWgZpW\YjB?7T6t0Z5-f6Yc?>LLA5=CC@$BZe`j(88Q6hMJdqZ#9>LJH[1@CY?n3kM`3JA:1+>gQ%h5t@c\9Uq)$eDY5VUAKa$8b:Df%k(mF5;=Z&5!SRg.=1V"+2oc>C#Y>F -%Kcs0kq[gZJSXKj=[2J+QH"M(2[ep[m5"!t$:<27pBcZX -%/G5O/bYXZM^_2XL,G5iIXIgc9.h!k*S+n6SFT@+X!_f^af.\%OeNQQe0mm3CGgUd(R_ZM>NBV=LM*%k#pV_[tjX[n)dqInWPs.dC -%)EA%sQ=IG>#R2p4BOi6[nYl?+q[.*oj$K*nA>?NE]`0M$nV5)6ORbCCjF)&hXapCF(@iIF:W+^9!FL!<-0sZJ>"f>dS -%;T?.)*Otd!kghi7Z;02'nQ^r#ghVgU.$KkB\n'j,@,L8%n[+S![3j$Uhoan]1So/1eNkoEMZ=dR,?)EKpR%A*l9a15\"E5Z$t[p6 -%3b3s=p$ANM\tk@R^g7Q<]I9OY0G<#DH+Rjam=X-+;S/:,0_[#F=SsW,R.u8UACqZBFpVhS&a3%Z(NZ-P!,4\;:9 -%4G%heIAUQ4Z`I>]E`rt2&Ai2ZPk\Ds"4FOMSp:2UrT>aTa^I8i4Xh;X\>d>%s](OdbWL0V>o9(gmA_:WLe7*A'aX,t. -%a$]Lc-&3Aj]7ih]'5&]$2#3QEcJ%j[PrANa[N)g-ZeoTBJR,)erAfpFq[UPSZf8G0J^QVr5I,_R`cB@qf@&q5idI%.>"/5Bt!--SXuBaV:@hm.VpL)QK*sNG-^JgOQ7YH1B-H.G=q2J1WIOVR$FdW!YJ_eo4f$JAp^Ai]"R3(Sr1#"]/HFN0ZV1qaZ>(92#O:3G>%/0DN9I[3![B5:)0PU1jA,hag1X;HfX -%lr#U(H]>,#N$CAFNU.MHQhG,7;RSfNWE:S%Yi[rG>in%H>f(n-BhF6j/!%"bOfVfBnLFcBXH'!7*2:GFCsdr2cA,k?B9Mk[L(J?` -%a/LIjS`CJ,@\=AVikn$j'D%SLBmoMH\h*^DBs"mQJ=)d)X2&-4E=C;Q0d`ogSGJHp:ORg$iDr[1PR1uljQIKDCh7"Nn?h[;c&$F' -%['#63pVi2N-A3\9GSr])Th+<@fG+'^'<:\,1_AoVBHTaUR'gj:qffkGDXHYUS\7E_QJ*lI('rL;%2^^O\'KG\;LjSHH2F;CbeK-fEu/;7ZAr04`/Q[Ygb*`3HjtN69F9\QM2qiUDT.mEjcuK -%\cpDkR\Ls3_r3uA?H$%^lJR4eToG5sf/htrLY\+lYAsKJNkn@0W^Yfrgl'*sR:NaN4*L6kiOBpX)`Xpsi@(hi/bjA1;6d=5:%M-7 -%YAIuKbe+^>,HUouorhI;9+ejR[q&\dgWhM-?$8<2ZjAGW0E`XG*ufA5,j2sLgm5:9&U(LTK[pq3+!D_R`qJ5KD/i@Rm):.EZ.#l- -%YmaPDn<1Y.6@tT\3J>PuDQDekUpA_^@H_.sa2M#)iX5-6;l7(A43j'>mbLY"@[&j;E6\bO83"n%X6q2Gi3JcWf1MRUCr23Ejd@62 -%.T.TJ.+3k*lh@>5m#/f]KQBo0]iu#&SaL(-icHgb&XK/AVXl,=:I0PVP%K8X75b0Wil&Vco;_5b9`RlY!R>GCkmZq&?u2!"B.EM, -%"D6&4AE-8`[jDat1_%RN?iZRY;0\J8+PO8QMlcQH-\A2C;iAb;EDlLdO_Bs^o;)jopC8?5`>Lu%Pb?D/Sb4_A8"'_XBoIe2!EuFs -%X<>]jGd]]!+]KJP1B?-"r.*gTW[.ekER<_/+s$to2mcDUQ].dmc(1P$9tL^KQft'Z4(QDFhB=#(^]P$(M,Ig(W[S0d=U^*'F$?Zu -%VYX92aM*0J(4ut_.!3@K1)gH':cQ`2.fg@4C?V(7$O9L!R06>W)auU,0[\nE+tPh>&BAlt6Ph]"lS`lU#mIt/7=GB5Q8fN,S/Y0:T9*8k@9+*aT+H_LiiL[=VkOC0%%f^m(E*U6DB,KHo#pqIkg`;Tk"9qPDbLTs3YmBI/+dNo"_*1ECK/*f9KgeT%l<:e1p\ -%A.Y<,0W7gA@U*(c0J/766DFgm&nDIk_2_i=M@Y^1kGRVk!\4FYT13%,V+XZ%PX,^3$/?#/gqoV>$4#@sV?! -%&Ogq0$af,nq4VUt-+0,r$("beX=\DmeJYs2B -%:Ip=YcL[uEa9X)7RtKl=Z?`J#%Hap@0(Q&U3%P<0:X+0!''gFtmhpF_0&nK\Z(MrZ#QWC,+`AuR,_rgWJ^mt=[LCnfKG5b:6&WL:NN%UZG\$7.;iRX>=:%2Mbm*/'IKaIeXY)/ -%rU:R$L;3qcmLYd/e1G"`#pa&62t1)ZBaK/gN)0i<%D2A/(P_=(d2_2nFOj^M^m@C@_&"t/G4;oXOH;+mY'cFPVsUQ(R2,aIdD[(KB>lJYp-8T,$'B)(JH%qR:dcb5sjTe^6*E$1B.Z[ -%LZ^\9R0689:)=3a:*6O+oPJ):k$$)-iNga$0N-%k1T"BN:Pk/GeRDEl$regUdR%=k/HfN+l\o94:UJ9Ko;/9oM#S&9)$5=V8erf; -%9GEp5-SrGp=_6s$5_g!2,q@;QZMiN]We$j2ZP=]VE:`iNiX7AFI, -%q+M6m"o_>-+bmlKQk4RLM%V+@=$b#5j8^'ia>cc:D_f8?UerD1F+2*&LX55s$??*413)]*SD63]/$#[ -%cT"&m:eA\RJ1:u/2#&%U(4[9a5H7!V&R\_"3db30DE -%3E=?s#"8h)&m6V+5p@huJR6YL`GI;'X/VcPI(GgsSC95>83p%J.`4.jEe.RHNpXDR&k=5GQ8g'+=2@FXn>7[Vh)n -%72,W?+IcNFLQ"1C`b94N`_:*/e08l=d5ckI=K-sm#V.K&90..Ie.rXh?q&;`N4CBh6d8%!P>F'_s%5bAVhDB&8nMrUZ"B2_BuTea -%p9ZZHF%W;Q>TLYV"@s_D$6mQKWD&6cph>TJ-4DmZR5U>X'([B.#1?Ik5*Rp=b`aGX"ho+;VTn$So6J7*/_eU+T!:W*.Z5K4mC40= -%C%,'$T1Nja!3ekZ+0-7?W(39G1rJoWI*o7FN3O.3S-D!N;2_0jPm1s-+N'?D-CkN[/'Y;PRt^/g`9Ym&_D&@6kUdIT9QFRQQ6MBI -%0#nTnK-r<'LK*']uNZeN9!%*H90f8-U@iGU3q9\e_MKOhaXfRt1VD -%V#p`p$Io:Z>LM(HqYOpAiRG6,,6&;D(])gjUt1nD(_6IN&0F*V?=A9hn_Y2PUF>&d[4Lf?D34p&e>dRR_ila?"D(Gl0XK]*"Yu_m -%U+ckqU?YR%;.@&=P6YZM:m;7LFOt8i+F\U9O2KHCpfsdp((1G<%^r9qZ=<7U;nsa=fbB^nmV-q-];7 -%"9]'d-3sl.:G@qR5QC0'M[2a#+q-T-LjY#Cnle@/J>c1Ak0D&(5U@s,'Tj)DjAdI'R_Vhf;No$O[7XCdngIDVCPeh9_*j\/XLo+e -%&0VSk6R7D`$P=8=/6HLPW[JM!,#+:_*9;jO#SA%C&0a(872-'fNTgI+b9f.n7uTg6Hpc3S\9s`79'4OsNjWVMlBe0g(fEcuV2Yj_ -%n<8m)P6H.d:LO4k+kPVpOf5(Nm(5n%kkU%9IKW$*l(:#R.%_0)SJ9K5VSl!l-*p:7>rDBE8['.e-/.1?++ -%j[E96M%Pa*Cc7:b\ioqUJu%RK1SFl)a8qG7UUl4T5"KP,cgYg/]$t-D\R!Te4#.p;8gj%hH_X>Ir]3J%35SP2E?i[CuEYJ%b^PiVr]&naiq7F-"rTHu]o:bk@RVV7g46KE(]'I,SF5rT\U-5Q,B2qLI]- -%r!1)%KK;#F@Del:YJu',rk-5Mi@2t^JfXX,Js`03J"]btam\0CPgtcnmopD=K'NAl:uSuqW&oaF:Bo=0f=/fHa45Cc2[$)?*n*Dt -%SU>\-?T[gUK22^.Q[Bd65V?pH'MIKjmmp@@QR-3JrE[uTK_Zj$B7@)BC6iQTR>'H1`]%UXh7T_n7=Jj(fE@&9rXF8-8-NHa\':5JRBg9 -%I[B]S%7@)g:=\Bk]usUf0B&%M@0YW+E.V,dP>Y35L."R_.TM\pj>@umTj\MQ,Jq@mNc;q'[18,W(/DR3BiE]cgI"&2DFnr6nCfJ. -%A4qtCaGL=9NXi0/q\kM^C4YJ5r^gLs^(&[OUc3`q$3Vo+D=kUs(5TE>p*JAB8A.#T>NT`[Nr\JnfS64Z@qh+0fhA#R53%?Dn@+S;&i]bqtN/-DRN"g9!S#ji>`%bl]q2p=PFhuJ.* -%J:MLc8M18OHp8qJ`_V'`%#O<^#bDL@&AUG.TE(a?h*-BV!.IGmA,^f`KK0VeRuZ6BNY7)aGQ&Vc#%tZAoniN3jrV)lof,Wk:!;sd -%T[NM3U4YNMN7P6\n1C>Uf20X-?Ak36+U6,>H*h/=)4GFlgUh"G8(:qrCRZ*1;.m*LqYRG`-QE0@04AlKJc^2Eb522U#"lfp%kLf_ -%?Y136635F>P5,G!!9IgEF9=-R\GYlTE%nR((nf/F_k(7o(Jl'sKHW%&f2&c,&280\>M2idlpF@(PQ0T?/`74f1="cKLMPQ]4.u -%O=)W6E`G%\DsHJ:8%>N,n>+3GLs5M]:#N`$(dG$c&2Q3<=r'4a3/F\\E:+uqP*6Z3[$7gd6W-q,K+Ym4l\'7XSkeP\:Rc*r@1J_YR$BZYe9>?@':P^hj&[q;ND6d-aqMO%95GQr -%np<(tH%I3:WlLkJ*V_a>"!qJf(6/o%%?H*(AG)/L]gTjBL%lCETKRt9EAp!1)Z(SfJ_frM@Fhn1;8C''2I].ld=s[jNR.ks9YX(3 -%+jdPYC>]REZZR8%UQ"XM*&+VV\HN+#P16E48VP!]kk,L[kOHWCn0H8W%lY_O(bkS#:'cF/)t@4t:a-:S\ -%EOegb&_KWE"b(G>Ta$QX=s-@hGLUWAPh-MTKCd?"nebtmAjg^kHndlO5.!GFU!le$9jQN"6#t,k#?2Gc.N_i-3$;8Y!k.]7(6e7o -%WZpX>0IZuI#^H&;@2?m+Lcs5UfO>>p#!_9Ia.k2aXO7;H&R3s1re]Kd\u7BX@Z3$Y"+!DQH]D3#,oS\!RGt2C>$^O"JF7rJ5b;J_qYk8a*n:B -%\9#'FII3/Sqt*1k"E)iYN+gr\KR%ocb>SBE['X!N9Ar:)2,kW5uX+'S],c -%&ZT`rNNWAh.Zc's$D8j5YM=no!Z59"U"p<@bk3L'St+t0&,M,?'?E?*Gn0BtjL$dj7C4r2F@Wn'rL3Wc30D6hHA:nGPC/a>*Jg05 -%FWc)Nh9Yj;HtFWRCbW[g3JmmX1r*UPCA^4ufKd+a<:\qW(7')@pl9S"](\.f0Pk^ALu-)";GBcL*i@Y%l-KaM#Q$TM2DE`S_q?2` -%N6ncI[tCP;?8Z,";ZI=hn\_n7,OFjYaqje&7Yo,K_h[eME`p^k9Z)9S6+nle%r1t!hbRL -%CC22'Q%l[tk2VuZ'Jg9U5YV:GZ_?Z4.)b(n`+1PX!N^GGUPWJ4!7m\K/$#7FCWIkBMub%ZAc;^"&8[Ke6c499>in'B#j^;ch\/LM -%I-H&h$m]j4D/7ks*glsa/V=n7LE#0U$']b-ZNNl&_&8o!S'QUC3,?71V?8rdK2k`_#4ct.EYBksIL;9fWC20W2?oh$d -%+FjrqdL>CQ)"L/Y66IUZJhoGqTt1:`/^Wcd%Q`l#2'F#nL,_R7bP)DfFS(p*T%A,D^8#M\!218MY8KZ;b4cI949Gb0!1c/9VKn7( -%`*1Y"%=mRZJ=f)?Uo58`ciBL6i..C">VTX&%f(sfYso"EEJd#]EKr6l6Ik#O`'>Nu#bZ.(:^.QH#(SQ&,9CZej0R%3mQWUI%)>(N3fCnF4)&6@06Bp'H*np,Xqt -%iSfF(9>`,toe`rT%q)\1<<*q,Ekq,EHR=MS"?"7XL(PsUi44:P'6h@,\E+sFd$i_]9FlB8inV"a\7Z?^*I&92 -%95-)0cRlE!%Q&\Jjg!SrHuPJuAUR:MZ>e^J;&^oeRP%.H)1r`Un\EVh]5\i!gph2LeRgo8#!Ogp-<'\!g'n,Y[!e#$s1)Q\Z3@+g -%NDtJ-V*N54_,rjp3RhUX7(E$4QJ<0tWG4a*!;MA'ei+U8"lgOk1*O_%6>7cBJ5?Ir@M>@7XMTB9?j)(-I7#M5[.)[\>X^RUkRO## -%HJr3L87!V,)N.#M=j`nPH-^7!k;1Z%7/cDZm/"Z>VNl-&W,1$h(suo34pB` -%EMOVu4`3&MKUaXhSMH,DLg_^%C>/9JqRYd2"/`lL<$_j0\f_h(N'P=CQ9"LO=:Lr^bb"<_Gro'g[mPIa$[PWD=rXUi-NOhuj.Y^, -%[SpS+#aH<)155h/%Hec;fHVU5?4dJ;%&A%bqcLndH(+">cNcm`a>/Lc3f-Hdk+G?H?=cDj?AmWL!"4YN0gcG6=; -%5kNYc%L^_$.O]S@XZ-fj-3m#EBMBcI4[9SMDus3$a`jD?G(cfsViAb82n4C,M'nEm!8f#c@#kZ#>"]mg`G3#0n&SC\PQ[C[K[]ZP -%\WiZn<0Ncjd=D?%XF?ZK:BHQ5L+WQR4F+0Ie]'^Ao+dcH$A"St=;?o%bQcjcmPkeoMEi(oO1lXoZ/ZK&W,ij7#[jRAB;t/^fI2b: -%,-m2qo+4oQL@0$n;H&m9FKi&ieRNG6C_O5*MAAD'/d-'I@RHf=e<=F(_u.]f/^`TB/"X?c\t"dY.G&36q.%[MD[:8kVZmEJX?!A> -%%MPT@HsL6I@A"@AMed^]9FY!,LGclr$Z>,KFWrr=bL7#ub2il*QA]J\h9:`g3.anm0;>'^bDD,f8.8n^cmpAZ%m5C$hMgKObBWY4 -%CFHb)?ch=u#jer3<,d,jq/I_Y7Q13+KI;u_Tb#De5UL$dkHsk -%[K5D.1,'EB.e->>3286/WH^XW`l\D%AuKE@NL#:nV87]nQ.uL@E+#Yl7WJ!,b&2Y(@6RMQ8k#%4,EDf -%[QS86lh>>4N9G+H5*.=Jdfcnf_4goP&fR!hciWRcA`Eu*]d=>rUrHe`GopIP]qg$C#ClLMqj;t(#IM)%RNZ7g>%%b_.LW/k_?OH/ -%gB?%p,ugc=W4Lalg0&KF#pU?,<$G6Tdm2.eN^&6ss4c[G;]QFI1Tm6UjPX"Z533]2t&_''G4PZJ(O"D2Xc7[bb7L4=a7q#6HU0-<5:j]SZaVNcDH5/s]X>"ET -%oK_14KY4d_0PX2-'*RG&Q69NR1/ef,Pb+<]7K2n%3:Rl&32A:G#O7dFIg[QJsH0`g4#?=PrQF!KuUl%pN)2k;Gs=@*=$ -%&AB9[**kN)1hMiWjd.^8NL97o7K@t)+!A8reqL,-30;krb#<7![\+_"it4q-:I1Lf$dRi$_M*uDIb&)kci@';k(Y&5$-sSXWK5FU -%^l5j5-5?b'IfuJidBN(W&Fs0[/iW6A6#boggSW]sr^uJM!UA?sD^O1Fue90Eq/" -%88`CJ%Z?4H.9[+KJsRV2$@^<66SP5-3BS_?69a^rS$@n&^26.PQ!On\Tgh!/183b64T9CmDhHuoKD[q-_mITIHmlcGp#A>J*Rlfc -%Q]bku7g"8k0ZNft!!,KhU2:)g=Q=ISXfY+BbT1$sDS:5]6a+8G=k7S)F,7'pdd?#tn5+X"RI;5*d>fQ?&Wr.Uc3G0:ssQo/7j8VEjq] -%SjAYU:d0X7IHY'0r4$$"Q6<:GG=3>#N_-676AH.TB:FMC)m;)klUD8UL*7Pt011%)T8qnNpLi,HOde+^n8rCjPfhH@if=YfmBhSM -%cZt3X,H6q$Ysldk+d7@@TltGUeI;g/q*@`UZ8uF9`mdE5N(d^\*.&`$.NYn9<"\QNE4-QaD_11'6`q8'a\*_*5)9Kp*Y#R]M$*_ANq/9%_F]k)^X]e:c\lrmu?,8T92.OL.PRiT+k*p@Z%D\Ecmj$Z'[XF\0C=jtAUL>.0s[l2:uci9(e5sNOb3.Shbq(o>drH]gU3ia]7VDhk, -%_ijj/*a,32+l:atC=7&dp`h(F+O\Dnb"'Bs3Pk6P?X?lq`ReRFjn9_M[sbXAX@=m,-%@uVTY?Y;74Q'G."s4LY&/53hslsaP'^OmQ\I,30D=dTE%b>91& -%P06Z,JD]d)e.JZ[V@5``1i_el*TD+.r%0s\L_>f;$>5%e]c9`FHN;`@mRZDg`Su2BtF5C%//e%^#IE -%8m>q#(u1tH9obEVb.&HQ,+asYCM0f)`\h%m0-O;&7DTRN/(IjH%4,?AlV(S*gJT;$hA?,#r!#=br^sErZ`8Q*7oM$Z@.<]$#ZD;a -%T)#==&Zq5]#fUcU`jb_<9hD+*%%F]U0UaLH(s;!72M4Y4+`"raI-*4*FZ3&#Bu#0Tl>8S29GC?DAq]&fE;19p0NSGZ-_E,/1VfIa -%0TX[[9qm76!Oq[S_8L;4`=)&3fkHCE4X"P^K?Js+bSr*i,I2!7)!>dhnG(@rn%TFm/kV$X&6rh3N>D_7@q<`L9`eUB!`]R=lq_#P"]X;D=ur79dR//,7OL[Y2DO\B2h@b -%j)8Ra(?b$o:RM`d.G5nEo+Bo=Y75XtS2A,9uK-WGUD -%B:`6:jFf.2W(`R)/SH=S52qTg92>Z?k?d"REY_8Y\u8,r0=YdDl(2Zoald+asFCJMg7#;FZCJdW)A(K#W]T.Ep77&ST7mPD>C/Aft;1 -%gnd]UT6WhfGG@PChSS*O[gDm!q)e0*nAa2)/B)F-,kr$(+fu81jCY8:jrHQ)!atMAA=YEJkPTVqM>8U'S'W,J;J3:ur$qadm%RD\ -%N[_@G&2ulg!Ej4XM>+!jdPpI%>_YiPj\LDRhJ_)X4k"uR"F?!MIUb4UIE&a<*k*XUa):NUOh0kq#C&_HD#65EO;:?.e$mW#AJug\bco@'Td6#%[N(E?EqJqTfL*W7Xi^aFParo5 -%*!'Q$"-N%51jI4TI$8feF\DQe%6m-G4^=&&$\9$7hr8@/!uIP"+779B?G.k5i=o7f'A+EuVSTN3'Gl"bqjL!=M)VY=rmoo,\*1E:67T8_f.5\Tf="1\$Wj(Qo/Z6*$I+mKo"L\j%!Gi=h(OK_1,7uhIbihF=R:(Ae_5/F -%;tH)T+R/8r`JSU('Vhpq2-FQ]1/ad(!jf&S>c(7Ea"mj<_Zac+1btm0fg4+nJ$J@H!H#iK/oE7CIib]&*t/-Se.25uG4G22gau/Ode1fhYk"ff=#Vc&QN?9 -%aFnql(47`\Lng6/EgBVOFDi"%3V.f@,P4gBkGGJS]*Joamg$nDbj.<&UE8d*A&"IRhV[3(^G?#/f -%JE%u#AO0/$hV0%.GJi9LjN#J&m>6g\#LgBg&DE@/9M`$6L+59)8s##!>&'5\l)OT$%n0)\$`;'-2Xfg&;R(G>UkE"X:'g"('>k1Z -%G.M;c0--!n0Q>PVV+I%D`r:Sq&aor\k'c(L4OLJRb4-)q9?*=.BBVFA];K22.nVZuH'u(_Q1aGBbaI&o45AgMq6s;i!l#TG2BtHK -%f4@&r1O:]e7MHIN+6iYeK";Ye,+]@k(7eN1FL\LY3sdSP`iE7._+1(lM-Lee?@%UL3Oq\P_8)dZb -%e+/[`N%>_5PY^/+&Q,Q;8"`9TX(pq!dk?Dh91I!eVJWKJg9d'V'D'SAmG8O\@rW0FUPoO7P=I]9::q[OT2_s2.0dYC"#7so%UYAY -%-BoTI?si#;i>59ORG"$@Vgb60QFqe..5DZ[TbQn60<BikeWRFp\l:)[KN^6. -%X@.a-nQ=nA%7Kp-ZFAoF^Jm@$'>XVfh[0L^qI/"0c;Du."Tpn]rkX;nAFnI#9=]8>.IW3e+I%8pH,3TUE,b,UCh&sfA.`V]liNfG -%UiqgJTP5D.j2GqZStCoL;j)t7"YJ`9N2e8Y>L@5@SP-Po+XINh!hpti-.`;F)2C-qOq95eRuYm+;arcLc.f07qg=IYFQ=?_]EC

'V(m;R69]Ku\j_VAEaUc\k -%E50eMroNNcaIf(\^GqH97tt\q#@W^87p,)h%s>.[PW[]8#qR,(r%<=Jk_9;1UnTb)gW.3*%ZCTb9RJ1TXgrC7p,Ao^$8p`4dIB]+B]bV_ftG]A*SX -%q/l\HU&UXP.qSqD0nsQD[s(#o`9bbtSn+k3ETl3NBOoVLhI+`WL+XYPq"MFBcn;G^/%]XSL7VDZGn-B*ruf'aIQ8K9'XeTLq%\QR -%rAoJ`d!s8k_'`t[^8cE2s7ZHdY:KWm:T*KG(jDP96D\b,GW+"%35Yd_i__q,Q93JhoVZ9*CZ+N?[%)[XAb]cnXEp_e?cDo?_T7&\,@<=mBJh8\PP-&D8ek`,Ld -%qqJ?):@)BC0G+?KFIL7.:!LVC"5#BbcEH77j%f$:AVj_._K(CeP-L400A3MP])Vk?lhra0WfZh!i*C&h(q=lWZI:/e>\'Y#X-HM1 -%)8L+Q5A*f3F2WMSmF'nNI4_.##2p#%dTi72[BcZm?t8;BpGbO4V'pu3";P/+VA!6h39/c?kA$(9":jJ%2S&1GK@gs*ANN&RZA+k/ -%^Yf&Lnt/hq,c]*men"@JgIm*o/`M2G=_4(5etarGj04D^W9*(XZ]9^OEaWNYZ\V%Sk^\JO2aK157pa^]rJ,lia,ZuYh.>?k%7X[t -%?f1lAo)G!j^a;[m:p"JVQ*DQjeO4LE.p#)Zg]p"%Jf[P.`e\DS\KN8CF;df&,HeE.OLmJFT0jra,).Z,#-`L0Ce(Q2o&)6H`7O=i -%7iW$!oD02J#:=Af%@6_.B4+R3\`oN2[F3L0LFWUa<6B7?;Yid\'ST)eI1?1D?m^o+/b<0D@2FMe(3Be$OZZt?23Ml-+["T*I"Zt< -%9*#DqLjZG-W9LN\-.uLNPLq\uOmQFGK*aH8NU!MZf`DoM@BG)4@SK@QP_tOEmTLGeGbA*qEQB_eca%FrX5f-.eCX<_=/1a!K>E$XBj#V36SdJR:%6Pa)iit-d]AA&RO;bSSm#,?g7h"GW]VYLB!M;0ZY$C[K -%F9&hF\Lp>fJ3MhVO*>sV+@72Fk\Luo1D2Z@;P=8l:TsN2Fu&jo(^$:&o_%Qs`^OPK(*GF.?kNU4T[/OBK**((`kM_d<"+_:mA4]@ -%0ipJEnhh2<$_XgPKI:o$NYs\G:_Fq)r"lY\`3sRnO0E^_W3jVPB6U3F+aY$s"/)]+[k!4!-EHt]h@pag&%e4A:?PY4kEiZ*NGU,e -%(esb@737>!o'#eqZ[l\$aCKoR1-h8jk#ItqVFTlL0FH)kVc\sa^h[o]cFsKq?pkE`r\HUKPmI27a4D^OjR'1adF-R>b(lp/We$>C -%:[T6&P6^[V?%3=o+o4WRph37?]H0CN,eHB-9sUd(%.5GKHlH;las-E=/-O69]HiQ)HjdK@9]5(oeeo[B6EC2LhtM51%uhLXE$"Fl -%+##.p-"[Jr-E##.I-(NcK:Xk]o[c2\jO:cu0g*=\d?NK3O)TTnf.[Eop7VdEl+i)X$J551mlrVc=BkqWZ7K%blrH@uoM4'AGP+3L -%St*lU#T/,9,_ -%?WE/.Uji\,i1SQum?cFP?"-=*?_m1V,LMF?`Lc)J8g.L\k82kYVeSnIk(dY+@sFejaMKs;)W:lI?q4q_U^-U5^\:,L&ppQ2d9Mn_a,hEL#.#_KW -%;nH$]h1rZjg;1)ZA5$[#Ma+5Mae5geFa9Pa*nfmtXra4iBtDG=IV+O*%dI9ghK46(].SR"M&h@$;h_od`Y=2Ku'>I@rX0`P>#KT\qe-R)'!m;Y[mAfN/9e2P#VRq\A;W'I!)91Gq9+]V;Sa56*-=_h#W0*;UEJ6Qf -%FM]/c`T!hb+Kf2jXlT)nc(VuGh>*rseddI88(ELb!n3]N= -%&RrmU")]NZc32NQ!fJFp@.aqEX88Lu[7@T@#@8@na@X7cbb']\;DkL4_n[A#:)Cl_Ic1=5o64K)_2KstV!dhFPe;7_#Y@H<$Z8M@ -%%qbD+_ub'lZBHFi6PqC#)CI,^gPs-:!nq`W*mK9:\*EgY=8UMS73\\E%Or;f0jTZrL> -%A0[&AggY`PekSgOTVu6#YB*Pg2Q$V*5]F)$1q)-@*i=6f=@Z#!-c6QM6!9T1&6P)dI!i*JSG8"2q4X*Y^jZb==.>bR/L!-+ndPVc -%9[!ou3.7O?VE0ZeNO^V-QSM'hk`%M"ghKHs!`hj22aQX]0m("=Gd7Gd$4AY2b:jh^Y]UVF/j%aQ`GXG^U]`S0_.Lm[+CBCmU&)Z+ -%YA3i$,R-Z6jVd2LS-K.Z.RkV)QpuU)OFA,GS$Y6Ua:d)^0k(:-IEp9:UAY_S`U'G"#_A(:DNo4d8TJU6""nY^H0lU&,npL5L!DO- -%.p]k';nakYVYeU&<.c$)Gp/Z?C#>o4SErnc%tH0Ii$BY<*)/@-/@BphN:dr=:inMtUf')\`YTunL,^[`H,Q;Dk/LP="IG*0 -%YJm>JDk!gGX])4I`8h\Ckp]'a6kNo4gEm5VDTuK+.H'-_(iF%",a;>3]8$opdS:K@FCih7C+kXl -%$\H&M_n_d;egQFU87R^9$Y>HUuFCr51R@'=d))R"lmqPprheK/;:-!l+-p(Aq"*&hK9#bYXXJ^d)?e;&;f3,dK6`fcnZk085!EOc&7mE`0t)O#%_jft;C53,;AG/cF$L'PCEBA0OiTgWEE*$+-8nXb@+GBJSFlQI`d.rt#j=t+S8:mQE5I'3XtIF[Z&4*"cUT1`1!/cPOCpLT,`>sOPnMO2!&1>o6u?A1hn`D< -%(n+aH?M0t>LiS#XQ5C\`rlYWkfbIs1\4?5JB,A^p9eKNh,LY5=NsD:%E?FPoP"LTf\+T$l[1?/t!_'Y-o9:_P>3miBUUoMTUff+D -%M:.X'$X!"LES1rNJ=\+^3Rk"q:U?Go.E+'4&jU1u1F53*m^$faJZZX$p=[>H"2U%t.HkOFW@Kisb7G$NT3ksmH;K(A9_8IO*_T/L -%(?#UoQ"ojLCuEI%V'Cn_IQQ@Q2RM37X7U4dAlt#r>g_F5HOD*uJh?MC.Od!bQDZZ;5pARJA(ZmbY].T)!Td^0aQ;GC5l]lO":!Ea -%m_'>e+QIF@mq=*$;M^R,8e;*IA?rLSaKpsd7n_@f/PW$>8ntF]ZHK_-<)(@DKK*KtR+''?.K-L@;!M=EArK=B&$@qAU(ha+4tZFC -%YC`!=p#^-T/jAlk(6`h=a6ctsrC2)V=hIK6G#)ohfo505(c4#TC`tCYpm?3gF0%'NOegk9lL?/.'>=;kpBPQ]_\sob#[[Z:^7YAh -%rZ<'GAn!NR@VleN+Q,#K>Bk)>Qj6h4H/=P)>Rl=.R%U1=WP0#oY*-`>I$]2"dEZPr&H,oHR]-%;j;#2)VH@7tD3J74T@Y6\N2DY\B&,X?C^*u#kUu`L\en'cf3@DZ@n<-$8b:GMY4@b9B1[*;.++]Z -%(g*^?JJ82YWoa4CODJ_K\pPZa>o\k+#=ZV1LQ2=/JKU)l#[ -%o-Bu(oI4p<4%To4"ClrHe5@>@b6B1X**e*Bf9:h=Wig,8EmdN4SfUmYGt*@J..M;/Zt!"B%KfF_3f]P/,#e."3MJpm09>RA'Vc,# -%A[[I4Xbe/B(4M/pWp\r+hOosY=@">;eYF8D&U,$b<^JJlg#n@U[@;`Ka_"!r/ul$Anktno)JJ4*PL*1soCHEUX%ml.R4KW;5YhjV -%"/iHV\jY@@kfpJM[>U$0rY72kcb[=h010)Y\F1KJ>M+c"/a5>(`D!oAhPTV\YjKKn'GZQGF17[WWY2:uak&'=7=*PQ5S(j7jjPo5&D_XLqCbR@7JDH^JWi^nn4*M+g!a)Zl%hJb:nZ`56NM2W\.h*%0`4*^r:X\(n@kb&m(_LNe -%MGffIcr#B*"e%>L#,=ck%Ftt2!X2Pg$k_M07(?9]q&]:2<,P,d[hBLC:/)7bdgetePjsp+'hFZb>?R"n[#dfl-,Fo:<>\Tj,;3aj -%:2IA]ZkPk9lu<`KTcfDj+dcfK1Wum,gP@g"4!30)fEPm7`5;?lo%TB[[+2T6;-D0Q -%>;`a[+qfNuLY-X*+Ghukd6MMW)DDl7co0QFZ$Q5SOH+1s6Xid[&/Y)W!aUY[@VUK0U+Np7_cAnQZDCa1\`C.C&K?As+utY3=tmHI -%GugCi]fS&sT*'P->/aFa/gnc_Kp<@tbA[,>=SL6`gn$bHH> -%@QSQW6)t,r]7tb_dRIHPN/'Q05U/XNb>P\#"ZD!R'5,h)ki\Vrk"$q9fH+"8YZ@QU8GH+qE+pQE(:Iu'5*LD]p_OMjFatjm`&kn9 -%Q^tK8k"5a1D3qE2,T<+r>p4&GZH3&4h#]W,aQ]e+e#OeVP\*uTTXeZ/(/Oh1&=[,1((Mtr#?kM6Pa*dOr\EcJa\GB;1(D"K0,2up -%Zk%;,MY#>d$aZ^q+b+a+JA%>MQ@rncZ"p(.1$(H3LFuL.jLDRA3_eGnb=,M]MU;`D])6@rG`fpg;nndag`4J36TV3&S!iTt[US4i -%;!QOWXt_[c<(a';%Jb/+&ruT6C8Bb=_HPLp.#9_&&pT$3>0TeE[Us$WKfPJ4,cde*/l!8"$9'6Xu0^-5(gSSdg -%J5`d.29S/j,eK0."=b$]=L5%;8u1GMN5[,IZQa''4AaJF:Z\:AK79;?XO:*:_.2SB=`'(g0\qX#(H2e\,esuD<`D39hOqi)4s]dA -%4LO-Q#?Rm!77)%Y*`3Jj$I>rfC'kY-gm3>,'a1t>&(W:rDU.mba8cHfZdC'81G5M+l'*$h%d-dW.m3Bo,CZ1KX=t/O -%eBC.8!(ZJ63Z:^:$&MIKG"bPjG9skE;qh_,>)"$Ejj[A:J/OAUA59C/-YX>Hd^%6"/!ben+TUecM>N\Y[L/nu6!'?9;_51BlL3b> -%i&I3D4Ci(IS>`g9%7*;@kC?ne!3>/k\MD<1;GfEH3t*!&nmO,$1i4[9bTO5tl%5NaARocF-i'Cq(:BjW70pV)<1Y3;M'=)_Gas65 -%53bO.:`c^ZpOa,#KSY$'f`mC.3A*=fATFg -%Pj@"g^kL2Td9l&^^p-9A'&M`V-ZIu%`[;:GVtqXI4?WH$E]>?0i,?K$E.OZCSAZ:>8#f=NmDQKX7j;'m@ZnNDLC#,tU6a<\J7#56 -%5h=T_HS,?W@\D9"79WF5:6m=2:8eqDhuM\138cM+^`#q(2A2&T0"Q\HADmGo%d'_>NuZ`DHI8 -%Olpa$2FP<\W*+&MN?\.KQ^0(-/Y`"PWa"hCF5gI1ni_;Gf@5t]Xj=_l@ -%Ig(C*Q,c/!-`_EG1dNhB_+=4QSP#i52oJVP8L<%:p=es)_JDkU;2fUAFA"3?lC3h8^Wf_D/e"e&$BRN'PQdJQnl":hX/R(<:]Asl -%a_bsi5ThjLPu2$3LDo?U;cM,U.[L8aIoQ5FirOAX2(+V2S)ZuMB#l8TackBj7d<(.V:Y$PKUa*4J8W/!8:P"n71uVcgUBAnE$:>9m(n@o83-S#:`%ur2_pO$%0Fmc)':NZ'^%Rgg+A+]3 -%5c!M"0PosRJes.@%[6El5)?d?h1/%(Nac21k@oIUWN0I\A&u(^E<'S`%c;*&(3c[oVs(Hp\1-[2;gj6a4gN<,o,s'JN&q(db&r*e -%#"Sf*`7,GV":4`:15`:Ub*_]m2u@(M&lJ!gll")nEl4Uh#oH9:%Tcl<\hMdUdqET!)f.MM@7F*K(p/VXpRK?b%1a,bc!jQI"lSi# -%D$-8fDUbbV(75Rc(mkqmNc%P6/=-iA:U1FVD)149REM;l:Z2f%_A^-Wm1aOP1u/u2M52U,;oP5l44rAd*K)g(l6IQ]t:od%7dLCS5HM?0D$KM$+$#:J?b0M_k(0Xe/;IL7sJMmq\R?goW/IVAB;0' -%*:u8;1J.M"XXePMQ`>Bj)K@U+j[<7Hm]q=D\Jh#u<0t4rHk&XZUZe-bp>^q/]h]$Kc#$=V:X@Dh[,m[a`d%a^'UFA=O.D-CY?Qa' -%3dGGg!B`3@:4hL4[iHd+&nRsYbe\>)JY9SJjeAW>i&m3fXns)N/-%pZX#LRDVS$tb%LuVOpEnTAdFlEdhrP$M+>sZ\a:_,e"Va>Ft9j3l[[V-%6hK@u?H$j'gA3&).VKkkUF;,\15-p6.#+&mpoea)%H5.utlcH67_uRs]jaA1ik.48Q#_uR$D*#6i3;L?4dPIpad**ab -%U[te-[2bhJMW(9']j>>"C=e(X1VZ)ns#))+eQP*0Ys2_6g8t^ba*h$"2u`4r;H1jrFqa!dKG8^T/ilKb:f-u*G9DHrF.l_r3r2^K -%,_;a0XuT#]T4bIh.NE-mZYE6#bpc)WVJjnRl9^i2aXdK%H&8N#:.W7=")n1m5ZII2bMg4)$^BGrX^-C5$Is,-pJ[[`R/.O's7Omb-If'OJ&Rj3Cu;3Ha\` -%5B1J,&oBCo."73TD5N8V$^K$QM[&i(?O*_W3\M&_/;_`9ZlMU\?l(C+q&#)ghlt$'((0=E_bhQe/"CZ7>Mr]>d('J#p"L][*%O_h -%I#>rb]?S@0DQ6+ACik;rh;G.<$s-(U6"1SW"g:N0FJgj5mUA%;LAs/KL=;gGf]pLn<9'j:ZP<:ZY:V_th'EDq.%Bt/>OMn2!_hA$ -%i%rTjh57B)CDhlq:J\!i@,`PkeB6J\/M.LEH,Xh1rNL"`,16p=TrtAb&`T#dF!`+>qN,KL:/JuJFB!5Aq?Hp;s4\e;Ho3IjZ.(OB -%].kB0]9(=8W2U3K/("f7g(l$8?J%7*:t-T\KpkoM!s%\b*LES=8iWL2`k:sumoMX2MI5-/E?V\.>/Tj5OT7aJ#u:tJJpkFHokAR^ -%oM"F@6ilT[#7S1>YrB8%*en*):BS7(WcdnF_U7XW\0?1lQRh\q*a;tg?-L7`9,IUf2`\Tl.r+" -%O"DT%4lKugX=Z7T^tW%ZfiUZLg!H>P5;8hNl"9c\&ouY!#H&$;/NiI[V=:rhV/W&Zs7c.(VM7l?[:\,tK95Gr1g;WUWADC2%'a8V -%GV%NS9K5DD(7+41_]r.aE$^eZIqNC?c%d"H_e;Y+Nr[R`:PpC?`B"go0EnYfi[J(BQPR&@2anXJ*oZYLX@&Ij@mXcqF<.VEgo*g2,4*E*Eus=)-%CuYn1^rSu>85i>Wp+SlN#*Y4UHDLAo'^6-ucNfc"=ADCSnGWb0d?[M9,6otWHh -%["!2).VmStA51>":C<0J%',p8h58emrgVf2H'siM]"L?qd7l2\#_7.YPaehe0;\o:;-@^WdghKgo3#O*?tR[k!6gB2aTEZZa1YuH -%``J[(>=m[+^iIO"E0LDKC5`EG(_uP1.GEs%L=Z,nWt&#$a3T9YN&oc)"\m!!m<4-obI!Q6CmK.:NWkc2ZM/Pf^!59)Q@W$E^B>Ya -%)]-&XBsFXK=TR;0B[$os(Sm0)])AeNaI_[*k6S_&=ntS]O41\2=f=#lI&!X4A=3Q9M3?tN%g($57$19S%t%hi@d:+:$ld*#f*,?_CsCEP,:u@SPA_"S+q%*bcSYo/di:T^M@PH8SYcMFnYhp -%S]$7Ng38?X,Rj$X'O@F`$OSpJ0&/>7K%8)`]\T\d[o/mO]^.oRB:G6'1O^Z?mm.5Tl!K4'h/Mlpa#0OSJEb)N6I;G]4Jl$Ndn6f! -%J9V@p*+%G:?\_Z)-)A#Hr/?*Ch,>TDb97BpiVfp%8O*<./(CdeG%AL5+6qOQD(eL:+5$E^@E6>:j;^M/V;$cV&gX$iWfEDtOtMtj -%XO0M'V"dX4G4@E.cNlTc0!7Y+,Nj%$1i.^s75%*B/HfFh7P+CfLR$_.$+K"X!XEN,ZI',r)ibbg&Q-5,J3pJI'$+oH;:,:0<=+U6 -%4;[o7/;^092[(D-]*,kUlc*#-n\*.T%Q>lM=4D5@I7!@ElY,2We6ML@fH8E()ZTm25/]kg&Nc:T1o[AtTdd"WV:gp`f7/9AMt3>F:*=8F.KH8fRgn`rM;$L*T0XPD8sD\J/crLjpUG9[J0n.=Lf!V;.".83#] -%Ba/r-:*.?`\3>AnZD?[lZ8*Q?!9>$YA)62jYV)%!kTL5t``J$G)##Y3rAam;Ai2=\1^\,9cBF)W&VJLa^M@DDh[u9'paf(k*JAbV!R7*& -%ra>?;2l["a/MDZg@6&A4#^3^QKLEt8OChkMS&]0rQ<.l"9G1[A(R#I="KlA(O]$RP!qAQk;84[cgNiL\dGnr9\!]n)c*:/344Vb> -%)5s\GU.GLA!3Hs+ZOK;BbL/[)Z_"uOdS!H8;0OHmB/VAn-Urepe9FteH1X"a_+%dSp*6ZWA+**]^ -%>5&nfC#^_or>&[&))2k\:BCHeQ'iG,65EQNMi3;+D7ig-ZY`>^ZM9j!FY[s]UmV7F<8#aL,QRHJp3aM*[,-mI_Q6,Mj2XA6:abMBh>!UUQZ>m>Ak2l2pcc5qtroL+BV2H35LMU^5,9;!Gq.N/0%L5(hgE+[p3Bn5^2a -%@!=OeNSAU2>dJ#@"JDt3@[FgFnnRYq3fP6=Ii.9O[L_m(&)hcijH`N19lLY_m9&PAgP)Qo -%OpT_8BZ&77NGhM40"!#-<.Nn/Q?,sRSf>f4i`3IaHt39`2%6r% -%cq.;q`.hij'S_UN\CGa?EJouZFELen%6cFtI4%bC0_nP-11bj1SLei2^,+i6_M^c9)KoYs-s[,rG"68o8kqCQW/9P0L:nJght+*t -%@&ZOd&;*\LhumkPr%"+mO@Uo]iDaIl4:iG1]0fLB6K!!][K=(Y+%8HHe*dOk5%:49h70c+Y[56P# -%fJF>8D,]l,o,[FUUL.t:_3U#mXSZAYW*-P'&j!]SINg?F@._o;Dc=*"Lqbhp.YDQ).-k'4A&>DKcZd`c@pUNH6h8'dbOM]u/]e6@ -%$\#NN?e7N'PQ.Gu!tlt^;F[i6p*7kpRoIPW]`.mp(Xj^79X);CV_hG"1IEk<8DkEf:@*%>4fudhe#[+"pG9: -%[2/0Ba[.C]F7@ct`SAfC.okEp`@GT1+M:(f46Znm*AsDGgM5&(qnF1Il.Z=heb7YN<92I4'f9E*[-*9MXt')G'9SW3'Wm([VE%c28ErVEW2Y<4"<)Ar5,T`!.(b]Pf>Y-`i>.et=]C`n-;.U@ -%lR"EcJUX##$&]__d<&^*BQB43Ih(s//H#)Zl)QA41`.%$@OFLpLNS7a13Urb;oQ)#.>4T')KBEZc"2g8Y99(pMS4`Z,%-rbeus't -%5\qq-f!U*P5jBTBZQnP*m.Zidi(K,h3LohcSV$Hpi"',B[@8$%3R"sX8;]Xi*6WBCK5$g[Bh_VEK=iOK?.d2t8^4;kiiY%41E"r1 -%)(6B>[$eJ].,cFt^CpI31_@WN\AWe^;i<$oLmO7TF,u=\*177X[)0GW_\B/0%Nrn,eP,]2EP>$iOpI9d(0NYoYRX+Zb2Khp$j2R% -%-CB4oGRi179h:l#AZ^ob%DNTo8KWb!]Md6B`fV^pN!&+%))DpUIu4.QK)[TdBdghZ"Js^F4=k+^4]j\+]9NoA7f#"Z8D;Rh:(RJ[ -%%[VH`@qUU+;Wj^;@$U!>r*`So2X6/n+K6J.M7a>/`@P:Z@UF*uNd7rC$!iJGS2QNOlfZ$,3AdZ'^5UQ@`]jO5fZ<9]*D*WY"=g[# -%`]UqAK706:PCR4VT,Q1q@3t<8d(0<@+5;[1TPX0KA0ps0raij$i7++-;HDe'K&[1om4#k"))>Rs[TGR9Dr)8W_[3m<*D"$/;G+$*Z8uTl9NRMB -%9*HoI.9);gR&Mg&nms,B]8o30rbf,[2L2Q)-pS$;U_Fo'I@4]B[P)BKka@#i(Hh=PFO=o)buRFaYnSuY3hM/)6[>(M#;m'5+]i[W -%(28J+2iQfPic&i-^6Wa7Qk#TD.OKH`GIbtq*9(&8>(:5H7o6$b0NfhDpe@fZI?,t9WVR;Pt)ET!03eU1khZ\-'Ca+uL_*lKUq9)=dVS+D(JSGO\ -%3J521_UuQ.5B_rg.[jd=E+s6ElI8Hk,&Z-<[n/T$.H:mj&eDbC_?3;BA6>i"8#bD)Z]'KYE!M,2qMpi2G5/A+IFk7FMl6erRnM`` -%$rO7@7^ErRIC*ok=AmdR,X^M%L7)/<7N4'l%eA:(T&%VXl#`8[NZ^)Q7N<#idS?*=iRb]1UM2&I4-$qUZ278%!R"@IKMOHY]+'&R -%$m4nL.U0Hr,8l%_%6mP;;9%FEB'CTlI1>me5)P[SS=lR9\BoX<3Kau^8"-C[E?',DAL-iAr8h3VeZrX8&[s?W3)O57\bs/P)*I'=p!Y&$"-.]pgLR>$u's`ps#C?rV,([DZ^[hfn@*50b:Z^.)`#/Vq\!1&((b_$>a99"6-7!M -%)3Me=kCu'[\ua+c&VQ0eU=M_W?ogkdMcCW>!-mI1EtZsVSb'%b<$g;l$A=2;5Js@!IFcKmsq,N`R[djLu9*M&O)ON -%&kX7kXMmqhnS:RESI;u,A;C'pk(2bpL^F3=Y+M)t&oW=R\YhIfn,L$&"&AAc"bXI#JOC*7TE%Dc2*1usXi/pr/BDsK2+Y>oUVdm< -%I2^s=0uVaD6/a8G*/HM("e1DRCYikKED6cBA?1R3@Ddl -%'%O/%Y[@ss5]u5QF1tfkj(GmcflbsO+G(,(,g&S\mAmW2!+r6rU#\VGW>P,$UfSWJ\g.4+PL9X+_&qN5+o&A1D,,Na*Y&c(i8.4+ -%1E:!KAZlP,;1Gle(f\Ag&_n+Y]BkhTdCHAOK4ATb]Mg.+;hD=1R,:^F^lBo+Y\10o_R"R-*!WMXC6Jdhb$AI0b!4T)D!siF&5-HA -%D%W*>Mam6i>]JUG$Kd=CLsAr]('0+2/nsR'k9Eo\OY]8k.Y@14SB#;)cH$@VHMVSig]%`Inbc1`PiWLLVccR]&;^\K1Q$=Hloe@\ok\ZJ)bTJ%'a:+_S!H@_VN"at)rm?J;^95S.MIGt^ -%X#oj!:'/+T6V3L+<`>2eB_.1qH"0+?t%R6^,Z0 -%MUF(r7d"Fij\_RCTu7="a!)cMS3hOVnF+8c!oU"ee^G-O2V$<[feDA5PfDA?([>Fkc@Nadt\o86SIF8%U/Q-RFG?9HQ- -%dPsTGNL2NW,p`@fA#BB[,\DI#,$19@X4[=RaFM\Kd+6-mq-Qp-Q2400^!1%FDR9*?::$oL#=lYZ;Y\Yhmnls<:gW3iZD_qKP/qff -%?'cqu)`_4]!psOs+<3(pV/QJYM\uX+#bo@9$m]%(Q%/ouil7?Q`kmqhm-I(5P[^WiU\S;nLhVi3KW(E0IeECp;1.#O,(G7pbdto` -%rN!(QS%o7Q38:AU[Od#65o0ru&dTUK=b`G$FI`=pArqNDk+B.dmZVX[^n9#I71mF8F1^U3fcpT%J6SMe!EauOM"Dp&d9Nb"'F)4] -%Ui\?l#<]pq9p#s)n7q$$juF]iSOm@TT+Y4U<5:-L,\9^\%V$)pLIcllpeO#-/4#A(Q4lM(:e4"FR.P$+p_phfIQ"!9'_$%2@9JSA -%%'uq5mQrpe1b&I)7cGlW+R>:e+fH -%lj.h\-6l3D%"&;2SOFn6U,&n8/qZ2K@)J^mfa)N@FG..O!3?1-"-1dMVk8RIPY@:/ak2@_,5u7L2S\7PF;jEPG0]4pfB4Hs\S\0: -%dcPfc`Ffs3m%p8F%"e8lA+KF\LQN=)L&+O(A&U00sd;FjUlE6]>&&0!") -%R/YHnfRf$!!VV+J/l)%h?aKGa+hqPloRS3$AM$eWFbH+*-;=&W2=*N[U=Fe:=R^m:E@f9EL"I&LHn$Ll;bV"bX+fc`da -%2D\s7hs&i;eR,R4kWddu`$Z@F/Ib>Z1#K%bk@Ybi\Xg'-5O6J*bUA(Oe"WYc^nSPnAraG^2)*C38D,N`.lTW<'_1\i;lsq;%05;n -%AG<5:'6Jn91\bI]I.$Lp"TPCRVob3<]*1.o:+CX+"gld>%9k==0Y=&:)TJLcR -%D)%'EnY.M-@ILMbQ=Umea5V$rGiU_sd?K,;;*9"5Z]LJ%q*nFL-pGKsW9NY@rN)LE$)d![J!eIudmFC`\i0VL)`lL0[c+C.3B^&b -%f#;(LeM$:"AL-#`^;N;H^o]NoWb`pPVc`35ZPfOW?C#B8i^utK]j"&K#;3h\<@C/+"fJ@6A4$\_(Pc$LNb:ed -%Go?H;X?eKhHp5tYR_sm6\u+b3[$p/$1PZ`[:l -%;FD>+ebM$2*&d?^7&:*<_Z'bXn8o/7X73HYg/*MJ3'a<[pZn"jQegTiKdfKoV82=U:N$V"fORusVZEXs9UOp&AM_s?=a<@ldjRi\ -%ZjUAZkD=&;W2;IrPc.?gK]2ugmc<0O6CqG6QE[-7+C2-U?rHJqs-2Om#5]k^Q.Z]@0fShkROFH3S,/5^H8SY)@,=+3j1Z?Wi]'0g -%U;A4+h.2A)N#)!jKHEFJ3.c/+HB<4^9Q(Mo[/J)N@2i6p@0ipI'ja,%l#"+J7?&\\$ufi%EAeN[ -%l2:TO&bS"iHeDsq,`6Xr\2&l0RL2YATd\&r@o%r\DHZ'4GCQk>K9K%ukd&KCZ$ohL0Q(DH&Wn'$`afeD$pDF[Xe7Sf&@4pq[C?qt -%5%C^KPAkt_nn-/g:M0.fR7J?,+nUm[_33eKkFs7W^Hf-S)+F$tRsJg1-U-osUl\hk]2R[??\a"E=FI\7rb%j>B&%[Wdb?fcS-ZW6 -%ST_k<@G(Y#8BuHmTJf&b(bg8GuDQ:d#'u/_mnXRi7HG$leQJY-d"?A3[eJaW$FFpG#>@ -%?Jo$nTeqj&&I%2S(rYJ0qD8lt@=q\(R-B@[d:0`Ta>*;'9CFuQQ\.=sXb9h0p_ASpq-*P,6Ypj?WFr4#V:/gh&XlJ^3:pVXA5M@65 -%e\jD8a@$W1,rJ\Pc.&jXq-t!@:!72qfV859:08;IB6HlKSGGdVB+sC#_(f4;nX$8D_rGCF:f/=3MN+-`!JP/P:VfYpQ%K7]O1V`s -%qeQO."Ao4!=#;RXU.Va@$PEcd$E;&k&/RsKJ86IYZQkq*cM@6*J*9B2M39!,@$s;/R]T5LQ*GH&2Z>*aR`PCMY6tJ'BSeGCiPU%% -%X8c:6+d(HL9Ms=]tVT-W`K8l;&RO"E$E;EFV#CdP:'(!>oiT]AC-]8YBEkr$I:G`Z#A=^LA -%<4:'XTgY9H\skf2@rsYT;GGI`4LB[U*O>*Q(R\![*!.^0"^3kYTLB8AKgVbnl#%::mo>K^"h1TB&^;=/]t3X$:q0c6!((S*j7mG3 -%X,I\KWKI?r7X%FQTEs%.K#+mOklDYI!XF/>%oKW1#>1`#+oI@"]1%_&:^Y(=2?4=ci4I[R8PA)UC37jrIl`tuAW,+f.r0p[;8U0Q -%?2@4KJ]Y[+RWUDIB.<$5YhL`0s071'9L?CF;7=%"XDZLf3K!tf-gDW67jer"T>TMcB84-!6^UuID*e1\Q&11snd.%I'l)f?=.A63 -%KJ*?fkhruG&;`N@e:],9AI:/a81K>;.JDiYk"GAt]?usI%$GB%%69#+h.5jaFOBYtX.]-P2?YJAVXj.g];*lB>%\r.],CR^(ECf% -%#B''#`&8(m`bB)AS,'>JBdX9o<&VYXZOPb>AK'H?'%"^#_#i\V19J\lpiIXP*Qp3-7$6P(JL$/_=Pob4B$H?MO$ngk@/I1b+MeJ$aDs!4T%GY_<^!?31;p-,DrK&^tXTlg^o"[4+[#HEdF[D[6B\*@!PaHp30%m4C=1jp=Xm8M$8fg^]]mQ6[Ms0>AD[.7Rr$'C072C1eUkf9j^o_"uiMGPX -%AE.2V7J%5YkJM=YPOm]N@`:uHQ47/borgPF,^5W0$NcG(ou-bg/<6+UI&C,(<=gHa6R_0fT7H9*67_T/_$j/ILa&cCK>Z]fh-\,Z -%`s7o1O$="#[0-.l]T`^Rfr3uhmG3G8^Y?A!"Psiuc)@3X>$^b[_G@;.jnh^JTjoUJm82%$>Wu(0^r(221ZYZoL'^DhE)8=97/rur -%AJDSZ/@L(k!@p@ghGrjGr_AYlfuLl2BdB_mb5>SK]L1;u#pP/q&Bc_%Hn==#99nDl.OJctBnpM/(1rO(%6U\Z:?F',DKMDC&e?.m -%,Dcj5_HKL=gukRbaaKeRVNQRg.,[X(`tqa#E-`b+XRbQSZEm%Tb*`k(HDd4[*gV8Cj9?q,AC?7J`:K`PdMu-8SV%^h+(Hb=mZ0(c -%`.@b(TN4F)JT>#?iFT8MghWD7>t`kg@e/J$b1L1M9,6HF^E:3Lk;Xo*pn$afa%T<3>HIUI!-4ZQ-!1PN-t=EtO*ju6Qc+;q>W'1? -%:-Gr$j/E6M,J0eC1*flD)LlJ5JVE>rj:D?iPpV`:Pl&VF-ZHp9E'u@?L&N(7.Fn^/3 -%Y]@.3TGi/F/IG(+-SQs,/(i<,$%pbXW)ed(OpA"A6"jbRFqb.]@Cqt++mD\%j6Iibh$4,c]DLrZfT?U8^ebQiR)6j[9O6]HNjb'^ -%Fhf/l.SPR2V4"*))#8$;)&!%#IF-;qdm?&HDA%WcU],mBeM9O-*+],C6X5*up6 -%n;fUF4V)AV)N+/@%_5QOQD&>Pb`>!.7-*t.>t![FZAk-FY>tbs/8W!HV1Z+KMlr>d:7Y"]ZD173Fa8i=P.)]<+Vt5u$:9MJ=7[]Y -%9@gdY%>SoVWc!ZL,XLr"niB19#"`K"5I0\#8d/ -%-UH0Br^I^_s0T(LeX\qT9',0Z,R`&Ng+^rmd!7s_:0aTX/b;qTP%8DL9t2[R3ab3IJF.Z8R+1O(>CZqM*4'/'k_,cWhV,5aaU\5a -%<`+N-iJK..hNFTN[nh;TnOsnoH6FO:_2FL=\D-Z5PH9#$bgPg!D]hfJ_TA&]g!o_b+tij3qu@r;nSELGa#CU#3)f1_[Da)eW90h& -%&,UC'7iU6r3)mHl/@!jdbd@g5M0VcWS]O#pRhC$I<%&*XD'M`74\9$O(NSk5-hpT'>;MtjqK+*iE;\_s\Hh-7-K -%Hd\;,kY`;:_?Ku1Yl=t*d7>EWe_mY#)F$hXqC<`s -%!L+Q5(g)f-D:<:N;hjU-*r+j/Mtp)n5DJn/s1E*:kgh.P'KE0XgoZUhgj*_"&?*_MrmHk*9NWGFZ1/!.!-!VF,])0dmNi!Y-[?f) -%IKOk-`3%$1-*c<*CJm:dA5d.g=U(if4GBdkdT3(=+!^!DM#iO\A-2OAHoJD0QoAZT\<=qr81d0^#e:*YeF8]=(Blnl,)%-u=IYcF -%r`aaRi?]sVs6/'I<'ZRB60/),;7Zm%<'$-*Qtipt_0Z7WR\WcI%?l>$U>udX"rf)&R(uf@G=o>Z5n!k88Q()s$1o5"bre4+PM&6U -%L0D?X%I5IfZG;SaK:G2L?HQ[Z^lmS0I=Gb#4h-c#h1YLh'.no3\-F,;!HaJ%&6m%PN]eF9TiqK -%ncu+S.Y\U]@gELa--n'f.=HB_=2lA/oQgtc,L8Y^QMD>V0uP9k^$L[T>6?(M5($,0V`W'RT57&8`*"PnY#;-TYFs>E,pV0!Z!=5q -%G)JJfmBKUdL42E_(V]qaT%F]eA/Z@[ZJ7HN6#[f`a,@FD[\71KK7IfX;PC+FbPX*7Rq[>u&1\)+)'RNCL10oiINoJs2@L0"&.&M* -%e-?NeIrnYG;O1Zu.^4pe$mV0LV(Q_[n^su?3QXmO3nf0_!(n5q[9k+@JbU#kR;-cLiOBGj;Q)7$qf8#Z$Lf(Q2*f<;C\9F)Rq[XO[F=men?0JXUfShQWXsF.9FboY]CQ(4,r$^i1,s?q@."XCIL;?(0oA$(;:;)VO -%mX9"3Xn\W*f(i'AXhs4/Hr6Gb#AmjLjdL`AN_Y,S]9hI1WEd -%:b[9Uo4FVeQ+Eu6UFgS"#Ue#L?TJp<*sIco$(Sd>E#6$*oR*S#DQnPfB*muVl2WYH2)pG7]hlf\Z#).,W"_"?=+t0'@KWF:lSK4> -%P&OO2Zl>VT8jgQO.##2W#`sJmh1p83cd.2J;^iZ=_V5q^GciUd+C3L+1p%/Ae.?R;XBbSYJ+kR,RVrOgp4j/4kSmJC0K/1XfW,Xp -%k;u,r@%1-=YRh`^c,cmo>)FT[P\mEmaP*HC>4-')_?NC`&Jdi>lT*+sR42rUf(F!h3A&Z(+0pPLJouoA(o?BL -%csm$61=4)J@>gcH<-@9bj_&fo`&L$-$L\Xn7&kf%`d%rq -%ISA^"B2VPI0TltXKFM0]$A&gHra.;Ei\#!5;5?2B<>1dJP69["Z!h>WPh22_EAc)VWk6E8]jf(=e>_lXTMNf4Wq&b[icM4Gi*k9mFSqN(Wm5CRjqFF5dc2l='k&#c,_3-FFt\aS&$O`+82ddI[Oe-L.ATb'CWZ/h -%d885-G_f[a<>si;,f-VI$77>)DNZQqaQ]-M>+$*VDa9Gh%re,jkZD^pM_V@ij)4eVlIJI'"f*d&@E*[kiOoLWJ=.AI[>`@-o"(lp -%i8T]uXX0F*l?3M>nq]i.B"^pZO*NJJKq+Fn.5RiRi&=>";K7Nu/Fp5_gH[ZG9)LP:K,PMp"_*n6"B]W3EM'&Lh,dKOf"m)MRLCf2 -%>P9XH:L=#U�qm^(B9L6P4oJZf/cQ^iIj$g9?*Run?2+=dfR -%&^_0,*6o.?beplu3Vi.>\8$#JE-=5b9mJWB8pQ?*Tna8aoE`HqE%ah;(/8:k0OR8h,%,GWp55$A7G%`="uWQ'<_oSrL]Qm7\O=fp -%iD$#h'A+.D01ljC:rS0s7OT?!0Uf<4m&Fs]N5*SWMjPJ"c!-H8pJd5KJ/g"Cfp1uC3>FcT$AOR1='k+7i24;PMgscqgd:WqNHt]7 -%r0[MbL2/P>br[6s@Tf";n`j)3=VB?eW+nj)JNLX\6F:Gc)B\K-Xqp;_0!7abiQMqZ"(e!gDQT_LpiP@40>MPE. -%L"0dpoGW/A#!O,9_=tR%Nu/:aQrJp[I=3<.blS^qm`HdGnO0'"nB@XpnD@Bn7gJ.>l9uN`2t^>T,+L^I#FtF$9@Zlm0[6/ -%#o^AhQLc/qps(STr4ZUKoqqnA:u'l' -%XnLf.?sb$KMH*l5<@U7tJ0cGuEj%,SbO@9#gXZD(!@#VUnVaWSKo-\ET0.6D^`HT8-k)\#nE0rq]0UC/s#cE-"lCpi]eTuj4W7??7* -%?M6kGJ/'5PT/c-cCp_0,j9[9O#m2iH$`+m,NQh:($_e^;%o\K`86_\mfP]K4^2].>s&7gS^mlY->68nIqaFI#jA)^I`Un/$ck2rB -%F;f=FPRAb^ib@-$Pl-b+`a+:X#fL&S5*>nKc$VK1S!rtUjT&oQSYr.JSe!,bQXn?\#W#Z=3o>fP6(/bWZ41K@SA6kQ%\]qpU8 -%bZ!![P;`sRmD#4Mi3FmpJ>fYJ(^Q=A%bF,9`j*a/FU0Y1e;7/[C=*I*K+V2h?A`bd*R+6Zj1rqqkBJ`K9,@V5Z6AKja)P:^$:+5r -%m]sSq=r@aS7n93)TAoZC11=t3U;fjl:K==le9=lV1FkAiR)2da*"`"dl,.MDbHC@o$TKqsRG8nFKmDDG2CC`O`pjPKPu(JA*[r:P -%1Ui1qaC>#VL;SZZ"%8$V<_]"`*15,B2(-#.<)9p;-]&b^74e4mN6WR45hFros`c.+mb@GS6>i=M\aHOf:cQ!q>kPRk$F,2*;DukSM*'86`g*T -%NIATOo)%28X>>leqnS+O]#B:u*d).@o&NF##+-H0^``'"]"M$r0Qe-0RabS!bRUNbk`'1K`(]F&Y,([40RO*26l -%YZUQg9Al@d#cYd:6,1eodH\Al4(XsQr[[ig8SR#oTW9Y+H6/;;)$Vq\lVrIkbtQo/lED6UruafXMoPn"=0J>jiPV\)7+K&nc$e+_ -%8@BS)#uqaG<#DWGA6/bcPio\_VnYN7ZuK1[L(oUA^_A[>%kM9l+j7Wb:u:EY -%3?-YrnNmU?m6Bf!Jq_pAKtnpq>CWYB#a9oA&-l+$,RnQ\!hg%KC0RA],`i`H:[OHg -%_nP$P^iD"ia7D3g%qZ[@\%6T/[KDG_JFd?pQ6BH9c!9g;W-U_0ZkJ.L#/$lJ*_Qgm"RqeG=[EfjPKYG\""Bic=&,0,FegR(\'baV -%%?5O=Ub+Y^C"BELmdrXSG[_Nf)UI/S3nfUNj;VRCV]?0i)()k!MWqog&,EhR9F2+@"AhY^=h9m?EbJW"fU=uq[d"TKSjM'D2)H_r -%fT/R!!#-aK)\`439V&VE6U9_`@,eL"m,>W"m&Ch.'?_gnl1g`n4KL`Bf?WV[snLM6aX!Pr,]2?US2W([ULCiRaBCWS`Zo."1L.t@VP)G2;*%?)i+cZFpF -%2J0LU5)6\)?1?hNO*\l9`.1fT[H=WNfid[+$(,,rR"/!H':)>pN=u5A.+2T,2!_sZ76FDb%ZjAE.9.S=-PjRI1iK^r"ssQ`9Ytsf -%3/'1D9KRrtV/j*`<`k%qm:,%q7XgCJfF95mi7Cb3fOf[;0p_nP6_W8AW+-EP#DfpPXeQJqDR'io)p&FS_W:o)=CSX!/+OP&g[$0e -%En$lXTn<@*<)F/+Y;!c0QK6b`34e=06KB@@(%<:6Do3i`'H..C;&7LLdNO381GJN#5Q^[W-fYBnFh1>>%X"2!YU$=r,7r,OXYT>J -%$t,&#PJ2hD2CiH$9*"ujp^5ULV>N9!Qg%J0Ak>IMVjJj(7W@c#[.Mj5aDQ1E]"-V91b4VW4OJ:uc7X'EOf068#/6Hq/=5*O&N61Z -%fcUZq\#sf]lBmB(7,K%sGa&jDkam#%*@3BG_T0]9hPS&bn?NVLDYB@(Jd[,)(E'.'I5JNm(8U\Z.R6r$^gHZ8Uh\?]F5I=5VB)!pa)RDY -%;sHan_NU]bV`$=j_T6VHJ"VF@/AM;.!Xqs,CSf=gaNLgYJ`2(ej__;;.ZZEDW1!Y93Ou[/R*Kp!gi2SV\P#+.9/??)>?HM@7F9%O -%UETD+EVL^JP#$](>$i\XfDB@BUjidHDC@M>-&kRV;2G1M_3gqB\JK,\(IP<$GRDQ5&!.Y&6_gr!0D9Do_)gP!pMqAT[YZ9PU9 -%G7W.eFB-g\f."-3L81-W#^*/nQ!(Z#Wi9F:\QnG<66YA7$!l]564mms&P4;U4-C)ZE7lL^m'^&Z/cW&%<&mRfmnSW\?+?\<"!:`@ -%Ve@jt"X4o?I2\J*m4nCFBq(f((X<\e+FcI\5Zb6qFM!o<#*?B3jCY3"+dp(biQ@$GFY@T&a93(@D/s*4[BeHJU**0Fdb><^1[WsF -%'m@VlUtKe[_t`DJs'o+.s2q;.4crTe-:KMD/OSpsPMAC8?4'+;jp#V5tJ($Pm5P_T"t -%d=asG0#ZMAo&Djai)?["[KjF5*q$TOrc1!;lbJ>ojOC#c;PM8K)nsO+HP4A272Le/5;9reDHiqYQEhel4aj([eQ\7,InZQgoM$s" -%cN(P0:#oPkj/.%;V8iuS4pD=RMsG?Ai5[,=>qd9F=M?B_2W)qY<#30_bE?P`b4>PKcpo<;O^8 -%;1t1EEg^`%a2+osQLGo`LjnGIOQF&HWOXH2Z,ANu4c5SoQEH=7N9S$&0=0I@E>(?9Md=@HU9SOp!\P#m0Mi%-\'Onu,$>KGVJ7F7 -%WT/ciF@Pj^c\_jT,&%qqLrc]l00SR#o6=&'3SJhSc2jtnT030hqp3uKR)NPdDj)_XJ4Iu2D3K?AKi-NhLVF*C#I8$6d^r,T;D?qG -%/1_Oe_qdsU1#lLKaCH.#\1VGs\&^_8@ISY`:3i:JTA;Z*;*EJWP/U8Hh>d)SN><3L#J&UE@IoDmhlsDf%Q?Z#EAt-ET1%3\SCb0lo3le;tu$>:c/o8&lAR` -%X/&@O%u7L)\Tr4o5R5h?PO+LPJXHO,QsHqd:h7`%/acd0e5C0:pm.FmXo/m@C-Ehr@>&+d$$[s*:El/Cr/T91.oWTn!t"";G,`3DbQF;.7G3I-SFAM0h-Z,gN$P6&V(]7S=hJHPT=&D!8F[RibTV)4m5[PFh\0G!m^U],0s;.fVnit%rS -%oKHe6nr(U%crWC0Wr#oYQ_$bp6JZI\fj+%("*pA(WCfG7Q>]'&Vq@F823TcTgSc8^V?g'GNaY'Y!TN]MB_40H\+u$C@c^K\MCcQ/22DkfJ*Mi^H6>c5WN8W>\*15#ls#(Y -%:l:0]/g-f8$3R'$AA[ -%k#?JK+Ya.M-H"q4!X8@]0uPc1i@cj\,5WQAF:nBR).UJ$NVG62Ui'EuJ&qVF,1>J3s.kRJ)krhNV<.fS5JTa8.=k90K1(8mEj)2O -%]d./[3e..*+\FYkU.nJh80PEE0OXL+PcSbTfTC0??p1CVC$^@oQ6Ks/_nY%PFS7L&A -%jPSp6i,(Zm(]TGoa`aD6Vl\sZG#fB*3iNG1@U(2-o_iPs`T&Vr/nn-);8]^;Q3,PcMA.1DLM[*L\%os^9=J$l!0;YDAp78"SdQmr -%)/=oA2m7C]Sg2.2L,EXh=IP9Uo4k.3*!04nUG-DL6L)am?krKY92ohZC5s^"!Z>H4,5]gd/[o2A@g,UWKLCE4Ijg'W?2uCbgP,W&g;OK^-VI'dmc`5OY:t_A9NegmU$[kCm6//VqUZu -%YTcf0MT7j"oH.!JZ[4G;_bi_EoHC4WZMSM;J5p9IdTM5*fXU%-=<7o37h)$&a2#+]'I!P`GG:suhlZUlro0er_m45spa&&H;<"c/'`,EQ"[qP%]=:bs]FQS2)E+-ZUX+(q=&MV$$&*.R9V+W:n> -%q,5S"!.A((N]^@P6DncOJ*GSS5fC&uFhqO"B!9ZU:#O9&(J?Qm)-'DePeGd^2^;W,uZ37K2ZncL:P22a-^bS -%OBgl!$M]OuD<^g=SQ21]U9O)q;.`J<]1&Q`?3[8?\Zg'&FAPY\<^J`K'i&)=&G" -%4WGiX?Z+\4]*MXPH;r[,CE<1%alXOrloJU`TJ0_A72)2iBF^]hY5&meP-]F2P@K;PYJ\YC:Q;?Db$*B[0TLD`Vgp(E7Lca\su -%mT;?Kn9q25N,uJ?^7H$D"=Gf;?t,P@3MkI#&0c^Mb>O05!&jbgDKJ%WcaX2+-A^Oc'PN_]6bJ1VO%-9>T%_X-pKa:IcqKM%5e@I9 -%Itih>5Wfmo$pPj*9f_W7PRJ?_^mU!dJWR]n91cuqpRA-/BKY:"p_]h2TEIBL,l)?g*ask6\[0.^1N+%H8aCs:Z"o!7$Mfgh'`M(h*JboP];cDbUF:4N`<7PJ0NMd!,Vlm!o0)MG*+Rf$E&?Ql -%M3P8c#sJQ!'=N7[?#*$)\cr1h[,8(5AV8&\q-DJr0!@"CJAh&E8q)UbN,d)Of[B!09UE#@;+Y1Qu!YC+R7+#_Z.'*?rC;^Qb!,dlK&, -%]Xktep^SL:_+3-^mI;up4%rSqRsGY99tp\+**I"1jn1EE7d12+_Gioq7B$g)MpO1N(8"$rCTn-gqBf7&`E5_;2'pteT!u?k.;Z,% -%5=D2-tdQmQ^< -%St@BBe\5hiMFhOpc_*&J>jQ%/T#H+.SQ.-S[rcSp96HZ&p72B(Eq_?J0#Gb;;ELSh&ncR4FR"M<]Wm8t*J#s.:sH3b)N;26#6eIt -%Do*f,Q.W-545]c\92?&js7S,+RRB8u\86(\qa6qli3Ma54*7]:a)0V_SW^$1nLgi`/N7WYW:5&@EVFp:aZ^t/==5a7i7p[9+&X#6 -%7E-n'><\9?f8=pE#pLo:$7'9MEpP-%`13,MMYPg>8IhqR2FaJl'>^@6(-\XSCk7'CpG,Zd'FD`X>m8GLTLdlBa0_'a_4HOI5/3.2 -%H9$8,KMn!9Q3jK\Ejk'"+a*&Y_k)_lZB7`r+%;s(i@S&6mUUS>Vi>:WnM=8B_9cQnA0$/kP"n!,d.Ts;oPlc!G;D@.jJ%qdc?FD: -%X%=Q?;_agd=N*qQG6\h=;>+3e.\`W99_DjBh/KHhA;sOr"iFa?D-/AiP1%csSMq3+UWGXJjPn)\Z&]TK$.,3_i]W3gV#g@@6OW[- -%s%pjnWE:2DJ!*BEKJeihAUpD#nF*J5Pm0W@jW:-``,dJ6iaD1<)XnRU3=)Zf]g1-Ki9iHi-aTi1IP%spBS]%6\Rg4mX::nsG*[7! -%07u9[A>plS=1]C>SB4M],WHsHnU?K+mZ'u'6@OKTNM3A%L7?t0ARKg4eqhdu-mE4BbAM/6s7ti]pG.Zs:g%/Fh^T'O'n$p*9BM5u -%r:p5]YUK-K_P$A-s -%1aA6P!in6B$=1"',4fHB9GU806J4sj$G))QT;W/3`)\KY056'H6>/9Ri]mf;s7q",f4j@>f*!+:F/'@/dj`/X-j!LeDYK^4Ku -%Zbn)tW&'pAg=e6kZ'njRUBm-SLo6"+a)/k<]H$Ze85I@T)"0/B&b.Zi<.'`h3/Sh8I^VID9J@m#dD\)bCZgaA1]JKN%9U[[8c+pa-HQA/K -%;;Q,20q?`(lnER#Pf"WjSg\5o.Y5?I#$?i%UFJ^\P+LrfAEDL'`)JtpI`gs2JoAh#<08@r[muS$kp\fE0Yu^/7&O3@Aq.2"([M$Y -%E=oXjXu;J"B''%ipMRU+,[#q:1g%<64X./;&OO>4P\2i -%R;L]*mBr0tR?E-=MLr/O>kQ1Q=L3'?+ioL;m$@ul(f:a',SlT>dQ9::+r&h#M+Jkfq%N^WISb(S]n:gi@"fnc:j7qs'3>)p,1j1A -%gA1TT'ch@)G+Pt\Hd9]LdeSm?L@nU1>Nmkjo'qNt#9<:aSbaqY#$?.%otU;P@\-[F6p:CKm!T+^(5A6Zg'enP*Ru97fTBE(\0arG -%M6$ht%]F?9*"ofM&Q-AR9q'^HY't2i<,71F-RKDk'MKP=n%1?tpS)F@'h@U1&M=J&*e8>LjGTV`aI^!6g6fJ^<&)J7=+H'eEuuPp -%E4CI+RoAuQ3VrqAXf`WAd.T'B`*bQch^8!2F&@P9'.pX?67p1m\fX*`NGBi*6."j]J^1j'/a-3^kKSmHAb*`N`K44^kFQ.>G^4J= -%QHRW=]8`)[BI&NAgbYT35XSClk,FEEUKdFPTZMssV:X/7L`HRT[=)'ukiU9&gXtLp9J%(:i&>Cc_gKXRolDC$j5PM6+%$9#jOs.X2QFp*gb\qFdo>I5i7Mca:.Q'a\B4QdMBAg=O>XKoY-(?4;,@Z92ri'n[jU9Z">1X5fF:=#mM4G#X&`h/2L^QTe[g(`[#F>,gLRX&=frR]j=-!_aJ;W -%*G]2e8I_/l1k/J"=B.1uQ.81R@Q?kR40FL[J0$lKeX>PY"(r/:maS[k0"jKG.rWMj)T;%^k;T(KDfTKHGi]rBB3=)%1]#?3sHjt/jFVnf>3Xi7W'U+W-_\%#2 -%n;`5R_)4[2+@re:CTI@W:,j[EeT8:O95=(UV)L;adu<8P\o./!qf!AY0S&i?`FR;C&j:@o+T9O8c'UF5aQ@5HWt@&KfG(9M@UjUK -%P:DGag5$LKQm^.T(L=e3I86F0U2;!HgETC[Q(SYBFXXNF9=qK69t0dO=P^M,,f="`Z"E$Y$JeG4+It)>\piqXHfu]5o9jM61;3UJ -%G`1^"%/rP1gYWU2K*7+E%d]V1=hKj"7h>-n6-jV*#I/e6*j)dHYD*WmOHs%64\)3n9hKn&THA%.YD]d.Rq$hIl -%m&sqX6KX5576@0I\3ZV`r?khGbr4-XORKa"'4rYeJm[Lm(j@N*/>%\6\U&A+D]T5%Eh9^FoorV/?g9525dO3$5QGF^POg@_e8FU[ -%4Sp`?c0iD-L0;ia=ef_f5>PYUm;ALnLq(<#i^E&*!IF!tHb>?bD8pn1AMLEOZT'/LaUj#&HI:Ls'hR.LLnc7Jul0YOc:)&LcKJ)lWTY$([Kj9A4N'WCm)M -%`gCaqf(]4Z3`EuIP2cD\ro&*VB>Gh]D4#,OSs=3GTf$4?c_5F&:\+QCZQ>#.F0Eo8NG?uE$`TY,.8P*jO?,I]`0,[]_"G1C`R0t* -%iUD3gmWFBLZE#.Rn7Z@O$_E=H@K;3\,Q$U(N^G64%irRKrK7P2-F4H?)d'6G82=b[9t8DTkm>*?d3lf.kZk@9'gnD\.3L#sZ0PWC -%fJ)B.&A-(#Icf[Wqi@GK,OdY17tXZ*==$#1VlH+UO)=FX)CT- -%Z1A,AbG&4neT`C5G9>/FPNsJg8;?J;/VdP#T[5,KO_gIXfU-XWrXo:mr?00dHr"7KRi4NQgR+uP#3)Su<9=%LU7`nA`,<@4=[[tV -%-n\=,D:TOm.3U_>/8NI4kF$7^ujoc'o;@`';&PL0;dUn,Q*juTkWgDX!(ehBWfh&8C1@raA>[nY305++@-^SJYgeD`.jS`3OiU[oC7KPVOPNq3F1-uokmX>ONTf^'TiYkVhuS5 -%O*H/2(`"*UW!@LNNu!M.RkRsJ7':)brAfJh9G)Mn.$F0)9S9_.EPpNC32tP\E%k8oM9%Z0W1G*sS/=CLhZ*K(G-g/>IKFjZ-]p7Xj_Y%!2`=^.V*NA#+a%pn*:?LG")T0N@p?iKuTs+-gAePH5$^\j_i -%s8K5$r]g?7J,I?:r0r32H[Yl8s5s@ZgV7sUs7#Ver7aI8h;A4n:\rCIktc\c6/Hs)MiTsuPP.TI1&_%%rsq?nlc26iY=IW&rOMn) -%Dh%cDraYg#5I(0js#pCGfXEAJnHn\-83pZlF#ng:6Lj+ai"bcVc2(8`$fl(@M*EAD.jFn$? -%iR'G;i6STVAkZ(d#&4eR5#EQ:3>L*Mq6@,3kR-DP<'H`e3B>8_Ml&CO)@45m`CPfs_)rqrHg9u]d?k3U8Jij=cPRf%KNg*-h@cFe-45W^sp6+ -%jSlRJOT98Q<,='6NlU11IY4i7Z5.Z3/e]Gl5T2N1mVP3#,7:ahun[OuYH`X8/6'jG-euZ3g!S$,U`hH$Kri_&K,@Zh[Y#E0 -%'Q2VFV%%ZMXG5ST:#BAu/Z&MW^*!GL`^MjO3:p+!D[c1VWpH^Q]s*uqacs$TTFoA%3Ptn"%ftf,p?pmbNX:mFq2T,F#GE5)gCA3T -%0MM'6rm" -%5Ybt'@35JDK)'YLkT^Jj5d1g[5M][LjuqoXlj!O-1P$+efCt>Tnb/!b#+Xg7\c)ru/Bn/[.llp^9'q`c-H4QCi1_V^XL#m/ReWdjTN%JoqBNktut;&mp47E"`\m@t^ejBP*&7P';IRbl`&QYu_o`+NaF!F]Hhik_j7AXC=ee*6j0ZDtq014VBQ -%R`dledQX27n#,c%T:R+kEgeJND=ElMqSuPPJ't!r<6ZJi%/:MMnTr8.kRRK&EH>NA,2FJnmT2!\S0(<[`^je4UojJB?la@_bk'?*iKk/M*Q!(Yj!ns-6]b4Ieh@EN6Q%q4 -%k[ZXDeJH!F#YNS6UlfCOV;R*h'16.D4XcRSfYfQ[Ea3.JO`+>u/%GD',]>lgX^W!bd+Qame7r7]=U2REpdKq^k]<$<1K\)tCJ"s0 -%cr]EtXZF0o/0pk[4m4H[Ae#h!>OboFdkRE6,g-W4m\0( -%+/-_+BTg-ee:[b4CBXT1G)8OR![,8o`#j`^G9?fpA`3-d^]'`NH4C-:g4LD&838@&$Agk7@n -%+]TWq,@FS`E6h=.4^6@^]uk[XQ[S&oo'*7M5fmC#J=J5=+OTIC0m_Cr@HB0gNV%]lS760"=ssdW'D@<8oc=dR(nbN=9VF.leT2`p -%,WL[#jK_X?7HH#.B43Vc^P/MJ9lM=R(j*A^`"^f*_+gVII_03\Vs/MMYcK6BTnHC7oCjL177\#:43?fHu$pF63H -%K/?sj2V=LeqpER'-=[d].q6sA(&e(\b7dmH%DKO&'ore]>UMOV$D@u -%Fch=F\(AF4c(OEGd?\7`m@ne?r+7duRmOp\rpaP=.4gRa(NhNtm*DjR0oi8I24Jon/D!nk%HkIO6gF0([##0\8I_W%EV0TF05\^8 -%pt99ai3]!OYg5KIOSM1h_In/m'[d]S"C#+cQ\>QTdh6Ps?-6_7)k4>?UpjqeW:nCZuRRaWkAA4Ye4[DZi\$EX0*Z+p*UA)N+t)uT%3lJ(@92^$B,N6)5j#I^.`dZi&^I,s\5Eb.XubGeEH.N^YQW,O]F,drehK0k/O/Z*(s*@c<0?2qh_P -%^43"([6K/PXmq)2H%'uc\3E:G(JgBC>C!g*S'Sd'@ZPiH:-0=M'>Jo/ImI19\IOV-pH9RNC?UU/LJ#nt5JC"sk,YHca"!B7amX%\jmi:@s2Oi.$CLq\?bNnKq4_Cb?ncHkP<*5%p,fs^&;kHcB8 -%BS1:mhuJfo,V*7"\AYX46d.4cN83>q7OMZkH?VfiYBi+RpJsq]K""dk.<[3G<19Z)?C,(JN?X+6f -%_77Oho#;M(%!0)Z3p@qrK!$>U5o^+9qi3?:BcZ?^02',514)e95Ne<:#5eiS^@T\Ndn`2eK#ZM#L^X-(CU'\/I9>WY!DDM]f25;+ -%c2!&,SDWGVRU`a<"@u0n,:`1Q%C@]*XZR#!m7r-\[>, -%$OtK,A9`ou8+![@UJ[(Hg"aV-IaqKCZ?kRTOsJ"GRm(BU>d9hdnAD-PJR>h0W.R=X-*s[IA6T:q)\=a^s@:`$`pmb -%.mEq^&"5N-BERQ3MS5dZ!TZt7BT5C$O(+TlimF>L+c*E:%4J8h+3P0engq]">S8gLM'QR9EPc,VG(P)LJh#OsR3.Qd7g?gqK42]U -%R&obU*8kF+-pi(ZQL4W[&q3^h_c;8JA&s0%(o"FR'VC!Uu'"VV!HhIW(t.]C.tCFM]%Ob -%FnQqZ3HpHt^3"?(fFjYZ.(W@YX!+-9SHm*XFCAmi<(7T)"*P0maX`?a>BE-s8]FdZGYehNXu]!;QQh>3*\:OjIL_2[bFd:GQC&;R -%W$99-H..:t!V6esGB!gL$OWQ8%"LHPI1DUc3jIr\RgDb\3Lcrk,Ph]@7_^lIHC]uFlOdm7=J[g0&Lm^+5 -%;sFA,Fr0g+ef`0dXA+rD:0d&i`*,EiX7W&:T[Ia]9r\Tf@aT<;61[`\H'8DK)MEroa4B7KKkn63SYYu>XW46`Afe#>.cuJc*q%Gj^e.+biG)EcGC8_AB60a7T6J81Z6ie`5 -%cu$>S/.ira(aSe^$TGkJk]kMdAC_&ZbknD^S4U*G3ksZ&OD<\uLjQp]5_]?AK;EpLl0Z"[Eki3pF[=Fs?^WBfVta@OiQ(9-L/%T( -%^Nt#iIrm.L\3X&EmEHBj-5?-0="oAF_U(Ou-/il0j,KI"g/-RC4S&Q8TksRAK+b\Cg8Icq,"6LB2 -%nkY&Q,jLE:q'.03Jse%VgJiT0eV]!W`=!d5Nu6Y3@aIPrW:!b'`aQ\@EJ6S!FWUcQrNm$:_6/H6('N')n%`+_e-(]SUf.Yj_T%>E -%U)=n,ODRTX/QIB(3$#cVnq=!5o#bgPK\'$:M*p'bb6U?2a_We`-U%uqhfKbT+1M"s5Hk?[&"&$]KDcI3G%7+e;sfV'f%ZLrZY -%Q+0JUpiM'/cUMQMlWI]uLfMA@&:$I$AI5UgC0OU.JmLmO.CqD_#qtJNUbR^%cF6l":b^?FaD)@!(*>:.P87\l@iC;jQ"u#[/?1t9 -%jK,CM!;VbJ"hG$JAeE(Vi2TT]KfT:n."VEknl"XaZ'6meFafE@+lH8n1h8s>F?&UN=>HJWJ^@E.23*8Cg&eYkKJRVT,p]^^B\Pt. -%38o*L/_JVf"lu)pU#W]7V)r5>2,:mbNYFgWp]Nj<;-nPkHKO;W$.0*WF1Ps,K3k9S1o\Xt -%2g$/XHj[lg*n#YM^oe3O6q@C`^AX8@[pG@HMe@`W;@d7]5RD7"dFW<$82EXu"G%3:Uci=i":OFRm#0X&CD%hS>Br%><,V+RU-sK[ -%cZA/N,&%8VZFLGdD+1+*iiNe]Se`p9.;kX/ZH5.WeJUgF"h7H)Z$hMDQjjKNr@E'(b"iSP,0nYOf-V*2CtTI5D^3Fs'Y(2%6+>EV -%r$96u5s0sYQkrf1Cu&::=>5S_81dDoM2;&Vlp`$lP&$`V4$]snCk -%b-GGWJHaOGZ!.8M1Uj__`l$gKC1I.PY`'8Ao%>'p1PIWQRJ!YQa2A;`g>Q^Z2F@KoXcm6MPFBus0,*@RiG1F1Uf"L:0A(m?cnuB\ -%J^^+b8$83R:#2I:/?(]rK*JE$2Q$V7guRZMb>.'`".$$*JaY-Xpm.,'oJT9N/g[^KaGmMPo`BRd"<=jVj7.pfhJU<=N>F2=SV$a/ -%3&o7[f@PE@U-Dfkp$_nO5Q:&RJ,HpNs6tOm.Thi"9&/n5eFq]ZWF*$ciadRh]G+'*>NX%@5tn4$NA9TDtrs)C`*OiR#?qg*#Dh#rYK,^#!O^Dgm/uDJ8o#HlA4rA)i\6WueD6BqS$C3q!GqU*^q& -%Hl$`8_MrrH/\_)WmG2Xj0_Ck$#g)'hll-HhVn00l6LW[2M)=Pc^af\)Gd#A!rVZA,f)m;@S]<^oL@*l3U/1POL_H=HZeMA'Q3Mnf -%[k5>kq47E=*e8Qu8Ni^O8K%XQBDMsl+DkC+LU@>`_Q4*dS8XG\tJo#856S;3gDn$L&X5JM9SlPY/Uk.:Hs*^c=SBcB"C9,cf6gWF(JYP3rf -%-ou_.O8jC2KG[$X1?s#=C\'JL^U_rdHFiD`?+9cU[FB?T"BGs'`-ZA"HD'GJIDj^pK7G@9C&W$P$\B<7YV9O,DnXW^Dgm.VYMYma -%e>4MDk[R_HLYH[IHT/A7k52j#q!RIp6XbPf^Y -%hF+27ZMkV#1h,'cGc[8+5nr7H(4Y`CgH0hZA)V(Y0$(fkVqk24FV?_U$qn@af&M%Ime"+\"n*Z,`1?%VB+Re&^lEP"%cf%qC\(Ul -%^V/Al-5?@cP.H;-1S&n/gAktn;;P0bh\P,Jr6G7)[%qNO$0bPZ/'r-E?LIs!"0_H*>C?2:488Wni_A:QbZNgY^M'AHj7,H,"obAF -%^A%GoHc>H'oW[qBs89A+nAi:jS8nH;k!6sbd:Fu.fcAR05klQ'o+!gbGPu]#M]6GsGl>29f(f7-GOB_sLjZT+`MXk2B0ZF^T:"tk -%m.V,8RDI-*\nIHur"dGQT\#U]_j3XEmSiCeg[Un#r'\3=9LSX,6!TpOR*m$g?Y4b&+a.FJGlceO8CJ(`eEA;CP]D[/&H3HmfsSK3PFeTr\XiBmK3"D&2JFL>[aY&^KM`3*P2spZ -%EG`RR/gQ#E<\8/G5+O(q+UC[t_MlUYcK$_oM\Hk3%/$gb9\UZ%SJGehq*"S%KSAo%N"^irYU(JeU^fU_\NJeL6q2;AtrJ"mdr)g7\B5Upgt96*0h@17-fJM%!I60eGlC76l#%-U.sB(^tJ5o,qpN/2%/9F8>?KF8W*Jqs\/*_;`h -%D]Y]7\3&aY9/ibXD^).\J?Q!f]UER"FCPp?*7^d,$,OSdK_n8gPhM,";LlJk0uH#A\If6]9ak1KFfm0\MKC_S'>^?=E)5_Jnj(-G3/i"]"ZY6)0:dB4D -%`,46_JSAWiEQ3)PnB.oB`Gs$>ph[JRIA%"R#$R4#EjmU'lnMXGBngdZu'XJm/:45aL:0Q`\Q= -%1@_]LH:ch%C>#a9?_3+8,bp*9r"A:#?4<$NI -%>qGk-RF7\gXSZ*;$>*A@r#(jQ]^JLCgl<\(pN8T^]3=J_7o[=gD6Dr_hjD_?H1q/qV49$[><+mMjdFUbbYs2]t;;r=):HoKAIZKq'WViX[9G/0FX< -%Y!X>g"6-D]7Lq9b=`Q4T<(Y1qcKQjLd)QVTUs3+8RDQA5GHF,%]P%q!i-NO1Q=Yb#\mHUSiR-Ld[@aOJHa@\qYPSd>VTf7Z(uBT[Sl%52njEIr0gV^D\e"k7^A'-A[Vr -%%TURS,gK>N*)B9E!?trJC2t17-G6u[Cclq'kpe"FEAZ[7])7R^au.:s\)q-J/;?Q;!km@(*Y%Q!OdH.rVuTf!F?pHXfpDR;hH'cW -%/V"M(.g`CEgBYT!/pYo`%3AJI`ePW*SsnX]3Pu0BlL,G:Ap*.3fME45or02t3PGS@FgDD4!q -%ZiubPCi(IR(-PQbK,i7rmeaf4gRfgMFf:9dX-%`.$NCV:K7b! -%I2_tc'R$e'mS4NJa%@Y_883'bKu2?3eabPT7/r6Q;FPPZbhHX]JO'dMkYON>pO)?cI18pC$NCYQRM^t+npLP?-L_<)a^>3>[_.uL -%Rr6Z[[IMJ")%W,+/m9r40RNnodj.r/F5lhkK,j4r'nJGX.$@fIS&o/YnEG]tK)/WO=(*=);L(#/BZ&mp -%O+#BMhto0i-$IBXlfc3@LN+HSJl?13#-p@ooEi\ha!7BcPbqh_Qj$=*H/'/m=?BB6QpSL4=S'_5YT=>M)kPVq;oV@#1m+*AV!$PE -%TeLWL?qm?a@Zg#A;FZW]TSeH9P[-Vm@6l5uoop6:88.-lrF2CTN8L+jlQF#'rp/Q@:3omQEniY6s(k.;Ko.EE2:lSu;A@E+:k\O8Y$% -%+hu_W@mjdmJs,O,a"+-'R@rXdc`q7EGSPGT,ujok]:s^#9J0$8P75E%$I:i^P1L@<$8;i -%Ml[P-iYac\&+9V8!d=9X$O%Yn3NOTG)aIXJ=TrqdZ+fh[]?$-/p>!2QbOauQ+h0j\/N2@Pl;Q"1+H+<9oIR:Y,S!!YCM`-3^S\&% -%;=Zp6l-QHZot"'+ZTDrgiBtRm -%d_t7_oO5VeAc@X:W<_B!KY6i^9JnklRb2#cBSqd7T,T.dm._R`.a;iRjec"98[Qe)5*=E,nZ`4K9rNqPb-Y[E;DUIB82SHEA9V`:,$L&F,cBrKtS2=:oY-Qe)sFh+;Pu&t+`K-o;GP=aQTTJl"Q.fR.QSA\IhYh)UoVF5GH::0E.U-ErbO1C$/&'+@ndBEK,d(G -%rYs18*R&X"LBAiJVTpcIf>"kY'nMa.d[FPi(<[6R?=%j]!\-VuMsGh:I$Mc:N7ef"2!*YXmfWZ\+ikPfB@s?uesrVA^G^bHiF?G5 -%%0\>]`YL'c-&]^KmBWf@e#lZfE?F#&>6/4V^6J#qK4LiN-VG=5_\_NFJL>7^86FqTI%P8$IZ0Ll1If -%r@6*$_K&S4Nne):g"_RP"MANKKdqrnZKoEaa#XRfVnh3M=gb-2C2h9V7CF((4M%gk>;9c?d`Ic'UpgDZVNA6P$ilX_o,4L1/h`!e -%B#J -%a7MR7!U.3J!HE'C"LXZ=>HQ`M7iX.gO5Y!RG3"pD47\ab(8S-k6';k2Io+G?sp1FuCVe1OiE@r1t6Gr<:*jC6i$ih2Ge#611Q$bd#.Z6LJ8bsPIqRr%&QHkN_Je&%6?&bX$-SNki7h1?j:.WG@8+7H>@ftM -%8N3/2:\K`m2A^XT?$X$6?8CjEE]O")%Zq1K^2>Ve:(g`Pm0Z`)*+r>\3$$1OC^Yc$'Ll>7p'$0mL-3`;f/QPrR1:j>/3mcC_QgJq -%KNo/u%VB1bD-Ag?UOKeL`3JlU6U6]OX?/A:?:J(9n&LepC/X^e('!jpI97[&K+odeOi\3/O$&U-Iainqkl>;BPqIbf3f\Hk -%QB42$%!G#i_&ZC-i%hVL!@]6]B.1#:&Qp/D9pQKd1>69(^I21,L0ogg\8c(6FbZ%G5S7:V+/@n@^rmQc9bL:*Th%_Tq"3#=0Ok*1 -%9D_D<,C&k&.b?XmSm4=+bnr75dd&q:1FCOO4XdY74F5r0(g8@T,8+\0?cV+hOCl!UH/D@%)et+LH>Wc:1Y+*u6`oICc*Aa#gOYh_ -%em;2g$Sk3"rnu%gZS+<=B29EB5b-4O<^2BroHlj0!BJV2hRrS=V,S,aSnA`K8jF&\#mEt6J&cqghFZG_Gree+C\DO%!Rid6AHehJ -%2UIeYeB]7O*_i1Uc8:sKf7(d[n -%8,,ih('4Y@8dj$MP%2^?X;1hjd]ZJ!i#qi-F9hNKoj=K;M>@M82/CWZ2u9&4R<+U$B"Bg;dc2mdiPTO60b_)$2kr%Or+_<<*3=sQ`rb`@ucj!fASl#r,S+R;]5S-YGq=!aDN -%$"aT/T@[Jm7j7'qlTb?c5Q9Krr8g`E&$Sf&iT"qO`PDOZ.A5biFoV*[WiLQZUMD!SNcW:S?[g(4(B!/R9t)e4X);'J5tqfek5OWF -%oABO3U-IT6JYAi2rdtenjDuD%rKAdqqZsUSqdJ"npU6(k2E+&u*^>8YI:XN?`f`%bI)-5G-1qsb\cN%5jQGep$:FKpN:p#*6S&h:&"[^ -%.3?fT4`;H3j/#j7_h9R3Upb;"rTsE`S*@ulGTDTMB>(139g>5Ege>JrR1@-deQ\N0/'n:R9V:?k -%Iu``:Y^bG%5J*!FA,F7sq`HcU9q-RNXPQW89XESLHG;3+qeMDTt -%k&@_NRn/"nZu'loGAaiL>\uc6IlFptlgBCjr6487_V*7?DpKEl]5GsC:>>_1[LM6q*nB(qh9YOEm_A)V,(t(8NTFT]:HNTj5*%lf -%G+P0a,^ZLUZcTlUFJl>2N9i9TRpIuQHO0WO$(26+Y@c8h`Y-dQXDZ]i6p3l-FqJ\4p3^nYqWr;NP`t\19L<`0$62AV5EToBKH<.] -%_2&:UA`NBc>5B`dn=gAgL7l7qk)fPA/X$l=^$5pA]0dM$7qkX55`c'EXD!aVs&ZuF8>[P-+;N9:]@ou"32@Djp[Wmh/b[`XMg*\O/LaBoT6'r+d"[Mpg?1TjKlV#tp -%We^D@a&\9WF.)A>`4AbSbM;6Q1r3G>eFGE9W[LF[D/G*qZ<;Po@tK&9*+7-cZt7kGGV-JjH;P[a]R:R9=q7NiVZ2j(Dhe:mW]f)L -%7i2^h]BNtr6iSTiIV@r-'LZgW8k8pkPN2UQ#d9qO=>]`t@7ARD['u&OJ_6f<9Q*:*Mq^d%SlMYHk5ed'cHBTTA(nF^Dj,F)9almf -%YQLgdJu%YA9Hdt%:nM8(A68*oE!?prf8XhK>sfa62FUG&:;Z4Vr#F`3FI4VG9hat&YT$[(#Z2E3A-`*M4)"UgZQ8PJMVeH%'0lT1 -%WO8iQ6QhYa+o"5rG'putAVM=[[H*?p:iQpgBda4X3WpXHKh`W))0;boW(E@,li<_[3)d%H6q8DG"1*NP_;9P?+4ADmq+82Xi7:>t*uR%adq!i.>[;[3^ap!pkgF*g)U<-^],^(L-r`:@'m))/9C`q;dN$QEP0rs:pAj^`-;ca_PB"@fOs4hC7d"eR3L`TqH^q[i"0--KosbIKUhAIJnA:+:CJsjT;%khY3l%@O\hd%)%SZi7__1"A -%,t[]Ver##.">isu!UmiN>uUtAh1cGDk?3kfT#`h.WQk0pK?I_U,bsG%>Mm7TYlR(8ZuMc_l:$gE66(o+kdq!r5M:D\N8#=)=u@AK(u;iJR(]hW5>M!G5o -%,nN-Xbe0iK/&4='.6goDEj3N0oK]5H9i(:n#%1XS-s!\Mt@h>g6Xd[TWpL0"6D+g^:"&$ -%-@pb;@/"hFP=Q^YK]9Kd(^qLYE;HN!lRi;$GK^DQGT'#\L)@nW,q'JdJH?TNV$Z`bLCHlL_CcBN!(<^k%TRa9GT+kgmLV`=f%6+D -%8D86o_:&IT!hakq*\pW]aR(2HEXl5cb?#WIlT>%B.`6r\EuG"LaE"$qsL7;*ic#J3k^[W -%JMeLf]ZC"eQg\�GiX=aB#RMdi5,Fc:S9["(s$_]j+XaL!:E8=n.Ni]I'tc6,!"@*MUuQ< -%$3Ukk(e!f;@gibcF&101OC_t98FD;nB2s;q#PPXda5-2X!gBM]I.M6ANC>iT!+<].%./kr@]"K0g5B%=S -%W^5mSV4o?+5p`AYdr=/eNuuC-YuRG5&GX(fAlL&gMp_6$Ha/5(DJ]MAke!s'0mB'2,1Q93%ZdGMQRf;^hlmT("@]ErQpQ';EQIY+M^buD7i19YDEC-Fcn>iVpDfDoh%d4Si?Ue*PflJ*?'iiZkBDb0e90A]pr)dRk!"%dNHO+<*q\%\f'>JVq]7,pdoP;N\=)`/A%$T&]Zdh!A%)8og"u)\,KoIr]iDaklbM6hBb-gj"!,]g%/ofG=CCW(Z6RA3l!/G?ASlPVAf#G- -%_@:M"Ba5!fL2e5%,[/,pj*.E\"j!U3[c[&8C_XDb?[(k2qjHp1m1JZt/`.QrQ8DT.i;<34B:d^1MB!1WGMfQES>PE&FkM1h>F)ON -%Z`hg-cf]cKG+J4f3,[U,i]U%D+alT(oCgW"ADH>P!c#>3ccP-#HKr9/e(ai@37j^FA'O:3T)tGKrk!!FabR5G[H4DG^Cs_(7a3]kZEYSo!tbni^_GN<8VD+t$+*)p4^<92?:'1*V?>*_B3K`+C8KX!6hf9f#/>O-kEXo>kkE9=gLCi\o$< -%NtYB!2,pdb@,5,M"N;fo[g3d^3nL(nQ*_PD-IBEDJjU2UQ;c?KX,G"a8%])^""J)C&.qT)86[8d$*9f]OR?EIiIpk<)-A](c8TUU -%Hm4Hff2M.\@h$Qk6t6DFWZ4G0cnifgStr0\235ZuW0f;[)u*YX"/QC)<(8;9.ob -%r6WuJ9U'Cn59h(:Y%Z",igM;F"_IgT(r2Y#&HmE-W94]'Eckmu!@V&49tDb8JYRX8']SAd;5a+.Ks?mNV`nt&O;76k#]5bho*fqh -%gjL?0aFI5qb)RtB\AN*'C`WD-`k5DRR-@uopZo.>MHIUA8P;pi$7XLK8n\Fp(i8IMZac(Q%qCPkML9NSDBhk.\tV#Q*":1;;mjuL -%"(b`XrQE&r[O#Bb(eqnL`mQ,Gr!MJ7JPomH3T`ELUd/ZkeZE#.3,s8-CX:nZ9m"umV/D7Ke8(0iR"D.A/q@LF7D=f>=JNDoAVG5& -%>7YOPbti$ZWAJ8HF.2Fk1&Ld,;]NMra%2(b"\2JE%B>#9-t2Z/T((Qek?^tZ70T&G'#+JUU@C&'+':ji)D4Zh@6n(;8h,'$0R?s0 -%k\2k:*R$3t6-BiM[N'e^p -%,K5HeJ7l;gi(H\.YqQbieN?1=3%,:VQW2Fqco=G#n=FVj>WafE#q.PfSumt\H"eU#pAsbO!%YS><&L*MnR\6dj<8slZ5LS+\hG3JF>I\T"D&_V,\@]Y(8.t1Zn.Q"+9jU)?9BunX+kC5I#+e8F'LV>DjiHi`ok+ -%9P&rq`8fa[6fSfr)7IU6Wp?+IL/:=LcfD)^PbQOmH:LkMX(7ET86!c?hpC#HGG9g;%i^?"D^G+eqeE*W)U#HFg`>`mA:@Es`8f*O -%p_G$.U6K`,e1/$?&TNsNU]U[li*3Qsa.UYlT^Y11qa<-np5"`FPV+oMFdo -%H.3K_)"7g"\F%B48_/2@Tu`,@)r*(Zr+O!K,2#L7,oaiXPkDg'T/<3d1AQ8gbBq\^dgSs8gcSJlZ%oQF+0Np$BItR7>_?JTKRF3# -%GmI392[t+%24k7?:NbgKG^^XCPk@E@Ad->qD#&1ocp2dj&!o0$AhV$cQC.96gVe]GXEC4/<0loChB5"7l6b;BWeI'q2QQp]0.9>q -%[p1R>r5I,Ecj)6+l45,XVJ9]NN"\X2g"tJ4T)%J!r&W":+#1G&eaer2Z:##05!i&g9'>[QnN^1mJs.'"fqr+*W;UOeDK=@W1-WA_ -%OK1;UM]k>O!fEK.8qIs=ShpXW0D&EAW<&'sY2@BP,N1b]6VOuQAMAVS)9eI`eMV>$n2u_KYom*mn8#rFO?8AhF&RFlX`Urc?8Gf[ -%FVJRDTQGG%.4%$]JR/^H'mC3A-TnFrlk6.o_,'*(f:O;NR27bYYS'jjb).;XZh]"$0"N' -%"(N2b%b-$,&Bq5749N'ob&]<)[%E%f!;>J;.NY0J"ObeLWU.1**(To4<>fn*L57u8]$Sk3-;kYlD$`Rtmg#pk/r""+^/km_3@f&VNi3Yl$uffPUrR,=7@-.6?Y+Nj#hb2nX:(a7<*_0Y#L*La%&4"*hoNfgt[QAEE^"sjONEXoY+F"XC!UI&D`=X'qT+n5B[QZ/\"m;rBo+S"?uD:d)X2%\G)D)D(^u=Dppe? -%MGg-IT52ui5h!WW#W#l;%N4l@;sZ*>^&R?-pPGsQ=Zt*3#l>&`."p7eG$h!8F]Ra]a%s\"@;_HWhs#ObOm%0(b+KL`.qtd4!246' -%DL?YjS79A]88t0'-KQU?VPppJ*G&e`diY:AS0G%]fr)VC/7PQ0ep#=,e9*suB%IdXTO&?,72::]pTsSt:2iY>X4N"ZmJJSjN/+kC -%oIF%rOT,Ig(h_8FlbRW&H+L8Mib&6O@d3Vs%#.?A@9D363KS?o"BrGc3113o+7$1=Q:Z$%blk[3]#n.Dt3 -%6mO?(`l0^-E4WeT)+WSOhDnk12QYAdrm0uUO,VK*HB+p6,cmI"rjY4'eB(2hrpYBm4W\*oAY%dKt`RoMrCN;.CPn7i\_UBbpfq!cm?;+o1U(!XDPHmIK)%q.QFa0UJ"@*n-BL/VV -%ccA@qa#ifORBd`m,K)A<[mM$,GFFn)F10CEXS3K]/!Jc%?5#ZgTo;m*F0Rfh!7gs.[:!'fkQFM)]d%sFS$D3"Y -%@b=j30@]R&Il?DYtYNa;H%mH -%kI)qaPfRa__3%uQ3!G[hJQ`SE`HI+#PpC@ZmS$\:jPKN*da6`H:gjgOU4qqN8Q$OH&Sl_=)$A!HD]AY&As#1+/(UYrgU8nK_Su!` -%%LiYX,l("o'&ehFdMA/l%"esT8EmC\2+oM4;L;%K_0Tr['G!QUYDP=,Bn3A&r1UV"ST0X6&edIm9F/BgP1Xr:X7jZ:'-U1i=:%fE -%JIlQ]8T8hrLLjE?>LN)`=M#(Igt,-]ek*WZ9!YNTA9Vi(SV_pj=EanJW!K,-1Aq?'`]ZH:=C$iK<%*74E=/=Dr;D3Gh1[j.06+#[M==BrI8 -%!4Xm5o\'!)r](T-,i[6;Z\m!;gssuZrM']56NP'l5Socka!5lW+..%u5uS??npmB,_0H[r9p&a]k.,euVoD=2+d@SV7\n\C$n)=P -%J=*-33U)nm.1WgVT1kV@8HY#;/!aU1aCrCU>?Z#cl@KOt:;@>435S?o5%(?]7jc7-MpE(/$^7jTp%U#S+>(ki9O\5A;)XAo>`c:J -%/Ns"=_.U<@0>eX%5KkR:I)E0H4DX8g(fS&(X/=?8fNC>Jg3/Zn>Bm*o[`_[iUT8ftq)sZSF!3nngKk:F[S>*_/.Tb'(Y/H@L58"S -%@GD,"7iOX%SVk`JN3Mf7cQoAhN6`P7Ana"rfH*NHMe@tCcoa+f1=eJW&u(W -%5?#O*!^#LZ@Z\/CDHYO%UVNF)6^G=.E!X-fAThSA..&=(AXnr5B:["%KO>0q=L^fH`aXLR1KfTm]5a9DZ;^%a%22L\.n;`Ba!,9^L7O* -%!Bc*mSRDdSK0dDZe$PpY_T37%Am:0*e>?JMTt6L^`^chMEEkgYT\/pn!T`%CcS/&VJjD"m:d6^eaZ_m37lVT6T)l54`.f.;aqX90 -%'<<&'UGG*O'ug)"*^[jR9"iG`eo%1SK)#A8-q$ -%oscAI\[B:qGSg`m-r*9A`j!s=-q$),$@dtN4>tN[ -%ficS*Y75Y(90ZY`=Dg"pUNsa_@Np7AO8#M\*J`G:j:MEe_$CR8I3CG48;P@.an/%=8S>\j!?(j4GZSKN.r&VWWcs`^K5lNc[bPIQk*'.;XgDOL?#+RpE, -%i`#*t>"It62Pt:7gc-%#-(\Z=?qY`r@4S/M5q6G:Z&bRMRC3"p^5,b8]jiBP[-)mPE$eEA,rR2!aEXB7+s)Wj>8[Z\3LlfKdMW%u -%GTCThYHR\qV5.5D']C!!``t;pnrVi.*\-9mOh"_=1$%/NFkr\#e'.#,=n#PRd3R_1XW0?[U%f^NI-eS/8:u[ZW^pM%=5HnF$6oma -%9-a[=#dXgXR"ZkrE-VXFEEhW7s7g:bh!8tT_#AhloVMMV9M/6N>7i,`FFLNe`jW(Y!dHe;"4>['nn4$f.1%Brom$iOk^F2J^g'rk[@eU= -%?k0C@\7uQ^T&jSJ?%m^jV4o4W$X@(g;j2jA3VU85P.eI"2-q1\rTU=*6LT!ELoD/GS&@-PVer'Al7'/LJct7;c:-[NHTus9)dAl_ -%*JT7Qd0,OW5d^oIW>tmQD'Z`#TXXfe0q"*[$D^RdBZOc*co(DQ"4o<^>UYhh.#N)Y+G5Ll^fhAO9K/b.FH?!0fkJ"JKb8f -%HhS>Q2"'1ljWDbl*GRq.$bMl>4"N0or0[V-pYuh#hH*[7S2S8aUp'alY,T0TL.(,'cdYnCVO16MWu5bLF?YV>,$KM%JfPl"fGf)= -%eO?/kp#lo^B]f/X1.Rsd\r)+`mMpg+bu>B@Ye$'"WSVq/Q"T2MZG8B2CmetA?CBl?:(!5as/\(7!pm*r&Gm@<>9t_E0;_\Q`SQ"t -%Ad(D#`(e(L%YI/m1JhA70JZeh$Qk!UF3N)bn>:(Pa>Le'cCG8mn(!lt2#1FQTSUl/I6p+Nk'VfIo3t2li":XT7Vs99s$`MgdPf#V[+=l]R -%P@V\.?Kj(0[h4-5*Gq)p'mNK^oN\$.pVU>+EceuZQ!SK@i_aSIMT3r]j"QM]l4hkNEZ?f?.!T-A0O8*=fL<7N@&$`OFp][d)'PLn -%Q,=;nNa,=?n2u60V>sG43BKD@kE["\JIn9i"L0.=1o]I^3<$OU!mS9FV,1>l2'?86%'inl-[DrKW_O%4X..mqQ1ad@+2oj-Y.M=#_^>ON;"9-3Eo5Z[m4Y7QZf6.bg -%ZEt67Pj/m)""kJ:mAE!7"_gEY3Ng>I;na"\TtL`r1/I_BoFXfd_`I3S;rF*\o-!f]2h;LQo94eh_lkR_F&l+Q#-M'?Ie9!Bb3tYr=3Uo,(2T9a8WGe39 -%c4HpbU:n`>7Q+6J$Fm?iEto8K%@+%j(a"V2D`Ci-\[AqZk7&j\6H<.'7N#/BA1:bSU -%ikW!5Mlmjt&Rg)]EF)p3K]X\c%@T*'OH$mk$nb4@?pM]IG(>i2jtl9rBh7oM:'Xb/bH\hqQ0`#b(!$Z-o;4QdnV&ljgI -%m$M5DWQZJ9@HS<+B=JO?U.%M@1?@\=[\X;I>IAV#kd(A)#ip$%Z\_+&>0fTA<.6^TX;"b8^s`E\!F-,p`p\P-N8rRl(Vaj515&C8 -%NN0r^C0Zl7*%H>K1`e''1!`]j;A;]F(I:7rLT.kJ)E%:DKg77,UR8.-4Kf-`kX;])4$T2A^>/5nib$u_%\'@`bg%B`hc%gRoi8f1%n@7_kL[93b?)SC3lqE#s^P9"foJQ5BuI9=W217d&dYVj=Hfog`Z-qNs/[no"`?SOQ$_)6q,"A.d]S$NV!AUo9VRDb7+E`"_!HF-u"8L]dOs4/E8MVPnP?^Zk?7!E4Yjdo.`PskE(<@Yk:nlrTmO(2.b=#tIBf(3*FFNY\cn1.<@FH@H5Z%q9)mj4( -%fTLl1+oG6h"9WjQLoU5$]ol+&3r*'+I.VHsRL\3NZ%_]\L4&M>F;hhTi:6D&4$-r,\I3)%E%n-EVd]'eAoX;FViF_,ernfKK:MFU -%]k&sDVfb"ljG)>OTiB:C7?Yapmt(0(Fc?>?#GMS#Eud*7_kL9]2_(%+U@2%pRrrDao;4C>MCJKD[/:Y"C[;a8F#!HJ8OrNK.8uB'Ku7h/Qj5/iZ`EZ3')Ft`QId:/c[?)1_0k:+`bkuiDSc\ijX)0#9t=so -%Br]0@B%KP#j9/n2`Jc,i[$/[Q0)#hM%K,u1]h3f?j.VNJV][eW`\=ffR-KbjMtt@qrVA,gXdic6#TSVnpsD%XMpp9+1jXZ_Y?-KN -%b0W6T#J=u[4Y4.+7RWBL1$Ni);TBn&?M,n;H.k*A5I^.V=,a;h,IUn06@]74HBo*rW)4O=lP=CQ_Ze(-'`,W+a_0/i.@qdVd[0H`I68@Q^Kt*n*RZU%Q -%2,BA0E!Urm`"u6)(_:("/"N)^7n*agX!WK=PCu#Oodo"RW8PeS/)V;e'\B,Z`5m*F6QYc%,@k-\fmSOi2Kk(.W%NqT1R.umd!_&G\utVo`S!qL!>BAMK%.4:K'%&&A"W -%$G-.PkX/41;_VH+;a2=H.8T)gjPI3'l!dCsEQI^94cl&]#_*Ds;H7RuMZCiU)bBfnL'1m8H,-P6T"-B8jl,!I!hu#I3FhkiG=Udf -%`d<;aTrD9.mPqJ6=bk&B]CL_tXIH;l5tO0Gd\]@]?[fRWFf5"4W58o>M=;N_VFoYIWSq9Y."s)L]:4DMhe(dX=cjTFTXOp*[[\oH -%:EAF<,Lgk?C5#8TO7uaGXXE4XDnIDrPg$Y38J-nr%iCo&jT`%ICWMslP2nPjXJ98*Q%j%_!@pcb_#-bOYZN*0!t:\r_i8f-ZA.T/ -%@/OuolmJmS#P,ZM^i3>/WrP>$*2o/kL-0L;+1PEH=VEt&LA<$cJAI'k^D&OpaHFadUM\VtLF\H\NrjKoams?m#5\kE5%HgoE_m7g -%RhZ[G,`/.J,=F5%6u[ks[3W[g+B\^M-lAqi8#,ndDSCNtbYJaKXDr'F>D"jpKit\YkW9RF%Qd!2pf"qu'o'ah(!2E]#L:mN%CeBM -%A7-u1XL`WpPBSBZfD:Nr@*CcOMPCuM"@Mquql'H,PT\/.*Vg0*eP:*l"]%3.;kg;b -%h?Hea)EHOBMrH]HiL^]0nGaFN1_lV8kBA!.H@^:_X1H]Ak-k)_mkZ%>llZ#p\"Z8(/rON07>J5QCV.'<:d2'Ma1dI[E+,e2Vd0n-qlnd$a2 -%Zd7ICE^.?nC9[d8,(;4Nmap(d1TV1GeI[MOZJf+4lt';-eD7nbg+Y?>h?Bm*,2QLPC'.i]!>9I=N@M#4MTb-8[SJ0U:s_3U$iZk, -%a3ZY@5SBj*`7;DhO_VOgt -%%)"d@7n:nTR&n"XG-7eOrGe_>[T,J'C2,4E"A#-J!`07T4R#qtfpT$pRoa*4EZ""8E@M>!:>Rm%+;r)=T8O -%ML.B'%iFn`MoLjg]/eY'%B=4-Jh8qIAlY_]H?qrE5Mha#Q\Ts,m:bK]nm)3lqk-?(31%ZSfZ;f"%KsH_GD\[E=hPX/k<]1UK_aT_H".`$PW:j"t._M*2q6 -%&,cA=HLALFr6h4G4qX?3A\#%N;9o(0"s7%mbaM_sE.7Cn^_T5KouVaQYFOUrg8.mcW5mX)o,_,4T#OkU<`/1&D:15+aMJPLqBJ1oskZIHpEb?'"c(b"jCG-*HIP,,E6l$;-g8`;l9X(:5d7P_OKL\ki,I+5#/\"L2tE -%:VV%Dl8Fam4\\4.a(*e_=d#"1m'kd,H"#OpWf*.pP2nE_,N)NGPsrZ_e`X)2Lr\eR8E/0hB-$VYi,\9?2KtJ];oK,l00jkr&^+?0JnQRS33S8M=ZG& -%)1qKZ_RJ')aaBP-RU2',oFcU8[9q2@ODBTgU` -%s8&5R!SY<_>_MuJ'r1<0KEr`VHp$&T)ps:$S>1A#*@^6j/8_)U-JZ_McgdPR;eJHLWHei_pIQLn.3MsoVQFiA7i>q)dMD[je3J)n -%$>nk<7kl^pQ/..A.8LcS+8om#`N4s#!$mE:O%jDa;Cbs3BDQ.6OI`.D(c"FdVRP6Y,!MgM*t+pVG$a_olIm^IZo`g7$38AU;"j!: -%U,r6s(*s)&(-UAu&3t+*nu@K2W=b6%al'/c-F(S2I+,n/Qk0(t^\HcqWp"P^HZ^Q\YTf/7WJPZu:Pk&,0LC#O.j$4RFpO3ac$:9] -%?2e;V@aV4qTXoH7/7BXCb#PD+ZCHO'0;0%A$1b%B2XNYucgIk(g/n(_Mkoo$cBLmAD>"j2e)g8qhd,Z- -%l`r$,D5W.e=%ZSiN`?+UP(6?D]B6Z;0XC4?0<_TS(bBR<4`@btdEN@5M6r4u.5.%7;UM!=;qSo=9ZO#-aD%<]RO<*WU%GFf+/m&s\EV\KcbG,M\&3<(&*n;b;=bspY -%p43;=jl#ZNRL;s>UuHI<[6eK%WS%.5=-%D?.L:sRQgiYSOFMo3gm3L\_$Q&5QJOjCiEUL0-USX9d@H=.Otg:+)X1R@F]Q$]W#6OK^O -%/UZ19@t*S\_V'YPmp,hFRBs3l5d%tDVjEOA!N^LulMCCi4<5`ics'0PP#VaE?ch)dSpp>/;m.tdS/n-t`\jD`$$i+V<7QY37Pspo -%8,:W:>p;iDB#Q-^r?fRQP>rcEEIl%0f^P7AEL.h0SFoih,j5h"]KbT"K9Dr<*eK>"-qRKp&5Eq].VVat39-b*,:(/=\g\D50mo4. -%P7$6@589#e/"b9bH/O4KUN<\.`2=!Q37? -%+!0=a-<\Fpj`_cfSSoYEe_hCB,0COc[fG:k[M]JRdaBchqkL],NBe0/UE\\/4QbT7n0T#='NHVNb)Ra4&ZV8+bFmRB*#K3mdeN1( -%,:rGdXq&_1`N*G"Yr -%daB\<_9@I!FD9sV'oOSb[n6R&>]5'WTo_U1#eDRNPI)!YU019=c4m.IPI/0RUUr?&5u8cG-0//:%3BH -%Eg=ER^u).kWNt>2.XDdUKoTEh1-s#B]V::5CGeBJq*!_;X&sBRgp-3<'bE1$KX2Jg`bK-R.SIAb5Y:i)V@]-nYBimVIhEQm0nkH] -%,7LqLOt`OPU/hsg2I^*o+dOE:N/phaQfWUhM(DqAR)@iZNq2F75'g6Yl:=BLVUoi'[umi0mTa0G`fmPsY0Oa$/@_&L5.J%=d?c,6 -%(J&^;SJ(CMp\PU%_/uPe$!?cf-s5c9]#glf6Dgd8b>Wd'mLKRDiX.Fl8d>=s,8O0>^"LFG8V]T_rU^M#HT(u%aD -%?"ekWL]>b*mlAom=K*%4jXs_:/=V]g=S7fFP(Ig10&URO0tJN)0;cBbF0-t^`>#br#@54f?nae!N2E.crm$i:\&P3\q&9u -%:R?>_L!I3McS#h+*agd.(!KZAZ=49l'&@Y1,%m:Y_8*S>"0XXUpk6Q-R7VsN,*Ljb1<;1KCaBZOd/.e.M^GK[a%*fRS`"Ba'btQB -%N1n:+q2;]GWK;m;jL+)H0+IUI;UE5>L>6!1bS3rg,bImr$u.k&J0hKXTEtj@6MI7T!BD)"9-gOH7E4B(/ZN6]6N-Mo>gGgrPk;\Z -%9hnsD]c;kAL]>;VB/P*mq6c\gk=LRH&)2URgcg$"R6"nNYOeSPImg77s-lQC+d($Wb'Hl"rC@C$>*3S4E`PmK@hCs8#+b^)5\sHs -%YoBQ;QjE'`S*@&PUj";&VEZ^)O$b#7d>a"IC_n2d''86hkLT4mcX(@SY6t$$<0ahr8-n7"lAJ^3l8Bu+eD'; -%W%D+r`8J'8SN_0*[a7*[oXAHJXq`Gij\tSH>SrX7ZdZi1LJI-OEH^8^#ppshcgVmAG,!,d80mdi8U?>V@96T#gLt&u^I%-4fZj*$ -%*L#%Ni&C#M(T\(?N#X38Z2QILqnM>V>@kDt?rEO2/=bK,mhrc1D[lWiW^pj?]_1bN2Q<\Pod7oS6LMO'c-P\nhbSuIqIl"%j]9hJ -%XahDZ:\'"?l@A=-i<*Ssf[LU4:oK'k6HX34E-l^B&H&rH8Q^Zj=_]f'HkFE5lRI`aO*d))\5WX79n?B.b]?5ej^q%BN.[o)!hhDD -%o\[$>?q5aIh^";cqNit?pj1`ua2W.KS-]U'1[c&Q,+N$:U7+JohlipFXt/*?LL(*U7aY#d:$_'l#@&F!'2:-tE8U/N#\6M8?BIoJ -%.(FNkW!chrX_R@80S#'03ud!Da8u^I?DC*/E\9=q2_[X""eAR*BeXOW^TQ!$a1Y&O2!.FUV:@#%&)g#(QhWQ816aZVTV]JgL>(4\ -%S)+SubJU_1^'>kr,At\35kTHKnN>L9o'PoP>5P=,:&T/SM=i\0]LPOp5A`:>X`=SNV;=lihYI(m(h3!kUbRVNm\gf8ELOpD(CR@' -%i"4RVE`9!JM+pp?Bn$17&6@=]RM,^0VJ)62\2Ss\+[As+C9t'^h!Xn,BHMB,JBVU?E$g\4S!t7fa\%VDem#GuA'%@aL3tTs)8?%0 -%JqLa=K3a3""i*Q0oO42\GtH0iCN9i7+B^tFW^,.h$rWbmj4=]@G^#tc`f;Od@7!cXSGa).$]`Q,JlAI/)CqtG;!(4FI-:j1Bdpe: -%+3Ah-T0CTZq*]J!\p.6O8`5G5Ge<8TO06$#\O2PNM?%KoF"H5FreGMQgLQ[GBZY1-'9ucHKF8M&0l4gj:UK*5Lsk:e$<0)dn\O=7 -%\IeRT(H:A5gb]no0i]e7_/8#XV*7b=S'^ -%fNGsH_3;-hWVdtg^7C^#!gY[Zj=SJS`-E28F4SsW:*4)k`+39cLC&Zi'fm -%35Tg?j@/fg+Y[6o_T7m[Z%8gd12f6Y?A!6'>Q)[iV@&\*/KZ>JnA1l2kTB!J*i>GbN@_"bKVhkOqB[]:->[;t=m-Dkh)%/3jL5gY -%2fQ0Mr+h]Dm!I#G%KDgkA9%iJEm@c&*g<=DX0?)QJd]5u[qOMOLfN8KjkN'G*gc9r9rA\ZVm2_gELH$FS%jL(uH#AU\4K2)=d-Bo+j'_aIPK8k0g6$-W"N -%OMlGMX4Uuh.piPRqiHBG*bCV81+uWOI7pmH[J>3(U8H79`XLEo^$RbM*UO[\gW4D)`6XSAO6G9*1Vr#$7#kjord&qKV=-R'Qf3L_ -%=/i.\e8jh@Neo$j=YE`h&r>l5V-g@k!-eUe:1dg3no)@U&[0Fo*]P?MYe4_IpsT)DQtCTa0T*@BkG^,W,G*mJ`gL_?Oqc:/\0J*M6;Z,*);)/FJVNtbrPFY.sEo=DMk-LTF^UtZc1M-"ci[)U?A=S9ZY@"1@J=*q$ -%(/Okm@_/ZkV+gk+:Gu#j`5Zs""Q=RZr.@9/o>.J -%+M%cH3bBj`$aX].nQ<.3KmZb)f-7[^FkuBa*kGL^AXAM"aXDh.\be7.jRHEFOo7-5+4[etWA.(m3Z0?ap_O$tg3a`O;)K"-7N8>M -%J@7s1d7SY7dGhL3YKVE]Vr"Xp2Mopbmm7\7$aY7_7gY<8EVif_JOI^ru+iZ8p4?>elATP[MO`!)M2!AC- -%BCiKP^[[M'q'dksZ""W?mP'F9P'mlHob,rjZ"%\CkUlesD07#ie)5KY^ABBh-SR@)LMCs(QX2K"X8iB`'"IkYe&[Bii[gFp:]hE& -%oB*]B^UO\87a\_P\^*hBer:X`=&TY>T\oaQQ&IM8,7(KpE'YG@X7V)Df$pt%M(G"B#g%k8_U!*E=0kcIaHkE5DfM530p""T;dVmS -%%(nr*?!:W36hbT-i2$\`=oNu4O"*'0p^Vk@Ac_46V_qjk7Jmn5VJiNl*3T:-ng0MpF+TG\>m(d=,A%?":\FDq>K1e@IQQr/E/..Xk']89mZ[Qdhte2I17O2L`W3Z=P-H\$,JB]E -%it&.:126FP1(L0mbGo/6Wd+s#WD(\Ln38Zu"fDB]/jG<1;UIf$,%H'YEnu6FI<,F_;UC:[f.e(ke8a?UVUV -%?Pi:BEYD:r9m';=qA"E?:H=a'ER/4&i#A]I/L?BcYn]pfF`Xc:NUuD>Ac<(mA01H,Y;KY#E];0/qt!U -%X10gfO)saHkl1J"esX9qD(3/a%f+^oI#HgZc;5[7,)O=f1l.%"kd:gBj/s/)iNIOp$K2"RN&/Cr[slkNs/*]hl]:8$qpfk@b`(I@ -%D#%0Sr=%\1/mJH:o]oFE+*6-c5-2dp=Jcrr8m7S&3(qHff\nP2Nuqr`I[]H9>o)Z9&Au)K&Bp<=]s9:odVm_`P7@dIBXHs.Go.Mo -%Mn\\k,+Sid1UQgFHcFe68u9E0,F?SY0gc*R::>G0Skb2"(c[V5"1^fL1d'>osM/%o2,/J=k&=ck#IbFq-9e:1d0T. -%:Xs7EB5(G,Rq]U$IP%M]AbV_rK%@V6rE?;a[=4-rja@SjqRN4fB"gH/Ud(I5icSeSWT',Ee]LrSNK[DDa]+O,.s&J+*E6lXiI\gF -%TrkJGa\r'1aD*h][qE!ll2m4dIE>Zp>Ub3G?E83a"`LMD>LD!8;ld=@N$Cme?ab#MmhTlmp:EcDQb]^gps_JPlPf>O.+IXQB3_K; -%U39kM.@/).Yei>/oc[IU3r\b`_.T%@8Lef0N+blrUtGhYO..c/N3Z+]]SZ4?f&Bc?2a_*\dKAa3!rS#!cS=it-ml:MBSp&HpI -%TZo\@pn.>\BCb\9cF?W)bX60_5E_214fO0"XqPR)MM9:7@ES`&-tM/.g(c@'j$&I#$6kf%R+:$r'$=Q2;4gY)S]SlsChQ#QAb.g, -%lhq.?Z3knB"6/&+QD#Qp[BK=@R\E.ZR8jO0%7C.??`f6.R8q5V\mFSJ>ZV)A=!D&FD#0DQJ(9a.?$oa)++"W+[Qr4W[f1C7Yfs4k -%R@h'1p3Z_D-5^H6gI:hdm0oAh%i/[^O`dI)A#Q^;fERu>VK\=C6Il`qH0&2aB2&i[gHA+q?e(`L:k%(K=\L%k0=Wqk-CaHHd*TZg>n$JlSkPJ#L;>5q?@gdG8I,FXb_q:%@rSt8,2J\D^Dd*i2.I8/H1"K=a4g5=4eC6Rdn;nd"2I9] -%P63W`\3A&!Z.t%Qmab];U!@F*D=]kQek4b)btf^-^$jn0b^k=Ib_1:RaABKH04)TKDDG@n>msIbq4]"IK3u%ebY'm\A -%haP;sds%chqU9Yfr8GhC&Ztp-=j5fL('0QsnkipqH2/jXLL*10WH6seTWQ%W/u.f+,%'f4j0+JY1FSbqkOBt2o<-60pY,V%*54)& -%.&FS8qtJeIY(41ULDI1\DlD8JT@:^LX%6LeI+%8FcSViaRj';Q7QBkSHl#W00`-4CF'J$k -%V^f+B:Png0='O2][e/-nSUNa&B2NNrdWf)Gp=j@JiN(=D:E>I^7K5H=e3-?-]O0LEH(E.o$fN//$?D*O[VQiW7II[/`q1sTc? -%-W(L>dC^7j\nBhXN;rjs]>*Ns=92_qU*V*ohQrF=]CiOND._Dm9eU#Kh3qRUbK!IiCHd[ToSlksh3NoD_/40Caj.nIft-:)1QdBVf/sjS3#mG).T7orRBG1&@FShq-d8Vfg!3?]gt[0g=oI`7Wnlq;-B8GHFm=d2gU5pE+Mr -%leCcoZT_hl@!PA4g7!ERqc0cYS"=ErQP$l$#(3D)`@tc:,-4MQSB5e&"4ee/Y(YPa'qLAnD@"`N4Hl^@#*'h>]\#-&QZI_DZc5fS -%$`IAI/gr2=N81dX`DE\9cenQ[ISXqVYHN-!)F=+/_u$]"lMKBng63OpmG0PN[.eLpL.CrC[&9/shP+SXd>!*oihe=(G2f#JAG(TS -%>21c$+8GRPF\:St):-D$jaI!E1d;<37sR-Q>Sc36cdh@Lr\CprlYoKEmJ=80phDQnpk]hVcRk^?*dMh^eoqaCtbAI(_)V@J%s?+Xofq -%O\G<^qd_!4&q3rO:EOr]ZTV_36*6ds3>#Za)17+B6k7+I>H4cX(k[u$P?s(aKklEVR8T -%bHWE]m20(6#FOP!^b./)4!sl)EB)ViX+r4W!JQYNI[J,%%]Um].`!\6/TZBr,gFh-E@9STjBh#^/>i'`CQBgCTH*( -%*"uR,S3uW?oB1Oc?:>F*DC9ah"K:tZql7/`RoSIs82,rT)uFDJXoo:e.aSY;.m$s676(tlCFeF_CoG?b -%NY0GSPZ>BMSqe'O->Jj:.tV\k -%rF7De#a+CWT1.[^N!elO,g1RQWb@c&!s^'dA52s[:jI=2c/MdW/E8Z_J_V>jN<_/;]M\/Mp/dZC<=n0kojsa0j2"?IQ*.)u3#HY( -%C-7lYOtF![-k,Uo-UV/(bX9^5QQ%?rXpt/7cJ7.T:g$'p+T^Ad*H3a5fH"o>7-PJUW>WrQXD*1D2bqpN81_$!cn#$W9A`r3d6>>\_A/[2c3$ -%,lM6YZ0@>l'ifSU\po>>@7b"am&i[r3b7?;i8k0W(h?TOL[HqZX[+AY8,u&aW\G[p/t%!?5H-24)U&+@];8`Nknk(sW[?JV9m&Hr -%cF9d+CGH0oIa3(tX2/lf#K*W^7[OUimFM+q7tX*qf;mmm#>Y,>]m(?pK^U)""eq4!raAt;3GfUpCdF!t_-Xml.c -%Z2;93br%_e/nXY`4[tZk^n=ojMI[*`P_@.r8WGGqG+n^/eCJpB[llIU(=JIX(ZfJ@\W^AoRJ(-%;W"(;rncBhIW..SU,k/<8B'4V -%^9^'$]j4\t"#'ki#Be=0ibhTtG1T[CSpKE-*Cb.-8:oFeM5b\l[f\hX[,jN28i]UA4h]62(Q)c.![=9X4._VD["QZ:,:tss7m%Hh@33I'&<$,ZN -%Y-``sQi"HLj6,GdF^Pr\KRLOFj7r8%@V#*O*?!=n8q)q+>3-JXK<&l/.HbD`fm&)*d'9]?^u$*'b.Lc5EKQ@U7/Q1:&"(0[:5o1uI]"?>$u9bGPSRaD3c;d.Mi+:A`O]5'8n(lSZ(K -%>G7"R@HY,96%9@@dhmK,0dj+k"F@a8&rm)HM4MUJg(N=INR`;LeQqb= -%hHmTh/sO./+(niUQJ#QY/B'M1j1ISNmE>EVYIZuFkK(YFl>1c<'h(Ma8/"BTr&^@"r;>':lG7*.CbCjUDTB0@?f($QI7IaGaE(IC -%=7iP]&LJY3a^Z.pZI1NXVcgWW>J/33CS\)K\Y%m&67%t-SE=^gYdqXCihtCVDfnD]F?pp`Uo0$^%:l0'QO.9FpMJ3[FR$@Hn\dlB -%(p6DLgknP(.7p/_`o-N]j7`DnD^?#+;%pb;DSp1]GgX[r0(LL2aiJ\V]2ndY+"PY"Ip'`]Mtb=g,*e!b=abSU8$rgkmaU16H%DM% -%+.19_@Ip5OT%H#iD4^[P*Th_oBqW&dNFAFMpfm^mrT_;/NDJg[$Q1aL5ULrI^7AS9L=HifAfO-"-EQ'mgo=aB5<'b&Z4s5;>N4aM -%hSjs`\Xm_9,rpB2Ohl8QYTaJCd*F&[Oo7Xf6JXShZDd339EACZ.IF]P,3A[Nl\>i(VPd`s^SOaY+?ke"$sdq;IU55*ZEF_*C(5[c -%OldHEd>_9V6Z8)$.R!12LHk2$c_hq8&&[2G2fK(>]cpr=InJl]T7+4m`(*'s5\M)b=MF/ -%(9>4$NAoZ1D"Apo1Wp`NEShrs>=F=(Xs"YSG+M]+`S8#uiW-P=04Z34]0)\_B^JF7(c"e=FeSME-(NBEaR!,LIQ?(^:Y4s,)-;^` -%&-/X$"%4$@RP.&3(maXRFO7B0>pjn+Y_dA\>D9$B7Cp%VL*UrOHB4k^-!j=XI;H0P7\9SeI?i?.hluQZ@Z,]2_Q* -%W76Y2]mK#?>lV0O9ng6dX^"f`_l)Sk+ZQai&H'p6M[cS%[:BI`r;00?:o(3UD-29pGW)'qY[3um+m`+-f+\_.o6I)o/]2'KI;jdM -%ZWgTthP?hhFR>3T1ZlSWoYc&?G%+0p4naYFS!h34fkTAHLj*p*4Sm?bkghum[BpHc"SU0Ob'/%5E;(JlGb\c'ZCasiYhdZ:#/Ut8JT=)/9f`S&Krgi!5$p9P=0 -%iuo@BP=&3ne_,8&T>hn\Fde3nab*=c0siJS8)$^o%o&?A4o/'VhE80<"ZQ"A'!fig",IbNVXJ9;M8lg.WYL;@*i9L@_Vfc7W&-=6uC -%S$eK"N*0"KY@e&+'$N4<\tgfGr>DYZ^j05j@_fU>b!o+K8gj'9H0?/3j?tP\F,"pNjP,e_g;W4=U0bqp3GU7rXX5]0-m5V4Zl8*IR^,,)S9e+m;195LUmqMPg86@DW_;=QDl=/O3NTO15d!Zs.# -%fil]MM[9;dTUT(\/fB*Fisu((&'(5i:pa+k%(K1.VDSTsZ>:`)*OL?k2'iuA1;OS))\X&9?/Ru*YMR+Wu=QPE6lrnT)=u%p0H1\b=ZN%%h!O!0jOW<)c2hiHr:tWbhh@KO@M6fLOcr%Pm-MV -%h?ma=\kLIXFXq7NglF!!&hiYC103;^(fh]=0D"IEh<5m\]nWCLlRJ`)Rpm6g]b^^TJRTXCrh=pkOu*oL[j#X([YC1;paO-fW@^q9^=7EY'U?oRVM>O-C%l?SH,*gr:Oi;`kk_./Hk(SLD]Qq:CUWs2/\[-sL7kZ@<%a:*`[HW_X4N-LQW -%EW%A9Df?)Zr$!op;$m=aQ`N]h%,.d+p'OQrG_70Z(;^Vqqtl!hk1UTt#-FVU*+FK@/!U.OLRLia3$DYKmsF:-=jrTXn\199%kfdW -%E.KL2UhD*s$]&(0)AX)/aEX2a,A^2THEdNfAJ2W2<3g9X=ZeeiUH+GgRE]a4_#LG582c+g,[SBnX\`j7hNTY*L>2j[6IsR5B!#A/'JnX)%rP6W/0V -%P<--P2Q'u_WeOUgfXI[TZ\@SQf$K@pE?fMII#;_u*6ot6IiS6B)JqRS^R,V[_>OoA%ZIoRBK(i'1CF#;*EW`@!m2J4UgLk'HSp`ZFl!F6bRWC++u6W/^/+f"E:9ST>)phM@DMdmYa>?ZGK\ObSV9a(nU7`nJmTYpg^6],(26rcV&Ek-cXpZt_c+sf1G$nolJ%_V6Idc4BXeM,F=fJg -%^qL5OUs@GGjYsZ:[A;j0&'0*W2P<]!-^.PF3:<'N[tiU(+SNoFUkraBi['8h!e3-JId.LBm459:Wb)iR]7dpOH&jE62_5(WX38@i> -%+KS/bHq?$9;,e8B9*.(Pr4T22m+WtsfLNA#PEeVQ&tp(55C'AOX:i0t94M,i4\3_Rl>U0aj%]eaL7=!`!*RI&lGUG4eT[@E"^0Sl -%3u`NA;f'BLamr8!ErcA+=o+5W34"cp;JfC_RP2`MTg#eCAgJb1Jmo9<77=>*Xof7kD^.N'"@UA4Zt -%5&GpL>)''"c,V]Sg=J9lF_7T^5CfAuBm@s/cS0%hRqa -%FC'"X_Lo"$R[)Q?&?35YHA)bR*kR9pYSMS?-/3mR\Y3KJ.&5VM\b[([2g-0ubM]k^:RYA9NV1=GK[gE,50_$$B)XR/]VneiAh1-"WL(6%.m,/> -%+7q=63i(sZ^t^&J8&SAWN_Ts%@c))&Lo)OP2Nq/qKs42$G -%PeeA/F)ie3ZWM+/Hd,r+P<%@*/ebN_2qKPH3Ep[#i-AEtG61p$^YSU#1SuhC;d?sjgWS)opZ:&MZ'9C*8T=%&TZR%%29n717n('m -%^XrsXV?DacM5?D\n&:pW^T]/_l`l89A_SYl.E&n%bImG)fR')S?@mFq-f2rsD-0msS9j"7b'#-6.)?:h!u^3'-+--"KF+Ft=j2oR -%"Bp>X=FHGs72!PE3>b+)[OC"lDS0g_c_AkJq1S,nWY+c%A91[gX42&g\(,.X]nNk&*>k:hLHme,ZjNW]2dicE"\@YJaM=)>Sf_ -%diKN=_8*.8;,,d%S;b55+VMOlVO"6%B#Oc05om.',+Ho3TF!Urhn?FKoA185#4,qcc<3<*fS&Z_C;g9Qp^I.4!F[4jnZWdF^9$n:YXH#c;R^*:HI_Jon/77F%U%A" -%F=7fubQ>`)mY+fboFLh/#E+Ij4q*_%8_pHa(N9/q*&44)^lP]]AQf1l.W,)/hgug6J`6fMn%EP1Tr^=s1CY@bI86TWuL17WihIGhBFRV=8hg:@nj#9:\ -%f0FL[k`uXU@:3I3CpJULYdj\`5VgR1Qh`YW69'tHOOa1]Cl^5:(#n?3=D9h_<('rAARn1bf`K*dL(Ej#,fqh54Hf2k%oKq>5Jqf& -%b>9!CUrt+k_r*9%/0j*A6BR@A"(2MG)Dbn$XX^RLDZF<9=G!UX -%V?*c-?*OY99<=f'+afr^p]Q])&)%'S7V:8G=<-+s8K2]PV[7&1PC!A"`K9U?0W]EiQ=Q*+]L6&,4QNBp1rc+Vl9f@")'igO@U%t& -%QNU]^9JJN[nAUYUMip14?K<%K:lT[/KQc+n"RC)%N-N/7j_klC9fj4dPe];lg#$AdhC!Kd_^MT@XFB<[Yaq6UZb#G;X=-r>Y0t -%`aV6%at[+"&^S<36t#q%Z5EN`I*]7J#BH?m!q5,.)[c,MN66(+cXosDfsqjBjX\:ulX5R4Pl]>Qjb[do[gjB$3m+]E\j/M?DF-7h -%7FKY'c._BJbfM2qohPj/9@hg`SYT-o5er[*[M'YkGC,A>`R)SJCiR#Jo34_V,E4#+].^"E?Y&i8RY5,SGt,kUOD!?s[cdL$cgqWS -%pXSk>UV?+385g'r/;J>efuZ5E2+Q`LI+DuTNk%TqfYWAf2nS+/^i.pW9>A6C=Vt>uH@=K]]_CY`HE;-oX!o8A$lp%;Y)b)pr6 -%_ok";%f6!85/5sd]j86f`/ZghB`s:b/IRa,oVt'Gqeb@rT6>5%pRV"Q!ShdVkIWVHc?B^l`Notj1S\>e+uRG!E&IF4I8rkK_sG<3 -%c%=Z^%T[']Kq4^G"S$h&AZuET-2F'7:J;]YERpD07fYI@1ck9lrdD6`!j/hSO-=O"de+*W('U:@_VUFLt7BF6QCMe<$=&n77(!K!8(m#=`fEaO\\DUr?AJ+gr"5(gZ3!C!]7Pi['LT2T5%)k1( -%,hYL1d(TSGDSo$8I)0Ab[nUit\[`s2QA(7<+ -%MYJR)FkI_ip@A-']DaE%h61P'qdG7P2:QLfcrAaEaI"qRTF -%,QLRi)<`0>m[m2[T["aO(A@T9S/*!l%/7uG1GD2[c,:S[Gu#l$-O$6kKe,;Guui;d0a -%EE%Ju+/=S0QW<2\/jJN1cf2k*5V>\YK7=_0dsre+'J++n=p/f@/LsGL,>T]qN"Q/_\4uOt/[AY_Ks"\-blXS\dCYJ-pP(CYW_LOk -%YaE(9*$Ci)CK@h[r&l5GY.J*i'hj#aUqlL(d=3"#AH_T/h-=(FE:2uKB-;K`H"dsZ"-ELf7CIa9-(m[\G4P3r&kh<>997c>=GMWA -%6t6YQ@)d8l08*mLZBfB*fSs")]Wk!.<'u)u0k*qFJX--5@G-6\1.OouPaE1W9>gA>J;0sP7.sInUq>M$hdIB^aCY(M>=9GsRmYlC -%\ZLDh#61*a[gu\p]jfQ:Ms#nq!N-p)c8\DpXLcnA'@URqZ1[\3GZ7'QFe8ZV(P-FS..>mqCZ8Pf20N)sq&D,EDBKguJ>VNG -%+U=Je^aU:3oYC9V-'!##P&4a^YkYDO)IU@K/n$Z#h)U?-dHj>b"ZiDo,'BZQZ8nS)?@0SS3DeJ:prAkldZ!&GmG/"q2^E]OA7I=Z -%_8h+")cKfp`OWUmS!>Z!c-),-)Pk*&?oTBbh2Qlr!'$==82NLJQ59J>\YES@`#^ZfAn+gX6NHRL)MJBK%4A'l&g0AHaImm,s#n-' -%!gq.r_M>p0J0p,[#Nsr/.h\2AX>2_;*3MY/QeWe<1()M$T3BOH]_(K17[h4+^qhr1&!fgIRRB9K35Yg^/=p(sPpgle5(kOAe^(ONg"UDd:N%TGlL!h= -%IfBRjBtb!HMdOK5Y8F^srM6T^e,<]!;I#j7(hR[V7]@If1Z`ASBI*25b[-bJKER7Y[(lFZ5Mi0&D3f7nqsHVsU[9jY5/ZW2hb1QJ -%e#\Iu68JS;%&+I,9G=XMAFkr(=j_%qYY.qgK(MdMh\MSSgtT;,_ll_ -%['d[g#kFRaDjWu0A=ade0rEpuI=)!^hlW<9=Un!/hX\HlGdJRE[=<")S1=KtiJCi*)R:@[R]GNd2[*P)\%I*j>^GDiiUQ(ta5@f6 -%Q<>-F-?G6=GFj0Wc4BU%11M=90;mOB8d!/>RqLSpJmr,17XJZ,gaOT`+__D=6bnB6TSA:)n>6ca9L'DibaBS-p'-03[8%[nncKs% -%D)1[:"WUB=raL"+B`;#P(2;;i[CGRp:9m7mhs6%,.,\^+e25O;4eu^mMB!l]\?gH^@;:u?,DWJbP`BK5o_+^'MA9i*PPthWh.H/>51OTPA,6sdRN*]TBRQjp-GUkWD1"WH$%J'[W!/2$c1_q_)K!2LjN"](pE-C(AK#-'e\uu -%pe+_Y?r,H59]`2HJ%1OO:[,N([YIWP"?^q[i$&Oj;G:^^.10#dT^:.AaL0;IKO>go!G5u(+(!s2=R[\/8s\U\]85[/,.`SZ.WcG; -%p0MY]\enN60^PApj546\dpI`AJ`HR,m9d^ohV1lCq.I#S-D8jVdfP6b=D+IR&N=S%gp@-;bOg7e9iVpq2q\#Rp&o5L/$=Nr -%XhiV%k\6F]X;j)B_e%Ki2iE_0$chO#]SBmY-iSY:^_[r&k'k*JV2qta%GRW8./CurrL@2G@Hla']G*ejL1pWOX+niHd-8hQo@=7(poTVs=U7L'u,^WL*+@!%89mhQr%DS0 -%ct"F[)m93RBrT,5(h2n&Eb)1n2Ui3!h^smcZcS*,>q$9,>jW_Oc:7`Y$pNg8Gnt0NYE&Jm]?P1I(Qc@n"5b]KDmV,cY.OLnVr?[g -%""1r@mkb^dUA*Di+J*_/Bd@4OQQKS3j#ae9MAL=$VpKH]aZHkGf5fqZJCt[gN97A)39Mu!lGEF$6j?5^QAXSaTHf:(Nbm-@<6P'R -%XA8S:Tl;q;OW[tB2t0V?H"n*6m"m$M3`*h]2$B'*K2laJ4<+reS"m6Nf_Mo`jkagC_Ztfs(@>*e>*6QQlp'uuNP?Q)e7*;T!sNEd -%$QSNS3:8nb6u>Ri7WV.EZt6s.*$dehCs/9u>gi3O,g*K)eU(1Xo'Udt*4Am$Z2LV<8Wo'InX>6MeGg_&R(m*A3N(?Nm@(Pb'YVPr -%>+T&qk-TY=c1"Y$#U!Znt!GF7t(n+ZG9K/;8$n6!EW<'qtt -%MP=WnEIBaGM5TMn9JoquOC(+%bsSm*l',CaaWpiWEIoC4B31][B%YK*)(0@MVrM"W@msMQI'Es(;=c>7+\e]UF"*bLDX1[?]'Uo; -%bZW_ZIV:T&_CG`^$ZY/UUd0EHihdZ$#7]E-rnh9*P]u'(g%;XRhX-\5BR4+.eLpMWXH_j$KV`97,A&mqd98GU9(pEM>9(XMTc)q: -%+,1bDC,7&)8dm><2^I[67;&$*2(a^q1KsS`]]&g*:XH'NHC[IiRM[@o1#u7d8t)DA2.EE$[_^)1"QjX#DOFWW3#;> -%R:,n@n!2cqSnr`i-chPl[8KlWlt*KP%e8*(S:(*QfiQ#Hd:DcPn4I6?%$)9W+G)Sl/EZJ[bg^Q8_:t@67;M])#(UQ(*uVPJYYP<bH]4OfK(uiaa>3j_!fq:GZ=0E:\1+9(NV -%J,Jr\`..Rns7fC)hZ)Pis7lWQ^F]78J,(btqZ$R[hThblc*+n]h:I/OqhOn?o,lDAJ+<9j1'_\>)&m\ -%]m%rBWh7fA'9O`@"3d>_7#7u9,5GYk5O1D">lJu:L_KXqq1_V&ZdkXQ86Fs=R,r-Nrs7?Vl<+eR-DWb*9UKdpf_6SArF#r\Z`3H@ -%j$+78TdG4na4L^[Jsroq8!H=]!@Hn+M*g`tR+NhHq(.P:$->)^QdNS=@1Q,b?<['*22(3BDP_^3*bVjkefO"6$O;SRVdLU33,`ra -%7ie_7>h$P1h>kHB-H(o)F*)5sJ]CKo`3[_#Pod!a2[5&p`X$JD/k4HI^5^f)\DU.&D7C3E861UacTVbT'>hctau9T)AO_6-]1r9g -%Fr2dRa_,7kD]:7;/n*UnUO^Q$AC0iEU?QoY_8m$t&"fsaZ%4NR5WQ:Xm-SX:9b!YL4hm"<_`A!(NfFff -%euAq!&=Kc=S][;Hpjj"=cr.?Q/LQCQMa\j#0qp4(HoOk9&]lZ#&f/peiRhtT(0I?T7+hhL+f([O -%ALAN!Cf^%^Z:tV2m5%_J!:Pj5Fnep"2XFEa:ea-q?[0*MC*PB-1V7iBs`VX4>PE8+[!^9[.Cj!RE9MF=QTJ";gDu?DWCJo;/\8?Ye!= -%SuVHkBJTb.e$=Ji(oMpCLG(>SK908BG)iL&VJ5/A]8g#tn^?@%qeG!<'ej)t^<;n7B[8HAar6A="8#!bR`9aG=\$9_IaTSm'S;@6 -%-7;B9T>Q0;`%UZX[AVanPOV7.*LiDVaq/_h(pklH:n%c<$KY-5QU)U'<1Fc7`YOOBY7;,(C[[.Pf#0.a%0BOr9LiH-TeSATKg";.fSg#d2S/eS&f'<3mLHPo5Xjkg;6!>FF:]d6o=^)mmWG@+*ld^nXQQKFbD7lM'$#'=h[QS[rW/jF>hQ -%&HL.1`72'BmA;!K0fK$lT[=$=ACo'%4=tUk'agR]/-]l)Fl^"_<5sit!P!'*T$8uA0X\O=XDdL:9O%,A\Rj%*QRn'B\^`&H-ea'$;>tK!'32!&n7DLq0_QT:s6i -%a*KT#.LkWEp*QS)\nOSWYgea`."d2fk:Sc*_Kn;>=7?HBui<',Fl! -%PGdu>fJaI8O__=n9]+l:KjYXK?qbDU>VcC%6;YnZSJ<8G]5ggIGZ6W61?7%-Qad?Kfiu_4_C^$e-luls>sZ2!S6Aq)_Zu@V4P^jB -%UhR\.QC]?JR^Gfb?JSd&X#6TZ%BcT7Vj`]N_!^teZ\`P:,0@DTgP*aU2LQWU1QiS!ju<1Wf5fsX$TV_V,)[4aPsoG)MhK\oU1Sln -%V5C;:%s%_fpXct+o$fgP;gZ,N4l(CkF*LQTkY5W,eqr#%L0`(?l[HfNn9`gAVMhP/5"93Y3g"M-2s&n%$0.<^Um.kEAbQqL*t80Y -%igc0Y0Q;G]eR%laZ.g:0X?A>F<3?*?hB+f#YS?"O1*P2>c"+9KlmhFDb11o\G!,HW*funls#tXN!?lPo^E7W0T`\J*r-^$+pp85* -%_AnIdS+j]nd`2q^[6V,E.@)V=.tu*j;X$&NN[5KBF"(MINce+r1jB&:(?p1gVX^&XX&F(4M*NopPKMOg+1gQhFDAqjb2^MT_[QDl_pt"l8ojTX+FBn@!YAS#r]4@aJ)T$!;V8R$.+bQJRXat>rPFpBCV5Ag2E@Y1,1he(+(-d'$ -%!R9uV@A>2^TRE(+2f5IjA=5V.ln\9RVV"Aoahl79nnR,!i*o,'oO0*HrIPL)8)8cEpO;c#Dgq1PgAPrKL]-nLJ,^2lqqWCJGR9Q3 -%>Jk!SEgrUF*$/@7];Zs1hk%asF_!LsDblAjLA5KdnZmZEYbjl(ZH71jd-5V`T$f/nEmj"X_pJ0Fs^K;d":L -%mNi+RPIS_3$_a`Bb8;Ht8E+^ua'9o/=K/e6\'0bk$:5B9,EIOYg`f\UX\\R]5JBVUIiPBKBuY147rcp&"N`*MN?*A8%d5c?`3@J= -%cj7,ghjRgV;=g]rY_EC]!A.4Jfk$aaet$Y!ag2RI`O"nOi5'9F0B!7CiMuDmA-d-[!/@>sc--j;u5"Th$/21]6f/PsV#R4t;K2?,$bE5X4PDDV_mD6UE.Cm^S-,2=llt:nDI"L!1=IG"[ei -%Ir5Ma]sAfsFa0t3%459DVNBaib\f8K_strYZNK`]3Q1"fDAHUXU3MYt_rOO4DYJRk0,M^m("!4GS/UX#5O8&"]+\aT3Ssi_0(+4N -%Jk*n^2-lY@"Dl/ek',e?m#o[c,uekKh:0TQ1i1HY?5Qr -%F_&?Dm2k"iK/@kO;n/*[)tQL9A9U@kZ,03hq1P.%l,K0IJ(k^LJ6u+l!8pru4]29?VIpXGJoLM_Y6ZX3J3;Tn/GK&pi8=2H1CZ_. -%+(n!,(g-Cak#rgn,')>=[^fC`f3tGs%5D)k9IhT*@YGd8/*[j4X'6*826d/45c@=q-V@XLmpJUKoWg*)oiu?'"'OoPVUu\j+.'Xm -%^e3gq(<:=`nsT&[fNF9lN8i.nSgCc.*bN1a1?\k60Y;?/5Vc7faSI91P7%Y;*^]Y# -%CpXbak1t$m224cZ(Cr+g63_F9*f;i<*FsgSg(D$^&qoaZrG]XFi^3/i&TX<)YSm\0'g?X -%A!pb5Z[)V*7-l$Rt)T[;3-BBDl.s&?&`1di:(9,=_cGA8H3t>2q)0AE(lWlJ?/ZOTEfBK4bZGtY^=.PMl.hY.99XjUi*;a;PS=uR^T=@`cDFM4/E:q$b^0Z$7O[sH23=[ugEQj@:ji=,A1#")mGMaSn,E#Fr5HGKiNN7Fb9-`JT7?gO -%J,/Otrm),&T7(25['oOts7d]8cTh?N5Q1G>5Q9>CroIL7q=:^rs78JTiU?:&TE"[N4eDRY*rgRlX8Y_Xor;,1Z@&+E$@?@;Cl%X1 -%'%QB6Ys$pLqj;WaZ7R)oaA`^2?ZgNpDjEXnV,AUs+U&fNqZ=1TA1*QoN9\FiH,UY0Z#W^nZdN0qn.V]3rZ+qgaXEOJ^:#?R[rh\PnJ]:^m9Zg<.UEC=hN\i'#%=0a+ZeN^Hu]9gHe$&\ -%s.[W+3NEDVEfAK;$_cI7+lpauAO&=*0F/n;90I0%:!X_=#X[N-5?p^..TN9e1TJ1LEFBPf]ci;Gl)VFVbuTS5NS]#Qc:#BUd;Tft -%^Af$lM.I::7\f83Wg+M.1j,R/dIA3^qeECHk.<1IAmQ0T?IW&61(B<,dR&g>',]hCG;1'E-FCi%KI"huTge:G`8'<:Bm1N>DqpE2 -%2`%duroSfqpE3_k[79q\ -%poH-+;U'4WRf;CRb4_hl/E0BmIqpDjN`Ti4hJqY@)M^./dI]oOIF?n\%J4\!j -%Fpu3BPOKriiC/W`D0M#*,Do.+"^8%DY]e-4gN&pc=@*880S)oGW,Bs(Fk>0:Mq<0>4Vr;2g1N.K?Hc$_@01@$6M1S -%Hm^J+rsPHi3sFp*5b"X%lE(t*mC2SCY/G&!&.A6b'G3)n0T_p-]?(oa)2OdM:[5gjj,U=_q@K -%5@!0Rb.9]D._qDhO>*q7JLhWTbu;UR.9oc27(Km9KjK.*bt9VE_*81T"P5#o=.$[TqTl;ln!OYG/*# -%UDWmY-fHU^]b;,.bCR9a67;t81eCdqg8>9$:8IX8Y),^^$?]jko!\*XQ>jkHjr&24GSpe6IP8_rf:It;[1k7b)BsDg27K/iYa9;m -%>d6:s0;R!jOI)Un_W0![?t*@RjPUurSQe*7.OjU?E*U`-5agMm>Bq*b#WcUcff`n211jV.n@U\&"M]10D_2LQDK>uQ"?C5iVa)@E -%0Q#!Qb=l3&c#0Ib',nfE_IZO`5T,=4:f^g\g!q?@@`h^u>0B6DK*/dAo5!;1t1n6B1]fq -%'/J?Y6(_R<753^LnCh@1;!am3C6;p2PP^/f=Jd.FS$Y^r1#2+"u-kGf"ETG\)ZTpZu5Df!E],/eDt* -%fBQ:'11eph -%Frg5KRE3*S`9VH)M/;^ibV#&T4lGaF^(P_uS`")]_u],j_bOpDr\^BghW2`IR!0'W.66PG+\tbq:#]KG7fqd."%19(mBfK/+`!4. -%Ycb=Pe*7EqD[nd=f9RQYoZGi@qEi7mN2X-4S4L(D)]E`S\IChn%U[O"+GnN:X8B!pQU1Q7iY.=?B(C$/7FJDL:qs[c5CW<@oa"p& -%d/\/4QE:e\^.Ra*R2)>QiJ$WEG#i0si0M+l^ZLKB*LUJ2;d9A9QNNG-A-6CYkGo,pD/[9@UtmeMQac:[Nq6e),FQgraLuo?4IH\j -%_=+XR[^8U)CK_ho2q\j_\*Z,4Vq2"@,:!nne/8Gi?@Z1:Gp=S@;HC;f.g*[kem.M9E8/8%-@G`\6`bB.Gs=N`39's$qo[Qt^IgOZ -%&Y+X3kU(EGPH&C5*$*7Y_/?J>&g10u?t -%A_WfiJ"h2@MRpC'8NRKL.\RbMp.iPC:?#loH9lHmY2^/,Yj;mRq%cH3_Mj=5cr[iS#C8VOV[q5]YN!TL^-6eHBSZL9Y0A(gG!i]( -%1L[H@e';`Q<'`7JN5VT*+g_eh5&SJd*H8<8@H5B9#qo`LrL0%$@$_[SkrbXm$X9hZCbqsM\D!LN#e2bP7^h[Gs&fg+-$oBLMc)sl -%hrQX+WKV-Tjca:j8WE)Pl6k!+N)7I_R_(:d>aMo7fDK0iL&q[X.k3Sl,Wd>G*On1#A?8+@k^i;odq)#[jln[UK(MSlh$GY0K3_EHAYC_sl6q;1+NEc":N#fhK36f8h#^qt[m$:oqg4k3ot/'>CNt@PD5kAU=g>r<1Hk*h>+h -%':V8Vo[UoB]5j4lqB;@a6$AWN+"6Ud0&u(*rt%\f_"?qgP(GT.G>\^O@_`Gf[gX7`)EmNpCDU)JTNRJPpT?EJ"rg4< -%gn0XsC>l1'U>-dJ]L[XV=1(%O-r9P#ELL^),1#6D0LYAS"1fr!Z]iPZb.kSo7]JWm3_iFg^ei -%fW6r4_jjiZ@HupZ=0bo@Z@$manTK>l8JZ5#+L;kNRAUURVaen(qQUoR,[L$Vks[XJ^&KfO5-JEq0N--^/&56kaF*5$oal>Fd$aE; -%R@`XXX1d_U+<#Q3M9*94iX:tOLJ4i3^[R<($*@4MB -%eeq+Y,$2G#iO'Lc6,rsdRD+/@DN9UZ!&k.4pX=YqH.cF)TBOZTodOZlNn=onC0l--r&8HFU/rZ$k;$I'cnK0fMauSdb*N+t4RJ_6 -%6VgsS/C15!e?OaTjBLl2@PN'`YQEhAjLJjSId-3>_dNV#-'o4B6t\(!haLJtA?J^k'8b[AS+i?CHrbRARHjb' -%Cla\\=Z/Yj"Wg%Y7neX,\VBhK:l?`i)!1+>O^WDLHYa,-iX9OJRkO5S.q;*+DmC?]O(J1@O=VI76;Ntk+9(kq\Xpab3JNj/#7rTS -%abd"\1AL79G^`\b7^hT1rUIenqff#)RlLdOW6(D)U,gL -%KPC%[0[hN?Df7NuTTea]45T&[b+aU@;.pFdk^i#86f^7d0,"V.Y+Xe,$93K-%s^4R]=d -%)@g3H1TFURA=`XmW7kjqk];r?DPj&=4#l$(@;'-^($,KZ/'f%cV`O8T3=[0=s0j(WZprF0>!SnQqYs"G-[l-7D -%[oJ6gI`W=YADJ@Mb$e=Hg+Fn0YW.VGNL^5mTL-:99J#Za=hi_)mt'i`hE@&L13qc[^G+oN5U_4p -%Y"h`%p(B_)YZdTf-IGn)&W6#/r0('I7%!qe?+gf'DNZ5OaCbD$`Oap)f]S`^ARh%Y^T<]!ok`%(KhrZ?`NIa`5CT00nta''A4*+] -%5([U[E)AQiOSLRl4Z.m)&EL_'XP^MH#_Te7`QAC>2laODpDl4lios4mEWNqd3,]W-)#G4cPB<`qR$KrsJm'9g&QlXL&qt9>DkN'g -%>Eeeia#'*1RO?$_DciT<>o_*GWBO.$k?OY>F:\pX_*&d#BHVWf\QBF6qSrfYl2&+!5+'642k(s`P*R'*EffCHA-1WQiI!m#,b@<= -%T5D]"rjZ6H6>DYI%Te_sjhP=Kka\M$G^"96df%[K:(+6t-6K\n3fF*41bGm^EQ#sWb=ij3;6\p=2JFdeD>E"k6t4t@^%(X$c/"he=.(D7@FMVD\Cin;Ho19'2J=M.D' -%93D4Ln+Wgm,:J$m^\Fj&PLhm8k^L3"J;@Q-+emXZFG&sTK31])nN7f:q^h8[F>ko^krVS.M*0RhtlB=jNpU9pO)7rO2!5T@JI)+s2N\#)7elFmQIG00T(M>MpVR4'Xe["]Bl(3@^YM)lL5hfTdua"kA=V$_4c^+dKcYbJD6$#ZV]$ -%Pk5/"oi=E.&O8CRRrqNP,Wh8P,3>HshOQ-P![l$LW^[+n"6<(qa4HP-FR9Ms8-.>Ij^1j&^b=gQoq4=HB>g4*QZF.0Cd\QW>>aNf -%]E`<[-7cag%;_0#Ai$T+Ak$c&,gULF\3A\3N>+$Fm;$Tu3_qD@4F4f)U:k:K:0=YC'BjuelqeNnn]r2.MR9ZYFDO$qEOQ#foq"XW -%.HGM+ABp2B?f?=UGNkK^neEl-6u^be(%3;9%U?Q'*u"),I=58kB0/*A.H62Z`-,6KlW&R.3Cd&$:MV_:Xn)l'mXrg>OUsoKc8.a> -%YIdJ^W%LCD-oVl+&S>MC;S/oImd6V>2qiDbF+>4Br4^4ccZ;05Bo4TcHqj2MP-Yf/(bKd2m+,cnCNr\7a -%l=*@6MCe+"0@8_J?ll%kAbr'&\)!Q&/6O`Y)fJcH^fZ)VDUHS:P7>JY&M-p&"t@?XG]l'/V?cqDkR+hnEsB>D^pSK[G"aG.A`nXi -%:4='VS.%h2Tt$'?#Kn\Sj^j#6fc%IQE2p;diQIOp$hnam&L_3&^\B:`0e?/&N;%MD.Rn5A#R*j@Q=fsG)lR(d_niWp^t-i9jEV&Q -%G%$V'H/C?#&ZB#4ZN<9_2lh^9%!0_^!JrR$#*N?!$Z"6ZMLZ3E7EI#"k*>mU<'^QRo6G8I<:<"+dt:tdA]%e)HP!<:+)SsP^5\e. -%m<450&%l2u*4J4Q(eKe@5au'p$hWkb.b4;CWptoXF#r(aY:n(KID1r^:*4AGDYITsLBOrY4aufUV>Ofu"PS_?"Po6Mhn7M+LXg]Q -%kokL7[h=be@`A<"aW!PuRZIiq1JTP8VH2o5EVqgQm'%r;r-eZpNg9:C2I^5$-m=S;>.9Ik]sd;=@8th"*ZKVdH,r,VilfVnE'B34 -%l(c434Y'BF&XaQB9?Y;ll@^AnB$[GqQq]+!LaTfM3a=F=dl)jBU(o%cB*6UeIHeSi(`5TogGaK!J>81'Bl4S6f#B7rjhWu:^enJa -%*=)P$fY\RqNo,+K.QIK6o;&JK.oG=l"Q":q'Wq#/TPc0/Y:e\G=WJE<16QCI#;d-K/EL>g#QoJWEV4WgDL&JMj`KGkZE_tdfRqt^ -%Op">q4$4$t\(j^KrY*Sgp8^H6?QbYW$1i*A+U7%m^!N5>B`,?HUD> -%HY\X,s0s1I(!Lp1\@D@@nm7si_.7hE`IVOR`u\Qcjjqga[:9kB2BtSu=#P_HNDh4M(^l0V>/F[_9JD+%NYBK=&QMLf?0U^P2pT -%]n*nl(>3t6Te!kDC,H:ip\?Kr[YLkm_]KnsNa[u250m"Bi_,EP#?S -%)?fN@F&on_M6V7ha6&**4Z.*Zf@,BGE5[3t-i&1Z?0e.cGF%8c=M?PFU*ZT[5=3\S!U/&_lW2MeF-]P5lQk.XpN+Ot',S3=1]1P= -%?k-h&N994MRB4K.%PY&!6;O3qZ6h3:eZcC%Im.H]Pht$Rn?PGtDaji#Kh4H)aukEH%tb\b=_Kn5T8k4$3&b:0,,J15b!LXfOcI#ScH$KYS[^;b+ZYB^SF -%H9$7K7'K]$hVo:&P#Xqd@`ZXTn?.BaD:]TJ_[#SZbXthIK[ImrK&'US1-N'/&F@B -%p1ZNr-JVHL[VRV"F"G@e(AEr>LBM`FBo2DHSkK,m<(*jG0gI_S4sO]n[6"J*35`G>L1kr$Qri"cajQfIN:97FS5S)/O+gC;R5)S; -%_Pk4qkc<qOko(s1G)r?,:AWQ*98YYE>];;a7NhT[s@;!T)MTY%Uluo($J(^"hkO -%OjK*MV'JBbcaAb$lqLq8Xnm,WNPa)?QgcrT)+OATMd\`,LEX:l-/Qb9*&3.?*p,\X!;#OhCs*+;*X?:*;h]NZ0KMblY&SR$_Qg-fcpq9oAQ)p(3jR$9->\f<@pZX@CZ`gKgB6#)kj[2u140XKcC@0TG -%#$U:XUnIk"c.jbJ\/D]:#o8GQTiKmlNNQhI]IXMW^<)\)B(_NU)HirngL98I&Mn3#moIM.lmM1uQpXQG!ntmmFaMV(0_Oc?B2]uS -%4PkN@/`rlC>FlXb0d*+%4XrNH!>%r+aEQ+<:DQ.gTXJ7Zj'a#Lnk'j$!>O];MshaZYQMj%^!K@&6E:.4YYlhuaO\SG*+)(5Ea%q`5A2Hlpg@jRFS`\j4m%.\3/5j7D@9;pR:^cV6a";40j`XV1@R@6(Idc)jH,Lja?> -%3V7HtX!50-V/AIWT5F@Me2)H#]*"]"CMoQkWCAN*+VO`aciu]E\PHucDTS/82l_sl[4JnopRe+IfmpZX?fZaO7cU+'AaWR -%mQa.$LPL1A[9K3,ls]Kf'/tQ:(IYl/eTtf%Om"\ob`i/09%rOH/p&#A>NHmJT"un??e[J/"VTUD!d!Dt*h]`T?DN`?@gsQuYXn-& -%A35L2.foN4X-V[2Wku8Q,r6(uA]:i^WB#"A;k2DK:,"qV*5K957@La[W*8FDE&HO1DNclT)'c$jcZUsYmsKSoN[EqEnU1eZp?d+n -%^*`/e!o(&]MoV#FEX@i'8Y%^YYZ/ -%PBc=-rL0Tj`MIa#W*3*-s4lpo$`OnOD"kKrE;4D-tGS_1YFqoiT&'?V&"N9(,Cj)"n/3EQ"iS-dA,-10?PKV!Y*bmalXih,?e'img.+LLhN# -%kXJB4l#S)n9.[(($!f^20KJDCbUtRd;4o]?aPpX&S0OZmd)i"C?=_Br^75qpb-g*mf0QE(*;K#T!fe*n#4MK.&03e-g5%m#\b%\GjmjT51J.SB]3b0T,5D3]YACm'dl3N*Y;kHp907^6aW+NaBD5>rcogDj9I$=*!Sd16'i;09cee=Css(96XM$\0A6@7l%?@ -%F@^^5GD2J"^bH^LL&]qk*/O8M;/J8OOp*:O04sItA;R&nd&gV50^.n]k@6mC\_ADsQWaR,nWghKNqM<5nXr4+gtX7Q3Eq4cBAXp8 -%aU>/$N$qb7"O99[A&BS`2n@L3g+pc,d$qt&,Kkh[E#n6\rY,r&-pH%iVC3cK:GIB:a?/#0$fn*eUD2X'gh]%sA,=T2k -%p.B!s[5r"d94ml1AS%F*YSY7i@Qjk?Wkc/.;@m>GLuJ,204VHXZK/p5QE-%AZLT!iVFEqJ[d[GU]Hr[kcY&e#Wp=,r!gjSfVg80F -%S%H>_'FRHhWC`\q=-[WQmqPQm?I@nYK;fC7p#"=5KXrN'UgRW3k2W,l'VA)M3.u"PbPP5rQg7De] -%PN*5k#_dA-&aDe_\E\2f]+')h?M8K[oa=paZnJAWANZ`>oChj"_:4T)iaUG4*)"pM91N9ZC#3VS?>q-slhA+SS7EX?OFj(4WY4/j -%f,)ecZj%L)b4/Nd$Q=iIlHuQjpU0)KpIghsG!HhoQjSf,nImab;q\;=o%lYP>-F[6jFZXng6ZO<]?e?M1$S+.HCm/l^;OpjK#3#nZ_'7e\oQ17Da,[cGMW2BU-1P[<+S[6>?b,)Gf&hE# -%VXLH^!h!SQh<\(8JR^iQ+mMsgK8L)T/O)K1.Pf6"o).Jb<.XLpJ">PBCnKP9@3`G\a1ae>+_;`>s4h%=j4)o?G(k4*ph]-\e`73K -%?m=F?aW)^mY52]@2n'D_USb*kNLf-&6if3qgH8dILnhECM!B<"H,d2^4$dPuU(@O[Rh_ii%^@JR"U[EaJP[?n[qA4'GlKb1#O1_M -%\)9\N;=FS&mK\3%ieaE8^b5rM6jqA[nHFlKZ?bT0o?6!(W\&(uLsGNP<+=IFLTl/NG/sPb.$]@N:#%:PM0@As\WR\UUJRJcGkP+W -%hSE-0M@`%#Y&&NrOso91`X4Xd)7^j,YMIKB1O,hjCY2Js3QUoY5%;AIB$4:*lBs)b/7!(Tj$5HLTbTl7gaOTFg.re<:e@0Lf\6=O -%Y=X!*muaddh1tN3pbg2FS1)*PG8N-Qn$#lB:HtYMq^<*\3c>C!Of;[$T -%G2ZQJ(J"5Jci#TdboIX*jO+QI;gH/mr6V(;!+p;!OSQoIJC+/5bd2u?DD"JL)K@ZfVC-Z.K..LKYAl:!(DsY`L!2O9b5l'XJN[64 -%MW48Sl'*b`o3T=uQnCdKB11W1Pf(;o]dZmO3^kn5HS\^,QT`pS[7Q,e`SC@<'/L[r_aW;@gV*Aq?l)mPf?b5(*j;m%j[66\6=Jp:3ej?epjK8a[ah=\8g5qVYi"Ta0sP`=fm0K@R<#`T)4'\:?B&jFDC4C#@$P5].k8W>k2d((;2*[1Du4F<;#WadD7nD/ -%dH0El1b2>[=DfA9TTWa-r:`rSRKT;P1Q:l=1&[1.CF%a[(*cPG5uNu#b6u1C!gW&[Y^S?(caBF<*5R$Pc=rqRC7I4ZMUO&"W4r_E -%eh"=r]i_:ICQs_k^Q40f*HDRii\1V.e)WZ[;66k`2BlG2^1/.6IhVdoV\jLF\ViJ!FRP>J;(SrK28>Y@";Tg(hti&%6nWG.$<*8C -%[N>;s([VXL@=pXq)h^O]>r2#2B$GIr@n]MAOnTcY1C"ct2*F'Pal&4=E3KXjKh0Yt09GAp69#t\P3P)RkTr;O_TT"R@]?EQU=(L5 -%eone1S=:A6,6ES%]sHK_2Ie@$71`&#B"uYh1FHC9Ln7W;%EjVF#p&'Dn7]K7*8!p#DKJKYQG\94YK@pDlEC_F"B8q4rQ>("(ZhZI -%9?bMNE&)UOPC&^chC_,-GFnLD!7Pc%)96=YCJ5AU:64BJ[n^b"%hKIM6,s)T`JprLP7f[858!Vu"eh=>r+#_i7+bMTX_%;DL.FEc(!ldS5H@,+g,%>,ShH>%* -%CEs;mF75PY\Z<$A1=o#aXIJ6k/bT.EP5nPs5%JO-KI'FF03,tiPsP:)ZCpX]4M.qooStFGh.I>6=48^dWh3`j.[V.u>?A1FZ,pQd -%7%cW2Q_qFOmLEqTQfRdFW$U^d#V0qhY:8%>$9,dMW*JAF`c3Y.Y6@5p)P.)UXr=D=1*u%S[tN](@u&GE,@g8 -%-bh)`/>]Bp>tS18LggQ;M+45bMR%I'(c*sc7GRX.egh_eC')u+6F,>YiX/bi;#*g"!B7'MpB#mY`j,0pW[\h5(C21K5cut"k"I7P -%VtkI3e^'jYh;(i/TPW<;p5iRZdaIlF8I>_X9>I-A"cuAtm;J4JQUA&F"0$a6aG@`oA[;s%G\QBt*/#>W[MApRG/& -%[hk>t'[aiSC2::a%E9"6Sg&`?U.+.*1r(Xs1K0/Hnn'M%2DCHdb6.ZMnf^Bt[j7.'=c7Hp'Wh8!_dl&_C:i@X`d$f7D;fmUUn$^;1'Y2J#@"aJNgU]!f%W$#$->*liDgC9KKkeW*#AEkCI?EerD%QqV -%6-6p?FN'!5Z_iFLHD,a"^Oo0ETZti4I5CGU/l76ZXr>)^+];Z_La-3H(W+8%BD-/TmW#H/,4WpBBZP,r.+GCMncSgUd[ul&1kd^k -%?kiD(g';D)V?Ml6m/_b;N80Z+#aJGYpk-+R`m$^eM]HA(9kAY04adTIAHacjKei1j]pr8D4.X8@0lE$&Q+OD)'?)e)`C"CBpSRiJ(Jj>;V.pe:@F_.E@A9Stbi/)Om1FB*gkFsrl#)G99LPR_9@-pRKLpC)g!^n*t5ac@lFk^JD -%_B[Gu0WHc--)YpiQ*Nhafk)6onO!p%Kp\rI@IDOKh97[>?4E8"SRqm'1OR>!LQo/IOCa_>;:)rW01$9o3L[B@M-73',[\[tal/X2M:.+SVN3$Jbc9*p&P!]Ni'^EMcH%E=$cd#,N2$[/N7'm=G^s472'fjVt(4M -%^7RLhc^^+Ef&Os2a:]kl/FY[CVl)ZXgMe'.a`cV21i%$NaJO];M(7SOddLE@Pr`+q6N#V++l3je]X8N4-n/+Cr7ZP?`se[1(>R@h -%S@NG=aXZ0l&dL(2jgM!@=)QEhEqbePA((2?C2EbFm7Rdt@FkuX^"tu?6h[jS]'2003mNn\/D62JRS?jZO<>U`"65'HB8\\mZ4(s_f?<)FHW+'/]\_r/8# -%RKD`=n%`c*roJHaH0(sYS*W2L192Yn@f`(Q3O!mln/'&!Et)jZ$Yf[/`MA;t7LI8]5pR*U/*B_:9i -%cuO@Aq1c#t3Rhq&oFq"0d>pR(?umkPDPo4km7,\dmLY0B1^c=6UI06#2[XPPGM\iUgLN^beoW-]`JPnbfYk*qhsGfF\kp-2BCZck -%jXeOAS8Q"bP[(Q0n)AL\52?-bW;[.3&3#IZ>=33cXjD8A:gWbpbfm^iM0,61rF,mt!MEopuk?Yf>K6gl? -%(q2W0R.TjL$f\F9>W5W)oiUcfm0Sm7booK]j=[<3D=.=J-_f1b4?^(2-"#L1)f#OLh,UqJ9V864K0._s0J;Ki=sUIkT:ZaV:>p3[ -%n=ZI/oj&M"j/J&1`3pthCQE-f[ntEg2o)GcpK@?=OnZ(cI7ZT&;KC'CgD66#'W9,+Wr&A,Y;'o$7A_iiGmFXfp7)cm)Z*[Pt7=gZ#paiA_5j=D4p]TQ`gY8nGkqZKiFedmL3!F*&3Sef9`^!c!i`< -%KLk.#fq22Npcg@`]/XKJlP6=dl#09R(R&VhD@.;k4`3M\ooCge`$nGkC:jS4(F^q(#NXYI9^2?VGs<3#ogO'13S27":R0"(jXhL`UAL.dI-RE.e4e.2o"4>e'Doi0%S6FSk:h@" -%O."K#CdT"WI8!`3;s`l0P$QH],A6[p2EA.;@,u_$aY"Fc_i8 -%,7Q?'>D^8A!.Q=[Z?0g4Cth&HCL4Qd4#NP5S/h5.muPb:\0ORScPg>P*#qi)EE&*:MAYMG,oVX-YeL^k\6TGS,GfpI>#r26Km)ee -%92u,DGK^Z5/HL*[ZHQ;%n972h@>XKFma^$3W@)-^$=^9oG@"H;4*Q^FDYDg.[o-+G@G`SHGDNINU+gK,C6*(Q'qE[7Dl]nBnVQr3 -%5_:M',\`,)?Tjj"#LG6q4(r@06GU#m/DZPRWb'R(U4dqSJT\-Ibr9YBn2nkt25K'! -%\N9PVis$XYTcC_M[T*%#$/d@^]Kln+\'P'jr]E#r\"UH9g2q<>)9W%WB8IP#O%jDT-WmiCJH:CiOQFWtXb]sd<6^"?eJ6n9ge5;KMQ8k@?)j^P%^HZ`+k8E+)jl7GThh:_T48R8SS[cMdQ4K8(ZP6o)#9Xh0EK/%_2(9=UN^?Hl8lJ6du264kL -%3`d-<<['a`58004Bc`qQ`e-]0?nl)*`ia:(M=N@#WUBskj;S?VrARrP)F-I:-\]1gW0h_agaqK5`]5:E?JDb"3u;9]bb`q$U6'*] -%e9L($IZ$oYmD."M*%qmfmtsn!@I.^?[qd'b^6d!SXfcdBIn\5gHTkCu:';&5'V%7Rac:%;VuF8-"?^-_D:mZoU97[c`$T5MSO>Ep+7GDp3.X=5R9M\3BC/)b?.\M#SK>jk7A -%e#=pAs8"QZrDH)?Nj\W<0=!pZ.F8tNGld%-WS/JX7n_:a;8?%P"hbuqr]U`Nf!="EAV$9j$H*W8u8m:ss -%;5Pj7oKFf*NEH!1&?>O\].lO%p>C6`f#O!Ib*,K4Uf2&+';h6afD`_X:e6PUi4fT;sOijLm_W8*>&G'Q1+Ql=7p_T!-2*r?mf-F$bUnPY`7[KP!@\)'LA -%cE;<,%T[6M\K_;f.J/F9V:$&Y!7Ck/6SKT_X^ZVjbK]'cIN]IKAc@oA=ti4&:jYikp3XAD*U\5TCKp1()PG.-+Vm]e3='i@U^f9X -%dR!*Ih_Sd*gD&X:)mnht>s=@Zb.G6&eY4,3*'`eG6s"%eZPF*TE;,,ch#QXt-[jAClc&<&7-CDoV9VqLI"sqgr$b_gX5;j2gsO(\Xp&F=EFO! -%@8q0UIb1c-MS$PD[4luO&$U16b.OJ?64X(o\,qFI5j?[hFa#LnlA@pdN=`9O]tnB/o]_'pBW`Rk^_MS&^-@PkJSYF47lMOs-`:U3 -%.UK4['o9J8np,$t4@<6%-A<%#gQL:Bm@JuI)(>o.Cf%4b+tp^eKZ$QoQn4:6n0"4@>l= -%oj/XG*U@::SbL^1Gjj37ZgaBpK:3/\7ha)d5PJ)8>OTIf2Esjj%t/[%OL[e=@.j#XpL^Rg%YQRYf\)B`f5ck2\2)X`D91$fDteCJ -%"`M.bnX*bqgE61GU:NfuJY&W$R[r?pjQnKP)oM&\WVSKa7ON[9WKENF)`GL.L/U6]PaG)Z?$./'.tOc:h8j&@hAiMt`q0/cX4c6t -%lb7[GQ['m5qB]4jk("kaIK`3GhHHP=`)SJ'@d*lgbsY^UOrFV!L9*3._"WHNs8ZrluHNd1q3h/\+@,eD_$1k)EU#l -%l9f1;jP7uC*SJrp_f]7Sp;u\JS$H8MVgT&^*oDp^IZ#aOaMm/1LE6S'AnAVF -%m_Km"UA!D@PNX7$!$-4*34#e(YDBC9g(:7lFX8^5rPis"2>32iO[!LprPcp[>rmKlTL+fT/CAgH6d%b7`/GRsG++7s`q)gF_"IPE -%*1Ghu);K5q/'*T6'LqoMU;%N,dB\;iUjmD]P9B; -%1Su>)lkt<\Rh4T)-`HPh10%aA2=eJ.D,ZI]r(^aZ%_)RdQ:>-ioQ%qe>\`b1#!`[U^;qjqh\A$3)X"\b&'EHq[T9I*o1]b\J\/6T -%pAPKaY`s;mek9uGb@\5j+CH%31!?\a$t1SO+o1:Ado(cO18&!S'"qDR"3EkHo1BV'/O:CHoPr`l=Q;GKqcb\a[a-6n-hS)%/$KUgS]f9tW@nJQUrJ0`ZkV+fe1k];/Z2iq?k`=!N'SqWuAJt`f1L0/S!!AphEZ1m'`Y#]dJgsJB3cL->cpa8<3=MJWpieF?N0b[lL\BQ+#c5C+8,Qilio%kZ^37g?`g7p+09crP8N;91r5Y -%b\S&P]#I@jU26BYG*>n445bnGgaS"Q_?DM:?HTsFlkZ9NF.Kn>lUjX?*sNPc4@sUq!=9 -%(1uH*eOe];%Xj73>K$W*`C6AG".P\JI_sI,COu8fE5t/)&"83sCn[T\[f1p`\Q,q>L#k8-E4GL$jQa45JI,l;fIWj'2K).t"X\B@ -%4?G$(Wq=mkDG&?^cB'+9JRp_:5k#M_^Sq,0V7`!JnO)H_>8?r=.;4M0`7<-Q$>7o?%AtS8aL5I$HS/hAT#Jb:%4c6 -%YHZ:k<^7e;\o-E>W:_KY[Zl&YBD!5,>>Ff;4P5%:;2%G+o3D>ZX>YoufjltO[IiI8LU>`"(CiG!/;Z]8nuR3i5`#nD'HQl_u0,>**?/6c94S?#NL,l0n&fEqH`2U,$TM0Wi;GF3DJV8k_'jB0g+k()/a&(^TGj5G3b/(DS3>+XW)S+hSUWphPJ3lgZcJOG[qr?9?Wu5t-N -%a^kXJYf#FrZ,nDGGB*6oIk$4#c4ZngmYe$YZ9g,!+>Eo>Q)D66RtanEno;$`Q`X`FiBG&e'-N=[df<;$kYVjD46^\%a\aK"=,0l9,6Vo18beia`BPb=E@,*nqls37cGoKu+orkSE]hM%:*@c#/O%jqZFVTm`3F=+A%RLg/9NXQ+;J:A#AJ.Gcs_ -%`hLgdh=XJ7FC2Qn4*QIpSQ>bD0]ni-jSuCamWY=IbuTfsd[Ro5/J]j]CV -%IRbqo\a1Xi_'N,84dUI>eJnOkef.?=)B&)X<4f4S6,K#"doCX]EX%2lX#Gf+$`6/jQB!;GM5[F2dr[+XDaBdaG8S -%e3.HC2\pK@Jl*.uFZYX7oOBAZ56V:d$Im-Mei1;5tdh@W!:ncldCKRQcom#j!?U`inLk4QDO@(e.tW7HYrE9;2)c/C3<@L'L:mG7L?->,Eo/;+@;&I(]N%4-hZ9,_NOI5;^:I/PY[C0\[D0?H;!&sp\?eu42VKq8K"^'SL[1G24%hs2'1Gl$h5#EUY<0()lgWJJ*<<3l3ugni"B(Z2mg01.JOs)_a4]-GIRe]`f%!.re+ -%U0$LL4uk?'<<:FJduL4nFt;8#U7F4KDmP7&^NF=n0qu:8I:P^GNd0NRb&SnTeICkfd%c71RKL8o"H6,d[Q&p.\du4m<>ElFi,9PL -%4!Om4c'uihj5*e6I]>=:YrHo0c8?2QA\'&p*b):l<#BZ=K"+`tkTP)I[GFrXa5Q3`#,kZ1$88H<6D:9+*QhVB[m2ZZp?7OF><".1 -%g7/"^YhdI2^#/[;3:Z#rk"l'hXL]:E=%i0+h,:NTFR`"JgW_ukhE%CdN1nbd`c(&;12+`.n5h)hRNBB[jMq5dK4ZQLe[ll$SasAA -%A^U]5R"q]N:s@-@649)n9T\6Po(tDKmrq#e,->&lA1j,7X9BfjAW1aFL#1Rc]ZSd1P'[iGZL)4mjM"+pp=2$+DY, -%Ri$]U2][u^V1"8Sm#B8PTAMVY3+k&<=_U@aeP[VpP$'7"lW[*(AsuO-Xe)J$Y\U!l.AWbsLbarthTT4&4H0=@%\PEC@p:=ZN%k5f -%#Q#7di.3n`:[^i[5Wh:g`DT3082&&so<[j8Hp<\:2j/AKQ[5]!8dMMG`>2nGLJ-q3[00BZKH6EWmoq>BDi];K@(^2PB>H6M\cDgG -%YK6%&V&Ji[]DE/)BYV/>#LMc<.bp!Ief)L0VUMc>I4P74[Gu;kcNh_HO?*&.7JTg1[Rr5Q-YH(QE48mt%(Q91`8N;A$/s1#Q`e4&TkJDoMLg(KD->6*?/"!.8<%7Y?M%4#&u6k -%9\\)@"d"udHlmun>?^7!&>uC8(QR.b,C%U=h0e!pqL0JR\%Vp\FQ"bJ[F(Vk57OnGL4-n/K_4!51bn!3;oi$<"=n"LEmP`^#MBJR -%T@h*CBqal-\pK&1(g5:U>%@o(h2'B8!SMo?QCh("[gjCL`VlHTA1c"DWdrV3'3QjOAhG5-l`$HDkHX]A1\s]paD?>SMj_Of'M!:h8>HVKsa`5Ytp+Z&oM1N'N=[[6S'Hg*tJFCd'Ld&f#YIP9*4+mc-^TolY%,C"B'Bmj#7fK&`D0BP'e(S\PF6e@(Z,NCUGN722WpFV(C?6X! -%"HB51p[mrkq?RB0ErtSSH[BGc,PoCn-%aM"nOE0.c\$V+GIlGEB&5^kUX:H3i"gpJAI;/A0e6V1hRq_ENK7p[E;K/s)AMV4hB\Ol -%`V89i&T;37`2Y0eogU-Z(\/@]8ed-sRkE'*J2Y#_"MTcMQG6sEYr_"Dq"$T/H?4L/ek%;l7FJZja]0n9CXWX8(l_"/qnI;m5pc%B -%CXu\=G$+]khX<_=AkYp5\o*=&M@HD-"T4fkFg>k_RX[O3nNG_5;s:Zk/1n!55qLq0UhV@2iR_rNHUVOq+e8KHG>T*fA2YUE"Kb>/ -%mt0p37=kS$g:P9.$A)a;DcPare8=:F!VW>f1pCR$:%4fM(Rn;0,`G@i/ncGXFp`P;9BofPU1JCb!Rhd`_5@P87qRO0:)UiMIOOI1 -%Q$W&AgGB+n6IYFk65IaY6sdZf6$'.(0&CJ2G?/TWllh&U%-:LR2LXc=Hg<*pFn/;8Egt3herFqD&CUs!QB25Ed/p8G<>cJm;M_&@ -%l%&GW_7ngpVD#bOo"Ai&3Vr/K3cE8PltT%HRFtRrAM.b<1Cnm:jCclT0^(bdrReThMg^!L,p0o$F"L[;FcaGh@!r7IoR0uX^(thi -%!A)D!c%6-0i)F-L^Gqt0Rq3fh"E7e8W#>j)gURReZ-S]*iuMec1-++G6ci_MU@pma"MGn`aKCpikN8_+^CR(5D99rsG1J[O-1MH4 -%^r&\h6RS(!H\02^(7u8%SF>XGoqTp$3`/CSO!O,9'H!:1KIq4)JO(59l@k,:2bcl"Q-P28m+7!Q#uuf=bfI.['C?!%HpOG6pO9`% -%Nj2-.6m&JHm:\%c(OHZTVUibuoima+^fX8rqeM&V<+]J%(e=qO=A^-sn^GZ`U6F1ErZ.2e&F\;`oU1kDc7on^pt?Ser*1<@`AgkiruNf"qZ5mX&Frp<%0"'@74*+;kWiH@hLNU:WCs5A$A_iYG'-o)NWVsa#5J%WX6uc$QF_5 -%FDN28B_:'pf!NlYAdqfZdPGD&bJ3qlAn2_1M=e.R4GB-&S<=b2Q=&<&kf),Wo-OPuKJ/$^*m,$0eG%]0Z[uEn5%/h!G5oj+$7@[- -%-$=(W/3JnX%ZqVDY1OXrH8$/*d/_P#_=h3B\oG15[@*EPZ#6%_]?+7Id%/T1I+JVCi+P/].BFbSQQAe#DW/6X?^gAOcG3nqW&Ood -%`d'd9Uq]#FK)5E.j7&Rqol2flQEI'PB2`n@GBYAp$uk]e&2dt!/I/Ukge=Z:RjX^g1U81o%$L'Y6VZ?e":aO)2.(n>mV>X```FoG -%luU)L^K[V^ESG\81r,L]65dB?WYmm>:sl0X7dpA1Y;U?+F%"3R/(@P\\7J"g&_LsVg+S@e@ceQ-7nO0B!7;ra9dJkWg9,Xif)Rs% -%!@WU(@uU]>K/M<7(`N/r.@"#AG'0_ugL@T&$J85rZNV?-\hQii$c4t'0YEm$CQ"_)1S*+>8Z`$4bFS=W%rU_3b`/i!:g2;WBrYrJ -%LOV;,Xa>#b6MW/Fn$:[WG`\?bVtS$c[6ffFHK!bY[1?6j;6;ll$8Vba^G1i,3efOMrPGZlr4/ha6-U0jTZ3/\TYaPpB/p'-#hCf78d;R'i@"4rVUGTD1J;.FNhIiWfZo_7d#!+1"4g7KHs*]gMM@sgXXTWd!&.WX(J>qoaO\@[*E\_ -%2STd.4l@o%l1>g<^f%5#+NMr.']=Zh=2S?TO$CtFs.u$PpXu5*&h'+HT+lb7?=je]-$gT;_m2]lFAJ=l7;J(E4L[:a8sbf/WEc8m?hbsA`X5Ac;g:piCZ5EKB; -%);m*>NO12YRcT`XD<%U\<*W(he/b)5K."\ -%qKuOLYZ+^'eDjY_bI0s>)Rhe?oK1(scba&8&.R'jFtlst#*`&&b%!"o_fN?m2(*3!kZug-%F7$l5[/goM*g7[KWl(.Lqcilc`TMV -%Y2(&Z$Jaq2UZ1)VQ!78CRk':L(W]%cO)H7!;?YKt5SaXfVL[CJ!8h?/!b3C:J2-m/U\j"a>]'Y8:QVK_M`:>>=Ji_tRbWZ1^s>KCq5')b?";'9seJ1eR["$Qa'"iSA(;J="$d] -%4X2a]W].Q#W@Dm>P5nT`X/_q+EbUIJ"70c1K\KLX\a/1No]r]8nj7'ZZ8O@NLr,p2hIUe- -%#l2aeU%LH'UaQAY">D?MdgG35)Xn9*0f94 -%l@.W/2kW6:;;\hOZ#6bZ-$dE`[/1Mh%>WT1fFOApRjrs:bG^s'MDVSLfU6)Lkk"\2"$d1X -%e+#/12(&Ptmromu[&_$/GprpTad7;.>g12u,0X+rOI]J:`dJI\]^[g0IkU3gOOh^U':GB!!9F1uM+45!#:X@@P%$:+a`#c@gmO3A -%;FmBV3o.W5I;>HFeuc4-RAD$HN4`U#+V]2>\!dp5Tl=e5?]d&X^]2L7s7?9f+9%>9qnjNTiV1*>nLsq$huD0o5+2H;YC?5X^\de]^]1/1q3UE6^Nf_ODuS4PIt%@ZqBc)\q1&D+ -%5JR3ZIs_.3s78#EVdJ^Bs8+JLpA_jUq0TaIhgG5\k0&VNo?L63hHfY/WA""b[&%,"?Wb'm[Z6<&q"s4t*m?@Yn,2&AobUOP?GF!S -%;#PlMTt&W%o.RlOhsh%gZN8b!ie(i-/RW`jnM)&goNEkboSaB@[8('(\fhS\h<[[X%++"[4+@U*=T>(+8JF+l%*uc70$rtI?L6/B>1d9\^58%kMlDuESW13DpNh@88"A+n6@fs%iCR/K2E=7hR-*oD0l8#qt=Nc@>&X>!9fsH1)]!bgL)FatS\T,%" -%B,.60AZdGCn650^aZHa\rRfY7bcU*;104b*/^/:T[:AJ8^:&%#/sI^nPF)+,#&+Q^efDE_5Mg6[q[Q(H>cIqcDS('80]VY-?.TR2 -%=#L5pV`A'BWh7$ujdQ;!"[e)(@]i/2*UVLFJqdX<"agH&p[7,4-[$QjHq?d$X-04VI2Q]?Shr`&0-]R;QNk_2S<^mEKS"79%R#7#2K -%3':.!I@5L*tluV6S.-pXknR]Z/2PNWFCc3uQdH'B4\XWRYNq3nQPk -%^n9A-f$'/4ZXqsb$G?NXQ%dVV1]#j3".1QsVH`e`GBRD(-lD9sp6rS\+F>8q5;oQ(%;'^Z*e)=JoRG,$QW;E._QgX^913(>hBkRD -%m+AoGp1"D1m%Xo_cFA$O::8i^S;\DRg_M^/FjVdg]uA-ng$onH2kM^N0"tkGI!N6o39Ki$+7Ags<0&i.RC+C/\27EnMKZTG`pNE. -%1bntnj0Wj51GCiQL_S0#Wo3[W%^53n@c%s;Y:c37(>%GmH!6$E-2XpZD;7&F/Le,R4[Mk9hK-=&,Ru+23dP/Hb_@+UERrNbl")]j -%o$hBD*G8@E^6:Cfi"8q8UCjG$o')GRNOu=7U&C8_:oP!Cf@*75nTC -%)Q029NQ.;(iPt,8^]l$1l^56Ba1Z]]=&3hunGTm%]dg)3Tln>4e&d=c>%QJDIbOr2"E?t^f^KP??k,Z_b=lb.6t$BSfuS/N/8V=E -%,@9Nj0:@9u5J)&u9^X1b#u/79qgt9f%2LB:=33i-B5G"Gs2+SLptH_TNAnXZ2!TYYc/Hb6dc9Dt#IC27H1b*uE96kUYI -%oC0asPe3]%M=mZL2]\EWpeuHs'$&a\ -%>j=-H@_)[(7!?<1OY5J+7.C"-^0V+Q@.rH\"m0B''b@g;#?F:>Q%S4!RDj-SCELoeGmoG'B(S8.\Cldm)BWP[8r)*A8Z=EETPsh: -%Z[/-V.?fLQO=\c/>4oiS*`Cc1qA-]jV4@$\PjkpR-q`P3=,GViot'= -%70RQfo.6Blc,/\%)DK>*\W?lFOZNBCB[)'ISHD,]gl:)lI9r:`=k["1^U3'660k(R\N/MS'bbp_$tmR$Hc)4&#,k0nF",.@T[9R[ -%>HQ&F9gj_J[+"-WQcEk`7X_e!j4tcKlSo,;+QJ_;TAP4ii`90G4S1^WUS!G$R/9fiZ@ILm&cVZb&(J"Toa$hbQi4rWjs66m*ujZV -%0o."oiN$T52$XeV?jtuXDVc4V+hLUc4`RDSWhQ^?'s@Z!DD0(`@:HB1ogK(.,*b_!Xd9lt2?d>:B%\DR;]VB@QL442& -%NrA('?(17`P`6OA27%eWCWe$%7W-(_*5ol",*i^iQkFlj_t00fpYm6:sIXNR8)SkMGb2b -%MEneZgc2'PB%[:_5bHI^H)llMo'm@@@YldD2d;tr(12W:8LiQ%R&HN&SOn+gPC26iT,C-3]o4HKMun9.kN*<;32%.Ph1+hUQ]7i)(Z%9M?O;KBo*),QOXYD3T;"aO#*Cfci1k=Vcr4rAk`W2?P2r8-!I4"unm,?"Nc1Wmc!-Ct^L1WFe_>4$._KgV+F"R,U?cLgsN&g+! -%!9.V;r7tJ4]*:FW&;SY7M(d/Z1l%sC5.'B&C>s.T;DFHs'MhOYlo?G6"Cb\b_VM%bNN8s#4N8%S*T'M=eS4cP_QpZZEcq_>l4B(VLD;&+7iW3[gpq1Zo$)C -%O^8D?E!*Q,@kT+D$eE-ic3V=AT7J5iYamHF^(!,V2m[rm[H^-O*h52#p^S+s&<%)kFQ56!M$&So[Upr/3..(rC[>I3,Q6YGX,6W9 -%LQKM>"E"C>6B;1@bPMG1@/ -%(nL0&p_B#$Y6`.Kkl+M.**!T94VT,K;`Nel>@J25KXkq\E[kDPLWg$%h#5=HhhnW_AmA>si5nP!;"9_B\!iZsToZR> -%oF>5jSD6Hl2b/]ic](AO^m!5d92iF(,.^%Cm;ah]\6"@;@>rs0_WnXuGtmO;6^Z!QC+-1#RgiM5Oc6&u??+lN+j -%\o>e+!Zq:dTX=?sq+K9g9K4HfdY3b=qP>OP7:ohA)>"4G2PV)]%m$T3&Y$-MO4697.e,8@pA&j+Y9$qO[VJ'gLTo\,hP>&=<`0Y* -%NSJE8?()bfgu>dMGr#^CGkdZ,!FOq?[eL7lroXPV?LHil^RRL$O"ZQ$l/?E,q!O2i`,R_]fQeN]WPa2YYkK14alAD-hL1GHom'=t -%DuWT\`T^&V+$YOEl?K0hS:AScnp%/uSA<1oqVb[Dq>_meiPD^Bn3N*6b/(E0n:Hg\BkD7'R'*K1BmN)bn(!PtDFD@tf1";Y9_+UV -%`F$*S]o_.WZZS^SB!.?\9[DMjfouQiQDSot\FCV!l/QsdYk:4#'8H\OiUD+PW")>O_sqq5.Z]AM_ZB[S=MGsD%kbZF>rXk\#9W$> -%F2![?hgRT"[Z<)&YP>UE*Z!%8NL^jFC"8fAp\?mq#TO=?`^;`V&@rjuS7=hV(d&f@X^anF%,[)=hD$E@L6'A?o,*WSL9JWopD=Sd -%"6a7!I14##In0r0U_&RNL1=]P0o9mDGT9X,a#(pQlI/W`NCg#OEg7T#)Jth`m@Cmps*IEfHMpXUpjX1*%eC5SL%;m -%2PIj3%CaWs&qe.Ikr+k4R*'H\`[E`p47qM+gF>OLC08(<;NA$k@GH22!liKO,7K=/P2bR.o04#),C@9Xe(@W.)VnR\/il'M"!__? -%:Le!Sl?LRAiD_jtH3J`^S?i"s8&1(:6eUMi473na_M![1iC=n[6pgjcZ;":X\mK-*WlDn2[hi*_`07i-c8(>itVR[R'A/D`\0L[C:\P?FKZ&;dfJ@i437+"gY=I#6UQ#;Sf2!$5! -%]jd9"T(u$>@8[]-OA!2bm%,=t[80VRf5)o^DI\;/p:/?"3'\X)ef?,g%LT/Gp&p;CJO<%U;bTm_b[n9g7I$'rEs'RlXuU#';MWf\ -%r4c2>2>iJiOc5l9$=hZiFR^)?E2-Za!!/Mj7-@>l!egH,qapJT?9uKg'[45jWp3&dGS-soh=(KKd3g%O;2EIQRk"FWSVsqVik<7b -%n>$*=YW@2[0n'P2qQJcmM:0QE70@c]"i&rS]ZJo;p7&SES@VN#>XH3O"KL0u6?++G_)GM*]t -%Z+6YGW8F9h4rItL+!>2>62[X2cS^7Ai84nMP:]Qg37E.m0/rL\&L2%)^3^Q9Wb,ijE,K1^lOM[Ii3-40o>^Cs5h9,j24A-`S89JoP>2^N1-8St[i*)&G9.ubP3&fuEKlHD7fYU9Q@h18kB;<`/L'qfWAeNNQ+2s0J/1(.B(Qn0P -%JSFt8[Gd>cT0TiVSXIJ=\)j+V2\)K'->N\Wf9V"Kj2]PCt:,r\3bI%UO'Y_l&3##9V!I; -%a5Z9FFSh@U6k7`/Q,FlRLgk0JVN(>KlM;fXH)l-qMsh*:5UF"YK,C^5lcDGr\D^21!%UEU'<;.;[1$,84eI\Kl&ZV`>l,YO'EZ$o -%*aW1o&A:mNYYc'ok?DIQJ1gKqClXsb-+qH^?8,kd2Q'aa#tM094Im05$U!L0(`L#+AhA')qQW>n"4D^Bl&u/2G;nSN$ -%,BGDbYLm'*^HKAe:j2/aj[m8%BaT:,VnMaM[1]-i"b\0iS:6Cq&^C*+H^T+V6F?2AA`C7&1fNLp=`7dENDpc_V,tg'WG#4Z0V*[O:WHI`o\>=@K6#/gQ$*? -%A.Y^J;:\-J`tWJ?E"mA'...VH!OUhpW9,V]iPn;XQ3CO.WHQTmocZ**5/i]JVM,b#XFl=?F[?r/]e(:\l6#6A.YkOl.`82YgO^&! -%N+<<`Vk$5'Eu]C9ok1rr"5PQeN8=XW%ZPPUOZt'Z;,cDDT.p=oQ[)$iBIVX"":V)M/[@rOL\ATXo$B:4fKl73kVQ18SZg]0kiNW' -%@)0NE?7o;2RFciW%SFDd/rf.1lWAtaJ6?oHT\GfQ_q)2TN$;1Jb:Ls5_Z1/?Lp@kTD.]m2,&D.YP;n0O@0!oI10HqoZ0Vl0aAN6K -%&,e)!H'\O&bo=?*jBKJVnOOO`1f!\ZgKL.Tp]QT66L7Tl#79W(qQNu3!Jt%C6f[blgJVW=X&s#s.k*%R'#0QZ(iT'],j)g+hEeqX -%]@\i5m$7lF4UTpIOU/DUP:srMG%PL_?5e)dM66Pr*I1LQ3V[4A(/oW_YZkF@s-c,)dH'`73OR_(p[mZW% -%=WHpa:9-FN:dMKB51G)K>1D@KV9%\iJEqj`@qb+%?dnpcZ'3Dr(ime7R.M*GX+X.INnH_%IM4LUH]$7PkD?p[\\NorNP$fWr)n(3Tn/Xt40,M,p0U=o4rq?ZI\e'lC=lX(=5s,Iu8qanPMbj8I;"F\)Wc/mj]*l=6q6`Nk -%+'6`;URb4GkS%[N)SaZ&(*2s`__,QS@_b40OsO57]B!4(ehD]cJd;+r>97$p5P$4!FF6SPoYfe_[F8^ -%[KVl!j4*!l[LnP5+VmllnE$86#_on3S?=nljI!3q)d&&DbrCuOp%'+)Ui>4ofL`3G13U_#bW$G<*02m2rY?CYWMFu3DQI+s!PJOs -%Zs#T`pGQ3@dVn.N8H!>uZTp>:gjo?(J"'eDkF8U1^6b"K=2-?MFTL?2%M]6/g.QAs"?aV;"Eb8$lAV0]'X]mtdJg)1sP,/D94c'F'K5H=*& -%YGg`i%6q'2'1n3r-IpY^D@cm@j>BZKJ_ZZ-\Qc(@am6#BgDDtEk64p@2poS2UlWkZ=!di.T+#)TdWQr7Bm`;$@M1if7;[*BI?@+j -%4ZA;Nn+?^oe/9^TldE(rEfK[/Vma7g.2js--fD(hq=t@&]7Lr^FHe!bZ>]ut4q7=:DHpZ);Rsf+28i;qZM&NHmPnf0$8F[K1'@Ls:qP6l(>Go_&?VqIC:@BHeEuO:#6U7u^LM1hfI@q[<\YU+6u"i`n[Cr`*]I"Ac,qM;(g4p3&s">H -%9n-NQV+L&R-nLOEYa]!i^8tS4:!'>EsJ(p%lGU'b^QkuE12_IB:u$$L9eF&.gk16ODNC8Fn2]&^NX2=48`'en";X%E3H81:\_qY!c',?';*ES)ufgMQI47. -%JPol\Aeela(UGQoUTYSc+$-$R.;M0rR_2D1[M(-*TYBh"EI%$h6VU8'gt -%q#hpa2JlRE:CFd5]9-jKL.WbLaX'k@;5k&1eJ*6MN!Y^sT>4p[I,-3lQL3W565oG%"e3mt!>/%V:[2-AWe6;cRSno?iiK>+0GbhIL@/(g\ -%NB'6FVAsRb%NmU)6&c-X:5E)%!1.b/S1_Xf`X]d>'$J-LM:CP\PTO7_Q]a_'!t8il@T402&PtbJ\.p/Ap/?kN49j*ZSrj#>KTVPl -%)umk)^/_Aa;h.BWLO`2mJ[)K^e28<9+/o5;%p0O96h$GFIbJ1 -%%$V%:5asocJ^/TpX6-V4anQBmdmGMk#:=<=(O?m5[Yo*Sg1F9&U'q]+kECdCN'"p6]5]pbDX3$u0Yf!SA;Tl[g>W)P/6 -%Zl94J88Q-Oa3c=_KJZ\o^`;[bChiWL3r&RbY"K3q?-< -%GZ>_%_Dru02d3`ufm7\JC,i54pAndZ0V8uim0AO5qPIEk%?$uOnEqZ -%#9G9FB/YH30j4`qe>o[b1Od\%4<\2ZIX?TX=WJFB)D_^P0Q-'/q'3]MH-L[+4/WLF%14GO3Sm/.E4VL5o0%BQ2hlZp!H]K0bc"-6 -%#>YFd4X$PZl92HL[Ms?C$*52>Lap,jX4:#\`n';aatR1ff;^CP%-&TXM[aQg#AQ[[B_HVto=d6iRpo)=SH.nm_dJfdG["$J1%W-6 -%/-p;+]T@AgH]pl1!h%g@gAo&l((p!hFH"Ni[m=3T<+`A!IG'X-hSA?GUa8rC@%tD3Z3.W(QfZB<[(25#q=<4$lJZ\Li -%R8O$Z+SC]qB,'^_2lsF$"ZWN4J9DnfTk,U>5_E[O_F3m\0SquhYPSe&N'6_`B(U$P:Q*)k)[XKS -%a?[JFCp$d6tM/M]L*khV*sGf94n!.NBq=#^mHqRALfg\p[)E.rMO -%!e=WN-n%AK>;TC"d7_c=uWZV]sd?%aKUUCHtqur6oD<0e+e^HJLCr:)(6:'jeLI;7c8C$@k2)K.0>$AUc&!<989b2o1<_2 -%Pe]7\^ED`]N<3)=&#M^jUg-<(1a?u][Ond;E(.I_@;aJgWJJZ*itCQs'fd.T#HS;<("0@)F9`?Z1k<\f#LjX+bW!(GoPt(Tc`HTG -%Jo99kBsNC]g)8_D7/=&NBN;]uQg;sJDlSA>C$5s)`&U*82)_Pmg5`DV_fa-o-h%>EnS&?18qDE6mr)Z'BBZ'MeE9[2f&;%&-CohR -%-BiOQiaca@Ye]J,@VR/pb.SW)%h3Nk`sY`rA`&',#F2b4Z)fDRG2HaGAo+2JGm-*W6M)2\H,lrt:jCKC4@<$aLEN%AhuSYgd5lc7CcLcg-A7em$:`-+ZQ;Q\mXL_un';P!Ot5[sJrEEY@9p^I>mWo_/u -%!ml>"WB,I%Aid)[N!(YFN1@I;%.HkaR7;DD@9JQ\6,KhKB=]c,( -%NE8fac[VoDKmGO\JET]e#+,Zt$GXO)@(8*Rc@i0'CBdM/:^NA;GDIS#U+:_3`^!1b/gK#rhWUDaOAMQ,kEN2Xe(-c9h.EJ/%91I5 -%']:b(pk"H/dR*#ccj?r#BD+%1*RX;KY_04a+CaKTGePKm_c -%'H=>SN8Y`qm,('8noTjI5k!5C/qAX,_8,aS$8CtHK2,ui?sdb_5`g17",JPqDoU?'C#qKC'#2EK&>-U0#NmT@G]mV;ip9r@ql*H\ -%;aXfO`P3PWH,KtIE>ZElo%OSgQ#.3pcs4\D1mG#iO%"&Q=LSVZ4YNk2$SuCJOYuo-D@o^)l]+Z7l6b+p+;+U`SNu+1Etf0,eL[e:f9;k!U=hX<%uq`"e'@aVAWtmO2rg<6i$UGaIO(7R5J`g(2@G&WXB+0lc..G -%jlF_>Y<2ihD9U3HA+_=gKf_U;D&FgHITP%mM-R=CJ$(&D;Ig@KF8F_n[RBsBbVW,V#QIb6FmHe!FQ[c$S4%HW:jF4c!sGFLdD5?4ULP7q&WSK\1q4fRl$6;8hfenE_Q` -%G*GjNOBaliZQ4bT*_"rr!c]S:\[1SV=eP12AbRU"GEg01M!7&.mlcL!*T[,>V#QH1JO`#B#P#Wo:>o'sn3R!A.$St><.'d7I$/5, -%ME2d^+E8ih%q;b5iRj@2 -%lrf;@-sV+b\:'IV4\FlY7_qSHY2)1k*?j5+un%0C$%%-@TEBI*d7OH5npg -%&,_Q6U<.tIo"\OVi45?q0dlD5O_&UpiuGTk8"S%h&bNj[3YRJ_N2-^PdZNd9j?u0#ViG#_,:i)2_0$rK*Ece]%'gQ"m)VeG@'Deu -%h2].X'8Q"s[lZD;*a!e;_V^InprFXA0Fj_bM'jA)RIYU`7NQi>OdU@;-,E.V.eL5$/rV/)k`Ib!1UZk+JU1k-*dOlK*7uKCp;!bX -%@,[[_]16K%!t4mT1&T$CIc)A6E0a;\js(91aHo(GWukHr%ufm#\,/Pq5;L5SeFEh[qN8%3jL.;Bi/aE(1V*M'_gg\4+5-T?-%N=: -%^enIs6&XYe\)`NPP&'?RR'q(iRb`ag,6,Vi`G4VYkF&^OIkj:KJo,M:g%XL@#g->l`TqgVoK0%CWalo[KoUq7U71VP` -%nt9TR4Gi@Q#%h@*pl8@Zq>e'[)td4`W!IH@Y`fc6D"1rI,d.70\SOPb6ePb/]+1>04DI8IkXce[ViE6,#f4\;?)h-AEhW.P'nm03)61=A9)tU/*Gu39YWcK5(4Ls+jig)d -%@;+iue#/k?(B5baSf,u<*O327at"dDe''cceOOZ-bkY.?6-/N/'fEQ6?ac\*3;+u%>;]S_h:.82=(G4$7]%KU./B:B\_Y!JWRtF- -%.U\l@;@_Y#l>NoRUsXgrr;e8-24,5M:;^F4::=,5]ErU`MPk7jaN&WS[:fqE[\-7L^l3r"TIDTMS$k-B@&e2N)T$*eG>od#8t;st -%W"s5:XAud[#f0fjb0F4H<&`sUHgRTQ\-!bG%95P0RFqqp!]NlO]68@43Wua.)3kojTG156A25iC8Sdoq:h91Jj\+jZ0piL5?H1hl -%WrSkHLE$]Tig7uoR+:)s3878SSViFS;F]UL9NCSgX-'[g+',?I#Bhs8HV>_QIoRZ^$Bh']2`WM@Ir7]#O:V3.^KiZ1aI)Tq`MnO899:K`Cu -%QKRqTHHth6Q[Dqef.]!=Qn(qmS0RiVD2t"8q"SP_)IIus]V"=9VheuoS!l]j_CLFo;!7.''"DC:`.;IhoRe-HQSI)X6+Io8ABPGm -%.<#$fq?kSNP9-4E7,"nUEWHpQI8t>k]DF,CdattHM-:XLoZNWQigedp`C7/t('mD4E\W91TYpC:M;oaJ]No,'Hkuc&B')Zo"D45d -%8H9G\2DuA^.IDDLRkE*bcTPRCpW%I(Si]FDTe^tp4FO8)juSa)pB.$lgJWA`EnT`[n$/:-^:9"RH8/_bpM9ol?mNh%Z2]_3%E)>u -%(!tL3`CU[_n%C'bpNl58`FbFIBaP4APm&4H8b`s#-R`-ZmOA4F%1a5EOaq-6'8l=nI&-L>\UtWE,>::*II*%L*]7S,P -%#ROA5ajI(I,cPisQ)tqsnJ(g$q3p9m-%W3g9Xof*e0Gn5#MB*XU"n:qOBmAcM2EAg$Y@pj)mEBB#c*0cVFV])9t:9\.l?,hX_$=Z -%[19&3V6Yn>NuULY_usD8_J/HNnYj;=b9!+ -%/]DC8.Lt1?'MH!tRb'fF)&TOBlWUD`X_%k?CR7Y#F/mSp5!g==I3jm+JbNYUr>G7^"#Ob)p&Jf3b'P%CT]>qC]j,fW)*@oVba,VY -%LsPYJE(\@I9fM^'N?;W(^-3l/776\pmcUi9YT76h)NaEighm&G[#\*"b -%(Vf"C]0t>""&bAcE*.hHTL,q_XeX`'TXgJo

bT6=p=9(^$%Lnd\@Z9i<\6P'MaP!q)?k1c':T<:Y5(lW2'K4mH9(&2q(uV7Qm< -%5l-pHTHW/A#&&R!ksU7&:\?'U!&gnP)>nd*^J[%sO;d3tY7I'JG683K8>dPl!2JYDXh]e6$EN/g()Ll9EHcdmihFiZO'pO,VP&*LVD;c'Eq]%';R$Z[^;G#ZpI7B,%'I`T@YQ/ZTq -%d%rQ!;o@ER@P!'3(ccc0b_9UpMOA!&Vp'SL,%MJATnYqdMR6ILnf8M9O8"q-1;Ja:EPps,.l.R'D0SqI-k-PTk@'J7%O:!@'3>OF -%QR>H^8[R2IbXgs]6EU;Xj^]/E%N7STi[?ArDQs7,@GoXnEgopEZ:%k?:;P-`huP&7`heO\IS)8,[&Crfp8n/2M%Ln@.P!`r\Ps(! -%P5K2,D8\sP].,I5&hKM63JSB2k[maPrk/QGBapP#V9^$b.\T"n<=q%:K"fg,aGif:m@Z/QX=iO"mf\X&uooMl3Ohg-);%<<^YTh';Ugf.qF(_ -%,'QIB!f&cu:%XP6FXIGd'.nZ-e;=\m9I,O+V)rN8ZX_eqJ@.fLflT)!=3_/0_>QN!H7hjAdgm3YH7Y=_)pKU9!3`mXrg7?Z^H+V@ -%XiX$"L^4EN&I%)r?`;o@)V^FXWZZbV* -%BD%qmST8D6,E:ilh@=ar1G-Ze/CNN&jIc]5H#SEFcfH6[$j1f7KgP_nkTQg1,b]#YpIt]R^-*[P&8\b_]3g- -%4fnbiRqYq]R0A)aIiWTAa/mu^#4@ST46H2WF+D;YiBq5IR"`32]Hb$;Tj0mN2Z`feK[[:jXBK'p3.<>S6n"G?kh2upU:Q+E.HFaf -%-f4"p^f#uDR8LB$9Bs&OX[psLCTCD1M^:G/!WL6n`L>j&BBe\p>_3Andk]f?gC(Ds(n#.qUBHAp16BOmjYH]]DL?5Q>o#J->7VCQDi*eooGgbN#)6ZJ5#YW(`fPL'1c_nY -%eG4f\b(DTD6p"QYO!do?$02to*)<#t1dPP),I(9u/]uq\Mqi.;0%='Gc+-G_Prjk)F9B(&`PIg,$8#U7]N]Q4 -%O-#[uYeGF<6lhR9&_0mcJ&,nHk14F#KRS:">`o9G`ueP(<&Cr`F@fp[&3=/ecgqON43)e@h<56b]_X>tIpM7J>SNZU?\)"piRcla -%QA[Odl_/KgpXG@;l+7.>cR/atIPY$(p'rdMlRau1F3A$-m0^,2oEjnAb;A4[ocbj2FRqdE@$$TI?']il$^;*.bW%RId)g&n$^u!; -%[7f,70Pa/;"T3.g)KX;3cWo,$"sf(P1q\3_KT[ie/Nq1t6nhXnYr24:\QeTnT"EeZ<@IDPCSpgP=Yh984>nZI(RPNB1c)2)GtAk$ -%N5Qa*lm\0G.n-%/P@p&X%QrcQLpWn&C!rDT2>uiU]J.&W/L,3;YrRE[tm3D\W6-"P1!KpE*C^ub-1o(YnW+lp!T28AuJ5q`P?oY?nRTn32 -%Q`rJDelaQ11&TOcEjn-73<_H`30k-5@/ts?9,NQRCC+7F@<95jpE.Sqk0Tak -%T*jRP1o9\W6Yr32ZPb%r&HPD*77d*.AKZ?^aUW27gef9Q*2/"L+r,R4f*LF"'E+!ALC]=*j3-Ha4"eLE(@=%5 -%g'MaQqfAa^Z#^3+,D+cXT=rU2pFNHO+S`&ScinMi>+^gbH-Q`oD=Ua7^G^oAV?>FuH2?Q[&h -%-d]^T^-V\X(>5f0:!Kb#`ak00IYW1ITmi4n8DIV56k.he''_KOWUBWlS0/G_!!PV5@U32`"#7RBo"41iRO1B2AJk9`d`!&]gs[2oNkM+W_.)QK8?N?))WtCiQq+]6)*/,pJ6F1M'3L.9=5jOQ)TV-@"QpW -%mW'<#8M7i5jJ7tV13;GMYkjVYs03niX<.;e2#5n*oC:qiWB.UtLX#JC2W!I0rHUL)_#X]=93]0;.A^a]o=/ta&>8J))TR6S,8>o@ -%eKbub)(?9X<7sKZE#oPCo5X^(i-q0WGGk@kjoqDDD5#?kWA2J7e4g9j[]L%2/X'lP!(-^o416:iG"+1>Z/'uAKSg*B#3Z-]GkNCB -%!t?`BG2J:@I4MV*n7g)E%^%.^!LR_BLk0?NU\ba,4N&A_B]UhOH(Sg2:2'>`a,P`K](riMCbfM\YuO/SpiL?Ng(ANk$r7,kc5:(X -%_e\mD1$=LQqi:$mTFQ>JV?\Vlo*PA;,L]^?JC3ganAgd2hTrDPI*DaR#ADfP,n;'#NJgLhE>X/0MV.==SYaH(h&D1^ojBgi3 -%V$_4Q>_Eq[tQG2#k7$"M^?+Q -%"YV[,Y&&cKXM;M&O^AHLZYBcB3auAED)J!5F\,tgG_3A[PX_@Yg0u]\b=$92GQltU\Vt=j!LIn&Hu3k5\U`D`3[@>FbY=^gaH@DWdh/:1?JMqK+Q"2#grR4EKY)$oi:%)ardqM;^H -%i3ON1gkVQf+oHWoeW*2[Xu6^&&IV3)^9f'CW-i:\+$ch3@J0qI?6*l3d!1>1&Zq&T.WP-C%%t\4OSdIDjFVQ'!g#C*sY?`RA3J:L] -%".4Lb#,@_tCHnNI3\%*;\b4Fi83*IX?[)rUj0AE7DJ%An&\G(]"3+M9Sp>nZWGn":oh\'._oKJ=%jp9M3o]g'Bu3EIX!2/m_&BU4!H"6&=p'p<6<6Q-3Q?;&R@\Ph30PO?`6 -%%ln?YB]a7i1"9^BZ+$96J9c4s7ITe/.!4LWA%t7FiAlZCOsf:U@5WYUu-mYsmVAoV!rI-PtD_/J@Vj -%bp\)7s'tM'Qg6]8F3uA^45c1#S/d1LHhWKar35EFQ!O$Y,0/H;?+X&I#['\(5QOI"b1#f#QZ(*)[<`IP-&IiHWcO?*$r6H[H]Q?/ -%^7i3'dK!ECi"LYTLh\sh+02!mRVY&b6"J0r-Y']WKN.8:R)c$Q>]'f]P7T3t;AZX9;9Lc"R^&>K6o.1VE-YEH/V1KIXor+4&\'EA -%WhC%gD/uHU-8_V'Xbb4-7DMKrYtIEslQoeKA[*0'\a"a.[@/Q'-e"'U]a[r1<";+J<3!tPp/GG.bjl'JG+C/d\r+ILb,"Z5k*NCn -%<9RnGMU9k'2Wm[Oq[3@j;Ml5h9qbU]m4HHpOVjn8C4#P[7:F885``rg@BCkp]f4RNm=$@&Y71LCc@XC`fW8IKSh"d/$>Q\Z8rca) -%oP,,qF0ZUOlDgkmSg8ga\aH,E-)BcIICE3*HVZa[b3>N6ll^,`@gdo4V:\A;K-ariD!&C'Cp#J4Wp"3.:olD\1SiIG -%.SC>+?K,MNe)%8,\HE*OE6H$T_UU4aGZ?`<:sDrF<`0$e[e82*CI?dUSZSl\X#uSj:/k;u2L0Qoa,X_2 -%A^2hAO0WjaZ[`oe!;KQYqc+"Rj.n[aN(GKS&1Fi`)oT6gRK7l=\dE@`;2gi%rDJh&WEH&?.Gh*+Ca$#uW(_gK^ls[0@'>.bd:bQ$ -%$3VkJ:e#3VeM+J6cn`'\FfoBoW.Ueh]WkML=t36+-&l?&k$3ZA*_F6/'YBctQ"_kbYeQ;jYiT03l'4lID7(fBbBH682bpMV*:"[. -%Q$YO2`t"6=X/Oc&;+IK!'THX<<^+I#72`QS_>h:ejn$"f!TLZLN)3&cf"20'(Vkf?#u7\`QP-QATH6r$OI_jYcte'ukZksmcBW4! -%/":^jCZ#O)0>'+4G&Is^mbg7;pQ^Wd2b#FjU5nu*]8@R?9)LplZ;O@ZAX$U_AI9K^=HI?p*b9q^(QF)?5=-D.hr(mp@,!'l/LeCIkk@6H_5/n6.4:g*[(D;2D@$NK'pZ"r(Z"A7mF2BL<-7'tUdR2;=52D3aU-9Fa"WO^"NL)q*1EM?.n#4]9#VD>ieXLP8EdQUr\u6^*)]B=fI'0WPs\0e(&#fo;N(2%Bk/,!WFG4<=kt:7DF+%ZHV(1VI/dbHQg70`:\HsOrNeB:+MDc]Dl^\9BJ6T_I@]oZAXK5[Z(sLct.*/38R=(ih[4Et2 -%/@QgO_iSNQX#&<&mcI#cV;D@d;mfGLi;3BMVMu>(foH^mQfYJ.?*E\=tcpL*YB;[L*Ygo4jSP85"tPg<+F^ -%pU7a?9hE=bP&8NMCr,`kn[+(SkN:B6KG;bP%C6drZ9@q#gP1\ -%mT#O4V?p+VE67l$L#4Q_*otOOP,kqjAWujlE/.tO:.:(7893Wt:9[InJ"s8L1XJb##rI6%HVUNX]O'"2FtCO]@'O7s!"Hc[L3`u5 -%pSuh:Mb8g;>X:0J0kJ-]6ke675QbsZ7(^M'k>h1?NIs-%'WU%2)\Ahn,#[*>[lX!#-'ihlngFl,DBo0%e>:g5I7BJ'%"i9&gotG<(kRcTu)GRnp1$q3q;=KR?j%&oJ^6p>5clC1^`0?*\sJMc(VkROuJDV7`ldON\^`%"hlM.CJ$T[M(#Y1b)(t -%H!UTIDiBklFA2A+FU(U"#_Bte>]`Nn679\u9u>EV&icP?81;Ni(u1_Y/Q$5i9Qi3OO@51L:A+g_.FC^4"KHNE`)qC0``1$H%ishXrIq8RgfR9 -%^rmmdhLc)^cIK9OZ)q-a$ar[^C_:@2.-BX?iB+[(B&6SN06c]>YfJirj/\)>"2Q/i.KYZ@D@84&j+h$II]4K:&qPhdRqfb#%r`sV -%gu$IMjA=e'/*Q_LT8H;s@.`bck*L?=^slFB_2>?Gcj-:A&Z^tV/g)rP_'2hJ_XXR9UOAOEZhiE1biL?-JF`24"9VCNCZi(\P-GiG_jSWCl!h/WmhL-:An -%,k#'Hpd;Bp[MD/R_4*bkJS8#lFY;Xiki&7nRhD8E1l29/VcC-?77A.DF"<.*MNTqq-O6[7Gg^qg(_F3<]T>,I#c08qF0%-<%9^>u -%Hs\DZ@+EW^#b01LNg$1oQmh*=*7$iTO8TSd!\9'.p"qI`*FN&S2hs(!d3($`PX44439,8knP]q*?6(5s,h0%M`t5'-ELohnTb_>EHb*UL/aHR3AG>%tF1G\(q$e#07G&MRThHglLf7::_MR*(Q@*ADr^.TE*%!XZG#A%3lleC'6?_706QD>ccD,gRMF: -%VJoVW')oNLTi$]O5LCMtL%jYrpq[mY',Tj80C__,bLROP0<9P,b[9;Ia!\`=FNL'7#+13&->cbI"]Ae:SO+k%nUp?f(SGA\-,bAa -%d7Q5hZg(Pt(,#onN?CD6Wh69?bkm:']6Q.Ng^-hLjZ679[umMn=&q,G?T]AR1dYFn5:+QAAsM60"JSjn1*T[Aclpf+d(g^(.%<]/ -%5/^+2K^#i6@cTPQ'$&2(M+K"W<-J7hM3lW0%tIT@f]/C/,SPsSQG(]l6T/5VY,`Kr#n0/t,@73'1TO(n:JECL?i_pZ+?8Rh%9IS( -%dB)5?1*ge:%&%7[1Td8R(/QNGFu1&O`pQLD?1Qr,Krn$s[UZY0-GljSq@6'?%/PrjaF'G2rW/he]gT7FSO1SP5Hi)=bc+5;MCF!,X3ah#.R]^n*YXE2u4>9-@-:;LGJjJ>qLK<*/X[::hSg6Bn0G;dW:bmJ6<#=qa -%BL^$Ga\N+^OWB`Q"@]qF'W48QALEiJ^oYD1%a-70`t`Hd2+ -%Yua=?7WI+7;mAtO@9OT)g\atXTF3/Y-Kt.+..J.i''V7Xap^Qn"8L+J<+cBcZO[%>!=Q$fMFRB9'rY#2ZC8mk&=Zo%^/cn"!0eh[ -%22RirJSru;K0]l-1]C-bH8N.A\Q.loC('`Ll<&^t,QWNW+W$#hb%f./)Q,g=ag3mZ!k;c8`>L4'@XZ2R"2*fM0JJS1=@B96aBV=H -%MjU:U0L8348@l2U/`]kHPdBG4DW#YO@'$KG=]5E#Z^27t$:Cf!9:W8"+jF`VjL,fU_1M35Un!aFGE-^u:3a41EWh:3"BSTtB=LTu_!.8.IKF/$dp'#EV*fF*?L_$CR.;4JfnkeH -%7(<>Ua<[hV9Fjp"3f5C^mW3g&'VN,:f'<-qE7WojFS-B.I]WAVb_2Z]0fD3"L<;[jC5'^"c5A4m'uUCf6E=f)BP1,H+N;pSM[W7@ -%N/Eq&'K?u]65e"5?7`8jek;edG*ShV'(?3?LLKLdh9aIT2+1:Sa$&55UsK[PB,'e"/JLt!6QM<9-,r/Rbl -%I,eC*dQg9QnRS%e`&t%F@L^OlX&->MXDS2l[fY,"!;hK^^f@o&XC8D`Ak67]0 -%pW99V:/H\6=?7YmLEkeh8`\!UD\q"2APYqL-W'qa?8QBV$sf5+J)u!b6GbI[WN6s -%mOU)0K'&n\0$H1tX/Q%ScR[r^nIU>dZN18nN3JkRGY&5Mhb2n*,Gn6C^!2ToZZk\EdmQP:iT0L:>EUpF+q(W8'F[IMaeU[H*>lac -%H,#_[o?:(R1QC6i"%bMDJe9lmiT`B),7:FZ,/r"$=&mV*1+D^#e-0!1 -%Y:*hDk!J"?)!\I.!9+CERqVo!o%APlUdjSM19(<*)OR'(M%OJPMdZMc$A^2@2K4@P0ZdN^8Zko8I#bnH33^ML'DEqtAI1hJ]0g&aI1kFY]gdCMMFRkP.:$'tX;P#H&?].2 -%dNifKBqV-C+c2E>Gst[B'hT1k'k?]+F7qQKY9ec+7*?Rsm@9=G,n*GrfE.hXK;^,?mHR[knmj`U#o)Ys+3H6A!Ac`#H[*aK=\Ckr -%EbgjMN,_:t,-=2H0$BE!#0K`l$mgMd4".H)qpS??X\Sk#j1MPaCScpak/UiuQcrBrJUQ.?W&-jcRBg#(fjnfW<%H3Qs6?\!X\m:- -%%7*:9$6K""ds;qkr=1je\c09/nu5h+<+SKo.EAA(X[G`-$Jsk*TbjhO1)#+3b\I@L"(eXs!7>k[o[#CA'PcmlNY>Y\$2ME'L!fOT -%2H'`Z@E*YsMXepWML\6uJD2D:E/I=l]oqLsipVN%GBKcL$QtNOWtMDc=3UDs6kM@&.#Sh5GbsDR'2%NN6P9i#hFGNsKs^?+3(%M8 -%]MJfO>)@[O6Z(eDZNtV,?]1Cc.S@rB@ETsth'Xb9h#D%aoR'fJcbnX?9r0Zb[.'&:f$a/MP" -%-"[d0Vq*D0h]*>skSHFt6MJ6BMts)e#m)5qUPNYoF[uT;P(Xo.W1(hU^B" -%GkU9hm`AP$((E4_IENp`>Jsob^VPjSsYS"t` -%4Agd=1>G-`[F,@i0I!Pt9HLgI*/[MSfsELW47Rq@p'^X]k2o+^5Vk.*m'Wo=7k-ef8aJAG[a?Ap>@TR4=LVH8P%h&"]'^!A@JZH# -%Z19iN[-0deB-mr^AHil/!'NfA?lA*464^A-HB[lHYEf).<='b5'Ak<'/q7dNHTn0EDUS_l!`D^uV)TnX1Y%mmK[ZWbZ!=?@a4>Eb -%-SDH5-I.Vm&70$kEgJ9BSuJ1;?0]aY;.4G=I30CT+>fS258!Q!7h[i([21+Fe;bm["e=)jq^_G9]LY-#]4/2eFKOBKC2G[9Yq -%E5=D1j/Jca'I9Hi(0^m9CLQs:2NDN.%Pgr1)ur\i#:T)_e^pYA(hqTqJZj4=E)Be1o0&OZBjcXXHU-H$6M*Dd"Wu0JY>C4^d#nnG -%bfZpob8.%uUMub6[I"*-eWt&QAaA)-)C425l4t -%=%#@cpU,!hE.*@jV7!T:ZhLDMUP5gl4.^M2[=jOd"=5>1H#QfKMK,&9 -%$qNj%e/082/pjF.=LO[;+a1!t..E>%;DCEcS[-,8"thm]K:Y)g8;[INpcl(&tBK7YZ;OH=sUaD:'HQ,7\6;^"nhA&asKir[l -%_E=W0?D2Nh9Q8?jiNp[]GG\[q0V3oTfZag:`uCr[#-"9*&\jYBZdfQm)Yc$.d:V3LnhfX((\=iq\uo`J?-d2'DeVmrVo9Tg-$r>E -%c8NBA?h051huUoDKLT8O0(1dSQQ)W$l3P<-E/.2S]gZBd/2aHJ]ACFG"u,c9Yo=\1iF*eOR#(Q,P:9R%GD"5j"c;E-2P1/&/9cS,e3_iW[HJ>pOCl)AjF(q?7go'(tX)&E3'_a[X1T -%Um2Xk@CjoA0kr"kC*hhRR$om+iu4eBXX/a^'?Pu#B>aAKPuKXF0ek\g-n3)--U44pIR:#JlgPD'$f -%Y@^cSWpthi3&45XQ9sbN?Pd7N_;.4FOXmN-Q<7[m="^_?Br)J<'j%\9f^MG>[]0kfe:?nV!Rq)15>b/C',nRdfnrh'&I^b+i:jebibGVSP\niZ+)9Ms>mn6X8sq/gl4,6c*aQ -%/Hg-j2]'A!"#B%*Etb[ac2RK.PI-YmHDTV0%d>\%FI8IWb[Ol"GMUT(*Tk_/ZY`c!F,)cg_d)*,]\lWsnM&^B,r9g2KmB'M]TO"h -%gkbdVAD/RG*9!3\r$F;4VhH9b;^KJ5Acn?Hq["\jlJs(;0Fkk."lk$)Af_pa"fY?tMBXA]T%&/I?AW`ek[X^[:H7:/c5^#Q[sHK.oGOWI&UGGaT?.,6seW@W_CQC85F$+ -%TU:o*H,0uhC2E6`>,bU\36`Kg-"''qBVhnX#;gk;4Z0%Scub$CLZjWa5aII.kTdV6#h^7&,qbgA50sZ$,dk3Y8)Sc/?j,O46N5Tb -%"'/;+#"]%M#n"R\L1/fR+@Tb3Xtp/]_6uh\8e_EEGHdgKQ66Jk1;V)=jdef!/#81-qSs>Na<@\HOFV?dK0R]Yp9]Z<2@6:<<9I%8$Et^.nh_["d)Fj#65(2 -%E)pKsnEeUI-0XSSHg$Q(F9Q>@!+h5ddO<`$`CVcCUbHQYf0tc'dFF4O`C3[* -%0rru=@gD\HIn1t[c(CHcY>,t>3SW/EE0^^^,3^j3K8H)rk71`CY1]#I`8e?6*,cfY&DrS=(:]X,ITSNHOE;,B2E0Q\.td]l%fA0M -%LD:YYT=ka"WK=mhi`8of;uAo;UNYFoJMPAQkl[4?qck)-PVpr`=&'W+$aP"qr1\X8:A3\6QQAQ)(:,qd4E").\j3[N"?%<)!^h,+ -%"OnuNW[J'iCc_2mc5R[(Ji^9r&B==\[YBRK`$"FS@LUTa"XeXm^,.AJiOk06!U1*t109g3iP@Z.6dd'F@/rEXaQghNW%8(IC/P!C -%r<=p8P<:Moo48\YWucNZC8ZJHM^Y^3TWmSJI5^hILd3[16'eadTt%mS]S!5"o(n-Q(qiu;,$Y5MXa2\&&;7nr#[4Hl/Jnh5N[Gk> -%.:Y&P7&u&p1"\BeSS8/(:+LlKk)(9(*[68q@^0HW5P'J)/`d?4O5b=1,#nGZfA!!0T8B+ -%itrXo6rB!7Q7LV3+c^W"p`+oR=)as&`9@UiFb"!C@U<.*YsU)0&9YUBclJj+#IrY+N:71GG_eI'Tp1=gjtZRT"XcIO<"IC..nK%N -%Wd=pL]n-t@ilVK3oG+b0&D97c^^guVVlSaV!D7,2dDbWT,j?ba2Ec-qE1#SA?HLS5VK33p^/bocp63UQBkJq6C;XSj@G9I.MVKnV -%DO>[XP,($1kSpDuXeZ9+U_N6n*j-b;NY37cWK1h/P/EO,EUMp\Rc]&gk:lRM,u&KK;EDr`>tIs8A[DqG?WYZdLFKXKjP,qfh-j4M -%+T6L1A]8B;gpNMKpMS!K0JsNfgFB^sNRNAskId<)mJ'0hF_&Eu7T&JbH -%)\6;a)hq(tW]LV89^(:^-K-49hT(8c&3p=E&ff'sVsk8rD*,a/X(*fq'!PSW%b3"unr#+1X6XRs1T(tD:ep/)S>itVuk>'5jVL.K-''$66'>kbsA6DS"ZLqWB3dQGA?7FH`Kq;6I]dEZ6c?:`TH!VNjItb9NN -%SAp&I:u:IsP>m+m\/dOAW(HhEJ"o;8Hl++G-JP\t>BL#_aPLY>' -%ikl[0_*-Hs"9'U2U#"mH)R;E+'0oPCOs/ILN@G*0"k7tIJ[I+S$^J?::YKrfib#`M;0hSuOU3hn#K17G\mh70`6k6u=7H_j*).4u -%U`$@PnaLh+^<-Of4BXf;r,`ik*@PC_.)+c\pUr#YWT;?&KmPb&l.lMg2i,".lt6C^:Ej[VEXg6;dKPo;+BD!Y1.3VdKe[TRXD -%c?0A*^'9EOZpNM6:J/WR]?6O!jOY;*E=H$^p9"5*FRgrAILK-#LIpbq7RHuY2tr^NY#P>UR1G%E%N?F3@+a/kYQj/!UVb8;4<5j* -%4QQ,OY^``"3EK,]._JjTpI`G#=+jbZ"/:m$RO3Y,@AG;I;Cn,?)Iu9,^h9W6>,XGc[9;(Ci2U=g\\UhbZp+27";hPNSnkI@e$p%? -%TOcPEH)[',<5YG1.g<)1\Yc-te7&>k[:I#Z$LPj`8F-Z2r2Rt\(qisC>U0lU<-8coAeBW`]P-7+P$qOOUisr='B$Yl+CjCkk&5[U)K).eAl.JlV:i/-n@WE6[#l_OE-=p%XS:55T4WiNB.Ktq,]BJA`_!+Tl -%T2d4r3IY*J:jBUGr!h9SNo5\k(@4_XCnp=Y&b)!JP`VS]&.TGB<-j/-+T[cnLYnNi#_Ft -%6ffPfaU&hs"UR%k6Tkuo-Qfhug'C_8cp//T'uNsl&r?^qB`haKT[Oo91!FflRfHG5Oo\[je^I97A7gPU@Z:k-8=VCYfbb?BXAF," -%=?_Im+=kqb6^j,P8s04#aXZ>fLn%npiipJuE"=nNhR3H1_JkDB2WMs"?.n;Vj"NSV`@dc.DPk%Ze_o=H2stXK&!"Qck_rUjG&I++ -%*N,bL-S&Rjf82tia?cN8]eu73&Z*@+HsrSE@8QQ9=<2IZP30"6k-.&4?7jLdlEP/eChM=la[RoTB6gHtnJ_TE.N6'1UN%XgCGpc@i41/@&`\>bD=jF\8ihK$fGgieUDgN\Xb_3/;h4KGZ3:Am -%a-iAek/_kb(!BB_'t^G_:hIVW$M$oEW!uUcj$JY*7iW?;Zh4D7V]^,>UHAnAbXS6b3qr)lQhJ%=p"AX"L(ggQBh=+H80,JQ^l0Oeu3*VBcqc:n,[Lg4 -%driO%20,H($dtCrBt-A34)'shA4T3G,VE4C3Do+%Zf;sa#Z>'CAW(MX'Xbn>2[p3Q"6h2D`@F$jEL3]:<@=ORV:;f=V.HYt['5G< -%<#60n1aqkeH")"3NB(QNfOoq422"W.RVBpn',E%_?=E_*Yra.'E%+]9[,rFVodIQs%>*;-A#:O,3@l'\9;+u;p(2:I7L.kQfTc%n -%A@$=dnCa=""@\7cC''KO+4lAbX;:GA>'Z4*-ja$-Cr3$j&G9^/7S0LkC8Rj0)dW'P/$NDF6Y*W-nHl'f6O-_=^ce>.n+?28UJIZt -%$0jq`9@_0(\al=%?J`AbCmT9o=+/de2cmS/#=Lm'b+TPrU,=Eq+mIA]6.5`U)'5^+P;bIsUXQl%n;!@Kn2f77HJ\VY&Dg,h;re9/ -%K[l?F;%L"-Qn*OK4`j`?\OQ#adkt5,-ml1@Oh/T13b2N%AS<*i\INml7i\d$51q[^lj?Cf?\AO7=X6=PZcu)%,37LcEW)?7kWt6u -%=$!7$R^8&OK:=T-daD4rQpGij;A;-J\F;e%?Y".p&a\Lk,e'++\m4'A2gn_fBM`TauU=/8LPWbdIfnFPb9o*s%SiFr2'-J -%BLti%:Cdm`ArmbP8]AmWEQUBoHC7S3`h,M-Ci-&?='hB/TJGVs4roimS?DFl%#J;FUbLgi]#0-33tt:B"!b7N+YD.aKp2H58gWJ* -%c/N/[@qQ@p8H:]TGg&k&Z_B/N!K.[O5cELn,WHJk-gE[H9Ok73_6kK7UO(A+_UC#(W^l``LP;r+MIc>9k6ZT+53$s:PVIlHWk4o$ -%Q]i^qVh.-O`p`/f15?iAo`NRiXL(gJ[Z'sL*A9Cf_-:N"[0E.4bH$?@2h8/00FgMi-j&0=77KqSB(kHP[q``5k?NQ=U)Y:"SdBs* -%;T/<01NI,^>VQmu"IUkk8('XZ[GEld.n=?3.UC\\`0RIuV%Y2VkB`,&Fri)<+Lq$AYJ@M8>,7bH3W,-'+]`3O!lpEiHq:43Q.uIK -%:PK\]4WNX;qX7JsMfR"oT+*&e?ncS$,Bn"O/)Lh@]r(r1/e@&-Y#Gsr5p.ot)BbqtNKLI.NLm -%h]ui6ZBZhN1W.`PR#Ob9V"@mBE+=pT>"R7E,_!6@WEh)Hk-CcgM%2Uu*e_]1=b$`&#[OBAO97TKWN6(+P"Ljg2))"D>JM4,q1Tke -%BVG#9PSupl#F6:PTEnssgP!LJjV+I3BWi%(M&8pUciLHI&`oOI);*2m=;g4o.74k)SLcIckIQOeYVcG^"dH]#7`>Q-cP_FW;W:Pf -%J1+ad+&eiu"TJ[/f<2:9<;44MHQYl\c`L.Y*Rl%a9m^NbIP!p9QqP1l8S(_@AYhT68hHB`=#Ko=jIEL%j`\NTe^>[]ZBY>d/Z?JW=L9@S&#_D*%HTK#pE)f)IaG51+3o(?ce1J,u`t,rXEKgc6@ttc`mofm&]9g -%,h*69G#0HGc2d-2,`S<5LslD\$8`C_:AYh#nu.AsKAj,RU1,Y7a+!e]Ac%:L($OhbPg$Ambcj'dEJBTc=l&ks>7]/'qTdA)S6#Ee2hl$5k?"g%NF45W%L10n"4T4Zh4+T0Al@$rpoWdZM`X`i+Kh$fCn;j -%?bcO3mG$7Mr:0-uRu?$:&cVXdYF!jb`'=:rlg(mXMjGeB4]1`6oL=>\s5u&mobi,"Zf[T;pg;,-RgR$jEY.5L$cis&VS7k8e5[sLOIHQFgQ^m=89hiX%s.];KMa7_(qWshp\u."s'K\(EeD?TIYsZ/- -%#mS+?Z'/E/qF+t$?]1a,7QB1fATBjflJKReH"@:*LQ>@RV<<@Y$e1\qKZ/Fp7g7\.@h^*.tZ.2JVUhDms=o2rEAgHd[ -%0\Q].C]^S6$cZ5nRBZTs;o2pG2BWns8)'82QicqeKo4.5\WpP8L"iW-gk.&r>0oVSFE3`o&o5lZRWO"l:(JpQ7$!URQ+h?8a&^$. -%_W$ff+-S$ld<;Rl:::EDa$C6->LuL?'4r(aT.T*3VsgO5[-8d1*L?=Ok@&n',4Bu\:hL-eeC'Q.?I(tcK@oW4-4J=_^%YIo?*\/0?pEJAY#`]#-iglR4f\OZnjOUZ?qW`fEn)Ok4j]1BZmA#O,[XfZ22%43nO:?uHhDB5*N0hj8,F++m -%jj&&bX03CWF>sAIW@9E$e2n9NIhoLsE@YcTS+C/tGn6b%oW+-j\Ai -%E&0(h=i)V@^R(b+Y_cYts5=?5>UiJr7K$R%gX,8>q!]4T-!-dBG&^3#+uhIMKo/7@!O"cjFh?e)d]Sh1;AT,-\%uVD)2Vj[McWB$ -%9S"Qq78%A,*P7)q([%%TJEeS*'K,I9Kqp>9Di:3\BMW:0CBI-1&bt,%`!OJV7LT[P\1*#`KRO4YXl1"["_X-61+%*=6cK`+9!-EIF:KB0MiDg$YAf$ -%kC0st;pSiHF=_^-=$A#c5.fRV=op#de/];m>7PgX#OBCTcUg?g))*rh$0U#I60t=?:c5i`K#8V9:iRuJgd"'Z9m0M82#$_3n"@u[r8/IRpup@C"=+!PelLQ`g1_E -%2T0iF^lrDYUUe.T:sMBb)GFTJO&1GY.Fa'^=LUPJ8arUQRdOE,P=dqoBZ1`#EsNN0?B@K?P7k1DLS<\XUu6pT:[t5/f80>b$Ag00 -%N.*/fXb+beg/i&e1XYEiQ%EcqDCB.pGu`PqgiFkNJ$7r8=LXRaS$ -%DI>Y83-<)XL8RG_>EBE*=qk?L/e@'[>F;Nk(-AWM/L1,?]%'NNC^p"KkV9p[12(WO"K:`$9IFeP8Kb;#2f^LoWkVL`<_F*c=K))- -%(ZHD34i`(TSFDgWV0^X^P+ie[`,(o^L+E&[KZ)I0&Xk9(=;+:EclUX)NH5KRL9Zk%H#;Zkb-p'4LkrFm`'s,WLdkO(TBi2L%B+T5 -%Ket$U_n"%n?< -%m+WYQ$$s3S"IQ&E+>QFG!3L=jHM#KTJ$;@TXj.Fu@kuD]`a@q6:%k8]eJ/gjc&F>&X'&/a"9s*e,nXklM;KAd+(;K/oImdbnXdr. -%74m(L&Sf@673WcIIWN1C%RgPpm"XL>j6]nrf=qX'&?3lTn]@5F0RM:X<#/g9Z`L -%W)6RACfSB@ff;?,eRC=&iTr9,`dli46'Q@``ENF%_G3RP%Ohc7hpm\kg'6&g]rkX,lnGm/D.on^_dJ?JTas3@`<0:[/JiPjWamK7 -%&1@p,No,+Xh8N^;p/`_E:a/]K^(JKB)]gp'4)R!kG[Ya%U^b8-NL<# -%DWWfD3jJFfR0uX%F`9@*q3aedf2K-@W8snlQ5$1To_-_I3]qFE5.*>Z=6u\c\ -%akR/Y0B\7l[Nsd'nK"I!njtfn=Z?R5hGf]]_'OoK*+$HWErTm?RSVkBjg`@*HBkcmPP^nM(`nG[cS59klM2Z6Xq7gAnZmG8P[k`U -%C/B.c.<3-r46B8b,p0DQ%8[/Kiamf17K`VRJuPKc!m_,e(mBhRn]i$YdOH/c`>9eZk#;^U=D1A?7XjUDS$S&9iGO:>/^e??W-%_7 -%1\-?fI57ppllY`4S*;XN)hNaLG>Rfuo[c2$L63dgIYY:[DUNV]fP-Op$%h9KOKb2(D1t,b)LT%V7+_PTE`X7C`0n?%N!7NNV2[\K -%keO9<=9UT1OIBd18Mn6N/*R&i\sUu^:+p+DF(2II'1s-2MdjsXIOf9;$>aCNa)`#gdN?qT;5&hd]`d\f=edma!H2He)f"ngFe$X9 -%JPM=[.)]SS8qj:o3=LjEiR+[21XY:3D'`Ygg4tFj#*5gae.L/YL*(:_bT$b8:O+67#VCJ:!?T52"eFb(Nfg6'YP:bNoJ_@iKA-n(UC+.\T`s#$#U3<;^7T?EodR#F`gc%L*&Keu!C[)rG-M>k`$PWpffnh -%(0qd>^W.6^]/o^cN"r/sW6e1k%l\g0:A*aa,2a,rc\"OZKsno0Du;a7(_lY+gn64O:6REcB![8(n!8V=<'eg\,dMZkdQ,0D.B`;0`QgU%\X9D,gW&#lo%07Wl\:%#))NV8>E<,XR<.39gTB_@"hXkf)^:VJmY0:pqMo-d4o4)Gpi6+_`q<[Y\E("^3CfEh!kclMjk'hPWr! -%0`e]64;;*741)%NEsil5.a"@9T0UUOESs==eH+/'JJ(-8,,4@9+MN0.Q1^g\I7'?8(Db$ML_Hi_1]>"->%_ASXt=0eN:qP&CWN>/$(4@]4O>\j,7V(SO"6,"HOSJ]braK9u"/2QaY?>`,Amh:AW9bP% -%-/pGM1,KXZc^0UsZ+5"Uq"p?W&HY=KTR?*?k=(udp00QhU,,c6"n5W-0Lk+);/'d'7Bj6h)R+TVIQb)iV.0W7-<,3?1is2lMg/[! -%CH8.\?5WHrYeQs"Eja>GBndlC#ce9O:8EF5c":Dn'&euUXrAu+_?5!D4'AB4YQ.XBn6=V+$NjL,I\_UOirK[2b_pu].sB?W[R7Vk -%A.r$iYS[II`DiSdILDT=Ul8mK5j%_^$?[LUk%4ubeN2(L#,og@-,'fr_@H>'g&]2N[A?k=Zfnd%%'"hSAS'VQEu$-cYZD4Z.eb"_ -%=>[?&_^\PP7TR@J(K(dlA.O;p.'Y?$,;!]IAg6\2,W$W-+0-9Z;522d<"(>"Cqk!#%a[t>FA9V3+d0IiTQPf(Ke"IXjeG^B"/;E> -%UXU]"@pQl^E#VUoC6&IKqSR`l&W.sn,o.g6BO-@HgYrUd,Z:>S>?[\u^n7:$HJ.,E.RAWYT.fiW2AJN3(j4 -%%bOTSN1i\hV8MjT!,iPAZ@VgTcbr&/dob/>6WL1^+`8#J'Cs#g_*ZN+=.j-eH),?dZqA]hKOe+0F;)/;,GG_F[gpD*Dke,KSQ,1r -%S+T6m(P[c3P&(a6TW0qbeun.F$cYE9FIcgho'X1hna%l?!6#=n -%D#hVN6j=p,XnCn?D7e9"%YlL9TtiGk$tW2&K2TiWO;AIt!fUe%=0%2Lq[DJaSTaZ2M7D=AA):$AMoiate@K?H-.+J#0X$n=L%Nb" -%]Uf^K?(k5/[Wl^iN-'17pb?)AJ/#mSK-URDf[=fBR_QY -%hb8_K:@o*kBn0lfnEL#\I!Q#0J\5`*8W4s0?k,XPH-J`:#<"hR>+>c0UI9ma!,VOK>_,l%eFk/(F^dR2kS>!7i0/65jQEL8"2GS+\)m^<7uAg<%A+/ROcd,GgXl#,Ege_$Nge:7af -%gNqPgYZ7t>m+!dY>3aUHDDa+C$/HB?!d^,Hl:1+m6ZnRE.Bk`[/JXW%#aX+qME;DTZg^-$hp[:7;p+p#,-7*K#%p0j!"$+mSY`V_ -%T:U846@,qEjCs1TJJaFp>D!2cKW&f_NJs7,YZS*%AS[,a-X-MG0juidTSHJ%.:^,"A="K.8*ik`^=6hL0ML,9(R3AC_0ac/7i!m.gq[P'APjCe9E1[LbP=;BU$\paceJip5Fc!oYd.DV-V"P/*YX!-PEo;fVB("0V1goi_g.&Fdc9>pU??N)"\c1p>?VoH.DH5d -%T*$:>N2W(S%H_o*YPr'[J/i%Jg?6;fVs#4h$P9T)'L\N/)'s/cEZ -%VInt1l1g-K7WIage\=:/)]HD*T3Lm+mMs_P3HS?m;=`bq,KO1PhsPDS?sH@)p*m@sQ>Ci_gBDJSQKU:`Vm=ol-+I#@&]WY*HJ -%Ak1H\rB\95Br6@caFL!`VECk1/?2uq4Y>T:=g&KI[T##Y66P5Dg$qj_'hE-f/6C2\bA0!IC^d+/f,7si`:`@XfFum&k[,#P+Zttd1P_1)l6PUs?^^'e#p[EX;DN@8^hiCR3W.JZOeaph(5EqO(\M_*!M_"#.imY;j12^]H;&Ajo)tfPY -%3d@8+gd$2@A6C;fXWsrlFuef,+i7T=8C$FBk!leqHHc_,MP4E\^ck%'T0YZ`*l7,hK7:rl,VTI -%E&2iK2UI;D+Z!1t@fl:P9c4=JG(f*>G2u#QOD@'Y-CTS1\s8% -%X(VIqk'l[(N.09,f84>\h5:b>_5=kg/"8JM'>4PopZ/W9G@#^bJ3@E6I5r/6f5QgGk'3rr3-#m$4PZ.k3L5Kt,Lj(EJ#U$;KU7/i -%;_iig0HaqR5q -%(g/D&C>h]8Q;Ek_)"fX/Tp&`i,1O1p/Kl.B.&Eb^/"%Ke(q2kqXN=Bna9Oe)Vd"gNh6gRo1m"Qp!<&(,'?Zj.Rg^T4AIVnaA0\jr -%:a2dc^P>6Ukc^Lo!C2iAZp$&^LigWNGoq`p72f9?V$L1Y^b',kWYT3Z^mOlRPT*0n(_T2iD%A3,>TP4[XKZWX@ee -%G#>maY:JDL*d%"Z"O7uZeWukYf+#f9qPAdEB9sAcCboQu%lb%M19.0(_sM_"p=8.4X-K -%Mopm_V%L\!TP&-PbpjoiIOYHTbRPFG&<34'e=J-pVI8@ -%8@t2&#,Apl)eV*s5,g(i/JURI[`Bg(MsG=ol;EB3e\@a*e7L>\/oKf@6Zrp(%k0c/!#e8\mfir_1TKZ5[t=dR]M`0H`"#\QQXYE< -%N@L(/Z_o5uX_$T1W>PjMQks@fAcZ[]^`-A(>cYOB9>d,=RMls&YS#NM(hcs$K>17IquiD1)S9]dn$E[_mncJW/XR[%S[dd99Mm_PM"JI<7@OmLbWQbp]eE0V.%q$(cD+1[N1S=oke^.Zjf@XeXSOgP_#)OD=/9AD9tp0K--;XO(i8e92uK7 -%L*Xf($_C.Kf")IUoijLlc"JMg5[-[EZ9>)ba -%U"B!(3(0j9q[I!s"cC0O\7IcW!#/;H2<@0Kk/jS9WX#sY5C&gDQZ?_+G9tbuJr%9%-]@*?t@%oSen"soH -%q^pMOA-o*Uha`Sjc7JMP;8E-h*,jJ'G83S8=_.R?8`JpYl\]a+8;)4r.!QcpJsH7`aDVC`+b(Fn%]$hp99*T]WE5PBJpC;'_.6.6 -%qmXarmIZ`O:E8Oei7^J!31C,s)("@KL)e)^+\33^KZFNP`dYs7m-nhPrbIKb4-T0Whqq]=nb2PMc/nV*:JXF' -%"P_+Lq!@b4d_C#Ss7F:&s5g_VYBi!srR1]:jI\X5j^3K2iqGAb0D^1tr+d)I_oXRHGgkFBlcIKQIeE!;s4]"$0B29rLQc(m2ZD=C -%S\9?ms6NO1q6/Cgmf)79n%[t6qrP#!DpQ/TrR$Nf]tOC0mAl02o8B7!Va$gRrVW/.="eJFY5-t)F*[cIo&ff8G.2tL_E7Yfo/HE' -%_"nmsYWa['lFZ*MnuK6r?&,[`Ah`g?GCp]jrku&`Yd([];,/dm.J>9D_M+eD4g1`mi)[tY&7`'45IV4VX(]mIlMq!p,DjE -%h#e#=(sTA(GDGbcc/kGdDuOkSlMe%nhgE6^Ddu=^3rY%]IJSkmg["[[e[IK@0AgU:o")KJD]-:!H$amenLq@ahgTWl^5]P1]\_IF -%Qe-"7ItJORGP5qSDn`op4aV6khp]0N>X.`ik5O4Y'HXq2n%Z2Y[Z)`g];>Q,U%J9O]062^o&Z@KCY!h#h,aBUh7Yn)D_<[BqTZ_- -%bB=)@rpJQO0CKjrYQ"47>H)GEB* -%_=[Ef=]Z_QrVksMp!I=(QH?LrMrt>NR*ml^F0qVr25C]s%DW/LIcj2Y,?>/Z&t\9`K/,p@[apZg1u5HM^Y= -%pnKMb?6+,>D)A1S*DZT)Rp0cA1d\rVufb#5c:Z -%Y1NXMro*7uB?+*>#LMMFIs#ZLig&AlVrp"BDJoL=]5Q96P!?KPa5,Vje(`W\cd"2X3'Y$)BH'6$heb`/p4.."CKPYe59@<5-ZgeUC(O0u9Pi'KnEC'(5.X,[lLN1AcRr:;i=G!KIk4I;NSR?*51aGVQZ'UK\p1QH`E8`# -%j`pc?c+u,)iO1H@lKD!pfCYf^FkuM/4anM7+*D\'lh;IZX`Q]gnh'ap`U.#^MK`n+X7UmZnHHW+h:\6LrUR3*NXpO:\#$c#@.k-0 -%N?86HEuMK=Ed32:G;FYs,"s>#V>l=dA2Z6""(3n!^A-I%X"V1IH[55=[aGOI4?UaSDJm5fk2t4=?gkUQ2Ja1J`4,:L6V/>69>8&d -%FgdRF_jVTkrsc<"A_=oXh4D!T[$,>2M?Mn>!`\tCmL^`'gDDs?D -%qZlkEr8[$B:k[^jo"6#"M78^@r7+iNrZ<>FGU$_oJb"UUJu8D>o8"LahJMB%GfkZJOV;c=%rV-hps%pdDdT'+?X-lA^\Q^=[p+5? -%*dHSF7;4]#hgWqas*c*3B"%_'#35etG9]1^?Wm@,q);sK;G`nf1Oh'A!/@YfVg'd?XBirhV[W& -%q=WjM=8.&L/h[-9,JFuYn(kCZO+,D<^'C6WJ+in<4J\P9n*Jf`S#[&&XsmYig\j&i+,Jg.3kF>c^A")kH!\*cIql1VgHE6VX)dC< -%]=A^kq=@[Sf,&'=6%7+-hDsKVkARQ\^*@a1E-tr0jITQKH"Sre?XCIWr7enp\\2AmbXR=sS_hgihjiNZO$nEm-HtpRcaGilH?:"MU_WCu-PAp4k`uRgEAL@e7;_eq1g0$9p*$i;neM>N(9^8e$W:FT%'/@X]h+s/GUI -%4hnOQp$3'/P^#TDk5oo;FkoYG^FR['f46,o]J';,1%Fsm6<54AO-s520"5FcP"E&6eMaXfic^]/.n3jqFBoDg'T^D14:".4%6InO$+gDIqm -%$0U`qG%AHM1?"24?q`P(fAbPCZT#Y0s5(?"IX1JVjn3rmo:LD!XQ,oqV#RL?e=cbr9@c7V@q[[AE#?<=,IYr"q#9G8=5VlI?GE$p -%J2;V6+oLkaRN[m,b!,2#OVi>jjE@n`_+]NFYpM3>HIRGLQX@HrJ2.PL'!VmH'gUXtJRIjf2LBEW4Qn87FKA -%[P7dIkYBa]:@72Tme=<,L?-ujDC9RKVsF'uj/mDd4Ru3.-DNaN)0L;0kVa+I*Y\tYj5o/O?N'EEg%SikAM-4H7&BjuX[b6\id>s5 -%2tFO2qL"6(rd]4MV\?>rbtKk8i'-&F`]cj@pGAqQ">,Z,3f[([+*fid.-8Q*9)56aa>$;tNHI3M.C[\$:HV8FS'/"MIf'!$"jr8# -%@2quaS!m-m"T&,WeZ52.56's9`PqN5rFB5^hVYEX^YXA;\'(7B(N2LP]m0AKc0a3WWe9fYZ]/;UG!A,;innS]lX0hZ=O?PN+<:oe -%UOdMDOPYnHoUF%bu?N=o?Vpd[OYbs -%n@3:G9RH^ZO6aWRUlF.Qqu&^srR*:GD%,_QhoeNO[JSA,c'oZn-_I\k9Z_eAL\oW`Rm3KMY.cV4aN<9a;8j3op9k$Ga&N!(jKh&o -%'n7Iu\>Q.^De7LlOG^fC"Ie'c.U:0muBN(5MhcNN4Pc)FL6[\G0kC>?6AR-c"T#,VB+0pdIjEi6!NUMd1/4k5t="MdnB0Om%A]DhG^%r -%[Z(UK]6j"[HFMAt^[Lmp]??NO8/=j9,Q66^hAsKm(D"TEr4.km)$Kg5M^NiQ2A2T@H3-"g$2E!(gTTJJ]!u'@Va&V3%/8f5kuJio -%61WRZl\jZW?MsQP^(8edeh&Va9Sfqmq'#%Hp@Ns-?JcdOp"QN3o\K,Jqn\t1@9$G'GW14rq<%UE5@)"7Ik]J5?gu+j(t+t8 -%5;mP%^6SKjIU^g?Y(NhrGOZM4_Z.74m(`kmRB=^1Omlcu6[1R>.XU@ -%eF\aY.6`24rR9.0[r^JgqVk#K0A_1gs(iWQn9DUbFk?WWX&irss7Q2ELi0pi42617rBG/=0rr4fGW^GIjt"-A -%,P)U.k#U*o,P,M2mN-i%C]Vj@['^q_s8S).-$u>N0Rn*r`CEgLHRi5)a1C"hDT""#T'L94Wo2g5Bj,Fi#mP_P,Dq4oj@m7fB"6.[ -%K1fuu@mk[W*[,PFTI6$:&Zd#**=($dOgCE$L:W*p](//Wk@.u!dRC0;XHP(Gjgc[Yugk5+'<>09>& -%N;\3da7Y!t?i/YCC+LH\p\LYqRl<9f,6i@E?L(DQE,Ve9qT"R']Dl\cbKG%0#/?^ll;+>_^Ce0K.Fm@c1@&q`lh;IZX`XNHe_lL, -%fgai(D2mOHce&F:mGh-RR@EFI:YAd[re.1c/$JFUT!GJ?rNT/OYmAqp16]2*M0mD1J%4gK`TR9jLsRBtmmp9\-%_;,=(;nIoqQ1m -%4uRHk-+j;L'BCu(EJ>75+n\@LQ.c":H]iT)p/'c\N^,pF6L2*Yf'ra*QJXt0V#T]Qm/$D,mt#*>[r8Irs)!\Wo-'^&2eQK7jjb80R^d]oIZSn$S8?-=I&G;OUK-S@ -%l!KH4l$`#rBD'36Ch+drmA4/3pX4EG9E%;kQ@;5%n1X`srpAh77TT8Y1AF$rmt!Hc5Q'oU]n:;iP1R\d>!>sT_%BK<"]oStH<\j_83B%N0qOKN5AR55ObK/8$fa&3 -%@O>N1k,4SASnkZ]b)sX<=e4i"6GiN!(29Fc\$pMN+8fu(eg3o%FYO+!Z'oHlI^S7*r`JcG^T>b%%?Z-Vl@7qDBqY)IW;LAu5Y,#r -%/L>[Z1mT+P(nR#Rb/q2;2W`N)c-u;9pQ9H.q\QrT,jZO"26bFlb>VeWI9(B\IVGH.JnloTI8t%5#$`[Br0WB8-N!_IYGm*(s3/*J -%Zfk'?e6`?99[^G@&$B@1`T/iM[J)6\JDMh#7.eOP>RI*3R;fD]^ -%r,&'9""o*YP)TJ -%b7Lq@I$!`>V;`&%>_lD4gqGHHhI$mY7fs4Li3KZn+to?WI?iq!En'NSOQQgO%:3)@c]?:E?\jlOr`CXV(8Bp))7/alP%E\IBh/OT -%F0T+jHq[7pdmVB+XprlEKsG^qTuE(h'Tu.-haHR:3F=?(l_4j\D%l"n/\ZAR9&IiSXnH$d*T-*ImG#$00>3okO`0LR:4@,uG?.D( -%ZA*#69gNr:ErDg);V'LTo2R-#Y:C7:B>12d/!312@C(kDaBce9;6sP[I2BH<)lgB9VPl`1>[LiEM4.tJH;Znu^KPUU]$T']Zj0NP -%p!/S^l#EPs]:7D8o?0/_\IB#UC=a!`5A9N?^A'b#f>K#]Rhj#T1jAX&=oW95$(/u`UX1A[+s+7CF(:qV/YC.M$ -%Y<$I<<"1lmI;eEcom_J-df)k%.`'r3b/@r=(HF3*EDEZuhQL+hDNU*OSitt<.>N&(dIB5lVbKr^QggWZ-9IULjBMUgV^jV"rSFS; -%n\"K?8CPL%kVn7qIF4bN7ZVZF<0rQ;HIs,iXW?P.ot3sc2!07Ec;0YU#-ncL^&!b)oErs\@a8,; -%NZ?L&O+o02=4:C,W7?@$.qtljX/EhtK^Pp5[MJP@o&E+IcnUfp`I#0,EpnpU)IC;[_T'Y]efWEX<;?e\g*3jL8lb.<7OG`S,l1W) -%U>f9K[rugm?d^Bep-DWmYFiI;H@\"ieM#d-^3`PT_Sf&[(Y2/10:L0U\%2mlnQZeNmsa$[O2AA5-H/tkOG0dnXo2h\MfL8lWF$`p -%\k4'@j0b_e$eko.J!T:uA'RN?488WG\175VN0A.^9M\G_bopc8EdpJfGLB?/T'&2ag5;'A2e8O>Cp'Mt]i4%("RJiDnP*r@hGMk% -%pfaLum5^a[-Q6AWaeA5=jKuE_?(Wg]s1tQ>Efc71m+[&mk-ahG?stbD+NP!D(*5V;Q"P+tKo7:Ri\W^boe8gTW8pP%QERiu^WWJ2^%,BUVhhSWI:R2Gf!,1/r&on7U>f/)-7<4\ -%PBg8PHlrfNFjD[5?;F)VG=\\/V5b(??(G+FJ1a7CnTgiF^5B5TkTKHbpUdp'HW<#9$Gh.eG:%Sg05X7cj1@q<-\XL6(PPX'TGJd8 -%Zej"GT?k@q-!Kco>:X>R^8b2V]U7'RQ%O-9piZ=>'6a>,H^$FI<'aP-:@[GQg<2aV[ZO1dXjZt1#e\0t^g\B/\] -%(i!$hg#[fIWj.VKKV=l8=Ak-5$6D!T<$[K`5M,^Xf6Ws47a^6,/(H[ -%[(aQZ4l44kH;*B)jqC?FTfdl'qaksDQFW+SgaDH6[J<5Gm3c0m(9;Jl^.A,!+E%n);f^7@a`#UKGZdGRKm6s,9dk<@$ZiTX9''9C -%[V)%:p@cf'546%uk46&@I?$6q251F)0@UiEW(sj.$;s>S_"P#\tBB\bR@SF9d+Mt:!\SF@KLbI -%)HFKLk[_BK73Tfms(?N'SZ=]DGeUfd\BW)jnD3_BjC%&d"]';62\2s(_\:lKni!GAM)9.kCI>G-j!)/sB&/2`I\3ZuRhIF.i1"KW -%Ung(RA7/8OfR>,-2sH;+FYj8);7Yfjg1@P4&GNYagPt$jlGl?3I=A\_f^'@AB;(qI?CV.r+87^OqkUuMH6L[hP+BC.";98T*3Hr]!sq6>dp-"2^=o -%Du7\'fs05CqRqIB/"Rh<4eJdA/'-2`:PBW>Np[kC7HEKKigY""aGW+9(YO!Q?2R"bU5S=cLd0)1b!\,^]GH!Fhbcn(4==IJ.E_k" -%p;og#!_n)YW\p0fG=n!l+Ps-t^eWnS?J(VpKVph(EOu$aNO%HK_uu07-Rl^HM3n$"3qm# -%374m2$YRABFY`fq.B"Ok]EE;tii$Z#G$u&,@Nnl_(@PKDkF+4];,g3-`D&q=m;8hV#`C`)4I`IoFYGA4P+o53MT+g]hj"P,Y!^efA(EAR:k8"-%Iqg5l8'N$M<_=d:G+u^QITls:lN"?W\k^:Y2o2j^+GQ_k`HmR>eW4I(`bpC-M5aoCEBWWt84/Z0!'Sl(PtJ>o]j0p"2E3NYlCW;3a?*^2V'D[%LZoQD -%KcaT8+@PH[Q,Sslm!5A.OndJp4mKdDl-=$$X6m'L2@34%%+%;a9fBi;`(Egn[[Sn%?F&W=n23mAD*'@%nhWfh'ceclbu(!'I5@e" -%B@(p$Y9qhri8\cs#g$@*:6rWGqn%sN9.sp0;ET[K%Z2NqWd1bZ.bCV3`R-P2_Yu<'eo"ZAmtl^G!9WC2U,G9r**'((6kU7D1dmC? -%Yi!1K5Y<)!Aq(??Ug$sOs$!($;QG*r]U5sG43RVa@M[,T#:RLNm+9u=OYV\h)bUmAkbB.MMV>Uk(mpC=9sdZ"ik&!GF?l``)DBZD%hI*4b2Z$-B.uE]*ka -%/bT_7Okb0As2X-b\X?i4\+sgYYjD>HF7%H2jkDj`ZH5jBD;&6` -%fKl:h"50)Zn8t$<2_bBfM4sf3W1CZ%YEo$Z@3?U%o"#D -%duu*g!pX2u*!"NqD7:&-KD;Er4W30DO?I=;&C@#UE!U:+B'5#d^%l%H^jGV_LVWY[KnBAQ@fIJPi=da>+:t/%E<(qnB&We5+-+g6 -%TmUh%4;l@u]ljCG:RX6KcmMO-!9o[O%Kc=V>Our=+(jL4@%X"G&\&@HHoenNYK5/nIcaRS3lDQ#SHD-+n>[N0o95RhSDSGZo7&aq -%bQ%#1ooCW-5Gs`j6m$Vn:41K.Y@!m6roWS%Mj#YrVuo@s4@8eJ*[,Zp?'W=mI_RX^3OjHIIZ']gFp:S4o>6J=QegW3,UF>F(]u64I.t.YjAqmgL0fg=4-kfJC>DlJ -%T_ieG@QXZfnFCK`7cAOP23Qg!"O9_BSBE`>p;Frk`XV"ZjMZ46!K0)N\]F9\'1m+VNk0Lg%\-=CDsC]88UKKp@9-?-#j*;g-l8l7a/hPAu'a+E:jT#CS,V6t8l@Dr<8/0^,Yn -%AIu.D%*1MdUP"nZ;A5]0Z<;n7KJP2VOX8BZ-Manj-s%HBRkl84Wf0X2bsm;n?n,;QG0;BNZhoj'PKkAo,_ka*nbIXR,QVW&R -%?!%ST7ufdiqc8?^hIQa=pror6Rp#^dXur.GZ$O^XZ?A[+I/Ylm>E_gIOslT:ig5 -%hNXC)GD4#F71UYU_V:hh?aDZUW\p4JUr?Qhder:E2MkOoE,%r`c`N*NtP_YjbU\CE]l6VBhg\Jc^o6-HD[bmqQ,agM&VfnE[%]B9+2df"h%,Z%(`%!jcrK[9,;Gu=0[r0 -%7!bS\1Dq#iAI.u)FW0k<*#J2C#8O9O'A2r:MUtfD7NgT&oF)AKXCRI3K@RW6\C2h`V+\9pK3=BOc7I&h]9dOD)o(9a3,];4e!X_:rYbOs4md&IktT+O2lf -%m*KkIN@Um^"lRMt/]^OOGIW3%)"p!\_j(6@*I:o\7*8f_0LjBU,.=)^QXN@m[tsn,#qQ -%a\;0-4:.Oj_Y4Q;n)WW+`!Ns]EgCoM35>sG]]Wp]SMt\eN*a5e$1WjF0p.G5]IF5bRq[RM;0'c58:rM3&UJN -%1S+=MoRSFSjSe$!:BdZ3"ss'GC@U4\mOrO!l?$Q,YiqC!%VZ_-esLP`KbOcK8j[#&1Q`oE)ZQ[5m0\He/chZ8.1.72f`FpE7eW4] -%lbMJ\U#Iq=59^%rN*hTK)r2^1l);F7f#1,srZ>WgXt*/N.uA^@rkjjOYRY+`jE8kurA8(E%5 -%5^,m,LiE:j[HT6<@Bn;p:M\b1,92`lrMI2=h]ai@bJPO$F2BtWocT2.7r1'nT:qVhk\>`'NX\?`s*jc,@Ri7\#hYiV>$D41$[B2e -%+>"MS^7YE+lWM`@jm -%GH]nD'sfo@OnX16A#Vst6:?.1j*mDa;A%)[?hB:M,+[gQ91&fM)!er?kr1 -%::&aRJef?:1.lXScL,iYRodOXLT/h>-.Xf9:g2(^d4a>*6$LSBEgo5EYn9C2F&E&+&Q'Ft*^k%:3s6@N2'N5+h!PG`hBI`?!nR68 -%(,-p_?b01Sa8)jT"&cnh4Et":"O`^9+sZ["Bntr+?Z.8qRV?L,J3St@5p">\ouRB=B7qP?EGS(4dL3_NYW!SE!1Ns8HY29os0D9: -%$UHI0aUBDhe&]HIlGf=!mEcb9u0bgZ4_MYHj4<<@e]0+Wbe!YSbU?;Mc0c.=n%Dd2.??16]FXoKE6aQ3UeFt/!U -%7DOA':V?%N!L1$a!.DhbJt1-YUa:%\B4::R"`g"iJ]G2?Qkj)>&JCl>`96m'"\K:4FIN]Bfuk:P-9\RRH9VY6Q8H1G>JC..b41qS -%\%n\i^:lOJ8f`8/ajJ/%NU6!4$Xo#Yo+KuND+s?drlq=uc0*E??Uo>GE&XB+DL:_X9oQuQi9.ts%o=inUeYYGqY#/. -%h>l,Z6VY$gh<4/\&-4tDlb12RJ&fFhrA;BZ%*m30"l6rl+'cjkl)@nq.QPKiR"').A7[n/!O^i$\&L*">NI.q5oKkSp\8s#?c&Ae -%K^KVpG)MRCqpF0XC]+:dO4!Y5bpO@rPO_Xc9-hR*jDB*qf9N2M5X2CG@N5OG5Pf$FnhM`ti$da7Ekk^*_$7nZbWt'O -%rdJr$9-j-%*l*9!"rK/;^GLg*Hcn?Pb#)ukTKA,,]Lfe%2f2&OqK9L[Ql3Q8h+I!_R8qICGi)nB07-L3ICuH$K91YP_AgJaigWX[ -%-W+aJn;Jb\kn_*DiUjQ\A0&T=&EG?hD#7)p`ua:l36B;5p'/RB^\rPeX;MdWSU<]7l5j%,IV/'pVeCk;oq6/B\_eNe"ShrBQ7&5) -%ZEhZs,P0M\W'sjU;jDdn!noYqt(!cf440"Zn3uP -%[_O-)g7Q9i4sDPeG:`]5AHbftHg!'Bre"0&(/pOnIG>d=,=@?;!\%.51f`sZO1pW_IoHG+6.(kEUYs`G)7P5K_bMkZ9&6N4N4(TU -%Nm(r^E/pSq"YK(R>K;A:g;4l_=5t4m)dSA;'m5VuPI*a*niZAVpk[Jk$D6%YT;]&^=@P@G2XX:OPNFdi>B]r"N;26]*ZG,df0NJ! -%:T2ILW&WefUtE"5b+LYTj)CR+(5H:J$m9u3[RM=JJCU514hs?*@"`fo8oWVqrk6YN&8a"Js-iIq%T'Q(g6Q%q+>bcqJBn;p#N43n -%fqV9=$sp$Db=#j,Jb-UNV-B!0\)7pf[gfuO$s/"$Q*$/L>@s$]F`=oFK!->f74JJfi?f)),":N>E9KU(dK;\7JV.koAk,T7gB!W= -%l;OtID+(X=\BLW7;=4^9&,pljbFtm;["Ig#>Dor!/5^D%GlMBjcTaX5MMZfs)=1`G%NT'gsn$KkG(-,S2d4)-s`bZl#!4."V -%PF(#pmD]oaoWGEXL=PTtDLcYYc'2gf((n^$>G*>ZT>?H7"uL,XC\nG`XX.$(AC!LZ"gG4B.LMrC3E*dP#,C(3\KN]!^.*?71F.:X -%6U:/<7L"p/adPNQred>oTOTeQ..3.3EG)FW+)0XbRk);%'YDbB@c2FMgM[Zl&E(-;],5dbNtHR4j[Zq$J3j!o/RMUe/C0S4R?TPdkq&+J0s*2$r;r!^.p&-D#JptnU)n>f'%cV7"IoC+ab^9r;2u?PU<$9L0).j8cd[VEbL`fTsPRReX):El[_tkd+kc)(WHD -%8\&MaL)8tEccDJ4$U!FNRg&e!6Er]3pfBEIX8/>ON]$iaN%!LFc2*JQULAH))narVG+o)$:d4b(R/\&[,iE)0LR4P##Vq^hVF0"X -%kpUd?7ehYW90i"h.(EeJhqti4,6fa8@m:['!'3$(bgEj:*I\mr8dMprW\"BR>9pk^?XsI%f\c0V>iBhT[KV94BE\9qTt:A$%#^4S -%oD[A"7G/mLYrP,6pZnJ47cuef(g"Yt=b?6m+2aV5'DI]=MY'+Y2W)`+?'ZcS -%SK`?&2`eVY&b51X?6b0[P;.ZJ@bgD0A13OGU]'\)Du9T^7MO=:P`YtR+q!9h\=MuhK#HSf;41oJ'#D$rmM4'04ZG:HK0=Jg)gF&f -%=@%j8aWBBbKIa)-nN;GKV@E9F#0Z5:IiMBcK&X`?O2H\<&EJ=0aE*hm7Lk1>e!cnp*+Q6t -%cc6=/INsd0][LlM5YpQf@c:;?mu2CQ$bBd=r_;@W*B"GF*Ln@M\S[5Ddr7)OTlqp/Wc8Ei(6g'/K1.=AIBWm%2!YEb -%a9*!Q)ZRI@EDd!Z&m_F>g3Kr.",N1g$AaL\K,9G\p5O)S&02k">X8tkC?p>-mdOd\k06hjt=:NmC&;lrg!Y"d>)MS<`iTsc):hMZbST$<"6+0=pe^dGc+nl%2L:DOn -%\AETB@I8@"Kd-lGma',?It?c@WHTu1f/HspqX),5'MpJ731!Q=:#/M$q+;5YTV9V9!,O6ZHQ[rSj>lu3OJa>M^^(u%5Ro!REGX+i -%CP0.aiLrrSn])c)0+UT]<_OeO=m3`6>]3u9Y@,0nBD%p*\?HC#Utc"3HO]S4T.s')neK:LAROS`PlJ_/_m\SX>Nd`5a95/:WMG)* -%cQAQY/l9>j&dm9!?_J^3CK\LGb=Eg[?hY;lSi]>W"op(p;MR,2kI$d%NN?@l#.h4P)um;tp8q]57A]BYpTh6n&VN0966e<>Cd`lQUMM@j%t%g -%5@Y&K(-LG\H7]c;Z#1YMq>QFQ0l^!^k4thl]s1=_f)%U&O(JT$a1IY][W@V@2UFgM.:CO&^P9qLIIHdS/V(LDIr&=4M''Ql^Ae[) -%HfGB89I$YJT;!D8j/&Vj>.>siUTO9g]_)s9CUcak?M;q;RrX.f`.FX0CNmk2Yf[tADt:OnI^T&*/sa.?'E6XmY-ne@CN/DJl]q9U -%<9\`4.]55..XGgT3U]p^)8aO^Rr6?YCn.&BBK7kYaZ;jOa#j(1#?-9m6gCc`gL]tWL,J/lPq5BRL6FD1'&3/dACq>ga9:3X[<-Fa,@hl\MI0EQ9;0;KhrCAb%Aql75=S]bOk:i8 -%A(:4mq!QJ%i1GYA5=V">&;a`Um12*n&V)ncAMSbP&rn6uf3b?02d,_UZb>,l%=AP\J&7]E+n4?/(J[BiD\kblmD-bL.s -%]AW[lm_E7g]R_3*p/Lb,p7Y:D$27#E+n)kI*hX!&15!T,R@nuS"EO\6Rlc0I+'m>Y4=j,9./9*i5UY.'jFr#*g1'a)PS4E,1O?lP -%]Yq/,_"+UmJ-OKroJ+bQh)Rt+*tgPF6qHXQ4_LWnd:X9tQquVpN`K3A?M['q+p.(i9FE4OTJ,r)Id9OI/K=%us. -%-eQp`h0]Z,ht65:@beXEJFH(.J"s+fRgsAk -%::]II^Hn5q8,U)26eq6Img=UnEJVZ7Jb2YoE6]DRkoRYW/oE)H8ajRjD/)gb,8-dP:Le2;^U1s_&`C5g3n[.%Y:i\ao!m=q!h$'s -%Of$f'7)/^MSVmR7$u@'4_"[VX#^^g`,.hAK(l.+(LkkglGe60@_qhCI%@&SO;/6Xf_0fdK/\)F@Sro[R]"j8np2)(fg_!%nhrr=R -%i5Ta\j;FA*Al]d7BJ(H9L8Dmg4=AYT:]XOD9LFkghWEd3Y`n7)J-]m-5X#P5pX"P^@GI1(\&;""XL9-;+sLCQ9E?EO.I`"Bh#n8t -%!L_"-'!Tn+\X?erO1tu1gU2#1n#5C8Df@DVQ?puE)n(sHJhoFm<\nd0P2&Wl@R$7-fkgi%D,N[L)mgYOPA8gW,u[.2DICsg9CVg5 -%_FZ#AYmeVW$E'ma?_Z*UZB*Z>p1pquNrSC8b+.PL;],U72,F.A*3*)3A&b7dENPi+kOU%0jCW+u$Ui47`0F]11Xkd76!8/-AJ9E< -%XR -%QN/2B!8?Xll>;CG:ld^Z0RC*=GoIX8SOKhRGias^T^ufTTO03jrhB::dVbH^Ag49bEis>VN$-495Jg1Wgs0-#:>a[MKB+.!pk/VY -%_Ka/U6ig,4?XWS8#IRLE63u6&P%bHU[WI[:&W(e\qtBboKJ/G%1oUPB\a>l*gm6[t\q!GD@LYe-P%Vbse@pOsC7bE3S)Lp_=*>^stW/pRO$:"iHMU#_STED3=&pojpU=#5 -%B!`(H0A#rC(G&'a[*h_U7=EXAu(_\_@K:+8`(TUUJG+![:E6knFl*e2MC3OTWKX#rMnMKDL" -%C=j0BZt,E^-fa>=b3r)*bc"*0AA]mj/5ZDEmUokqjM5W\GInEjVL`^o$d#Tm."_38HY#7MI;&E<)`[#^1?NVqNu$]BdA9?18-t0d -%[nuCFaaTHAWb/YY_]r,fTh%)g[pUl^/j<1)AI\o?].Z)1mcF*b*,G2sX$7In"FdIU_Jnht:)QYbtm+5]&Z\lH>(dMl%B+`gt -%[M!*'K$c00/QPQ(7^qAI[R+R33F9n8ihS5`^eKHF(D2FF/+#c3aum+%[\No3Ke;_Z_b8_N(4'eUCt9!+G&S\t+2RD9^hXjor,KIO -%HhA`n*6Wd'h&3]94DPk%Y;nDJDZD"c<$CT-EU2/N:<-@I@[iA5_7U@M8^V6+ANdb%KV'l_:]&.+lIgWhEE(_ -%f.QHX[ZulI?[4MVNDQI4p -%)L(=qRt(Q]CVRulVe:X2Z$Z_G#KC>6S=mFMGL/P`-YPXogJ3pN+Pl$FOtk=?P[gA'lZgo&3-h35UI?E;Hik5%s*F>% -%WD`P+dig%)eD,HsR.HK*#JieeW1sqIIpXn;;ZY'cAd'rp,m/PS*;5i:A(u4jRt.Nq2E6&ai"djeqC$mD"?`u!Cg/$An1Rdnko"7+ -%03pu2YuEeaoEf39juBgX_Zs7'd6'B'P!D8(RM20lpX9heVR2q\.iLTTOf;cPcA4L*pn4jCUr&t8A>ApC@>Pl,0,0^FQfb*7hI -%@taGgYjtgclZLgEG:0PB6J"D20uLi`e`Y927P@(qiA,_-7_f!.U'hYZm*DU"Q]fI2* -%%Kj,rF2&gqAq^eO&`f3XY$4F5T`>3R*G'cr$"UM1:]:6**Ku6r"`a#Pp/b@+-1V79!=36]*!0dpqZ6=DGiC(8ThjK`IARn'be!+' -%J1r_,$rl_=dLHGX3Ah&68V4GZMfOFddND^5%-t&j=mZejgLa/\G[HO+T*kp25_9\hD2a7\Nf+%ri)/hBpo%e!efM&i>SE3,fteeR -%1^1=r"N?t7i-HA301e6m$t1"u/&+W$0Lb1N%;?!p%O?d!n`o2VRd^6INgp6V"\MaUZ"ZtVYRk,K"JBB%%g?@\0R#&0-;6#/Ur^;Sq];m.7NOfh$ZR\.A.;#;.Y),$eAfQo6L1T%R6'hWh7B8\bUD?f)W36*/D>I+/Fkl*"(TK4EPLr2dfeA18`,]IXpo)!IkeNq9) -%R9%(SpC5`Nl4psuJ+l=ZX(o>FiZH'N!$'o0_,hZ<9EN:!JBO3>9C%5#A9)Jg*!S])o?nV=-l+V='-8CoY09]_q4saL+V6+1[@)WU -%R0AtW9'n2(nZH3sK.<066]$U1:nn(2]Ygcs>&"6+23mr!Vc$fU:qZjsS.&okf-dDb3d&7I_tcIZZ[qk.W85o:ppVclQX=qd(L6AC -%H8Uko+2GH+!?A:4X_lm1(lHgHqVCPlH_;/g(3O:kij'-NP24aJ]EP-c5R1.P)8s1El6'[LoNm`J:>T"'"2n(%'h6q5BW4Rg]9Tgi -%LTt^^(*<^A?\.k1o!&$!H<[D+V"(Dnc:aCR$igo:,@o!#Y*Z(M6Ytk%P.#\V#`i&n;E\QI+t@5AkmG\FS.U9=0*GR(V4-!g-2O)N -%2K1d>H[Wk_bN=.>XffEoUX")37V!,gC%QBDpaY'j]XJd#l+&s -%Ih\%%fMje60"C+o1'jk_WmnTfrR`h:5S1j+f40JpWli5>G#b*q\6"5h@YK(C9$hFhZWlUkbHKcMaKWrO!;.2jKiFL/'n8,:p+:q9\b-jA+t%rcGc\Ej=BW-10VRm^:Z]8boAjGQfT<'8p;aEDs5h\2',C7;L(?3.R-m -%HY(QWZrN4^Esq29kW"f^.@c0gK"PDKW=H5CeZirf"'G"I)[Q -%D%"Q]:BfRSo_fUgQ>JET;Chr>:=r/4cEM[R':-!?jf?0dH)C^Ke,.Zq+4U^^$W2&kf1*5)[5P']?:BUI.D)QlBl^DcFHbVV@r+e. -%X(Zf'+LOP9b>^"N0rH2$KB3CO`>3nh$7Im%kt3b7'HL&QeSeB$pc0W6L*Qhe>I7:_focCDVN[s01ibFWI'?%&W,7`45Rbt-C+p"1 -%[=rel029J&#H!#*WJ?"uFXp+sYSI'9-K0V3(mO\_KU2F@ILcqn"mk^n(6P4["o&nfOr9t+*C>!P5*Q7Pidu+t+N`RQ^h;dc0__8l -%Zo'_F#QdFI9Mk[6)TZ!q-(#\t2ab93YUG`W"*)n@q!g#e-@- -%"k:?S0q?Q[+7LJEOc_68)Yob>95n`;k -%mUM'Yg$NjC5]$4Q0:5pu]E,g_gMf`HmqS?!QlV\AB9;-o*D?0#aE;q7rDpqp(7\p).TO:LJV2jt.tEl)Nr.#e;*Sc,[FuL -%XtQKS1XMO`^6Ec$A\pdL*_M%%#85(8ifEcU^6IW-F5V!P!TMZAl200FacPE3*3#0\N3`*Q4$VX@G)!2O@:u9c!inTgEA!`gD6](F,qkK8m81o`/FYAo\De- -%2QaLL3Y.^([1$NhDu;diTFK.2"PJmuU``NE42@#mOXD9j/IhMR4K^dI:$Rb7``>4)>R@r?j'h\2%Vsn#eU+H1DAM,K/l'k%hQ/:g;L67(uB$3RZDli+r&C_].MT63.8]+DCl[jS.5P -%8;!bJ^B$!B!1@*t]>7HNj%D]2[HNCh`lgI1I]j^QIW@A%ZUVI=m64^M?sm"jE"]4k!H=X.1*:a5:rp>M7#a:Rn!t.YAO#-bQ;aI7 -%V5R$qs6(8+=A%5/cQDSmUK!9ukYb::@BdPGJ@_U"ajV_`s$MAYV$C!\UmOOLJ6)^d3%GJtt>@!pWn[Z1WIA+6")\s0?afOg%+4_>T0/g:#fc>qj/C@-_E^*aE[r@,ZHAX+P[4ZF7rq[Wg/1h^OhjrB;H2 -%^/mn1jc#2Q/A2_+^B3R[SO#PJ)EkU5']93aFY(>$\;43WhcDMT]%#i_hn)$#RcY/N9XnS'E_D=84Qr$mn&m.6:Z-;B"8)gc^k(8$ -%R1*ZH^,o]s?F`Yd:?18<[t#qHj4-Q^@A:$Jenn=6o;ooj3Y-E+i/Rf$Xr6#3>dJ7+lQD]eLGS)h_q$BPG,uYJhQVNbW$VL)NF()' -%]qp0:kq&K-jc6/Q@o.<*D@j&Kr$Dq8p`8$!n\"Xp^*ug9FB=Y-GajK9d`Rro7jk/ld]V+ -%$]E`8hYfIFhY@KJ,i3KIp[t)pZI)!#0.T)fTnJ`fV(l?Gpkp/[ERD@L4tFEV+*7OV9!Cg2']r6[jJ'?3Amm_(,)Ed0E6/^=.b1iD -%d1V9l/bX7bIJ!A8#HC(b=Np7kda9B(XT]G86OE*]V4qjNr^"/B:ruS6VUj5f$o< -%r@R5<]P2(_iY;H'DM7$L'BgbL$J7KEdN=3bh<"nK$uP7'X#2]&c^I@e^$\Y+(S&qI0\EOf7rl1qJ_B)O?5#'5G#-E5m0:&4J_)_n -%(+`*bMqRPuo9#/J[Qr%.4J+1D()]Ep;QH`!=1Q0!H=[\Pn=e'=l"h`3fk+]1.*\a+#Kt+:+'71IV_-qSmO#8C$.$(p=9dd]>%1mR -%6,PFE\@$0WW!ejG]Ujenmd'r!hl?FR+O&dh.+\D?g@AgEeEVVN6Fe+CXJnW%Q&N-WGhneMm?74`k_S>[;o1gmN3[]bKCbcqWH6k=$Mlp`IRXQ*Bh-u:OoY3mKlk*["kTF68,BZ[MtHWAkH'K*\m -%/$f)l9%U1&XYcH%II-Q%i*$Erj8tTje\u>o1=Uk:,7G`MlON=1^j2gEm_f[,0i+cS_O!8a`A6nuNfnJ8fe\>lmI9p6Q-ZHV]r#*Y -%DoLM&^6B)P[/V2XQ/G@ci.1S"$n>VC8mG[a(nl,*J/tUVeut#G`B82V -%L/bPuN8@k*(rd',A`]u2'^bMWs[07j#`W51\;-4mT?pUH#(Va&H@/]rZJu)^a[[Cm9RAuq6WH]C*Q&^[d9pa/$ -%#Ql_,LN5"@UDXd'c3%$L_El6$iCgW`fnR%c1%7 -%RK+])[>4\\;VN&l'MQ3Y>d2lAVqBZ)j:sj.$Ic*q3ID_f<+*Z]AQBnXDu>!OGF/An21%o%nX&l>; -%D4/'`i$q_Kg`pmW;oT_sV@0+^kZ1/*bAoeRcP-B@h;tB.i@N=NC'Mp_."3)YlIlG;2r*%gkAa61p_$9kBbA&CZE@h+'/ohu=BF@7 -%n,"uN&A69WXSVAak8VWS=#O(s/B>ODHiN>$OIM<=S[/h"S5,6GdUJl:0;SpN=^r]GEP+46\%qk[4Rm1!;e1R'T7l17\5Ss*b*/FN -%k?&K1gup^H+8nu0K>uc?PfA!u!4n:3oDQ4$^[b#_pS9V@cSq5EXYr[W0&0U!fEZUEeilJA%Sgo3GpKO-K]h6G2cq[:IbK;X20B2m0]LrNA[`gjJ+,?r9IM);a1iRlF)P!Pd3RJu#O'&[r/T;2/=)`\Vpl^4r-4:L5q2u#LU#?`er -%`&XM\cok.W[CA(sgU!dWb"rXM7'cJa-'"%minpYn[I!YcC8dI_XXnKV5 -%"tm<\B"!*#iDDQ4aNQF7cFnAVfet_2o!@1=U,BNI!KXqm#_Lipn&CDH8%Ff<)<+OR/aCPh@;IG75.@*qbDsPaaA?3NVhj_\E5!*2 -%m'pr?F;lS2Cj1UkV->sTlssLYmaldh`CU7gk%sbX\< -%!bKO/Z,N3WH.qWjDC%gKh\P"`E%B&4J%bA+:\BLmKtXoqaGdhi]1J:$$2*UgA%Xq=\0E=BSC&70@k1a<1EB#21TF]O&^FK\g, -%]r($.k(^AeDRZ.10ZEGlEK0W)hgOA1ZhDrNmegXP4@0EccOb]k2s8uRgk"]FmPT2)cR3h]Y>R5i4)W_phojuHd'If<-k;\oeYV2r -%4mk7!"h76O75O8I6C/QA>=Xo\X&+@_P;cFJ@fV9=W7B&$)s4P5XS3%-`6@Ok"7*Ur2>2u2J^c!9H,Qh697D&un!P_MdPJ<"eW?Eb -%.\EXCR!J2Hd#&e1)Uf`X!eIll8$%=+'WrJJ;*edR!5&id'\*Be*8nET2)$&6WJGbRUr(_Te`%k]QXYe&=>7%(oZ2"_#JaRNXVkt0 -%c`/$Tb3%IM\_"4&igeE*RaU[30__#hVqUOrBfBumnpW[.o1k-Trh.G[1^*?+B:@nX>#oRP5Tn9%jRDq6U -%4CGO\gL6dRs1<`0c=^kgXTRdTj?p`er[6VHF>Wd,:MpjCbp\=r0M>QY-#^j_7\j#>Br^mR#(#F8b')oeC7_)8PFsWcV/UK0(F-Y1?(O_mri?bY>k -%fs-JJ$t;8IY>Te(0sJLiYQ(0"-\;]7R+L+E&9Milr^bZsJ&4)gV(j2NGF1rQq=2&Iat7cH+,BSRmF,M'pB6'C-?041%1LIL[:XWt -%,A$Si@bPGgO4qe^*pJ.EQZ@&g.c]ZSW?d1T%q^^9)0U;U-o2=AhsN;`2H2O,*hf\9OV8:=A7\jeBrK^!Kb)K^#g5++!duCk&qslbjK+b>m@T!jJD!Y+#FeP(R>L-IG>l)>n -%J-pIg`Ss3T@bI?3S0Rs)P!WP6AODgWi:Tpgc\8rch.Y9uB^euFEn')TiY2]\2;N,%$HQ!JrgY+Klij+TcQ9C]+_=HV1:LSs\@&_b -%U),Fu<&([pH4PDL,(U(##]=?cCB>2^ke0+&DQ,%GbS';+K.;edHfY(3Z0f(UgZg$IhG+DC6$LFq2WFV4SnRe<&?f:qhAKZ@!YhNl -%TLuslcLm%]B8E"ZMXXn:[Co[n1<[3Ar!*7*c<\Pbb+@&mJQ]8M_o^IG["JG1dm,[`A+$`$t."H9--1\8EnkfCZO+1j? -%;/1YpEaq$/gGW^3lR5acVjZ'QpLoG5**,Z"/tdM`VgV.u+j1olY4,>Re./3J35P((#W$A%8j+-*1*X0-r,kpEjC-J;H^d1F6(B_: -%8LC!eJR'P!o*n+D>(2q/@4Gd&Im*Y@8*aMLCJ:U4=LT^LH8"MC\'6SK!nnjWhR/IW]rg%KPF-s2]Q%F,&(X87!Yb3YM<6;CXhO;mE(ASclIC=i7.$DW8qG0N""H$?a/ -%p(>J*bn5X*KE+';jp:D`E/nnb(J*-H/9dTjFPdXK_Cn`2F]n(@ko:',@5r!a]HiDQ<]Q,Yd5H[`!Ld0$G]1U+C\N26l.7:'39Sj%=GhN2s1#+m.uoC&N2Zm+]*g[_LG5BsL":K+-C%nE#Qm[A6"f,T[!d8)/Ni<&LYr^?GGUkFb3"4S@Df3&SY -%X/1ihr.XeUXj[!Yi3G^OcMMV,;bPDSZ<-e1L\U;Zj4cYbkV0YU@Z:]_-`BO/di_SV+M'J`=SeQ(^_:H6S-K<5RFY -%<@Rm>BF_%["L^0^FT]Uhmkiu"4Z?tT=AnXSe_6A&05MN.IEn7PGH`!^bY9XZkHOZ?1oK"`N*mFm"XEKm^k4gFpSd736pAn3f7^;> -%]gCI"h1W!!M[i^&?dH4[:Mr\XXlUIsTPU9*]!LS,aIJ&jMtOVV4>ReLDVi6qB&%u`\KT/GM'.YB#0>..:1Ec6g6q3!(%rA$.#[7< -%M3A?1[5)kd\M--C.DI(*".%_:cLO:T]ZeRd)@;;V9`.rS0[5Hoo]\Jcb#;al!d[+boKE_sm4Z9!X#e+>nKfa:^5!mO;F'>68lkD6 -%qj,sO+:ujtj;S/F]Uij3F+2*L1qablOhBnriq\?HC.Vud'UR8`q90uq7elra'e1Mb)[X(0O]cUV,P1de_L?1lQYdiiYSs@TKrf?" -%N;"%[&?@c.N]!M%ODZpZM)4B!p?Jc*I2Ct)-H1+]O>RL+YV\$*p4a?3m)f!AA.7-,0gsF9G*!QY/HR>K$l@P8NAM`6S!f4Rd=hg< -%9AX9?('AWVN9s,ik$&JP`lA;pIj?epq=Dai>V#%/_LfUKBB4,#.JMZ5'MTO@5o0QC^@YWV(*$k#H'LM'tr>f-N -%p/%b%aY72?I&%*&g(>J4':+kJ!t,J.TVjKp]lhnEK"#\`;^H^bLtJbn`Y9?)r9f54.nP^(>C.$VeG -%3041E7EZN-3CgN]#$J)H>AtB#bpig?AW_Se+hj@4AR*^)JfmjmD&GPCR0t5j3UK'p,:%)Bg'Cd]WU@I[$m;V'S2@VY]OrbXi>P=W -%K-#usLGK-aarl.[q9XQQ3C=]g4Dq\8C+0Ue\"=as1dR2-Aac$Z0c(R!1@LV)nP0)g*_G17Yl9mqJ48H$P!Vo1MHT6i_%8lCIJ<-Q -%kJ4aZ5pQe9^c-Q>Or]97O&@pf\M,tkKim[3KJf.(2't1IMVPt$btt6/"SECm)nfbR=h>5,:VB^N2r1On0INg14 -%_VJE1q4&mLCUb;lS0BR%;(Q,(+^KOdZ%T#F@E.8=-%Q)-5)L\uHJ65q"G,VS3-0;rr_;s.dLa-9c7'dg-PsFl(Yh^JTkD%E#:4-h -%@/U!Hp#TEu%K!u7=\hPY8M>I':skD"UpEYk2YuTQ)R8gP)MQ0XXP9_[gFX'XTDDF>G72/SP5U*Nk&V@=r3W=%2RI4oVR#:$8ZCIiVS/?ess.(c%BX201/IZ'F^#7WK]@ -%FD&Dh=+of\11HI*pNpMP.[h%KSR&AD^ZjWE`r6rFup=+@G'+0H4TJGg.PuTcD7G`u6HR8js!IbXu3)'s#VD1YCb9+I@[$ -%ad*B^1+5a%]M/d?LG$S6XMQ>^>"'4Id#=Wi5j"H6?IRh[R"?3@\Rc=WH\G0R/OTR`$sO5l-qf0*:ff)RL37AOZ8Yk5N'9jc]f+RU -%9K>3jb8$Aifj\DKApBVVlSPC\?r,p?W<-o-RUlj'GnL6%[9Wk]=c-(\`s".KHJtFIg>3^T?Qiq6]iE9ZKpVU-#nRu;]S_).S4A1K -%9'C-JO(Of!"^DYq^W2VUug#0SR"ONc9O#[lTdQ(\Jk>+M[+)cFHJaQM+sXMC)_Xu&hkqUfJKb46ZlQ[&+6PENR/[0c4NG?;,= -%hKpU"Y7h=Eb7KD#MbkH_#Eu3cNS@Hdj*7.,A"V=/q/3HFEpcCLZ6b[`0'q8B@>=0G(!,pgV,Nna.u7L`*pXqEl]oL==,q;o.Oq]5 -%^B'&AnHU+-Y+4]j]KOq*Q.Ssu*bd3lm(c3WT=Aht5"8"Q;Tc;++@#H?T\u?U$L[B94THoR6=JY43UmYKq*["S_]Ineo*P/'q1q0M -%il(<-#[>8LDpV[H+Aulp?%e,[l4_6kH+(q"6>[;1I@omGB&HHc`UST"jkcCr7h3MX+%RGEofX\OT6n.i%JaK+TURP).1q4%!mBZ1 -%e#;Gip.BEmh=2:@_rrB7Fi7k\3P<.C]h]L\k7Ooc;KHH%!#ZN,_A:HfLKh@G%3J@RoOFts(NA`Jke*V+8qNFN;3`u3t>^`jLg?sXPXed52bJ/U98bSgo,r:9rMd%[J.Zsi89[u9]Zf&Al*Z*n.CFp5,/d9lBr?d%OHS&V^ -%Mqej`VtV0g*Mp&0MD&c$[sI-Olg;f=Sf:]Dq_V^?SC8LBa1DSYbY&t>.0!sh50GiZ"/EK_44^IiX:,*X!8Te"42n+Ud9[[`A)TAG -%,"2B&,>>9uK0U?Yl,,;$;M#@!"d*-l@655tI,/k90D9_sbSGF34=V.?/^aF,T<-1P23g-+/js81M0e`()Z><#k7-8[ODT_=[rIf9 -%hS6(l-X#*Nk7KQtNJF(eM%_]o>$%^R`0.Br5n/s)V<+RLMg/]qp-'K2!)I)baW6*I\tY*Ub$7sVVrr5$Of,Ufelu/D#Dlt).cS\/]&T?n8&'60b$tSrgG'&1:AbM -%/Ha)Mm(djA76.Xukhj1_,\/&P$Q*+B;KpaVJH_"[^gL+j&cOsoQbbX%*kl`NgU50Ub5D -%b@e_U],o8akWZ.%?f3+g1X_^C6;`8T!%UL7)9oD0B9,-"JH28^=QutT:`lM;]"g]V`_"e:7AA3N/cM#_Aq@lu3!q1pHaIRF0 -%&qkJ*CO?8k]Gj-X7te(g[b-sa@BWN)1K]pg.nmM/M^)6Ri,-cO%1?NLkt)N7&m)!YneH#JS0h!po*hO4gJ&!'kE-_dDEBd19^>EH -%b;S.cndX%0&Sf_ZpIS)F-aLc)>s+6HU$`&IC?k`%nX`1RlIssFRZXT&"&gc8> -%P[t.$pjA$>QIF'hY$-'+lO:'i-[QEu&VK7.'e@eE\%iPYE,-@Cjc>XE)^s"r..q=>-hC\^3@I%Z+42aOpA<@_C2,>_8(k^=4qY90 -%TRu]#VfN_p6a]&>\iA5q!Vh&$n55[km&X1C"#=oH\=s3J_LcJbg_'JE:!%rlHg)Lk[/>=lp!tcCc.D-IMsEYpY91sZ#\D@Y;.C,7 -%,%t]H.dd]6q&&($>0NCS^s^Z>W*\8gi2^)e8$$)'ZWfEoX@C>e#VT+,;S'aHC'*s$Sf)+['sZBgMG%dM`u0oG[Q57X14oKR*\--J -%CHXZ8p$dR5>[@Z=DYC#LWECVihb<00KEPGKeTBKf`?7C7*DTP0roph'm93@IO)osMV9n:+&&l_l=IfNaSB4=]M[YJ.e -%QPH-)/XF$Uhod$P'S(;?(VJYi%q<*<1P:8^ZtQGoOql8/$l>18CCBjm.aN!@:DU_A:!YNMXATP0FSHKHplt5Y.UuG'[FKM7Z'kh; -%-/VMDFDg[M=ct;_@MIDKjsi]*6P,O7%%]51#KdeUShCD*kZabb2S%Ym"CuK(`i*#&a]]Q6Ks4\F5un@P^"I0Mq5-i/Y=p:NRauR2 -%1.EZ"?.UU.BZmXTN&&fGf?(:`V3&G6%6j3#X_sf3nZRI:Vi9*gH_S=a^Oh[+`)kTb+&*J!_Jk=i'kTiVq+c_?GB9+jBm#qW&%cnH -%^lCq:-o^'/*PjCj("86'!bF&PK(P$`GF4_%:Z>;6>TLJok&IVAKn2n.2G$s%C;)LDJPH%5;=ZlBmm.`CZkeYBbi%i[I_TI<[QNHM -%pr>76@#[;Jn)4EMpNNa6oiX5R=1qC2]"\7jr0[?K,8dG-qWA^ln8Z6aNa&j4+YGb`3t:r1DVJTPP?QLU!:EX -%CtQII0q8/5j,SgN_PV[Ad:>3388XQa!_@Z*cqkSGVO-N69..@Sj=S1lFlMt*!qNL2iD*fmZs\[\jp59*QtukPc'0-?5.aP:jK>n_ -%FVsQ^qj,KhV2C%^EQKP1(5o9!,s6e?jDEh`dlVCi6npNA%%q(V$hW]C5V`=`Hs(ZR3seY;O/5pIcf"/C8!)kj#-OBhCB"tA -%,h"EmZY/+(!9BA%YS:%Ej1a*>/$jE7j/+`2$,6TSU]?d>V/9fcfbq'6^^;uRDh;J$nBTOahh%F_`Z`-B'5lk/'3Npt-K)to'3`4D -%*^)aP;/annd]h\7DF?Md9H2+Ndn<\)co-d-jQd"0n&tPc"q#Dm2)#7n_*_?49hEGW$0RhlK)=PE-Mp4_"u2iJqD;k>/"J]1bS5"o -%^q+EqbYAM$Y\1^5J@=3r$tekI9Xh9pm_K%*GB4ha.o8a^KS6if>2\t>U&2&>*5rmDT]HjXX?9=)-]Z08e>7NApblqWNCN%4jS?pT -%,AY`%7N$c'd%]Y`.<^3*9oC6)iXIN@?Q-QsR;$Z6[*Kf`SWLY;4BF[:'#GRN1"Oi"WQ37$PA0o!."W4Oa7)k/>T:1!!WE,gQuAu] -%8nMnIn$LQNF`>+5ai3W`-R7S'"@Xe+9=C^SVe-q'rkao=?.$m4UnYj9N7U3K5bG_QK<=bP!INU"#id3tQ#nX+PZD?& -%bAIO[$@Xf8gF'JNdr%9N,F6Nfc&&6q4@5)X/k"JiT\L@m#NV;EAHR4Vb[-m`kNg,Ak`b'n5364)4XV.%%rh5O9:r_WVol33H%@fS -%P$*nT]nZiEO=fiYP2MBLn/+CH_"Erdhlk*]>P%J*-o,JGMk>VA^Ygb>7.W4s(p_WW2E=c\)n'VL0Fpt!5fYa-AY5&2IX7f!VPI_B -%1X_LNe(::r13MtW;oebC'V(K4Es'`pa,p%TmXO9K3(XNi7f4SLHEPGe=m=c"(_knGZ7nl&-V:#5L0*'h2Gfh!\0TA0A:*JueO,?B%VhDe@mJ!JP2/-oa.;a,hPM9V^r=B?oW,H0YG+!NJ([PAtBK<8[MA+$_bQF6lQf%S)q7ju(i[ -%MI=4`9i>fN1te+SLB;o)f7P'12CGs.d"'0!B#\RoCN,GWr.;Q5h_r5J:1nlQ8LHobh[\MPerm)E^*d'=`\0Q%H&Jn%*E9M6SXT2V -%k00T8k[0QY-MC[\%uk]EC\\/BTkMYbgbL`#c_!"^k![-"/7*8[^!YW\G:M%>N-d1G+qN6SCCAmtga-M+Na%6,L^@gn9frZ*m;e"e -%rfL]rP&Y62S\\KmKd+j%5'JBOmG$F@dg;@,?[+MZJ&+4$8R=]T,*br -%`S@%,*Op/@W-ZY+s!&Ze`@PQt>8d$K1_Xl"-B*`)oI/1F<4#qZ(=^7)aCP-FDBnO71/_5mL#kfn&*Bh^lnCCV-H8;CCdsO8[3-), -%W1"pQC'sFLQSUNCeBfC/&4nD=:3/*oLObX(7eWlE[W8'hRa^[WTXn<[$#7R1MW2mlQ6c.(&MR'8I5Sb?hFn+6pCa\o2o4rH$`l"K -%"=L2:%%HFlcU)-lb)Fsd=\Ao'#X-\oQ@!^7_$nOjGYpW:Q=RokU9lV.?<6qNdlrF-$gr)QD%`7e)A\k6f,@-eLCie8Z@pgc -%BAmhbS-p(SMf.WC4D?DnB0%sg3G^U]0`l-HO*UXl:IL&Kf9BustWT./e(HBE)co!eC+bsi+;@f1! -%!nKjAaHa-N($jS:qV6:K1"8u_!^QI0n.F14fLlcF=i#j,iEWuS^?okJ_hl;bqMDa-<&44=,QK[`fK5L!0'!]C_bgi`^.Ope(2JcJ -%nN'LM6^^heD-1]6lT"bF(lUD,q_r=62\LYuNtFRkDr/9h#0R*Z$jlKh3Y3ulrk!9KFjFI=OoN?e;t&/Bi+BLA=(H@X$gu;5UTUMhXHE;pgG$nCD7!%S3o_#>$a&TW@a3Z:IS":D,&1(W!/kllZLNf;UkE&GGY%r!`jabsZ&W)ILmu0&$9l.aiKSFMCZ\ugAo9`$ -%Zs=BEW<7$"RLatsgBb6upJ;++J3@ApW:.'%bE;3Gl0YX?30Jq8E9&gAh"@'\K3)]%h%YbVXM?rD7u -%UL96^oR%DJ5Mm`YAXLG&SoW#KfeO$tGQF=30PPqE``+^qNPEM?B\6&g=*m-'5DR3_b1##76'PE/L1Y0`8F#=[%C>P8hc65u3Y5B' -%]2B3@gfqr^1)M=^VAOXOFuk`X`'E+b!G?RRpH!!9;L@%dn:r&=WT)QaH#':&5+,V%p^CgW#A&JVkb1h+3?9I/BI1KKp:qR?BV7#h -%9_&hmRNbNA7NAdG%mUgRWFNeP;s@u7aJ'E$KViDP]CR\KQ">^i[Jg):/Ko#P_G15qILd+poR_'E8OAe>2O>LE\P(##7_^s`2c"Ka -%YF)Zn->.J8.O1`@8cfE"WtsH[F4IA2G;QY5M,t*I)5,!$CoH"**e<+`MA@Bgo;G8PCMF#CelOQ>cD!8-K@&g[)EeHd=]s6+3Vek$ -%jTTrG)[2mDl@^Y,nM%1M-r!g07^Z-844=Nm[)_*`Ub/R_+d^+bS`q]K!]_phabMGqgTh0rFK:PN9h6',!jqcJlTsYU,Y:I*%34?Y -%IeGCE?j8P9p^I6c./-J\i'c$OPCW6-<7"prHioCfYb(goEjSWApF#H1__ihARQ0f"';b>N(o;_1b#^c@0NE2f!l_"QV: -%1;qf&0\9eh2mi%o#h-0@Nni9M[u?q-mO,i6D8m;GBI>H7q0i(O27Y+S;:VO(/@6:8hL.Pp>!Y -%:^gb;<=f:Gf&I5b.NuS8C`b&eF^*t&TGo6Q%0=M_XoH``(UMuH62'5Z?lX*%fr]mRMREZ_r>8rgfDQI)?GYqZoN-8hfl\4j9>Qg. -%Yl2h.!cR#(%<&XIi@WY&q"%(nYtH0(`7^1>^JRGK7lBe+(P(qs#Q]:JGWUjN=LZmP3u2NlJd2V/4"Lmm&F$_';=Y&Ur8I$cpSeHj,fh$+>OU2dO(ced4%:6q`_3C)N3rl/Aq8?YO@mOZ]@!lP.c_bWiLZGPm4;eQ9c+-fF2m&K!i@)mEZu/*m?@k<4L6%:$7%PmB?hQ#sm+8B\_agIr)KPYf#`UN6MLL&60_^ld/F03/`FOH^>AJ=^TMI#K`d[<8GT+kLqNKBAW -%TYN]_9F&W_@n<+N^+>;DE+@3@Hl& -%LoYX''c>?#W5>,p#g??.$D)6Mh_U'ki7D$2'.Z0_32((#EWITH8t(,_N\upoO_.#gC+lnijAj1#1Ec"OP$#&AoOKe_p#'=a^/pM% -%4n*5%"d&NXc6?7p')@:XLc5KI4^%MJ>)%PXg&(7!>`uP:I#jTV`/5UKL;k(L8qbn1mVVD<=>a^dUc3LZ!g&6,O'S*G/XX.sb:Af) -%f@/Qs2]^??O$W1O*:2&gnRBM1+6pI<7Z&ljqcAM8#^VSiW+"`q+NI,o\88NAR.1h01.To#2WJEQES[Kg`>.ar)=h:gfnHm0HY85W -%]g_A)++mhYl&0mcCWhZ7Oh4)Uei2[<8A:oBr$QHD9F+6"!EO2PVr\fD%+9;nc`DXiR,IaO"Z)$6Ub388'&X@n-F:`gb[J4Ahi7+2 -%MUV^(#6h;6)F5Fq^j9,gfn2';9A=c[]E5q[``FQjg/;Yf#H8Ck%*]&1./27W09J<0_AoiE]itQ@$m"[9empV+1G#C0p^"I\k@915 -%>%K=HM#Y3P9Ei2_oYJa;=j%jc>?25rhL5U*#c2f17ed*\OZ]^r;;sAtp7Pf(?'N[D';24\V5^IF.'#&oiB&)2M -%acik76Fn!0>-9BMM7S3fbbPr'#ZAMa-isaWN'!L@iPX'OF#(l8!;`I"$l%RVGAg@_X<&p\1t^`ID<8Hc0mLDAU9lLKU__U/J2f$, -%h4,AZD0*G]gC?m(lBCU?M:d%UX'L%/pi5`cgutXE/%[=kj3Z'-DmkC%1I1K, -%cFAqZ=hA7'o"NVO&X-Z-f>>Dl8iD!bnJ$-m5`4\5>86O:e4bn8PAF*VfJO>P<"'20qd>aXE=9Ao#9A0T/'El%FHF-s=I3l89UHU% -%kKf:hCm-"^#Hsu>7p2(piPYLqqQJ"%-V2G<@a(ps,&i(*?Ee[/nE?@,o;1^qaM=?Qh_9LslOFb*!!^`tGn6Q?FY]c]7u&`5gA1h$ -%WNqOGN&BKYljd<9m\\QY3L@?p`sUZ/i&0k-%QP$=T5.)Y8ff<7J6_P=r;8\.V60N>=^q!%'d)B"cU5JZ@#5&bSoK5gE#tq^hU?ba -%4cCLe;Js=,TJ-q1&uB=+UI$HGW!KA[T^#&r@S6*ic -%!dEJW#7(9XZmB$;oD2X">c8+^rRT.SNhTT^]9ZqDKtQ,DDqCIHXD&V-pg!ND% -%A&&cUIM4scd:+Yt'L3n,N7Jn:p2LYeU6V@JJL+=@>WL_V4rZd+g'!(#meI^YI9MBa>04-NPH.paA@Te1-_L`An0%Ir%]si]4tXSM -%r);?9m`-A2s/EJT=9CSHe2#b3d^7`^EXW[m_5NC2#2DT^`YTB%E;Kdi\dY4-N7.9f5;LF,%tq6 -%!m3L[H>s&m8/LdeCQ)2poq4S76%Q-C+56!FVUScUBZUbsa1+/dAD,+P'mKkPaR_.'+Qh:PfYH.R'E!:m5`\b,\E]lP4oL>NDI&Z0 -%T9O.^-YpN^UX%eLi>?N$C'*D)r_]\2q4iK2b/q_2jA=?%UWu2o*`pj;k_!!o7ZiQHP?i*"\9I6P3)@An47'[fBPtEX(UI9R>gV.+ -%H:EZ2Lr8j4YTC4:Q;AUFLZK?L$'ZLla0@B;a)V\R.&V'5"h)WVQk$uA&+\Cr?LU!O_8tZco/p-jbq>U#RA'VWeQ[sQ-!*-(6"Pn1 -%YQ:oI"LkjqT2WOKSU_:m)*Kqb_J`c0P@2.n$uJ!YXP0_MXa^!K^M*^iVI&RY"?>Tg]e*m@$oV"#3%(PTChMl'YPiR?ai(FL@\&]- -%Y62=.\!G[@J&"TFTkHnMWCV<,>ch&lAq/]r$',04+9r&-F'(c2/\sB[1TWTi=Q*kS-K3BpTB-T+7AT+d[ar+WAu1)C1,=8WAL-: -%PhSr$G-%7+Hk^EX`uP!28]DV'?*7S'mX*+lN.urd0OH@dWUg+,7rVl\7>LJC^B$VK5Fu0&1Z-7=,C#M7l8NS-gHKBRNg&lVSR2?) -%!cf?h=/bp@Y?O)\FK<28L^NB'0UY01> -%b2iYcLG'I"ZrJfVVKU[+J\iU]TZdICF:RI'^W430D$`,""h#J:J1\k.Du6-hH?90@O9NkTdKN1r-K(?&lop$/+3g,HIkH.:'<)4p -%\7lJXF&B`cAM$0U[8bk&PD9>*f7a9S&Eet*TmGGpZWdUm;;[Ee\$jfDK>(2IhZRoqD%@<,;m(lhjB_150EM_/qu!@q^b=9Q6@nMS -%grHi4^%FsRG[9$Zjtd9W!]2""Kk158s*`,kqX91mT(u_ljCL##4,a^lSo#!$anb0]66;_87hJ97%u/&J\F;t:M84tpG(<2epo\)hnY-@$3=arq%C'Q_=lN.Jmi/-N*"1TO>e_upL\-L4X(1N^h]/4:A30@8sBalWsFp@oW`Oa+WNFi'?%MdQ7 -%e*=d9GXd9e]Rn#D(5e`7Y=S^Q7fuPa#9"Rn(57k#6[M+0R5DM[7N(tDIQd;s6o301@Z-co2-B_7<0`3=CkiH(]+r*KFc6U_AaLc103)2"HKSbX/ndG`CXSclUe/c2+'6t_UgC!)-3?ePm^qt#/B#^LalR&ek$CZ5S -%n.pAek-\]jkWi\5fa..DD+uZ]hh#U`ICM(9qW^\A+h18g(n"_)PkCK8^cWiT6!9?/]*mm@4(DM"]'br91FX_7q@pTUF&;&kjl+$u -%pgX0e&hHW"$k*BLJp08#/1`[lOq5(e!$3DM"@]JGl[nT7VJ0ds-,\]:6=$?qYZ"`n45K9;fIOF-'.@5m5O=]iK-f=oUtXTO9Yi/9 -%Pg7&.El$RIBf-h5OFV[&_i)R7JkLQn4DBM%5oSD""eX7a$NBcBj(#+%_^cP9(T.9NnUUq^2ZV.VOumqZfi-7u(^F[".Km6n4K!Kf -%#LF;Pfi-C'Z<\:NE@es`Gj)\FF8S9:AAm]A4^7b]`2o&,.mc/`,YN%<->)co,^!=SK[kZLXs=BZ1(o<-8]hCl@FT+2TV$k(Up_]g)ppK/l=Q('M"s"hVK5-Z9l)a\/(\3al^b+SB-<(?>I8.@Sf=&%TB9L?/_A(W5YYi8$\`&J -%R$&&G=1B(iEc0!"C./@nOT,mqYLE7]WZmIR9gJBElHr`':s;_qD7Y=?_Yh+[pgOY-i9$6,E5Xu]7+t5O@)S=S#/k!&G,gWQ@l]/O -%`lPQb=lNRo41)RgbK5jb.iFSm,&:R@5\77^co)'3,(_h[&VdeA(#9VtaXH(4R?oF(,Y(T6bk0^B&jd":oY8K:tpZRS9,_T->Tg$#J_"rG)=kAU6%^[,K`.uYEVP(po:Am@/#W(0#PIaAmm"[M)o*pg;M;blKd%A -%!G9`&6Rf8a8eRgias>:<>MU^cUXUKb\lm;/@FP[qR$?6cqN`@qsMfsq:#(;1,Q'f^Gj?e,H[\ji@fINq8%0ZX; -%7;[DAEsJZZG\gjQ<*++4fYi`S8hP5Jg&d$B/7bPQ(Q>=67Sa>`.[5pfr_9(.,?ZLMY2A_!T5%'(uI^-VJ3HX#*Y7Y#nRY6QNY&Fs3UHAq"CYk#91<% -%*d9ZI2mM`k5l@5&!#=UK`QCLfUE\Jd^jXMG@Ga.c,R;e\[;.@WC;$h0%;I5b-"f!fK!hVL5-3(e_g\J5@Y(P#?"g%0D/q-u=&6SS -%ILdZBi\K5m,tGAIH)VY]Y&U*s]VhMtXHsIaa^8\#dq_")r6cB0TVcel2?L=5"-[6WcLO*kphSt(30kT2>)s*Wk60;$0,2W.I19Lk -%U[0XAEN4:$ln#bqc&rB;+.L<-k'\maH7R\#)$iaps-Z:4EUqI>V]A3kiu=K3*tQU@5,P!i[S>K&5)[7P7Z`t(U:L$oq]_`b@StnXI"o,K.'ng -%+tMM)E>u8ElPWdB24:[lQ;9=K#8[]E6GUUeBE==$'3XgHC`0*IT4.YcP"!lDP\F8N,W_s+fk3X5eWe&69Li[RjT.i@,b1Tk!1#dr -%;[!GlSL);Y`1le+q5(C)9)o63oO/3I![l&D5a>WeWs%U3gr\SbHe]odpI"j;4q2G@'N".3(0J>W%_.%Z0q_\09]Q=.rZ.Ea1:q:P -%BFS`[9JZ!rL`i_+=LV]SYoKD/g1r\jfDa>:]=HG](/PBiq_dh3Q4_9*hIhT?0+eEi0Ir8I1I@Z;;/";XPqUo]:.]``f"A\:3rheP -%"m6_/=WkECBZe+#++\9e!`-OhI)QIu6_2i3I;onca`_'HY;CFHA=C-nZ56MY!lM4dg'0='WAD$>9>llH0D\Iq($G(U7gKXE/;a=&/d+U.tk`(91$h?,->)jg,d-M"UZpNj$s$Y1]Y60ID4:cbQ!ZU-b9N"j_Deh@lp1rF_R -%fB`dCT'hET+$oHM!;qT!Qn10(F-Wk/.$f!W0NWit&GCe)37DIb1]b^"lUj61dfkk-e"Q^btW9NLXd<&p5cik[($h)bd,X9B*QF$m/S0I?f#D>2],J7qs1ae/\$H\a^=L@-ON7l`nb`Rj%8SM8( -%@^6nL5V9VF3pHi284'iF<8YZ'PgV:eA%Yrc\C488p^E6ri<;cC\W@7;^,FJ1HnjA:b;CtYl@>_&=9n:lk8iHd?'TJa! -%=pp'RFPSimEXP0J493-OA(?rBJt#A3Ys%\JCZdT;G8cFCI+Cb&._C0T%t.3!YI_MJ_+ZF&0TO9U@GOg8Q0`su^39F>\OIbC2a97B -%XLr<.l=_'@k?c^DSpu8\0Qgn0O6I@"7EUl:i1?T)a@ge[Z5$-RU0^.$H5+0`a#LLOJ-.#WEXcJ>f6(hnN[PYiZ<2HNc9.?N8nLP- -%B9E0Dgl0t<3#&97n0hr9JR[UK,:m:bEk%,<4-c#TPj7;O;fMu),[b;+o7==mj)f5Ln-Z?4cXe0VB1BHO#k$+sN-.s+-MCin4\3!N4V7]hfG%#cZl1C;k8@0g!-n2H*+sVb]cA)B6[^_"SeDb!#F$`&##Y>K,-!mY*@VL#VaX%+d -%Jk9aV!k\ca7u%V@N9Xf2_2<7Q_\d2LDM,hbJmgd=IE-NH^t4p'E'D#/TOrL@nB%l<`8Q(%!b?HY7[[A]#VK=^><$Yo/-k.ToHW]7nu1.AcMgX:'g>Y-KQ_HgO"d&C)+%:e^PrL3A^0kGtSEZtOd -%Xc>*f)gLpYbT5gLhSo)QRu&`>,pT_"a3@P;$eB`m+EsT4ms>rVR%nUHa@DZ!;RSB)CbAo/gs4Pq"Lh$_#2&2'L!FsHbP![+Pu3Ij -%OuujE`4c:?8aS8La-o_Sq#V'S\H=UgcI+HFL<3RT"\Y@[?;?kFkr#ro6*#9)O=TQ$$:!Qg4[MH@pro/bU%\Rc>uLf:7$jb[eq-)h -%SbX,tiYKGD#Ee23q-*neBF&SBN-T[!&bhd9*E`EWrdCD)SEd.*"<_NZhuKMR`W/J*^O0)in7lWb#S`f\FTf10Wh=lui^u07edXef -%GYS)2-GZYEh"WcU_.I)>$hOk!p#M-l/W(\6&SK-&*3AO$YRP!pLSJTB%tE$u(2TmgP/gnX6Cq;LC:S>),!YT%]b!j -%TK]tr%[)mW8:We(gG2G)%+Z*`k]KfA56:nclXA0r6E>idFG@?F@1j^,Y1eJsR/*D\&hlD>_buRfqZD(\pF[S8 -%E6T?Vh?[A7Jbt,bI3-KjNH;tHO."g@k](!]*)W3Y6eE4G0Q3a6^7l6/KVc")]YiKXaEIQO\W$hWAHok*UKbNPr;(O@"h[@M5`^%P -%FpK4OM+,"J!?,<)o?]&!i9#gJp<6nKafB8?BCao4cQIEPmsfsGDm[=6?lF:HLSU^+W^k$1"/k`Q37qd=E##5CN9Ge'M!jH1Q'ffL -%Bub-[Ya`mUe`iMiO>)((.ci'sN^:YnF]r`O7-K;EUs)U[%l8$9Md^N/uH(3r%i";cnd(mQA -%`OuZ#LV74MkL&sf`N)./UM@*%&oeCrN+KY-o/6kV;4Z#HI2T6",K;+ofe0tpZ2hn4@K';J?p8P-5VZjk=kr]F_(ZJ>-<49E -%g^@tc>-:M%IeON6Z[a,_[u'2QYU9MV=?,XY^V`@l5^j3Np;rfGp"h%_2OM6oVf)4J`R@1fa,J`-#0pGYVLVgeniIYV/[@X#cK-fr -%eIf[,@h8K&bnFKYObG]V3c]]OPBg=i"N(0=Z3Q!^O3r'=<3b.ok6h)j;H?d&Us+n_^nRi+R?VGb(B^7?/DoN]01/`VlWlc,q$%1l -%SZ*)!YtA9b)=!,H(^hs6*6R7/8Lp,0L^KN&E^Nl\#L4.:tL&R5>[FOS-E#! -%7d]cJgSUl73V;FSObeUDIVeimXFL:2hs,:)JQX'q2FDUpa^urr?(59AbN-mi&=0IpCHt."rrX+!C1Ri9bg;a./bVFd'7_Oi@/RpT -%n-8a#O)+B>N_9msQs#[#]SN5%Z#@.u#]j+W9T2Fm>.P[MU$Qb+.#sJrD,Ab9",;?"kG&Q(77$20(SOc"FSA6E0i`TV!1,Qo(-U)#q'%qWCo-.]<-\DGoC?U!.9`:I`W8 -%A3I!P`a+W,fWh_:jVB;MHhqTuSZf6/'K&C?=%3_O6KeIZ?5^RMAddAgOscMG`jm%sLkOLB,dLA'B!>k6E@n,`bXnogFnL^Od#G)[ -%55X^J;+D9kFQ5iC=:q@+e>97#`qU@B%RuB'<-amC$=qrVNo<-t7=WL^[n(Me*T]eiTQC@6LpHdK35FF#8%n/ke(p09d&+HDn:r#l -%7f<9EQZ4.R9g&J@TC9ra5gt?a2*@9l^u,4qkBn%:=6]r=JmVPqFgY7u-9oQkPS2W/U1V#;bKVOd_FcC1iQ.Rc$@CZ#=t+CEN7WS] -%q"!gtYcn;+qujui,U&FJcqnZ,R(FYO:P0CKY/h=1--aBJL,_3IsmQnTRNIM.D9;)YET?";M`KnmD\6n(THRLK*Q#6N-ri>L#X[T"/H1d[ur#6nlrL1Sdm!sVLpg$O%no1*fl9/P\cs!h.Qj,n!fBt(iX/a#7S>2bbP_\,+"'V@M/!r -%s+%>ef-'L"Lc\1<"=FtRWB;qmXk)R=$t(8mO&pS("$3IQXH:"IME<&sRE>/M[-7!pM],^2XVj,pVP$nGT7cJ2nj8^Q(U&@"Hp6mi -%UFDV)(F(mEnQ3M:`1L2Uj=2CPJOm[]j7YnBb_TNQ\2DOI-Sl*;DV#9Of&B8Gh5MMU_m\%F6q'R[,;Sq9L(P`XBY -%"rY3[.?P8.W[""$0tdhGKIP -%LiICY.QgSphSH75#%o4P/QloB<8biKF7:H"@_WqHVe78kg>.'F;s"?YqKGqiR:@qCpjLZ'oX6jSFogcXWZ!9M!/UCuCb#2Y>r)nUDV[otPJf:X]C<_m:3[`&Z/Nc7Nbs -%bX&N(6t=c4ie#U+CP+Xc3.$*;@O$]%&NRKt/OM6*r6Jl+V75en"05XKVTHa0f;6t=5'`V=.lP%$f\GFfGE4pt1A,[gCW4@HiiV]B0"GG,:Zi%7iQECfRp' -%rDPHF>!5=\B;lJm!d:o)_`K9XCKV`pd6JJW`**'K>=o$t-3%5#:,O"2=4bu4E1CTZ?h,7qqrJ41%aYR0rl5YoMeY!.J:pIf95gOABupcs]b`uo3L#-W5S'.C9:8PAe>mKe+YX>qrdbD^nL2<14T2Ol+4Vk:Tp -%$9'.+;BGT.qUZ!*?rSekaU;?,EO`m,6?m<>VR"e$_8/$F9O%*N(hCnq)NS@IPI8Wp&/_%h\dtZ@,L9gVSMX-Kj^=Z,qph$:rJNY8 -%K=1hOg[;UBK0LFUEI^RKg92)&lDP2VZ;)Il5^!RofWd5)%/5g0Wo]jS$W'>&'AQ]ak.s^LFACRQ?ZY0jTn5;hJ80@X,#l1^Pu"PEfh4PH+ki'2fr -%Y>[(odB?oC\\1<^a56M7#cm#7!%1le>@;VI6$\0sr9N\J!5]p6$=IdFBp8k51WWK_3Z!A,(GUsQCl5^Dhq%&e7E!X[DL>6f%>2>.6Js0UZkkg"S%*PhN"`6!BXZ0aEE=QpY#)RY?QMG_ARq*5nTZ>1@2LC(LQW*n6Y[*^T8GJ,3U0gO9;$`BY+3r?d'] -%JIP9tQ\$:T`\3&k7GI)D>OV2!cmFRp32d4$ql;4JC*tODUeHh3K)9<(K2nh?Jg(38.N^N-4EThaq7M?ig!ZVg`.]"nnoG.i1qI_S -%RW*drjX?L=3=+&6s.QPe?'aUMkDg:I]97afhol=FE$k7d\B=OHY]e+^@BH%*Y*+?W)DWkiqY-"^T[4?OUQuQ2b_D2"+UC'@qG*"`>DV;-Uh""Jli!cXb6),d^=/-1Jbo#e7:DOl)=9Wu"$3sqX[d_lJ$S]Ga`#)=(_&YrA'9*urMt0#?q[a>,K\cgd+eKqb=k][]KcYW2.,;%k"@Rn7:WIsboJ8/3sV<"CMO&V6Ol3FCFKjBg.NNgUTWcVh%,iTbm!ftR.CiC/QWehl4^;.0d -%C1>8IX,56"%PsRU\3[LP`6eiE(-q]IcVWS/r/_7U=;:m=C`KgQB&C9&5Z;VT^Z -%&X)[\jbi><_0J[Q0Q2dTat5=_B%>2U4fu_o.P'1)%9c+TY:Xmp7J49rG%n12qs/XAF\$IMJP4O;XkW<="_,U6ec\s]/8G8P!`^1= -%Mt//%R2"b`qZVmk#)GUG%&9OU^Y4-](?2t&P;!."[:daqjT7&;ePG&PLk;gSCP0T(-RTY`U($'`]6FA;=(H5<5kT;/NAR1FCIE5b -%,$l)'g%$@uoKrjD&_e.9>9AK)O0Ng;%12/$ONRhNQPcl>&e?@_'S=QJaNmBXa<4q@a:[M*W;VCuA(]ujpo]0Q+TfYO*.K&MHMp]u -%@H.C^r>8aVj*oW&NidMM3%h1A^o4AB7-5rG*j.(tmP9"ML/j#/AF98Ep>=K=P*Q*gDqE\YaOqd[J!C)jXf]qC[[@g,ld5sAAp`@] -%[0IS%b*g8sWj]VsqO?"ZPYXGt0n/KV*4[MQh9?iM*In(tSQ]b[Y5UHBthV4Klnn."@Oci?u4f"*(g"!KI3l@d:(LJPr'NNN#I9CFL?3-U@2K+BLt9YY9bJH:%f#b#Lfc/OZM$JKRbN>3TQkUiG+PY6WiXG>>S1m*24VjMq:(QQXJ4K?G`)d3 -%!@G:#C1l'q]j\97/ma)F/Vi:8I`:3N]9-f)-)(AYrp(_f\Qnl?\;B%\VC -%bsa`HXlMo#qk*$gf`ErLQ58ihnkoJPBSG?%N9p[Ca,rR6&jW*!1TFLjNrqo3Y&Cbb7J#O&QM$d,N^6Zg/q=l,[M -%fk(MP@65eI9&o6\IB4Oa^26c`br_9bc5<$-<8W]PX#dnBaT>79!IjjDYrB3DR'"CS+K7JPGi[PtRC;>DTq!ZD"*Eo[^u]`,DHPZP -%N6JkW9WK!r^s2nLXR/FVc0@+fBT;ajJ<'HCm:9!RI:rX'J@^S9/l`DGR5Cla+_Gepfk=?V6)`JdY@9%_o$G@Skl5AiP#?ttR.,N) -%fgEg)FUI7/rV$!aQSDQTUC.8Rm=h)tm=1%?/OQ3FKmgQddA'PDt5;' -%)O!-ZZ>/LaA6'%8%:iKtg]O%QSZIBq?Bk*XX;SS2STUS/6jM9/RSKuk,%ENR7J5Hke;uc4k#Zdan&ND^?U-FS,=hj.=,DaX.KK:e -%WM=T279Eu/'!,K0!C9uUp#YGVI^n4%B-$&iH0fF6l[c84cI,fOoj4Kc-/9g_nC+X<5u!*D^KchiA]8oq\N3VJ/Sk1H@_S.L1sB/, -%,>`O[_BR)`)0IAu,n*$UCA183jDutaT7Y/bN&W`8^:i=b^sqa^!_*=;2;o'aMlAYLDkop0`hMuq(o>FI_[aT:?SW.4PV?r8r&3D< -%Q>IuW+I#'lYi_7t0]$pJMXp('N_O75bVaB!gsT*B?s7=HC-\-f\8.qejlp6&pokf(QR;hs;Op=T^jMI6@Ia88HX&^P)(D_[GDATe -%a*RZ1h+,mLn;`A$(;(/fQKgUP3J1B=5^u;@G6*.#H))c,fF49;-Lu^cj3(!?87XTgat35'b[\=*jslW=VSsDUS8J@%1=oa_5q94R -%Km^L.">!?7!g[+F"=tom*(en5'r9!:]OK[\["@ePjTPlb'GiONLu^52T_gDuq".Bi'EERg*lUks*BmFQ6f&8BC)#]:=l7@=>r1eRe)-#^ccF"YH1K(8T5W6>EVY`m]8pTnr%dNEKG-PaPb^\C -%_H;4b)28AXXhsG/b$]OH^9Y$d.o-QPVECsp8'&iTf70lpX3C)Bn6kZW.-]Nlgu9pJVsTV.(&#*RHFUS"dRfk_1\m#WUcH20[mfjK -%9%5G<_7Ja8NeIiaK/ng]XH@%-LL47(*Y]%%Y)7/+XL8TA5g>*<<;lTL`h;!(OUf@2aWD03B_?b+"?+_ -%0hLG\AH%NV?!HGl79F\\"s2aL!^&moha0_]!A`g=Z0c[MJ-VN#/`8)VVXBT.1g?$DY99S*"<#s+aEnfJ -%i:o'[!;@`"dni:lK+p$N!@^-l>BkS,O4>-Gn8]W<1sqltQ=_(m55^^_@\*[%Kn$YXRt1"5/HXoN>m,8q/OK`mJg($4^A?HJqnU=, -%,ikdj(-idM]80bG$!*490/B0JjqP@-"CE=f>/^:*Fs@L@8IqD@[=Y?2\\K9bN4a%_)&@-$Y`<$Xj:i'$Td+50**IAtCt+/Ep?#Ka -%Z31RR'!Dk^lCg16db&Ln/mpZH(YEfUU/5P)5ncMF1Z6oMK,.?0>`e@]]%-]$qIibV@Q[%XE%Q!PjYMfW]MqoH@oHrB##kJuf.Z7^ -%cUbSC!-I%3KtRWTc[\jfmK+#H>"gH3pVe^l,Te4/$.E_^6hH8laO*](=^FWr)],\9V-#q.ik5_^hC&-FY0;/Y\B"oCGssC]"r%F. -%KnA[h16JZ!8h.UfN-s2R6BTXQJJk5NB4.P3%fqaF:dX+U&-CIh=+a'aRfmt=7(s@)EX%nHn951`JG?q5AHXPH+(DL2*R,DHT[,fSc4MAl!=rF]I++,Jp$lUt3N)G0K5.P(;e'^%3B2T]=B;k5 -%@2X7fjT(jqkdh+H3*A+N!\t2@+p%#nE(QbiC^"r,"^!F\<4=3Ip#/Vf5QY+2hPK^YL#"%$I+SO]62/nE1MXr^5&cUq4?Q6p;bN]( -%nYas^F86/-)>K>8R)kh2cbUo3.)YI4E;s;+R:Hm%eT<^dVoFqZm:GgfAWMRm2RD*)5./qgikD^7U'I(0mVk[l,kDcEZ/OtO5e8Q` -%)a>;Tb?0'I>THs5O%lbYFR7c,H/T@UParL3bNt?^WP@,1i%a6X-?)sUPHq+oE5$=SbsZ59`@[@(3p5mC:J&Pe@F^<#5T'kfI^s!0_pA(2rf7DE#f_ -%*&:*#G^gL@4-+NrgN.^BOT(_cogYrLPm/`$/Rp1**[1VpnU?-mk1XWHCBTpN3YmgV,,_!Mn*o3gg#NQjl1!4K0UsnrV,k@FXDSp' -%H'&[#2>&JUnp=-tojo/U3.$b#^!6V3L7H)T$crRjmA;6M2[b^2XJ]Rm`55_d@4!",a]B-/-[@qn2n,mBGi`XfI/q9U;*Q**`;4NK -%?FUD.!1+RVHdP'?%+TF@8o!mE+]uu(%`cVeY0(Bb3I>s4$A3FD($K! -%aj1t[Fg&0o7pRUN>.se)eAo\tApOqP//^5U_+=DokQXZ_K??W_!m#r.'H;st,D5`i*sk^4i3Xre=$bIqt:;i,>+igIPUVPQW'^g\%W:,F+Wn(Upfa%qZ4>eb5,Yrl6AO3e-RH>ii<&C -%=`<2[V5?^$.h%C^$]+e"ku(/-\9R,l[4O&-O?2LI;V,(>^6(WADbQ=\G7rik;Jp]A%/b4Z@GXKjQ?Au^W(EU`1gETo@i!uak;i_F -%T(<(d4%kTG9 -%WM4@(_f(+4[J$?\b@MX -%C88kYP:9BOpVf"dFV,<":MQBYQ.mM7%=U=ZGODTg`d5DePV>Xi^,DcYZXpUsaGc&>hAJ`)E!ck1jWk"cQJqXD!dMJ670'79=]N(+ -%*FTSjq*=]b-3:>7V!WKo%r##cNI;-d1Ou_D/_6+g["<7!MVIXQWgd"-6aHI`>q2;U-f8V*'#.ah6u!gVQn&FMDU,3H9ds3(UFbT1 -%k[4QSf4bEg'YoXOn9sJXH.HK>PR;YhD/*Zr'/(M-/8;s"go0E>Y,*p]be0DQ89`s6&7/t>(UMS5,-^bHbt_%VRiNk?nkhXkNR_lH=s`*g -%_"A%,<-AX&TQpqLY'XppA's(V*BDCWe:Re"Z'GT;"3oBXi9H)>\LZ=cE&8PJ!Zp4Xan*RVAm5lA_$Sb?,A>rFVG6:NE$l^I!r`MQ -%gnPA9B<[=(E(=E%"]Y)X!^^d7j[5V*hP6Z9@b94:.b-]m"DWQkWiT=;8h4*06L!^lHc\)hEdC]FlV>Cn=A*M;AXAV1Qrc!9[grSZFJ4C\3SUli,%mY]TZZE4=TZd/M'3)bncA5ZX -%)=I!?Yg6QJ@%)WgQ.0\?/-[L(RkZLe6b9D=Rd*2(@g2!NV6*^K:OLAL;X0CJ"&/fdLiUD)Fr&@jje+a5-b0VIB%\R1W&h -%(*-eg>r%V"q)2V?qODVJBX!t%b7fFZfMfFFj(AOXF$u)kSrS4KoeqHsQPI5NV,kX7Ihenh3bL.cUUg.TdW5_m`<*&lj8KH5\9IS# -%M`h):Mp1!q+^?S_/URPul\Nh`A4,I`iPq)b5%KM('6BR-j=Zu3)6TW*c!^=R(:eNY,u6(>>3jX0%D^T#ac6,7\!d3!iR^`g43\n> -%CcDWca.6h(a1?IPT'TAVE;JDpKPN=pjlH&n7?"U!E9:jXr,D\+NAGpPCaZ0N.8Jhn -%X6V?JfOl.;]4kFl(#\E$IB7oiSi42UMjMR]lNR!A,;-ETUG8L*[\J**C%$rtV#;hsKoqnAG%uL6DY:&\F=>)P!ou.^3]95fQEgJo -%mgh-8jF84E-Yltgjm6d>mK[.ph%p+Wc!K:Z46+d^2C7A^/`r1#S!'(W?cIij%3kqcW`dEhI#\)$=kp%8.AC\fXi=-Gb+4,TZ1OkJGR*&0kq_)5s0es -%.nF11E*o1f?Qg-Nqt`n\G:^K7(o;@9,4T`.)6ukM21bR$kn]kNrBMhuh!BFnl%*K/JZs6qjXiS#pu-BU/TUZ#V@g5m6&dL:@Xobl -%^!6FeS?/B.1]VHTL&ugKJ/O7P&WB.1h\\lSV,MMoBNSF\bJ[k<2-,I6YWpqpi$kVnluCkXfY$_Pg%p`EB5k1Eo'JVh0`DuW.,P*( -%QP6RXT>AG"]q61c$4?n64iYP_W*I%lL$oE,^YSgEUi/30kqep)@'0qQ>[e;jQ*9-!iN"qo1=#G -%=3B-mh@MJkN_p<3a$457qpN[!2*]>=l8$d7A(p1C3e(:mLEdu-d*`[G;DF=9W^Oen!hN!n:flc=%/c$-0Rk_< -%0=Nh>C+=`?\.moh7%Cc^5i;^OC?#eq424IK-rU-)Ld#1=7Ie6?PTYs5gE.64Q<8N1""X]B]E2fBJEh,PYg,i]=fP(AS78Dd=UJ94 -%n"A`I$n.LpS]h-/?)J?Z6,fh4@b1ZAZ2QNr$l`Z9DOQ)=Ka6LEJ@_ -%^<"j0Dh*&41/:To"f,qB,AJ:YBrsVTiL6=MShE -%br^/eH0&!"b"Y-fDY=>eC[f6WUXcY2gKf>[IBTl$K_.gIApD6Z^h^!A"d*6L+:TmE1Z6Ye'2U8>,6rci5:qrV%X)DE&5\;F9gFFN -%>tH0U`IGbWZg9ION!2>jGB4@8>T\60Br##c`erfin7's,dmM;c?LDbN>A>5j?qfm*f!"1E#[(e:b4)LBmK0eT4i5P[&28]8!k.K@ -%"F7TZ*sEbuT#'abgo[O@!jt-TK%hWFTWbAN[ganB#p=qqY.->%cpDN^qbl)&&)0,jV&Q&*'PpCYKVH_]@7%;#D&H)L'OOsH_sji_G8Lqd'gukE^p++1mq^k8;NZCAJ^a;/3#,0SUI]%#P@\W=@bd<=:JE9sm$BpIJBf96B6]sE5D+se)e9bJE1qo_#9R72%EV^5\<_NF3,W_u>J_R`V)@(Yn" -%l!+Sbl,e03L3^#",9@I6$3`%L$Q8=X;,A:+WU:/bU -%+2^bSW@:_7U.#H*QE(VN%29AXX)S8`HA(U"%_b9F:o!]\#F]].Td&aW7+SWeYAgHNI^tG4)K+,0fnr/<''=Wi"dp/7Qmn^:aCGc^ -%AK?/P!%IZTC&O`!0<.6:oYhRQ312N>FAjO@%aIQhn?@@cMqR_"In)hEqD1h.LDM$<9k?VX[_2NH!]`2iY7DFh6SC\M=mK)CaNBq& -%a\H'[&r^r!`MSU'nGShBm9>0tQY.gWkAe9e_Nu.\@F,K2W6!oJ[4p,--,W14fmJTR* -%[4Ak9Oq/rnPuE[*JE0kUT_atg4H+F'<60b0m.94@>.j+fSB?lMlS4HTE/Qf%h-[Sn_QL@lDIrK9L;,@[1YjoYnE-1_@mfG]o(k9G -%E6YLp#tD@'`erA@_IJqLL!L;oNqG&^VX1FpbC&9Y`E#H%4RU6WbeBqk+o\!;IB*AJhVArTCP5_-c05ToMo&AMIam1S4$,CXeKE -%lUT)u4I&T9k'*)I`;CItm?k-/q^0)hDD"G!u;u+ih-g9RVWHmbr(V!KQ`OBal6U2^7Qp!h^YZ"SRKcEGNNc6 -%:QFB#*NW`QoI$-EnA]DVA2ZV2r3N60$3VqZM(5)\'#;t#UjNmUXT\fgY2eFG87AodLH -%Ih-.?>"[H@'5?1niep8#U>^Bb]1[)6Y]s)NZEVktTUGI'?!&!a]O:0scFdQQ6#`E7]%l&[[U^Y,EQ:D?FU`hUF3)^>1=.!.DB+C4-*1 -%e*FYQSYmRnOJ1DJA:0U)ST4Rg_thT9C3YnT'=&h]Ig56=k*%HnkK@DrC"\Wu#+#G1nuP\$1DF6skb` -%_V:PmlOLnPFHr2$,/.Al0LCJc0u&DG9FH^C30n!#"\p&&^;JHh/q$tM^FE&Do&p-<<+r%gi%Ro_8sH$d@"H26+j]Ti?k%S!VX+r>)8o?JFG@HflTaBJr& -%2sq+N(*A;?Ne>s>K*B^SsH7j;6KM$hsE3+eqlBa02-1n:[Y)Pd0B%b+l)$["*`^dQa=C*C3`j==NO -%CHWQ-b(>fF1ec10KN^t:VJR[ZZNYIL,D3#hh->en'J4mmGrhon9@MqjjfN$d7AnG[$`N;0'G)s&=/Us.+K#D4p#Q[iMpS($]fGsN -%K9RSOFBZ?1gF^4;R!N*e2)GSaPLY6PEAo8!pQ*K73I\lb_>\:qWsRSk5;-&9BYd8*DYBDJOm$bL^nb1icCP?%PCB-_T!2@\dN=4^ -%k"_4Qa<[f<7_6j19b%?k@tGpV>:cADQOTNJ0t^E)?i+Bi5Ag+BCsi?Yb5[[?;*+MO&t1Y%;m+jk2+dW)c\>Ra/Dpi7.fnsEJW!G6 -%@Q"M=C`0qR$asfQb65?s]=jrFTV[:%2=OF,P)SbQ#C,ZK@9r@LFI8[/ZPFQ=)YKLca6PR4HAo*S,JMdgRM4UU8eI!m"Rgh!F**"]T,b\LpkkdGj!6g\_)U -%F/kQ%Fru!I7kC!M>"6VJI:d@;_b'!s-,F^$ELMaX`/XS/p_1P,31?(7[UE72RoV -%Up/Ci$L^dm/l4XPC#VQOL?\j*"=ZU2[gJH=CW4pb!QKksM(6fAQ,[9BbNGG44E+!SGG]GJS?8Q'%9@Ks;;1#G=1)I2VmKB3mD^sh[_!SoOU(>+\)!7U1t -%_8Gk'Q8uI*GRI)."2CLiI&F9CDUIS$QH,^R`$8%Zih^"o&DDZ40*gG4 -%bIZ#I0X`3iB,TBnkToOfb?/Y=dgSPF7@h+"W1r2:F]FKMpUo!(o[XG=7C%R>qd5,qF^\:NZ8g::TdH`JiPtb -%h(9"6dEQ^N/o5In2P3)a?b8VUN5(\&eu^S!I:5hV'faM!lKW0hssI$kcVL7@;Df1Sj&jgK1^YUdJ!ej$"-TTYbICU[>+ -%K^N=V``FTq73u2De].jUa1?epln0+72t8j^"%t3V+%h.6m=p.*PXu'oX[oPLqeTb6f4LFC++o>m&q7JL)[eP]c;q_ulpC5MFN5%2 -%k'i?Fm9\P?p65:`]Ss,S!j:'T+"e=:&eHiiY<:,hNSSPiUdZ(EQY17d(e9!Vhtq+pbYFlpq:M`KWOX0A<@cu;CA%h4YcD8<,"Mai -%=HY9!gKg-1Vr;A6``SUqDlWr&/PeTn1\b@hMT,J]?N.!Ts&X^Kq`k#G5JR6WT7?a-J,&u755hr,oW/#kqSutBnbS%=p\O49ZGuDh -%GGD25(-e$(kNS[6H\S(JRUGP6aM\$k\t?Kc??,m%9*%'6%VU$JYj+L4Trruqf*4R+?sXB>iR.o&i>s[(Cseqa/qMKQ$&Y+IRE#gB -%:+I)__/@r8qm88X+_$`H?i#GZm?AU:ZZ@r3oBj,!0%/E0nQ\M]`Qk5JP=49u%l=1R3*L'*HuSDe#8d)V54$FdYCjOrNhhIuni,de!BmV'i+>8*#\./bTE]AmHuWHW)N"d&+4/D(a>1=4Sd:u+%[_$)B\.b441Z"isQKSWgY%7ca$Sqf`2[Xj,sele,m*@'^]Y*,OX8fF`>,>2ff"D2scIBZd'/#$7=F`rn@uL\0rOV24miY1FTb(0YGS@V;%7 -%[kf:'l0(g+$3b"(")sb1pL]k0gQN)Xe_NYN=$UsQ_R'R"XtS&"a"G_kd/d9`.nC8k@ak/UWUSV-[923na@VJURN\`'K/5\UO_o5) -%dL-hYCQa"k$V'U&1?4k9@E#(Jod$6\$3pbK6sDAN^Ok'r#=*7cmLlcs,-K=i^m!@.QI,=aG0F57P"t*#g&^]s]j%'sf0_elQq8jR -%Eq\H.6up+$b>Kd``kmnd=@:'`qlO#8^4I:uU,;=")(HBX=8k`3hjp8J+SBBg9Ca-+D8@ -%8&P'FZe.3#SmJaZ@Sm>pNNq+*2EA%a,/d^1AI,5]k7^2;n,feS:.8F"oK3Fd=q9>LRWj>#8J5:dV%/3S95!((q@%J2je:hf.I=qe<95S-aobWO7=7Aenq7),7M\>l:MFC3da-^I -%C-o^7@[e_Z3"L*k'QH0p[.nMtncS,bY9mN -%)%EueiH%%lIg!Ud6kOL0j@Y$I6bpTW4-FOcX:<[%l4Q]5WfIo/$=BBd8F;Ci=^5-s)0,50DZ(]ceoBF9-@&]B,"T=.6)?T*eFY=o -%5jQH=TGTX3inVWYk[cj#b/"KskP5Lm("tsN&r=-;LYGjX)/;Q,teoT,Ia26TB`!n -%PVIQ)kMT"&-W(sh1d7)kKnpalYM6oSId@P*T$M/<0Uka!U^9iT5oTdN5[Rq&EuegcS@B<\MWgY4dMQPTkR>2"W61W,hu;"PGdc=-`Q7 -%$H@DBY=u#<*4b7!d4=JVR/[iM51C&@PA4N%0C.R`.`[J*%orQk9ek8Gp43;T^KL+!jT:hsgg@ -%'`mKB"R"p?[QC4>I1DcYWVPVcD`l(UJ1#p'7LiTN^V_>X"2]p>$hrH/]idNZR'_pV%Og7f`X#@E.,AI1=ccq9bL'@):3E]J\qI!1P6kS$D^%M<8^rmuKBpuT4 -%Y*M:g*oJp^\tq&Em)K7R(EA==M!KN&B?q8]0 -%)W*jcCFq^*`We4!I,T>@>6df#2>;>"@62=X-lYAf=NAu*pr,bP,V%Y<]0cSQ=;#YpOhmkgLW% -%@!O+\nb$a"aU7O1Omf`j]A -%WXr#SH)QbpnBKE?3>mgrbG&;<`ABQiKcsT9"gZ\)&+EtJT$:r@"MAhhod!f"s(nsLCm&\`m0EZo2mJeWmY)dl$h9+3+,X7poVOU- -%"kEalgfDI8-b)*u591@7'?,?bM$k@odj&8XbY-et);PP)0*O_BQ8Dh@O;l@s'g+I4]rD+8?mD]gg+Sm#aVHS5U/:2%5A2:t&m1gh -%mNa6u/CjZ`?Flb3,>&)M/UbT)0bt#U?n)VYj]F%:P')(*$'P+*Jf6(SS9#b8d`9lfBg!4K'Q?]d=FV1TalrO'%.C=sE'=qDc8PcN -%JA]2Z?AA[Dg%YutPQIH:!2ulM#*P'AEZ*0p/GHu8BRH-6&Sb0A)53=YFIQ$A.raU?.teO;^*;b=.3tXh9T*L885@&"q-CE3%on3j"[>Jn8De)SWJ6[r$b635bs42NVVq=s@>+=nXYU -%G8C7nKOnt-`e(U-8L[?j=,[mGC^8].$CZ*qYeu@R=L"P>iu%"c"7aWa"?(8^^UoC_;Dpe!Js4%/?2 -%gQN_&C,`cP=)1BVTk,Cj<22[ZktfX9D'0$JX37LA)>+CGLcMMahZ-9OAm-mrlFnBD:=s#'[5?!0Z4uH6j?Q%n,iApteT!9F2hGFQ -%C,Lb29I/8JgXuC.RC8r"MI*@Oj8k`jTV8H^%IVp`oYaeO\?@c.V.4;$Ea&]1-b[sXl\)9W0 -%5TlO\i.;`mrZ%=[M'\&1;aJ>n%JW$b6,Pe$AFh3#P+MZA/N05aj_)Q)g#K`rp$^H+snH72ukDmb>VdqDK8bUsl(A#uV1&5Vg'(7b"*$I'@KHkPT(QZX*iO -%7^fZ"^%i2Mr2H4-[>=9bK7\P0,+f>"f2*'.NP -%Z[sn4@B9cthdHmX4Pljkme5ecf%)E/gK_Gb]^0B`#N&GY@bH:C#D((\#[tU\UilAJY`HlhTE"\+k*N;MTnXcC;D2"VTH7gA\=-oPK3pHKl$"BThD1LS;%/WMV(4SiBQ*`ZKNn`8.-M.OL?j+LSV]na]Y':]L1B#W!Gi5KC!/H -%&1)n,=IP\?$uVX#Fbr7WBXrrP&jK-I*`]5dI2Me*2GB_Y1be347RSpab1gCZHjS(NFVm@"j99O -%^AAGk.li^`.j-@/]Hj=F?,Xgjct`1I!>hh!LqDt\6-YpqrRNhu#m80-\s(Z:nkU]J2Ge0f5-q6nS"Z.%,C9J-.huWVJ/)Md<\L\;/5oXSL-F3SaPG#Ea-j& -%S/QkZ$]fC=;p#/!iVCSPUaW2K?W*_4Z[Dp?J5!HrH,[S54#dNfgV/L5+4)$-_;Z769s_K3Br[u/tB85SCc#hGFH:M#)c+b9ja-bF/Ji].MVa\8ZC.X_6OP=*3c'sI1%jXqBm2*V>9[+B6FjnQ!^]Ik/f[MFM4)'N'[XP"o5,3Z[SHB2ZRU8K?d3*W1J1k3^,B&cHq)eqg0gi3W5RGi,U%g7r -%3_Q2JO<"mU9.-Bgk)L3;8r^2VPWR>pKH%'S9a=rJ65U7=LaXpBet+NCaW[LX3Ib)8OC?9(X2A>D'=-6__:8iUYPb,+$Rh2R6h=MR5C=c1MY%jsN&Vl?O#*Y+dt62+MO -%BN9O1%C0UQm^k4CWGa1F=8uO#5I?4>041WVMR"sEUD=F/W+^Q&/9PG-LrLkXTfV>A>9m$%^'`)?_!&b1J.iY+hTEZ"e931jJh.g] -%V;0:EE@<\JqDA4&a^X%!s(m@Dk,H%^s6C3?WT#I']df#"ICo&]FTtJ1bGGPZBP#o)r%L+_S,6#d]g+/F#V[M4b:d\'g7dFaDao\G -%lk#jjVb+hPn.8eg"%]Fk6Eq8!>eeBi9"9&m/iN)Ul*bYbMX5:k>SM(2!rkb%Zg#t53P`4dN^^uVWC$R2[> -%(2_Z(1#5.?I25YS,SYfGH?G>9Q80^n5:?NJ=dH.,=^qV_%fA7_[;utMirROo$O#'kp(i@jg/u6=i!jJ9qW]#3\.[; -%&7WJ^g_r!TALcJCe"UlMKi3>e^V^0-8p$!h#IYF>j3Z1)"LM[V%m2GVu<9'KofuT@q?Dhd('hqQ`DB.[&?mS -%+!sHuk8)Fu#5)Y@-t(ekgQD//q-d$/CeU`S52!MtUdF7K*ZOiiPkX1GpIsa#?p9eqq -%Z4A,S%;S8cR"C0\YtEHLg4(=edrDGt0A"==nF:D$($6U&NaOlMU^*V_=n9XsK0VJ1<)o90aMj'E9CU(qfS+U(WPh?bPA+`o"h=AC -%dD?M"OaNY,6HM2$$fg'p/9[r@_br]^"2j^HgBq/#EnPYk*/0-A:%Cs_GV+%n;YRT^Bo#U^NKK^(/g-XW-4k4Ts0X'':3HZ'I.L3g -%2m5BVj[Kc!YDZD12RER+^5R4,Zo,:N]TjA,@LH6_^U$G(JEA^&XqT["KUT#.@5e]jLsQX(3I.0KH5r/&kRns]=BH1& -%itE8G5mrL?nokZjQpg%XhG@IX)/fY[RJ4o8Usjr"&dr6Z$rL+W$Y-Z_()H'&f"tO)<^[O*h3_C6$BKmkI7I_IYK[E#!3Jc6.ljW9 -%5]:/jV(8/Bc>DaoNnp^/=2(X)6pSb[X)'V;#e0)h/SX:g>'?JChe4$sGa$u*IVA7>:MiWH;/hHN$XuC5YA"H^`bFC3YT]B`!=lQa -%8q2_i.#G'#Lf1A,bDl!Cpf@4.$4[GFIo['2!BR;jX[srcs6t,PleS<^muXomHDVbmCmCNL87O[2*V^QMhqB\/EE'6rS*MXS4EN,j8&j>He?$FY`cF90__Wt -%HVsu1?i`47aJuhR4QFYRV@*..O+)=aDu8/aJEnb^B'M&J(-e#c>T1n]-8r834!)ZY-_TRpBVn.MKg`k! -%ieIu/Uib7t/.ge>34r,\[(rZ&I>F$t,*:;(UT6>:5E'"Q;gs$7l!XpK_b%!:M7J'C>hqAsUB-m8c2]SN!$VWe6+Q"9&/em";Xd(P -%`I/(J4Y=\;qa&,n@sV=>0i-`9V+f\KbV5L0nqn=p_.9+M\pu3cfV0-WKle)K(gjgZX`G7/6+Tj/S[KkClXdI(53<;C:Fmd@`(E5# -%QFJGY/c6?*M^rkZ^/OS/dsik!_LS9nTOe<<1a:TJ"qVinM\fYVYkWt%)0[kHfYcTpFQ6UTR*;lc?b.(fo]+cgiJ'F -%:VY?r;8(=e(;!)9K:8lt6h7fdUUFD0K8dM3#0N,iIpHA!Q3>rV`_3r3*M+L[(Fs0%C'$/#[^4#]J>mEm(iCc5`*eNi8_;eo5!HWZ7/YI-+ -%gVGrJ'57_#O(oUu58CG!-4s>ir<%LNahX -%jRr3jG!r0LV8nMH2hmF-^N*tU[\O%ffCf-7;]`nTOi4Jr8,KYu:F+G,I!Ri11rDhueMmNeZl"o&J>FH_V1o@kooCQe61@$*R.G\G -%blUMW/>)gb\B@!Z,JM,-HUGofS&uW8olMiW+i.o*?]Bkr-XcWCked5P-c.u -%91C/&7)Wi7Rl3F_?1)PBBnhc5.GT*@2gt9>OI7NpFX)//G&iqD/^FNqibJgu4,=oF&[Yfg]C%l,+\bdKY6IZfjad4$j9P)NA`0D[ -%_!GSojC=p3U%k]/]oc;:]g9RT*eRodDE9JLMf*>l0[Nq.Ge;8AqoE^7JYVh+s'Udo`aamrcc3Wr)7`d4a`oir-q+#rbMH)D_35;' -%:RFJZ@6IH9Iu>DK'A:8D,dj8Vl.aL?(;8lON0KE>:W!^7M0I;uTjT20r=ad1RGqS&cuWt!oN-P:Rm2;s`F&Z$^3t>-mC2!Op5cua -%a%ua*5Q&FfIf8NcDu]@ZJ+;d<\OQOAf71"(qpg1ErBnWns6DoIi=E^&rGV]&+91iJ5QBlts5S$Is7a;*rBL5Ef=t,ArVRJbs8INC -%bs24+T>(9]^\n35qepr^:]L>3+MW1"LMss)Vr,[os5IVeo[h]EJ+]F?rqNdKqWm$Es8KLZJ,ep/?hr%Il!IcXTD$$Kor%,*r(kqZ -%r4a'?T0Ag(3pF+.kGMcMqAJb^]52\_cW_J,G@oct1u09A)>?B@Au]n$.N,:+VZK -%J58PArcI=5OehXW;C&j&arnM;6(Pi381%AE`uafC)u%kLL.Qt* -%3jE;(TR$&"baH@$GtFqeN8gMUTZ-Qr5:TL+O*P%9m3D@_8j]n/U\pua[r(.OIU^c[7"dqlFs -%j12Af^r3$ghP/T%4kXBVT`6n,$Z>UM]\\_,"b5c!pED10"3h1M8PG%:G;R`GKHl@?[T#J4)/udog:#IiE -%1q++569fOsY^=u^OdaOJc`"'=7u;jZ50D9NLKtb*q.JMoeB9CEp#hHA3V@do^qNNcj^8<:4giR_V%<$s,)qdcM:ao.roQ.V6#80@Mrm;Sra'VPG]XALO@3 -%VfC`?^9iK+-cp?%W23Png04]@h.Nie^/R!9[".o>ZdgMnA7u+jKRe$aceV5`UlS>bo,oUtE[.EOBL1,+((bLQ94j=7;^B(LSS'0# -%hr1Sc.*o6/gK:-TWCT'JC2a9uBGd^[N-:jQ_H!5[a3f*GJZ,!/SnUQMbmJU(SYB04BA;O9]"Af<1HL$`hN -%Aq8(t'7M/VtfGZhR -%8B_(dS^8pRGV@q#jKN0SY?9e]ZccKo^_s3X?3,2:9`")HX,.Y/*YRA7C>CoWD5h7>r+Re92pC[Ce^1_.Tk$H0KL$(u+V.n_#bbBg -%jqU2spM52b.7ddPemb]=Eh)bDa]DR6SI'XHBosRPV]*'+A,_+;J.-[VR@;(`mAZ)5$SN&Qtj+#:r.L&+3Gun'?-&B0.,%[ -%%-8k'nBajSOFu/+cnpn/V/1p$CSn-s@Z[T73h\d)!O*>L8sUh2^m"s8!.)Is?rM&htk-AcB_(hS0r -%YPMWpdBKR'(jr@Dl][Gp+e/-[W6tBLpO9(io)=OiYe$2X@)qO+`' -%;U0Q0CJb#=_fHsnjdRmUVV/\QD$3WfLO#hLgSg!co).m/1%u\kkf'=jh0@MXt3q_BJ>i$L7NLnujek&a(,q+W(p/Ra.Yp"Tie:/J!o+2Pb$LM-@FS/'B -%63sPf"Y#)Bo+G)F99^1J"%i%]qYYAPpN_j6i&6X,?cG48YNS+:o<;hRI@Z..Rp3SPK9sJ<[L#0VE]T)4ch6",,JU(no6%`=MjB!m -%dfpnIj:Sg-2MoOm9dH'&;>1/eo#^!t??LB4kR48--(RP:HX'q@TYW6L?u2")Q1nWm\-t=WWM+O%RQ@=/:P@955//)07n:k#W_&@1 -%_WOe??D,'e^er/Qm[tiqS5!.cDTj+El/ZMR,-4Sp"t.N1[,P\> -%?2G+6iFuffH#^VVd#.h#cbM^cmGR*kY1B:r_kGSqq&rmRC]\\eo06Iu6H>PF2G&nXNV]%sY(:JQ;FX0ArS_LsPH:Ge&TTn0n,-fQfS8DY)cmF.5Z\N?0a.t3jhop@nS2G/jLZG)h`a/;+-5M:cO]QT%o;-(bC01B+iqFrUF.-G"G?KecO:'Kc[T7d -%aJ+OK&JAOeofIalRLT,b_a=([h[p\\!T+V1iZ,ZW3+P%Sh\@4'4Q2nS+C`4ZcOUVUK^T6\R>C;='<-fV#o&eXmg0_sK^T6`h'VZ5 -%_F=/L^FN]6>?3s9AAgq,*C1n`nQfQJqb"URE5W:cB8;N6@=D#AaJSGii?OQU>lgbUF8.a=,c97B7hCMkMr,+9@RA@a"Hn!Sh[rI9 -%&`4D$8BI&pIr8*)1IZeB=NU,N^FQPL22=CT[,h$f5-V6+>N3]59FIr-=$+'$06o>VffUroPUa%$)&JV_d#5N[T'B(C!/ -%n/?.`Jo'N,L/dPAd]AoNg4m?eTED_V"GlsO@*?+:kh.^NdL61XWe$-m@_hjem/nIR/i@6'FP/)DbC0mQ3,+1b[kOj[m$\t:T\k@& -%)a%>IXPeA@]\N^J"gF#77m%'dON1BW7^R[8>\p(1?)/QS66hd/>-51K12l[[U&c)Fr^/VRJ7JhsQ;)&1UW]V:6Pa -%`M[*A[02l++C(pk]4\hp`_'#-d_$X8@_06+-9uF^^3I8lF10=0LZnA8ZST:KSsM4a61:$f%:/`?IBH1dHcB:Ja&Mt[j#%/K.)G%D -%cRcjr&YW+]/+3uA&Ff0HC9l5?a!]W`rricLN01]e[L/)jDDYt:hK?U0Ci4BjD\kV\GO"2S<8ur@aRkWkb.>=/)VS!4BK$PYD9juJ -%pM!EHqhi=7_.:0`X!o4XI7)-Hc@0?#2-XUnhU*Vkn` -%kS8eOk!!FTZ4LWT6L(W>(@\/P2Ua\9JAW/%e\M`9HVcV]AZRipKqQ;Y*oL2R5R]8$ckaOS@u\d\#f'P`W`-9ndh?9U-S'D+9Jn#RU;KLkR*R*BCD1Q0NaKiJeFhE4hX.$Hls>J2p3 -%g1U^-nb^$F'gW/=oV"F&buX!h3YD2RKQ.iQ=)2Yb3GlJK7B)2G9>Xhn\PF]k&Pnb(M:k%KXt"&!00gp/XE!pb1oAZ/CmH -%O!")kO%B#1nC9K;gDloXYF<07I65h\E>-n\det\-kW?(:cCNbTD8Z?qH5Edu]!@jGecMLJVS_X,T;_0X6EY-")^/*J/'&?sn"?.o -%W[KsI_$qrBjYWPnmBAANa27?q>U3:3M^LVo-V(R>8/6!)n3LqR^qGEPAt1iTHuhf@:XA66Pehc%[h[^dlEI4B4TTC#A=V^IS)Hk& -%CZnAUEncHDBe9Lg1$6U;a)f))df_dY!C,Z\u9UR -%eX<`n7U]eWl!K50mRB7<>!m@tYGi_?MphE,fa4c]gTA/`_H:u8oKMp;f`ol886.1.qekpuDs1bOT>kDHh.,58UYFC5J3_q`JdB4\ -%S%X)7/U\NN?D@dFGO5jYhD%JjV+YQu== -%jn!ST>_ffGZ6e^ak.RaO@ha%7^!*$*S4M4?&*.<`=r,0QaeQUs;00'c"[+42ouK=+A@>"rDhZ+t3@(TUb7`ZUE:J3L06&*NGZAE/ -%U^Z=U)H"+%d/;=5_(D(FFd*qbp2,@,kh=i`Nf6gumq2t>_lV\_W%*)4'ks20d, -%Ie[9B0B>'!iQ@=cr\4l>0I^iKH^!uG-i:G5D-]?]!MjA2k_gpY?HU"0T?%S'ls7T9@>g8%B3du0O9Wr84,]bP(2fhp3[Pac/VBn= -%R[IBe9H9e6*;M!qkX^j@3ftZ.?"pMhXtiAVH9A!/m6Fcg!s/;G/128if@0=lQDZc323kUo\,WjOV`lbSS;XLG-gln"\S0u;P065b -%@Q?T>-eNC[.Ou,$dt2/[G2pp6J7qDA-1M,s@]&-pc#$uY5SB2o:)[bHJo!H]o.j.EH-fQm+_fABGH0lTWmS2,iM"*.FnGO69_3U1 -%%7k.*9TaS"E]cE(/W-Oj%8saD5Dj;`4'Xbm:.2n6%o8/oMPt?W,X:W7ZVn7nG$g[Aqk:NsjWqrj5,f/!knhT*#kDkg/[Y_GWYQ/e?sTR/b_UV4OFU-Ib<:G -%nq;Us2psp4E:B,.is+8R;i_"i7'oSp2I0g9:*7m28q+"'d;=,8XU[C8PC""$GgHG\+`aVC/7BCkPn?cXZF:'XI3Qs0X;kftrR8Q%G^g&]+e`iAbcOJ&NE(VY;@@U,.K+8R_Va#H#!NjN1^IUZY/;=ho'^Q!?DA-#j8.-Y\_0MhKg0B]I['f51"T%^V%k7a]Sn[2dL!qcpkT:0\7`$$#u0:@@7*hi3]b`G2^X_b;p`193N[_+koZ^OP'\c&W@IVW -%T.2bF<1mmhOtGRhb10EJm"rks,+^3-cW.g%(W(Ci?[@rD0DkV#++O7dJ,[\W/Wp#s#2u135SX6r3-*b$a`Y3*^Ak;0s&:mWNP.m& -%V";nIfOGOkd;AOCKaY]e"*\[GY2&j_/E>Ghk/S;8QI5"sZK3_bYI -%dp(>HYHU5aB=ctOhDY&.#KCKtO<63cfflRUTPhd>7lNZS%YB_?APW0'Nt09p%R?$F -%g@Z)WfMb`[Km?$S_,VsuSO8HIo)mfo<.2$]Qtj]E9Ug/Ep^q"o -%2F2/FjTM,mST_CJ3%AYP"15j(bI]=]dEdRa_A30-!H8PbV=`6U@S48Ei`0.m/R5AY^1-Z6+:(4sJm/!iC*%ZAZ-..V5K\ -%>+o;oG[/8nIX;O`JURUPFt[0@$)Q=V$@L?LCfS4PqCVEnlEhJ1d",Pcb^4mZ33XS9 -%3Qk-7Z[9&U33)D,lQL*K,oXA]9WiIAp,Q7+n'Td%6M"/OXO%XK!/4:;16kI[U5Wt'9hE6t -%kS",%:IGDI9DS;GZ8r(?4F)fT8!]@6A&"@gm;6RTLo4nr7u_b2_]S=70Ii`QplA+H3\4RX5*<[Impi]H&`)f,Fl'\m$s:PgJ>!0> -%gt'(08VVHV7cD,:8b+)a!-,Iam[q/g8cLK.\bML)]!obG): -%DZa!pR[3FIYtVV?5*M-R*^-/YK#B6*JVN&L>,_+c9t!j>$a=MTUonH"oSqpR]VUENZCeUEX0ded:$5h -%8[q]GZSGPpHa:VLjM$S4M=B6Ec:ZA-D91dq%mff\1g&1n#*5(jdPTS+i;s0Pdg)R/9In*/'W8KA[X02YZ@G*d&YO4Y2S2gbcrFcL -%TS"5Ck'[h;Aas#/mkN46lc&hU9#BqI+@sHWWKhb1Hq=Pm)t_O*7D,g,.sJ7//BVju+4e>1SB*&e%G@eaS*se]0'"<[%:;Qj&P\jJ -%27LD^1S[e'd4b6uB%^]4gVs_jXtXi2A!nF93R_$Gg/W(75nt2e*XTX)*b+lJft/8<[,/d*0a`\5n(+KeQ?N`q-'0`F.T/?6FhY,5 -%g5C3MCEmKdc&`ZHPc%"M0E1)e55j$hs$9?E:VZ[OZ0hSRLL:)D+"nT45Q'?pR`58as7sPUs8/F;Qe_Y2-s6?oGbZqB?eQB5_lmg# -%Rn$%1$u!"Z0KZ6k.pN%T7E7O8:/BnS_,^q7CNiQ"(O4sh\X2S;dO;t41[L?Mn8#& -%*e*k?:dqb^JKqj1\Y=WYbs7M+S4RpYC&9g\Vs]FDl;H( -%.28!$l@O/Ne(.gRdT/jBU[D6l1+ET#k?f=^FD;qKnVZ?AMS)sk6I-5YFOI`bnI!ZR'X`V1XKiuEa>:cJffql0iUc,_tcoU4\_#5^JH"1)r9@IR(7$LG-_ -%W+e1,@I[S59g;Xu-t(MT#O5O[4.r$bmHpVDTXhXc'lTeQ`;Mp&4gS/O;/7V[5//qEj4`bOq:g(m=be;<-t@lE"HUf'bC*L%3qL+s -%DS8"'9hYLb;LBLU/Z*5)mI8%3G`qr,96@[):@%2Di(7ekLd^3&PN_(tNYq^fVn'hTq -%/9.nZNg:d?&TNQNFdZFX?u:<^SVmjMAnfTr,%@2pAnYZ)pJ3WN0sE8ei<*h4K48nMDcU2D/okW6`=M4t?1tYFd*rt9o3WY^[tQEF -%AD943+0!-:A0$e%jQMS^Mc@,3d&b3QV0'k?"".)aVSk%AhF>S_97SH(6L -%eH:H\M..4dbl+*fq"isW"le+'%;Mfl"+6p]aNRDU?iYK"oJ$9@_6=ll-ibZ:/S=2G#eaV%dmRRheSUIeDu=L:2(B -%4O@ZIgBAU.8)'^qp?G>KYbEsoW6nOX$.'1]#_*tDB-*0d>V'EBQU>E@B%E'CW/+;g4MIWoj[lH*mW,&#MK)drLf=iA`\)fKXPFI8n??T'e)rHb7nt"bNK'Q45HrFpB)P,&/6I"rLtS6OD!u)SF$)nH@S?9U3*9s+RU`PB?Zn!OhrcEmokABlYMKQlZBJHaYnVEYW$Z_2K0_oG6gBV4X?C$=&"h/(sHA,7.YRN -%aNP\#-o[TK?F_<&l.4BINM?9>>Wp-gK_Ra,!"'X%JUA5MERp*"$*W](U)5d/8Fg9p"e>dX0&)m!nV?F09#82A,$EO)pFRap[3!U\[W=nknT4E\8;'G&RX"e -%bMf9,p:.LeD$8C;n!b-2Fp9G)C)Ic(dZ=d,S`%=iCj9<]@6k@(%F^Is2Dc7#g#i>c6oel%*CJiN7SQ`eA++C(C@$N0bTNND#;*l+ -%7:_cOkm/__n*FdDH@Y>uT^YO=`dp'lR%INpe*!tlgg::lf%8JS4Ig&^TiN2-+0F>dBitGdF!DA]*'CjZ?q2tQoj)dgc_kk$;)Mjd -%@0M_3f8*L;_&ffNf8!nGKt-jemQ`T -%@<&".,[k,t%9-+jQ])&HXrZr)'U8s/\W'2=#+cBeeLuJaW>5 -%\4shQVm_H12(@^iVWp`i:mI5CAdi9=Vg?3:LXW5&S>dqcCeUZr_: -%8.2KkrDOR$DT,_0N9GZIJ^[G.@u3(E4/$@KQu8lA"[d7L?Ep1JGcW'ug5shHqD'+IJJ'cCB.uKKII]eX@%B;+2;4''S8"Cc\tLTL -%$VP`;lH#EieQ4m3.(/.PE#o=5Kf-40K6=f1;"e?)Ts=F1mP/L%%^T-k+TRhS6qdj*Qj#E;^tAf@%LsDP-W2E72Brb..+;u,%."J8 -%3F/c68S:9nM"JePab<@q8Q^^!F]lN9*Erag>=K*#S:>]H(nS,4&-_qrCc(h&C@:Y^f)=:7BLo,Z4k;rWQ)XoT%BsH0>;2.\P+@`NC -%0)!f-5\@V'-:/XkR`4Kf%(t_\RWnGho;4%(oPURj^!*fa"T;0@,t_5Y#+)45C58C[i,LS\L8S%p$-^)_Gl?=`/@#=\,*m`] -%APWY;5YL_=bcr_\f=c_Z5i]0N$U(WKqF"b5>%k4pM4kRp)KCuMmbsIIW\-1'l:Nf;*1_k3WPnUGq:DW&(P5]QU7gj6FD6KI]@KQG -%.,Fiel&,mP=AhC6V#m]HArFR:C+f`VkFul18Z%sB%GUk=V=kqM(ufpXnt/%a#!DmSPEP@.?gGETSU!X5j=th1fc6j)PV8.3jJb3C -%Bg)qP,83GA#.LTXp_P\K-niSA-pR2/MH>CdoMVgO2B=.Yf70(Z]Z+UHO.dQSqkhTT6H#IWo6AW4',/-W_kH2!oDc1aWJ"@D1]>L!Bc3Obb;N[_e*DjRg%Eo[:ic39s# -%;;fIdEe#271R\k8O_!e2**R`$>F7D:/>S[+6_e4.(1K$+U!gZVBR -%-UhM6%o\O.KO#sfB&L?<^EV=O$D%*fWd6L^FC(0$G4u2YB[UR -%bhg6-%;1f?CabfQ?+i%\-$g'<>H9HWL86@1;7,?.3?c4mgT-_AQ56i=\6<9L3l`6r$B(ari>!R!>&54aNmXppFaNOIVeoHLARVD9 -%7uWO(7F>L,U^m2:ZcIBS]B7re-UnY_@#acU&TPEf^!&C^lgI6TX+j<]r&Ur\4S5cI!,0II-Ngn:`K%eWIrbmrloU7 -%nMG'Z@S62k1G>%@CiWF+#JS%\C5&]V*IoJ8UG)lqMQON&X?dY.o3c!OnhXqoYmRGb"M1#5#0pbk@uDA+mBZ[^%jU[m3`S@bNgf49 -%FN$&E.pL[PdA,f$VEhlOl,JCi\HdJD#3?Rh"B9Of6pm2u`_/S=!4>8e=g1#_idPgk6,`s1WP\?dTWSh`*E3a1@66@Y?6Rj#)mE,M -%R'Ula:Si?="g#-/4(O625p]eS.Euc_4<-FrST'Jo7`.Xi">SZrY$]G?kQ$$F'l%ajdf6$1S;hL*MJ;Lg?!L$BfP=>I.0&+\KV?X:.[8ge(6j`WS#=jnMJ*:UW-aP%BR'Z@f31?r2>D0F+q<1".g -%ob\.=\XrF:+p'<'&@!C(hd@9])et(CK7uZal3f.DUfku+/0C>Gm'.]mAHq6Y83s*J"\?]u/G_^U-F`!`o?t"`_@GQhH4Ug]8./?t -%U&-N@Q/D$3,`iV)< -%kSi$5bpFRdXaICuF:U56$]Bm"4V=?t5SP3^VE*H?gte+$%hBJ.\*pZ"9RCW27cDU>NtZ!6`D^`3g9H4Wj!"Mj",j\"04&&QDU$i7 -%V)+&VM9*'^J@N$R;`mLI]AcJ[nggk8QtPNfbRdu]Q=6d6A1ZD-hH$c/"i)c7Ad_mFh%-j@HhTW`,N6HQg&ai;4iM\,RV$-R^@Eq= -%Y@j!?05S'CSeo-&_QuSlJg0aEpKa>7[9*S&Q.#r6Cr'.j.?t&?if!sG\.=fUB["b#a\[&OKi7WuOOPJ.I:`^uU!'+(1(;]HL8N]. -%MIJIX]'55?#O#b&Gm;F&HH!`%$b@`n-e%4>#d)$VQ'E:2Bc:s(o5%bj@P*(td" -%o>6W).4>0T-8FjWnfMU*6Zr8KLIKc`pk%#5C*5'G"_W5^cj_h!?apTCQ$`lm[WN20#!a,K.[: -%5jnQ5n5`'@0(s61SRM44Mj7hl_Bi9jIi12\$GTRI:LQ'.fY">*is=,pn3"IsEslkTC]_p6ib7bXd.FN*ASY=:Ane68LWJ`Za!57@ -%2F^p3bmmdK'W]h&3%`p8H-h*'H*_e=<$`]uJicViS+ecTRZm-77hAhId\I:XnC.#QS:Zr=RYQC8dV[+u,IR,_?raBDg>c^)R?KV= -%U^65F(O@pcm-)#kC/XS<@jM'Gd[13T$,RiO8F#` -%roOpE"'.!:QXIrIf->\'_K%IC1lKch5LtpZ7sdW5Bk1Z:d$.F"eo$M>*b?RPq&$30Q6pQg1A-%XlT"n$ -%f^:n&G)L",;Y!;4>bQ9i:[RXVe;_&&\`.=R`.-`ip^MgnQ,5S5[qbu5nRJaT#EdoF3*/?3Y%BSY,)8',0_1KOD2G2;W$ZOB*; -%fX;o6,OFd)YTm>X1R3&?#59F)Z&e-=,KhB]?dm/t^!J-PT_m9$N[#"+]5Qj$'>E,%!AAPCE,$0W3`W8sQB)%$5m!7qGP@Pc$afI1 -%o8%L57m-uI>PLQ2XK$afFd=6SlU"iNa+>H/JCi`PiT"5(.B<9k,&)l*iuC6IMlA\+Wa\/@r>SDfk4_;S&!ZZ -%/!"=aP;)O40ZdB[0rD"L<&ubcm0O'c(K+lV$_a#%Z?5f`5k^*k_JPgZ_>63H+e[2"d_sG%M]5e^"1;>$&:h>0eV?o>/Jr);N+hN4 -%Jr\B1a]][@aEZjG/j7sP`kdm7h^`nm**$qlIRi39@?6B,_dCUn0;RZM%JVijm@8V-;5T#hBqqjaXES*/7Vu#i`f;AM,55,'M.lB!1ARel9!12j$]K:3&Gj@Ka"jXn$F4M%B$e^B\6GEDLNBR*3"L6E<4/S& -%M[<`\OEHJ2^Vc&bLYi+^K9baQY"tr`[BJ&4ne"pgV[^uSnd:Dp-P5)BQkt]7g5K!Ag'VLCrBt*BT4!58:.AL5oVK0agj86NS8^], -%SMfS+C6`3W0L(NA,ZT!goO7uH8fdF:C0aI*hD2A/@d'PHSjhZ,Ws#5n\Y8YFG,0qoVJnWbWGW\fEl6/:,@=g8WXA6*>4 -%S5KEV>f6.$`jmmP`/u?2Yi-%cBsrTu#mZ7UX9$?<__.bO33_q*dQiC%i!DjYR))s<&Tob>;Pr)=(@(#jCP-ISeBR%.&/KF8[p=k, -%bEG3L?[S$uK^V8acDYaAe.EP*B>R=$4YdLfCC=8Omo@[HS&%Yu;E\FEbFo@XDB'+3>k^,*Ct[9kLar,r%%F("g.-t99E@j^R:f-F -%'\Fp2d2YGn*rU`IRo@p=XS5YG(7[XI`lt!'cX>Z>a(?^6q#D!l=?l/d\/B@!p5E<>)@UCqG7V-?@\u<%Qkc7KOo11Es2c(:.Q7Ao -%>/&a89IFH=gmCRG.$JgoJ$mCWk/%oE[L(LBkOgaQ3 -%[[kW[.\M%gMoNR5Z8u"D7_TCH04G[5EgWaX/HnWh3;F2jn)N>,XR)aT2$jP$XDFd4AB-rI_[=R.P?C&/!BWWhiJa-h^)(SfL#F&c -%:U*&F"Ua"WPa(CQ_F,L-13HFJ`XWO6d?A_r^%ShGArJm@bK,!@l"sc)rCQ!*"n6p4Xq0e(1IYN4X^e7Vm,j0^#Nd0kSo/r8\Q#<4 -%?#jQV`G^gR$h)\bkDOr[!8O-^Iku*a4uQ@C$&mWq]qa/ursd.:l#q'aaK?MK:M=*oct&f:aghG[S#"_c>2d\iUi"#Xo_)<=nb$mBb(:67e^SLG`qpee.cPs)(+co9/*cYe+4/qUp:;_>NjJQ6Jqn@&2u=$7h8U'SZ)Vc%,FLR -%%SJuR=S?cJ9HDpE4DQc-FTJ.7$!i")$fD/NU`/*,AkFukr<5@g8VeCq@.Fb$&W3[I2\*-q3"QB+JG"@.n'fL'HJ"`W:qRX#3n&T!2#&6^!I&fKPK9Ke@6"I5nBK1AIqq>Zh/HQC@s,Y@>/qAi&!6D,5ErZ_OQ];_)a?lLYR -%+HdZ+JdSE+H$cFCO2o@hHN=J5"dPZ@Su:R0^C_OLk%??gS%n -%G41K.dmpX1eiWGp\)X,b7KUi9VYW3V&.Z(8h*;6tUsIq'iN)fUXscV0npOcBF@8GX`#S'*97eTj(2,5K52hRDUJ\.`rX?Z'pE*T: -%X(KFj3!7!2T'-pOM+\M-Ve*R:,YthR-t_ts-'-4>NIou>/i:rp]JQWmnjA<.o3n!i"'?LU(Upl2JFq"C6=_C@#jt=R_IX,&@V'Q= -%Jld-PG[+ZZke#)oS?I%U9s[T*7qu$emp^[1fFcsu[-pT'S#M_HoH[-I5+\Ch`cj.U;D8ljdT&%N=W@/.l?q.BcCgEN^pdTu(0.M: -%3*%%O6!I3!q]QG]:?W8so<:,i:2&B\.'/XjdIMmUIo.BEN6ogP*RS^T:4Q,ZB]h-K\m--^0Mm#5EohGcYp,%%gjfR<]Z!nXL#O:1 -%]M"FY>TiCLCS%b;[n&tIm;#pi,q`4l_K.a5cc\HpY"OWlc\6`ffdu]AP_o -%aeE9[)(loLPe/5qP]i7#KSr\q3[+uC[KW6Gck -%PjWL(_=,)A-OD(p$GE4SYlk`5,-7cH=?84Cc-Mor];Q_oUk!=6RY+Y_4X:k!fUmKlhJPc#?N3rd,s^0gNj4+I]kA-,U:nfN?A;6` -%e_I';DHZ,)#9:>hn6O.JD3nnJD>JGMWNXtr6+=%i/=qH(43]b7^@.NFPFM>\!'HZFh1I"rZ'HDZd0@kl5:R6@P+GXsYA?GmQ_Xi! -%Mjg7cgNT<.p6`.!J"_$;\?H['V4.N+a9b&3MGN1aIN!#`)Y"C^g.HP.#k$3J'#oi%4k -%4WEcCII*JY(U)h5G&NEUD6*SHS7rGKcLN)hd'UjYF$5*uE9r]>7rN6b#d6!*+eO+KJNP6aIn!c_HfU,3L`dZ\(1f.@ps[!In6;#@QKN:#$@KcPJcB -%XC7kjF=8lBh8ZEp8-cXOmcDVd)o0I0qN)t3"'@o+=bSjYK5Y;JPLtf(A=FN^NQR"]^S#0QqJgX$TA9!M'kp\d7W(i(!F:1-1Qe"mR]7HXh,@7&VV?-4 -%h!*67=B(O[7dfN\j`5Wre(Y,mS9H!S-8#M/.\FZJq83+^l5me@.*jKh.'IkVEob0aY.W`+,(0!IdTXS--6mX'jsK`./Rtnh'AaG4 -%kN:ql?UQg)>C$:<,uSA*It+u;C>N0b&E]amM6JqW's3omjB;1VXX"+++rXf -%c*(?4nMmRNFXfiu]5u:u^J`OsFnQOeSLN6)!h?Un(3Bp>fs^_^YV4n:DG3%ZY\'+2io;ZEPSE@=E)kU"B[!XDQ@t_eJX?3<*J+L? -%XH2OJl7tVFc/a;rB4 -%hZ/WL3Wnn(f97Uab>,ZVQQ>.Te9g_q57P&AEu++WAM/P6P#]*J)n\id",@bq#u_i`f:_k0i,D>O%S2LqJ^-DQ'>Ql@oH4pBTA":` -%1GM^.dj-spl#-""Ng9:opLF.&(M60lEQ*de`NIi*/4ho-#4$8%r`hLU]ROb.Ijt&Gp1qhoaub2m.XHD9QK<9Not7bff$L&grSi03 -%7?+5Fq)7NXW2s!+,jhfF8j1iZ!U)%p"lCN#m$D_C/mF,EYAU9S=F6VRp4h)%0\&\bo=2q7>%4gF"-C7XWZ\@W''1]soaUfW'UI[$TR\>B'.6$o)MJMt@GCCC11XnKY6QC=d4*7DGRm8cm`5[OOP;$<*(T -%kWrc_R'Wa!G@MXMN1$8(N?X2fDV)#XS&DObI]FXl=>Kepem&FaYqs9&g>GBY,us"#O<.3cl<6Vq*hC-XpL(WPlb1/!4f_:525hQV -%GlB/bM_AK\Q]o,WCt[Z#F!#sRMN_:MXRC`\:1fL8$,QYK&T,>Y]gX=?q.[XM?Cj -%]0TV:?P3qtn/,Sj8&5P-kd8p)IB/hQ#\Yr5iAIe)=UHO0d&fM0Vk>@cfm;^q+MEMP8P@l/2QohPSEk/b^O*l=g7B;[s'OgV7aMQT-1n/A$h^0apmEN?od=2eMqsT#nf. -%GG:`*\6o1?&b_g^,ZaE1]Jgm@cermaiWYJhX;#=%s-uYRQBs*$8Fal>*IV=83KP\E^]Nn`J -%Y05n(g=cR\A1)kim"PDeFrRk+gXgeb?BT;Qg-1(YNXr:Em[$-!P,)%[e],++oY9RTbkA[J0-YL3&8L;0*n^^YJ5MeTio=/oIt*:4 -%^TYr(Ag7S2s'5Qb77lmLp7a$QM\@3mIK&1(I5n9o](]fHZHh_0]u[*l;F`>NcuT$)/IQW59uUM4\AD$80`4mKP5Xpi?5_(b*P -%Z#`5,PF\M)6J"C'ZPUnU[''YOEK^NWig?9<=lCklr9mol!$5pTQ)#U0]'T7i27%TakrhF;IUIeU0u"MV'Ld9OX(f43"0-q7ZJESS -%*c[.=2Y,VY%UGHCnVl3M0ig.U,KXP"+XKgW;Vllg@$[lDi6F7HV4DGm4lSs6;L7sNY?]HV5%:d*n*CJlr)&h^m/7q#%S7;Tm"&Yq -%:#YVlC(ku_rV_8'Rl28#]$sjg!>1Z%UcWa!4,klsX(V5D!7/kKdX0$j.Wdc]nMefWEO6KL\4)[e7XotQYT[nHn.JR"da]er=uR87:7M*h#%F*V#"-q&H.!cjk<%Z$TSd8;13Ekb=,m6qIS"+r`o -%[)@U";(ZiBOh2`1DgT4d>YB\f6D?3!`TZT2PaG\HD2Yj9kbZ@IY&kUTa&]@4-b8$']:q9nU`JPB6Tk=)V4>0H`u]3*Ks4p!@&*ol -%D9)\sp!&@/_Bg-B?h?_Sgj1gkDsJd(K'T`33?)?m%/hJW^84XifgYb:Qf/W_rCWn!G8L,a*kSQc$/9=2*U>h?VSFd+qNsChkM4(t -%Xp$Ni790#IY8HSHZi)X\Xf`*`;FE\m:g@AB>DF0Cuad`g%Rs0$IuH-nR#S -%^p'7rXhFGMPC.^Vg?*MZJS/aq#6BVIU0'iDQ1Bh![Gl!'6J@Hgr$!!&pM,0gFC+GLm'quan]2(LAVG&XI3Kub6R/u71C5!p:"1\HWEHHlVAS*.A2,(uOe^\?AhR6?pia0H6nk+(kGHTF_K*#C+PS)M>gG\l+Ioue&V03m(ebCQ+-df`Np=`8 -%U5k*U"fgK\"S[\H)TeA$CB%QAE:4Lu,cF=[D8nL+F0Z,h`r[oW__c_gAlWL.`9)e]fqe$n>cYt"q>,$OVb`d@o*rn_J37.UN""7+UARC8,R`!)'>7I7XWi6CEFr -%S_X^WBnoUAY:e$,@B7uP8g#.L,+$,+F?/7J`s@l!cu3bHNkDN,BsNT,_pX+#'ZU+>>VZ)mru]>BVuCDZKb!M_+ui#s`ab.a;&cNn -%9t5,B-h$@Z/%rjh84'F];a*Z>'?;aH9D?$nkX/?HP@oE[njGr,Q/Y5`lp61dMV5eCLBC3:>X4%^)/u5/E=j]YfoeKFbcV`0mWN46r^@(#;/Kb@F3BqXDR\+>O45@kg"\QH!^:aU@^bt,LFCjSbd:n%N[oNCr -%`%fU2SMgq2qmi=+.h1:>ITmXFeG.p/nEVCDUuP(6O##<70BA3Zt@fsh1TO&pZ-N$gK7 -%3bQJDbt(<13f3Mo2(U-fS'>PMggXGu_g\s5`\us$R_u>i^QgKc8O]mN8Dgc@IYOP$?10?/VEL??Gp-(3$7\Ho,#Y`kGl3lQC45Cj -%B5=B64Z/'CXj]8p80+hPX=Jmh0-*/DIB.F$S[#KH,(_="lEDOU*k[XWhJEQ:X1gaHMhU7:3Nc9[.9G1d_Ue-,jr*T+4l4b4)HP!H -%QBET,a?4ot>;WI3ZRW)#6D7O1[t7A4N&&/.>o(\kE3Gi$>h.%:iCgW7BgJQ2%]/-b-XUuJ*XReNEnS0`AfF*nAq@-4U) -%=(@$WY>!Bn"^SZE9HJN//(8*KQ`^fh.Y^@+ZO8m*^I2ZdKfjKb*e&;qp:S=Zmb=4?egVRPkfE;fDC%FP9qZf,rj&*n+(UEPHgI-k -%\]a+<]X4"D]NK_4>dR!oh9-hQ[p$kYkF=j#Gb$NA-CI)PMq<3^AAhqnO0kd!&q\Z^E=q>SN\u.2D`$U!WZbd/QE3]^C/r6aSUQ)D -%fb\PG8oD9;E;Kr@EgZ5=\0TK&Wn3"=06Lhq=HcuOE\i>IXNmJ-MsRce-=]Mm>Lq1^-U%.^L24E91BBu7kbl52rp[g&YO?Z144ZKV -%4RcjFnnpfN'[Q'tR:qRpdjs+b0Ib`pe4Mt"V_^-s_rNid,q,._ -%"suVZ3\5NdfnCCfJoe#Kjo>_u2eK"4?/aldN2j=@&atPi(-S%@a_e&^gQhTOj3GqX,!X,qFomPS_]#cDH]Qt% -%Id,])NPtFLq?K6T0rYC'`A.u=`7Ft&S?*P:m*'K7ZsQh8/"3Q\3K:-a=ui!qC+DO29CW8Hffjo_,!ORRNOrZBc(]Rsdm,Q1PJn,H -%>V51B-ji&rEWRjj2[1S&L'3]USH/[W7WC*G6BA,m(DeIqd9SGP`k%+u(=:]&u`*D5P'ZjCV:M -%T5!J![*`%/o1TbAqGbHm1dbj/S's&WR_ccP*]YVBjim-J+deHGM7C+]dLW!>+*74=CVqt"/irbVUum!@a?KiYAi=q0m/"m2cn^;* -%m'rF;NL(D-/BG3fT=l7%TFdt=gmU4H!SfoM#aFl2Y-c'hN3Xcb=[n=(a(,;^:e_5QZA$l4WOEU"Pum%UTYQ^S2XXi(dbN^Ao)7"1 -%/hAi%KL76T=GI?qP/[3p!)MGo&"T[k0[j"sb'rWQIJiKY@6"<#Wh.A^<&]QFaiod^P#`?bh_u325]5mSS40]k!&![JMu<=2FtXXE -%NnSF'+A;N*P7!JL"[.@i,/Y,)lYH.,/p7i,7*#^96*4LJ/b:%c;cTKHYkjM-=!tg3#$B=Y,8/e9o)GU/QY9.!XV4kOO'>f@`<*OX -%g@jLZT`e!cjQ393L2IfD$F]=:B)_\[mX@2%QZQ!EYA6d^;l,T=]"qp*,[cXn^H"D3SB`XZI)iOq_?,)jW[\Ygl9FY0g=6/jG1N6g -%;kp3KmIG!6"c1[tf,J#0G:M4[-C<.PkRa&^E;(D0[*#PFXscPtrK':(al8_SM<\ml%e"P:.?jJ/*s.2Y3Yb_lEko9_>EdmI%[Q(H -%]m.D18'AOl(1'p>6?'U2a#kk&f&u`,D-NtO]5j;apio46[i5r)\Fsmgl'%B2OKhG0"4P\@Lp]&7@fa-;n.=u-EK"_Cnq\dZ\PY(sR%[keccs;?]HFopi*r?]77*N*h-sF^8'iR#<\:A#^1e"!.8g4[\&map5JO<]V%aGK[ZZK9[ -%`piJ5?ke$bbtP3GMm]_((7S)_"a2,abbGpL808n>eJr(2c^=Jd%/12%Rua5hp-rGP?QA<2#hfnNG5U()>-prU"MgTok/XSeWA<[L -%]an`s?sPS4GCG6pN3>M#_Z:nmBLQmm(4!I2%UhYfOV4WGpXffg_8^ik>Urp2]8@!QdSBsu-ph["Rtd@UR-c:VS%7BXEq_b!mdj4, -%,m\D%ne_*iR$F#%F*XRN:Xp=R#7fjo4`n/2#sH/thF/l(-j'W!NJ4,[bgEIDK%;)XG\!2*frSqKB'"["X/T=)TUj=ON*I*+2Lsdl -%Mp#q>5baj948Rt8E9q/7mZ%0e*_VqKC*Y%M5bBgQMSjW\n@Yo,ej\Ve--W:CD#%L\bRO+a6sXjSLUj!HV=&F?Dk'VI=F"3;95A8V -%nCCIuga2p(d][ta:s%Y%*4.M"KW@b*Eg;Jhdj6Ot\dXaF(XEIHYYP].cXE)#3HrJTb`fD%Rj6F+ER:_c#gWp[HtXiaIS+YnK!#eo -%'I#R!qRU:,_e:XM%fCT><`l/ts1pe"(dEmpOlZ)9j+#>jOCMIH8o@i%6oo!d5WGICTE71OG:c'b]qmOsAR&D@!%MIBQ -%>2)&`0]J87Ofm4DEr/#8UD:<%He>bTY]sY'R/9s<&nJ5>JG$*+4-@`n7.Q+!Ht3S6-p/9YfGf0jFfA.Q\;4D+_5UD13eKb@46l[* -%V&q''.6*O`_Yu)s5QLe2V-S"ZER/8[6+CRdo2[)H+?fY4;/`YA!jFMM_R#.,8Db26$,R/e!YCUBMe$0Z<6):1qmme=c1d -%,onUb'Xd)AqZ'RoGh#f6!mPqsZ?R"e@M.K':V/mf#!Q`XZcR8u:l]o8CsIOa0gYh>]^/G2W(Ab$Qp@pq<1^l)kTcf0(O+7YM7O7q -%9`T+/':W]sW:^X)\U!H--$P([K*:7_"Od>\q(NH;P0>6L_>[Q%bkfisMR1iO2[%"<"#sTRd@am8$JtkA^GE<7M&9Z<:7I_^n7&:r -%lY6/seR&MK.02j0WBfaVq$j]j=%bFC^9*$4Pb7d]j>Var6s0<.?u\g]K&-=cR]7VFB'frT4/QA[g48sSd%fO)-:f*$>p=ZtB0jFK -%J9eQPF2+7lH,G1F1,tJQZ[V+!RUAhu^]25%:(aE\u3Ps>!A?Ip?dI!O6!YNp`KIV6GHYhR7B(-f\1/5`)[8ZDCioXNk]5eOh -%BW7_M9(Ln09+ektp:e&d;XCUthO,1^5D=T%/T'4KQco7\7jh%IHW=.,8\;d;C"kO=1(ro23B22F)B\\iW1?0JLC$u[WOW0-9cIO_ -%,J3`Q,HXH`-X>b-dO%(M]RD;$ZuEkX]+^^+%2Y5c3/?lSl$R307SjAn]5^O#EY#uqQT6j*>BgWe*Xpb-I*c6:l16]9N6EhiB5K_n -%S`OWHkoW'F+VL_A^Eo"?/VU6;DoH*UrO6qX/iXBIU@liJ=agYJJtd$cY6(#Xek4I]ABe6d*JqkrhYbmkbZ'M:/kuW&FP@pWHU="j -%BN/^PP52i4`&Qk`WqfQnYkLJ3BX[.]GC=)8J>u/W,/djMqA48X`9Zk":S^%*I7XG.YAqpAK -%Ou9Qg,6bsq4^@kNQA\(2RS%N_A"*mY;H5A'a3\DVD=).+2Gn%kOtYTOBc^EeRILL7.o5+WnqtX*/89>0;9Dl1RVDVgFoB*4jguJ9 -%pTfEmP7ZQrR?hi!Pn]#p?;+n2R-;&;s20Ntn#pO.I;;kh?DI%n>i9F6H,^n9qWM%[4$8YfqrWO$g6 -%0QMaPlZU"BB;>akg3HSK8:cmef<-_C')_&pqR?B+W(nDG"JSW^;bp6G3+ot1"GtBWGeHd]@r;iV8F>WtSSO6K.II4OX/lD9ZAKhS -%CL4sbFQZR-tEo'AQ&*HdJKp0iH`*= -%f6BtBL/>Ve5m5sIGtbo>1U-r) -%S.6lZ&]D9l%7#LuZ&C&-]d0f)a=r37OIR5#N>9n>#PVHHjl$0>6nk^XO6#qp5!NBOV$LS"B%X%)';G95-"MO6hqLGb-6QPuV=F7+ -%&6.?.Shsl:rde?S:o]hsMEQm^$+e6iXEcqsW?)^8Jt1aqjY9m%l1jgk^,?e_pB#[RTWZ-F4fFoYG9miE!Lrn/* -%nEG?[JCUAW(HEgU1-,IY\#e-u9Up%%G)313V/Ye^Sp-crJm$Gm!s3:joO(.WV2q$eZ>NB<`+WORN\#ZE.Zo1_Y$R147NWD<7r[nm -%HEE-J)XEs)@2OQD*M]MC;qdm5BDViXR^m@O9>jRdHXGcfi2R85?2Kl9++f?Z7p$G[aSKHio&%H$M+3:ZM+=0G)Q.ib?26.8C$j:D -%OA?AC.re,W:pu+V(!k,,(_s.hWN%tFG5g-TIg/.b:`6=l"Y)kBaY+ssl9Bs-ppns\+6(mJ(O2=6.N'!+]:B>ELRX.i?D'pAGIl", -%Ol]u/Pru>2>-D^H?Or':'f>5j#8HPU`GY?mK,UudE*_/`_$B_e;QR?=r9QI@%9sFSAA)0e/]\L4I3eXYbEq+f)8iI.ui*LqZI2(QAU4I[:boJ:)UpA#r3%9M^nec/sU/V3r$j([kU??^/tA)Vc._n9j$@qNiW -%AfJ_Qg&L[!eS$5]n@We60p7@'H&>'Abr\O/k#g_ka@S?>=krXK_J&RVJT?,9V`9O^*PgTR[*D/T)GLe -%S]`KNRj(Z,BeWJAh./D6#BgTZ(ja/XrRT7]OSVtV_>lpBT'M1FJ=1E.Q*(Vu6B#]BC8a/$7!Zm^nbgmCe]KYN^$8AEqt]O/[WSfF -%MToAse+-O?htD"'*kl1V1"TEGPh;9@Hdk19+ZOAo`kagoX^&?EHpMer?S0IKoShBo)3rH<;O8oL]dLib/pGr6bU%eiXNhJY4i%]S -%C+I+sS6g-.B.C/VcYP,Vd0#K+'+[XEasG1<[94dlpe'.aSq#91S9SWss!HPh&`8p.rN:53S[GdK,8J]7K:'0*.Sq<1\$dL2I[HI+ -%D;F"m&aTpckMjK>6EKVsGhG[@]D@;ED]ah&_O/e.h07e2C#q8UkVBDIf6=&:@^s8qPWdX\D>FK1OiJT%9g\`8,52qa%OXN,m/uUV -%[dl4J^J]t>Jf"3Om[?MQ)&dM70[`3G1b!)PEn#C-W<"8lMH"9!>2aMmY^S63Tk,1]A[EQ`WhPJ1$S+,f)"+!Qg_VZO>hrXBRoSVt -%$.!uI/&BRY*XktMf=0@Z[3)q"HArV]&,ts>X?,aOp[RWPRun_2"$/'3@m4K!V&7`7;%P#Ho4'Q`!7'k.Fmm"kSJWop/.9E?r:no8 -%J?W]i^_)pAl/"Dp^u.,j10B&m&,;'dSM<8OoO=lZ0KbF(1`kb`+LnFM0(hd5iWlT7HHeN\?TK=q.9kXJ)<&LJDD+ -%T)^0B&N8#qV#t0s.e$m";%CF1OQF^"f1^trjanRN[--tlB(G?#l;.aZ.-2pmjC^cgaW^'7('/1M53mo@?n1$l;\deO+Ge1'<*4f3 -%5Q(^gYD1V_l&B;s9IlGR3".#I9+<)8Ot?;k6?%h3jZ^kh9Hn/KB%^f,;:g`P$Q,(3,_A@,#N#.bjVXj9h'jbJDO)B1^W^CD1^Lso -%J(!+*Cs_EUD!ZmbRH-G-p_:!DDt1baG3@ZOj&I*(qOmuje-q*T.RD@d\DA>jPK.>NZY(@u"GOBY2OJ,2Zu6*"j]Sh0_?cAY"0j`@ -%TlH&rW:k5ToP2k5k!&dM?K=SAYRi>i0I!%cV)%B?O&98#ZYg_6HJ9Co*dn*nileM(pT=Magl4`VVqdgKb.-Rm8elf&K0du*+u444 -%=B+_P%9Re%E:jAd*`9TYl.HD5&uhPgS_,_,+"O)0'_@oK5/T-(@fFB3f8SZV=Ob32GDR[t75_.3&JP=A;S9^I:X\(C[c)0F3h&D*(RAM.=/_Q(/RkN@\p92uco),l%t4s`pm_bV7nWO?*-,fOo?DW3(E\[0_H -%$4FrMpsj%1kZQAkM]FG0"lDnX@Gj^:Ef&WObPDk -%I(pK'gdudVio(sd[j3NAXB.?\]&&m+hp)r->e+L%].t9>ocUl_^&LsO^@0hc*!fPmqU\A`8*aXkbmSY@mEEP)X&SFfQI/WaCOY^. -%=2m=q*.Q]'LbDA%0X[Ve(9;7`G>(6hcO0_KbC6p4%WfR0?PF1FVYph\fI-KLN?/lAl4PHh[Nfmpq@_k;&RhM"I:Y'SPRs;@@%ho,eXtDo>%$0D3P/(iA%"1[TmVk;l2 -%0;X6tZ2mY`C<)O\S1TR.j2k?/"piIeTl_S*WWpt'&D&gd,X%s%P%[eFfHK>ME9=DsA8G.0!sj2R6aIFF`<[,2Phoi\n*HMSo:e1t -%BKUGi\&$`,@5VE0OI8t,@*u'[c8WSIj_d:`A$+OQ2EOZO9?4*[2t"ubeN\#Y+b+%c -%4bC"%GWX."PLia#,#Cu'L-%Q1\\+?-e6`ES@jO1idX3q;DoHC`$2&;;O*`gPSO*mZWcb&W5C-'5S5A#DQl9gih4mciN5C>RXQ&?H8pmc`&"!=X,K@Zuho-IHhM_aq32bPb';R>GG>M[hQo`LZtGH)bQ -%+j9p$rY04ph9r7&W(W:GcIH7]qV"=e\6>_@H]8[p7n:j%W_BX.^L07"]_iFd2+7>Ge]QP7q0Sr#fp, -%%)T/Z$eY\]GibVLrh/qIKM.CYSWW#Z/0Q-XU-2p -%9=-Kf0ijt1Wqh]'?oui/>EmZF%H0kI9Q+s+3H@"`DY)"n6+Le7f)XKZcoA7&WK(pO5>[qiIG-YZ5!uHHbNDY*u;1BI/`+Z"dFKfLTXa4Z4+5i(:#OB%Ot1(H$iB.;r+G -%oNE==S&!t\#29[_Up9YD6L]et:=!]bKh!g]_$DPI3iT*_DMip!jbsG8KMkdjI1+]f!E+RV!E$iJ_=5"md$#_JMmIr04L\P#TB$Bfqdj(lU1Ul1h1I35Ya/"2o-c0k@ncNQ.E:SDY`a8_XEnmXkrp-1Q9AOrQ?Zs5h2T(2Q?u&% -%iicHf,TLk.iQcKu4Z*7L/iGqK]@h1i1j`o6Ziur_Uj'k!Btf!h3/KmI5HpaAS7YP:@(68P-YJJ.d#q -%E7WbR:?>Dr_J1M&YCpifF1ELX,tD6]4W>cl/C3^r4umHqY.tB&^Y'`nq5YFl[@[>!=X>KL -%q[pY]V*[!HH%"u+C[cg-`,ZZ(gfqmkMY4n@U5$ITO(aD9t0/3mO^/]_-Fk[fQ"X32bBbk^[ZGJ<*/PWQbC(3#-Dq8F^#S8X))l^ -%cpt>7P5#"UCNl`e>8%"JOW)Re&nVB@qU_MF8(_D4+E%VmD_UY1r))9UrhP?DKU9AA;C6_B.6I#lG6,=0KV52,eGobE#6QOR(t?/V -%aq4'0VPtThgUT;MViN]-"erS.^p=P4D9$T"qhfS[eN6KT.i&K.9mp9Q1.7s2^ZSd'L^/BAXEE^(hNKjVmV;2=OWq0hufsE"l:`5H!q4o?NZ_\ViNbT\"53(Na;Y9d&6VLr*C6(6h%55Fto1%%g^X4g4uj=UUh.P]kjReFDjIPo+.,1Y8X -%XX0C67Y,>A0s`5V]F\_ioMTH/@cdEbI77)hBum&?K6/Acl=$FZ>K?G;QGYkF:A"'?"kQ^(nef)JMTi(:&I4@O"8iF?WC"1Y`oO&P-GA,>#uR-_ZN0L`B/2-7,H?77Qn9` -%poNoELY[JV^pT5pIC%=UW8$%nM2aekp0sh2>7>I%qf+0UH^DNsdDIDgVI@M!@g()$UPMrF^Fkqljh&'D"W526N"MT@AiB6n7_W%N -%'hfjNU67>Hr>L!J)S*@E$ol^$kspGHL7H6>)..as`F*EJ0PC*^I/S=AhZEu+j/'L(iU)6n$SjU#/lq"n(E`cqoP0uB>XBcY/Hr&9 -%G4SYk+0gKoU0Gi#ESp?%'&;`#*ar,kfO6Oee%,_qDU.Zo6G"l1:A,hZfF5tfQ^DA#+8-k\G7:MU^EJ4k4"[n#j>=*r5?70BZW3u/ -%XB4[df`D^hVX!/SKU),0jCH2iV#XGs^Z2.7O)@+Q_9=G$Sn$VToWf\iJuLVMG!"aqdjh'tg;4T*JOCIN]*.ElE+d@$LtZr0d/fA)W,DFJg<-uV$^*cS -%ZKYmG7[7(iHek".+)sr:`P*"5bD6&a1AD3Gj<'6SD4RODp\PQZ/UC[d^1U9jih0Q2ZBAf*0&!tlRH$p2%-m.r\!94N>G_%q(>mR4 -%>PBef:EFk&\tX5dc1oPTUiAA=XJ6[? -%p9@$?j+Off,*K5T,nn'',9[$a`BWr7/oQU,EdUV[r]]$TIQ3N-.(Y4Fl(!nlQB1-QM9`Ni3Cd2jZV<-9_',q\SJ>#gAfcGk2^Nb1 -%&XN"rKB`aNdb=)0DtsZhqtUY8>&#BjI@V=#p-1rap`?:F>"#t3c!3)Mp$qG!fRC)6pJnd2;_*F7O5)G/cITr*VL6OX3eAZG5#_,& -%KV*+g@LHuXEqPX#L0"*J&i1Rf=4L(D#B5fh*P,VXhEcc\Ds>ElP6eY$eQ/"j/0;u5$ijEiE&6N0!$hZ?5Sho;(N?-!YdWlr-P3*D -%b2.qTG%$YRe0cZON)a13[]c=Q,;i:@YCll)B.[bL:gP6L0ZM8mc$.(N6rSQ?WfVP:,uCoF8?tjnSCQ4NDh7/8TI9$>h/cMf!l\)r -%+cqi]5th>lO;Vo(muG_&WrV3o.lCHC_f64.?Z4Nq^H@H*Om(6mC1DXc`'M+M<5FX?Wh7dY>1,Qn?#]R*/&PWFT,@"S&!c,d*8IZN -%Za2R\95PiX([#$(WLZ>4'TOcTXXdu__Co*k>"^ak**7LArCHhcTKr_H9uQ&i_Or%p_[/,`G"CqmRlsIp$:M:8QlWg?MV])#M!'os -%+3o"4_(EN%*1l%fKN9"KP69D[6LOARD$Ft2iN=UA3]^L@,4Cpf&Y]>7NO'AF14tmd'p$D3Elh2L=0A4F1HMC -%+cXf+n*fCYZ5+f(X'0@H^D39>T!lM8T6Qs/VSl2,#OWaaA5Bc_\4i@'58BcNl+cK?.lF1uQ=_5l.JpJ_FP:_QV`/473AF#+>S;RR -%lmfob5s1M-(/#X87D=)uVI:dTcYOO+9+ecj8\SbY#u[O$p1`,rfG0L'WsauRR8QQo(=O]uP'A6Ul&tFsLGTs?99'rJjQ_3Zb>^6V -%0WG--(,Sg9X!8GYRD:Qt,SU)<.;!iE(XRlHjfUDC-f_RQ_QJ+@VD>2(>M0K^N;fpN/7r6j%Ad3Z,%+.p:7r -%(8=dHQ."dIL)jAg_`;;HYLGSjM -%jWcHGU-%Qg9_^Ng0I%BoC9:C@fO/l]*:nd$fW6].P5SAR/:!O`VB-VLW`[M9$(2S5f=fnY3QArGjt@SnlLT9M-m]>1ch:S^&M_$BfO*:+C;V$'c> -%p3bP]7B-HG+%2GrdsbKnPLsXEja)L]C@Pj\BTLgW5F0NB#]&D,$#n.LW[t8BBU2_^6T*dE[-TK/qsLG2.NeI97Hb6/bh< -%XtYMJ4(WSt/b+7nacC:SnG/#h=*t=f1$h76U-u*;gdUW1Lq+iRjtajtLjiWSX"FkAd12J=fc0A#/Y@K6GqX#Sq8$Loq+*M<*YpqZ)%15jX`>a.LQJnoE1,rc&Po[&W"DW9^DDGmAeas0M -%`_Z2mpT^76Jr*0&Y(*afrU63os*1c,Nq:tQs4@;I?Tp^Sj,a65s8INIO#U2;o7+1HEN?H2jp#*A0.Wd%R`a$?DT\QY+NFT5J38H]67$VRI! -%)63(;'f0)i_Bktp?:UHUcldQgaL[h=qqW+@1hm!lSs8CNDeFK3j82\JkS'EDAk^O&SKX)b#J-@2XN>k_N"5&D9g63VB"OJ -%Gm6?5mbp,j(cbnS-!:N9qj)8Qhnk]<#epAr_g'9mMS"MV_'=jU]!*/nDCn[4S/%*/(L-53"SondMG-)t!\6Ura)6Gp`\>2%=$KC_ -%H4)jNf2npPSsuFQfGZQ9kT,eDFfpLP.gE1bQspQ,H)>F/$`K__/V?b.`=(^[W@fA:X$>YC%SAo`[)r;VcAWC'a6 -%V5ndJYKs7%LV?)=>NnjBD::NdhmL1p!-_O!7buH/ek,hU.HioEs-i^4D\7'!AN0:-PmRW3,G-iNVU)EUC=8+NBbZt-=>a/,LrMP$ -%4e'J@U012<>IS))BRKB$bPu7M<]e`\OKe=RJVFDe1#*F$k3pOI-2>,<99&;<2Pd%._c4X\iO;0qVQeH"Ph&&iNeg[1Z#g_k)g`5o,$&"FF8Lu2"T1:iR -%C]dKa/\pj[>R6\mCjt\P9(kYT'1eq0g,'u9'4UtnfOWqUWN0c7X1GtZ.5=mOoR@2VM6J=>jG-F$6]m-Hk=SM+GnRQE@!=h&W/,FF -%Mfh@tBd`k;HAF^%(dWAZZF9J_BWbR^N'S8Zl4?:p.e63*'HQTGaQO?(@ggHB=G?10C -%RQ]ENA'[6U5#_^5%WJ8V>I5nCpfmkTp5D&<.DN)Do;V!3*^_*8Vt3[pYt,/M,_4goTTfC(U,$d!1gS?Zn3jUVO]tLHEJ%ij4g,#X -%oOa:0*H6J@#2S'_`%nO94!>(NH+@`,iJe8h@HMD>N'SVdQ40)Y$9H4k!5S>=Q)UC=m%AcRSI=U^Asp]\Efb6G"$.k^=g!n, -%H#\'^6S-+>?nR:fKo4kJ\_+T,&F8Z1;$E3^WC5Dpj\OS^KJ$Z4o%Gd@/TUB"nDeEsQhdOhdqfA67eK1\QRLk@[&f(*k;)QMm1qNp -%2\_m9eU)pIk`R?G4G1JRmJF05I+bHCHO>o<15 -%^67C_G3[9m6"nn?kI"a9?p:h8ikY?:jO1UN4M*4+aGdg"\Am*EF5n<'W6d01(9-'`@`q_lSa/N_Q5hXE^1X_BS%lFkQRB -%5_Cb>he'UD1lk7]WA@dqB"$P7G0W^p*=J#j.qO>ANZZpJ+3o7,3Hh]W[j`WZXLMtsXjHC>+f0OJLS[6%jm>32s@6pZ)C(_RM#FQ>GT!s#Z:gX.c0@BTD/O1cHZ8=_>bpD&+e,](0_g4SB$2E,i&]kYho&;3@%6[m)$ts*[Acs(C9^!hPl6aU*3d*GK9c"mFtWKuLO=Y5)W\I^GB+l28387jtko:VBo$.)MGK -%TYB*d>9&Bt;Q;o_c,3R6Wi<5gI!O)m1_IhPfPc3HK`/1%%$'ksO-N/A'iY6WLl*k.k -%"P%c\"1A=:!-+6?.;;WA'RY`>8[Wt];;mjtF9"TdB`D1N(20_lT%c#a'Ro7R-+:ngCt*t4.5,=N;q;Nb*4;^fr:g\RklcRG:JW;` -%_,8GISp2M4(0&nWi]89"6/aY#Vj_A_%u[uT33qn%n?L]^.uY#9@C=[L%5;=hi8mJGiLmT]PQE&J1f-U5Md4Z&#em3dF=&`TLK>B# -%1:Z"9$O(a.&WFldkMO!*6BlCu4<.jX8KX!h=P5*S$+@g#k'Zq= -%<\*:W/nmjZ(^Fp%-0)dX':=;?R;bPg@h1qmEhPd+;_qs`h,>H)37)jS]Y& -%He?u:grcZCDRR6Vi_u5-rn/(E:@?$?hu7?BR&3*Cih,!R;"qOu4A!8ZZsZ>+L\i^_8W]!' -%o0bFm&I\pbEE`YXmC^URWQ=&GB/b!^9rfmjX7&.t9ANs2)Yh5^1j#bbg&'DffLp:1]sL>F%FTqX+OR,EMjBVc'NF)n%$u_mc;ZFt -%D.=M\p!(n8pQr*cJJZD%%\Hr*U<#$61s\+4ifOA=mD??ggj/OPl2H/!n;_3Tal,5QJ\s8Z;2JtQdgR'\r\@AE]Bq$gk"h\H8qZ:M -%&W&g*KHHerd8r?QY/gBGJU&-fH&*4TIFZ@YI(O:C9A5&]JOOJD@4Q\h4b3tl(AYDKWuODhp[s,3rZ#65[m?!-R+4j]!%K//_.Dg: -%0,Ic#(W[sDO&ELq#!JhI<-#L7[e1_g+4[R+Y5d1;NQA[l5j3eMqWErpnNS\^B#[VHU&-a*"/C+$%-e-UQ8NpiWlnHomG-$OMQ`.I -%;\P_K4OLR^XNIc>lu+,]ooZlf2Apcb8DYq'5umBl)ns"Tl$"%rMXn^#aZ[;KVH<+rf0JcMAN*9D)KqAISk0<\jhOKEeZ_mD9.nn47mTn2",,;.E'`FNc>dK32UH7[ldrkf]:6P^2mWl+10F4.O04m*h8!gohAB<@nfM9/e$EBPmT[2QEl1]GUSf^TP+8L&aOI(h$YePaTOE+)aM!Tc=Y%7Y+H`RBQB)]h*2&(.+O<<=T^-kT_'p<$Gk6u(ZB-+7p4#.^EcB/VZGqK]X]/bd^R+P.*=8082_g,L= -%#=VFM^h28M_*TamGi#7'pYRQH+2"p:U8`d*(egC.NY-a&m>A28K\VaZIu62JoG%7),0Gh!4u!t/QGH:nM'>C"pA!nko5Y4.c'u?pP^u-noL5ue/-5`a9B2Ik)pgGWZY&W]\#X-CBV!/_O0N7/)@+e#Xc_Y,]YOmAlCW)$(/^c:-+f4I -%&Yjq"8?p.JHJ8>DkN0XP[WXX61ng03rbT'EnK^*JM!nqMS2E5RI40qH\V5;dYgAg(5Xg9 -%1]8MUTI=:"c<_"cnYHd[Ms8PQW2a?hE#C!PIO4^i6G[eD:etl3O!>>6l(/iI4htbAhX(>FIn3OMqTu),)dsQM5UgP^KW6^.RV:<+ -%FgK0F9c$(4>-^>fXtZmqZa"GKDEn6EbPSQBqk_?p)@4mY(UIRD3*=1s5]a!]9nJ%mHS@i.MB?&7`>5q#nAiQ=fkS.u,[#;0R`[8P -%`tb@1LUZTj.>]0:WSk6DembifWRDgPR`h$Y7bf^^P%JV7OOIPjkXin3:i\P`I^4DoZm(^W&J1`kc!El0_SmU#3?sM?0h0Vg`_^b`4oIc\VKZfrle`m;\*s,XF4gATSMW'kqd[COkQ/0')slO<\qTQu))=Tp!G4\^Rg06&6N4WfA)R -%g4(#)e9c8l2&AQ$raJ/K!B$N:p?>(U[tsK6F10U7dDoZFZifp']7Fb'K]3<>UKeeXr -%.jKB^TOD?;me/bn4uo[]_e`QM"0F(`GERuj6r#"I1N(mNOO'lu%giH&[,tZSa:3Y5'6l8nhcVLooOT`nA.J`0[JZsm]`=JWsUq3Q3;h[l]lfYWH->nYAsP[a*t.#_IS\n(%t7AoV$PqJP[Y#OBL4RTiH(MjBcI$ -%a+9/"8ced/J9U8gmRm]8_b"#S*U3.s!pL9'lF/?C'M8GG!,?2.+?,u2[G8LU$Q8,]g/AiEmns[g#;!%N:(%:&99Sa?MM0 -%ghHL>F!B6njtm(9*@C![!^)gO4(H]`'%GA[`L)-^R_=M8,ET<5Q-/6si=]-=*A_bF%bu_qFDu))$.hO)Kpc'7`!M71T/=E/jg$:2N[A`EH!U0:2V>&U_7l-4RE]#i]!!.lO!&Js'Yip"obihdcTKfP1B$Fg\qb -%MGur0WgnG>#$.oqrYeoEY#06bMHnJE=luOcaqc\F3\lZHkL"\/6_Y\ -%aoXuXBtf_M+"QS#W%gV$c4IL+89!\8e6)Y6#3n?Qq.b_Fh]MrEc#D&<58=^*E2rT6Z)E,5Z;@9Xsr?2is^V^If\'-4KV#\n8A(8+M,n'ZAr$U\0m]m=P#^'9*!eh?C7>1 -%YYi<*F/X)[Fr_W*,+la%4Pu#5&7O`1e!mHUI1^$E\%,fpnB/IjVu^O_@KKWCSIpX'9ap_sl.:loQEf]rZ -%E=]u(N>.6f%^_Rg;a::]Iu2eGFI;RP_;O!PG;f'UYM_,TM2J[(:ZKb%k<&QhfO-L*E\e9.HBHUWi9XOiK`MuM95N1uSNZf?Ok^;' -%Hke>cOr>nB`4*?o;ZZ/g=Wp#J9c#ePmukXW3#S5ubjKS3q_m`K!Mfo)^1fL^qtjXO=pVS$G+3L:K'dG$!(?GC-FbQ-il-"8B5S:( -%3+fEj95WYrSSie85.X7\,r=)(Ag&A"KUDe5A(:bgg:R%to0o+ejS-hG.6Dhu#/@h.X%B#*/7tDOI;JMt=%1kO4u602Iqp\iR5j]] -%PCOpi)7[&NTghhHBW*^k*(&t1qS[n^rq7,@\l8WOCf?PoA?d^dQVrpa*iEF?0g)UCZU0>MGZ9c:9l(H/n:I""@HH;s?b*:fX:\W( -%pmIUWmK%(tg/]tmcCN_ADJ--Hab$G3Gt_'/m"#N)V8)%c(Tp\U^A48'ZU^qF%+NC`c_lti(h,GdJMc(jN- -%n*_SCBPE%67OD*K1oU*R;>5rl_4ul6(O=FRjjJ!Yq^@3`4\,!=U4j<.R+G"l7T"O6RaLI^#1tk:Ht:JQ5pTB/7&KutNAgagk -%5&N#0Df+]Ea[HRL(W(#A$01nQf/1-;#C"nW?3tENL.8s#@-mBDDsieUH#:4=I);%q$?hosI`RJtBrjFKl&-99rc$L9,m[@ijl=.U -%($oP#@'d^+R)r7-FubG(:%Wt)`a$?0V&TgBg3$1VWPE7<=Rj3QTqlJ7M!E&AHT\"bKj[S-YdZ&^hcSpTo7LG*7M)\<5qt;:Daa(P=ZsN^<7NTg_9-F[KBULW7Z/^BHVeDQQrsS\)X'Y.d2# -%n'ik5BUh*-@$6kG:+L>A-au0W@S&.ps%iF!=8)bC=_VN0I=IHG:?)9uV)7-GInZ2L1:0tJCf7(u;tj\)dH1UOGmnhY+k2l.*HOj@6Xgo#1Ra7WPm:E3Zp6&";ha:A*QqW9$`rUkC)0@c5g%OD7\Cl`s!L%B#61jQCN>+A?(pDjf5/h17l.B]Q>6mA;O=elY3.\kWNVRnU\FVfP -%q37.ilctVjm\"PBb@J>I9cZ%u+t0BIZZ(D%'LfZ\^oo1(T]@&l&s!25pW0re38:?m3&M"L[8AE1Rt\D35s/aN>HZJclYK>2h)uUZ -%T4#ee8s&DJPWQWB#YupCmL)IKA2N]N']Q]%mPdnaBV,)%fDHA[uQc.rgEVLuliB:IA3AX+<1OitgFA`&6_K6!p(*epMl6p/*"-a)>it+9Un48Di1S -%Wo(Ms=Z*]f1+RP$=".-U9WOZq^l.%%\KU,%+@>)hA-E@53WFHqK,NF)kB3VOi*Uag#*#aahob6BZ!s3IfX0G\D&QN-pDC9VDBK6kXBo=DkFK1q[i][8eU>8b'_6snE?";=9L,J1ZHBeAJ"cDT]<^&3fbG;I=9 -%!/?RPdGq6)`QlmJ!*I4.R!'\3Wk!WW^)-4s#L%Dnqjj.JDsL*A!q_poD.'ttIiE@3"*Q#+_V]aaEuG.QG?o&7a"L&m:LJ%+(QRIZ -%bBCXmAd#["j3udB(REpHobVkS15:X.ci8Gg9sR$LSW#)^EEGLZm!fK`&H^m3#:P1GOs\P4_sdfYLDN5_n*cU#%\VArOO5/oc4XF, -%Nrm=R+ZeE2?ggbRTuL"6j'M`7W+NYk)g+;MBJ@%8qii[6S?;>*ObKR'H4%n:\L=SlCE2cLK%Bg?;:;2qolY?:l!j"DI-khmHY)OQ -%9#Rukpd)(;j.;Fsi6NVk'F/KREsmMDm**RB7"ZI\SH.qkiW)X#iCY:maDTgl80R+$hj^s#?<0g.04BCE;\jheWqXuXKO1p+3S0`[ -%/;''rr\h!N/KLg,]C#=ogqT;ZHe`9@kCE!/:j$DFH.a#7G)i<;p/@oLCKN*0CB=Q4=;PY;3P8^3Q6T1X3VPm8JV6KU8d>=?&aSiD -%%K#MpF\6]4NY=HrIXf$T\:(R-.;-^nN4K;``2q6>gY%Jq:-G6$1dMKrbg*&F7,J'$l5irRfFa?Rc(t*oLEJ,%+meh4LQStlP_9K= -%:>Yjo1jDo!1/^NnAB/W97;>G8O?k6`>)@Y3rk_DgLRh\`Q@S@@US:4@DnE7$W@*Vok>FC6Pl8E9*"?j+UJ>f)%LBKn=c(>/?)Wl8 -%38H1j;(S>jRLc&Job_h`H3WNgJNg#/>(oIC3i(@Wr&h/W7ChKqU2ELZIsbu2FiqQO-d+=Bimq,7M=5;OmbkZ^kMGkrWOit_a2U6m -%'8ZdQe8u(@OUTrH>kI:q!i'!]K:rdkQsce02M)/#/G].((WE&0C2JYAP[CAA*oJMMpbdqc:\"l^lG9"cN1?X+QR=K#Za8^ffOcEZ -%haVVCJbh27Ca01H>M&O9!.Rn.gpIKG\R1#ui2^Inb+rqs_O2E=_A1j1HF]TlGn:t)fP&0Y@^-4ZbOk:((YJ1.n$P5I&^re[[\jA< -%dh3Se\;jt6cRE:RnDfDHlWBDKF^:'_7tsj/qKe>k"W[s%QLLg:7kqf`&V=J]j87]7=PK%Xtpl`4r1FuTs^fW?`7 -%m_\D6a0(r0SMdrAP?o_oTN&'asN&"no0)7"7_ga3g3T?]EcgYh$8o^BpIXkn4R4\\h&$I7F/bCSXND7>0^%r[89(Z?3? -%lhV'WMJ-f<*c&+G)guQd"-',@4+mT.:IF#)f<-$?;>d#Dpc5gss0)1_?gr%6#C9>K[srk0s4dSEofrKJIsh2j=BEQCIXb9?o!5Iu -%TDnSg>>YJ-^uTj<@/>ZXE7.1!Va>NAk"CI$?1:dBn`X"AeX6q1Y&SF2l\F,D[k82OQMGb/it"d.]GC]oY9MWQ-.T7:NjpieCj_/`=gC9BOlinN0;^4Hq:p+i@%X_ouWuH2$$K;rii2`h3ajDD"l8ll#q3? -%0`;Y=`,I1IIi-W2)Xp44%,(\5Jt$-I+dpA>_PtWq*@'(QQt-iu#^,nQb=;XZ -%@8JpaBQVb(WT'FG?UK2e*]aUcS&]u>YLOaVU]WL!%oPk\mg-NFs5E%dkBI9[5G71&pZonI&lcO'@m7U?C_GkuZYtqH<dp@*JuhP2`BR[P=*'BXE:+kk\jjrY]H`*e4P@%+o99+=$BHc -%nJW*u_#9pX&1WSO^0iar)CTGj&2af#88L05IoI(B^bfAd3I^;9XY_+0",B -%1.aB$^5b??K"HBnfN1H&,N9#V((gT-6i^_4BN/C81>UP#n/S(Oi[XB$LDPgB_fXjq-u$UB7cL,N(pWT9p\P3P%5j#&]1J2D*dr\C -%j)V`C10C<>n/C0XXN0YO=iK8p5g`h"_Fa)nfC6jei6-4Sro+W4K&sLS5C?JNjp.mi%TkL!a]CjmB)W)qA]c&7;[`4QN@ek1?Mu64@;fJXd;' -%3I@@:;#=c#Ti3oR56r.!$0gZo6)pMc#g0XO/D.EEIm=O5L=fcN3MU7oaHD+&[#_So_?8*q%O!-mco`8l%JF6Jd<,C[DBe$a];'_UNX+P-9qgG/n4#EhD7DH6>q -%nOlB-"@)YNb>#GX'Fp(G+rB>0UI7ZhYEq;N+RMAoR7<5IjeoaJo9A!X6/b_PFKi0M_F+"C=tV)6LPK:2"b`R^`dpA$co,(5A/SaK -%;[>h13&<_r8?G@QmVCB&mJWH;6H@Vg:W#FoW&fR(k)kE=o?SC#5A_B"Zlb0T%C3,(E3\(M7]?.A7Jt[#Onkq#3LKfM0g:4sgF0lq -%aC[VV#^3-KCZ4(J2.Z&ZW\tp04]S%=%+\j;l"`Tbb%HI;.5GNuFhN;\ls"TaJ[Z**.YW4q#/.lEW(h2'HW4LlH#j=qLMn'f2j-;_ -%5d?T7G,V#n!\+]TK??*M8PMS$%8W^pdnWH_72=NDUlJUU+LbB+KH,'\!Oo_M`mKCfUH)4aaUt>'Bf',8NrA]8\cPil/i"&di_2bW -%%,j<\2.(E2@)r\(I@bn>^a^E8%=of00sMmXQc_VD#",5J`Ub'Yo?(R>j74!FXq?k6Cm^$*+"$NVY!g.Ch?Q9r;$g4Q[(3;)%&L\L -%)B4*cWkFcq8Q4.IJMMjPE-!4YT,]+ -%Kl_AZF-RF96Vbfp%P_u0B`jl[<"^"@0#Q/(PuNc'pHFB"b!Xqh/oZA>Z8RXG\4!>mIo70`\FJqXiqnbU[Ut%DrZH&XOPooQ\&$<@ -%FRVS#qNWGFM$mM\gbp?IQ?"Z!Jqrpo*fWI3>&1LHIW%e.hiC:X5D]>X58#\UU>-[5s1T=W8bV9g`%Cbq)t?DnBJNZKob;0rppkP1 -%;HMoU0<(1c1j@J+XBkMG9Y2W5IS1U=,=d8uSqAH*C0ANJDl\Y[m!G;N.n$X0(#h^^K;PoSPlGNd`a^FlmYSTjAH;^cd;% -%cVSH9K!;A$%Y9&BcXHQBQ<96QlcD)h"E9aVrTl+l2+@2R\3:ZB,:M`j?#<-J+XBj656uVR=p8.C6(>(('Lf'@S07e2r.BLOoB>BB -%n,VnW8TYRB8g7i0$=NicGG6YWjLE.>];LqEf'ur1]ABK]j-'ajDK^g?F+.sPXVO2/Bg>j=h3/+T^p^=ib2$TO.'>T(p!\6M -%2Ap#M*);NeB$1H4g7k5YWOsYO!,O4`m5g[>*e6q'#qW)u0Wm>KZOZV,T4mPd+;gF8>S40Q`bQl8HJ:+^NY"57@/9L1*=WFd4UY@QpUH?Cd;,$0_s314Dg$uXV5)V/$fmoR15P"3IVps>Z -%PG[s6j2inDf6nC'HXFbdO5&W2a@2EZn,'oNcb.JtLc9-\UG4T:IV98O?IqVaOPGJiAW]j'\3\_Peg%#%6&[MGmA\op.1.oNG#,D3 -%N*VW!+Q`hk!d[!j&n\CmS$oBpBRpuTh6]S3U-Fr3&*W_Y$l4VAnKSHmn*XXd[>:k%T!6g.mY%_@DP\FtL9$;u,BSh__)uc"ap!aD -%`Y3sY68\CO)#(-^H]3hpZR6U"YWf[2AW>5V0GHfo`Z"18$o[7:BTp.$:@&RiV%Jfjr4ILjHRYAafY946K*TIIq2VU7SEa]^A!mtU -%XAKu;G91U!EEm)2\ZN.MYaQa)'b8D\]PhT=0:dkai^W:BWh-;_=!M<@XKlYT.occH(I^,Dn\!#PJgPK9t:'VJ*")J/RWW/qg%Yq2Qcu3gZs_"O!i]Js,hBZC2U1&^8WD?W73uTn&R(1gZ3'E#<$j$*tGBVAC.#3mrS^beLqKq -%/qpW**A-*$Qk,:kD]1QH?6.\eET8*fI=C=K+>,bB*2ZMY:q7Dm?S+4Fi=@>bIro\oKa2Tb,7JquFf#pO1($I;Mcj6&XcpWm6We#e -%g)>rG&SjnBn@6SaKL6[rLm@4GM3K8KGFQ8?WY]UZrA=iR98ZZ]'-VH"-A+("Jtu2Of%9kfU#.(*e!<$R?S>Kk*ZE)Y3UT-GU":OU -%Zuq\2.u4'q/EL=1P)NK%*L8JH(;8%:2N?.b3\bq=+3?(M#WFk:I5e7Z!kDI5W?E2r56VDndgsf2*eClUh)'KF5jXZb*d!T`M#gO)%>\eQo$U]?p+2_]5C-X/Jo:*qS%ReSj5[.=jrFm#YN-f9t;is*7+rcnW+b4'\Z,]u^Z)+I)p3U"dVg:$`$VS&\DD>A!C^>mC"ff\bhn(L9W -%gpo-rs*j[3,.#NR2&=g2BP;2H5Y0ei1\a"Pcb.jPk3FUbH=V=^rtG9G&(*J\a7VJ>`g2;o9_EO?;C2DT -%Uq^gM1l^u0CS!q5=05-poOA1#-/b8@hKQgTYJlt[%Uli@2N(/+'6-1?M?2i7/sJ/>MVkNE8GCE2r(,?<3tdOe_"BBd<8c`@g(J7)ZOq?On&HKW$%B8Xnabol1hG1Rbj`L -%F:^Pk;)al#MIZ\AY%E$]5rU4iBBc?\b+2VX+[-Ch]b*Ra%^9 -%F*!;U?ASC?b4IjnqKDd^MHpN]/UNUW=,nMim&=kT7)4aTEuNbir+Z@K_@j!8&XRo-;\&-naE.7$la2D0P7Y3O'MXP;B8MBhZ'%lH -%LsLH>%t,GX%qO),9@4iX@&P)$\@HgT.c-QW3:1?44(Xj)3%1Q%'V)5h(q+SoF2"29681n]im9,]aeOE!F-ScmO-@Ir*JksXN3Alj -%]#cT%hg+kLDT=@R--(5:/\l+h]3q&(N9>Mhmr='Hq:OBq2#!WZGb96sp*_AhCH\,e'2+9@?f?,?*E9An&>KTt!"s7S -%0IXa:7W_(0ebNaNf$%\ehHq&:@Q(@O'(M^$N,;,GqEW'%B^]rMTET?,TprnAg3:)T&t*$);RmK0\3IZh.`fB&.k=d+J*4c&'R6('l+"^+,;Y,7(kh:jdpX?h*.\H,'h_pd$0NDJuefAJ+ -%46LC88[8)X:XZf`\:\Y1?K8ZS!)14QLd<4Rr8H_rn#![a[*l^VCYTNW,X+$KNSq(%A$5cEd'o7"H\e+=k$k(o+3;qJ^JY%O_,F^W -%O8J^NT^r%pfl]ZCX]i77CO+C=aS%ggIBe%VI^'SS'S6.'q"Up`!C#28Hq4J@+YN,Il]8Op#Z!Dnkk--Li$+K1o:R((YBg%52f?EX -%/[MZ:RAt?Ffo)Z%"!UCepd_HK.IH@A=e1dO')7&H0:r%Pc(:I=KEPW;Mu\?R[;PYH>N'65SnF5sWM$O,R^CT[lmHUF42S(:VVSi;0AE+;+'B!;7Aop^u4*fdnCG9uhQI^0HX\>Dd -%jjfOf>=sid`eta3];Ta4l4tgmS^ugto?;)!H0pJmGSO$p/U=WkD!Sqb0.n!a1C^rblVN!1=M3=+Cod8($u'+,Z7uA36Q-5d.3XGk -%Mh1NE(3HrRnARrYAi#5JVH$BK9EILc*PUI_7T>pF?!4LtE.5P`I^3;Dpc1M56l9IJ -%OG`_!/PTr=`O%:o&W`[6L6f9pg1G=T>1O6cW%+a*>GO([6[.-S8I]CX/'t<^1Lb/Cr5A]A5h&K1aB([tLQtd'2Su_Y(9B%;E/DhK -%:H3Xt[MDaPad9TrLZTM\FWcSeX*YbcVDK3);Ap&n'8os[g71SYMo(EgcB?\_mojIG3C5HtE[Hp+d5^Ee;*qIR6lF3f -%$p\7'd;Yq.D\@&%%;$lhWtr]:eGIm[A38_dkhB^8`/;J/WZVg8L-bT"fSI`jm8Y -%AT!dYc>+Y?&Vk3M*7hR(=Wco(L;q;G>[gkVDk(GdL=R3Q;!_B92n2/P0E" -%qBjdj*54JJ$@8+cS5#YtT&]ac@pt7EEta:ck3*b5"`?no%VmOp?Ol6'f4/1$G6jJWj`SG9FACdh4GoiXR -%AJIcD'eDVPC?=;T>945E?H@/E]l1RNWYeUB^F.mena8F<$kn^>=sIL$'08p26J!qQS;LL\0jE_hD:N#_#JgqJTp>/elt]0_NkAAP -%9k+6gQQ;aD%cfVZMX)#IHn?/j8L@gP)F\oANo#S!cp5L^A]Pd4'\&:SDUN/Lo]4,0N3"9pq9`W&n=rt?'ZBS_Jt@BF1qGP6qj<^` -%nVoPI2`+W"WCEXFJgZ%K'h;+X]j<&UZGXVXd1JV<:fdLp>:\BE$Y;pUoieeE3(`WLi+/+rkIqnS1=[uJ]f,%I1ZXMm1?j:lQH]>ZLmr#G`b$JE:YsJlKL:GMY6`o&&43B"O_pVO -%`A;/>)%-uD;'Kua%;eki+JgJBi9JI)nM74deXNOm3S_J@V/MR32THbJ"s<^Q%^Y=&-oc'ia-ubqV+kDP[E\re_Y@TN[_cfWUH;a& -%6^@b3R-Vf$J"nKcLE/s#`1HlGi\!?akX;*&.!_3@Y[*k/4(sL"0XRJS7!H6Rf@\(?d3X&eJV'2m@4jV%MqMrG(M,:0 -%c/C@$fE#>NSqI3k8-e!OOD=?qlJ.+R/2LTQ>^MR4h8r8IDSD21AIU]?'#d"/U*jkL]L!?m>hT4XJa?J@YmME"=LId=R0AA66Cf@r -%+7aK*HF+e4<`>\*mC+C_`E_V+E,*MJRfY>Ifr5N.E1&Ja"MGW]$_pk/fhMHR15eoqXlBRk5)ASL8[&J*,h^&L:YoM>.IDZNOu0&U -%7Y^CGQkd#KK0r5[.WXl0R/K#_VZ>unl -%0#Jd-L>[g62!qcF\PFe8YKbOB[@l07?aN"cJLc)LVn5d3:-'/CN#;c@o+[aIk2Q8C+0VED>8Zuqn`adWn#Rr-@l]LPTT"UB()"(, -%3$oU=io0$BIpPn-=UcN,Yf0-*[k-Vk%XU4dIoh^0Ycq+H,@#"abJOl\pT:UrWqDL73m`H@]N7CO$l"\`NN.92h+1s:#':^iNAk'I -%Ji"6odRN8%SahYJ(Ie["2[YK3V.chOS>.'B*&fZ?,Mk#-:t*+`_b*dZ0PN6'm9oTqBl(+P9AG:&^0=hu,G:CC*#Lu]Q_TOZ:P5@D -%++4DU^0qaple.BQ3&iPMs4XtTNl(:aiX$JU.=<`KW+:(F$po&)Vm[Wo4l"8@9OAHLn;R.W%Em]"=?n$V;iI0jOSnCsd0RuGSObX_?AEX`C__G^ -%BIn!oOX\Qn3,Y6,H.,nY6`iRd=c3l.ojNYgQ*#UR`mRtR&kc0,gX?jg)O#[j@9%SD>^R`t$[gNbGIlP)b524L6VZ*Z+&uL'PoZ'n -%/lZ(J@j+ohnlSOjjF\r0e2T]:>:aK>=5H7nS,C.*p0'P.js\6n?reUR&,IKiPK#VVSYskf2$DoMWh)`JW+\i,(Lf:fKsp'm[Vc/h -%,j/qd^/s*jeg`)jltL?L`=*RR,a7k$l-t50!Qh"/,W^&t2`"%@.'T,p]k^FONc^AHd]_qh4Gb'1oJ -%&#TQ#8P^J@7Hdk=N.Ipll>n1L=17;M@O.7b5Tr"]D.,@/]UmNeikU91;>loq\6&Ag=/HGf6Cu?'[p,(h8Dodd%N,dRulQ&*/M -%^4HMsk*#IE[lXV=qj>f/SI>fWn0ZOAb=l=!0?MXY-m24C,mD'm7C(1IG:HD[hS'+e1EXng%U5^h3>a&tT`+k+`QQ7")N5'HU**ih -%hHnk-bC0BVLVJpVQYYe4m]r#-,Zt'9aZGM)VSSD*aUF@k;q[>m12r&pUj&$o.S+okd$r[b.?TlVc@P^/+U5%&8Y]u]2].`XYR[IG -%eJEJ_3kBMp%6!^O'(lnGJM=AqS>*68Lf&&QhQ&B<*^0l:c^:"VP$d(cHQi+BSa)=>()2;;EbeTr!d#Lk>@nLKDAd^%20Lm(pA4t-M%4o272=-ougE -%TW:EGki40,kiB!?kad]_2,ch)q$sh_c$qq9,Y+]KKVTt2TS_XKp,,Cp+H9SfPGYK`l`dqb(laH!]9-'tW&2Q@9!;^X8VdYuXW -%KC)hYRqfGe)e>LC;,Gu1PW=i*6Yf[6+JcT',bu!6N)m"@RUqYrZ"C1G>\sma9ics]A#;5`Z9K]84TH5.c_P[5fR*b>'j;p@gDTNS -%OF`Y96Fq;h#?NSKnb0SCq;.if":2/og4Z]`;rAFKbBc9g!("RXAZK/:-jDr -%`5_mrA$1')"mq7Gqt$Yb/[G/o-7@32O;';tRdk4U$#fr82Q5S'K]AmM^JBrR.Z*,t6%Xk\_Q+,[;T?]J=Y(8tR"@n=*1ZY-)@,X3 -%a??&_S'O>Lq2@7)Nc:fERd9]>bX?Kb2Lt,ckc*3Bl8IjPBlds?JTOEb/&tb%]UXPiCsZo92u$7BD9_:S;M4"2PFK-alK-=8\>sYW -%-Nl_nlY?d?$aHkoDmtnV>E&c]Z)'_*$6(gk3nN8uMFW:cI`#_,Z8+>YU?+],:%#t!^)E<[@S)J/4o(lZ>FS=UbOI1qOH1>gJ;LZ- -%".g883@=#a+)l?,"LQnRi605eB6=CEhq!T2M_Fi#`S57nn+O=t!hRrrNX/RPK,I%>s0rO;,p@=qH\C%jokorqm&C4= -%Z)a=<[PX_c9lP!!?]'9klJa-ff,:sHI!#J%l][;1>VtId<(aeoY>FppMA/>Z6hl35X&JbRm.E!\eA2m!4PI@@CWJkOCqd0\sf]ZXJ*U6^:Pl1P5'f,i9Y43CqnYXJWlL/0F@U>5M=62>hBdPs?^J@:E?9.tpA<[Yknd&4C;uWKq9p<"4C@O[MKD-5uf<2rTI"k[i -%f9Bl,qa4La.87Qr%rf,8:1q,62B#oIRb%Q):VT:gD3<7Fk[#6)W#@PF@MS*Wd?\Ed<[d>M+<)LE&!_+%l)SU;cu`fWF7DsE_DKi& -%@]DWj[;KrGWtkMVHQdH/C'Nn.1H*/dhDLX+8augU+,p(IG#/ePmqi^1Mg,f;*1=WD[MTfYCM$DQ_U>`2(*l(Vi.e_HeZ0rX@YUj+'&Uo99:"+Z\6mH`_\%tS]q-g6c: -%59c39*!7@6D`!Ye[(A7`gHm7qC.*VOoF?1r&.U4EdR[m&Y3k[Ll)Hg/@B$QL<"0rg2:K6npe1]_G6@@gq-l1QW:-cemTn8r>3--Q -%h4)#sBW3gTKhJ;E6+.R+Jk@u^l*?RV"uR@pj`U/gW=$tTX;QR$)?XOjO>YQc)hf#+V4;bWYlhJ38_XfCd`1DSgr4L/Gl)QFn*IKe -%?;bLYR!pL36[Nm3s3fLJ+jqaF67tnVIfNcBh,;JZ>=,u+OJl@YX<C\#HG(TruqBFIk4!Wl88)(>EY/)rWsX=kgE]QJ_ZK$GraUjc@c2"tNp@C[M.CPu#I -%[d59`f`$WO^Y/'?EZ*1]Bftq6N:g@KEUVJ)J%YRlfKgkFMRr<[-Q1--RjqVu6.CaT5qi>TL5Mq7SXc^,@FD#^hI47Fi5E*6'5pip -%T'V2tXW/.u#)El@@@ld6im!AAI//_#PmL8i(SuZ-]/GBPYXr5&RP[Wb+uanL3GTE%-$Jh4ZogW2Ek@ZTO9T.B9-79X8sQqTSt47s -%ROJNu)*IA%Q[B%KLmW4jj>?pX!Vp$P'hI`f"Lsb\KOYS^d6T2BOj"lZ9EcMO0eF'0!4@GZJR\*YN4I[a(RqbiWuo\^HpY7nhuRa$ -%*+L#)^R*Qs8K!l]5TP^B\A[mX.BCd,d'0!JTbF:@niAYEVq;=qRB1YU&8fCT]rqUn8ZTiYAcm,k(O*SF^".G]aC&uu[aO;oBNX*5 -%_.g:llfflNWT!=@-?"?.O12kZfT?fZRcLTtiqOlZ"63[X+\\.2aP%9oS'hae3fAb8,@5no:m&P9^,L7R\GW14b5m6!MI/PH`mJ9Ge0D'+5B -%eH<9X\+LoS$;gUXDPX/Ph9%X]h=18$4bNML('@96Rb4K_V@5V8%dV8T42#EX@it'/g[@8%ZLA9j9d8`lK7^@Rtt=#S71B`)DpgV2B\B>@Dlg@4fMlY4Wi\`:W=f2!g-7 -%&b6(6.sg,t.UN9U,W\m-;iCo%)9gRX>-en['99`[&cFhVS!hbKnDd'.6,p6Q"glZLO+j_^:;VISXP@-4V]i3_rm-GF]QRn/Hr;,Mq -%+2;Kt`WWmV-cUqfDDn,J&KFueQD[4FGGYO_/T-PTngm?X>MlShNSBMZ'!V<;�G#9J(I,`XI1-DHo]u$79)O]JgeE6:>naHl0)D -%T$WE,:$@Pe((^76H,JBCU#(er/G9&W"V?3tIEC:hP0M)8ahVbT6Wdjh)6>JnV_^oB<$IJTWgdB,F,@5a[5$`d'?d[YY19Cd9H9>B -%W,]jTSW'5SfH+T#!quQC[W>?)Sr<\npa.>e4H!>q\H4);YirORX$!+(A:TDg+4[ht@Ip_G55BXfC,6bWCSW\ae1WEE;[(XSMF))( -%>b2,m`nE>5%5h""!"j*C,gF3\(%A?@s!<\h:)$RIT#tO$Lm[rV*3cX0:FT -%>1*Gq3u['r[;FS&*%0)YDfe4pO/:quGLl0f_ch-JEci1>jV%bB<5QU8R_af\%^%J"VQfc!`J2*b@AiNo#uejq"g3ubB:BXUBrP(;4`O(n]6g&91R -%Lr"qMIMd9oC>8#o\?cl+UcUmu2M9s.CZ@][Ql?YG=fNa/.+en>/ -%dArb>p+7@-Qu*"%-=.]'@^S(FqXCiZd6H./]m#.(a)0'%mS#6DB=BGN?;@k,:q8TGf!6iAkent(>u[JEKD_eG0*T -%=gH_I]afR-_R,!G9CsS1.CS.43khH>BG[l?nb*oMH0(8d)oS9;m'3>EI^8OKe+Cg;e]$2Ca(X*@S8dS%08RR`hS=Pgo'4c9D=H#T -%j)F<"'qe,Jbk%dhARn-H<@.cVb>N7b#Y,!RDMk-gl&8?7#N22j$8J=KjFj*(Ho2\SrDPNB"K+QGEm64C^nkt'B"Y@6h^/"Xk`5(j -%8iP-^jHh/l\oD+6ULthHB"7*`ag^FJ*T!(u/UX7hSJT_t)AqU.$Ga52rr$5$@MZ^9r>o,'8?5f1c#XZ$QNib=YucfBP>m!5gsaCg -%\6K5DKpfAGPcP[2Nm_c!OT^;iVMTW:$6mKAh-RTfo7F!DY,*!9!9)A5k>.edmWPe^lJ%q(n.Ed>;^3p4*Rh7gX](bH%InKnoS\lruHH(#[BQ-_Gl_ -%:)6j=^p_T.6X7u6l0>[5dK\5*+`$aX;Q_g1T/bNl:://@QulV!"Aa%bL4sPkgKPrb@?n/NYGAVM4LW*,i"F$X>Ia7r:>CEG`[5LO -%92":NpjA4pnE6]K#oO'lN`FdV)EmX -%.`*I9I*uGZDba0Md!>bo2T[ibS`^!T]iH.FfPInV;Y=.TrOk*6]&VV99+e*t8+p..,7.=1Q0G$/B=J/>G$?1H8<-[eIiDH7)WOCFt1*8/4@=7sLB.l-oB^NhaR^9gW0M -%HGp804D((2T#sULVfM.,4Cf]]_F1K`Pk]#SYP]qJmg(SZoOb;6#'s&`1CLY)r-C=1OGbgQS_&O@K'k&n`-8T@,k9,%a=OR=`9=3- -%l=&@m]!D32G.JgXaik(*Q^5EMikrZ',>k_adQe@G85P;qK@=@nbqJ``JU%#\.^&2SUdS]CUrd.5_UXGAG]Ps.D;l@3kl9c]a+&N2 -%V58Yes8DZNc(B7ZF99Ea2GhbaGJl1;(>/qN[\:11%,d\1R>djde&>_B[W5L1C6i[M\Ri^7V8;Bm;o**%XRb@(AX.Bn+=8.QV"<>6 -%O8`;q(P.I+3KtJPsLkof]Ysq7ZiGH6h5Ce$8'E&NNnUtf4Z2+ED:aW(IdMmpiC;M -%:_GVuOt($(Y#K6fc5Is4g-P.DfspUg4jno.7MJ7-3d&n*W[N]RM/J_9!,;+)!eN'l+%mO&Lg+p+R;@;/[!hG?d=X$1iV^8#<-X.M -%Na@Ku@s-e4?Z.6nh/)_r4oWsAV=cZ*`P_9nUBJr[f8H9?g,>GIK,5UW\9N8-D*aEJ]4]_=)a4@mg(WB.'DoK.1NDS(hMcsk-G6dL\j<@b%Npr9XBQ-m[#WCTpn -%gJTnr2RI'3YKq4@U'-##_IE#tM/Q#p#FG's?_t?gl#H,&j8->3M!,VfN#ilEG*U@k)NT@OfBOtC+;C7^(Mc>))Oap1_&O;81ob"U -%V3&J/<_#)k/:hS(2,Y?.^qht'G!sS>D*0P>1b&A)NR)FdK1$fbRr\D>iSl>&Lm6n%3<6,U:GK(Z79Wj,o@i8@Oi8>7o,ULln4c9U!V`2BhV"9:*g,d'h3\Gf!i\DNLe1OD,p_Ej!C)C6cEWa@>`Wktg?&hLXcKH0VCNPr0Jn -%Qs.=O(Je#.q2C<3-clRT=cr[.m3cqRQ\rfO&^`"GSXd6b#*#^4!)RMV3+;>/[dop6b)$(RU1NTNbGoLVf -%)d>gBoqN.KYTT(_TS1i6%ocO5j>iVWF/_f[&0M1=gdJAgC%Q9e?rTU$[IAG^f$OaAL8Pk)V036Ro@6cCkATaO+g!f7"2!.(G]bH1 -%n0NZlPN#N""BS;0_Sb`CO?4?t_GoBOL.WY+7QNp>iP@T(QW9@0Q6]i?67$O#G\0bs,)^hRKVLj93siIEWmIR=>9K!KPqbcib!:#J -%+j:gn^6\[]D&mG1`P6o3Dq\)K9e!>eA##BhFI?><^BB^LOP3.tO?U,q>=/hGTV1=kY7TH&]hqd`W?`:JBkrK3]!TAjPF]btj^eN? -%kJu*TfuR?4-6&qS"e.k,*J8WYc#Ppk#A?[D/A07H;*m'E%p_4=PEBdf;\KXuZQ^q[(^&6JkL#W7XsELKXaQ,1R9*Xo8uYp;'WOa1 -%5+.R*HX%>-IVBg$.s&*-Dk$V(K:Fb`4"3gK+CII&9Kr/%+d`UmR((_nO2eTV0MJi2p9Ppd-Z*9$kdI8-dE''[]p'j9"H2g=fH7HB -%R+h -%LMF7kHnr)5-[0ZH1BKTDU0*N^7lYZgO4IrE:6:d?]/Hc(.I`nr]`))<`G\N%MV#lSF`Z7aCYHfF#89@*+1@3op1e:<'0%Nu107(G -%@5B`gW/ZYWf_b'5-A`]b`[[$W'0_S>*bg"cY7Hn2]87\1!sMPVE#`uSMZsAncEhetLhkWb\rgn(IL3XbZ$01FL'i."YrWI05SMjR -%Z0Xg5glc93%X"<,3pYk#'\40)#HjS0(<RE -%PtpRWN9Mk3[5I)46[0:;R$EG9gVl_o#8r,U<*[qjJ,s,Sf9j#&:n7XQ&5nBsJZ(=ESX5-7CXh'HG%-6JH?H^!b<+U7dqN`pE;;6)mKW!c;mSj.kqLDM^=*65S9`>msR,a.ZLGrE.b=oa)NGWW_1GOEQ1aJ -%PmGB9E,m+aJ'A3K=&2SP"T9MeD(@@oYaiX"`=X;S,j[pege0[4)@jANuFjTMja"W(\ -%61LNs4tQI0Y^;74=s?s<02C=*VbQ`BMb:$d7*DW@H`t[S%_!0l[9a[f?d?W0_D&B=2W_nW8FmO#8+COu&;eWl:k`,c/>#?4I!Ak7 -%LK/-4`\hG!d7:a#enGVD`CE%hm]FDRlPkrJ%fRc0:BX<)>9i&Ug6f[kUl71W[iq7S"mUOpKO'Ok^*oQ=fd#AOmglr=L"*OI0FHJ-EV'CpNe0bD0H?R93TL[-r6`rDbk:@?uedA$*(rQSD>6B,O+Kfs9"1\io -%1_?-O/+d%3Rq!gX`sU3pT2L8lhXPGtUXh<*Ffb/gG'1["+S>>%_D`[*l:aA2a%g%^c#6bj=(QP66g!1Ph9?nL]fgkMDp`#\"P+SM -%amhTtN_8SF&TrBgp,H<^Bcu0ep,#)`N1K7cJoOG4.S9uRO=ZWVYO\AfVC`-1n<3>nYXX1eZluFqZ%lmZ)m;.K6;s:A/`NM"Ca[t; -%=csC\,"#9W1!T%fKp\8PNML/;"KKQTg6"p*kN*T1A)sAC@$lf0A7&6dZ9frHR2Yig>(cru#,k$D/$Qi>cp,CIdNfK]#]MrVPfq') -%V3OQ-Rfc)'3epP>ZfML,8&s5G&L1A-;oW]7'4=r`/rabIU7D)8LG4+,FnB7/MM5*H8>u7KlJMu_aL.iVMLYbZm/58Kj,2CniaXGc"bj)_LU!/5AO]UghE:"PK12]O73,l8DP1HQW?Zsn8BhV(:NNEZs -%Y`XjYdZP*<_U.!T;T/DUQEO+Pj5ZJ5fjmK_`$nfsE/K4[q'J&VLC+r=?.XUj94RL53k.`MEG'tUB>s-?,i5V4o33^8;VH"fX$6F; -%3phshSP'3n_Saff>K=slCD=,Hi:!Y(KX4ETY'hXoqPOf/NXSq4c=#3,R@ntB)U&Bd@tdI=Wgn1B%m@2KfpH4/a#$uA*CIf,YRsQ$ -%,78\'iq1R%D`G0F1]4J"ODpCF`FK8*)C(Y)$2&r_p[dcB8V)k) -%c5SS8pt6:eCXD9^l4XE[=O]+fHCi\:W'/H`>A/L2[%]5N*_hb!Y(^&]Y%dOl#&V+*O%6fA.a2q0>2 -%\*f_Y"Y-_/bC9H!4+C@n7H2VTqoWnCqpHi$DRU%cF'<:D8<4/89PrQ[2F!P8,6W`[M3nthmtj"`/2X3.m#36OV;\MWlPUL+:#;8m -%m-=cSMDNF`CfF9PD%`-/QH&e-DPRdF,2R\][rGtlb9n5':4H@<`"nrKKL'gL'Vdtr?h+'DR^'lCGVSMhYldi1k8(#\`W`h-3Xjas -%iVH;BMjf]h-c),XirXkB*Vd=1rAY7!h$g`pjQLMM#o\AV2D,5/@$W*KBP1t9:ts@S>L55o6Xjg?ig"a*9mr!t!1"d0?"cB?bHXe]0Io+nB3(Y;( -%jJUNDOaT1i-^YUL7rl1E-FU2=O[%QN>?<>--=KCU;SNa.Be$GBN/=tD+V_01YtsU'1W)%QA5>/-8cFc5.^#jo@7%nkD6\*sO^&oD -%%U*,f.7cE.6I<[hO'4?LBT.p%U2+L,"al"8kMZu,Lm/COW-h^rS#"Qi`[8R)=H3L0!c78W_B%r&cWo/^]H\FeEAkV`a6TQ9 -%C0K(NS?R$hl+5cFjjhBDHSN&.[$\:;c'W13#D9IF@Bhk,SLbX9di$Z&;J;:O4-!=$mhkeWIIAZ8-lYZN0IPTjI)"lY:@;=Zq1Xf$ -%0O?i@HO>&n:;pL+-/NoY?t0]0+\pM@O2Yk@ja)9rKDW#unC-!mHp'Kjc&md'*$4F.*&*2_>O*8e#bS;_OO -%jJmbMabZn4JBPa9*P,/6d@jY[_=neGm*;II.'`:DTkQp`[#pU>1t,1qfF -%Od0"J`Nf&o4"5ThetH9rQt/720V:1&"&O2tSZMp%D]mOUMb%Z?"W>L$7GD6*U2@(*WHMB!<'!E/j^E;-N1oG$rq<&hlnZ`HK2niu -%$V%@X;bC9s0.>ptno4BVLP_=#`H<%tN_aNM`M)M7MZ*_A*OXOQ6V%utJhQdV*q>]B%&aY:W^uWt1mYDH3#"jo&6n@'ZCT8T0]k\j -%2[XD/i1qWe3ul3a*@TH:>\YnGiWd%cKu*?2IN68Cg9IF;-^#fY+I$=9+&k))k@jX^oa-4i5s'%M9QGLQBS+Y0joqVN@VOD=9#ZbJ -%o`R\NZ?m-=V2u2CSk1)JW?G'*'*b4Z1.(THgKIUbt!%PB/F/0KmEX?$!IOTDaFlFm*H4ADet%Wpt9fp+Ku -%dQWSZ'4.f)GBG;[.&Ub;,S5s"06PRGNGtuh`dO69BRgObgMDhJ?#80&cHX7'_8B1'--mVAerr`H\XhtI)*L%-8I3kJ_GHh3gd6_D -%3O=opD05I5jJ+;[CMQEeUH#87XYGmkH?Mp6<;dT4S[Fq)3sORXJ@M$gtR?O+[>VeB9Q85.c3g#I%Qc-A2n/X -%lmZjWA=,5on#X$/n4<3cD-+pb1r="*D?juQTNnGu]6^bFQ9NF.Qfl1jo-?8um$hdK"LMN"7gV+,Mntna-`:;lh7r5=e(/sfh>C_K -%h#@?s9Bk(Z't_pr-OT2lF1ce=M?umFkkGq/+&Be8-ZZNK)W%CNkqr("l(M>(7dj!#<6N[e-'V(_Bch41* -%9*?oT\0Af0)&pp^+n-WAMBcM`%V;]PDMSa!P4Rh5jrd"JEX2F@l41rB-D2S&&0Vc$9VV3b30(h&@O14X-3Na.fcj%.6KC`hL%p&# -%r%+QjeKo?,r+5;mOP6/r7)H/Cn_'@ug>F.Ym:AC=LFa]2/Jkqf_Qa+jU.c'&@`i%3-J\1R<_=t(@]G:$3fmR9148a8"0i8l]\H2c(I`-Aab9Z@:7']c3V_jE/kA8/+Un?8o&-7*7Fa$'j9#RBSc]3f5%QJu% -%YcTNDZr"Ef$FY4]kZ3_LACdj%W#*AUor1(k%!'%6XAKGoW:O!IVu!(';^UDpn:Z3-:X)gH@&c2_r/88as9poEsT -%>_uuJI;i!6E>"/?+OWQk8*!S`iooA=8g>_q_YP;"/u=YiO^Ss.3)sb_;gtN0.4rj"mVn2Th[Z:`(J8;D\r?-t4cKG%&q8T'5r&3fZQfDB7:fa(^of$eCT'-rVT'=X5#I -%nfsT&?/`IW(kT?_d,I4C0C+3M.:.^EKdne!7\8*DN`=F/aslOU[UrHCjZq_W_c94[:$6SQ-4b)pM/eQoOElC`\I'X:FlHW-/M&/^ -%Z;.7HJos:(,5gtW)3_fm)@)7Sg+K9a*'N5*8@N1"o-:W&526kG6i$pndk]d=N`l'RH5%j/Ak1TKku4BBLH(Zhg8!M;l[0@LuqdfdZJ:<_<7BfedZu*NN&P*TV\W"%UWA610drAT&1c"[4RbUXlF$c"*n&j#Ttd"Q5lZPO4C3W&`[R@ -%o2mLTE!G]K6ED*8E[o6,qB1Pf7fmQ;Oc=rXYAUu61(5NXhNZ[mRop&oW+t:jm4TC0RrU-S0f;'1`1h04OSrl^91eD=PN)(JKBho! -%I&1thSeArcgUr//)[&3/.3Qo1VX=uMsh'(U&Ep?]$Ze!hPNDRiV:caT+[HL-)-_pT[Q5\r7Z&"r5<,F!P&(&SoK59_cf]$UnWaQRBH>$De^ -%2&0Y-AQbePXm\^L`<50IAQlB?/KlVhJRV.9Um;U"d-YNV5n/J1SYa-/+l9-gk)CF(\7CSf$TWOp6`P_=p,a%mNUmLg.1D[ -%b\':JZU<)cX2FM%C5gU,bbX#5MZlondDV;u_a[:M^(HQAF6t^KTU)7JEFCk2TpSs">Nqe'\-?h@@90o66H+l:UFX<+?e@+$0]OeSVAZN#cNl6t#\gYH=Bq&M05@,-2C16MZ'+kOWQ3&3U=5HHNMI%aph7(T,'n"Mh_r$' -%Wh-A(cPd4j2C$FPC.^cd4.HFOA=[+nF?b2,\\dc5gbp"b,>a9-6)5]+CQ6KMGm&\-J]b&fVcS+/ -%GRE^^pZ`q-KWVP,@'Yh'H=/,#a^iasR%"#,>(Wq";G#/Cg4Q5QV?%?rp!@0bMFsb6mUh/MOfI*=SP$q.p4Vn-R,SiB5ZE')"(=.) -%8p2+50bpe[S>k(QEpl&W\_/@A+_\2\Dht,)'t0LI>fY>`%rD0HT<:)U(J/ -%I#h"t/<"J5p3;2;NKiJbm85:S5hl$ZDR&09nfEdC@Qf+>;UUR7:o0u=VIh(oe_`us%%"!gIdC-gfj!'0fH[36Qo2:h7JBE`N*gZn -%A;R-dMK;lZE=9KmhQ*J$X_f6s8Lm`W[oC'+Bq[EG*#nll##9e[jjUfO\N68=,7+D([hUJUB'+din$+,WUK(FN-e_;WV9M0nW5QhM -%%<7LY#a*f;(3F<.]UbMWJ"ClKX&St86C\OMert;Wj!rO\XZCBFWGqQu1`;b)6ai]TdI'\\;jei.]3/acOh?Nj.KgiW-u8:7=`2OXYukq)CE1YULNlKXkIEG0@OH]j:Tj1P/t%" -%hBeSQf.5++^l(r6-PcB@M==c?V#Fh;rXoNC"nVS.Z^144Cb/&o\;ZePWRCpW!t#3L<5QELKaLE@3fM4=$BW`gUX>oTiG`&*0gPD`TiORAK?aFAei9Cg;rY` -%*cf(.41il/;FOIQ1VZ8]8--1dp(!@HUKb$:X>G]6a -%,k?ba]I_-;'@p/QmR`\b@uZ2dKNTIZ9dnd[7Of2?R&XorsJm08$"SCZ:YcEY=ceQ3M;Q)\+ZdSLIT+^/85g+b;r7*T.M3<4WHL"%-DgkN!j-p,"!c -%W2l9=Q4u&0.9g,"3;s#=PtQa$jK`7[bH!25F!g4LE9%p') -%8JSBRBghAYe^>cX%]WXa)`iKmO@Be1NP^*0)C`?rlsq633:LSqe$1OTQUkAiN(?THTHb3&b6)`=9eer:Y;3&.]""_U!.f';G_TH\ -%s,>?/Zbb>AC/W@/Z$%&TDM>7.ge/%`[3p4.$26GFX##Q:_SgU5.61WB)bq[q/2Kkui@J9t+&NS.$-k^j4;3M7&'KVf!5d?/+;n@#r\n3(g -%J]i^`*LSrq?ilG!Rt;$5c&pA?c%)/O\%LZ52&rg-YAkqoQr_@0m4X^uBQZ->b"DJJJA>c<#/+D7)6+)06t9QXK*oai,P_^?o27%t -%#H!;,G?MWuVq7Ec047;*:-:'2!'K'%aFhCkZ[h;\lY6h,/%bi:7rd3dkW)b?iBbJD83KX]1iCEW'gadJW30V`^/EKK6R1euNcFBX -%7V^So:b=4HN3G=f#99&LL)H#W"jg%[TrM?>RT@\K^2D=5I1K#.\+S'l!+HoGMfbI[%kHg='tUY%9pa -%7<'iU\b!<]-fS.nYZ,;@)C./Vi!*7D)_L1r!a(?r>Q@k13>SBkB"jju"0AKW)?oM`YrSc>GM#nhW(9pIq=)3^9_:k;UlK>8*,]BK -%:kbo5qPi//!ZnKjiA=,k8qB2F4UEKmo(AK7psB,Rb,o//jegL>,?#hU!;t3I*kkQ&U1k&=,c3%S8(OX-NF@.nnA[;nWEZL%m?Cg\ -%6"I6q/G1pp_K@&dRUQ6@+]5N]rEb$T'R3S&rGu5/EU"d98FLB\Ls"8 -%1.d?AobtH%3d(YKN6n5HWA_u]; -%Ks93MA*cEW98+7ln\2%S2(+?k&L*i]9XO_Bd"^i"gb?:1A[E;cd$`J(`GmgO'7$*iga8FBoW8s@;Tg]KLGc@=BiG_q2$BtH#?_JB -%#e%@-NW=SdL;r\3cEoT@b>X@Bcr3'P)d)Lq&`hb"SZA\l4!m\og&,Sq^&,FZ9CS%)PXSd!?Co=WFZ6$1qMl4.Cbp6VIDdEFdP3Z^ -%U^f"L_h@.Vl])=l`V^;"^K*=g-[2(b9Yo@-on*aDRmk1hlUW#887"u(5-0j'kftJtTH$epkfg:4):6AY0p?TkF]Udu6Zf@j:Mucd -%;M]=`>fFF&Z:[.p>cSR*0Z,qlVm^os(eC/ZO?D5d(l[NG&(1IBXH1+LG@5%^PT,)*OkkXmN:Q[uW`s;]rK9PNB.VZSoUj?:bI`0D -%"2eIG#&AX`.:3K+SSrE($YuM5\p%=#@OOICGFf)p3L)-j:EP,%nDS4OmIV%um)Sso_uWttFf9cZ@Zii@$E2,UaL -%iXR&+\"Be`?JM8u;@lMR@fm2lIRrlp%<<F5!W<5st(%7(e"$%H#@c;qrjpMd:dfA71ol1K\LLd6P=9$t?QJ=l^uGXVc($0kW@i8)jRQ -%hpfsR6gX@Z6H;!+J![3Gp[km/2+SrTS#]]i&pOjS@jG1RR_F$Xl530!AiSjr1%#>bY;)0f(*SlnfMZ,VAn*TX1;+MZ9Le9*9R8PV -%\"Fr&3p8pG#.H*?J2)Z*d&QIYb;^r&L-c634YA9,)M`+aeE-"Gj)'Z1Dm09Ep -%lMt=ekLX\df+SiNYVm]28AD\cIg+H.LV[j]fkp!`2hX,W8,Gf:hKUU\6EeJ2/rq\fqrIl( -%IH^@(]>?3X+l"Rr`)&8iBlt*p,-E?,Fs)GT:Q-4?@CRiP5hY)+&LB\'7)KS)*a.qq,5i<0,062IeJ>[C``dQ*2OfXR>3fHTs -%gTF_aI][JeCY#=uf33lqrY1%7)?h.4%!h7CN'YLB5cHY#j:^iV.)q6E'6Trb%bT[TYVj;7aeDfP)+$S-Y>f`h#aWnlp-8&b=..VX@1>QJ[?P)@mC4*Mf=NQHh,1p -%7cWCVdc@Z!+X`'YCNfjEA,_eUf8rPB?;mcfB*YJo=jI0BO\.HK<_W\:k+;(*f*']M,!E3E<+s\rKD7Y*JjCuq'Q3Y5@F`7SRb"Er -%.lS:3ohO(@jeR4!Mr[>gMTI,U@jG?8eZlIP06YV0ik!CffELX?.moi/DXagM9$%O9]s3e7j`.HY'<:gHR=b*&Lur73,-7SS3(og3 -%(52gJTVkqsU1dPp.U_Ed?FMlLpK:BNhkh&E@*ocrk%rX< -%=rTT`-YbNi[R,8ilkE)jG2nan/tP(j$]mhL0'kq.C>!34H\qu/1$<;5ZKjr$HUhARWDKu+Z3!^tE7=MCfRCjff#]1j.,Ogb2U<13 -%#;duWa_fb?M?TCqkoMQ2YY`u3YA[2FrmLE^^h -%1$<-1-n86%r_NpK8dKiMnr85S="?WW4@&ktL]^=?Ipj@=PF2uK\Y(0u5ZW%q,M-bN[G?Tf#Yf*i));>>Ai5H,]8hf#7;Bdljt\B( -%>..;[!2'cYBkP^7G;^)&.^QNL%GC],8_a4.RA1c0F5[!WZ"dLM_IBKK.(gjmhiknXdnFJ;R,fVNH/-s<-)S'hD1LJNn+P"*.J38l -%kcOV[3`*Os'R0<0mDu>"0EB'!U6f,0g,0S`?E_`;%]WprLkmMH2'(C:l4M2&BOaYNXK-=Md6*e+*I[7`*b''CYC,,[\9[blEDJN6 -%RJt]/HGFa%$[0/6*k`dF%bMF5266?-2Q)Q_+#i!jl*.gcb-9K'^TuN6+tatO6F#c+qB9>([?9#)E18X!j$r&Qri,!kFAGP9PA*4S -%kRs(&6(mOKN#K!.hAB.La2+du*]>lTVhsMm"'P(HqZAHhH_\QP]Z#IU)VZCr>?op>?CaY##=uEao'r&kGOoDE&n\\A"E!D`/qSu> -%*48,T$it]H-&dH"5JLcPkU-isq04gG;UdDGb@HYY-SVhmnZ@\2O$>X:nc_4d!Y7+!)OufW[pIGeK$D`,-YZFo*,Y%(,N!me*6B^ckrd(6(j$,,+ru794R,[W5C>4g`+:%*6M'UU+@D`R)WD5cYWi&QXC< -%P=:D'EuN#67gTN*cr8XVl8oSd5dW_NY -%`![ns7dQ/?iG,M5j\SPDg32(D6[G1f@iiZ/Oo,fh=^7*.%b-%d9U6$j7_Yrl#deSd-Jli'%p,W"_cfT$hC*'Kd3_sclXp9o#$Y;G -%g)$e2.ekp@A$I6d("bY4eU90.41nW2,B@s: -%2^4TGOI+/m#rr0AfT.201I65rm1-R]c;f#<23(,qUWMj[&"<4NB0dd4\!D)6P"C!Z'ASJZ7$WFo -%L/[AlVbK1gCVP>B>?4`O1@_WKec)pu%.?a4B+l/<;SGj^@^jNnH4E4i+iblmpc30g?@:=NpC\p)V)T'=t2Z"h#1#m61(c)k?B&]&2pdSU:Kr_V$u/b?$XhZk!l[_P@FRgptfDB\/9M1\>F)O`_)!_^4"N'(Dbqr0Mj!M\fC4g3Oh]kK+&Cf)YJk!:BC8p7KL5+u$og*7j0gr+sm3GIf$DFLG[ -%WmK;hfj9'e\#nNEP^e,MrRYt:kHi2fT=t+!PLj0trO2.HmsXNn2g=`'s/d.+*a_)/o[ObMIsUjq++Nk1(O&ZY5(2tG]AGZPqHM!i -%NrT.,h`Um2YDn&0adY4B?@VrE?bC[[g#k#;n($amrq,k2?bL]t?11!1A,kJ25QCAf?TnAWeP#i;#;:Pug#m$ok79fSd?!2?IJ:u6 -%YJ9lagqA48kG+Y6qr7CC5)0h*FcroMb'j3Or-'j)c)8ae.'5 -%29,\8!N1hp#ocVaYDYE%bFs^Q"41e?Z@(hAb2[9/j-t8]IJ;"PcT_BVh)c^+nG_J.(Jiq6p#ZpuG$A_Omerb!YPpW0Nq75H -%rVl=Oi@s!RIP/AbN4^b0ci<7bgrE0"Xi8+GB*3"MFZ4,ae9fNM@I;[89M^_I;7B$?5R,l0F^%DhqsP&EoLr4t%MN4Loq)2X1W=8B[@Y -%L\20Z@$SabiQ+r5:V\$>hYgItWu[`WR]9k7N@]FE/lX6Y7\qUqV7P*f7gJ*",_>>Ne%$9Z<3lL0"`#S+'f3Hk?ns&iD2Y&im,g,o -%;4[/$%sVT2:-_*G@F@k#*'un=ei8)2d67Ffk5HWVFdpL4Z:LPpHA0q+_Au@#M-/L;&)W2K>9P7S&3;;9$3n!0/F)^uT%;AfRr)V*aWcE/MG#!a-E;)p)Rc0/>T@&ksrV`_C2)Q`$-d$G=u<^]>To#M_^ -%nOSS^OX"C;I#(f5.A]uE#h:b\F4k3W$m;s4W5dgR_22T[h)LhP*?15==$C!_K$sM4$<\o-KGppH,*L?5-cm:7?HZTgZ8)MKgh]t3 -%F((2aG9;+BmK\=TNuCb`Zl+BI5t73h(nfJN`<-aFJg -%X'jIs,mV(C.@\Ci)kib`P>k8r:8s+24,2rO$j)6=d!fe9V%VlH93q6d?JCXEpD/>_u5)>U2K1VP@&g>jICjg/fTBiP#gs0p"2N)j%('_@[R'Z=Ng"j3-Lq*ic/ERuaBOfsD*=`Y6C9.M`1ml\]%i3ms4UWT3P6KX+@D^$QfiV9bmqb*$?E%J7)*H<)UFK.^PFI?u"t0iXCdfd*ClFRs2*nHg1&EVL7S99Wc9jB=C140ptUuc,UCiAsR^c848"MB^t2q87KgNoI_+(\YbC,G)Kn<5gP;tPiQo$20*lLVUkAJ3bO:CK87,sl,?L4 -%]c^Kb:OJ"Fs1pc>1Xoh[\:_lBjGaOW,gR5b\?J/k_2]e^nj[7>jmIik3qk`;4^E@#VN8@b`6*X5ijB"C/&tq=qV/tX"N;b"Lc!`8XAJN$Y@;nUWXm9IOCW9LB8=Ga,P[cMFr&<>!X/*S1m`'_Me(F5^0P2\eC(V-%m^9]i9At'j/OKpgElQ+n_pnlkI?U\Il;-oP.PO0M-B=FCDt`JEknoJ@/m[;9f2c;$ZLFabWjB -%ZP5>[$mqhG]?@79EV%_jd,DO,"U-k\F1uXfgo4bjOumZG&,=NF^]#FE_]"3f9of&9,6L74^K\*;m.W&1u(nPOq4842LLH:nWGU5O'Io8>SS69-$WF$n.?W -%o?S@%ePteS)LKRC_&!)7@oZp!qW6NtVcnJ&,cl=I]G_3Ak+==cuD+MY`PAf+pVlOLBasW<0grQ(pA&66`>1"g9=[ -%cMW3uaA\+(iR4(?/+"Ic4el(>$S^3VI&0PYqstb.^1BtGT@jX=R$n97Zifa0LZRmJRR[u`pZE+^kE(',/c`lKTJg,2'"(Rd]_>5H -%7IM\3V`%rI=6"lAn&?p&h9i82U$cud_T'O6mLpQ,.L*ND@B?5cOB#\0L1@&p_KT1:4;_r[u+SK?s@P^mip(Jf\Bl`4[= -%@/&nWB@l')ND&k>*U\Oo28&`45h]eYR+f?_:">>cd&J1:,`CD]*\i_tGr6ise"uHVTd8J#.b`XF*/-2]YKQ.^NLg -%;ZHn[EN^2nJYW9lhY7a9fuAH$gQ3c:![V]^@Ek%ojn@gC_L45q'U%%U\HsFM2d&pTDEID]B5UrJb'dT4oIEeM*=FBo\fDnD!IJhA -%XE+,eqHTGCts_KfW=$8Ek&?E(F3IrZkmsrZcO$5ibZC`>fLCC0*K=9$PqOX -%_M;7OONhoO.$E\%/]c%f6actES,9Xe/=WEDJ1h^ViI]0f:?2K+D!pG;hcr.=$`p\FZ4#6i3P>e'FQ"DsaO''G06#>$H7p\pKqlA4 -%9:K/#&5LFK?Z;s%@)9]TXiS?\=`"1q"j+=]="F@'(>N"gY:U0gJ706[P6E2c67`L_k+S/r9tL\cCe1uLjOl5*.ibo>jNbT:%8XH" -%9cNY@"f338G7J"tLqXVjg9?&W/@H]*:ZU:MXO%&eBE[A,(SL4uk-/[$>=`;.kcir5>Ynpj:KKc.JS0qSqBkcQ/$m_E*?L0pMUIac -%LQ)1qY81ZjRK\`)+"J4kP[80UYf'?";#5LB,e,@jh7UJ&R+3#Z24a@+TDU#1j;8U -%CPi&h>=($2(O,I'pkBT#=!1"u\?TI>jiFkg#X=kJd`H)mPc*-n5j8iZQCLbJXk2a$fR/L/..u8S^2bgc]\t2h<=*.BXt'Prd*3Ng -%]m?6>::)f),V84Vcdpe/$m'CMT#`VB$ZW5?Bp<:/4.U<02^?F!Q\gHLHhr(EqHQJUCRiJ-[ -%Ib\P]cAU+%d6igDUZeoT&Pj`XF=;"?0\LWrD=V_WFr%;`7J4Z''Pb9>A'UTedG8*aaF9K/kb+'hG1ICJX1S_m9qL??[QAf3/*AQ( -%Q)eXUNm1dr+ASbQ>is!:C)eIZ^E\7b#npk_PZH*?dp>@Y=1>HlU'+g:ErX:kqrAd9Xii.1k_=Tg;*bWXkkt5IuTG")m&9IZNcc")&nkUnrS_6H3P^V=UZ;i7\D1KG<$kM>sPVZP#OTVu\HiQQuAc]WkjI'@E7J^=30'i!Pa<$]JoX0sYC6Sre@$^6g)@L-q8& -%GHp&a)?%/-K-e#r>j[&\q&lTA5o3CZ,Z)Y9M-b![!nYdR3^cOj+u_P@_b[Qr]bFd4[oeh#&G'?dBI!hN7H\O"\rHY();r6A`K#B* -%1f+:RL&Ih=O(co&H@jteX4,mp5bG]+dYM0l,cNaTrSir_(a5f4IsE"1/Y:pna!,g"NePmS,pc"@KR!CR)cfXZ]i55'0W0UVYgR^j -%!Q[al..I`N43cYF0?OS2lI5=;\rZ5*2/+lE>@0cRQM0Ru)9U)AQ&@dn=kQ:'NjGF#nlB>L]M@s2)nWltXpj#%F4aRVC%r`+SCIIa -%(],dVZ$O=EXt%1^hEe:Z*Y=4YRZj69k\,X:e/YC8?W*IYHI9p[4p6*(8XS3LVmoK]o,J%1bN,dt)mT"bD=%#\8Q).m:HlbXKCdN_ -%aOri,cG^B>L"+Pp8StZjD,mDd?Jo5SSFDBqr)B4"alHuW0\Y3)eg!khoL85NVXHqTpC`3m$'T+_'LFaSso^_i.t_o6g7@o1J%h:6B/[s5ngDN"07g/p7/+n9V>B*knma+JT -%6!%QGj57mK)ng6AMn:t+iW,DX:n3kNd6Co?cc8'IFL,&h-P_ec9[JqN5)EN9$L3)q7];Fo1g[kQ3&AAP+uI]h]t6X/#'6*q%m,ZVe_W<>$T_YMa*s4b@-8kM -%/PrY[f:&k@@_jOpm^(dsoR1;.2=,k%i8-Jh)nJlo`%1aO9db[TQeI;W4c9]S,Pu;\=$p6JaS@GAYbUM:Q*jkP$=RtROu^6Li!JO` -%Ks8];[Pn2'e_G[4[R;!87)n;t9Z$s/Bh-u:bB=32)L(sJ?"Y0$h;,`'o0$![#Z8B[O-Hl:cEF"q`f-9n?dRW#Zg3]h@--Xan#%=@ -%(b?o8$f+u8%d&>\RiN$?_r*Hi+P@=BAA5lo0CEf851$,3?Z-Nk^e4^0A[lqF%H\EC^6i@k@rj`=9,Md%`W6f)Mb`#FGp0qUZCc'A -%3rs6&iNj?i>fZ4!5i0s!hS+?[$Tq](s#)"f/]d@G(U/7\*iRX_CbKZ7aM/?FYs#*U=FA!QSq,RC$.WkXoBWEB!4d6!kB5+[<_\0_ -%Xa@&tPZ><"B&r&,MM6]j\+O!eFp -%P(]>%i^RHa]L>?5Dbsu,)a3RPf>(tYg3"%BIJ!U][Vb'=\;g)CjuSV5<7^P]O!tjg4:L(U-j.oJfLT&2nJ<`Fin$aUcq\tni%gNLUE!V!YeKpQ80(-o)oNmWW7n'JnZc^PD-=C'duE]+Bi7?(hPFZ93eqa7gC6!pgS&\gKSfS?jJb\i_le2i8Kp)#Vqk,g'*3tunk_]g -%*he>uI.t'roQW7FaU5XI!F44jKA.uTHsV1U5n!_Y;I(ZGNmKNtG%&`[G[p#04Z09)[?\0Jo,AQqAR1%9@gK0olhe1e;gX[^=L",Z -%$*?1m%-[o2TJ_8K.e=.8o&'CtQ)@f'gkNTsUQE0HXXB4(;rM?cf(7[pGL>s=*U8)[U=OXLP@H\gmG\VZo@KRn]@_T06MPH6[^SN[ -%h?oVX7KU8?[@65n^9)%T'm!;+2K2g,Q"W*opH$1(3#Jgej.+po?BnX&Q1tKrA?3G,cS\KT[Mfo&cd.u\W^hd\e$4+ZM;2Mj^P]9` -%'2nl/**)?udPL)-Ca'm-q>cqoh2C#Ih]jo;(Y43#e(9`;R$$Q<5!2rDBmQC\hEYt8<7?9`8c92&XUmmV29DG(E0O?eV:`KdgOd'N -%L>&L>OrT@(E?f*M!l,;Q\JEtp(8CNN,joU(@:W>64CQ/rPaV>e)hC=gKR#-``u-&1PdOuTmkItt:6C0s$tQo%Ho8d[D;53?!5:c5 -%H@]aQE$<8+G.cr[3)(#OC-g#&2FeTUcA*Xk+4&'S[KHZN8J#bm7Sf[oN-QGKn52];.tjYRi_eqtTBfk.NBi`q8f]-&*]1d[Q^A3J@m -%9iA1KI:IB+jrhj$]S)O,o!tsmA%Thlr3o0lG,1eO,'HYR7kN$%c4`/h`!dPc7RMK@Nm\Y$d@XV8eOu=k)R$^#90*dZK^Rollop'AlJ=#n`s7P0AcX%`>:a#;=fs@2u\tn]HU:31>I8i*clD\ -%bG.V]n?>^n)_G3Kr-UUa,JR(je7#Tl;(r3r[/b'@Z;NI -%Rbc#lc%:I)#LMW[a`jl"Ca'f__Sg8-@r=#?Dpj>="+YD][;Jo..@n-,3Z0aT5"h]>:oYq[R*M]@I0lG15ZIklK8g69R)f?'"Nnkg -%p!!c_=LZ$e0IBf*8**LInM!EN)Q-60,98G60#EWfITgb!Tn60/"Wi[t?DATT-%b"Ec;%GrQZ+[P%9b?*pT)^/EW%"#Z7n-7DUH.>@dIL -%A7A/f(R#(>6pWj@CNrClnH*L\KXg5RadmPKc -%X]/$eBItEI)PBP!0u&?ERtkfk4d_[81WCI4qdql@-AMiX6?U-(q(P[ZAsD%Y<]34PG_p<+fH%F-L_Nege[Q-omn`8tFma(4WdrUh -%gqUeMkVLQ67T_#QQ?59aQ6dC:TWW,8J(\as%%iB6YOYm0p+n#P3g[j+,k4c,^`M46cuCSdj,6p%g[pCSh6R(jg.OqG0ZVbqbJ^Nh1o+$6fB0HQ9R`GgjpPf#:U(I/I+=Z+7>IAbV'+8k?U^$*(4Hf',=aieUPo&fUXInpO'kO3odpMk9Soq/mCrFB1f9b7-odoSb]nUpSN21KR= -%i4EpAHMQP*lXr-YXJCf[W4c=8PY(:]**MGAR"\NrKJBdr4G,J*3"STD\Cg -%4I0`3p,R+f>#%bqs2#efD`IelaQkgGJCZMh?dDOH -%NV>[8hB.gYnE]kK^\2#^r7OkpnGE7-fC<)6IJE*rJ+`Anht\1>l>QU:bCB:OrXWrHS)=&\I]NJ(J+-86r."Nh++4U5ocO4mRt(!q -%J,)lirce@J?i=o.a+*^ts5K[LPLk^]+iEia;[LJ,]2WNhnK1oRH^Ms6p!\O8nkJYPo.5 -%`j`_XZ[_u#s6Ronr(hh(5P8g\I.Z=pq>^C0s60?pq5aOpj)t=ps82ilB4(Z+fC2_Rp>1;r&,s'MB!Ad3M;'kP;>Fr,mPAAZ,th;-0Isa,_J?R&1"8X+AjCf8T_DVR?.7)B."EkMA8s -%%rKn,pY'Ddpoa9Rn+6/g2/Z76?amrQju<(Mf4nk+);23morGgmTDf/spMAO6I0TF^@fECrqAn3df3)VVsg]Dgoqci$Z;j"J@jA@?>SigDptr65nE`6Z*m$6*]5.Pu%j\D58QhYH'$e0=ma"nahM;kE\t1hp.'E1XQ>ubbh]WJp6&IEW*h7jHWZe)"QXuR3OI[k3$$rQ#"bnX,32+ -%n!1q3]o[m8=uWlrJY\q:[U\JQS3<&l\V%c'Ll*=NS?*J_5O=GPS??5Ph -%PP:^W^L,AQH%T(p_4]ISQd$Dq,0r0'>-(.S:]FnAaq*5EH/)V>au:,hY&XL>NgVJ_`^PHYh'OfOFRdje2%&F7pj`08j<*i6T=8h' -%2_2m+:48!s\C9G)2hKAeH#2#mnk$U1SN2#qVk;6ReLJmOa?(!F9(ZH&j2d?'9*Q[)"BVF^?U5Fh>hV'5:!u0(7cV<,/RPb.poHT= -%a*nu8ZqC%!^@1^ij4i^>9%@_7CccS(Q/K":Sldp&WA'$@p\f(,WmBikA8qLr;c,n4D8>=i0&=0dm-?+&;S9+/n22S2#Of7th1E(l -%F%4"?HHfR+B(`GY?*!%#ec!Z5UNT\[rgt:Hp>Gr#,ASVOcTlDZcJ/RGG"TnL5i7s%t2N%_,J\XHfSPQH7_2q -%N7Ifl%t$++6/oaX@G%%/n6,K]YNqr2r:Y$Kae*GLB(LnZ*T%/:'DH%PJ,ZX68p!,?hfB[TlM3S9qNjqSX?!mF_Rt6aVp@.45<35t -%nu[95Cg&rsDKm<%h\*D/IsgLWaG7IaABL4EY\)ZS]mXdRpa.LUD"Ve81NMrT>1G_6]3_R!@,[E(8+pkgebS#T2/2s^oW&.j#$mY5 -%X+%hmD]\pn@[$"(HbIZo4"nB^jZYZ5Gte.Kla3.qiS_fkqcAc8%*[TSm?.BQkfr<0*-CL0d/LR9'`)qpec>C?4jq>9fegHVk/)`9N[IXfecj&^/h%7YSQK)b#0/^i*d\jgd, -%]\R)^!F.L&D]N%DWh,[&MtR)An9'%W0Q6e#!H_qq)`fHn!I-'P1./km?!ocj.51A`5HtufsE?/mp`V.gp#*A^*E-]B53ia,lJ`.q[mF4Z@UGAf]DTGZqQM'nNN'psYI0sSj-[$>a#6\,X6--SK2s!##2YX$e'l3^ -%rl8CGp/L%`ra)l.siXR$;Ll,jE=qc!"/f+6)@*9R.1k6q8P3_dE_6AbH*1oftt -%*T-)QnX`AaW5Veq;,MW"q@e(jGND#uIXKnj!uk.q.6D"VWI*!'^5-s#k;<'qK`0O?gJLUi3/b\T;kBD=+!mUGR^X$CP -%r3DfiFtO`!JM/N4nuL6U],k500roRZ)a<_fPqWi0m34DlGOF+Z>e&u3DY)89F0O*U?9c*82bjKFgK?V`5KJhrDP,Uk@U)ikhZX1o -%ou!5,Q,7'%LcrraR8K__hTO9`Y9-l:%>4AnqIA+u^QnSsgcK.m0'l^ffI3jbEJK=k=-Hk2]_kfVgTK5SbJu3*YLi&%FR5s?/P:_>>B.SBI/;EVc[-I` -%KT\J7mCelhM8AZ$2braBXiUj:.W]!_D9=ZhCXq/4manj?srL^!U9)ri=EFa&WYbl*Oj<`:_/g,eY^q>F#\3 -%<3=d3n#g]Jjb#'R2(ZiE[dH4n:f\iGBT;jOa%W'Y\4ueGa]`u6f?fNGr4%%afpp$ncN!&!mA-(Ss8IpbMhs+!I:DU5ZEZ@B"Qk9ZQ8al-)-%b1J`j%DO.JCPE:^S6`XA%n%A,ao<*&+b&k`bm&<+r. -%]`se^PTiiBY<$VWU#Y#jZ"@[;=KK[/FYnjXfDQ)h(Nd\-'e@jYjL"/]ZDti'^s0lI5F=LG:]7L1$[5`nr(c[^UFZ2,Otr^!MkkR4,-Z5q".Y,4(.5"GRa`^6MtDC^c6F]4*8D_nF_30gH7S0uTk3&s1p-S,eV>ct9oHK@IbHTVU;&XWYj&NZ -%ir6K,5&,it\k&TI;eJlHoR=G!A7tQ7@+(uKn$,a)*")NnO>_eVC=r?ZtJf_G%JUb$&gV%>cV4(Ni)$nV%lE-dJ/= -%Ufk>rp0uS=;3T&pBrELYn+Gd#*djlt6$qbMQ'p`arA&;EjlqiD4f!.i3%aEpBHO)%#'.Qg,$Mrm=-AHe#Hh*khYX9hqqJNA_kr3tp3)V&^4o -%'A@j0O*B,u/aGtdWRlIK`:86pC%6Je.eK4DGi!Bo:23S]"uF)\SPp/F$#[ce#HgS3Mf38H^?b(`KiqA@DTflV7s0;7ET^G4cmNVC -%SC[kte>tH@%5,n,G>G92E*qu!&XtGP(;%.jH7_fJqlW*,T*m.]/a"jljhT82gK-oKR+*%`lJ(-a4s&.RDOi,&Vm!!>E+Aq7pCc?u -%CV/l=Rdk;9?I4WPTDIqd:4$qtbCgdUCU#c"8+^_kGW>5*qmkIBSN=JtrSfgZ/R6!\`-!X-mA#RqP2Gro)>1.ZV`"r6%NjGDjY<0k -%n"*cCS7^[AX)o78]Q]RXPHaVq^-$H3f$2C9NugE&jQ'mDE:0@tC/D0g44D2fQS6.'n6,5.Yg;0U=Xs-r&"iTj:FT2Va7/%Nl6g\5 -%?uraI4:M/b[r:-9*R7%(%P5b_mXO+FdpUh.A!+1\rhT]I-hR>po6hG)6e;jmDaWZOhdXCbiEanGG+'/#Y!//a`l"Zla1Ntg^TSG( -%>GY*GnCbWcNo"dUlLE\7Fre17QLDu!Bf*PrYEh=lr:!IHik#DBlh2_=Qkps0:N.u!5>fBr/72Ct:[IJW;!?``.rkK'VQG>d<7?5L)#5i]IEa"]BI%W,W%Ib(Y0.6e3?n_34PqtKI1GPKgi -%o2fiV)/dPtn6J#f?`?8/qV2s@S&@Au.L\o)>(#/@FoCUUlSn:fbK9XQa;)&u:-U&1-8/UdZ[_fZd9"$cInP7DALTWj&Mu6q+ -%c[7g`hk\SArp\C!c*KLMFi-hH2OmGrr1<,`F7.sF]8iJtG4jq)&"?(OIBU#FqK`iTnlQUM.^4o4]@ -%F6-['G&!$#]8H@[r9,fd$feCj]4]WN^8obV097K!$@\E/`clLi8)Iuq1h$ar5)rH>re8GIbZj04"?:pJ)])F*4`P.>W]<%AFAiioYB!a -%lbacKgblQ.\Gn%G0kJhU?gYaK*a:e)IV@*+oj4rmi\.fl`Ei5`IP\H;7pD8=iEH_*1W<8WU:?YTR81a"O[="mO?g^!ur>5::#C!>B5.G2"Zp*rF9H>9b2'9MBlhBR[4R(U@ -%mbPBtik*I-:@6NC<1Y/M[i4o;E93*%0&1i;\(qQQ_FJcd=>H^kdkVHO3PSap`PC0-^--N1lKt58\t&YAD?N&hh&ASN1TGdkg7o50 -%L!$e@3r=hP#C\dZou?C2p[18eh_<,sE;0'cWu'*RpjVt7cf^>Sf=FSZ]T?gSl](J;qG1>$B'\ISG*\:3!!3KqGk)pk^0HDOMXkGRU.hrg7Q]dhH5mZCDAR:5,S5O2Gi21+Q33=[j;j#s*%CHNH"2K)ChC7t/5R8!NHPOJ43LtCaK;34:qTpKE@%>)ZFb/iD"?KJ-%r.$RlZa?](TU7D?ti)F!4B&Af7Ep-[+Ei)K1SM:+9)tsC3LZZ:+-N8B(:k"#Af3VY/;^DZ+5,sH2.2X$]H*\Q -%#d\ZAEB[P+AD6[DJ\s"43S63b#p]VM#*DBJmii2ek_IqPJO%L+)B>=?=Ga9#!F]Dp>"_t"JUr?-*eHd-e4F:Im%?StUt-So=AUpI -%6scC:IXoS]1RTpc(R?Bj;UZ*6QO1CRZe\/&'"s3?)GGp^H(jXd&NBjDNMB&L\fr]QM49T?:e]He16p:j.TZ$i.JF*^MaK$e\fJF7 -%T`gDD&m$M"bGU&&-a&*%LE]?DdH';![=t$]i9H2WA5kF'Zj0nHd -%"+:SSC_H?$Ja>r^%TqoD#7<9)M+hLQ4S3?]UI5%!_T8[og?6jOQg'IY5Sc[7?*b1k(f2#X771Dg7]Sr9.Z$hp$Z&-jI33c.T-P)YJf4?uF,'W#[M(B@VC<]\T(@l=C&k)$neHKXK&pd1t4\OK([f&*FRmJJ,K534 -%W%f0U@p$Ziet@Pq(%CmX4m*E$_iOEmrV)G%3E@i[qub=-r9J8CpPEEOl_CW'%]+OOYt6Cg[)^u`Q`+-N0qYDsZ1VT2Lt/`!6^HJdUpgobXgO_$sRLX;u?rMBuH$sEB9SLWgmJ6f4eqT.+&Q7a+KYTgc#f2ek\de(Or_k=/-/,-.6 -%_1*8D-dXsP6c"kXT[b>sf2tokXn@+kBg8,XGc0'L5MLhgnQX%\X4k`-uXnIhW.>$S8k,k'-M#SNB1cP1(i:+3& -%+,iiI&_3MeDJ:Kt]CX>F\S&p;^NH&*$c.#V,Ik\5eZ1'!TYIN[^RBN@F+nA10Q$d:2Xnaoj'r?u0AcV@48sTfM;4V>3m'*YlOU/9 -%J,HuFg_8eII(ae\,Gr*>$`\CRs%mjcnVc:HJ\PM#r@KuPFBu6=1O_pl\i[H(53;Y*\a/t&4l,&"f>?S65=%8Ve"tr=T>k;$o<.95 -%gX-'%XL@b1DXJQn8"jn?r;l&BZ6()H\uI(U]Cs6k6*^:5/+u0J]se_dV;@1+0lSQ_]_;j/fHK/8k2r6R"+O?XH6G6AaqAgIRir4, -%00!56m^mXa,lH'Z9CU86?OiX>droul&4h8`I+VNaFo;e5\Ft3UTQ91d6jM#g[R&oW+*)GkCrXUL;m3\n:oG(gn3P*8F*;.#n(L.= -%[Cn_r0nZ'IDBZBae[1<&EL!Vb+NOkeF)t,NMm_?]&F%)"A$Pa^n)rj"_QU#sXb4i'`qq@HiUec(<:T"H]*2,]Eb;RYmt80](RG2. -%`m5Qj.8s=@/fas$hZ"/D(IF[AReBKmb_b8iLV[9hLQ.D0m<0HPJEco;-9ABGlPHV7luMO-mEhcgmPTDd4as-Fi"8\8HCoO.iIT`j -%[u7ZjqKD;gAMD`d*^\@3^HIEgAM]tLU^E*';1$YHg/ -%=4A-IIseA#k,(3HhgOeM?ihdln>Gkb6UR_Hpgg[X7fA0bqS+':\ef;^@DuRPr``U3&VfZKrY+Ko%4BID-o#f9a%m%'Cp*q[gURi) -%R=".S+(sW4mJcdf38b`ORbU4J]^D^Q5s=tY`],#u];=`J^:ocIfXcIDD],3\RSFc">FnA-3kV%Hn\^GjqH)=K%M#.=HYbp[#A1-! -%1P[FsI\hK\lGg%e"MJP=N0TpAlc@Xg5,alE?p$0 -%m-cB!$pL8t-P#d7-RL*=C`ZCEi4YA`O"0]l7qi"jqH2%:?#7f1)i5#?JS!K*$g&,9J]ZQXJHhHeO=7;_d -%1D;!:r\L_WEaHdHYA5Ek^8,jfo+A`OZQohs"D>#u5keO7MY(0D-Kr1`g5:nM6pQ?'B1Wf%:_OXtKd%=Pm-_-b%>7SMceAIt@9[j@ -%g"GO:PqMU@pu5Xmmjs9"kTl(`(X\V?*ul(j/[(A5.ZH5l7:,I\Y\XDtI+$3nLd8$nK_LKKqA:?C`TP%KaZ_t/1Qn%*d-QZQ0aM)& -%lu>Hsp,'mA`CCnGF<^aGk+`-?A!+Nf:=st6CYJki-I#S/.9jJZH'JdM8;Mr^_&j"_%=k;8!T_>1dL]PUE0Pi?R2!AOt*+7 -%Q,_.>#0Maq\uXWO=bn#Ig1:^Tc^$9c%B7>I."7;?'\9i?>!82?Z"mB.3`+?s]\"Xo+;q\l_qI_aZ&8bsT:X,!JBXEu0mj2q!VAL% -%NAsQOmJm7+0t79Jp?[A4L8T^h`AJ^4Z:b]h\4-8*SjBrL<%0^aJ0@O35'XO&0E[mP_9:*WGk`nU)Y@/EJq*tTY6EY(\k"oV$6p$t -%cuTie(<\QIc_?,F/2!\X!$?dWOD-9&iYj-o:5Nm2SYh]I)(8?R:F8c*kRCV,T*=;(ODcunG$tr*#:+#Z!Am]M_[Xd2Tr(!0kV9omaKQL8o$f!#m406&M%V5id2bjOC#8WOIGS%!<_\jBRbR -%a;CHJ3l6O__@A'%37P!%P)gf"6XjC^ebVmCemTSB!!P?@.r^b9)^&$P6\0eZ7Mc8aXpH/m,*+^^Ee0$d)J?k716g6$/R0%tL"Sb6 -%#_O'JdD,7:^'\Q+=KJggnq)cLaYYI"8k:!K:K9su^`^uWd?jSokZ1M\JoLof@dtZ-U9(^SmHcq4!MJ.]EV%;0NRFI<2kLS#1kf'J -%e7Do@a0qcH+?S\+X&pS(Uate40Pj2K3U!o_Jl%!E]sN?h#C4IAmV-FH5hE(oN8ZdupoFQ/7kub-PfJGqe9pKaP,k]a]O7#O/7&F2 -%cfQ_(A\eSgc1e'J%,I3AL0#^a0LhNZnc^]Pi",ql-WIbh=paXTe]\5,_))IN@#lYs+S6M>Y8iOJ-US/Q`IUG)YR8+[Tj/2T(j9DR -%S-,h6Z?/`^H(V>fW#\Es3eV\[+XMhd"9bELd"]?#'(?\_R\Bms0np;:$hXRO/O=GN*K#^9dJ?Il]'aUA4LIJ!E=%(!;Y+W=#2N>V -%/h;VJ"j4C4)2p@6:h/aB1>s%M0a1C^P_U -%.S2)kAk*N=,9(+#'sT$9.UlPX+PCmB6B$4GD:u(*8jW`\i/6_>PkJ'1;Gn0M5jOKL;B;Ad^Tgs]dGkkd4oqJ&'J'e'VK6lA\q5kr -%PR.,oc>m"#!2n37(?IY,/HKZqYJRsYAA$"%"nX7)/c_e1#4GMXTGdABlGkS[n6?#eB!0,8Ub%7VW3f[g)i'q_,0Gbk>[ilgDU;0] -%1+Y*[1ha)0.#l28.]a8oan'dS+XRX$cm.,P'u5d)/V0h\,@OQX^p?aXON*Gf2O?[Z7mUHjd".2DdNf829#tSJns)?Q,g50JK#.XD -%Kg]Z0=M9rX(Y0pIaXZ[H4#GD+AU;uUM2C7B-/_T2$Ia)T*RRR"&$Tp(l?M7t%!o9.$Hb,ng.F:6n6E^(!YAb;-7%B4#D-6Q&iO=k -%6lR7RW8$LF&SS02W_K%\@"jWD3Yno)gk'(56N)Lq+e!$P-O[6.GSgPc`RZodaiU-id9)D>7N=&[P(?%J#\jVS:$NOLK0&-QCmSig -%K1$*4HS+*Y$i$6CG*YY6@ER+C'ibWpn]7GUnOjOc(#@@ChrEp6("aYr9:aF1;J^O/MkOY-Xscj5FP.D]N`]KS$#ICDL%D[F`3+`Q -%iG0jV*Mg6=Q'oWdkib"?D+uV>[NgF]%[AAL#,M4/`C!r=^nQc'bd!IU=<$./"i!+0oE#Q"/lA=f#g:PPY@T3\,H(T+aKQ(a-U?=7 -%js#%G-hBd\OO#I/9t"V!-fXsT$tToWYooOa$js#(&P5Kup.UekVD.$0[1Le73f@C*iR/_l7KNiX7T2[[jXZm6RMnjiD6$p%00h6T -%!u)Va0d24XD-Ab@Ymnf^!*_.cWZ?p&O@7b?55_Vd9UbMZdm9.Vo0mUG)TDjS"iWAl -%Fp5%K#nYdsE!O3]^VKk*XX6R!H[VOU9ZI$C`le"N4&!/6l%LtG$GT0.;1h@#,(SQ.>pYOpg0Gf&R/!O;5]j=nAn4p$nRh=@%Pqq/3jgnS=)+B^'TH^Hr5#OSM-\t\X$ -%%3sM3O5S\j!0+r"_,TFM3FI2V$b&77]kh81au,fD_.j%ZXm2!S#-3I?HMk1%[EaPlJlpT4DkZ[mO[_2'<`_T'+m+=ogeeEK:]M(s -%%2r(WF>?B[P6D5Lo;#->M67iTZDe)$AWs(+CX@WK)J?kK4t-DFgBFm.:'cOrbh<^p;JN)'I\+SY6li8er@^qs^uu#QRIM@9D/6U]E$)Cc=T2el-dHf=SD*2@90)?&/u>4dV8s -%BekVRp$F2N?CW!Kb6`r4ZouAlba\F$,((/GKm`!<5a1T7O"0($3kumbSXuTQ3mF)?,?dY#i1sb`k>P-#R97$M,QoJX=,\f?)C!%) -%[lEA<>$H'5"F]bpMea*?/llF8aun-MPGtCBoWf9&:Y;uFK2jH[CQ&-"a%^"U5qBNo!:Qt.CeFa8KEtC!6CJP27<)T.!,c!H[NW&) -%Hp+$J=u9RHH*i@fkZ5BgNo%Q"f(iMn$;0=l*LRl)]M=Y%+AL-@+@(XH#WONhfIHuo)3^,,H#JJp,&A"`/V'Ocp/HE[0H)r`%"_OD -%6mm4ce!/.i9/@o.E6E!NDBt[-iJ^H2ZX>oE"s4Q":#G)$3W0<=P!:$L3Q8NoP_k4J4/Q\uo8s.:B_)O)V"o.992R4oianTlAf+T[ -%$U>o>mh-cmi@(G?m=f>d&_T=gnnQP#dZPT]4q]lbZK6fkW@c,KJ5LEWB_Y%+qS8ela-B`Ggus^%kYbf.ijVRN4"UPD*iTL0*=]n0GN -%brdt+9S3di%AF9';!e!T`VMe>XHJX5rPsgsnKe):@]h-Y,Zp-OhBl708rC7>7s]ddqoEFc44l4c"%93fS1BH9ro[NN:Zs;-qY+>` -%6MB+1CE2G]4^I!f'nQDYg63?6,q#OVe)TOeZLj>RL[(/I4Ln:d;rsRjmq[ajpsn8Yr=6[2NtI]n%6jSnOCPQL-)el`qd\iI7=.!" -%$'`T2(5i2=rOG%58Wp5@6tMFN$T_GPY.Ya$P?OO^V(Ap4FP`';(*ga=!Lkb-e7nFX04uW]EfpW2>V:2r%:#5 -%%_VUn3#emB=,S!E'#.T_JDi'qD-kp[(452?R%6q1o_YRLh:!L-:o$_Z\,sF7%^>:pCVF#B'oTb+Z.aP]nL2_u*#0p=Ln?Wl[]C7X -%jfKkH!DP[epY"@i@^/6oZ9'=F%DCiWEBLb7]G._ap40(o7]^FPTp`/fo@4X!S6sl1(2G_+GK'>NSFTGIT78X(`a[JQ9H>0#Q)luh -%g#B7M2ZT<;i`G/qc(-Z#6(8Zj/7^unG84C[k6tbpYo<&L@sRPGi#fZO/k3Rna*Et@Xfst -%1'n+6:YZ\9.::pn]:lh9:S8M-Wd2;A7.W>>H9fBi$R[d_@YK3r%^-_S%Vm7bd^*`c(?aFZ0(KoSQaJlm0l"G(6S6&;H$[eEXD&uR -%Nu+s%^J'8_7hlU0qR4cQn$Hkp!Ih:_h1mkEB(@GD,,aVRd=Ad79#ID%ca$3eRra]u4I^nn%_&0.4 -%Hq(lDEtp6+X?_kWf!o/QYuiXhUrY^qTl%D%62>V"(1'"eE4\<%B3U!(pS^^kgoZ!^jo2kCqR$2lD>B[AKWi!NO)t_D&9p93bm"Ebf -%/O&""*J0#8&:",ioN9>U3PXh$$bcd#%%2UbtVt%Uo*K)dZG9)eXD\)YEgUTZsNE:r9jH[ -%^2+I`RK*`1\ZnNg:Vg\0S8^H@UgO.FPS-Y>RZ>6:,6`RGB2?iUVf1UX_EZ>K*.-Lg1%tV0(W23HS#0f7Ji2hY!KGn6$L`Ib@Vg(4 -%+O-JE?%XT8WYK!/+Y6V;Uhi62I,C[jk.gbIrhaID4*2>>T*5nE4M>p7cf -%;#5AHc]69tjk:i3qYg*/.O"(<2^oTX6O2-I1H@0C$3lRA(c\[Ff3T]:3hLU;\[OK(MKS`.@_Gn;:?o^J=2c[U241ZFX"A[Y5Ar('5'E1L@`3*'H2IJ(;qEHtNT[-lDjj47Oa6k7%U -%G&E^MD"oa_HZ/Xl*q/b$@fj+Z,P0!iI;o%]&,4Ot3&it1/iQo>7C\sCL>r*n:S+CFDK"eOrL>WacK+0aK^7W,=AqQsK#.8ApkcUXN"2G, -%eU$5=>urrXMaW5BhO'pl+Rsbs@WA_FIk*Htn'>[?F'fH=B]92Rhi.J$p;C=9erH^DMn@DM++?m5nP^sL--9,`cT^o%oX#Fc -%F\Bq&\E\N`4TA+S&'f#4QVtH%c&s1>q*fK[+'LZc[>M!Ap>c+<*`\R42pNH"\,D6,WFFfMWqjIIhk%K,-Z:l!];PCP[:![/Nf>,M -%!E-4;hmmO3n(PBlhnK&:I7(5Bq/IcF#I?((SEeoT87t.bhU'G1UVPFmn1^c`iI3DuO@h\)2"-[q'_)Yu(8<[qY`bg"BLK -%1E/N:U#@*RqQKCeK^bq)T3A2CIh[..7d#dt=UGkCd@s50AgQ1gCYQ4"PKkc&Q_Lr)WgMs$27p87Q;k4]"^lnRLSI./X,(\_%RsiW -%s3kE3MFW[^ET3bjdPAoDPKcjMQY6p^8)UYdmL!h70Lu>K6ru8)Q>E09YMt4JG"+t*7">B)*DcaAKS+OC!BWXHAf-OAqTq6Oa:o=7 -%]So!MSu,b+_5g7ji-.)uj%'J%=^r6hABO[)QOt_#b\-'A]"ssZEJupkjT$ninj%f9<+d&!6%DaN\%.sH!FLjsak'-qQW_6L3&BW1 -%\-CtT&=9;Bp&k[gj>$c"_-KN1$^"_R-M@J-U,0C1o-3gJ*1Z/9MWtZO+M,q?9.V/R]7=\B2oRpp\\=W]#eH[+3,29;].Up;!H$%8#S>-K_&a.T71=X-0*#f;["3HL`F\6;h2L?i -%_@H`f-3M?+2NXY*#*Ks_g'`a<*Q2,mF3ksQ-dZXD9$eW3N5<7YN_E[8kOMbRZ]ZmNOLT0./A@'MLDW[Yo)oabE'>Ur/R\(E)-(fJ -%6NMfP1'autHD;Y:+N,;98dUL#4jKci*J,6o>FIN,=[Lm!/%#La`+V7C8#oO*ZJ4rK/EpX-]gQfQE>;0<4He"MB;DAYB -%J?'6?0*FHoFOj;_X5LAG!(!.Udr_M*_4TL<'"=eQiNE[f\3u+)$FAd]NM?aL>j5.QFM>KTUVQ5QR]j -%#g+!+HQ+]2!"NV6"NE%)>i.%#d8b.65SlKp,%XF.PdEedMB-diD?U(%H3un^I7&T3RBed*3+9dZI4kF#=VOi"SOR%VRc5t(-iadI -%0_WhEfL,AR]?r#iNOl$c/+.1E=7 -%Fgl":#TTd[P9:i[rPF(Im[T;pq#JuW-M4_PX$P(t$HQ6.3IaRD;BN(Lt,(r+Y-'W_C5?I[j5(%.M'+p0[8LnT_"GYJO'+F(lZbU>(LO\q70L`Z'G-VhV5&<>(8_%dO08)["A -%6'9h5W977a_]dAJ`9B"W4.u!e_T!DYY00,1M9d\?/JN`1&6t5JcVD"%Ko(q1%B>s24,>^/7WF1c[OjoZ%6ukmjd7Y,S:P?8l5HtP -%#hI`#I#a;T_1B-84HLkP,V1JH2cUDA/>eB*%<4A1$3UBc,L]CX_OT89P3=8?mfngJ0`Hu5Qc1j4N)<1Oc!&P%PQ@F*Khjtr(Pq5t -%e/OX+:jY_6:Y8U>!t`,V)htupp^6JL>7lJB*/[^I0HOFb[5_V8!luWn:Eu'\fW5f.[c7[1$"@Qba<*P,5u7X1Wj<-8e-$[e*da"T -%'A&CT1YW[[qljdbn<`s=!?&m#=hIX*F`VMq$o%N[%OAKaBV6$ZLB=bbd5M%h8G;nZ!E`e^Eqk5nbm*'5]AIsenf@T&sQG,8Au!TS]D7(T;6(@3?nSTX$=q;?=Xra"ZE^*XcI43Q0Xf\.B^S.eq-D!9\S7)$4e;mb:a+rIF@5qM$+oWC,TPE&j.!_35L@ -%_*Qq.ab4&1.Y1B;#!aXJL'^F&kUIc@=@WY+&"t't#F'"UV+6dW?g`U38-3Ng9f?"q]o=a41_q7/+5!CR:*QCP0RL5,g0dW"N#SL@ -%R8F!YmQSYtgR@I6_?_Jj$+MA"R_aiCLn$.$rW3C4d4%lrAlesV(WI:KhGXGP5L0O/aF=cW&3snW73/rD!P,0>3DLhT)q`^-AU^>ZA*du3V -%Y!5(5cPuHW(B4;oYN6G.pq&X\qj6JUYJhY5o>WKH6(@h3rd)d>&_0\$)_IOLX8hi5034r>8G!o!pUi$=hss;k?GB8$V@d4cF)_rd -%mnmKKds9kYbI$`kX$m/up9OLAjOXH1_=Bf*N)uL8X'DR:g$_AVB$^9V,X45JIf"7PV*8D"eno0Bd:'XuV1B!LA^^uVIk"?i']nWP>]Cms'9ZW1k#+eQUDHEB5YQ)N30&\#F-IJ2HF.B(;E -%*P1@fm2J8134*J_Uoo]7#6X0ML7B$[>889*'g&k-`l"h%\<"Zh9[4h_j5]S]rig"SBBqc$G\FHl-M_F)q7O\ -%q=FJ"99Da%YP50c*c!KM3`BE&-ib-LD:GKsG(CQ7D#n,BB>AjQS$?N#q^Ji7qY?Qd'k9Zo%e!$Iq=gQ7:.A:]pTP!`k1NI\5@/RB -%19NWTfofd?PB&'3lEc2[7K.1[*_ip2(OS6?[2:Zn!tE;n=WPWg3>D.ZLAWYGXdIl/h8Ck5cM:orU7&$(mgad7"oHhPq0k,e7JQ81 -%I9Qk4<&fjSSkBN"^2diFVj&7;HHk[5n<]=r]TX.ifl'(sX#BO4q,fFrLG:$H%18H\=XIY0l4kNW]]&6Bhn=cXm-U[/DA;\W"Sl%9 -%Z0[ATi%(rjB#3QJ_>dlB=H/&WnKFO,?ed"9kDZ7`5BLoZ0rS+i[q+G&=hVBM?fPbE>Q=MdlEOI7"mZu_(R8`3Kr0oce(:aj(&aA; -%PP/@u[2Xs//!!fHk-MV)k"Gn'7-QFAG&3QSQ^"(1%(Q#>0'?p-r*0A>pkO@\QUhK1>.pXnP/XD6pZeneYVU!KNG9?0Dr[TL': -%kfspL[[k%9B/mVu'_?FY7VjR(aXF'nQXhl1,AE0fnkeQ.70VN'CH"`+$l7-@_=NZJ.G=O8N\efWPNihLq< -%*G7:T);6Vc=tj^c_9\Nr]%Il9U<%ma859'^B;][<>TT+mF2?"5oj`XKhp&i[?r:!C`pt^eqMa0SiTrT0e+DE9LFKn0.F_klq587O -%D\&;Ip%1gAgXK>Qo$4*!UO_R8B`7Z'kHEW[i2>>?=#L\fi\[u9u>S[ab"A:,&j[@h!_BWIcA1tDs('^C9oW,n9+G_Idb6>";'h21P[mt_\)_4i$IuVc*t+=WNREB -%Ce3I;(bUu^0aWGQjl#u2NmOgZI*%c-7MD]Y?_+VK^*Vt7Q>(JO'kkBA=a;kZMqhQkVEMDMOmL'`:E'L*ZcauBqn\E6h9*cE@@$c< -%+.l9Q6(b51rhMt[F:1$4"$@$"J -%ZI&aZ:#,o2RDUGHZQ$pq(d)[7Up`C)bKi9GYUjh`>s<8hLXYd4VjfmkhQp_B"GMHPqDg77S?%E/l_SF3T*H"@]PVb$)5oat]6kbH -%UXu%=e)JTJoN?qj'5$srVhK,0i4r6ZH18*0G]78;LKMFdhX&93a6aP@LEo6eC<\l&chb_nI=C(om8JSAhOAX1+74+7gl["h=,]d\ -%28W@7gg%oD?:+34)22pIh=-+_]VMX7i*uG3AjWS5cfKpTFM*rR%RJZke)PI(AL2Dg1WdCNjabh1,4T[6&SN?i+ipR[IIP -%;RVFob%.mJSDC"l?er;9mkoLO\uj_rXIRtA4&rj/g.6Bh@!Z>Dj&0i+4Z";mQNiPD>:Q=>`uPn^M-KRp;O -%:bPIt9n6i62(F_Fa5`@r:NI5*MJ)HnYic;e8_8jP#5VP?jjf,SA9T@J$kj0PZO#S0Cgq,m[LS;la3_fGntVeL6f;KZB:Wi!i#qS= -%)fT;Yn7"()"?;&c;kR=McpC\5F_"aS_&Y+-('FSRkI$5*&)=W0`lbo"kZt-nF?"\$Z$QO+/-P_hK_=>.TR^\SZTNR"YXp!eq -%6$+ZI#Wq+;RfQd0^;O=Y+;[OD*`HKG'(b^FJ'^$+<6J0U7)7"43IIXJ/07\lF0;#]WT2MJuu31G^r#OH=TZ3&cB!RUgdj -%o^KX'6_8I?XG/\QQ9Rm5DrH3KiFj:)0&\e"<9,cT)"jZN85.=n.1T3hD>FC[&"m/s@Uf4(QqCj8occoNsA1ZEO%% -%:#b:NE!A,%!-OH$[Y+&#@4qG=RFu4\")t[U,V8N!8)-Ib9@1eQlS+l%2?QO(dg@)Z[a'+&iM8lE?i?!4''d*!BI+l;[-;O6!PX?b>EL25ZV!QSWH-:CE4a!_KLG?g?/,c -%NEron1uX4U78=iS%"UYDT]5BM$8k)&")]Mk:^'7G#5k1E?%BJKqiF0mP3b,>Q#86A;@-]$>mk&g!aos^hl[]qG(cmr&$nQX)4n7S -%8M(4dE6LXi==/*cJh'lLeBA(%2uk:9%r#IG1)VhSrbbGB3:'!(/lOmY+^?(YkCR4J$:7+i@U8+T#5"ST=LT*Nm*.VNRXm#7b -%p]Ai#=YPD\PakFB-;-*O!CI\K'*2Q%#g)*r:d<%ek;$"%#bQXu=_WKB+fKs+Li)KG;LXDsTf$CoJ;$Jl7a!$BbA?jRNZT\N2`Dm! -%/Vi!KktZj2lrHZ'LN!pV)?>C+5mc=VBmqj*W#dL,9M"D9&S]'R8dZ\++"GHbX4T??Po*98VAVZ*L[,q)oYCO$eQXC-HU%_$T$drh -%:n8K_NW^$:,I8TH<8T6Th;gh1e5]'sK-SJF+$U%Ci((,cL_B -%+s8#cQ2$CC#]R`$n+mA&i"QIn;G'2>MRsH3J5=OA*si3,%J0U'5eui[QsD0pGBU^(a!(7MIJl%2/,R`Gs,aF6+o`NJEE?99!\Z_' -%^:^YRm!g\`Yl""$IN'm9/+1TAS\adp'\3&/iS@t(r>gB72ARe[3q_;9hEu0U@"lJoJ+f/*@kjac!ZbCNWY^[A?ID`.,\-o*GkMRp -%ZsU#&`,37mX`5'Z9b>qO;pUYOqJX^#AIs4N%mf"f!J0le>'=X'8;27,f+Zkh5:S3S_0:c'.17E:*aT-+n23TUBW_/S(=2jsl1Nrr -%0.rpOje_5[[>P.kFQ-.NYIkkPRn9Q5VSi81o@()@JfK4M?X1ZMrM3VXmPTW@^@Q6,#O2K%;!dWl(B3]m'3Sj.\4T!rfZ+?4UK"hj -%N1SV0==e&b.Mi+`kf)G8rRJ`AY;^@M#c4Y,^0WP^@kX&r/Z!>?Hf_o+Z.R62C0+G6bHI36NhA>i/SP;NRPRbMESkW\m%*(PZ*`t# -%'jsS%ch;7G=?W62m?>t7KLV=M\r$\o9@K%*\)obKm)*>9V/+sjGrpUd(n9t>0H$YG7J.:"Ap?Dh" -%4co3M3-N0HA`)\L+.)Zb25#0*)WG_]=@IlaV^KJnR3,0KZq9;'?[k]Ij+cU6Z7E0N%X)47qgRM^p=2K5%q2uYHXOk3^_Sj$, -%[suq`?8-MB#2RpS[s0Kbc-$B=p:pS_kC?amR.^:((JfNL8aMn<':gN`#GV6)#I3_jZe*<./Vk<#MOH>'l:l41M?'NkX?I0S5kF6bT+*m]3B -%h6V)lD/jW,ZWN(HNFgBe4"%$nHgb22ZhN2fER`k@G#2#1M^(&!(Y=_=0WJ&kq2Bd[76O#)%@fgYoh=KeBr,NUgNR;'*9r'DFY]+#N0?eo>\?GHk?#+3P[O -%j7o&TnJT8SeN_j`0HYSqFmGqW+13a@9>#"fYl7%>^?!-'P?[0kWL3T&.ABfsAEJZMW"jCT3^R -%mb^"9Do;L%D3E'a/P"9Mh$8A@If&QHMUV]@/Uf[+n\WC84#bCLf-Y)!PD[ei@m$YXn"Ffg0:P*Y]B'^9%SJZmn1[%dIt6k"*060> -%Gg'[tMAt'sZ`o6cn\<>$s3fk@W7@k_)DG%0&$-*>9^j$)$0V(1kuBJh3M2am!Mc@PlGplWLUs]j+GoR`(m"3rpiH6R]KZ0[i-#b[G'a$BY\\3Kf#/ -%\u\(=]e;SulQ?_%6;[QF+?j@$N'V2-9 -%gEt&CT=h_R.o'X=K;Kk@cE*5nfqFiU_@q1Xl/6Lg-T6-r5g6])j:;e[Ch_*fJt^fWd:22?n:!Y.P:Si\a"Al"O]0K0I$U!. -%NE=K.n:b?P*57R$D/ke"CjI>eDi/>HY#^g_O8.;!\OVQ7=GLifF74QS<,*>2id/KdE.o1<]BP!o`Fk@BS9 -%<,0jK6#,fO4B/>E'Wi[>Pkru\Q*M&l[3Z(,&t;-UY(ucfRBB4H,U" -%I-RsHe%^,e"F]PK84=1m*4hoEZWL+7EqMc&1-J+p=H#\"lJ^B0.>/611chF@Z:-kc$u&RG"IfF<6BGm-*6(#6Jm*\CQ2kfa%7cE_ -%a"Z%!#SQgoWcSXs/dp#?nc6lFN*GD""oskqGROh=GgJ6lWphm;!eOSb7P]+*he!o@a#'#q..e*(Kh\X];J(\AU&rNB8-l"X:Ml3U -%Lt8&NK>POOifVhQ,I%fKY/[Ute/53OU\Tcf/ieI7+q8Wg/Q_EZ7!8]8/`G]pBgQ>#*7L)5#M(>n\As,.NohJA'hM6[cOl0jQeMVo -%'J!G"6%MP4H#?Jq8d@P9smm -%LQ!)S;CcQT#!kKDW0Tk&:t'Y7@%q$PF]$la=@Q'.!/r7<6%U9?3V5Lg(pL`fOrLbr.iB[J2.M?OGRb(f)1nD)3.QXMOID>n_XMpi -%HEB9_>U_B--Hm6%k$Y-o\/6t6'!db24<_0IJ2MVC#.PL`4A!NF1o69rS&O0/[Sf9^ -%M'jtfI5f7lKc42gh7+.;F-M@\MI8b<"TU*gk. -%bQ7Yf!JT3hWclA#dod3_f8u>=/ZD$>6\K -%BumETPF3TtR>0/WF&WXrgC^:L!G%8f:bp"$*Ha;nYAbRuMCtc!*0[V23j-GYJSDps-4O]g?3lW;S]r%g,D-E(/)*d/F^e0,OefcT -%9uoTB_I9La`jLrY#!qpH&6JoVL2e\Sp0c4k.g_jH6kWq/n$>3UXb>AZ61:8.H6HBo7-eNCa?4jDmJ)Y3Zo+O9FU`r@ZJK\*c*.AL -%*tZN9F_"Y!:T>;@<*YU/W)R"/:"#9kV9)'%nekhO'gRkL9XJ38q*"mrZ'Wk/^+JDq/=eDYWEC:+Z1t3YEn+C.c:DIm(I93Mf%$KAe=;HLkNc)M(Z%eU2OK'U8dR9 -%)_D&6Rb5"jJAERWC64-@]&nO2jn#TRC@+n+S(9-PG,GY,i2$X9_"6n%+2S/&2Ts*4( -%dL,!t'i%Po'fRkpO>Bd-Nc\+b3DpZZn0-M5*`b6878k4L2]dS!%t$>:=]cHSct+OcaGhDt/D=j^$__(r$tYd-*IJZ_4TP"5.PV5G -%RrHRm7FA!NgEo7._o(T#38Oe^D]NsZJuJ2EHjM)'4br"n&k.C3'^%-mU@707]uY8Xn`H[qfuBP6N=kjIf^^3Y[b= -%mU@$W95F$Z.e82UZEQa*pT2$OiTd@\lDX`:anR4dqE$CGb(/E*q0(ts=W#Rgt%2dH[&6i(Da23BYI6N+aAVK4@J@7i[bi?'VOpe?osi -%,(j[3E!gU;b])1o\]iGNe1ST<@B]gdR'TW93_a0N-_;S@lq/-83]qRo:(@B`BJTi3)oms!^nF:q2Fit"1d$O(a3fg0W\'t4 -%ABJS/%5OBJTtk^"3?6!nGVb6_>S^Ir\u!Mg&M)1[G7n@FdT#'5Xo8kK@VHH0LTdE9atn_OgNCF[7(UGn$f]O3V+`"I.YW+890Y)dXK+jCC4S04A\M3*hX")++iPGV8 -%C>sOHG(mY`N&[s]RS^^2O3eW:.7B!UfN`Sj[13R.D;)h/MKl.0)+W!W#*.,b$+-&+;74:AJ0Nd1qKOa&om;0bO'8+bS_SB6_6],[Z$%&f[J\Ml35 -%gWYR>=2*"VT`oZ(MG_sQ1_0:Kl%#!U&KSGt?1pG82J&m1kb&njCMf8o_SC\A*ChJ1!1kPQk,98XI:RN>CC,c(L26;7RO?B3;o>%. -%fa7'TY0p;=]f>ckTIX9K_\+!VNt,1_[G(8R-cju$52U9_%1t0/eeRqbO[1*/^/g!'#Bdm]0]b?OH-p` -%@G=HsY6iH9*7.2Np>H5`@>&]GTdf^>=ob90bak?T+CV2AdJ$!!WCO,NbfC=S/([5[6j"*e%rlhk`'d+,&V3RLU$('g;P74-ai@aJ -%T95O.Vn6?G>$f-rnO1e*=P\D11N5J8Tom[(E\p>*gQ'XG0F(fD -%$Ls?+Tp7\(KcDoWkRR=(K>loPo0b<(@&9!CF!JC/?VZ6IQKd$D&j;cq^]BoI/a?1!2)r(8aB>K3U'_?`$+oo"kXuCEJL5<93)+DG+-PS-&TdclP]io8U-kX`a6snn"phEX*i[I!5$^f!ZCA\gUG@@gU'3nODZP0frf%q -%3!>m^rlXPQ[3hG+2s],)C0'LU/_`06e#m2?p)TWECXt4\^T%gc)aK3:\n/V5XptCM,HNl$:pmBbmFsHJ:npV&VEo,"nW[(I"@2gp -%+?;tA,RBN?[ap;6^-(A)6%bR:4mfPKinDU)@`"N_c%0gT5UY<`7Noh$Ab+k-/nG6$11p@]E+qPPp"cLq:#qf6oYb%^^Ql'&tI+d;DV=Hi,fjN$4>l\]Ih$` -%*!-[N@`!RXfQ#UCa$Z)j(bFbu1Vd#Qn[8`!8FU,_@VeuMRk/Sn)87Rf0EATiTads3K/"FuQ>%d<,+Q*gE&M,Hkd!FkU2tVoOFJm4 -%!Ue1rGu+2Q!%5Sm:(rS$QcCk:i$\8c1l2#;IYJ,"S,49bMeeeEQXK<+-5/\<$3p@u==")GrbZ\qJhu,40e&\'4D"X6)I-+(;Wh`":[d#iqC,soM")HA,j-nq"h)Nfj[5\@s!SuGr114UE'oHWYNi#qK=(a*eT=Wq.6Y/N%7PftM\Off!C10==Q -%.I)(;UHM.&5naSH=!cV^:Z]QRa,qT]Ba@Fh:S^g(9l1rhHN=FEk?bCX(mZ$"[]RY;RYV'^JL&,U?$95aOdiO\-+tY9C!rBU,##G! -%I)V?qD(jD5!%BAB(!^/S?-0QU%q!]e\WeI-Nb/K&BABV*IQC%QFrZ![XoRQIF`A&a2pcLql3-^pRJ](@QE9H0:T#>nDA!Y>d,bt*MI8fR9nd$LMHBJ.;cM3&mY -%5YkIGG+98PaTX+!d@m+qYiP>J\L6[,A@aM#$b9X.#Q_Yn,qIB29S@_;R9kV]P5pot0uQu@/5`^KfGK9DBYnRSB>p,#d(r,kIY>Cn -%%\!Ju/Z8`+N$qB\o4lQO="7=Z97fQTU:Z;G#\q=+o,V@_/?/^*c-iEI0V"9L#+)d[!-%+R'h_77J5h@DeWO`=B;KPnd6bH;XcT\) -%c87:*J6+:lm7a"\&Oj)]'\ef@LX@K^QDRi0TA60j$^>;BF -%-MrP_`*og_S"^%K80q*/NSGJ%=!ZDY3ljSG(faYKWiOJf`CA+2Rj_8l:L8dr&1DNWl4==K5n.KhcsZSS01Mipj;!C.9+Q'[h5V@G -%Ii74C=oqZ]hTK;Vg8cq4a)L5BR.,E^n#FVRRMm0Ljm_m*Uqnn:jXq*TlM.q9aqk2-8Fb>$[apnq/$fpAVkF_!S'F(9fh!&8E)i'H -%B56aK,pQY^L-f73mg*kR7h!/V"VZIF9S.e'>Ctcti4u]/40Rn'Z=&AbT(3l+nd*)<0i?o"b>Hk>*,d@+(9C]8iX^9Kc=]GI[J9kLnYs=_#D-Ai3T'63V$6H^m=paoK_<_tX!?:iR!@'$N@5:PB06lO[L+%D/oR6h2m18Y.dL8N.o?n)M#"2u)'h5_.?&-5L]&V<7u9dH9lD&reT_,;Rq#RE2\%Qagh -%MJ(NBFG]<^^iW*Q$p>QiU*(p_pj=6LL"HB5hP$VNAgR[iW5OXmipYFYr"G#Cad#J`c,\p0:6'>U!e@Q#1!LP#6`3q?8ONpp$$V)= -%RQh4TZ['&GHVdPG%RKQt@(nb@2!@\^WQ7SN-#0,D8[SSj[keY!AH:I9#/S^132-U+0oV4^`F3#07,S-.N9gNE,Psr4!aQTr\Dga( -%]+KSKoRoW%,?ck^]3M^eRY!#Ac%)_XnQcVu:B2ak-?knb$ofjTp4e6_OH&+6a2an8Jh1m12iKA>P_T?7Cj*^ipj*_rJskEH)R1gV -%iR!+_+,()q\)EVj4,0RDWXep'acljm+d'q*$"a#F:jcI]$Z;nqD!]n?]h:B;TiF2\eAb19'LcNb!$"D8l;mtinsRfji,B78JhTa: -%e:RrN$?(Ql3hl'Eibf1J`#sFoJjVd7MBPe)^<\tf$U"Br*WK9>bO#'ZL]kDX>d50r.+BSenoRqM!HAf4*8&3G"Rf9!^]oRo9lh$! -%JOB86peK_U7.J.Tcs-k/LI0uU.`SNA6"c(BKb-[Jd&\4k:U:iAKa3l].km_MZ',Zj:T;fH&Bfr@'_/j\joXL,/e1D(TEuVOUY@M% -%'[I=SFcT'#/;'=i.+,7Q?dk]A2#dh -%5<@_T7$]/4>mR&l^1dl3(E?Z.^bp6ph8.g_&1L_0/>\j=HlZnM6Mp:b'U_?o*28!9m>BrC[cPaPVm+M^nh>YEk-\Vs,c+p'VfLu:X@eRfA[#U5d]1hC3XalKuC_^=B$(4NPaR%8&"LL'2+Q76JB0ZkBt;#qIdgD:&GMV'6E -%FBm`]\>@/Qb$tZIk%q]\EbWp`;9J$_AZIg+KM9`,M&$([?gpTZ)GQ.p?ULCl=MK6W*A`-/9T\nW(/UC'FK2M6mN3O2Grj -%N;5i%Qd3;X-:OZh+e+(3I9e8]I#P5Zfe"=C8iW[:kpX]I3*+.O4!@oVA,!&B/Bd$?4-BrPJ)c;Xt -%Lq@;?:qA#_M;\>!Ya26pm73'5RafOP>'-H1*K&-pC4_j'PPnCqIc$eJ`>Bq:'Bt$$Z`q4V[%F4R%uF*:Z"%JdG8B:FFG]I@4Cb&m -%c?3^IM-CYYCL#$os2G;O&H6Q]I"m1;)tc(PQVtKJVdT`lR!;%FOie$OI@;%'DbpL=p7ipam0IEXa]F>>O_'0<^0G,AM:;MF]pds# -%9;pN6/=l9Y3e\J>N$1GJ1\po-%*K/!/&2uFq*f7L!ME/8+.ipFb[Y+8XDg:)n5(D+8"[]_`$NV4L,b>U"&"mIi#%oZ,%5lQ!]<7" -%/b*Hd3u0)gVC):XNo("iTZMXlfJGSSV8P>AJM>IAKZSW4#.Om*2\)h7E?YQ:b'1s<_!uNnF2]FEXBC;&duhH`8&GlI.tAXtKG8eO -%8%c^t3a#=%_XI"!SDgdY*"0ibggL5^B[,8j1r?"f8"b,/IKaeaV_.+)Of;8,SMVC5Ob:)s+oggA,DJ0*`i=I2U.@gONe -%%#;)nXS7D9:L`%3#or)9ksu^IeG)MsS$?:l@9G9[;rbXe]?/)^_Q4:?6b;m(fiVsP73`&F=JaBf3l$?JV4'nKa:Fm$?09' -%Xj)6FK@;_nt(b)!@l7$J1Kp!,-hsB$"R^QRlND#1JjST0l4i(mZ&2 -%mKLU^6)T((&*JY%=F>d!(t#E3muLc.LXLc`EU,V%bK@)+3^`caTUar5$!3X%%SB@9koN+1Bo?h`FrS@kOeiD"S^=!Cj6j55$2;]Y -%-'WZ(Mo"nH\97;Qd&,E:8G8AC;SaA+S`G&OA3Ah,U8&U`PINrF@1?C.c".IKbM50V3aGA_U&tGJT%\CNgBtANNZ?ARn1_![+E,8h -%Bo4;sBWX^'gm!dkIDV_r&RQ^-Ci[`'`O?,lOi]+:Yr75YF7Pg+blu9m*KUdi$1E@T`TST=V@4&jeFI3=]>Ndf!kf1]\;Cn\a&u\W -%i(*mu)8T=0,],$nVNUfbS4-s,;,LXim-qs'e/1rf'W1ej!1(H-Q;c\`/3X,MOQ8;"#\\fDq1tPC9'H]B0PL/t#T=s>*rO,XYWkB_ -%W*:_u^GC^4/D/e`%hqUK8VTL=(]';XFCXYnp+h818]it0UAPb=!9&0)mYdm,!T,A%5tE73;:Ik"7$9B>Z=.&+P\+kN'@$W=o`S%B -%5g;N0J&$W$R7*:R'7cJR,_@2;0.b4&?nDZl+,S280F:;G)4$9s^7<1g/\NM>-\^363*@q,8d#BQHK3qWnZ\gh5ebBo'X0uQcX9\7 -%"ElcLZfDiDSk-(;UBsdEII^i+g_`VNE.E.qKbPZaZ^c\%659S'dR5Blr!gs26a!=4bZKP2r'6R%J=%2>8tAZf*'eBX^qGqj74IIo -%W=eXFd9AXcVm-sIH]7!>,d0Cg1k;3t@1>UoKLJS"?jqBC,#jP`_EJV>R0c=d)OHL,*QLt%_^WJ[,TS[emf>GUkX,tBI55sb7KGk( -%8Bsc^]VlC^&qGDFJUP/_)?eh9*"epqM3>]-+]VC]@80>h7i(-g)%#.s5"t,9XOa5[9'n71+'m8_PZI;F,c\,"up%E4cr@ -%80S"I<"A:)73mRXP[8?`h3X:L`X%rl&/r5>L2^-q:1<99A]9t&%aG_`fQ<>h3oNJ+8->:#,1;t9d`UJU$CW)'P[iTDC^H<>24AdD.T7A=F0OeLg:r1`i)B6,KONFJOpBjXKgIcB:KP2c30-JO1EqnNFZGUjJYCLmmur -%;D'#Q'O:2K4Vj(K/Jb.^Le+S'iHU"V'>G.9%$6m,:cG3fOd7sR8pj:)Hm9oMnW"3L<+uV23Y,4fBTc>Vl4LlWP#ClC"FVGa\[2kE -%:*:XR1h[Zfk3,b0Sba1C8p0-'Kie?O]F0/;6eW;rNRKmKtt6:_RlAdeu%g4U'+,3<0h;S5Ft$Hg8q]AY$[#aV9Z?FWG#H!` -%I0'JuA4D_[VLN@S7^7)Jk'<,UN@K-krC^'D!S8W;raJi%URK!m705>T&k_FjS9H(i->*HO*n$;a'88P?W0@.8rO,h)_Tt\"q>@%q -%,Ke1d=jb,YH*5@ -%4rTH^VMl68E`WgL=(^A\Q*/`7jREGN;9B7rV_LieWX_ep*f;4ou'Hu%2a$YUh+2p#9*%@l)PH`RmuP2 -%UuDO6hUXIMFd[HhAB`7:A&cd! -%nHt`7B3eT.ghZ6D^`*X$'4NdERWJoM_G=9*60f4q&V;r1@a^/@#uQG75d'ro9M,U)Qe`m\5]q+t\f4=J.J4R$])sCC>i=R7CC*R\ -%N[n7P,gZt5cVbCT`oP@;nOQbSk"9].a67XHdi0q,51=^nn?Y@#*AY:u-N8@_YJ24o:e5p&N]o<7,oQ=DoV0a#PVG[SfeZu#([6iGdY_LG"p9FG -%^KHofj=I3I7HBNd6tHD?!B -%#Gh_63<0Jl.)-FOr[D-;O[kY'*`s^5YWfujalONL-`,9fYGE?\,0<"b&Z"/Q0N]"L3S(F5I`42dOn2>#RmLR@Yo(b&$DG$$6S)-d -%rIbCK(<86uF59^c!^)G\Qh)iYbcZ[\8Fu_l;Ma=Fc/1..KCZN6R!&_*5_/ckEFnDGY)8WYUeh@0@.=oW:qVCl5Q3NT\jZK'X! -%A*(?]W-);(Q-4.\%Dqtr$Mg'iom5H>\2O3I2JC4tE7ioJ$*T;b/(_!:3u19`.fktIQ]FH.@]q[qYptfmU.&\$NLM]&&;:IXJ(/eQ -%D2Zb!D@-oo[X:'1D]4bYjT+]7#;1e$Op^A9C;$g98n6YYf6])m"fZ;ZdFRjG92u6V`@-QYU@SD&NuLHm@7Xt1B`)3fA_^7#d-00t -%^T/OSC^b[.nOd@R*e#i`N13_s.F+Ba*WJ`n:`LZV%D=?]DGBg.dAMjmi*S`+q#AG8P>"C>^K*^mY@j9W8B4U&^K=&&5Nl;GJW;JP -%@^Y6r.1P?Q+qQ^W*I+^5rTKUNiFRYmALHQ7lRf.Q?4=l -%JjYiYZV`_HKLt_<%Cn7meS@la4/[_iT*,!%U^d1k_c\!8\P$RQA`j+((27kP)5K+gd?4k)jJ\eTm.Sd_Tdh7@mU1__+M[dC"EnI@ -%D-!LU["c$7Z;S+hkr.$K?nEt2M"pGPb:tT,)H#h5BMQJ0FfR5bb$YlHP%&NJ/%k]BEJZ#W]%(+YYIIV\Wb+L$:9WS^=447:ST8R0 -%A]uGZ*&MW/(A91b.QF^,kZg;@pfO,'K( -%bpS!D.F]7XLp"is63UPW_L8H,44Wc+B1k5TBW"a&b%N+UkWiTgkIOY\TDQMj>,A_!'`Y91oiCoh1;X7%IVq.1[d]=iqVqkOSKU&6 -%RMA.p2M_8!s%2NG)BB?dM!_k:>Ffc72.:pEXu3gK1.";'1hkHcBS=?.@lhR%)lQ!TDe6l1>.Pm8:M7cDA$gDpdFp1Y[;i8'6Yu.] -%p#CZL.Zh.VOEo/;#qFeDU]K"9/eWt4'<@(,%E)lKFMmZk1P6/\Cb_lQ`,+G9gRN_+p8?:(ZnDAlNI/&Fr]M)rWfU)o8l+Y062.L( -%>8qd%0MYM25;;J;7\?+NN2?O@\PX%BX2/Ls`akJ*Ib=NiMSCCQ^?9G5s$Wq%VQ;Q?2rh6g2V -%:TH4&+lEm@Y//s3%n@j$U<5uA>]3>GPYJ`./.J("f[r'-gOBD'7712I -%jh$^RYP*nP'9D>_RB"l;S^`OjQK=S'W"!#h$6NP+bgis,b(4!WrBH];W;'/j-S[gLAu#/^RnW\dK;U=i*p172faKI.sK7;bl2hJCl?*Xbl=age"s+c)dq**g';[oq6eL/8kCtb&*Ltl$Jd.kuc -%0V%*jE`9@V,0/`$<2og^/tP%GAEhOYO\EjId8BX05+p11%P#uX];>!\:"/T1F]TTCJNr7XG!<8O+a.Kfn,N0n-&S$qW)".bj61Et5Dl%1JjYgA2U"b92"qsaNCqs3+Du*75o1cGEhLp0U2teGJ21SAO -%>''J:@>Ql!(osb:cF)#n?<\$7b)2u\epE%HVEc.04J\1^PAf$l?XtbKnmW*VEbR@u&`RbY.iX]#Hu8ib0PU1!lCg-`j2Tt$%f\.9 -%Enk@,2Kn0PP^7.1[0DA,+ofhI'?W7?c&?tfoPQe)Xq%E3_D7`u:5M!,Ep]PLb@Td):pZ27_*?9&VRUklM`X%V]o?t-3N[*qp4(#h -%rXF;BZC'5V&L$nP<8,^Oq%"[h9ur82!F8VAKp-&0jiW=(3[P8r\>h(U^o:c2%MAo"KS\mh:0&Jb@pYiKd2" -%ftf7Yoaa$lQ,`hns)p*d[kYSr.IZGFmFQ%HH\>WVj.QAT%TD?q[CG+)m$jQR`@ZBbmR`<'e[(mkG'hZ+6KBk*q!+pOE?jWi-\""+ -%N#4OMBXe*XbW'.SN^H8E/5i#$$?5h85/4edr2Yif0H#R4BCKY6f_f-sr]QWuot_?[#1Y$)]S!2j0'b-Hhr.t_Ie$bCXeu#'F.d54 -%D(ojIR/`GWruU=;j=nW(<6G39))^U-ro.P=J#TPld6_2iQTMprLG=Q,QQt]s63R8i:Hf^W[".jI8G`-J4E.$`loe[ -%rhCiuQ@^s@a?P!FA4Ikd7kH)L7jReH2pn!L;2FKmS*82NI_Xi0j8\>"'!<1OB,&\DCncc9 -%oL-f]6Gc1G*DQO.-]04J[=:YH(d^GBe))D>oX@];AJ5mYo;FT3$/V*\_<'Ml.GDG/t%gMX2EHP8V,)GOZ34r;1 -%@-'rig(Kh!^"3qX9d$LqhQ=NKE[:;D"4n'HNf6) -%L8d\eE,/([/7[fS=gg%?O!Jl**+^0gPf*Nq<(R&;TE[IAJ-9$)^d3SB77]-1hb&HL8&cN,"VtbNpOBqYc>+)g1"3/r>H2\,3%KGF]tB7UHBKC@=pf!)qLkjdONQ]?g)F.!Y"q"KtMFY?OTggN)5I"-#0$oV,%Dm;heuk$]9C>FETYs\NB&raokL&tdBLuI?*p+Mr^8:gLVO%V1p@[c^\dmK(5C=t\_ai,&8*sib=\bbCJT]f[d2.6KM/0g(_KDRaKLADT.)61*8`('akTT2-H1=Or!.$STO5-oEbG.&5G=>1F"a3>XfLag;; -%IHQ>\*3Sn+EkB6YT'O/i,>nmJI9tk[oP8DILo9aRAKL51Wq-]8B>a*^mP6 -%?Z$KWHr&AXlNA4CR-tFL`Vm_dppJmRc,Fo$d@I^F5=-V2>$3-3l&UEqo"6r]A"(J-\J`hea%^j7[*=A,%jN<9NsBRJV]I+es@D$4!.CG&uVSU-_JPfEGHlpMcNbE+8U)QXb8b]eo_fn -%=*c`<7kpSY-mn"E>N>.Dh8*/gqApq=TjN/Q55eae-&R]seuja\7MCe@h$d.%9X\"%[8KJ28imp2GmRjrPf:mj-f=K.Tl)Oc:uOrs -%^iNmNCMbn6F@sk_NK9B?#D3V%.ggb38OA0FWHr_bOm7>Q"TCN"I+6Y6*lNt7mWMb@'b\A+_k/,-2#6?qn2K@/_e3G*Kq8>r2k@+M -%gd5T+CA#sIot"\e/DJMfQE[CW/=s1I*&epa`#^4+a7qDg<0)ij4@6Ts8/U,j(2et/dta$ -%[F)JlBs5)mcn7?I5!V%ml64UL3#g8rJ4<:KSQTgR&Mf?8tRC!X/fYYQ)+OM2!\nUjE3f@&!b2H$>M"A$X%%< -%B#ZIQEgMYbknBAfL'mQSK4pOaX6$CbWeKZ%MdZ@]Y9s]h7I81SYh7K-:h4QJN(0)&1)-l?,\%/b&Rh\T5p]sW,Qe2>*['hXhgu5m -%"L+rN7J65GY`aeM.lh;'5;)nQFOWlUKg@Gp<"]g76.4AJI\[nq_35%&6nT&])>g/C8Qm=[(.9u5\P+!BVYYW22d.jKV3P&GU7msZ -%(B"hF.q`Ef>uJ`Y'j[rR].QQ@bK!s84oYrTjD*Ge,W`p&i);!*cpc//M4mp&)jrgYX%nVN_^qN#_\muDA4V^V]fh"aJgY#CZS3._ -%#a%oJ?iBi*#L30r+Id-=(=j8;$pi'V4rfVIL454FrDooL2Ef*!2pQ-)3d%o2*0OG*ss7p)5#+Ls_9kuB-gQ(oEA7i]n<;&*F -%qu6N[!rVf^&)UQSQ;p*S\kO!+ESBquLIY7$pIj(];R6Kl`B`F.]i>r7`LT -%Ut9J]=,9('OihW$DR?^B\,M\7dLQ)>m1@10J1T!EN&LK+8Gs?'i7ZCFLrY+hGV],bc/q6lg&+E>'\LW#N(/DU=T!BtT0K1M$MmnR -%[#"1iDPJD4@/RL/3be*'C"7u;U`H&7g=+5b[f^p0lm=.:ec$mo1JZjeOgR_:rPM(ko&S&Y#-[S^^b8SR7HR\`>Q"oVLe!38+40@&F^$_,*kZANj&%R>R8o6]0hPlbE%Q5&&`faY@>I$U9_d$d=11`kmLmTkL.OkP) -%/ZBY=D:uKdL)Z%b8Jf,$n/(ZXtY0k:\=0>ae-)=d9Lhc4F -%[jE1T2+!c1QY:*0Mb;Ns/N!&72N]NuIgqK/5=C,+:EZJah\4eOchaXO?W8DF7@qI>KFpL"78/Hb'p\Ti3t`1:TTuD_+.$$B3U-fk -%UTO4#'AZH4S4a&>ZQ-2+W\kNl,]gV]R8&J-lHt1$'g`X%.rBRM@pCSS7gfBIFTe8Jf%\C'W& -%&4M3:k!/&hFO7&@e/1c4*^$bRE0&ES&J[%Lc%4-ORalp7XIQ]tB_?&f$E\bgNm"gbg,ZM]PKKte2R5;19jRr#S[Nu]fp&@UTjM^q -%bN!$CgM9rY]_gnN54g/_q.Y_Po0iol7D5`^)7qF6Ujctj_5EDYPub(fRj'=G)`DFoT[jGKcB;+Hfjf8/rA^u5WW$-+ruq"aIG.O% -%BB]VrO57,?XIR$G7?["rS)[)%Gf96?N1j?j0Gl:h8p8ud80Y1X7(\/mK!Rb\V?kTmd"4*bR#8KGImu^mpL(Ch$4KGLR8&6h>mlXc -%<\W_E^hL/.0H+B"[hTXXA&nnGTZOtap;uU!4dZF$Lj`H#%#QlgUN(W/ZY\338?kA,+/uun>jbAe/(h%b^F$jA4%Kbcmc%`q -%P2[lQ*KIYQp5f_.07ZW&`#i/WrMV`6X%(?2=roOk=jp"b5JUmN\FA[c54)*l#&foLJ63M:BX\lA6jb`Y.&2nHXAY$t1H7glJY_>3:(WYX1`?Is_aqq/H4UTDU1P&`CL=r\G/WN\EAPp&c,;%B6e]fYW57X>)LFM@QcQ>:s!Tc=a20c.8]F);$P8BJ^3.PLPIjT[:^j^WL7llqb?)C,_VNA%!ok'iO`V*_iS>HdJ,Fp(8\%8:tS2@U3(^$_f*j -%#J72k$3ZhA-upH%'[;N8(FUVt(/q=H;s-D7RNu^kJg7!Vp58i[g7tK6US`jNQigZ,q!'U&Rq#X00Ak3\c@]r29tZ$=?f9$JnfId>72/q -%PUe8N3`gjO)+D^KnnBC+Sru$2^gUp@NhWqAUhguHM`@ZZC_4,eEPh(t'(8HDbe$2s:;%rRVI)brVIJ[b+iSK[9?C%8B\geBSXW2EGj.O'04]W-*G&Z;[cEgMQnGr`caoaAUt@U;a`F*U;:<"t*j#&-!W2=K9jl3W1279i^/Z,tZPI6(4NgEXFah^S9:&]i/*tF$b%u@8t/LT:YA5u^GW"I2^JJQHG -%28[m&F(qb;,,pYA>:<$?iTdr-56i9`I8M7*3(m^icWZe81,hToEboI4.sr#r4tqYiHpqd^[-OW6f$S>CN3K:a.,N&35iq5!A@7UoV.K*V@'q?1 -%+Snkn#`^%h!XV[I%E.*LUn)@FN<@83am,V.hR(ZL7i[d(4";gC.P7$+NOj(Qdcg`-Op&(-e'd8;LqhZ(UHNLCc]iK$"QOY_R]XCo -%H2._88K7'-==S$q$N/'=)^RAJeR\i*0IG_KRk'A/sQ<-mi>".Q(g2rRKb+i,i[m"S)-QG0V7__hR -%$JYDl!Z&])CELq:Yg#p3oE:]FXMDlU,>JM(ieW+0:'`i=OFSQN#WSP'@$ZjA?^dI7,MWDAEC.I'T[pS`[2:Xc-JFStb`(=k1)/L. -%C2+:4:dIdqXs#A)#M"jS/WSiqli,2nn&&rnstiKt8kNp0(oc;C%"KO`d_*-4H`0df(CDFTjIMi_duXU^J$L:*u'lc9]O2<(V[ -%'.2"[`)T6jX$A!XXt!Zb3UV]lj%cO5mZZ_DY5[,7/gEfZ,$4p`.,Oj5d8pLX9TBYCXY[)W@Rr&kq>>HEuDd*IUopq2sRmo3ceRJ2* -%20qj6*b5.=QY/8H?6%tE:k._$VD>dRAHqhQK\"iVmUo;`$>\\lJU:G-bFY?e]H<3fr5%N0ZuD@9^#(8M2UhKB@c]Wq,jm.l]rh7H -%OXDmjY?u,eHq_F1&+=c<8$fs3cYSXp:(C'`PPmm`pFb\#'Sha3gVWa]0ndR<:bD*Hp):%&/2A-NWU00)#"QA]c[,<`r$mo`*XFF` -%"5u/#?Ydpoq-<1[Kf+tjOahS.g+EPLiqhMY4ubX:ai'h/*aG;h_al0l]iXqkg/TBXc*p2l+]COlcLelBhYX4LSWd2?GknU+*_5eW -%O;M1B*St[5ek'9n<3?u7;fAeBrGo0,NGXTSLrMtIn&*'53'F78V;"0D$%^EeC7VZ^\^i$'SDK.,__5rpWjTAPFm&[hOkm';F_gG, -%p+_"&9m20JZ_Y+=J)p;m-K=)+NTN,2gmKFJd-`9qe">h/^H^6?530,B5*''rT3KYsrKc:(;(/cuo#2\mSYBH[!`.FV&*R7?!^>EA+'_5-a8ua'kHCVWe&U:k -%=ZdflVn7[Y9a6`GAA'cst[.850?Is=WHBGd%$Jh;6G1iFXKfqB6_qdJ!Vk]GUdnXi=N`N&1O4dbk6[&d5H$6+Kqh;N2X-XW7V_=BD -%a1>#c0=9K[LM4#-dckfsoJ5Y7fUZ>rNr#*a7$uZlgMpVO:8QWKa.CG>gSE;RRo#g55@J`(\-T1I%poAAe7gmu4%3%@iC^Gcp`&V- -%*qnn0NW8OM[Y['\2thYGm7bhmn!g9bFLn[A'K,a_mIEeA5IR>"Kp/3SO*3QIf[A$orEO^?P>8Fp_QfC=DN?/(qekWi:o!\\Y&kYF -%k.3&[=CGo$7QN[D:'3PF\ikpU&4mOA:ZY?ZSZW(XYLNm)D,rmQEMbUXkVjI3FZPA.VPp:N86lCAbI]fO]iU%aD:RKP3pe+p](*KE -%;p'=?f7tlMIr"cN,?0!`bZJ4$k=;U4mkq)(p;";*UO#Z#ZPD)?N?s6:C#"oUK`:;qA+e^?1&W.H+/b])^F$nDlZ_s(+19]0jf<:< -%@VZk/qq*U)IC;!m&C%u@0AC3l=1i"I[EI)i]jt#&;=^#rD^OO\HfI2eC\q_E.k.B5@5Xn]>!JtpU_RBe^Wg\FND71EH0RJ/o<6L9 -%e=Q6]Y[['mfD)pkmE]Kl<&4FKFXq(-=C:X0N+SYP@iBnu6 -%'s8h/\8tlq4ro*kf&OmGDI?Cb96TDiUA-WpXrXB0_J9'\CFq#1c.gPQo<3s@f932o`a3pThqBW+n;8Ma@*h#-lc:]8bCR'dj=%L0 -%auqm9jcCe6/r@fVqYKlOD2Us*p?]AGf&c+@iL:4\`T#MK(S5Z"E;GQ(/k@;'m%2fg=p0uEi0qj/EBVs:9!7iF\b8U(kPV+j8,q@L -%bJYKL@1]Pi,TPRNKM"QEZ'VG%#0"q\1pT]/#5fO`>)nJtfT!!s7$'T5G\hc:GIi-DJ*\n5<[-OH,OQSq+uko,Ic'p'>N5At4SA%F -%(\,7JIEZkZX2S7=2a#[L6H.F012Ch]O+'#3(\r:0iB=hn%IRmmVUh!ULNdjJp1V']M3LUF>Y*R(*WdtEpdFWcXRLd;t,;?N2AZ!?NG)_\8+8=S9cCnT0V2IV8) -%4Ql[*Y;r;Z)QeXS>'rZWe'$OJm=ART>0U#mmW#Ln\DEq(?8TC*p<2;9'kKSfLb@)$1JcM41p62j7k=$OIipe^6VWhUeEk#9/8kid -%7NS'.7I;r&g1be2ImD>Zp[<,p-!3$Wqo2'd]g(ED%"kU99;[>_H*kKDZle.XBC.C$@]C\p5qSZRbZ^NVmfrXKRS9&mDD]gbH,tZ$ -%H$-R&h:Pi[%1[&fOkhuHpOS,^E0/WVf86&+2>/r5T00\6,Kn2eU_s)l\8`'@L7oU1NEo,gY8fpKTCQA4h9J#dQ\Vgb6X_eJ=UYVY -%kiZCLn.Bb%YE'TlePHqHWlH@_&_Wrb&j$LY8*GN__mYqFUg#okCQmMT3/S$+[`8B=_LrFM5cWWlnp`F(2`\% -%QcEfu8N2uR\Q@Zf9//6&4Tb*OM5=bG0e[YGo!,XYI7^RpHXDpoqNg`$8W8KO[8UeT#fV^Zc8Kq+/fI5,]XE+(WOLTc-utY"D>2HF -%E&ks8g?dQ*T.T29.>?LP7Z"O;E;++QQo7UZVnnOm,ker0^PAYeg[HfNTk#-l`l/dP)Y2:c$?2cVb@*\i$A -%TiXCh,@NLGlI6O<-l9 -%81r6*lX\.>PTdRs#PH*3c"QM1'2tI:;du]UejKZU?V,#dT!"nZGC>nSX#l,Nlt')@k!%e$;?$4[4"FUgi(cLt6d:To_4_I$@tg:j -%s(*s)`W3*AcHg"V?K"gCcg[aH9l6+-l;Q].HnSEZhJ>-AY0P+SFahSgNFqkce"(An(q^36lioj#gp$"+6kGb`k]r>:((YfgW?_+% -%k$km9*sTW;_hFuLnL@8tf[Pa9mfLW=Ls+i:Lg)F'[0o^f@hocrcopg@FcQX`6uUAD?KO2`:O$/Y/fRk^GWk.m?eC'%Dr7?+K6l4p -%C6?hrej!$W2NhPC:,FcCF2I60ZX9uuGKA&A@-^-HV\1=hm6p"-=2C!8X/ -%5E5r<>cKCg%oVL<^-on@Lb9uQ"F#2"P[<;?:"`fj+UVI1>(#qO?Uq$&*\OIRn_/8e`Ksa$PfHi7IjckqAG6UP;Ehh.np<)-0O$:3 -%Z;uo-LY7,L]@1qBj'eN;hB>`HM%$DtnU8/3"$f6%T/C]c@^f*%Hf(@QPoD657]k?0[o(qL;AS$Ic+L:_!a86dB^#1*k6Dg\,F_uO -%*L6LgiFR&JH^S@jLN<1X258]`(:gjT_VT:*?!(ESj"[:rpSJoTFP33l=LR_8D=r:=AKs;T#3GS2j6d9'L;B43/.:Y=$0LF7#a=ks -%4N+I`I\W;o2i[V8bEKYbnb'A5HlB*Bh8eijL!/li,)80HSHD0%?Y*M%WGm7I(JZ;&:`8c.9UE1V':)3n[(7bE)'NimP/n'@#3_P* -%7GH2n9HekHdN8iq"j:I!rG[7mn4c.?OMJC!/<3;LgoaAi!#1.-f!klTO7:TOk?DDSDBJ5B_q'IX3a"7fl-iq5-JQ:3*)f'U=$)[)MA:TN_+br6$Nt)*L\YSB*B\E+&rU#cC#gaD/7IQV9 -%SAOmh)HWFAa0Jhe1&Om-Qo9nP7'?@M,?/`BK^e1a;>)"_J]9Ze/mSnOh,GpmMf[]3BP<>NQ4XMZ1)J-AeMA7nJN'V#rb`=QXQ;.Q -%Wj#a5r;;Pn1;q'iogH%K>ZcuQN_jdIC.k(@F,FNdIU=-q?qFh<[X'!"Ne[bY_H&5"4FDqQq0N^YXJ`>=d`!t0F4j%ncRY==`emlA -%H$&R]^m0/T-').tK6snbK5F>$Fr95g/6_TCSe9XoY`cXGiCKgcoPM6_\UVA1\c4SMQMY:n.WqfoCj0]PQ8lelkq.6d9AFoYNK+QK -%b&MEY8OWNcBAYhseR_;>U\4J?g&$P`RFgnYfB]?(MlG=35-aeW=bMsDIH-tg/16Z]iu^VroE28D/;eRETTYM:M3B>[tNa\eG+`?TSkY?W3L -%R>Vq`G!&?5:#oem%ciW)J"4XV$.M4HI/Bf!B30L$5[LfD!Y5Q_CH((acDMtm/A\= -%o[N(A5l/D'UWVP5GBsd:h\&/6`21T,"#"0[@ -%.bG^uWc=quZTlM"jM;_bQn^Re*i`[(49JuL)[erWZG&c&a^pM?2S21(Dn,Ts]Y)]Nl@eMK9A\JAo"e69e'l6>>(DpJ(+)4F]OdZN -%RA*[dXWYg8Ksj^g-2.IE#EPqG`]6oRL:]\l,aT82RgY9dZ%*HW,PrZFJf_?*AfRqgBrNl>R"60#fX>;6S@DnE6">O.7IlJm>bole"u)DXc].paYK4TJ/EgTHJR)t/kJH=jB&'A:[XEu1KJ&>5;qO4l6h'T_,[&tF?&N`5>d3uJ(;>l% -%@h)\Lb1<>pkOS,OaJE*U:B@:p##G4jRR7qfbmW@A)!0(qqnbTQ0"aJXl8-QE,Du_=rDQ?i0CjW9MWsW)S'Ku -%M`EaR[W!SY[<;WMk(6huaE*'$OtSPOSRJ\\r/r1mmXL]4_U=s/\X<\O]$HYE92Y*0FO2IFP=$-T?t$HGi)OV3*76CIM0ADA^:mh" -%;e]"eflY1C*#d.8.u*)kQa1)/X@J:MOn:@a@[QXVC%dWf2KHpMNGLX$h1_LN\s?is\6tIVYCcG?C]bq"p9eV;)n9K8"O1n1AF)Xr -%7r94]Jb1ZtR[]X87uo[72oP.2r`$1a-0q_GIe+e7.D`XZ5XlD -%*[$f)8YIIie&V'jcq5eVW"HCQYeTSe,25Nn]`@?P4p-G$"k4W5PK]6g$cqErF'2?K$_8`:9[%U>'2o_$>b58teao6R?7FV8Hh[Cb -%98'BCV!so<9G>XZYd"W/'3[,'J1QTnj,^gV6UETgqW@=,/KuP3M%>-Es6+%bs0&$[@aoOQP%\"o;bcoL1)f8 -%hZ+;3jmD'=ml=t9^!n:Qd*AfNOdOi -%5n,Mc_\K`\&SC-Z_H:`/R6 -%?=^'+W-)jR@h`JWqj=5IVuWh%*u=1pWsq"TMb3OCLe1o\^C:MdHf49h3BM5G"5g;[ -%&*I1K"jmNAlS6RO?oPhP7gVd=j9nB./-jLXC!>PTYs$tIbdW=F12hI#9Vl&bqTAe$$Xc;Es)sO?*>YN:j\MH]B7.gb["[Cd!<^si -%W8]([+?*s*%MPAWn0lSmCj@(5K-TXcdtTHGb&VrOKIR0F0-`Ci6$b=BK$Lu1]ZKVUKW6%*P81sPOa^2GO3e^oZ-:]i/3eVG'$GGq -%SRotIfZg%a!$bZEiHm\nKnRLaeaaNbKCL@Lc2VLH#=-!"u#S*AJYU&HV'VQnR=(S/-G$='$KF"_t/as -%-([aAbGsC5?`mL[)_8O4.UVrm&WqY%k3b"X8ofI[PQ8OBk,UoYaSh?af7h3lpX'hmGgafVi]ch9#BP`fptOHN%:X43S"08<0BaDM -%BkP+Ga:M.CX*'p_plh*P$gJCHY9-#4*I7U"hG!taCX^RWAKOOEo8NkEgR,3QN_iV2=k"flcT_*-m-Jfd$*RR\`KRM+[QD2o\cUpF -%cecDsb]dL,G-ZF2jgfC[[LhhIq"aa)QGOO5@oqX5p$f2OmDVlu]3D!,/)sGKc>W\1[I8E)%[cJf@&D9*JOJFUq,$`r2&"G%<3:ME -%)LUR0n5-O\R;*?D[If6SFlcl"+*jegpIr!f>ipL6g2nr?IAg?D9Js*MQMs^g%`jQSq2'm,Fb>>Us%p+@E5i\'\3\JHckg.4o";k% -%a$\Cgn9lmoIVBkk"-?9C";6e0s"-ofHa?l`Bb -%#0nPXGp.Dj#<7(Uf,<*-C^tNN,Au9HT'\4LHs%7J7WA(V/*87q`?IN200G_68:Z%m`ncY4387;R;`6b-_fZ@BE^=rY[F<8,Q0&dP -%c#J'S?^0]-B6,7=(PHF:V#_7"D2c)G%+"&9B<,D&q?oTMrRff2*JZa-_2iS!df&9r%O>i.&cF0N'5'Su@D'7_= -%bR`$S5A\-gRMB%=DDM_]Ha+;A5,1"(ME*Q-c#fk?XLGd6ZNb&Xhg)\]B5;/6Ee_68 -%Hd?.=DeH+!f`oUAoldbmlr81iCj8+4CThR3cF/(NI5u4Yj4GDCTj56KBBu>AX^9=[%W!-2`T$Q,k;[5-gY);R)j^#;[P:j]"ch:[ -%f230! -%*b$+8OYGf[LDY5\oN.;BJJdR/*aB72mP$HLS;;16h-VX@HoW]hLD]3&-$(fZ\D#g>3Q1\ZaEhaB3"O;DEQ#A$m-%=Zj*%]&b<_(s -%<#W`7ru>M'EqboT(jBtiho-2f$8)X%pQ$K;kJef.6B#,]U0&1?SC6%Fo1069>2s9(t[3'nMXV?".9ZSY1I'2"u-UZ/+oZj5D'g9bLs9O -%@bd[U1+-NNEi5D2od(g%+ZGYb%V>HlEG'1sc\iWQ7,7_@@XL0mAjhTa@n4cT7>r#F5`G$8C&JHLggtSUrW$D4040/41!]Z.rF1S& -%LUkps7#WpC6S0<5^'"rQ#@^s0@a:#X`YgVAFKtcAc$TP&l%j?1$R!V_N3b970-;odpYP4V&EAf4r`k8!$b=#?`&Pk`E'NMi_5>th -%F+`saieo&$j`jG$GJ`MP^=E(DIgRpUrIWupLiHANpeh^aMLV_QaMknF`43M"[g^3bmR=Q+6B%CH2dIb>*.-Z>T=F&GqZatuoB\+< -%1!W,:=3V?;o:a&:Cq.[[F6IS>*:1jETu.UqZ-2`[k]#ju/.3K$_'Ass3daST&?+CM-h!Cm+jeBX-Cq'oqGp.:>dAQUMk\tm]fJ:h4g7-$Q -%6AO=.@(7J(\?Zp>=G8&r_bGOq91=UdfPnkCh%%fjHkG1mU;PLnh*6Z)B37_iJ.B'-=\*>;&3=(4L@b3:k!b'ONT$GWoJEtd5TK_j/^:o)'Ig>bOTgVR0TM\:P06H%$5DY+.NZ1\)4CE.oKXYEggV -%*Nk2.h)ciS7>EC(8:7X+K+:u:e)sS5-9>DJL>,*a/;+Kll7bGR%X5K;o:a((p18O5E!71u\9hL*3aC>X#0LOlk]#Vpb4toW5_gj_ -%a[C,$#p$2"@=A\,^=7NHU%VXMflAOlYK9F9=5P5Y![RUodn:c;HiM69!7^.b>VhS=;fW$%21NlHjOgnR.T:#0?cIm-VG["=^4pjC -%ja4i+<+bU6of&E-(#t4Wk`d&Q3NZ>@O/(C3fNWh`5_F+R`inWg6sJuBGF^_\F;Ngl2h9NCYgZYZ[o5IImHkh>:lQ'f9?2!LAW7,dh"L^.t>l\"Ss3-sH+9Xp]G -%rRJZHjh>DYGf7UBOBhaJV8R_Q:aFZPIS7IO0BnJG'--JSN48Ird'f$XCk.B44SX`#kR`cuBH*'CN-ELnq;d$XXrS.n(l)-E\nph\X%rlVK/]FIulTCZi7M_&Kp`_?[h;na)-Z:o"kOV[cAlEFK'@T,3A -%d63i:7,,OcgLYqDBWUlIc3>22O\'qTZd57a@.M:[Qolu2Pm><2k';67,HJiOE(S^3btNGI40O7\j5#a&*ganO\%WPm.``FAXY7S" -%_2Dk1O>,OLEPs!`Qd*<)=[5!6EhgOEVZX'\VJ395:jC:MNC%+rGlC>QJ0u;=Z'i5dikQ7L+V>a-R"Gh*,t98u#fGG;(Nu`pH`S+J -%qoB`6gPZn'Wm&JnV1g=+e@OB2@/Zh,*A67Aq8G@-CtgA(=YoBE0NXj:Oo%e?)Z6EYI^R$43CTI2UY9oaV -%n3]^"C^_bY9#ogru#p`eiK#)_Y4ZVgM>HnWmG$l[a?HN&`HZHO'9UZ6aD"anC`+*os?p -%liVjq)=;BirSH>^i\OTsF)g8hH/NlsR]p#Pfrn2],r-Qa -%I7NjgEjo^+[[eZ1YomkLU%mjn2MuZ#pfgRZ";78]NqV)!,7L)N6U/R/Pj:G"hdCh3].'9=t2%^CaN:XBMRk2#0 -%Ha@da%)?.[H`^BU:?C*hF)fZU.5@/Y`g^n-r'KQMSMk9-5NSZh7l&i5=# -%fiOeV%*61(1lBXhq(Q*fRK5I\PR+e4Zbg#AcE0678;G;G;RL,1nQmW)a5SB)hX$3)Fon8"2gffjbsZ&GPE4apiN0IbC*f%4#>aZH -%X7##Ihjl3&n#S^c`_u,f]=#<7CJ[%GBRPg@Z-(bo>PtOIeiEYS^\Bd*2^TKu(\M22/=FX[eiF`e5`Y"$>R89o]Ut&U61-SaMdL=0n2?_L[>MuNC2Q>S"d_`GEe2%J/J9]2 -%]=k"eWu&XC\B7PKLk4bB)R((3/CkMmk.AECmJc.*aIUpHLAuBM0(E:.9DO)2Vot)HUtV>HI$)7 -%?\D^TK/_i#V6?XA*T';#e!4C!RI\+-rtUiWgW'!InY1@^^K$0ijn#N: -%(8^bGc?LmHc5#jj&pr*`gdg`%!U\Fu21tV^:=I?!^3$4?=BVK3GU^qngE3'^OQrRuhEJ]dGP_HLnhf@B$nQ`!XjV;o)Qpg#l/"E\)ps"3&Q/UnoBHfmc&>2)3q/[\sVXmpWtdiY/Ud&cZLiOR:Y3R.gA]o.uViU:;,NK%*'C,9jfH5R3FB:u3+`u[t\Vh_7pgh5S/d$YsC*^i-dm+H4Xjq9>]^KljTebl1uLjaV'h[Ve7;NIW( -%B+"Zd5MV7/a)EI)no+J4s5@,"jiR3#)ZaX=#50g@rVB97Z<*Ie=>hqjH7JcGmm=`/Ge-;lG`NuAC/1InLOB!\/tVGNp;50#^(#,G -%5+W\!eG3/?$0^:]%il6`humqBcYjIcp\&a7pu[&eND2pHA[GMDgLr!QhpM(5<(F:+O(>7V#;sjq=Y1tKANjR2uc_Y8,O\EVo-MQN`C.tu":DEp#"$P@NM*FQpM1.!gaYOh'#6j_1La@23.gb%F/hBe'T -%kbEr)l/A^G&H/)ujUg&#^(/'6SPSfPTbANBZ0'V:'0:P()CkbT1gr@!krt-&W6mPq1n5n>.43)8=ZP5ag.gcT0C@TmYV75UN5o' -%p*#'QWG2Q_He,Kj8mqT[GJ6#W;1?nPRq/_*/oS%T_<_p*94H7n%N"D3pRmqF#%InCqkIET3\mNWE;Ir)2=J!Bo'NL")mJ7i@R1j7 -%kI56a\(DIC%-2VI]A?M"Y]5:b(A6cnPCj-H4*Ms,eY#`@4I[,D[Vo*;`a5X>&Qlb+na$aJAi]ti#j%mYL32b**^c8gWSHKh7BIcbHF&'f*qg\]QdZj6 -%qrq/(1E[IcnRU9)^7WY.PW/^*2nEGphgM#n"t>T&NKeW87Z_*WI=&I[h99d`UQJjS\)!7cS]U'qI5jI5cYDQ77*3R7hE`m,Ibi5] -%S?/![MA`YTIG.g-Z369q2q:O*atg?6^o-4,3@[KcN-B\j/66I2?kZX2Jee*`"`_"1jYLXj's0[eEoh0%9uYa-:/$ -%G,gtRd-)GTNVjQ]ottpZkMK:0.0etr6qp9$f(\C8`&VP@;Vo[0;H`2EJ!HLUT4W-^J\8penC -%4"N'@Qf%d3p2[V#"(kTV[pN4O8o*$K8F&WJrqR$:"+:u6-_ET00Z+H=Cj(MdH5Xiem2Z4Eq*&OE.3\uK=[QGAirnc<[hgJK&&-81 -%DmWY\I!mB)rf[XR='[AMcr&GEKH*DU_c9AX35Nt5s)+lq(C!YP>Cl9/;@oI2iTN-)J=",fZ&n_#Fli8b.A>JgTco,O2NCb3eW4Mh -%Q!Ynt;Z6cdKe55uid*J'Fj^'06oqZ/Q38=;5[p*FfmHsn%CASSXfmjU;B$B9)0pS?G'S8?+7mgtr,umL-2\:VGOLDQmn:,dYFNlF -%>A$7kj^p[Oe*MFkptT-Ci8'1G"N1;g;ksJ%\s'g:j#Pr,nTV=!n's/S(@/"D/,eRIC26%_>KXX/AN04_pXs'HD>MXA9GK]Jq84[k -%.51ROLHNR;cU]->;mX<[BTQ]+`3Xeu\4smW -%g1+cs5hLmQZX;tQ!&55"3H'Or$q5Y>HolKnM>m9^eE%!`2\2"UfhNOn7q\m]:cgVXM>@.eZ1p*I`PqSr^gT3$fIc;:E`Z3%;Go&4 -%j_3X:86t;"SrjMl]-HX[]6MWCcZ,VDmAK5ub/LcT0`,Vhs%^&[3C0R9'o%Z.d9L#1md.UeRh_"XY)m)n)8D!V$6@`,nSP_g6ot?P -%Wpn[5FDt=7hK(HKdcJt>)YQ^Tf0BD7Yn1os[R1q5Q)hn%f#EF)FYN0m/6GR@Q@#tJ$;0@J[X)1G]5cAQh(Qnm&@(,p#B;LbH8C^T -%Lc7c@T2mIumhD7!H0ga\)FY[\ls.4>[Q\">J^)&_Cko=0r[:%AWabk< -%He1FR:"8l0ZZ?;A/#c%o?g.914".Yq9\'>B@ob74gWjoNWP0$)SLa,RF`m`BaE".:eh[Ks6CM\gY^9O"buI!WenT;^B;X_U%ShY3 -%>%sT9Y[U-Cl.=Kjns7cXM?BZk"bX'MYf1)9*UkP/ -%bUrQ>SRSaASHI3gK8O-fK6fPe(fGf\0ccG#K=X2S>7F11.YDaq,\2,?6UEW,*E8u)NEqt_C9h%0KG9`8]Y*W:(13\h6_&l\FV3oP -%`Fd`\]A,pC(idH:3D))Z6B9HOfYcq;204%DH8K`Dc=M9P/F5=6d3jJgKUs=Zo3tfj7dn@"8YquebB -%c*_BK:<_*SSI?u;3l"B`(A49Hkqh=blt,QicahN'e!-M0<3Z+*=TLBrZE.Scn"u#S[@?U5+WX;;X_]g9\5drO2_NErhGG->8[?>] -%0@in9ZaJp_H5\"A5W^5J(Yq]N&#shp1!bqZjf-G`BM`a[$1Tb,6/bYgq:H9CqtplE#s3H7BHLp3+nak?[gr_L@F?SfO@UX5^Z')1 -%%uIY*RRF]d"*n:"cC]7B>edn+GFLJ$qb"??G=\h59QpGN1]>PO?P_tDJMK9L;U8q5_e2U)GkXphW]liCc)AU<#pmnd<%V%'W^njc -%U3\PX;t%AH)YSkV2U#cKF0^9P(TYqA9UeIKZajSR":n:#UY%r.C::g+Y^/#eY%00/")EBk%fquB@<,TpqF[M8%ndiAG5TTu2?Us* -%_5pd\0&Y/']#JpkNG"WX4M%FnnbrA!b@^)cf\O,1O&K];)s9baDT!iV?R_(n^KdrTb86$I7GHE&"f6"F%A[:FF^3V5RMft[m9G9k -%g:i!K6ba)FiHh]m%O;)d;#J;G/J`9Of9[\?q`q!1T0@^dY2F4YD4]i=aNBM-NI4`r[eAu1mh2t%GM!A,'epUZn]p*q$Q -%'N_UWhT?;A[\?e8Gi;-F=M,X]YGZE=dP^6tTSa!eYC'9e$?&,D&+pDkTNdRZ?%A19)h&2t11$<=[IW!lY7H!T"iWfZHW_I^p"V]bW0iJn_`r9-g`SV%p"CdYP -%ScA="RH)"=aToMn;9XNuh[>EFAk&9%kl2)-k!&47*&AkUZ37EMZHp\>"tDr=D2gO -%0D0I,\JpX6:qrh7>sI$ZkrPiKHC2;KbnfE$QDPOHE(rsFm"0&h%c7(KhGHVW>r!5%8 -%4)m,:QkMj\ -%5re!Q#,LiP&JPX_W/18be!;jG@*[(C-r,kg/e.#E=7'ilEEK!.B0'_pKDn"pl%=.Nb^"QEY.piVqB0TPkikm:[We9^M6ROg+ -%_h9Df7BK28^bLu$B:jFmd4H4S@Ud9o8X3?2(rJD?o6rj8-e;6jOjf[>nl-5r)2 -%3/np/meN^DSgQb;8$D+n<_e1_>XGgi/r-#aU=/jB57.hOR8Cu=24P,idW4^>NdcZ37T/=i#^ULSO+tj"u1%o>-cN& -%R,K*a)sC_lQ:&(1*FY]8W*dndKJM(dr/p>=$"'Vc0+@UL7NQ$kLlI?4U=B%-8EfY5+usuj45cSP*C^Aq]$]hR#<-:.VA7@V1"80C -%#2Z@(j:I+tX,L/JB:(dX^'[F9fjgaQhg$3*&6JDEmmd#oaTFr)Pm`S=+)uc&bt2t.Nn3W>)kN,EVVRSV^"K>KVR]p/+["H1rjTM* -%8a^t#p%c>_UgLB^1Z9=U=S+RY5Q&g@H0'D!,SKak!Fi%_,'1-.l1?bR]Xi#+0sS=pil7&4Yp:J$_aO'L%^c6](,fYKd=3/rJ_Sti -%:d7%eL>'AbD(,NtA$u+"HP[P[O(>bos#]!,m+rKrd?;-*T6Xq6^LBuW^6SR$?;:%EMr9mH4?Qu+l,pAl"T@Lq^9_t4b-gu%j6YBA -%&gFX<,-f0j1IAEV+:5?c4[Vot=$7,d)o?h%8,-Z1c3%!>^'bemLm3PW.]V;?%7(IrU]VZ>i:&>UEZ_G"ID[RdKTEniANY)o -%`!Z$F)Is"QaFR<]'%#PpPmmqlYS'B6:pV;@9hUCBY;HrYVf+hM5o``2]Fmj;hYJ9POk^*6Ej:YNF%.JY0`RG -%Xl7[;1oNP1iEI&*8,\(BrJ-`ad)j[9FR((:%>MRbm5n5rJIpt.67%.U@IXmIqpUaRa@dMp`P=%^Y!/b?*H[FuH-Q&WSuJ#40k@$b -%!MVk28ODL7n"'':e1T&*ZdV&u4q)eq-3ot[MQK8$e1Q3'J`cpKA,*PrabBJhq_\<^;5FSR@k>U(q!W7DGAD,I:$<&84!2B82K9%3 -%_/pC%I7-cD'-qLL8RoD%@X5WpW0\0/ZsiFcmPu3EFTGr>&tub\4:IeC54`I@NeFVq]U4+pm;X2#7kDgrIT0^R1P9csJC@CS4bL\$IUGRA;nP&ghr[PB)^M_^f*3YZ(Nh1[p+FK0\4MjrCZ:ho) -%+Kl[29RAXuMN[ScoEk]^%noqjB0)Wsh]behTWd@n87tI!>@2`5XDXMA9VdK*8Rr_LSYi!!BSS4HUu[Z"6RC&chlnS6g_>JDlc)Vf -%K"7fug[uS4f#$a@Gk-0JD[2jser9u+\RGo.MYk=OY/fqIe9uWP>Ib;`Gug-ZDsbP;kpeNe4qM^;nB$KLRuk/R29D24K/F8H+lp*1 -%LoZPgLUZ[9$lc_7lam[i"P$n(>n@+tl6s>8&>BL5GX&VpbF_Jr2Tbcjd6aH];"lX$4G8^h6H\Lt*`J=h;@"0m$8KqTUiu/>n]'6R -%p8WLb7D)biiZO/>lde++$?mFUj1%npY:%)f5eEtUg3@kIp%?L<=I:Tg[aYZ%?)Dpsd)SIPQ4%\J>n7/&_`E[u<^MC[E\&2QU/>7% -%??(W9!4K9CgFj@)fg'T0NV*]_j?HM'KQ%j&1%5`@W!]sHJrc=hok#f38ld%fb5@Z -%MC_RI&b]Pt*XdtcAdOaX(;lQbojTm:mN"Q;oQmst.W"79(Z%)bp3JM&(fU>D!5F>NL"a$%3UqOhi!`qBMhKffT8,tC2fA/S+=[9[ -%Pl#\TFNB;o>f+(n>0mE__O88T&r)6bL@S&FbWd-rKPdEN$+8)<0-K^3!5gCRK8!;-Q\Rpg=BIFGF$Wc)J5G6]S[(pgK>Bb"UPcUd -%pUgSPpc')8jR6H`3[e1:fi(ko+2j9_;;)C$q9h5^%ZCqtA8[ -%]=HK8BcMmg$]SY5mf64jr7tUR7L&@4rW1?m'*!gTr!?0:G7$?c]nKQ#d;2BCc9TL-TS;e%5[Gjag]cQ@_.q3$.CAuZZ">Y=qGQls -%^P)J-B')"2*T^W%;;F^,0eR\DZdp(%-PFE0j-L39@[QZhS?N@#k-s5-) -%2YIF95]ZSUS">tmA*(A=9UkjAcYT-:'LW[M$Q*]1%fdiDW#h4Y_+V1rADP?;o$?b\,0shV$o0GjfSbkeIO)KJ@e:bu>c0je\X*-p -%Hi9LQo^"Q-h$M#^4DWa3puLF(^?FCf`j/;o!8!62$GlA9GX`rcB%)aJl(WT6D%u%+M/Rh:^'Z`j[l1(cY`C.FV#COf#fEX:7tp!p -%987dm4A:fh`C8G -%YIDhMl\@.a(uA4/:OknGYI4'hWf8!CS30C\,tjNC=lV'd)OAg->>dJ@\-.sO7Edq^m5K59S@L^E".>WD7GK@A]j$!!SK=Y(&uW#@ -%dRi[+d<_aU/t;tuV>cA'\8e,F$^A_H\p5="hqB$",^Tui1WR;mP3<0YkCc;e%(a4TnHOf'FMC*i=_5t4RkpB@bScTA@jFM!0HDf= -%N[5-VPXs5\NR\&Pr*"(@Zp7FafFQH@YWWc9(d'Ph5qB]Q68Wk@ZqT@r-g][&3\tH;j`Ue+#fGcr%fRi9,&#$ULCjA8#_*NGDk`J> -%OA28=UmWA"?;ed$^%K*`+OinJRUs1uC)cL8p43knF`gt2anFWG;fj[PDK>E#1u/k,9)tN`e.DR11=Wi;0IBZ#4_mVEXQ[qYdGGJ0 -%Zf/M\JeJne9]7=6UE=#!_T1;Q1!uUciTN@"5\DtA0gOWf%YD3=Y*KorJV&re82dXC.Ki\b25'?`Paekq*%f:jk -%`PE#'n3F)2fkM8*Y=ge:oO6>\!D1f4)uEFo+bWVbM#77WeU?cl;;!VIVls_FS)&5:O=P60r=&QqU.mSl]X[9>m9rjs/i9NcW(ImS -%kK1D3Ih%&4HPm!>1I2Qlb/Qrei(O[bLO.oK^u.lt"GcMUP$r;V#_I\dD\NW*"@7"rPYj+o'*Q/1Hn6->B7_6cGfhEOS-af*E$&mO -%%*euAE3Lsi?uRFuJj[-W,@GI;#_GG=@j>B#-4#2*WuM:qo5SeI1kWQ40E?_]_'c.XPFar4jRGNT9J)P9K/5e)*(HPnL;B9##S-[8 -%&MQ2>5]H;Qp-rDF^"i%-gJipeXM.Jg%UjMqhr",BT4WRaG-1iu$:fmk-f#!j;bbQ*5hlnY(9"gJ@iqa#u*\*@O=G -%H#o^'\gS,J=K>I[lB4m-J]?g)NJ5BAcSOC$AJZa%=-gFkZcT."N#^3^\3'!JW&[YF20/,M\-W]:m[_$#iF:MJ$1_WQ/q8-'IU\BU -%c8[3tr'3gJ24&61S2i;kD6Mdaj5R[>g<68)Mm,9$JrV9bh/&??G"OQEgG>8CfrIpJ&BkT;gKFn6E_#T69OEm+^[h1nnbOA0-aETF -%l*a06o;je2[g'_,GnTB8'IhD4_(19[R)40!k1<2uiVKFj3s8hKpR.tD%+\'!"<#`:29e`ITE;U[D!-3/Q?JnSIGopLL6peAl@QsH -%,EU)e`HpeD4[^E>WE?M)UN.`gMk)f9q8RTddlkJGmS/I&@OP>#dH[?S[[oe514N5o^"2'I1ZgI-2gt_"Y>a1]#VM&.T3KLIHb$i0 -%B=\H0h9(dfk,EFG06a0Elnm86V3qN*?_r#GIRBE6[r]6)i^7moZiFI%^K`#NhdLI8BP=hSBJb`%ZNjho2g"JAWuL,K+K[2*9`3[0 -%SpLmH,ic&qrc^6]C[G@"s*cNUeXi6&et]Wd/`cU5S!t>qV07&_\'jWMk20`3 -%F2r3VgKV)O*Y)s=++>L[eY)Y!opRR#/h+Zug0#Y8R9Uj^!6`V,7[4Ft>3sZL@&D01b!UXKmkG53,O+ZI_cKHM)QVr&ON9 -%NGk@McMHarJ&a15F(.lk=SPqc]qpRV(F_TImQW?;SR:V-ZT[%%[^31l:rQ8S^qhdhic6c%mZoM,F4JZoSrH),[T?B\YQ%ol.:(eI -%bi_0^hX+\hl_a!)=uDc)![\1M_1J3_.dq*iDIIc@>qN3;j!Dh[njWF4Z[R?]]3)$#Im/f-66YJ!+hm=+IoUs+N=,+@;gfsc%4mupNTC2HjV#P`gkga*@q955X -%Yl36SjVS$Crl#$Z$,=^O%sOHLAe3jEm4`bR[?JnE)n!54]j/1Z=[%6II9b(E(Ar=TKPD%HlhBk^c\K_gbN_kdCF -%Y?sD`WGi`eB2m&1F*i3,leZ-9lM$i4jig>e,MQ%!9Jb(0oDX\Gm)l7cM -%[mpa)bZ8`BGgGOt?Yl!)-#tV2^H&KV9Tr?WF,6T9@/p"5"no=(=2P>)_=[e4elIONpG%p?Clb14M5mA>E -%)CqkH8\Mu3R;Y:M51cqfgb>7eVU"j5,S420.&VEUPG?h4/,VKmr5%D>8(e;k\7+lVl5q+gH]5:ZfdUlClqVfum0^W*&,q(TM,B9rtn09)H>.l8Nm@:2Qn)#t]SuSJfHa;!W>*fUqMDbqE?k"/[8M#S`.pMHc#O=L:>]oRc?gYN -%/]34MhbA]0+:P>.^03UQIM\I/C1o!,m!Uk=[5L32FR+\<(L,_U?$DEAX3KYd[t=nm?mjX(K.e8EQB%[:3OBkQndchTci(")LX`>Sab>YV&=N]3h!4M5P&\dY-A>dK3E["jiX`8?:A%(CD/ -%YMYSN2q^!no3d/irphrOru&\"#+[X(@SoTIoB%M!ODQZFA+^"bWRC[pbTtRt^]; -%Q0Xugo@']io#E,CdUhR@hQ+@=BQjXf1tkLEkGM/DX_-grPSa\4\J'l8MEdg -%r8("Ob5-R`f2n!8$X%d_HsN3tqUE?NAq;6*oAVL=^9aBPO>`I)l.;U"@q($sjaLe,4igM@-$!g\8FeGJ"_C?FLkJdB)V"*GOBs0j%/WmGa2Wpoi!fW#-$!g\a@$lL@?ej< -%0d9s+Bf6D0m!4s_jn9u;OVGd+7>W!',Efj^SjeJU)^CM$ -%fOn&*a2Wr%c/i;/,%$3>)1OF`2P8CeTGQOfNVON0Yl+m;T-Z@e@4i425>,`T92/3nr@FrDN12@Fg4#@;Hq$.Tg%MbJjth=I38+#3 -%UujJ^r\2IfZ_Z`iYeBHhrXCc'Gb8[H=]4i/!=hi4r@FrDN4e7_gWu%OcV2OR,hpY.Ra6:&4oaV^YSg9<8[b8)V"*ieq$jdZ?N0!B -%@&"r[PANNWC-KPH9Xt$PWVHr8RrJ7-;Y-<%@l;C%Z_Z_>I[`%=p9URW1\*5`D*L[.4u<)%PAEHVC-JD:(6`T"956ZNQF)LWT-Z@e -%@J)#'Ib&9u>JfSeJeU/imFZ[An:bZU33CAMB_f7#8/ -%C6+@dradNAlp'%V==*)m@Fo`(+;RVk.TB![a:O%9T*rl4m5Bb&d1G]M(GkQ2rpYaM];)SOtpY8.5R3HKFa,c!^+S[0U2n:IAqL?"PD'bdfSX!201NrG\]RmXfu!=6/XKBo>%)q]aTf(:P?5d -%O'6+25sb]UY&Bo1m;O=ilq&(pF(!K8UC3B'O64"k-a6aiHn:=!ON\hskX.lSXpg[EH/bKY;A$`r>cbZ5,_h(\(A`c@juA_K:C-Pm -%O?1krs59`L)'FG$pc8qc6?ABKB$I@@qGuB6$8=6)9FEfV6(iL_Fb!>JiFjf"0:iT*a33JQ4=f2?'O7"77QfZH,#ZdCRaGm*$^L9k -%aT8B*#ERm_"a'sTQZRaWMmQ`)QYrS[27I!ddT=YoE.,t6g^1+0:aSV4^oR['[Us'-otePMZAp/4VEXEZNL%ZEXn^[dR.Z5%nh&p' -%n2QdsS;QrTNP@U?8p2pmoUH>8WR/c*QuAjbAf-k$9N6"W-HJ<#qh-uLjcCUd\3u++T!0oBK&B8GSl#5P=.p`;'TFs[%`OS*Oskl+ -%M%*-Z4!$W&'>cG8/&?t!)*)lU50`h<\dc[?&7Laq;i\*XomTfMYAR$8U%%)i&%L)P0?1a]uCur+:reJ`f*O(2VE? -%E?BIP7:K>L&P.:mK.?G>jFJh3ET0XUM2WHg1*@auecUR2-l*eY+9s)=#WY)r,kMSd0,uO?$_rC8K:.$,-pCZ8WWED5rij]/E7lgQ -%Hlqm@KN2I$03n8fl+7htR$clpf7U`4NtiC%KT=aZL]l&&"0u*60.7-(">'d+-[_c$bnnggFUFcT=@3ujcru/i;?l(9='`QSJ8Ga& -%,SA:TmmZcsYot.PO^M1r`/:]Ac&u[unQ:huVC;;'a+[=kkTaBpfUBk/%]qh4K!,sD1]@pYk/552\D4k-N0AJEEjJ9!$O1]ERVd%o^hL"#rWb2;Z`\T!^SIs,Ut5l;4M\ncWDh'fo[<:%Bq8??U>Tekm6On-)cmUR;h2mBd6o8`^.8^Ldn=RQd*^CF, -%5PRS?Zmj6LnG%S#5XF?n@?+st@FM<2:5rj$BP!dZ/u?Z&n9c.>es'DVaZ%!BnGM5s9b&Rs>/'LY+_*fD8WQl9Hq7:UWM)tH#ojP2 -%1L,O-&mW6(Ze$uf%uHHYB+WFa#b07r5dT^]!DoZT6bIdU#D*lcm8EKu3M.Hl34PTF#=65#F=]V`TqH%\4]8SHFmF<0(k^RcBsB$a -%TH!#H5)7(E-H]gpA21('"J;nV$.DQ``h9sWKGpin3C;ea(_?m:\Yt@+dNM'!6UX2m+sr:Cc?L+,a]2M%4c.0+H=QjZM*8!%`b?_thT'?(3'9[Pc/3MQ;+-POlAAn=&o`cpl^R]G\uE-.r[ -%<)Z:LF=F!s+fE#SH8EK@Seb@ScF$WP`s&HSVF7J!>Sq/pO^)7I*l\jGLJsQ!6,br"`=gY0C_?1&#eHHR@)D)>63eq&@T?7nYgX:_ -%80/h@NC&aJ0L\TEAJCZNNn4<_l!a=D657FhR)#E)"?>[O]]#Zh2,I\ijn-<9_5mR6T'$=?E(WV/*(P0Y'Zn,c/. -%U>Zj_!MZhd0Jo-Y7*6C5a4c9V/#rP^p;A@KPH<-DjJG&j<8:tDr?r'FTgCAR)L;D>EC*6qRN'+PIlHG6j'A4R_+oT&+O>4SFSC.Y3WtVo-t4,YpKn4>ARZCi`_2nHBe:[R0QU -%-E=nd\ekZ0Uf;?I)ck8$#UN5Hp-GH-ZshF?S(FkV((uTa_5?7iD]HciK1L#+K5RP?_Asr5XWd.F89#G*kU,?8[#j?iP?`1aKc;*k -%jQGQs?oVO.7Kf$Q!&P[oN04W=Z_;=S$]0SuaI*TI@tC"\Z"P-gkX/4^OIR:9,n[CmK4se>,bDFQjYhh2$n.Dip!ZH>g4UR%MPS4S -%5&GDh,R*Q\po[a/nn_923g/b5X;T/A:*["ZT$(nBRlJ,?Q'.jN/m;"OF1?br$T9L0/=//,QaSb62Hg,?_hG*#Cu-K*-(a0=4PKKX -%,^S/IIiNO/>Z8@[-S`V]=CDZ_.mEVO!@f9-*=r]?XB(AqY4J9%!k'N/V:).!lH-W$nH0YUtA2lYI$_&UEP'2j(i5^i;X9IR,j1JU$O%ck0Q"dnqHtbK_,+dQ+VAM>A@I6]@-NNeF`Crl:q5M -%?#BMB[o55VlMoA9C9)LO=FI:.iu@<]?11#mFfTS1pD6\G96C"%FQl^aomb.>&V'~> -%AI9_PrivateDataEnd diff --git a/contrib/bind9/doc/arm/isc-logo.pdf b/contrib/bind9/doc/arm/isc-logo.pdf deleted file mode 100644 index 71d3fdd..0000000 Binary files a/contrib/bind9/doc/arm/isc-logo.pdf and /dev/null differ diff --git a/contrib/bind9/doc/arm/man.dig.html b/contrib/bind9/doc/arm/man.dig.html deleted file mode 100644 index 7d0e437..0000000 --- a/contrib/bind9/doc/arm/man.dig.html +++ /dev/null @@ -1,665 +0,0 @@ - - - - - -dig - - - - - - - -

-
-
-
-

Name

-

dig — DNS lookup utility

-
-
-

Synopsis

-

dig [@server] [-b address] [-c class] [-f filename] [-k filename] [-p port#] [-q name] [-t type] [-x addr] [-y [hmac:]name:key] [-4] [-6] [name] [type] [class] [queryopt...]

-

dig [-h]

-

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

-
-
-

DESCRIPTION

-

dig - (domain information groper) is a flexible tool - for interrogating DNS name servers. It performs DNS lookups and - displays the answers that are returned from the name server(s) that - were queried. Most DNS administrators use dig to - troubleshoot DNS problems because of its flexibility, ease of use and - clarity of output. Other lookup tools tend to have less functionality - than dig. -

-

- Although dig is normally used with - command-line - arguments, it also has a batch mode of operation for reading lookup - requests from a file. A brief summary of its command-line arguments - and options is printed when the -h option is given. - Unlike earlier versions, the BIND 9 implementation of - dig allows multiple lookups to be issued - from the - command line. -

-

- Unless it is told to query a specific name server, - dig will try each of the servers listed - in - /etc/resolv.conf. -

-

- When no command line arguments or options are given, will perform an - NS query for "." (the root). -

-

- It is possible to set per-user defaults for dig via - ${HOME}/.digrc. This file is read and - any options in it - are applied before the command line arguments. -

-

- The IN and CH class names overlap with the IN and CH top level - domains names. Either use the -t and - -c options to specify the type and class or - use the -q the specify the domain name or - use "IN." and "CH." when looking up these top level domains. -

-
-
-

SIMPLE USAGE

-

- A typical invocation of dig looks like: -

-
 dig @server name type 
-

- where: - -

-
-
server
-

- is the name or IP address of the name server to query. This can - be an IPv4 - address in dotted-decimal notation or an IPv6 - address in colon-delimited notation. When the supplied - server argument is a - hostname, - dig resolves that name before - querying that name - server. If no server - argument is provided, - dig consults /etc/resolv.conf - and queries the name servers listed there. The reply from the - name - server that responds is displayed. -

-
name
-

- is the name of the resource record that is to be looked up. -

-
type
-

- indicates what type of query is required — - ANY, A, MX, SIG, etc. - type can be any valid query - type. If no - type argument is supplied, - dig will perform a lookup for an - A record. -

-
-

-

-
-
-

OPTIONS

-

- The -b option sets the source IP address of the query - to address. This must be a valid - address on - one of the host's network interfaces or "0.0.0.0" or "::". An optional - port - may be specified by appending "#<port>" -

-

- The default query class (IN for internet) is overridden by the - -c option. class is - any valid - class, such as HS for Hesiod records or CH for Chaosnet records. -

-

- The -f option makes dig - operate - in batch mode by reading a list of lookup requests to process from the - file filename. The file contains a - number of - queries, one per line. Each entry in the file should be organized in - the same way they would be presented as queries to - dig using the command-line interface. -

-

- If a non-standard port number is to be queried, the - -p option is used. port# is - the port number that dig will send its - queries - instead of the standard DNS port number 53. This option would be used - to test a name server that has been configured to listen for queries - on a non-standard port number. -

-

- The -4 option forces dig - to only - use IPv4 query transport. The -6 option forces - dig to only use IPv6 query transport. -

-

- The -t option sets the query type to - type. It can be any valid query type - which is - supported in BIND 9. The default query type is "A", unless the - -x option is supplied to indicate a reverse lookup. - A zone transfer can be requested by specifying a type of AXFR. When - an incremental zone transfer (IXFR) is required, - type is set to ixfr=N. - The incremental zone transfer will contain the changes made to the zone - since the serial number in the zone's SOA record was - N. -

-

- The -q option sets the query name to - name. This useful do distinguish the - name from other arguments. -

-

- Reverse lookups — mapping addresses to names — are simplified by the - -x option. addr is - an IPv4 - address in dotted-decimal notation, or a colon-delimited IPv6 address. - When this option is used, there is no need to provide the - name, class and - type arguments. dig - automatically performs a lookup for a name like - 11.12.13.10.in-addr.arpa and sets the - query type and - class to PTR and IN respectively. By default, IPv6 addresses are - looked up using nibble format under the IP6.ARPA domain. - To use the older RFC1886 method using the IP6.INT domain - specify the -i option. Bit string labels (RFC2874) - are now experimental and are not attempted. -

-

- To sign the DNS queries sent by dig and - their - responses using transaction signatures (TSIG), specify a TSIG key file - using the -k option. You can also specify the TSIG - key itself on the command line using the -y option; - hmac is the type of the TSIG, default HMAC-MD5, - name is the name of the TSIG key and - key is the actual key. The key is a - base-64 - encoded string, typically generated by - dnssec-keygen(8). - - Caution should be taken when using the -y option on - multi-user systems as the key can be visible in the output from - ps(1) - or in the shell's history file. When - using TSIG authentication with dig, the name - server that is queried needs to know the key and algorithm that is - being used. In BIND, this is done by providing appropriate - key and server statements in - named.conf. -

-
-
-

QUERY OPTIONS

-

dig - provides a number of query options which affect - the way in which lookups are made and the results displayed. Some of - these set or reset flag bits in the query header, some determine which - sections of the answer get printed, and others determine the timeout - and retry strategies. -

-

- Each query option is identified by a keyword preceded by a plus sign - (+). Some keywords set or reset an - option. These may be preceded - by the string no to negate the meaning of - that keyword. Other - keywords assign values to options like the timeout interval. They - have the form +keyword=value. - The query options are: - -

-
-
+[no]tcp
-

- Use [do not use] TCP when querying name servers. The default - behavior is to use UDP unless an AXFR or IXFR query is - requested, in - which case a TCP connection is used. -

-
+[no]vc
-

- Use [do not use] TCP when querying name servers. This alternate - syntax to +[no]tcp is - provided for backwards - compatibility. The "vc" stands for "virtual circuit". -

-
+[no]ignore
-

- Ignore truncation in UDP responses instead of retrying with TCP. - By - default, TCP retries are performed. -

-
+domain=somename
-

- Set the search list to contain the single domain - somename, as if specified in - a - domain directive in - /etc/resolv.conf, and enable - search list - processing as if the +search - option were given. -

-
+[no]search
-

- Use [do not use] the search list defined by the searchlist or - domain - directive in resolv.conf (if - any). - The search list is not used by default. -

-
+[no]showsearch
-

- Perform [do not perform] a search showing intermediate - results. -

-
+[no]defname
-

- Deprecated, treated as a synonym for +[no]search -

-
+[no]aaonly
-

- Sets the "aa" flag in the query. -

-
+[no]aaflag
-

- A synonym for +[no]aaonly. -

-
+[no]adflag
-

- Set [do not set] the AD (authentic data) bit in the query. The - AD bit - currently has a standard meaning only in responses, not in - queries, - but the ability to set the bit in the query is provided for - completeness. -

-
+[no]cdflag
-

- Set [do not set] the CD (checking disabled) bit in the query. - This - requests the server to not perform DNSSEC validation of - responses. -

-
+[no]cl
-

- Display [do not display] the CLASS when printing the record. -

-
+[no]ttlid
-

- Display [do not display] the TTL when printing the record. -

-
+[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. -

-
+[no]nssearch
-

- When this option is set, dig - attempts to find the - authoritative name servers for the zone containing the name - being - looked up and display the SOA record that each name server has - for the - 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. -

-
+[no]cmd
-

- Toggles the printing of the initial comment in the output - identifying - the version of dig and the query - options that have - been applied. This comment is printed by default. -

-
+[no]short
-

- Provide a terse answer. The default is to print the answer in a - verbose form. -

-
+[no]identify
-

- Show [or do not show] the IP address and port number that - supplied the - answer when the +short option - is enabled. If - short form answers are requested, the default is not to show the - source address and port number of the server that provided the - answer. -

-
+[no]comments
-

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

-
+[no]stats
-

- This query option toggles the printing of statistics: when the - query - was made, the size of the reply and so on. The default - behavior is - to print the query statistics. -

-
+[no]qr
-

- Print [do not print] the query as it is sent. - By default, the query is not printed. -

-
+[no]question
-

- Print [do not print] the question section of a query when an - answer is - returned. The default is to print the question section as a - comment. -

-
+[no]answer
-

- Display [do not display] the answer section of a reply. The - default - is to display it. -

-
+[no]authority
-

- Display [do not display] the authority section of a reply. The - default is to display it. -

-
+[no]additional
-

- Display [do not display] the additional section of a reply. - The default is to display it. -

-
+[no]all
-

- Set or clear all display flags. -

-
+time=T
-

- - Sets the timeout for a query to - T seconds. The default - timeout is 5 seconds. - An attempt to set T to less - than 1 will result - in a query timeout of 1 second being applied. -

-
+tries=T
-

- Sets the number of times to try UDP queries to server to - T instead of the default, 3. - If - T is less than or equal to - zero, the number of - tries is silently rounded up to 1. -

-
+retry=T
-

- Sets the number of times to retry UDP queries to server to - T instead of the default, 2. - Unlike - +tries, this does not include - the initial - query. -

-
+ndots=D
-

- Set the number of dots that have to appear in - name to D for it to be - considered absolute. The default value is that defined using - the - ndots statement in /etc/resolv.conf, or 1 if no - ndots statement is present. Names with fewer dots are - interpreted as - relative names and will be searched for in the domains listed in - the - search or domain directive in - /etc/resolv.conf. -

-
+bufsize=B
-

- Set the UDP message buffer size advertised using EDNS0 to - B bytes. The maximum and minimum sizes - of this buffer are 65535 and 0 respectively. Values outside - this range are rounded up or down appropriately. - Values other than zero will cause a EDNS query to be sent. -

-
+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. -

-
+[no]multiline
-

- Print records like the SOA records in a verbose multi-line - format with human-readable comments. The default is to print - each record on a single line, to facilitate machine parsing - of the dig output. -

-
+[no]fail
-

- Do not try the next server if you receive a SERVFAIL. The - default is - to not try the next server which is the reverse of normal stub - resolver - behavior. -

-
+[no]besteffort
-

- Attempt to display the contents of messages which are malformed. - The default is to not display malformed answers. -

-
+[no]dnssec
-

- Requests DNSSEC records be sent by setting the DNSSEC OK bit - (DO) - in the OPT record in the additional section of the query. -

-
+[no]sigchase
-

- Chase DNSSEC signature chains. Requires dig be compiled with - -DDIG_SIGCHASE. -

-
+trusted-key=####
-
-

- Specifies a file containing trusted keys to be used with - +sigchase. Each DNSKEY record must be - on its own line. -

-

- If not specified dig will look for - /etc/trusted-key.key then - trusted-key.key in the current directory. -

-

- Requires dig be compiled with -DDIG_SIGCHASE. -

-
-
+[no]topdown
-

- When chasing DNSSEC signature chains perform a top-down - validation. - Requires dig be compiled with -DDIG_SIGCHASE. -

-
-

- -

-
-
-

MULTIPLE QUERIES

-

- The BIND 9 implementation of dig - supports - specifying multiple queries on the command line (in addition to - supporting the -f batch file option). Each of those - queries can be supplied with its own set of flags, options and query - options. -

-

- In this case, each query argument - represent an - individual query in the command-line syntax described above. Each - consists of any of the standard options and flags, the name to be - looked up, an optional query type and class and any query options that - should be applied to that query. -

-

- A global set of query options, which should be applied to all queries, - can also be supplied. These global query options must precede the - first tuple of name, class, type, options, flags, and query options - supplied on the command line. Any global query options (except - the +[no]cmd option) can be - overridden by a query-specific set of query options. For example: -

-
-dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
-
-

- shows how dig could be used from the - command line - to make three lookups: an ANY query for www.isc.org, a - reverse lookup of 127.0.0.1 and a query for the NS records of - isc.org. - - A global query option of +qr is - applied, so - that dig shows the initial query it made - for each - lookup. The final query has a local query option of - +noqr which means that dig - will not print the initial query when it looks up the NS records for - isc.org. -

-
-
-

IDN SUPPORT

-

- If dig has been built with IDN (internationalized - domain name) support, it can accept and display non-ASCII domain names. - dig appropriately converts character encoding of - domain name before sending a request to DNS server or displaying a - reply from the server. - If you'd like to turn off the IDN support for some reason, defines - the IDN_DISABLE environment variable. - The IDN support is disabled if the variable is set when - dig runs. -

-
-
-

FILES

-

/etc/resolv.conf -

-

${HOME}/.digrc -

-
-
-

SEE ALSO

-

host(1), - named(8), - dnssec-keygen(8), - RFC1035. -

-
-
-

BUGS

-

- There are probably too many query options. -

-
-
- - - diff --git a/contrib/bind9/doc/arm/man.dnssec-keygen.html b/contrib/bind9/doc/arm/man.dnssec-keygen.html deleted file mode 100644 index 3b8d2d8..0000000 --- a/contrib/bind9/doc/arm/man.dnssec-keygen.html +++ /dev/null @@ -1,269 +0,0 @@ - - - - - -dnssec-keygen - - - - - - - - -
-
-
-

Name

-

dnssec-keygen — DNSSEC key generation tool

-
-
-

Synopsis

-

dnssec-keygen {-a algorithm} {-b keysize} {-n nametype} [-c class] [-e] [-f flag] [-g generator] [-h] [-k] [-p protocol] [-r randomdev] [-s strength] [-t type] [-v level] {name}

-
-
-

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 - TSIG (Transaction Signatures), as defined in RFC 2845. -

-
-
-

OPTIONS

-
-
-a algorithm
-
-

- Selects the cryptographic algorithm. The value of - algorithm must be one of RSAMD5 (RSA) or RSASHA1, - DSA, DH (Diffie Hellman), or HMAC-MD5. These values - are case insensitive. -

-

- Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement - algorithm, - and DSA is recommended. For TSIG, HMAC-MD5 is mandatory. -

-

- Note 2: HMAC-MD5 and DH automatically set the -k flag. -

-
-
-b keysize
-

- Specifies the number of bits in the key. The choice of key - size depends on the algorithm used. RSAMD5 / RSASHA1 keys must be - between - 512 and 2048 bits. Diffie Hellman keys must be between - 128 and 4096 bits. DSA keys must be between 512 and 1024 - bits and an exact multiple of 64. HMAC-MD5 keys must be - between 1 and 512 bits. -

-
-n nametype
-

- Specifies the owner type of the key. The value of - nametype must either be ZONE (for a DNSSEC - zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with - a host (KEY)), - USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). - These values are - case insensitive. -

-
-c class
-

- Indicates that the DNS record containing the key should have - the specified class. If not specified, class IN is used. -

-
-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. - The only recognized flag is KSK (Key Signing Key) DNSKEY. -

-
-g generator
-

- If generating a Diffie Hellman key, use this generator. - Allowed values are 2 and 5. If no generator - is specified, a known prime from RFC 2539 will be used - if possible; otherwise the default is 2. -

-
-h
-

- Prints a short summary of the options and arguments to - dnssec-keygen. -

-
-k
-

- Generate KEY records rather than DNSKEY records. -

-
-p protocol
-

- 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. -

-
-r randomdev
-

- Specifies the source of randomness. If the operating - system does not provide a /dev/random - or equivalent device, the default source of randomness - is keyboard input. randomdev - specifies - the name of a character device or file containing random - data to be used instead of the default. The special value - keyboard indicates that keyboard - input should be used. -

-
-s strength
-

- Specifies the strength value of the key. The strength is - a number between 0 and 15, and currently has no defined - purpose in DNSSEC. -

-
-t type
-

- Indicates the use of the key. type must be - one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default - is AUTHCONF. AUTH refers to the ability to authenticate - data, and CONF the ability to encrypt data. -

-
-v level
-

- Sets the debugging level. -

-
-
-
-

GENERATED KEYS

-

- When dnssec-keygen completes - successfully, - it prints a string of the form Knnnn.+aaa+iiiii - to the standard output. This is an identification string for - the key it has generated. -

-
    -
  • nnnn is the key name. -

  • -
  • aaa is the numeric representation - of the - algorithm. -

  • -
  • iiiii is the key identifier (or - footprint). -

  • -
-

dnssec-keygen - creates two files, with names based - on the printed string. Knnnn.+aaa+iiiii.key - contains the public key, and - Knnnn.+aaa+iiiii.private contains the - private - key. -

-

- The .key file contains a DNS KEY record - that - can be inserted into a zone file (directly or with a $INCLUDE - statement). -

-

- The .private file contains - algorithm-specific - fields. For obvious security reasons, this file does not have - general read permission. -

-

- Both .key and .private - files are generated for symmetric encryption algorithms such as - HMAC-MD5, even though the public and private key are equivalent. -

-
-
-

EXAMPLE

-

- To generate a 768-bit DSA key for the domain - example.com, the following command would be - issued: -

-

dnssec-keygen -a DSA -b 768 -n ZONE example.com -

-

- The command would print a string of the form: -

-

Kexample.com.+003+26160 -

-

- In this example, dnssec-keygen creates - the files Kexample.com.+003+26160.key - and - Kexample.com.+003+26160.private. -

-
-
-

SEE ALSO

-

dnssec-signzone(8), - BIND 9 Administrator Reference Manual, - RFC 2535, - RFC 2845, - RFC 2539. -

-
-
-

AUTHOR

-

Internet Systems Consortium -

-
-
- - - diff --git a/contrib/bind9/doc/arm/man.dnssec-signzone.html b/contrib/bind9/doc/arm/man.dnssec-signzone.html deleted file mode 100644 index 2d0ce06..0000000 --- a/contrib/bind9/doc/arm/man.dnssec-signzone.html +++ /dev/null @@ -1,323 +0,0 @@ - - - - - -dnssec-signzone - - - - - - - - -
-
-
-

Name

-

dnssec-signzone — DNSSEC zone signing tool

-
-
-

Synopsis

-

dnssec-signzone [-a] [-c class] [-d directory] [-e end-time] [-f output-file] [-g] [-h] [-k key] [-l domain] [-i interval] [-I input-format] [-j jitter] [-N soa-serial-format] [-o origin] [-O output-format] [-p] [-r randomdev] [-s start-time] [-t] [-v level] [-z] {zonefile} [key...]

-
-
-

DESCRIPTION

-

dnssec-signzone - signs a zone. It generates - NSEC and RRSIG records and produces a signed version of the - zone. The security status of delegations from the signed zone - (that is, whether the child zones are secure or not) is - determined by the presence or absence of a - keyset file for each child zone. -

-
-
-

OPTIONS

-
-
-a
-

- Verify all generated signatures. -

-
-c class
-

- Specifies the DNS class of the zone. -

-
-k key
-

- Treat specified key as a key signing key ignoring any - key flags. This option may be specified multiple times. -

-
-l domain
-

- Generate a DLV set in addition to the key (DNSKEY) and DS sets. - The domain is appended to the name of the records. -

-
-d directory
-

- Look for keyset files in - directory as the directory -

-
-g
-

- Generate DS records for child zones from keyset files. - Existing DS records will be removed. -

-
-s start-time
-

- Specify the date and time when the generated RRSIG records - become valid. This can be either an absolute or relative - time. An absolute start time is indicated by a number - in YYYYMMDDHHMMSS notation; 20000530144500 denotes - 14:45:00 UTC on May 30th, 2000. A relative start time is - indicated by +N, which is N seconds from the current time. - If no start-time is specified, the current - time minus 1 hour (to allow for clock skew) is used. -

-
-e end-time
-

- Specify the date and time when the generated RRSIG records - expire. 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 end-time is - specified, 30 days from the start time is used as a default. -

-
-f output-file
-

- The name of the output file containing the signed zone. The - default is to append .signed to - the - input filename. -

-
-h
-

- Prints a short summary of the options and arguments to - dnssec-signzone. -

-
-i interval
-
-

- When a previously-signed zone is passed as input, records - may be resigned. The interval option - specifies the cycle interval as an offset from the current - time (in seconds). If a RRSIG record expires after the - cycle interval, it is retained. Otherwise, it is considered - to be expiring soon, and it will be replaced. -

-

- The default cycle interval is one quarter of the difference - between the signature end and start times. So if neither - end-time or start-time - are specified, dnssec-signzone - generates - signatures that are valid for 30 days, with a cycle - interval of 7.5 days. Therefore, if any existing RRSIG records - are due to expire in less than 7.5 days, they would be - replaced. -

-
-
-I input-format
-

- The format of the input zone file. - Possible formats are "text" (default) - and "raw". - This option is primarily intended to be used for dynamic - signed zones so that the dumped zone file in a non-text - format containing updates can be signed directly. - The use of this option does not make much sense for - non-dynamic zones. -

-
-j jitter
-
-

- When signing a zone with a fixed signature lifetime, all - RRSIG records issued at the time of signing expires - simultaneously. If the zone is incrementally signed, i.e. - a previously-signed zone is passed as input to the signer, - all expired signatures have to be regenerated at about the - same time. The jitter option specifies a - jitter window that will be used to randomize the signature - expire time, thus spreading incremental signature - regeneration over time. -

-

- 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. -

-
-
-n ncpus
-

- Specifies the number of threads to use. By default, one - thread is started for each detected CPU. -

-
-N soa-serial-format
-
-

- The SOA serial number format of the signed zone. - Possible formats are "keep" (default), - "increment" and - "unixtime". -

-
-
"keep"
-

Do not modify the SOA serial number.

-
"increment"
-

Increment the SOA serial number using RFC 1982 - arithmetics.

-
"unixtime"
-

Set the SOA serial number to the number of seconds - since epoch.

-
-
-
-o origin
-

- The zone origin. If not specified, the name of the zone file - is assumed to be the origin. -

-
-O output-format
-

- The format of the output file containing the signed zone. - Possible formats are "text" (default) - and "raw". -

-
-p
-

- Use pseudo-random data when signing the zone. This is faster, - but less secure, than using real random data. This option - may be useful when signing large zones or when the entropy - source is limited. -

-
-r randomdev
-

- Specifies the source of randomness. If the operating - system does not provide a /dev/random - or equivalent device, the default source of randomness - is keyboard input. randomdev - specifies - the name of a character device or file containing random - data to be used instead of the default. The special value - keyboard indicates that keyboard - input should be used. -

-
-t
-

- Print statistics at completion. -

-
-v level
-

- Sets the debugging level. -

-
-z
-

- Ignore KSK flag on key when determining what to sign. -

-
zonefile
-

- The file containing the zone to be signed. -

-
key
-

- Specify which keys should be used to sign the zone. If - no keys are specified, then the zone will be examined - for DNSKEY records at the zone apex. If these are found and - there are matching private keys, in the current directory, - then these will be used for signing. -

-
-
-
-

EXAMPLE

-

- The following command signs the example.com - zone with the DSA key generated by dnssec-keygen - (Kexample.com.+003+17247). The zone's keys must be in the master - file (db.example.com). This invocation looks - for keyset files, in the current directory, - so that DS records can be generated from them (-g). -

-
% dnssec-signzone -g -o example.com db.example.com \
-Kexample.com.+003+17247
-db.example.com.signed
-%
-

- In the above example, dnssec-signzone creates - the file db.example.com.signed. This - file should be referenced in a zone statement in a - named.conf file. -

-

- This example re-signs a previously signed zone with default parameters. - The private keys are assumed to be in the current directory. -

-
% cp db.example.com.signed db.example.com
-% dnssec-signzone -o example.com db.example.com
-db.example.com.signed
-%
-
-
-

SEE ALSO

-

dnssec-keygen(8), - BIND 9 Administrator Reference Manual, - RFC 2535. -

-
-
-

AUTHOR

-

Internet Systems Consortium -

-
-
- - - diff --git a/contrib/bind9/doc/arm/man.host.html b/contrib/bind9/doc/arm/man.host.html deleted file mode 100644 index 6bc2188..0000000 --- a/contrib/bind9/doc/arm/man.host.html +++ /dev/null @@ -1,249 +0,0 @@ - - - - - -host - - - - - - - - -
-
-
-

Name

-

host — DNS lookup utility

-
-
-

Synopsis

-

host [-aCdlnrsTwv] [-c class] [-N ndots] [-R number] [-t type] [-W wait] [-m flag] [-4] [-6] {name} [server]

-
-
-

DESCRIPTION

-

host - is a simple utility for performing DNS lookups. - It is normally used to convert names to IP addresses and vice versa. - When no arguments or options are given, - host - prints a short summary of its command line arguments and options. -

-

name is the domain name that is to be - looked - up. It can also be a dotted-decimal IPv4 address or a colon-delimited - IPv6 address, in which case host will by - default - perform a reverse lookup for that address. - server is an optional argument which - is either - the name or IP address of the name server that host - should query instead of the server or servers listed in - /etc/resolv.conf. -

-

- The -a (all) option is equivalent to setting the - -v option and asking host to make - a query of type ANY. -

-

- When the -C option is used, host - will attempt to display the SOA records for zone - name from all the listed - authoritative name - servers for that zone. The list of name servers is defined by the NS - records that are found for the zone. -

-

- The -c option instructs to make a DNS query of class - class. This can be used to lookup - Hesiod or - Chaosnet class resource records. The default class is IN (Internet). -

-

- Verbose output is generated by host when - the - -d or -v option is used. The two - options are equivalent. They have been provided for backwards - compatibility. In previous versions, the -d option - switched on debugging traces and -v enabled verbose - output. -

-

- List mode is selected by the -l option. This makes - host perform a zone transfer for zone - name. Transfer the zone printing out - the NS, PTR - and address records (A/AAAA). If combined with -a - all records will be printed. -

-

- The -i - option specifies that reverse lookups of IPv6 addresses should - use the IP6.INT domain as defined in RFC1886. - The default is to use IP6.ARPA. -

-

- The -N option sets the number of dots that have to be - in name for it to be considered - absolute. The - default value is that defined using the ndots statement in - /etc/resolv.conf, or 1 if no ndots - statement is - present. Names with fewer dots are interpreted as relative names and - will be searched for in the domains listed in the search - or domain directive in - /etc/resolv.conf. -

-

- The number of UDP retries for a lookup can be changed with the - -R option. number - indicates - how many times host will repeat a query - that does - not get answered. The default number of retries is 1. If - number is negative or zero, the - number of - retries will default to 1. -

-

- Non-recursive queries can be made via the -r option. - Setting this option clears the RD — recursion - desired — bit in the query which host makes. - This should mean that the name server receiving the query will not - attempt to resolve name. The - -r option enables host - to mimic - the behavior of a name server by making non-recursive queries and - expecting to receive answers to those queries that are usually - referrals to other name servers. -

-

- By default host uses UDP when making - queries. The - -T option makes it use a TCP connection when querying - the name server. TCP will be automatically selected for queries that - require it, such as zone transfer (AXFR) requests. -

-

- The -4 option forces host to only - use IPv4 query transport. The -6 option forces - host to only use IPv6 query transport. -

-

- The -t option is used to select the query type. - type can be any recognized query - type: CNAME, - NS, SOA, SIG, KEY, AXFR, etc. When no query type is specified, - host automatically selects an appropriate - query - type. By default it looks for A records, but if the - -C option was given, queries will be made for SOA - records, and if name is a - dotted-decimal IPv4 - address or colon-delimited IPv6 address, host will - query for PTR records. If a query type of IXFR is chosen the starting - serial number can be specified by appending an equal followed by the - starting serial number (e.g. -t IXFR=12345678). -

-

- The time to wait for a reply can be controlled through the - -W and -w options. The - -W option makes host - wait for - wait seconds. If wait - is less than one, the wait interval is set to one second. When the - -w option is used, host - will - effectively wait forever for a reply. The time to wait for a response - will be set to the number of seconds given by the hardware's maximum - value for an integer quantity. -

-

- The -s option tells host - not to send the query to the next nameserver - if any server responds with a SERVFAIL response, which is the - reverse of normal stub resolver behavior. -

-

- The -m can be used to set the memory usage debugging - flags - record, usage and - trace. -

-
-
-

IDN SUPPORT

-

- If host has been built with IDN (internationalized - domain name) support, it can accept and display non-ASCII domain names. - host appropriately converts character encoding of - domain name before sending a request to DNS server or displaying a - reply from the server. - If you'd like to turn off the IDN support for some reason, defines - the IDN_DISABLE environment variable. - The IDN support is disabled if the variable is set when - host runs. -

-
-
-

FILES

-

/etc/resolv.conf -

-
-
-

SEE ALSO

-

dig(1), - named(8). -

-
-
- - - diff --git a/contrib/bind9/doc/arm/man.named-checkconf.html b/contrib/bind9/doc/arm/man.named-checkconf.html deleted file mode 100644 index 7db5021..0000000 --- a/contrib/bind9/doc/arm/man.named-checkconf.html +++ /dev/null @@ -1,130 +0,0 @@ - - - - - -named-checkconf - - - - - - - - -
-
-
-

Name

-

named-checkconf — named configuration file syntax checking tool

-
-
-

Synopsis

-

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

-
-
-

DESCRIPTION

-

named-checkconf - checks the syntax, but not the semantics, of a named - configuration file. -

-
-
-

OPTIONS

-
-
-t directory
-

- Chroot to directory so that - include - directives in the configuration file are processed as if - run by a similarly chrooted named. -

-
-v
-

- Print the version of the named-checkconf - program and exit. -

-
-z
-

- Perform a test load of all master zones found in - named.conf. -

-
-j
-

- When loading a zonefile read the journal if it exists. -

-
filename
-

- The name of the configuration file to be checked. If not - specified, it defaults to /etc/named.conf. -

-
-
-
-

RETURN VALUES

-

named-checkconf - returns an exit status of 1 if - errors were detected and 0 otherwise. -

-
-
-

SEE ALSO

-

named(8), - named-checkzone(8), - BIND 9 Administrator Reference Manual. -

-
-
-

AUTHOR

-

Internet Systems Consortium -

-
-
- - - diff --git a/contrib/bind9/doc/arm/man.named-checkzone.html b/contrib/bind9/doc/arm/man.named-checkzone.html deleted file mode 100644 index 93e17ec..0000000 --- a/contrib/bind9/doc/arm/man.named-checkzone.html +++ /dev/null @@ -1,294 +0,0 @@ - - - - - -named-checkzone - - - - - - - - -
-
-
-

Name

-

named-checkzone, named-compilezone — zone file validity checking or converting tool

-
-
-

Synopsis

-

named-checkzone [-d] [-j] [-q] [-v] [-c class] [-f format] [-F format] [-i mode] [-k mode] [-m mode] [-M mode] [-n mode] [-o filename] [-s style] [-S mode] [-t directory] [-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] [-o filename] [-s style] [-t directory] [-w directory] [-D] [-W mode] {zonename} {filename}

-
-
-

DESCRIPTION

-

named-checkzone - checks the syntax and integrity of a zone file. It performs the - same checks as named does when loading a - zone. This makes named-checkzone useful for - checking zone files before configuring them into a name server. -

-

- named-compilezone is similar to - named-checkzone, but it always dumps the - zone contents to a specified file in a specified format. - Additionally, it applies stricter check levels by default, - since the dump output will be used as an actual zone file - loaded by named. - When manually specified otherwise, the check levels must at - least be as strict as those specified in the - named configuration file. -

-
-
-

OPTIONS

-
-
-d
-

- Enable debugging. -

-
-q
-

- Quiet mode - exit code only. -

-
-v
-

- Print the version of the named-checkzone - program and exit. -

-
-j
-

- When loading the zone file read the journal if it exists. -

-
-c class
-

- Specify the class of the zone. If not specified "IN" is assumed. -

-
-i mode
-
-

- Perform post-load zone integrity checks. Possible modes are - "full" (default), - "full-sibling", - "local", - "local-sibling" and - "none". -

-

- Mode "full" checks that MX records - refer to A or AAAA record (both in-zone and out-of-zone - hostnames). Mode "local" only - checks MX records which refer to in-zone hostnames. -

-

- Mode "full" checks that SRV records - refer to A or AAAA record (both in-zone and out-of-zone - hostnames). Mode "local" only - checks SRV records which refer to in-zone hostnames. -

-

- Mode "full" checks that delegation NS - records refer to A or AAAA record (both in-zone and out-of-zone - hostnames). It also checks that glue address records - in the zone match those advertised by the child. - Mode "local" only checks NS records which - refer to in-zone hostnames or that some required glue exists, - that is when the nameserver is in a child zone. -

-

- Mode "full-sibling" and - "local-sibling" disable sibling glue - checks but are otherwise the same as "full" - and "local" respectively. -

-

- Mode "none" disables the checks. -

-
-
-f format
-

- Specify the format of the zone file. - Possible formats are "text" (default) - 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. -

-
-k mode
-

- Perform "check-names" checks with the - specified failure mode. - Possible modes are "fail" - (default for named-compilezone), - "warn" - (default for named-checkzone) and - "ignore". -

-
-m mode
-

- Specify whether MX records should be checked to see if they - are addresses. Possible modes are "fail", - "warn" (default) and - "ignore". -

-
-M mode
-

- Check if a MX record refers to a CNAME. - Possible modes are "fail", - "warn" (default) and - "ignore". -

-
-n mode
-

- Specify whether NS records should be checked to see if they - are addresses. - Possible modes are "fail" - (default for named-compilezone), - "warn" - (default for named-checkzone) and - "ignore". -

-
-o filename
-

- Write zone output to filename. - This is mandatory for named-compilezone. -

-
-s style
-

- Specify the style of the dumped zone file. - Possible styles are "full" (default) - and "relative". - The full format is most suitable for processing - automatically by a separate script. - On the other hand, the relative format is more - human-readable and is thus suitable for editing by hand. - For named-checkzone - this does not cause any effects unless it dumps the zone - contents. - It also does not have any meaning if the output format - is not text. -

-
-S mode
-

- Check if a SRV record refers to a CNAME. - Possible modes are "fail", - "warn" (default) and - "ignore". -

-
-t directory
-

- Chroot to directory so that - include - directives in the configuration file are processed as if - run by a similarly chrooted named. -

-
-w directory
-

- chdir to directory so that - relative - filenames in master file $INCLUDE directives work. This - is similar to the directory clause in - named.conf. -

-
-D
-

- Dump zone file in canonical format. - This is always enabled for named-compilezone. -

-
-W mode
-

- Specify whether to check for non-terminal wildcards. - Non-terminal wildcards are almost always the result of a - failure to understand the wildcard matching algorithm (RFC 1034). - Possible modes are "warn" (default) - and - "ignore". -

-
zonename
-

- The domain name of the zone being checked. -

-
filename
-

- The name of the zone file. -

-
-
-
-

RETURN VALUES

-

named-checkzone - returns an exit status of 1 if - errors were detected and 0 otherwise. -

-
-
-

SEE ALSO

-

named(8), - named-checkconf(8), - RFC 1035, - BIND 9 Administrator Reference Manual. -

-
-
-

AUTHOR

-

Internet Systems Consortium -

-
-
- - - diff --git a/contrib/bind9/doc/arm/man.named.html b/contrib/bind9/doc/arm/man.named.html deleted file mode 100644 index 70539b4..0000000 --- a/contrib/bind9/doc/arm/man.named.html +++ /dev/null @@ -1,293 +0,0 @@ - - - - - -named - - - - - - - - -
-
-
-

Name

-

named — Internet domain name server

-
-
-

Synopsis

-

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

-
-
-

DESCRIPTION

-

named - is a Domain Name System (DNS) server, - part of the BIND 9 distribution from ISC. For more - information on the DNS, see RFCs 1033, 1034, and 1035. -

-

- When invoked without arguments, named - will - read the default configuration file - /etc/named.conf, read any initial - data, and listen for queries. -

-
-
-

OPTIONS

-
-
-4
-

- Use IPv4 only even if the host machine is capable of IPv6. - -4 and -6 are mutually - exclusive. -

-
-6
-

- Use IPv6 only even if the host machine is capable of IPv4. - -4 and -6 are mutually - exclusive. -

-
-c config-file
-

- Use config-file as the - configuration file instead of the default, - /etc/named.conf. To - ensure that reloading the configuration file continues - to work after the server has changed its working - directory due to to a possible - directory option in the configuration - file, config-file should be - an absolute pathname. -

-
-d debug-level
-

- Set the daemon's debug level to debug-level. - Debugging traces from named become - more verbose as the debug level increases. -

-
-f
-

- Run the server in the foreground (i.e. do not daemonize). -

-
-g
-

- Run the server in the foreground and force all logging - to stderr. -

-
-m flag
-

- Turn on memory usage debugging flags. Possible flags are - usage, - trace, - record, - size, and - mctx. - These correspond to the ISC_MEM_DEBUGXXXX flags described in - <isc/mem.h>. -

-
-n #cpus
-

- Create #cpus worker threads - to take advantage of multiple CPUs. If not specified, - named will try to determine the - number of CPUs present and create one thread per CPU. - If it is unable to determine the number of CPUs, a - single worker thread will be created. -

-
-p port
-

- Listen for queries on port port. If not - specified, the default is port 53. -

-
-s
-
-

- Write memory usage statistics to stdout on exit. -

-
-

Note

-

- This option is mainly of interest to BIND 9 developers - and may be removed or changed in a future release. -

-
-
-
-t directory
-
-

Chroot - to directory after - processing the command line arguments, but before - reading the configuration file. -

-
-

Warning

-

- This option should be used in conjunction with the - -u option, as chrooting a process - running as root doesn't enhance security on most - systems; the way chroot(2) is - defined allows a process with root privileges to - escape a chroot jail. -

-
-
-
-u user
-
-

Setuid - to user after completing - privileged operations, such as creating sockets that - listen on privileged ports. -

-
-

Note

-

- On Linux, named uses the kernel's - capability mechanism to drop all root privileges - except the ability to bind(2) to - a - privileged port and set process resource limits. - Unfortunately, this means that the -u - option only works when named is - run - on kernel 2.2.18 or later, or kernel 2.3.99-pre3 or - later, since previous kernels did not allow privileges - to be retained after setuid(2). -

-
-
-
-v
-

- Report the version number and exit. -

-
-x cache-file
-
-

- Load data from cache-file into the - cache of the default view. -

-
-

Warning

-

- This option must not be used. It is only of interest - to BIND 9 developers and may be removed or changed in a - future release. -

-
-
-
-
-
-

SIGNALS

-

- In routine operation, signals should not be used to control - the nameserver; rndc should be used - instead. -

-
-
SIGHUP
-

- Force a reload of the server. -

-
SIGINT, SIGTERM
-

- Shut down the server. -

-
-

- The result of sending any other signals to the server is undefined. -

-
-
-

CONFIGURATION

-

- The named configuration file is too complex - to describe in detail here. A complete description is provided - in the - BIND 9 Administrator Reference Manual. -

-
-
-

FILES

-
-
/etc/named.conf
-

- The default configuration file. -

-
/var/run/named.pid
-

- The default process-id file. -

-
-
-
-

SEE ALSO

-

RFC 1033, - RFC 1034, - RFC 1035, - named-checkconf(8), - named-checkzone(8), - rndc(8), - lwresd(8), - named.conf(5), - BIND 9 Administrator Reference Manual. -

-
-
-

AUTHOR

-

Internet Systems Consortium -

-
-
- - - diff --git a/contrib/bind9/doc/arm/man.rndc-confgen.html b/contrib/bind9/doc/arm/man.rndc-confgen.html deleted file mode 100644 index 056bcbd..0000000 --- a/contrib/bind9/doc/arm/man.rndc-confgen.html +++ /dev/null @@ -1,222 +0,0 @@ - - - - - -rndc-confgen - - - - - - - -
-
-
-

Name

-

rndc-confgen — rndc key generation tool

-
-
-

Synopsis

-

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

-
-
-

DESCRIPTION

-

rndc-confgen - generates configuration files - for rndc. It can be used as a - convenient alternative to writing the - rndc.conf file - and the corresponding controls - and key - statements in named.conf by hand. - Alternatively, it can be run with the -a - option to set up a rndc.key file and - avoid the need for a rndc.conf file - and a controls statement altogether. -

-
-
-

OPTIONS

-
-
-a
-
-

- Do automatic rndc configuration. - This creates a file rndc.key - in /etc (or whatever - sysconfdir - was specified as when BIND was - built) - that is read by both rndc - and named on startup. The - rndc.key file defines a default - command channel and authentication key allowing - rndc to communicate with - named on the local host - with no further configuration. -

-

- Running rndc-confgen -a allows - BIND 9 and rndc to be used as - drop-in - replacements for BIND 8 and ndc, - with no changes to the existing BIND 8 - named.conf file. -

-

- If a more elaborate configuration than that - generated by rndc-confgen -a - is required, for example if rndc is to be used remotely, - you should run rndc-confgen without - the - -a option and set up a - rndc.conf and - named.conf - as directed. -

-
-
-b keysize
-

- Specifies the size of the authentication key in bits. - Must be between 1 and 512 bits; the default is 128. -

-
-c keyfile
-

- Used with the -a option to specify - an alternate location for rndc.key. -

-
-h
-

- Prints a short summary of the options and arguments to - rndc-confgen. -

-
-k keyname
-

- Specifies the key name of the rndc authentication key. - This must be a valid domain name. - The default is rndc-key. -

-
-p port
-

- Specifies the command channel port where named - listens for connections from rndc. - The default is 953. -

-
-r randomfile
-

- Specifies a source of random data for generating the - authorization. If the operating - system does not provide a /dev/random - or equivalent device, the default source of randomness - is keyboard input. randomdev - specifies - the name of a character device or file containing random - data to be used instead of the default. The special value - keyboard indicates that keyboard - input should be used. -

-
-s address
-

- Specifies the IP address where named - listens for command channel connections from - rndc. The default is the loopback - address 127.0.0.1. -

-
-t chrootdir
-

- Used with the -a option to specify - a directory where named will run - chrooted. An additional copy of the rndc.key - will be written relative to this directory so that - it will be found by the chrooted named. -

-
-u user
-

- Used with the -a option to set the - owner - of the rndc.key file generated. - If - -t is also specified only the file - in - the chroot area has its owner changed. -

-
-
-
-

EXAMPLES

-

- To allow rndc to be used with - no manual configuration, run -

-

rndc-confgen -a -

-

- To print a sample rndc.conf file and - corresponding controls and key - statements to be manually inserted into named.conf, - run -

-

rndc-confgen -

-
-
-

SEE ALSO

-

rndc(8), - rndc.conf(5), - named(8), - BIND 9 Administrator Reference Manual. -

-
-
-

AUTHOR

-

Internet Systems Consortium -

-
-
- - - diff --git a/contrib/bind9/doc/arm/man.rndc.conf.html b/contrib/bind9/doc/arm/man.rndc.conf.html deleted file mode 100644 index 4e8154c..0000000 --- a/contrib/bind9/doc/arm/man.rndc.conf.html +++ /dev/null @@ -1,255 +0,0 @@ - - - - - -rndc.conf - - - - - - - - -
-
-
-

Name

-

rndc.conf — rndc configuration file

-
-
-

Synopsis

-

rndc.conf

-
-
-

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 - named.conf. Statements are enclosed - in braces and terminated with a semi-colon. Clauses in - the statements are also semi-colon terminated. The usual - comment styles are supported: -

-

- C style: /* */ -

-

- C++ style: // to end of line -

-

- Unix style: # to end of line -

-

rndc.conf is much simpler than - named.conf. The file uses three - statements: an options statement, a server statement - and a key statement. -

-

- The options statement contains five clauses. - The default-server clause is followed by the - name or address of a name server. This host will be used when - no name server is given as an argument to - rndc. The default-key - clause is followed by the name of a key which is identified by - a key statement. If no - keyid is provided on the rndc command line, - and no key clause is found in a matching - server statement, this default key will be - used to authenticate the server's commands and responses. The - default-port clause is followed by the port - to connect to on the remote name server. If no - port option is provided on the rndc command - line, and no port clause is found in a - matching server statement, this default port - will be used to connect. - The default-source-address and - default-source-address-v6 clauses which - can be used to set the IPv4 and IPv6 source addresses - respectively. -

-

- After the server keyword, the server - statement includes a string which is the hostname or address - for a name server. The statement has three possible clauses: - key, port and - addresses. The key name must match the - name of a key statement in the file. The port number - specifies the port to connect to. If an addresses - clause is supplied these addresses will be used instead of - the server name. Each address can take an optional port. - If an source-address or source-address-v6 - of supplied then these will be used to specify the IPv4 and IPv6 - source addresses respectively. -

-

- The key statement begins with an identifying - string, the name of the key. The statement has two clauses. - algorithm identifies the encryption algorithm - for rndc to use; currently only HMAC-MD5 - is - supported. This is followed by a secret clause which contains - the base-64 encoding of the algorithm's encryption key. The - base-64 string is enclosed in double quotes. -

-

- There are two common ways to generate the base-64 string for the - secret. The BIND 9 program rndc-confgen - can - be used to generate a random key, or the - mmencode program, also known as - mimencode, can be used to generate a - base-64 - string from known input. mmencode does - not - ship with BIND 9 but is available on many systems. See the - EXAMPLE section for sample command lines for each. -

-
-
-

EXAMPLE

-
-      options {
-        default-server  localhost;
-        default-key     samplekey;
-      };
-
-

-

-
-      server localhost {
-        key             samplekey;
-      };
-
-

-

-
-      server testserver {
-        key		testkey;
-        addresses	{ localhost port 5353; };
-      };
-
-

-

-
-      key samplekey {
-        algorithm       hmac-md5;
-        secret          "6FMfj43Osz4lyb24OIe2iGEz9lf1llJO+lz";
-      };
-
-

-

-
-      key testkey {
-        algorithm	hmac-md5;
-        secret		"R3HI8P6BKw9ZwXwN3VZKuQ==";
-      };
-    
-

-

-

- In the above example, rndc will by - default use - the server at localhost (127.0.0.1) and the key called samplekey. - Commands to the localhost server will use the samplekey key, which - must also be defined in the server's configuration file with the - same name and secret. The key statement indicates that samplekey - uses the HMAC-MD5 algorithm and its secret clause contains the - base-64 encoding of the HMAC-MD5 secret enclosed in double quotes. -

-

- If rndc -s testserver is used then rndc will - connect to server on localhost port 5353 using the key testkey. -

-

- To generate a random secret with rndc-confgen: -

-

rndc-confgen -

-

- A complete rndc.conf file, including - the - randomly generated key, will be written to the standard - output. Commented-out key and - controls statements for - named.conf are also printed. -

-

- To generate a base-64 secret with mmencode: -

-

echo "known plaintext for a secret" | mmencode -

-
-
-

NAME SERVER CONFIGURATION

-

- The name server must be configured to accept rndc connections and - to recognize the key specified in the rndc.conf - file, using the controls statement in named.conf. - See the sections on the controls statement in the - BIND 9 Administrator Reference Manual for details. -

-
-
-

SEE ALSO

-

rndc(8), - rndc-confgen(8), - mmencode(1), - BIND 9 Administrator Reference Manual. -

-
-
-

AUTHOR

-

Internet Systems Consortium -

-
-
- - - diff --git a/contrib/bind9/doc/arm/man.rndc.html b/contrib/bind9/doc/arm/man.rndc.html deleted file mode 100644 index 96ed547..0000000 --- a/contrib/bind9/doc/arm/man.rndc.html +++ /dev/null @@ -1,202 +0,0 @@ - - - - - -rndc - - - - - - - - -
-
-
-

Name

-

rndc — name server control utility

-
-
-

Synopsis

-

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

-
-
-

DESCRIPTION

-

rndc - controls the operation of a name - server. It supersedes the ndc utility - that was provided in old BIND releases. If - rndc is invoked with no command line - options or arguments, it prints a short summary of the - supported commands and the available options and their - arguments. -

-

rndc - communicates with the name server - over a TCP connection, sending commands authenticated with - digital signatures. In the current versions of - rndc and named, - the only supported authentication algorithm is HMAC-MD5, - which uses a shared secret on each end of the connection. - This provides TSIG-style authentication for the command - request and the name server's response. All commands sent - over the channel must be signed by a key_id known to the - server. -

-

rndc - reads a configuration file to - determine how to contact the name server and decide what - algorithm and key it should use. -

-
-
-

OPTIONS

-
-
-b source-address
-

- Use source-address - as the source address for the connection to the server. - Multiple instances are permitted to allow setting of both - the IPv4 and IPv6 source addresses. -

-
-c config-file
-

- Use config-file - as the configuration file instead of the default, - /etc/rndc.conf. -

-
-k key-file
-

- Use key-file - as the key file instead of the default, - /etc/rndc.key. The key in - /etc/rndc.key will be used to - authenticate - commands sent to the server if the config-file - does not exist. -

-
-s server
-

server is - the name or address of the server which matches a - server statement in the configuration file for - rndc. If no server is supplied on the - command line, the host named by the default-server clause - in the options statement of the rndc - configuration file will be used. -

-
-p port
-

- Send commands to TCP port - port - instead - of BIND 9's default control channel port, 953. -

-
-V
-

- Enable verbose logging. -

-
-y key_id
-

- Use the key key_id - from the configuration file. - key_id - must be - known by named with the same algorithm and secret string - in order for control message validation to succeed. - If no key_id - is specified, rndc will first look - for a key clause in the server statement of the server - being used, or if no server statement is present for that - host, then the default-key clause of the options statement. - Note that the configuration file contains shared secrets - which are used to send authenticated control commands - to name servers. It should therefore not have general read - or write access. -

-
-

- For the complete set of commands supported by rndc, - see the BIND 9 Administrator Reference Manual or run - rndc without arguments to see its help - message. -

-
-
-

LIMITATIONS

-

rndc - does not yet support all the commands of - the BIND 8 ndc utility. -

-

- There is currently no way to provide the shared secret for a - key_id without using the configuration file. -

-

- Several error messages could be clearer. -

-
-
-

SEE ALSO

-

rndc.conf(5), - named(8), - named.conf(5), - ndc(8), - BIND 9 Administrator Reference Manual. -

-
-
-

AUTHOR

-

Internet Systems Consortium -

-
-
- - - diff --git a/contrib/bind9/doc/draft/draft-baba-dnsext-acl-reqts-01.txt b/contrib/bind9/doc/draft/draft-baba-dnsext-acl-reqts-01.txt deleted file mode 100644 index 1030e57..0000000 --- a/contrib/bind9/doc/draft/draft-baba-dnsext-acl-reqts-01.txt +++ /dev/null @@ -1,336 +0,0 @@ - - - - -Internet-Draft T. Baba -Expires: March 11, 2004 NTT Data - September 11, 2003 - - - Requirements for Access Control in Domain Name Systems - draft-baba-dnsext-acl-reqts-01.txt - -Status of this Memo - - This document is an Internet-Draft and is subject to all provisions - of Section 10 of RFC2026. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/1id-abstracts.html - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html - - Distribution of this memo is unlimited. - - This Internet-Draft will expire on March 11, 2004. - -Abstract - - This document describes the requirements for access control - mechanisms in the Domain Name System (DNS), which authenticate - clients and then allow or deny access to resource records in the - zone according to the access control list (ACL). - -1. Introduction - - The Domain Name System (DNS) is a hierarchical, distributed, highly - available database used for bi-directional mapping between domain - names and IP addresses, for email routing, and for other information - [RFC1034, 1035]. DNS security extensions (DNSSEC) have been defined - to authenticate the data in DNS and provide key distribution services - using SIG, KEY, and NXT resource records (RRs) [RFC2535]. - - - -Baba Expires March 11, 2004 [Page 1] - -Internet-Draft DNS Access Control Requirements September 2003 - - - At the 28th IETF Meeting in Houston in 1993, DNS security design team - started a discussion about DNSSEC and agreed to accept the assumption - that "DNS data is public". Accordingly, confidentiality for queries - or responses is not provided by DNSSEC, nor are any sort of access - control lists or other means to differentiate inquirers. However, - about ten years has passed, access control in DNS has been more - important than before. Currently, new RRs are proposed to add new - functionality to DNS such as ENUM [RFC2916]. Such new RRs may - contain private information. Thus, DNS access control will be - needed. - - Furthermore, with DNS access control mechanism, access from - unauthorized clients can be blocked when they perform DNS name - resolution. Thus, for example, Denial of Service (DoS) attacks - against a server used by a closed user group can be prevented using - this mechanism if IP address of the server is not revealed by other - sources. - - This document describes the requirements for access control - mechanisms in DNS. - -2. Terminology - - AC-aware client - This is the client that understands the DNS access control - extensions. This client may be an end host which has a stub - resolver, or a cashing/recursive name server which has a - full-service resolver. - - AC-aware server - This is the authoritative name server that understands the DNS - access control extensions. - - ACE - An Access Control Entry. This is the smallest unit of access - control policy. It grants or denies a given set of access - rights to a set of principals. An ACE is a component of an ACL, - which is associated with a resource. - - ACL - An Access Control List. This contains all of the access control - policies which are directly associated with a particular - resource. These policies are expressed as ACEs. - - Client - A program or host which issues DNS requests and accepts its - responses. A client may be an end host or a cashing/recursive name - server. - - - -Baba Expires March 11, 2004 [Page 2] - -Internet-Draft DNS Access Control Requirements September 2003 - - - RRset - All resource records (RRs) having the same NAME, CLASS and TYPE - are called a Resource Record Set (RRset). - -3. Requirements - - This section describes the requirements for access control in DNS. - -3.1 Authentication - -3.1.1 Client Authentication Mechanism - - The AC-aware server must identify AC-aware clients based on IP - address and/or domain name (user ID or host name), and must - authenticate them using strong authentication mechanism such as - digital signature or message authentication code (MAC). - - SIG(0) RR [RFC2931] contains a domain name associated with sender's - public key in its signer's name field, and TSIG RR [RFC2845] also - contains a domain name associated with shared secret key in its key - name field. Each of these domain names can be a host name or a user - name, and can be used as a sender's identifier for access control. - Furthermore, SIG(0) uses digital signatures, and TSIG uses MACs for - message authentication. These mechanisms can be used to authenticate - AC-aware clients. - - Server authentication may be also provided. - -3.1.2 End-to-End Authentication - - In current DNS model, caching/recursive name servers are deployed - between end hosts and authoritative name servers. Although - authoritative servers can authenticate caching/recursive name servers - using SIG(0) or TSIG, they cannot authenticate end hosts behind them. - For end-to-end authentication, the mechanism for an end host to - discover the target authoritative name server and directly access to - it bypassing caching/recursive name servers is needed. For example, - an end host can get the IP addresses of the authoritative name - servers by retrieving NS RRs for the zone via local caching/recursive - name server. - - In many enterprise networks, however, there are firewalls that block - all DNS packets other than those going to/from the particular - caching/recursive servers. To deal with this problem, one can - implement packet forwarding function on the caching/recursive servers - and enable end-to-end authentication via the caching/recursive - servers. - - - - -Baba Expires March 11, 2004 [Page 3] - -Internet-Draft DNS Access Control Requirements September 2003 - - -3.1.3 Authentication Key Retrieval - - Keys which are used to authenticate clients should be able to be - automatically retrieved. The KEY RR is used to store a public key - for a zone or a host that is associated with a domain name. SIG(0) - RR uses a public key in KEY RR for verifying the signature. If - DNSSEC is available, the KEY RR would be protected by the SIG RR. - KEY RR or newly defined RR can be used to automatic key retrieval. - -3.2 Confidentiality - -3.2.1 Data Encryption - - To avoid disclosure to eavesdroppers, the response containing the - RRsets which are restricted to access from particular users should be - encrypted. Currently, no encryption mechanism is specified in DNS. - Therefore, new RRs should be defined for DNS message encryption. - Instead, IPsec [RFC2401] can be used to provide confidentiality if - name server and resolver can set up security associations dynamically - using IPsec API [IPSECAPI] when encryption is required. - - In case encryption is applied, entire DNS message including DNS - header should be encrypted to hide information including error code. - - Query encryption may be also provided for hiding query information. - -3.2.2 Key Exchange - - If DNS message encryption is provided, automatic key exchange - mechanism should be also provided. [RFC2930] specifies a TKEY RR - that can be used to establish and delete shared secret keys used by - TSIG between a client and a server. With minor extensions, TKEY can - be used to establish shared secret keys used for message encryption. - -3.2.3 Caching - - The RRset that is restricted to access from particular users must not - be cached. To avoid caching, the TTL of the RR that is restricted to - access should be set to zero during transit. - -3.3 Access Control - -3.3.1 Granularity of Access Control - - Control of access on a per-user/per-host granularity must be - supported. Control of access to individual RRset (not just the - entire zone) must be also supported. However, SOA, NS, SIG, NXT, - KEY, and DS RRs must be publicly accessible to avoid unexpected - results. - - -Baba Expires March 11, 2004 [Page 4] - -Internet-Draft DNS Access Control Requirements September 2003 - - -3.3.2 ACL Representation - - Access Control List (ACL) format must be standardized so that both - the primary and secondary AC-aware servers can recognize the same - ACL. Although ACL may appear in or out of zone data, it must be - transferred to the secondary AC-aware server with associated zone - data. It is a good idea to contain ACL in zone data, because ACL can - be transferred with zone data using existing zone transfer mechanisms - automatically. However, ACL must not be published except for - authorized secondary master servers. - - In zone data master files, ACL should be specified using TXT RRs or - newly defined RRs. In each access control entry (ACE), authorized - entities (host or user) must be described using domain name (host - name, user name, or IP address in in-addr.arpa/ip6.arpa format). - There may be other access control attributes such as access time. - - It must be possible to create publicly readable entries, which may be - read even by unauthenticated clients. - -3.3.3 Zone/ACL Transfer - - As mentioned above, ACL should be transferred from a primary AC-aware - server to a secondary AC-aware server with associated zone data. - When an AC-aware server receives a zone/ACL transfer request, the - server must authenticate the client, and should encrypt the zone - data and associated ACL during transfer. - -3.4 Backward/co-existence Compatibility - - Any new protocols to be defined for access control in DNS must be - backward compatible with existing DNS protocol. AC-aware servers - must be able to process normal DNS query without authentication, and - must respond if retrieving RRset is publicly accessible. - - Modifications to root/gTLD/ccTLD name servers are not allowed. - -4. Security Considerations - - This document discusses the requirements for access control - mechanisms in DNS. - -5. Acknowledgements - - This work is funded by the Telecommunications Advancement - Organization of Japan (TAO). - - The author would like to thank the members of the NTT DATA network - security team for their important contribution to this work. - - -Baba Expires March 11, 2004 [Page 5] - -Internet-Draft DNS Access Control Requirements September 2003 - - -6. References - - [RFC1034] Mockapetris, P., "Domain names - concepts and facilities", - STD 13, RFC 1034, November 1987. - - [RFC1035] Mockapetris, P., "Domain names - implementation and - specification", STD 13, RFC 1035, November 1987. - - [RFC2401] Kent, S. and R. Atkinson, "Security Architecture for the - Internet Protocol", RFC 2401, November 1998. - - [RFC2535] Eastlake, D., "Domain Name System Security Extensions", - RFC 2535, March 1999. - - [RFC2845] Vixie, P., Gudmundsson, O., Eastlake, D. and B. Wellington, - "Secret Key Transaction Authentication for DNS (TSIG)", - RFC 2845, May 2000. - - [RFC2916] Faltstrom, P., "E.164 number and DNS", RFC 2916, - September 2000. - - [RFC2930] Eastlake, D., "Secret Key Establishment for DNS (TKEY RR)", - RFC 2930, September 2000. - - [RFC2931] Eastlake, D., "DNS Request and Transaction Signatures - (SIG(0)s)", RFC 2931, September 2000. - - [IPSECAPI] Sommerfeld, W., "Requirements for an IPsec API", - draft-ietf-ipsp-ipsec-apireq-00.txt, June 2003, Work in - Progress. - - -Author's Address - - Tatsuya Baba - NTT Data Corporation - Research and Development Headquarters - Kayabacho Tower, 1-21-2, Shinkawa, Chuo-ku, - Tokyo 104-0033, Japan - - Tel: +81 3 3523 8081 - Fax: +81 3 3523 8090 - Email: babatt@nttdata.co.jp - - - - - - - - -Baba Expires March 11, 2004 [Page 6] diff --git a/contrib/bind9/doc/draft/draft-daigle-napstr-04.txt b/contrib/bind9/doc/draft/draft-daigle-napstr-04.txt deleted file mode 100644 index fffa8a5..0000000 --- a/contrib/bind9/doc/draft/draft-daigle-napstr-04.txt +++ /dev/null @@ -1,1232 +0,0 @@ - - -Network Working Group L. Daigle -Internet-Draft A. Newton -Expires: August 15, 2004 VeriSign, Inc. - February 15, 2004 - - - Domain-based Application Service Location Using SRV RRs and the - Dynamic Delegation Discovery Service (DDDS) - draft-daigle-napstr-04.txt - -Status of this Memo - - This document is an Internet-Draft and is in full conformance with - all provisions of Section 10 of RFC2026. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on August 15, 2004. - -Copyright Notice - - Copyright (C) The Internet Society (2004). All Rights Reserved. - -Abstract - - This memo defines a generalized mechanism for application service - naming that allows service location without relying on rigid domain - naming conventions (so-called name hacks). The proposal defines a - Dynamic Delegation Discovery System (DDDS) Application to map domain - name, application service name, and application protocol to target - server and port, dynamically. - - - - - - - -Daigle & Newton Expires August 15, 2004 [Page 1] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 - 2. Straightforward-NAPTR (S-NAPTR) Specification . . . . . . . 4 - 2.1 Key Terms . . . . . . . . . . . . . . . . . . . . . . . . . 4 - 2.2 S-NAPTR DDDS Application Usage . . . . . . . . . . . . . . . 5 - 2.2.1 Ordering and Preference . . . . . . . . . . . . . . . . . . 5 - 2.2.2 Matching and non-Matching NAPTR Records . . . . . . . . . . 5 - 2.2.3 Terminal and Non-Terminal NAPTR Records . . . . . . . . . . 5 - 2.2.4 S-NAPTR and Successive Resolution . . . . . . . . . . . . . 6 - 2.2.5 Clients Supporting Multiple Protocols . . . . . . . . . . . 6 - 3. Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . 7 - 3.1 Guidelines for Application Protocol Developers . . . . . . . 7 - 3.1.1 Registration of application service and protocol tags . . . 7 - 3.1.2 Definition of conditions for retry/failure . . . . . . . . . 8 - 3.1.3 Server identification and handshake . . . . . . . . . . . . 8 - 3.2 Guidelines for Domain Administrators . . . . . . . . . . . . 8 - 3.3 Guidelines for Client Software Writers . . . . . . . . . . . 9 - 4. Illustrations . . . . . . . . . . . . . . . . . . . . . . . 9 - 4.1 Use Cases . . . . . . . . . . . . . . . . . . . . . . . . . 9 - 4.2 Service Discovery within a Domain . . . . . . . . . . . . . 10 - 4.3 Multiple Protocols . . . . . . . . . . . . . . . . . . . . . 10 - 4.4 Remote Hosting . . . . . . . . . . . . . . . . . . . . . . . 11 - 4.5 Sets of NAPTR RRs . . . . . . . . . . . . . . . . . . . . . 12 - 4.6 Sample sequence diagram . . . . . . . . . . . . . . . . . . 12 - 5. Motivation and Discussion . . . . . . . . . . . . . . . . . 14 - 5.1 So, why not just SRV records? . . . . . . . . . . . . . . . 15 - 5.2 So, why not just NAPTR records? . . . . . . . . . . . . . . 15 - 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . 16 - 7. Security Considerations . . . . . . . . . . . . . . . . . . 16 - 8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 17 - References . . . . . . . . . . . . . . . . . . . . . . . . . 17 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 18 - A. Application Service Location Application of DDDS . . . . . . 18 - A.1 Application Unique String . . . . . . . . . . . . . . . . . 18 - A.2 First Well Known Rule . . . . . . . . . . . . . . . . . . . 18 - A.3 Expected Output . . . . . . . . . . . . . . . . . . . . . . 18 - A.4 Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 - A.5 Service Parameters . . . . . . . . . . . . . . . . . . . . . 19 - A.5.1 Application Services . . . . . . . . . . . . . . . . . . . . 19 - A.5.2 Application Protocols . . . . . . . . . . . . . . . . . . . 20 - A.6 Valid Rules . . . . . . . . . . . . . . . . . . . . . . . . 20 - A.7 Valid Databases . . . . . . . . . . . . . . . . . . . . . . 20 - B. Pseudo pseudocode for S-NAPTR . . . . . . . . . . . . . . . 20 - B.1 Finding the first (best) target . . . . . . . . . . . . . . 20 - B.2 Finding subsequent targets . . . . . . . . . . . . . . . . . 21 - Full Copyright Statement . . . . . . . . . . . . . . . . . . 23 - - - - -Daigle & Newton Expires August 15, 2004 [Page 2] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - -1. Introduction - - This memo defines a generalized mechanism for application service - naming that allows service location without relying on rigid domain - naming conventions (so-called name hacks). The proposal defines a - Dynamic Delegation Discovery System (DDDS -- see [6]) Application to - map domain name, application service name, and application protocol - to target server and port, dynamically. - - As discussed in Section 5, existing approaches to using DNS records - to dynamically determining the current host for a given application - service are limited in terms of the use cases supported. To address - some of the limitations, this document defines a DDDS Application to - map service+protocol+domain to specific server addresses using both - NAPTR [7] and SRV ([5]) DNS resource records. This can be viewed as - a more general version of the use of SRV and/or a very restricted - application of the use of NAPTR resource records. - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in RFC2119 ([2]). - -2. Straightforward-NAPTR (S-NAPTR) Specification - - The precise details of the specification of this DDDS application are - given in Appendix A. This section defines the usage of the DDDS - application. - -2.1 Key Terms - - An "application service" is a generic term for some type of - application, indpendent of the protocol that may be used to offer it. - Each application service will be associated with an IANA-registered - tag. For example, instant messaging is a type of application - service, which can be implemented by many different application-layer - protocols, and the tag "IM" (used as an illustration here) could be - registered for it. - - An "application protocol" is used to implement the application - service. These are also associated with IANA-registered tags. In - the case where multiple transports are available for the application, - separate tags should be defined for each transport. - - The intention is that the combination of application service and - protocol tags should be specific enough that finding a known pair - (e.g., "IM:ProtC") is sufficient for a client to identify a server - with which it can communicate. - - - - -Daigle & Newton Expires August 15, 2004 [Page 3] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - - Some protocols support multiple application services. For example, - LDAP is an application protocol, and can be found supporting various - services (e.g., "whitepages", "directory enabled networking", etc). - -2.2 S-NAPTR DDDS Application Usage - - As outlined in Appendix A, NAPTR records are used to store - application service+protocol information for a given domain. - Following the DDDS standard, these records are looked up, and the - rewrite rules (contained in the NAPTR records) are used to determine - the successive DNS lookups, until a desirable target is found. - - For the rest of this section, refer to the set of NAPTR resource - records for example.com shown in the figure below. - - example.com. - ;; order pref flags service regexp replacement - IN NAPTR 100 10 "" "WP:whois++" "" bunyip.example. - IN NAPTR 100 20 "s" "WP:ldap" "" _ldap._tcp.myldap.example.com. - IN NAPTR 200 10 "" "IM:protA" "" someisp.example. - IN NAPTR 200 30 "a" "IM:protB" "" myprotB.example.com. - - -2.2.1 Ordering and Preference - - A client retrieves all of the NAPTR records associated with the - target domain name (example.com, above). These are to be sorted in - terms of increasing ORDER, and increasing PREF within each ORDER. - -2.2.2 Matching and non-Matching NAPTR Records - - Starting with the first sorted NAPTR record, the client examines the - SERVICE field to find a match. In the case of the S-NAPTR DDDS - application, that means a SERVICE field that includes the tags for - the desired application service and a supported application protocol. - - If more than one NAPTR record matches, they are processed in - increasing sort order. - -2.2.3 Terminal and Non-Terminal NAPTR Records - - A NAPTR record with an empty FLAG field is "non-terminal". That is, - more NAPTR RR lookups are to be performed. Thus, to process a NAPTR - record with an empty FLAG field in S-NAPTR, the REPLACEMENT field is - used as the target of the next DNS lookup -- for NAPTR RRs. - - In S-NAPTR, the only terminal flags are "S" and "A". These are - called "terminal" NAPTR lookups because they denote the end of the - - - -Daigle & Newton Expires August 15, 2004 [Page 4] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - - DDDS/NAPTR processing rules. In the case of an "S" flag, the - REPLACEMENT field is used as the target of a DNS query for SRV RRs, - and normal SRV processing is applied. In the case of an "A" flag, an - address record is sought for the REPLACEMENT field target (and the - default protocol port is assumed). - -2.2.4 S-NAPTR and Successive Resolution - - As shown in the example NAPTR RR set above, it is possible to have - multiple possible targets for a single application service+protocol - pair. These are to be pursued in order until a server is - successfully contacted or all possible matching NAPTR records have - been successively pursued to terminal lookups and servers contacted. - That is, a client must backtrack and attempt other resolution paths - in the case of failure. - - "Failure" is declared, and backtracking must be used when - - o the designated remote server (host and port) fail to provide - appropriate security credentials for the *originating* domain - - o connection to the designated remote server otherwise fails -- the - specifics terms of which are defined when an application protocol - is registered - - o the S-NAPTR-designated DNS lookup fails to yield expected results - -- e.g., no A RR for an "A" target, no SRV record for an "S" - target, or no NAPTR record with appropriate application service - and protocol for a NAPTR lookup. Except in the case of the very - first NAPTR lookup, this last is a configuration error: the fact - that example.com has a NAPTR record pointing to "bunyip.example" - for the "WP:Whois++" service and protocol means the administrator - of example.com believes that service exists. If bunyip.example - has no "WP:Whois++" NAPTR record, the application client MUST - backtrack and try the next available "WP:Whois++" option from - example.com. As there is none, the whole resolution fails. - - An application client first queries for the NAPTR RRs for the domain - of a named application service. The application client MUST select - one protocol to choose The PREF field of the NAPTR RRs may be used by - the domain administrator to The first DNS query is for the NAPTR RRs - in the original target domain (example.com, above). - -2.2.5 Clients Supporting Multiple Protocols - - In the case of an application client that supports more than one - protocol for a given application service, it MUST pursue S-NAPTR - resolution completely for one protocol before trying another.j It MAY - - - -Daigle & Newton Expires August 15, 2004 [Page 5] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - - choose which protocol to try first based on its own preference, or - from the PREF ranking in the first set of NAPTR records (i.e., those - for the target named domain). However, the chosen protocol MUST be - listed in that first NAPTR RR set. - - That is, what the client MUST NOT do is start looking for one - protocol, observe that a successive NAPTR RR set supports another of - its preferred protocols, and continue the S-NAPTR resolution based on - that protocol. For example, even if someisp.example offers the "IM" - service with protocol "ProtB", there is no reason to believe it does - so on behalf of example.com (since there is no such pointer in - example.com's NAPTR RR set). - -3. Guidelines - -3.1 Guidelines for Application Protocol Developers - - The purpose of S-NAPTR is to provide application standards developers - with a more powerful framework (than SRV RRs alone) for naming - service targets, without requiring each application protocol (or - service) standard to define a separate DDDS application. - - Note that this approach is intended specifically for use when it - makes sense to associate services with particular domain names (e.g., - e-mail addresses, SIP addresses, etc). A non-goal is having all - manner of label mapped into domain names in order to use this. - - Specifically not addressed in this document is how to select the - domain for which the service+protocol is being sought. It is up to - other conventions to define how that might be used (e.g., instant - messaging standards can define what domain to use from IM URIs, how - to step down from foobar.example.com to example.com, and so on, if - that is applicable). - - Although this document proposes a DDDS application that does not use - all the features of NAPTR resource records, it does not mean to imply - that DNS resolvers should fail to implement all aspects of the NAPTR - RR standard. A DDDS application is a client use convention. - - The rest of this section outlines the specific elements that protocol - developers must determine and document in order to make use of S- - NAPTR. - -3.1.1 Registration of application service and protocol tags - - Application protocol developers that wish to make use of S-NAPTR must - make provision to register any relevant application service and - application protocol tags, as described in Section 6. - - - -Daigle & Newton Expires August 15, 2004 [Page 6] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - -3.1.2 Definition of conditions for retry/failure - - One other important aspect that must be defined is the expected - behaviour for interacting with the servers that are reached via S- - NAPTR. Specifically, under what circumstances should the client - retry a target that was found via S-NAPTR? What should it consider a - failure that causes it to return to the S-NAPTR process to determine - the next serviceable target (a less preferred target)? - - For example, if the client gets a "connection refused" from a server, - should it retry for some (protocol-dependent) period of time? Or, - should it try the next-preferred target in the S-NAPTR chain of - resolution? Should it only try the next-preferred target if it - receives a protocol-specific permanent error message? - - The most important thing is to select one expected behaviour and - document it as part of the use of S-NAPTR. - - As noted earlier, failure to provide appropriate credentials to - identify the server as being authoritative for the original taret - domain is always considered a failure condition. - -3.1.3 Server identification and handshake - - As noted in Section 7, use of the DNS for server location increases - the importance of using protocol-specific handshakes to determine and - confirm the identity of the server that is eventually reached. - - Therefore, application protocol developers using S-NAPTR should - identify the mechanics of the expected identification handshake when - the client connects to a server found through S-NAPTR. - -3.2 Guidelines for Domain Administrators - - Although S-NAPTR aims to provide a "straightforward" application of - DDDS and use of NAPTR records, it is still possible to create very - complex chains and dependencies with the NAPTR and SRV records. - - Therefore, domain administrators are called upon to use S-NAPTR with - as much restraint as possible, while still achieving their service - design goals. - - The complete set of NAPTR, SRV and A RRs that are "reachable" through - the S-NAPTR process for a particular application service can be - thought of as a "tree". Each NAPTR RR retrieved points to more NAPTR - or SRV records; each SRV record points to several A record lookups. - Even though a particular client can "prune" the tree to use only - those records referring to application protocols supported by the - - - -Daigle & Newton Expires August 15, 2004 [Page 7] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - - client, the tree could be quite deep, and retracing the tree to retry - other targets can become expensive if the tree has many branches. - - Therefore, - - o Fewer branches is better: for both NAPTR and SRV records, provide - different targets with varying preferences where appropriate - (e.g., to provide backup services, etc), but don't look for - reasons to provide more. - - o Shallower is better: avoid using NAPTR records to "rename" - services within a zone. Use NAPTR records to identify services - hosted elsewhere (i.e., where you cannot reasonably provide the - SRV records in your own zone). - - -3.3 Guidelines for Client Software Writers - - To properly understand DDDS/NAPTR, an implementor must read [6]. - However, the most important aspect to keep in mind is that, if one - target fails to work for the application, it is expected that the - application will continue through the S-NAPTR tree to try the (less - preferred) alternatives. - -4. Illustrations - -4.1 Use Cases - - The basic intended use cases for which S-NAPTR has been developed - are: - - o Service discovery within a domain. For example, this can be used - to find the "authoritative" server for some type of service within - a domain (see the specific example in Section 4.2). - - o Multiple protocols. This is increasingly common as new - application services are defined. This includes the case of - instant messaging (a service) which can be offered with multiple - protocols (see Section 4.3). - - o Remote hosting. Each of the above use cases applies within the - administration of a single domain. However, one domain operator - may elect to engage another organization to provide an application - service. See Section 4.4 for an example that cannot be served by - SRV records alone. - - - - - - -Daigle & Newton Expires August 15, 2004 [Page 8] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - -4.2 Service Discovery within a Domain - - There are occasions when it is useful to be able to determine the - "authoritative" server for a given application service within a - domain. This is "discovery", because there is no a priori knowledge - as to whether or where the service is offered; it is therefore - important to determine the location and characteristics of the - offered service. - - For example, there is growing discussion of having a generic - mechanism for locating the keys or certificates associated with - particular application (servers) operated in (or for) a particular - domain. Here's a hypothetical case for storing application key or - certificate data for a given domain. The premise is that some - credentials registry (CredReg) service has been defined to be a leaf - node service holding the keys/certs for the servers operated by (or - for) the domain. Furthermore, it is assumed that more than one - protocol is available to provide the service for a particular domain. - This DDDS-based approach is used to find the CredReg server that - holds the information. - - Thus, the set of NAPTR records for thinkingcat.example might look - like this: - - thinkingcat.example. - ;; order pref flags service regexp replacement - IN NAPTR 100 10 "" "CREDREG:ldap:iris-beep" "" theserver.thinkingcat.example. - - Note that another domain, offering the same application service, - might offer it using a different set of application protocols: - - anotherdomain.example. - ;; order pref flags service regexp replacement - IN NAPTR 100 10 "" "CREDREG:iris-lw:iris-beep" "" foo.anotherdomain.example. - - -4.3 Multiple Protocols - - As it stands, there are several different protocols proposed for - offering "instant message" services. Assuming that "IM" was - registered as an application service, this DDDS application could be - used to determine the available services for delivering to a target. - - Two particular features of instant messaging should be noted: - - 1. gatewaying is expected to bridge communications across protocols - - 2. instant messaging servers are likely to be operated out of a - - - -Daigle & Newton Expires August 15, 2004 [Page 9] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - - different domain than the instant messaging address, and servers - of different protocols may be offered by independent - organizations - - For example, "thinkingcat.example" may support its own servers for - the "ProtA" instant messaging protocol, but rely on outsourcing from - "example.com" for "ProtC" and "ProtB" servers. - - Using this DDDS-based approach, thinkingcat.example can indicate a - preference ranking for the different types of servers for the instant - messaging service, and yet the out-sourcer can independently rank the - preference and ordering of servers. This independence is not - achievable through the use of SRV records alone. - - Thus, to find the IM services for thinkingcat.example, the NAPTR - records for thinkingcat.example are retrieved: - - thinkingcat.example. - ;; order pref flags service regexp replacement - IN NAPTR 100 10 "s" "IM:ProtA" "" _ProtA._tcp.thinkingcat.example. - IN NAPTR 100 20 "s" "IM:ProtB" "" _ProtB._tcp.example.com. - IN NAPTR 100 30 "s" "IM:ProtC" "" _ProtC._tcp.example.com. - - and then the administrators at example.com can manage the preference - rankings of the servers they use to support the ProtB service: - - _ProtB._tcp.example.com. - ;; Pref Weight Port Target - IN SRV 10 0 10001 bigiron.example.com - IN SRV 20 0 10001 backup.im.example.com - IN SRV 30 0 10001 nuclearfallout.australia-isp.example - - -4.4 Remote Hosting - - In the Instant Message hosting example in Section 4.3, the service - owner (thinkingcat.example) had to host pointers to the hosting - service's SRV records in the thinkingcat.example domain. - - A better way to approach this is to have one NAPTR RR in the - thinkingcat.example domain pointing to all the hosted services, and - the hosting domain has NAPTR records for each service to map them to - whatever local hosts it chooses (and may change from time to time). - - - - - - - - -Daigle & Newton Expires August 15, 2004 [Page 10] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - - thinkingcat.example. - ;; order pref flags service regexp replacement - IN NAPTR 100 10 "s" "IM:ProtA" "" _ProtA._tcp.thinkingcat.example. - IN NAPTR 100 20 "" "IM:ProtB:ProtC" "" thinkingcat.example.com. - - - and then the administrators at example.com can break out the - individual application protocols and manage the preference rankings - of the servers they use to support the ProtB service (as before): - - thinkingcat.example.com. - ;; order pref flags service regexp replacement - IN NAPTR 100 10 "s" "IM:ProtC" "" _ProtC._tcp.example.com. - IN NAPTR 100 20 "s" "IM:ProtB" "" _ProtB._tcp.example.com. - - - - _ProtC._tcp.example.com. - ;; Pref Weight Port Target - IN SRV 10 0 10001 bigiron.example.com - IN SRV 20 0 10001 backup.im.example.com - IN SRV 30 0 10001 nuclearfallout.australia-isp.example - - -4.5 Sets of NAPTR RRs - - Note that the above sections assumed that there was one service - available (via S-NAPTR) per domain. Often, that will not be the - case. Assuming thinkingcat.example had the CredReg service set up as - described in Section 4.2 and the instant messaging service set up as - described in Section 4.4, then a client querying for the NAPTR RR set - from thinkingcat.com would get the following answer: - - thinkingcat.example. - ;; order pref flags service regexp replacement - IN NAPTR 100 10 "s" "IM:ProtA" "" _ProtA._tcp.thinkingcat.example. - IN NAPTR 100 20 "" "IM:ProtB:ProtC:" "" thinkingcat.example.com. - IN NAPTR 200 10 "" "CREDREG:ldap:iris-beep" "" bouncer.thinkingcat.example. - - Sorting them by increasing "ORDER", the client would look through the - SERVICE strings to determine if there was a NAPTR RR that matched the - application service it was looking for, with an application protocol - it could use. The first (lowest PREF) record that so matched is the - one the client would use to continue. - -4.6 Sample sequence diagram - - Consider the example in Section 4.3. Visually, the sequence of steps - - - -Daigle & Newton Expires August 15, 2004 [Page 11] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - - required for the client to reach the final server for a "ProtB" - service for IM for the thinkingcat.example domain is as follows: - - - Client NS for NS for - thinkingcat.example example.com backup.im.example.com - | | | - 1 -------->| | | - 2 <--------| | | - 3 ------------------------------>| | - 4 <------------------------------| | - 5 ------------------------------>| | - 6 <------------------------------| | - 7 ------------------------------>| | - 8 <------------------------------| | - 9 ------------------------------------------------->| - 10 <-------------------------------------------------| - 11 ------------------------------------------------->| - 12 <-------------------------------------------------| - (...) - - - - 1. the name server (NS) for thinkingcat.example is reached with a - request for all NAPTR records - - 2. the server responds with the NAPTR records shown in Section 4.3. - - 3. the second NAPTR record matches the desired criteria; that has an - "s" flag and a replacement fields of "_ProtB._tcp.example.com". - So, the client looks up SRV records for that target, ultimately - making the request of the NS for example.com. - - 4. the response includes the SRV records listed in Section 4.3. - - 5. the client attempts to reach the server with the lowest PREF in - the SRV list -- looking up the A record for the SRV record's - target (bigiron.example.com). - - 6. the example.com NS responds with an error message -- no such - machine! - - 7. the client attempts to reach the second server in the SRV list, - and looks up the A record for backup.im.example.com - - 8. the client gets the A record with the IP address for - backup.im.example.com from example.com's NS. - - - - -Daigle & Newton Expires August 15, 2004 [Page 12] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - - 9. the client connects to that IP address, on port 10001 (from the - SRV record), using ProtB over tcp. - - 10. the server responds with an "OK" message. - - 11. the client uses ProtB to challenge that this server has - credentials to operate the service for the original domain - (thinkingcat.example) - - 12. the server responds, and the rest is IM. - - -5. Motivation and Discussion - - Increasingly, application protocol standards are using domain names - to identify server targets, and stipulating that clients should look - up SRV resource records to determine the host and port providing the - server. This enables a distinction between naming an application - service target and actually hosting the server. It also increases - flexibility in hosting the target service: - - o the server may be operated by a completely different organization - without having to list the details of that organization's DNS - setup (SRVs) - - o multiple instances can be set up (e.g., for load balancing or - secondaries) - - o it can be moved from time to time without disrupting clients' - access, etc. - - This is quite useful, but Section 5.1 outlines some of the - limitations inherent in the approach. - - That is, while SRV records can be used to map from a specific service - name and protocol for a specific domain to a specific server, SRV - records are limited to one layer of indirection, and are focused on - server administration rather than on application naming. And, while - the DDDS specification and use of NAPTR allows multiple levels of - redirection before locating the target server machine with an SRV - record, this proposal requires only a subset of NAPTR strictly bound - to domain names, without making use of the REGEXP field of NAPTR. - These restrictions make the client's resolution process much more - predictable and efficient than with some potential uses of NAPTR - records. This is dubbed "S-NAPTR" -- a "S"traightforward use of - NAPTR records. - - - - - -Daigle & Newton Expires August 15, 2004 [Page 13] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - -5.1 So, why not just SRV records? - - An expected question at this point is: this is so similar in - structure to SRV records, why are we doing this with DDDS/NAPTR? - - Limitations of SRV include: - - o SRV provides a single layer of indirection -- the outcome of an - SRV lookup is a new domain name for which the A RR is to be found. - - o the purpose of SRV is focused on individual server administration, - not application naming: as stated in [5] "The SRV RR allows - administrators to use several servers for a single domain, to move - services from host to host with little fuss, and to designate some - hosts as primary servers for a service and others as backups." - - o target servers by "service" (e.g., "ldap") and "protocol" (e.g., - "tcp") in a given domain. The definition of these terms implies - specific things (e.g., that protocol should be one of UDP or TCP) - without being precise. Restriction to UDP and TCP is insufficient - for the uses described here. - - The basic answer is that SRV records provide mappings from protocol - names to host and port. The use cases described herein require an - additional layer -- from some service label to servers that may in - fact be hosted within different administrative domains. We could - tweak SRV to say that the next lookup could be something other than - an address record, but that is more complex than is necessary for - most applications of SRV. - -5.2 So, why not just NAPTR records? - - That's a trick question. NAPTR records cannot appear in the wild -- - see [6]. They must be part of a DDDS application. - - The purpose here is to define a single, common mechanism (the DDDS - application) to use NAPTR when all that is desired is simple DNS- - based location of services. This should be easy for applications to - use -- some simple IANA registrations and it's done. - - Also, NAPTR has very powerful tools for expressing "rewrite" rules. - That power (==complexity) makes some protocol designers and service - administrators nervous. The concern is that it can translate into - unintelligible, noodle-like rule sets that are difficult to test and - administer. - - This proposed DDDS application specifically uses a subset of NAPTR's - abilities. Only "replacement" expressions are allowed, not "regular - - - -Daigle & Newton Expires August 15, 2004 [Page 14] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - - expressions". - -6. IANA Considerations - - This document calls for 2 IANA registries: one for application - service tags, and one for application protocol tags. - - Application service and protocol tags should be defined in an RFC - (unless the "x-" experimental form is used, in which case they are - unregistered). There are no restrictions placed on the tags other - than that they must conform with the syntax defined below (Appendix - A.5). The IANA registries should list the tags and the RFC that - defines their use. - -7. Security Considerations - - The security of this approach to application service location is only - as good as the security of the DNS servers along the way. If any of - them is compromised, bogus NAPTR and SRV records could be inserted to - redirect clients to unintended destinations. This problem is hardly - unique to S-NAPTR (or NAPTR in general). - - To protect against DNS-vectored attacks, applications should define - some form of end-to-end authentication to ensure that the correct - destination has been reached. Many application protocols such as - HTTPS, BEEP, IMAP, etc... define the necessary handshake mechansims - to accomplish this task. - - The basic mechanism works in the following way: - - 1. During some portion of the protocol handshake, the client sends - to the server the original name of the desired destination (i.e. - no transformations that may have resulted from NAPTR - replacements, SRV targets, or CNAME changes). In certain cases - where the application protocol does not have such a feature but - TLS may be used, it is possible to use the "server_name" TLS - extension. - - 2. The server sends back to the client a credential with the - appropriate name. For X.509 certificates, the name would either - be in the subjectDN or subjectAltName fields. For Kerberos, the - name would be a service principle name. - - 3. Using the matching semantics defined by the application protocol, - the client compares the name in the credential with the name sent - to the server. - - 4. If the names match, there is reasonable assurance that the - - - -Daigle & Newton Expires August 15, 2004 [Page 15] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - - correct end point has been reached. - - It is important to note that this document does not define either the - handshake mechanism, the specific credenential naming fields, nor the - name matching semantics. Definitions of S-NAPTR for particular - application protocols MUST define these. - -8. Acknowledgements - - Many thanks to Dave Blacka, Patrik Faltstrom, Sally Floyd for - discussion and input that has (hopefully!) provoked clarifying - revisions of this document. - -References - - [1] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform Resource - Identifiers (URI): Generic Syntax", RFC 2396, August 1998. - - [2] Bradner, S., "Key words for use in RFCs to Indicate Requirement - Levels", BCP 14, RFC 2119, March 1997. - - [3] Crocker, D. and P. Overell, "Augmented BNF for Syntax - Specifications: ABNF", RFC 2234, November 1997. - - [4] Eastlake, D., "Domain Name System Security Extensions", RFC - 2535, March 1999. - - [5] Gulbrandsen, A., Vixie, P. and L. Esibov, "A DNS RR for - specifying the location of services (DNS SRV)", RFC 2782, - February 2000. - - [6] Mealling, M., "Dynamic Delegation Discovery System (DDDS) Part - One: The Comprehensive DDDS", RFC 3401, October 2002. - - [7] Mealling, M., "Dynamic Delegation Discovery System (DDDS) Part - Three: The Domain Name System (DNS) Database", RFC 3403, October - 2002. - - [8] Mealling, M., "Dynamic Delegation Discovery System (DDDS) Part - Four: The Uniform Resource Identifiers (URI)", RFC 3404, October - 2002. - - - - - - - - - - -Daigle & Newton Expires August 15, 2004 [Page 16] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - -Authors' Addresses - - Leslie Daigle - VeriSign, Inc. - 21355 Ridgetop Circle - Dulles, VA 20166 - US - - EMail: leslie@verisignlabs.com; leslie@thinkingcat.com - - - Andrew Newton - VeriSign, Inc. - 21355 Ridgetop Circle - Dulles, VA 20166 - US - - EMail: anewton@verisignlabs.com - -Appendix A. Application Service Location Application of DDDS - - This section defines the DDDS application, as described in [6]. - -A.1 Application Unique String - - The Application Unique String is domain label for which an - authoritative server for a particular service is sought. - -A.2 First Well Known Rule - - The "First Well Known Rule" is identity -- that is, the output of the - rule is the Application Unique String, the domain label for which the - authoritative server for a particular service is sought. - -A.3 Expected Output - - The expected output of this Application is the information necessary - to connect to authoritative server(s) (host, port, protocol) for an - application service within a given a given domain. - -A.4 Flags - - This DDDS Application uses only 2 of the Flags defined for the - URI/URN Resolution Application ([8]): "S" and "A". No other Flags - are valid. - - Both are for terminal lookups. This means that the Rule is the last - one and that the flag determines what the next stage should be. The - - - -Daigle & Newton Expires August 15, 2004 [Page 17] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - - "S" flag means that the output of this Rule is a domain label for - which one or more SRV [5] records exist. "A" means that the output - of the Rule is a domain name and should be used to lookup address - records for that domain. - - Consistent with the DDDS algorithm, if the Flag string is empty the - next lookup is for another NAPTR record (for the replacement target). - -A.5 Service Parameters - - Service Parameters for this Application take the form of a string of - characters that follow this ABNF ([3]): - - service-parms = [ [app-service] *(":" app-protocol)] - app-service = experimental-service / iana-registered-service - app-protocol = experimental-protocol / iana-registered-protocol - experimental-service = "x-" 1*30ALPHANUMSYM - experimental-protocol = "x-" 1*30ALPHANUMSYM - iana-registered-service = ALPHA *31ALPHANUMSYM - iana-registered-protocol = ALPHA *31ALPHANUM - ALPHA = %x41-5A / %x61-7A ; A-Z / a-z - DIGIT = %x30-39 ; 0-9 - SYM = %x2B / %x2D / %x2E ; "+" / "-" / "." - ALPHANUMSYM = ALPHA / DIGIT / SYM - ; The app-service and app-protocol tags are limited to 32 - ; characters and must start with an alphabetic character. - ; The service-parms are considered case-insensitive. - - Thus, the Service Parameters may consist of an empty string, just an - app-service, or an app-service with one or more app-protocol - specifications separated by the ":" symbol. - - Note that this is similar to, but not the same as the syntax used in - the URI DDDS application ([8]). The DDDS DNS database requires each - DDDS application to define the syntax of allowable service strings. - The syntax here is expanded to allow the characters that are valid in - any URI scheme name (see [1]). Since "+" (the separator used in the - RFC3404 service parameter string) is an allowed character for URI - scheme names, ":" is chosen as the separator here. - -A.5.1 Application Services - - The "app-service" must be a registered service [this will be an IANA - registry; this is not the IANA port registry, because we want to - define services for which there is no single protocol, and we don't - want to use up port space for nothing]. - - - - - -Daigle & Newton Expires August 15, 2004 [Page 18] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - -A.5.2 Application Protocols - - The protocol identifiers that are valid for the "app-protocol" - production are any standard, registered protocols [IANA registry - again -- is this the list of well known/registered ports?]. - -A.6 Valid Rules - - Only substitution Rules are permitted for this application. That is, - no regular expressions are allowed. - -A.7 Valid Databases - - At present only one DDDS Database is specified for this Application. - [7] specifies a DDDS Database that uses the NAPTR DNS resource record - to contain the rewrite rules. The Keys for this database are encoded - as domain-names. - - The First Well Known Rule produces a domain name, and this is the Key - that is used for the first lookup -- the NAPTR records for that - domain are requested. - - DNS servers MAY interpret Flag values and use that information to - include appropriate NAPTR, SRV or A records in the Additional - Information portion of the DNS packet. Clients are encouraged to - check for additional information but are not required to do so. See - the Additional Information Processing section of [7] for more - information on NAPTR records and the Additional Information section - of a DNS response packet. - -Appendix B. Pseudo pseudocode for S-NAPTR - -B.1 Finding the first (best) target - - Assuming the client supports 1 protocol for a particular application - service, the following pseudocode outlines the expected process to - find the first (best) target for the client, using S-NAPTR. - - - target = [initial domain] - naptr-done = false - - while (not naptr-done) - { - NAPTR-RRset = [DNSlookup of NAPTR RRs for target] - [sort NAPTR-RRset by ORDER, and PREF within each ORDER] - rr-done = false - cur-rr = [first NAPTR RR] - - - -Daigle & Newton Expires August 15, 2004 [Page 19] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - - while (not rr-done) - if ([SERVICE field of cur-rr contains desired application - service and application protocol]) - rr-done = true - target= [REPLACEMENT target of NAPTR RR] - else - cur-rr = [next rr in list] - - if (not empty [FLAG in cur-rr]) - naptr-done = true - } - - port = -1 - - if ([FLAG in cur-rr is "S"]) - { - SRV-RRset = [DNSlookup of SRV RRs for target] - [sort SRV-RRset based on PREF] - target = [target of first RR of SRV-RRset] - port = [port in first RR of SRV-RRset] - } - - ; now, whether it was an "S" or an "A" in the NAPTR, we - ; have the target for an A record lookup - - host = [DNSlookup of target] - - return (host, port) - - - -B.2 Finding subsequent targets - - The pseudocode in Appendix B is crafted to find the first, most - preferred, host-port pair for a particular application service an - protocol. If, for any reason, that host-port pair did not work - (connection refused, application-level error), the client is expected - to try the next host-port in the S-NAPTR tree. - - The pseudocode above does not permit retries -- once complete, it - sheds all context of where in the S-NAPTR tree it finished. - Therefore, client software writers could - - o entwine the application-specific protocol with the DNS lookup and - RRset processing described in the pseudocode and continue the S- - NAPTR processing if the application code fails to connect to a - located host-port pair; - - - - -Daigle & Newton Expires August 15, 2004 [Page 20] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - - o use callbacks for the S-NAPTR processing; - - o use an S-NAPTR resolution routine that finds *all* valid servers - for the required application service and protocol from the - originating domain, and provides them in sorted order for the - application to try in order. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Daigle & Newton Expires August 15, 2004 [Page 21] - -Internet-Draft draft-daigle-napstr-04 February 2004 - - -Full Copyright Statement - - Copyright (C) The Internet Society (2004). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - - - - - - - - - - - - - - - -Daigle & Newton Expires August 15, 2004 [Page 22] - diff --git a/contrib/bind9/doc/draft/draft-danisch-dns-rr-smtp-03.txt b/contrib/bind9/doc/draft/draft-danisch-dns-rr-smtp-03.txt deleted file mode 100644 index 4a01d91..0000000 --- a/contrib/bind9/doc/draft/draft-danisch-dns-rr-smtp-03.txt +++ /dev/null @@ -1,1960 +0,0 @@ - - - -INTERNET-DRAFT Hadmut Danisch -Category: Experimental Oct 2003 -Expires: Apr 1, 2004 - - The RMX DNS RR and method for lightweight SMTP sender authorization - draft-danisch-dns-rr-smtp-03.txt - -Status of this Memo - - This document is an Internet-Draft and is subject to all provisions - of Section 10 of RFC2026. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six - months and may be updated, replaced, or obsoleted by other - documents at any time. It is inappropriate to use Internet-Drafts - as reference material or to cite them other than as "work in - progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/1id-abstracts.html - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html - -Abstract - - This memo introduces a new authorization scheme for SMTP e-mail - transport. It is designed to be a simple and robust protection - against e-mail fraud, spam and worms. It is based solely on - organisational security mechanisms and does not require but still - allow use of cryptography. This memo also focuses on security and - privacy problems and requirements in context of spam defense. In - contrast to prior versions of the draft a new RR type is not - required anymore. - - - - - - - - - - - - -Hadmut Danisch Experimental [Page 1] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - Table of Contents - - -1. General Issues . . . . . . . . . . . . . . . . . . . . . . . . . 4 -2. Problem and threat description . . . . . . . . . . . . . . . . . 4 - 2.1. Mail sender forgery . . . . . . . . . . . . . . . . . . . 4 - 2.1.1 Definition of sender forgery . . . . . . . . . . . 4 - 2.1.2 Spam . . . . . . . . . . . . . . . . . . . . . . . 5 - 2.1.3 E-Mail Worms . . . . . . . . . . . . . . . . . . . 5 - 2.1.4 E-Mail spoofing and fraud . . . . . . . . . . . . . 5 - 2.2. Indirect damage caused by forgery . . . . . . . . . . . . 6 - 2.3. Technical problem analysis . . . . . . . . . . . . . . . . 6 - 2.4. Shortcomings of cryptographical approaches . . . . . . . . 7 -3. A DNS based sender address verification . . . . . . . . . . . . 7 - 3.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . 7 - 3.2. Envelope vs. header sender address . . . . . . . . . . . . 9 - 3.3. Domain part vs. full sender address . . . . . . . . . . . 9 -4. Mapping of E-Mail addresses to DNS names . . . . . . . . . . . . 10 - 4.1. Domain part only . . . . . . . . . . . . . . . . . . . . . 10 - 4.2. Full address . . . . . . . . . . . . . . . . . . . . . . . 11 - 4.3. Empty address . . . . . . . . . . . . . . . . . . . . . . 11 -5. Mandatory entry types and their syntax . . . . . . . . . . . . . 11 - 5.1. Overall structure . . . . . . . . . . . . . . . . . . . . 11 - 5.2. Unused . . . . . . . . . . . . . . . . . . . . . . . . . . 12 - 5.3. IPv4 and IPv6 address ranges . . . . . . . . . . . . . . . 12 - 5.4. DNS Hostname . . . . . . . . . . . . . . . . . . . . . . . 13 - 5.4.1 Road warriors and DynDNS entries . . . . . . . . . 13 - 5.5. APL Reference . . . . . . . . . . . . . . . . . . . . . . 14 - 5.6. Domain Member . . . . . . . . . . . . . . . . . . . . . . 14 - 5.7. Full Address Query . . . . . . . . . . . . . . . . . . . . 15 - 5.8. DNS mapped authorization . . . . . . . . . . . . . . . . . 15 - 5.9. RMX reference . . . . . . . . . . . . . . . . . . . . . . 16 -6. Optional and experimental entry types . . . . . . . . . . . . . 16 - 6.1. TLS fingerprint . . . . . . . . . . . . . . . . . . . . . 16 - 6.2. TLS and LDAP . . . . . . . . . . . . . . . . . . . . . . . 16 - 6.3. PGP or S/MIME signature . . . . . . . . . . . . . . . . . 16 - 6.4. Transparent Challenge/Response . . . . . . . . . . . . . . 17 - 6.5. SASL Challenge/Response . . . . . . . . . . . . . . . . . 17 -7. Encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 - 7.1. Alternative encoding as TXT records . . . . . . . . . . . 17 - 7.2. RMX Records . . . . . . . . . . . . . . . . . . . . . . . 17 - 7.2.1 Overall structure . . . . . . . . . . . . . . . . . 18 - 7.2.2 Record encoding . . . . . . . . . . . . . . . . . . 18 - 7.2.3 Encoding of IPv4 and IPv6 address ranges . . . . . 18 - 7.2.4 Encoding of DNS . . . . . . . . . . . . . . . . . . 18 - 7.2.5 Encoding of unused and full query . . . . . . . . . 19 - 7.2.6 Additional Records . . . . . . . . . . . . . . . . 19 -8. Message Headers . . . . . . . . . . . . . . . . . . . . . . . . 19 - - - -Hadmut Danisch Experimental [Page 2] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - -9. SMTP error messages . . . . . . . . . . . . . . . . . . . . . . 20 -10. Message relaying and forwarding . . . . . . . . . . . . . . . . 20 - 10.1. Problem description . . . . . . . . . . . . . . . . . . . 20 - 10.2. Trusted relaying/forwarding . . . . . . . . . . . . . . . 21 - 10.3. Untrusted relaying/forwarding . . . . . . . . . . . . . . 21 -11. Security Considerations . . . . . . . . . . . . . . . . . . . . 22 - 11.1. Draft specific considerations . . . . . . . . . . . . . . 22 - 11.1.1 Authentication strength . . . . . . . . . . . . . 22 - 11.1.2 Where Authentication and Authorization end . . . . 22 - 11.1.3 Vulnerability of DNS . . . . . . . . . . . . . . . 23 - 11.1.4 Sneaking RMX attack? . . . . . . . . . . . . . . 25 - 11.1.5 Open SMTP relays . . . . . . . . . . . . . . . . . 25 - 11.1.6 Unforged Spam . . . . . . . . . . . . . . . . . . 25 - 11.1.7 Reliability of Whois Entries . . . . . . . . . . . 26 - 11.1.8 Hazards for Freedom of Speech . . . . . . . . . . 26 - 11.2. General Considerations about spam defense . . . . . . . . 27 - 11.2.1 Action vs. reaction . . . . . . . . . . . . . . . 27 - 11.2.2 Content based Denial of Service attacks . . . . . 27 -12. Privacy Considerations . . . . . . . . . . . . . . . . . . . . 28 - 12.1. Draft specific considerations . . . . . . . . . . . . . . 28 - 12.1.1 No content leaking . . . . . . . . . . . . . . . . 28 - 12.1.2 Message reception and sender domain . . . . . . . 28 - 12.1.3 Network structure . . . . . . . . . . . . . . . . 29 - 12.1.4 Owner information distribution . . . . . . . . . . 29 - 12.2. General Considerations about spam defense . . . . . . . . 29 - 12.2.1 Content leaking of content filters . . . . . . . . 29 - 12.2.2 Black- and Whitelists . . . . . . . . . . . . . . 30 -13. Deployment Considerations . . . . . . . . . . . . . . . . . . . 30 - 13.1. Compatibility . . . . . . . . . . . . . . . . . . . . . . 30 - 13.1.1 Compatibility with old mail receivers . . . . . . 30 - 13.1.2 Compatibility with old mail senders . . . . . . . 30 - 13.1.3 Compatibility with old DNS clients . . . . . . . . 30 - 13.1.4 Compatibility with old DNS servers . . . . . . . . 30 - 13.2. Enforcement policy . . . . . . . . . . . . . . . . . . . 31 -14. General considerations about fighting spam . . . . . . . . . . 31 - 14.1. The economical problem . . . . . . . . . . . . . . . . . 31 - 14.2. The POP problem . . . . . . . . . . . . . . . . . . . . . 32 - 14.3. The network structure problem . . . . . . . . . . . . . . 33 - 14.4. The mentality problem . . . . . . . . . . . . . . . . . . 33 - 14.5. The identity problem . . . . . . . . . . . . . . . . . . 33 - 14.6. The multi-legislation problem . . . . . . . . . . . . . . 34 -Implementation and further Information . . . . . . . . . . . . . . . 34 -References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 -Draft History . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 -Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . . 35 - - - - - - -Hadmut Danisch Experimental [Page 3] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - -1. General Issues - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in - this document are to be interpreted as described in RFC 2119 [1]. - -2. Problem and threat description - -2.1. Mail sender forgery - - The amount of e-mails with forged sender addresses has dramatically - increased. As a consequence, damages and annoyances caused by such - e-mails increased as well. In the majority of examined e-mails the - domain name of the envelope sender address was forged, and the e- - mail was sent from an IP address which does not belong to a network - used by the actual owner of the domain. - -2.1.1. Definition of sender forgery - - As discussions, comments to prior versions of this draft, and - different approaches to stop forgery showed, different perceptions - of "mail forgery" exist. For example, there are mechanisms to - verify e-mail addresses for mailing lists, web servers, or to stop - spam, which do send a message with a random number to the given - address and expect the user to send a reply. Here, someone is - considered to be allowed to use a particular e-mail address, if and - only if he is able to receive informations sent to this address, - and is able to reply to such a message. While this definition - appears to be quite plausible and natural, it can't be used for a - simple technical solution. Sending back a challenge and expecting a - reply is simply too much overhead and time delay, and not every - authorized sender is able or willing to reply (e.g. because he went - offline or is not a human). - - Within the scope of this memo, sender forgery means that the - initiator of an e-mail transfer (which is the original sender in - contrast to relays) uses a sender address which he was not - authorized to use. Being authorized to use an address means that - the owner (administrator) of the internet domain has given - permission, i.e. agrees with the use of the address by that - particular sender. This memo will cover both the permission of the - full e-mail address and the domain part only for simplicity. - - Within context of Internet and SMTP, the sender address usually - occurs twice, once as the envelope sender address in SMTP, and once - as the address given in the RFC822 mail header. While the following - considerations apply to both addresses in principle, it is - important to stress that both addresses have distinct semantics and - - - -Hadmut Danisch Experimental [Page 4] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - are not neccessarily the same. The envelope address identifies the - initiator of the transport, while the header identifies the author - of the message content. Since this memo deals with the message - transport only and completely ignores the message content, the - method should naturally be applied to the envelope sender address. - -2.1.2. Spam - - A common and well known problem is the dramatic increase of - unsolicited e-mail, commonly called "spam". Again, the majority of - examined e-mails had forged sender addresses. The abused domains - were mainly those of common webmailers as hotmail or yahoo, or - well-known companies. - - Unfortunately, there is no accurate definition of spam availabe - yet, and neither are the concise technical criterions to filter or - block spam with technical mechanisms. There are efforts to design - content based filters, but these filters are expensive in - calculation time (and sometimes money), and they do not reliably - provide predictable results. Usually they give false positives - and/or require user interaction. Content filters in general suffer - from a design problem described later in this memo. Therefore, - this proposal does not use the content based approach to block - spam. - - As analysis of spam messages showed, most of spam messages were - sent with forged envelope sender addresses. This has mainly three - reasons. The first reason is, that spam senders usually do not - want to be contacted by e-mail. The second reason is, that they do - not want to be blacklisted easily. The third reason is, that spam - is or is going to be unlawful in many countries, and the sender - does not want to reveal his identity. Therefore, spam is considered - to be a special case of sender forgery. - -2.1.3. E-Mail Worms - - Another example of sender forgery is the reproduction of e-mail - worms. Most worms do choose random sender addresses, e.g. using - the addresses found in mailboxes on the infected system. In most - cases analyzed by the author, the e-mails sent by the reproduction - process can also be categorized as forged, since the infected - system would under normal circumstances not be authorized to send - e-mails with such e-mail addresses. So forgery does not require a - malicious human to be directly involved. This memo covers any kind - of e-mail sender address forgery, included those generated by - malicious software. - -2.1.4. E-Mail spoofing and fraud - - - -Hadmut Danisch Experimental [Page 5] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - Forging e-mail sender addresses for fraud or other kinds of - deception ("human engineering") has also dramatically increased. - There are many known cases where single or mass e-mails were sent - with wrong sender addresses, pretending to come from service - provider, software manufacturers etc., and asking the receiver to - install any software or patches, or to reply with any confidential - information. The Internet is becoming more and more a scene of - crime, and so are it's services, including e-mail. It is obvious - that crime based on e-mail is eased by the fact that SMTP allows - arbitrary sender address spoofing. - -2.2. Indirect damage caused by forgery - - As observed by the author, mass mails and worms with forged sender - addresses can cause a severe damage for the real owner of the - abused sender addresses. If a sender A is sending an e-mail to the - receiver B, pretending to be C by using a sender address of C's - domain, then C has currently no chance to prevent this, since C's - machines and software are not involved in any way in the delivery - process between A and B. B will nevertheless send any error - messages (virus/spam alert, "no such user", etc.) to C, erroneously - assuming that the message was sent by C. The author found several - cases where this flood of error messages caused a severe denial of - service or a dramatic increase of costs, e.g. when C was - downloading the e-mail through expensive or low bandwidth - connections (e.g. modem or mobile phones), or where disk space was - limited. The author examined mass mailings, where several tens or - hundreds of thousands of messages were sent to several addresses - around the world, where these messages caused only annoyance. But - since several thousands of these addresses were invalid or didn't - accept the message, the owner of the DNS domain which was abused by - the spammer to forge sender addresses was flooded for several - months with thousands of error messages, jamming the e-mail system - and causing severe costs and damages. - - As a consequence, when A sends a message to B, pretending to be C, - there must be any mechanism to allow C to inform B about the fact, - that A is not authorized to use C as a sender address. This is what - this memo is about. - -2.3. Technical problem analysis - - Why does e-mail forgery actually exist? Because of the lack of the - Simple Mail Transfer Protocol SMTP[2] to provide any kind of sender - authentication, authorisation, or verification. This protocol was - designed at a time where security was not an issue. Efforts have - been made to block forged e-mails by requiring the sender address - domain part to be resolvable. This method provides protection from - - - -Hadmut Danisch Experimental [Page 6] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - e-mails with non-existing sender domains, and indeed, for some time - it blocked most spam e-mails. However, since attackers and spam - senders began to abuse existing domain names, this method was - rendered ineffective. - -2.4. Shortcomings of cryptographical approaches - - At a first glance, the problem of sender address forgery might - appear to be solvable with cryptographic methods such as challenge - response authentications or digital signatures. A deeper analysis - shows that only a small, closed user group could be covered with - cryptographical methods. Any method used to stop spam forgery must - be suitable to detect forgery not only for a small number of - particular addresses, but for all addresses on the world. An - attacker does not need to know the secrets belonging to a - particular address. It is sufficient to be able to forge any - address and thus to know any secret key. Since there are several - hundreds of millions of users, there will always be a large amount - of compromised keys, thus spoiling any common cryptographic method. - Furthermore, cryptography has proven to be far too complicated and - error prone to be commonly administered and reliably implemented. - Many e-mail and DNS administrators do not have the knowledge - required to deal with cryptographic mechanisms. Many legislations - do not allow the general deployment of cryptography and a directory - service with public keys. For these reasons, cryptography is - applicable only to a small and closed group of users, but not to - all participants of the e-mail service. - -3. A DNS based sender address verification - -3.1. Overview - - To gain improvement in e-mail authenticity while keeping as much - SMTP compatibility as possible, a method is suggested which doesn't - change SMTP at all. - - The idea is to store informations about how to verify who is - authorized to transmit e-mails through SMTP with a particular - sender address (either full address or - for simplicity - only the - domain part of the address) in a directory service, which is - currently the DNS. To be precise, the verification consists of two - steps, the classical pair of authentication and authorization: - - The first step is the authentication. While several methods are - possible to perform authentication (see below), the most important - and robust method is the verification of the sender's IP address. - This is done implicitely by TCP/IP and the TCP sequence number. The - authenticated identity is the IP address. It has to be stressed - - - -Hadmut Danisch Experimental [Page 7] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - that this TCP/IP "authentication" is a weak authentication and - vulnerable to several attacks. It is nevertheless sufficient for - this purpose, especially for blocking spam. It doesn't take any - implementation and it doesn't cost: It is already there, it is a - functionality of TCP/IP. An incoming SMTP connection based on - TCP/IP already carries the sender's IP address without any - modification of SMTP. See below (section Entry types) for more - details about authentication methods. - - The second step is the authorization. It is based on the identity - given by the previous authentication step, e.g. the IP address of - the originator of the incoming SMTP connection, and on the - envelope sender address. The mechanism proposed in this memo - answers the question "Is that particular sender (IP address,...) - allowed to send with that sender address" by querying and - processing informations stored in a directory service, which is - DNS. - - When the sender has issued the "MAIL FROM:" SMTP command, the - receiving mail transfer agent (MTA) can - and modern MTAs do - - perform some authorization checks, e.g. run a local rule database - or check whether the sender domain is resolvable. - - The suggested method is to let the DNS server for the sender domain - provide informations about who - this means for example which IP - address - is authorized to use an address or a domain as a part of - it. After receiving the "MAIL FROM:" SMTP command, the receiving - MTA can verify, whether e. g. the IP address of the sending MTA is - authorized to send mails with this domain name. Therefore, a list - of entries with authorized IP addresses or other informations is - provided by the authoritative DNS server of that domain. The entry - types are described in the subsequent chapters. Some of these - methods are - - - An IPv4 or IPv6 network address and mask - - A fully qualified domain name referring to an A record - - A fully qualified domain name referring to an APL record - - RMX records of these types would look like this: - - somedomain.de. IN RMX ipv4:10.0.0.0/8 - rmxtest.de. IN RMX host:relay.provider.com - danisch.de. IN RMX apl:relays.rackland.de - relays.rackland.de. IN APL 1:213.133.101.23/32 1:1.2.3.0/24 - - where the machine with the example address 213.133.101.23 and the - machines in the example subnet 1.2.3.0/24 are the only machines - allowed to send e-mails with an envelope sender address of domain - - - -Hadmut Danisch Experimental [Page 8] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - danisch.de. Since the APL records do not necessarily belong to the - same domain or zone table as the RMX records, this easily allows to - refer to APL records defined by someone else, e.g. the internet - access or server hosting provider, thus reducing administrative - overhead to a minimum. In the example given above, the domain - danisch.de and several other domains are hosted by the service - provider Rackland. So if the relay structure of Rackland is - modified, only the zone of rackland.de needs to be modified. The - domain owners don't need to care about such details. - -3.2. Envelope vs. header sender address - - Questions were raised why the proposed mechanism is based on the - envelope sender address, and not on the sender address given in the - message header. Technically, both can be used. Actually, it makes - sense to use the envelope address. - - In common, the header sender address identifies the author of the - content, while the envelope sender tells who caused the - transmission. The approach proposed in this memo is transmission - based, not content based. We can not authorize the author of a - message if we don't have contact with him, if the message does not - already contain a signature. In contrast, the sending MTA is linked - to an IP address which can be used for authentication. This - mechanism might not be very strong, but it is available and - sufficient to solve today's e-mail security problems. - - Some people argued that it is the header address and not the sender - address, which is displayed in common mail readers (MUAs), and - where the receiver believes the mail comes from. That's true, but - it doesn't help. There are many cases where the header sender - differs from the envelope sender for good reasons (see below in the - consequences chapter for the discussion about relaying). Relaying, - mailing lists etc. require to replace the sender address used for - RMX. If this were the header address, the message header would have - to be modified. This is undesirable. - -3.3. Domain part vs. full sender address - - Former versions of this draft were limited to the domain part of - the sender address. The first reason is that it is common and MX- - like, to lookup only the domain part of an e-mail address in DNS. - The second reason is, that it was left to the private business of - the domain administration to handle details of user verification. - The idea was that the domain administration takes care to verify - the left part of an e-mail address with an arbitrary method of - their individual taste. RMX was originally designed to ignore the - left part of the address and to expect the domain administration to - - - -Hadmut Danisch Experimental [Page 9] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - take over responsibility for enforcing their policy. If, e.g., a - spam message arrived and passed the RMX mechanism, it is known to - be authorized by the domain administration and they can be blamed, - no matter what is on the left side of the sender address - it's - their private problem what happens on the left side of the @. By - far the most of the comments to prior versions of this draft agreed - with that. A few comments asked for a finer granularity. - - And indeed, there is no technical reason against a finer - granularity. All it takes is a mapping from a given envelope - sender address to a DNS name, and the RMX lookup for that - particular e-mail address could be done instead of a lookup for the - domain part only. However, to my knowledge, most domain - administrators would not like to provide an RMX entry for every - single e-mail address. In many cases, this would also overload DNS - servers. - - It is to be discussed how to cover both views. One method could be - to query the full address, and if no RMX records were found to - query the domain part only. A different approach would be to query - the domain part only, and if it's RMX record contain a special - entry, then a new query for the full address is triggered. A third - way would be to always query the full address and to leave the - problem to the wildcard mechanism of DNS. This still has to be - discussed and will be described in future versions of this draft. - - - - - - - - - - - -4. Mapping of E-Mail addresses to DNS names - - To perform the RMX query, a mapping is needed from E-Mail addresses - to DNS fully qualified domain names. - - This chapter is under development and just a first approach. - -4.1. Domain part only - - Mapping of the domain part is trivial, since the domain part of an - e-mail address itself is a valid DNS name and does not need - translation. It might be nevertheless desirable to distinguish the - - - -Hadmut Danisch Experimental [Page 10] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - RMX entries from other entries, depending of the encoding of the - records. If the RMX entries are encoded in TXT record types, they - might collide with other uses of TXT records. It might be - necessary to prepend the domain part with a special prefix, e.g. - _rmx. So the e-mail address some.user@example.com could be mapped - to example.com or _rmx.example.com. - -4.2. Full address - - Mapping a full address is slightly more difficult. The @ sign must - be unambiguously translated, and therefore can not be simply - translated into a dot. The e-mail addresses some.user@example.com - and some@user.example.com must have different mappings. Therefore, - the @ sign could be translated into _rmx, implicitely assuming that - this is not an allowed domain name component of normal domain - names. Then the rightmost _rmx in the mapped DNS name always - corresponds to the @ sign. some.user@example.com would e translated - into some.user._rmx.example.com and can be covered by a wildcard - entry like *._rmx.example.com. - - Character encoding and character sets are still to be discussed. - -4.3. Empty address - - Unfortunately, SMTP allows empty envelope sender addresses to be - used for error messages. Empty sender addresses can therefore not - be prohibited. As observed, a significant amount of spam was sent - with such an empty sender address. To solve this problem, the host - name given in the HELO or EHLO command is taken to lookup the RMX - records instead. This makes sense, since such messages were - generated by the machine, not a human. - - - - -5. Mandatory entry types and their syntax - - The entry types described in this section MUST be supported by any - implementation of this draft. - -5.1. Overall structure - - Similar to APL, an RMX record is just a concatenation of zero or - more RMX entries. The entries within one record form an ordered - rule base as commonly usual in packet filtes and firewall rulesets, - i. e. they are processed one ofter another until the first entry - matches. This entry determines the result of the query. Once a - matching entry is found, the RMX processing is finished. - - - -Hadmut Danisch Experimental [Page 11] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - For any domain name there should not exist more than a single RMX - record. Due to the structure of DNS, it is nevertheless possible to - have more than a single RMX record. Multiple RMX records are - treated as a single record consisting of the concatenation of all - records. While the entries in a record are ordered, the records are - not ordered and may be processed in arbitrary order. If the order - of the entries matters, it is the zone maintainer's responsibility - to keep those entries in a single record. For example, there are - negative entries, which exclude IP addresses from authorization. - It is important that these entries are processed before positive - entries giving permission to a wider address range. Since order is - guaranteed only within a record, corresponding negative and - positive entries must be put in the same record. - - An RMX record may consist of one or more entries, where the entries - are separated by whitespace. An entry must not contain white space. - Each entry consists of an optional exclamation sign, a tag, a - colon, and the entry data: - - [!] TAG : ENTRY-SPECIFIC-DATA - - If the entry starts with an exclamation sign, the entry is negated. - See the entry type description below for details. - - The TAG is the mnemonic type identifier or the decimal number of - the entry. The TAG is case-insensitive. It is immediately followed - by a colon. - - The syntax and semantics of ENTRY-SPECIFIC-DATA depends of the the - entry type. See description below. - - Example: - - danisch.de. IN RMX apl:relays.rackland.de !ipv4:1.2.3.5 - ipv4:1.2.3.0/24 - -5.2. Unused - - This is a primitive entry which just says that this sender address - will never be used as a sender address under any circumstances. - Example: - - testdomain.danisch.de IN RMX unused: - -5.3. IPv4 and IPv6 address ranges - - These entry types contain a bit sequence representing a CIDR - address part. If that bit sequence matches the given IP address, - - - -Hadmut Danisch Experimental [Page 12] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - authorization is granted or denied, depending on the negation flag. - - The entry is prepended with the tag "IPv4" or "IPv6". The colon is - followed with an IPv4 or IPv6 address in standard notation, - optionally followed by a slash and a mask length. If the negation - flag is set, then the given address range is excluded. Examples: - - danisch.de IN RMX ipv4:213.133.101.23 ipv6:fe00::0 - IN RMX ipv4:10.0.0.0/8 ipv6:fec0::0/16 - IN RMX !ipv4:1.2.3.4 - - (Please note that it does not make much sense to use - RFC1918-Addresses in RMX records, this is just to give a syntax - example.) - - -5.4. DNS Hostname - - This entry type simply contains a regular DNS name, which is to be - resolved as a host name (fetch the A record or IPv6 equivalent). If - the given IP address matches the result, authorization is granted - or denied, depending on the negation flag. It is still to be - defined how to treat unresolvable entries. - - The entry is prepended with the tag "host", followed by a colon and - the hostname. Examples: - - danisch.de IN RMX host:relay.provider.de - IN RMX !host:badmachine.domain.de apl:relays.domain.de - -5.4.1. Road warriors and DynDNS entries - - Several people argued against RMX that it would break their - existing installation which delivers e-mail from dynamically - assigned IP addresses, because their IP providers didn't assign a - static address, or because they are a road warrior, plugging their - notebook in any hotel room on the world. - - RMX provides a simple solution. If such a machine has a dynamically - updated DNS entry (e.g. DynDNS), all it takes is an RMX entry of - the hostname type pointing to this dynamic DNS entry. - - The cleaner solution would be to deliver mail the same way as it is - received: If downloaded by POP from a central relay with a static - address, where the MX points to, then it would be a good idea to - deliver e-mail the same way in reverse direction. Unfortunately, - plain POP does not support uploading yet. - - - - -Hadmut Danisch Experimental [Page 13] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - -5.5. APL Reference - - This entry type simply contains a regular DNS name, which is to be - resolved as an APL record index (fetch the APL record). If the - given IP address positively matches the APL, authorization is - granted. Details of the semantic (espially when the negation bit is - set) are still to be defined. It is still to be defined how to - treat unresolvable entries. - - The entry is prepended with the tag "host", followed by a colon and - the hostname. Example: - - danisch.de IN RMX apl:relays.rackland.de - -5.6. Domain Member - - In many cases it is desirable to cover all hosts of a given domain - with an RMX record without the need to duplicate the list of these - hosts. This entry type does it (thanks to Eric A. Hall for pointing - out this entry type). It contains a regular DNS name. - - If this entry type is given, a reverse DNS query for the IP address - of the sending MTA is performed to find its official fully - qualified domain name. To prevent spoofing, this domain name is - accepted only if a subsequent address query to the given domain - name points to exactly the IP address of the sending MTA (the usual - procedure to verify PTR records). - - The entry matches if the fully qualified domain name of the sending - MTA ends in the given domain. The negation flag works as usual. - - The tag for this entry type is "domain". After the colon the domain - name is given, but might be empty, thus pointing to itself. - Example: - - somedomain.org IN RMX domain:somedomain.org domain:provider.com - - would authorize all machines which's hostname can be verified - through an PTR and A query, and which ends in "somedomain.org" or - "provider.com". - - With such an entry, large companies with different networks can - easily be covered with just a single and simple RMX entry. - Obviously, it requires proper PTR records. - - As a special shortcut, the DNS name may be empty. In this case the - domain name of the zone itself is taken. Thus, with a very simple - entry of the type - - - -Hadmut Danisch Experimental [Page 14] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - somecompany.com IN RMX domain: - - a company could authorize all machines which's IP addresses map to - DNS names end in somecompany.com, which applies in the majority of - companies. - - - - -5.7. Full Address Query - - As described above, RMX records will in most cases apply to the - domain part of the sender address. In special cases it might be - desirable to query the RMX record for a particular address. An RMX - entry of the Full Address Query type may occur in a domain RMX - record only. It signals that the RMX record for the full address is - to be fetched and processed. - - This entry type does not take arguments. The negation flag is not - supported. The tag is "full". - - If such a full address query is to be performed, the mail address - must be mapped to a valid and non-ambiguos DNS name. This mapping - is still to be defined. It is not sufficient to simply replace the - @ with a dot, because of case sensitivity, character sets, etc. The - e-mail addresses - - john.doe@example.org - John.Doe@example.org - john@doe.example.org - - must all be mapped to different DNS entries. This entry type might - vanish in future versions of the draft, depending on the discussion - about whether to query the domain name part only or the full - address. - -5.8. DNS mapped authorization - - As I learned from comments to prior versions of the draft and from - alternative proposals, many users wish to have a DNS mapped - authorization table, i. e. the client queries a DNS entry of the - form a.b.c.d.domain, where a.b.c.d is the sender's IP address. - Since people wish to have this, RMX will now include such a mapping - entry. The entry has a parameter giving the DNS domain name where - to look at. If the parameter is empty, then the same domain is - taken as for the RMX lookup. - - As this is currently under construction and discussion in an IETF - - - -Hadmut Danisch Experimental [Page 15] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - group, details will be published in future versions of this draft. - -5.9. RMX reference - - This entry type has no parameters. It means that all those machines - are authorized, which are pointed to by an MX record. - -6. Optional and experimental entry types - - The following subsections roughly describe further entry types - which might not be supported by all implementations and might not - be allowed in all legislations. These methods might vanish in - future versions of the draft and are just considerations about what - to include in RMX and what to not include. The main purpose of this - section is to start discussion about such entry types. - - The disadvantage of the following methods is that they violate the - basic idea of RMX, i. e. to be simple, robust, easy to implement - and easy to administer. I personally do not believe that it is a - good idea or even feasible to implement cryptography for a world - wide e-mail transfer network. Keep in mind that cryptographic keys - can be copied. If only <0.1% of cryptographic keys were revealed, - this completely compromises and spoils RMX. Cryptography is simply - the wrong tool for the problem RMX is intended to solve. I - nevertheless like to discuss these methods. - -6.1. TLS fingerprint - - The sender is considered to be authorized if the message was - transmitted through SMTP and TLS, and the sender used a certificate - matching the fingerprint given in the RMX record. - -6.2. TLS and LDAP - - This means that the receiver should perform an LDAP query for the - sender address (through the LDAP SRV record or given in the RMX - record), fetch the X.509 certificate for the sender. The sender is - considered to be authorized when the message was transmitted - through SMTP and TLS using this certificate. - -6.3. PGP or S/MIME signature - - It would be possible to accept a message only if it was signed with - PGP or S/MIME with a key which's fingerprint is given in the RMX - record or to be fetched from LDAP or any PGP database. This is - just for discussion, since it violates the idea of RMX to focus on - the transport, not on the content. It would also allow replay - attacks and not cover the envelope sender address or message - - - -Hadmut Danisch Experimental [Page 16] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - header. - -6.4. Transparent Challenge/Response - - It would also be possible to implement a challenge-response - mechanism without modifying the syntax of SMTP. For example, the - receiving MTA could issue a challenge with it's very first greeting - message, the sending MTA could hide the response in the HELO - parameter and when the receiving MTA later learns the sender - envelope address, it could verify the response based on - informations in the RMX record. - -6.5. SASL Challenge/Response - - Modern SMTP implementations already include a SASL mechanisms, - which easily allows to plugin new authentication mechanisms. While - common SASL mechanisms require to use a previously shared password, - a new mechanism could perform a challenge response authentication - as a SASL method. - - - - - - -7. Encoding - -7.1. Alternative encoding as TXT records - - The main objection against the prior versions of this draft was - that it requires a new RR entry type and upgrading all DNS servers. - - Therefore and alternative encoding is proposed. Instead of using a - new RR type, the TXT record type is used to contain the RMX record. - The records would simply look as described in the entry type - chapters above, e.g. - - _rmx.danisch.de. IN TXT "apl:relays.rackland.de" - - To allow smooth introduction of RMX without the need to immediately - upgrade all DNS servers, all clients (which have to be newly - installed anyway) MUST support both the TXT and the RMX records. A - client has to perform an ANY or a TXT and a RMX query. Servers/zone - tables may currently use TXT entries but SHOULD use RMX entries in - future. - -7.2. RMX Records - - - - -Hadmut Danisch Experimental [Page 17] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - -7.2.1. Overall structure - - Each entry starts with an octet containting the entry type and the - negation flag: - - +---+---+---+---+---+---+---+---+------ - | N | Entry Type Code | Parameters... - +---+---+---+---+---+---+---+---+------ - - N If this bit (MSB) is set, an IP address - matching this entry is not authorized, - but explicitely rejected. See entry - type descriptions for details. - - Entry Type A 7bit number simply determining the entry - type. - - - Currently, entries do not have an explicit length field, the entry - length is determined implicitely by the entry type. Applications - are required to abort if an unknown entry type is found, instead of - skipping unknown entries. - -7.2.2. Record encoding - - A RMX record is simply a concatenation of RMX entries. - -7.2.3. Encoding of IPv4 and IPv6 address ranges - - After the entry type tag as described above, one octet follows - giving the length L of the bit sequence. Then a sequence of exactly - as many octets follows as needed to carry L bits of information (= - trunc((L+7)/8) ). - - +---+---+---+---+---+---+---+---+ - | N | Entry Type Code (1 or 2) | - +---+---+---+---+---+---+---+---+ - | Length Field L | - +---+---+---+---+---+---+---+---+ - | Bit Field | - / ((L+7)/8) Octets / - +---+---+---+---+---+---+---+---+ - - -7.2.4. Encoding of DNS - - After the entry type tag immediately follows a DNS encoded and - compressed [3] domain name. - - - -Hadmut Danisch Experimental [Page 18] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - +---+---+---+---+---+---+---+---+ - | N | Entry Type Code (3..5) | - +---+---+---+---+---+---+---+---+ - | Length Field L | - +---+---+---+---+---+---+---+---+ - | Encoded DNS | - / Name as described in RFC1035 / - +---+---+---+---+---+---+---+---+ - - In contrast to earlier versions of this draft, the DNS name cannot - be compressed, since this would cause decompression errors when a - DNS server is part of the query chain which does not know this - particular RR type. - -7.2.5. Encoding of unused and full query - - These entries do not contain parameters and does not allow the - negation flag. So the encoding is quite simple: - - +---+---+---+---+---+---+---+---+ - | 0 | Entry Type Code (6 or 7)| - +---+---+---+---+---+---+---+---+ - - - -7.2.6. Additional Records - - In order to avoid the need of a second query to resolve the given - host name, a DNS server should enclose the A record for that domain - name in the additional section of the additional section of the DNS - reply, if the server happens to be authoritative. - - In order to avoid the need of a second query to resolve the given - host name, a DNS server should enclose the APL record for that - domain name in the additional section of the additional section of - the DNS reply, if the server happens to be authoritative. - - - -8. Message Headers - - An RMX query must be followed by any kind of action depending on - the RMX result. One action might be to reject the message. Another - action might be to add a header line to the message body, thus - allowing MUAs and delivery programs to filter or sort messages. - - In future, the RMX result might be melted into the Received: header - line. - - - -Hadmut Danisch Experimental [Page 19] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - The details of such entries are to be discussed. As a proposal the - following form is suggested: - - X-RMX: RESULT addr ADDRESS by HOST on DATE mechanism MECHANISM - - where - - RESULT is one of "Granted", "Denied", "NotInRMX", "NoRMX", - "TempFail", "BadData", "Trusted". - - ADDRESS is the IP address of the sending machine - - HOST is the name of the machine performing the RMX query. - - DATE is the date of the query. - - MECHANISM is the RMX method used to authorize the sender. - - - -9. SMTP error messages - - If a message is rejected because of RMX records, an error message - should be issued which explains the details. It is to be discussed - whether new SMTP error codes are to be defined. - - -10. Message relaying and forwarding - -10.1. Problem description - - Message forwarding and relaying means that an MTA which received an - e-mail by SMTP does not deliver it locally, but resends the message - - usually unchanged except for an additional Received header line - and maybe the recipient's address rewritten - to the next SMTP MTA. - Message forwarding is an essential functionality of e-mail - transport services, for example: - - - Message transport from outer MX relay to the intranet - - Message forwarding and Cc-ing by .forward or .procmail-alike - mechanisms - - Mailing list processing - - Message reception by mail relays with low MX priority, - usually provided by third parties as a stand-by service - in case of relay failure or maintenance - - "Forwarding" and "Bouncing" as a MUA functionality - - In all these cases a message is sent by SMTP from a host which is - - - -Hadmut Danisch Experimental [Page 20] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - not covered by the original sender domain's RMX records. While the - RMX records would forbid accepting this message, it still must be - accepted. The following subsections explain how to cope with - relaying. - -10.2. Trusted relaying/forwarding - - In some cases the receiving MTA trusts the sending MTA to not fake - messages and to already have checked the RMX records at message - reception. As a typical example, a company might have an outer mail - relay which receives messages from the Internet and checks the RMX - records. This relay then forwards the messages to the different - department's mail servers. It does not make sense for these - department mail servers to check the RMX record, since the RMX - records have already been checked and - since the message was - relayed by the outer relay - always would deny the message. In this - case there is a trust relationship between the department relays - and the outer relay. So RMX checking is turned off for trusted - relays. In this example, the department relays would not check - messages from the outer relay (but for intranet security, they - could still check RMX records of the other departments sub-domains - to avoid internal forgery between departments). - - Another common example are the low-priority MX relays, which - receive and cache e-mails when the high-priority relays are down. - In this case, the high-priority relay would trust the low-priority - relay to have verified the sender authorization and would not - perform another RMX verification (which would obviously fail). - - When a relay forwards a message to a trusting machine, the envelope - sender address should remain unchanged. - -10.3. Untrusted relaying/forwarding - - If the receiving MTA does not trust the forwarding MTA, then there - is no chance to leave the sender envelope address unchanged. At a - first glance this might appear impracticable, but this is - absolutely necessary. If an untrusted MTA could claim to have - forwarded a message from a foreign sender address, it could have - forged the message as well. Spammers and forgers would just have to - act as such a relay. - - Therefore, it is required that, when performing untrusted - forwarding, the envelope sender address has to be replaced by the - sender address of someone responsible for the relaying mechanism, - e.g. the owner of the mailing list or the mail address of the user - who's .forward caused the transmission. It is important to stress - that untrusted relaying/forwarding means taking over responsibility - - - -Hadmut Danisch Experimental [Page 21] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - for the message. It is the idea of RMX records to tie - responsibility to message transmission. Untrusted relaying without - replacing the sender address would mean to transmit without taking - responsibility. - - The disadvantage is that the original sender address is lost. - Therefore, whenever a sender address replacement happens, the - Received-Line must contain the old address. Many of today's MTAs - already insert the envelope recipient address, but not the sender - address into the Received header line. It seems reasonable to - require every Received line to include both the sender and - recipient address of the incoming SMTP connection. - - -11. Security Considerations - -11.1. Draft specific considerations - -11.1.1. Authentication strength - - It is important to stress, that the suggested method does not - provide high level security and does not completely prevent forged - e-mails or spam under any circumstances. It is a robust, but not - highly reliable and completely secure security mechanism. Keep in - mind that it is based on DNS, and DNS is not secure today. - Authorization is based on the IP address. The very same machine - with the very same IP address could be authorized to send e-mail - with a given sender address and sending spam at the same time. - Maybe because several users are logged in. Or because several - customers use the same relay of the same ISP, where one customer - could use the sender address of a different customer. It is up to - the ISP to prevent this or not. Machines can still be hijacked. - Spammers are also domain owners. They can simply use their own - domain and authorize themselves. You will always find people on the - world who do not care about security and open their relays and RMX - records for others to abuse them. RMX is to be considered as a - very cheap and simple light weight mechanism, which can - nevertheless provide a significant improvement in mail security - against a certain class of attacks, until a successor of SMTP has - been defined and commonly accepted. - -11.1.2. Where Authentication and Authorization end - - Previous versions of RMX records did not cover the local part of - the e-mail address, i.e. what's on the left side of the @ sign. - This is still to be discussed. Authentication and authorization are - limited to the sending MTA's IP address. The authentication is - limited to the TCP functionality, which is sufficient for light - - - -Hadmut Danisch Experimental [Page 22] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - weight authentication. The RMX records authorize the IP address of - the sending host only, not the particular sender of the message. So - if a machine is authorized to use sender addresses of more than a - single domain, the authentication scheme does not prevent that any - user on this machine can send with any of these domains. RMX is not - a substitute for the host security of the involved machines. - - The proposed authentication scheme can be seen as a "half way - authentication": It does not track back an e-mail to the effective - sender. It tracks only half of the way, i. e. it tracks back to the - domain and it's DNS administrators who authorized that particular - sender IP address to use it for sending e-mail. How the party - responsible for that domain performs user authentication, whom it - grants access to, how it helds people responsible for abuse, is - completely left as the private business of those who are in charge - of that domain. So this draft does not interfere with the domain's - individual security policy or any legislation about such policies. - On the other hand, the proposed authentication scheme does not give - any statement about the nature and quality of the domain's security - policy. This is an essential feature of the proposal: E-mail - authentication must be deployed world wide, otherwise it won't do - the job. Any security scheme interfering with the local - legislations or the domain's security policy will not be accepted - and can't effectively deployed. Therefore, the security policy must - remain the domain's private business, no matter how lousy the - policy might be. - - In order to achieve this and to make use of the only existing world - wide Internet directory scheme (DNS), the approach of this proposal - is to just ignore the local part of the sender address (i.e. what's - left of the @ part) and limit view to the domain part. After all, - that's what we do anyway when delivering to a given address with - SMTP. - -11.1.3. Vulnerability of DNS - - DNS is an essential part of the proposed authentication scheme, - since it requires any directory service, and DNS is currently the - only one available. Unfortunately, DNS is vulnerable and can be - spoofed and poisoned. This flaw is commonly known and weakens many - network services, but for reasons beyond that draft DNS has not - been significantly improved yet. After the first version of this - draft, I received several comments who asked me not to use DNS - because of its lack of security. I took this into consideration, - but came to the conclusion that this is unfeasible: Any - authentication scheme linked to some kind of symbolic identity (in - this case the domain name) needs some kind of infrastructure and - trusted assignment. There are basically two ways to do it: Do it - - - -Hadmut Danisch Experimental [Page 23] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - yourself and trust nobody else, or let someone else do it. There - are methods to do it the former way, e.g. to give someone some kind - of authentication information after a first successful e-mail - exchange, e.g. some kind of cookie or special e-mail address. This - is certainly interesting and powerful, but it does not solve the - problem on a world wide scale and is far to complicated and error - prone for the average user, i. e. 99% of the users. - - The latter method to let someone else do the symbolic name - assignment and create the authentication framework is well known. - It context of public key cryptography, this is called a Public Key - Infrastructure (PKI). On of the best known facts about PKIs is - that, until now, we don't have any covering a significant part of - the Internet. And we won't have any in near future. The complexity - is far too high, it is too expensive, and it involves cooperation - of every single user, which is simply unrealistic and extremely - error prone. So what do we have we can use? All we have is the DNS - and the Whois database. And we have countries who don't allow - cryptography. So the proposal was designed to use DNS without - cryptography. It does not avoid DNS because of its vulnerability, - it asks for a better DNS, but accepts the DNS as it is for the - moment. Currently there are two main threats caused by the DNS - weakness: - - - A spammer/forger could spoof DNS in order to gain false - authorization to send fake e-mails. - - - An attacker could spoof DNS in order to block delivery from - authorized machines, i. e. perform a Denial of Service attack. - - The first one is rather unrealistic, because it would require an - average spammer to poison a significant part of the DNS servers of - its victims. A spammer sending messages to one million receipients - would need to poison at least 1-10% which is 10,000 to 100,000 - receipient's DNS servers. This should be unfeasible in most cases. - - In contrast, the second threat is a severe one. If an attacker - wanted to block messages from one company to another, he just needs - to poison the recipients DNS server with a wrong RMX record in - order to make the recipient's SMTP machine reject all messages. And - this is feasible since the attacker needs to poison only a single - DNS server. But does this make SMTP more vulnerable? No. Because - the attacker can already do even more without RMX. By poisoning the - sender's DNS server with wrong MX records, the attacker can also - block message delivery or even redirect the messages to the - attacker's machine, thus preventing any delivery error messages and - furthermore getting access to the messages. - - - - -Hadmut Danisch Experimental [Page 24] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - As a consequence, e-mail delivery by SMTP requires a better DNS - anyway. The requirements are not significantly expanded by RMX. - -11.1.4. Sneaking RMX attack? - - While writing a test implementation, a certain kind of attack came - into my mind. I'm still not sure, whether this attack is possible - on any DNS server, but I believe it should be mentioned: - - Imagine an unauthorized sender is sending a forged mail (e.g. - spam). At connection time, before querying the RMX record, the - receiving MTA usually performs a PTR query for the IP address of - the sending MTA. If the sender has control over the authoritative - name server for that particular IP address, the sender could give a - normal PTR answer, but could append a wrong RMX, APL, or A record - in the additional section of the query. A subsequent RMX query - could receive wrong DNS data if the DNS server used by the - receiving MTA accepted those forged records. - -11.1.5. Open SMTP relays - - Open SMTP relays (i.e. machines who accept any e-mail message from - anyone and deliver to the world) abused by spammers are a one of - the main problems of spam defense and sender backtracking. In most - cases this problem just vanishes because foreign open relay - machines will not be covered by the RMX records of the forged - sender address. But there are two special cases: - - If the spammer knows about a domain which authorizes this - particular machine, that domain can be used for forgery. But in - this case, the IP address of the relay machine and the RMX records - of the domain track back to the persons responsible. Both can be - demanded to fix the relay or remove the RMX record for this - machine. An open relay is a security flaw like leaving the machine - open for everybody to login and send random mails from inside. Once - the administrative persons refuse to solve the problem, they can be - identified as spammers and held responsible. - - The second special case is when a domain authorizes all IP - addresses by having the network 0.0.0.0/0 in the RMX/APL record. In - this case, open relays don't make things worse. It's up to the - recipient's MTA to reject mails from domains with loose security - policies. - -11.1.6. Unforged Spam - - This proposal does not prevent spam (which is, by the way, not yet - exactly defined), it prevents forgery. Since spam is against law - - - -Hadmut Danisch Experimental [Page 25] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - and violates the recipients rights, spam depends on untracability - of the sender. In practice the sender forges the sender address - (other cases see below). This proposal is designed to detect such - forgeries. - - However, the RMX approach is rendered ineffective, if the sender - doesn't forge. If the sender uses just a normal address of it's own - domain, this is just a plain, normal e-mail, which needs to be let - through. Since it is up to the human's taste whether this is spam - or not, there's no technical way to reliably identify this as spam. - But since the sender domain is known, this domain can be - blacklisted or legal steps can be gone into. - -11.1.7. Reliability of Whois Entries - - Once the RMX infrastructure gets deployed, what's the security - gain? It allows to determine the domain which's DNS zone - authorized the sending machine. What's that good for? There are - some immediate uses of the domain name, e.g. in black- and - whitelisting. But in most cases this is just the starting point of - further investigations, either performed automatically before - message acceptance, or manually after spam has been received and - complainted about. - - The next step after determining the domain is determining the - people responsible for this domain. This can sometimes be achieved - by querying the Whois databases. Unfortunately, many whois entries - are useless because they are incomplete, wrong, obsolete, or in - uncommon languages. Furthermore, there are several formats of - address informations which make it difficult to automatically - extract the address. Sometimes the whois entry identifies the - provider and not the owner of the domain. Whois servers are not - built for high availability and sometimes unreachable. - - Therefore, a mandatory standard is required about the contents and - the format of whois entries, and the availability of the servers. - After receiving the MAIL FROM SMTP command with the sender envelope - address, the receiving MTA could check the RMX record and Whois - entry. If it doesn't point to a real human, the message could be - rejected and an error message like "Ask your provider to fix your - Whois entry" could be issued. Obviously, domain providers must be - held responsible for wrong entries. It might still be acceptable to - allow anonymous domains, i. e. domains which don't point to a - responsible human. But it is the receivers choice to accept e-mails - from such domains or not. - -11.1.8. Hazards for Freedom of Speech - - - - -Hadmut Danisch Experimental [Page 26] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - Currently, some governments try to enforce limitations of internet - traffic in order to cut unwanted content providers from the - network. Some of these governments try to hide a whole country - behind firewalls, others try to force Internet providers to poison - DNS servers with wrong A records for web servers, e.g. one county - administration in Germany tries to do so. If message reception - depends on DNS entries, the same governments will try to block not - only HTTP, but SMTP also. - - However, since most MTAs already reject messages from unresolvable - domain names this is not a new threat. - -11.2. General Considerations about spam defense - - After discussing security requirements of the proposal, now the - security advantages of the RMX approach over content based filters - will be explained. Basically, there are three kinds of content - filters: - - - Those who upload the message or some digest to an external - third party and ask "Is this spam"? - - - Those who download a set of patterns and rules from a third - party and apply this set to incoming messages in order to - determine whether it is spam. - - - Those who are independent and don't contact any third party, - but try to learn themselves what is spam and what isn't. - - - The message filters provided by some e-mail service providers are - usually not a kind of their own, but a combination of the first two - kinds. - -11.2.1. Action vs. reaction - - Content filters suffer from a fundamental design problem: They are - late. They need to see some content of the same kind before in - order to learn and to block further distribution. - - This works for viruses and worms, which redistribute. This doesn't - work for spam, since spam is usually not redistributed after the - first delivery. When the filters have learned or downloaded new - pattern sets, it's too late. - - This proposal does not have this problem. - -11.2.2. Content based Denial of Service attacks - - - -Hadmut Danisch Experimental [Page 27] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - All three kinds of content filters, but especially the second and - the third kind are vulnerable to content based Denial of Service - attacks. - - If some kind of third party (e.g. non-democratic government, - intellectual property warriors, religious groups, military, secret - services, patriots, public relation agents, etc.) wants certain - contents not to be distributed, they could either poison the - pattern/rule databases or feed wrong sets to particular receivers. - - Such pattern/rule sets are the perfect tool for censoring e-mail - traffic and denial of service attacks by governments and other - parties, and a similar threat are virus filters. E. g. the content - industry could demand to teach all virus and spam filters to delete - all e-mails containing the URL of an MP3 web server outside the - legislations. Software manufacturers could try to block all e-mails - containing software license keys, thus trying to make unallowed - distribution more difficult. Governments could try to block - distribution of unwanted informations. - - This proposal does not have this problem. - - -12. Privacy Considerations - - (It was proposed on the 56th IETF meeting to have a privacy section - in drafts and RFCs.) - -12.1. Draft specific considerations - -12.1.1. No content leaking - - Since the RMX approach doesn't touch the contents of a message in - any way, there is obviously no way of leaking out any information - about the content of the message. RMX is based solely on the - envelope recipient address. However, methods to fix problems not - covered by RMX might allow content leaking, e.g. if the acceptance - of a message with an empty sender address requires the reference to - the message id of an e-mail recently sent, this allows an attacker - to verify whether a certain message was delivered from there. - -12.1.2. Message reception and sender domain - - Message delivery triggers RMX and APL requests by the recipient. - Thus, the admin of the DNS server or an eavesdropper could learn - that the given machine has just received a message with a sender - from this address, even if the SMTP traffic itself had been - encrypted. - - - -Hadmut Danisch Experimental [Page 28] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - However, most of today's MTAs do query the MX and A records of the - domain after the MAIL FROM command, so this is not a real new - threat. - -12.1.3. Network structure - - Since RMX and its associated APL records provide a complete list of - all IP addresses of hosts authorized to send messages from this - address, they do reveal informations about the network structure - and maybe the lifestyle of the domain owner, since a growing number - of domains are owned by single persons or families. E.g. the RMX - records could reveal where someone has his job or spends his time - at weekends. - - If such informations are to be kept secret, it is the user's job to - not sent e-mails from there and to relay them from non-compromising - IP addresses. - -12.1.4. Owner information distribution - - As described above, RMX depends partly on the reliability of the - whois database entries. It does not make anonymous domains - impossible, but it requires to keep the database entries "true", i. - e. if a whois entry does not contain informations about the - responsible person, this must be unambigously labeled as anonymous. - It must not contain fake names and addresses to pretend a non- - existing person. However, since most Internet users on the world - feel extremely annoyed by spam, they will urge their MTA admin to - reject messages from anonymous domains. The domain owner will have - the choice to either remain anonymous but be not able to send e- - mail to everyone in the world, or to be able but to reveal his - identity to everyone on the world. - - It would be possible to provide whois-like services only to - recipients of recent messages, but this would make things too - complicated to be commonly adopted. - -12.2. General Considerations about spam defense - -12.2.1. Content leaking of content filters - - As described above in the Security chapter, there are spam filters - which inherently allow leakage of the message body. Those filters - upload either the message body, or in most cases just some kind of - checksum to a third party, which replies whether this is to be seen - as spam or not. The idea is to keep a databases of all digests of - all messages. If a message is sent more often than some threshold, - it is to be considered as a mass mail and therefore tagged as spam. - - - -Hadmut Danisch Experimental [Page 29] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - While the digest itself does not reveal the content of the message, - it perfectly reveals where a particular message has been delivered - to. If a government finds just a single unwanted message, if a - software manufacturer finds a single message with a stolen product - license key, if someone finds a message with unpatriotic content, - it takes just a single database lookup to get a list of all people - who received this particular message. Content filters with digest - upload are the perfect "Big Brother". - -12.2.2. Black- and Whitelists - - Some proposals against spam are based on a central database of - white- or blacklisted IP addresses, Sender names, Message IDs or - whatever. Again, there is a central database which learns who has - received which e-mail or from which sender with every query. This - allows tracking relations between persons, which is also a breach - of privacy. - - - -13. Deployment Considerations - -13.1. Compatibility - -13.1.1. Compatibility with old mail receivers - - Since the suggested extension doesn't change the SMTP protocol at - all, it is fully compatible with old mail receivers. They simply - don't ask for the RMX records and don't perform the check. - -13.1.2. Compatibility with old mail senders - - Since the SMTP protocol is unchanged and the SMTP sender is not - involved in the check, the method is fully compatible with old mail - senders. - -13.1.3. Compatibility with old DNS clients - - Since the RMX is a new RR, the existing DNS protocol and zone - informations remain completely untouched. - - If RMX is provided as a TXT record instead, it must be ensured that - no other software is misinterpreting this entry. - -13.1.4. Compatibility with old DNS servers - - Full compatibility: If the server does not support RMX records, RMX - in TXT records can be used. - - - -Hadmut Danisch Experimental [Page 30] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - -13.2. Enforcement policy - - Obviously, for reasons of backward compatibility and smooth - introduction of this scheme, RMX records can't be required - immediately. Domains without RMX records must temporarily be - treated the same way as they are treated right now, i.e. e-mail - must be accepted from anywhere. But once the scheme becomes - sufficiently widespread, mail relays can start to refuse e-mails - with sender addresses from domains without RMX records, thus - forcing the owner of the domain to include a statement of - authorization into the domain's zone table. Domain owners will - still be free to have an RMX record with a network and mask - 0.0.0.0/0, i.e. to allow e-mails with that domain from everywhere. - On the other hand, mail receivers will be free to refuse mails from - domains without RMX records or RMX records which are too loose. - Advanced MTAs might have a configuration option to set the maximum - number of IP addresses authorized to use a domain. E-mails from a - domain, which's RMX records exceed this limit, would be rejected. - For example, a relay could reject e-mails from domains which - authorize more than 8 IP addresses. That allows to accept e-mails - only from domains with a reasonable security policy. - - - -14. General considerations about fighting spam - - Is there a concise technical solution against spam? Yes. - - Will it be deployed? Certainly not. - - Why not? Because of the strong non-technical interests of several - parties against a solution to the problem, as described below. - Since these are non-technical reasons, they might be beyond the - scope of such a draft. But since they are the main problems that - prevent fighting spam, it is unavoidable to address them. This - chapter exists temporarily only and should support the discussion - of solutions. It is not supposed to be included in a later RFC. - -14.1. The economical problem - - As has been recently illustrated in the initial session of the - IRTF's Anti Spam Research Group (ASRG) on the 56th IETF meeting, - sending spam is a business with significant revenues. - - But a much bigger business is selling Anti-Spam software. This is a - billion dollar market, and it is rapidly growing. Any simple and - effective solution against spam would defeat revenues and drive - several companies into bankrupt, would make consultants jobless. - - - -Hadmut Danisch Experimental [Page 31] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - Therefore, spam is essential for the Anti-Spam business. If there - is no spam, then no Anti-Spam software can be sold, similar to the - Anti-Virus business. There are extremely strong efforts to keep - this market growing. Viruses, Worms, and now spam are just perfect - to keep this market alive: It is not sufficient to just buy a - software. Databases need to be updated continuously, thus making - the cash flow continuously. Have a single, simple, and permanent - solution to the problem and - boom - this billion dollar market is - dead. - - That's one of the reasons why people are expected to live with - spam. They have to live with it to make them buy Anti-Spam - software. Content filters are perfect products to keep this market - alive. - -14.2. The POP problem - - Another problem is the history of mail delivery. Once upon a time, - there used to be very few SMTP relays which handled the e-mail - traffic of all the world, and everybody was happy with that. Then - odd things like Personal Computers, which are sometimes switched - off, portable computers, dynamicly assigned IP addresses, IP access - from hotel rooms, etc. was invented, and people became unhappy, - because SMTP does not support delivery to such machines. To make - them happy again, the Post Office Protocol[4] was invented, which - turned the last part of message delivery from SMTP's push style - into a pull style, thus making virtually every computer on the - world with any random IP address a potential receiver of mails for - random domains. Unfortunately, only receiving e-mail was covered, - but sending e-mail was left to SMTP. - - The result is that today we have only very few SMTP relays pointed - to by MX records, but an extreme number of hosts sending e-mail - with SMTP from any IP address with sender addresses from any - domain. Mail delivery has become very asymmetric. Insecurity, - especially forgeability, has become an essential part of mail - transport. - - That problem could easily be fixed: Use protocols which allow - uploading of messages to be delivered. If a host doesn't receive - messages by SMTP, it shouldn't deliver by SMTP. Mail delivery - should go the same way back that incoming mail went in. This is - not a limitation to those people on the road who plug their - portable computer in any hotel room's phone plug and use any - provider. If there is a POP server granting download access from - anywhere, then the same server should be ready to accept uploading - of outgoing messages. - - - - -Hadmut Danisch Experimental [Page 32] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - But as I saw from the comments on the first version of this draft, - people religiously insist on sending e-mail with their domain from - any computer with any IP address in the world, e.g. when visiting a - friend using her computer. It appears to be impossible to convince - people that stopping mail forgery requires every one of them to - give up forging. - -14.3. The network structure problem - - A subsequent problem is that many organisations failed to implement - a proper mail delivery structure and heavily based their network on - this asymmetry. I received harsh comments from Universities who - were unable to give their network a good structure. While they do - have a central mail relay for incoming mail to the universities - domain, they developed a structure where every member of the - University randomly sends e-mails with that University's domain as - a sender address from home or everywhere in the world with any - dynamically assigned IP address from any provider. So this domain - is to be used from every possible IP address on earth, and they are - unable to operate any authentication scheme. Furthermore, they were - unable to understand that such a policy heavily supports spam and - that they have to expect that people don't accept such e-mails - anymore once they become blacklisted. - - As long as organisations insist on having such policies, spammers - will have a perfect playground. - -14.4. The mentality problem - - Another problem is the mentality of many internet users of certain - countries. I received harsh comments from people who strongly - insisted on the freedom to send any e-mail with any sender address - from anywhere, and who heavily refused any kind of authentication - step or any limitation, because they claimed that this would - infringe their constitutional "Freedom of speech". They are - undeviatingly convinced that "Freedom of speech" guarantees their - right to talk to everybody with any sender address, and that is has - to be kept the recipient's own problem to sort out what he doesn't - want to read - on the recipient's expense. - - It requires a clear statement that the constitutional "Freedom of - Speech" does not cover molesting people with unsolicited e-mail - with forged sender address. - -14.5. The identity problem - - How does one fight against mail forgery? With authentication. What - is authentication? In simple words: Making sure that the sender's - - - -Hadmut Danisch Experimental [Page 33] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - - real identity meets the recipients idea of who is the sender, based - on the sender address which came with the message. - - What is identity? It is the main problem. Several countries have - different ideas of "identity", which turn out to be somehow - incompatible. In some countries people have identity cards and - never change their name and birthday. Identities are created by - human birth, not by identity changes. Other countries do not have - such a tight idea about identity. People's temporary identity is - based on nothing more than a driving license and a social security - number. With this background, it is virtually impossible to create - a trustworthy PKI covering all Internet users. I learned that it is - extremely difficult to convince some people to give up random e- - mail sending. - -14.6. The multi-legislation problem - - Many proposals about fighting spam are feasible under certain - legislations only, and are inacceptable under some of the - legislations. But a world wide applicable method is required. - That's why the approach to ask everone on the world to sign - messages with cryptographic keys is not feasible. - - -Implementation and further Information - - Further informations and a test implementation are available at - - http://www.danisch.de/work/security/antispam.html - http://www.danisch.de/software/rmx/ - - - Additional informations and a technology overview are also - available at - - http://www.mikerubel.org/computers/rmx_records/ - - -References - - - -1. S. Bradner, "Key words for use in RFCs to Indicate Requirement Lev- - els," RFC 2119 (March 1997). - -2. J. Klensin, "Simple Mail Transfer Protocol," RFC 2821 (April 2001). - - - - - -Hadmut Danisch Experimental [Page 34] - -INTERNET-DRAFT DNS RMX RR Oct 2003 - - -3. P. Mockapetris, "DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION," - RFC 1035 (November 1987). - -4. J. Myers, M. Rose, "Post Office Protocol - Version 3," RFC 1939 - (May 1996). - - -Draft History - - 00 Dec 2002 - 01 Apr 2003 - 02 Jun 2003 - 03 Oct 2003 - -Author's Address - - Hadmut Danisch - - Tennesseeallee 58 - 76149 Karlsruhe - Germany - - Phone: ++49-721-843004 or ++49-351-4850477 - E-Mail: rfc@danisch.de - -Comments - - Please send comments to rfc@danisch.de. - -Expiry - - This drafts expires on Apr 1, 2004. - - - - - - - - - - - - - - - - - - - -Hadmut Danisch Experimental [Page 35] - diff --git a/contrib/bind9/doc/draft/draft-dnsext-opcode-discover-02.txt b/contrib/bind9/doc/draft/draft-dnsext-opcode-discover-02.txt deleted file mode 100644 index 7b5e8cc..0000000 --- a/contrib/bind9/doc/draft/draft-dnsext-opcode-discover-02.txt +++ /dev/null @@ -1,241 +0,0 @@ - -IETF DNSEXT WG Bill Manning -draft-dnsext-opcode-discover-02.txt ep.net - Paul Vixie - ISC - 13 Oct 2003 - - - The DISCOVER opcode - -This document is an Internet-Draft and is subject to all provisions of -Section 10 of RFC2026. - -Comments may be submitted to the group mailing list at "mdns@zocalo.net" -or the authors. - -Distribution of this memo is unlimited. - -Internet-Drafts are working documents of the Internet Engineering Task -Force (IETF), its areas, and its working groups. Note that other groups -may also distribute working documents as Internet-Drafts. - -Internet-Drafts are draft documents valid for a maximum of six months and -may be updated, replaced, or obsoleted by other documents at any time. It -is inappropriate to use Internet-Drafts as reference material or to cite -them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - -The capitalized keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", -"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this -document are to be interpreted as described in RFC 2119 - -0. Abstract: - - The QUERY opcode in the DNS is designed for unicast. With the - development of multicast capabilities in the DNS, it is desireable - to have a more robust opcode for server interactions since a single - request may generate replies from multiple responders. So DISCOVER - is defined to deal with replies from multiple responders. - - As such, this document extends the core DNS specifications to allow - clients to have a method for coping with replies from multiple - responders. Use of this new opcode may facilitate DNS operations in - modern networking topologies. A prototype of the DISCOVER opcode - was developed during the TBDS project (1999-2000), funded under DARPA - grant F30602-99-1-0523. - -1. Introduction: - - This document describes an experimental extension to the DNS to receive - multiple responses which is the likely result when using DNS that has - enabled multicast queries. This approach was developed as part of the - TBDS research project, funded under DARPA grant F30602-99-1-0523. The - full processing rules used by TBDS are documented here for possible - incorporation in a future revision of the DNS specification." - -2. Method: - - DISCOVER works like QUERY except: - - 1. it can be sent to a broadcast or multicast destination. QUERY - isn't defined for non-unicast, and arguably shouldn't be. - - 2. the Question section, if present, has - tuples. TBDS tried to augment this structure as follows: - . While this worked for our purposes in - TBDS, it is cleaner to place the SRV question in a separate pass. - - 3. if QDCOUNT equals 0 then only servers willing to do recursion should - answer. Other servers must silently discard the DISCOVER request. - - 4. if QDCOUNT is not equal to 0 then only servers who are authoritative - for the zones named by some QNAME should answer. - - 5. responses may echo the request's Question section or leave it blank, - just like QUERY. - - 6. responses have standard Answer, Authority, and Additional sections. - e.g. the response is the same as that to a QUERY. It is desireable - that zero content answers not be sent to avoid badly formed or - unfulfilled requests. Responses should be sent to the unicast - address of the requester and the source address should reflect - the unicast address of the responder. - - Example usage for gethostby{name,addr}-style requestors: - - Compute the zone name of the enclosing in-addr.arpa, ip6.int, or - ip6.arpa domain. - - DISCOVER whether anyone in-scope is authoritative for this zone. - - If so, query these authoritative servers for local - in-addr/ip6 names. - - If not, DISCOVER whether there are recursive servers available. - - If so, query these recursive servers for local - in-addr/ip6 names. - - So, a node will issue a multicast request with the DISCOVER opcode at - some particular multicast scope. Then determine, from the replies, - whether there are any DNS servers which are authoritative (or support - recursion) for the zone. Replies to DISCOVER requests MUST set the - Recursion Available (RA) flag in the DNS message header. - - It is important to recognize that a requester must be prepared to - receive multiple replies from multiple responders. We expect that - there will be a single response per responder. - - Once one learns a host's FQDN by the above means, repeat the process - for discovering the closest enclosing authoritative server of such - local name. - - Cache all NS and A data learned in this process, respecting TTL's. - - TBDS usage for SRV requestors: - - Do the gethostbyaddr() and gethostbyname() on one's own link-local - address, using the above process. - - Assume that the closest enclosing zone for which an authority server - answers an in-scope DISCOVER packet is "this host's parent domain". - - Compute the SRV name as _service._transport.*.parentdomain. - - This is a change to the definition as defined in RFC 1034. - A wildcard label ("*") in the QNAME used in a DNS message with - opcode DISCOVER SHOULD be evaluated with special rules. The - wildcard matches any label for which the DNS server data is - authoritative. For example 'x.*.example.com.' would match - 'x.y.example.com.' and 'x.yy.example.com.' provided that the - server was authoritative for 'example.com.' In this particular - case, we suggest the follwing considerations be made: - - getservbyname() can be satisfied by issuing a request with - this computed SRV name. This structure can be - populated by values returned from a request as follows: - - s_name The name of the service, "_service" without the - preceding underscore. - s_aliases The names returned in the SRV RRs in replies - to the query. - s_port The port number in the SRV RRs replies to the - query. If these port numbers disagree - one - of the port numbers is chosen, and only those - names which correspond are returned. - s_proto The transport protocol from named by the - "_transport" label, without the preceding - underscore. - - Send SRV query for this name to discovered local authoritative servers. - - Usage for disconnected networks with no authoritative servers: - - Hosts should run a "stub server" which acts as though its FQDN is a - zone name. Computed SOA gives the host's FQDN as MNAME, "." as the - ANAME, seconds-since-1Jan2000 as the SERIAL, low constants for EXPIRE - and the other timers. Compute NS as the host's FQDN. Compute the - glue as the host's link-local address. Or Hosts may run a - "DNS stub server" which acts as though its FQDN is a zone name. The - rules governing the behavior of this stub server are given elsewhere - [1] [2]. - - Such stub servers should answer DISCOVER packets for its zone, and - will be found by the iterative "discover closest enclosing authority - server" by DISCOVER clients, either in the gethostbyname() or SRV - cases described above. Note that stub servers only answer with - zone names which exactly match QNAME's, not with zone names which - are owned by QNAME's. - - The main deviation from the DNS[3][4] model is that a host (like, say, a - printer offering LPD services) has a DNS server which answers authoritatively - for something which hasn't been delegated to it. However, the only way that - such DNS servers can be discovered is with a new opcode, DISCOVER, which - is explicitly defined to discover undelegated zones for tightly scoped - purposes. Therefore this isn't officially a violation of DNS's coherency - principles. In some cases a responder to DISCOVER may not be traditional - DNS software, it could be special purpose software. - -3. IANA Considerations - - As a new opcode, the IANA will need to assign a numeric value - for the memnonic. The last OPCODE assigned was "5", for UPDATE. - Test implementations have used OPCODE "6". - -4. Security Considerations - - No new security considerations are known to be introduced with any new - opcode, however using multicast for service discovery has the potential - for denial of service, primarly from flooding attacks. It may also be - possible to enable deliberate misconfiguration of clients simply by - running a malicious DNS resolver that claims to be authoritative for - things that it is not. One possible way to mitigate this effect is by - use of credentials, such as CERT resource records within an RR set. - The TBDS project took this approach. - -5. Attribution: - - This material was generated in discussions on the mdns mailing list -hosted by Zocalo in March 2000. Updated by discussion in September/October -2003. David Lawrence, Scott Rose, Stuart Cheshire, Bill Woodcock, -Erik Guttman, Bill Manning and Paul Vixie were active contributors. - -6. Author's Address - - Bill Manning - PO 12317 - Marina del Rey, CA. 90295 - +1.310.322.8102 - bmanning@karoshi.com - - Paul Vixie - Internet Software Consortium - 950 Charter Street - Redwood City, CA 94063 - +1 650 779 7001 - - -7. References - -Informational References: - -[1] Esibov, L., Aboba, B., Thaler, D., "Multicast DNS", - draft-ietf-dnsext-mdns-00.txt, November 2000. Expired - -[2] Woodcock, B., Manning, B., "Multicast Domain Name Service", - draft-manning-dnsext-mdns-00.txt, August 2000. Expired. - -Normative References: -[3] Mockapetris, P., "DOMAIN NAMES - CONCEPTS AND FACILITIES", - RFC 1034, November 1987. -[4] Mockapetris, P., "DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION", - RFC 1035, November 1987 - - ----------------------------EOL----------------------- - diff --git a/contrib/bind9/doc/draft/draft-durand-dnsop-dynreverse-00.txt b/contrib/bind9/doc/draft/draft-durand-dnsop-dynreverse-00.txt deleted file mode 100644 index 224e7ad1..0000000 --- a/contrib/bind9/doc/draft/draft-durand-dnsop-dynreverse-00.txt +++ /dev/null @@ -1,240 +0,0 @@ -Internet Engineering Task Force Alain Durand -INTERNET-DRAFT SUN Microsystems -Feb 21, 2003 -Expires Aug 2, 2003 - - - - Dynamic reverse DNS for IPv6 - - - - -Status of this memo - - - This memo provides information to the Internet community. It does - not specify an Internet standard of any kind. This memo is in full - conformance with all provisions of Section 10 of RFC2026 [RFC2026]. - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - - -Abstract - - This document describes a method to dynamically generate PTR records - and corresponding A or AAAA records when the reverse path DNS tree is - not populated. - - A special domain dynrev.arpa. is reserved for that purpose. - - -1. Introduction - - In IPv4, the reverse path tree of the DNS under in-addr.arpa. - although not perfectly maintained, is still mostly usable and its - existence is important for a number of applications that relies on - its existence and decent status. Some applications performs some - (very) weak security checks based on it. Mail relays relies on it for - some anti-spams checks an some FTP server will not let you in unless - your IP address resolve properly with a PTR record. - - IPv6 addresses being much longer (and cumbersome) than IPv4 - addresses, it is to fear that the reverse path tree under ip6.arpa. - would not be as well maintained. Also, tools like 6to4, Isatap and - others have made creative use of the 128 bits of an IPv6 address to - automatically embed an IPv4 address to enable seamless connection to - the IPv6 Internet. However, no provision has been made to make sure - the reverse path tree gets automatically updated as well for those - new IPv6 addresses. One step furter, RFC3041 describes a mechanism - to basically use random bits in the bottom part of an IPv6 address to - preserver anonymity. If those addresses are to resolve in the reverse - path tree, it obviously has to be with anonymous data as well. - Another point to note is that home customer ISPs in IPv4 have a - current practice to pre-populate the reverse path tree with names - automatically derived from the IP addresses. This practice is no - longer possible in IPv6, where IP address allocation is not dense as - it is the case in IPv4. The mere size of typical customer allocation - (2^48 according to the recommendation of RFC3177) makes it - impossible. - - Applications that check the existence of PTR records usually follow - this by checking if the name pointed by the PTR resolve in a A (or - AAAA for IPv6) that match the original IP address. Thus the forward - path tree must also include the corresponding data. - - One simple approach of this problem is to simply declare the usage of - the reverse path DNS as described above obsolete. The author believe - this is too strong an approach for now. - - Similarly, a completely different approach would be to deprecate the - usage of DNS for the reverse tree altogether and replace it by - something inspired from ICMP name-info messages. The author believes - that this approached is an important departure from the current - practise and thus not very realistic. Also, there are some concerns - about the the security implications of this method as any node could - easily impersonate any name. This approach would fundamentally change - the underlying assumption of "I trust what has been put in the DNS by - the local administrators" to "I trust what has been configured on - each machine I query directly". - - - -2. Dynamic record generation - - If static pre-population of the tree is not possible anymore and data - still need to be returned to applications using getnameinfo(), the - alternative is dynamic record generation. This can be done is two - places: in the DNS servers responsible for the allocated space (/64 - or /48) in the ip6.arpa. domain. or in the DNS resolvers (either the - sub resolver library or the recursive DNS server). - - 2.1. On the resolver side. - - The resolver, either in the recursive DNS server or in the stub - library could theoretically generate this data. - - In case DNSsec is in place, the recursive DNS server would have to - pretend these records are authentic. - - If the synthesis is done in the stub-resolver library, no record - needs to be actually generated, only the right information needs to - be passed to getnameinfo() and getaddrinfo(). If the synthesis is - done in the recursive DNS server, no modification is required to - existing stub resolvers. - - -2.2. On the server side. - - PTR records could be generated automatically by the server - responsible for the reverse path tree of an IPv6 prefix (a /64 or /48 - prefixes or basically anything in between) when static data is not - available. - - There could be impact on DNSsec as the zone or some parts of the zone - may need to be resigned each time a DNS query is made for an - unpopulated address. This can be seen as a DOS attack on a DNSsec - zone, so server side synthesis is not recommended if DNSsec is - deployed. - - - -3. Synthesis - - The algorithm is simple: Do the normal queries. If the query returns - No such domain, replace this answer by the synthetized one if - possible. - -3.1. PTR synthesis - - The synthetized PTR for a DNS string [X] is simply [X].dynrev.arpa. - where [X] is any valid DNS name. - - The fact that the synthetized PTR points to the dynrev.arpa. domain - is an indication to the applications that this record has been - dynamically generated. - - -3.2. A synthesis - - If [X] is in the form a.b.c.d.in-addr.arpa, one can synthetized an A - record for the string [X].dynrev.arpa. which value is d.c.b.a. with - a,b,c & d being integer [0..255] - - -3.3. AAAA synthesis - - If [X] is in the form - a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.s.t.u.v.w.x.y.z.A.B.C.D.E.F.in- - addr.arpa, one can synthetized a AAAA record for the string - [X].dynrev.arpa. which value is - FEDC:BAzy:xwvu:tsrq:ponm:lkji:hgfe:dcba with - a,b,c....x,y,z,A,B,C,D,E,F being hexadecimal digits. - - -3.4. Server side synthesis - - If synthesis is done on the server side, PTR could be set not to use - the dynrev.arpa domain but the local domain name instead. It culd be - for instance dynrev.mydomain.com. - - Note also that server side synthesis is not incompatible with - resolver side synthesis. - - - -4. IANA considerations - - The dynrev.arpa. domain is reserved for the purpose of this document. - - - -5. Security considerations - - Section 2. discusses the the interactions with DNSsec. - - - -6. Authors addresses - - Alain Durand - SUN Microsystems, Inc - 17, Network Circle - UMPK17-202 - Menlo Park, CA 94025 - USA - Mail: Alain.Durand@sun.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-2929bis-01.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-2929bis-01.txt deleted file mode 100644 index fa41e76..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-2929bis-01.txt +++ /dev/null @@ -1,928 +0,0 @@ - -INTERNET-DRAFT Donald E. Eastlake 3rd -Obsoletes RFC 2929, Updates RFC 1183 Motorola Laboratories -Expires: February 2006 August 2005 - - - - Domain Name System (DNS) IANA Considerations - ------ ---- ------ ----- ---- -------------- - - - - -Status of This Document - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Distribution of this draft is unlimited. It is intended to become - the new BCP 42 obsoleting RFC 2929. Comments should be sent to the - DNS Working Group mailing list . - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than a "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/1id-abstracts.html - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html - - - -Abstract - - Internet Assigned Number Authority (IANA) parameter assignment - considerations are given for the allocation of Domain Name System - (DNS) classes, RR types, operation codes, error codes, RR header - bits, and AFSDB subtypes. - - - - - - - - -D. Eastlake 3rd [Page 1] - - -INTERNET-DRAFT DNS IANA Considerations August 2005 - - -Table of Contents - - Status of This Document....................................1 - Abstract...................................................1 - - Table of Contents..........................................2 - - 1. Introduction............................................3 - 2. DNS Query/Response Headers..............................3 - 2.1 One Spare Bit?.........................................4 - 2.2 Opcode Assignment......................................4 - 2.3 RCODE Assignment.......................................5 - 3. DNS Resource Records....................................6 - 3.1 RR TYPE IANA Considerations............................7 - 3.1.1 DNS TYPE Allocation Policy...........................8 - 3.1.2 Special Note on the OPT RR...........................9 - 3.1.3 The AFSDB RR Subtype Field...........................9 - 3.2 RR CLASS IANA Considerations...........................9 - 3.3 RR NAME Considerations................................11 - 4. Security Considerations................................11 - - Appendix: Changes from RFC 2929...........................12 - - Copyright and Disclaimer..................................13 - Normative References......................................13 - Informative References....................................14 - - Authors Addresses.........................................16 - Expiration and File Name..................................16 - - - - - - - - - - - - - - - - - - - - - - - -D. Eastlake 3rd [Page 2] - - -INTERNET-DRAFT DNS IANA Considerations August 2005 - - -1. Introduction - - The Domain Name System (DNS) provides replicated distributed secure - hierarchical databases which hierarchically store "resource records" - (RRs) under domain names. DNS data is structured into CLASSes and - zones which can be independently maintained. See [RFC 1034, 1035, - 2136, 2181, 4033] familiarity with which is assumed. - - This document provides, either directly or by reference, general IANA - parameter assignment considerations applying across DNS query and - response headers and all RRs. There may be additional IANA - considerations that apply to only a particular RR type or - query/response opcode. See the specific RFC defining that RR type or - query/response opcode for such considerations if they have been - defined, except for AFSDB RR considerations [RFC 1183] which are - included herein. This RFC obsoletes [RFC 2929]. - - IANA currently maintains a web page of DNS parameters. See - . - - "IETF Standards Action", "IETF Consensus", "Specification Required", - and "Private Use" are as defined in [RFC 2434]. - - - -2. DNS Query/Response Headers - - The header for DNS queries and responses contains field/bits in the - following diagram taken from [RFC 2136, 2929]: - - 1 1 1 1 1 1 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | ID | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - |QR| Opcode |AA|TC|RD|RA| Z|AD|CD| RCODE | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | QDCOUNT/ZOCOUNT | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | ANCOUNT/PRCOUNT | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | NSCOUNT/UPCOUNT | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | ARCOUNT | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - - The ID field identifies the query and is echoed in the response so - they can be matched. - - The QR bit indicates whether the header is for a query or a response. - - -D. Eastlake 3rd [Page 3] - - -INTERNET-DRAFT DNS IANA Considerations August 2005 - - - The AA, TC, RD, RA, AD, and CD bits are each theoretically meaningful - only in queries or only in responses, depending on the bit. However, - many DNS implementations copy the query header as the initial value - of the response header without clearing bits. Thus any attempt to - use a "query" bit with a different meaning in a response or to define - a query meaning for a "response" bit is dangerous given existing - implementation. Such meanings may only be assigned by an IETF - Standards Action. - - The unsigned fields query count (QDCOUNT), answer count (ANCOUNT), - authority count (NSCOUNT), and additional information count (ARCOUNT) - express the number of records in each section for all opcodes except - Update. These fields have the same structure and data type for - Update but are instead the counts for the zone (ZOCOUNT), - prerequisite (PRCOUNT), update (UPCOUNT), and additional information - (ARCOUNT) sections. - - - -2.1 One Spare Bit? - - There have been ancient DNS implementations for which the Z bit being - on in a query meant that only a response from the primary server for - a zone is acceptable. It is believed that current DNS - implementations ignore this bit. - - Assigning a meaning to the Z bit requires an IETF Standards Action. - - - -2.2 Opcode Assignment - - Currently DNS OpCodes are assigned as follows: - - OpCode Name Reference - - 0 Query [RFC 1035] - 1 IQuery (Inverse Query, Obsolete) [RFC 3425] - 2 Status [RFC 1035] - 3 available for assignment - 4 Notify [RFC 1996] - 5 Update [RFC 2136] - 6-15 available for assignment - - New OpCode assignments require an IETF Standards Action as modified - by [RFC 4020]. - - - - - - -D. Eastlake 3rd [Page 4] - - -INTERNET-DRAFT DNS IANA Considerations August 2005 - - -2.3 RCODE Assignment - - It would appear from the DNS header above that only four bits of - RCODE, or response/error code are available. However, RCODEs can - appear not only at the top level of a DNS response but also inside - OPT RRs [RFC 2671], TSIG RRs [RFC 2845], and TKEY RRs [RFC 2930]. - The OPT RR provides an eight bit extension resulting in a 12 bit - RCODE field and the TSIG and TKEY RRs have a 16 bit RCODE field. - - Error codes appearing in the DNS header and in these three RR types - all refer to the same error code space with the single exception of - error code 16 which has a different meaning in the OPT RR from its - meaning in other contexts. See table below. - - RCODE Name Description Reference - Decimal - Hexadecimal - 0 NoError No Error [RFC 1035] - 1 FormErr Format Error [RFC 1035] - 2 ServFail Server Failure [RFC 1035] - 3 NXDomain Non-Existent Domain [RFC 1035] - 4 NotImp Not Implemented [RFC 1035] - 5 Refused Query Refused [RFC 1035] - 6 YXDomain Name Exists when it should not [RFC 2136] - 7 YXRRSet RR Set Exists when it should not [RFC 2136] - 8 NXRRSet RR Set that should exist does not [RFC 2136] - 9 NotAuth Server Not Authoritative for zone [RFC 2136] - 10 NotZone Name not contained in zone [RFC 2136] - 11 - 15 Available for assignment - 16 BADVERS Bad OPT Version [RFC 2671] - 16 BADSIG TSIG Signature Failure [RFC 2845] - 17 BADKEY Key not recognized [RFC 2845] - 18 BADTIME Signature out of time window [RFC 2845] - 19 BADMODE Bad TKEY Mode [RPC 2930] - 20 BADNAME Duplicate key name [RPF 2930] - 21 BADALG Algorithm not supported [RPF 2930] - - 22 - 3,840 - 0x0016 - 0x0F00 Available for assignment - - 3,841 - 4,095 - 0x0F01 - 0x0FFF Private Use - - 4,096 - 65,534 - 0x1000 - 0xFFFE Available for assignment - - 65,535 - 0xFFFF Reserved, can only be allocated by an IETF - Standards Action. - - - -D. Eastlake 3rd [Page 5] - - -INTERNET-DRAFT DNS IANA Considerations August 2005 - - - Since it is important that RCODEs be understood for interoperability, - assignment of new RCODE listed above as "available for assignment" - requires an IETF Consensus. - - - -3. DNS Resource Records - - All RRs have the same top level format shown in the figure below - taken from [RFC 1035]: - - 1 1 1 1 1 1 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | | - / / - / NAME / - | | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | TYPE | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | CLASS | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | TTL | - | | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | RDLENGTH | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| - / RDATA / - / / - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - - NAME is an owner name, i.e., the name of the node to which this - resource record pertains. NAMEs are specific to a CLASS as described - in section 3.2. NAMEs consist of an ordered sequence of one or more - labels each of which has a label type [RFC 1035, 2671]. - - TYPE is a two octet unsigned integer containing one of the RR TYPE - codes. See section 3.1. - - CLASS is a two octet unsigned integer containing one of the RR CLASS - codes. See section 3.2. - - TTL is a four octet (32 bit) bit unsigned integer that specifies the - number of seconds that the resource record may be cached before the - source of the information should again be consulted. Zero is - interpreted to mean that the RR can only be used for the transaction - in progress. - - RDLENGTH is an unsigned 16 bit integer that specifies the length in - - -D. Eastlake 3rd [Page 6] - - -INTERNET-DRAFT DNS IANA Considerations August 2005 - - - octets of the RDATA field. - - RDATA is a variable length string of octets that constitutes the - resource. The format of this information varies according to the TYPE - and in some cases the CLASS of the resource record. - - - -3.1 RR TYPE IANA Considerations - - There are three subcategories of RR TYPE numbers: data TYPEs, QTYPEs, - and MetaTYPEs. - - Data TYPEs are the primary means of storing data. QTYPES can only be - used in queries. Meta-TYPEs designate transient data associated with - an particular DNS message and in some cases can also be used in - queries. Thus far, data TYPEs have been assigned from 1 upwards plus - the block from 100 through 103 while Q and Meta Types have been - assigned from 255 downwards except for the OPT Meta-RR which is - assigned TYPE 41. There have been DNS implementations which made - caching decisions based on the top bit of the bottom byte of the RR - TYPE. - - There are currently three Meta-TYPEs assigned: OPT [RFC 2671], TSIG - [RFC 2845], and TKEY [RFC 2930]. - - There are currently five QTYPEs assigned: * (all), MAILA, MAILB, - AXFR, and IXFR. - - Considerations for the allocation of new RR TYPEs are as follows: - - Decimal - Hexadecimal - - 0 - 0x0000 - TYPE zero is used as a special indicator for the SIG RR [RFC - 2535] and in other circumstances and must never be allocated - for ordinary use. - - 1 - 127 - 0x0001 - 0x007F - remaining TYPEs in this range are assigned for data - TYPEs by the DNS TYPE Allocation Policy as specified in - section 3.1.1. - - 128 - 255 - 0x0080 - 0x00FF - remaining TYPEs in this rage are assigned for Q and - Meta TYPEs by the DNS TYPE Allocation Policy as specified in - section 3.1.1. - - - - -D. Eastlake 3rd [Page 7] - - -INTERNET-DRAFT DNS IANA Considerations August 2005 - - - 256 - 32,767 - 0x0100 - 0x7FFF - assigned for data, Q, or Meta TYPE use by the DNS - TYPE Allocation Policy as specified in section 3.1.1. - - 32,768 - 65,279 - 0x8000 - 0xFEFF - Specification Required as defined in [RFC 2434]. - - 65,280 - 65534 - 0xFF00 - 0xFFFE - Private Use. - - 65,535 - 0xFFFF - Reserved, can only be assigned by an IETF Standards Action. - - - -3.1.1 DNS TYPE Allocation Policy - - Parameter values specified above as assigned based on DNS TYPE - Allocation Policy. That is, Expert Review with the additional - requirement that the review be based on a complete template as - specified below which has been posted for three weeks to the - namedroppers@ops.ietf.org mailing list. - - Partial or draft templates may be posted with the intend of - soliciting feedback. - - - DNS RR TYPE PARAMETER ALLOCATION TEMPLATE - - Date: - - Name and email of originator: - - Pointer to internet-draft or other document giving a detailed - description of the protocol use of the new RR Type: - - What need is the new RR TYPE intended to fix? - - What existing RR TYPE(s) come closest to filling that need and why are - they unsatisfactory? - - Does the proposed RR TYPR require special handling within the DNS - different from an Unknown RR TYPE? - - Comments: - - - - - - - -D. Eastlake 3rd [Page 8] - - -INTERNET-DRAFT DNS IANA Considerations August 2005 - - -3.1.2 Special Note on the OPT RR - - The OPT (OPTion) RR, number 41, is specified in [RFC 2671]. Its - primary purpose is to extend the effective field size of various DNS - fields including RCODE, label type, OpCode, flag bits, and RDATA - size. In particular, for resolvers and servers that recognize it, it - extends the RCODE field from 4 to 12 bits. - - - -3.1.3 The AFSDB RR Subtype Field - - The AFSDB RR [RFC 1183] is a CLASS insensitive RR that has the same - RDATA field structure as the MX RR but the 16 bit unsigned integer - field at the beginning of the RDATA is interpreted as a subtype as - follows: - - Decimal - Hexadecimal - - 0 - 0x0000 - Allocation requires IETF Standards Action. - - 1 - 0x0001 - Andrews File Service v3.0 Location Service [RFC 1183]. - - 2 - 0x0002 - DCE/NCA root cell directory node [RFC 1183]. - - 3 - 65,279 - 0x0003 - 0xFEFF - Allocation by IETF Consensus. - - 65,280 - 65,534 - 0xFF00 - 0xFFFE - Private Use. - - 65,535 - 0xFFFF - Reserved, allocation requires IETF Standards Action. - - - -3.2 RR CLASS IANA Considerations - - DNS CLASSes have been little used but constitute another dimension of - the DNS distributed database. In particular, there is no necessary - relationship between the name space or root servers for one CLASS and - those for another CLASS. The same name can have completely different - meanings in different CLASSes; however, the label types are the same - and the null label is usable only as root in every CLASS. However, - as global networking and DNS have evolved, the IN, or Internet, CLASS - has dominated DNS use. - - -D. Eastlake 3rd [Page 9] - - -INTERNET-DRAFT DNS IANA Considerations August 2005 - - - There are two subcategories of DNS CLASSes: normal data containing - classes and QCLASSes that are only meaningful in queries or updates. - - The current CLASS assignments and considerations for future - assignments are as follows: - - Decimal - Hexadecimal - - 0 - 0x0000 - Reserved, assignment requires an IETF Standards Action. - - 1 - 0x0001 - Internet (IN). - - 2 - 0x0002 - Available for assignment by IETF Consensus as a data CLASS. - - 3 - 0x0003 - Chaos (CH) [Moon 1981]. - - 4 - 0x0004 - Hesiod (HS) [Dyer 1987]. - - 5 - 127 - 0x0005 - 0x007F - available for assignment by IETF Consensus for data - CLASSes only. - - 128 - 253 - 0x0080 - 0x00FD - available for assignment by IETF Consensus for - QCLASSes only. - - 254 - 0x00FE - QCLASS None [RFC 2136]. - - 255 - 0x00FF - QCLASS Any [RFC 1035]. - - 256 - 32,767 - 0x0100 - 0x7FFF - Assigned by IETF Consensus. - - 32,768 - 65,279 - 0x8000 - 0xFEFF - Assigned based on Specification Required as defined - in [RFC 2434]. - - 65,280 - 65,534 - 0xFF00 - 0xFFFE - Private Use. - - 65,535 - 0xFFFF - Reserved, can only be assigned by an IETF Standards Action. - - -D. Eastlake 3rd [Page 10] - - -INTERNET-DRAFT DNS IANA Considerations August 2005 - - -3.3 RR NAME Considerations - - DNS NAMEs are sequences of labels [RFC 1035]. The last label in each - NAME is "ROOT" which is the zero length label. By definition, the - null or ROOT label can not be used for any other NAME purpose. - - At the present time, there are two categories of label types, data - labels and compression labels. Compression labels are pointers to - data labels elsewhere within an RR or DNS message and are intended to - shorten the wire encoding of NAMEs. The two existing data label - types are sometimes referred to as Text and Binary. Text labels can, - in fact, include any octet value including zero value octets but most - current uses involve only [US-ASCII]. For retrieval, Text labels are - defined to treat ASCII upper and lower case letter codes as matching - [insensitive]. Binary labels are bit sequences [RFC 2673]. The - Binary label type is Experimental [RFC 3363]. - - IANA considerations for label types are given in [RFC 2671]. - - NAMEs are local to a CLASS. The Hesiod [Dyer 1987] and Chaos [Moon - 1981] CLASSes are essentially for local use. The IN or Internet - CLASS is thus the only DNS CLASS in global use on the Internet at - this time. - - A somewhat out-of-date description of name allocation in the IN Class - is given in [RFC 1591]. Some information on reserved top level - domain names is in BCP 32 [RFC 2606]. - - - -4. Security Considerations - - This document addresses IANA considerations in the allocation of - general DNS parameters, not security. See [RFC 4033, 4034, 4035] for - secure DNS considerations. - - - - - - - - - - - - - - - - - -D. Eastlake 3rd [Page 11] - - -INTERNET-DRAFT DNS IANA Considerations August 2005 - - -Appendix: Changes from RFC 2929 - - RFC Editor: This Appendix should be deleted for publication. - - Changes from RFC 2929 to this draft: - - 1. Changed many "IETF Consensus" for RR TYPEs to be "DNS TYPE - Allocation Policy" and add the specification of that policy. Change - some remaining "IETF Standards Action" allocation requirements to say - "as modified by [RFC 4020]". - - 2. Updated various RFC references. - - 3. Mentioned that the Binary label type is now Experimental and - IQuery is Obsolete. - - 4. Changed allocation status of RR Type 0xFFFF and RCODE 0xFFFF to be - IETF Standards Action required. - - 5. Add an IANA allocation policy for the AFSDB RR Subtype field. - - 6. Addition of reference to case insensitive draft. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -D. Eastlake 3rd [Page 12] - - -INTERNET-DRAFT DNS IANA Considerations August 2005 - - -Copyright and Disclaimer - - Copyright (C) The Internet Society (2005). This document is subject to - the rights, licenses and restrictions contained in BCP 78, and except - as set forth therein, the authors retain all their rights. - - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - -Normative References - - [RFC 1034] - Mockapetris, P., "Domain Names - Concepts and - Facilities", STD 13, RFC 1034, November 1987. - - [RFC 1035] - Mockapetris, P., "Domain Names - Implementation and - Specifications", STD 13, RFC 1035, November 1987. - - [RFC 1183] - Everhart, C., Mamakos, L., Ullmann, R., and P. - Mockapetris, "New DNS RR Definitions", RFC 1183, October 1990. - - [RFC 1996] - Vixie, P., "A Mechanism for Prompt Notification of Zone - Changes (DNS NOTIFY)", RFC 1996, August 1996. - - [RFC 2136] - Vixie, P., Thomson, S., Rekhter, Y. and J. Bound, - "Dynamic Updates in the Domain Name System (DNS UPDATE)", RFC 2136, - April 1997. - - [RFC 2181] - Elz, R. and R. Bush, "Clarifications to the DNS - Specification", RFC 2181, July 1997. - - [RFC 2434] - Narten, T. and H. Alvestrand, "Guidelines for Writing an - IANA Considerations Section in RFCs", BCP 26, RFC 2434, October 1998. - - [RFC 2671] - Vixie, P., "Extension mechanisms for DNS (EDNS0)", RFC - 2671, August 1999. - - [RFC 2673] - Crawford, M., "Binary Labels in the Domain Name System", - RFC 2673, August 1999. - - [RFC 2845] - Vixie, P., Gudmundsson, O., Eastlake, D. and B. - Wellington, "Secret Key Transaction Authentication for DNS (TSIG)", - RFC 2845, May 2000. - - -D. Eastlake 3rd [Page 13] - - -INTERNET-DRAFT DNS IANA Considerations August 2005 - - - [RFC 2930] - Eastlake, D., "Secret Key Establishment for DNS (TKEY - RR)", September 2000. - - [RFC 3363] - Bush, R., Durand, A., Fink, B., Gudmundsson, O., and T. - Hain, "Representing Internet Protocol version 6 (IPv6) Addresses in - the Domain Name System (DNS)", RFC 3363, August 2002. - - [RFC 3425] - Lawrence, D., "Obsoleting IQUERY", RFC 3425, November - 2002. - - [RFC 4020] - Kompella, K. and A. Zinin, "Early IANA Allocation of - Standards Track Code Points", BCP 100, RFC 4020, February 2005. - - [RFC 4033] - Arends, R., Austein, R., Larson, M., Massey, D., and S. - Rose, "DNS Security Introduction and Requirements", RFC 4033, March - 2005. - - [RFC 4034] - Arends, R., Austein, R., Larson, M., Massey, D., and S. - Rose, "Resource Records for the DNS Security Extensions", RFC 4034, - March 2005. - - [RFC 4044] - Arends, R., Austein, R., Larson, M., Massey, D., and S. - Rose, "Protocol Modifications for the DNS Security Extensions", RFC - 4035, March 2005. - - [US-ASCII] - ANSI, "USA Standard Code for Information Interchange", - X3.4, American National Standards Institute: New York, 1968. - - - -Informative References - - [Dyer 1987] - Dyer, S., and F. Hsu, "Hesiod", Project Athena - Technical Plan - Name Service, April 1987, - - [Moon 1981] - D. Moon, "Chaosnet", A.I. Memo 628, Massachusetts - Institute of Technology Artificial Intelligence Laboratory, June - 1981. - - [RFC 1591] - Postel, J., "Domain Name System Structure and - Delegation", RFC 1591, March 1994. - - [RFC 2929] - Eastlake 3rd, D., Brunner-Williams, E., and B. Manning, - "Domain Name System (DNS) IANA Considerations", BCP 42, RFC 2929, - September 2000. - - [RFC 2606] - Eastlake, D. and A. Panitz, "Reserved Top Level DNS - Names", RFC 2606, June 1999. - - [insensitive] - Eastlake, D., "Domain Name System (DNS) Case - - -D. Eastlake 3rd [Page 14] - - -INTERNET-DRAFT DNS IANA Considerations August 2005 - - - Insensitivity Clarification", draft-ietf-dnsext-insensitive-*.txt, - work in progress. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -D. Eastlake 3rd [Page 15] - - -INTERNET-DRAFT DNS IANA Considerations August 2005 - - -Authors Addresses - - Donald E. Eastlake 3rd - Motorola Laboratories - 155 Beaver Street - Milford, MA 01757 USA - - Telephone: +1-508-786-7554 (w) - email: Donald.Eastlake@motorola.com - - - -Expiration and File Name - - This draft expires February 2006. - - Its file name is draft-ietf-dnsext-2929bis-01.txt. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -D. Eastlake 3rd [Page 16] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-axfr-clarify-05.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-axfr-clarify-05.txt deleted file mode 100644 index f0ce70a..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-axfr-clarify-05.txt +++ /dev/null @@ -1,393 +0,0 @@ - - - -INTERNET-DRAFT Andreas Gustafsson -draft-ietf-dnsext-axfr-clarify-05.txt Nominum Inc. - November 2002 - - - DNS Zone Transfer Protocol Clarifications - - -Status of this Memo - - This document is an Internet-Draft and is in full conformance with - all provisions of Section 10 of RFC2026. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - -Abstract - - In the Domain Name System, zone data is replicated among - authoritative DNS servers by means of the "zone transfer" protocol, - also known as the "AXFR" protocol. This memo clarifies, updates, and - adds missing detail to the original AXFR protocol specification in - RFC1034. - -1. Introduction - - The original definition of the DNS zone transfer protocol consists of - a single paragraph in [RFC1034] section 4.3.5 and some additional - notes in [RFC1035] section 6.3. It is not sufficiently detailed to - serve as the sole basis for constructing interoperable - implementations. This document is an attempt to provide a more - complete definition of the protocol. Where the text in RFC1034 - conflicts with existing practice, the existing practice has been - codified in the interest of interoperability. - - - - -Expires May 2003 [Page 1] - -draft-ietf-dnsext-axfr-clarify-05.txt November 2002 - - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in [RFC 2119]. - -2. The zone transfer request - - To initiate a zone transfer, the slave server sends a zone transfer - request to the master server over a reliable transport such as TCP. - The form of this request is specified in sufficient detail in RFC1034 - and needs no further clarification. - - Implementers are advised that one server implementation in widespread - use sends AXFR requests where the TCP message envelope size exceeds - the DNS request message size by two octets. - -3. The zone transfer response - - If the master server is unable or unwilling to provide a zone - transfer, it MUST respond with a single DNS message containing an - appropriate RCODE other than NOERROR. If the master is not - authoritative for the requested zone, the RCODE SHOULD be 9 - (NOTAUTH). - - Slave servers should note that some master server implementations - will simply close the connection when denying the slave access to the - zone. Therefore, slaves MAY interpret an immediate graceful close of - the TCP connection as equivalent to a "Refused" response (RCODE 5). - - If a zone transfer can be provided, the master server sends one or - more DNS messages containing the zone data as described below. - -3.1. Multiple answers per message - - The zone data in a zone transfer response is a sequence of answer - RRs. These RRs are transmitted in the answer section(s) of one or - more DNS response messages. - - The AXFR protocol definition in RFC1034 does not make a clear - distinction between response messages and answer RRs. Historically, - DNS servers always transmitted a single answer RR per message. This - encoding is wasteful due to the overhead of repeatedly sending DNS - message headers and the loss of domain name compression - opportunities. To improve efficiency, some newer servers support a - mode where multiple RRs are transmitted in a single DNS response - message. - - A master MAY transmit multiple answer RRs per response message up to - the largest number that will fit within the 65535 byte limit on TCP - - - -Expires May 2003 [Page 2] - -draft-ietf-dnsext-axfr-clarify-05.txt November 2002 - - - DNS message size. In the case of a small zone, this can cause the - entire transfer to be transmitted in a single response message. - - Slaves MUST accept messages containing any number of answer RRs. For - compatibility with old slaves, masters that support sending multiple - answers per message SHOULD be configurable to revert to the - historical mode of one answer per message, and the configuration - SHOULD be settable on a per-slave basis. - -3.2. DNS message header contents - - RFC1034 does not specify the contents of the DNS message header of - the zone transfer response messages. The header of each message MUST - be as follows: - - ID Copy from request - QR 1 - OPCODE QUERY - AA 1, but MAY be 0 when RCODE is not NOERROR - TC 0 - RD Copy from request, or 0 - RA Set according to availability of recursion, or 0 - Z 0 - AD 0 - CD 0 - RCODE NOERROR on success, error code otherwise - - The slave MUST check the RCODE in each message and abort the transfer - if it is not NOERROR. It SHOULD check the ID of the first message - received and abort the transfer if it does not match the ID of the - request. The ID SHOULD be ignored in subsequent messages, and fields - other than RCODE and ID SHOULD be ignored in all messages, to ensure - interoperability with certain older implementations which transmit - incorrect or arbitrary values in these fields. - -3.3. Additional section and SIG processing - - Zone transfer responses are not subject to any kind of additional - section processing or automatic inclusion of SIG records. SIG RRs in - the zone data are treated exactly the same as any other RR type. - -3.4. The question section - - RFC1034 does not specify whether zone transfer response messages have - a question section or not. The initial message of a zone transfer - response SHOULD have a question section identical to that in the - request. Subsequent messages SHOULD NOT have a question section, - though the final message MAY. The receiving slave server MUST accept - - - -Expires May 2003 [Page 3] - -draft-ietf-dnsext-axfr-clarify-05.txt November 2002 - - - any combination of messages with and without a question section. - -3.5. The authority section - - The master server MUST transmit messages with an empty authority - section. Slaves MUST ignore any authority section contents they may - receive from masters that do not comply with this requirement. - -3.6. The additional section - - The additional section MAY contain additional RRs such as transaction - signatures. The slave MUST ignore any unexpected RRs in the - additional section. It MUST NOT treat additional section RRs as zone - data. - -4. Zone data - - The purpose of the zone transfer mechanism is to exactly replicate at - each slave the set of RRs associated with a particular zone at its - primary master. An RR is associated with a zone by being loaded from - the master file of that zone at the primary master server, or by some - other, equivalent method for configuring zone data. - - This replication shall be complete and unaltered, regardless of how - many and which intermediate masters/slaves are involved, and - regardless of what other zones those intermediate masters/slaves do - or do not serve, and regardless of what data may be cached in - resolvers associated with the intermediate masters/slaves. - - Therefore, in a zone transfer the master MUST send exactly those - records that are associated with the zone, whether or not their owner - names would be considered to be "in" the zone for purposes of - resolution, and whether or not they would be eligible for use as glue - in responses. The transfer MUST NOT include any RRs that are not - associated with the zone, such as RRs associated with zones other - than the one being transferred or present in the cache of the local - resolver, even if their owner names are in the zone being transferred - or are pointed to by NS records in the zone being transferred. - - The slave MUST associate the RRs received in a zone transfer with the - specific zone being transferred, and maintain that association for - purposes of acting as a master in outgoing transfers. - -5. Transmission order - - RFC1034 states that "The first and last messages must contain the - data for the top authoritative node of the zone". This is not - consistent with existing practice. All known master implementations - - - -Expires May 2003 [Page 4] - -draft-ietf-dnsext-axfr-clarify-05.txt November 2002 - - - send, and slave implementations expect to receive, the zone's SOA RR - as the first and last record of the transfer. - - Therefore, the quoted sentence is hereby superseded by the sentence - "The first and last RR transmitted must be the SOA record of the - zone". - - The initial and final SOA record MUST be identical, with the possible - exception of case and compression. In particular, they MUST have the - same serial number. The slave MUST consider the transfer to be - complete when, and only when, it has received the message containing - the second SOA record. - - The transmission order of all other RRs in the zone is undefined. - Each of them SHOULD be transmitted only once, and slaves MUST ignore - any duplicate RRs received. - -6. Security Considerations - - The zone transfer protocol as defined in [RFC1034] and clarified by - this memo does not have any built-in mechanisms for the slave to - securely verify the identity of the master server and the integrity - of the transferred zone data. The use of a cryptographic mechanism - for ensuring authenticity and integrity, such as TSIG [RFC2845], - IPSEC, or TLS, is RECOMMENDED. - - The zone transfer protocol allows read-only public access to the - complete zone data. Since data in the DNS is public by definition, - this is generally acceptable. Sites that wish to avoid disclosing - their full zone data MAY restrict zone transfer access to authorized - slaves. - - These clarifications are not believed to themselves introduce any new - security problems, nor to solve any existing ones. - -Acknowledgements - - Many people have contributed input and commentary to earlier versions - of this document, including but not limited to Bob Halley, Dan - Bernstein, Eric A. Hall, Josh Littlefield, Kevin Darcy, Robert Elz, - Levon Esibov, Mark Andrews, Michael Patton, Peter Koch, Sam - Trenholme, and Brian Wellington. - -References - - [RFC1034] - Domain Names - Concepts and Facilities, P. Mockapetris, - November 1987. - - - - -Expires May 2003 [Page 5] - -draft-ietf-dnsext-axfr-clarify-05.txt November 2002 - - - [RFC1035] - Domain Names - Implementation and Specifications, P. - Mockapetris, November 1987. - - [RFC2119] - Key words for use in RFCs to Indicate Requirement Levels, - S. Bradner, BCP 14, March 1997. - - [RFC2845] - Secret Key Transaction Authentication for DNS (TSIG). P. - Vixie, O. Gudmundsson, D. Eastlake, B. Wellington, May 2000. - -Author's Address - - Andreas Gustafsson - Nominum Inc. - 2385 Bay Rd - Redwood City, CA 94063 - USA - - Phone: +1 650 381 6004 - - Email: gson@nominum.com - - -Full Copyright Statement - - Copyright (C) The Internet Society (2000 - 2002). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implmentation may be prepared, copied, published and - distributed, in whole or in part, without restriction of any kind, - provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - - - -Expires May 2003 [Page 6] - -draft-ietf-dnsext-axfr-clarify-05.txt November 2002 - - - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE." - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Expires May 2003 [Page 7] - - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-dhcid-rr-12.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-dhcid-rr-12.txt deleted file mode 100644 index 07749d9..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-dhcid-rr-12.txt +++ /dev/null @@ -1,674 +0,0 @@ - - - - -DNSEXT M. Stapp -Internet-Draft Cisco Systems, Inc. -Expires: September 1, 2006 T. Lemon - Nominum, Inc. - A. Gustafsson - Araneus Information Systems Oy - February 28, 2006 - - - A DNS RR for Encoding DHCP Information (DHCID RR) - - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on September 1, 2006. - -Copyright Notice - - Copyright (C) The Internet Society (2006). - -Abstract - - It is possible for DHCP clients to attempt to update the same DNS - FQDN or attempt to update a DNS FQDN that has been added to the DNS - for another purpose as they obtain DHCP leases. Whether the DHCP - server or the clients themselves perform the DNS updates, conflicts - can arise. To resolve such conflicts, "Resolution of DNS Name - - - -Stapp, et al. Expires September 1, 2006 [Page 1] - -Internet-Draft The DHCID RR February 2006 - - - Conflicts" [1] proposes storing client identifiers in the DNS to - unambiguously associate domain names with the DHCP clients to which - they refer. This memo defines a distinct RR type for this purpose - for use by DHCP clients and servers, the "DHCID" RR. - - -Table of Contents - - 1. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 3. The DHCID RR . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 3.1. DHCID RDATA format . . . . . . . . . . . . . . . . . . . . 3 - 3.2. DHCID Presentation Format . . . . . . . . . . . . . . . . 4 - 3.3. The DHCID RR Identifier Type Codes . . . . . . . . . . . . 4 - 3.4. The DHCID RR Digest Type Code . . . . . . . . . . . . . . 4 - 3.5. Computation of the RDATA . . . . . . . . . . . . . . . . . 5 - 3.5.1. Using the Client's DUID . . . . . . . . . . . . . . . 5 - 3.5.2. Using the Client Identifier Option . . . . . . . . . . 5 - 3.5.3. Using the Client's htype and chaddr . . . . . . . . . 6 - 3.6. Examples . . . . . . . . . . . . . . . . . . . . . . . . . 6 - 3.6.1. Example 1 . . . . . . . . . . . . . . . . . . . . . . 6 - 3.6.2. Example 2 . . . . . . . . . . . . . . . . . . . . . . 6 - 3.6.3. Example 3 . . . . . . . . . . . . . . . . . . . . . . 7 - 4. Use of the DHCID RR . . . . . . . . . . . . . . . . . . . . . 7 - 5. Updater Behavior . . . . . . . . . . . . . . . . . . . . . . . 8 - 6. Security Considerations . . . . . . . . . . . . . . . . . . . 8 - 7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 8 - 8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 9 - 9. References . . . . . . . . . . . . . . . . . . . . . . . . . . 9 - 9.1. Normative References . . . . . . . . . . . . . . . . . . . 9 - 9.2. Informative References . . . . . . . . . . . . . . . . . . 10 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 11 - Intellectual Property and Copyright Statements . . . . . . . . . . 12 - - - - - - - - - - - - - - - - - - -Stapp, et al. Expires September 1, 2006 [Page 2] - -Internet-Draft The DHCID RR February 2006 - - -1. Terminology - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in RFC 2119 [2]. - - -2. Introduction - - A set of procedures to allow DHCP [6] [10] clients and servers to - automatically update the DNS (RFC 1034 [3], RFC 1035 [4]) is proposed - in "Resolution of DNS Name Conflicts" [1]. - - Conflicts can arise if multiple DHCP clients wish to use the same DNS - name or a DHCP client attempts to use a name added for another - purpose. To resolve such conflicts, "Resolution of DNS Name - Conflicts" [1] proposes storing client identifiers in the DNS to - unambiguously associate domain names with the DHCP clients using - them. In the interest of clarity, it is preferable for this DHCP - information to use a distinct RR type. This memo defines a distinct - RR for this purpose for use by DHCP clients or servers, the "DHCID" - RR. - - In order to obscure potentially sensitive client identifying - information, the data stored is the result of a one-way SHA-256 hash - computation. The hash includes information from the DHCP client's - message as well as the domain name itself, so that the data stored in - the DHCID RR will be dependent on both the client identification used - in the DHCP protocol interaction and the domain name. This means - that the DHCID RDATA will vary if a single client is associated over - time with more than one name. This makes it difficult to 'track' a - client as it is associated with various domain names. - - -3. The DHCID RR - - The DHCID RR is defined with mnemonic DHCID and type code [TBD]. The - DHCID RR is only defined in the IN class. DHCID RRs cause no - additional section processing. The DHCID RR is not a singleton type. - -3.1. DHCID RDATA format - - The RDATA section of a DHCID RR in transmission contains RDLENGTH - octets of binary data. The format of this data and its - interpretation by DHCP servers and clients are described below. - - DNS software should consider the RDATA section to be opaque. DHCP - clients or servers use the DHCID RR to associate a DHCP client's - - - -Stapp, et al. Expires September 1, 2006 [Page 3] - -Internet-Draft The DHCID RR February 2006 - - - identity with a DNS name, so that multiple DHCP clients and servers - may deterministically perform dynamic DNS updates to the same zone. - From the updater's perspective, the DHCID resource record RDATA - consists of a 2-octet identifier type, in network byte order, - followed by a 1-octet digest type, followed by one or more octets - representing the actual identifier: - - < 2 octets > Identifier type code - < 1 octet > Digest type code - < n octets > Digest (length depends on digest type) - -3.2. DHCID Presentation Format - - In DNS master files, the RDATA is represented as a single block in - base 64 encoding identical to that used for representing binary data - in RFC 3548 [7]. The data may be divided up into any number of white - space separated substrings, down to single base 64 digits, which are - concatenated to form the complete RDATA. These substrings can span - lines using the standard parentheses. - -3.3. The DHCID RR Identifier Type Codes - - The DHCID RR Identifier Type Code specifies what data from the DHCP - client's request was used as input into the hash function. The - identifier type codes are defined in a registry maintained by IANA, - as specified in Section 7. The initial list of assigned values for - the identifier type code is: - - 0x0000 = htype, chaddr from a DHCPv4 client's DHCPREQUEST [6]. - 0x0001 = The data octets (i.e., the Type and Client-Identifier - fields) from a DHCPv4 client's Client Identifier option [9]. - 0x0002 = The client's DUID (i.e., the data octets of a DHCPv6 - client's Client Identifier option [10] or the DUID field from a - DHCPv4 client's Client Identifier option [12]). - - 0x0003 - 0xfffe = Available to be assigned by IANA. - - 0xffff = RESERVED - -3.4. The DHCID RR Digest Type Code - - The DHCID RR Digest Type Code is an identifier for the digest - algorithm used. The digest is calculated over an identifier and the - canonical FQDN as described in the next section. - - The digest type codes are defined in a registry maintained by IANA, - as specified in Section 7. The initial list of assigned values for - the digest type codes is: value 0 is reserved and value 1 is SHA-256. - - - -Stapp, et al. Expires September 1, 2006 [Page 4] - -Internet-Draft The DHCID RR February 2006 - - - Reserving other types requires IETF standards action. Defining new - values will also require IETF standards action to document how DNS - updaters are to deal with multiple digest types. - -3.5. Computation of the RDATA - - The DHCID RDATA is formed by concatenating the 2-octet identifier - type code with variable-length data. - - The RDATA for all type codes other than 0xffff, which is reserved for - future expansion, is formed by concatenating the 2-octet identifier - type code, the 1-octet digest type code, and the digest value (32 - octets for SHA-256). - - < identifier-type > < digest-type > < digest > - - The input to the digest hash function is defined to be: - - digest = SHA-256(< identifier > < FQDN >) - - The FQDN is represented in the buffer in unambiguous canonical form - as described in RFC 4034 [8], section 6.1. The identifier type code - and the identifier are related as specified in Section 3.3: the - identifier type code describes the source of the identifier. - - A DHCPv4 updater uses the 0x0002 type code if a Client Identifier - option is present in the DHCPv4 messages and it is encoded as - specified in [12]. Otherwise, the updater uses 0x0001 if a Client - Identifier option is present and 0x0000 if not. - - A DHCPv6 updater always uses the 0x0002 type code. - -3.5.1. Using the Client's DUID - - When the updater is using the Client's DUID (either from a DHCPv6 - Client Identifier option or from a portion of the DHCPv4 Client - Identifier option encoded as specified in [12]), the first two octets - of the DHCID RR MUST be 0x0002, in network byte order. The third - octet is the digest type code (1 for SHA-256). The rest of the DHCID - RR MUST contain the results of computing the SHA-256 hash across the - octets of the DUID followed by the FQDN. - -3.5.2. Using the Client Identifier Option - - When the updater is using the DHCPv4 Client Identifier option sent by - the client in its DHCPREQUEST message, the first two octets of the - DHCID RR MUST be 0x0001, in network byte order. The third octet is - the digest type code (1 for SHA-256). The rest of the DHCID RR MUST - - - -Stapp, et al. Expires September 1, 2006 [Page 5] - -Internet-Draft The DHCID RR February 2006 - - - contain the results of computing the SHA-256 hash across the data - octets (i.e., the Type and Client-Identifier fields) of the option, - followed by the FQDN. - -3.5.3. Using the Client's htype and chaddr - - When the updater is using the client's link-layer address as the - identifier, the first two octets of the DHCID RDATA MUST be zero. - The third octet is the digest type code (1 for SHA-256). To generate - the rest of the resource record, the updater computes a one-way hash - using the SHA-256 algorithm across a buffer containing the client's - network hardware type, link-layer address, and the FQDN data. - Specifically, the first octet of the buffer contains the network - hardware type as it appeared in the DHCP 'htype' field of the - client's DHCPREQUEST message. All of the significant octets of the - 'chaddr' field in the client's DHCPREQUEST message follow, in the - same order in which the octets appear in the DHCPREQUEST message. - The number of significant octets in the 'chaddr' field is specified - in the 'hlen' field of the DHCPREQUEST message. The FQDN data, as - specified above, follows. - -3.6. Examples - -3.6.1. Example 1 - - A DHCP server allocating the IPv4 address 10.0.0.1 to a client with - Ethernet MAC address 01:02:03:04:05:06 using domain name - "client.example.com" uses the client's link-layer address to identify - the client. The DHCID RDATA is composed by setting the two type - octets to zero, the 1-octet digest type to 1 for SHA-256, and - performing an SHA-256 hash computation across a buffer containing the - Ethernet MAC type octet, 0x01, the six octets of MAC address, and the - domain name (represented as specified in Section 3.5). - - client.example.com. A 10.0.0.1 - client.example.com. DHCID ( AAABxLmlskllE0MVjd57zHcWmEH3pCQ6V - ytcKD//7es/deY= ) - - If the DHCID RR type is not supported, the RDATA would be encoded - [13] as: - - \# 35 ( 000001c4b9a5b249651343158dde7bcc77169841f7a4243a572b5c283 - fffedeb3f75e6 ) - -3.6.2. Example 2 - - A DHCP server allocates the IPv4 address 10.0.12.99 to a client which - included the DHCP client-identifier option data 01:07:08:09:0a:0b:0c - - - -Stapp, et al. Expires September 1, 2006 [Page 6] - -Internet-Draft The DHCID RR February 2006 - - - in its DHCP request. The server updates the name "chi.example.com" - on the client's behalf, and uses the DHCP client identifier option - data as input in forming a DHCID RR. The DHCID RDATA is formed by - setting the two type octets to the value 0x0001, the 1-octet digest - type to 1 for SHA-256, and performing a SHA-256 hash computation - across a buffer containing the seven octets from the client-id option - and the FQDN (represented as specified in Section 3.5). - - chi.example.com. A 10.0.12.99 - chi.example.com. DHCID ( AAEBOSD+XR3Os/0LozeXVqcNc7FwCfQdW - L3b/NaiUDlW2No= ) - - If the DHCID RR type is not supported, the RDATA would be encoded - [13] as: - - \# 35 ( 0001013920fe5d1dceb3fd0ba3379756a70d73b17009f41d58bddbfcd - 6a2503956d8da ) - -3.6.3. Example 3 - - A DHCP server allocates the IPv6 address 2000::1234:5678 to a client - which included the DHCPv6 client-identifier option data 00:01:00:06: - 41:2d:f1:66:01:02:03:04:05:06 in its DHCPv6 request. The server - updates the name "chi6.example.com" on the client's behalf, and uses - the DHCP client identifier option data as input in forming a DHCID - RR. The DHCID RDATA is formed by setting the two type octets to the - value 0x0002, the 1-octet digest type to 1 for SHA-256, and - performing a SHA-256 hash computation across a buffer containing the - 14 octets from the client-id option and the FQDN (represented as - specified in Section 3.5). - - chi6.example.com. AAAA 2000::1234:5678 - chi6.example.com. DHCID ( AAIBY2/AuCccgoJbsaxcQc9TUapptP69l - OjxfNuVAA2kjEA= ) - - If the DHCID RR type is not supported, the RDATA would be encoded - [13] as: - - \# 35 ( 000201636fc0b8271c82825bb1ac5c41cf5351aa69b4febd94e8f17cd - b95000da48c40 ) - - -4. Use of the DHCID RR - - This RR MUST NOT be used for any purpose other than that detailed in - "Resolution of DNS Name Conflicts" [1]. Although this RR contains - data that is opaque to DNS servers, the data must be consistent - across all entities that update and interpret this record. - - - -Stapp, et al. Expires September 1, 2006 [Page 7] - -Internet-Draft The DHCID RR February 2006 - - - Therefore, new data formats may only be defined through actions of - the DHC Working Group, as a result of revising [1]. - - -5. Updater Behavior - - The data in the DHCID RR allows updaters to determine whether more - than one DHCP client desires to use a particular FQDN. This allows - site administrators to establish policy about DNS updates. The DHCID - RR does not establish any policy itself. - - Updaters use data from a DHCP client's request and the domain name - that the client desires to use to compute a client identity hash, and - then compare that hash to the data in any DHCID RRs on the name that - they wish to associate with the client's IP address. If an updater - discovers DHCID RRs whose RDATA does not match the client identity - that they have computed, the updater SHOULD conclude that a different - client is currently associated with the name in question. The - updater SHOULD then proceed according to the site's administrative - policy. That policy might dictate that a different name be selected, - or it might permit the updater to continue. - - -6. Security Considerations - - The DHCID record as such does not introduce any new security problems - into the DNS. In order to obscure the client's identity information, - a one-way hash is used. And, in order to make it difficult to - 'track' a client by examining the names associated with a particular - hash value, the FQDN is included in the hash computation. Thus, the - RDATA is dependent on both the DHCP client identification data and on - each FQDN associated with the client. - - However, it should be noted that an attacker that has some knowledge, - such as of MAC addresses commonly used in DHCP client identification - data, may be able to discover the client's DHCP identify by using a - brute-force attack. Even without any additional knowledge, the - number of unknown bits used in computing the hash is typically only - 48 to 80. - - Administrators should be wary of permitting unsecured DNS updates to - zones, whether or not they are exposed to the global Internet. Both - DHCP clients and servers SHOULD use some form of update - authentication (e.g., TSIG [11]) when performing DNS updates. - - -7. IANA Considerations - - - - -Stapp, et al. Expires September 1, 2006 [Page 8] - -Internet-Draft The DHCID RR February 2006 - - - IANA is requested to allocate a DNS RR type number for the DHCID - record type. - - This specification defines a new number-space for the 2-octet - identifier type codes associated with the DHCID RR. IANA is - requested to establish a registry of the values for this number- - space. Three initial values are assigned in Section 3.3, and the - value 0xFFFF is reserved for future use. New DHCID RR identifier - type codes are assigned through Standards Action, as defined in RFC - 2434 [5]. - - This specification defines a new number-space for the 1-octet digest - type codes associated with the DHCID RR. IANA is requested to - establish a registry of the values for this number-space. Two - initial values are assigned in Section 3.4. New DHCID RR digest type - codes are assigned through Standards Action, as defined in RFC 2434 - [5]. - - -8. Acknowledgements - - Many thanks to Harald Alvestrand, Ralph Droms, Olafur Gudmundsson, - Sam Hartman, Josh Littlefield, Pekka Savola, and especially Bernie - Volz for their review and suggestions. - - -9. References - -9.1. Normative References - - [1] Stapp, M. and B. Volz, "Resolution of DNS Name Conflicts Among - DHCP Clients (draft-ietf-dhc-dns-resolution-*)", February 2006. - - [2] Bradner, S., "Key words for use in RFCs to Indicate Requirement - Levels", BCP 14, RFC 2119, March 1997. - - [3] Mockapetris, P., "Domain names - concepts and facilities", - STD 13, RFC 1034, November 1987. - - [4] Mockapetris, P., "Domain names - implementation and - specification", STD 13, RFC 1035, November 1987. - - [5] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA - Considerations Section in RFCs", BCP 26, RFC 2434, October 1998. - - - - - - - -Stapp, et al. Expires September 1, 2006 [Page 9] - -Internet-Draft The DHCID RR February 2006 - - -9.2. Informative References - - [6] Droms, R., "Dynamic Host Configuration Protocol", RFC 2131, - March 1997. - - [7] Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", - RFC 3548, July 2003. - - [8] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "Resource Records for the DNS Security Extensions", RFC 4034, - March 2005. - - [9] Alexander, S. and R. Droms, "DHCP Options and BOOTP Vendor - Extensions", RFC 2132, March 1997. - - [10] Droms, R., Bound, J., Volz, B., Lemon, T., Perkins, C., and M. - Carney, "Dynamic Host Configuration Protocol for IPv6 - (DHCPv6)", RFC 3315, July 2003. - - [11] Vixie, P., Gudmundsson, O., Eastlake, D., and B. Wellington, - "Secret Key Transaction Authentication for DNS (TSIG)", - RFC 2845, May 2000. - - [12] Lemon, T. and B. Sommerfeld, "Node-specific Client Identifiers - for Dynamic Host Configuration Protocol Version Four (DHCPv4)", - RFC 4361, February 2006. - - [13] Gustafsson, A., "Handling of Unknown DNS Resource Record (RR) - Types", RFC 3597, September 2003. - - - - - - - - - - - - - - - - - - - - - - -Stapp, et al. Expires September 1, 2006 [Page 10] - -Internet-Draft The DHCID RR February 2006 - - -Authors' Addresses - - Mark Stapp - Cisco Systems, Inc. - 1414 Massachusetts Ave. - Boxborough, MA 01719 - USA - - Phone: 978.936.1535 - Email: mjs@cisco.com - - - Ted Lemon - Nominum, Inc. - 950 Charter St. - Redwood City, CA 94063 - USA - - Email: mellon@nominum.com - - - Andreas Gustafsson - Araneus Information Systems Oy - Ulappakatu 1 - 02320 Espoo - Finland - - Email: gson@araneus.fi - - - - - - - - - - - - - - - - - - - - - - - -Stapp, et al. Expires September 1, 2006 [Page 11] - -Internet-Draft The DHCID RR February 2006 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2006). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Stapp, et al. Expires September 1, 2006 [Page 12] - - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-dns-name-p-s-00.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-dns-name-p-s-00.txt deleted file mode 100644 index 438e800..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-dns-name-p-s-00.txt +++ /dev/null @@ -1,1397 +0,0 @@ -DNS Extensions Working Group G. Sisson -Internet-Draft B. Laurie -Expires: January 11, 2006 Nominet - July 10, 2005 - - - Derivation of DNS Name Predecessor and Successor - draft-ietf-dnsext-dns-name-p-s-00 - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on January 11, 2006. - -Copyright Notice - - Copyright (C) The Internet Society (2005). - -Abstract - - This document describes two methods for deriving the canonically- - ordered predecessor and successor of a DNS name. These methods may - be used for dynamic NSEC resource record synthesis, enabling - security-aware name servers to provide authenticated denial of - existence without disclosing other owner names in a DNSSEC-secured - zone. - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 1] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 2. Notational Conventions . . . . . . . . . . . . . . . . . . . . 3 - 3. Absolute Method . . . . . . . . . . . . . . . . . . . . . . . 4 - 3.1. Derivation of DNS Name Predecessor . . . . . . . . . . . . 4 - 3.2. Derivation of DNS Name Successor . . . . . . . . . . . . . 4 - 4. Modified Method . . . . . . . . . . . . . . . . . . . . . . . 5 - 4.1. Derivation of DNS Name Predecessor . . . . . . . . . . . . 6 - 4.2. Derivation of DNS Name Successor . . . . . . . . . . . . . 6 - 5. Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 - 5.1. Case Considerations . . . . . . . . . . . . . . . . . . . 7 - 5.2. Choice of Range . . . . . . . . . . . . . . . . . . . . . 7 - 5.3. Wild Card Considerations . . . . . . . . . . . . . . . . . 8 - 5.4. Possible Modifications . . . . . . . . . . . . . . . . . . 8 - 5.4.1. Restriction of Effective Maximum DNS Name Length . . . 8 - 5.4.2. Use of Modified Method With Zones Containing - SRV RRs . . . . . . . . . . . . . . . . . . . . . . . 9 - 6. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 - 6.1. Examples of Immediate Predecessors Using Absolute - Method . . . . . . . . . . . . . . . . . . . . . . . . . . 10 - 6.2. Examples of Immediate Successors Using Absolute Method . . 13 - 6.3. Examples of Predecessors Using Modified Method . . . . . . 19 - 6.4. Examples of Successors Using Modified Method . . . . . . . 20 - 7. Security Considerations . . . . . . . . . . . . . . . . . . . 21 - 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 21 - 10. References . . . . . . . . . . . . . . . . . . . . . . . . . . 22 - 10.1. Normative References . . . . . . . . . . . . . . . . . . . 22 - 10.2. Informative References . . . . . . . . . . . . . . . . . . 22 - 9. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 21 - Appendix A. Change History . . . . . . . . . . . . . . . . . . . 22 - A.1. Changes from sisson-02 to ietf-00 . . . . . . . . . . . . 22 - A.2. Changes from sisson-01 to sisson-02 . . . . . . . . . . . 23 - A.3. Changes from sisson-00 to sisson-01 . . . . . . . . . . . 23 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 24 - Intellectual Property and Copyright Statements . . . . . . . . . . 25 - - - - - - - - - - - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 2] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - -1. Introduction - - One of the proposals for avoiding the exposure of zone information - during the deployment DNSSEC is dynamic NSEC resource record (RR) - synthesis. This technique is described in [I-D.ietf-dnsext-dnssec- - trans] and [I-D.ietf-dnsext-dnssec-online-signing], and involves the - generation of NSEC RRs that just span the query name for non-existent - owner names. In order to do this, the DNS names which would occur - just prior to and just following a given query name must be - calculated in real time, as maintaining a list of all possible owner - names that might occur in a zone would be impracticable. - - Section 6.1 of [RFC4034] defines canonical DNS name order. This - document does not amend or modify this definition. However, the - derivation of immediate predecessor and successor, while trivial, is - non-obvious. Accordingly, several methods are described here as an - aid to implementors and a reference to other interested parties. - - This document describes two methods: - - 1. An ``absolute method'', which returns the immediate predecessor - or successor of a domain name such that no valid DNS name could - exist between that DNS name and the predecessor or successor. - - 2. A ``modified method'', which returns a predecessor and successor - which are more economical in size and computation. This method - is restricted to use with zones consisting only of single-label - owner names where a maximum-length owner name would not result in - a DNS name exceeding the maximum DNS name length. This is, - however, the type of zone for which the technique of online- - signing is most likely to be used. - - -2. Notational Conventions - - The following notational conventions are used in this document for - economy of expression: - - N: An unspecified DNS name. - - P(N): Immediate predecessor to N (absolute method). - - S(N): Immediate successor to N (absolute method). - - P'(N): Predecessor to N (modified method). - - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 3] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - - S'(N): Successor to N (modified method). - - -3. Absolute Method - - These derivations assume that all uppercase US-ASCII letters in N - have already been replaced by their corresponding lowercase - equivalents. Unless otherwise specified, processing stops after the - first step in which a condition is met. - -3.1. Derivation of DNS Name Predecessor - - To derive P(N): - - 1. If N is the same as the owner name of the zone apex, prepend N - repeatedly with labels of the maximum length possible consisting - of octets of the maximum sort value (e.g. 0xff) until N is the - maximum length possible; otherwise continue to the next step. - - 2. If the least significant (left-most) label of N consists of a - single octet of the minimum sort value (e.g. 0x00), remove that - label; otherwise continue to the next step. - - 3. If the least significant (right-most) octet in the least - significant (left-most) label of N is the minimum sort value, - remove the least significant octet and continue with step 5. - - 4. Decrement the value of the least significant (right-most) octet, - skipping any values that correspond to uppercase US-ASCII - letters, and then append the label with as many octets as - possible of the maximum sort value. Continue to the next step. - - 5. Prepend N repeatedly with labels of as long a length as possible - consisting of octets of the maximum sort value until N is the - maximum length possible. - -3.2. Derivation of DNS Name Successor - - To derive S(N): - - 1. If N is two or more octets shorter than the maximum DNS name - length, prepend N with a label containing a single octet of the - minimum sort value (e.g. 0x00); otherwise continue to the next - step. - - 2. If N is one or more octets shorter than the maximum DNS name - length and the least significant (left-most) label is one or more - octets shorter than the maximum label length, append an octet of - - - -Sisson & Laurie Expires January 11, 2006 [Page 4] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - - the minimum sort value to the least significant label; otherwise - continue to the next step. - - 3. Increment the value of the least significant (right-most) octet - in the least significant (left-most) label that is less than the - maximum sort value (e.g. 0xff), skipping any values that - correspond to uppercase US-ASCII letters, and then remove any - octets to the right of that one. If all octets in the label are - the maximum sort value, then continue to the next step. - - 4. Remove the least significant (left-most) label. If N is now the - same as the owner name of the zone apex, do nothing. (This will - occur only if N is the maximum possible name in canonical DNS - name order, and thus has wrapped to the owner name of zone apex.) - Otherwise repeat starting at step 2. - - -4. Modified Method - - This method is for use with zones consisting only of single-label - owner names where an owner name consisting of label of maximum length - would not result in a DNS name which exceeded the maximum DNS name - length. This method is computationally simpler and returns values - which are more economical in size than the absolute method. It - differs from the absolute method detailed above in the following - ways: - - 1. Step 1 of the derivation P(N) has been omitted as the existence - of the owner name of the zone apex never requires denial. - - 2. A new step 1 has been introduced which removes unnecessary - labels. - - 3. Step 4 of the derivation P(N) has been omitted as it is only - necessary for zones containing owner names consisting of more - than one label. This omission generally results in a significant - reduction of the length of derived predecessors. - - 4. Step 1 of the derivation S(N) had been omitted as it is only - necessary for zones containing owner names consisting of more - than one label. This omission results in a tiny reduction of the - length of derived successors, and maintains consistency with the - modification of step 4 of the derivation P(N) described above. - - 5. Steps 2 and 4 of the derivation S(N) have been modified to - eliminate checks for maximum DNS name length, as it is an - assumption of this method that no DNS name in the zone can exceed - the maximum DNS name length. - - - -Sisson & Laurie Expires January 11, 2006 [Page 5] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - - These derivations assume that all uppercase US-ASCII letters in N - have already been replaced by their corresponding lowercase - equivalents. Unless otherwise specified, processing stops after the - first step in which a condition is met. - -4.1. Derivation of DNS Name Predecessor - - To derive P'(N): - - 1. If N has more labels than the number of labels in the owner name - of the apex + 1, repeatedly remove the least significant (left- - most) label until N has no more labels than the number of labels - in the owner name of the apex + 1; otherwise continue to next - step. - - 2. If the least significant (left-most) label of N consists of a - single octet of the minimum sort value (e.g. 0x00), remove that - label; otherwise continue to the next step. - - 3. If the least significant (right-most) octet in the least - significant (left-most) label of N is the minimum sort value, - remove the least significant octet. - - 4. Decrement the value of the least significant (right-most) octet, - skipping any values which correspond to uppercase US-ASCII - letters, and then append the label with as many octets as - possible of the maximum sort value. - -4.2. Derivation of DNS Name Successor - - To derive S'(N): - - 1. If N has more labels than the number of labels in the owner name - of the apex + 1, repeatedly remove the least significant (left- - most) label until N has no more labels than the number of labels - in the owner name of the apex + 1. Continue to next step. - - 2. If the least significant (left-most) label of N is one or more - octets shorter than the maximum label length, append an octet of - the minimum sort value to the least significant label; otherwise - continue to the next step. - - 3. Increment the value of the least significant (right-most) octet - in the least significant (left-most) label that is less than the - maximum sort value (e.g. 0xff), skipping any values which - correspond to uppercase US-ASCII letters, and then remove any - octets to the right of that one. If all octets in the label are - the maximum sort value, then continue to the next step. - - - -Sisson & Laurie Expires January 11, 2006 [Page 6] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - - 4. Remove the least significant (left-most) label. (This will occur - only if the least significant label is the maximum label length - and consists entirely of octets of the maximum sort value, and - thus has wrapped to the owner name of the zone apex.) - - -5. Notes - -5.1. Case Considerations - - Section 3.5 of [RFC1034] specifies that "while upper and lower case - letters are allowed in [DNS] names, no significance is attached to - the case". Additionally, Section 6.1 of [RFC4034] states that when - determining canonical DNS name order, "uppercase US-ASCII letters are - treated as if they were lowercase US-ASCII letters". Consequently, - values corresponding to US-ASCII uppercase letters must be skipped - when decrementing and incrementing octets in the derivations - described in Section 3.1 and Section 3.2. - - The following pseudo-code is illustrative: - - Decrement the value of an octet: - - if (octet == '[') // '[' is just after uppercase 'Z' - octet = '@'; // '@' is just prior to uppercase 'A' - else - octet--; - - Increment the value of an octet: - - if (octet == '@') // '@' is just prior to uppercase 'A' - octet = '['; // '[' is just after uppercase 'Z' - else - octet++; - -5.2. Choice of Range - - [RFC2181] makes the clarification that "any binary string whatever - can be used as the label of any resource record". Consequently the - minimum sort value may be set as 0x00 and the maximum sort value as - 0xff, and the range of possible values will be any DNS name which - contains octets of any value other than those corresponding to - uppercase US-ASCII letters. - - However, if all owner names in a zone are in the letter-digit-hyphen, - or LDH, format specified in [RFC1034], it may be desirable to - restrict the range of possible values to DNS names containing only - LDH values. This has the effect of: - - - -Sisson & Laurie Expires January 11, 2006 [Page 7] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - - 1. making the output of tools such as `dig' and `nslookup' less - subject to confusion; - - 2. minimising the impact that NSEC RRs containing DNS names with - non-LDH values (or non-printable values) might have on faulty DNS - resolver implementations; and - - 3. preventing the possibility of results which are wildcard DNS - names (see Section 5.3). - - This may be accomplished by using a minimum sort value of 0x1f (US- - ASCII character `-') and a maximum sort value of 0x7a (US-ASCII - character lowercase `z'), and then skipping non-LDH, non-lowercase - values when incrementing or decrementing octets. - -5.3. Wild Card Considerations - - Neither derivation avoids the possibility that the result may be a - DNS name containing a wildcard label, i.e. a label containing a - single octet with the value 0x2a (US-ASCII character `*'). With - additional tests, wildcard DNS names may be explicitly avoided; - alternatively, if the range of octet values can be restricted to - those corresponding to letter-digit-hyphen, or LDH, characters (see - Section 5.2), such DNS names will not occur. - - Note that it is improbable that a result which is a wildcard DNS name - will occur unintentionally; even if one does occur either as the - owner name of, or in the RDATA of an NSEC RR, it is treated as a - literal DNS name with no special meaning. - -5.4. Possible Modifications - -5.4.1. Restriction of Effective Maximum DNS Name Length - - [RFC1034] specifies that "the total number of octets that represent a - [DNS] name (i.e., the sum of all label octets and label lengths) is - limited to 255", including the null (zero-length) label which - represents the root. For the purpose of deriving predecessors and - successors during NSEC RR synthesis, the maximum DNS name length may - be effectively restricted to the length of the longest DNS name in - the zone. This will minimise the size of responses containing - synthesised NSEC RRs but, especially in the case of the modified - method, may result in some additional computational complexity. - - Note that this modification will have the effect of revealing - information about the longest name in the zone. Moreover, when the - contents of the zone changes, e.g. during dynamic updates and zone - transfers, care must be taken to ensure that the effective maximum - - - -Sisson & Laurie Expires January 11, 2006 [Page 8] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - - DNS name length agrees with the new contents. - -5.4.2. Use of Modified Method With Zones Containing SRV RRs - - Normally the modified method cannot be used in zones that contain - SRV RRs [RFC2782], as SRV RRs have owner names which contain multiple - labels. However the use of SRV RRs can be accommodated by various - techniques. There are at least four possible ways to do this: - - 1. Use conventional NSEC RRs for the region of the zone that - contains first-level labels beginning with the underscore (`_') - character. For the purposes of generating these NSEC RRs, the - existence of (possibly fictional) ownernames `9{63}' and `a' - could be assumed, providing a lower and upper bound for this - region. Then all queries where the QNAME doesn't exist but - contains a first-level label beginning with an underscore could - be handled using the normal DNSSEC protocol. - - This approach would make it possible to enumerate all DNS names - in the zone containing a first-level label beginning with - underscore, including all SRV RRs, but this may be of less a - concern to the zone administrator than incurring the overhead of - the absolute method or of the following variants of the modified - method. - - 2. The absolute method could be used for synthesising NSEC RRs for - all queries where the QNAME contains a leading underscore. - However this re-introduces the susceptibility of the absolute - method to denial of service activity, as an attacker could send - queries for an effectively inexhaustible supply of domain names - beginning with a leading underscore. - - 3. A variant of the modified method could be used for synthesising - NSEC RRs for all queries where the QNAME contains a leading - underscore. This variant would assume that all predecessors and - successors to queries where the QNAME contains a leading - underscore may consist of two lablels rather than only one. This - introduces a little additional complexity without incurring the - full increase in response size and computational complexity as - the absolute method. - - 4. Finally, a variant the modified method which assumes that all - owner names in the zone consist of one or two labels could be - used. However this negates much of the reduction in response - size of the modified method and may be nearly as computationally - complex as the absolute method. - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 9] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - -6. Examples - - In the following examples: - - the owner name of the zone apex is "example.com."; - - the range of octet values is 0x00 - 0xff excluding values - corresponding to uppercase US-ASCII letters; and - - non-printable octet values are expressed as three-digit decimal - numbers preceded by a backslash (as specified in Section 5.1 of - [RFC1035]). - -6.1. Examples of Immediate Predecessors Using Absolute Method - - Example of typical case: - - P(foo.example.com.) = - - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255.\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255.\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255.fon\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255.example.com. - - or, in alternate notation: - - \255{49}.\255{63}.\255{63}.fon\255{60}.example.com. - - where {n} represents the number of repetitions of an octet. - - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 10] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - - Example where least significant (left-most) label of DNS name - consists of a single octet of the minimum sort value: - - P(\000.foo.example.com.) = foo.example.com. - - Example where least significant (right-most) octet of least - significant (left-most) label has the minimum sort value: - - P(foo\000.example.com.) = - - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255.\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255.\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255.\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255.foo.example.com. - - or, in alternate notation: - - \255{45}.\255{63}.\255{63}.\255{63}.foo.example.com. - - - - - - - - - - - - - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 11] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - - Example where DNS name contains an octet which must be decremented by - skipping values corresponding to US-ASCII uppercase letters: - - P(fo\[.example.com.) = - - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255.\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255.\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255.fo\@\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255.example.com. - - or, in alternate notation: - - \255{49}.\255{63}.\255{63}.fo\@\255{60}.example.com. - - where {n} represents the number of repetitions of an octet. - - - - - - - - - - - - - - - - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 12] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - - Example where DNS name is the owner name of the zone apex, and - consequently wraps to the DNS name with the maximum possible sort - order in the zone: - - P(example.com.) = - - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255.\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255.\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255.\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255.example.com. - - or, in alternate notation: - - \255{49}.\255{63}.\255{63}.\255{63}.example.com. - -6.2. Examples of Immediate Successors Using Absolute Method - - Example of typical case: - - S(foo.example.com.) = \000.foo.example.com. - - - - - - - - - - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 13] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - - Example where DNS name is one octet short of the maximum DNS name - length: - - N = fooooooooooooooooooooooooooooooooooooooooooooooo - .ooooooooooooooooooooooooooooooooooooooooooooooo - oooooooooooooooo.ooooooooooooooooooooooooooooooo - oooooooooooooooooooooooooooooooo.ooooooooooooooo - oooooooooooooooooooooooooooooooooooooooooooooooo.example.com. - - or, in alternate notation: - - fo{47}.o{63}.o{63}.o{63}.example.com. - - S(N) = - - fooooooooooooooooooooooooooooooooooooooooooooooo - \000.ooooooooooooooooooooooooooooooooooooooooooo - oooooooooooooooooooo.ooooooooooooooooooooooooooo - oooooooooooooooooooooooooooooooooooo.ooooooooooo - oooooooooooooooooooooooooooooooooooooooooooooooo - oooo.example.com. - - or, in alternate notation: - - fo{47}\000.o{63}.o{63}.o{63}.example.com. - - - - - - - - - - - - - - - - - - - - - - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 14] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - - Example where DNS name is the maximum DNS name length: - - N = fooooooooooooooooooooooooooooooooooooooooooooooo - o.oooooooooooooooooooooooooooooooooooooooooooooo - ooooooooooooooooo.oooooooooooooooooooooooooooooo - ooooooooooooooooooooooooooooooooo.oooooooooooooo - oooooooooooooooooooooooooooooooooooooooooooooooo - o.example.com. - - or, in alternate notation: - - fo{48}.o{63}.o{63}.o{63}.example.com. - - S(N) = - - fooooooooooooooooooooooooooooooooooooooooooooooo - p.oooooooooooooooooooooooooooooooooooooooooooooo - ooooooooooooooooo.oooooooooooooooooooooooooooooo - ooooooooooooooooooooooooooooooooo.oooooooooooooo - oooooooooooooooooooooooooooooooooooooooooooooooo - o.example.com. - - or, in alternate notation: - - fo{47}p.o{63}.o{63}.o{63}.example.com. - - - - - - - - - - - - - - - - - - - - - - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 15] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - - Example where DNS name is the maximum DNS name length and the least - significant (left-most) label has the maximum sort value: - - N = \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255.ooooooooooooooooooooooooooooooooooooooooooo - oooooooooooooooooooo.ooooooooooooooooooooooooooo - oooooooooooooooooooooooooooooooooooo.ooooooooooo - oooooooooooooooooooooooooooooooooooooooooooooooo - oooo.example.com. - - or, in alternate notation: - - \255{49}.o{63}.o{63}.o{63}.example.com. - - S(N) = - - oooooooooooooooooooooooooooooooooooooooooooooooo - oooooooooooooop.oooooooooooooooooooooooooooooooo - ooooooooooooooooooooooooooooooo.oooooooooooooooo - ooooooooooooooooooooooooooooooooooooooooooooooo. - example.com. - - or, in alternate notation: - - o{62}p.o{63}.o{63}.example.com. - - - - - - - - - - - - - - - - - - - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 16] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - - Example where DNS name is the maximum DNS name length and the eight - least significant (right-most) octets of the least significant (left- - most) label have the maximum sort value: - - N = foooooooooooooooooooooooooooooooooooooooo\255 - \255\255\255\255\255\255\255.ooooooooooooooooooo - oooooooooooooooooooooooooooooooooooooooooooo.ooo - oooooooooooooooooooooooooooooooooooooooooooooooo - oooooooooooo.ooooooooooooooooooooooooooooooooooo - oooooooooooooooooooooooooooo.example.com. - - or, in alternate notation: - - fo{40}\255{8}.o{63}.o{63}.o{63}.example.com. - - S(N) = - - fooooooooooooooooooooooooooooooooooooooop.oooooo - oooooooooooooooooooooooooooooooooooooooooooooooo - ooooooooo.oooooooooooooooooooooooooooooooooooooo - ooooooooooooooooooooooooo.oooooooooooooooooooooo - ooooooooooooooooooooooooooooooooooooooooo.example.com. - - or, in alternate notation: - - fo{39}p.o{63}.o{63}.o{63}.example.com. - - - - - - - - - - - - - - - - - - - - - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 17] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - - Example where DNS name is the maximum DNS name length and contains an - octet which must be incremented by skipping values corresponding to - US-ASCII uppercase letters: - - N = fooooooooooooooooooooooooooooooooooooooooooooooo - \@.ooooooooooooooooooooooooooooooooooooooooooooo - oooooooooooooooooo.ooooooooooooooooooooooooooooo - oooooooooooooooooooooooooooooooooo.ooooooooooooo - oooooooooooooooooooooooooooooooooooooooooooooooo - oo.example.com. - - or, in alternate notation: - - fo{47}\@.o{63}.o{63}.o{63}.example.com. - - S(N) = - - fooooooooooooooooooooooooooooooooooooooooooooooo - \[.ooooooooooooooooooooooooooooooooooooooooooooo - oooooooooooooooooo.ooooooooooooooooooooooooooooo - oooooooooooooooooooooooooooooooooo.ooooooooooooo - oooooooooooooooooooooooooooooooooooooooooooooooo - oo.example.com. - - or, in alternate notation: - - fo{47}\[.o{63}.o{63}.o{63}.example.com. - - - - - - - - - - - - - - - - - - - - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 18] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - - Example where DNS name has the maximum possible sort order in the - zone, and consequently wraps to the owner name of the zone apex: - - N = \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255.\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255.\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255.\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255.example.com. - - or, in alternate notation: - - \255{49}.\255{63}.\255{63}.\255{63}.example.com. - - S(N) = example.com. - -6.3. Examples of Predecessors Using Modified Method - - Example of typical case: - - P'(foo.example.com.) = - - fon\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255.example.com. - - or, in alternate notation: - - fon\255{60}.example.com. - - - - -Sisson & Laurie Expires January 11, 2006 [Page 19] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - - Example where DNS name contains more labels than DNS names in the - zone: - - P'(bar.foo.example.com.) = foo.example.com. - - Example where least significant (right-most) octet of least - significant (left-most) label has the minimum sort value: - - P'(foo\000.example.com.) = foo.example.com. - - Example where least significant (left-most) label has the minimum - sort value: - - P'(\000.example.com.) = example.com. - - Example where DNS name is the owner name of the zone apex, and - consequently wraps to the DNS name with the maximum possible sort - order in the zone: - - P'(example.com.) = - - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255.example.com. - - or, in alternate notation: - - \255{63}.example.com. - -6.4. Examples of Successors Using Modified Method - - Example of typical case: - - S'(foo.example.com.) = foo\000.example.com. - - Example where DNS name contains more labels than DNS names in the - zone: - - S'(bar.foo.example.com.) = foo\000.example.com. - - - - - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 20] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - - Example where least significant (left-most) label has the maximum - sort value, and consequently wraps to the owner name of the zone - apex: - - N = \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255.example.com. - - or, in alternate notation: - - \255{63}.example.com. - - S'(N) = example.com. - - -7. Security Considerations - - The derivation of some predecessors/successors requires the testing - of more conditions than others. Consequently the effectiveness of a - denial-of-service attack may be enhanced by sending queries that - require more conditions to be tested. The modified method involves - the testing of fewer conditions than the absolute method and - consequently is somewhat less susceptible to this exposure. - - -8. IANA Considerations - - This document has no IANA actions. - - Note to RFC Editor: This section is included to make it clear during - pre-publication review that this document has no IANA actions. It - may therefore be removed should it be published as an RFC. - - -9. Acknowledgments - - The authors would like to thank Olaf Kolkman, Olafur Gudmundsson and - Niall O'Reilly for their review and input. - - -10. References - - - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 21] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - -10.1 Normative References - - [RFC1034] Mockapetris, P., "Domain names - concepts and facilities", - STD 13, RFC 1034, November 1987. - - [RFC1035] Mockapetris, P., "Domain names - implementation and - specification", STD 13, RFC 1035, November 1987. - - [RFC2181] Elz, R. and R. Bush, "Clarifications to the DNS - Specification", RFC 2181, July 1997. - - [RFC2782] Gulbrandsen, A., Vixie, P., and L. Esibov, "A DNS RR for - specifying the location of services (DNS SRV)", RFC 2782, - February 2000. - - [RFC4034] Arends, R., Austein, R., Larson, M., Massey, D., and S. - Rose, "Resource Records for the DNS Security Extensions", - RFC 4034, March 2005. - -10.2 Informative References - - [I-D.ietf-dnsext-dnssec-online-signing] - Ihren, J. and S. Weiler, "Minimally Covering NSEC Records - and DNSSEC On-line Signing", - draft-ietf-dnsext-dnssec-online-signing-00 (work in - progress), May 2005. - - [I-D.ietf-dnsext-dnssec-trans] - Arends, R., Koch, P., and J. Schlyter, "Evaluating DNSSEC - Transition Mechanisms", - draft-ietf-dnsext-dnssec-trans-02 (work in progress), - February 2005. - - -Appendix A. Change History - -A.1. Changes from sisson-02 to ietf-00 - - o Added notes on use of SRV RRs with modified method. - - o Changed reference from weiler-dnssec-online-signing to ietf- - dnsext-dnssec-online-signing. - - o Changed reference from ietf-dnsext-dnssec-records to RFC 4034. - - o Miscellaneous minor changes to text. - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 22] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - -A.2. Changes from sisson-01 to sisson-02 - - o Added modified version of derivation (with supporting examples). - - o Introduced notational conventions N, P(N), S(N), P'(N) and S'(N). - - o Added clarification to derivations about when processing stops. - - o Miscellaneous minor changes to text. - -A.3. Changes from sisson-00 to sisson-01 - - o Split step 3 of derivation of DNS name predecessor into two - distinct steps for clarity. - - o Added clarifying text and examples related to the requirement to - avoid uppercase characters when decrementing or incrementing - octets. - - o Added optimisation using restriction of effective maximum DNS name - length. - - o Changed examples to use decimal rather than octal notation as per - [RFC1035]. - - o Corrected DNS name length of some examples. - - o Added reference to weiler-dnssec-online-signing. - - o Miscellaneous minor changes to text. - - - - - - - - - - - - - - - - - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 23] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - -Authors' Addresses - - Geoffrey Sisson - Nominet - Sandford Gate - Sandy Lane West - Oxford - OX4 6LB - GB - - Phone: +44 1865 332339 - Email: geoff@nominet.org.uk - - - Ben Laurie - Nominet - 17 Perryn Road - London - W3 7LR - GB - - Phone: +44 20 8735 0686 - Email: ben@algroup.co.uk - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Sisson & Laurie Expires January 11, 2006 [Page 24] - -Internet-Draft DNS Name Predecessor and Successor July 2005 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2005). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Sisson & Laurie Expires January 11, 2006 [Page 25] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-2535typecode-change-06.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-2535typecode-change-06.txt deleted file mode 100644 index bcc2b4e..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-2535typecode-change-06.txt +++ /dev/null @@ -1,442 +0,0 @@ - - -INTERNET-DRAFT Samuel Weiler -Expires: June 2004 December 15, 2003 -Updates: RFC 2535, [DS] - - Legacy Resolver Compatibility for Delegation Signer - draft-ietf-dnsext-dnssec-2535typecode-change-06.txt - -Status of this Memo - - This document is an Internet-Draft and is subject to all provisions - of Section 10 of RFC2026. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as - Internet-Drafts. - - Internet-Drafts are draft documents valid for a maximum of six - months and may be updated, replaced, or obsoleted by other - documents at any time. It is inappropriate to use Internet-Drafts - as reference material or to cite them other than as "work in - progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/1id-abstracts.html - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html - - Comments should be sent to the author or to the DNSEXT WG mailing - list: namedroppers@ops.ietf.org - -Abstract - - As the DNS Security (DNSSEC) specifications have evolved, the - syntax and semantics of the DNSSEC resource records (RRs) have - changed. Many deployed nameservers understand variants of these - semantics. Dangerous interactions can occur when a resolver that - understands an earlier version of these semantics queries an - authoritative server that understands the new delegation signer - semantics, including at least one failure scenario that will cause - an unsecured zone to be unresolvable. This document changes the - type codes and mnemonics of the DNSSEC RRs (SIG, KEY, and NXT) to - avoid those interactions. - -Changes between 05 and 06: - - Signifigantly reworked the IANA section -- went back to one - algorithm registry. - - Removed Diffie-Hellman from the list of zone-signing algorithms - (leaving only DSA, RSA/SHA-1, and private algorithms). - - Added a DNSKEY flags field registry. - -Changes between 04 and 05: - - IESG approved publication. - - Cleaned up an internal reference in the acknowledgements section. - - Retained KEY and SIG for TKEY, too. Added TKEY (2930) reference. - - Changed the names of both new registries. Added algorithm - mnemonics to the new zone signing algorithm registry. Minor - rewording in the IANA section for clarity. - - Cleaned up formatting of references. Replaced unknown-rr draft - references with RFC3597. Bumped DS version number. - -Changes between 03 and 04: - - Clarified that RRSIG(0) may be defined by standards action. - - Created a new algorithm registry and renamed the old algorithm - registry for SIG(0) only. Added references to the appropriate - crypto algorithm and format specifications. - - Several minor rephrasings. - -Changes between 02 and 03: - - KEY (as well as SIG) retained for SIG(0) use only. - -Changes between 01 and 02: - - SIG(0) still uses SIG, not RRSIG. Added 2931 reference. - - Domain names embedded in NSECs and RRSIGs are not compressible and - are not downcased. Added unknown-rrs reference (as informative). - - Simplified the last paragraph of section 3 (NSEC doesn't always - signal a negative answer). - - Changed the suggested type code assignments. - - Added 2119 reference. - - Added definitions of "unsecure delegation" and "unsecure referral", - since they're not clearly defined elsewhere. - - Moved 2065 to informative references, not normative. - -1. Introduction - - The DNSSEC protocol has been through many iterations whose syntax - and semantics are not completely compatible. This has occurred as - part of the ordinary process of proposing a protocol, implementing - it, testing it in the increasingly complex and diverse environment - of the Internet, and refining the definitions of the initial - Proposed Standard. In the case of DNSSEC, the process has been - complicated by DNS's criticality and wide deployment and the need - to add security while minimizing daily operational complexity. - - A weak area for previous DNS specifications has been lack of detail - in specifying resolver behavior, leaving implementors largely on - their own to determine many details of resolver function. This, - combined with the number of iterations the DNSSEC spec has been - through, has resulted in fielded code with a wide variety of - behaviors. This variety makes it difficult to predict how a - protocol change will be handled by all deployed resolvers. The - risk that a change will cause unacceptable or even catastrophic - failures makes it difficult to design and deploy a protocol change. - One strategy for managing that risk is to structure protocol - changes so that existing resolvers can completely ignore input that - might confuse them or trigger undesirable failure modes. - - This document addresses a specific problem caused by Delegation - Signer's [DS] introduction of new semantics for the NXT RR that are - incompatible with the semantics in RFC 2535 [RFC2535]. Answers - provided by DS-aware servers can trigger an unacceptable failure - mode in some resolvers that implement RFC 2535, which provides a - great disincentive to sign zones with DS. The changes defined in - this document allow for the incremental deployment of DS. - -1.1 Terminology - - In this document, the term "unsecure delegation" means any - delegation for which no DS record appears at the parent. An - "unsecure referral" is an answer from the parent containing an NS - RRset and a proof that no DS record exists for that name. - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in [RFC2119]. - -1.2 The Problem - - Delegation Signer introduces new semantics for the NXT RR that are - incompatible with the semantics in RFC 2535. In RFC 2535, NXT - records were only required to be returned as part of a - non-existence proof. With DS, an unsecure referral returns, in - addition to the NS, a proof of non-existence of a DS RR in the form - of an NXT and SIG(NXT). RFC 2535 didn't specify how a resolver was - to interpret a response with both an NS and an NXT in the authority - section, RCODE=0, and AA=0. Some widely deployed 2535-aware - resolvers interpret any answer with an NXT as a proof of - non-existence of the requested record. This results in unsecure - delegations being invisible to 2535-aware resolvers and violates - the basic architectural principle that DNSSEC must do no harm -- - the signing of zones must not prevent the resolution of unsecured - delegations. - -2. Possible Solutions - - This section presents several solutions that were considered. - Section 3 describes the one selected. - -2.1. Change SIG, KEY, and NXT type codes - - To avoid the problem described above, legacy (RFC2535-aware) - resolvers need to be kept from seeing unsecure referrals that - include NXT records in the authority section. The simplest way to - do that is to change the type codes for SIG, KEY, and NXT. - - The obvious drawback to this is that new resolvers will not be able - to validate zones signed with the old RRs. This problem already - exists, however, because of the changes made by DS, and resolvers - that understand the old RRs (and have compatibility issues with DS) - are far more prevalent than 2535-signed zones. - -2.2. Change a subset of type codes - - The observed problem with unsecure referrals could be addressed by - changing only the NXT type code or another subset of the type codes - that includes NXT. This has the virtue of apparent simplicity, but - it risks introducing new problems or not going far enough. It's - quite possible that more incompatibilities exist between DS and - earlier semantics. Legacy resolvers may also be confused by seeing - records they recognize (SIG and KEY) while being unable to find - NXTs. Although it may seem unnecessary to fix that which is not - obviously broken, it's far cleaner to change all of the type codes - at once. This will leave legacy resolvers and tools completely - blinded to DNSSEC -- they will see only unknown RRs. - -2.3. Replace the DO bit - - Another way to keep legacy resolvers from ever seeing DNSSEC - records with DS semantics is to have authoritative servers only - send that data to DS-aware resolvers. It's been proposed that - assigning a new EDNS0 flag bit to signal DS-awareness (tentatively - called "DA"), and having authoritative servers send DNSSEC data - only in response to queries with the DA bit set, would accomplish - this. This bit would presumably supplant the DO bit described in - RFC 3225. - - This solution is sufficient only if all 2535-aware resolvers zero - out EDNS0 flags that they don't understand. If one passed through - the DA bit unchanged, it would still see the new semantics, and it - would probably fail to see unsecure delegations. Since it's - impractical to know how every DNS implementation handles unknown - EDNS0 flags, this is not a universal solution. It could, though, - be considered in addition to changing the RR type codes. - -2.4. Increment the EDNS version - - Another possible solution is to increment the EDNS version number - as defined in RFC 2671 [RFC2671], on the assumption that all - existing implementations will reject higher versions than they - support, and retain the DO bit as the signal for DNSSEC awareness. - This approach has not been tested. - -2.5. Do nothing - - There is a large deployed base of DNS resolvers that understand - DNSSEC as defined by the standards track RFC 2535 and RFC 2065 - and, due to under specification in those documents, interpret any - answer with an NXT as a non-existence proof. So long as that is - the case, zone owners will have a strong incentive to not sign any - zones that contain unsecure delegations, lest those delegations be - invisible to such a large installed base. This will dramatically - slow DNSSEC adoption. - - Unfortunately, without signed zones there's no clear incentive for - operators of resolvers to upgrade their software to support the new - version of DNSSEC, as defined in [DS]. Historical data suggests - that resolvers are rarely upgraded, and that old nameserver code - never dies. - - Rather than wait years for resolvers to be upgraded through natural - processes before signing zones with unsecure delegations, - addressing this problem with a protocol change will immediately - remove the disincentive for signing zones and allow widespread - deployment of DNSSEC. - -3. Protocol changes - - This document changes the type codes of SIG, KEY, and NXT. This - approach is the cleanest and safest of those discussed above, - largely because the behavior of resolvers that receive unknown type - codes is well understood. This approach has also received the most - testing. - - To avoid operational confusion, it's also necessary to change the - mnemonics for these RRs. DNSKEY will be the replacement for KEY, - with the mnemonic indicating that these keys are not for - application use, per [RFC3445]. RRSIG (Resource Record SIGnature) - will replace SIG, and NSEC (Next SECure) will replace NXT. These - new types completely replace the old types, except that SIG(0) - [RFC2931] and TKEY [RFC2930] will continue to use SIG and KEY. - - The new types will have exactly the same syntax and semantics as - specified for SIG, KEY, and NXT in RFC 2535 and [DS] except for - the following: - - 1) Consistent with [RFC3597], domain names embedded in - RRSIG and NSEC RRs MUST NOT be compressed, - - 2) Embedded domain names in RRSIG and NSEC RRs are not downcased - for purposes of DNSSEC canonical form and ordering nor for - equality comparison, and - - 3) An RRSIG with a type-covered field of zero has undefined - semantics. The meaning of such a resource record may only be - defined by IETF Standards Action. - - If a resolver receives the old types, it SHOULD treat them as - unknown RRs and SHOULD NOT assign any special meaning to them or - give them any special treatment. It MUST NOT use them for DNSSEC - validations or other DNS operational decision making. For example, - a resolver MUST NOT use DNSKEYs to validate SIGs or use KEYs to - validate RRSIGs. If SIG, KEY, or NXT RRs are included in a zone, - they MUST NOT receive special treatment. As an example, if a SIG - is included in a signed zone, there MUST be an RRSIG for it. - Authoritative servers may wish to give error messages when loading - zones containing SIG or NXT records (KEY records may be included - for SIG(0) or TKEY). - - As a clarification to previous documents, some positive responses, - particularly wildcard proofs and unsecure referrals, will contain - NSEC RRs. Resolvers MUST NOT treat answers with NSEC RRs as - negative answers merely because they contain an NSEC. - -4. IANA Considerations - -4.1 DNS Resource Record Types - - This document updates the IANA registry for DNS Resource Record - Types by assigning types 46, 47, and 48 to the RRSIG, NSEC, and - DNSKEY RRs, respectively. - - Types 24 and 25 (SIG and KEY) are retained for SIG(0) [RFC2931] and - TKEY [RFC2930] use only. - - Type 30 (NXT) should be marked as Obsolete. - -4.2 DNS Security Algorithm Numbers - - To allow zone signing (DNSSEC) and transaction security mechanisms - (SIG(0) and TKEY) to use different sets of algorithms, the existing - "DNS Security Algorithm Numbers" registry is modified to include - the applicability of each algorithm. Specifically, two new columns - are added to the registry, showing whether each algorithm may be - used for zone signing, transaction security mechanisms, or both. - Only algorithms usable for zone signing may be used in DNSKEY, - RRSIG, and DS RRs. Only algorithms usable for SIG(0) and/or TSIG - may be used in SIG and KEY RRs. - - All currently defined algorithms remain usable for transaction - security mechanisms. Only RSA/SHA-1, DSA/SHA-1, and private - algorithms (types 253 and 254) may be used for zone signing. Note - that the registry does not contain the requirement level of each - algorithm, only whether or not an algorithm may be used for the - given purposes. For example, RSA/MD5, while allowed for - transaction security mechanisms, is NOT RECOMMENDED, per RFC3110. - - Additionally, the presentation format algorithm mnemonics from - RFC2535 Section 7 are added to the registry. This document assigns - RSA/SHA-1 the mnemonic RSASHA1. - - As before, assignment of new algorithms in this registry requires - IETF Standards Action. Additionally, modification of algorithm - mnemonics or applicability requires IETF Standards Action. - Documents defining a new algorithm must address the applicability - of the algorithm and should assign a presentation mnemonic to the - algorithm. - -4.3 DNSKEY Flags - - Like the KEY resource record, DNSKEY contains a 16-bit flags field. - This document creates a new registry for the DNSKEY flags field. - - Initially, this registry only contains an assignment for bit 7 (the - ZONE bit). Bits 0-6 and 8-15 are available for assignment by IETF - Standards Action. - -4.4 DNSKEY Protocol Octet - - Like the KEY resource record, DNSKEY contains an eight bit protocol - field. The only defined value for this field is 3 (DNSSEC). No - other values are allowed, hence no IANA registry is needed for this - field. - -5. Security Considerations - - The changes introduced here do not materially affect security. - The implications of trying to use both new and legacy types - together are not well understood, and attempts to do so would - probably lead to unintended and dangerous results. - - Changing type codes will leave code paths in legacy resolvers that - are never exercised. Unexercised code paths are a frequent source - of security holes, largely because those code paths do not get - frequent scrutiny. - - Doing nothing, as described in section 2.5, will slow DNSSEC - deployment. While this does not decrease security, it also fails - to increase it. - -6. Normative references - - [RFC2535] Eastlake, D., "Domain Name System Security Extensions", - RFC 2535, March 1999. - - [DS] Gudmundsson, O., "Delegation Signer Resource Record", - draft-ietf-dnsext-delegation-signer-15.txt, work in - progress, June 2003. - - [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - - [RFC2931] Eastlake, D., "DNS Request and Transaction Signatures - (SIG(0)s)", RFC 2931, September 2000. - - [RFC2930] Eastlake, D., "Secret Key Establishment for DNS (TKEY - RR)", RFC 2930, September 2000. - - [RFC2536] Eastlake, D., "DSA KEYs and SIGs in the Domain Name - System (DNS)", RFC 2436, March 1999. - - [RFC2539] Eastlake, D., "Storage of Diffie-Hellman Keys in the - Domain Name System (DNS)", RFC 2539, March 1999. - - [RFC3110] Eastlake, D., "RSA/SHA-1 SIGs and RSA KEYs in the - Domain Name System (DNS)", RFC 3110, May 2001. - -7. Informative References - - [RFC2065] Eastlake, D. and C. Kaufman, "Domain Name System Security - Extensions", RFC 2065, January 1997. - - [RFC2671] Vixie, P., "Extension Mechanisms for DNS (EDNS0)", RFC - 2671, August 1999. - - [RFC3225] Conrad, D., "Indicating Resolver Support of DNSSEC", RFC - 3225, December 2001. - - [RFC2929] Eastlake, D., E. Brunner-Williams, and B. Manning, - "Domain Name System (DNS) IANA Considerations", BCP 42, - RFC 2929, September 2000. - - [RFC3445] Massey, D., and S. Rose, "Limiting the Scope of the KEY - Resource Record (RR)", RFC 3445, December 2002. - - [RFC3597] Gustafsson, A., "Handling of Unknown DNS Resource - Record (RR) Types", RFC 3597, September 2003. - -8. Acknowledgments - - The changes introduced here and the analysis of alternatives had - many contributors. With apologies to anyone overlooked, those - include: Micheal Graff, John Ihren, Olaf Kolkman, Mark Kosters, Ed - Lewis, Bill Manning, and Suzanne Woolf. - - Thanks to Jakob Schlyter and Mark Andrews for identifying the - incompatibility described in section 1.2. - - In addition to the above, the author would like to thank Scott - Rose, Olafur Gudmundsson, and Sandra Murphy for their substantive - comments. - -9. Author's Address - - Samuel Weiler - SPARTA, Inc. - 7075 Samuel Morse Drive - Columbia, MD 21046 - USA - weiler@tislabs.com - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-bis-updates-01.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-bis-updates-01.txt deleted file mode 100644 index 3a800f9..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-bis-updates-01.txt +++ /dev/null @@ -1,616 +0,0 @@ - - - -Network Working Group S. Weiler -Internet-Draft SPARTA, Inc -Updates: 4034, 4035 (if approved) May 23, 2005 -Expires: November 24, 2005 - - - Clarifications and Implementation Notes for DNSSECbis - draft-ietf-dnsext-dnssec-bis-updates-01 - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on November 24, 2005. - -Copyright Notice - - Copyright (C) The Internet Society (2005). - -Abstract - - This document is a collection of minor technical clarifications to - the DNSSECbis document set. It is meant to serve as a resource to - implementors as well as an interim repository of possible DNSSECbis - errata. - - - - - - - -Weiler Expires November 24, 2005 [Page 1] - -Internet-Draft DNSSECbis Implementation Notes May 2005 - - -Proposed additions in future versions - - An index sorted by the section of DNSSECbis being clarified. - - A list of proposed protocol changes being made in other documents, - such as NSEC3 and Epsilon. This document would not make those - changes, merely provide an index into the documents that are making - changes. - -Changes between -00 and -01 - - Document significantly restructured. - - Added section on QTYPE=ANY. - -Changes between personal submission and first WG draft - - Added Section 2.1 based on namedroppers discussions from March 9-10, - 2005. - - Added Section 3.4, Section 3.3, Section 4.3, and Section 2.2. - - Added the DNSSECbis RFC numbers. - - Figured out the confusion in Section 4.1. - - - - - - - - - - - - - - - - - - - - - - - - - - -Weiler Expires November 24, 2005 [Page 2] - -Internet-Draft DNSSECbis Implementation Notes May 2005 - - -Table of Contents - - 1. Introduction and Terminology . . . . . . . . . . . . . . . . . 4 - 1.1 Structure of this Document . . . . . . . . . . . . . . . . 4 - 1.2 Terminology . . . . . . . . . . . . . . . . . . . . . . . 4 - 2. Significant Concerns . . . . . . . . . . . . . . . . . . . . . 4 - 2.1 Clarifications on Non-Existence Proofs . . . . . . . . . . 4 - 2.2 Empty Non-Terminal Proofs . . . . . . . . . . . . . . . . 5 - 2.3 Validating Responses to an ANY Query . . . . . . . . . . . 5 - 3. Interoperability Concerns . . . . . . . . . . . . . . . . . . 5 - 3.1 Unknown DS Message Digest Algorithms . . . . . . . . . . . 5 - 3.2 Private Algorithms . . . . . . . . . . . . . . . . . . . . 6 - 3.3 Caution About Local Policy and Multiple RRSIGs . . . . . . 6 - 3.4 Key Tag Calculation . . . . . . . . . . . . . . . . . . . 7 - 4. Minor Corrections and Clarifications . . . . . . . . . . . . . 7 - 4.1 Finding Zone Cuts . . . . . . . . . . . . . . . . . . . . 7 - 4.2 Clarifications on DNSKEY Usage . . . . . . . . . . . . . . 7 - 4.3 Errors in Examples . . . . . . . . . . . . . . . . . . . . 8 - 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 8 - 6. Security Considerations . . . . . . . . . . . . . . . . . . . 8 - 7. References . . . . . . . . . . . . . . . . . . . . . . . . . . 8 - 7.1 Normative References . . . . . . . . . . . . . . . . . . . 8 - 7.2 Informative References . . . . . . . . . . . . . . . . . . 9 - Author's Address . . . . . . . . . . . . . . . . . . . . . . . 9 - A. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 9 - Intellectual Property and Copyright Statements . . . . . . . . 11 - - - - - - - - - - - - - - - - - - - - - - - - - -Weiler Expires November 24, 2005 [Page 3] - -Internet-Draft DNSSECbis Implementation Notes May 2005 - - -1. Introduction and Terminology - - This document lists some minor clarifications and corrections to - DNSSECbis, as described in [1], [2], and [3]. - - It is intended to serve as a resource for implementors and as a - repository of items that need to be addressed when advancing the - DNSSECbis documents from Proposed Standard to Draft Standard. - - In this version (-01 of the WG document), feedback is particularly - solicited on the structure of the document and whether the text in - the recently added sections is correct and sufficient. - - Proposed substantive additions to this document should be sent to the - namedroppers mailing list as well as to the editor of this document. - The editor would greatly prefer text suitable for direct inclusion in - this document. - -1.1 Structure of this Document - - The clarifications to DNSSECbis are sorted according to the editor's - impression of their importance, starting with ones which could, if - ignored, lead to security and stability problems and progressing down - to clarifications that are likely to have little operational impact. - Mere typos and awkward phrasings are not addressed unless they could - lead to misinterpretation of the DNSSECbis documents. - -1.2 Terminology - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in RFC 2119 [4]. - -2. Significant Concerns - - This section provides clarifications that, if overlooked, could lead - to security issues or major interoperability problems. - -2.1 Clarifications on Non-Existence Proofs - - RFC4035 Section 5.4 slightly underspecifies the algorithm for - checking non-existence proofs. In particular, the algorithm there - might incorrectly allow the NSEC from the parent side of a zone cut - to prove the non-existence of either other RRs at that name in the - child zone or other names in the child zone. It might also allow a - NSEC at the same name as a DNAME to prove the non-existence of names - beneath that DNAME. - - - - -Weiler Expires November 24, 2005 [Page 4] - -Internet-Draft DNSSECbis Implementation Notes May 2005 - - - A parent-side delegation NSEC (one with the NS bit set, but no SOA - bit set, and with a singer field that's shorter than the owner name) - must not be used to assume non-existence of any RRs below that zone - cut (both RRs at that ownername and at ownernames with more leading - labels, no matter their content). Similarly, an NSEC with the DNAME - bit set must not be used to assume the non-existence of any - descendant of that NSEC's owner name. - -2.2 Empty Non-Terminal Proofs - - To be written, based on Roy Arends' May 11th message to namedroppers. - -2.3 Validating Responses to an ANY Query - - RFC4035 does not address now to validate responses when QTYPE=*. As - described in Section 6.2.2 of RFC1034, a proper response to QTYPE=* - may include a subset of the RRsets at a given name -- it is not - necessary to include all RRsets at the QNAME in the response. - - When validating a response to QTYPE=*, validate all received RRsets - that match QNAME and QCLASS. If any of those RRsets fail validation, - treat the answer as Bogus. If there are no RRsets matching QNAME and - QCLASS, validate that fact using the rules in RFC4035 Section 5.4 (as - clarified in this document). To be clear, a validator must not - insist on receiving all records at the QNAME in response to QTYPE=*. - -3. Interoperability Concerns - -3.1 Unknown DS Message Digest Algorithms - - Section 5.2 of RFC4035 includes rules for how to handle delegations - to zones that are signed with entirely unsupported algorithms, as - indicated by the algorithms shown in those zone's DS RRsets. It does - not explicitly address how to handle DS records that use unsupported - message digest algorithms. In brief, DS records using unknown or - unsupported message digest algorithms MUST be treated the same way as - DS records referring to DNSKEY RRs of unknown or unsupported - algorithms. - - The existing text says: - - If the validator does not support any of the algorithms listed - in an authenticated DS RRset, then the resolver has no supported - authentication path leading from the parent to the child. The - resolver should treat this case as it would the case of an - authenticated NSEC RRset proving that no DS RRset exists, as - described above. - - - - -Weiler Expires November 24, 2005 [Page 5] - -Internet-Draft DNSSECbis Implementation Notes May 2005 - - - To paraphrase the above, when determining the security status of a - zone, a validator discards (for this purpose only) any DS records - listing unknown or unsupported algorithms. If none are left, the - zone is treated as if it were unsigned. - - Modified to consider DS message digest algorithms, a validator also - discards any DS records using unknown or unsupported message digest - algorithms. - -3.2 Private Algorithms - - As discussed above, section 5.2 of RFC4035 requires that validators - make decisions about the security status of zones based on the public - key algorithms shown in the DS records for those zones. In the case - of private algorithms, as described in RFC4034 Appendix A.1.1, the - eight-bit algorithm field in the DS RR is not conclusive about what - algorithm(s) is actually in use. - - If no private algorithms appear in the DS set or if any supported - algorithm appears in the DS set, no special processing will be - needed. In the remaining cases, the security status of the zone - depends on whether or not the resolver supports any of the private - algorithms in use (provided that these DS records use supported hash - functions, as discussed in Section 3.1). In these cases, the - resolver MUST retrieve the corresponding DNSKEY for each private - algorithm DS record and examine the public key field to determine the - algorithm in use. The security-aware resolver MUST ensure that the - hash of the DNSKEY RR's owner name and RDATA matches the digest in - the DS RR. If they do not match, and no other DS establishes that - the zone is secure, the referral should be considered BAD data, as - discussed in RFC4035. - - This clarification facilitates the broader use of private algorithms, - as suggested by [5]. - -3.3 Caution About Local Policy and Multiple RRSIGs - - When multiple RRSIGs cover a given RRset, RFC4035 Section 5.3.3 - suggests that "the local resolver security policy determines whether - the resolver also has to test these RRSIG RRs and how to resolve - conflicts if these RRSIG RRs lead to differing results." In most - cases, a resolver would be well advised to accept any valid RRSIG as - sufficient. If the first RRSIG tested fails validation, a resolver - would be well advised to try others, giving a successful validation - result if any can be validated and giving a failure only if all - RRSIGs fail validation. - - If a resolver adopts a more restrictive policy, there's a danger that - - - -Weiler Expires November 24, 2005 [Page 6] - -Internet-Draft DNSSECbis Implementation Notes May 2005 - - - properly-signed data might unnecessarily fail validation, perhaps - because of cache timing issues. Furthermore, certain zone management - techniques, like the Double Signature Zone-signing Key Rollover - method described in section 4.2.1.2 of [6] might not work reliably. - -3.4 Key Tag Calculation - - RFC4034 Appendix B.1 incorrectly defines the Key Tag field - calculation for algorithm 1. It correctly says that the Key Tag is - the most significant 16 of the least significant 24 bits of the - public key modulus. However, RFC4034 then goes on to incorrectly say - that this is 4th to last and 3rd to last octets of the public key - modulus. It is, in fact, the 3rd to last and 2nd to last octets. - -4. Minor Corrections and Clarifications - -4.1 Finding Zone Cuts - - Appendix C.8 of RFC4035 discusses sending DS queries to the servers - for a parent zone. To do that, a resolver may first need to apply - special rules to discover what those servers are. - - As explained in Section 3.1.4.1 of RFC4035, security-aware name - servers need to apply special processing rules to handle the DS RR, - and in some situations the resolver may also need to apply special - rules to locate the name servers for the parent zone if the resolver - does not already have the parent's NS RRset. Section 4.2 of RFC4035 - specifies a mechanism for doing that. - -4.2 Clarifications on DNSKEY Usage - - Questions of the form "can I use a different DNSKEY for signing the - X" have occasionally arisen. - - The short answer is "yes, absolutely". You can even use a different - DNSKEY for each RRset in a zone, subject only to practical limits on - the size of the DNSKEY RRset. However, be aware that there is no way - to tell resolvers what a particularly DNSKEY is supposed to be used - for -- any DNSKEY in the zone's signed DNSKEY RRset may be used to - authenticate any RRset in the zone. For example, if a weaker or less - trusted DNSKEY is being used to authenticate NSEC RRsets or all - dynamically updated records, that same DNSKEY can also be used to - sign any other RRsets from the zone. - - Furthermore, note that the SEP bit setting has no effect on how a - DNSKEY may be used -- the validation process is specifically - prohibited from using that bit by RFC4034 section 2.1.2. It possible - to use a DNSKEY without the SEP bit set as the sole secure entry - - - -Weiler Expires November 24, 2005 [Page 7] - -Internet-Draft DNSSECbis Implementation Notes May 2005 - - - point to the zone, yet use a DNSKEY with the SEP bit set to sign all - RRsets in the zone (other than the DNSKEY RRset). It's also possible - to use a single DNSKEY, with or without the SEP bit set, to sign the - entire zone, including the DNSKEY RRset itself. - -4.3 Errors in Examples - - The text in RFC4035 Section C.1 refers to the examples in B.1 as - "x.w.example.com" while B.1 uses "x.w.example". This is painfully - obvious in the second paragraph where it states that the RRSIG labels - field value of 3 indicates that the answer was not the result of - wildcard expansion. This is true for "x.w.example" but not for - "x.w.example.com", which of course has a label count of 4 - (antithetically, a label count of 3 would imply the answer was the - result of a wildcard expansion). - - The first paragraph of RFC4035 Section C.6 also has a minor error: - the reference to "a.z.w.w.example" should instead be "a.z.w.example", - as in the previous line. - -5. IANA Considerations - - This document specifies no IANA Actions. - -6. Security Considerations - - This document does not make fundamental changes to the DNSSEC - protocol, as it was generally understood when DNSSECbis was - published. It does, however, address some ambiguities and omissions - in those documents that, if not recognized and addressed in - implementations, could lead to security failures. In particular, the - validation algorithm clarifications in Section 2 are critical for - preserving the security properties DNSSEC offers. Furthermore, - failure to address some of the interoperability concerns in Section 3 - could limit the ability to later change or expand DNSSEC, including - by adding new algorithms. - -7. References - -7.1 Normative References - - [1] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "DNS Security Introduction and Requirements", RFC 4033, - March 2005. - - [2] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "Resource Records for the DNS Security Extensions", RFC 4034, - March 2005. - - - -Weiler Expires November 24, 2005 [Page 8] - -Internet-Draft DNSSECbis Implementation Notes May 2005 - - - [3] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "Protocol Modifications for the DNS Security Extensions", - RFC 4035, March 2005. - - [4] Bradner, S., "Key words for use in RFCs to Indicate Requirement - Levels", BCP 14, RFC 2119, March 1997. - -7.2 Informative References - - [5] Blacka, D., "DNSSEC Experiments", - draft-blacka-dnssec-experiments-00 (work in progress), - December 2004. - - [6] Gieben, R. and O. Kolkman, "DNSSEC Operational Practices", - draft-ietf-dnsop-dnssec-operational-practices-04 (work in - progress), May 2005. - - -Author's Address - - Samuel Weiler - SPARTA, Inc - 7075 Samuel Morse Drive - Columbia, Maryland 21046 - US - - Email: weiler@tislabs.com - -Appendix A. Acknowledgments - - The editor is extremely grateful to those who, in addition to finding - errors and omissions in the DNSSECbis document set, have provided - text suitable for inclusion in this document. - - The lack of specificity about handling private algorithms, as - described in Section 3.2, and the lack of specificity in handling ANY - queries, as described in Section 2.3, were discovered by David - Blacka. - - The error in algorithm 1 key tag calculation, as described in - Section 3.4, was found by Abhijit Hayatnagarkar. Donald Eastlake - contributed text for Section 3.4. - - The bug relating to delegation NSEC RR's in Section 2.1 was found by - Roy Badami. Roy Arends found the related problem with DNAME. - - The errors in the RFC4035 examples were found by Roy Arends, who also - contributed text for Section 4.3 of this document. - - - -Weiler Expires November 24, 2005 [Page 9] - -Internet-Draft DNSSECbis Implementation Notes May 2005 - - - The editor would like to thank Olafur Gudmundsson and Scott Rose for - their substantive comments on the text of this document. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Weiler Expires November 24, 2005 [Page 10] - -Internet-Draft DNSSECbis Implementation Notes May 2005 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2005). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Weiler Expires November 24, 2005 [Page 11] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-experiments-01.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-experiments-01.txt deleted file mode 100644 index ee03583..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-experiments-01.txt +++ /dev/null @@ -1,784 +0,0 @@ - - - -DNSEXT D. Blacka -Internet-Draft Verisign, Inc. -Expires: January 19, 2006 July 18, 2005 - - - DNSSEC Experiments - draft-ietf-dnsext-dnssec-experiments-01 - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on January 19, 2006. - -Copyright Notice - - Copyright (C) The Internet Society (2005). - -Abstract - - In the long history of the development of the DNS security extensions - [1] (DNSSEC), a number of alternate methodologies and modifications - have been proposed and rejected for practical, rather than strictly - technical, reasons. There is a desire to be able to experiment with - these alternate methods in the public DNS. This document describes a - methodology for deploying alternate, non-backwards-compatible, DNSSEC - methodologies in an experimental fashion without disrupting the - deployment of standard DNSSEC. - - - - -Blacka Expires January 19, 2006 [Page 1] - -Internet-Draft DNSSEC Experiments July 2005 - - -Table of Contents - - 1. Definitions and Terminology . . . . . . . . . . . . . . . . 3 - 2. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 4 - 3. Experiments . . . . . . . . . . . . . . . . . . . . . . . . 5 - 4. Method . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 - 5. Defining an Experiment . . . . . . . . . . . . . . . . . . . 8 - 6. Considerations . . . . . . . . . . . . . . . . . . . . . . . 9 - 7. Transitions . . . . . . . . . . . . . . . . . . . . . . . . 10 - 8. Security Considerations . . . . . . . . . . . . . . . . . . 11 - 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . 12 - 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 13 - 10.1 Normative References . . . . . . . . . . . . . . . . . . 13 - 10.2 Informative References . . . . . . . . . . . . . . . . . 13 - Author's Address . . . . . . . . . . . . . . . . . . . . . . 13 - Intellectual Property and Copyright Statements . . . . . . . 14 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Blacka Expires January 19, 2006 [Page 2] - -Internet-Draft DNSSEC Experiments July 2005 - - -1. Definitions and Terminology - - Throughout this document, familiarity with the DNS system (RFC 1035 - [4]) and the DNS security extensions ([1], [2], and [3]. - - The key words "MUST, "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY, and "OPTIONAL" in this - document are to be interpreted as described in RFC 2119 [5]. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Blacka Expires January 19, 2006 [Page 3] - -Internet-Draft DNSSEC Experiments July 2005 - - -2. Overview - - Historically, experimentation with DNSSEC alternatives has been a - problematic endeavor. There has typically been a desire to both - introduce non-backwards-compatible changes to DNSSEC, and to try - these changes on real zones in the public DNS. This creates a - problem when the change to DNSSEC would make all or part of the zone - using those changes appear bogus (bad) or otherwise broken to - existing DNSSEC-aware resolvers. - - This document describes a standard methodology for setting up public - DNSSEC experiments. This methodology addresses the issue of co- - existence with standard DNSSEC and DNS by using unknown algorithm - identifiers to hide the experimental DNSSEC protocol modifications - from standard DNSSEC-aware resolvers. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Blacka Expires January 19, 2006 [Page 4] - -Internet-Draft DNSSEC Experiments July 2005 - - -3. Experiments - - When discussing DNSSEC experiments, it is necessary to classify these - experiments into two broad categories: - - Backwards-Compatible: describes experimental changes that, while not - strictly adhering to the DNSSEC standard, are nonetheless - interoperable with clients and server that do implement the DNSSEC - standard. - - Non-Backwards-Compatible: describes experiments that would cause a - standard DNSSEC-aware resolver to (incorrectly) determine that all - or part of a zone is bogus, or to otherwise not interoperable with - standard DNSSEC clients and servers. - - Not included in these terms are experiments with the core DNS - protocol itself. - - The methodology described in this document is not necessary for - backwards-compatible experiments, although it certainly could be used - if desired. - - Note that, in essence, this metholodolgy would also be used to - introduce a new DNSSEC algorithm, independently from any DNSSEC - experimental protocol change. - - - - - - - - - - - - - - - - - - - - - - - - - - -Blacka Expires January 19, 2006 [Page 5] - -Internet-Draft DNSSEC Experiments July 2005 - - -4. Method - - The core of the methodology is the use of strictly "unknown" - algorithms to sign the experimental zone, and more importantly, - having only unknown algorithm DS records for the delegation to the - zone at the parent. - - This technique works because of the way DNSSEC-compliant validators - are expected to work in the presence of a DS set with only unknown - algorithms. From [3], Section 5.2: - - If the validator does not support any of the algorithms listed in - an authenticated DS RRset, then the resolver has no supported - authentication path leading from the parent to the child. The - resolver should treat this case as it would the case of an - authenticated NSEC RRset proving that no DS RRset exists, as - described above. - - And further: - - If the resolver does not support any of the algorithms listed in - an authenticated DS RRset, then the resolver will not be able to - verify the authentication path to the child zone. In this case, - the resolver SHOULD treat the child zone as if it were unsigned. - - While this behavior isn't strictly mandatory (as marked by MUST), it - is unlikely that a validator would not implement the behavior, or, - more to the point, it will not violate this behavior in an unsafe way - (see below (Section 6).) - - Because we are talking about experiments, it is RECOMMENDED that - private algorithm numbers be used (see [2], appendix A.1.1. Note - that secure handling of private algorithms requires special handing - by the validator logic. See [6] for futher details.) Normally, - instead of actually inventing new signing algorithms, the recommended - path is to create alternate algorithm identifiers that are aliases - for the existing, known algorithms. While, strictly speaking, it is - only necessary to create an alternate identifier for the mandatory - algorithms, it is RECOMMENDED that all OPTIONAL defined algorithms be - aliased as well. - - It is RECOMMENDED that for a particular DNSSEC experiment, a - particular domain name base is chosen for all new algorithms, then - the algorithm number (or name) is prepended to it. For example, for - experiment A, the base name of "dnssec-experiment-a.example.com" is - chosen. Then, aliases for algorithms 3 (DSA) and 5 (RSASHA1) are - defined to be "3.dnssec-experiment-a.example.com" and "5.dnssec- - experiment-a.example.com". However, any unique identifier will - - - -Blacka Expires January 19, 2006 [Page 6] - -Internet-Draft DNSSEC Experiments July 2005 - - - suffice. - - Using this method, resolvers (or, more specificially, DNSSEC - validators) essentially indicate their ability to understand the - DNSSEC experiment's semantics by understanding what the new algorithm - identifiers signify. - - This method creates two classes of DNSSEC-aware servers and - resolvers: servers and resolvers that are aware of the experiment - (and thus recognize the experiments algorithm identifiers and - experimental semantics), and servers and resolvers that are unware of - the experiment. - - This method also precludes any zone from being both in an experiment - and in a classic DNSSEC island of security. That is, a zone is - either in an experiment and only experimentally validatable, or it - isn't. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Blacka Expires January 19, 2006 [Page 7] - -Internet-Draft DNSSEC Experiments July 2005 - - -5. Defining an Experiment - - The DNSSEC experiment must define the particular set of (previously - unknown) algorithms that identify the experiment, and define what - each unknown algorithm identifier means. Typically, unless the - experiment is actually experimenting with a new DNSSEC algorithm, - this will be a mapping of private algorithm identifiers to existing, - known algorithms. - - Normally the experiment will choose a DNS name as the algorithm - identifier base. This DNS name SHOULD be under the control of the - authors of the experiment. Then the experiment will define a mapping - between known mandatory and optional algorithms into this private - algorithm identifier space. Alternately, the experiment MAY use the - OID private algorithm space instead (using algorithm number 254), or - may choose non-private algorithm numbers, although this would require - an IANA allocation (see below (Section 9).) - - For example, an experiment might specify in its description the DNS - name "dnssec-experiment-a.example.com" as the base name, and provide - the mapping of "3.dnssec-experiment-a.example.com" is an alias of - DNSSEC algorithm 3 (DSA), and "5.dnssec-experiment-a.example.com" is - an alias of DNSSEC algorithm 5 (RSASHA1). - - Resolvers MUST then only recognize the experiment's semantics when - present in a zone signed by one or more of these private algorithms. - - In general, however, resolvers involved in the experiment are - expected to understand both standard DNSSEC and the defined - experimental DNSSEC protocol, although this isn't required. - - - - - - - - - - - - - - - - - - - - - -Blacka Expires January 19, 2006 [Page 8] - -Internet-Draft DNSSEC Experiments July 2005 - - -6. Considerations - - There are a number of considerations with using this methodology. - - 1. Under some circumstances, it may be that the experiment will not - be sufficiently masked by this technique and may cause resolution - problem for resolvers not aware of the experiment. For instance, - the resolver may look at the not validatable response and - conclude that the response is bogus, either due to local policy - or implementation details. This is not expected to be the common - case, however. - - 2. In general, it will not be possible for DNSSEC-aware resolvers - not aware of the experiment to build a chain of trust through an - experimental zone. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Blacka Expires January 19, 2006 [Page 9] - -Internet-Draft DNSSEC Experiments July 2005 - - -7. Transitions - - If an experiment is successful, there may be a desire to move the - experiment to a standards-track extension. One way to do so would be - to move from private algorithm numbers to IANA allocated algorithm - numbers, with otherwise the same meaning. This would still leave a - divide between resolvers that understood the extension versus - resolvers that did not. It would, in essence, create an additional - version of DNSSEC. - - An alternate technique might be to do a typecode rollover, thus - actually creating a definitive new version of DNSSEC. There may be - other transition techniques available, as well. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Blacka Expires January 19, 2006 [Page 10] - -Internet-Draft DNSSEC Experiments July 2005 - - -8. Security Considerations - - Zones using this methodology will be considered insecure by all - resolvers except those aware of the experiment. It is not generally - possible to create a secure delegation from an experimental zone that - will be followed by resolvers unaware of the experiment. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Blacka Expires January 19, 2006 [Page 11] - -Internet-Draft DNSSEC Experiments July 2005 - - -9. IANA Considerations - - IANA may need to allocate new DNSSEC algorithm numbers if that - transition approach is taken, or the experiment decides to use - allocated numbers to begin with. No IANA action is required to - deploy an experiment using private algorithm identifiers. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Blacka Expires January 19, 2006 [Page 12] - -Internet-Draft DNSSEC Experiments July 2005 - - -10. References - -10.1 Normative References - - [1] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "DNS Security Introduction and Requirements", RFC 4033, - March 2005. - - [2] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "Resource Records for the DNS Security Extensions", RFC 4034, - March 2005. - - [3] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "Protocol Modifications for the DNS Security Extensions", - RFC 4035, March 2005. - -10.2 Informative References - - [4] Mockapetris, P., "Domain names - implementation and - specification", STD 13, RFC 1035, November 1987. - - [5] Bradner, S., "Key words for use in RFCs to Indicate Requirement - Levels", BCP 14, RFC 2119, March 1997. - - [6] Weiler, S., "Clarifications and Implementation Notes for - DNSSECbis", draft-weiler-dnsext-dnssec-bis-updates-00 (work in - progress), March 2005. - - -Author's Address - - David Blacka - Verisign, Inc. - 21355 Ridgetop Circle - Dulles, VA 20166 - US - - Phone: +1 703 948 3200 - Email: davidb@verisign.com - URI: http://www.verisignlabs.com - - - - - - - - - - - -Blacka Expires January 19, 2006 [Page 13] - -Internet-Draft DNSSEC Experiments July 2005 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2005). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Blacka Expires January 19, 2006 [Page 14] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-online-signing-02.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-online-signing-02.txt deleted file mode 100644 index 7503c66..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-online-signing-02.txt +++ /dev/null @@ -1,616 +0,0 @@ - - - -Network Working Group S. Weiler -Internet-Draft SPARTA, Inc -Updates: 4034, 4035 (if approved) J. Ihren -Expires: July 24, 2006 Autonomica AB - January 20, 2006 - - - Minimally Covering NSEC Records and DNSSEC On-line Signing - draft-ietf-dnsext-dnssec-online-signing-02 - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on July 24, 2006. - -Copyright Notice - - Copyright (C) The Internet Society (2006). - -Abstract - - This document describes how to construct DNSSEC NSEC resource records - that cover a smaller range of names than called for by RFC4034. By - generating and signing these records on demand, authoritative name - servers can effectively stop the disclosure of zone contents - otherwise made possible by walking the chain of NSEC records in a - signed zone. - - - - -Weiler & Ihren Expires July 24, 2006 [Page 1] - -Internet-Draft NSEC Epsilon January 2006 - - -Changes from ietf-01 to ietf-02 - - Clarified that a generated NSEC RR's type bitmap MUST have the RRSIG - and NSEC bits set, to be consistent with DNSSECbis -- previous text - said SHOULD. - - Made the applicability statement a little less oppressive. - -Changes from ietf-00 to ietf-01 - - Added an applicability statement, making reference to ongoing work on - NSEC3. - - Added the phrase "epsilon functions", which has been commonly used to - describe the technique and already appeared in the header of each - page, in place of "increment and decrement functions". Also added an - explanatory sentence. - - Corrected references from 4034 section 6.2 to section 6.1. - - Fixed an out-of-date reference to [-bis] and other typos. - - Replaced IANA Considerations text. - - Escaped close parentheses in examples. - - Added some more acknowledgements. - -Changes from weiler-01 to ietf-00 - - Inserted RFC numbers for 4033, 4034, and 4035. - - Specified contents of bitmap field in synthesized NSEC RR's, pointing - out that this relaxes a constraint in 4035. Added 4035 to the - Updates header. - -Changes from weiler-00 to weiler-01 - - Clarified that this updates RFC4034 by relaxing requirements on the - next name field. - - Added examples covering wildcard names. - - In the 'better functions' section, reiterated that perfect functions - aren't needed. - - Added a reference to RFC 2119. - - - - -Weiler & Ihren Expires July 24, 2006 [Page 2] - -Internet-Draft NSEC Epsilon January 2006 - - -Table of Contents - - 1. Introduction and Terminology . . . . . . . . . . . . . . . . . 4 - 2. Applicability of This Technique . . . . . . . . . . . . . . . 4 - 3. Minimally Covering NSEC Records . . . . . . . . . . . . . . . 5 - 4. Better Epsilon Functions . . . . . . . . . . . . . . . . . . . 6 - 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 7 - 6. Security Considerations . . . . . . . . . . . . . . . . . . . 7 - 7. Normative References . . . . . . . . . . . . . . . . . . . . . 8 - Appendix A. Acknowledgments . . . . . . . . . . . . . . . . . . . 8 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 10 - Intellectual Property and Copyright Statements . . . . . . . . . . 11 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Weiler & Ihren Expires July 24, 2006 [Page 3] - -Internet-Draft NSEC Epsilon January 2006 - - -1. Introduction and Terminology - - With DNSSEC [1], an NSEC record lists the next instantiated name in - its zone, proving that no names exist in the "span" between the - NSEC's owner name and the name in the "next name" field. In this - document, an NSEC record is said to "cover" the names between its - owner name and next name. - - Through repeated queries that return NSEC records, it is possible to - retrieve all of the names in the zone, a process commonly called - "walking" the zone. Some zone owners have policies forbidding zone - transfers by arbitrary clients; this side-effect of the NSEC - architecture subverts those policies. - - This document presents a way to prevent zone walking by constructing - NSEC records that cover fewer names. These records can make zone - walking take approximately as many queries as simply asking for all - possible names in a zone, making zone walking impractical. Some of - these records must be created and signed on demand, which requires - on-line private keys. Anyone contemplating use of this technique is - strongly encouraged to review the discussion of the risks of on-line - signing in Section 6. - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in RFC 2119 [4]. - - -2. Applicability of This Technique - - The technique presented here may be useful to a zone owner that wants - to use DNSSEC, is concerned about exposure of its zone contents via - zone walking, and is willing to bear the costs of on-line signing. - - As discussed in Section 6, on-line signing has several security - risks, including an increased likelihood of private keys being - disclosed and an increased risk of denial of service attack. Anyone - contemplating use of this technique is strongly encouraged to review - the discussion of the risks of on-line signing in Section 6. - - Furthermore, at the time this document was published, the DNSEXT - working group was actively working on a mechanism to prevent zone - walking that does not require on-line signing (tentatively called - NSEC3). The new mechanism is likely to expose slightly more - information about the zone than this technique (e.g. the number of - instantiated names), but it may be preferable to this technique. - - - - - -Weiler & Ihren Expires July 24, 2006 [Page 4] - -Internet-Draft NSEC Epsilon January 2006 - - -3. Minimally Covering NSEC Records - - This mechanism involves changes to NSEC records for instantiated - names, which can still be generated and signed in advance, as well as - the on-demand generation and signing of new NSEC records whenever a - name must be proven not to exist. - - In the 'next name' field of instantiated names' NSEC records, rather - than list the next instantiated name in the zone, list any name that - falls lexically after the NSEC's owner name and before the next - instantiated name in the zone, according to the ordering function in - RFC4034 [2] section 6.1. This relaxes the requirement in section - 4.1.1 of RFC4034 that the 'next name' field contains the next owner - name in the zone. This change is expected to be fully compatible - with all existing DNSSEC validators. These NSEC records are returned - whenever proving something specifically about the owner name (e.g. - that no resource records of a given type appear at that name). - - Whenever an NSEC record is needed to prove the non-existence of a - name, a new NSEC record is dynamically produced and signed. The new - NSEC record has an owner name lexically before the QNAME but - lexically following any existing name and a 'next name' lexically - following the QNAME but before any existing name. - - The generated NSEC record's type bitmap MUST have the RRSIG and NSEC - bits set and SHOULD NOT have any other bits set. This relaxes the - requirement in Section 2.3 of RFC4035 that NSEC RRs not appear at - names that did not exist before the zone was signed. - - The functions to generate the lexically following and proceeding - names need not be perfect nor consistent, but the generated NSEC - records must not cover any existing names. Furthermore, this - technique works best when the generated NSEC records cover as few - names as possible. In this document, the functions that generate the - nearby names are called 'epsilon' functions, a reference to the - mathematical convention of using the greek letter epsilon to - represent small deviations. - - An NSEC record denying the existence of a wildcard may be generated - in the same way. Since the NSEC record covering a non-existent - wildcard is likely to be used in response to many queries, - authoritative name servers using the techniques described here may - want to pregenerate or cache that record and its corresponding RRSIG. - - For example, a query for an A record at the non-instantiated name - example.com might produce the following two NSEC records, the first - denying the existence of the name example.com and the second denying - the existence of a wildcard: - - - -Weiler & Ihren Expires July 24, 2006 [Page 5] - -Internet-Draft NSEC Epsilon January 2006 - - - exampld.com 3600 IN NSEC example-.com ( RRSIG NSEC ) - - \).com 3600 IN NSEC +.com ( RRSIG NSEC ) - - Before answering a query with these records, an authoritative server - must test for the existence of names between these endpoints. If the - generated NSEC would cover existing names (e.g. exampldd.com or - *bizarre.example.com), a better epsilon function may be used or the - covered name closest to the QNAME could be used as the NSEC owner - name or next name, as appropriate. If an existing name is used as - the NSEC owner name, that name's real NSEC record MUST be returned. - Using the same example, assuming an exampldd.com delegation exists, - this record might be returned from the parent: - - exampldd.com 3600 IN NSEC example-.com ( NS DS RRSIG NSEC ) - - Like every authoritative record in the zone, each generated NSEC - record MUST have corresponding RRSIGs generated using each algorithm - (but not necessarily each DNSKEY) in the zone's DNSKEY RRset, as - described in RFC4035 [3] section 2.2. To minimize the number of - signatures that must be generated, a zone may wish to limit the - number of algorithms in its DNSKEY RRset. - - -4. Better Epsilon Functions - - Section 6.1 of RFC4034 defines a strict ordering of DNS names. - Working backwards from that definition, it should be possible to - define epsilon functions that generate the immediately following and - preceding names, respectively. This document does not define such - functions. Instead, this section presents functions that come - reasonably close to the perfect ones. As described above, an - authoritative server should still ensure than no generated NSEC - covers any existing name. - - To increment a name, add a leading label with a single null (zero- - value) octet. - - To decrement a name, decrement the last character of the leftmost - label, then fill that label to a length of 63 octets with octets of - value 255. To decrement a null (zero-value) octet, remove the octet - -- if an empty label is left, remove the label. Defining this - function numerically: fill the left-most label to its maximum length - with zeros (numeric, not ASCII zeros) and subtract one. - - In response to a query for the non-existent name foo.example.com, - these functions produce NSEC records of: - - - - -Weiler & Ihren Expires July 24, 2006 [Page 6] - -Internet-Draft NSEC Epsilon January 2006 - - - fon\255\255\255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255 - \255.example.com 3600 IN NSEC \000.foo.example.com ( NSEC RRSIG ) - - \)\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255 - \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255 - \255\255.example.com 3600 IN NSEC \000.*.example.com ( NSEC RRSIG ) - - The first of these NSEC RRs proves that no exact match for - foo.example.com exists, and the second proves that there is no - wildcard in example.com. - - Both of these functions are imperfect: they don't take into account - constraints on number of labels in a name nor total length of a name. - As noted in the previous section, though, this technique does not - depend on the use of perfect epsilon functions: it is sufficient to - test whether any instantiated names fall into the span covered by the - generated NSEC and, if so, substitute those instantiated owner names - for the NSEC owner name or next name, as appropriate. - - -5. IANA Considerations - - This document specifies no IANA Actions. - - -6. Security Considerations - - This approach requires on-demand generation of RRSIG records. This - creates several new vulnerabilities. - - First, on-demand signing requires that a zone's authoritative servers - have access to its private keys. Storing private keys on well-known - internet-accessible servers may make them more vulnerable to - unintended disclosure. - - Second, since generation of digital signatures tends to be - computationally demanding, the requirement for on-demand signing - makes authoritative servers vulnerable to a denial of service attack. - - Lastly, if the epsilon functions are predictable, on-demand signing - may enable a chosen-plaintext attack on a zone's private keys. Zones - using this approach should attempt to use cryptographic algorithms - that are resistant to chosen-plaintext attacks. It's worth noting - - - -Weiler & Ihren Expires July 24, 2006 [Page 7] - -Internet-Draft NSEC Epsilon January 2006 - - - that while DNSSEC has a "mandatory to implement" algorithm, that is a - requirement on resolvers and validators -- there is no requirement - that a zone be signed with any given algorithm. - - The success of using minimally covering NSEC record to prevent zone - walking depends greatly on the quality of the epsilon functions - chosen. An increment function that chooses a name obviously derived - from the next instantiated name may be easily reverse engineered, - destroying the value of this technique. An increment function that - always returns a name close to the next instantiated name is likewise - a poor choice. Good choices of epsilon functions are the ones that - produce the immediately following and preceding names, respectively, - though zone administrators may wish to use less perfect functions - that return more human-friendly names than the functions described in - Section 4 above. - - Another obvious but misguided concern is the danger from synthesized - NSEC records being replayed. It's possible for an attacker to replay - an old but still validly signed NSEC record after a new name has been - added in the span covered by that NSEC, incorrectly proving that - there is no record at that name. This danger exists with DNSSEC as - defined in [3]. The techniques described here actually decrease the - danger, since the span covered by any NSEC record is smaller than - before. Choosing better epsilon functions will further reduce this - danger. - -7. Normative References - - [1] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "DNS Security Introduction and Requirements", RFC 4033, - March 2005. - - [2] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "Resource Records for the DNS Security Extensions", RFC 4034, - March 2005. - - [3] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "Protocol Modifications for the DNS Security Extensions", - RFC 4035, March 2005. - - [4] Bradner, S., "Key words for use in RFCs to Indicate Requirement - Levels", BCP 14, RFC 2119, March 1997. - - -Appendix A. Acknowledgments - - Many individuals contributed to this design. They include, in - addition to the authors of this document, Olaf Kolkman, Ed Lewis, - - - -Weiler & Ihren Expires July 24, 2006 [Page 8] - -Internet-Draft NSEC Epsilon January 2006 - - - Peter Koch, Matt Larson, David Blacka, Suzanne Woolf, Jaap Akkerhuis, - Jakob Schlyter, Bill Manning, and Joao Damas. - - In addition, the editors would like to thank Ed Lewis, Scott Rose, - and David Blacka for their careful review of the document. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Weiler & Ihren Expires July 24, 2006 [Page 9] - -Internet-Draft NSEC Epsilon January 2006 - - -Authors' Addresses - - Samuel Weiler - SPARTA, Inc - 7075 Samuel Morse Drive - Columbia, Maryland 21046 - US - - Email: weiler@tislabs.com - - - Johan Ihren - Autonomica AB - Bellmansgatan 30 - Stockholm SE-118 47 - Sweden - - Email: johani@autonomica.se - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Weiler & Ihren Expires July 24, 2006 [Page 10] - -Internet-Draft NSEC Epsilon January 2006 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2006). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Weiler & Ihren Expires July 24, 2006 [Page 11] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-opt-in-07.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-opt-in-07.txt deleted file mode 100644 index 17e28e8..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-opt-in-07.txt +++ /dev/null @@ -1,896 +0,0 @@ - - - -DNSEXT R. Arends -Internet-Draft Telematica Instituut -Expires: January 19, 2006 M. Kosters - D. Blacka - Verisign, Inc. - July 18, 2005 - - - DNSSEC Opt-In - draft-ietf-dnsext-dnssec-opt-in-07 - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on January 19, 2006. - -Copyright Notice - - Copyright (C) The Internet Society (2005). - -Abstract - - In the DNS security extensions (DNSSEC, defined in RFC 4033 [3], RFC - 4034 [4], and RFC 4035 [5]), delegations to unsigned subzones are - cryptographically secured. Maintaining this cryptography is not - practical or necessary. This document describes an experimental - "Opt-In" model that allows administrators to omit this cryptography - and manage the cost of adopting DNSSEC with large zones. - - - -Arends, et al. Expires January 19, 2006 [Page 1] - -Internet-Draft DNSSEC Opt-In July 2005 - - -Table of Contents - - 1. Definitions and Terminology . . . . . . . . . . . . . . . . . 3 - 2. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 3. Experimental Status . . . . . . . . . . . . . . . . . . . . . 4 - 4. Protocol Additions . . . . . . . . . . . . . . . . . . . . . . 4 - 4.1 Server Considerations . . . . . . . . . . . . . . . . . . 5 - 4.1.1 Delegations Only . . . . . . . . . . . . . . . . . . . 5 - 4.1.2 Insecure Delegation Responses . . . . . . . . . . . . 6 - 4.1.3 Wildcards and Opt-In . . . . . . . . . . . . . . . . . 6 - 4.1.4 Dynamic Update . . . . . . . . . . . . . . . . . . . . 7 - 4.2 Client Considerations . . . . . . . . . . . . . . . . . . 7 - 4.2.1 Delegations Only . . . . . . . . . . . . . . . . . . . 7 - 4.2.2 Validation Process Changes . . . . . . . . . . . . . . 7 - 4.2.3 NSEC Record Caching . . . . . . . . . . . . . . . . . 8 - 4.2.4 Use of the AD bit . . . . . . . . . . . . . . . . . . 8 - 5. Benefits . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 - 6. Example . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 - 7. Transition Issues . . . . . . . . . . . . . . . . . . . . . . 10 - 8. Security Considerations . . . . . . . . . . . . . . . . . . . 11 - 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 12 - 10. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . 12 - 11. References . . . . . . . . . . . . . . . . . . . . . . . . . 13 - 11.1 Normative References . . . . . . . . . . . . . . . . . . . 13 - 11.2 Informative References . . . . . . . . . . . . . . . . . . 13 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 14 - A. Implementing Opt-In using "Views" . . . . . . . . . . . . . . 14 - Intellectual Property and Copyright Statements . . . . . . . . 16 - - - - - - - - - - - - - - - - - - - - - - - -Arends, et al. Expires January 19, 2006 [Page 2] - -Internet-Draft DNSSEC Opt-In July 2005 - - -1. Definitions and Terminology - - Throughout this document, familiarity with the DNS system (RFC 1035 - [1]), DNS security extensions ([3], [4], and [5], referred to in this - document as "standard DNSSEC"), and DNSSEC terminology (RFC 3090 - [10]) is assumed. - - The following abbreviations and terms are used in this document: - - RR: is used to refer to a DNS resource record. - RRset: refers to a Resource Record Set, as defined by [8]. In this - document, the RRset is also defined to include the covering RRSIG - records, if any exist. - signed name: refers to a DNS name that has, at minimum, a (signed) - NSEC record. - unsigned name: refers to a DNS name that does not (at least) have a - NSEC record. - covering NSEC record/RRset: is the NSEC record used to prove - (non)existence of a particular name or RRset. This means that for - a RRset or name 'N', the covering NSEC record has the name 'N', or - has an owner name less than 'N' and "next" name greater than 'N'. - delegation: refers to a NS RRset with a name different from the - current zone apex (non-zone-apex), signifying a delegation to a - subzone. - secure delegation: refers to a signed name containing a delegation - (NS RRset), and a signed DS RRset, signifying a delegation to a - signed subzone. - insecure delegation: refers to a signed name containing a delegation - (NS RRset), but lacking a DS RRset, signifying a delegation to an - unsigned subzone. - Opt-In insecure delegation: refers to an unsigned name containing - only a delegation NS RRset. The covering NSEC record uses the - Opt-In methodology described in this document. - - The key words "MUST, "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY, and "OPTIONAL" in this - document are to be interpreted as described in RFC 2119 [7]. - -2. Overview - - The cost to cryptographically secure delegations to unsigned zones is - high for large delegation-centric zones and zones where insecure - delegations will be updated rapidly. For these zones, the costs of - maintaining the NSEC record chain may be extremely high relative to - the gain of cryptographically authenticating existence of unsecured - zones. - - This document describes an experimental method of eliminating the - - - -Arends, et al. Expires January 19, 2006 [Page 3] - -Internet-Draft DNSSEC Opt-In July 2005 - - - superfluous cryptography present in secure delegations to unsigned - zones. Using "Opt-In", a zone administrator can choose to remove - insecure delegations from the NSEC chain. This is accomplished by - extending the semantics of the NSEC record by using a redundant bit - in the type map. - -3. Experimental Status - - This document describes an EXPERIMENTAL extension to DNSSEC. It - interoperates with non-experimental DNSSEC using the technique - described in [6]. This experiment is identified with the following - private algorithms (using algorithm 253): - - "3.optin.verisignlabs.com": is an alias for DNSSEC algorithm 3, DSA, - and - "5.optin.verisignlabs.com": is an alias for DNSSEC algorithm 5, - RSASHA1. - - Servers wishing to sign and serve zones that utilize Opt-In MUST sign - the zone with only one or more of these private algorithms. This - requires the signing tools and servers to support private algorithms, - as well as Opt-In. - - Resolvers wishing to validate Opt-In zones MUST only do so when the - zone is only signed using one or more of these private algorithms. - - The remainder of this document assumes that the servers and resolvers - involved are aware of and are involved in this experiment. - -4. Protocol Additions - - In DNSSEC, delegation NS RRsets are not signed, but are instead - accompanied by a NSEC RRset of the same name and (possibly) a DS - record. The security status of the subzone is determined by the - presence or absence of the DS RRset, cryptographically proven by the - NSEC record. Opt-In expands this definition by allowing insecure - delegations to exist within an otherwise signed zone without the - corresponding NSEC record at the delegation's owner name. These - insecure delegations are proven insecure by using a covering NSEC - record. - - Since this represents a change of the interpretation of NSEC records, - resolvers must be able to distinguish between RFC standard DNSSEC - NSEC records and Opt-In NSEC records. This is accomplished by - "tagging" the NSEC records that cover (or potentially cover) insecure - delegation nodes. This tag is indicated by the absence of the NSEC - bit in the type map. Since the NSEC bit in the type map merely - indicates the existence of the record itself, this bit is redundant - - - -Arends, et al. Expires January 19, 2006 [Page 4] - -Internet-Draft DNSSEC Opt-In July 2005 - - - and safe for use as a tag. - - An Opt-In tagged NSEC record does not assert the (non)existence of - the delegations that it covers (except for a delegation with the same - name). This allows for the addition or removal of these delegations - without recalculating or resigning records in the NSEC chain. - However, Opt-In tagged NSEC records do assert the (non)existence of - other RRsets. - - An Opt-In NSEC record MAY have the same name as an insecure - delegation. In this case, the delegation is proven insecure by the - lack of a DS bit in type map and the signed NSEC record does assert - the existence of the delegation. - - Zones using Opt-In MAY contain a mixture of Opt-In tagged NSEC - records and standard DNSSEC NSEC records. If a NSEC record is not - Opt-In, there MUST NOT be any insecure delegations (or any other - records) between it and the RRsets indicated by the 'next domain - name' in the NSEC RDATA. If it is Opt-In, there MUST only be - insecure delegations between it and the next node indicated by the - 'next domain name' in the NSEC RDATA. - - In summary, - - o An Opt-In NSEC type is identified by a zero-valued (or not- - specified) NSEC bit in the type bit map of the NSEC record. - o A RFC2535bis NSEC type is identified by a one-valued NSEC bit in - the type bit map of the NSEC record. - - and, - - o An Opt-In NSEC record does not assert the non-existence of a name - between its owner name and "next" name, although it does assert - that any name in this span MUST be an insecure delegation. - o An Opt-In NSEC record does assert the (non)existence of RRsets - with the same owner name. - -4.1 Server Considerations - - Opt-In imposes some new requirements on authoritative DNS servers. - -4.1.1 Delegations Only - - This specification dictates that only insecure delegations may exist - between the owner and "next" names of an Opt-In tagged NSEC record. - Signing tools SHOULD NOT generate signed zones that violate this - restriction. Servers SHOULD refuse to load and/or serve zones that - violate this restriction. Servers also SHOULD reject AXFR or IXFR - - - -Arends, et al. Expires January 19, 2006 [Page 5] - -Internet-Draft DNSSEC Opt-In July 2005 - - - responses that violate this restriction. - -4.1.2 Insecure Delegation Responses - - When returning an Opt-In insecure delegation, the server MUST return - the covering NSEC RRset in the Authority section. - - In standard DNSSEC, NSEC records already must be returned along with - the insecure delegation. The primary difference that this proposal - introduces is that the Opt-In tagged NSEC record will have a - different owner name from the delegation RRset. This may require - implementations to search for the covering NSEC RRset. - -4.1.3 Wildcards and Opt-In - - Standard DNSSEC describes the practice of returning NSEC records to - prove the non-existence of an applicable wildcard in non-existent - name responses. This NSEC record can be described as a "negative - wildcard proof". The use of Opt-In NSEC records changes the - necessity for this practice. For non-existent name responses when - the query name (qname) is covered by an Opt-In tagged NSEC record, - servers MAY choose to omit the wildcard proof record, and clients - MUST NOT treat the absence of this NSEC record as a validation error. - - The intent of the standard DNSSEC negative wildcard proof requirement - is to prevent malicious users from undetectably removing valid - wildcard responses. In order for this cryptographic proof to work, - the resolver must be able to prove: - - 1. The exact qname does not exist. This is done by the "normal" - NSEC record. - 2. No applicable wildcard exists. This is done by returning a NSEC - record proving that the wildcard does not exist (this is the - negative wildcard proof). - - However, if the NSEC record covering the exact qname is an Opt-In - NSEC record, the resolver will not be able to prove the first part of - this equation, as the qname might exist as an insecure delegation. - Thus, since the total proof cannot be completed, the negative - wildcard proof NSEC record is not useful. - - The negative wildcard proof is also not useful when returned as part - of an Opt-In insecure delegation response for a similar reason: the - resolver cannot prove that the qname does or does not exist, and - therefore cannot prove that a wildcard expansion is valid. - - The presence of an Opt-In tagged NSEC record does not change the - practice of returning a NSEC along with a wildcard expansion. Even - - - -Arends, et al. Expires January 19, 2006 [Page 6] - -Internet-Draft DNSSEC Opt-In July 2005 - - - though the Opt-In NSEC will not be able to prove that the wildcard - expansion is valid, it will prove that the wildcard expansion is not - masking any signed records. - -4.1.4 Dynamic Update - - Opt-In changes the semantics of Secure DNS Dynamic Update [9]. In - particular, it introduces the need for rules that describe when to - add or remove a delegation name from the NSEC chain. This document - does not attempt to define these rules. Until these rules are - defined, servers MUST NOT process DNS Dynamic Update requests against - zones that use Opt-In NSEC records. Servers SHOULD return responses - to update requests with RCODE=REFUSED. - -4.2 Client Considerations - - Opt-In imposes some new requirements on security-aware resolvers - (caching or otherwise). - -4.2.1 Delegations Only - - As stated in the "Server Considerations" section above, this - specification restricts the namespace covered by Opt-In tagged NSEC - records to insecure delegations only. Thus, resolvers MUST reject as - invalid any records that fall within an Opt-In NSEC record's span - that are not NS records or corresponding glue records. - -4.2.2 Validation Process Changes - - This specification does not change the resolver's resolution - algorithm. However, it does change the DNSSEC validation process. - Resolvers MUST be able to use Opt-In tagged NSEC records to - cryptographically prove the validity and security status (as - insecure) of a referral. Resolvers determine the security status of - the referred-to zone as follows: - - o In standard DNSSEC, the security status is proven by the existence - or absence of a DS RRset at the same name as the delegation. The - existence of the DS RRset indicates that the referred-to zone is - signed. The absence of the DS RRset is proven using a verified - NSEC record of the same name that does not have the DS bit set in - the type map. This NSEC record MAY also be tagged as Opt-In. - o Using Opt-In, the security status is proven by the existence of a - DS record (for signed) or the presence of a verified Opt-In tagged - NSEC record that covers the delegation name. That is, the NSEC - record does not have the NSEC bit set in the type map, and the - delegation name falls between the NSEC's owner and "next" name. - - - - -Arends, et al. Expires January 19, 2006 [Page 7] - -Internet-Draft DNSSEC Opt-In July 2005 - - - Using Opt-In does not substantially change the nature of following - referrals within DNSSEC. At every delegation point, the resolver - will have cryptographic proof that the referred-to subzone is signed - or unsigned. - - When receiving either an Opt-In insecure delegation response or a - non-existent name response where that name is covered by an Opt-In - tagged NSEC record, the resolver MUST NOT require proof (in the form - of a NSEC record) that a wildcard did not exist. - -4.2.3 NSEC Record Caching - - Caching resolvers MUST be able to retrieve the appropriate covering - Opt-In NSEC record when returning referrals that need them. This - requirement differs from standard DNSSEC in that the covering NSEC - will not have the same owner name as the delegation. Some - implementations may have to use new methods for finding these NSEC - records. - -4.2.4 Use of the AD bit - - The AD bit, as defined by [2] and [5], MUST NOT be set when: - - o sending a Name Error (RCODE=3) response where the covering NSEC is - tagged as Opt-In. - o sending an Opt-In insecure delegation response, unless the - covering (Opt-In) NSEC record's owner name equals the delegation - name. - - This rule is based on what the Opt-In NSEC record actually proves: - for names that exist between the Opt-In NSEC record's owner and - "next" names, the Opt-In NSEC record cannot prove the non-existence - or existence of the name. As such, not all data in the response has - been cryptographically verified, so the AD bit cannot be set. - -5. Benefits - - Using Opt-In allows administrators of large and/or changing - delegation-centric zones to minimize the overhead involved in - maintaining the security of the zone. - - Opt-In accomplishes this by eliminating the need for NSEC records for - insecure delegations. This, in a zone with a large number of - delegations to unsigned subzones, can lead to substantial space - savings (both in memory and on disk). Additionally, Opt-In allows - for the addition or removal of insecure delegations without modifying - the NSEC record chain. Zones that are frequently updating insecure - delegations (e.g., TLDs) can avoid the substantial overhead of - - - -Arends, et al. Expires January 19, 2006 [Page 8] - -Internet-Draft DNSSEC Opt-In July 2005 - - - modifying and resigning the affected NSEC records. - -6. Example - - Consider the zone EXAMPLE, shown below. This is a zone where all of - the NSEC records are tagged as Opt-In. - - Example A: Fully Opt-In Zone. - - EXAMPLE. SOA ... - EXAMPLE. RRSIG SOA ... - EXAMPLE. NS FIRST-SECURE.EXAMPLE. - EXAMPLE. RRSIG NS ... - EXAMPLE. DNSKEY ... - EXAMPLE. RRSIG DNSKEY ... - EXAMPLE. NSEC FIRST-SECURE.EXAMPLE. ( - SOA NS RRSIG DNSKEY ) - EXAMPLE. RRSIG NSEC ... - - FIRST-SECURE.EXAMPLE. A ... - FIRST-SECURE.EXAMPLE. RRSIG A ... - FIRST-SECURE.EXAMPLE. NSEC NOT-SECURE-2.EXAMPLE. A RRSIG - FIRST-SECURE.EXAMPLE. RRSIG NSEC ... - - NOT-SECURE.EXAMPLE. NS NS.NOT-SECURE.EXAMPLE. - NS.NOT-SECURE.EXAMPLE. A ... - - NOT-SECURE-2.EXAMPLE. NS NS.NOT-SECURE.EXAMPLE. - NOT-SECURE-2.EXAMPLE NSEC SECOND-SECURE.EXAMPLE NS RRSIG - NOT-SECURE-2.EXAMPLE RRSIG NSEC ... - - SECOND-SECURE.EXAMPLE. NS NS.ELSEWHERE. - SECOND-SECURE.EXAMPLE. DS ... - SECOND-SECURE.EXAMPLE. RRSIG DS ... - SECOND-SECURE.EXAMPLE. NSEC EXAMPLE. NS RRSIG DNSKEY - SECOND-SECURE.EXAMPLE. RRSIG NSEC ... - - UNSIGNED.EXAMPLE. NS NS.UNSIGNED.EXAMPLE. - NS.UNSIGNED.EXAMPLE. A ... - - - In this example, a query for a signed RRset (e.g., "FIRST- - SECURE.EXAMPLE A"), or a secure delegation ("WWW.SECOND- - SECURE.EXAMPLE A") will result in a standard DNSSEC response. - - A query for a nonexistent RRset will result in a response that - differs from standard DNSSEC by: the NSEC record will be tagged as - Opt-In, there may be no NSEC record proving the non-existence of a - - - -Arends, et al. Expires January 19, 2006 [Page 9] - -Internet-Draft DNSSEC Opt-In July 2005 - - - matching wildcard record, and the AD bit will not be set. - - A query for an insecure delegation RRset (or a referral) will return - both the answer (in the Authority section) and the corresponding - Opt-In NSEC record to prove that it is not secure. - - Example A.1: Response to query for WWW.UNSIGNED.EXAMPLE. A - - - RCODE=NOERROR, AD=0 - - Answer Section: - - Authority Section: - UNSIGNED.EXAMPLE. NS NS.UNSIGNED.EXAMPLE - SECOND-SECURE.EXAMPLE. NSEC EXAMPLE. NS RRSIG DS - SECOND-SECURE.EXAMPLE. RRSIG NSEC ... - - Additional Section: - NS.UNSIGNED.EXAMPLE. A ... - - In the Example A.1 zone, the EXAMPLE. node MAY use either style of - NSEC record, because there are no insecure delegations that occur - between it and the next node, FIRST-SECURE.EXAMPLE. In other words, - Example A would still be a valid zone if the NSEC record for EXAMPLE. - was changed to the following RR: - - EXAMPLE. NSEC FIRST-SECURE.EXAMPLE. (SOA NS - RRSIG DNSKEY NSEC ) - - However, the other NSEC records (FIRST-SECURE.EXAMPLE. and SECOND- - SECURE.EXAMPLE.) MUST be tagged as Opt-In because there are insecure - delegations in the range they define. (NOT-SECURE.EXAMPLE. and - UNSIGNED.EXAMPLE., respectively). - - NOT-SECURE-2.EXAMPLE. is an example of an insecure delegation that is - part of the NSEC chain and also covered by an Opt-In tagged NSEC - record. Because NOT-SECURE-2.EXAMPLE. is a signed name, it cannot be - removed from the zone without modifying and resigning the prior NSEC - record. Delegations with names that fall between NOT-SECURE- - 2.EXAMPLE. and SECOND-SECURE.EXAMPLE. may be added or removed without - resigning any NSEC records. - -7. Transition Issues - - Opt-In is not backwards compatible with standard DNSSEC and is - considered experimental. Standard DNSSEC compliant implementations - would not recognize Opt-In tagged NSEC records as different from - - - -Arends, et al. Expires January 19, 2006 [Page 10] - -Internet-Draft DNSSEC Opt-In July 2005 - - - standard NSEC records. Because of this, standard DNSSEC - implementations, if they were to validate Opt-In style responses, - would reject all Opt-In insecure delegations within a zone as - invalid. However, by only signing with private algorithms, standard - DNSSEC implementations will treat Opt-In responses as unsigned. - - It should be noted that all elements in the resolution path between - (and including) the validator and the authoritative name server must - be aware of the Opt-In experiment and implement the Opt-In semantics - for successful validation to be possible. In particular, this - includes any caching middleboxes between the validator and - authoritative name server. - -8. Security Considerations - - Opt-In allows for unsigned names, in the form of delegations to - unsigned subzones, to exist within an otherwise signed zone. All - unsigned names are, by definition, insecure, and their validity or - existence cannot by cryptographically proven. - - In general: - - o Records with unsigned names (whether existing or not) suffer from - the same vulnerabilities as records in an unsigned zone. These - vulnerabilities are described in more detail in [12] (note in - particular sections 2.3, "Name Games" and 2.6, "Authenticated - Denial"). - o Records with signed names have the same security whether or not - Opt-In is used. - - Note that with or without Opt-In, an insecure delegation may have its - contents undetectably altered by an attacker. Because of this, the - primary difference in security that Opt-In introduces is the loss of - the ability to prove the existence or nonexistence of an insecure - delegation within the span of an Opt-In NSEC record. - - In particular, this means that a malicious entity may be able to - insert or delete records with unsigned names. These records are - normally NS records, but this also includes signed wildcard - expansions (while the wildcard record itself is signed, its expanded - name is an unsigned name). - - For example, if a resolver received the following response from the - example zone above: - - - - - - - -Arends, et al. Expires January 19, 2006 [Page 11] - -Internet-Draft DNSSEC Opt-In July 2005 - - - Example S.1: Response to query for WWW.DOES-NOT-EXIST.EXAMPLE. A - - RCODE=NOERROR - - Answer Section: - - Authority Section: - DOES-NOT-EXIST.EXAMPLE. NS NS.FORGED. - EXAMPLE. NSEC FIRST-SECURE.EXAMPLE. SOA NS \ - RRSIG DNSKEY - EXAMPLE. RRSIG NSEC ... - - Additional Section: - - - The resolver would have no choice but to believe that the referral to - NS.FORGED. is valid. If a wildcard existed that would have been - expanded to cover "WWW.DOES-NOT-EXIST.EXAMPLE.", an attacker could - have undetectably removed it and replaced it with the forged - delegation. - - Note that being able to add a delegation is functionally equivalent - to being able to add any record type: an attacker merely has to forge - a delegation to nameserver under his/her control and place whatever - records needed at the subzone apex. - - While in particular cases, this issue may not present a significant - security problem, in general it should not be lightly dismissed. - Therefore, it is strongly RECOMMENDED that Opt-In be used sparingly. - In particular, zone signing tools SHOULD NOT default to Opt-In, and - MAY choose to not support Opt-In at all. - -9. IANA Considerations - - None. - -10. Acknowledgments - - The contributions, suggestions and remarks of the following persons - (in alphabetic order) to this draft are acknowledged: - - Mats Dufberg, Miek Gieben, Olafur Gudmundsson, Bob Halley, Olaf - Kolkman, Edward Lewis, Ted Lindgreen, Rip Loomis, Bill Manning, - Dan Massey, Scott Rose, Mike Schiraldi, Jakob Schlyter, Brian - Wellington. - -11. References - - - - -Arends, et al. Expires January 19, 2006 [Page 12] - -Internet-Draft DNSSEC Opt-In July 2005 - - -11.1 Normative References - - [1] Mockapetris, P., "Domain names - implementation and - specification", STD 13, RFC 1035, November 1987. - - [2] Wellington, B. and O. Gudmundsson, "Redefinition of DNS - Authenticated Data (AD) bit", RFC 3655, November 2003. - - [3] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "DNS Security Introduction and Requirements", RFC 4033, - March 2005. - - [4] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "Resource Records for the DNS Security Extensions", RFC 4034, - March 2005. - - [5] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "Protocol Modifications for the DNS Security Extensions", - RFC 4035, March 2005. - - [6] Blacka, D., "DNSSEC Experiments", - draft-ietf-dnsext-dnssec-experiments-01 (work in progress), - July 2005. - -11.2 Informative References - - [7] Bradner, S., "Key words for use in RFCs to Indicate Requirement - Levels", BCP 14, RFC 2119, March 1997. - - [8] Elz, R. and R. Bush, "Clarifications to the DNS Specification", - RFC 2181, July 1997. - - [9] Eastlake, D., "Secure Domain Name System Dynamic Update", - RFC 2137, April 1997. - - [10] Lewis, E., "DNS Security Extension Clarification on Zone - Status", RFC 3090, March 2001. - - [11] Conrad, D., "Indicating Resolver Support of DNSSEC", RFC 3225, - December 2001. - - [12] Atkins, D. and R. Austein, "Threat Analysis of the Domain Name - System (DNS)", RFC 3833, August 2004. - - - - - - - - -Arends, et al. Expires January 19, 2006 [Page 13] - -Internet-Draft DNSSEC Opt-In July 2005 - - -Authors' Addresses - - Roy Arends - Telematica Instituut - Drienerlolaan 5 - 7522 NB Enschede - NL - - Email: roy.arends@telin.nl - - - Mark Kosters - Verisign, Inc. - 21355 Ridgetop Circle - Dulles, VA 20166 - US - - Phone: +1 703 948 3200 - Email: markk@verisign.com - URI: http://www.verisignlabs.com - - - David Blacka - Verisign, Inc. - 21355 Ridgetop Circle - Dulles, VA 20166 - US - - Phone: +1 703 948 3200 - Email: davidb@verisign.com - URI: http://www.verisignlabs.com - -Appendix A. Implementing Opt-In using "Views" - - In many cases, it may be convenient to implement an Opt-In zone by - combining two separately maintained "views" of a zone at request - time. In this context, "view" refers to a particular version of a - zone, not to any specific DNS implementation feature. - - In this scenario, one view is the secure view, the other is the - insecure (or legacy) view. The secure view consists of an entirely - signed zone using Opt-In tagged NSEC records. The insecure view - contains no DNSSEC information. It is helpful, although not - necessary, for the secure view to be a subset (minus DNSSEC records) - of the insecure view. - - In addition, the only RRsets that may solely exist in the insecure - view are non-zone-apex NS RRsets. That is, all non-NS RRsets (and - - - -Arends, et al. Expires January 19, 2006 [Page 14] - -Internet-Draft DNSSEC Opt-In July 2005 - - - the zone apex NS RRset) MUST be signed and in the secure view. - - These two views may be combined at request time to provide a virtual, - single Opt-In zone. The following algorithm is used when responding - to each query: - V_A is the secure view as described above. - V_B is the insecure view as described above. - R_A is a response generated from V_A, following RFC 2535bis. - R_B is a response generated from V_B, following DNS resolution as - per RFC 1035 [1]. - R_C is the response generated by combining R_A with R_B, as - described below. - A query is DNSSEC-aware if it either has the DO bit [11] turned - on, or is for a DNSSEC-specific record type. - - - - 1. If V_A is a subset of V_B and the query is not DNSSEC-aware, - generate and return R_B, otherwise - 2. Generate R_A. - 3. If R_A's RCODE != NXDOMAIN, return R_A, otherwise - 4. Generate R_B and combine it with R_A to form R_C: - For each section (ANSWER, AUTHORITY, ADDITIONAL), copy the - records from R_A into R_B, EXCEPT the AUTHORITY section SOA - record, if R_B's RCODE = NOERROR. - 5. Return R_C. - - - - - - - - - - - - - - - - - - - - - - - - - -Arends, et al. Expires January 19, 2006 [Page 15] - -Internet-Draft DNSSEC Opt-In July 2005 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2005). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Arends, et al. Expires January 19, 2006 [Page 16] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-rsasha256-00.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-rsasha256-00.txt deleted file mode 100644 index 390420a..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-rsasha256-00.txt +++ /dev/null @@ -1,392 +0,0 @@ - - - -DNS Extensions working group J. Jansen -Internet-Draft NLnet Labs -Expires: July 5, 2006 January 2006 - - - Use of RSA/SHA-256 DNSKEY and RRSIG Resource Records in DNSSEC - draft-ietf-dnsext-dnssec-rsasha256-00 - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on July 5, 2006. - -Copyright Notice - - Copyright (C) The Internet Society (2006). - -Abstract - - This document describes how to produce RSA/SHA-256 DNSKEY and RRSIG - resource records for use in the Domain Name System Security - Extensions (DNSSEC, RFC4033, RFC4034, and RFC4035). - - - - - - - - - -Jansen Expires July 5, 2006 [Page 1] - -Internet-Draft RSA/SHA-256 DNSKEYs and RRSIGS January 2006 - - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 2. RSA/SHA-256 DNSKEY Resource Records . . . . . . . . . . . . . . 3 - 3. RSA/SHA-256 RRSIG Resource Records . . . . . . . . . . . . . . 3 - 4. Implementation Considerations . . . . . . . . . . . . . . . . . 4 - 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . . 4 - 6. Security Considerations . . . . . . . . . . . . . . . . . . . . 4 - 7. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . 5 - 8. References . . . . . . . . . . . . . . . . . . . . . . . . . . 5 - 8.1. Normative References . . . . . . . . . . . . . . . . . . . 5 - 8.2. Informative References . . . . . . . . . . . . . . . . . . 5 - Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 6 - Intellectual Property and Copyright Statements . . . . . . . . . . 7 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Jansen Expires July 5, 2006 [Page 2] - -Internet-Draft RSA/SHA-256 DNSKEYs and RRSIGS January 2006 - - -1. Introduction - - The Domain Name System (DNS) is the global hierarchical distributed - database for Internet Addressing. The DNS has been extended to use - digital signatures and cryptographic keys for the verification of - data. RFC4033 [1], RFC4034 [2], and RFC4035 [3] describe these DNS - Security Extensions. - - RFC4034 describes how to store DNSKEY and RRSIG resource records, and - specifies a list of cryptographic algorithms to use. This document - extends that list with the algorithm RSA/SHA-256, and specifies how - to store RSA/SHA-256 DNSKEY data and how to produce RSA/SHA-256 RRSIG - resource records. - - Familiarity with the RSA [7] and SHA-256 [5] algorithms is assumed in - this document. - - -2. RSA/SHA-256 DNSKEY Resource Records - - RSA public keys for use with RSA/SHA-256 are stored in DNSKEY - resource records (RRs) with the algorithm number [TBA]. - - The format of the DNSKEY RR can be found in RFC4034 [2] and RFC3110 - [6]. - - -3. RSA/SHA-256 RRSIG Resource Records - - RSA/SHA-256 signatures are stored in the DNS using RRSIG resource - records (RRs) with algorithm number [TBA]. - - The value of the signature field in the RRSIG RR is calculated as - follows. The values for the fields that precede the signature data - are specified in RFC4034 [2]. - - hash = SHA-256(data) - - signature = ( 00 | 01 | FF* | 00 | prefix | hash ) ** e (mod n) - - Where SHA-256 is the message digest algorithm as specified in FIPS - 180 [5], | is concatenation, 00, 01, FF and 00 are fixed octets of - corresponding hexadecimal value, "e" is the private exponent of the - signing RSA key, and "n" is the public modulus of the signing key. - The FF octet MUST be repeated the maximum number of times so that the - total length of the signature equals the length of the modulus of the - signer's public key ("n"). "data" is the data of the resource record - set that is signed, as specified in RFC4034 [2]. - - - -Jansen Expires July 5, 2006 [Page 3] - -Internet-Draft RSA/SHA-256 DNSKEYs and RRSIGS January 2006 - - - The prefix is the ASN.1 BER SHA-256 algorithm designator prefix as - specified in PKCS 2.1 [4]: - - hex 30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 - - This prefix should make the use of standard cryptographic libraries - easier. These specifications are taken directly from PKCS #1 v2.1 - section 9.2 [4]. - - -4. Implementation Considerations - - DNSSEC aware implementations MUST be able to support RRSIG resource - records with the RSA/SHA-256 algorithm. - - If both RSA/SHA-256 and RSA/SHA-1 RRSIG resource records are - available for a certain rrset, with a secure path to their keys, the - validator SHOULD ignore the SHA-1 signature. If the RSA/SHA-256 - signature does not verify the data, and the RSA/SHA-1 does, the - validator SHOULD mark the data with the security status from the RSA/ - SHA-256 signature. - - -5. IANA Considerations - - IANA has not yet assigned an algorithm number for RSA/SHA-256. - - The algorithm list from RFC4034 Appendix A.1 [2] is extended with the - following entry: - - Zone - Value Algorithm [Mnemonic] Signing References Status - ----- ----------- ----------- -------- ---------- --------- - [tba] RSA/SHA-256 [RSASHA256] y [TBA] MANDATORY - - -6. Security Considerations - - Recently, weaknesses have been discovered in the SHA-1 hashing - algorithm. It is therefore strongly encouraged to deploy SHA-256 - where SHA-1 is used now, as soon as the DNS software supports it. - - SHA-256 is considered sufficiently strong for the immediate future, - but predictions about future development in cryptography and - cryptanalysis are beyond the scope of this document. - - - - - - -Jansen Expires July 5, 2006 [Page 4] - -Internet-Draft RSA/SHA-256 DNSKEYs and RRSIGS January 2006 - - -7. Acknowledgments - - This document is a minor extension to RFC4034 [2]. Also, we try to - follow the documents RFC3110 [6] and draft-ietf-dnsext-ds-sha256.txt - [8] for consistency. The authors of and contributors to these - documents are gratefully acknowledged for their hard work. - - The following people provided additional feedback and text: Jaap - Akkerhuis, Miek Gieben and Wouter Wijngaards. - - -8. References - -8.1. Normative References - - [1] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "DNS Security Introduction and Requirements", RFC 4033, - March 2005. - - [2] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "Resource Records for the DNS Security Extensions", RFC 4034, - March 2005. - - [3] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "Protocol Modifications for the DNS Security Extensions", - RFC 4035, March 2005. - - [4] Jonsson, J. and B. Kaliski, "Public-Key Cryptography Standards - (PKCS) #1: RSA Cryptography Specifications Version 2.1", - RFC 3447, February 2003. - - [5] National Institute of Standards and Technology, "Secure Hash - Standard", FIPS PUB 180-2, August 2002. - - [6] Eastlake, D., "RSA/SHA-1 SIGs and RSA KEYs in the Domain Name - System (DNS)", RFC 3110, May 2001. - -8.2. Informative References - - [7] Schneier, B., "Applied Cryptography Second Edition: protocols, - algorithms, and source code in C", Wiley and Sons , ISBN 0-471- - 11709-9, 1996. - - [8] Hardaker, W., "Use of SHA-256 in DNSSEC Delegation Signer (DS) - Resource Records (RRs)", Work in Progress Feb 2006. - - - - - - -Jansen Expires July 5, 2006 [Page 5] - -Internet-Draft RSA/SHA-256 DNSKEYs and RRSIGS January 2006 - - -Author's Address - - Jelte Jansen - NLnet Labs - Kruislaan 419 - Amsterdam 1098VA - NL - - Email: jelte@NLnetLabs.nl - URI: http://www.nlnetlabs.nl/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Jansen Expires July 5, 2006 [Page 6] - -Internet-Draft RSA/SHA-256 DNSKEYs and RRSIGS January 2006 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2006). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Jansen Expires July 5, 2006 [Page 7] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-trans-02.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-trans-02.txt deleted file mode 100644 index dd8cbf0..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-dnssec-trans-02.txt +++ /dev/null @@ -1,839 +0,0 @@ - -DNS Extensions Working Group R. Arends -Internet-Draft Telematica Instituut -Expires: August 25, 2005 P. Koch - DENIC eG - J. Schlyter - NIC-SE - February 21, 2005 - - - Evaluating DNSSEC Transition Mechanisms - draft-ietf-dnsext-dnssec-trans-02.txt - -Status of this Memo - - This document is an Internet-Draft and is subject to all provisions - of Section 3 of RFC 3667. By submitting this Internet-Draft, each - author represents that any applicable patent or other IPR claims of - which he or she is aware have been or will be disclosed, and any of - which he or she become aware will be disclosed, in accordance with - RFC 3668. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as - Internet-Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on August 25, 2005. - -Copyright Notice - - Copyright (C) The Internet Society (2005). - -Abstract - - This document collects and summarizes different proposals for - alternative and additional strategies for authenticated denial in DNS - responses, evaluates these proposals and gives a recommendation for a - - - -Arends, et al. Expires August 25, 2005 [Page 1] - -Internet-Draft Evaluating DNSSEC Transition Mechanisms February 2005 - - - way forward. - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 2. Transition Mechanisms . . . . . . . . . . . . . . . . . . . . 3 - 2.1 Mechanisms With Need of Updating DNSSEC-bis . . . . . . . 4 - 2.1.1 Dynamic NSEC Synthesis . . . . . . . . . . . . . . . . 4 - 2.1.2 Add Versioning/Subtyping to Current NSEC . . . . . . . 5 - 2.1.3 Type Bit Map NSEC Indicator . . . . . . . . . . . . . 6 - 2.1.4 New Apex Type . . . . . . . . . . . . . . . . . . . . 6 - 2.1.5 NSEC White Lies . . . . . . . . . . . . . . . . . . . 7 - 2.1.6 NSEC Optional via DNSSKEY Flag . . . . . . . . . . . . 8 - 2.1.7 New Answer Pseudo RR Type . . . . . . . . . . . . . . 9 - 2.1.8 SIG(0) Based Authenticated Denial . . . . . . . . . . 9 - 2.2 Mechanisms Without Need of Updating DNSSEC-bis . . . . . . 10 - 2.2.1 Partial Type-code and Signal Rollover . . . . . . . . 10 - 2.2.2 A Complete Type-code and Signal Rollover . . . . . . . 11 - 2.2.3 Unknown Algorithm in RRSIG . . . . . . . . . . . . . . 11 - 3. Recommendation . . . . . . . . . . . . . . . . . . . . . . . . 12 - 4. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 13 - 5. References . . . . . . . . . . . . . . . . . . . . . . . . . . 13 - 5.1 Normative References . . . . . . . . . . . . . . . . . . . 13 - 5.2 Informative References . . . . . . . . . . . . . . . . . . 13 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 14 - Intellectual Property and Copyright Statements . . . . . . . . 15 - - - - - - - - - - - - - - - - - - - - - - - - - -Arends, et al. Expires August 25, 2005 [Page 2] - -Internet-Draft Evaluating DNSSEC Transition Mechanisms February 2005 - - -1. Introduction - - This report shall document the process of dealing with the NSEC - walking problem late in the Last Call for - [I-D.ietf-dnsext-dnssec-intro, I-D.ietf-dnsext-dnssec-protocol, - I-D.ietf-dnsext-dnssec-records]. It preserves some of the discussion - that took place in the DNSEXT WG during the first half of June 2004 - as well as some additional ideas that came up subsequently. - - This is an edited excerpt of the chairs' mail to the WG: - The working group consents on not including NSEC-alt in the - DNSSEC-bis documents. The working group considers to take up - "prevention of zone enumeration" as a work item. - There may be multiple mechanisms to allow for co-existence with - DNSSEC-bis. The chairs allow the working group a little over a - week (up to June 12, 2004) to come to consensus on a possible - modification to the document to enable gentle rollover. If that - consensus cannot be reached the DNSSEC-bis documents will go out - as-is. - - To ease the process of getting consensus, a summary of the proposed - solutions and analysis of the pros and cons were written during the - weekend. - - This summary includes: - - An inventory of the proposed mechanisms to make a transition to - future work on authenticated denial of existence. - List the known Pros and Cons, possibly provide new arguments, and - possible security considerations of these mechanisms. - Provide a recommendation on a way forward that is least disruptive - to the DNSSEC-bis specifications as they stand and keep an open - path to other methods for authenticated denial of existence. - - The descriptions of the proposals in this document are coarse and do - not cover every detail necessary for implementation. In any case, - documentation and further study is needed before implementaion and/or - deployment, including those which seem to be solely operational in - nature. - -2. Transition Mechanisms - - In the light of recent discussions and past proposals, we have found - several ways to allow for transition to future expansion of - authenticated denial. We tried to illuminate the paths and pitfalls - in these ways forward. Some proposals lead to a versioning of - DNSSEC, where DNSSEC-bis may co-exist with DNSSEC-ter, other - proposals are 'clean' but may cause delay, while again others may be - - - -Arends, et al. Expires August 25, 2005 [Page 3] - -Internet-Draft Evaluating DNSSEC Transition Mechanisms February 2005 - - - plain hacks. - - Some paths do not introduce versioning, and might require the current - DNSSEC-bis documents to be fully updated to allow for extensions to - authenticated denial mechanisms. Other paths introduce versioning - and do not (or minimally) require DNSSEC-bis documents to be updated, - allowing DNSSEC-bis to be deployed, while future versions can be - drafted independent from or partially depending on DNSSEC-bis. - -2.1 Mechanisms With Need of Updating DNSSEC-bis - - Mechanisms in this category demand updates to the DNSSEC-bis document - set. - -2.1.1 Dynamic NSEC Synthesis - - This proposal assumes that NSEC RRs and the authenticating RRSIG will - be generated dynamically to just cover the (non existent) query name. - The owner name is (the) one preceding the name queried for, the Next - Owner Name Field has the value of the Query Name Field + 1 (first - successor in canonical ordering). A separate key (the normal ZSK or - a separate ZSK per authoritative server) would be used for RRSIGs on - NSEC RRs. This is a defense against enumeration, though it has the - presumption of online signing. - -2.1.1.1 Coexistence and Migration - - There is no change in interpretation other then that the next owner - name might or might not exist. - -2.1.1.2 Limitations - - This introduces an unbalanced cost between query and response - generation due to dynamic generation of signatures. - -2.1.1.3 Amendments to DNSSEC-bis - - The current DNSSEC-bis documents might need to be updated to indicate - that the next owner name might not be an existing name in the zone. - This is not a real change to the spec since implementers have been - warned not to synthesize with previously cached NSEC records. A - specific bit to identify the dynamic signature generating key might - be useful as well, to prevent it from being used to fake positive - data. - -2.1.1.4 Cons - - Unbalanced cost is a ground for DDoS. Though this protects against - - - -Arends, et al. Expires August 25, 2005 [Page 4] - -Internet-Draft Evaluating DNSSEC Transition Mechanisms February 2005 - - - enumeration, it is not really a path for versioning. - -2.1.1.5 Pros - - Hardly any amendments to DNSSEC-bis. - -2.1.2 Add Versioning/Subtyping to Current NSEC - - This proposal introduces versioning for the NSEC RR type (a.k.a. - subtyping) by adding a (one octet) version field to the NSEC RDATA. - Version number 0 is assigned to the current (DNSSEC-bis) meaning, - making this an 'Must Be Zero' (MBZ) for the to be published docset. - -2.1.2.1 Coexistence and Migration - - Since the versioning is done inside the NSEC RR, different versions - may coexist. However, depending on future methods, that may or may - not be useful inside a single zone. Resolvers cannot ask for - specific NSEC versions but may be able to indicate version support by - means of a to be defined EDNS option bit. - -2.1.2.2 Limitations - - There are no technical limitations, though it will cause delay to - allow testing of the (currently unknown) new NSEC interpretation. - - Since the versioning and signaling is done inside the NSEC RR, future - methods will likely be restricted to a single RR type authenticated - denial (as opposed to e.g. NSEC-alt, which currently proposes three - RR types). - -2.1.2.3 Amendments to DNSSEC-bis - - Full Update of the current DNSSEC-bis documents to provide for new - fields in NSEC, while specifying behavior in case of unknown field - values. - -2.1.2.4 Cons - - Though this is a clean and clear path without versioning DNSSEC, it - takes some time to design, gain consensus, update the current - dnssec-bis document, test and implement a new authenticated denial - record. - -2.1.2.5 Pros - - Does not introduce an iteration to DNSSEC while providing a clear and - clean migration strategy. - - - -Arends, et al. Expires August 25, 2005 [Page 5] - -Internet-Draft Evaluating DNSSEC Transition Mechanisms February 2005 - - -2.1.3 Type Bit Map NSEC Indicator - - Bits in the type-bit-map are reused or allocated to signify the - interpretation of NSEC. - - This proposal assumes that future extensions make use of the existing - NSEC RDATA syntax, while it may need to change the interpretation of - the RDATA or introduce an alternative denial mechanism, invoked by - the specific type-bit-map-bits. - -2.1.3.1 Coexistence and migration - - Old and new NSEC meaning could coexist, depending how the signaling - would be defined. The bits for NXT, NSEC, RRSIG or other outdated RR - types are available as well as those covering meta/query types or - types to be specifically allocated. - -2.1.3.2 Limitations - - This mechanism uses an NSEC field that was not designed for that - purpose. Similar methods were discussed during the Opt-In discussion - and the Silly-State discussion. - -2.1.3.3 Amendments to DNSSEC-bis - - The specific type-bit-map-bits must be allocated and they need to be - specified as 'Must Be Zero' (MBZ) when used for standard (dnssec-bis) - interpretation. Also, behaviour of the resolver and validator must - be documented in case unknown values are encountered for the MBZ - field. Currently the protocol document specifies that the validator - MUST ignore the setting of the NSEC and the RRSIG bits, while other - bits are only used for the specific purpose of the type-bit-map field - -2.1.3.4 Cons - - The type-bit-map was not designed for this purpose. It is a - straightforward hack. Text in protocol section 5.4 was put in - specially to defend against this usage. - -2.1.3.5 Pros - - No change needed to the on-the-wire protocol as specified in the - current docset. - -2.1.4 New Apex Type - - This introduces a new Apex type (parallel to the zone's SOA) - indicating the DNSSEC version (or authenticated denial) used in or - - - -Arends, et al. Expires August 25, 2005 [Page 6] - -Internet-Draft Evaluating DNSSEC Transition Mechanisms February 2005 - - - for this zone. - -2.1.4.1 Coexistence and Migration - - Depending on the design of this new RR type multiple denial - mechanisms may coexist in a zone. Old validators will not understand - and thus ignore the new type, so interpretation of the new NSEC - scheme may fail, negative responses may appear 'bogus'. - -2.1.4.2 Limitations - - A record of this kind is likely to carry additional - feature/versioning indications unrelated to the current question of - authenticated denial. - -2.1.4.3 Amendments to DNSSEC-bis - - The current DNSSEC-bis documents need to be updated to indicate that - the absence of this type indicates dnssec-bis, and that the (mere) - presence of this type indicated unknown versions. - -2.1.4.4 Cons - - The only other 'zone' or 'apex' record is the SOA record. Though - this proposal is not new, it is yet unknown how it might fulfill - authenticated denial extensions. This new RR type would only provide - for a generalized signaling mechanism, not the new authenticated - denial scheme. Since it is likely to be general in nature, due to - this generality consensus is not to be reached soon. - -2.1.4.5 Pros - - This approach would allow for a lot of other per zone information to - be transported or signaled to both (slave) servers and resolvers. - -2.1.5 NSEC White Lies - - This proposal disables one part of NSEC (the pointer part) by means - of a special target (root, apex, owner, ...), leaving intact only the - ability to authenticate denial of existence of RR sets, not denial of - existence of domain names (NXDOMAIN). It may be necessary to have - one working NSEC to prove the absence of a wildcard. - -2.1.5.1 Coexistence and Migration - - The NSEC target can be specified per RR, so standard NSEC and 'white - lie' NSEC can coexist in a zone. There is no need for migration - because no versioning is introduced or intended. - - - -Arends, et al. Expires August 25, 2005 [Page 7] - -Internet-Draft Evaluating DNSSEC Transition Mechanisms February 2005 - - -2.1.5.2 Limitations - - This proposal breaks the protocol and is applicable to certain types - of zones only (no wildcard, no deep names, delegation only). Most of - the burden is put on the resolver side and operational consequences - are yet to be studied. - -2.1.5.3 Amendments to DNSSEC-bis - - The current DNSSEC-bis documents need to be updated to indicate that - the NXDOMAIN responses may be insecure. - -2.1.5.4 Cons - - Strictly speaking this breaks the protocol and doesn't fully fulfill - the requirements for authenticated denial of existence. Security - implications need to be carefully documented: search path problems - (forged denial of existence may lead to wrong expansion of non-FQDNs - [RFC1535]) and replay attacks to deny existence of records. - -2.1.5.5 Pros - - Hardly any amendments to DNSSEC-bis. Operational "trick" that is - available anyway. - -2.1.6 NSEC Optional via DNSSKEY Flag - - A new DNSKEY may be defined to declare NSEC optional per zone. - -2.1.6.1 Coexistence and Migration - - Current resolvers/validators will not understand the Flag bit and - will have to treat negative responses as bogus. Otherwise, no - migration path is needed since NSEC is simply turned off. - -2.1.6.2 Limitations - - NSEC can only be made completely optional at the cost of being unable - to prove unsecure delegations (absence of a DS RR [RFC3658]). A next - to this approach would just disable authenticated denial for - non-existence of nodes. - -2.1.6.3 Amendments to DNSSEC-bis - - New DNSKEY Flag to be defined. Resolver/Validator behaviour needs to - be specified in the light of absence of authenticated denial. - - - - - -Arends, et al. Expires August 25, 2005 [Page 8] - -Internet-Draft Evaluating DNSSEC Transition Mechanisms February 2005 - - -2.1.6.4 Cons - - Doesn't fully meet requirements. Operational consequences to be - studied. - -2.1.6.5 Pros - - Official version of the "trick" presented in (8). Operational - problems can be addressed during future work on validators. - -2.1.7 New Answer Pseudo RR Type - - A new pseudo RR type may be defined that will be dynamically created - (and signed) by the responding authoritative server. The RR in the - response will cover the QNAME, QCLASS and QTYPE and will authenticate - both denial of existence of name (NXDOMAIN) or RRset. - -2.1.7.1 Coexistence and Migration - - Current resolvers/validators will not understand the pseudo RR and - will thus not be able to process negative responses so testified. A - signaling or solicitation method would have to be specified. - -2.1.7.2 Limitations - - This method can only be used with online keys and online signing - capacity. - -2.1.7.3 Amendments to DNSSEC-bis - - Signaling method needs to be defined. - -2.1.7.4 Cons - - Keys have to be held and processed online with all security - implications. An additional flag for those keys identifying them as - online or negative answer only keys should be considered. - -2.1.7.5 Pros - - Expands DNSSEC authentication to the RCODE. - -2.1.8 SIG(0) Based Authenticated Denial - - -2.1.8.1 Coexistence and Migration - - - - - -Arends, et al. Expires August 25, 2005 [Page 9] - -Internet-Draft Evaluating DNSSEC Transition Mechanisms February 2005 - - -2.1.8.2 Limitations - - -2.1.8.3 Amendments to DNSSEC-bis - - -2.1.8.4 Cons - - -2.1.8.5 Pros - - -2.2 Mechanisms Without Need of Updating DNSSEC-bis - -2.2.1 Partial Type-code and Signal Rollover - - Carefully crafted type code/signal rollover to define a new - authenticated denial space that extends/replaces DNSSEC-bis - authenticated denial space. This particular path is illuminated by - Paul Vixie in a Message-Id <20040602070859.0F50913951@sa.vix.com> - posted to 2004-06-02. - -2.2.1.1 Coexistence and Migration - - To protect the current resolver for future versions, a new DNSSEC-OK - bit must be allocated to make clear it does or does not understand - the future version. Also, a new DS type needs to be allocated to - allow differentiation between a current signed delegation and a - 'future' signed delegation. Also, current NSEC needs to be rolled - into a new authenticated denial type. - -2.2.1.2 Limitations - - None. - -2.2.1.3 Amendments to DNSSEC-bis - - None. - -2.2.1.4 Cons - - It is cumbersome to carefully craft an TCR that 'just fits'. The - DNSSEC-bis protocol has many 'borderline' cases that needs special - consideration. It might be easier to do a full TCR, since a few of - the types and signals need upgrading anyway. - - - - - - -Arends, et al. Expires August 25, 2005 [Page 10] - -Internet-Draft Evaluating DNSSEC Transition Mechanisms February 2005 - - -2.2.1.5 Pros - - Graceful adoption of future versions of NSEC, while there are no - amendments to DNSSEC-bis. - -2.2.2 A Complete Type-code and Signal Rollover - - A new DNSSEC space is defined which can exist independent of current - DNSSEC-bis space. - - This proposal assumes that all current DNSSEC type-codes - (RRSIG/DNSKEY/NSEC/DS) and signals (DNSSEC-OK) are not used in any - future versions of DNSSEC. Any future version of DNSSEC has its own - types to allow for keys, signatures, authenticated denial, etcetera. - -2.2.2.1 Coexistence and Migration - - Both spaces can co-exist. They can be made completely orthogonal. - -2.2.2.2 Limitations - - None. - -2.2.2.3 Amendments to DNSSEC-bis - - None. - -2.2.2.4 Cons - - With this path we abandon the current DNSSEC-bis. Though it is easy - to role specific well-known and well-tested parts into the re-write, - once deployment has started this path is very expensive for - implementers, registries, registrars and registrants as well as - resolvers/users. A TCR is not to be expected to occur frequently, so - while a next generation authenticated denial may be enabled by a TCR, - it is likely that that TCR will only be agreed upon if it serves a - whole basket of changes or additions. A quick introduction of - NSEC-ng should not be expected from this path. - -2.2.2.5 Pros - - No amendments/changes to current DNSSEC-bis docset needed. It is - always there as last resort. - -2.2.3 Unknown Algorithm in RRSIG - - This proposal assumes that future extensions make use of the existing - NSEC RDATA syntax, while it may need to change the interpretation of - - - -Arends, et al. Expires August 25, 2005 [Page 11] - -Internet-Draft Evaluating DNSSEC Transition Mechanisms February 2005 - - - the RDATA or introduce an alternative denial mechanism, invoked by - the specific unknown signing algorithm. The different interpretation - would be signaled by use of different signature algorithms in the - RRSIG records covering the NSEC RRs. - - When an entire zone is signed with a single unknown algorithm, it - will cause implementations that follow current dnssec-bis documents - to treat individual RRsets as unsigned. - -2.2.3.1 Coexistence and migration - - Old and new NSEC RDATA interpretation or known and unknown Signatures - can NOT coexist in a zone since signatures cover complete (NSEC) - RRSets. - -2.2.3.2 Limitations - - Validating resolvers agnostic of new interpretation will treat the - NSEC RRset as "not signed". This affects wildcard and non-existence - proof, as well as proof for (un)secured delegations. Also, all - positive signatures (RRSIGs on RRSets other than DS, NSEC) appear - insecure/bogus to an old validator. - - The algorithm version space is split for each future version of - DNSSEC. Violation of the 'modular components' concept. We use the - 'validator' to protect the 'resolver' from unknown interpretations. - -2.2.3.3 Amendments to DNSSEC-bis - - None. - -2.2.3.4 Cons - - The algorithm field was not designed for this purpose. This is a - straightforward hack. - -2.2.3.5 Pros - - No amendments/changes to current DNSSEC-bis docset needed. - -3. Recommendation - - The authors recommend that the working group commits to and starts - work on a partial TCR, allowing graceful transition towards a future - version of NSEC. Meanwhile, to accomodate the need for an - immediately, temporary, solution against zone-traversal, we recommend - On-Demand NSEC synthesis. - - - - -Arends, et al. Expires August 25, 2005 [Page 12] - -Internet-Draft Evaluating DNSSEC Transition Mechanisms February 2005 - - - This approach does not require any mandatory changes to DNSSEC-bis, - does not violate the protocol and fulfills the requirements. As a - side effect, it moves the cost of implementation and deployment to - the users (zone owners) of this mechanism. - -4. Acknowledgements - - The authors would like to thank Sam Weiler and Mark Andrews for their - input and constructive comments. - -5. References - -5.1 Normative References - - [I-D.ietf-dnsext-dnssec-intro] - Arends, R., Austein, R., Massey, D., Larson, M. and S. - Rose, "DNS Security Introduction and Requirements", - Internet-Draft draft-ietf-dnsext-dnssec-intro-13, October - 2004. - - [I-D.ietf-dnsext-dnssec-protocol] - Arends, R., "Protocol Modifications for the DNS Security - Extensions", - Internet-Draft draft-ietf-dnsext-dnssec-protocol-09, - October 2004. - - [I-D.ietf-dnsext-dnssec-records] - Arends, R., "Resource Records for the DNS Security - Extensions", - Internet-Draft draft-ietf-dnsext-dnssec-records-11, - October 2004. - - [RFC1034] Mockapetris, P., "Domain names - concepts and facilities", - STD 13, RFC 1034, November 1987. - - [RFC1035] Mockapetris, P., "Domain names - implementation and - specification", STD 13, RFC 1035, November 1987. - - [RFC2931] Eastlake, D., "DNS Request and Transaction Signatures ( - SIG(0)s)", RFC 2931, September 2000. - -5.2 Informative References - - [RFC1535] Gavron, E., "A Security Problem and Proposed Correction - With Widely Deployed DNS Software", RFC 1535, October - 1993. - - [RFC2535] Eastlake, D., "Domain Name System Security Extensions", - - - -Arends, et al. Expires August 25, 2005 [Page 13] - -Internet-Draft Evaluating DNSSEC Transition Mechanisms February 2005 - - - RFC 2535, March 1999. - - [RFC2629] Rose, M., "Writing I-Ds and RFCs using XML", RFC 2629, - June 1999. - - [RFC3658] Gudmundsson, O., "Delegation Signer (DS) Resource Record - (RR)", RFC 3658, December 2003. - - -Authors' Addresses - - Roy Arends - Telematica Instituut - Brouwerijstraat 1 - Enschede 7523 XC - The Netherlands - - Phone: +31 53 4850485 - Email: roy.arends@telin.nl - - - Peter Koch - DENIC eG - Wiesenh"uttenplatz 26 - Frankfurt 60329 - Germany - - Phone: +49 69 27235 0 - Email: pk@DENIC.DE - - - Jakob Schlyter - NIC-SE - Box 5774 - Stockholm SE-114 87 - Sweden - - Email: jakob@nic.se - URI: http://www.nic.se/ - - - - - - - - - - - - -Arends, et al. Expires August 25, 2005 [Page 14] - -Internet-Draft Evaluating DNSSEC Transition Mechanisms February 2005 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2005). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Arends, et al. Expires August 25, 2005 [Page 15] - - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-ds-sha256-05.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-ds-sha256-05.txt deleted file mode 100644 index 2460cb6..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-ds-sha256-05.txt +++ /dev/null @@ -1,504 +0,0 @@ - - - -Network Working Group W. Hardaker -Internet-Draft Sparta -Expires: August 25, 2006 February 21, 2006 - - - Use of SHA-256 in DNSSEC Delegation Signer (DS) Resource Records (RRs) - draft-ietf-dnsext-ds-sha256-05.txt - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on August 25, 2006. - -Copyright Notice - - Copyright (C) The Internet Society (2006). - -Abstract - - This document specifies how to use the SHA-256 digest type in DNS - Delegation Signer (DS) Resource Records (RRs). DS records, when - stored in a parent zone, point to key signing DNSKEY key(s) in a - child zone. - - - - - - - - -Hardaker Expires August 25, 2006 [Page 1] - -Internet-Draft Use of SHA-256 in DNSSEC DS RRs February 2006 - - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 2. Implementing the SHA-256 algorithm for DS record support . . . 3 - 2.1. DS record field values . . . . . . . . . . . . . . . . . . 3 - 2.2. DS Record with SHA-256 Wire Format . . . . . . . . . . . . 3 - 2.3. Example DS Record Using SHA-256 . . . . . . . . . . . . . . 4 - 3. Implementation Requirements . . . . . . . . . . . . . . . . . . 4 - 4. Deployment Considerations . . . . . . . . . . . . . . . . . . . 4 - 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . . 5 - 6. Security Considerations . . . . . . . . . . . . . . . . . . . . 5 - 6.1. Potential Digest Type Downgrade Attacks . . . . . . . . . . 5 - 6.2. SHA-1 vs SHA-256 Considerations for DS Records . . . . . . 6 - 7. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . 6 - 8. References . . . . . . . . . . . . . . . . . . . . . . . . . . 7 - 8.1. Normative References . . . . . . . . . . . . . . . . . . . 7 - 8.2. Informative References . . . . . . . . . . . . . . . . . . 7 - Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 8 - Intellectual Property and Copyright Statements . . . . . . . . . . 9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Hardaker Expires August 25, 2006 [Page 2] - -Internet-Draft Use of SHA-256 in DNSSEC DS RRs February 2006 - - -1. Introduction - - The DNSSEC [RFC4033] [RFC4034] [RFC4035] DS RR is published in parent - zones to distribute a cryptographic digest of a child's Key Signing - Key (KSK) DNSKEY RR. The DS RRset is signed by at least one of the - parent zone's private zone data signing keys for each algorithm in - use by the parent. Each signature is published in an RRSIG resource - record, owned by the same domain as the DS RRset and with a type - covered of DS. - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in [RFC2119]. - - -2. Implementing the SHA-256 algorithm for DS record support - - This document specifies that the digest type code [XXX: To be - assigned by IANA; likely 2] is to be assigned to SHA-256 [SHA256] - [SHA256CODE] for use within DS records. The results of the digest - algorithm MUST NOT be truncated and the entire 32 byte digest result - is to be published in the DS record. - -2.1. DS record field values - - Using the SHA-256 digest algorithm within a DS record will make use - of the following DS-record fields: - - Digest type: [XXX: To be assigned by IANA; likely 2] - - Digest: A SHA-256 bit digest value calculated by using the following - formula ("|" denotes concatenation). The resulting value is not - truncated and the entire 32 byte result is to used in the - resulting DS record and related calculations. - - digest = SHA_256(DNSKEY owner name | DNSKEY RDATA) - - where DNSKEY RDATA is defined by [RFC4034] as: - - DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key - - The Key Tag field and Algorithm fields remain unchanged by this - document and are specified in the [RFC4034] specification. - -2.2. DS Record with SHA-256 Wire Format - - The resulting on-the-wire format for the resulting DS record will be - [XXX: IANA assignment should replace the 2 below]: - - - -Hardaker Expires August 25, 2006 [Page 3] - -Internet-Draft Use of SHA-256 in DNSSEC DS RRs February 2006 - - - 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Key Tag | Algorithm | DigestType=2 | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - / / - / Digest (length for SHA-256 is 32 bytes) / - / / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| - -2.3. Example DS Record Using SHA-256 - - The following is an example DNSKEY and matching DS record. This - DNSKEY record comes from the example DNSKEY/DS records found in - section 5.4 of [RFC4034]. - - The DNSKEY record: - - dskey.example.com. 86400 IN DNSKEY 256 3 5 ( AQOeiiR0GOMYkDshWoSKz9Xz - fwJr1AYtsmx3TGkJaNXVbfi/ - 2pHm822aJ5iI9BMzNXxeYCmZ - DRD99WYwYqUSdjMmmAphXdvx - egXd/M5+X7OrzKBaMbCVdFLU - Uh6DhweJBjEVv5f2wwjM9Xzc - nOf+EPbtG9DMBmADjFDc2w/r - ljwvFw== - ) ; key id = 60485 - - The resulting DS record covering the above DNSKEY record using a SHA- - 256 digest: [RFC Editor: please replace XXX with the assigned digest - type (likely 2):] - - dskey.example.com. 86400 IN DS 60485 5 XXX ( D4B7D520E7BB5F0F67674A0C - CEB1E3E0614B93C4F9E99B83 - 83F6A1E4469DA50A ) - - -3. Implementation Requirements - - Implementations MUST support the use of the SHA-256 algorithm in DS - RRs. Validator implementations SHOULD ignore DS RRs containing SHA-1 - digests if DS RRs with SHA-256 digests are present in the DS RRset. - - -4. Deployment Considerations - - If a validator does not support the SHA-256 digest type and no other - DS RR exists in a zone's DS RRset with a supported digest type, then - - - -Hardaker Expires August 25, 2006 [Page 4] - -Internet-Draft Use of SHA-256 in DNSSEC DS RRs February 2006 - - - the validator has no supported authentication path leading from the - parent to the child. The resolver should treat this case as it would - the case of an authenticated NSEC RRset proving that no DS RRset - exists, as described in [RFC4035], section 5.2. - - Because zone administrators can not control the deployment speed of - support for SHA-256 in validators that may be referencing any of - their zones, zone operators should consider deploying both SHA-1 and - SHA-256 based DS records. This should be done for every DNSKEY for - which DS records are being generated. Whether to make use of both - digest types and for how long is a policy decision that extends - beyond the scope of this document. - - -5. IANA Considerations - - Only one IANA action is required by this document: - - The Digest Type to be used for supporting SHA-256 within DS records - needs to be assigned by IANA. This document requests that the Digest - Type value of 2 be assigned to the SHA-256 digest algorithm. - - At the time of this writing, the current digest types assigned for - use in DS records are as follows: - - VALUE Digest Type Status - 0 Reserved - - 1 SHA-1 MANDATORY - 2 SHA-256 MANDATORY - 3-255 Unassigned - - - -6. Security Considerations - -6.1. Potential Digest Type Downgrade Attacks - - A downgrade attack from a stronger digest type to a weaker one is - possible if all of the following are true: - - o A zone includes multiple DS records for a given child's DNSKEY, - each of which use a different digest type. - - o A validator accepts a weaker digest even if a stronger one is - present but invalid. - - For example, if the following conditions are all true: - - - - - -Hardaker Expires August 25, 2006 [Page 5] - -Internet-Draft Use of SHA-256 in DNSSEC DS RRs February 2006 - - - o Both SHA-1 and SHA-256 based digests are published in DS records - within a parent zone for a given child zone's DNSKEY. - - o The DS record with the SHA-1 digest matches the digest computed - using the child zone's DNSKEY. - - o The DS record with the SHA-256 digest fails to match the digest - computed using the child zone's DNSKEY. - - Then if the validator accepts the above situation as secure then this - can be used as a downgrade attack since the stronger SHA-256 digest - is ignored. - -6.2. SHA-1 vs SHA-256 Considerations for DS Records - - Users of DNSSEC are encouraged to deploy SHA-256 as soon as software - implementations allow for it. SHA-256 is widely believed to be more - resilient to attack than SHA-1, and confidence in SHA-1's strength is - being eroded by recently-announced attacks. Regardless of whether or - not the attacks on SHA-1 will affect DNSSEC, it is believed (at the - time of this writing) that SHA-256 is the better choice for use in DS - records. - - At the time of this publication, the SHA-256 digest algorithm is - considered sufficiently strong for the immediate future. It is also - considered sufficient for use in DNSSEC DS RRs for the immediate - future. However, future published attacks may weaken the usability - of this algorithm within the DS RRs. It is beyond the scope of this - document to speculate extensively on the cryptographic strength of - the SHA-256 digest algorithm. - - Likewise, it is also beyond the scope of this document to specify - whether or for how long SHA-1 based DS records should be - simultaneously published alongside SHA-256 based DS records. - - -7. Acknowledgments - - This document is a minor extension to the existing DNSSEC documents - and those authors are gratefully appreciated for the hard work that - went into the base documents. - - The following people contributed to portions of this document in some - fashion: Mark Andrews, Roy Arends, Olafur Gudmundsson, Paul Hoffman, - Olaf M. Kolkman, Edward Lewis, Scott Rose, Stuart E. Schechter, Sam - Weiler. - - - - - -Hardaker Expires August 25, 2006 [Page 6] - -Internet-Draft Use of SHA-256 in DNSSEC DS RRs February 2006 - - -8. References - -8.1. Normative References - - [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - - [RFC4033] Arends, R., Austein, R., Larson, M., Massey, D., and S. - Rose, "DNS Security Introduction and Requirements", - RFC 4033, March 2005. - - [RFC4034] Arends, R., Austein, R., Larson, M., Massey, D., and S. - Rose, "Resource Records for the DNS Security Extensions", - RFC 4034, March 2005. - - [RFC4035] Arends, R., Austein, R., Larson, M., Massey, D., and S. - Rose, "Protocol Modifications for the DNS Security - Extensions", RFC 4035, March 2005. - - [SHA256] National Institute of Standards and Technology, "Secure - Hash Algorithm. NIST FIPS 180-2", August 2002. - -8.2. Informative References - - [SHA256CODE] - Eastlake, D., "US Secure Hash Algorithms (SHA)", - June 2005. - - - - - - - - - - - - - - - - - - - - - - - - -Hardaker Expires August 25, 2006 [Page 7] - -Internet-Draft Use of SHA-256 in DNSSEC DS RRs February 2006 - - -Author's Address - - Wes Hardaker - Sparta - P.O. Box 382 - Davis, CA 95617 - US - - Email: hardaker@tislabs.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Hardaker Expires August 25, 2006 [Page 8] - -Internet-Draft Use of SHA-256 in DNSSEC DS RRs February 2006 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2006). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Hardaker Expires August 25, 2006 [Page 9] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-ecc-key-07.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-ecc-key-07.txt deleted file mode 100644 index 2cdcdb1..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-ecc-key-07.txt +++ /dev/null @@ -1,928 +0,0 @@ - -INTERNET-DRAFT ECC Keys in the DNS -Expires: January 2006 July 2005 - - - - Elliptic Curve KEYs in the DNS - -------- ----- ---- -- --- --- - - - Richard C. Schroeppel - Donald Eastlake 3rd - - -Status of This Document - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - This draft is intended to be become a Proposed Standard RFC. - Distribution of this document is unlimited. Comments should be sent - to the DNS mailing list . - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than a "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/1id-abstracts.html - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html - - -Abstract - - The standard method for storing elliptic curve cryptographic keys and - signatures in the Domain Name System is specified. - - -Copyright Notice - - Copyright (C) The Internet Society (2005). All Rights Reserved. - - - - - -R. Schroeppel, et al [Page 1] - - -INTERNET-DRAFT ECC Keys in the DNS - - -Acknowledgement - - The assistance of Hilarie K. Orman in the production of this document - is greatfully acknowledged. - - - -Table of Contents - - Status of This Document....................................1 - Abstract...................................................1 - Copyright Notice...........................................1 - - Acknowledgement............................................2 - Table of Contents..........................................2 - - 1. Introduction............................................3 - 2. Elliptic Curve Data in Resource Records.................3 - 3. The Elliptic Curve Equation.............................9 - 4. How do I Compute Q, G, and Y?..........................10 - 5. Elliptic Curve SIG Resource Records....................11 - 6. Performance Considerations.............................13 - 7. Security Considerations................................13 - 8. IANA Considerations....................................13 - Copyright and Disclaimer..................................14 - - Informational References..................................15 - Normative Refrences.......................................15 - - Author's Addresses........................................16 - Expiration and File Name..................................16 - - - - - - - - - - - - - - - - - - - - - -R. Schroeppel, et al [Page 2] - - -INTERNET-DRAFT ECC Keys in the DNS - - -1. Introduction - - The Domain Name System (DNS) is the global hierarchical replicated - distributed database system for Internet addressing, mail proxy, and - other information. The DNS has been extended to include digital - signatures and cryptographic keys as described in [RFC 4033, 4034, - 4035]. - - This document describes how to store elliptic curve cryptographic - (ECC) keys and signatures in the DNS so they can be used for a - variety of security purposes. Familiarity with ECC cryptography is - assumed [Menezes]. - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in [RFC 2119]. - - - -2. Elliptic Curve Data in Resource Records - - Elliptic curve public keys are stored in the DNS within the RDATA - portions of key RRs, such as RRKEY and KEY [RFC 4034] RRs, with the - structure shown below. - - The research world continues to work on the issue of which is the - best elliptic curve system, which finite field to use, and how to - best represent elements in the field. So, representations are - defined for every type of finite field, and every type of elliptic - curve. The reader should be aware that there is a unique finite - field with a particular number of elements, but many possible - representations of that field and its elements. If two different - representations of a field are given, they are interconvertible with - a tedious but practical precomputation, followed by a fast - computation for each field element to be converted. It is perfectly - reasonable for an algorithm to work internally with one field - representation, and convert to and from a different external - representation. - - - - - - - - - - - - - - -R. Schroeppel, et al [Page 3] - - -INTERNET-DRAFT ECC Keys in the DNS - - - 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |S M -FMT- A B Z| - +-+-+-+-+-+-+-+-+ - | LP | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | P (length determined from LP) .../ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | LF | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | F (length determined from LF) .../ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | DEG | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | DEGH | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | DEGI | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | DEGJ | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | TRDV | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |S| LH | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | H (length determined from LH) .../ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |S| LK | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | K (length determined from LK) .../ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | LQ | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Q (length determined from LQ) .../ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | LA | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | A (length determined from LA) .../ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | ALTA | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | LB | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | B (length determined from LB) .../ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | LC | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | C (length determined from LC) .../ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | LG | - - -R. Schroeppel, et al [Page 4] - - -INTERNET-DRAFT ECC Keys in the DNS - - - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | G (length determined from LG) .../ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | LY | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Y (length determined from LY) .../ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - SMFMTABZ is a flags octet as follows: - - S = 1 indicates that the remaining 7 bits of the octet selects - one of 128 predefined choices of finite field, element - representation, elliptic curve, and signature parameters. - MFMTABZ are omitted, as are all parameters from LP through G. - LY and Y are retained. - - If S = 0, the remaining parameters are as in the picture and - described below. - - M determines the type of field underlying the elliptic curve. - - M = 0 if the field is a GF[2^N] field; - - M = 1 if the field is a (mod P) or GF[P^D] field with P>2. - - FMT is a three bit field describing the format of the field - representation. - - FMT = 0 for a (mod P) field. - > 0 for an extension field, either GF[2^D] or GF[P^D]. - The degree D of the extension, and the field polynomial - must be specified. The field polynomial is always monic - (leading coefficient 1.) - - FMT = 1 The field polynomial is given explicitly; D is implied. - - If FMT >=2, the degree D is given explicitly. - - = 2 The field polynomial is implicit. - = 3 The field polynomial is a binomial. P>2. - = 4 The field polynomial is a trinomial. - = 5 The field polynomial is the quotient of a trinomial by a - short polynomial. P=2. - = 6 The field polynomial is a pentanomial. P=2. - - Flags A and B apply to the elliptic curve parameters. - - - - - - -R. Schroeppel, et al [Page 5] - - -INTERNET-DRAFT ECC Keys in the DNS - - - A = 1 When P>=5, the curve parameter A is negated. If P=2, then - A=1 indicates that the A parameter is special. See the - ALTA parameter below, following A. The combination A=1, - P=3 is forbidden. - - B = 1 When P>=5, the curve parameter B is negated. If P=2 or 3, - then B=1 indicates an alternate elliptic curve equation is - used. When P=2 and B=1, an additional curve parameter C - is present. - - The Z bit SHOULD be set to zero on creation of an RR and MUST be - ignored when processing an RR (when S=0). - - Most of the remaining parameters are present in some formats and - absent in others. The presence or absence of a parameter is - determined entirely by the flags. When a parameter occurs, it is in - the order defined by the picture. - - Of the remaining parameters, PFHKQABCGY are variable length. When - present, each is preceded by a one-octet length field as shown in the - diagram above. The length field does not include itself. The length - field may have values from 0 through 110. The parameter length in - octets is determined by a conditional formula: If LL<=64, the - parameter length is LL. If LL>64, the parameter length is 16 times - (LL-60). In some cases, a parameter value of 0 is sensible, and MAY - be represented by an LL value of 0, with the data field omitted. A - length value of 0 represents a parameter value of 0, not an absent - parameter. (The data portion occupies 0 space.) There is no - requirement that a parameter be represented in the minimum number of - octets; high-order 0 octets are allowed at the front end. Parameters - are always right adjusted, in a field of length defined by LL. The - octet-order is always most-significant first, least-significant last. - The parameters H and K may have an optional sign bit stored in the - unused high-order bit of their length fields. - - LP defines the length of the prime P. P must be an odd prime. The - parameters LP,P are present if and only if the flag M=1. If M=0, the - prime is 2. - - LF,F define an explicit field polynomial. This parameter pair is - present only when FMT = 1. The length of a polynomial coefficient is - ceiling(log2 P) bits. Coefficients are in the numerical range - [0,P-1]. The coefficients are packed into fixed-width fields, from - higher order to lower order. All coefficients must be present, - including any 0s and also the leading coefficient (which is required - to be 1). The coefficients are right justified into the octet string - of length specified by LF, with the low-order "constant" coefficient - at the right end. As a concession to storage efficiency, the higher - order bits of the leading coefficient may be elided, discarding high- - order 0 octets and reducing LF. The degree is calculated by - - -R. Schroeppel, et al [Page 6] - - -INTERNET-DRAFT ECC Keys in the DNS - - - determining the bit position of the left most 1-bit in the F data - (counting the right most bit as position 0), and dividing by - ceiling(log2 P). The division must be exact, with no remainder. In - this format, all of the other degree and field parameters are - omitted. The next parameters will be LQ,Q. - - If FMT>=2, the degree of the field extension is specified explicitly, - usually along with other parameters to define the field polynomial. - - DEG is a two octet field that defines the degree of the field - extension. The finite field will have P^DEG elements. DEG is - present when FMT>=2. - - When FMT=2, the field polynomial is specified implicitly. No other - parameters are required to define the field; the next parameters - present will be the LQ,Q pair. The implicit field poynomial is the - lexicographically smallest irreducible (mod P) polynomial of the - correct degree. The ordering of polynomials is by highest-degree - coefficients first -- the leading coefficient 1 is most important, - and the constant term is least important. Coefficients are ordered - by sign-magnitude: 0 < 1 < -1 < 2 < -2 < ... The first polynomial of - degree D is X^D (which is not irreducible). The next is X^D+1, which - is sometimes irreducible, followed by X^D-1, which isn't. Assuming - odd P, this series continues to X^D - (P-1)/2, and then goes to X^D + - X, X^D + X + 1, X^D + X - 1, etc. - - When FMT=3, the field polynomial is a binomial, X^DEG + K. P must be - odd. The polynomial is determined by the degree and the low order - term K. Of all the field parameters, only the LK,K parameters are - present. The high-order bit of the LK octet stores on optional sign - for K; if the sign bit is present, the field polynomial is X^DEG - K. - - When FMT=4, the field polynomial is a trinomial, X^DEG + H*X^DEGH + - K. When P=2, the H and K parameters are implicitly 1, and are - omitted from the representation. Only DEG and DEGH are present; the - next parameters are LQ,Q. When P>2, then LH,H and LK,K are - specified. Either or both of LH, LK may contain a sign bit for its - parameter. - - When FMT=5, then P=2 (only). The field polynomial is the exact - quotient of a trinomial divided by a small polynomial, the trinomial - divisor. The small polynomial is right-adjusted in the two octet - field TRDV. DEG specifies the degree of the field. The degree of - TRDV is calculated from the position of the high-order 1 bit. The - trinomial to be divided is X^(DEG+degree(TRDV)) + X^DEGH + 1. If - DEGH is 0, the middle term is omitted from the trinomial. The - quotient must be exact, with no remainder. - - When FMT=6, then P=2 (only). The field polynomial is a pentanomial, - with the degrees of the middle terms given by the three 2-octet - - -R. Schroeppel, et al [Page 7] - - -INTERNET-DRAFT ECC Keys in the DNS - - - values DEGH, DEGI, DEGJ. The polynomial is X^DEG + X^DEGH + X^DEGI + - X^DEGJ + 1. The values must satisfy the inequality DEG > DEGH > DEGI - > DEGJ > 0. - - DEGH, DEGI, DEGJ are two-octet fields that define the degree of - a term in a field polynomial. DEGH is present when FMT = 4, - 5, or 6. DEGI and DEGJ are present only when FMT = 6. - - TRDV is a two-octet right-adjusted binary polynomial of degree < - 16. It is present only for FMT=5. - - LH and H define the H parameter, present only when FMT=4 and P - is odd. The high bit of LH is an optional sign bit for H. - - LK and K define the K parameter, present when FMT = 3 or 4, and - P is odd. The high bit of LK is an optional sign bit for K. - - The remaining parameters are concerned with the elliptic curve and - the signature algorithm. - - LQ defines the length of the prime Q. Q is a prime > 2^159. - - In all 5 of the parameter pairs LA+A,LB+B,LC+C,LG+G,LY+Y, the data - member of the pair is an element from the finite field defined - earlier. The length field defines a long octet string. Field - elements are represented as (mod P) polynomials of degree < DEG, with - DEG or fewer coefficients. The coefficients are stored from left to - right, higher degree to lower, with the constant term last. The - coefficients are represented as integers in the range [0,P-1]. Each - coefficient is allocated an area of ceiling(log2 P) bits. The field - representation is right-justified; the "constant term" of the field - element ends at the right most bit. The coefficients are fitted - adjacently without regard for octet boundaries. (Example: if P=5, - three bits are used for each coefficient. If the field is GF[5^75], - then 225 bits are required for the coefficients, and as many as 29 - octets may be needed in the data area. Fewer octets may be used if - some high-order coefficients are 0.) If a flag requires a field - element to be negated, each non-zero coefficient K is replaced with - P-K. To save space, 0 bits may be removed from the left end of the - element representation, and the length field reduced appropriately. - This would normally only happen with A,B,C, because the designer - chose curve parameters with some high-order 0 coefficients or bits. - - If the finite field is simply (mod P), then the field elements are - simply numbers (mod P), in the usual right-justified notation. If - the finite field is GF[2^D], the field elements are the usual right- - justified polynomial basis representation. - - - - - -R. Schroeppel, et al [Page 8] - - -INTERNET-DRAFT ECC Keys in the DNS - - - LA,A is the first parameter of the elliptic curve equation. - When P>=5, the flag A = 1 indicates A should be negated (mod - P). When P=2 (indicated by the flag M=0), the flag A = 1 - indicates that the parameter pair LA,A is replaced by the two - octet parameter ALTA. In this case, the parameter A in the - curve equation is x^ALTA, where x is the field generator. - Parameter A often has the value 0, which may be indicated by - LA=0 (with no A data field), and sometimes A is 1, which may - be represented with LA=1 and a data field of 1, or by setting - the A flag and using an ALTA value of 0. - - LB,B is the second parameter of the elliptic curve equation. - When P>=5, the flag B = 1 indicates B should be negated (mod - P). When P=2 or 3, the flag B selects an alternate curve - equation. - - LC,C is the third parameter of the elliptic curve equation, - present only when P=2 (indicated by flag M=0) and flag B=1. - - LG,G defines a point on the curve, of order Q. The W-coordinate - of the curve point is given explicitly; the Z-coordinate is - implicit. - - LY,Y is the user's public signing key, another curve point of - order Q. The W-coordinate is given explicitly; the Z- - coordinate is implicit. The LY,Y parameter pair is always - present. - - - -3. The Elliptic Curve Equation - - (The coordinates of an elliptic curve point are named W,Z instead of - the more usual X,Y to avoid confusion with the Y parameter of the - signing key.) - - The elliptic curve equation is determined by the flag octet, together - with information about the prime P. The primes 2 and 3 are special; - all other primes are treated identically. - - If M=1, the (mod P) or GF[P^D] case, the curve equation is Z^2 = W^3 - + A*W + B. Z,W,A,B are all numbers (mod P) or elements of GF[P^D]. - If A and/or B is negative (i.e., in the range from P/2 to P), and - P>=5, space may be saved by putting the sign bit(s) in the A and B - bits of the flags octet, and the magnitude(s) in the parameter - fields. - - If M=1 and P=3, the B flag has a different meaning: it specifies an - alternate curve equation, Z^2 = W^3 + A*W^2 + B. The middle term of - the right-hand-side is different. When P=3, this equation is more - - -R. Schroeppel, et al [Page 9] - - -INTERNET-DRAFT ECC Keys in the DNS - - - commonly used. - - If M=0, the GF[2^N] case, the curve equation is Z^2 + W*Z = W^3 + - A*W^2 + B. Z,W,A,B are all elements of the field GF[2^N]. The A - parameter can often be 0 or 1, or be chosen as a single-1-bit value. - The flag B is used to select an alternate curve equation, Z^2 + C*Z = - W^3 + A*W + B. This is the only time that the C parameter is used. - - - -4. How do I Compute Q, G, and Y? - - The number of points on the curve is the number of solutions to the - curve equation, + 1 (for the "point at infinity"). The prime Q must - divide the number of points. Usually the curve is chosen first, then - the number of points is determined with Schoof's algorithm. This - number is factored, and if it has a large prime divisor, that number - is taken as Q. - - G must be a point of order Q on the curve, satisfying the equation - - Q * G = the point at infinity (on the elliptic curve) - - G may be chosen by selecting a random [RFC 1750] curve point, and - multiplying it by (number-of-points-on-curve/Q). G must not itself - be the "point at infinity"; in this astronomically unlikely event, a - new random curve point is recalculated. - - G is specified by giving its W-coordinate. The Z-coordinate is - calculated from the curve equation. In general, there will be two - possible Z values. The rule is to choose the "positive" value. - - In the (mod P) case, the two possible Z values sum to P. The smaller - value is less than P/2; it is used in subsequent calculations. In - GF[P^D] fields, the highest-degree non-zero coefficient of the field - element Z is used; it is chosen to be less than P/2. - - In the GF[2^N] case, the two possible Z values xor to W (or to the - parameter C with the alternate curve equation). The numerically - smaller Z value (the one which does not contain the highest-order 1 - bit of W (or C)) is used in subsequent calculations. - - Y is specified by giving the W-coordinate of the user's public - signature key. The Z-coordinate value is determined from the curve - equation. As with G, there are two possible Z values; the same rule - is followed for choosing which Z to use. - - - - - - -R. Schroeppel, et al [Page 10] - - -INTERNET-DRAFT ECC Keys in the DNS - - - During the key generation process, a random [RFC 1750] number X must - be generated such that 1 <= X <= Q-1. X is the private key and is - used in the final step of public key generation where Y is computed - as - - Y = X * G (as points on the elliptic curve) - - If the Z-coordinate of the computed point Y is wrong (i.e., Z > P/2 - in the (mod P) case, or the high-order non-zero coefficient of Z > - P/2 in the GF[P^D] case, or Z sharing a high bit with W(C) in the - GF[2^N] case), then X must be replaced with Q-X. This will - correspond to the correct Z-coordinate. - - - -5. Elliptic Curve SIG Resource Records - - The signature portion of an RR RDATA area when using the EC - algorithm, for example in the RRSIG and SIG [RFC records] RRs is - shown below. - - 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | R, (length determined from LQ) .../ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | S, (length determined from LQ) .../ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - R and S are integers (mod Q). Their length is specified by the LQ - field of the corresponding KEY RR and can also be calculated from the - SIG RR's RDLENGTH. They are right justified, high-order-octet first. - The same conditional formula for calculating the length from LQ is - used as for all the other length fields above. - - The data signed is determined as specified in [RFC 2535]. Then the - following steps are taken where Q, P, G, and Y are as specified in - the public key [Schneier]: - - hash = SHA-1 ( data ) - - Generate random [RFC 4086] K such that 0 < K < Q. (Never sign two - different messages with the same K. K should be chosen from a - very large space: If an opponent learns a K value for a single - signature, the user's signing key is compromised, and a forger - can sign arbitrary messages. There is no harm in signing the - same message multiple times with the same key or different - keys.) - - R = (the W-coordinate of ( K*G on the elliptic curve )) interpreted - - -R. Schroeppel, et al [Page 11] - - -INTERNET-DRAFT ECC Keys in the DNS - - - as an integer, and reduced (mod Q). (R must not be 0. In - this astronomically unlikely event, generate a new random K - and recalculate R.) - - S = ( K^(-1) * (hash + X*R) ) mod Q. - - S must not be 0. In this astronomically unlikely event, generate a - new random K and recalculate R and S. - - If S > Q/2, set S = Q - S. - - The pair (R,S) is the signature. - - Another party verifies the signature as follows: - - Check that 0 < R < Q and 0 < S < Q/2. If not, it can not be a - valid EC sigature. - - hash = SHA-1 ( data ) - - Sinv = S^(-1) mod Q. - - U1 = (hash * Sinv) mod Q. - - U2 = (R * Sinv) mod Q. - - (U1 * G + U2 * Y) is computed on the elliptic curve. - - V = (the W-coordinate of this point) interpreted as an integer - and reduced (mod Q). - - The signature is valid if V = R. - - The reason for requiring S < Q/2 is that, otherwise, both (R,S) and - (R,Q-S) would be valid signatures for the same data. Note that a - signature that is valid for hash(data) is also valid for - hash(data)+Q or hash(data)-Q, if these happen to fall in the range - [0,2^160-1]. It's believed to be computationally infeasible to - find data that hashes to an assigned value, so this is only a - cosmetic blemish. The blemish can be eliminated by using Q > - 2^160, at the cost of having slightly longer signatures, 42 octets - instead of 40. - - We must specify how a field-element E ("the W-coordinate") is to be - interpreted as an integer. The field-element E is regarded as a - radix-P integer, with the digits being the coefficients in the - polynomial basis representation of E. The digits are in the ragne - [0,P-1]. In the two most common cases, this reduces to "the - obvious thing". In the (mod P) case, E is simply a residue mod P, - and is taken as an integer in the range [0,P-1]. In the GF[2^D] - - -R. Schroeppel, et al [Page 12] - - -INTERNET-DRAFT ECC Keys in the DNS - - - case, E is in the D-bit polynomial basis representation, and is - simply taken as an integer in the range [0,(2^D)-1]. For other - fields GF[P^D], it's necessary to do some radix conversion - arithmetic. - - - - 6. Performance Considerations - - Elliptic curve signatures use smaller moduli or field sizes than - RSA and DSA. Creation of a curve is slow, but not done very often. - Key generation is faster than RSA or DSA. - - DNS implementations have been optimized for small transfers, - typically less than 512 octets including DNS overhead. Larger - transfers will perform correctly and and extensions have been - standardized to make larger transfers more efficient [RFC 2671]. - However, it is still advisable at this time to make reasonable - efforts to minimize the size of RR sets stored within the DNS - consistent with adequate security. - - - - 7. Security Considerations - - Keys retrieved from the DNS should not be trusted unless (1) they - have been securely obtained from a secure resolver or independently - verified by the user and (2) this secure resolver and secure - obtainment or independent verification conform to security policies - acceptable to the user. As with all cryptographic algorithms, - evaluating the necessary strength of the key is essential and - dependent on local policy. - - Some specific key generation considerations are given in the body - of this document. - - - - 8. IANA Considerations - - The key and signature data structures defined herein correspond to - the value 4 in the Algorithm number field of the IANA registry - - Assignment of meaning to the remaining ECC data flag bits or to - values of ECC fields outside the ranges for which meaning in - defined in this document requires an IETF consensus as defined in - [RFC 2434]. - - - - - -R. Schroeppel, et al [Page 13] - - -INTERNET-DRAFT ECC Keys in the DNS - - - Copyright and Disclaimer - - Copyright (C) The Internet Society 2005. This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - - This document and the information contained herein are provided on - an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE - REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND - THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT - THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR - ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A - PARTICULAR PURPOSE. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -R. Schroeppel, et al [Page 14] - - -INTERNET-DRAFT ECC Keys in the DNS - - - Informational References - - [RFC 1034] - P. Mockapetris, "Domain names - concepts and - facilities", 11/01/1987. - - [RFC 1035] - P. Mockapetris, "Domain names - implementation and - specification", 11/01/1987. - - [RFC 2671] - P. Vixie, "Extension Mechanisms for DNS (EDNS0)", - August 1999. - - [RFC 4033] - Arends, R., Austein, R., Larson, M., Massey, D., and - S. Rose, "DNS Security Introduction and Requirements", RFC 4033, - March 2005. - - [RFC 4035] - Arends, R., Austein, R., Larson, M., Massey, D., and - S. Rose, "Protocol Modifications for the DNS Security Extensions", - RFC 4035, March 2005. - - [RFC 4086] - Eastlake, D., 3rd, Schiller, J., and S. Crocker, - "Randomness Requirements for Security", BCP 106, RFC 4086, June - 2005. - - [Schneier] - Bruce Schneier, "Applied Cryptography: Protocols, - Algorithms, and Source Code in C", 1996, John Wiley and Sons - - [Menezes] - Alfred Menezes, "Elliptic Curve Public Key - Cryptosystems", 1993 Kluwer. - - [Silverman] - Joseph Silverman, "The Arithmetic of Elliptic - Curves", 1986, Springer Graduate Texts in mathematics #106. - - - - Normative Refrences - - [RFC 2119] - S. Bradner, "Key words for use in RFCs to Indicate - Requirement Levels", March 1997. - - [RFC 2434] - T. Narten, H. Alvestrand, "Guidelines for Writing an - IANA Considerations Section in RFCs", October 1998. - - [RFC 4034] - Arends, R., Austein, R., Larson, M., Massey, D., and - S. Rose, "Resource Records for the DNS Security Extensions", RFC - 4034, March 2005. - - - - - - - -R. Schroeppel, et al [Page 15] - - -INTERNET-DRAFT ECC Keys in the DNS - - - Author's Addresses - - Rich Schroeppel - 500 S. Maple Drive - Woodland Hills, UT 84653 USA - - Telephone: +1-505-844-9079(w) - Email: rschroe@sandia.gov - - - Donald E. Eastlake 3rd - Motorola Laboratories - 155 Beaver Street - Milford, MA 01757 USA - - Telephone: +1 508-786-7554 (w) - EMail: Donald.Eastlake@motorola.com - - - - Expiration and File Name - - This draft expires in January 2006. - - Its file name is draft-ietf-dnsext-ecc-key-07.txt. - - - - - - - - - - - - - - - - - - - - - - - - - - - -R. Schroeppel, et al [Page 16] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-interop3597-02.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-interop3597-02.txt deleted file mode 100644 index 160afc3..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-interop3597-02.txt +++ /dev/null @@ -1,334 +0,0 @@ -DNS Extensions Working Group J. Schlyter -Internet-Draft May 19, 2005 -Expires: November 20, 2005 - - - RFC 3597 Interoperability Report - draft-ietf-dnsext-interop3597-02.txt - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on November 20, 2005. - -Copyright Notice - - Copyright (C) The Internet Society (2005). - -Abstract - - This memo documents the result from the RFC 3597 (Handling of Unknown - DNS Resource Record Types) interoperability testing. - - - - - - - - - - -Schlyter Expires November 20, 2005 [Page 1] - -Internet-Draft RFC 3597 Interoperability Report May 2005 - - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 2. Implementations . . . . . . . . . . . . . . . . . . . . . . . 3 - 3. Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 3.1 Authoritative Primary Name Server . . . . . . . . . . . . 3 - 3.2 Authoritative Secondary Name Server . . . . . . . . . . . 3 - 3.3 Full Recursive Resolver . . . . . . . . . . . . . . . . . 4 - 3.4 Stub Resolver . . . . . . . . . . . . . . . . . . . . . . 4 - 3.5 DNSSEC Signer . . . . . . . . . . . . . . . . . . . . . . 4 - 4. Problems found . . . . . . . . . . . . . . . . . . . . . . . . 4 - 5. Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 - 6. Normative References . . . . . . . . . . . . . . . . . . . . . 4 - Author's Address . . . . . . . . . . . . . . . . . . . . . . . 4 - A. Test zone data . . . . . . . . . . . . . . . . . . . . . . . . 5 - Intellectual Property and Copyright Statements . . . . . . . . 6 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Schlyter Expires November 20, 2005 [Page 2] - -Internet-Draft RFC 3597 Interoperability Report May 2005 - - -1. Introduction - - This memo documents the result from the RFC 3597 (Handling of Unknown - DNS Resource Record Types) interoperability testing. The test was - performed during June and July 2004 by request of the IETF DNS - Extensions Working Group. - -2. Implementations - - The following is a list, in alphabetic order, of implementations - tested for compliance with RFC 3597: - - DNSJava 1.6.4 - ISC BIND 8.4.5 - ISC BIND 9.3.0 - NSD 2.1.1 - Net::DNS 0.47 patchlevel 1 - Nominum ANS 2.2.1.0.d - - These implementations covers the following functions (number of - implementations tested for each function in paranthesis): - - Authoritative Name Servers (4) - Full Recursive Resolver (2) - Stub Resolver (4) - DNSSEC Zone Signers (2) - - All listed implementations are genetically different. - -3. Tests - - The following tests was been performed to validate compliance with - RFC 3597 section 3 ("Transparency"), 4 ("Domain Name Compression") - and 5 ("Text Representation"). - -3.1 Authoritative Primary Name Server - - The test zone data (Appendix A) was loaded into the name server - implementation and the server was queried for the loaded information. - -3.2 Authoritative Secondary Name Server - - The test zone data (Appendix A) was transferred using AXFR from - another name server implementation and the server was queried for the - transferred information. - - - - - - -Schlyter Expires November 20, 2005 [Page 3] - -Internet-Draft RFC 3597 Interoperability Report May 2005 - - -3.3 Full Recursive Resolver - - A recursive resolver was queried for resource records from a domain - with the test zone data (Appendix A). - -3.4 Stub Resolver - - A stub resolver was used to query resource records from a domain with - the test zone data (Appendix A). - -3.5 DNSSEC Signer - - A DNSSEC signer was used to sign a zone with test zone data - (Appendix A). - -4. Problems found - - Two implementations had problems with text presentation of zero - length RDATA. - - One implementation had problems with text presentation of RR type - code and classes >= 4096. - - Bug reports were filed for problems found. - -5. Summary - - Unknown type codes works in the tested authoritative servers, - recursive resolvers and stub clients. - - No changes are needed to advance RFC 3597 to draft standard. - -6. Normative References - - [1] Gustafsson, A., "Handling of Unknown DNS Resource Record (RR) - Types", RFC 3597, September 2003. - - -Author's Address - - Jakob Schlyter - - Email: jakob@rfc.se - - - - - - - - -Schlyter Expires November 20, 2005 [Page 4] - -Internet-Draft RFC 3597 Interoperability Report May 2005 - - -Appendix A. Test zone data - - ; A-record encoded as TYPE1 - a TYPE1 \# 4 7f000001 - a TYPE1 192.0.2.1 - a A \# 4 7f000002 - - ; draft-ietf-secsh-dns-05.txt - sshfp TYPE44 \# 22 01 01 c691e90714a1629d167de8e5ee0021f12a7eaa1e - - ; bogus test record (from RFC 3597) - type731 TYPE731 \# 6 abcd ( - ef 01 23 45 ) - - ; zero length RDATA (from RFC 3597) - type62347 TYPE62347 \# 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Schlyter Expires November 20, 2005 [Page 5] - -Internet-Draft RFC 3597 Interoperability Report May 2005 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2005). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Schlyter Expires November 20, 2005 [Page 6] - - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-keyrr-key-signing-flag-12.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-keyrr-key-signing-flag-12.txt deleted file mode 100644 index 6bffb70..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-keyrr-key-signing-flag-12.txt +++ /dev/null @@ -1,560 +0,0 @@ - -DNS Extensions O. Kolkman -Internet-Draft RIPE NCC -Expires: June 17, 2004 J. Schlyter - - E. Lewis - ARIN - December 18, 2003 - - - DNSKEY RR Secure Entry Point Flag - draft-ietf-dnsext-keyrr-key-signing-flag-12 - -Status of this Memo - - This document is an Internet-Draft and is in full conformance with - all provisions of Section 10 of RFC2026. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that other - groups may also distribute working documents as Internet-Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at http:// - www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on June 17, 2004. - -Copyright Notice - - Copyright (C) The Internet Society (2003). All Rights Reserved. - -Abstract - - With the Delegation Signer (DS) resource record the concept of a - public key acting as a secure entry point has been introduced. During - exchanges of public keys with the parent there is a need to - differentiate secure entry point keys from other public keys in the - DNSKEY resource record (RR) set. A flag bit in the DNSKEY RR is - defined to indicate that DNSKEY is to be used as a secure entry - point. The flag bit is intended to assist in operational procedures - to correctly generate DS resource records, or to indicate what - DNSKEYs are intended for static configuration. The flag bit is not to - - - -Kolkman, et al. Expires June 17, 2004 [Page 1] - -Internet-Draft DNSKEY RR Secure Entry Point Flag December 2003 - - - be used in the DNS verification protocol. This document updates RFC - 2535 and RFC 3445. - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 2. The Secure Entry Point (SEP) Flag . . . . . . . . . . . . . . . 4 - 3. DNSSEC Protocol Changes . . . . . . . . . . . . . . . . . . . . 5 - 4. Operational Guidelines . . . . . . . . . . . . . . . . . . . . . 5 - 5. Security Considerations . . . . . . . . . . . . . . . . . . . . 6 - 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . . 6 - 7. Internationalization Considerations . . . . . . . . . . . . . . 6 - 8. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . 6 - Normative References . . . . . . . . . . . . . . . . . . . . . . 7 - Informative References . . . . . . . . . . . . . . . . . . . . . 7 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 7 - Intellectual Property and Copyright Statements . . . . . . . . . 9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Kolkman, et al. Expires June 17, 2004 [Page 2] - -Internet-Draft DNSKEY RR Secure Entry Point Flag December 2003 - - -1. Introduction - - "All keys are equal but some keys are more equal than others" [6] - - With the definition of the Delegation Signer Resource Record (DS RR) - [5] it has become important to differentiate between the keys in the - DNSKEY RR set that are (to be) pointed to by parental DS RRs and the - other keys in the DNSKEY RR set. We refer to these public keys as - Secure Entry Point (SEP) keys. A SEP key either used to generate a - DS RR or is distributed to resolvers that use the key as the root of - a trusted subtree[3]. - - In early deployment tests, the use of two (kinds of) key pairs for - each zone has been prevalent. For one kind of key pair the private - key is used to sign just the zone's DNSKEY resource record (RR) set. - Its public key is intended to be referenced by a DS RR at the parent - or configured statically in a resolver. The private key of the other - kind of key pair is used to sign the rest of the zone's data sets. - The former key pair is called a key-signing key (KSK) and the latter - is called a zone-signing key (ZSK). In practice there have been - usually one of each kind of key pair, but there will be multiples of - each at times. - - It should be noted that division of keys pairs into KSK's and ZSK's - is not mandatory in any definition of DNSSEC, not even with the - introduction of the DS RR. But, in testing, this distinction has - been helpful when designing key roll over (key super-cession) - schemes. Given that the distinction has proven helpful, the labels - KSK and ZSK have begun to stick. - - There is a need to differentiate the public keys for the key pairs - that are used for key signing from keys that are not used key signing - (KSKs vs ZSKs). This need is driven by knowing which DNSKEYs are to - be sent for generating DS RRs, which DNSKEYs are to be distributed to - resolvers, and which keys are fed to the signer application at the - appropriate time. - - In other words, the SEP bit provides an in-band method to communicate - a DNSKEY RR's intended use to third parties. As an example we present - 3 use cases in which the bit is useful: - - The parent is a registry, the parent and the child use secured DNS - queries and responses, with a preexisting trust-relation, or plain - DNS over a secured channel to exchange the child's DNSKEY RR - sets. Since a DNSKEY RR set will contain a complete DNSKEY RRset - the SEP bit can be used to isolate the DNSKEYs for which a DS RR - needs to be created. - - - - -Kolkman, et al. Expires June 17, 2004 [Page 3] - -Internet-Draft DNSKEY RR Secure Entry Point Flag December 2003 - - - An administrator has configured a DNSKEY as root for a trusted - subtree into security aware resolver. Using a special purpose tool - that queries for the KEY RRs from that domain's apex, the - administrator will be able to notice the roll over of the trusted - anchor by a change of the subset of KEY RRs with the DS flag set. - - A signer might use the SEP bit on the public key to determine - which private key to use to exclusively sign the DNSKEY RRset and - which private key to use to sign the other RRsets in the zone. - - As demonstrated in the above examples it is important to be able to - differentiate the SEP keys from the other keys in a DNSKEY RR set in - the flow between signer and (parental) key-collector and in the flow - between the signer and the resolver configuration. The SEP flag is to - be of no interest to the flow between the verifier and the - authoritative data store. - - The reason for the term "SEP" is a result of the observation that the - distinction between KSK and ZSK key pairs is made by the signer, a - key pair could be used as both a KSK and a ZSK at the same time. To - be clear, the term SEP was coined to lessen the confusion caused by - the overlap. ( Once this label was applied, it had the side effect of - removing the temptation to have both a KSK flag bit and a ZSK flag - bit.) - - The key words "MAY","MAY NOT", "MUST", "MUST NOT", "REQUIRED", - "RECOMMENDED", "SHOULD", and "SHOULD NOT" in this document are to be - interpreted as described in RFC2119 [1]. - -2. The Secure Entry Point (SEP) Flag - - - 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | flags |S| protocol | algorithm | - | |E| | | - | |P| | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | / - / public key / - / / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - DNSKEY RR Format - - - - - - -Kolkman, et al. Expires June 17, 2004 [Page 4] - -Internet-Draft DNSKEY RR Secure Entry Point Flag December 2003 - - - This document assigns the 15'th bit in the flags field as the secure - entry point (SEP) bit. If the the bit is set to 1 the key is - intended to be used as secure entry point key. One SHOULD NOT assign - special meaning to the key if the bit is set to 0. Operators can - recognize the secure entry point key by the even or odd-ness of the - decimal representation of the flag field. - -3. DNSSEC Protocol Changes - - The bit MUST NOT be used during the resolving and verification - process. The SEP flag is only used to provide a hint about the - different administrative properties of the key and therefore the use - of the SEP flag does not change the DNS resolution protocol or the - resolution process. - -4. Operational Guidelines - - The SEP bit is set by the key-pair-generator and MAY be used by the - zone signer to decide whether the public part of the key pair is to - be prepared for input to a DS RR generation function. The SEP bit is - recommended to be set (to 1) whenever the public key of the key pair - will be distributed to the parent zone to build the authentication - chain or if the public key is to be distributed for static - configuration in verifiers. - - When a key pair is created, the operator needs to indicate whether - the SEP bit is to be set in the DNSKEY RR. As the SEP bit is within - the data that is used to compute the 'key tag field' in the SIG RR, - changing the SEP bit will change the identity of the key within DNS. - In other words, once a key is used to generate signatures, the - setting of the SEP bit is to remain constant. If not, a verifier will - not be able to find the relevant KEY RR. - - When signing a zone, it is intended that the key(s) with the SEP bit - set (if such keys exist) are used to sign the KEY RR set of the zone. - The same key can be used to sign the rest of the zone data too. It - is conceivable that not all keys with a SEP bit set will sign the - DNSKEY RR set, such keys might be pending retirement or not yet in - use. - - When verifying a RR set, the SEP bit is not intended to play a role. - How the key is used by the verifier is not intended to be a - consideration at key creation time. - - Although the SEP flag provides a hint on which public key is to be - used as trusted root, administrators can choose to ignore the fact - that a DNSKEY has its SEP bit set or not when configuring a trusted - root for their resolvers. - - - -Kolkman, et al. Expires June 17, 2004 [Page 5] - -Internet-Draft DNSKEY RR Secure Entry Point Flag December 2003 - - - Using the SEP flag a key roll over can be automated. The parent can - use an existing trust relation to verify DNSKEY RR sets in which a - new DNSKEY RR with the SEP flag appears. - -5. Security Considerations - - As stated in Section 3 the flag is not to be used in the resolution - protocol or to determine the security status of a key. The flag is to - be used for administrative purposes only. - - No trust in a key should be inferred from this flag - trust MUST be - inferred from an existing chain of trust or an out-of-band exchange. - - Since this flag might be used for automating public key exchanges, we - think the following consideration is in place. - - Automated mechanisms for roll over of the DS RR might be vulnerable - to a class of replay attacks. This might happen after a public key - exchange where a DNSKEY RR set, containing two DNSKEY RRs with the - SEP flag set, is sent to the parent. The parent verifies the DNSKEY - RR set with the existing trust relation and creates the new DS RR - from the DNSKEY RR that the current DS RR is not pointing to. This - key exchange might be replayed. Parents are encouraged to implement a - replay defense. A simple defense can be based on a registry of keys - that have been used to generate DS RRs during the most recent roll - over. These same considerations apply to entities that configure keys - in resolvers. - -6. IANA Considerations - - The flag bits in the DNSKEY RR are assigned by IETF consensus and - registered in the DNSKEY Flags registry (created by [4]). This - document assigns the 15th bit in the DNSKEY RR as the Secure Entry - Point (SEP) bit. - -7. Internationalization Considerations - - Although SEP is a popular acronym in many different languages, there - are no internationalization considerations. - -8. Acknowledgments - - The ideas documented in this document are inspired by communications - we had with numerous people and ideas published by other folk. Among - others Mark Andrews, Rob Austein, Miek Gieben, Olafur Gudmundsson, - Daniel Karrenberg, Dan Massey, Scott Rose, Marcos Sanz and Sam Weiler - have contributed ideas and provided feedback. - - - - -Kolkman, et al. Expires June 17, 2004 [Page 6] - -Internet-Draft DNSKEY RR Secure Entry Point Flag December 2003 - - - This document saw the light during a workshop on DNSSEC operations - hosted by USC/ISI in August 2002. - -Normative References - - [1] Bradner, S., "Key words for use in RFCs to Indicate Requirement - Levels", BCP 14, RFC 2119, March 1997. - - [2] Eastlake, D., "Domain Name System Security Extensions", RFC - 2535, March 1999. - - [3] Lewis, E., "DNS Security Extension Clarification on Zone - Status", RFC 3090, March 2001. - - [4] Weiler, S., "Legacy Resolver Compatibility for Delegation - Signer", draft-ietf-dnsext-dnssec-2535typecode-change-05 (work - in progress), October 2003. - -Informative References - - [5] Gudmundsson, O., "Delegation Signer Resource Record", - draft-ietf-dnsext-delegation-signer-15 (work in progress), June - 2003. - - [6] Orwell, G. and R. Steadman (illustrator), "Animal Farm; a Fairy - Story", ISBN 0151002177 (50th anniversary edition), April 1996. - - -Authors' Addresses - - Olaf M. Kolkman - RIPE NCC - Singel 256 - Amsterdam 1016 AB - NL - - Phone: +31 20 535 4444 - EMail: olaf@ripe.net - URI: http://www.ripe.net/ - - - Jakob Schlyter - Karl Gustavsgatan 15 - Goteborg SE-411 25 - Sweden - - EMail: jakob@schlyter.se - - - - -Kolkman, et al. Expires June 17, 2004 [Page 7] - -Internet-Draft DNSKEY RR Secure Entry Point Flag December 2003 - - - Edward P. Lewis - ARIN - 3635 Concorde Parkway Suite 200 - Chantilly, VA 20151 - US - - Phone: +1 703 227 9854 - EMail: edlewis@arin.net - URI: http://www.arin.net/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Kolkman, et al. Expires June 17, 2004 [Page 8] - -Internet-Draft DNSKEY RR Secure Entry Point Flag December 2003 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - intellectual property or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; neither does it represent that it - has made any effort to identify any such rights. Information on the - IETF's procedures with respect to rights in standards-track and - standards-related documentation can be found in BCP-11. Copies of - claims of rights made available for publication and any assurances of - licenses to be made available, or the result of an attempt made to - obtain a general license or permission for the use of such - proprietary rights by implementors or users of this specification can - be obtained from the IETF Secretariat. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights which may cover technology that may be required to practice - this standard. Please address the information to the IETF Executive - Director. - - -Full Copyright Statement - - Copyright (C) The Internet Society (2003). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assignees. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - - - -Kolkman, et al. Expires June 17, 2004 [Page 9] - -Internet-Draft DNSKEY RR Secure Entry Point Flag December 2003 - - - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Kolkman, et al. Expires June 17, 2004 [Page 10] - - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-mdns-43.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-mdns-43.txt deleted file mode 100644 index 5de6e85..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-mdns-43.txt +++ /dev/null @@ -1,1740 +0,0 @@ - - - - - - -DNSEXT Working Group Bernard Aboba -INTERNET-DRAFT Dave Thaler -Category: Standards Track Levon Esibov - Microsoft Corporation -29 August 2005 - - Linklocal Multicast Name Resolution (LLMNR) - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on March 15, 2006. - -Copyright Notice - - Copyright (C) The Internet Society 2005. - -Abstract - - The goal of Link-Local Multicast Name Resolution (LLMNR) is to enable - name resolution in scenarios in which conventional DNS name - resolution is not possible. LLMNR supports all current and future - DNS formats, types and classes, while operating on a separate port - from DNS, and with a distinct resolver cache. Since LLMNR only - operates on the local link, it cannot be considered a substitute for - DNS. - - - - - -Aboba, Thaler & Esibov Standards Track [Page 1] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - -Table of Contents - -1. Introduction .......................................... 3 - 1.1 Requirements .................................... 4 - 1.2 Terminology ..................................... 4 -2. Name Resolution Using LLMNR ........................... 4 - 2.1 LLMNR Packet Format ............................. 6 - 2.2 Sender Behavior ................................. 9 - 2.3 Responder Behavior .............................. 10 - 2.4 Unicast Queries and Responses ................... 12 - 2.5 Off-link Detection .............................. 13 - 2.6 Responder Responsibilities ...................... 13 - 2.7 Retransmission and Jitter ....................... 14 - 2.8 DNS TTL ......................................... 15 - 2.9 Use of the Authority and Additional Sections .... 15 -3. Usage model ........................................... 16 - 3.1 LLMNR Configuration ............................. 17 -4. Conflict Resolution ................................... 18 - 4.1 Uniqueness Verification ......................... 19 - 4.2 Conflict Detection and Defense .................. 20 - 4.3 Considerations for Multiple Interfaces .......... 21 - 4.4 API issues ...................................... 22 -5. Security Considerations ............................... 22 - 5.1 Denial of Service ............................... 23 - 5.2 Spoofing ...............,........................ 23 - 5.3 Authentication .................................. 24 - 5.4 Cache and Port Separation ....................... 25 -6. IANA considerations ................................... 25 -7. Constants ............................................. 25 -8. References ............................................ 25 - 8.1 Normative References ............................ 25 - 8.2 Informative References .......................... 26 -Acknowledgments .............................................. 27 -Authors' Addresses ........................................... 28 -Intellectual Property Statement .............................. 28 -Disclaimer of Validity ....................................... 29 -Copyright Statement .......................................... 29 - - - - - - - - - - - - - - -Aboba, Thaler & Esibov Standards Track [Page 2] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - -1. Introduction - - This document discusses Link Local Multicast Name Resolution (LLMNR), - which is based on the DNS packet format and supports all current and - future DNS formats, types and classes. LLMNR operates on a separate - port from the Domain Name System (DNS), with a distinct resolver - cache. - - The goal of LLMNR is to enable name resolution in scenarios in which - conventional DNS name resolution is not possible. Usage scenarios - (discussed in more detail in Section 3.1) include situations in which - hosts are not configured with the address of a DNS server; where the - DNS server is unavailable or unreachable; where there is no DNS - server authoritative for the name of a host, or where the - authoritative DNS server does not have the desired RRs, as described - in Section 2. - - Since LLMNR only operates on the local link, it cannot be considered - a substitute for DNS. Link-scope multicast addresses are used to - prevent propagation of LLMNR traffic across routers, potentially - flooding the network. LLMNR queries can also be sent to a unicast - address, as described in Section 2.4. - - Propagation of LLMNR packets on the local link is considered - sufficient to enable name resolution in small networks. In such - networks, if a network has a gateway, then typically the network is - able to provide DNS server configuration. Configuration issues are - discussed in Section 3.1. - - In the future, it may be desirable to consider use of multicast name - resolution with multicast scopes beyond the link-scope. This could - occur if LLMNR deployment is successful, the need arises for - multicast name resolution beyond the link-scope, or multicast routing - becomes ubiquitous. For example, expanded support for multicast name - resolution might be required for mobile ad-hoc networks. - - Once we have experience in LLMNR deployment in terms of - administrative issues, usability and impact on the network, it will - be possible to reevaluate which multicast scopes are appropriate for - use with multicast name resolution. IPv4 administratively scoped - multicast usage is specified in "Administratively Scoped IP - Multicast" [RFC2365]. - - Service discovery in general, as well as discovery of DNS servers - using LLMNR in particular, is outside of the scope of this document, - as is name resolution over non-multicast capable media. - - - - - -Aboba, Thaler & Esibov Standards Track [Page 3] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - -1.1. Requirements - - In this document, several words are used to signify the requirements - of the specification. The key words "MUST", "MUST NOT", "REQUIRED", - "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", - and "OPTIONAL" in this document are to be interpreted as described in - [RFC2119]. - -1.2. Terminology - - This document assumes familiarity with DNS terminology defined in - [RFC1035]. Other terminology used in this document includes: - -Positively Resolved - Responses with RCODE set to zero are referred to in this document - as "positively resolved". - -Routable Address - An address other than a Link-Local address. This includes globally - routable addresses, as well as private addresses. - -Reachable - An LLMNR responder considers one of its addresses reachable over a - link if it will respond to an ARP or Neighbor Discovery query for - that address received on that link. - -Responder - A host that listens to LLMNR queries, and responds to those for - which it is authoritative. - -Sender - A host that sends an LLMNR query. - -UNIQUE - There are some scenarios when multiple responders may respond to - the same query. There are other scenarios when only one responder - may respond to a query. Names for which only a single responder is - anticipated are referred to as UNIQUE. Name uniqueness is - configured on the responder, and therefore uniqueness verification - is the responder's responsibility. - -2. Name Resolution Using LLMNR - - LLMNR is a peer-to-peer name resolution protocol that is not intended - as a replacement for DNS. LLMNR queries are sent to and received on - port 5355. The IPv4 link-scope multicast address a given responder - listens to, and to which a sender sends queries, is 224.0.0.252. The - IPv6 link-scope multicast address a given responder listens to, and - - - -Aboba, Thaler & Esibov Standards Track [Page 4] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - - to which a sender sends all queries, is FF02:0:0:0:0:0:1:3. - - Typically a host is configured as both an LLMNR sender and a - responder. A host MAY be configured as a sender, but not a - responder. However, a host configured as a responder MUST act as a - sender, if only to verify the uniqueness of names as described in - Section 4. This document does not specify how names are chosen or - configured. This may occur via any mechanism, including DHCPv4 - [RFC2131] or DHCPv6 [RFC3315]. - - LLMNR usage MAY be configured manually or automatically on a per - interface basis. By default, LLMNR responders SHOULD be enabled on - all interfaces, at all times. Enabling LLMNR for use in situations - where a DNS server has been configured will result in a change in - default behavior without a simultaneous update to configuration - information. Where this is considered undesirable, LLMNR SHOULD NOT - be enabled by default, so that hosts will neither listen on the link- - scope multicast address, nor will they send queries to that address. - - By default, LLMNR queries MAY be sent only when one of the following - conditions are met: - - [1] No manual or automatic DNS configuration has been performed. - If DNS server address(es) have been configured, then LLMNR - SHOULD NOT be used as the primary name resolution mechanism, - although it MAY be used as a secondary name resolution - mechanism. A dual stack host SHOULD attempt to reach DNS - servers overall protocols on which DNS server address(es) are - configured, prior to sending LLMNR queries. For dual stack - hosts configured with DNS server address(es) for one protocol - but not another, this inplies that DNS queries SHOULD be sent - over the protocol configured with a DNS server, prior to - sending LLMNR queries. - - [2] All attempts to resolve the name via DNS on all interfaces - have failed after exhausting the searchlist. This can occur - because DNS servers did not respond, or because they - responded to DNS queries with RCODE=3 (Authoritative Name - Error) or RCODE=0, and an empty answer section. Where a - single resolver call generates DNS queries for A and AAAA RRs, - an implementation MAY choose not to send LLMNR queries if any - of the DNS queries is successful. An LLMNR query SHOULD only - be sent for the originally requested name; a searchlist - is not used to form additional LLMNR queries. - - While these conditions are necessary for sending an LLMNR query, they - are not sufficient. While an LLMNR sender MAY send a query for any - name, it also MAY impose additional conditions on sending LLMNR - - - -Aboba, Thaler & Esibov Standards Track [Page 5] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - - queries. For example, a sender configured with a DNS server MAY send - LLMNR queries only for unqualified names and for fully qualified - domain names within configured zones. - - A typical sequence of events for LLMNR usage is as follows: - - [a] DNS servers are not configured or attempts to resolve the - name via DNS have failed, after exhausting the searchlist. - Also, the name to be queried satisfies the restrictions - imposed by the implementation. - - [b] An LLMNR sender sends an LLMNR query to the link-scope - multicast address(es), unless a unicast query is indicated, - as specified in Section 2.4. - - [c] A responder responds to this query only if it is authoritative - for the domain name in the query. A responder responds to a - multicast query by sending a unicast UDP response to the sender. - Unicast queries are responded to as indicated in Section 2.4. - - [d] Upon reception of the response, the sender processes it. - - The sections that follow provide further details on sender and - responder behavior. - -2.1. LLMNR Packet Format - - LLMNR is based on the DNS packet format defined in [RFC1035] Section - 4 for both queries and responses. LLMNR implementations SHOULD send - UDP queries and responses only as large as are known to be - permissible without causing fragmentation. When in doubt a maximum - packet size of 512 octets SHOULD be used. LLMNR implementations MUST - accept UDP queries and responses as large as the smaller of the link - MTU or 9194 octets (Ethernet jumbo frame size of 9KB (9216) minus 22 - octets for the header, VLAN tag and CRC). - -2.1.1. LLMNR Header Format - - LLMNR queries and responses utilize the DNS header format defined in - [RFC1035] with exceptions noted below: - - - - - - - - - - - -Aboba, Thaler & Esibov Standards Track [Page 6] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - - 1 1 1 1 1 1 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | ID | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - |QR| Opcode | C|TC| T| Z| Z| Z| Z| RCODE | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | QDCOUNT | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | ANCOUNT | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | NSCOUNT | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | ARCOUNT | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - - where: - -ID A 16 bit identifier assigned by the program that generates any kind - of query. This identifier is copied from the query to the response - and can be used by the sender to match responses to outstanding - queries. The ID field in a query SHOULD be set to a pseudo-random - value. For advice on generation of pseudo-random values, please - consult [RFC1750]. - -QR Query/Response. A one bit field, which if set indicates that the - message is an LLMNR response; if clear then the message is an LLMNR - query. - -OPCODE - A four bit field that specifies the kind of query in this message. - This value is set by the originator of a query and copied into the - response. This specification defines the behavior of standard - queries and responses (opcode value of zero). Future - specifications may define the use of other opcodes with LLMNR. - LLMNR senders and responders MUST support standard queries (opcode - value of zero). LLMNR queries with unsupported OPCODE values MUST - be silently discarded by responders. - -C Conflict. When set within a request, the 'C'onflict bit indicates - that a sender has received multiple LLMNR responses to this query. - In an LLMNR response, if the name is considered UNIQUE, then the - 'C' bit is clear, otherwise it is set. LLMNR senders do not - retransmit queries with the 'C' bit set. Responders MUST NOT - respond to LLMNR queries with the 'C' bit set, but may start the - uniqueness verification process, as described in Section 4.2. - - - - - -Aboba, Thaler & Esibov Standards Track [Page 7] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - -TC TrunCation - specifies that this message was truncated due to - length greater than that permitted on the transmission channel. - The TC bit MUST NOT be set in an LLMNR query and if set is ignored - by an LLMNR responder. If the TC bit is set in an LLMNR response, - then the sender SHOULD discard the response and resend the LLMNR - query over TCP using the unicast address of the responder as the - destination address. See [RFC2181] and Section 2.4 of this - specification for further discussion of the TC bit. - -T Tentative. The 'T'entative bit is set in a response if the - responder is authoritative for the name, but has not yet verified - the uniqueness of the name. A responder MUST ignore the 'T' bit in - a query, if set. A response with the 'T' bit set is silently - discarded by the sender, except if it is a uniqueness query, in - which case a conflict has been detected and a responder MUST - resolve the conflict as described in Section 4.1. - -Z Reserved for future use. Implementations of this specification - MUST set these bits to zero in both queries and responses. If - these bits are set in a LLMNR query or response, implementations of - this specification MUST ignore them. Since reserved bits could - conceivably be used for different purposes than in DNS, - implementors are advised not to enable processing of these bits in - an LLMNR implementation starting from a DNS code base. - -RCODE - Response code -- this 4 bit field is set as part of LLMNR - responses. In an LLMNR query, the sender MUST set RCODE to zero; - the responder ignores the RCODE and assumes it to be zero. The - response to a multicast LLMNR query MUST have RCODE set to zero. A - sender MUST silently discard an LLMNR response with a non-zero - RCODE sent in response to a multicast query. - - If an LLMNR responder is authoritative for the name in a multicast - query, but an error is encountered, the responder SHOULD send an - LLMNR response with an RCODE of zero, no RRs in the answer section, - and the TC bit set. This will cause the query to be resent using - TCP, and allow the inclusion of a non-zero RCODE in the response to - the TCP query. Responding with the TC bit set is preferable to not - sending a response, since it enables errors to be diagnosed. - Errors include those defined in [RFC2845], such as BADSIG(16), - BADKEY(17) and BADTIME(18). - - Since LLMNR responders only respond to LLMNR queries for names for - which they are authoritative, LLMNR responders MUST NOT respond - with an RCODE of 3; instead, they should not respond at all. - - LLMNR implementations MUST support EDNS0 [RFC2671] and extended - - - -Aboba, Thaler & Esibov Standards Track [Page 8] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - - RCODE values. - -QDCOUNT - An unsigned 16 bit integer specifying the number of entries in the - question section. A sender MUST place only one question into the - question section of an LLMNR query. LLMNR responders MUST silently - discard LLMNR queries with QDCOUNT not equal to one. LLMNR senders - MUST silently discard LLMNR responses with QDCOUNT not equal to - one. - -ANCOUNT - An unsigned 16 bit integer specifying the number of resource - records in the answer section. LLMNR responders MUST silently - discard LLMNR queries with ANCOUNT not equal to zero. - -NSCOUNT - An unsigned 16 bit integer specifying the number of name server - resource records in the authority records section. Authority - record section processing is described in Section 2.9. LLMNR - responders MUST silently discard LLMNR queries with NSCOUNT not - equal to zero. - -ARCOUNT - An unsigned 16 bit integer specifying the number of resource - records in the additional records section. Additional record - section processing is described in Section 2.9. - -2.2. Sender Behavior - - A sender MAY send an LLMNR query for any legal resource record type - (e.g., A, AAAA, PTR, SRV, etc.) to the link-scope multicast address. - As described in Section 2.4, a sender MAY also send a unicast query. - - The sender MUST anticipate receiving no replies to some LLMNR - queries, in the event that no responders are available within the - link-scope. If no response is received, a resolver treats it as a - response that the name does not exist (RCODE=3 is returned). A - sender can handle duplicate responses by discarding responses with a - source IP address and ID field that duplicate a response already - received. - - When multiple valid LLMNR responses are received with the 'C' bit - set, they SHOULD be concatenated and treated in the same manner that - multiple RRs received from the same DNS server would be. However, - responses with the 'C' bit set SHOULD NOT be concatenated with - responses with the 'C' bit clear; instead, only the responses with - the 'C' bit set SHOULD be returned. If valid LLMNR response(s) are - received along with error response(s), then the error responses are - - - -Aboba, Thaler & Esibov Standards Track [Page 9] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - - silently discarded. - - If error responses are received from both DNS and LLMNR, then the - lowest RCODE value should be returned. For example, if either DNS or - LLMNR receives a response with RCODE=0, then this should returned to - the caller. - - Since the responder may order the RRs in the response so as to - indicate preference, the sender SHOULD preserve ordering in the - response to the querying application. - -2.3. Responder Behavior - - An LLMNR response MUST be sent to the sender via unicast. - - Upon configuring an IP address, responders typically will synthesize - corresponding A, AAAA and PTR RRs so as to be able to respond to - LLMNR queries for these RRs. An SOA RR is synthesized only when a - responder has another RR in addition to the SOA RR; the SOA RR MUST - NOT be the only RR that a responder has. However, in general whether - RRs are manually or automatically created is an implementation - decision. - - For example, a host configured to have computer name "host1" and to - be a member of the "example.com" domain, and with IPv4 address - 192.0.2.1 and IPv6 address 2001:0DB8::1:2:3:FF:FE:4:5:6 might be - authoritative for the following records: - - host1. IN A 192.0.2.1 - IN AAAA 2001:0DB8::1:2:3:FF:FE:4:5:6 - - host1.example.com. IN A 192.0.2.1 - IN AAAA 2001:0DB8::1:2:3:FF:FE:4:5:6 - - 1.2.0.192.in-addr.arpa. IN PTR host1. - IN PTR host1.example.com. - - 6.0.5.0.4.0.E.F.F.F.3.0.2.0.1.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2. - ip6.arpa IN PTR host1. (line split for formatting reasons) - IN PTR host1.example.com. - - An LLMNR responder might be further manually configured with the name - of a local mail server with an MX RR included in the "host1." and - "host1.example.com." records. - - In responding to queries: - - - - - -Aboba, Thaler & Esibov Standards Track [Page 10] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - -[a] Responders MUST listen on UDP port 5355 on the link-scope multicast - address(es) defined in Section 2, and on UDP and TCP port 5355 on - the unicast address(es) that could be set as the source address(es) - when the responder responds to the LLMNR query. - -[b] Responders MUST direct responses to the port from which the query - was sent. When queries are received via TCP this is an inherent - part of the transport protocol. For queries received by UDP the - responder MUST take note of the source port and use that as the - destination port in the response. Responses MUST always be sent - from the port to which they were directed. - -[c] Responders MUST respond to LLMNR queries for names and addresses - they are authoritative for. This applies to both forward and - reverse lookups, with the exception of queries with the 'C' bit - set, which do not elicit a response. - -[d] Responders MUST NOT respond to LLMNR queries for names they are not - authoritative for. - -[e] Responders MUST NOT respond using data from the LLMNR or DNS - resolver cache. - -[f] If a DNS server is running on a host that supports LLMNR, the DNS - server MUST respond to LLMNR queries only for the RRSets relating - to the host on which the server is running, but MUST NOT respond - for other records for which the server is authoritative. DNS - servers also MUST NOT send LLMNR queries in order to resolve DNS - queries. - -[g] If a responder is authoritative for a name, it MUST respond with - RCODE=0 and an empty answer section, if the type of query does not - match a RR that the responder has. - - As an example, a host configured to respond to LLMNR queries for the - name "foo.example.com." is authoritative for the name - "foo.example.com.". On receiving an LLMNR query for an A RR with the - name "foo.example.com." the host authoritatively responds with A - RR(s) that contain IP address(es) in the RDATA of the resource - record. If the responder has a AAAA RR, but no A RR, and an A RR - query is received, the responder would respond with RCODE=0 and an - empty answer section. - - In conventional DNS terminology a DNS server authoritative for a zone - is authoritative for all the domain names under the zone apex except - for the branches delegated into separate zones. Contrary to - conventional DNS terminology, an LLMNR responder is authoritative - only for the zone apex. - - - -Aboba, Thaler & Esibov Standards Track [Page 11] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - - For example the host "foo.example.com." is not authoritative for the - name "child.foo.example.com." unless the host is configured with - multiple names, including "foo.example.com." and - "child.foo.example.com.". As a result, "foo.example.com." cannot - reply to an LLMNR query for "child.foo.example.com." with RCODE=3 - (authoritative name error). The purpose of limiting the name - authority scope of a responder is to prevent complications that could - be caused by coexistence of two or more hosts with the names - representing child and parent (or grandparent) nodes in the DNS tree, - for example, "foo.example.com." and "child.foo.example.com.". - - Without the restriction on authority an LLMNR query for an A resource - record for the name "child.foo.example.com." would result in two - authoritative responses: RCODE=3 (authoritative name error) received - from "foo.example.com.", and a requested A record - from - "child.foo.example.com.". To prevent this ambiguity, LLMNR enabled - hosts could perform a dynamic update of the parent (or grandparent) - zone with a delegation to a child zone; for example a host - "child.foo.example.com." could send a dynamic update for the NS and - glue A record to "foo.example.com.". However, this approach - significantly complicates implementation of LLMNR and would not be - acceptable for lightweight hosts. - -2.4. Unicast Queries and Responses - - Unicast queries SHOULD be sent when: - - [a] A sender repeats a query after it received a response - with the TC bit set to the previous LLMNR multicast query, or - - [b] The sender queries for a PTR RR of a fully formed IP address - within the "in-addr.arpa" or "ip6.arpa" zones. - - Unicast LLMNR queries MUST be done using TCP and the responses MUST - be sent using the same TCP connection as the query. Senders MUST - support sending TCP queries, and responders MUST support listening - for TCP queries. If the sender of a TCP query receives a response to - that query not using TCP, the response MUST be silently discarded. - - Unicast UDP queries MUST be silently discarded. - - If TCP connection setup cannot be completed in order to send a - unicast TCP query, this is treated as a response that no records of - the specified type and class exist for the specified name (it is - treated the same as a response with RCODE=0 and an empty answer - section). - - - - - -Aboba, Thaler & Esibov Standards Track [Page 12] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - -2.5. "Off link" Detection - - A sender MUST select a source address for LLMNR queries that is - assigned on the interface on which the query is sent. The - destination address of an LLMNR query MUST be a link-scope multicast - address or a unicast address. - - A responder MUST select a source address for responses that is - assigned on the interface on which the query was received. The - destination address of an LLMNR response MUST be a unicast address. - - On receiving an LLMNR query, the responder MUST check whether it was - sent to a LLMNR multicast addresses defined in Section 2. If it was - sent to another multicast address, then the query MUST be silently - discarded. - - Section 2.4 discusses use of TCP for LLMNR queries and responses. In - composing an LLMNR query using TCP, the sender MUST set the Hop Limit - field in the IPv6 header and the TTL field in the IPv4 header of the - response to one (1). The responder SHOULD set the TTL or Hop Limit - settings on the TCP listen socket to one (1) so that SYN-ACK packets - will have TTL (IPv4) or Hop Limit (IPv6) set to one (1). This - prevents an incoming connection from off-link since the sender will - not receive a SYN-ACK from the responder. - - For UDP queries and responses, the Hop Limit field in the IPv6 header - and the TTL field in the IPV4 header MAY be set to any value. - However, it is RECOMMENDED that the value 255 be used for - compatibility with Apple Bonjour [Bonjour]. - - Implementation note: - - In the sockets API for IPv4 [POSIX], the IP_TTL and - IP_MULTICAST_TTL socket options are used to set the TTL of - outgoing unicast and multicast packets. The IP_RECVTTL socket - option is available on some platforms to retrieve the IPv4 TTL of - received packets with recvmsg(). [RFC2292] specifies similar - options for setting and retrieving the IPv6 Hop Limit. - -2.6. Responder Responsibilities - - It is the responsibility of the responder to ensure that RRs returned - in LLMNR responses MUST only include values that are valid on the - local interface, such as IPv4 or IPv6 addresses valid on the local - link or names defended using the mechanism described in Section 4. - IPv4 Link-Local addresses are defined in [RFC3927]. IPv6 Link-Local - addresses are defined in [RFC2373]. In particular: - - - - -Aboba, Thaler & Esibov Standards Track [Page 13] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - - [a] If a link-scope IPv6 address is returned in a AAAA RR, - that address MUST be valid on the local link over which - LLMNR is used. - - [b] If an IPv4 address is returned, it MUST be reachable - through the link over which LLMNR is used. - - [c] If a name is returned (for example in a CNAME, MX - or SRV RR), the name MUST be resolvable on the local - link over which LLMNR is used. - - Where multiple addresses represent valid responses to a query, the - order in which the addresses are returned is as follows: - - [d] If the source address of the query is a link-scope address, - then the responder SHOULD include a link-scope address first - in the response, if available. - - [e] If the source address of the query is a routable address, - then the responder MUST include a routable address first - in the response, if available. - -2.7. Retransmission and Jitter - - An LLMNR sender uses the timeout interval LLMNR_TIMEOUT to determine - when to retransmit an LLMNR query. An LLMNR sender SHOULD either - estimate the LLMNR_TIMEOUT for each interface, or set a reasonably - high initial timeout. Suggested constants are described in Section - 7. - - If an LLMNR query sent over UDP is not resolved within LLMNR_TIMEOUT, - then a sender SHOULD repeat the transmission of the query in order to - assure that it was received by a host capable of responding to it, - while increasing the value of LLMNR_TIMEOUT exponentially. An LLMNR - query SHOULD NOT be sent more than three times. - - Where LLMNR queries are sent using TCP, retransmission is handled by - the transport layer. Queries with the 'C' bit set MUST be sent using - multicast UDP and MUST NOT be retransmitted. - - An LLMNR sender cannot know in advance if a query sent using - multicast will receive no response, one response, or more than one - response. An LLMNR sender MUST wait for LLMNR_TIMEOUT if no response - has been received, or if it is necessary to collect all potential - responses, such as if a uniqueness verification query is being made. - Otherwise an LLMNR sender SHOULD consider a multicast query answered - after the first response is received, if that response has the 'C' - bit clear. - - - -Aboba, Thaler & Esibov Standards Track [Page 14] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - - However, if the first response has the 'C' bit set, then the sender - SHOULD wait for LLMNR_TIMEOUT in order to collect all possible - responses. When multiple valid answers are received, they may first - be concatenated, and then treated in the same manner that multiple - RRs received from the same DNS server would. A unicast query sender - considers the query answered after the first response is received, so - that it only waits for LLMNR_TIMEOUT if no response has been - received. - - Since it is possible for a response with the 'C' bit clear to be - followed by a response with the 'C' bit set, an LLMNR sender SHOULD - be prepared to process additional responses for the purposes of - conflict detection and LLMNR_TIMEOUT estimation, even after it has - considered a query answered. - - In order to avoid synchronization, the transmission of each LLMNR - query and response SHOULD delayed by a time randomly selected from - the interval 0 to JITTER_INTERVAL. This delay MAY be avoided by - responders responding with names which they have previously - determined to be UNIQUE (see Section 4 for details). - -2.8. DNS TTL - - The responder should insert a pre-configured TTL value in the records - returned in an LLMNR response. A default value of 30 seconds is - RECOMMENDED. In highly dynamic environments (such as mobile ad-hoc - networks), the TTL value may need to be reduced. - - Due to the TTL minimalization necessary when caching an RRset, all - TTLs in an RRset MUST be set to the same value. - -2.9. Use of the Authority and Additional Sections - - Unlike the DNS, LLMNR is a peer-to-peer protocol and does not have a - concept of delegation. In LLMNR, the NS resource record type may be - stored and queried for like any other type, but it has no special - delegation semantics as it does in the DNS. Responders MAY have NS - records associated with the names for which they are authoritative, - but they SHOULD NOT include these NS records in the authority - sections of responses. - - Responders SHOULD insert an SOA record into the authority section of - a negative response, to facilitate negative caching as specified in - [RFC2308]. The TTL of this record is set from the minimum of the - MINIMUM field of the SOA record and the TTL of the SOA itself, and - indicates how long a resolver may cache the negative answer. The - owner name of the SOA record (MNAME) MUST be set to the query name. - The RNAME, SERIAL, REFRESH, RETRY and EXPIRE values MUST be ignored - - - -Aboba, Thaler & Esibov Standards Track [Page 15] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - - by senders. Negative responses without SOA records SHOULD NOT be - cached. - - In LLMNR, the additional section is primarily intended for use by - EDNS0, TSIG and SIG(0). As a result, unless the 'C' bit is set, - senders MAY only include pseudo RR-types in the additional section of - a query; unless the 'C' bit is set, responders MUST ignore the - additional section of queries containing other RR types. - - In queries where the 'C' bit is set, the sender SHOULD include the - conflicting RRs in the additional section. Since conflict - notifications are advisory, responders SHOULD log information from - the additional section, but otherwise MUST ignore the additional - section. - - Senders MUST NOT cache RRs from the authority or additional section - of a response as answers, though they may be used for other purposes - such as negative caching. - -3. Usage Model - - Since LLMNR is a secondary name resolution mechanism, its usage is in - part determined by the behavior of DNS implementations. This - document does not specify any changes to DNS resolver behavior, such - as searchlist processing or retransmission/failover policy. However, - robust DNS resolver implementations are more likely to avoid - unnecessary LLMNR queries. - - As noted in [DNSPerf], even when DNS servers are configured, a - significant fraction of DNS queries do not receive a response, or - result in negative responses due to missing inverse mappings or NS - records that point to nonexistent or inappropriate hosts. This has - the potential to result in a large number of unnecessary LLMNR - queries. - - [RFC1536] describes common DNS implementation errors and fixes. If - the proposed fixes are implemented, unnecessary LLMNR queries will be - reduced substantially, and so implementation of [RFC1536] is - recommended. - - For example, [RFC1536] Section 1 describes issues with retransmission - and recommends implementation of a retransmission policy based on - round trip estimates, with exponential backoff. [RFC1536] Section 4 - describes issues with failover, and recommends that resolvers try - another server when they don't receive a response to a query. These - policies are likely to avoid unnecessary LLMNR queries. - - [RFC1536] Section 3 describes zero answer bugs, which if addressed - - - -Aboba, Thaler & Esibov Standards Track [Page 16] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - - will also reduce unnecessary LLMNR queries. - - [RFC1536] Section 6 describes name error bugs and recommended - searchlist processing that will reduce unnecessary RCODE=3 - (authoritative name) errors, thereby also reducing unnecessary LLMNR - queries. - -3.1. LLMNR Configuration - - Since IPv4 and IPv6 utilize distinct configuration mechanisms, it is - possible for a dual stack host to be configured with the address of a - DNS server over IPv4, while remaining unconfigured with a DNS server - suitable for use over IPv6. - - In these situations, a dual stack host will send AAAA queries to the - configured DNS server over IPv4. However, an IPv6-only host - unconfigured with a DNS server suitable for use over IPv6 will be - unable to resolve names using DNS. Automatic IPv6 DNS configuration - mechanisms (such as [RFC3315] and [DNSDisc]) are not yet widely - deployed, and not all DNS servers support IPv6. Therefore lack of - IPv6 DNS configuration may be a common problem in the short term, and - LLMNR may prove useful in enabling link-local name resolution over - IPv6. - - Where a DHCPv4 server is available but not a DHCPv6 server [RFC3315], - IPv6-only hosts may not be configured with a DNS server. Where there - is no DNS server authoritative for the name of a host or the - authoritative DNS server does not support dynamic client update over - IPv6 or DHCPv6-based dynamic update, then an IPv6-only host will not - be able to do DNS dynamic update, and other hosts will not be able to - resolve its name. - - For example, if the configured DNS server responds to a AAAA RR query - sent over IPv4 or IPv6 with an authoritative name error (RCODE=3) or - RCODE=0 and an empty answer section, then a AAAA RR query sent using - LLMNR over IPv6 may be successful in resolving the name of an - IPv6-only host on the local link. - - Similarly, if a DHCPv4 server is available providing DNS server - configuration, and DNS server(s) exist which are authoritative for - the A RRs of local hosts and support either dynamic client update - over IPv4 or DHCPv4-based dynamic update, then the names of local - IPv4 hosts can be resolved over IPv4 without LLMNR. However, if no - DNS server is authoritative for the names of local hosts, or the - authoritative DNS server(s) do not support dynamic update, then LLMNR - enables linklocal name resolution over IPv4. - - Where DHCPv4 or DHCPv6 is implemented, DHCP options can be used to - - - -Aboba, Thaler & Esibov Standards Track [Page 17] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - - configure LLMNR on an interface. The LLMNR Enable Option, described - in [LLMNREnable], can be used to explicitly enable or disable use of - LLMNR on an interface. The LLMNR Enable Option does not determine - whether or in which order DNS itself is used for name resolution. - The order in which various name resolution mechanisms should be used - can be specified using the Name Service Search Option (NSSO) for DHCP - [RFC2937], using the LLMNR Enable Option code carried in the NSSO - data. - - It is possible that DNS configuration mechanisms will go in and out - of service. In these circumstances, it is possible for hosts within - an administrative domain to be inconsistent in their DNS - configuration. - - For example, where DHCP is used for configuring DNS servers, one or - more DHCP servers can fail. As a result, hosts configured prior to - the outage will be configured with a DNS server, while hosts - configured after the outage will not. Alternatively, it is possible - for the DNS configuration mechanism to continue functioning while - configured DNS servers fail. - - An outage in the DNS configuration mechanism may result in hosts - continuing to use LLMNR even once the outage is repaired. Since - LLMNR only enables linklocal name resolution, this represents a - degradation in capabilities. As a result, hosts without a configured - DNS server may wish to periodically attempt to obtain DNS - configuration if permitted by the configuration mechanism in use. In - the absence of other guidance, a default retry interval of one (1) - minute is RECOMMENDED. - -4. Conflict Resolution - - By default, a responder SHOULD be configured to behave as though its - name is UNIQUE on each interface on which LLMNR is enabled. However, - it is also possible to configure multiple responders to be - authoritative for the same name. For example, multiple responders - MAY respond to a query for an A or AAAA type record for a cluster - name (assigned to multiple hosts in the cluster). - - To detect duplicate use of a name, an administrator can use a name - resolution utility which employs LLMNR and lists both responses and - responders. This would allow an administrator to diagnose behavior - and potentially to intervene and reconfigure LLMNR responders who - should not be configured to respond to the same name. - - - - - - - -Aboba, Thaler & Esibov Standards Track [Page 18] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - -4.1. Uniqueness Verification - - Prior to sending an LLMNR response with the 'T' bit clear, a - responder configured with a UNIQUE name MUST verify that there is no - other host within the scope of LLMNR query propagation that is - authoritative for the same name on that interface. - - Once a responder has verified that its name is UNIQUE, if it receives - an LLMNR query for that name, with the 'C' bit clear, it MUST - respond, with the 'T' bit clear. Prior to verifying that its name is - UNIQUE, a responder MUST set the 'T' bit in responses. - - Uniqueness verification is carried out when the host: - - - starts up or is rebooted - - wakes from sleep (if the network interface was inactive - during sleep) - - is configured to respond to LLMNR queries on an interface - enabled for transmission and reception of IP traffic - - is configured to respond to LLMNR queries using additional - UNIQUE resource records - - verifies the acquisition of a new IP address and configuration - on an interface - - To verify uniqueness, a responder MUST send an LLMNR query with the - 'C' bit clear, over all protocols on which it responds to LLMNR - queries (IPv4 and/or IPv6). It is RECOMMENDED that responders verify - uniqueness of a name by sending a query for the name with type='ANY'. - - If no response is received, the sender retransmits the query, as - specified in Section 2.7. If a response is received, the sender MUST - check if the source address matches the address of any of its - interfaces; if so, then the response is not considered a conflict, - since it originates from the sender. To avoid triggering conflict - detection, a responder that detects that it is connected to the same - link on multiple interfaces SHOULD set the 'C' bit in responses. - - If a response is received with the 'T' bit clear, the responder MUST - NOT use the name in response to LLMNR queries received over any - protocol (IPv4 or IPv6). If a response is received with the 'T' bit - set, the responder MUST check if the source IP address in the - response, interpreted as an unsigned integer, is less than the source - IP address in the query. If so, the responder MUST NOT use the name - in response to LLMNR queries received over any protocol (IPv4 or - IPv6). For the purpose of uniqueness verification, the contents of - the answer section in a response is irrelevant. - - Periodically carrying out uniqueness verification in an attempt to - - - -Aboba, Thaler & Esibov Standards Track [Page 19] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - - detect name conflicts is not necessary, wastes network bandwidth, and - may actually be detrimental. For example, if network links are - joined only briefly, and are separated again before any new - communication is initiated, temporary conflicts are benign and no - forced reconfiguration is required. LLMNR responders SHOULD NOT - periodically attempt uniqueness verification. - -4.2. Conflict Detection and Defense - - Hosts on disjoint network links may configure the same name for use - with LLMNR. If these separate network links are later joined or - bridged together, then there may be multiple hosts which are now on - the same link, trying to use the same name. - - In order to enable ongoing detection of name conflicts, when an LLMNR - sender receives multiple LLMNR responses to a query, it MUST check if - the 'C' bit is clear in any of the responses. If so, the sender - SHOULD send another query for the same name, type and class, this - time with the 'C' bit set, with the potentially conflicting resource - records included in the additional section. - - Queries with the 'C' bit set are considered advisory and responders - MUST verify the existence of a conflict before acting on it. A - responder receiving a query with the 'C' bit set MUST NOT respond. - - If the query is for a UNIQUE name, then the responder MUST send its - own query for the same name, type and class, with the 'C' bit clear. - If a response is received, the sender MUST check if the source - address matches the address of any of its interfaces; if so, then the - response is not considered a conflict, since it originates from the - sender. To avoid triggering conflict detection, a responder that - detects that it is connected to the same link on multiple interfaces - SHOULD set the 'C' bit in responses. - - An LLMNR responder MUST NOT ignore conflicts once detected and SHOULD - log them. Upon detecting a conflict, an LLMNR responder MUST - immediately stop using the conflicting name in response to LLMNR - queries received over any supported protocol, if the source IP - address in the response, interpreted as an unsigned integer, is less - than the source IP address in the uniqueness verification query. - - After stopping the use of a name, the responder MAY elect to - configure a new name. However, since name reconfiguration may be - disruptive, this is not required, and a responder may have been - configured to respond to multiple names so that alternative names may - already be available. A host that has stopped the use of a name may - attempt uniqueness verification again after the expiration of the TTL - of the conflicting response. - - - -Aboba, Thaler & Esibov Standards Track [Page 20] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - -4.3. Considerations for Multiple Interfaces - - A multi-homed host may elect to configure LLMNR on only one of its - active interfaces. In many situations this will be adequate. - However, should a host need to configure LLMNR on more than one of - its active interfaces, there are some additional precautions it MUST - take. Implementers who are not planning to support LLMNR on multiple - interfaces simultaneously may skip this section. - - Where a host is configured to issue LLMNR queries on more than one - interface, each interface maintains its own independent LLMNR - resolver cache, containing the responses to LLMNR queries. - - A multi-homed host checks the uniqueness of UNIQUE records as - described in Section 4. The situation is illustrated in figure 1. - - ---------- ---------- - | | | | - [A] [myhost] [myhost] - - Figure 1. Link-scope name conflict - - In this situation, the multi-homed myhost will probe for, and defend, - its host name on both interfaces. A conflict will be detected on one - interface, but not the other. The multi-homed myhost will not be - able to respond with a host RR for "myhost" on the interface on the - right (see Figure 1). The multi-homed host may, however, be - configured to use the "myhost" name on the interface on the left. - - Since names are only unique per-link, hosts on different links could - be using the same name. If an LLMNR client sends requests over - multiple interfaces, and receives replies from more than one, the - result returned to the client is defined by the implementation. The - situation is illustrated in figure 2. - - ---------- ---------- - | | | | - [A] [myhost] [A] - - - Figure 2. Off-segment name conflict - - If host myhost is configured to use LLMNR on both interfaces, it will - send LLMNR queries on both interfaces. When host myhost sends a - query for the host RR for name "A" it will receive a response from - hosts on both interfaces. - - Host myhost cannot distinguish between the situation shown in Figure - - - -Aboba, Thaler & Esibov Standards Track [Page 21] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - - 2, and that shown in Figure 3 where no conflict exists. - - [A] - | | - ----- ----- - | | - [myhost] - - Figure 3. Multiple paths to same host - - This illustrates that the proposed name conflict resolution mechanism - does not support detection or resolution of conflicts between hosts - on different links. This problem can also occur with DNS when a - multi-homed host is connected to two different networks with - separated name spaces. It is not the intent of this document to - address the issue of uniqueness of names within DNS. - -4.4. API Issues - - [RFC2553] provides an API which can partially solve the name - ambiguity problem for applications written to use this API, since the - sockaddr_in6 structure exposes the scope within which each scoped - address exists, and this structure can be used for both IPv4 (using - v4-mapped IPv6 addresses) and IPv6 addresses. - - Following the example in Figure 2, an application on 'myhost' issues - the request getaddrinfo("A", ...) with ai_family=AF_INET6 and - ai_flags=AI_ALL|AI_V4MAPPED. LLMNR requests will be sent from both - interfaces and the resolver library will return a list containing - multiple addrinfo structures, each with an associated sockaddr_in6 - structure. This list will thus contain the IPv4 and IPv6 addresses - of both hosts responding to the name 'A'. Link-local addresses will - have a sin6_scope_id value that disambiguates which interface is used - to reach the address. Of course, to the application, Figures 2 and 3 - are still indistinguishable, but this API allows the application to - communicate successfully with any address in the list. - -5. Security Considerations - - LLMNR is a peer-to-peer name resolution protocol designed for use on - the local link. While LLMNR limits the vulnerability of responders - to off-link senders, it is possible for an off-link responder to - reach a sender. - - In scenarios such as public "hotspots" attackers can be present on - the same link. These threats are most serious in wireless networks - such as 802.11, since attackers on a wired network will require - physical access to the network, while wireless attackers may mount - - - -Aboba, Thaler & Esibov Standards Track [Page 22] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - - attacks from a distance. Link-layer security such as [IEEE-802.11i] - can be of assistance against these threats if it is available. - - This section details security measures available to mitigate threats - from on and off-link attackers. - -5.1. Denial of Service - - Attackers may take advantage of LLMNR conflict detection by - allocating the same name, denying service to other LLMNR responders - and possibly allowing an attacker to receive packets destined for - other hosts. By logging conflicts, LLMNR responders can provide - forensic evidence of these attacks. - - An attacker may spoof LLMNR queries from a victim's address in order - to mount a denial of service attack. Responders setting the IPv6 Hop - Limit or IPv4 TTL field to a value larger than one in an LLMNR UDP - response may be able to reach the victim across the Internet. - - While LLMNR responders only respond to queries for which they are - authoritative and LLMNR does not provide wildcard query support, an - LLMNR response may be larger than the query, and an attacker can - generate multiple responses to a query for a name used by multiple - responders. A sender may protect itself against unsolicited - responses by silently discarding them as rapidly as possible. - -5.2. Spoofing - - LLMNR is designed to prevent reception of queries sent by an off-link - attacker. LLMNR requires that responders receiving UDP queries check - that they are sent to a link-scope multicast address. However, it is - possible that some routers may not properly implement link-scope - multicast, or that link-scope multicast addresses may leak into the - multicast routing system. To prevent successful setup of TCP - connections by an off-link sender, responders receiving a TCP SYN - reply with a TCP SYN-ACK with TTL set to one (1). - - While it is difficult for an off-link attacker to send an LLMNR query - to a responder, it is possible for an off-link attacker to spoof a - response to a query (such as an A or AAAA query for a popular - Internet host), and by using a TTL or Hop Limit field larger than one - (1), for the forged response to reach the LLMNR sender. Since the - forged response will only be accepted if it contains a matching ID - field, choosing a pseudo-random ID field within queries provides some - protection against off-link responders. - - Since LLMNR queries can be sent when DNS server(s) do not respond, an - attacker can execute a denial of service attack on the DNS server(s) - - - -Aboba, Thaler & Esibov Standards Track [Page 23] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - - and then poison the LLMNR cache by responding to an LLMNR query with - incorrect information. As noted in "Threat Analysis of the Domain - Name System (DNS)" [RFC3833] these threats also exist with DNS, since - DNS response spoofing tools are available that can allow an attacker - to respond to a query more quickly than a distant DNS server. - However, while switched networks or link layer security may make it - difficult for an on-link attacker to snoop unicast DNS queries, - multicast LLMNR queries are propagated to all hosts on the link, - making it possible for an on-link attacker to spoof LLMNR responses - without having to guess the value of the ID field in the query. - - Since LLMNR queries are sent and responded to on the local-link, an - attacker will need to respond more quickly to provide its own - response prior to arrival of the response from a legitimate - responder. If an LLMNR query is sent for an off-link host, spoofing - a response in a timely way is not difficult, since a legitimate - response will never be received. - - Limiting the situations in which LLMNR queries are sent, as described - in Section 2, is the best protection against these attacks. If LLMNR - is given higher priority than DNS among the enabled name resolution - mechanisms, a denial of service attack on the DNS server would not be - necessary in order to poison the LLMNR cache, since LLMNR queries - would be sent even when the DNS server is available. In addition, - the LLMNR cache, once poisoned, would take precedence over the DNS - cache, eliminating the benefits of cache separation. As a result, - LLMNR is only used as a name resolution mechanism of last resort. - -5.3. Authentication - - LLMNR is a peer-to-peer name resolution protocol, and as a result, - it is often deployed in situations where no trust model can be - assumed. This makes it difficult to apply existing DNS security - mechanisms to LLMNR. - - LLMNR does not support "delegated trust" (CD or AD bits). As a - result, unless LLMNR senders are DNSSEC aware, it is not feasible to - use DNSSEC [RFC4033] with LLMNR. - - If authentication is desired, and a pre-arranged security - configuration is possible, then the following security mechanisms may - be used: - -[a] LLMNR implementations MAY support TSIG [RFC2845] and/or SIG(0) - [RFC2931] security mechanisms. "DNS Name Service based on Secure - Multicast DNS for IPv6 Mobile Ad Hoc Networks" [LLMNRSec] describes - the use of TSIG to secure LLMNR responses, based on group keys. - - - - -Aboba, Thaler & Esibov Standards Track [Page 24] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - -[b] IPsec ESP with a null-transform MAY be used to authenticate unicast - LLMNR queries and responses or LLMNR responses to multicast - queries. In a small network without a certificate authority, this - can be most easily accomplished through configuration of a group - pre-shared key for trusted hosts. - - Where these mechanisms cannot be supported, responses to LLMNR - queries may be unauthenticated. - -5.4. Cache and Port Separation - - In order to prevent responses to LLMNR queries from polluting the DNS - cache, LLMNR implementations MUST use a distinct, isolated cache for - LLMNR on each interface. The use of separate caches is most - effective when LLMNR is used as a name resolution mechanism of last - resort, since this minimizes the opportunities for poisoning the - LLMNR cache, and decreases reliance on it. - - LLMNR operates on a separate port from DNS, reducing the likelihood - that a DNS server will unintentionally respond to an LLMNR query. - -6. IANA Considerations - - This specification creates one new name space: the reserved bits in - the LLMNR header. These are allocated by IETF Consensus, in - accordance with BCP 26 [RFC2434]. - - LLMNR requires allocation of port 5355 for both TCP and UDP. - - LLMNR requires allocation of link-scope multicast IPv4 address - 224.0.0.252, as well as link-scope multicast IPv6 address - FF02:0:0:0:0:0:1:3. - -7. Constants - - The following timing constants are used in this protocol; they are - not intended to be user configurable. - - JITTER_INTERVAL 100 ms - LLMNR_TIMEOUT 1 second (if set statically on all interfaces) - 100 ms (IEEE 802 media, including IEEE 802.11) - -8. References - -8.1. Normative References - -[RFC1035] Mockapetris, P., "Domain Names - Implementation and - Specification", RFC 1035, November 1987. - - - -Aboba, Thaler & Esibov Standards Track [Page 25] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - -[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - -[RFC2181] Elz, R. and R. Bush, "Clarifications to the DNS - Specification", RFC 2181, July 1997. - -[RFC2308] Andrews, M., "Negative Caching of DNS Queries (DNS NCACHE)", - RFC 2308, March 1998. - -[RFC2373] Hinden, R. and S. Deering, "IP Version 6 Addressing - Architecture", RFC 2373, July 1998. - -[RFC2434] Alvestrand, H. and T. Narten, "Guidelines for Writing an IANA - Considerations Section in RFCs", BCP 26, RFC 2434, October - 1998. - -[RFC2671] Vixie, P., "Extension Mechanisms for DNS (EDNS0)", RFC 2671, - August 1999. - -[RFC2845] Vixie, P., Gudmundsson, O., Eastlake, D. and B. Wellington, - "Secret Key Transaction Authentication for DNS (TSIG)", RFC - 2845, May 2000. - -[RFC2931] Eastlake, D., "DNS Request and Transaction Signatures - (SIG(0)s)", RFC 2931, September 2000. - -8.2. Informative References - -[Bonjour] Cheshire, S. and M. Krochmal, "Multicast DNS", Internet draft - (work in progress), draft-cheshire-dnsext-multicastdns-05.txt, - June 2005. - -[DNSPerf] Jung, J., et al., "DNS Performance and the Effectiveness of - Caching", IEEE/ACM Transactions on Networking, Volume 10, - Number 5, pp. 589, October 2002. - -[DNSDisc] Durand, A., Hagino, I. and D. Thaler, "Well known site local - unicast addresses to communicate with recursive DNS servers", - Internet draft (work in progress), draft-ietf-ipv6-dns- - discovery-07.txt, October 2002. - -[IEEE-802.11i] - Institute of Electrical and Electronics Engineers, "Supplement - to Standard for Telecommunications and Information Exchange - Between Systems - LAN/MAN Specific Requirements - Part 11: - Wireless LAN Medium Access Control (MAC) and Physical Layer - (PHY) Specifications: Specification for Enhanced Security", - IEEE 802.11i, July 2004. - - - -Aboba, Thaler & Esibov Standards Track [Page 26] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - -[LLMNREnable] - Guttman, E., "DHCP LLMNR Enable Option", Internet draft (work - in progress), draft-guttman-mdns-enable-02.txt, April 2002. - -[LLMNRSec] - Jeong, J., Park, J. and H. Kim, "DNS Name Service based on - Secure Multicast DNS for IPv6 Mobile Ad Hoc Networks", ICACT - 2004, Phoenix Park, Korea, February 9-11, 2004. - -[POSIX] IEEE Std. 1003.1-2001 Standard for Information Technology -- - Portable Operating System Interface (POSIX). Open Group - Technical Standard: Base Specifications, Issue 6, December - 2001. ISO/IEC 9945:2002. http://www.opengroup.org/austin - -[RFC1536] Kumar, A., et. al., "DNS Implementation Errors and Suggested - Fixes", RFC 1536, October 1993. - -[RFC1750] Eastlake, D., Crocker, S. and J. Schiller, "Randomness - Recommendations for Security", RFC 1750, December 1994. - -[RFC2131] Droms, R., "Dynamic Host Configuration Protocol", RFC 2131, - March 1997. - -[RFC2292] Stevens, W. and M. Thomas, "Advanced Sockets API for IPv6", - RFC 2292, February 1998. - -[RFC2365] Meyer, D., "Administratively Scoped IP Multicast", BCP 23, RFC - 2365, July 1998. - -[RFC2553] Gilligan, R., Thomson, S., Bound, J. and W. Stevens, "Basic - Socket Interface Extensions for IPv6", RFC 2553, March 1999. - -[RFC2937] Smith, C., "The Name Service Search Option for DHCP", RFC - 2937, September 2000. - -[RFC3315] Droms, R., et al., "Dynamic Host Configuration Protocol for - IPv6 (DHCPv6)", RFC 3315, July 2003. - -[RFC3833] Atkins, D. and R. Austein, "Threat Analysis of the Domain Name - System (DNS)", RFC 3833, August 2004. - -[RFC3927] Cheshire, S., Aboba, B. and E. Guttman, "Dynamic Configuration - of Link-Local IPv4 Addresses", RFC 3927, October 2004. - -[RFC4033] Arends, R., Austein, R., Larson, M., Massey, D. and S. Rose, - "DNS Security Introduction and Requirement", RFC 4033, March - 2005. - - - - -Aboba, Thaler & Esibov Standards Track [Page 27] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - -Acknowledgments - - This work builds upon original work done on multicast DNS by Bill - Manning and Bill Woodcock. Bill Manning's work was funded under - DARPA grant #F30602-99-1-0523. The authors gratefully acknowledge - their contribution to the current specification. Constructive input - has also been received from Mark Andrews, Rob Austein, Randy Bush, - Stuart Cheshire, Ralph Droms, Robert Elz, James Gilroy, Olafur - Gudmundsson, Andreas Gustafsson, Erik Guttman, Myron Hattig, - Christian Huitema, Olaf Kolkman, Mika Liljeberg, Keith Moore, - Tomohide Nagashima, Thomas Narten, Erik Nordmark, Markku Savela, Mike - St. Johns, Sander Van-Valkenburg, and Brian Zill. - -Authors' Addresses - - Bernard Aboba - Microsoft Corporation - One Microsoft Way - Redmond, WA 98052 - - Phone: +1 425 706 6605 - EMail: bernarda@microsoft.com - - Dave Thaler - Microsoft Corporation - One Microsoft Way - Redmond, WA 98052 - - Phone: +1 425 703 8835 - EMail: dthaler@microsoft.com - - Levon Esibov - Microsoft Corporation - One Microsoft Way - Redmond, WA 98052 - - EMail: levone@microsoft.com - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - - -Aboba, Thaler & Esibov Standards Track [Page 28] - - - - - -INTERNET-DRAFT LLMNR 29 August 2005 - - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at ietf- - ipr@ietf.org. - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -Copyright Statement - - Copyright (C) The Internet Society (2005). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - -Open Issues - - Open issues with this specification are tracked on the following web - site: - - http://www.drizzle.com/~aboba/DNSEXT/llmnrissues.html - - - - - - - - - - - -Aboba, Thaler & Esibov Standards Track [Page 29] - - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-nsec3-04.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-nsec3-04.txt deleted file mode 100644 index 8c6c5b1..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-nsec3-04.txt +++ /dev/null @@ -1,2352 +0,0 @@ - - - -Network Working Group B. Laurie -Internet-Draft G. Sisson -Expires: August 5, 2006 R. Arends - Nominet - February 2006 - - - DNSSEC Hash Authenticated Denial of Existence - draft-ietf-dnsext-nsec3-04 - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on August 5, 2006. - -Copyright Notice - - Copyright (C) The Internet Society (2006). - -Abstract - - The DNS Security Extensions introduces the NSEC resource record for - authenticated denial of existence. This document introduces a new - resource record as an alternative to NSEC that provides measures - against zone enumeration and allows for gradual expansion of - delegation-centric zones. - - - - - -Laurie, et al. Expires August 5, 2006 [Page 1] - -Internet-Draft nsec3 February 2006 - - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4 - 1.1. Rationale . . . . . . . . . . . . . . . . . . . . . . . . 4 - 1.2. Reserved Words . . . . . . . . . . . . . . . . . . . . . . 4 - 1.3. Terminology . . . . . . . . . . . . . . . . . . . . . . . 4 - 2. NSEC versus NSEC3 . . . . . . . . . . . . . . . . . . . . . . 5 - 3. The NSEC3 Resource Record . . . . . . . . . . . . . . . . . . 5 - 3.1. NSEC3 RDATA Wire Format . . . . . . . . . . . . . . . . . 6 - 3.1.1. The Hash Function Field . . . . . . . . . . . . . . . 6 - 3.1.2. The Opt-In Flag Field . . . . . . . . . . . . . . . . 7 - 3.1.3. The Iterations Field . . . . . . . . . . . . . . . . . 8 - 3.1.4. The Salt Length Field . . . . . . . . . . . . . . . . 8 - 3.1.5. The Salt Field . . . . . . . . . . . . . . . . . . . . 8 - 3.1.6. The Next Hashed Ownername Field . . . . . . . . . . . 9 - 3.1.7. The Type Bit Maps Field . . . . . . . . . . . . . . . 9 - 3.2. The NSEC3 RR Presentation Format . . . . . . . . . . . . . 10 - 4. Creating Additional NSEC3 RRs for Empty Non-Terminals . . . . 11 - 5. Calculation of the Hash . . . . . . . . . . . . . . . . . . . 11 - 6. Including NSEC3 RRs in a Zone . . . . . . . . . . . . . . . . 11 - 7. Responding to NSEC3 Queries . . . . . . . . . . . . . . . . . 12 - 8. Special Considerations . . . . . . . . . . . . . . . . . . . . 13 - 8.1. Proving Nonexistence . . . . . . . . . . . . . . . . . . . 13 - 8.2. Salting . . . . . . . . . . . . . . . . . . . . . . . . . 14 - 8.3. Iterations . . . . . . . . . . . . . . . . . . . . . . . . 15 - 8.4. Hash Collision . . . . . . . . . . . . . . . . . . . . . . 16 - 8.4.1. Avoiding Hash Collisions during generation . . . . . . 16 - 8.4.2. Second Preimage Requirement Analysis . . . . . . . . . 16 - 8.4.3. Possible Hash Value Truncation Method . . . . . . . . 17 - 8.4.4. Server Response to a Run-time Collision . . . . . . . 17 - 8.4.5. Parameters that Cover the Zone . . . . . . . . . . . . 18 - 9. Performance Considerations . . . . . . . . . . . . . . . . . . 18 - 10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 18 - 11. Security Considerations . . . . . . . . . . . . . . . . . . . 18 - 12. References . . . . . . . . . . . . . . . . . . . . . . . . . . 21 - 12.1. Normative References . . . . . . . . . . . . . . . . . . . 21 - 12.2. Informative References . . . . . . . . . . . . . . . . . . 22 - Editorial Comments . . . . . . . . . . . . . . . . . . . . . . . . - Appendix A. Example Zone . . . . . . . . . . . . . . . . . . . . 22 - Appendix B. Example Responses . . . . . . . . . . . . . . . . . . 27 - B.1. answer . . . . . . . . . . . . . . . . . . . . . . . . . . 27 - B.1.1. Authenticating the Example DNSKEY RRset . . . . . . . 29 - B.2. Name Error . . . . . . . . . . . . . . . . . . . . . . . . 30 - B.3. No Data Error . . . . . . . . . . . . . . . . . . . . . . 32 - B.3.1. No Data Error, Empty Non-Terminal . . . . . . . . . . 33 - B.4. Referral to Signed Zone . . . . . . . . . . . . . . . . . 34 - B.5. Referral to Unsigned Zone using the Opt-In Flag . . . . . 35 - B.6. Wildcard Expansion . . . . . . . . . . . . . . . . . . . . 36 - - - -Laurie, et al. Expires August 5, 2006 [Page 2] - -Internet-Draft nsec3 February 2006 - - - B.7. Wildcard No Data Error . . . . . . . . . . . . . . . . . . 38 - B.8. DS Child Zone No Data Error . . . . . . . . . . . . . . . 39 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 41 - Intellectual Property and Copyright Statements . . . . . . . . . . 42 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Laurie, et al. Expires August 5, 2006 [Page 3] - -Internet-Draft nsec3 February 2006 - - -1. Introduction - -1.1. Rationale - - The DNS Security Extensions included the NSEC RR to provide - authenticated denial of existence. Though the NSEC RR meets the - requirements for authenticated denial of existence, it introduced a - side-effect in that the contents of a zone can be enumerated. This - property introduces undesired policy issues. - - An enumerated zone can be used either directly as a source of - probable e-mail addresses for spam, or indirectly as a key for - multiple WHOIS queries to reveal registrant data which many - registries may be under strict legal obligations to protect. Many - registries therefore prohibit copying of their zone file; however the - use of NSEC RRs renders these policies unenforceable. - - A second problem was the requirement that the existence of all record - types in a zone - including unsigned delegation points - must be - accounted for, despite the fact that unsigned delegation point - records are not signed. This requirement has a side-effect that the - overhead of signed zones is not related to the increase in security - of subzones. This requirement does not allow the zones' size to grow - in relation to the growth of signed subzones. - - In the past, solutions (draft-ietf-dnsext-dnssec-opt-in) have been - proposed as a measure against these side effects but at the time were - regarded as secondary over the need to have a stable DNSSEC - specification. With (draft-vixie-dnssec-ter) [14] a graceful - transition path to future enhancements is introduced, while current - DNSSEC deployment can continue. This document presents the NSEC3 - Resource Record which mitigates these issues with the NSEC RR. - - The reader is assumed to be familiar with the basic DNS and DNSSEC - concepts described in RFC 1034 [1], RFC 1035 [2], RFC 4033 [3], RFC - 4034 [4], RFC 4035 [5] and subsequent RFCs that update them: RFC 2136 - [6], RFC2181 [7] and RFC2308 [8]. - -1.2. Reserved Words - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in RFC 2119 [9]. - -1.3. Terminology - - The practice of discovering the contents of a zone, i.e. enumerating - the domains within a zone, is known as "zone enumeration". Zone - - - -Laurie, et al. Expires August 5, 2006 [Page 4] - -Internet-Draft nsec3 February 2006 - - - enumeration was not practical prior to the introduction of DNSSEC. - - In this document the term "original ownername" refers to a standard - ownername. Because this proposal uses the result of a hash function - over the original (unmodified) ownername, this result is referred to - as "hashed ownername". - - "Hash order" means the order in which hashed ownernames are arranged - according to their numerical value, treating the leftmost (lowest - numbered) octet as the most significant octet. Note that this is the - same as the canonical ordering specified in RFC 4034 [4]. - - An "empty non-terminal" is a domain name that owns no resource - records but has subdomains that do. - - The "closest encloser" of a (nonexistent) domain name is the longest - domain name, including empty non-terminals, that matches the - rightmost part of the nonexistent domain name. - - "Base32 encoding" is "Base 32 Encoding with Extended Hex Alphabet" as - specified in RFC 3548bis [15]. - - -2. NSEC versus NSEC3 - - This document does NOT obsolete the NSEC record, but gives an - alternative for authenticated denial of existence. NSEC and NSEC3 - RRs can not co-exist in a zone. See draft-vixie-dnssec-ter [14] for - a signaling mechanism to allow for graceful transition towards NSEC3. - - -3. The NSEC3 Resource Record - - The NSEC3 RR provides Authenticated Denial of Existence for DNS - Resource Record Sets. - - The NSEC3 Resource Record (RR) lists RR types present at the NSEC3 - RR's original ownername. It includes the next hashed ownername in - the hash order of the zone. The complete set of NSEC3 RRs in a zone - indicates which RRsets exist for the original ownername of the RRset - and form a chain of hashed ownernames in the zone. This information - is used to provide authenticated denial of existence for DNS data, as - described in RFC 4035 [5]. To provide protection against zone - enumeration, the ownernames used in the NSEC3 RR are cryptographic - hashes of the original ownername prepended to the name of the zone. - The NSEC3 RR indicates which hash function is used to construct the - hash, which salt is used, and how many iterations of the hash - function are performed over the original ownername. The hashing - - - -Laurie, et al. Expires August 5, 2006 [Page 5] - -Internet-Draft nsec3 February 2006 - - - technique is described fully in Section 5. - - Hashed ownernames of unsigned delegations may be excluded from the - chain. An NSEC3 record which span covers the hash of an unsigned - delegation's ownername is referred to as an Opt-In NSEC3 record and - is indicated by the presence of a flag. - - The ownername for the NSEC3 RR is the base32 encoding of the hashed - ownername prepended to the name of the zone.. - - The type value for the NSEC3 RR is XX. - - The NSEC3 RR RDATA format is class independent and is described - below. - - The class MUST be the same as the original ownername's class. - - The NSEC3 RR SHOULD have the same TTL value as the SOA minimum TTL - field. This is in the spirit of negative caching [8]. - -3.1. NSEC3 RDATA Wire Format - - The RDATA of the NSEC3 RR is as shown below: - - 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Hash Function |O| Iterations | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Salt Length | Salt / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - / Next Hashed Ownername / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - / Type Bit Maps / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - "O" is the Opt-In Flag field. - -3.1.1. The Hash Function Field - - The Hash Function field identifies the cryptographic hash function - used to construct the hash-value. - - The values are as defined for the DS record (see RFC 3658 [10]). - - On reception, a resolver MUST ignore an NSEC3 RR with an unknown hash - function value. - - - - -Laurie, et al. Expires August 5, 2006 [Page 6] - -Internet-Draft nsec3 February 2006 - - -3.1.2. The Opt-In Flag Field - - The Opt-In Flag field indicates whether this NSEC3 RR covers unsigned - delegations. - - In DNSSEC, NS RRsets at delegation points are not signed, and may be - accompanied by a DS record. The security status of the subzone is - determined by the presence or absence of the DS RRset, - cryptographically proven by the NSEC record or the signed DS RRset. - The presence of the Opt-In flag expands this definition by allowing - insecure delegations to exist within an otherwise signed zone without - the corresponding NSEC3 record at the delegation's (hashed) owner - name. These delegations are proven insecure by using a covering - NSEC3 record. - - Resolvers must be able to distinguish between NSEC3 records and - Opt-In NSEC3 records. This is accomplished by setting the Opt-In - flag of the NSEC3 records that cover (or potentially cover) insecure - delegation nodes. - - An Opt-In NSEC3 record does not assert the existence or non-existence - of the insecure delegations that it covers. This allows for the - addition or removal of these delegations without recalculating or - resigning records in the NSEC3 chain. However, Opt-In NSEC3 records - do assert the (non)existence of other, authoritative RRsets. - - An Opt-In NSEC3 record MAY have the same original owner name as an - insecure delegation. In this case, the delegation is proven insecure - by the lack of a DS bit in type map and the signed NSEC3 record does - assert the existence of the delegation. - - Zones using Opt-In MAY contain a mixture of Opt-In NSEC3 records and - non-Opt-In NSEC3 records. If an NSEC3 record is not Opt-In, there - MUST NOT be any hashed ownernames of insecure delegations (nor any - other records) between it and the RRsets indicated by the 'Next - Hashed Ownername' in the NSEC3 RDATA. If it is Opt-In, there MUST - only be hashed ownernames of insecure delegations between it and the - next node indicated by the 'Next Hashed Ownername' in the NSEC3 - RDATA. - - In summary, - o An Opt-In NSEC3 type is identified by an Opt-In Flag field value - of 1. - o A non Opt-In NSEC3 type is identified by an Opt-In Flag field - value of 0. - and, - - - - - -Laurie, et al. Expires August 5, 2006 [Page 7] - -Internet-Draft nsec3 February 2006 - - - o An Opt-In NSEC3 record does not assert the non-existence of a hash - ownername between its ownername and next hashed ownername, - although it does assert that any hashed name in this span MUST be - of an insecure delegation. - o An Opt-In NSEC3 record does assert the (non)existence of RRsets - with the same hashed owner name. - -3.1.3. The Iterations Field - - The Iterations field defines the number of times the hash has been - iterated. More iterations results in greater resiliency of the hash - value against dictionary attacks, but at a higher cost for both the - server and resolver. See Section 5 for details of this field's use. - - Iterations make an attack more costly by making the hash computation - more computationally intensive, e.g. by iterating the hash function a - number of times. - - When generating a few hashes this performance loss will not be a - problem, as a validator can handle a delay of a few milliseconds. - But when doing a dictionary attack it will also multiply the attack - workload by a factor, which is a problem for the attacker. - -3.1.4. The Salt Length Field - - The salt length field defines the length of the salt in octets. - -3.1.5. The Salt Field - - The Salt field is not present when the Salt Length Field has a value - of 0. - - The Salt field is appended to the original ownername before hashing - in order to defend against precalculated dictionary attacks. See - Section 5 for details on how the salt is used. - - Salt is used to make dictionary attacks using precomputation more - costly. A dictionary can only be computed after the attacker has the - salt, hence a new salt means that the dictionary has to be - regenerated with the new salt. - - There MUST be a complete set of NSEC3 records covering the entire - zone that use the same salt value. The requirement exists so that, - given any qname within a zone, at least one covering NSEC3 RRset may - be found. While it may be theoretically possible to produce a set of - NSEC3s that use different salts that cover the entire zone, it is - computationally infeasible to generate such a set. See Section 8.2 - for further discussion. - - - -Laurie, et al. Expires August 5, 2006 [Page 8] - -Internet-Draft nsec3 February 2006 - - - The salt value SHOULD be changed from time to time - this is to - prevent the use of a precomputed dictionary to reduce the cost of - enumeration. - -3.1.6. The Next Hashed Ownername Field - - The Next Hashed Ownername field contains the next hashed ownername in - hash order. That is, given the set of all hashed owernames, the Next - Hashed Ownername contains the hash value that immediately follows the - owner hash value for the given NSEC3 record. The value of the Next - Hashed Ownername Field in the last NSEC3 record in the zone is the - same as the ownername of the first NSEC3 RR in the zone in hash - order. - - Hashed ownernames of glue RRsets MUST NOT be listed in the Next - Hashed Ownername unless at least one authoritative RRset exists at - the same ownername. Hashed ownernames of delegation NS RRsets MUST - be listed if the Opt-In bit is clear. - - Note that the Next Hashed Ownername field is not encoded, unlike the - NSEC3 RR's ownername. It is the unmodified binary hash value. It - does not include the name of the containing zone. - - The length of this field is the length of the hash value produced by - the hash function selected by the Hash Function field. - -3.1.7. The Type Bit Maps Field - - The Type Bit Maps field identifies the RRset types which exist at the - NSEC3 RR's original ownername. - - The Type bits for the NSEC3 RR and RRSIG RR MUST be set during - generation, and MUST be ignored during processing. - - The RR type space is split into 256 window blocks, each representing - the low-order 8 bits of the 16-bit RR type space. Each block that - has at least one active RR type is encoded using a single octet - window number (from 0 to 255), a single octet bitmap length (from 1 - to 32) indicating the number of octets used for the window block's - bitmap, and up to 32 octets (256 bits) of bitmap. - - Blocks are present in the NSEC3 RR RDATA in increasing numerical - order. - - "|" denotes concatenation - - Type Bit Map(s) Field = ( Window Block # | Bitmap Length | Bitmap ) + - - - - -Laurie, et al. Expires August 5, 2006 [Page 9] - -Internet-Draft nsec3 February 2006 - - - Each bitmap encodes the low-order 8 bits of RR types within the - window block, in network bit order. The first bit is bit 0. For - window block 0, bit 1 corresponds to RR type 1 (A), bit 2 corresponds - to RR type 2 (NS), and so forth. For window block 1, bit 1 - corresponds to RR type 257, bit 2 to RR type 258. If a bit is set to - 1, it indicates that an RRset of that type is present for the NSEC3 - RR's ownername. If a bit is set to 0, it indicates that no RRset of - that type is present for the NSEC3 RR's ownername. - - Since bit 0 in window block 0 refers to the non-existing RR type 0, - it MUST be set to 0. After verification, the validator MUST ignore - the value of bit 0 in window block 0. - - Bits representing Meta-TYPEs or QTYPEs as specified in RFC 2929 [11] - (section 3.1) or within the range reserved for assignment only to - QTYPEs and Meta-TYPEs MUST be set to 0, since they do not appear in - zone data. If encountered, they must be ignored upon reading. - - Blocks with no types present MUST NOT be included. Trailing zero - octets in the bitmap MUST be omitted. The length of each block's - bitmap is determined by the type code with the largest numerical - value, within that block, among the set of RR types present at the - NSEC3 RR's actual ownername. Trailing zero octets not specified MUST - be interpreted as zero octets. - -3.2. The NSEC3 RR Presentation Format - - The presentation format of the RDATA portion is as follows: - - The Opt-In Flag Field is represented as an unsigned decimal integer. - The value is either 0 or 1. - - The Hash field is presented as a mnemonic of the hash or as an - unsigned decimal integer. The value has a maximum of 127. - - The Iterations field is presented as an unsigned decimal integer. - - The Salt Length field is not presented. - - The Salt field is represented as a sequence of case-insensitive - hexadecimal digits. Whitespace is not allowed within the sequence. - The Salt Field is represented as "-" (without the quotes) when the - Salt Length field has value 0. - - The Next Hashed Ownername field is represented as a sequence of case- - insensitive base32 digits, without whitespace. - - The Type Bit Maps Field is represented as a sequence of RR type - - - -Laurie, et al. Expires August 5, 2006 [Page 10] - -Internet-Draft nsec3 February 2006 - - - mnemonics. When the mnemonic is not known, the TYPE representation - as described in RFC 3597 [12] (section 5) MUST be used. - - -4. Creating Additional NSEC3 RRs for Empty Non-Terminals - - In order to prove the non-existence of a record that might be covered - by a wildcard, it is necessary to prove the existence of its closest - encloser. A closest encloser might be an empty non-terminal. - - Additional NSEC3 RRs are generated for empty non-terminals. These - additional NSEC3 RRs are identical in format to NSEC3 RRs that cover - existing RRs in the zone except that their type-maps only indicated - the existence of an NSEC3 RRset and an RRSIG RRset. - - This relaxes the requirement in Section 2.3 of RFC4035 that NSEC RRs - not appear at names that did not exist before the zone was signed. - [Comment.1] - - -5. Calculation of the Hash - - Define H(x) to be the hash of x using the hash function selected by - the NSEC3 record and || to indicate concatenation. Then define: - - IH(salt,x,0)=H(x || salt) - - IH(salt,x,k)=H(IH(salt,x,k-1) || salt) if k > 0 - - Then the calculated hash of an ownername is - IH(salt,ownername,iterations-1), where the ownername is the canonical - form. - - The canonical form of the ownername is the wire format of the - ownername where: - 1. The ownername is fully expanded (no DNS name compression) and - fully qualified; - 2. All uppercase US-ASCII letters are replaced by the corresponding - lowercase US-ASCII letters; - 3. If the ownername is a wildcard name, the ownername is in its - original unexpanded form, including the "*" label (no wildcard - substitution); - This form is as defined in section 6.2 of RFC 4034 ([4]). - - -6. Including NSEC3 RRs in a Zone - - Each ownername within the zone that owns authoritative RRsets MUST - - - -Laurie, et al. Expires August 5, 2006 [Page 11] - -Internet-Draft nsec3 February 2006 - - - have a corresponding NSEC3 RR. Ownernames that correspond to - unsigned delegations MAY have a corresponding NSEC3 RR, however, if - there is not, there MUST be a covering NSEC3 RR with the Opt-In flag - set to 1. Other non-authoritative RRs are not included in the set of - NSEC3 RRs. - - Each empty non-terminal MUST have an NSEC3 record. - - The TTL value for any NSEC3 RR SHOULD be the same as the minimum TTL - value field in the zone SOA RR. - - The type bitmap of every NSEC3 resource record in a signed zone MUST - indicate the presence of both the NSEC3 RR type itself and its - corresponding RRSIG RR type. - - The following steps describe the proper construction of NSEC3 - records. [Comment.2] - 1. For each unique original ownername in the zone, add an NSEC3 - RRset. If Opt-In is being used, ownernames of unsigned - delegations may be excluded, but must be considered for empty- - non-terminals. The ownername of the NSEC3 RR is the hashed - equivalent of the original owner name, prepended to the zone - name. The Next Hashed Ownername field is left blank for the - moment. If Opt-In is being used, set the Opt-In bit to one. - 2. For each RRset at the original owner name, set the corresponding - bit in the type bit map. - 3. If the difference in number of labels between the apex and the - original ownername is greater then 1, additional NSEC3s need to - be added for every empty non-terminal between the apex and the - original ownername. This process may generate NSEC3 RRs with - duplicate hashed ownernames. - 4. Sort the set of NSEC3 RRs into hash order. Hash order is the - ascending numerical order of the non-encoded hash values. - 5. Combine NSEC3 RRs with identical hashed ownernames by replacing - with a single NSEC3 RR with the type map consisting of the union - of the types represented by the set of NSEC3 RRs. - 6. In each NSEC3 RR, insert the Next Hashed Ownername by using the - value of the next NSEC3 RR in hash order. The Next Hashed - Ownername of the last NSEC3 in the zone contains the value of the - hashed ownername of the first NSEC3 in the hash order. - - -7. Responding to NSEC3 Queries - - Since NSEC3 ownernames are not represented in the NSEC3 chain like - other zone ownernames, direct queries for NSEC3 ownernames present a - special case. - - - - -Laurie, et al. Expires August 5, 2006 [Page 12] - -Internet-Draft nsec3 February 2006 - - - The special case arises when the following are all true: - o The QNAME equals an existing NSEC3 ownername, and - o There are no other record types that exist at QNAME, and - o The QTYPE does not equal NSEC3. - These conditions describe a particular case: the answer should be a - NOERROR/NODATA response, but there is no NSEC3 RRset for H(QNAME) to - include in the authority section. - - However, the NSEC3 RRset with ownername equal to QNAME is able to - prove its own existence. Thus, when answering this query, the - authoritative server MUST include the NSEC3 RRset whose ownername - equals QNAME. This RRset proves that QNAME is an existing name with - types NSEC3 and RRSIG. The authoritative server MUST also include - the NSEC3 RRset that covers the hash of QNAME. This RRset proves - that no other types exist. - - When validating a NOERROR/NODATA response, validators MUST check for - a NSEC3 RRset with ownername equals to QNAME, and MUST accept that - (validated) NSEC3 RRset as proof that QNAME exists. The validator - MUST also check for an NSEC3 RRset that covers the hash of QNAME as - proof that QTYPE doesn't exist. - - Other cases where the QNAME equals an existing NSEC3 ownername may be - answered normally. - - -8. Special Considerations - - The following paragraphs clarify specific behaviour explain special - considerations for implementations. - -8.1. Proving Nonexistence - - If a wildcard resource record appears in a zone, its asterisk label - is treated as a literal symbol and is treated in the same way as any - other ownername for purposes of generating NSEC3 RRs. RFC 4035 [5] - describes the impact of wildcards on authenticated denial of - existence. - - In order to prove there exist no RRs for a domain, as well as no - source of synthesis, an RR must be shown for the closest encloser, - and non-existence must be shown for all closer labels and for the - wildcard at the closest encloser. - - This can be done as follows. If the QNAME in the query is - omega.alfa.beta.example, and the closest encloser is beta.example - (the nearest ancestor to omega.alfa.beta.example), then the server - should return an NSEC3 that demonstrates the nonexistence of - - - -Laurie, et al. Expires August 5, 2006 [Page 13] - -Internet-Draft nsec3 February 2006 - - - alfa.beta.example, an NSEC3 that demonstrates the nonexistence of - *.beta.example, and an NSEC3 that demonstrates the existence of - beta.example. This takes between one and three NSEC3 records, since - a single record can, by chance, prove more than one of these facts. - - When a verifier checks this response, then the existence of - beta.example together with the non-existence of alfa.beta.example - proves that the closest encloser is indeed beta.example. The non- - existence of *.beta.example shows that there is no wildcard at the - closest encloser, and so no source of synthesis for - omega.alfa.beta.example. These two facts are sufficient to satisfy - the resolver that the QNAME cannot be resolved. - - In practice, since the NSEC3 owner and next names are hashed, if the - server responds with an NSEC3 for beta.example, the resolver will - have to try successively longer names, starting with example, moving - to beta.example, alfa.beta.example, and so on, until one of them - hashes to a value that matches the interval (but not the ownername - nor next owner name) of one of the returned NSEC3s (this name will be - alfa.beta.example). Once it has done this, it knows the closest - encloser (i.e. beta.example), and can then easily check the other two - required proofs. - - Note that it is not possible for one of the shorter names tried by - the resolver to be denied by one of the returned NSEC3s, since, by - definition, all these names exist and so cannot appear within the - range covered by an NSEC3. Note, however, that the first name that - the resolver tries MUST be the apex of the zone, since names above - the apex could be denied by one of the returned NSEC3s. - -8.2. Salting - - Augmenting original ownernames with salt before hashing increases the - cost of a dictionary of pre-generated hash-values. For every bit of - salt, the cost of a precomputed dictionary doubles (because there - must be an entry for each word combined with each possible salt - value). The NSEC3 RR can use a maximum of 2040 bits (255 octets) of - salt, multiplying the cost by 2^2040. This means that an attacker - must, in practice, recompute the dictionary each time the salt is - changed. - - There MUST be at least one complete set of NSEC3s for the zone using - the same salt value. - - The salt SHOULD be changed periodically to prevent precomputation - using a single salt. It is RECOMMENDED that the salt be changed for - every resigning. - - - - -Laurie, et al. Expires August 5, 2006 [Page 14] - -Internet-Draft nsec3 February 2006 - - - Note that this could cause a resolver to see records with different - salt values for the same zone. This is harmless, since each record - stands alone (that is, it denies the set of ownernames whose hashes, - using the salt in the NSEC3 record, fall between the two hashes in - the NSEC3 record) - it is only the server that needs a complete set - of NSEC3 records with the same salt in order to be able to answer - every possible query. - - There is no prohibition with having NSEC3 with different salts within - the same zone. However, in order for authoritative servers to be - able to consistently find covering NSEC3 RRs, the authoritative - server MUST choose a single set of parameters (algorithm, salt, and - iterations) to use when selecting NSEC3s. In the absence of any - other metadata, the server does this by using the parameters from the - zone apex NSEC3, recognizable by the presence of the SOA bit in the - type map. If there is more than one NSEC3 record that meets this - description, then the server may arbitrarily choose one. Because of - this, if there is a zone apex NSEC3 RR within a zone, it MUST be part - of a complete NSEC3 set. Conversely, if there exists an incomplete - set of NSEC3 RRs using the same parameters within a zone, there MUST - NOT be an NSEC3 RR using those parameters with the SOA bit set. - -8.3. Iterations - - Setting the number of iterations used allows the zone owner to choose - the cost of computing a hash, and so the cost of generating a - dictionary. Note that this is distinct from the effect of salt, - which prevents the use of a single precomputed dictionary for all - time. - - Obviously the number of iterations also affects the zone owner's cost - of signing the zone as well as the verifiers cost of verifying the - zone. We therefore impose an upper limit on the number of - iterations. We base this on the number of iterations that - approximately doubles the cost of signing the zone. - - A zone owner MUST NOT use a value higher than shown in the table - below for iterations. A resolver MAY treat a response with a higher - value as bogus. - - +--------------+------------+ - | RSA Key Size | Iterations | - +--------------+------------+ - | 1024 | 3,000 | - | 2048 | 20,000 | - | 4096 | 150,000 | - +--------------+------------+ - - - - -Laurie, et al. Expires August 5, 2006 [Page 15] - -Internet-Draft nsec3 February 2006 - - - +--------------+------------+ - | DSA Key Size | Iterations | - +--------------+------------+ - | 1024 | 1,500 | - | 2048 | 5,000 | - +--------------+------------+ - - This table is based on 150,000 SHA-1's per second, 50 RSA signs per - second for 1024 bit keys, 7 signs per second for 2048 bit keys, 1 - sign per second for 4096 bit keys, 100 DSA signs per second for 1024 - bit keys and 30 signs per second for 2048 bit keys. - - Note that since RSA verifications are 10-100 times faster than - signatures (depending on key size), in the case of RSA the legal - values of iterations can substantially increase the cost of - verification. - -8.4. Hash Collision - - Hash collisions occur when different messages have the same hash - value. The expected number of domain names needed to give a 1 in 2 - chance of a single collision is about 2^(n/2) for a hash of length n - bits (i.e. 2^80 for SHA-1). Though this probability is extremely - low, the following paragraphs deal with avoiding collisions and - assessing possible damage in the event of an attack using hash - collisions. - -8.4.1. Avoiding Hash Collisions during generation - - During generation of NSEC3 RRs, hash values are supposedly unique. - In the (academic) case of a collision occurring, an alternative salt - MUST be chosen and all hash values MUST be regenerated. - -8.4.2. Second Preimage Requirement Analysis - - A cryptographic hash function has a second-preimage resistance - property. The second-preimage resistance property means that it is - computationally infeasible to find another message with the same hash - value as a given message, i.e. given preimage X, to find a second - preimage X' != X such that hash(X) = hash(X'). The work factor for - finding a second preimage is of the order of 2^160 for SHA-1. To - mount an attack using an existing NSEC3 RR, an adversary needs to - find a second preimage. - - Assuming an adversary is capable of mounting such an extreme attack, - the actual damage is that a response message can be generated which - claims that a certain QNAME (i.e. the second pre-image) does exist, - while in reality QNAME does not exist (a false positive), which will - - - -Laurie, et al. Expires August 5, 2006 [Page 16] - -Internet-Draft nsec3 February 2006 - - - either cause a security aware resolver to re-query for the non- - existent name, or to fail the initial query. Note that the adversary - can't mount this attack on an existing name but only on a name that - the adversary can't choose and does not yet exist. - -8.4.3. Possible Hash Value Truncation Method - - The previous sections outlined the low probability and low impact of - a second-preimage attack. When impact and probability are low, while - space in a DNS message is costly, truncation is tempting. Truncation - might be considered to allow for shorter ownernames and rdata for - hashed labels. In general, if a cryptographic hash is truncated to n - bits, then the expected number of domains required to give a 1 in 2 - probability of a single collision is approximately 2^(n/2) and the - work factor to produce a second preimage is 2^n. - - An extreme hash value truncation would be truncating to the shortest - possible unique label value. This would be unwise, since the work - factor to produce second preimages would then approximate the size of - the zone (sketch of proof: if the zone has k entries, then the length - of the names when truncated down to uniqueness should be proportional - to log_2(k). Since the work factor to produce a second pre-image is - 2^n for an n-bit hash, then in this case it is 2^(C log_2(k)) (where - C is some constant), i.e. C'k - a work factor of k). - - Though the mentioned truncation can be maximized to a certain - extreme, the probability of collision increases exponentially for - every truncated bit. Given the low impact of hash value collisions - and limited space in DNS messages, the balance between truncation - profit and collision damage may be determined by local policy. Of - course, the size of the corresponding RRSIG RR is not reduced, so - truncation is of limited benefit. - - Truncation could be signaled simply by reducing the length of the - first label in the ownername. Note that there would have to be a - corresponding reduction in the length of the Next Hashed Ownername - field. - -8.4.4. Server Response to a Run-time Collision - - In the astronomically unlikely event that a server is unable to prove - nonexistence because the hash of the name that does not exist - collides with a name that does exist, the server is obviously broken, - and should, therefore, return a response with an RCODE of 2 (server - failure). - - - - - - -Laurie, et al. Expires August 5, 2006 [Page 17] - -Internet-Draft nsec3 February 2006 - - -8.4.5. Parameters that Cover the Zone - - Secondary servers (and perhaps other entities) need to reliably - determine which NSEC3 parameters (that is, hash, salt and iterations) - are present at every hashed ownername, in order to be able to choose - an appropriate set of NSEC3 records for negative responses. This is - indicated by the parameters at the apex: any set of parameters that - is used in an NSEC3 record whose original ownername is the apex of - the zone MUST be present throughout the zone. - - A method to determine which NSEC3 in a complete chain corresponds to - the apex is to look for a NSEC3 RRset which has the SOA bit set in - the RDATA bit type maps field. - - -9. Performance Considerations - - Iterated hashes impose a performance penalty on both authoritative - servers and resolvers. Therefore, the number of iterations should be - carefully chosen. In particular it should be noted that a high value - for iterations gives an attacker a very good denial of service - attack, since the attacker need not bother to verify the results of - their queries, and hence has no performance penalty of his own. - - On the other hand, nameservers with low query rates and limited - bandwidth are already subject to a bandwidth based denial of service - attack, since responses are typically an order of magnitude larger - than queries, and hence these servers may choose a high value of - iterations in order to increase the difficulty of offline attempts to - enumerate their namespace without significantly increasing their - vulnerability to denial of service attacks. - - -10. IANA Considerations - - IANA needs to allocate a RR type code for NSEC3 from the standard RR - type space (type XXX requested). IANA needs to open a new registry - for the NSEC3 Hash Functions. The range for this registry is 0-127. - Defined types are: - - 0 is reserved. - 1 is SHA-1 ([13]). - 127 is experimental. - - -11. Security Considerations - - The NSEC3 records are still susceptible to dictionary attacks (i.e. - - - -Laurie, et al. Expires August 5, 2006 [Page 18] - -Internet-Draft nsec3 February 2006 - - - the attacker retrieves all the NSEC3 records, then calculates the - hashes of all likely domain names, comparing against the hashes found - in the NSEC3 records, and thus enumerating the zone). These are - substantially more expensive than enumerating the original NSEC - records would have been, and in any case, such an attack could also - be used directly against the name server itself by performing queries - for all likely names, though this would obviously be more detectable. - The expense of this off-line attack can be chosen by setting the - number of iterations in the NSEC3 RR. - - Domains are also susceptible to a precalculated dictionary attack - - that is, a list of hashes for all likely names is computed once, then - NSEC3 is scanned periodically and compared against the precomputed - hashes. This attack is prevented by changing the salt on a regular - basis. - - Walking the NSEC3 RRs will reveal the total number of records in the - zone, and also what types they are. This could be mitigated by - adding dummy entries, but certainly an upper limit can always be - found. - - Hash collisions may occur. If they do, it will be impossible to - prove the non-existence of the colliding domain - however, this is - fantastically unlikely, and, in any case, DNSSEC already relies on - SHA-1 to not collide. - - Responses to queries where QNAME equals an NSEC3 ownername that has - no other types may be undetectably changed from a NOERROR/NODATA - response to a NAME ERROR response. - - The Opt-In Flag (O) allows for unsigned names, in the form of - delegations to unsigned subzones, to exist within an otherwise signed - zone. All unsigned names are, by definition, insecure, and their - validity or existence cannot by cryptographically proven. - - In general: - Records with unsigned names (whether existing or not) suffer from - the same vulnerabilities as records in an unsigned zone. These - vulnerabilities are described in more detail in [16] (note in - particular sections 2.3, "Name Games" and 2.6, "Authenticated - Denial"). - Records with signed names have the same security whether or not - Opt-In is used. - - Note that with or without Opt-In, an insecure delegation may be - undetectably altered by an attacker. Because of this, the primary - difference in security when using Opt-In is the loss of the ability - to prove the existence or nonexistence of an insecure delegation - - - -Laurie, et al. Expires August 5, 2006 [Page 19] - -Internet-Draft nsec3 February 2006 - - - within the span of an Opt-In NSEC3 record. - - In particular, this means that a malicious entity may be able to - insert or delete records with unsigned names. These records are - normally NS records, but this also includes signed wildcard - expansions (while the wildcard record itself is signed, its expanded - name is an unsigned name). - - For example, if a resolver received the following response from the - example zone above: - - Example S.1: Response to query for WWW.DOES-NOT-EXIST.EXAMPLE. A - - RCODE=NOERROR - - Answer Section: - - Authority Section: - DOES-NOT-EXIST.EXAMPLE. NS NS.FORGED. - EXAMPLE. NSEC FIRST-SECURE.EXAMPLE. SOA NS \ - RRSIG DNSKEY - abcd... RRSIG NSEC3 ... - - Additional Section: - - The resolver would have no choice but to accept that the referral to - NS.FORGED. is valid. If a wildcard existed that would have been - expanded to cover "WWW.DOES-NOT-EXIST.EXAMPLE.", an attacker could - have undetectably removed it and replaced it with the forged - delegation. - - Note that being able to add a delegation is functionally equivalent - to being able to add any record type: an attacker merely has to forge - a delegation to nameserver under his/her control and place whatever - records needed at the subzone apex. - - While in particular cases, this issue may not present a significant - security problem, in general it should not be lightly dismissed. - Therefore, it is strongly RECOMMENDED that Opt-In be used sparingly. - In particular, zone signing tools SHOULD NOT default to using Opt-In, - and MAY choose to not support Opt-In at all. - - -12. References - - - - - - - -Laurie, et al. Expires August 5, 2006 [Page 20] - -Internet-Draft nsec3 February 2006 - - -12.1. Normative References - - [1] Mockapetris, P., "Domain names - concepts and facilities", - STD 13, RFC 1034, November 1987. - - [2] Mockapetris, P., "Domain names - implementation and - specification", STD 13, RFC 1035, November 1987. - - [3] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "DNS Security Introduction and Requirements", RFC 4033, - March 2005. - - [4] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "Resource Records for the DNS Security Extensions", RFC 4034, - March 2005. - - [5] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "Protocol Modifications for the DNS Security Extensions", - RFC 4035, March 2005. - - [6] Vixie, P., Thomson, S., Rekhter, Y., and J. Bound, "Dynamic - Updates in the Domain Name System (DNS UPDATE)", RFC 2136, - April 1997. - - [7] Elz, R. and R. Bush, "Clarifications to the DNS Specification", - RFC 2181, July 1997. - - [8] Andrews, M., "Negative Caching of DNS Queries (DNS NCACHE)", - RFC 2308, March 1998. - - [9] Bradner, S., "Key words for use in RFCs to Indicate Requirement - Levels", BCP 14, RFC 2119, March 1997. - - [10] Gudmundsson, O., "Delegation Signer (DS) Resource Record (RR)", - RFC 3658, December 2003. - - [11] Eastlake, D., Brunner-Williams, E., and B. Manning, "Domain - Name System (DNS) IANA Considerations", BCP 42, RFC 2929, - September 2000. - - [12] Gustafsson, A., "Handling of Unknown DNS Resource Record (RR) - Types", RFC 3597, September 2003. - - [13] Eastlake, D. and P. Jones, "US Secure Hash Algorithm 1 (SHA1)", - RFC 3174, September 2001. - - - - - - -Laurie, et al. Expires August 5, 2006 [Page 21] - -Internet-Draft nsec3 February 2006 - - -12.2. Informative References - - [14] Vixie, P., "Extending DNSSEC-BIS (DNSSEC-TER)", - draft-vixie-dnssec-ter-01 (work in progress), June 2004. - - [15] Josefsson, Ed., S,., "The Base16, Base32, and Base64 Data - Encodings.", draft-josefsson-rfc3548bis-00 (work in progress), - October 2005. - - [16] Atkins, D. and R. Austein, "Threat Analysis of the Domain Name - System (DNS)", RFC 3833, August 2004. - -Editorial Comments - - [Comment.1] Although, strictly speaking, the names *did* exist. - - [Comment.2] Note that this method makes it impossible to detect - (extremely unlikely) hash collisions. - - -Appendix A. Example Zone - - This is a zone showing its NSEC3 records. They can also be used as - test vectors for the hash algorithm. - - The data in the example zone is currently broken, as it uses a - different base32 alphabet. This shall be fixed in the next release. - - - example. 3600 IN SOA ns1.example. bugs.x.w.example. ( - 1 - 3600 - 300 - 3600000 - 3600 ) - 3600 RRSIG SOA 5 1 3600 20050712112304 ( - 20050612112304 62699 example. - RtctD6aLUU5Md5wOOItilS7JXX1tf58Ql3sK - mTXkL13jqLiUFOGg0uzqRh1U9GbydS0P7M0g - qYIt90txzE/4+g== ) - 3600 NS ns1.example. - 3600 NS ns2.example. - 3600 RRSIG NS 5 1 3600 20050712112304 ( - 20050612112304 62699 example. - hNyyin2JpECIFxW4vsj8RhHcWCQKUXgO+z4l - m7g2zM8q3Qpsm/gYIXSF2Rhj6lAG7esR/X9d - 1SH5r/wfjuCg+g== ) - 3600 MX 1 xx.example. - - - -Laurie, et al. Expires August 5, 2006 [Page 22] - -Internet-Draft nsec3 February 2006 - - - 3600 RRSIG MX 5 1 3600 20050712112304 ( - 20050612112304 62699 example. - L/ZDLMSZJKITmSxmM9Kni37/wKQsdSg6FT0l - NMm14jy2Stp91Pwp1HQ1hAMkGWAqCMEKPMtU - S/o/g5C8VM6ftQ== ) - 3600 DNSKEY 257 3 5 ( - AQOnsGyJvywVjYmiLbh0EwIRuWYcDiB/8blX - cpkoxtpe19Oicv6Zko+8brVsTMeMOpcUeGB1 - zsYKWJ7BvR2894hX - ) ; Key ID = 21960 - 3600 DNSKEY 256 3 5 ( - AQO0gEmbZUL6xbD/xQczHbnwYnf+jQjwz/sU - 5k44rHTt0Ty+3aOdYoome9TjGMhwkkGby1TL - ExXT48OGGdbfIme5 - ) ; Key ID = 62699 - 3600 RRSIG DNSKEY 5 1 3600 20050712112304 ( - 20050612112304 62699 example. - e6EB+K21HbyZzoLUeRDb6+g0+n8XASYe6h+Z - xtnB31sQXZgq8MBHeNFDQW9eZw2hjT9zMClx - mTkunTYzqWJrmQ== ) - 3600 RRSIG DNSKEY 5 1 3600 20050712112304 ( - 20050612112304 21960 example. - SnWLiNWLbOuiKU/F/wVMokvcg6JVzGpQ2VUk - ZbKjB9ON0t3cdc+FZbOCMnEHRJiwgqlnncik - 3w7ZY2UWyYIvpw== ) - 5pe7ctl7pfs2cilroy5dcofx4rcnlypd.example. 3600 NSEC3 0 1 1 ( - deadbeaf - 7nomf47k3vlidh4vxahhpp47l3tgv7a2 - NSEC3 RRSIG ) - 3600 RRSIG NSEC3 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - PTWYq4WZmmtgh9UQif342HWf9DD9RuuM4ii5 - Z1oZQgRi5zrsoKHAgl2YXprF2Rfk1TLgsiFQ - sb7KfbaUo/vzAg== ) - 7nomf47k3vlidh4vxahhpp47l3tgv7a2.example. 3600 NSEC3 0 1 1 ( - deadbeaf - dw4o7j64wnel3j4jh7fb3c5n7w3js2yb - MX NSEC3 RRSIG ) - 3600 RRSIG NSEC3 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - YTcqole3h8EOsTT3HKnwhR1QS8borR0XtZaA - ZrLsx6n0RDC1AAdZONYOvdqvcal9PmwtWjlo - MEFQmc/gEuxojA== ) - a.example. 3600 IN NS ns1.a.example. - 3600 IN NS ns2.a.example. - 3600 DS 58470 5 1 3079F1593EBAD6DC121E202A8B - 766A6A4837206C ) - 3600 RRSIG DS 5 2 3600 20050712112304 ( - - - -Laurie, et al. Expires August 5, 2006 [Page 23] - -Internet-Draft nsec3 February 2006 - - - 20050612112304 62699 example. - QavhbsSmEvJLSUzGoTpsV3SKXCpaL1UO3Ehn - cB0ObBIlex/Zs9kJyG/9uW1cYYt/1wvgzmX2 - 0kx7rGKTc3RQDA== ) - ns1.a.example. 3600 IN A 192.0.2.5 - ns2.a.example. 3600 IN A 192.0.2.6 - ai.example. 3600 IN A 192.0.2.9 - 3600 RRSIG A 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - plY5M26ED3Owe3YX0pBIhgg44j89NxUaoBrU - 6bLRr99HpKfFl1sIy18JiRS7evlxCETZgubq - ZXW5S+1VjMZYzQ== ) - 3600 HINFO "KLH-10" "ITS" - 3600 RRSIG HINFO 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - AR0hG/Z/e+vlRhxRQSVIFORzrJTBpdNHhwUk - tiuqg+zGqKK84eIqtrqXelcE2szKnF3YPneg - VGNmbgPnqDVPiA== ) - 3600 AAAA 2001:db8:0:0:0:0:f00:baa9 - 3600 RRSIG AAAA 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - PNF/t7+DeosEjhfuL0kmsNJvn16qhYyLI9FV - ypSCorFx/PKIlEL3syomkYM2zcXVSRwUXMns - l5/UqLCJJ9BDMg== ) - b.example. 3600 IN NS ns1.b.example. - 3600 IN NS ns2.b.example. - ns1.b.example. 3600 IN A 192.0.2.7 - ns2.b.example. 3600 IN A 192.0.2.8 - dw4o7j64wnel3j4jh7fb3c5n7w3js2yb.example. 3600 NSEC3 0 1 1 ( - deadbeaf - gmnfcccja7wkax3iv26bs75myptje3qk - MX DNSKEY NS SOA NSEC3 RRSIG ) - 3600 RRSIG NSEC3 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - VqEbXiZLJVYmo25fmO3IuHkAX155y8NuA50D - C0NmJV/D4R3rLm6tsL6HB3a3f6IBw6kKEa2R - MOiKMSHozVebqw== ) - gmnfcccja7wkax3iv26bs75myptje3qk.example. 3600 NSEC3 0 1 1 ( - deadbeaf - jt4bbfokgbmr57qx4nqucvvn7fmo6ab6 - DS NS NSEC3 RRSIG ) - 3600 RRSIG NSEC3 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - ZqkdmF6eICpHyn1Cj7Yvw+nLcbji46Qpe76/ - ZetqdZV7K5sO3ol5dOc0dZyXDqsJp1is5StW - OwQBGbOegrW/Zw== ) - jt4bbfokgbmr57qx4nqucvvn7fmo6ab6.example. 3600 NSEC3 0 1 1 ( - deadbeaf - - - -Laurie, et al. Expires August 5, 2006 [Page 24] - -Internet-Draft nsec3 February 2006 - - - kcll7fqfnisuhfekckeeqnmbbd4maanu - NSEC3 RRSIG ) - 3600 RRSIG NSEC3 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - FXyCVQUdFF1EW1NcgD2V724/It0rn3lr+30V - IyjmqwOMvQ4G599InTpiH46xhX3U/FmUzHOK - 94Zbq3k8lgdpZA== ) - kcll7fqfnisuhfekckeeqnmbbd4maanu.example. 3600 NSEC3 1 1 1 ( - deadbeaf - n42hbhnjj333xdxeybycax5ufvntux5d - MX NSEC3 RRSIG ) - 3600 RRSIG NSEC3 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - d0g8MTOvVwByOAIwvYV9JrTHwJof1VhnMKuA - IBj6Xaeney86RBZYgg7Qyt9WnQSK3uCEeNpx - TOLtc5jPrkL4zQ== ) - n42hbhnjj333xdxeybycax5ufvntux5d.example. 3600 NSEC3 0 1 1 ( - deadbeaf - nimwfwcnbeoodmsc6npv3vuaagaevxxu - A NSEC3 RRSIG ) - 3600 RRSIG NSEC3 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - MZGzllh+YFqZbY8SkHxARhXFiMDPS0tvQYyy - 91tj+lbl45L/BElD3xxB/LZMO8vQejYtMLHj - xFPFGRIW3wKnrA== ) - nimwfwcnbeoodmsc6npv3vuaagaevxxu.example. 3600 NSEC3 0 1 1 ( - deadbeaf - vhgwr2qgykdkf4m6iv6vkagbxozphazr - HINFO A AAAA NSEC3 RRSIG ) - 3600 RRSIG NSEC3 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - c3zQdK68cYTHTjh1cD6pi0vblXwzyoU/m7Qx - z8kaPYikbJ9vgSl9YegjZukgQSwybHUC0SYG - jL33Wm1p07TBdw== ) - ns1.example. 3600 A 192.0.2.1 - 3600 RRSIG A 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - QLGkaqWXxRuE+MHKkMvVlswg65HcyjvD1fyb - BDZpcfiMHH9w4x1eRqRamtSDTcqLfUrcYkrr - nWWLepz1PjjShQ== ) - ns2.example. 3600 A 192.0.2.2 - 3600 RRSIG A 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - UoIZaC1O6XHRWGHBOl8XFQKPdYTkRCz6SYh3 - P2mZ3xfY22fLBCBDrEnOc8pGDGijJaLl26Cz - AkeTJu3J3auUiA== ) - vhgwr2qgykdkf4m6iv6vkagbxozphazr.example. 3600 NSEC3 0 1 1 ( - deadbeaf - - - -Laurie, et al. Expires August 5, 2006 [Page 25] - -Internet-Draft nsec3 February 2006 - - - wbyijvpnyj33pcpi3i44ecnibnaj7eiw - HINFO A AAAA NSEC3 RRSIG ) - 3600 RRSIG NSEC3 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - leFhoF5FXZAiNOxK4OBOOA0WKdbaD5lLDT/W - kLoyWnQ6WGBwsUOdsEcVmqz+1n7q9bDf8G8M - 5SNSHIyfpfsi6A== ) - *.w.example. 3600 MX 1 ai.example. - 3600 RRSIG MX 5 3 3600 20050712112304 ( - 20050612112304 62699 example. - sYNUPHn1/gJ87wTHNksGdRm3vfnSFa2BbofF - xGfJLF5A4deRu5f0hvxhAFDCcXfIASj7z0wQ - gQlgxEwhvQDEaQ== ) - x.w.example. 3600 MX 1 xx.example. - 3600 RRSIG MX 5 3 3600 20050712112304 ( - 20050612112304 62699 example. - s1XQ/8SlViiEDik9edYs1Ooe3XiXo453Dg7w - lqQoewuDzmtd6RaLNu52W44zTM1EHJES8ujP - U9VazOa1KEIq1w== ) - x.y.w.example. 3600 MX 1 xx.example. - 3600 RRSIG MX 5 4 3600 20050712112304 ( - 20050612112304 62699 example. - aKVCGO/Fx9rm04UUsHRTTYaDA8o8dGfyq6t7 - uqAcYxU9xiXP+xNtLHBv7er6Q6f2JbOs6SGF - 9VrQvJjwbllAfA== ) - wbyijvpnyj33pcpi3i44ecnibnaj7eiw.example. 3600 NSEC3 0 1 1 ( - deadbeaf - zjxfz5o7t4ty4u3f6fa7mhhqzjln4mui - A NSEC3 RRSIG ) - 3600 RRSIG NSEC3 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - ledFAaDCqDxapQ1FvBAjjK2DP06iQj8AN6gN - ZycTeSmobKLTpzbgQp8uKYYe/DPHjXYmuEhd - oorBv4xkb0flXw== ) - xx.example. 3600 A 192.0.2.10 - 3600 RRSIG A 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - XSuMVjNxovbZUsnKU6oQDygaK+WB+O5HYQG9 - tJgphHIX7TM4uZggfR3pNM+4jeC8nt2OxZZj - cxwCXWj82GVGdw== ) - 3600 HINFO "KLH-10" "TOPS-20" - 3600 RRSIG HINFO 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - ghS2DimOqPSacG9j6KMgXSfTMSjLxvoxvx3q - OKzzPst4tEbAmocF2QX8IrSHr67m4ZLmd2Fk - KMf4DgNBDj+dIQ== ) - 3600 AAAA 2001:db8:0:0:0:0:f00:baaa - 3600 RRSIG AAAA 5 2 3600 20050712112304 ( - - - -Laurie, et al. Expires August 5, 2006 [Page 26] - -Internet-Draft nsec3 February 2006 - - - 20050612112304 62699 example. - rto7afZkXYB17IfmQCT5QoEMMrlkeOoAGXzo - w8Wmcg86Fc+MQP0hyXFScI1gYNSgSSoDMXIy - rzKKwb8J04/ILw== ) - zjxfz5o7t4ty4u3f6fa7mhhqzjln4mui.example. 3600 NSEC3 0 1 1 ( - deadbeaf - 5pe7ctl7pfs2cilroy5dcofx4rcnlypd - MX NSEC3 RRSIG ) - 3600 RRSIG NSEC3 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - eULkdWjcjmM+wXQcr7zXNfnGLgHjZSJINGkt - 7Zmvp7WKVAqoHMm1RXV8IfBH1aRgv5+/Lgny - OcFlrPGPMm48/A== ) - - -Appendix B. Example Responses - - The examples in this section show response messages using the signed - zone example in Appendix A. - -B.1. answer - - A successful query to an authoritative server. - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Laurie, et al. Expires August 5, 2006 [Page 27] - -Internet-Draft nsec3 February 2006 - - - ;; Header: QR AA DO RCODE=0 - ;; - ;; Question - x.w.example. IN MX - - ;; Answer - x.w.example. 3600 IN MX 1 xx.example. - x.w.example. 3600 IN RRSIG MX 5 3 3600 20050712112304 ( - 20050612112304 62699 example. - s1XQ/8SlViiEDik9edYs1Ooe3XiXo453Dg7w - lqQoewuDzmtd6RaLNu52W44zTM1EHJES8ujP - U9VazOa1KEIq1w== ) - - ;; Authority - example. 3600 IN NS ns1.example. - example. 3600 IN NS ns2.example. - example. 3600 IN RRSIG NS 5 1 3600 20050712112304 ( - 20050612112304 62699 example. - hNyyin2JpECIFxW4vsj8RhHcWCQKUXgO+z4l - m7g2zM8q3Qpsm/gYIXSF2Rhj6lAG7esR/X9d - 1SH5r/wfjuCg+g== ) - - ;; Additional - xx.example. 3600 IN A 192.0.2.10 - xx.example. 3600 IN RRSIG A 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - XSuMVjNxovbZUsnKU6oQDygaK+WB+O5HYQG9 - tJgphHIX7TM4uZggfR3pNM+4jeC8nt2OxZZj - cxwCXWj82GVGdw== ) - xx.example. 3600 IN AAAA 2001:db8::f00:baaa - xx.example. 3600 IN RRSIG AAAA 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - rto7afZkXYB17IfmQCT5QoEMMrlkeOoAGXzo - w8Wmcg86Fc+MQP0hyXFScI1gYNSgSSoDMXIy - rzKKwb8J04/ILw== ) - ns1.example. 3600 IN A 192.0.2.1 - ns1.example. 3600 IN RRSIG A 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - QLGkaqWXxRuE+MHKkMvVlswg65HcyjvD1fyb - BDZpcfiMHH9w4x1eRqRamtSDTcqLfUrcYkrr - nWWLepz1PjjShQ== ) - ns2.example. 3600 IN A 192.0.2.2 - ns2.example. 3600 IN RRSIG A 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - UoIZaC1O6XHRWGHBOl8XFQKPdYTkRCz6SYh3 - P2mZ3xfY22fLBCBDrEnOc8pGDGijJaLl26Cz - AkeTJu3J3auUiA== ) - - - - -Laurie, et al. Expires August 5, 2006 [Page 28] - -Internet-Draft nsec3 February 2006 - - - The query returned an MX RRset for "x.w.example". The corresponding - RRSIG RR indicates that the MX RRset was signed by an "example" - DNSKEY with algorithm 5 and key tag 62699. The resolver needs the - corresponding DNSKEY RR in order to authenticate this answer. The - discussion below describes how a resolver might obtain this DNSKEY - RR. - - The RRSIG RR indicates the original TTL of the MX RRset was 3600, - and, for the purpose of authentication, the current TTL is replaced - by 3600. The RRSIG RR's labels field value of 3 indicates that the - answer was not the result of wildcard expansion. The "x.w.example" - MX RRset is placed in canonical form, and, assuming the current time - falls between the signature inception and expiration dates, the - signature is authenticated. - -B.1.1. Authenticating the Example DNSKEY RRset - - This example shows the logical authentication process that starts - from a configured root DNSKEY RRset (or DS RRset) and moves down the - tree to authenticate the desired "example" DNSKEY RRset. Note that - the logical order is presented for clarity. An implementation may - choose to construct the authentication as referrals are received or - to construct the authentication chain only after all RRsets have been - obtained, or in any other combination it sees fit. The example here - demonstrates only the logical process and does not dictate any - implementation rules. - - We assume the resolver starts with a configured DNSKEY RRset for the - root zone (or a configured DS RRset for the root zone). The resolver - checks whether this configured DNSKEY RRset is present in the root - DNSKEY RRset (or whether a DS RR in the DS RRset matches some DNSKEY - RR in the root DNSKEY RRset), whether this DNSKEY RR has signed the - root DNSKEY RRset, and whether the signature lifetime is valid. If - all these conditions are met, all keys in the DNSKEY RRset are - considered authenticated. The resolver then uses one (or more) of - the root DNSKEY RRs to authenticate the "example" DS RRset. Note - that the resolver may have to query the root zone to obtain the root - DNSKEY RRset or "example" DS RRset. - - Once the DS RRset has been authenticated using the root DNSKEY, the - resolver checks the "example" DNSKEY RRset for some "example" DNSKEY - RR that matches one of the authenticated "example" DS RRs. If such a - matching "example" DNSKEY is found, the resolver checks whether this - DNSKEY RR has signed the "example" DNSKEY RRset and the signature - lifetime is valid. If these conditions are met, all keys in the - "example" DNSKEY RRset are considered authenticated. - - Finally, the resolver checks that some DNSKEY RR in the "example" - - - -Laurie, et al. Expires August 5, 2006 [Page 29] - -Internet-Draft nsec3 February 2006 - - - DNSKEY RRset uses algorithm 5 and has a key tag of 62699. This - DNSKEY is used to authenticate the RRSIG included in the response. - If multiple "example" DNSKEY RRs match this algorithm and key tag, - then each DNSKEY RR is tried, and the answer is authenticated if any - of the matching DNSKEY RRs validate the signature as described above. - -B.2. Name Error - - An authoritative name error. The NSEC3 RRs prove that the name does - not exist and that no covering wildcard exists. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Laurie, et al. Expires August 5, 2006 [Page 30] - -Internet-Draft nsec3 February 2006 - - - ;; Header: QR AA DO RCODE=3 - ;; - ;; Question - a.c.x.w.example. IN A - - ;; Answer - ;; (empty) - - ;; Authority - example. 3600 IN SOA ns1.example. bugs.x.w.example. ( - 1 - 3600 - 300 - 3600000 - 3600 - ) - example. 3600 IN RRSIG SOA 5 1 3600 20050712112304 ( - 20050612112304 62699 example. - RtctD6aLUU5Md5wOOItilS7JXX1tf58Ql3sK - mTXkL13jqLiUFOGg0uzqRh1U9GbydS0P7M0g - qYIt90txzE/4+g== ) - 7nomf47k3vlidh4vxahhpp47l3tgv7a2.example. 3600 IN NSEC3 0 1 1 ( - deadbeaf - dw4o7j64wnel3j4jh7fb3c5n7w3js2yb - MX NSEC3 RRSIG ) - 7nomf47k3vlidh4vxahhpp47l3tgv7a2.example. 3600 IN RRSIG NSEC3 ( - 5 2 3600 20050712112304 - 20050612112304 62699 example. - YTcqole3h8EOsTT3HKnwhR1QS8borR0XtZaA - ZrLsx6n0RDC1AAdZONYOvdqvcal9PmwtWjlo - MEFQmc/gEuxojA== ) - nimwfwcnbeoodmsc6npv3vuaagaevxxu.example. 3600 IN NSEC3 0 1 1 ( - deadbeaf - vhgwr2qgykdkf4m6iv6vkagbxozphazr - HINFO A AAAA NSEC3 RRSIG ) - nimwfwcnbeoodmsc6npv3vuaagaevxxu.example. 3600 IN RRSIG NSEC3 ( - 5 2 3600 20050712112304 - 20050612112304 62699 example. - c3zQdK68cYTHTjh1cD6pi0vblXwzyoU/m7Qx - z8kaPYikbJ9vgSl9YegjZukgQSwybHUC0SYG - jL33Wm1p07TBdw== ) - ;; Additional - ;; (empty) - - The query returned two NSEC3 RRs that prove that the requested data - does not exist and no wildcard applies. The negative reply is - authenticated by verifying both NSEC3 RRs. The NSEC3 RRs are - authenticated in a manner identical to that of the MX RRset discussed - - - -Laurie, et al. Expires August 5, 2006 [Page 31] - -Internet-Draft nsec3 February 2006 - - - above. At least one of the owner names of the NSEC3 RRs will match - the closest encloser. At least one of the NSEC3 RRs prove that there - exists no longer name. At least one of the NSEC3 RRs prove that - there exists no wildcard RRsets that should have been expanded. The - closest encloser can be found by hashing the apex ownername (The SOA - RR's ownername, or the ownername of the DNSKEY RRset referred by an - RRSIG RR), matching it to the ownername of one of the NSEC3 RRs, and - if that fails, continue by adding labels. In other words, the - resolver first hashes example, checks for a matching NSEC3 ownername, - then hashes w.example, checks, and finally hashes w.x.example and - checks. - - In the above example, the name 'x.w.example' hashes to - '7nomf47k3vlidh4vxahhpp47l3tgv7a2'. This indicates that this might - be the closest encloser. To prove that 'c.x.w.example' and - '*.x.w.example' do not exists, these names are hashed to respectively - 'qsgoxsf2lanysajhtmaylde4tqwnqppl' and - 'cvljzyf6nsckjowghch4tt3nohocpdka'. The two NSEC3 records prove that - these hashed ownernames do not exists, since the names are within the - given intervals. - -B.3. No Data Error - - A "no data" response. The NSEC3 RR proves that the name exists and - that the requested RR type does not. - - - - - - - - - - - - - - - - - - - - - - - - - - -Laurie, et al. Expires August 5, 2006 [Page 32] - -Internet-Draft nsec3 February 2006 - - - ;; Header: QR AA DO RCODE=0 - ;; - ;; Question - ns1.example. IN MX - - ;; Answer - ;; (empty) - - ;; Authority - example. 3600 IN SOA ns1.example. bugs.x.w.example. ( - 1 - 3600 - 300 - 3600000 - 3600 - ) - example. 3600 IN RRSIG SOA 5 1 3600 20050712112304 ( - 20050612112304 62699 example. - RtctD6aLUU5Md5wOOItilS7JXX1tf58Ql3sK - mTXkL13jqLiUFOGg0uzqRh1U9GbydS0P7M0g - qYIt90txzE/4+g== ) - wbyijvpnyj33pcpi3i44ecnibnaj7eiw.example. 3600 IN NSEC3 0 1 1 ( - deadbeaf - zjxfz5o7t4ty4u3f6fa7mhhqzjln4mui - A NSEC3 RRSIG ) - wbyijvpnyj33pcpi3i44ecnibnaj7eiw.example. 3600 IN RRSIG NSEC3 ( - 5 2 3600 20050712112304 - 20050612112304 62699 example. - ledFAaDCqDxapQ1FvBAjjK2DP06iQj8AN6gN - ZycTeSmobKLTpzbgQp8uKYYe/DPHjXYmuEhd - oorBv4xkb0flXw== ) - ;; Additional - ;; (empty) - - The query returned an NSEC3 RR that proves that the requested name - exists ("ns1.example." hashes to "wbyijvpnyj33pcpi3i44ecnibnaj7eiw"), - but the requested RR type does not exist (type MX is absent in the - type code list of the NSEC RR). The negative reply is authenticated - by verifying the NSEC3 RR. The NSEC3 RR is authenticated in a manner - identical to that of the MX RRset discussed above. - -B.3.1. No Data Error, Empty Non-Terminal - - A "no data" response because of an empty non-terminal. The NSEC3 RR - proves that the name exists and that the requested RR type does not. - - - - - - -Laurie, et al. Expires August 5, 2006 [Page 33] - -Internet-Draft nsec3 February 2006 - - - ;; Header: QR AA DO RCODE=0 - ;; - ;; Question - y.w.example. IN A - - ;; Answer - ;; (empty) - - ;; Authority - example. 3600 IN SOA ns1.example. bugs.x.w.example. ( - 1 - 3600 - 300 - 3600000 - 3600 - ) - example. 3600 IN RRSIG SOA 5 1 3600 20050712112304 ( - 20050612112304 62699 example. - RtctD6aLUU5Md5wOOItilS7JXX1tf58Ql3sK - mTXkL13jqLiUFOGg0uzqRh1U9GbydS0P7M0g - qYIt90txzE/4+g== ) - jt4bbfokgbmr57qx4nqucvvn7fmo6ab6.example. 3600 IN NSEC3 0 1 1 ( - deadbeaf - kcll7fqfnisuhfekckeeqnmbbd4maanu - NSEC3 RRSIG ) - jt4bbfokgbmr57qx4nqucvvn7fmo6ab6.example. 3600 IN RRSIG NSEC3 ( - 5 2 3600 20050712112304 - 20050612112304 62699 example. - FXyCVQUdFF1EW1NcgD2V724/It0rn3lr+30V - IyjmqwOMvQ4G599InTpiH46xhX3U/FmUzHOK - 94Zbq3k8lgdpZA== ) - - The query returned an NSEC3 RR that proves that the requested name - exists ("y.w.example." hashes to "jt4bbfokgbmr57qx4nqucvvn7fmo6ab6"), - but the requested RR type does not exist (Type A is absent in the - type-bit-maps of the NSEC3 RR). The negative reply is authenticated - by verifying the NSEC3 RR. The NSEC3 RR is authenticated in a manner - identical to that of the MX RRset discussed above. Note that, unlike - generic empty non terminal proof using NSECs, this is identical to - proving a No Data Error. This example is solely mentioned to be - complete. - -B.4. Referral to Signed Zone - - Referral to a signed zone. The DS RR contains the data which the - resolver will need to validate the corresponding DNSKEY RR in the - child zone's apex. - - - - -Laurie, et al. Expires August 5, 2006 [Page 34] - -Internet-Draft nsec3 February 2006 - - - ;; Header: QR DO RCODE=0 - ;; - - ;; Question - mc.a.example. IN MX - - ;; Answer - ;; (empty) - - ;; Authority - a.example. 3600 IN NS ns1.a.example. - a.example. 3600 IN NS ns2.a.example. - a.example. 3600 IN DS 58470 5 1 ( - 3079F1593EBAD6DC121E202A8B766A6A4837 - 206C ) - a.example. 3600 IN RRSIG DS 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - QavhbsSmEvJLSUzGoTpsV3SKXCpaL1UO3Ehn - cB0ObBIlex/Zs9kJyG/9uW1cYYt/1wvgzmX2 - 0kx7rGKTc3RQDA== ) - - ;; Additional - ns1.a.example. 3600 IN A 192.0.2.5 - ns2.a.example. 3600 IN A 192.0.2.6 - - The query returned a referral to the signed "a.example." zone. The - DS RR is authenticated in a manner identical to that of the MX RRset - discussed above. This DS RR is used to authenticate the "a.example" - DNSKEY RRset. - - Once the "a.example" DS RRset has been authenticated using the - "example" DNSKEY, the resolver checks the "a.example" DNSKEY RRset - for some "a.example" DNSKEY RR that matches the DS RR. If such a - matching "a.example" DNSKEY is found, the resolver checks whether - this DNSKEY RR has signed the "a.example" DNSKEY RRset and whether - the signature lifetime is valid. If all these conditions are met, - all keys in the "a.example" DNSKEY RRset are considered - authenticated. - -B.5. Referral to Unsigned Zone using the Opt-In Flag - - The NSEC3 RR proves that nothing for this delegation was signed in - the parent zone. There is no proof that the delegation exists - - - - - - - - -Laurie, et al. Expires August 5, 2006 [Page 35] - -Internet-Draft nsec3 February 2006 - - - ;; Header: QR DO RCODE=0 - ;; - ;; Question - mc.b.example. IN MX - - ;; Answer - ;; (empty) - - ;; Authority - b.example. 3600 IN NS ns1.b.example. - b.example. 3600 IN NS ns2.b.example. - kcll7fqfnisuhfekckeeqnmbbd4maanu.example. 3600 IN NSEC3 1 1 1 ( - deadbeaf - n42hbhnjj333xdxeybycax5ufvntux5d - MX NSEC3 RRSIG ) - kcll7fqfnisuhfekckeeqnmbbd4maanu.example. 3600 IN RRSIG NSEC3 ( - 5 2 3600 20050712112304 - 20050612112304 62699 example. - d0g8MTOvVwByOAIwvYV9JrTHwJof1VhnMKuA - IBj6Xaeney86RBZYgg7Qyt9WnQSK3uCEeNpx - TOLtc5jPrkL4zQ== ) - - ;; Additional - ns1.b.example. 3600 IN A 192.0.2.7 - ns2.b.example. 3600 IN A 192.0.2.8 - - The query returned a referral to the unsigned "b.example." zone. The - NSEC3 proves that no authentication leads from "example" to - "b.example", since the hash of "b.example" - ("ldjpfcucebeks5azmzpty4qlel4cftzo") is within the NSEC3 interval and - the NSEC3 opt-in bit is set. The NSEC3 RR is authenticated in a - manner identical to that of the MX RRset discussed above. - -B.6. Wildcard Expansion - - A successful query that was answered via wildcard expansion. The - label count in the answer's RRSIG RR indicates that a wildcard RRset - was expanded to produce this response, and the NSEC3 RR proves that - no closer match exists in the zone. - - - - - - - - - - - - -Laurie, et al. Expires August 5, 2006 [Page 36] - -Internet-Draft nsec3 February 2006 - - - ;; Header: QR AA DO RCODE=0 - ;; - ;; Question - a.z.w.example. IN MX - - ;; Answer - a.z.w.example. 3600 IN MX 1 ai.example. - a.z.w.example. 3600 IN RRSIG MX 5 3 3600 20050712112304 ( - 20050612112304 62699 example. - sYNUPHn1/gJ87wTHNksGdRm3vfnSFa2BbofF - xGfJLF5A4deRu5f0hvxhAFDCcXfIASj7z0wQ - gQlgxEwhvQDEaQ== ) - ;; Authority - example. 3600 NS ns1.example. - example. 3600 NS ns2.example. - example. 3600 IN RRSIG NS 5 1 3600 20050712112304 ( - 20050612112304 62699 example. - hNyyin2JpECIFxW4vsj8RhHcWCQKUXgO+z4l - m7g2zM8q3Qpsm/gYIXSF2Rhj6lAG7esR/X9d - 1SH5r/wfjuCg+g== ) - zjxfz5o7t4ty4u3f6fa7mhhqzjln4mui.example. 3600 IN NSEC3 0 1 1 ( - deadbeaf - 5pe7ctl7pfs2cilroy5dcofx4rcnlypd - MX NSEC3 RRSIG ) - zjxfz5o7t4ty4u3f6fa7mhhqzjln4mui.example. 3600 IN RRSIG NSEC3 ( - 5 2 3600 20050712112304 - 20050612112304 62699 example. - eULkdWjcjmM+wXQcr7zXNfnGLgHjZSJINGkt - 7Zmvp7WKVAqoHMm1RXV8IfBH1aRgv5+/Lgny - OcFlrPGPMm48/A== ) - ;; Additional - ai.example. 3600 IN A 192.0.2.9 - ai.example. 3600 IN RRSIG A 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - plY5M26ED3Owe3YX0pBIhgg44j89NxUaoBrU - 6bLRr99HpKfFl1sIy18JiRS7evlxCETZgubq - ZXW5S+1VjMZYzQ== ) - ai.example. 3600 AAAA 2001:db8::f00:baa9 - ai.example. 3600 IN RRSIG AAAA 5 2 3600 20050712112304 ( - 20050612112304 62699 example. - PNF/t7+DeosEjhfuL0kmsNJvn16qhYyLI9FV - ypSCorFx/PKIlEL3syomkYM2zcXVSRwUXMns - l5/UqLCJJ9BDMg== ) - - The query returned an answer that was produced as a result of - wildcard expansion. The answer section contains a wildcard RRset - expanded as it would be in a traditional DNS response, and the - corresponding RRSIG indicates that the expanded wildcard MX RRset was - - - -Laurie, et al. Expires August 5, 2006 [Page 37] - -Internet-Draft nsec3 February 2006 - - - signed by an "example" DNSKEY with algorithm 5 and key tag 62699. - The RRSIG indicates that the original TTL of the MX RRset was 3600, - and, for the purpose of authentication, the current TTL is replaced - by 3600. The RRSIG labels field value of 2 indicates that the answer - is the result of wildcard expansion, as the "a.z.w.example" name - contains 4 labels. The name "a.z.w.example" is replaced by - "*.w.example", the MX RRset is placed in canonical form, and, - assuming that the current time falls between the signature inception - and expiration dates, the signature is authenticated. - - The NSEC3 proves that no closer match (exact or closer wildcard) - could have been used to answer this query, and the NSEC3 RR must also - be authenticated before the answer is considered valid. - -B.7. Wildcard No Data Error - - A "no data" response for a name covered by a wildcard. The NSEC3 RRs - prove that the matching wildcard name does not have any RRs of the - requested type and that no closer match exists in the zone. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Laurie, et al. Expires August 5, 2006 [Page 38] - -Internet-Draft nsec3 February 2006 - - - ;; Header: QR AA DO RCODE=0 - ;; - ;; Question - a.z.w.example. IN AAAA - - ;; Answer - ;; (empty) - - ;; Authority - example. 3600 IN SOA ns1.example. bugs.x.w.example. ( - 1 - 3600 - 300 - 3600000 - 3600 - ) - example. 3600 IN RRSIG SOA 5 1 3600 20050712112304 ( - 20050612112304 62699 example. - RtctD6aLUU5Md5wOOItilS7JXX1tf58Ql3sK - mTXkL13jqLiUFOGg0uzqRh1U9GbydS0P7M0g - qYIt90txzE/4+g== ) - zjxfz5o7t4ty4u3f6fa7mhhqzjln4mui.example. 3600 IN NSEC3 0 1 1 ( - deadbeaf - 5pe7ctl7pfs2cilroy5dcofx4rcnlypd - MX NSEC3 RRSIG ) - zjxfz5o7t4ty4u3f6fa7mhhqzjln4mui.example. 3600 IN RRSIG NSEC3 ( - 5 2 3600 20050712112304 - 20050612112304 62699 example. - eULkdWjcjmM+wXQcr7zXNfnGLgHjZSJINGkt - 7Zmvp7WKVAqoHMm1RXV8IfBH1aRgv5+/Lgny - OcFlrPGPMm48/A== ) - ;; Additional - ;; (empty) - - The query returned NSEC3 RRs that prove that the requested data does - not exist and no wildcard applies. The negative reply is - authenticated by verifying both NSEC3 RRs. - -B.8. DS Child Zone No Data Error - - A "no data" response for a QTYPE=DS query that was mistakenly sent to - a name server for the child zone. - - - - - - - - - -Laurie, et al. Expires August 5, 2006 [Page 39] - -Internet-Draft nsec3 February 2006 - - - ;; Header: QR AA DO RCODE=0 - ;; - ;; Question - example. IN DS - - ;; Answer - ;; (empty) - - ;; Authority - example. 3600 IN SOA ns1.example. bugs.x.w.example. ( - 1 - 3600 - 300 - 3600000 - 3600 - ) - example. 3600 IN RRSIG SOA 5 1 3600 20050712112304 ( - 20050612112304 62699 example. - RtctD6aLUU5Md5wOOItilS7JXX1tf58Ql3sK - mTXkL13jqLiUFOGg0uzqRh1U9GbydS0P7M0g - qYIt90txzE/4+g== ) - dw4o7j64wnel3j4jh7fb3c5n7w3js2yb.example. 3600 IN NSEC3 0 1 1 ( - deadbeaf - gmnfcccja7wkax3iv26bs75myptje3qk - MX DNSKEY NS SOA NSEC3 RRSIG ) - dw4o7j64wnel3j4jh7fb3c5n7w3js2yb.example. 3600 IN RRSIG NSEC3 ( - 5 2 3600 20050712112304 - 20050612112304 62699 example. - VqEbXiZLJVYmo25fmO3IuHkAX155y8NuA50D - C0NmJV/D4R3rLm6tsL6HB3a3f6IBw6kKEa2R - MOiKMSHozVebqw== ) - - ;; Additional - ;; (empty) - - The query returned NSEC RRs that shows the requested was answered by - a child server ("example" server). The NSEC RR indicates the - presence of an SOA RR, showing that the answer is from the child . - Queries for the "example" DS RRset should be sent to the parent - servers ("root" servers). - - - - - - - - - - - -Laurie, et al. Expires August 5, 2006 [Page 40] - -Internet-Draft nsec3 February 2006 - - -Authors' Addresses - - Ben Laurie - Nominet - 17 Perryn Road - London W3 7LR - England - - Phone: +44 (20) 8735 0686 - Email: ben@algroup.co.uk - - - Geoffrey Sisson - Nominet - - - Roy Arends - Nominet - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Laurie, et al. Expires August 5, 2006 [Page 41] - -Internet-Draft nsec3 February 2006 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2006). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Laurie, et al. Expires August 5, 2006 [Page 42] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-nsid-01.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-nsid-01.txt deleted file mode 100644 index 90d1a06..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-nsid-01.txt +++ /dev/null @@ -1,840 +0,0 @@ - - - -Network Working Group R. Austein -Internet-Draft ISC -Expires: July 15, 2006 January 11, 2006 - - - DNS Name Server Identifier Option (NSID) - draft-ietf-dnsext-nsid-01 - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on July 15, 2006. - -Copyright Notice - - Copyright (C) The Internet Society (2006). - -Abstract - - With the increased use of DNS anycast, load balancing, and other - mechanisms allowing more than one DNS name server to share a single - IP address, it is sometimes difficult to tell which of a pool of name - servers has answered a particular query. While existing ad-hoc - mechanism allow an operator to send follow-up queries when it is - necessary to debug such a configuration, the only completely reliable - way to obtain the identity of the name server which responded is to - have the name server include this information in the response itself. - This note defines a protocol extension to support this functionality. - - - -Austein Expires July 15, 2006 [Page 1] - -Internet-Draft DNS NSID January 2006 - - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 1.1. Reserved Words . . . . . . . . . . . . . . . . . . . . . . 3 - 2. Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 - 2.1. Resolver Behavior . . . . . . . . . . . . . . . . . . . . 4 - 2.2. Name Server Behavior . . . . . . . . . . . . . . . . . . . 4 - 2.3. The NSID Option . . . . . . . . . . . . . . . . . . . . . 4 - 2.4. Presentation Format . . . . . . . . . . . . . . . . . . . 5 - 3. Discussion . . . . . . . . . . . . . . . . . . . . . . . . . . 6 - 3.1. The NSID Payload . . . . . . . . . . . . . . . . . . . . . 6 - 3.2. NSID Is Not Transitive . . . . . . . . . . . . . . . . . . 8 - 3.3. User Interface Issues . . . . . . . . . . . . . . . . . . 8 - 3.4. Truncation . . . . . . . . . . . . . . . . . . . . . . . . 9 - 4. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 10 - 5. Security Considerations . . . . . . . . . . . . . . . . . . . 11 - 6. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 12 - 7. References . . . . . . . . . . . . . . . . . . . . . . . . . . 13 - 7.1. Normative References . . . . . . . . . . . . . . . . . . . 13 - 7.2. Informative References . . . . . . . . . . . . . . . . . . 13 - Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 14 - Intellectual Property and Copyright Statements . . . . . . . . . . 15 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Austein Expires July 15, 2006 [Page 2] - -Internet-Draft DNS NSID January 2006 - - -1. Introduction - - With the increased use of DNS anycast, load balancing, and other - mechanisms allowing more than one DNS name server to share a single - IP address, it is sometimes difficult to tell which of a pool of name - servers has answered a particular query. - - Existing ad-hoc mechanisms allow an operator to send follow-up - queries when it is necessary to debug such a configuration, but there - are situations in which this is not a totally satisfactory solution, - since anycast routing may have changed, or the server pool in - question may be behind some kind of extremely dynamic load balancing - hardware. Thus, while these ad-hoc mechanisms are certainly better - than nothing (and have the advantage of already being deployed), a - better solution seems desirable. - - Given that a DNS query is an idempotent operation with no retained - state, it would appear that the only completely reliable way to - obtain the identity of the name server which responded to a - particular query is to have that name server include identifying - information in the response itself. This note defines a protocol - enhancement to achieve this. - -1.1. Reserved Words - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in [RFC2119]. - - - - - - - - - - - - - - - - - - - - - - - -Austein Expires July 15, 2006 [Page 3] - -Internet-Draft DNS NSID January 2006 - - -2. Protocol - - This note uses an EDNS [RFC2671] option to signal the resolver's - desire for information identifying the name server and to hold the - name server's response, if any. - -2.1. Resolver Behavior - - A resolver signals its desire for information identifying a name - server by sending an empty NSID option (Section 2.3) in an EDNS OPT - pseudo-RR in the query message. - - The resolver MUST NOT include any NSID payload data in the query - message. - - The semantics of an NSID request are not transitive. That is: the - presence of an NSID option in a query is a request that the name - server which receives the query identify itself. If the name server - side of a recursive name server receives an NSID request, the client - is asking the recursive name server to identify itself; if the - resolver side of the recursive name server wishes to receive - identifying information, it is free to add NSID requests in its own - queries, but that is a separate matter. - -2.2. Name Server Behavior - - A name server which understands the NSID option and chooses to honor - a particular NSID request responds by including identifying - information in a NSID option (Section 2.3) in an EDNS OPT pseudo-RR - in the response message. - - The name server MUST ignore any NSID payload data that might be - present in the query message. - - The NSID option is not transitive. A name server MUST NOT send an - NSID option back to a resolver which did not request it. In - particular, while a recursive name server may choose to add an NSID - option when sending a query, this has no effect on the presence or - absence of the NSID option in the recursive name server's response to - the original client. - - As stated in Section 2.1, this mechanism is not restricted to - authoritative name servers; the semantics are intended to be equally - applicable to recursive name servers. - -2.3. The NSID Option - - The OPTION-CODE for the NSID option is [TBD]. - - - -Austein Expires July 15, 2006 [Page 4] - -Internet-Draft DNS NSID January 2006 - - - The OPTION-DATA for the NSID option is an opaque byte string the - semantics of which are deliberately left outside the protocol. See - Section 3.1 for discussion. - -2.4. Presentation Format - - User interfaces MUST read and write the content of the NSID option as - a sequence of hexadecimal digits, two digits per payload octet. - - The NSID payload is binary data. Any comparison between NSID - payloads MUST be a comparison of the raw binary data. Copy - operations MUST NOT assume that the raw NSID payload is null- - terminated. Any resemblance between raw NSID payload data and any - form of text is purely a convenience, and does not change the - underlying nature of the payload data. - - See Section 3.3 for discussion. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Austein Expires July 15, 2006 [Page 5] - -Internet-Draft DNS NSID January 2006 - - -3. Discussion - - This section discusses certain aspects of the protocol and explains - considerations that led to the chosen design. - -3.1. The NSID Payload - - The syntax and semantics of the content of the NSID option is - deliberately left outside the scope of this specification. This - section describe some of the kinds of data that server administrators - might choose to provide as the content of the NSID option, and - explains the reasoning behind choosing a simple opaque byte string. - - There are several possibilities for the payload of the NSID option: - - o It could be the "real" name of the specific name server within the - name server pool. - - o It could be the "real" IP address (IPv4 or IPv6) of the name - server within the name server pool. - - o It could be some sort of pseudo-random number generated in a - predictable fashion somehow using the server's IP address or name - as a seed value. - - o It could be some sort of probabilisticly unique identifier - initially derived from some sort of random number generator then - preserved across reboots of the name server. - - o It could be some sort of dynamicly generated identifier so that - only the name server operator could tell whether or not any two - queries had been answered by the same server. - - o It could be a blob of signed data, with a corresponding key which - might (or might not) be available via DNS lookups. - - o It could be a blob of encrypted data, the key for which could be - restricted to parties with a need to know (in the opinion of the - server operator). - - o It could be an arbitrary string of octets chosen at the discretion - of the name server operator. - - Each of these options has advantages and disadvantages: - - o Using the "real" name is simple, but the name server may not have - a "real" name. - - - - -Austein Expires July 15, 2006 [Page 6] - -Internet-Draft DNS NSID January 2006 - - - o Using the "real" address is also simple, and the name server - almost certainly does have at least one non-anycast IP address for - maintenance operations, but the operator of the name server may - not be willing to divulge its non-anycast address. - - o Given that one common reason for using anycast DNS techniques is - an attempt to harden a critical name server against denial of - service attacks, some name server operators are likely to want an - identifier other than the "real" name or "real" address of the - name server instance. - - o Using a hash or pseudo-random number can provide a fixed length - value that the resolver can use to tell two name servers apart - without necessarily being able to tell where either one of them - "really" is, but makes debugging more difficult if one happens to - be in a friendly open environment. Furthermore, hashing might not - add much value, since a hash based on an IPv4 address still only - involves a 32-bit search space, and DNS names used for servers - that operators might have to debug at 4am tend not to be very - random. - - o Probabilisticly unique identifiers have similar properties to - hashed identifiers, but (given a sufficiently good random number - generator) are immune to the search space issues. However, the - strength of this approach is also its weakness: there is no - algorithmic transformation by which even the server operator can - associate name server instances with identifiers while debugging, - which might be annoying. This approach also requires the name - server instance to preserve the probabilisticly unique identifier - across reboots, but this does not appear to be a serious - restriction, since authoritative nameservers almost always have - some form of nonvolatile storage in any case, and in the rare case - of a name server that does not have any way to store such an - identifier, nothing terrible will happen if the name server just - generates a new identifier every time it reboots. - - o Using an arbitrary octet string gives name server operators yet - another thing to configure, or mis-configure, or forget to - configure. Having all the nodes in an anycast name server - constellation identify themselves as "My Name Server" would not be - particularly useful. - - Given all of the issues listed above, there does not appear to be a - single solution that will meet all needs. Section 2.3 therefore - defines the NSID payload to be an opaque byte string and leaves the - choice up to the implementor and name server operator. The following - guidelines may be useful to implementors and server operators: - - - - -Austein Expires July 15, 2006 [Page 7] - -Internet-Draft DNS NSID January 2006 - - - o Operators for whom divulging the unicast address is an issue could - use the raw binary representation of a probabilisticly unique - random number. This should probably be the default implementation - behavior. - - o Operators for whom divulging the unicast address is not an issue - could just use the raw binary representation of a unicast address - for simplicity. This should only be done via an explicit - configuration choice by the operator. - - o Operators who really need or want the ability to set the NSID - payload to an arbitrary value could do so, but this should only be - done via an explicit configuration choice by the operator. - - This approach appears to provide enough information for useful - debugging without unintentionally leaking the maintenance addresses - of anycast name servers to nogoodniks, while also allowing name - server operators who do not find such leakage threatening to provide - more information at their own discretion. - -3.2. NSID Is Not Transitive - - As specified in Section 2.1 and Section 2.2, the NSID option is not - transitive. This is strictly a hop-by-hop mechanism. - - Most of the discussion of name server identification to date has - focused on identifying authoritative name servers, since the best - known cases of anycast name servers are a subset of the name servers - for the root zone. However, given that anycast DNS techniques are - also applicable to recursive name servers, the mechanism may also be - useful with recursive name servers. The hop-by-hop semantics support - this. - - While there might be some utility in having a transitive variant of - this mechanism (so that, for example, a stub resolver could ask a - recursive server to tell it which authoritative name server provided - a particular answer to the recursive name server), the semantics of - such a variant would be more complicated, and are left for future - work. - -3.3. User Interface Issues - - Given the range of possible payload contents described in - Section 3.1, it is not possible to define a single presentation - format for the NSID payload that is efficient, convenient, - unambiguous, and aesthetically pleasing. In particular, while it is - tempting to use a presentation format that uses some form of textual - strings, attempting to support this would significantly complicate - - - -Austein Expires July 15, 2006 [Page 8] - -Internet-Draft DNS NSID January 2006 - - - what's intended to be a very simple debugging mechanism. - - In some cases the content of the NSID payload may be binary data - meaningful only to the name server operator, and may not be - meaningful to the user or application, but the user or application - must be able to capture the entire content anyway in order for it to - be useful. Thus, the presentation format must support arbitrary - binary data. - - In cases where the name server operator derives the NSID payload from - textual data, a textual form such as US-ASCII or UTF-8 strings might - at first glance seem easier for a user to deal with. There are, - however, a number of complex issues involving internationalized text - which, if fully addressed here, would require a set of rules - significantly longer than the rest of this specification. See - [RFC2277] for an overview of some of these issues. - - It is much more important for the NSID payload data to be passed - unambiguously from server administrator to user and back again than - it is for the payload data data to be pretty while in transit. In - particular, it's critical that it be straightforward for a user to - cut and paste an exact copy of the NSID payload output by a debugging - tool into other formats such as email messages or web forms without - distortion. Hexadecimal strings, while ugly, are also robust. - -3.4. Truncation - - In some cases, adding the NSID option to a response message may - trigger message truncation. This specification does not change the - rules for DNS message truncation in any way, but implementors will - need to pay attention to this issue. - - Including the NSID option in a response is always optional, so this - specification never requires name servers to truncate response - messages. - - By definition, a resolver that requests NSID responses also supports - EDNS, so a resolver that requests NSID responses can also use the - "sender's UDP payload size" field of the OPT pseudo-RR to signal a - receive buffer size large enough to make truncation unlikely. - - - - - - - - - - - -Austein Expires July 15, 2006 [Page 9] - -Internet-Draft DNS NSID January 2006 - - -4. IANA Considerations - - This mechanism requires allocation of one ENDS option code for the - NSID option (Section 2.3). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Austein Expires July 15, 2006 [Page 10] - -Internet-Draft DNS NSID January 2006 - - -5. Security Considerations - - This document describes a channel signaling mechanism, intended - primarily for debugging. Channel signaling mechanisms are outside - the scope of DNSSEC per se. Applications that require integrity - protection for the data being signaled will need to use a channel - security mechanism such as TSIG [RFC2845]. - - Section 3.1 discusses a number of different kinds of information that - a name server operator might choose to provide as the value of the - NSID option. Some of these kinds of information are security - sensitive in some environments. This specification deliberately - leaves the syntax and semantics of the NSID option content up to the - implementation and the name server operator. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Austein Expires July 15, 2006 [Page 11] - -Internet-Draft DNS NSID January 2006 - - -6. Acknowledgements - - Joe Abley, Harald Alvestrand, Mark Andrews, Roy Arends, Steve - Bellovin, Randy Bush, David Conrad, Johan Ihren, Daniel Karrenberg, - Peter Koch, Mike Patton, Mike StJohns, Paul Vixie, Sam Weiler, and - Suzanne Woolf. Apologies to anyone inadvertently omitted from the - above list. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Austein Expires July 15, 2006 [Page 12] - -Internet-Draft DNS NSID January 2006 - - -7. References - -7.1. Normative References - - [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", RFC 2119, BCP 14, March 1997. - - [RFC2671] Vixie, P., "Extension Mechanisms for DNS (EDNS0)", - RFC 2671, August 1999. - - [RFC2845] Vixie, P., Gudmundsson, O., Eastlake 3rd, D., and B. - Wellington, "Secret Key Transaction Authentication for DNS - (TSIG)", RFC 2845, May 2000. - -7.2. Informative References - - [RFC2277] Alvestrand, H., "IETF Policy on Character Sets and - Languages", RFC 2277, BCP 18, January 1998. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Austein Expires July 15, 2006 [Page 13] - -Internet-Draft DNS NSID January 2006 - - -Author's Address - - Rob Austein - ISC - 950 Charter Street - Redwood City, CA 94063 - USA - - Email: sra@isc.org - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Austein Expires July 15, 2006 [Page 14] - -Internet-Draft DNS NSID January 2006 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2006). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Austein Expires July 15, 2006 [Page 15] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-rfc2536bis-dsa-06.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-rfc2536bis-dsa-06.txt deleted file mode 100644 index 5b6d655..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-rfc2536bis-dsa-06.txt +++ /dev/null @@ -1,464 +0,0 @@ - -INTERNET-DRAFT DSA Information in the DNS -OBSOLETES: RFC 2536 Donald E. Eastlake 3rd - Motorola Laboratories -Expires: January 2006 July 2005 - - - DSA Keying and Signature Information in the DNS - --- ------ --- --------- ----------- -- --- --- - - Donald E. Eastlake 3rd - - -Status of This Document - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Distribution of this document is unlimited. Comments should be sent - to the DNS extensions working group mailing list - . - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than a "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/1id-abstracts.html - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html - - -Abstract - - The standard method of encoding US Government Digital Signature - Algorithm keying and signature information for use in the Domain Name - System is specified. - - -Copyright Notice - - Copyright (C) The Internet Society 2005. All Rights Reserved. - - - - - -D. Eastlake 3rd [Page 1] - - -INTERNET-DRAFT DSA Information in the DNS - - -Table of Contents - - Status of This Document....................................1 - Abstract...................................................1 - Copyright Notice...........................................1 - - Table of Contents..........................................2 - - 1. Introduction............................................3 - 2. DSA Keying Information..................................3 - 3. DSA Signature Information...............................4 - 4. Performance Considerations..............................4 - 5. Security Considerations.................................5 - 6. IANA Considerations.....................................5 - Copyright and Disclaimer...................................5 - - Normative References.......................................7 - Informative References.....................................7 - - Authors Address............................................8 - Expiration and File Name...................................8 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -D. Eastlake 3rd [Page 2] - - -INTERNET-DRAFT DSA Information in the DNS - - -1. Introduction - - The Domain Name System (DNS) is the global hierarchical replicated - distributed database system for Internet addressing, mail proxy, and - other information [RFC 1034, 1035]. The DNS has been extended to - include digital signatures and cryptographic keys as described in - [RFC 4033, 4034, 4035] and additional work is underway which would - require the storage of keying and signature information in the DNS. - - This document describes how to encode US Government Digital Signature - Algorithm (DSA) keys and signatures in the DNS. Familiarity with the - US Digital Signature Algorithm is assumed [FIPS 186-2, Schneier]. - - - -2. DSA Keying Information - - When DSA public keys are stored in the DNS, the structure of the - relevant part of the RDATA part of the RR being used is the fields - listed below in the order given. - - The period of key validity is not included in this data but is - indicated separately, for example by an RR such as RRSIG which signs - and authenticates the RR containing the keying information. - - Field Size - ----- ---- - T 1 octet - Q 20 octets - P 64 + T*8 octets - G 64 + T*8 octets - Y 64 + T*8 octets - - As described in [FIPS 186-2] and [Schneier], T is a key size - parameter chosen such that 0 <= T <= 8. (The meaning if the T octet - is greater than 8 is reserved and the remainder of the data may have - a different format in that case.) Q is a prime number selected at - key generation time such that 2**159 < Q < 2**160. Thus Q is always - 20 octets long and, as with all other fields, is stored in "big- - endian" network order. P, G, and Y are calculated as directed by the - [FIPS 186-2] key generation algorithm [Schneier]. P is in the range - 2**(511+64T) < P < 2**(512+64T) and thus is 64 + 8*T octets long. G - and Y are quantities modulo P and so can be up to the same length as - P and are allocated fixed size fields with the same number of octets - as P. - - During the key generation process, a random number X must be - generated such that 1 <= X <= Q-1. X is the private key and is used - in the final step of public key generation where Y is computed as - - - -D. Eastlake 3rd [Page 3] - - -INTERNET-DRAFT DSA Information in the DNS - - - Y = G**X mod P - - - -3. DSA Signature Information - - The portion of the RDATA area used for US Digital Signature Algorithm - signature information is shown below with fields in the order they - are listed and the contents of each multi-octet field in "big-endian" - network order. - - Field Size - ----- ---- - T 1 octet - R 20 octets - S 20 octets - - First, the data signed must be determined. Then the following steps - are taken, as specified in [FIPS 186-2], where Q, P, G, and Y are as - specified in the public key [Schneier]: - - hash = SHA-1 ( data ) - - Generate a random K such that 0 < K < Q. - - R = ( G**K mod P ) mod Q - - S = ( K**(-1) * (hash + X*R) ) mod Q - - For information on the SHA-1 hash function see [FIPS 180-2] and [RFC - 3174]. - - Since Q is 160 bits long, R and S can not be larger than 20 octets, - which is the space allocated. - - T is copied from the public key. It is not logically necessary in - the SIG but is present so that values of T > 8 can more conveniently - be used as an escape for extended versions of DSA or other algorithms - as later standardized. - - - -4. Performance Considerations - - General signature generation speeds are roughly the same for RSA [RFC - 3110] and DSA. With sufficient pre-computation, signature generation - with DSA is faster than RSA. Key generation is also faster for DSA. - However, signature verification is an order of magnitude slower than - RSA when the RSA public exponent is chosen to be small, as is - recommended for some applications. - - -D. Eastlake 3rd [Page 4] - - -INTERNET-DRAFT DSA Information in the DNS - - - Current DNS implementations are optimized for small transfers, - typically less than 512 bytes including DNS overhead. Larger - transfers will perform correctly and extensions have been - standardized [RFC 2671] to make larger transfers more efficient, it - is still advisable at this time to make reasonable efforts to - minimize the size of RR sets containing keying and/or signature - inforamtion consistent with adequate security. - - - -5. Security Considerations - - Keys retrieved from the DNS should not be trusted unless (1) they - have been securely obtained from a secure resolver or independently - verified by the user and (2) this secure resolver and secure - obtainment or independent verification conform to security policies - acceptable to the user. As with all cryptographic algorithms, - evaluating the necessary strength of the key is essential and - dependent on local policy. - - The key size limitation of a maximum of 1024 bits ( T = 8 ) in the - current DSA standard may limit the security of DSA. For particular - applications, implementors are encouraged to consider the range of - available algorithms and key sizes. - - DSA assumes the ability to frequently generate high quality random - numbers. See [random] for guidance. DSA is designed so that if - biased rather than random numbers are used, high bandwidth covert - channels are possible. See [Schneier] and more recent research. The - leakage of an entire DSA private key in only two DSA signatures has - been demonstrated. DSA provides security only if trusted - implementations, including trusted random number generation, are - used. - - - -6. IANA Considerations - - Allocation of meaning to values of the T parameter that are not - defined herein (i.e., > 8 ) requires an IETF standards actions. It - is intended that values unallocated herein be used to cover future - extensions of the DSS standard. - - - -Copyright and Disclaimer - - Copyright (C) The Internet Society (2005). This document is subject to - the rights, licenses and restrictions contained in BCP 78, and except - as set forth therein, the authors retain all their rights. - - -D. Eastlake 3rd [Page 5] - - -INTERNET-DRAFT DSA Information in the DNS - - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -D. Eastlake 3rd [Page 6] - - -INTERNET-DRAFT DSA Information in the DNS - - -Normative References - - [FIPS 186-2] - U.S. Federal Information Processing Standard: Digital - Signature Standard, 27 January 2000. - - [RFC 4034] - Arends, R., Austein, R., Larson, M., Massey, D., and S. - Rose, "Resource Records for the DNS Security Extensions", RFC 4034, - March 2005. - - - -Informative References - - [RFC 1034] - "Domain names - concepts and facilities", P. - Mockapetris, 11/01/1987. - - [RFC 1035] - "Domain names - implementation and specification", P. - Mockapetris, 11/01/1987. - - [RFC 2671] - "Extension Mechanisms for DNS (EDNS0)", P. Vixie, August - 1999. - - [RFC 3110] - "RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System - (DNS)", D. Eastlake 3rd. May 2001. - - [RFC 3174] - "US Secure Hash Algorithm 1 (SHA1)", D. Eastlake, P. - Jones, September 2001. - - [RFC 4033] - Arends, R., Austein, R., Larson, M., Massey, D., and S. - Rose, "DNS Security Introduction and Requirements", RFC 4033, March - 2005. - - [RFC 4035] - Arends, R., Austein, R., Larson, M., Massey, D., and S. - Rose, "Protocol Modifications for the DNS Security Extensions", RFC - 4035, March 2005. - - [RFC 4086] - Eastlake, D., 3rd, Schiller, J., and S. Crocker, - "Randomness Requirements for Security", BCP 106, RFC 4086, June 2005. - - [Schneier] - "Applied Cryptography Second Edition: protocols, - algorithms, and source code in C" (second edition), Bruce Schneier, - 1996, John Wiley and Sons, ISBN 0-471-11709-9. - - - - - - - - - - -D. Eastlake 3rd [Page 7] - - -INTERNET-DRAFT DSA Information in the DNS - - -Authors Address - - Donald E. Eastlake 3rd - Motorola Labortories - 155 Beaver Street - Milford, MA 01757 USA - - Telephone: +1-508-786-7554(w) - EMail: Donald.Eastlake@motorola.com - - - -Expiration and File Name - - This draft expires in January 2006. - - Its file name is draft-ietf-dnsext-rfc2536bis-dsa-06.txt. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -D. Eastlake 3rd [Page 8] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-rfc2538bis-04.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-rfc2538bis-04.txt deleted file mode 100644 index 2ec9dbe..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-rfc2538bis-04.txt +++ /dev/null @@ -1,840 +0,0 @@ - - - -Network Working Group S. Josefsson -Internet-Draft August 30, 2005 -Expires: March 3, 2006 - - - Storing Certificates in the Domain Name System (DNS) - draft-ietf-dnsext-rfc2538bis-04 - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on March 3, 2006. - -Copyright Notice - - Copyright (C) The Internet Society (2005). - -Abstract - - Cryptographic public keys are frequently published and their - authenticity demonstrated by certificates. A CERT resource record - (RR) is defined so that such certificates and related certificate - revocation lists can be stored in the Domain Name System (DNS). - - This document obsoletes RFC 2538. - - - - - - -Josefsson Expires March 3, 2006 [Page 1] - -Internet-Draft Storing Certificates in the DNS August 2005 - - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 2. The CERT Resource Record . . . . . . . . . . . . . . . . . . . 3 - 2.1. Certificate Type Values . . . . . . . . . . . . . . . . . 4 - 2.2. Text Representation of CERT RRs . . . . . . . . . . . . . 5 - 2.3. X.509 OIDs . . . . . . . . . . . . . . . . . . . . . . . . 6 - 3. Appropriate Owner Names for CERT RRs . . . . . . . . . . . . . 6 - 3.1. Content-based X.509 CERT RR Names . . . . . . . . . . . . 7 - 3.2. Purpose-based X.509 CERT RR Names . . . . . . . . . . . . 8 - 3.3. Content-based OpenPGP CERT RR Names . . . . . . . . . . . 9 - 3.4. Purpose-based OpenPGP CERT RR Names . . . . . . . . . . . 9 - 3.5. Owner names for IPKIX, ISPKI, and IPGP . . . . . . . . . . 9 - 4. Performance Considerations . . . . . . . . . . . . . . . . . . 10 - 5. Contributors . . . . . . . . . . . . . . . . . . . . . . . . . 10 - 6. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 10 - 7. Security Considerations . . . . . . . . . . . . . . . . . . . 10 - 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 11 - 9. Changes since RFC 2538 . . . . . . . . . . . . . . . . . . . . 11 - Appendix A. Copying conditions . . . . . . . . . . . . . . . . . 12 - 10. References . . . . . . . . . . . . . . . . . . . . . . . . . . 12 - 10.1. Normative References . . . . . . . . . . . . . . . . . . . 12 - 10.2. Informative References . . . . . . . . . . . . . . . . . . 13 - Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 14 - Intellectual Property and Copyright Statements . . . . . . . . . . 15 - - - - - - - - - - - - - - - - - - - - - - - - - - -Josefsson Expires March 3, 2006 [Page 2] - -Internet-Draft Storing Certificates in the DNS August 2005 - - -1. Introduction - - Public keys are frequently published in the form of a certificate and - their authenticity is commonly demonstrated by certificates and - related certificate revocation lists (CRLs). A certificate is a - binding, through a cryptographic digital signature, of a public key, - a validity interval and/or conditions, and identity, authorization, - or other information. A certificate revocation list is a list of - certificates that are revoked, and incidental information, all signed - by the signer (issuer) of the revoked certificates. Examples are - X.509 certificates/CRLs in the X.500 directory system or OpenPGP - certificates/revocations used by OpenPGP software. - - Section 2 below specifies a CERT resource record (RR) for the storage - of certificates in the Domain Name System [1] [2]. - - Section 3 discusses appropriate owner names for CERT RRs. - - Sections 4, 5, and 6 below cover performance, IANA, and security - considerations, respectively. - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in [3]. - - -2. The CERT Resource Record - - The CERT resource record (RR) has the structure given below. Its RR - type code is 37. - - 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | type | key tag | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | algorithm | / - +---------------+ certificate or CRL / - / / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| - - The type field is the certificate type as defined in section 2.1 - below. - - The key tag field is the 16 bit value computed for the key embedded - in the certificate, using the RRSIG Key Tag algorithm described in - Appendix B of [10]. This field is used as an efficiency measure to - pick which CERT RRs may be applicable to a particular key. The key - - - -Josefsson Expires March 3, 2006 [Page 3] - -Internet-Draft Storing Certificates in the DNS August 2005 - - - tag can be calculated for the key in question and then only CERT RRs - with the same key tag need be examined. However, the key must always - be transformed to the format it would have as the public key portion - of a DNSKEY RR before the key tag is computed. This is only possible - if the key is applicable to an algorithm (and limits such as key size - limits) defined for DNS security. If it is not, the algorithm field - MUST BE zero and the tag field is meaningless and SHOULD BE zero. - - The algorithm field has the same meaning as the algorithm field in - DNSKEY and RRSIG RRs [10], except that a zero algorithm field - indicates the algorithm is unknown to a secure DNS, which may simply - be the result of the algorithm not having been standardized for - DNSSEC. - -2.1. Certificate Type Values - - The following values are defined or reserved: - - Value Mnemonic Certificate Type - ----- -------- ---------------- - 0 reserved - 1 PKIX X.509 as per PKIX - 2 SPKI SPKI certificate - 3 PGP OpenPGP packet - 4 IPKIX The URL of an X.509 data object - 5 ISPKI The URL of an SPKI certificate - 6 IPGP The URL of an OpenPGP packet - 7-252 available for IANA assignment - 253 URI URI private - 254 OID OID private - 255-65534 available for IANA assignment - 65535 reserved - - The PKIX type is reserved to indicate an X.509 certificate conforming - to the profile being defined by the IETF PKIX working group. The - certificate section will start with a one-byte unsigned OID length - and then an X.500 OID indicating the nature of the remainder of the - certificate section (see 2.3 below). (NOTE: X.509 certificates do - not include their X.500 directory type designating OID as a prefix.) - - The SPKI type is reserved to indicate the SPKI certificate format - [13], for use when the SPKI documents are moved from experimental - status. - - The PGP type indicates an OpenPGP packet as described in [6] and its - extensions and successors. Two uses are to transfer public key - material and revocation signatures. The data is binary, and MUST NOT - be encoded into an ASCII armor. An implementation SHOULD process - - - -Josefsson Expires March 3, 2006 [Page 4] - -Internet-Draft Storing Certificates in the DNS August 2005 - - - transferable public keys as described in section 10.1 of [6], but it - MAY handle additional OpenPGP packets. - - The IPKIX, ISPKI and IPGP types indicate a URL which will serve the - content that would have been in the "certificate, CRL or URL" field - of the corresponding (PKIX, SPKI or PGP) packet types. These types - are known as "indirect". These packet types MUST be used when the - content is too large to fit in the CERT RR, and MAY be used at the - implementer's discretion. They SHOULD NOT be used where the entire - UDP packet would have fit in 512 bytes. - - The URI private type indicates a certificate format defined by an - absolute URI. The certificate portion of the CERT RR MUST begin with - a null terminated URI [5] and the data after the null is the private - format certificate itself. The URI SHOULD be such that a retrieval - from it will lead to documentation on the format of the certificate. - Recognition of private certificate types need not be based on URI - equality but can use various forms of pattern matching so that, for - example, subtype or version information can also be encoded into the - URI. - - The OID private type indicates a private format certificate specified - by an ISO OID prefix. The certificate section will start with a one- - byte unsigned OID length and then a BER encoded OID indicating the - nature of the remainder of the certificate section. This can be an - X.509 certificate format or some other format. X.509 certificates - that conform to the IETF PKIX profile SHOULD be indicated by the PKIX - type, not the OID private type. Recognition of private certificate - types need not be based on OID equality but can use various forms of - pattern matching such as OID prefix. - -2.2. Text Representation of CERT RRs - - The RDATA portion of a CERT RR has the type field as an unsigned - decimal integer or as a mnemonic symbol as listed in section 2.1 - above. - - The key tag field is represented as an unsigned decimal integer. - - The algorithm field is represented as an unsigned decimal integer or - a mnemonic symbol as listed in [10]. - - The certificate / CRL portion is represented in base 64 [14] and may - be divided up into any number of white space separated substrings, - down to single base 64 digits, which are concatenated to obtain the - full signature. These substrings can span lines using the standard - parenthesis. - - - - -Josefsson Expires March 3, 2006 [Page 5] - -Internet-Draft Storing Certificates in the DNS August 2005 - - - Note that the certificate / CRL portion may have internal sub-fields, - but these do not appear in the master file representation. For - example, with type 254, there will be an OID size, an OID, and then - the certificate / CRL proper. But only a single logical base 64 - string will appear in the text representation. - -2.3. X.509 OIDs - - OIDs have been defined in connection with the X.500 directory for - user certificates, certification authority certificates, revocations - of certification authority, and revocations of user certificates. - The following table lists the OIDs, their BER encoding, and their - length-prefixed hex format for use in CERT RRs: - - id-at-userCertificate - = { joint-iso-ccitt(2) ds(5) at(4) 36 } - == 0x 03 55 04 24 - id-at-cACertificate - = { joint-iso-ccitt(2) ds(5) at(4) 37 } - == 0x 03 55 04 25 - id-at-authorityRevocationList - = { joint-iso-ccitt(2) ds(5) at(4) 38 } - == 0x 03 55 04 26 - id-at-certificateRevocationList - = { joint-iso-ccitt(2) ds(5) at(4) 39 } - == 0x 03 55 04 27 - - -3. Appropriate Owner Names for CERT RRs - - It is recommended that certificate CERT RRs be stored under a domain - name related to their subject, i.e., the name of the entity intended - to control the private key corresponding to the public key being - certified. It is recommended that certificate revocation list CERT - RRs be stored under a domain name related to their issuer. - - Following some of the guidelines below may result in the use in DNS - names of characters that require DNS quoting which is to use a - backslash followed by the octal representation of the ASCII code for - the character (e.g., \000 for NULL). - - The choice of name under which CERT RRs are stored is important to - clients that perform CERT queries. In some situations, the clients - may not know all information about the CERT RR object it wishes to - retrieve. For example, a client may not know the subject name of an - X.509 certificate, or the e-mail address of the owner of an OpenPGP - key. Further, the client might only know the hostname of a service - that uses X.509 certificates or the Key ID of an OpenPGP key. - - - -Josefsson Expires March 3, 2006 [Page 6] - -Internet-Draft Storing Certificates in the DNS August 2005 - - - Therefore, two owner name guidelines are defined: content-based owner - names and purpose-based owner names. A content-based owner name is - derived from the content of the CERT RR data; for example, the - Subject field in an X.509 certificate or the User ID field in OpenPGP - keys. A purpose-based owner name is a name that a client retrieving - CERT RRs MUST already know; for example, the host name of an X.509 - protected service or the Key ID of an OpenPGP key. The content-based - and purpose-based owner name MAY be the same; for example, when a - client looks up a key based on the From: address of an incoming - e-mail. - - Implementations SHOULD use the purpose-based owner name guidelines - described in this document, and MAY use CNAMEs of content-based owner - names (or other names), pointing to the purpose-based owner name. - -3.1. Content-based X.509 CERT RR Names - - Some X.509 versions permit multiple names to be associated with - subjects and issuers under "Subject Alternate Name" and "Issuer - Alternate Name". For example, X.509v3 has such Alternate Names with - an ASN.1 specification as follows: - - GeneralName ::= CHOICE { - otherName [0] INSTANCE OF OTHER-NAME, - rfc822Name [1] IA5String, - dNSName [2] IA5String, - x400Address [3] EXPLICIT OR-ADDRESS.&Type, - directoryName [4] EXPLICIT Name, - ediPartyName [5] EDIPartyName, - uniformResourceIdentifier [6] IA5String, - iPAddress [7] OCTET STRING, - registeredID [8] OBJECT IDENTIFIER - } - - The recommended locations of CERT storage are as follows, in priority - order: - 1. If a domain name is included in the identification in the - certificate or CRL, that should be used. - 2. If a domain name is not included but an IP address is included, - then the translation of that IP address into the appropriate - inverse domain name should be used. - 3. If neither of the above is used, but a URI containing a domain - name is present, that domain name should be used. - 4. If none of the above is included but a character string name is - included, then it should be treated as described for OpenPGP - names below. - - - - - -Josefsson Expires March 3, 2006 [Page 7] - -Internet-Draft Storing Certificates in the DNS August 2005 - - - 5. If none of the above apply, then the distinguished name (DN) - should be mapped into a domain name as specified in [4]. - - Example 1: An X.509v3 certificate is issued to /CN=John Doe /DC=Doe/ - DC=com/DC=xy/O=Doe Inc/C=XY/ with Subject Alternative Names of (a) - string "John (the Man) Doe", (b) domain name john-doe.com, and (c) - uri . The storage locations - recommended, in priority order, would be - 1. john-doe.com, - 2. www.secure.john-doe.com, and - 3. Doe.com.xy. - - Example 2: An X.509v3 certificate is issued to /CN=James Hacker/ - L=Basingstoke/O=Widget Inc/C=GB/ with Subject Alternate names of (a) - domain name widget.foo.example, (b) IPv4 address 10.251.13.201, and - (c) string "James Hacker ". The - storage locations recommended, in priority order, would be - 1. widget.foo.example, - 2. 201.13.251.10.in-addr.arpa, and - 3. hacker.mail.widget.foo.example. - -3.2. Purpose-based X.509 CERT RR Names - - Due to the difficulty for clients that do not already possess a - certificate to reconstruct the content-based owner name, purpose- - based owner names are recommended in this section. Recommendations - for purpose-based owner names vary per scenario. The following table - summarizes the purpose-based X.509 CERT RR owner name guidelines for - use with S/MIME [16], SSL/TLS [11], and IPSEC [12]: - - Scenario Owner name - ------------------ ---------------------------------------------- - S/MIME Certificate Standard translation of an RFC 2822 email - address. Example: An S/MIME certificate for - "postmaster@example.org" will use a standard - hostname translation of the owner name, - "postmaster.example.org". - - TLS Certificate Hostname of the TLS server. - - IPSEC Certificate Hostname of the IPSEC machine and/or, for IPv4 - or IPv6 addresses, the fully qualified domain - name in the appropriate reverse domain. - - An alternate approach for IPSEC is to store raw public keys [15]. - - - - - - -Josefsson Expires March 3, 2006 [Page 8] - -Internet-Draft Storing Certificates in the DNS August 2005 - - -3.3. Content-based OpenPGP CERT RR Names - - OpenPGP signed keys (certificates) use a general character string - User ID [6]. However, it is recommended by OpenPGP that such names - include the RFC 2822 [8] email address of the party, as in "Leslie - Example ". If such a format is used, the CERT - should be under the standard translation of the email address into a - domain name, which would be leslie.host.example in this case. If no - RFC 2822 name can be extracted from the string name, no specific - domain name is recommended. - - If a user has more than one email address, the CNAME type can be used - to reduce the amount of data stored in the DNS. Example: - - $ORIGIN example.org. - smith IN CERT PGP 0 0 - john.smith IN CNAME smith - js IN CNAME smith - -3.4. Purpose-based OpenPGP CERT RR Names - - Applications that receive an OpenPGP packet containing encrypted or - signed data but do not know the email address of the sender will have - difficulties constructing the correct owner name and cannot use the - content-based owner name guidelines. However, these clients commonly - know the key fingerprint or the Key ID. The key ID is found in - OpenPGP packets, and the key fingerprint is commonly found in - auxilliary data that may be available. In this case, use of an owner - name identical to the key fingerprint and the key ID expressed in - hexadecimal [14] is recommended. Example: - - $ORIGIN example.org. - 0424D4EE81A0E3D119C6F835EDA21E94B565716F IN CERT PGP ... - F835EDA21E94B565716F IN CERT PGP ... - B565716F IN CERT PGP ... - - If the same key material is stored for several owner names, the use - of CNAME may be used to avoid data duplication. Note that CNAME is - not always applicable, because it maps one owner name to the other - for all purposes, which may be sub-optimal when two keys with the - same Key ID are stored. - -3.5. Owner names for IPKIX, ISPKI, and IPGP - - These types are stored under the same owner names, both purpose- and - content-based, as the PKIX, SPKI and PGP types. - - - - - -Josefsson Expires March 3, 2006 [Page 9] - -Internet-Draft Storing Certificates in the DNS August 2005 - - -4. Performance Considerations - - Current Domain Name System (DNS) implementations are optimized for - small transfers, typically not more than 512 bytes including - overhead. While larger transfers will perform correctly and work is - underway to make larger transfers more efficient, it is still - advisable at this time to make every reasonable effort to minimize - the size of certificates stored within the DNS. Steps that can be - taken may include using the fewest possible optional or extension - fields and using short field values for necessary variable length - fields. - - The RDATA field in the DNS protocol may only hold data of size 65535 - octets (64kb) or less. This means that each CERT RR MUST NOT contain - more than 64kb of payload, even if the corresponding certificate or - certificate revocation list is larger. This document addresses this - by defining "indirect" data types for each normal type. - - -5. Contributors - - The majority of this document is copied verbatim from RFC 2538, by - Donald Eastlake 3rd and Olafur Gudmundsson. - - -6. Acknowledgements - - Thanks to David Shaw and Michael Graff for their contributions to - earlier works that motivated, and served as inspiration for, this - document. - - This document was improved by suggestions and comments from Olivier - Dubuisson, Olaf M. Kolkman, Ben Laurie, Edward Lewis, Jason - Sloderbeck, Samuel Weiler, and Florian Weimer. No doubt the list is - incomplete. We apologize to anyone we left out. - - -7. Security Considerations - - By definition, certificates contain their own authenticating - signature. Thus, it is reasonable to store certificates in non- - secure DNS zones or to retrieve certificates from DNS with DNS - security checking not implemented or deferred for efficiency. The - results MAY be trusted if the certificate chain is verified back to a - known trusted key and this conforms with the user's security policy. - - Alternatively, if certificates are retrieved from a secure DNS zone - with DNS security checking enabled and are verified by DNS security, - - - -Josefsson Expires March 3, 2006 [Page 10] - -Internet-Draft Storing Certificates in the DNS August 2005 - - - the key within the retrieved certificate MAY be trusted without - verifying the certificate chain if this conforms with the user's - security policy. - - If an organization chooses to issue certificates for it's employees, - placing CERT RR's in the DNS by owner name, and if DNSSEC (with NSEC) - is in use, it is possible for someone to enumerate all employees of - the organization. This is usually not considered desirable, for the - same reason enterprise phone listings are not often publicly - published and are even mark confidential. - - When the URI type is used, it should be understood that it introduces - an additional indirection that may allow for a new attack vector. - One method to secure that indirection is to include a hash of the - certificate in the URI itself. - - CERT RRs are not used by DNSSEC [9], so there are no security - considerations related to CERT RRs and securing the DNS itself. - - If DNSSEC is used, then the non-existence of a CERT RR and, - consequently, certificates or revocation lists can be securely - asserted. Without DNSSEC, this is not possible. - - -8. IANA Considerations - - Certificate types 0x0000 through 0x00FF and 0xFF00 through 0xFFFF can - only be assigned by an IETF standards action [7]. This document - assigns 0x0001 through 0x0006 and 0x00FD and 0x00FE. Certificate - types 0x0100 through 0xFEFF are assigned through IETF Consensus [7] - based on RFC documentation of the certificate type. The availability - of private types under 0x00FD and 0x00FE should satisfy most - requirements for proprietary or private types. - - The CERT RR reuses the DNS Security Algorithm Numbers registry. In - particular, the CERT RR requires that algorithm number 0 remain - reserved, as described in Section 2. The IANA is directed to - reference the CERT RR as a user of this registry and value 0, in - particular. - - -9. Changes since RFC 2538 - - 1. Editorial changes to conform with new document requirements, - including splitting reference section into two parts and - updating the references to point at latest versions, and to add - some additional references. - - - - -Josefsson Expires March 3, 2006 [Page 11] - -Internet-Draft Storing Certificates in the DNS August 2005 - - - 2. Improve terminology. For example replace "PGP" with "OpenPGP", - to align with RFC 2440. - 3. In section 2.1, clarify that OpenPGP public key data are binary, - not the ASCII armored format, and reference 10.1 in RFC 2440 on - how to deal with OpenPGP keys, and acknowledge that - implementations may handle additional packet types. - 4. Clarify that integers in the representation format are decimal. - 5. Replace KEY/SIG with DNSKEY/RRSIG etc, to align with DNSSECbis - terminology. Improve reference for Key Tag Algorithm - calculations. - 6. Add examples that suggest use of CNAME to reduce bandwidth. - 7. In section 3, appended the last paragraphs that discuss - "content-based" vs "purpose-based" owner names. Add section 3.2 - for purpose-based X.509 CERT owner names, and section 3.4 for - purpose-based OpenPGP CERT owner names. - 8. Added size considerations. - 9. The SPKI types has been reserved, until RFC 2692/2693 is moved - from the experimental status. - 10. Added indirect types IPKIX, ISPKI, and IPGP. - - -Appendix A. Copying conditions - - Regarding the portion of this document that was written by Simon - Josefsson ("the author", for the remainder of this section), the - author makes no guarantees and is not responsible for any damage - resulting from its use. The author grants irrevocable permission to - anyone to use, modify, and distribute it in any way that does not - diminish the rights of anyone else to use, modify, and distribute it, - provided that redistributed derivative works do not contain - misleading author or version information. Derivative works need not - be licensed under similar terms. - - -10. References - -10.1. Normative References - - [1] Mockapetris, P., "Domain names - concepts and facilities", - STD 13, RFC 1034, November 1987. - - [2] Mockapetris, P., "Domain names - implementation and - specification", STD 13, RFC 1035, November 1987. - - [3] Bradner, S., "Key words for use in RFCs to Indicate Requirement - Levels", BCP 14, RFC 2119, March 1997. - - [4] Kille, S., Wahl, M., Grimstad, A., Huber, R., and S. Sataluri, - - - -Josefsson Expires March 3, 2006 [Page 12] - -Internet-Draft Storing Certificates in the DNS August 2005 - - - "Using Domains in LDAP/X.500 Distinguished Names", RFC 2247, - January 1998. - - [5] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform - Resource Identifiers (URI): Generic Syntax", RFC 2396, - August 1998. - - [6] Callas, J., Donnerhacke, L., Finney, H., and R. Thayer, - "OpenPGP Message Format", RFC 2440, November 1998. - - [7] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA - Considerations Section in RFCs", BCP 26, RFC 2434, - October 1998. - - [8] Resnick, P., "Internet Message Format", RFC 2822, April 2001. - - [9] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "DNS Security Introduction and Requirements", RFC 4033, - March 2005. - - [10] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "Resource Records for the DNS Security Extensions", RFC 4034, - March 2005. - -10.2. Informative References - - [11] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0", - RFC 2246, January 1999. - - [12] Kent, S. and R. Atkinson, "Security Architecture for the - Internet Protocol", RFC 2401, November 1998. - - [13] Ellison, C., Frantz, B., Lampson, B., Rivest, R., Thomas, B., - and T. Ylonen, "SPKI Certificate Theory", RFC 2693, - September 1999. - - [14] Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", - RFC 3548, July 2003. - - [15] Richardson, M., "A Method for Storing IPsec Keying Material in - DNS", RFC 4025, March 2005. - - [16] Ramsdell, B., "Secure/Multipurpose Internet Mail Extensions - (S/MIME) Version 3.1 Message Specification", RFC 3851, - July 2004. - - - - - - -Josefsson Expires March 3, 2006 [Page 13] - -Internet-Draft Storing Certificates in the DNS August 2005 - - -Author's Address - - Simon Josefsson - - Email: simon@josefsson.org - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Josefsson Expires March 3, 2006 [Page 14] - -Internet-Draft Storing Certificates in the DNS August 2005 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2005). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Josefsson Expires March 3, 2006 [Page 15] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-rfc2539bis-dhk-06.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-rfc2539bis-dhk-06.txt deleted file mode 100644 index 5e6cb1d..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-rfc2539bis-dhk-06.txt +++ /dev/null @@ -1,580 +0,0 @@ - -INTERNET-DRAFT Diffie-Hellman Information in the DNS -OBSOLETES: RFC 2539 Donald E. Eastlake 3rd - Motorola Laboratories -Expires: January 2006 July 2005 - - - - - Storage of Diffie-Hellman Keying Information in the DNS - ------- -- -------------- ------ ----------- -- --- --- - - - - -Status of This Document - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Distribution of this document is unlimited. Comments should be sent - to the DNS extensions working group mailing list - . - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than a "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/1id-abstracts.html - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html - - -Abstract - - The standard method for encoding Diffie-Hellman keys in the Domain - Name System is specified. - - - -Copyright - - Copyright (C) The Internet Society 2005. - - - -D. Eastlake 3rd [Page 1] - - -INTERNET-DRAFT Diffie-Hellman Information in the DNS - - -Acknowledgements - - Part of the format for Diffie-Hellman keys and the description - thereof was taken from a work in progress by Ashar Aziz, Tom Markson, - and Hemma Prafullchandra. In addition, the following persons - provided useful comments that were incorporated into the predecessor - of this document: Ran Atkinson, Thomas Narten. - - - -Table of Contents - - Status of This Document....................................1 - Abstract...................................................1 - Copyright..................................................1 - - Acknowledgements...........................................2 - Table of Contents..........................................2 - - 1. Introduction............................................3 - 1.1 About This Document....................................3 - 1.2 About Diffie-Hellman...................................3 - 2. Encoding Diffie-Hellman Keying Information..............4 - 3. Performance Considerations..............................5 - 4. IANA Considerations.....................................5 - 5. Security Considerations.................................5 - Copyright and Disclaimer...................................5 - - Normative References.......................................7 - Informative Refences.......................................7 - - Author Address.............................................8 - Expiration and File Name...................................8 - - Appendix A: Well known prime/generator pairs...............9 - A.1. Well-Known Group 1: A 768 bit prime..................9 - A.2. Well-Known Group 2: A 1024 bit prime.................9 - A.3. Well-Known Group 3: A 1536 bit prime................10 - - - - - - - - - - - - - - -D. Eastlake 3rd [Page 2] - - -INTERNET-DRAFT Diffie-Hellman Information in the DNS - - -1. Introduction - - The Domain Name System (DNS) is the global hierarchical replicated - distributed database system for Internet addressing, mail proxy, and - similar information [RFC 1034, 1035]. The DNS has been extended to - include digital signatures and cryptographic keys as described in - [RFC 4033, 4034, 4035] and additonal work is underway which would use - the storage of keying information in the DNS. - - - -1.1 About This Document - - This document describes how to store Diffie-Hellman keys in the DNS. - Familiarity with the Diffie-Hellman key exchange algorithm is assumed - [Schneier, RFC 2631]. - - - -1.2 About Diffie-Hellman - - Diffie-Hellman requires two parties to interact to derive keying - information which can then be used for authentication. Thus Diffie- - Hellman is inherently a key agreement algorithm. As a result, no - format is defined for Diffie-Hellman "signature information". For - example, assume that two parties have local secrets "i" and "j". - Assume they each respectively calculate X and Y as follows: - - X = g**i ( mod p ) - - Y = g**j ( mod p ) - - They exchange these quantities and then each calculates a Z as - follows: - - Zi = Y**i ( mod p ) - - Zj = X**j ( mod p ) - - Zi and Zj will both be equal to g**(i*j)(mod p) and will be a shared - secret between the two parties that an adversary who does not know i - or j will not be able to learn from the exchanged messages (unless - the adversary can derive i or j by performing a discrete logarithm - mod p which is hard for strong p and g). - - The private key for each party is their secret i (or j). The public - key is the pair p and g, which must be the same for the parties, and - their individual X (or Y). - - For further information about Diffie-Hellman and precautions to take - - -D. Eastlake 3rd [Page 3] - - -INTERNET-DRAFT Diffie-Hellman Information in the DNS - - - in deciding on a p and g, see [RFC 2631]. - - - -2. Encoding Diffie-Hellman Keying Information - - When Diffie-Hellman keys appear within the RDATA portion of a RR, - they are encoded as shown below. - - The period of key validity is not included in this data but is - indicated separately, for example by an RR such as RRSIG which signs - and authenticates the RR containing the keying information. - - 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | KEY flags | protocol | algorithm=2 | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | prime length (or flag) | prime (p) (or special) / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - / prime (p) (variable length) | generator length | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | generator (g) (variable length) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | public value length | public value (variable length)/ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - / public value (g^i mod p) (variable length) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Prime length is the length of the Diffie-Hellman prime (p) in bytes - if it is 16 or greater. Prime contains the binary representation of - the Diffie-Hellman prime with most significant byte first (i.e., in - network order). If "prime length" field is 1 or 2, then the "prime" - field is actually an unsigned index into a table of 65,536 - prime/generator pairs and the generator length SHOULD be zero. See - Appedix A for defined table entries and Section 4 for information on - allocating additional table entries. The meaning of a zero or 3 - through 15 value for "prime length" is reserved. - - Generator length is the length of the generator (g) in bytes. - Generator is the binary representation of generator with most - significant byte first. PublicValueLen is the Length of the Public - Value (g**i (mod p)) in bytes. PublicValue is the binary - representation of the DH public value with most significant byte - first. - - - - - - - -D. Eastlake 3rd [Page 4] - - -INTERNET-DRAFT Diffie-Hellman Information in the DNS - - -3. Performance Considerations - - Current DNS implementations are optimized for small transfers, - typically less than 512 bytes including DNS overhead. Larger - transfers will perform correctly and extensions have been - standardized [RFC 2671] to make larger transfers more efficient. But - it is still advisable at this time to make reasonable efforts to - minimize the size of RR sets containing keying information consistent - with adequate security. - - - -4. IANA Considerations - - Assignment of meaning to Prime Lengths of 0 and 3 through 15 requires - an IETF consensus as defined in [RFC 2434]. - - Well known prime/generator pairs number 0x0000 through 0x07FF can - only be assigned by an IETF standards action. [RFC 2539], the - Proposed Standard predecessor of this document, assigned 0x0001 - through 0x0002. This document additionally assigns 0x0003. Pairs - number 0s0800 through 0xBFFF can be assigned based on RFC - documentation. Pairs number 0xC000 through 0xFFFF are available for - private use and are not centrally coordinated. Use of such private - pairs outside of a closed environment may result in conflicts and/or - security failures. - - - -5. Security Considerations - - Keying information retrieved from the DNS should not be trusted - unless (1) it has been securely obtained from a secure resolver or - independently verified by the user and (2) this secure resolver and - secure obtainment or independent verification conform to security - policies acceptable to the user. As with all cryptographic - algorithms, evaluating the necessary strength of the key is important - and dependent on security policy. - - In addition, the usual Diffie-Hellman key strength considerations - apply. (p-1)/2 should also be prime, g should be primitive mod p, p - should be "large", etc. See [RFC 2631, Schneier]. - - - -Copyright and Disclaimer - - Copyright (C) The Internet Society (2005). This document is subject to - the rights, licenses and restrictions contained in BCP 78, and except - as set forth therein, the authors retain all their rights. - - -D. Eastlake 3rd [Page 5] - - -INTERNET-DRAFT Diffie-Hellman Information in the DNS - - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -D. Eastlake 3rd [Page 6] - - -INTERNET-DRAFT Diffie-Hellman Information in the DNS - - -Normative References - - [RFC 2631] - "Diffie-Hellman Key Agreement Method", E. Rescorla, June - 1999. - - [RFC 2434] - "Guidelines for Writing an IANA Considerations Section - in RFCs", T. Narten, H. Alvestrand, October 1998. - - [RFC 4034] - Arends, R., Austein, R., Larson, M., Massey, D., and S. - Rose, "Resource Records for the DNS Security Extensions", RFC 4034, - March 2005. - - - -Informative Refences - - [RFC 1034] - "Domain names - concepts and facilities", P. - Mockapetris, November 1987. - - [RFC 1035] - "Domain names - implementation and specification", P. - Mockapetris, November 1987. - - [RFC 2539] - "Storage of Diffie-Hellman Keys in the Domain Name - System (DNS)", D. Eastlake, March 1999, obsoleted by this RFC. - - [RFC 2671] - "Extension Mechanisms for DNS (EDNS0)", P. Vixie, August - 1999. - - [RFC 4033] - Arends, R., Austein, R., Larson, M., Massey, D., and S. - Rose, "DNS Security Introduction and Requirements", RFC 4033, March - 2005. - - [RFC 4035] - Arends, R., Austein, R., Larson, M., Massey, D., and S. - Rose, "Protocol Modifications for the DNS Security Extensions", RFC - 4035, March 2005. - - [Schneier] - Bruce Schneier, "Applied Cryptography: Protocols, - Algorithms, and Source Code in C" (Second Edition), 1996, John Wiley - and Sons. - - - - - - - - - - - - - -D. Eastlake 3rd [Page 7] - - -INTERNET-DRAFT Diffie-Hellman Information in the DNS - - -Author Address - - Donald E. Eastlake 3rd - Motorola Laboratories - 155 Beaver Street - Milford, MA 01757 USA - - Telephone: +1-508-786-7554 - EMail: Donald.Eastlake@motorola.com - - - -Expiration and File Name - - This draft expires in January 2006. - - Its file name is draft-ietf-dnsext-rfc2539bis-dhk-06.txt. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -D. Eastlake 3rd [Page 8] - - -INTERNET-DRAFT Diffie-Hellman Information in the DNS - - -Appendix A: Well known prime/generator pairs - - These numbers are copied from the IPSEC effort where the derivation of - these values is more fully explained and additional information is - available. - Richard Schroeppel performed all the mathematical and computational - work for this appendix. - - - -A.1. Well-Known Group 1: A 768 bit prime - - The prime is 2^768 - 2^704 - 1 + 2^64 * { [2^638 pi] + 149686 }. Its - decimal value is - 155251809230070893513091813125848175563133404943451431320235 - 119490296623994910210725866945387659164244291000768028886422 - 915080371891804634263272761303128298374438082089019628850917 - 0691316593175367469551763119843371637221007210577919 - - Prime modulus: Length (32 bit words): 24, Data (hex): - FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 - 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD - EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 - E485B576 625E7EC6 F44C42E9 A63A3620 FFFFFFFF FFFFFFFF - - Generator: Length (32 bit words): 1, Data (hex): 2 - - - -A.2. Well-Known Group 2: A 1024 bit prime - - The prime is 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }. - Its decimal value is - 179769313486231590770839156793787453197860296048756011706444 - 423684197180216158519368947833795864925541502180565485980503 - 646440548199239100050792877003355816639229553136239076508735 - 759914822574862575007425302077447712589550957937778424442426 - 617334727629299387668709205606050270810842907692932019128194 - 467627007 - - Prime modulus: Length (32 bit words): 32, Data (hex): - FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 - 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD - EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 - E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED - EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 - FFFFFFFF FFFFFFFF - - Generator: Length (32 bit words): 1, Data (hex): 2 - - - -D. Eastlake 3rd [Page 9] - - -INTERNET-DRAFT Diffie-Hellman Information in the DNS - - -A.3. Well-Known Group 3: A 1536 bit prime - - The prime is 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 }. - Its decimal value is - 241031242692103258855207602219756607485695054850245994265411 - 694195810883168261222889009385826134161467322714147790401219 - 650364895705058263194273070680500922306273474534107340669624 - 601458936165977404102716924945320037872943417032584377865919 - 814376319377685986952408894019557734611984354530154704374720 - 774996976375008430892633929555996888245787241299381012913029 - 459299994792636526405928464720973038494721168143446471443848 - 8520940127459844288859336526896320919633919 - - Prime modulus Length (32 bit words): 48, Data (hex): - FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 - 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD - EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 - E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED - EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D - C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F - 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D - 670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF - - Generator: Length (32 bit words): 1, Data (hex): 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -D. Eastlake 3rd [Page 10] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-signed-nonexistence-requirements-01.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-signed-nonexistence-requirements-01.txt deleted file mode 100644 index 0af13c6..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-signed-nonexistence-requirements-01.txt +++ /dev/null @@ -1,755 +0,0 @@ - - -Network Working Group B. Laurie -Internet-Draft Nominet -Expires: March 2, 2005 R. Loomis - SAIC - September 2004 - - - - Requirements related to DNSSEC Signed Proof of Non-Existence - draft-ietf-dnsext-signed-nonexistence-requirements-01 - - -Status of this Memo - - - This document is an Internet-Draft and is subject to all provisions - of section 3 of RFC 3667. By submitting this Internet-Draft, each - author represents that any applicable patent or other IPR claims of - which he or she is aware have been or will be disclosed, and any of - which he or she become aware will be disclosed, in accordance with - RFC 3668. - - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as - Internet-Drafts. - - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - - This Internet-Draft will expire on March 2, 2005. - - -Copyright Notice - - - Copyright (C) The Internet Society (2004). - - -Abstract - - - DNSSEC-bis uses the NSEC record to provide authenticated denial of - existence of RRsets. NSEC also has the side-effect of permitting - zone enumeration, even if zone transfers have been forbidden. - Because some see this as a problem, this document has been assembled - to detail the possible requirements for denial of existence A/K/A - signed proof of non-existence. - - - - -Laurie & Loomis Expires March 2, 2005 [Page 1] -Internet-Draft signed-nonexistence-requirements September 2004 - - - -Table of Contents - - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 - 2. Non-purposes . . . . . . . . . . . . . . . . . . . . . . . . 3 - 3. Zone Enumeration . . . . . . . . . . . . . . . . . . . . . . 3 - 4. Zone Enumeration II . . . . . . . . . . . . . . . . . . . . 4 - 5. Zone Enumeration III . . . . . . . . . . . . . . . . . . . . 4 - 6. Exposure of Contents . . . . . . . . . . . . . . . . . . . . 4 - 7. Zone Size . . . . . . . . . . . . . . . . . . . . . . . . . 4 - 8. Single Method . . . . . . . . . . . . . . . . . . . . . . . 5 - 9. Empty Non-terminals . . . . . . . . . . . . . . . . . . . . 5 - 10. Prevention of Precomputed Dictionary Attacks . . . . . . . . 6 - 11. DNSSEC-Adoption and Zone-Growth Relationship . . . . . . . . 6 - 12. Non-overlap of denial records with possible zone records . . 7 - 13. Exposure of Private Keys . . . . . . . . . . . . . . . . . . 7 - 14. Minimisation of Zone Signing Cost . . . . . . . . . . . . . 8 - 15. Minimisation of Asymmetry . . . . . . . . . . . . . . . . . 8 - 16. Minimisation of Client Complexity . . . . . . . . . . . . . 8 - 17. Completeness . . . . . . . . . . . . . . . . . . . . . . . . 8 - 18. Purity of Namespace . . . . . . . . . . . . . . . . . . . . 8 - 19. Replay Attacks . . . . . . . . . . . . . . . . . . . . . . . 8 - 20. Compatibility with NSEC . . . . . . . . . . . . . . . . . . 8 - 21. Compatibility with NSEC II . . . . . . . . . . . . . . . . . 9 - 22. Compatibility with NSEC III . . . . . . . . . . . . . . . . 9 - 23. Coexistence with NSEC . . . . . . . . . . . . . . . . . . . 9 - 24. Coexistence with NSEC II . . . . . . . . . . . . . . . . . . 9 - 25. Protocol Design . . . . . . . . . . . . . . . . . . . . . . 9 - 26. Process . . . . . . . . . . . . . . . . . . . . . . . . . . 9 - 27. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 9 - 28. Requirements notation . . . . . . . . . . . . . . . . . . . 9 - 29. Security Considerations . . . . . . . . . . . . . . . . . . 10 - 30. References . . . . . . . . . . . . . . . . . . . . . . . . . 10 - 30.1 Normative References . . . . . . . . . . . . . . . . . . . 10 - 30.2 Informative References . . . . . . . . . . . . . . . . . . 10 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 10 - Intellectual Property and Copyright Statements . . . . . . . 11 - - - - - - - - - - - - - - - - -Laurie & Loomis Expires March 2, 2005 [Page 2] -Internet-Draft signed-nonexistence-requirements September 2004 - - - -1. Introduction - - - NSEC records allow trivial enumeration of zones - a situation that - has existed for several years but which has recently been raised as a - significant concern for DNSSECbis deployment in several zones. - Alternate proposals have been made that make zone enumeration more - difficult, and some previous proposals to modify DNSSEC had related - requirements/desirements that are relevant to the discussion. In - addition the original designs for NSEC/NXT records were based on - working group discussions and the choices made were not always - documented with context and requirements-- so some of those choices - may need to be restated as requirements. Overall, the working group - needs to better understand the requirements for denial of existence - (and certain other requirements related to DNSSECbis deployment) in - order to evaluate the proposals that may replace NSEC. - - - In the remainder of this document, "NSEC++" is used as shorthand for - "a denial of existence proof that will replace NSEC". "NSECbis" has - also been used as shorthand for this, but we avoid that usage since - NSECbis will not be part of DNSSECbis and therefore there might be - some confusion. - - -2. Non-purposes - - - This document does not currently document the reasons why zone - enumeration might be "bad" from a privacy, security, business, or - other perspective--except insofar as those reasons result in - requirements. Once the list of requirements is complete and vaguely - coherent, the trade-offs (reducing zone enumeration will have X cost, - while providing Y benefit) may be revisited. The editors of this - compendium received inputs on the potential reasons why zone - enumeration is bad (and there was significant discussion on the - DNSEXT WG mailing list) but that information fell outside the scope - of this document. - - - Note also that this document does not assume that NSEC *must* be - replaced with NSEC++, if the requirements can be met through other - methods (e.g., "white lies" with the current NSEC). As is stated - above, this document is focused on requirements collection and - (ideally) prioritization rather than on the actual implementation. - - -3. Zone Enumeration - - - Authenticated denial should not permit trivial zone enumeration. - - - Additional discussion: NSEC (and NXT before it) provide a linked - list that could be "walked" to trivially enumerate all the signed - records in a zone. This requirement is primarily (though not - - - - -Laurie & Loomis Expires March 2, 2005 [Page 3] -Internet-Draft signed-nonexistence-requirements September 2004 - - - - exclusively) important for zones that either are delegation-only/ - -mostly or do not have reverse lookup (PTR) records configured, since - enterprises that have PTR records for all A records have already - provided a similar capability to enumerate the contents of DNS zones. - - - Contributor: various - - -4. Zone Enumeration II - - - Zone enumeration should be at least as difficult as it would be to - effect a dictionary attack using simple DNS queries to do the same in - an unsecured zone. - - - (Editor comment: it is not clear how to measure difficulty in this - case. Some examples could be monetary cost, bandwidth, processing - power or some combination of these. It has also been suggested that - the requirement is that the graph of difficulty of enumeration vs. - the fraction of the zone enumerated should be approximately the same - shape in the two cases) - - - Contributor: Nominet - - -5. Zone Enumeration III - - - Enumeration of a zone with random contents should computationally - infeasible. - - - Editor comment: this is proposed as a way of evaluating the - effectiveness of a proposal rather than as a requirement anyone would - actually have in practice. - - - Contributor: Alex Bligh - - -6. Exposure of Contents - - - NSEC++ should not expose any of the contents of the zone (apart from - the NSEC++ records themselves, of course). - - - Editor comment: this is a weaker requirement than prevention of - enumeration, but certainly any zone that satisfied this requirement - would also satisfy the trivial prevention of enumeration requirement. - - - Contributor: Ed Lewis - - -7. Zone Size - - - Requirement: NSEC++ should make it possible to take precautions - against trivial zone size estimates. Since not all zone owners care - - - - -Laurie & Loomis Expires March 2, 2005 [Page 4] -Internet-Draft signed-nonexistence-requirements September 2004 - - - - about others estimation of the size of a zone, it is not always - necessary to prohibit trivial estimation of the size of the zone but - NSEC++ should allow such measures. - - - Additional Discussion: Even with proposals based on obfuscating names - with hashes it is trivial to give very good estimates of the number - of domains in a certain zone. Just send 10 random queries and look - at the range between the two hash values returned in each NSEC++. As - hash output can be assumed to follow a rectangular random - distribution, using the mean difference between the two values, you - can estimate the total number of records. It is probably sufficient - to look at even one NSEC++, since the two hash values should follow a - (I believe) Poisson distribution. - - - The concern is motivated by some wording remembered from NSEC, which - stated that NSEC MUST only be present for existing owner names in the - zone, and MUST NOT be present for non-existing owner names. If - similar wording were carried over to NSEC++, introducing bogus owner - names in the hash chain (an otherwise simple solution to guard - against trivial estimates of zone size) wouldn't be allowed. - - - One simple attempt at solving this is to describe in the - specifications how zone signer tools can add a number of random - "junk" records. - - - Editor's comment: it is interesting that obfuscating names might - actually make it easier to estimate zone size. - - - Contributor: Simon Josefsson. - - -8. Single Method - - - Requirement: A single NSEC++ method must be able to carry both - old-style denial (i.e. plain labels) and whatever the new style - looks like. Having two separate denial methods could result in - cornercases where one method can deny the other and vice versa. - - - Additional discussion: This requirement can help -bis folks to a - smooth upgrade to -ter. First they'd change the method while the - content is the same, then they can change content of the method. - - - Contributor: Roy Arends. - - -9. Empty Non-terminals - - - Requirement: Empty-non-terminals (ENT) should remain empty. In - other words, adding NSEC++ records to an existing DNS structure - should not cause the creation of NSEC++ records (or related records) - - - - -Laurie & Loomis Expires March 2, 2005 [Page 5] -Internet-Draft signed-nonexistence-requirements September 2004 - - - - at points that are otherwise ENT. - - - Additional discussion: Currently NSEC complies with ENT requirement: - b.example.com NSEC a.c.example.com implies the existence of an ENT - with ownername c.example.com. NSEC2 breaks that requirement, since - the ownername is entirely hashed causing the structure to disappear. - This is why EXIST was introduced. But EXIST causes ENT to be - non-empty-terminals. Next to the dissappearance of ENT, it causes - (some) overhead since an EXIST record needs a SIG, NSEC2 and - SIG(NSEC2). DNSNR honours this requirement by hashing individual - labels instead of ownernames. However this causes very long labels. - Truncation is a measure against very long ownernames, but that is - controversial. There is a fair discussion of the validity of - truncation in the DNSNR draft, but that hasn't got proper review yet. - - - Contributor: Roy Arends. - - - (Editor comment: it is not clear to us that an EXIST record needs an - NSEC2 record, since it is a special purpose record only used for - denial of existence) - - -10. Prevention of Precomputed Dictionary Attacks - - - Requirement: NSEC++ needs to provide a method to reduce the - effectiveness of precomputed dictionary attacks. - - - Additional Discussion: Salt is a measure against dictionary attacks. - There are other possible measures (such as iterating hashes in - NSEC2). The salt needs to be communicated in every response, since - it is needed in every verification. Some have suggested to move the - salt to a special record instead of the denial record. I think this - is not wise. Response size has more priority over zone size. An - extra record causes a larger response than a larger existing record. - - - Contributor: Roy Arends. - - - (Editor comment: the current version of NSEC2 also has the salt in - every NSEC2 record) - - -11. DNSSEC-Adoption and Zone-Growth Relationship - - - Background: Currently with NSEC, when a delegation centric zone - deploys DNSSEC, the zone-size multiplies by a non-trivial factor even - when the DNSSEC-adoption rate of the subzones remains low--because - each delegation point creates at least one NSEC record and - corresponding signature in the parent even if the child is not - signed. - - - - - -Laurie & Loomis Expires March 2, 2005 [Page 6] -Internet-Draft signed-nonexistence-requirements September 2004 - - - - Requirements: A delegation-only (or delegation-mostly) zone that is - signed but which has no signed child zones should initially need only - to add SIG(SOA), DNSKEY, and SIG(DNSKEY) at the apex, along with some - minimal set of NSEC++ records to cover zone contents. Further, - during the transition of a delegation-only zone from 0% signed - children to 100% signed children, the growth in the delegation-only - zone should be roughly proportional to the percentage of signed child - zones. - - - Additional Discussion: This is why DNSNR has the Authoritative Only - bit. This is similar to opt-in for delegations only. This (bit) is - currently the only method to help delegation-centric zone cope with - zone-growth due to DNSSEC adoption. As an example, A delegation only - zone which deploys DNSSEC with the help of this bit, needs to add - SIG(SOA), DNSKEY, SIG(DNSKEY), DNSNR, SIG(DNSNR) at the apex. No - more than that. - - - Contributor: Roy Arends. - - -12. Non-overlap of denial records with possible zone records - - - Requirement: NSEC++ records should in some way be differentiated - from regular zone records, so that there is no possibility that a - record in the zone could be duplicated by a non-existence proof - (NSEC++) record. - - - Additional discussion: This requirement is derived from a discussion - on the DNSEXT mailing list related to copyrights and domain names. - As was outlined there, one solution is to put NSEC++ records in a - separate namespace, e.g.: $ORIGIN co.uk. - 873bcdba87401b485022b8dcd4190e3e IN NS jim.rfc1035.com ; your - delegation 873bcdba87401b485022b8dcd4190e3e._no IN NSEC++ 881345... - ; for amazon.co.uk. - - - Contributor: various - - - (Editor comment: One of us still does not see why a conflict - matters. Even if there is an apparent conflict or overlap, the - "conflicting" NSEC2 name _only_ appears in NSEC2 records, and the - other name _never_ appears in NSEC2 records.) - - -13. Exposure of Private Keys - - - Private keys associated with the public keys in the DNS should be - exposed as little as possible. It is highly undesirable for private - keys to be distributed to nameservers, or to otherwise be available - in the run-time environment of nameservers. - - - - - -Laurie & Loomis Expires March 2, 2005 [Page 7] -Internet-Draft signed-nonexistence-requirements September 2004 - - - - Contributors: Nominet, Olaf Kolkman, Ed Lewis - - -14. Minimisation of Zone Signing Cost - - - The additional cost of creating an NSEC++ signed zone should not - significantly exceed the cost of creating an ordinary signed zone. - - - Contributor: Nominet - - -15. Minimisation of Asymmetry - - - Nameservers should have to do as little additional work as necessary. - More precisely, it is desirable for any increase in cost incurred by - the nameservers to be offset by a proportionate increase in cost to - DNS `clients', e.g. stub and/or `full-service' resolvers. - - - Contributor: Nominet - - -16. Minimisation of Client Complexity - - - Caching, wildcards, CNAMEs, DNAMEs should continue to work without - adding too much complexity at the client side. - - - Contributor: Olaf Kolkman - - -17. Completeness - - - A proof of nonexistence should be possible for all nonexistent data - in the zone. - - - Contributor: Olaf Kolkman - - -18. Purity of Namespace - - - The name space should not be muddied with fake names or data sets. - - - Contributor: Ed Lewis - - -19. Replay Attacks - - - NSEC++ should not allow a replay to be used to deny existence of an - RR that actually exists. - - - Contributor: Ed Lewis - - -20. Compatibility with NSEC - - - NSEC++ should not introduce changes incompatible with NSEC. - - - - -Laurie & Loomis Expires March 2, 2005 [Page 8] -Internet-Draft signed-nonexistence-requirements September 2004 - - - - Contributor: Ed Lewis - - -21. Compatibility with NSEC II - - - NSEC++ should differ from NSEC in a way that is transparent to the - resolver or validator. - - - Contributor: Ed Lewis - - -22. Compatibility with NSEC III - - - NSEC++ should differ from NSEC as little as possible whilst achieving - other requirements. - - - Contributor: Alex Bligh - - -23. Coexistence with NSEC - - - NSEC++ should be optional, allowing NSEC to be used instead. - - - Contributor: Ed Lewis, Alex Bligh - - -24. Coexistence with NSEC II - - - NSEC++ should not impose extra work on those content with NSEC. - - - Contributor: Ed Lewis - - -25. Protocol Design - - - A good security protocol would allow signing the nonexistence of some - selected names without revealing anything about other names. - - - Contributor: Dan Bernstein - - -26. Process - - - Clearly not all of these requirements can be met. Therefore the next - phase of this document will be to either prioritise them or narrow - them down to a non-contradictory set, which should then allow us to - judge proposals on the basis of their fit. - - -27. Acknowledgements - - -28. Requirements notation - - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - - - - -Laurie & Loomis Expires March 2, 2005 [Page 9] -Internet-Draft signed-nonexistence-requirements September 2004 - - - - document are to be interpreted as described in [RFC2119]. - - -29. Security Considerations - - - There are currently no security considerations called out in this - draft. There will be security considerations in the choice of which - requirements will be implemented, but there are no specific security - requirements during the requirements collection process. - - -30. References - - -30.1 Normative References - - - [dnssecbis-protocol] - "DNSSECbis Protocol Definitions", BCP XX, RFC XXXX, Some - Month 2004. - - -30.2 Informative References - - - [RFC2026] Bradner, S., "The Internet Standards Process -- Revision - 3", BCP 9, RFC 2026, October 1996. - - - [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - - - [RFC2418] Bradner, S., "IETF Working Group Guidelines and - Procedures", BCP 25, RFC 2418, September 1998. - - - -Authors' Addresses - - - Ben Laurie - Nominet - 17 Perryn Road - London W3 7LR - England - - - Phone: +44 (20) 8735 0686 - EMail: ben@algroup.co.uk - - - - Rip Loomis - Science Applications International Corporation - 7125 Columbia Gateway Drive, Suite 300 - Columbia, MD 21046 - US - - - EMail: gilbert.r.loomis@saic.com - - - - -Laurie & Loomis Expires March 2, 2005 [Page 10] -Internet-Draft signed-nonexistence-requirements September 2004 - - - -Intellectual Property Statement - - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - - -Disclaimer of Validity - - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - -Copyright Statement - - - Copyright (C) The Internet Society (2004). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - - -Acknowledgment - - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - -Laurie & Loomis Expires March 2, 2005 [Page 11] \ No newline at end of file diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-tkey-renewal-mode-05.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-tkey-renewal-mode-05.txt deleted file mode 100644 index 9c73c68..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-tkey-renewal-mode-05.txt +++ /dev/null @@ -1,1292 +0,0 @@ - - - - - -DNS Extensions Yuji Kamite -Internet-Draft NTT Communications -Expires: April 15, 2005 Masaya Nakayama - The University of Tokyo - October 14, 2004 - - - - TKEY Secret Key Renewal Mode - draft-ietf-dnsext-tkey-renewal-mode-05 - - -Status of this Memo - - This document is an Internet-Draft and is subject to all provisions - of section 3 of RFC 3667. By submitting this Internet-Draft, each - author represents that any applicable patent or other IPR claims of - which he or she is aware have been or will be disclosed, and any of - which he or she become aware will be disclosed, in accordance with - RFC 3668. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as - Internet-Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on April 15, 2005. - -Copyright Notice - - Copyright (C) The Internet Society (2004). - -Abstract - - This document defines a new mode in TKEY and proposes an atomic - method for changing secret keys used for TSIG periodically. - Originally, TKEY provides methods of setting up shared secrets other - - - -Kamite, et. al. Expires April 15, 2005 [Page 1] - -INTERNET-DRAFT October 2004 - - - than manual exchange, but it cannot control timing of key renewal - very well though it can add or delete shared keys separately. This - proposal is a systematical key renewal procedure intended for - preventing signing DNS messages with old and non-safe keys - permanently. - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 1.1 Defined Words . . . . . . . . . . . . . . . . . . . . . . 3 - 1.2 New Format and Assigned Numbers . . . . . . . . . . . . . 4 - 1.3 Overview of Secret Key Renewal Mode . . . . . . . . . . . 4 - 2. Shared Secret Key Renewal . . . . . . . . . . . . . . . . . . 5 - 2.1 Key Usage Time Check . . . . . . . . . . . . . . . . . . . 5 - 2.2 Partial Revocation . . . . . . . . . . . . . . . . . . . . 6 - 2.3 Key Renewal Message Exchange . . . . . . . . . . . . . . . 7 - 2.3.1 Query for Key Renewal . . . . . . . . . . . . . . . . 7 - 2.3.2 Response for Key Renewal . . . . . . . . . . . . . . . 7 - 2.3.3 Attributes of Generated Key . . . . . . . . . . . . . 8 - 2.3.4 TKEY RR structure . . . . . . . . . . . . . . . . . . 8 - 2.4 Key Adoption . . . . . . . . . . . . . . . . . . . . . . . 10 - 2.4.1 Query for Key Adoption . . . . . . . . . . . . . . . . 10 - 2.4.2 Response for Key Adoption . . . . . . . . . . . . . . 10 - 2.5 Keying Schemes . . . . . . . . . . . . . . . . . . . . . . 11 - 2.5.1 DH Exchange for Key Renewal . . . . . . . . . . . . . 11 - 2.5.2 Server Assigned Keying for Key Renewal . . . . . . . . 12 - 2.5.3 Resolver Assigned Keying for Key Renewal . . . . . . . 13 - 2.6 Considerations about Non-compliant Hosts . . . . . . . . . 14 - 3. Secret Storage . . . . . . . . . . . . . . . . . . . . . . . . 15 - 4. Compulsory Key Revocation . . . . . . . . . . . . . . . . . . 15 - 4.1 Compulsory Key Revocation by Server . . . . . . . . . . . 15 - 4.2 Authentication Methods Considerations . . . . . . . . . . 15 - 5. Special Considerations for Two Servers' Case . . . . . . . . 16 - 5.1 To Cope with Collisions of Renewal Requests . . . . . . . 16 - 6. Key Name Considerations . . . . . . . . . . . . . . . . . . . 17 - 7. Example Usage of Secret Key Renewal Mode . . . . . . . . . . 17 - 8. Security Considerations . . . . . . . . . . . . . . . . . . . 20 - 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 20 - 10. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 21 - 11. References . . . . . . . . . . . . . . . . . . . . . . . . . . 21 - 11.1 Normative References . . . . . . . . . . . . . . . . . . . 21 - 11.2 Informative References . . . . . . . . . . . . . . . . . . 21 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 22 - Intellectual Property and Copyright Statements . . . . . . . . 23 - - - - - - - -Kamite, et. al. Expires April 15, 2005 [Page 2] - -INTERNET-DRAFT October 2004 - - -1. Introduction - - TSIG [RFC2845] provides DNS message integrity and the - request/transaction authentication by means of message authentication - codes (MAC). TSIG is a practical solution in view of calculation - speed and availability. However, TSIG does not have exchanging - mechanism of shared secret keys between server and resolver, and - administrators might have to exchange secret keys manually. TKEY - [RFC2930] is introduced to solve such problem and it can exchange - secrets for TSIG via networks. - - In various modes of TKEY, a server and a resolver can add or delete a - secret key be means of TKEY message exchange. However, the existing - TKEY does not care fully about the management of keys which became - too old, or dangerous after long time usage. - - It is ideal that the number of secret which a pair of hosts share - should be limited only one, because having too many keys for the same - purpose might not only be a burden to resolvers for managing and - distinguishing according to servers to query, but also does not seem - to be safe in terms of storage and protection against attackers. - Moreover, perhaps holding old keys long time might give attackers - chances to compromise by scrupulous calculation. - - Therefore, when a new shared secret is established by TKEY, the - previous old secret should be revoked immediately. To accomplish - this, DNS servers must support a protocol for key renewal. This - document specifies procedure to refresh secret keys between two hosts - which is defined within the framework of TKEY, and it is called "TKEY - Secret Key Renewal Mode". - - The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", "MAY" and - "OPTIONAL" in this document are to be interpreted as described in - [RFC2119]. - - -1.1. Defined Words - - * Inception Time: Beginning of the shared secret key lifetime. This - value is determined when the key is generated. - - * Expiry Limit: Time limit of the key's validity. This value is - determined when a new key is generated. After Expiry Limit, server - and client (resolver) must not authenticate TSIG signed with the key. - Therefore, Renewal to the next key should be carried out before - Expiry Limit. - - * Partial Revocation Time: Time when server judges the key is too old - - - -Kamite, et. al. Expires April 15, 2005 [Page 3] - -INTERNET-DRAFT October 2004 - - - and must be updated. It must be between Inception Time and Expiry - Limit. This value is determined by server freely following its - security policy. e.g., If the time from Inception to Partial - Revocation is short, renewal will be carried out more often, which - might be safer. - - * Revocation Time: Time when the key becomes invalid and can be - removed. This value is not determined in advance because it is the - actual time when revocation is completed. - - * Adoption Time: Time when the new key is adopted as the next key - formally. After Adoption, the key is valid and server and client can - generate or verify TSIG making use of it. Adoption Time also means - the time when it becomes possible to remove the previous key, so - Revocation and Adoption are usually done at the same time. - - - Partial - Inception Revocation Revocation Expiry Limit - | | | | - |----------------|- - - - - - >>|- (revoked) -| - | | | | - previous key | | | - |- - - -|-------------------->> time - | | new key - Inception Adoption - - -1.2. New Format and Assigned Numbers - - TSIG - ERROR = (PartialRevoke), TBD - - TKEY - Mode = (server assignment for key renewal), TBD - Mode = (Diffie-Hellman exchange for key renewal), TBD - Mode = (resolver assignment for key renewal), TBD - Mode = (key adoption), TBD - - -1.3. Overview of Secret Key Renewal Mode - - When a server receives a query from a client signed with a TSIG key, - It always checks if the present time is within the range of usage - duration it considers safe. If it is judged that the key is too old, - i.e., after Partial Revocation Time, the server comes to be in - Partial Revocation state about the key, and this key is called - partially revoked. - - - -Kamite, et. al. Expires April 15, 2005 [Page 4] - -INTERNET-DRAFT October 2004 - - - In this state, if a client sends a normal query (e.g., question about - A RR) other than TKEY Renewal request with TSIG signed with the old - key, the server returns an error message to notify that the time to - renew has come. This is called "PartialRevoke" error message. It is - server's choice whether it returns PartialRevoke or not. If and only - if the server is ready for changing its own key, it decides to return - PartialRevoke. - - The client which got this error is able to notice that it is - necessary to refresh the secret. To make a new shared secret, it - sends a TKEY Renewal request, in which several keying methods are - available. It can make use of TSIG authentication signed with the - partially revoked key mentioned above. - - After new secret establishment, the client sends a TKEY Adoption - request for renewal confirmation. This can also be authenticated with - the partially revoked key. If this is admitted by the server, the new - key is formally adopted, and at the same time the corresponding old - secret is invalidated. Then the client can send the first query again - signed with the new key. - - Key renewal procedure is executed based on two-phase commit - mechanism. The first phase is the TKEY Renewal request and its - response, which means preparatory confirmation for key update. The - second phase is Adoption request and its response. If the server gets - request and client receives the response successfully, they can - finish renewal process. If any error happens and renewal process - fails during these phases, client should roll back to the beginning - of the first phase, and send TKEY Renewal request again. This - rollback can be done until the Expiry Limit of the key. - - -2. Shared Secret Key Renewal - - Suppose a server and a client agree to change their TSIG keys - periodically. Key renewal procedure is defined between two hosts. - -2.1. Key Usage Time Check - - Whenever a server receives a query with TSIG and can find a key that - is used for signing it, the server checks its Inception Time, Partial - Revocation Time and Expiry Limit (this information is usually - memorized by the server). - - When the present time is before Inception Time, the server MUST NOT - verify TSIG with the key, and server acts the same way as when the - key used by the client is not recognized. It follows [RFC2845] 4.5.1. - - - - -Kamite, et. al. Expires April 15, 2005 [Page 5] - -INTERNET-DRAFT October 2004 - - - When the present time is equal to Inception Time, or between - Inception Time and Partial Revocation Time, the behavior of the - server is the same as when a valid key is found. It follows [RFC2845] - 4.5.2 and 4.5.3. - - When the present time is the same as the Partial Revocation Time, or - between the Partial Revocation Time and Expiry Limit, the server - comes to be in Partial Revocation state about the TSIG key and - behaves according to the next section. - - When the present time is the same as the Expiry Time or after it, the - server MUST NOT verify TSIG with the key, and returns error messages - in the same way as when the key used by the client is not recognized. - It follows [RFC2845] 4.5.1. - - -2.2. Partial Revocation - - In Partial Revocation state, we say the server has partially revoked - the key and the key has become a "partially revoked key". - - If server has received a query signed with the partially revoked key - for TKEY Renewal request (See section 2.3.) or Key Adoption request - (See section 2.4.), then server does proper process following each - specification. If it is for TKEY key deletion request ([RFC2930] - 4.2), server MAY process usual deletion operation defined therein. - - If server receives other types of query signed with the partially - revoked key, and both the corresponding MAC and signed TIME are - verified, then server begins returning answer whose TSIG error code - is "PartialRevoke" (See section 9.). Server MUST randomly but with - increasing frequency return PartialRevoke when in the Partial - Revocation state. - - Server can decide when it actually sends PartialRevoke, checking if - it is appropriate time for renewal. Server MUST NOT return - PartialRevoke if this is apart long lived TSIG transaction (such as - AXFR) that started before the Partial Revocation Time. - - If the client receives PartialRevoke and understands it, then it MUST - retry the query with the old key unless a new key has been adopted. - Client SHOULD start the process to renew the TSIG key. For key - renewal procedure, see details in Section 2.3 and 2.4. - - PartialRevoke period (i.e., time while server returns PartialRevoke - randomely) SHOULD be small, say 2-5% of key lifetime. This is - server's choice. - - - - -Kamite, et. al. Expires April 15, 2005 [Page 6] - -INTERNET-DRAFT October 2004 - - - Server MUST keep track of clients ignoring PartialRevoke, thus - indicating ignorance of this TKEY mode. - - PartialRevoke error messages have the role to inform clients of the - keys' partial revocation and urge them to send TKEY Renewal requests. - These error responses MUST be signed with those partial revoked keys - if the queries are signed with them. They are sent only when the - signing keys are found to be partially revoked. If the MAC of TSIG - cannot be verified with the partially revoked keys, servers MUST NOT - return PartialRevoke error with MAC, but MUST return another error - such as "BADSIG" without MAC (following [RFC2845] 4.5.3); in other - words, a server informs its key's partial revocation only when the - MAC in the received query is valid. - - -2.3. Key Renewal Message Exchange - -2.3.1. Query for Key Renewal - - If a client has received a PartialRevoke error and authenticated the - response based on TSIG MAC, it sends a TKEY query for Key Renewal (in - this document, we call it Renewal request, too.) to the server. The - request MUST be signed with TSIG or SIG(0) [RFC2931] for - authentication. If TSIG is selected, the client can sign it with the - partial revoked key. - - Key Renewal can use one of several keying methods which is indicated - in "Mode" field of TKEY RR, and its message structure is dependent on - that method. - - -2.3.2. Response for Key Renewal - - The server which has received Key Renewal request first tries to - verify TSIG or SIG(0) accompanying it. If the TSIG is signed and - verified with the partially revoked key, the request MUST be - authenticated. - - After authentication, server must check existing old key's validity. - If the partially revoked key indicated in the request TKEY's OldName - and OldAlgorithm field (See section 2.3.4.) does not exist at the - server, "BADKEY" [RFC2845] is given in Error field for response. If - any other error happens, server returns appropriate error messages - following the specification described in section 2.5. If there are no - errors, server returns a Key Renewal answer. This answer MUST be - signed with TSIG or SIG(0) for authentication. - - When this answer is successfully returned and no error is detected by - - - -Kamite, et. al. Expires April 15, 2005 [Page 7] - -INTERNET-DRAFT October 2004 - - - client, a new shared secret can be established. The details of - concrete keying procedure are given in the section 2.5. - - Note: - Sometimes Adoption message and new Renewal request will cross on - the wire. In this case the newly generated key Adoption message is - resent. - - -2.3.3. Attributes of Generated Key - - As a result of this message exchange, client comes to know the newly - generated key's attributes such as key's name, Inception Time and - Expiry Limit. They are decided by the server and told to the client; - in particular, however, once the server has decided Expiry Limit and - returned a response, it should obey the decision as far as it can. In - other words, they SHOULD NOT change time values for checking Expiry - Limit in the future without any special reason, such as security - issue like "Emergency Compulsory Revocation" described in section 8. - - On the other hand, Partial Revocation Time of this generated key is - not decided based on the request, and not informed to the client. The - server can determine any value as long as it is between Inception - Time and Expiry Limit. However, the period from Inception to Partial - Revocation SHOULD be fixed as the server side's configuration or be - set the same as the corresponding old key's one. - - Note: - Even if client sends Key Renewal request though the key described - in OldName has not been partially revoked yet, server does renewal - processes. At the moment when the server accepts such requests - with valid authentication, it MUST forcibly consider the key is - already partially revoked, that is, the key's Partial Revocation - Time must be changed into the present time (i.e., the time when - the server receives the request). - - -2.3.4. TKEY RR structure - - TKEY RR for Key Renewal message has the structure given below. In - principle, format and definition for each field follows [RFC2930]. - Note that each keying scheme sometimes needs different interpretation - of RDATA field; for detail, see section 2.5. - - Field Type Comment - ------- ------ ------- - NAME domain used for a new key, see below - TYPE u_int16_t (defined in [RFC2930]) - - - -Kamite, et. al. Expires April 15, 2005 [Page 8] - -INTERNET-DRAFT October 2004 - - - CLASS u_int16_t (defined in [RFC2930]) - TTL u_int32_t (defined in [RFC2930]) - RDLEN u_int16_t (defined in [RFC2930]) - RDATA: - Algorithm: domain algorithm for a new key - Inception: u_int32_t about the keying material - Expiration: u_int32_t about the keying material - Mode: u_int16_t scheme for key agreement - see section 9. - Error: u_int16_t see description below - Key Size: u_int16_t see description below - Key Data: octet-stream - Other Size: u_int16_t (defined in [RFC2930]) - size of other data - Other Data: newly defined: see description below - - - For "NAME" field, both non-root and root name are allowed. It may - be used for a new key's name in the same manner as [RFC2930] 2.1. - - "Algorithm" specifies which algorithm is used for agreed keying - material, which is used for identification of the next key. - - "Inception" and "Expiration" are used for the valid period of - keying material. The meanings differ somewhat according to whether - the message is request or answer, and its keying scheme. - - "Key Data" has different meanings according to keying schemes. - - "Mode" field stores the value in accordance with the keying method, - and see section 2.5. Servers and clients supporting TKEY Renewal - method MUST implement "Diffie-Hellman exchange for key renewal" - scheme. All other modes are OPTIONAL. - - "Error" is an extended RCODE which includes "PartialRevoke" value - too. See section 9. - - "Other Data" field has the structure given below. They describe - attributes of the key to be renewed. - - in Other Data filed: - - Field Type Comment - ------- ------ ------- - OldNAME domain name of the old key - OldAlgorithm domain algorithm of the old key - - - - - -Kamite, et. al. Expires April 15, 2005 [Page 9] - -INTERNET-DRAFT October 2004 - - - "OldName" indicates the name of the previous key (usually, - this is partially revoked key's name that client noticed by - PartialRevoke answer from server), and "OldAlogirthm" - indicates its algorithm. - - -2.4. Key Adoption - -2.4.1. Query for Key Adoption - - After receiving a TKEY Renewal answer, the client gets the same - secret as the server. Then, it sends a TKEY Adoption request. The - request's question section's QNAME field is the same as the NAME - filed of TKEY written below. In additional section, there is one TKEY - RR that has the structure and values described below. - - "NAME" field is the new key's name to be adopted which was already - generated by Renewal message exchange. "Algorithm" is its - algorithm. "Inception" means the key's Inception Time, and - "Expiration" means Expiry Limit. - - "Mode" field is the value of "key adoption". See section 9. - - "Other Data" field in Adoption has the same structure as that of - Renewal request message. "OldName" means the previous old key, and - "OldAlogirthm" means its algorithm. - - Key Adoption request MUST be signed with TSIG or SIG(0) for - authentication. The client can sign TSIG with the previous key. Note - that until Adoption is finished, the new key is treated as invalid, - thus it cannot be used for authentication immediately. - - -2.4.2. Response for Key Adoption - - The server which has received Adoption request, it verifies TSIG or - SIG(0) accompanying it. If the TSIG is signed with the partially - revoked key and can be verified, the message MUST be authenticated. - - If the next new key indicated by the request TKEY's "NAME" is not - present at the server, BADNAME [RFC2845] is given in Error field and - the error message is returned. - - If the next key exists but it has not been adopted formally yet, the - server confirms the previous key's existence indicated by the - "OldName" and "OldAlgorithm" field. If it succeeds, the server - executes Adoption of the next key and Revocation of the previous key. - Response message duplicates the request's TKEY RR with NOERROR, - - - -Kamite, et. al. Expires April 15, 2005 [Page 10] - -INTERNET-DRAFT October 2004 - - - including "OldName" and "OldAlgorithm" that indicate the revoked key. - - If the next key exists but it is already adopted, the server returns - a response message regardless of the substance of the request TKEY's - "OldName". In this response, Response TKEY RR has the same data as - the request's one except as to its "Other Data" that is changed into - null (i.e., "Other Size" is zero), which is intended for telling the - client that the previous key name was ignored, and the new key is - already available. - - Client sometimes has to retry Adoption request. Suppose the client - sent request signed with the partially revoked key, but its response - did not return successfully (e.g., due to the drop of UDP packet). - Client will probably retry Adoption request; however, the request - will be refused in the form of TSIG "BADKEY" error because the - previous key was already revoked. In this case, client will - retransmit Adoption request signed with the next key, and expect a - response which has null "Other Data" for confirming the completion of - renewal. - - -2.5. Keying Schemes - - In Renewal message exchanges, there are no limitations as to which - keying method is actually used. The specification of keying - algorithms is independent of the general procedure of Renewal that is - described in section 2.3. - - Now this document specifies three algorithms in this section, but - other future documents can make extensions defining other methods. - - -2.5.1. DH Exchange for Key Renewal - - This scheme is defined as an extended method of [RFC2930] 4.1. This - specification only describes the difference from it and special - notice; assume that all other points, such as keying material - computation, are the exactly same as the specification of [RFC2930] - 4.1. - - Query - In Renewal request for type TKEY with this mode, there is one TKEY - RR and one KEY RR in the additional information section. KEY RR is - the client's Diffie-Hellman public key [RFC2539]. - - QNAME in question section is the same as that of "NAME" field in - TKEY RR, i.e., it means the requested new key's name. - - - - -Kamite, et. al. Expires April 15, 2005 [Page 11] - -INTERNET-DRAFT October 2004 - - - TKEY "Mode" field stores the value of "DH exchange for key - renewal". See section 9. - - TKEY "Inception" and "Expiration" are those requested for the - keying material, that is, requested usage period of a new key. - - TKEY "Key Data" is used as a random, following [RFC2930] 4.1. - - Response - The server which received this request first verifies the TSIG, - SIG(0) or DNSSEC lookup of KEY RR used. After authentication, the - old key's existence validity is checked, following section 2.3. If - any incompatible DH key is found in the request, "BADKEY" - [RFC2845] is given in Error field for response. "FORMERR" is given - if the query included no DH KEY. - - If there are no errors, the server processes a response according - to Diffie-Hellman algorithm and returns the answer. In this - answer, there is one TKEY RR in answer section and KEY RR(s) in - additional section. - - As long as no error has occurred, all values of TKEY are equal to - that of the request message except TKEY NAME, TKEY RDLEN, RDATA's - Inception, Expiration, Key Size and Key Data. - - TKEY "NAME" field in the answer specifies the name of newly - produced key which the client MUST use. - - TKEY "Inception" and "Expiration" mean the periods of the produced - key usage. "Inception" is set to be the time when the new key is - actually generated or the time before it, and it will be regarded - as Inception Time. "Expiration" is determined by the server, and - it will be regarded as Expiry Limit. - - TKEY "Key Data" is used as an additional nonce, following - [RFC2930] 4.1. - - The resolver supplied Diffie-Hellman KEY RR SHOULD be echoed in - the additional section and a server Diffie-Hellman KEY RR will - also be present in the answer section, following [RFC2930] 4.1. - - -2.5.2. Server Assigned Keying for Key Renewal - - This scheme is defined as an extended method of [RFC2930] 4.4. This - specification only describes the difference from it and special - notice; assume that all other points, such as secret encrypting - method, are the exactly same as the specification of [RFC2930] 4.4. - - - -Kamite, et. al. Expires April 15, 2005 [Page 12] - -INTERNET-DRAFT October 2004 - - - Query - In Renewal request for type TKEY with this mode, there is one TKEY - RR and one KEY RR in the additional information section. KEY RR is - used in encrypting the response. - - QNAME in question section is the same as that of "NAME" field in - TKEY RR, i.e., it means the requested new key's name. - - TKEY "Mode" field stores the value of "server assignment for key - renewal". See section 9. - - TKEY "Inception" and "Expiration" are those requested for the - keying material, that is, requested usage period of a new key. - - TKEY "Key Data" is provided following the specification of - [RFC2930] 4.4. - - Response - The server which received this request first verifies the TSIG, - SIG(0) or DNSSEC lookup of KEY RR used. After authentication, the - old key's existence validity is checked, following section 2.3. - "FORMERR" is given if the query specified no encryption key. - - If there are no errors, the server response contains one TKEY RR - in the answer section, and echoes the KEY RR provided in the query - in the additional information section. - - TKEY "NAME" field in the answer specifies the name of newly - produced key which the client MUST use. - - TKEY "Inception" and "Expiration" mean the periods of the produced - key usage. "Inception" is set to be the time when the new key is - actually generated or the time before it, and it will be regarded - as Inception Time. "Expiration" is determined by the server, and - it will be regarded as Expiry Limit. - - TKEY "Key Data" is the assigned keying data encrypted under the - public key in the resolver provided KEY RR, which is the same as - [RFC2930] 4.4. - - -2.5.3. Resolver Assigned Keying for Key Renewal - - This scheme is defined as an extended method of [RFC2930] 4.5. This - specification only describes the difference from it and special - notice; assume that all other points, such as secret encrypting - method, are the exactly same as the specification of [RFC2930] 4.5. - - - - -Kamite, et. al. Expires April 15, 2005 [Page 13] - -INTERNET-DRAFT October 2004 - - - Query - In Renewal request for type TKEY with this mode, there is one TKEY - RR and one KEY RR in the additional information section. TKEY RR - has the encrypted keying material and KEY RR is the server public - key used to encrypt the data. - - QNAME in question section is the same as that of "NAME" field in - TKEY RR, i.e., it means the requested new key's name. - - TKEY "Mode" field stores the value of "resolver assignment for key - renewal". See section 9. - - TKEY "Inception" and "Expiration" are those requested for the - keying material, that is, requested usage period of a new key. - - TKEY "Key Data" is the encrypted keying material. - - Response - The server which received this request first verifies the TSIG, - SIG(0) or DNSSEC lookup of KEY RR used. After authentication, the - old key's existence validity is checked, following section 2.3. - "FORMERR" is given if the server does not have the corresponding - private key for the KEY RR that was shown sin the request. - - If there are no errors, the server returns a response. The - response contains a TKEY RR in the answer section to tell the - shared key's name and its usage time values. - - TKEY "NAME" field in the answer specifies the name of newly - produced key which the client MUST use. - - TKEY "Inception" and "Expiration" mean the periods of the produced - key usage. "Inception" is set to be the time when the new key is - actually generated or the time before it, and it will be regarded - as Inception Time. "Expiration" is determined by the server, and - it will be regarded as Expiry Limit. - - -2.6. Considerations about Non-compliant Hosts - - Key Renewal requests and responses must be exchanged between hosts - which can understand them and do proper processes. PartialRevoke - error messages will be only ignored if they should be returned to - non-compliant hosts. - - Note that server does not inform actively the necessity of renewal to - clients, but inform it as responses invoked by client's query. - Server needs not care whether the PartialRevoke errors has reached - - - -Kamite, et. al. Expires April 15, 2005 [Page 14] - -INTERNET-DRAFT October 2004 - - - client or not. If client has not received yet because of any reasons - such as packet drops, it will resend the queries, and finally will be - able to get PartialRevoke information. - - -3. Secret Storage - - Every server keeps all secrets and attached information, e.g., - Inception Time, Expiry Limit, etc. safely to be able to recover from - unexpected stop. To accomplish this, formally adopted keys SHOULD be - memorized not only on memory, but also be stored in the form of some - files. It will become more secure if they are stored in ecrypted - form. - - -4. Compulsory Key Revocation - -4.1. Compulsory Key Revocation by Server - - There is a rare but possible case that although servers have already - partially revoked keys, clients do not try to send any Renewal - requests. If this state continues, in the future it will become the - time of Expiry Limit. After Expiry Limit, the keys will be expired - and completely removed, so this is called Compulsory Key Revocation - by server. - - If Expiry Limit is too distant from the Partial Revocation Time, then - even though very long time passes, clients will be able to refresh - secrets only if they add TSIG signed with those old partially revoked - keys into requests, which is not safe. - - On the other hand, if Expiry Limit is too close to Partial Revocation - Time, perhaps clients might not be able to notice their keys' Partial - Revocation by getting "PartialRevoke" errors. - - Therefore, servers should set proper Expiry Limit to their keys, - considering both their keys' safety, and enough time for clients to - send requests and process renewal. - - -4.2. Authentication Methods Considerations - - It might be ideal to provide both SIG(0) and TSIG as authentication - methods. For example: - - A client and a server start SIG(0) authentication at first, to - establish TSIG shared keys by means of "Query for Diffie-Hellman - Exchanged Keying" as described in [RFC2930] 4.1. Once they get - - - -Kamite, et. al. Expires April 15, 2005 [Page 15] - -INTERNET-DRAFT October 2004 - - - shared secret, they keep using TSIG for queries and responses. - After a while the server returns a "ParitalRevoke" error and they - begin a key renewal process. Both TSIG signed with partially - revoked keys and SIG(0) are okay for authentication, but TSIG would - be easier to use considering calculation efficiency. - - Suppose now client is halted for long time with some reason. - Because server does not execute any renewal process, it will - finally do Compulsory Revocation. Even if client restarts and sends - a key Renewal request, it will fail because old key is already - deleted at server. - - At this moment, however, if client also uses SIG(0) as another - authentication method, it can make a new shared key again and - recover successfully by sending "Query for Diffie-Hellman Exchanged - Keying" with SIG(0). - - -5. Special Considerations for Two servers' Case - - This section refers to the case where both hosts are DNS servers - which can act as full resolvers as well and using one shared key - only. If one server (called Server A) wants to refresh a shared key - (called "Key A-B"), it will await a TKEY Renewal request from the - other server (called Server B). However, perhaps Server A wants to - refresh the key right now. - - In this case, Server A is allowed to send a Renewal request to Server - B, if Server A knows the Key A-B is too old and wants to renew it - immediately. - - Note that the initiative in key renewal belongs to Server A because - it can notice the Partial Revocation Time and decide key renewal. If - Server B has information about Partial Revocation Time as well, it - can also decide for itself to send Renewal request to Server A. - However, it is not essential for both two servers have information - about key renewal timing. - -5.1. To Cope with Collisions of Renewal Requests - - At least one of two hosts which use Key Renewal must know their key - renewal information such as Partial Revocation Time. It is okay that - both hosts have it. - - Provided that both two servers know key renewal timing information, - there is possibility for them to begin partial revocation and sending - Renewal requests to each other at the same time. Such collisions will - not happen so often because Renewal requests are usually invoked when - - - -Kamite, et. al. Expires April 15, 2005 [Page 16] - -INTERNET-DRAFT October 2004 - - - hosts want to send queries, but it is possible. - - When one of two servers tries to send Renewal requests, it MUST - protect old secrets that it has partially revoked and prevent it from - being refreshed by any requests from the other server (i.e., it must - lock the old secret during the process of renewal). While the server - is sending Renewal requests and waiting responses, it ignores the - other server's Renewal requests. - - Therefore, servers might fail to change secrets by means of their own - requests to others. After failure they will try to resend, but they - should wait for random delays by the next retries. If they get any - Renewal requests from others while they are waiting, their shared - keys may be refreshed, then they do not need to send any Renewal - requests now for themselves. - - -6. Key Name Considerations - - Since both servers and clients have only to distinguish new secrets - and old ones, keys' names do not need to be specified strictly. - However, it is recommended that some serial number or key generation - time be added to the name and that the names of keys between the same - pair of hosts should have some common labels among their keys. For - example, suppose A.example.com. and B.example.com. share the key - ".A.example.com.B.example.com." such as - "10010.A.example.com.B.example.com.". After key renewal, they change - their secret and name into "10011.A.example.com.B.example.com." - - Servers and clients must be able to use keys properly for each query. - Because TSIG secret keys themselves do not have any particular IDs to - be distinguished and would be identified by their names and - algorithm, it must be understood correctly what keys are refreshed. - - -7. Example Usage of Secret Key Renewal Mode - - This is an example of Renewal mode usage where a Server, - server.example.com, and a Client, client.exmple.com have an initial - shared secret key named "00.client.example.com.server.example.com". - - (1) The time values for key - "00.client.example.com.server.example.com" was set as follows: - Inception Time is at 1:00, Expiry Limit is at 21:00. - - (2) At Server, renewal time has been set: Partial Revocation Time - is at 20:00. - - - - -Kamite, et. al. Expires April 15, 2005 [Page 17] - -INTERNET-DRAFT October 2004 - - - (3) Suppose the present time is 19:55. If Client sends a query - signed with key "00.client.example.com.server.example.com" to ask - the IP address of "www.example.com", finally it will get a proper - answer from Server with valid TSIG (NOERROR). - - (4) At 20:05. Client sends a query to ask the IP address of - "www2.example.com". It is signed with key - "00.client.example.com.server.example.com". Server returns an - answer for the IP address. However, server has begun retuning - PartialRevoke Error randomely. This answer includes valid TSIG MAC - signed with "00.client.example.com.server.example.com", and its - Error Code indicates PartialRevoke. Client understands that the - current key is partially revoked. - - (5) At 20:06. Client sends a Renewal request to Server. This - request is signed with key - "00.client.example.com.server.example.com". It includes data such - as: - - Question Section: - QNAME = 01.client.example.com. (Client can set this freely) - TYPE = TKEY - - Additional Section: - 01.client.example.com. TKEY - Algorithm = hmac-md5-sig-alg.reg.int. - Inception = (value meaning 20:00) - Expiration = (value meaning next day's 16:00) - Mode = (DH exchange for key renewal) - OldName = 00.client.example.com.server.example.com. - OldAlgorithm = hmac-md5-sig-alg.reg.int. - - Additional Section also contains a KEY RR for DH and a TSIG RR. - - (6) As soon as Server receives this request, it verifies TSIG. It - is signed with the partially revoked key - "00.client.example.com.server.example.com". and Server accepts the - request. It creates a new key by Diffie-Hellman calculation and - returns an answer which includes data such as: - - Answer Section: - 01.client.example.com.server.example.com. TKEY - Algorithm = hmac-md5-sig-alg.reg.int. - Inception = (value meaning 20:00) - Expiration = (value meaning next day's 16:00) - Mode = (DH exchange for key renewal) - OldName = 00.client.example.com.server.example.com. - OldAlgorithm = hmac-md5-sig-alg.reg.int. - - - -Kamite, et. al. Expires April 15, 2005 [Page 18] - -INTERNET-DRAFT October 2004 - - - Answer Section also contains KEY RRs for DH. - - Additional Section also contains a TSIG RR. - This response is signed with key - "00.client.example.com.server.example.com" without error. - - At the same time, Server decides to set the Partial Revocation Time - of this new key "01.client.example.com.server.example.com." as next - day's 15:00. - - (7) Client gets the response and checks TSIG MAC, and calculates - Diffie-Hellman. It will get a new key, and it has been named - "01.client.example.com.server.example.com" by Server. - - (8) At 20:07. Client sends an Adoption request to Server. This - request is signed with the previous key - "00.client.example.com.server.example.com". It includes: - - Question Section: - QNAME = 01.client.example.com.server.example.com. - TYPE = TKEY - - Additional Section: - 01.client.example.com.server.example.com. TKEY - Algorithm = hmac-md5-sig-alg.reg.int. - Inception = (value meaning 20:00) - Expiration = (value meaning next day's 16:00) - Mode = (key adoption) - OldName = 00.client.example.com.server.example.com. - OldAlgorithm = hmac-md5-sig-alg.reg.int. - - Additional Section also contains a TSIG RR. - - (9) Server verifies the query's TSIG. It is signed with the - previous key and authenticated. It returns a response whose TKEY RR - is the same as the request's one. The response is signed with key - "00.client.example.com.server.example.com.". As soon as the - response is sent, Server revokes and removes the previous key. At - the same time, key "01.client.example.com.server.example.com." is - validated. - - (10) Client acknowledges the success of Adoption by receiving the - response. Then, it retries to send an original question about - "www2.example.com". It is signed with the adopted key - "01.client.example.com.server.example.com", so Server authenticates - it and returns an answer. - - - - - -Kamite, et. al. Expires April 15, 2005 [Page 19] - -INTERNET-DRAFT October 2004 - - - (11) This key is used until next day's 15:00. After that, it will - be partially revoked again. - - -8. Security Considerations - - This document considers about how to refresh shared secret. Secret - changed by this method is used at servers in support of TSIG - [RFC2845]. - - [RFC2104] says that current attacks to HMAC do not indicate a - specific recommended frequency for key changes but periodic key - refreshment is a fundamental security practice that helps against - potential weaknesses of the function and keys, and limits the damage - of an exposed key. TKEY Secret Key Renewal provides the method of - periodical key refreshment. - - In TKEY Secret Key Renewal, clients need to send two requests - (Renewal and Adoption) and spend time to finish their key renewal - processes. Thus the usage period of secrets should be considered - carefully based on both TKEY processing performance and security. - - This document specifies the procedure of periodical key renewal, but - actually there is possibility for servers to have no choice other - than revoking their secret keys immediately especially when the keys - are found to be compromised by attackers. This is called "Emergency - Compulsory Revocation". For example, suppose the original Expiry - Limit was set at 21:00, Partial Revocation Time at 20:00 and - Inception Time at 1:00. if at 11:00 the key is found to be - compromised, the server sets Expiry Limit forcibly to be 11:00 or - before it. - - Consequently, once Compulsory Revocation (See section 4.) is carried - out, normal renewal process described in this document cannot be done - any more as far as the key is concerned. However, after such - accidents happened, the two hosts are able to establish secret keys - and begin renewal procedure only if they have other (non-compromised) - shared TSIG keys or safe SIG(0) keys for the authentication of - initial secret establishment such as Diffie-Hellman Exchanged Keying. - - -9. IANA Considerations - - IANA needs to allocate a value for "DH exchange for key renewal", - "server assignment for key renewal", "resolver assignment for key - renewal" and "key adoption" in the mode filed of TKEY. It also needs - to allocate a value for "PartialRevoke" from the extended RCODE - space. - - - -Kamite, et. al. Expires April 15, 2005 [Page 20] - -INTERNET-DRAFT October 2004 - - -10. Acknowledgements - - The authors would like to thank Olafur Gudmundsson, whose helpful - input and comments contributed greatly to this document. - - -11. References - -11.1. Normative References - -[RFC2119] - Bradner, S., "Key words for use in RFCs to Indicate Requirement - Levels", RFC 2119, March 1997. - -[RFC2539] - D. Eastlake 3rd, "Storage of Diffie-Hellman Keys in the Domain Name - System (DNS)", RFC 2539, March 1999. - -[RFC2845] - Vixie, P., Gudmundsson, O., Eastlake, D. and B. Wellington, - "Secret Key Transaction Authentication for DNS (TSIG)", RFC 2845, - May 2000. - -[RFC2930] - D. Eastlake 3rd, ``Secret Key Establishment for DNS (TKEY RR)'', - RFC 2930, September 2000. - -[RFC2931] - D. Eastlake 3rd, "DNS Request and Transaction Signatures (SIG(0)s - )", RFC 2931, September 2000. - -11.2. Informative References - -[RFC2104] - H. Krawczyk, M.Bellare, R. Canetti, "Keyed-Hashing for Message - Authentication", RFC2104, February 1997. - - - - - - - - - - - - - - - -Kamite, et. al. Expires April 15, 2005 [Page 21] - -INTERNET-DRAFT October 2004 - - -Authors' Addresses - - Yuji Kamite - NTT Communications Corporation - Tokyo Opera City Tower - 3-20-2 Nishi Shinjuku, Shinjuku-ku, Tokyo - 163-1421, Japan - EMail: y.kamite@ntt.com - - - Masaya Nakayama - Information Technology Center, The University of Tokyo - 2-11-16 Yayoi, Bunkyo-ku, Tokyo - 113-8658, Japan - EMail: nakayama@nc.u-tokyo.ac.jp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Kamite, et. al. Expires April 15, 2005 [Page 22] - -INTERNET-DRAFT October 2004 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2004). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Kamite, et. al. Expires April 15, 2005 [Page 23] - - - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-trustupdate-threshold-00.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-trustupdate-threshold-00.txt deleted file mode 100644 index a598826..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-trustupdate-threshold-00.txt +++ /dev/null @@ -1,1501 +0,0 @@ -Network Working Group J. Ihren -Internet-Draft Autonomica AB -Expires: April 18, 2005 O. Kolkman - RIPE NCC - B. Manning - EP.net - October 18, 2004 - - - - An In-Band Rollover Mechanism and an Out-Of-Band Priming Method for - DNSSEC Trust Anchors. - draft-ietf-dnsext-trustupdate-threshold-00 - - -Status of this Memo - - - By submitting this Internet-Draft, I certify that any applicable - patent or other IPR claims of which I am aware have been disclosed, - and any of which I become aware will be disclosed, in accordance with - RFC 3668. - - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as - Internet-Drafts. - - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - - This Internet-Draft will expire on April 18, 2005. - - -Copyright Notice - - - Copyright (C) The Internet Society (2004). All Rights Reserved. - - -Abstract - - - The DNS Security Extensions (DNSSEC) works by validating so called - chains of authority. The start of these chains of authority are - usually public keys that are anchored in the DNS clients. These keys - are known as the so called trust anchors. - - - - - -Ihren, et al. Expires April 18, 2005 [Page 1] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - - This memo describes a method how these client trust anchors can be - replaced using the DNS validation and querying mechanisms (in-band) - when the key pairs used for signing by zone owner are rolled. - - - This memo also describes a method to establish the validity of trust - anchors for initial configuration, or priming, using out of band - mechanisms. - - -Table of Contents - - - 1. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 1.1 Key Signing Keys, Zone Signing Keys and Secure Entry - Points . . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 2. Introduction and Background . . . . . . . . . . . . . . . . . 5 - 2.1 Dangers of Stale Trust Anchors . . . . . . . . . . . . . . 5 - 3. Threshold-based Trust Anchor Rollover . . . . . . . . . . . . 7 - 3.1 The Rollover . . . . . . . . . . . . . . . . . . . . . . . 7 - 3.2 Threshold-based Trust Update . . . . . . . . . . . . . . . 8 - 3.3 Possible Trust Update States . . . . . . . . . . . . . . . 9 - 3.4 Implementation notes . . . . . . . . . . . . . . . . . . . 10 - 3.5 Possible transactions . . . . . . . . . . . . . . . . . . 11 - 3.5.1 Single DNSKEY replaced . . . . . . . . . . . . . . . . 12 - 3.5.2 Addition of a new DNSKEY (no removal) . . . . . . . . 12 - 3.5.3 Removal of old DNSKEY (no addition) . . . . . . . . . 12 - 3.5.4 Multiple DNSKEYs replaced . . . . . . . . . . . . . . 12 - 3.6 Removal of trust anchors for a trust point . . . . . . . . 12 - 3.7 No need for resolver-side overlap of old and new keys . . 13 - 4. Bootstrapping automatic rollovers . . . . . . . . . . . . . . 14 - 4.1 Priming Keys . . . . . . . . . . . . . . . . . . . . . . . 14 - 4.1.1 Bootstrapping trust anchors using a priming key . . . 14 - 4.1.2 Distribution of priming keys . . . . . . . . . . . . . 15 - 5. The Threshold Rollover Mechanism vs Priming . . . . . . . . . 16 - 6. Security Considerations . . . . . . . . . . . . . . . . . . . 17 - 6.1 Threshold-based Trust Update Security Considerations . . . 17 - 6.2 Priming Key Security Considerations . . . . . . . . . . . 17 - 7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 19 - 8. References . . . . . . . . . . . . . . . . . . . . . . . . . . 20 - 8.1 Normative References . . . . . . . . . . . . . . . . . . . . 20 - 8.2 Informative References . . . . . . . . . . . . . . . . . . . 20 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 20 - A. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 22 - B. Document History . . . . . . . . . . . . . . . . . . . . . . . 23 - B.1 prior to version 00 . . . . . . . . . . . . . . . . . . . 23 - B.2 version 00 . . . . . . . . . . . . . . . . . . . . . . . . 23 - Intellectual Property and Copyright Statements . . . . . . . . 24 - - - - - - - -Ihren, et al. Expires April 18, 2005 [Page 2] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - -1. Terminology - - - The key words "MUST", "SHALL", "REQUIRED", "SHOULD", "RECOMMENDED", - and "MAY" in this document are to be interpreted as described in - RFC2119 [1]. - - - The term "zone" refers to the unit of administrative control in the - Domain Name System. In this document "name server" denotes a DNS - name server that is authoritative (i.e. knows all there is to know) - for a DNS zone. A "zone owner" is the entity responsible for signing - and publishing a zone on a name server. The terms "authentication - chain", "bogus", "trust anchors" and "Island of Security" are defined - in [4]. Throughout this document we use the term "resolver" to mean - "Validating Stub Resolvers" as defined in [4]. - - - We use the term "security apex" as the zone for which a trust anchor - has been configured (by validating clients) and which is therefore, - by definition, at the root of an island of security. The - configuration of trust anchors is a client side issue. Therefore a - zone owner may not always know if their zone has become a security - apex. - - - A "stale anchor" is a trust anchor (a public key) that relates to a - key that is not used for signing. Since trust anchors indicate that - a zone is supposed to be secure a validator will mark the all data in - an island of security as bogus when all trust anchors become stale. - - - It is assumed that the reader is familiar with public key - cryptography concepts [REF: Schneier Applied Cryptography] and is - able to distinguish between the private and public parts of a key - based on the context in which we use the term "key". If there is a - possible ambiguity we will explicitly mention if a private or a - public part of a key is used. - - - The term "administrator" is used loosely throughout the text. In - some cases an administrator is meant to be a person, in other cases - the administrator may be a process that has been delegated certain - responsibilities. - - -1.1 Key Signing Keys, Zone Signing Keys and Secure Entry Points - - - Although the DNSSEC protocol does not make a distinction between - different keys the operational practice is that a distinction is made - between zone signing keys and key signing keys. A key signing key is - used to exclusively sign the DNSKEY Resource Record (RR) set at the - apex of a zone and the zone signing keys sign all the data in the - zone (including the DNSKEY RRset at the apex). - - - - - -Ihren, et al. Expires April 18, 2005 [Page 3] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - - Keys that are intended to be used as the start of the authentication - chain for a particular zone, either because they are pointed to by a - parental DS RR or because they are configured as a trust anchor, are - called Secure Entry Point (SEP) keys. In practice these SEP keys - will be key signing keys. - - - In order for the mechanism described herein to work the keys that are - intended to be used as secure entry points MUST have the SEP [2] flag - set. In the examples it is assumed that keys with the SEP flag set - are used as key signing keys and thus exclusively sign the DNSKEY - RRset published at the apex of the zone. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Ihren, et al. Expires April 18, 2005 [Page 4] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - -2. Introduction and Background - - - When DNSSEC signatures are validated the resolver constructs a chain - of authority from a pre-configured trust anchor to the DNSKEY - Resource Record (RR), which contains the public key that validates - the signature stored in an RRSIG RR. DNSSEC is designed so that the - administrator of a resolver can validate data in multiple islands of - security by configuring multiple trust anchors. - - - It is expected that resolvers will have more than one trust anchor - configured. Although there is no deployment experience it is not - unreasonable to expect resolvers to be configured with a number of - trust anchors that varies between order 1 and order 1000. Because - zone owners are expected to roll their keys, trust anchors will have - to be maintained (in the resolver end) in order not to become stale. - - - Since there is no global key maintenance policy for zone owners and - there are no mechanisms in the DNS to signal the key maintenance - policy it may be very hard for resolvers administrators to keep their - set of trust anchors up to date. For instance, if there is only one - trust anchor configured and the key maintenance policy is clearly - published, through some out of band trusted channel, then a resolver - administrator can probably keep track of key rollovers and update the - trust anchor manually. However, with an increasing number of trust - anchors all rolled according to individual policies that are all - published through different channels this soon becomes an - unmanageable problem. - - -2.1 Dangers of Stale Trust Anchors - - - Whenever a SEP key at a security apex is rolled there exists a danger - that "stale anchors" are created. A stale anchor is a trust anchor - (i.e. a public key configured in a validating resolver) that relates - to a private key that is no longer used for signing. - - - The problem with a stale anchors is that they will (from the - validating resolvers point of view) prove data to be false even - though it is actually correct. This is because the data is either - signed by a new key or is no longer signed and the resolver expects - data to be signed by the old (now stale) key. - - - This situation is arguably worse than not having a trusted key - configured for the secure entry point, since with a stale key no - lookup is typically possible (presuming that the default - configuration of a validating recursive nameserver is to not give out - data that is signed but failed to verify. - - - The danger of making configured trust anchors become stale anchors - - - - -Ihren, et al. Expires April 18, 2005 [Page 5] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - - may be a reason for zone owners not to roll their keys. If a - resolver is configured with many trust anchors that need manual - maintenance it may be easy to not notice a key rollover at a security - apex, resulting in a stale anchor. - - - In Section 3 this memo sets out a lightweight, in-DNS, mechanism to - track key rollovers and modify the configured trust anchors - accordingly. The mechanism is stateless and does not need protocol - extensions. The proposed design is that this mechanism is - implemented as a "trust updating machine" that is run entirely - separate from the validating resolver except that the trust updater - will have influence over the trust anchors used by the latter. - - - In Section 4 we describe a method [Editors note: for now only the - frame work and a set of requirements] to install trust anchors. This - method can be used at first configuration or when the trust anchors - became stale (typically due to a failure to track several rollover - events). - - - The choice for which domains trust anchors are to be configured is a - local policy issue. So is the choice which trust anchors has - prevalence if there are multiple chains of trust to a given piece of - DNS data (e.g. when a parent zone and its child both have trust - anchors configured). Both issues are out of the scope of this - document. - - - - - - - - - - - - - - - - - - - - - - - - - - - -Ihren, et al. Expires April 18, 2005 [Page 6] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - -3. Threshold-based Trust Anchor Rollover - - -3.1 The Rollover - - - When a key pair is replaced all signatures (in DNSSEC these are the - RRSIG records) created with the old key will be replaced by new - signatures created by the new key. Access to the new public key is - needed to verify these signatures. - - - Since zone signing keys are in "the middle" of a chain of authority - they can be verified using the signature made by a key signing key. - Rollover of zone signing keys is therefore transparent to validators - and requires no action in the validator end. - - - But if a key signing key is rolled a resolver can determine its - authenticity by either following the authorization chain from the - parents DS record, an out-of-DNS authentication mechanism or by - relying on other trust anchors known for the zone in which the key is - rolled. - - - The threshold trust anchor rollover mechanism (or trust update), - described below, is based on using existing trust anchors to verify a - subset of the available signatures. This is then used as the basis - for a decision to accept the new keys as valid trust anchors. - - - Our example pseudo zone below contains a number of key signing keys - numbered 1 through Y and two zone signing keys A and B. During a key - rollover key 2 is replaced by key Y+1. The zone content changes - from: - - - example.com. DNSKEY key1 - example.com. DNSKEY key2 - example.com. DNSKEY key3 - ... - example.com. DNSKEY keyY - - - example.com. DNSKEY keyA - example.com. DNSKEY keyB - - - example.com. RRSIG DNSKEY ... (key1) - example.com. RRSIG DNSKEY ... (key2) - example.com. RRSIG DNSKEY ... (key3) - ... - example.com. RRSIG DNSKEY ... (keyY) - example.com. RRSIG DNSKEY ... (keyA) - example.com. RRSIG DNSKEY ... (keyB) - - - to: - - - - -Ihren, et al. Expires April 18, 2005 [Page 7] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - - example.com. DNSKEY key1 - example.com. DNSKEY key3 - ... - example.com. DNSKEY keyY - example.com. DNSKEY keyY+1 - - - example.com. RRSIG DNSKEY ... (key1) - example.com. RRSIG DNSKEY ... (key3) - ... - example.com. RRSIG DNSKEY ... (keyY) - example.com. RRSIG DNSKEY ... (keyY+1) - example.com. RRSIG DNSKEY ... (keyA) - example.com. RRSIG DNSKEY ... (keyB) - - - When the rollover becomes visible to the verifying stub resolver it - will be able to verify the RRSIGs associated with key1, key3 ... - keyY. There will be no RRSIG by key2 and the RRSIG by keyY+1 will - not be used for validation, since that key is previously unknown and - therefore not trusted. - - - Note that this example is simplified. Because of operational - considerations described in [5] having a period during which the two - key signing keys are both available is necessary. - - -3.2 Threshold-based Trust Update - - - The threshold-based trust update algorithm applies as follows. If - for a particular secure entry point - o if the DNSKEY RRset in the zone has been replaced by a more recent - one (as determined by comparing the RRSIG inception dates) - and - o if at least M configured trust anchors directly verify the related - RRSIGs over the new DNSKEY RRset - and - o the number of configured trust anchors that verify the related - RRSIGs over the new DNSKEY RRset exceed a locally defined minimum - number that should be greater than one - then all the trust anchors for the particular secure entry point are - replaced by the set of keys from the zones DNSKEY RRset that have the - SEP flag set. - - - The choices for the rollover acceptance policy parameter M is left to - the administrator of the resolver. To be certain that a rollover is - accepted up by resolvers using this mechanism zone owners should roll - as few SEP keys at a time as possible (preferably just one). That - way they comply to the most strict rollover acceptance policy of - M=N-1. - - - - - -Ihren, et al. Expires April 18, 2005 [Page 8] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - - The value of M has an upper bound, limited by the number of of SEP - keys a zone owner publishes (i.e. N). But there is also a lower - bound, since it will not be safe to base the trust in too few - signatures. The corner case is M=1 when any validating RRSIG will be - sufficient for a complete replacement of the trust anchors for that - secure entry point. This is not a recommended configuration, since - that will allow an attacker to initiate rollover of the trust anchors - himself given access to just one compromised key. Hence M should in - be strictly larger than 1 as shown by the third requirement above. - - - If the rollover acceptance policy is M=1 then the result for the - rollover in our example above should be that the local database of - trust anchors is updated by removing key "key2" from and adding key - "keyY+1" to the key store. - - -3.3 Possible Trust Update States - - - We define five states for trust anchor configuration at the client - side. - PRIMING: There are no trust anchors configured. There may be priming - keys available for initial priming of trust anchors. - IN-SYNC: The set of trust anchors configured exactly matches the set - of SEP keys used by the zone owner to sign the zone. - OUT-OF-SYNC: The set of trust anchors is not exactly the same as the - set of SEP keys used by the zone owner to sign the zone but there - are enough SEP key in use by the zone owner that is also in the - trust anchor configuration. - UNSYNCABLE: There is not enough overlap between the configured trust - anchors and the set of SEP keys used to sign the zone for the new - set to be accepted by the validator (i.e. the number of - signatures that verify is not sufficient). - STALE: There is no overlap between the configured trust anchors and - the set of SEP keys used to sign the zone. Here validation of - data is no longer possible and hence we are in a situation where - the trust anchors are stale. - - - Of these five states only two (IN-SYNC and OUT-OF-SYNC) are part of - the automatic trust update mechanism. The PRIMING state is where a - validator is located before acquiring an up-to-date set of trust - anchors. The transition from PRIMING to IN-SYNC is manual (see - Section 4 below). - - - Example: assume a secure entry point with four SEP keys and a - validator with the policy that it will accept any update to the set - of trust anchors as long as no more than two signatures fail to - validate (i.e. M >= N-2) and at least two signature does validate - (i.e. M >= 2). In this case the rollover of a single key will move - the validator from IN-SYNC to OUT-OF-SYNC. When the trust update - - - - -Ihren, et al. Expires April 18, 2005 [Page 9] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - - state machine updates the trust anchors it returns to state IN-SYNC. - - - If if for some reason it fails to update the trust anchors then the - next rollover (of a different key) will move the validator from - OUT-OF-SYNC to OUT-OF-SYNC (again), since there are still two keys - that are configured as trust anchors and that is sufficient to accpt - an automatic update of the trust anchors. - - - The UNSYNCABLE state is where a validator is located if it for some - reason fails to incorporate enough updates to the trust anchors to be - able to accept new updates according to its local policy. In this - example (i.e. with the policy specified above) this will either be - because M < N-2 or M < 2, which does not suffice to authenticate a - successful update of trust anchors. - - - Continuing with the previous example where two of the four SEP keys - have already rolled, but the validator has failed to update the set - of trust anchors. When the third key rolls over there will only be - one trust anchor left that can do successful validation. This is not - sufficient to enable automatic update of the trust anchors, hence the - new state is UNSYNCABLE. Note, however, that the remaining - up-to-date trust anchor is still enough to do successful validation - so the validator is still "working" from a DNSSEC point of view. - - - The STALE state, finally, is where a validator ends up when it has - zero remaining current trust anchors. This is a dangerous state, - since the stale trust anchors will cause all validation to fail. The - escape is to remove the stale trust anchors and thereby revert to the - PRIMING state. - - -3.4 Implementation notes - - - The DNSSEC protocol specification ordains that a DNSKEY to which a DS - record points should be self-signed. Since the keys that serve as - trust anchors and the keys that are pointed to by DS records serve - the same purpose, they are both secure entry points, we RECOMMEND - that zone owners who want to facilitate the automated rollover scheme - documented herein self-sign DNSKEYs with the SEP bit set and that - implementation check that DNSKEYs with the SEP bit set are - self-signed. - - - In order to maintain a uniform way of determining that a keyset in - the zone has been replaced by a more recent set the automatic trust - update machine SHOULD only accept new DNSKEY RRsets if the - accompanying RRSIGs show a more recent inception date than the - present set of trust anchors. This is also needed as a safe guard - against possible replay attacks where old updates are replayed - "backwards" (i.e. one change at a time, but going in the wrong - - - - -Ihren, et al. Expires April 18, 2005 [Page 10] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - - direction, thereby luring the validator into the UNSYNCABLE and - finally STALE states). - - - In order to be resilient against failures the implementation should - collect the DNSKEY RRsets from (other) authoritative servers if - verification of the self signatures fails. - - - The threshold-based trust update mechanism SHOULD only be applied to - algorithms, as represented in the algorithm field in the DNSKEY/RRSIG - [3], that the resolver is aware of. In other words the SEP keys of - unknown algorithms should not be used when counting the number of - available signatures (the N constant) and the SEP keys of unknown - algorithm should not be entered as trust anchors. - - - When in state UNSYNCABLE or STALE manual intervention will be needed - to return to the IN-SYNC state. These states should be flagged. The - most appropriate action is human audit possibly followed by - re-priming (Section 4) the keyset (i.e. manual transfer to the - PRIMING state through removal of the configured trust anchors). - - - An implementation should regularly probe the the authoritative - nameservers for new keys. Since there is no mechanism to publish - rollover frequencies this document RECOMMENDS zone owners not to roll - their key signing keys more often than once per month and resolver - administrators to probe for key rollsovers (and apply the threshold - criterion for acceptance of trust update) not less often than once - per month. If the rollover frequency is higher than the probing - frequency then trust anchors may become stale. The exact relation - between the frequencies depends on the number of SEP keys rolled by - the zone owner and the value M configured by the resolver - administrator. - - - In all the cases below a transaction where the threshold criterion is - not satisfied should be considered bad (i.e. possibly spoofed or - otherwise corrupted data). The most appropriate action is human - audit. - - - There is one case where a "bad" state may be escaped from in an - automated fashion. This is when entering the STALE state where all - DNSSEC validation starts to fail. If this happens it is concievable - that it is better to completely discard the stale trust anchors - (thereby reverting to the PRIMING state where validation is not - possible). A local policy that automates removal of stale trust - anchors is therefore suggested. - - -3.5 Possible transactions - - - - - - -Ihren, et al. Expires April 18, 2005 [Page 11] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - -3.5.1 Single DNSKEY replaced - - - This is probably the most typical transaction on the zone owners - part. The result should be that if the threshold criterion is - satisfied then the key store is updated by removal of the old trust - anchor and addition of the new key as a new trust anchor. Note that - if the DNSKEY RRset contains exactly M keys replacement of keys is - not possible, i.e. for automatic rollover to work M must be stricly - less than N. - - -3.5.2 Addition of a new DNSKEY (no removal) - - - If the threshold criterion is satisfied then the new key is added as - a configured trust anchor. Not more than N-M keys can be added at - once, since otherwise the algorithm will fail. - - -3.5.3 Removal of old DNSKEY (no addition) - - - If the threshold criterion is satisfied then the old key is removed - from being a configured trust anchor. Note that it is not possible - to reduce the size of the DNSKEY RRset to a size smaller than the - minimum required value for M. - - -3.5.4 Multiple DNSKEYs replaced - - - Arguably it is not a good idea for the zone administrator to replace - several keys at the same time, but from the resolver point of view - this is exactly what will happen if the validating resolver for some - reason failed to notice a previous rollover event. - - - Not more than N-M keys can be replaced at one time or the threshold - criterion will not be satisfied. Or, expressed another way: as long - as the number of changed keys is less than or equal to N-M the - validator is in state OUT-OF-SYNC. When the number of changed keys - becomes greater than N-M the state changes to UNSYNCABLE and manual - action is needed. - - -3.6 Removal of trust anchors for a trust point - - - If the parent of a secure entry point gets signed and it's trusted - keys get configured in the key store of the validating resolver then - the configured trust anchors for the child should be removed entirely - unless explicitly configured (in the utility configuration) to be an - exception. - - - The reason for such a configuration would be that the resolver has a - local policy that requires maintenance of trusted keys further down - the tree hierarchy than strictly needed from the point of view. - - - - -Ihren, et al. Expires April 18, 2005 [Page 12] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - - The default action when the parent zone changes from unsigned to - signed should be to remove the configured trust anchors for the - child. This form of "garbage collect" will ensure that the automatic - rollover machinery scales as DNSSEC deployment progresses. - - -3.7 No need for resolver-side overlap of old and new keys - - - It is worth pointing out that there is no need for the resolver to - keep state about old keys versus new keys, beyond the requirement of - tracking signature inception time for the covering RRSIGs as - described in Section 3.4. - - - From the resolver point of view there are only trusted and not - trusted keys. The reason is that the zone owner needs to do proper - maintenance of RRSIGs regardless of the resolver rollover mechanism - and hence must ensure that no key rolled out out the DNSKEY set until - there cannot be any RRSIGs created by this key still legally cached. - - - Hence the rollover mechanism is entirely stateless with regard to the - keys involved: as soon as the resolver (or in this case the rollover - tracking utility) detects a change in the DNSKEY RRset (i.e. it is - now in the state OUT-OF-SYNC) with a sufficient number of matching - RRSIGs the configured trust anchors are immediately updated (and - thereby the machine return to state IN-SYNC). I.e. the rollover - machine changes states (mostly oscillating between IN-SYNC and - OUT-OF-SYNC), but the status of the DNSSEC keys is stateless. - - - - - - - - - - - - - - - - - - - - - - - - - - -Ihren, et al. Expires April 18, 2005 [Page 13] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - -4. Bootstrapping automatic rollovers - - - It is expected that with the ability to automatically roll trust - anchors at trust points will follow a diminished unwillingness to - roll these keys, since the risks associated with stale keys are - minimized. - - - The problem of "priming" the trust anchors, or bringing them into - sync (which could happen if a resolver is off line for a long period - in which a set of SEP keys in a zone 'evolve' away from its trust - anchor configuration) remains. - - - For (re)priming we can rely on out of band technology and we propose - the following framework. - - -4.1 Priming Keys - - - If all the trust anchors roll somewhat frequently (on the order of - months or at most about a year) then it will not be possible to - design a device, or a software distribution that includes trust - anchors, that after being manufactured is put on a shelf for several - key rollover periods before being brought into use (since no trust - anchors that were known at the time of manufacture remain active). - - - To alleviate this we propose the concept of "priming keys". Priming - keys are ordinary DNSSEC Key Signing Keys with the characteristic - that - o The private part of a priming key signs the DNSKEY RRset at the - security apex, i.e. at least one RRSIG DNSKEY is created by a - priming key rather than by an "ordinary" trust anchor - o the public parts of priming keys are not included in the DNSKEY - RRset. Instead the public parts of priming keys are only - available out-of-band. - o The public parts of the priming keys have a validity period. - Within this period they can be used to obtain trust anchors. - o The priming key pairs are long lived (relative to the key rollover - period.) - - -4.1.1 Bootstrapping trust anchors using a priming key - - - To install the trust anchors for a particular security apex an - administrator of a validating resolver will need to: - o query for the DNSKEY RRset of the zone at the security apex; - o verify the self signatures of all DNSKEYs in the RRset; - o verify the signature of the RRSIG made with a priming key -- - verification using one of the public priming keys that is valid at - that moment is sufficient; - - - - - -Ihren, et al. Expires April 18, 2005 [Page 14] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - - o create the trust anchors by extracting the DNSKEY RRs with the SEP - flag set. - The SEP keys with algorithms unknown to the validating resolver - SHOULD be ignored during the creation of the trust anchors. - - -4.1.2 Distribution of priming keys - - - The public parts of the priming keys SHOULD be distributed - exclusively through out-of-DNS mechanisms. The requirements for a - distribution mechanism are: - o it can carry the "validity" period for the priming keys; - o it can carry the self-signature of the priming keys; - o and it allows for verification using trust relations outside the - DNS. - A distribution mechanism would benefit from: - o the availability of revocation lists; - o the ability of carrying zone owners policy information such as - recommended values for "M" and "N" and a rollover frequency; - o and the technology on which is based is readily available. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Ihren, et al. Expires April 18, 2005 [Page 15] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - -5. The Threshold Rollover Mechanism vs Priming - - - There is overlap between the threshold-based trust updater and the - Priming method. One could exclusively use the Priming method for - maintaining the trust anchors. However the priming method probably - relies on "non-DNS' technology and may therefore not be available for - all devices that have a resolver. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Ihren, et al. Expires April 18, 2005 [Page 16] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - -6. Security Considerations - - -6.1 Threshold-based Trust Update Security Considerations - - - A clear issue for resolvers will be how to ensure that they track all - rollover events for the zones they have configure trust anchors for. - Because of temporary outages validating resolvers may have missed a - rollover of a KSK. The parameters that determine the robustness - against failures are: the length of the period between rollovers - during which the KSK set is stable and validating resolvers can - actually notice the change; the number of available KSKs (i.e. N) - and the number of signatures that may fail to validate (i.e. N-M). - - - With a large N (i.e. many KSKs) and a small value of M this - operation becomes more robust since losing one key, for whatever - reason, will not be crucial. Unfortunately the choice for the number - of KSKs is a local policy issue for the zone owner while the choice - for the parameter M is a local policy issue for the resolver - administrator. - - - Higher values of M increase the resilience against attacks somewhat; - more signatures need to verify for a rollover to be approved. On the - other hand the number of rollover events that may pass unnoticed - before the resolver reaches the UNSYNCABLE state goes down. - - - The threshold-based trust update intentionally does not provide a - revocation mechanism. In the case that a sufficient number of - private keys of a zone owner are simultaneously compromised the the - attacker may use these private keys to roll the trust anchors of (a - subset of) the resolvers. This is obviously a bad situation but it - is not different from most other public keys systems. - - - However, it is important to point out that since any reasonable trust - anchor rollover policy (in validating resolvers) will require more - than one RRSIG to validate this proposal does provide security - concious zone administrators with the option of not storing the - individual private keys in the same location and thereby decreasing - the likelihood of simultaneous compromise. - - -6.2 Priming Key Security Considerations - - - Since priming keys are not included in the DNSKEY RR set they are - less sensitive to packet size constraints and can be chosen - relatively large. The private parts are only needed to sign the - DNSKEY RR set during the validity period of the particular priming - key pair. Note that the private part of the priming key is used each - time when a DNSKEY RRset has to be resigned. In practice there is - therefore little difference between the usage pattern of the private - - - - -Ihren, et al. Expires April 18, 2005 [Page 17] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - - part of key signing keys and priming keys. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Ihren, et al. Expires April 18, 2005 [Page 18] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - -7. IANA Considerations - - - NONE. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Ihren, et al. Expires April 18, 2005 [Page 19] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - -8. References - - -8.1 Normative References - - - [1] Bradner, S., "Key words for use in RFCs to Indicate Requirement - Levels", BCP 14, RFC 2119, March 1997. - - - [2] Kolkman, O., Schlyter, J. and E. Lewis, "Domain Name System KEY - (DNSKEY) Resource Record (RR) Secure Entry Point (SEP) Flag", - RFC 3757, May 2004. - - - [3] Arends, R., "Resource Records for the DNS Security Extensions", - draft-ietf-dnsext-dnssec-records-10 (work in progress), - September 2004. - - -8.2 Informative References - - - [4] Arends, R., Austein, R., Massey, D., Larson, M. and S. Rose, - "DNS Security Introduction and Requirements", - draft-ietf-dnsext-dnssec-intro-12 (work in progress), September - 2004. - - - [5] Kolkman, O., "DNSSEC Operational Practices", - draft-ietf-dnsop-dnssec-operational-practices-01 (work in - progress), May 2004. - - - [6] Housley, R., Ford, W., Polk, T. and D. Solo, "Internet X.509 - Public Key Infrastructure Certificate and CRL Profile", RFC - 2459, January 1999. - - - -Authors' Addresses - - - Johan Ihren - Autonomica AB - Bellmansgatan 30 - Stockholm SE-118 47 - Sweden - - - EMail: johani@autonomica.se - - - - - - - - - - - - -Ihren, et al. Expires April 18, 2005 [Page 20] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - - Olaf M. Kolkman - RIPE NCC - Singel 256 - Amsterdam 1016 AB - NL - - - Phone: +31 20 535 4444 - EMail: olaf@ripe.net - URI: http://www.ripe.net/ - - - - Bill Manning - EP.net - Marina del Rey, CA 90295 - USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Ihren, et al. Expires April 18, 2005 [Page 21] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - -Appendix A. Acknowledgments - - - The present design for in-band automatic rollovers of DNSSEC trust - anchors is the result of many conversations and it is no longer - possible to remember exactly who contributed what. - - - In addition we've also had appreciated help from (in no particular - order) Paul Vixie, Sam Weiler, Suzanne Woolf, Steve Crocker, Matt - Larson and Mark Kosters. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Ihren, et al. Expires April 18, 2005 [Page 22] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - -Appendix B. Document History - - - This appendix will be removed if and when the document is submitted - to the RFC editor. - - - The version you are reading is tagged as $Revision: 1.1.230.1 $. - - - Text between square brackets, other than references, are editorial - comments and will be removed. - - -B.1 prior to version 00 - - - This draft was initially published as a personal submission under the - name draft-kolkman-dnsext-dnssec-in-band-rollover-00.txt. - - - Kolkman documented the ideas provided by Ihren and Manning. In the - process of documenting (and prototyping) Kolkman changed some of the - details of the M-N algorithms working. Ihren did not have a chance - to review the draft before Kolkman posted; - - - Kolkman takes responsibilities for omissions, fuzzy definitions and - mistakes. - - -B.2 version 00 - o The name of the draft was changed as a result of the draft being - adopted as a working group document. - o A small section on the concept of stale trust anchors was added. - o The different possible states are more clearly defined, including - examples of transitions between states. - o The terminology is changed throughout the document. The old term - "M-N" is replaced by "threshold" (more or less). Also the - interpretation of the constants M and N is significantly - simplified to bring the usage more in line with "standard" - threshold terminlogy. - - - - - - - - - - - - - - - - - - -Ihren, et al. Expires April 18, 2005 [Page 23] -Internet-Draft DNSSEC Threshold-based Trust Update October 2004 - - - -Intellectual Property Statement - - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - - -Disclaimer of Validity - - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - -Copyright Statement - - - Copyright (C) The Internet Society (2004). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - - -Acknowledgment - - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Ihren, et al. Expires April 18, 2005 [Page 24] \ No newline at end of file diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-trustupdate-timers-02.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-trustupdate-timers-02.txt deleted file mode 100644 index 7cb9063..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-trustupdate-timers-02.txt +++ /dev/null @@ -1,730 +0,0 @@ - - - - -Network Working Group M. StJohns -Internet-Draft Nominum, Inc. -Expires: July 14, 2006 January 10, 2006 - - - Automated Updates of DNSSEC Trust Anchors - draft-ietf-dnsext-trustupdate-timers-02 - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on July 14, 2006. - -Copyright Notice - - Copyright (C) The Internet Society (2006). - -Abstract - - This document describes a means for automated, authenticated and - authorized updating of DNSSEC "trust anchors". The method provides - protection against single key compromise of a key in the trust point - key set. Based on the trust established by the presence of a current - anchor, other anchors may be added at the same place in the - hierarchy, and, ultimately, supplant the existing anchor. - - This mechanism, if adopted, will require changes to resolver - management behavior (but not resolver resolution behavior), and the - - - -StJohns Expires July 14, 2006 [Page 1] - -Internet-Draft trustanchor-update January 2006 - - - addition of a single flag bit to the DNSKEY record. - - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 1.1. Compliance Nomenclature . . . . . . . . . . . . . . . . . 3 - 1.2. Changes since -00 . . . . . . . . . . . . . . . . . . . . 3 - 2. Theory of Operation . . . . . . . . . . . . . . . . . . . . . 4 - 2.1. Revocation . . . . . . . . . . . . . . . . . . . . . . . . 4 - 2.2. Add Hold-Down . . . . . . . . . . . . . . . . . . . . . . 5 - 2.3. Remove Hold-down . . . . . . . . . . . . . . . . . . . . . 5 - 2.4. Active Refresh . . . . . . . . . . . . . . . . . . . . . . 6 - 2.5. Resolver Parameters . . . . . . . . . . . . . . . . . . . 6 - 2.5.1. Add Hold-Down Time . . . . . . . . . . . . . . . . . . 6 - 2.5.2. Remove Hold-Down Time . . . . . . . . . . . . . . . . 6 - 2.5.3. Minimum Trust Anchors per Trust Point . . . . . . . . 6 - 3. Changes to DNSKEY RDATA Wire Format . . . . . . . . . . . . . 6 - 4. State Table . . . . . . . . . . . . . . . . . . . . . . . . . 7 - 4.1. Events . . . . . . . . . . . . . . . . . . . . . . . . . . 7 - 4.2. States . . . . . . . . . . . . . . . . . . . . . . . . . . 8 - 4.3. Trust Point Deletion . . . . . . . . . . . . . . . . . . . 8 - 5. Scenarios . . . . . . . . . . . . . . . . . . . . . . . . . . 8 - 5.1. Adding A Trust Anchor . . . . . . . . . . . . . . . . . . 9 - 5.2. Deleting a Trust Anchor . . . . . . . . . . . . . . . . . 9 - 5.3. Key Roll-Over . . . . . . . . . . . . . . . . . . . . . . 9 - 5.4. Active Key Compromised . . . . . . . . . . . . . . . . . . 9 - 5.5. Stand-by Key Compromised . . . . . . . . . . . . . . . . . 10 - 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 10 - 7. Security Considerations . . . . . . . . . . . . . . . . . . . 10 - 7.1. Key Ownership vs Acceptance Policy . . . . . . . . . . . . 10 - 7.2. Multiple Key Compromise . . . . . . . . . . . . . . . . . 10 - 7.3. Dynamic Updates . . . . . . . . . . . . . . . . . . . . . 11 - 8. Normative References . . . . . . . . . . . . . . . . . . . . . 11 - Editorial Comments . . . . . . . . . . . . . . . . . . . . . . . . - Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 12 - Intellectual Property and Copyright Statements . . . . . . . . . . 13 - - - - - - - - - - - - - - -StJohns Expires July 14, 2006 [Page 2] - -Internet-Draft trustanchor-update January 2006 - - -1. Introduction - - As part of the reality of fielding DNSSEC (Domain Name System - Security Extensions) [RFC2535] [RFC4033][RFC4034][RFC4035], the - community has come to the realization that there will not be one - signed name space, but rather islands of signed name space each - originating from specific points (i.e. 'trust points') in the DNS - tree. Each of those islands will be identified by the trust point - name, and validated by at least one associated public key. For the - purpose of this document we'll call the association of that name and - a particular key a 'trust anchor'. A particular trust point can have - more than one key designated as a trust anchor. - - For a DNSSEC-aware resolver to validate information in a DNSSEC - protected branch of the hierarchy, it must have knowledge of a trust - anchor applicable to that branch. It may also have more than one - trust anchor for any given trust point. Under current rules, a chain - of trust for DNSSEC-protected data that chains its way back to ANY - known trust anchor is considered 'secure'. - - Because of the probable balkanization of the DNSSEC tree due to - signing voids at key locations, a resolver may need to know literally - thousands of trust anchors to perform its duties. (e.g. Consider an - unsigned ".COM".) Requiring the owner of the resolver to manually - manage this many relationships is problematic. It's even more - problematic when considering the eventual requirement for key - replacement/update for a given trust anchor. The mechanism described - herein won't help with the initial configuration of the trust anchors - in the resolvers, but should make trust point key replacement/ - rollover more viable. - - As mentioned above, this document describes a mechanism whereby a - resolver can update the trust anchors for a given trust point, mainly - without human intervention at the resolver. There are some corner - cases discussed (e.g. multiple key compromise) that may require - manual intervention, but they should be few and far between. This - document DOES NOT discuss the general problem of the initial - configuration of trust anchors for the resolver. - -1.1. Compliance Nomenclature - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in BCP 14, [RFC2119]. - -1.2. Changes since -00 - - Added the concept of timer triggered resolver queries to refresh the - - - -StJohns Expires July 14, 2006 [Page 3] - -Internet-Draft trustanchor-update January 2006 - - - resolvers view of the trust anchor key RRSet. - - Re-submitted expired draft as -01. Updated DNSSEC RFC References. - - Draft -02. Added the IANA Considerations section. Added text to - describe what happens if all trust anchors at a trust point are - deleted. - - -2. Theory of Operation - - The general concept of this mechanism is that existing trust anchors - can be used to authenticate new trust anchors at the same point in - the DNS hierarchy. When a new SEP key is added to a trust point - DNSKEY RRSet, and when that RRSet is validated by an existing trust - anchor, then the new key can be added to the set of trust anchors. - - There are some issues with this approach which need to be mitigated. - For example, a compromise of one of the existing keys could allow an - attacker to add their own 'valid' data. This implies a need for a - method to revoke an existing key regardless of whether or not that - key is compromised. As another example assuming a single key - compromise, an attacker could add a new key and revoke all the other - old keys. - -2.1. Revocation - - Assume two trust anchor keys A and B. Assume that B has been - compromised. Without a specific revocation bit, B could invalidate A - simply by sending out a signed trust point key set which didn't - contain A. To fix this, we add a mechanism which requires knowledge - of the private key of a DNSKEY to revoke that DNSKEY. - - A key is considered revoked when the resolver sees the key in a self- - signed RRSet and the key has the REVOKE bit (see Section 6 below) set - to '1'. Once the resolver sees the REVOKE bit, it MUST NOT use this - key as a trust anchor or for any other purposes except validating the - RRSIG over the DNSKEY RRSet specifically for the purpose of - validating the revocation. Unlike the 'Add' operation below, - revocation is immediate and permanent upon receipt of a valid - revocation at the resolver. - - N.B. A DNSKEY with the REVOKE bit set has a different fingerprint - than one without the bit set. This affects the matching of a DNSKEY - to DS records in the parent, or the fingerprint stored at a resolver - used to configure a trust point. [msj3] - - In the given example, the attacker could revoke B because it has - - - -StJohns Expires July 14, 2006 [Page 4] - -Internet-Draft trustanchor-update January 2006 - - - knowledge of B's private key, but could not revoke A. - -2.2. Add Hold-Down - - Assume two trust point keys A and B. Assume that B has been - compromised. An attacker could generate and add a new trust anchor - key - C (by adding C to the DNSKEY RRSet and signing it with B), and - then invalidate the compromised key. This would result in the both - the attacker and owner being able to sign data in the zone and have - it accepted as valid by resolvers. - - To mitigate, but not completely solve, this problem, we add a hold- - down time to the addition of the trust anchor. When the resolver - sees a new SEP key in a validated trust point DNSKEY RRSet, the - resolver starts an acceptance timer, and remembers all the keys that - validated the RRSet. If the resolver ever sees the DNSKEY RRSet - without the new key but validly signed, it stops the acceptance - process and resets the acceptance timer. If all of the keys which - were originally used to validate this key are revoked prior to the - timer expiring, the resolver stops the acceptance process and resets - the timer. - - Once the timer expires, the new key will be added as a trust anchor - the next time the validated RRSet with the new key is seen at the - resolver. The resolver MUST NOT treat the new key as a trust anchor - until the hold down time expires AND it has retrieved and validated a - DNSKEY RRSet after the hold down time which contains the new key. - - N.B.: Once the resolver has accepted a key as a trust anchor, the key - MUST be considered a valid trust anchor by that resolver until - explictly revoked as described above. - - In the given example, the zone owner can recover from a compromise by - revoking B and adding a new key D and signing the DNSKEY RRSet with - both A and B. - - The reason this does not completely solve the problem has to do with - the distributed nature of DNS. The resolver only knows what it sees. - A determined attacker who holds one compromised key could keep a - single resolver from realizing that key had been compromised by - intercepting 'real' data from the originating zone and substituting - their own (e.g. using the example, signed only by B). This is no - worse than the current situation assuming a compromised key. - -2.3. Remove Hold-down - - A new key which has been seen by the resolver, but hasn't reached - it's add hold-down time, MAY be removed from the DNSKEY RRSet by the - - - -StJohns Expires July 14, 2006 [Page 5] - -Internet-Draft trustanchor-update January 2006 - - - zone owner. If the resolver sees a validated DNSKEY RRSet without - this key, it waits for the remove hold-down time and then, if the key - hasn't reappeared, SHOULD discard any information about the key. - -2.4. Active Refresh - - A resolver which has been configured for automatic update of keys - from a particular trust point MUST query that trust point (e.g. do a - lookup for the DNSKEY RRSet and related RRSIG records) no less often - than the lesser of 15 days or half the original TTL for the DNSKEY - RRSet or half the RRSIG expiration interval. The expiration interval - is the amount of time from when the RRSIG was last retrieved until - the expiration time in the RRSIG. - - If the query fails, the resolver MUST repeat the query until - satisfied no more often than once an hour and no less often than the - lesser of 1 day or 10% of the original TTL or 10% of the original - expiration interval. - -2.5. Resolver Parameters - -2.5.1. Add Hold-Down Time - - The add hold-down time is 30 days or the expiration time of the TTL - of the first trust point DNSKEY RRSet which contained the key, - whichever is greater. This ensures that at least two validated - DNSKEY RRSets which contain the new key MUST be seen by the resolver - prior to the key's acceptance. - -2.5.2. Remove Hold-Down Time - - The remove hold-down time is 30 days. - -2.5.3. Minimum Trust Anchors per Trust Point - - A compliant resolver MUST be able to manage at least five SEP keys - per trust point. - - -3. Changes to DNSKEY RDATA Wire Format - - Bit n [msj2] of the DNSKEY Flags field is designated as the 'REVOKE' - flag. If this bit is set to '1', AND the resolver sees an - RRSIG(DNSKEY) signed by the associated key, then the resolver MUST - consider this key permanently invalid for all purposes except for - validing the revocation. - - - - - -StJohns Expires July 14, 2006 [Page 6] - -Internet-Draft trustanchor-update January 2006 - - -4. State Table - - The most important thing to understand is the resolver's view of any - key at a trust point. The following state table describes that view - at various points in the key's lifetime. The table is a normative - part of this specification. The initial state of the key is 'Start'. - The resolver's view of the state of the key changes as various events - occur. - - [msj1] This is the state of a trust point key as seen from the - resolver. The column on the left indicates the current state. The - header at the top shows the next state. The intersection of the two - shows the event that will cause the state to transition from the - current state to the next. - - NEXT STATE - -------------------------------------------------- - FROM |Start |AddPend |Valid |Missing|Revoked|Removed| - ---------------------------------------------------------- - Start | |NewKey | | | | | - ---------------------------------------------------------- - AddPend |KeyRem | |AddTime| | | - ---------------------------------------------------------- - Valid | | | |KeyRem |Revbit | | - ---------------------------------------------------------- - Missing | | |KeyPres| |Revbit | | - ---------------------------------------------------------- - Revoked | | | | | |RemTime| - ---------------------------------------------------------- - Removed | | | | | | | - ---------------------------------------------------------- - -4.1. Events - NewKey The resolver sees a valid DNSKEY RRSet with a new SEP key. - That key will become a new trust anchor for the named trust point - after its been present in the RRSet for at least 'add time'. - KeyPres The key has returned to the valid DNSKEY RRSet. - KeyRem The resolver sees a valid DNSKEY RRSet that does not contain - this key. - AddTime The key has been in every valid DNSKEY RRSet seen for at - least the 'add time'. - RemTime A revoked key has been missing from the trust point DNSKEY - RRSet for sufficient time to be removed from the trust set. - RevBit The key has appeared in the trust anchor DNSKEY RRSet with its - "REVOKED" bit set, and there is an RRSig over the DNSKEY RRSet - signed by this key. - - - - - -StJohns Expires July 14, 2006 [Page 7] - -Internet-Draft trustanchor-update January 2006 - - -4.2. States - Start The key doesn't yet exist as a trust anchor at the resolver. - It may or may not exist at the zone server, but hasn't yet been - seen at the resolver. - AddPend The key has been seen at the resolver, has its 'SEP' bit set, - and has been included in a validated DNSKEY RRSet. There is a - hold-down time for the key before it can be used as a trust - anchor. - Valid The key has been seen at the resolver and has been included in - all validated DNSKEY RRSets from the time it was first seen up - through the hold-down time. It is now valid for verifying RRSets - that arrive after the hold down time. Clarification: The DNSKEY - RRSet does not need to be continuously present at the resolver - (e.g. its TTL might expire). If the RRSet is seen, and is - validated (i.e. verifies against an existing trust anchor), this - key MUST be in the RRSet otherwise a 'KeyRem' event is triggered. - Missing This is an abnormal state. The key remains as a valid trust - point key, but was not seen at the resolver in the last validated - DNSKEY RRSet. This is an abnormal state because the zone operator - should be using the REVOKE bit prior to removal. [Discussion - item: Should a missing key be considered revoked after some period - of time?] - Revoked This is the state a key moves to once the resolver sees an - RRSIG(DNSKEY) signed by this key where that DNSKEY RRSet contains - this key with its REVOKE bit set to '1'. Once in this state, this - key MUST permanently be considered invalid as a trust anchor. - Removed After a fairly long hold-down time, information about this - key may be purged from the resolver. A key in the removed state - MUST NOT be considered a valid trust anchor. - -4.3. Trust Point Deletion - - A trust point which has all of its trust anchors revoked is - considered deleted and is treated as if the trust point was never - configured. If there are no superior trust points, data at and below - the deleted trust point are considered insecure. If there there ARE - superior trust points, data at and below the deleted trust point are - evaluated with respect to the superior trust point. - - -5. Scenarios - - The suggested model for operation is to have one active key and one - stand-by key at each trust point. The active key will be used to - sign the DNSKEY RRSet. The stand-by key will not normally sign this - RRSet, but the resolver will accept it as a trust anchor if/when it - sees the signature on the trust point DNSKEY RRSet. - - - - -StJohns Expires July 14, 2006 [Page 8] - -Internet-Draft trustanchor-update January 2006 - - - Since the stand-by key is not in active signing use, the associated - private key may (and SHOULD) be provided with additional protections - not normally available to a key that must be used frequently. E.g. - locked in a safe, split among many parties, etc. Notionally, the - stand-by key should be less subject to compromise than an active key, - but that will be dependent on operational concerns not addressed - here. - -5.1. Adding A Trust Anchor - - Assume an existing trust anchor key 'A'. - 1. Generate a new key pair. - 2. Create a DNSKEY record from the key pair and set the SEP and Zone - Key bits. - 3. Add the DNSKEY to the RRSet. - 4. Sign the DNSKEY RRSet ONLY with the existing trust anchor key - - 'A'. - 5. Wait a while. - -5.2. Deleting a Trust Anchor - - Assume existing trust anchors 'A' and 'B' and that you want to revoke - and delete 'A'. - 1. Set the revolcation bit on key 'A'. - 2. Sign the DNSKEY RRSet with both 'A' and 'B'. - 'A' is now revoked. The operator SHOULD include the revoked 'A' in - the RRSet for at least the remove hold-down time, but then may remove - it from the DNSKEY RRSet. - -5.3. Key Roll-Over - - Assume existing keys A and B. 'A' is actively in use (i.e. has been - signing the DNSKEY RRSet.) 'B' was the stand-by key. (i.e. has been - in the DNSKEY RRSet and is a valid trust anchor, but wasn't being - used to sign the RRSet.) - 1. Generate a new key pair 'C'. - 2. Add 'C' to the DNSKEY RRSet. - 3. Set the revocation bit on key 'A'. - 4. Sign the RRSet with 'A' and 'B'. - 'A' is now revoked, 'B' is now the active key, and 'C' will be the - stand-by key once the hold-down expires. The operator SHOULD include - the revoked 'A' in the RRSet for at least the remove hold-down time, - but may then remove it from the DNSKEY RRSet. - -5.4. Active Key Compromised - - This is the same as the mechanism for Key Roll-Over (Section 5.3) - above assuming 'A' is the active key. - - - -StJohns Expires July 14, 2006 [Page 9] - -Internet-Draft trustanchor-update January 2006 - - -5.5. Stand-by Key Compromised - - Using the same assumptions and naming conventions as Key Roll-Over - (Section 5.3) above: - 1. Generate a new key pair 'C'. - 2. Add 'C' to the DNSKEY RRSet. - 3. Set the revocation bit on key 'B'. - 4. Sign the RRSet with 'A' and 'B'. - 'B' is now revoked, 'A' remains the active key, and 'C' will be the - stand-by key once the hold-down expires. 'B' SHOULD continue to be - included in the RRSet for the remove hold-down time. - - -6. IANA Considerations - - The IANA will need to assign a bit in the DNSKEY flags field (see - section 4.3 of [RFC3755]) for the REVOKE bit. There are no other - IANA actions required. - - -7. Security Considerations - -7.1. Key Ownership vs Acceptance Policy - - The reader should note that, while the zone owner is responsible - creating and distributing keys, it's wholly the decision of the - resolver owner as to whether to accept such keys for the - authentication of the zone information. This implies the decision - update trust anchor keys based on trust for a current trust anchor - key is also the resolver owner's decision. - - The resolver owner (and resolver implementers) MAY choose to permit - or prevent key status updates based on this mechanism for specific - trust points. If they choose to prevent the automated updates, they - will need to establish a mechanism for manual or other out-of-band - updates outside the scope of this document. - -7.2. Multiple Key Compromise - - This scheme permits recovery as long as at least one valid trust - anchor key remains uncompromised. E.g. if there are three keys, you - can recover if two of them are compromised. The zone owner should - determine their own level of comfort with respect to the number of - active valid trust anchors in a zone and should be prepared to - implement recovery procedures once they detect a compromise. A - manual or other out-of-band update of all resolvers will be required - if all trust anchor keys at a trust point are compromised. - - - - -StJohns Expires July 14, 2006 [Page 10] - -Internet-Draft trustanchor-update January 2006 - - -7.3. Dynamic Updates - - Allowing a resolver to update its trust anchor set based in-band key - information is potentially less secure than a manual process. - However, given the nature of the DNS, the number of resolvers that - would require update if a trust anchor key were compromised, and the - lack of a standard management framework for DNS, this approach is no - worse than the existing situation. - -8. Normative References - - [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - - [RFC2535] Eastlake, D., "Domain Name System Security Extensions", - RFC 2535, March 1999. - - [RFC3755] Weiler, S., "Legacy Resolver Compatibility for Delegation - Signer (DS)", RFC 3755, May 2004. - - [RFC4033] Arends, R., Austein, R., Larson, M., Massey, D., and S. - Rose, "DNS Security Introduction and Requirements", - RFC 4033, March 2005. - - [RFC4034] Arends, R., Austein, R., Larson, M., Massey, D., and S. - Rose, "Resource Records for the DNS Security Extensions", - RFC 4034, March 2005. - - [RFC4035] Arends, R., Austein, R., Larson, M., Massey, D., and S. - Rose, "Protocol Modifications for the DNS Security - Extensions", RFC 4035, March 2005. - -Editorial Comments - - [msj1] msj: N.B. This table is preliminary and will be revised to - match implementation experience. For example, should there - be a state for "Add hold-down expired, but haven't seen the - new RRSet"? - - [msj2] msj: To be assigned. - - [msj3] msj: For discussion: What's the implementation guidance for - resolvers currently with respect to the non-assigned flag - bits? If they consider the flag bit when doing key matching - at the trust anchor, they won't be able to match. - - - - - - -StJohns Expires July 14, 2006 [Page 11] - -Internet-Draft trustanchor-update January 2006 - - -Author's Address - - Michael StJohns - Nominum, Inc. - 2385 Bay Road - Redwood City, CA 94063 - USA - - Phone: +1-301-528-4729 - Email: Mike.StJohns@nominum.com - URI: www.nominum.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -StJohns Expires July 14, 2006 [Page 12] - -Internet-Draft trustanchor-update January 2006 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2006). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -StJohns Expires July 14, 2006 [Page 13] - - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-tsig-sha-06.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-tsig-sha-06.txt deleted file mode 100644 index 00476ae..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-tsig-sha-06.txt +++ /dev/null @@ -1,522 +0,0 @@ - -INTERNET-DRAFT Donald E. Eastlake 3rd -UPDATES RFC 2845 Motorola Laboratories -Expires: July 2006 January 2006 - - HMAC SHA TSIG Algorithm Identifiers - ---- --- ---- --------- ----------- - - - -Status of This Document - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - This draft is intended to be become a Proposed Standard RFC. - Distribution of this document is unlimited. Comments should be sent - to the DNSEXT working group mailing list . - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/1id-abstracts.html - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html - - -Abstract - - Use of the Domain Name System TSIG resource record requires - specification of a cryptographic message authentication code. - Currently identifiers have been specified only for the HMAC MD5 - (Message Digest) and GSS (Generic Security Service) TSIG algorithms. - This document standardizes identifiers and implementation - requirements for additional HMAC SHA (Secure Hash Algorithm) TSIG - algorithms and standardizes how to specify and handle the truncation - of HMAC values in TSIG. - - -Copyright Notice - - Copyright (C) The Internet Society (2006). - - - -D. Eastlake 3rd [Page 1] - - -INTERNET-DRAFT HMAC-SHA TSIG Identifiers - - -Table of Contents - - Status of This Document....................................1 - Abstract...................................................1 - Copyright Notice...........................................1 - - Table of Contents..........................................2 - - 1. Introduction............................................3 - - 2. Algorithms and Identifiers..............................4 - - 3. Specifying Truncation...................................5 - 3.1 Truncation Specification...............................5 - - 4. TSIG Truncation Policy and Error Provisions.............6 - - 5. IANA Considerations.....................................7 - 6. Security Considerations.................................7 - 7. Copyright and Disclaimer................................7 - - 8. Normative References....................................8 - 9. Informative References..................................8 - - Author's Address...........................................9 - Additional IPR Provisions..................................9 - Expiration and File Name...................................9 - - - - - - - - - - - - - - - - - - - - - - - - - -D. Eastlake 3rd [Page 2] - - -INTERNET-DRAFT HMAC-SHA TSIG Identifiers - - -1. Introduction - - [RFC 2845] specifies a TSIG Resource Record (RR) that can be used to - authenticate DNS (Domain Name System [STD 13]) queries and responses. - This RR contains a domain name syntax data item which names the - authentication algorithm used. [RFC 2845] defines the HMAC-MD5.SIG- - ALG.REG.INT name for authentication codes using the HMAC [RFC 2104] - algorithm with the MD5 [RFC 1321] hash algorithm. IANA has also - registered "gss-tsig" as an identifier for TSIG authentication where - the cryptographic operations are delegated to the Generic Security - Service (GSS) [RFC 3645]. - - It should be noted that use of TSIG presumes prior agreement, between - the resolver and server involved, as to the algorithm and key to be - used. - - In Section 2, this document specifies additional names for TSIG - authentication algorithms based on US NIST SHA (United States, - National Institute of Science and Technology, Secure Hash Algorithm) - algorithms and HMAC and specifies the implementation requirements for - those algorithms. - - In Section 3, this document specifies the effect of inequality - between the normal output size of the specified hash function and the - length of MAC (message authentication code) data given in the TSIG - RR. In particular, it specifies that a shorter length field value - specifies truncation and a longer length field is an error. - - In Section 4, policy restrictions and implications related to - truncation and a new error code to indicate truncation shorter than - permitted by policy are described and specified. - - The use herein of MUST, SHOULD, MAY, MUST NOT, and SHOULD NOT is as - defined in [RFC 2119]. - - - - - - - - - - - - - - - - - - -D. Eastlake 3rd [Page 3] - - -INTERNET-DRAFT HMAC-SHA TSIG Identifiers - - -2. Algorithms and Identifiers - - TSIG Resource Records (RRs) [RFC 2845] are used to authenticate DNS - queries and responses. They are intended to be efficient symmetric - authentication codes based on a shared secret. (Asymmetric signatures - can be provided using the SIG RR [RFC 2931]. In particular, SIG(0) - can be used for transaction signatures.) Used with a strong hash - function, HMAC [RFC 2104] provides a way to calculate such symmetric - authentication codes. The only specified HMAC based TSIG algorithm - identifier has been HMAC-MD5.SIG-ALG.REG.INT based on MD5 [RFC 1321]. - - The use of SHA-1 [FIPS 180-2, RFC 3174], which is a 160 bit hash, as - compared with the 128 bits for MD5, and additional hash algorithms in - the SHA family [FIPS 180-2, RFC 3874, SHA2draft] with 224, 256, 384, - and 512 bits, may be preferred in some cases particularly since - increasingly successful cryptanalytic attacks are being made on the - shorter hashes. - - Use of TSIG between a DNS resolver and server is by mutual agreement. - That agreement can include the support of additional algorithms and - criteria as to which algorithms and truncations are acceptable, - subject to the restriction and guidelines in Section 3 and 4 below. - Key agreement can be by the TKEY mechanism [RFC 2930] or other - mutually agreeable method. - - The current HMAC-MD5.SIG-ALG.REG.INT and gss-tsig identifiers are - included in the table below for convenience. Implementations which - support TSIG MUST also implement HMAC SHA1 and HMAC SHA256 and MAY - implement gss-tsig and the other algorithms listed below. - - Mandatory HMAC-MD5.SIG-ALG.REG.INT - Optional gss-tsig - Mandatory hmac-sha1 - Optional hmac-sha224 - Mandatory hmac-sha256 - Optional hamc-sha384 - Optional hmac-sha512 - - SHA-1 truncated to 96 bits (12 octets) SHOULD be implemented. - - - - - - - - - - - - - -D. Eastlake 3rd [Page 4] - - -INTERNET-DRAFT HMAC-SHA TSIG Identifiers - - -3. Specifying Truncation - - When space is at a premium and the strength of the full length of an - HMAC is not needed, it is reasonable to truncate the HMAC output and - use the truncated value for authentication. HMAC SHA-1 truncated to - 96 bits is an option available in several IETF protocols including - IPSEC and TLS. - - The TSIG RR [RFC 2845] includes a "MAC size" field, which gives the - size of the MAC field in octets. But [RFC 2845] does not specify what - to do if this MAC size differs from the length of the output of HMAC - for a particular hash function. Truncation is indicated by a MAC size - less than the HMAC size as specified below. - - - -3.1 Truncation Specification - - The specification for TSIG handling is changed as follows: - - 1. If "MAC size" field is greater than HMAC output length: - This case MUST NOT be generated and if received MUST cause the - packet to be dropped and RCODE 1 (FORMERR) to be returned. - - 2. If "MAC size" field equals HMAC output length: - Operation is as described in [RFC 2845] with the entire output - HMAC output present. - - 3. "MAC size" field is less than HMAC output length but greater than - that specified in case 4 below: - This is sent when the signer has truncated the HMAC output to - an allowable length, as described in RFC 2104, taking initial - octets and discarding trailing octets. TSIG truncation can only be - to an integral number of octets. On receipt of a packet with - truncation thus indicated, the locally calculated MAC is similarly - truncated and only the truncated values compared for - authentication. The request MAC used when calculating the TSIG MAC - for a reply is the truncated request MAC. - - 4. "MAC size" field is less than the larger of 10 (octets) and half - the length of the hash function in use: - With the exception of certain TSIG error messages described in - RFC 2845 section 3.2 where it is permitted that the MAC size be - zero, this case MUST NOT be generated and if received MUST cause - the packet to be dropped and RCODE 1 (FORMERR) to be returned. The - size limit for this case can also, for the hash functions - mentioned in this document, be stated as less than half the hash - function length for hash functions other than MD5 and less than 10 - octets for MD5. - - - -D. Eastlake 3rd [Page 5] - - -INTERNET-DRAFT HMAC-SHA TSIG Identifiers - - -4. TSIG Truncation Policy and Error Provisions - - Use of TSIG is by mutual agreement between a resolver and server. - Implicit in such "agreement" are criterion as to acceptable keys and - algorithms and, with the extensions in this document, truncations. - Note that it is common for implementations to bind the TSIG secret - key or keys that may be in place at a resolver and server to - particular algorithms. Thus such implementations only permit the use - of an algorithm if there is an associated key in place. Receipt of an - unknown, unimplemented, or disabled algorithm typically results in a - BADKEY error. - - Local policies MAY require the rejection of TSIGs even though they - use an algorithm for which implementation is mandatory. - - When a local policy permits acceptance of a TSIG with a particular - algorithm and a particular non-zero amount of truncation it SHOULD - also permit the use of that algorithm with lesser truncation (a - longer MAC) up to the full HMAC output. - - Regardless of a lower acceptable truncated MAC length specified by - local policy, a reply SHOULD be sent with a MAC at least as long as - that in the corresponding request unless the request specified a MAC - length longer than the HMAC output. - - Implementations permitting multiple acceptable algorithms and/or - truncations SHOULD permit this list to be ordered by presumed - strength and SHOULD allow different truncations for the same - algorithm to be treated as separate entities in this list. When so - implemented, policies SHOULD accept a presumed stronger algorithm and - truncation than the minimum strength required by the policy. - - If a TSIG is received with truncation which is permitted under - Section 3 above but the MAC is too short for the local policy in - force, an RCODE of TBA [22 suggested](BADTRUNC) MUST be returned. - - - - - - - - - - - - - - - - - -D. Eastlake 3rd [Page 6] - - -INTERNET-DRAFT HMAC-SHA TSIG Identifiers - - -5. IANA Considerations - - This document, on approval for publication as a standards track RFC, - (1) registers the new TSIG algorithm identifiers listed in Section 2 - with IANA and (2) allocates the BADTRUNC RCODE TBA [22 suggested] in - Section 4. [RFC 2845] - - - -6. Security Considerations - - For all of the message authentication code algorithms listed herein, - those producing longer values are believed to be stronger; however, - while there have been some arguments that mild truncation can - strengthen a MAC by reducing the information available to an - attacker, excessive truncation clearly weakens authentication by - reducing the number of bits an attacker has to try to break the - authentication by brute force [RFC 2104]. - - Significant progress has been made recently in cryptanalysis of hash - function of the type used herein, all of which ultimately derive from - the design of MD4. While the results so far should not effect HMAC, - the stronger SHA-1 and SHA-256 algorithms are being made mandatory - due to caution. - - See the Security Considerations section of [RFC 2845]. See also the - Security Considerations section of [RFC 2104] from which the limits - on truncation in this RFC were taken. - - - -7. Copyright and Disclaimer - - Copyright (C) The Internet Society (2006). - - This document is subject to the rights, licenses and restrictions - contained in BCP 78, and except as set forth therein, the authors - retain all their rights. - - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - - -D. Eastlake 3rd [Page 7] - - -INTERNET-DRAFT HMAC-SHA TSIG Identifiers - - -8. Normative References - - [FIPS 180-2] - "Secure Hash Standard", (SHA-1/224/256/384/512) US - Federal Information Processing Standard, with Change Notice 1, - February 2004. - - [RFC 1321] - Rivest, R., "The MD5 Message-Digest Algorithm ", RFC - 1321, April 1992. - - [RFC 2104] - Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed- - Hashing for Message Authentication", RFC 2104, February 1997. - - [RFC 2119] - Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - - [RFC 2845] - Vixie, P., Gudmundsson, O., Eastlake 3rd, D., and B. - Wellington, "Secret Key Transaction Authentication for DNS (TSIG)", - RFC 2845, May 2000. - - [RFC 3174] - Eastlake 3rd, D. and P. Jones, "US Secure Hash Algorithm - 1 (SHA1)", RFC 3174, September 2001. - - [RFC 3874] - R. Housely, "A 224-bit One-way Hash Function: SHA-224", - September 2004, - - [SHA2draft] - Eastlake, D., T. Hansen, "US Secure Hash Algorithms - (SHA)", draft-eastlake-sha2-*.txt, work in progress. - - [STD 13] - Mockapetris, P., "Domain names - concepts and facilities", STD - 13, RFC 1034, November 1987. - - Mockapetris, P., "Domain names - implementation and - specification", STD 13, RFC 1035, November 1987. - - - -9. Informative References. - - [RFC 2930] - Eastlake 3rd, D., "Secret Key Establishment for DNS - (TKEY RR)", RFC 2930, September 2000. - - [RFC 2931] - Eastlake 3rd, D., "DNS Request and Transaction - Signatures ( SIG(0)s )", RFC 2931, September 2000. - - [RFC 3645] - Kwan, S., Garg, P., Gilroy, J., Esibov, L., Westhead, - J., and R. Hall, "Generic Security Service Algorithm for Secret Key - Transaction Authentication for DNS (GSS-TSIG)", RFC 3645, October - 2003. - - - -D. Eastlake 3rd [Page 8] - - -INTERNET-DRAFT HMAC-SHA TSIG Identifiers - - -Author's Address - - Donald E. Eastlake 3rd - Motorola Laboratories - 155 Beaver Street - Milford, MA 01757 USA - - Telephone: +1-508-786-7554 (w) - - EMail: Donald.Eastlake@motorola.com - - - -Additional IPR Provisions - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed - to pertain to the implementation or use of the technology - described in this document or the extent to which any license - under such rights might or might not be available; nor does it - represent that it has made any independent effort to identify any - such rights. Information on the procedures with respect to - rights in RFC documents can be found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use - of such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository - at http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention - any copyrights, patents or patent applications, or other - proprietary rights that may cover technology that may be required - to implement this standard. Please address the information to the - IETF at ietf-ipr@ietf.org. - - - -Expiration and File Name - - This draft expires in July 2006. - - Its file name is draft-ietf-dnsext-tsig-sha-06.txt - - - - - - - - -D. Eastlake 3rd [Page 9] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsext-wcard-clarify-10.txt b/contrib/bind9/doc/draft/draft-ietf-dnsext-wcard-clarify-10.txt deleted file mode 100644 index 9cf88a5..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsext-wcard-clarify-10.txt +++ /dev/null @@ -1,1063 +0,0 @@ -Internet-Draft dnsext-wcard January 9, 2006 - -DNSEXT Working Group E. Lewis -INTERNET DRAFT NeuStar -Expiration Date: July 9, 2006 January 9, 2006 -Updates RFC 1034, RFC 2672 - - The Role of Wildcards - in the Domain Name System - draft-ietf-dnsext-wcard-clarify-10.txt - -Status of this Memo - - By submitting this Internet-Draft, each author represents that - any applicable patent or other IPR claims of which he or she is - aware have been or will be disclosed, and any of which he or she - becomes aware will be disclosed, in accordance with Section 6 of - BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six - months and may be updated, replaced, or obsoleted by other - documents at any time. It is inappropriate to use Internet-Drafts - as reference material or to cite them other than as "work in - progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html - - This Internet-Draft will expire on July 9, 2006. - -Copyright Notice - - Copyright (C) The Internet Society (2006). - -Abstract - - This is an update to the wildcard definition of RFC 1034. The - interaction with wildcards and CNAME is changed, an error - condition removed, and the words defining some concepts central - to wildcards are changed. The overall goal is not to change - wildcards, but to refine the definition of RFC 1034. - - - - -DNSEXT Working Group Expires July 9, 2006 [Page 1] - -Internet-Draft dnsext-wcard January 9, 2006 - -Table of Contents - -1. Introduction . . . . . . . . . . . . . . . . 3 -1 1 Motivation 3 -1 2 The Original Definition 3 -1 3 Roadmap to This Document 4 -1 3 1 New Terms 4 -1.3.2 Changed Text 5 -1.3.3 Considerations with Special Types 5 -1.4 Standards Terminology 5 -2. Wildcard Syntax . . . . . . . . . . . . . . . 6 -2.1 Identifying a Wildcard 6 -2.1.1 Wild Card Domain Name and Asterisk Label 6 -2.1.2 Asterisks and Other Characters 6 -2.1.3 Non-terminal Wild Card Domain Names 6 -2.2 Existence Rules 7 -2.2.1 An Example 7 -2.2.2 Empty Non-terminals 9 -2.2.3 Yet Another Definition of Existence 10 -2.3 When is a Wild Card Domain Name Not Special 10 -3. Impact of a Wild Card Domain Name On a Response . . . . . 10 -3.1 Step 2 10 -3.2 Step 3 11 -3.3 Part 'c' 11 -3.3.1 Closest Encloser and the Source of Synthesis 12 -3.3.2 Closest Encloser and Source of Synthesis Examples 12 -3.3.3 Type Matching 13 -4. Considerations with Special Types . . . . . . . . . 13 -4.1 SOA RRSet at a Wild Card Domain Name 13 -4.2 NS RRSet at a Wild Card Domain Name 14 -4.2.1 Discarded Notions 14 -4.3 CNAME RRSet at a Wild Card Domain Name 15 -4.4 DNAME RRSet at a Wild Card Domain Name 15 -4.5 SRV RRSet at a Wild Card Domain Name 16 -4.6 DS RRSet at a Wild Card Domain Name 16 -4.7 NSEC RRSet at a Wild Card Domain Name 17 -4.8 RRSIG at a Wild Card Domain Name 17 -4.9 Empty Non-terminal Wild Card Domain Name 17 -5. Security Considerations . . . . . . . . . . . . . 17 -6. IANA Considerations . . . . . . . . . . . . . 17 -7. References . . . . . . . . . . . . . 17 -8. Editor . . . . . . . . . . . . . 18 -9. Others Contributing to the Document . . . . . . . . 18 -10. Trailing Boilerplate . . . . . . . . . . . . . 19 - - - - - - - - -DNSEXT Working Group Expires July 9, 2006 [Page 2] - -Internet-Draft dnsext-wcard January 9, 2006 - -1. Introduction - - In RFC 1034 [RFC1034], sections 4.3.2 and 4.3.3 describe the - synthesis of answers from special resource records called - wildcards. The definition in RFC 1034 is incomplete and has - proven to be confusing. This document describes the wildcard - synthesis by adding to the discussion and making limited - modifications. Modifications are made to close inconsistencies - that have led to interoperability issues. This description - does not expand the service intended by the original definition. - - Staying within the spirit and style of the original documents, - this document avoids specifying rules for DNS implementations - regarding wildcards. The intention is to only describe what is - needed for interoperability, not restrict implementation choices. - In addition, consideration is given to minimize any backwards - compatibility issues with implementations that comply with RFC - 1034's definition. - - This document is focused on the concept of wildcards as defined - in RFC 1034. Nothing is implied regarding alternative means of - synthesizing resource record sets, nor are alternatives discussed. - -1.1 Motivation - - Many DNS implementations diverge, in different ways, from the - original definition of wildcards. Although there is clearly a - need to clarify the original documents in light of this alone, - the impetus for this document lay in the engineering of the DNS - security extensions [RFC4033]. With an unclear definition of - wildcards the design of authenticated denial became entangled. - - This document is intended to limit its changes, documenting only - those based on implementation experience, and to remain as close - to the original document as possible. To reinforce that this - document is meant to clarify and adjust and not redefine wildcards, - relevant sections of RFC 1034 are repeated verbatim to facilitate - comparison of the old and new text. - -1.2 The Original Definition - - The definition of the wildcard concept is comprised by the - documentation of the algorithm by which a name server prepares - a response (in RFC 1034's section 4.3.2) and the way in which - a resource record (set) is identified as being a source of - synthetic data (section 4.3.3). - - This is the definition of the term "wildcard" as it appears in - RFC 1034, section 4.3.3. - - - -DNSEXT Working Group Expires July 9, 2006 [Page 3] - -Internet-Draft dnsext-wcard January 9, 2006 - -# In the previous algorithm, special treatment was given to RRs with -# owner names starting with the label "*". Such RRs are called -# wildcards. Wildcard RRs can be thought of as instructions for -# synthesizing RRs. When the appropriate conditions are met, the name -# server creates RRs with an owner name equal to the query name and -# contents taken from the wildcard RRs. - - This passage follows the algorithm in which the term wildcard - is first used. In this definition, wildcard refers to resource - records. In other usage, wildcard has referred to domain names, - and it has been used to describe the operational practice of - relying on wildcards to generate answers. It is clear from this - that there is a need to define clear and unambiguous terminology - in the process of discussing wildcards. - - The mention of the use of wildcards in the preparation of a - response is contained in step 3c of RFC 1034's section 4.3.2 - entitled "Algorithm." Note that "wildcard" does not appear in - the algorithm, instead references are made to the "*" label. - The portion of the algorithm relating to wildcards is - deconstructed in detail in section 3 of this document, this is - the beginning of the relevant portion of the "Algorithm." - -# c. If at some label, a match is impossible (i.e., the -# corresponding label does not exist), look to see if [...] -# the "*" label exists. - - The scope of this document is the RFC 1034 definition of - wildcards and the implications of updates to those documents, - such as DNSSEC. Alternate schemes for synthesizing answers are - not considered. (Note that there is no reference listed. No - document is known to describe any alternate schemes, although - there has been some mention of them in mailing lists.) - -1.3 Roadmap to This Document - - This document accomplishes these three items. - o Defines new terms - o Makes minor changes to avoid conflicting concepts - o Describes the actions of certain resource records as wildcards - -1.3.1 New Terms - - To help in discussing what resource records are wildcards, two - terms will be defined - "asterisk label" and "wild card domain - name". These are defined in section 2.1.1. - - To assist in clarifying the role of wildcards in the name server - algorithm in RFC 1034, 4.3.2, "source of synthesis" and "closest - encloser" are defined. These definitions are in section 3.3.2. - "Label match" is defined in section 3.2. - -DNSEXT Working Group Expires July 9, 2006 [Page 4] - -Internet-Draft dnsext-wcard January 9, 2006 - - The new terms are used to make discussions of wildcards clearer. - Terminology doesn't directly have an impact on implementations. - -1.3.2 Changed Text - - The definition of "existence" is changed superficially. This - change will not be apparent to implementations; it is needed to - make descriptions more precise. The change appears in section - 2.2.3. - - RFC 1034, section 4.3.3., seems to prohibit having two asterisk - labels in a wildcard owner name. With this document the - restriction is removed entirely. This change and its implications - are in section 2.1.3. - - The actions when a source of synthesis owns a CNAME RR are - changed to mirror the actions if an exact match name owns a - CNAME RR. This is an addition to the words in RFC 1034, - section 4.3.2, step 3, part c. The discussion of this is in - section 3.3.3. - - Only the latter change represents an impact to implementations. - The definition of existence is not a protocol impact. The change - to the restriction on names is unlikely to have an impact, as - RFC 1034 contained no specification on when and how to enforce the - restriction. - -1.3.3 Considerations with Special Types - - This document describes semantics of wildcard RRSets for - "interesting" types as well as empty non-terminal wildcards. - Understanding these situations in the context of wildcards has - been clouded because these types incur special processing if - they are the result of an exact match. This discussion is in - section 4. - - These discussions do not have an implementation impact, they cover - existing knowledge of the types, but to a greater level of detail. - -1.4 Standards Terminology - - This document does not use terms as defined in "Key words for use - in RFCs to Indicate Requirement Levels." [RFC2119] - - Quotations of RFC 1034 are denoted by a '#' in the leftmost - column. References to section "4.3.2" are assumed to refer - to RFC 1034's section 4.3.2, simply titled "Algorithm." - - - - - -DNSEXT Working Group Expires July 9, 2006 [Page 5] - -Internet-Draft dnsext-wcard January 9, 2006 - -2. Wildcard Syntax - - The syntax of a wildcard is the same as any other DNS resource - record, across all classes and types. The only significant - feature is the owner name. - - Because wildcards are encoded as resource records with special - names, they are included in zone transfers and incremental zone - transfers[RFC1995] just as non-wildcard resource records are. - This feature has been under appreciated until discussions on - alternative approaches to wildcards appeared on mailing lists. - -2.1 Identifying a Wildcard - - To provide a more accurate description of wildcards, the - definition has to start with a discussion of the domain names - that appear as owners. Two new terms are needed, "Asterisk - Label" and "Wild Card Domain Name." - -2.1.1 Wild Card Domain Name and Asterisk Label - - A "wild card domain name" is defined by having its initial - (i.e., left-most or least significant) label be, in binary format: - - 0000 0001 0010 1010 (binary) = 0x01 0x2a (hexadecimal) - - The first octet is the normal label type and length for a 1 octet - long label, the second octet is the ASCII representation [RFC20] - for the '*' character. - - A descriptive name of a label equaling that value is an "asterisk - label." - - RFC 1034's definition of wildcard would be "a resource record - owned by a wild card domain name." - -2.1.2 Asterisks and Other Characters - - No label values other than that in section 2.1.1 are asterisk - labels, hence names beginning with other labels are never wild - card domain names. Labels such as 'the*' and '**' are not - asterisk labels so these labels do not start wild card domain - names. - -2.1.3 Non-terminal Wild Card Domain Names - - In section 4.3.3, the following is stated: - -# .......................... The owner name of the wildcard RRs is of -# the form "*.", where is any domain name. -# should not contain other * labels...................... - -DNSEXT Working Group Expires July 9, 2006 [Page 6] - -Internet-Draft dnsext-wcard January 9, 2006 - - The restriction is now removed. The original documentation of it - is incomplete and the restriction does not serve any purpose - given years of operational experience. - - There are three possible reasons for putting the restriction in - place, but none of the three has held up over time. One is - that the restriction meant that there would never be subdomains - of wild card domain names, but the restriciton as stated still - permits "example.*.example." for instance. Another is that - wild card domain names are not intended to be empty non-terminals, - but this situation does not disrupt the algorithm in 4.3.2. - Finally, "nested" wild card domain names are not ambiguous once - the concept of the closest encloser had been documented. - - A wild card domain name can have subdomains. There is no need - to inspect the subdomains to see if there is another asterisk - label in any subdomain. - - A wild card domain name can be an empty non-terminal. (See the - upcoming sections on empty non-terminals.) In this case, any - lookup encountering it will terminate as would any empty - non-terminal match. - -2.2 Existence Rules - - The notion that a domain name 'exists' is mentioned in the - definition of wildcards. In section 4.3.3 of RFC 1034: - -# Wildcard RRs do not apply: -# -... -# - When the query name or a name between the wildcard domain and -# the query name is know[n] to exist. For example, if a wildcard - - "Existence" is therefore an important concept in the understanding - of wildcards. Unfortunately, the definition of what exists, in RFC - 1034, is unclear. So, in sections 2.2.2. and 2.2.3, another look is - taken at the definition of existence. - -2.2.1 An Example - - To illustrate what is meant by existence consider this complete - zone: - - - - - - - - - -DNSEXT Working Group Expires July 9, 2006 [Page 7] - -Internet-Draft dnsext-wcard January 9, 2006 - - $ORIGIN example. - example. 3600 IN SOA - example. 3600 NS ns.example.com. - example. 3600 NS ns.example.net. - *.example. 3600 TXT "this is a wild card" - *.example. 3600 MX 10 host1.example. - sub.*.example. 3600 TXT "this is not a wild card" - host1.example. 3600 A 192.0.4.1 - _ssh._tcp.host1.example. 3600 SRV - _ssh._tcp.host2.example. 3600 SRV - subdel.example. 3600 NS ns.example.com. - subdel.example. 3600 NS ns.example.net. - - A look at the domain names in a tree structure is helpful: - - | - -------------example------------ - / / \ \ - / / \ \ - / / \ \ - * host1 host2 subdel - | | | - | | | - sub _tcp _tcp - | | - | | - _ssh _ssh - - The following responses would be synthesized from one of the - wildcards in the zone: - - QNAME=host3.example. QTYPE=MX, QCLASS=IN - the answer will be a "host3.example. IN MX ..." - - QNAME=host3.example. QTYPE=A, QCLASS=IN - the answer will reflect "no error, but no data" - because there is no A RR set at '*.example.' - - QNAME=foo.bar.example. QTYPE=TXT, QCLASS=IN - the answer will be "foo.bar.example. IN TXT ..." - because bar.example. does not exist, but the wildcard - does. - - The following responses would not be synthesized from any of the - wildcards in the zone: - - QNAME=host1.example., QTYPE=MX, QCLASS=IN - because host1.example. exists - - QNAME=sub.*.example., QTYPE=MX, QCLASS=IN - because sub.*.example. exists - -DNSEXT Working Group Expires July 9, 2006 [Page 8] - -Internet-Draft dnsext-wcard January 9, 2006 - - QNAME=_telnet._tcp.host1.example., QTYPE=SRV, QCLASS=IN - because _tcp.host1.example. exists (without data) - - QNAME=host.subdel.example., QTYPE=A, QCLASS=IN - because subdel.example. exists (and is a zone cut) - - QNAME=ghost.*.example., QTYPE=MX, QCLASS=IN - because *.example. exists - - The final example highlights one common misconception about - wildcards. A wildcard "blocks itself" in the sense that a - wildcard does not match its own subdomains. I.e. "*.example." - does not match all names in the "example." zone, it fails to - match the names below "*.example." To cover names under - "*.example.", another wild card domain name is needed - - "*.*.example." - which covers all but it's own subdomains. - -2.2.2 Empty Non-terminals - - Empty non-terminals [RFC2136, Section 7.16] are domain names - that own no resource records but have subdomains that do. In - section 2.2.1, "_tcp.host1.example." is an example of a empty - non-terminal name. Empty non-terminals are introduced by this - text in section 3.1 of RFC 1034: - -# The domain name space is a tree structure. Each node and leaf on -# the tree corresponds to a resource set (which may be empty). The -# domain system makes no distinctions between the uses of the -# interior nodes and leaves, and this memo uses the term "node" to -# refer to both. - - The parenthesized "which may be empty" specifies that empty non- - terminals are explicitly recognized, and that empty non-terminals - "exist." - - Pedantically reading the above paragraph can lead to an - interpretation that all possible domains exist - up to the - suggested limit of 255 octets for a domain name [RFC1035]. - For example, www.example. may have an A RR, and as far as is - practically concerned, is a leaf of the domain tree. But the - definition can be taken to mean that sub.www.example. also - exists, albeit with no data. By extension, all possible domains - exist, from the root on down. - - As RFC 1034 also defines "an authoritative name error indicating - that the name does not exist" in section 4.3.1, so this apparently - is not the intent of the original definition, justifying the - need for an updated definition in the next section. - - - - -DNSEXT Working Group Expires July 9, 2006 [Page 9] - -Internet-Draft dnsext-wcard January 9, 2006 - -2.2.3 Yet Another Definition of Existence - - RFC1034's wording is fixed by the following paragraph: - - The domain name space is a tree structure. Nodes in the tree - either own at least one RRSet and/or have descendants that - collectively own at least one RRSet. A node may exist with no - RRSets only if it has descendents that do, this node is an empty - non-terminal. - - A node with no descendants is a leaf node. Empty leaf nodes do - not exist. - - Note that at a zone boundary, the domain name owns data, - including the NS RR set. In the delegating zone, the NS RR - set is not authoritative, but that is of no consequence here. - The domain name owns data, therefore, it exists. - -2.3 When is a Wild Card Domain Name Not Special - - When a wild card domain name appears in a message's query section, - no special processing occurs. An asterisk label in a query name - only matches a single, corresponding asterisk label in the - existing zone tree when the 4.3.2 algorithm is being followed. - - When a wild card domain name appears in the resource data of a - record, no special processing occurs. An asterisk label in that - context literally means just an asterisk. - -3. Impact of a Wild Card Domain Name On a Response - - RFC 1034's description of how wildcards impact response - generation is in its section 4.3.2. That passage contains the - algorithm followed by a server in constructing a response. - Within that algorithm, step 3, part 'c' defines the behavior of - the wildcard. - - The algorithm in section 4.3.2. is not intended to be pseudo-code, - i.e., its steps are not intended to be followed in strict order. - The "algorithm" is a suggested means of implementing the - requirements. As such, in step 3, parts a, b, and c, do not have - to be implemented in that order, provided that the result of the - implemented code is compliant with the protocol's specification. - -3.1 Step 2 - - Step 2 of section 4.3.2 reads: - -# 2. Search the available zones for the zone which is the nearest -# ancestor to QNAME. If such a zone is found, go to step 3, -# otherwise step 4. - -DNSEXT Working Group Expires July 9, 2006 [Page 10] - -Internet-Draft dnsext-wcard January 9, 2006 - - In this step, the most appropriate zone for the response is - chosen. The significance of this step is that it means all of - step 3 is being performed within one zone. This has significance - when considering whether or not an SOA RR can be ever be used for - synthesis. - -3.2 Step 3 - - Step 3 is dominated by three parts, labelled 'a', 'b', and 'c'. - But the beginning of the step is important and needs explanation. - -# 3. Start matching down, label by label, in the zone. The -# matching process can terminate several ways: - - The word 'matching' refers to label matching. The concept - is based in the view of the zone as the tree of existing names. - The query name is considered to be an ordered sequence of - labels - as if the name were a path from the root to the owner - of the desired data. (Which it is - 3rd paragraph of RFC 1034, - section 3.1.) - - The process of label matching a query name ends in exactly one of - three choices, the parts 'a', 'b', and 'c'. Either the name is - found, the name is below a cut point, or the name is not found. - - Once one of the parts is chosen, the other parts are not - considered. (E.g., do not execute part 'c' and then change - the execution path to finish in part 'b'.) The process of label - matching is also done independent of the query type (QTYPE). - - Parts 'a' and 'b' are not an issue for this clarification as they - do not relate to record synthesis. Part 'a' is an exact match - that results in an answer, part 'b' is a referral. - -3.3 Part 'c' - - The context of part 'c' is that the process of label matching the - labels of the query name has resulted in a situation in which - there is no corresponding label in the tree. It is as if the - lookup has "fallen off the tree." - -# c. If at some label, a match is impossible (i.e., the -# corresponding label does not exist), look to see if [...] -# the "*" label exists. - - To help describe the process of looking 'to see if [...] the "*" - label exists' a term has been coined to describe the last domain - (node) matched. The term is "closest encloser." - - - - -DNSEXT Working Group Expires July 9, 2006 [Page 11] - -Internet-Draft dnsext-wcard January 9, 2006 - -3.3.1 Closest Encloser and the Source of Synthesis - - The closest encloser is the node in the zone's tree of existing - domain names that has the most labels matching the query name - (consecutively, counting from the root label downward). Each match - is a "label match" and the order of the labels is the same. - - The closest encloser is, by definition, an existing name in the - zone. The closest encloser might be an empty non-terminal or even - be a wild card domain name itself. In no circumstances is the - closest encloser to be used to synthesize records for the current - query. - - The source of synthesis is defined in the context of a query - process as that wild card domain name immediately descending - from the closest encloser, provided that this wild card domain - name exists. "Immediately descending" means that the source - of synthesis has a name of the form: - .. - A source of synthesis does not guarantee having a RRSet to use - for synthesis. The source of synthesis could be an empty - non-terminal. - - If the source of synthesis does not exist (not on the domain - tree), there will be no wildcard synthesis. There is no search - for an alternate. - - The important concept is that for any given lookup process, there - is at most one place at which wildcard synthetic records can be - obtained. If the source of synthesis does not exist, the lookup - terminates, the lookup does not look for other wildcard records. - -3.3.2 Closest Encloser and Source of Synthesis Examples - - To illustrate, using the example zone in section 2.2.1 of this - document, the following chart shows QNAMEs and the closest - enclosers. - - QNAME Closest Encloser Source of Synthesis - host3.example. example. *.example. - _telnet._tcp.host1.example. _tcp.host1.example. no source - _telnet._tcp.host2.example. host2.example. no source - _telnet._tcp.host3.example. example. *.example. - _chat._udp.host3.example. example. *.example. - foobar.*.example. *.example. no source - - - - - - - -DNSEXT Working Group Expires July 9, 2006 [Page 12] - -Internet-Draft dnsext-wcard January 9, 2006 - -3.3.3 Type Matching - - RFC 1034 concludes part 'c' with this: - -# If the "*" label does not exist, check whether the name -# we are looking for is the original QNAME in the query -# or a name we have followed due to a CNAME. If the name -# is original, set an authoritative name error in the -# response and exit. Otherwise just exit. -# -# If the "*" label does exist, match RRs at that node -# against QTYPE. If any match, copy them into the answer -# section, but set the owner of the RR to be QNAME, and -# not the node with the "*" label. Go to step 6. - - The final paragraph covers the role of the QTYPE in the lookup - process. - - Based on implementation feedback and similarities between step - 'a' and step 'c' a change to this passage has been made. - - The change is to add the following text to step 'c' prior to the - instructions to "go to step 6": - - If the data at the source of synthesis is a CNAME, and - QTYPE doesn't match CNAME, copy the CNAME RR into the - answer section of the response changing the owner name - to the QNAME, change QNAME to the canonical name in the - CNAME RR, and go back to step 1. - - This is essentially the same text in step a covering the - processing of CNAME RRSets. - -4. Considerations with Special Types - - Sections 2 and 3 of this document discuss wildcard synthesis - with respect to names in the domain tree and ignore the impact - of types. In this section, the implication of wildcards of - specific types are discussed. The types covered are those - that have proven to be the most difficult to understand. The - types are SOA, NS, CNAME, DNAME, SRV, DS, NSEC, RRSIG and - "none," i.e., empty non-terminal wild card domain names. - -4.1 SOA RRSet at a Wild Card Domain Name - - A wild card domain name owning an SOA RRSet means that the - domain is at the root of the zone (apex). The domain can not - be a source of synthesis because that is, by definition, a - descendent node (of the closest encloser) and a zone apex is - at the top of the zone. - - -DNSEXT Working Group Expires July 9, 2006 [Page 13] - -Internet-Draft dnsext-wcard January 9, 2006 - - Although a wild card domain name owning an SOA RRSet can never - be a source of synthesis, there is no reason to forbid the - ownership of an SOA RRSet. - - E.g., given this zone: - $ORIGIN *.example. - @ 3600 IN SOA - 3600 NS ns1.example.com. - 3600 NS ns1.example.net. - www 3600 TXT "the www txt record" - - A query for www.*.example.'s TXT record would still find the - "the www txt record" answer. The asterisk label only becomes - significant when section 4.3.2, step 3 part 'c' is in effect. - - Of course, there would need to be a delegation in the parent - zone, "example." for this to work too. This is covered in the - next section. - -4.2 NS RRSet at a Wild Card Domain Name - - With the definition of DNSSEC [RFC4033, RFC4034, RFC4035] now - in place, the semantics of a wild card domain name owning an - NS RRSet has come to be poorly defined. The dilemma relates to - a conflict between the rules for synthesis in part 'c' and the - fact that the resulting synthesis generates a record for which - the zone is not authoritative. In a DNSSEC signed zone, the - mechanics of signature management (generation and inclusion - in a message) have become unclear. - - Salient points of the working group discussion on this topic is - summarized in section 4.2.1. - - As a result of these discussion, there is no definition given for - wild card domain names owning an NS RRSet. The semantics are - left undefined until there is a clear need to have a set defined, - and until there is a clear direction to proceed. Operationally, - inclusion of wild card NS RRSets in a zone is discouraged, but - not barred. - -4.2.1 Discarded Notions - - Prior to DNSSEC, a wild card domain name owning a NS RRSet - appeared to be workable, and there are some instances in which - it is found in deployments using implementations that support - this. Continuing to allow this in the specification is not - tenable with DNSSEC. The reason is that the synthesis of the - NS RRSet is being done in a zone that has delegated away the - responsibility for the name. This "unauthorized" synthesis is - not a problem for the base DNS protocol, but DNSSEC, in affirming - the authorization model for DNS exposes the problem. - -DNSEXT Working Group Expires July 9, 2006 [Page 14] - -Internet-Draft dnsext-wcard January 9, 2006 - - Outright banning of wildcards of type NS is also untenable as - the DNS protocol does not define how to handle "illegal" data. - Implementations may choose not to load a zone, but there is no - protocol definition. The lack of the definition is complicated - by having to cover dynamic update [RFC 2136], zone transfers, - as well as loading at the master server. The case of a client - (resolver, caching server) getting a wildcard of type NS in - a reply would also have to be considered. - - Given the daunting challenge of a complete definition of how to - ban such records, dealing with existing implementations that - permit the records today is a further complication. There are - uses of wild card domain name owning NS RRSets. - - One compromise proposed would have redefined wildcards of type - NS to not be used in synthesis, this compromise fell apart - because it would have required significant edits to the DNSSEC - signing and validation work. (Again, DNSSEC catches - unauthorized data.) - - With no clear consensus forming on the solution to this dilemma, - and the realization that wildcards of type NS are a rarity in - operations, the best course of action is to leave this open-ended - until "it matters." - -4.3 CNAME RRSet at a Wild Card Domain Name - - The issue of a CNAME RRSet owned by a wild card domain name has - prompted a suggested change to the last paragraph of step 3c of - the algorithm in 4.3.2. The changed text appears in section - 3.3.3 of this document. - -4.4 DNAME RRSet at a Wild Card Domain Name - - Ownership of a DNAME [RFC2672] RRSet by a wild card domain name - represents a threat to the coherency of the DNS and is to be - avoided or outright rejected. Such a DNAME RRSet represents - non-deterministic synthesis of rules fed to different caches. - As caches are fed the different rules (in an unpredictable - manner) the caches will cease to be coherent. ("As caches - are fed" refers to the storage in a cache of records obtained - in responses by recursive or iterative servers.) - - For example, assume one cache, responding to a recursive - request, obtains the record: - "a.b.example. DNAME foo.bar.example.net." - and another cache obtains: - "b.example. DNAME foo.bar.example.net." - both generated from the record: - "*.example. DNAME foo.bar.example.net." - by an authoritative server. - -DNSEXT Working Group Expires July 9, 2006 [Page 15] - -Internet-Draft dnsext-wcard January 9, 2006 - - The DNAME specification is not clear on whether DNAME records - in a cache are used to rewrite queries. In some interpretations, - the rewrite occurs, in some, it is not. Allowing for the - occurrence of rewriting, queries for "sub.a.b.example. A" may - be rewritten as "sub.foo.bar.tld. A" by the former caching - server and may be rewritten as "sub.a.foo.bar.tld. A" by the - latter. Coherency is lost, an operational nightmare ensues. - - Another justification for banning or avoiding wildcard DNAME - records is the observation that such a record could synthesize - a DNAME owned by "sub.foo.bar.example." and "foo.bar.example." - There is a restriction in the DNAME definition that no domain - exist below a DNAME-owning domain, hence, the wildcard DNAME - is not to be permitted. - -4.5 SRV RRSet at a Wild Card Domain Name - - The definition of the SRV RRset is RFC 2782 [RFC2782]. In the - definition of the record, there is some confusion over the term - "Name." The definition reads as follows: - -# The format of the SRV RR -... -# _Service._Proto.Name TTL Class SRV Priority Weight Port Target -... -# Name -# The domain this RR refers to. The SRV RR is unique in that the -# name one searches for is not this name; the example near the end -# shows this clearly. - - Do not confuse the definition "Name" with the owner name. I.e., - once removing the _Service and _Proto labels from the owner name - of the SRV RRSet, what remains could be a wild card domain name - but this is immaterial to the SRV RRSet. - - E.g., If an SRV record is: - _foo._udp.*.example. 10800 IN SRV 0 1 9 old-slow-box.example. - - *.example is a wild card domain name and although it is the Name - of the SRV RR, it is not the owner (domain name). The owner - domain name is "_foo._udp.*.example." which is not a wild card - domain name. - - The confusion is likely based on the mixture of the specification - of the SRV RR and the description of a "use case." - -4.6 DS RRSet at a Wild Card Domain Name - - A DS RRSet owned by a wild card domain name is meaningless and - harmless. This statement is made in the context that an NS RRSet - at a wild card domain name is undefined. At a non-delegation - -DNSEXT Working Group Expires July 9, 2006 [Page 16] - -Internet-Draft dnsext-wcard January 9, 2006 - - point, a DS RRSet has no value (no corresponding DNSKEY RRSet - will be used in DNSSEC validation). If there is a synthesized - DS RRSet, it alone will not be very useful as it exists in the - context of a delegation point. - -4.7 NSEC RRSet at a Wild Card Domain Name - - Wild card domain names in DNSSEC signed zones will have an NSEC - RRSet. Synthesis of these records will only occur when the - query exactly matches the record. Synthesized NSEC RR's will not - be harmful as they will never be used in negative caching or to - generate a negative response. [RFC2308] - -4.8 RRSIG at a Wild Card Domain Name - - RRSIG records will be present at a wild card domain name in a - signed zone, and will be synthesized along with data sought in a - query. The fact that the owner name is synthesized is not a - problem as the label count in the RRSIG will instruct the - verifying code to ignore it. - -4.9 Empty Non-terminal Wild Card Domain Name - - If a source of synthesis is an empty non-terminal, then the - response will be one of no error in the return code and no RRSet - in the answer section. - -5. Security Considerations - - This document is refining the specifications to make it more - likely that security can be added to DNS. No functional - additions are being made, just refining what is considered - proper to allow the DNS, security of the DNS, and extending - the DNS to be more predictable. - -6. IANA Considerations - - None. - -7. References - - Normative References - - [RFC20] ASCII Format for Network Interchange, V.G. Cerf, - Oct-16-1969 - - [RFC1034] Domain Names - Concepts and Facilities, - P.V. Mockapetris, Nov-01-1987 - - [RFC1035] Domain Names - Implementation and Specification, P.V - Mockapetris, Nov-01-1987 - -DNSEXT Working Group Expires July 9, 2006 [Page 17] - -Internet-Draft dnsext-wcard January 9, 2006 - - [RFC1995] Incremental Zone Transfer in DNS, M. Ohta, August 1996 - - [RFC2119] Key Words for Use in RFCs to Indicate Requirement - Levels, S Bradner, March 1997 - - [RFC2308] Negative Caching of DNS Queries (DNS NCACHE), - M. Andrews, March 1998 - - [RFC2672] Non-Terminal DNS Name Redirection, M. Crawford, - August 1999. - - [RFC2782] A DNS RR for specifying the location of services (DNS - SRV), A. Gulbrandsen, et.al., February 2000 - - [RFC4033] DNS Security Introduction and Requirements, R. Arends, - et.al., March 2005 - - [RFC4034] Resource Records for the DNS Security Extensions, - R. Arends, et.al., March 2005 - - [RFC4035] Protocol Modifications for the DNS Security Extensions, - R. Arends, et.al., March 2005 - - Informative References - - [RFC2136] Dynamic Updates in the Domain Name System (DNS UPDATE), - P. Vixie, Ed., S. Thomson, Y. Rekhter, J. Bound, - April 1997 - -8. Editor - - Name: Edward Lewis - Affiliation: NeuStar - Address: 46000 Center Oak Plaza, Sterling, VA, 20166, US - Phone: +1-571-434-5468 - Email: ed.lewis@neustar.biz - - Comments on this document can be sent to the editor or the mailing - list for the DNSEXT WG, namedroppers@ops.ietf.org. - -9. Others Contributing to the Document - - This document represents the work of a large working group. The - editor merely recorded the collective wisdom of the working group. - - - - - - - - - -DNSEXT Working Group Expires July 9, 2006 [Page 17] - -Internet-Draft dnsext-wcard January 9, 2006 - -10. Trailing Boilerplate - - Copyright (C) The Internet Society (2006). - - This document is subject to the rights, licenses and restrictions - contained in BCP 78, and except as set forth therein, the authors - retain all their rights. - - This document and the information contained herein are provided - on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION - HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET - SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL - WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO - ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT - INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -Intellectual Property - - The IETF takes no position regarding the validity or scope of - any Intellectual Property Rights or other rights that might - be claimed to pertain to the implementation or use of the - technology described in this document or the extent to which - any license under such rights might or might not be available; - nor does it represent that it has made any independent effort - to identify any such rights. Information on the procedures - with respect to rights in RFC documents can be found in BCP 78 - and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the - use of such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR - repository at http://www.ietf.org/ipr. The IETF invites any - interested party to bring to its attention any copyrights, - patents or patent applications, or other proprietary rights - that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - -Expiration - - This document expires on or about July 9, 2006. - - - -DNSEXT Working Group Expires July 9, 2006 [Page 19] diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsop-bad-dns-res-05.txt b/contrib/bind9/doc/draft/draft-ietf-dnsop-bad-dns-res-05.txt deleted file mode 100644 index 0855ba3..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsop-bad-dns-res-05.txt +++ /dev/null @@ -1,1232 +0,0 @@ - - - -DNS Operations M. Larson -Internet-Draft P. Barber -Expires: August 14, 2006 VeriSign - February 10, 2006 - - - Observed DNS Resolution Misbehavior - draft-ietf-dnsop-bad-dns-res-05 - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on August 14, 2006. - -Copyright Notice - - Copyright (C) The Internet Society (2006). - -Abstract - - This memo describes DNS iterative resolver behavior that results in a - significant query volume sent to the root and top-level domain (TLD) - name servers. We offer implementation advice to iterative resolver - developers to alleviate these unnecessary queries. The - recommendations made in this document are a direct byproduct of - observation and analysis of abnormal query traffic patterns seen at - two of the thirteen root name servers and all thirteen com/net TLD - name servers. - - - -Larson & Barber Expires August 14, 2006 [Page 1] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in RFC 2119 [1]. - - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 1.1. A note about terminology in this memo . . . . . . . . . . 3 - 2. Observed iterative resolver misbehavior . . . . . . . . . . . 5 - 2.1. Aggressive requerying for delegation information . . . . . 5 - 2.1.1. Recommendation . . . . . . . . . . . . . . . . . . . . 6 - 2.2. Repeated queries to lame servers . . . . . . . . . . . . . 7 - 2.2.1. Recommendation . . . . . . . . . . . . . . . . . . . . 7 - 2.3. Inability to follow multiple levels of indirection . . . . 8 - 2.3.1. Recommendation . . . . . . . . . . . . . . . . . . . . 9 - 2.4. Aggressive retransmission when fetching glue . . . . . . . 9 - 2.4.1. Recommendation . . . . . . . . . . . . . . . . . . . . 10 - 2.5. Aggressive retransmission behind firewalls . . . . . . . . 10 - 2.5.1. Recommendation . . . . . . . . . . . . . . . . . . . . 11 - 2.6. Misconfigured NS records . . . . . . . . . . . . . . . . . 11 - 2.6.1. Recommendation . . . . . . . . . . . . . . . . . . . . 12 - 2.7. Name server records with zero TTL . . . . . . . . . . . . 12 - 2.7.1. Recommendation . . . . . . . . . . . . . . . . . . . . 13 - 2.8. Unnecessary dynamic update messages . . . . . . . . . . . 13 - 2.8.1. Recommendation . . . . . . . . . . . . . . . . . . . . 14 - 2.9. Queries for domain names resembling IPv4 addresses . . . . 14 - 2.9.1. Recommendation . . . . . . . . . . . . . . . . . . . . 14 - 2.10. Misdirected recursive queries . . . . . . . . . . . . . . 15 - 2.10.1. Recommendation . . . . . . . . . . . . . . . . . . . . 15 - 2.11. Suboptimal name server selection algorithm . . . . . . . . 15 - 2.11.1. Recommendation . . . . . . . . . . . . . . . . . . . . 16 - 3. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 17 - 4. IANA considerations . . . . . . . . . . . . . . . . . . . . . 18 - 5. Security considerations . . . . . . . . . . . . . . . . . . . 19 - 6. Internationalization considerations . . . . . . . . . . . . . 20 - 7. Informative References . . . . . . . . . . . . . . . . . . . . 20 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 21 - Intellectual Property and Copyright Statements . . . . . . . . . . 22 - - - - - - - - - - - - -Larson & Barber Expires August 14, 2006 [Page 2] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - -1. Introduction - - Observation of query traffic received by two root name servers and - the thirteen com/net TLD name servers has revealed that a large - proportion of the total traffic often consists of "requeries". A - requery is the same question () asked - repeatedly at an unexpectedly high rate. We have observed requeries - from both a single IP address and multiple IP addresses (i.e., the - same query received simultaneously from multiple IP addresses). - - By analyzing requery events we have found that the cause of the - duplicate traffic is almost always a deficient iterative resolver, - stub resolver or application implementation combined with an - operational anomaly. The implementation deficiencies we have - identified to date include well-intentioned recovery attempts gone - awry, insufficient caching of failures, early abort when multiple - levels of indirection must be followed, and aggressive retry by stub - resolvers or applications. Anomalies that we have seen trigger - requery events include lame delegations, unusual glue records, and - anything that makes all authoritative name servers for a zone - unreachable (DoS attacks, crashes, maintenance, routing failures, - congestion, etc.). - - In the following sections, we provide a detailed explanation of the - observed behavior and recommend changes that will reduce the requery - rate. None of the changes recommended affects the core DNS protocol - specification; instead, this document consists of guidelines to - implementors of iterative resolvers. - -1.1. A note about terminology in this memo - - To recast an old saying about standards, the nice thing about DNS - terms is that there are so many of them to choose from. Writing or - talking about DNS can be difficult and cause confusion resulting from - a lack of agreed-upon terms for its various components. Further - complicating matters are implementations that combine multiple roles - into one piece of software, which makes naming the result - problematic. An example is the entity that accepts recursive - queries, issues iterative queries as necessary to resolve the initial - recursive query, caches responses it receives, and which is also able - to answer questions about certain zones authoritatively. This entity - is an iterative resolver combined with an authoritative name server - and is often called a "recursive name server" or a "caching name - server". - - This memo is concerned principally with the behavior of iterative - resolvers, which are typically found as part of a recursive name - server. This memo uses the more precise term "iterative resolver", - - - -Larson & Barber Expires August 14, 2006 [Page 3] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - - because the focus is usually on that component. In instances where - the name server role of this entity requires mentioning, this memo - uses the term "recursive name server". As an example of the - difference, the name server component of a recursive name server - receives DNS queries and the iterative resolver component sends - queries. - - The advent of IPv6 requires mentioning AAAA records as well as A - records when discussing glue. To avoid continuous repetition and - qualification, this memo uses the general term "address record" to - encompass both A and AAAA records when a particular situation is - relevant to both types. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Larson & Barber Expires August 14, 2006 [Page 4] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - -2. Observed iterative resolver misbehavior - -2.1. Aggressive requerying for delegation information - - There can be times when every name server in a zone's NS RRset is - unreachable (e.g., during a network outage), unavailable (e.g., the - name server process is not running on the server host) or - misconfigured (e.g., the name server is not authoritative for the - given zone, also known as "lame"). Consider an iterative resolver - that attempts to resolve a query for a domain name in such a zone and - discovers that none of the zone's name servers can provide an answer. - We have observed a recursive name server implementation whose - iterative resolver then verifies the zone's NS RRset in its cache by - querying for the zone's delegation information: it sends a query for - the zone's NS RRset to one of the parent zone's name servers. (Note - that queries with QTYPE=NS are not required by the standard - resolution algorithm described in section 4.3.2 of RFC 1034 [2]. - These NS queries represent this implementation's addition to that - algorithm.) - - For example, suppose that "example.com" has the following NS RRset: - - example.com. IN NS ns1.example.com. - example.com. IN NS ns2.example.com. - - Upon receipt of a query for "www.example.com" and assuming that - neither "ns1.example.com" nor "ns2.example.com" can provide an - answer, this iterative resolver implementation immediately queries a - "com" zone name server for the "example.com" NS RRset to verify it - has the proper delegation information. This implementation performs - this query to a zone's parent zone for each recursive query it - receives that fails because of a completely unresponsive set of name - servers for the target zone. Consider the effect when a popular zone - experiences a catastrophic failure of all its name servers: now every - recursive query for domain names in that zone sent to this recursive - name server implementation results in a query to the failed zone's - parent name servers. On one occasion when several dozen popular - zones became unreachable, the query load on the com/net name servers - increased by 50%. - - We believe this verification query is not reasonable. Consider the - circumstances: When an iterative resolver is resolving a query for a - domain name in a zone it has not previously searched, it uses the - list of name servers in the referral from the target zone's parent. - If on its first attempt to search the target zone, none of the name - servers in the referral is reachable, a verification query to the - parent would be pointless: this query to the parent would come so - quickly on the heels of the referral that it would be almost certain - - - -Larson & Barber Expires August 14, 2006 [Page 5] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - - to contain the same list of name servers. The chance of discovering - any new information is slim. - - The other possibility is that the iterative resolver successfully - contacts one of the target zone's name servers and then caches the NS - RRset from the authority section of a response, the proper behavior - according to section 5.4.1 of RFC 2181 [3], because the NS RRset from - the target zone is more trustworthy than delegation information from - the parent zone. If, while processing a subsequent recursive query, - the iterative resolver discovers that none of the name servers - specified in the cached NS RRset is available or authoritative, - querying the parent would be wrong. An NS RRset from the parent zone - would now be less trustworthy than data already in the cache. - - For this query of the parent zone to be useful, the target zone's - entire set of name servers would have to change AND the former set of - name servers would have to be deconfigured or decommissioned AND the - delegation information in the parent zone would have to be updated - with the new set of name servers, all within the TTL of the target - zone's NS RRset. We believe this scenario is uncommon: - administrative best practices dictate that changes to a zone's set of - name servers happen gradually when at all possible, with servers - removed from the NS RRset left authoritative for the zone as long as - possible. The scenarios that we can envision that would benefit from - the parent requery behavior do not outweigh its damaging effects. - - This section should not be understood to claim that all queries to a - zone's parent are bad. In some cases, such queries are not only - reasonable but required. Consider the situation when required - information, such as the address of a name server (i.e., the address - record corresponding to the RDATA of an NS record), has timed out of - an iterative resolver's cache before the corresponding NS record. If - the name of the name server is below the apex of the zone, then the - name server's address record is only available as glue in the parent - zone. For example, consider this NS record: - - example.com. IN NS ns.example.com. - - If a cache has this NS record but not the address record for - "ns.example.com", it is unable to contact the "example.com" zone - directly and must query the "com" zone to obtain the address record. - Note, however, that such a query would not have QTYPE=NS according to - the standard resolution algorithm. - -2.1.1. Recommendation - - An iterative resolver MUST NOT send a query for the NS RRset of a - non-responsive zone to any of the name servers for that zone's parent - - - -Larson & Barber Expires August 14, 2006 [Page 6] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - - zone. For the purposes of this injunction, a non-responsive zone is - defined as a zone for which every name server listed in the zone's NS - RRset: - - 1. is not authoritative for the zone (i.e., lame), or, - - 2. returns a server failure response (RCODE=2), or, - - 3. is dead or unreachable according to section 7.2 of RFC 2308 [4]. - -2.2. Repeated queries to lame servers - - Section 2.1 describes a catastrophic failure: when every name server - for a zone is unable to provide an answer for one reason or another. - A more common occurrence is when a subset of a zone's name servers - are unavailable or misconfigured. Different failure modes have - different expected durations. Some symptoms indicate problems that - are potentially transient; for example, various types of ICMP - unreachable messages because a name server process is not running or - a host or network is unreachable, or a complete lack of a response to - a query. Such responses could be the result of a host rebooting or - temporary outages; these events don't necessarily require any human - intervention and can be reasonably expected to be temporary. - - Other symptoms clearly indicate a condition requiring human - intervention, such as lame server: if a name server is misconfigured - and not authoritative for a zone delegated to it, it is reasonable to - assume that this condition has potential to last longer than - unreachability or unresponsiveness. Consequently, repeated queries - to known lame servers are not useful. In this case of a condition - with potential to persist for a long time, a better practice would be - to maintain a list of known lame servers and avoid querying them - repeatedly in a short interval. - - It should also be noted, however, that some authoritative name server - implementations appear to be lame only for queries of certain types - as described in RFC 4074 [5]. In this case, it makes sense to retry - the "lame" servers for other types of queries, particularly when all - known authoritative name servers appear to be "lame". - -2.2.1. Recommendation - - Iterative resolvers SHOULD cache name servers that they discover are - not authoritative for zones delegated to them (i.e. lame servers). - If this caching is performed, lame servers MUST be cached against the - specific query tuple . Zone - name can be derived from the owner name of the NS record that was - referenced to query the name server that was discovered to be lame. - - - -Larson & Barber Expires August 14, 2006 [Page 7] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - - Implementations that perform lame server caching MUST refrain from - sending queries to known lame servers based on a time interval from - when the server is discovered to be lame. A minimum interval of - thirty minutes is RECOMMENDED. - - An exception to this recommendation occurs if all name servers for a - zone are marked lame. In that case, the iterative resolver SHOULD - temporarily ignore the servers' lameness status and query one or more - servers. This behavior is a workaround for the type-specific - lameness issue described in the previous section. - - Implementors should take care not to make lame server avoidance logic - overly broad: note that a name server could be lame for a parent zone - but not a child zone, e.g., lame for "example.com" but properly - authoritative for "sub.example.com". Therefore a name server should - not be automatically considered lame for subzones. In the case - above, even if a name server is known to be lame for "example.com", - it should be queried for QNAMEs at or below "sub.example.com" if an - NS record indicates it should be authoritative for that zone. - -2.3. Inability to follow multiple levels of indirection - - Some iterative resolver implementations are unable to follow - sufficient levels of indirection. For example, consider the - following delegations: - - foo.example. IN NS ns1.example.com. - foo.example. IN NS ns2.example.com. - - example.com. IN NS ns1.test.example.net. - example.com. IN NS ns2.test.example.net. - - test.example.net. IN NS ns1.test.example.net. - test.example.net. IN NS ns2.test.example.net. - - An iterative resolver resolving the name "www.foo.example" must - follow two levels of indirection, first obtaining address records for - "ns1.test.example.net" or "ns2.test.example.net" in order to obtain - address records for "ns1.example.com" or "ns2.example.com" in order - to query those name servers for the address records of - "www.foo.example". While this situation may appear contrived, we - have seen multiple similar occurrences and expect more as new generic - top-level domains (gTLDs) become active. We anticipate many zones in - new gTLDs will use name servers in existing gTLDs, increasing the - number of delegations using out-of-zone name servers. - - - - - - -Larson & Barber Expires August 14, 2006 [Page 8] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - -2.3.1. Recommendation - - Clearly constructing a delegation that relies on multiple levels of - indirection is not a good administrative practice. However, the - practice is widespread enough to require that iterative resolvers be - able to cope with it. Iterative resolvers SHOULD be able to handle - arbitrary levels of indirection resulting from out-of-zone name - servers. Iterative resolvers SHOULD implement a level-of-effort - counter to avoid loops or otherwise performing too much work in - resolving pathological cases. - - A best practice that avoids this entire issue of indirection is to - name one or more of a zone's name servers in the zone itself. For - example, if the zone is named "example.com", consider naming some of - the name servers "ns{1,2,...}.example.com" (or similar). - -2.4. Aggressive retransmission when fetching glue - - When an authoritative name server responds with a referral, it - includes NS records in the authority section of the response. - According to the algorithm in section 4.3.2 of RFC 1034 [2], the name - server should also "put whatever addresses are available into the - additional section, using glue RRs if the addresses are not available - from authoritative data or the cache." Some name server - implementations take this address inclusion a step further with a - feature called "glue fetching". A name server that implements glue - fetching attempts to include address records for every NS record in - the authority section. If necessary, the name server issues multiple - queries of its own to obtain any missing address records. - - Problems with glue fetching can arise in the context of - "authoritative-only" name servers, which only serve authoritative - data and ignore requests for recursion. Such an entity will not - normally generate any queries of its own. Instead it answers non- - recursive queries from iterative resolvers looking for information in - zones it serves. With glue fetching enabled, however, an - authoritative server invokes an iterative resolver to look up an - unknown address record to complete the additional section of a - response. - - We have observed situations where the iterative resolver of a glue- - fetching name server can send queries that reach other name servers, - but is apparently prevented from receiving the responses. For - example, perhaps the name server is authoritative-only and therefore - its administrators expect it to receive only queries and not - responses. Perhaps unaware of glue fetching and presuming that the - name server's iterative resolver will generate no queries, its - administrators place the name server behind a network device that - - - -Larson & Barber Expires August 14, 2006 [Page 9] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - - prevents it from receiving responses. If this is the case, all glue- - fetching queries will go answered. - - We have observed name server implementations whose iterative - resolvers retry excessively when glue-fetching queries are - unanswered. A single com/net name server has received hundreds of - queries per second from a single such source. Judging from the - specific queries received and based on additional analysis, we - believe these queries result from overly aggressive glue fetching. - -2.4.1. Recommendation - - Implementers whose name servers support glue fetching SHOULD take - care to avoid sending queries at excessive rates. Implementations - SHOULD support throttling logic to detect when queries are sent but - no responses are received. - -2.5. Aggressive retransmission behind firewalls - - A common occurrence and one of the largest sources of repeated - queries at the com/net and root name servers appears to result from - resolvers behind misconfigured firewalls. In this situation, an - iterative resolver is apparently allowed to send queries through a - firewall to other name servers, but not receive the responses. The - result is more queries than necessary because of retransmission, all - of which are useless because the responses are never received. Just - as with the glue-fetching scenario described in Section 2.4, the - queries are sometimes sent at excessive rates. To make matters - worse, sometimes the responses, sent in reply to legitimate queries, - trigger an alarm on the originator's intrusion detection system. We - are frequently contacted by administrators responding to such alarms - who believe our name servers are attacking their systems. - - Not only do some resolvers in this situation retransmit queries at an - excessive rate, but they continue to do so for days or even weeks. - This scenario could result from an organization with multiple - recursive name servers, only a subset of whose iterative resolvers' - traffic is improperly filtered in this manner. Stub resolvers in the - organization could be configured to query multiple recursive name - servers. Consider the case where a stub resolver queries a filtered - recursive name server first. The iterative resolver of this - recursive name server sends one or more queries whose replies are - filtered, so it can't respond to the stub resolver, which times out. - Then the stub resolver retransmits to a recursive name server that is - able to provide an answer. Since resolution ultimately succeeds the - underlying problem might not be recognized or corrected. A popular - stub resolver implementation has a very aggressive retransmission - schedule, including simultaneous queries to multiple recursive name - - - -Larson & Barber Expires August 14, 2006 [Page 10] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - - servers, which could explain how such a situation could persist - without being detected. - -2.5.1. Recommendation - - The most obvious recommendation is that administrators SHOULD take - care not to place iterative resolvers behind a firewall that allows - queries to pass through but not the resulting replies. - - Iterative resolvers SHOULD take care to avoid sending queries at - excessive rates. Implementations SHOULD support throttling logic to - detect when queries are sent but no responses are received. - -2.6. Misconfigured NS records - - Sometimes a zone administrator forgets to add the trailing dot on the - domain names in the RDATA of a zone's NS records. Consider this - fragment of the zone file for "example.com": - - $ORIGIN example.com. - example.com. 3600 IN NS ns1.example.com ; Note missing - example.com. 3600 IN NS ns2.example.com ; trailing dots - - The zone's authoritative servers will parse the NS RDATA as - "ns1.example.com.example.com" and "ns2.example.com.example.com" and - return NS records with this incorrect RDATA in responses, including - typically the authority section of every response containing records - from the "example.com" zone. - - Now consider a typical sequence of queries. An iterative resolver - attempting to resolve address records for "www.example.com" with no - cached information for this zone will query a "com" authoritative - server. The "com" server responds with a referral to the - "example.com" zone, consisting of NS records with valid RDATA and - associated glue records. (This example assumes that the - "example.com" zone delegation information is correct in the "com" - zone.) The iterative resolver caches the NS RRset from the "com" - server and follows the referral by querying one of the "example.com" - authoritative servers. This server responds with the - "www.example.com" address record in the answer section and, - typically, the "example.com" NS records in the authority section and, - if space in the message remains, glue address records in the - additional section. According to Section 5.4 of RFC 2181 [3], NS - records in the authority section of an authoritative answer are more - trustworthy than NS records from the authority section of a non- - authoritative answer. Thus the "example.com" NS RRset just received - from the "example.com" authoritative server overrides the - "example.com" NS RRset received moments ago from the "com" - - - -Larson & Barber Expires August 14, 2006 [Page 11] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - - authoritative server. - - But the "example.com" zone contains the erroneous NS RRset as shown - in the example above. Subsequent queries for names in "example.com" - will cause the iterative resolver to attempt to use the incorrect NS - records and so it will try to resolve the nonexistent names - "ns1.example.com.example.com" and "ns2.example.com.example.com". In - this example, since all of the zone's name servers are named in the - zone itself (i.e., "ns1.example.com.example.com" and - "ns2.example.com.example.com" both end in "example.com") and all are - bogus, the iterative resolver cannot reach any "example.com" name - servers. Therefore attempts to resolve these names result in address - record queries to the "com" authoritative servers. Queries for such - obviously bogus glue address records occur frequently at the com/net - name servers. - -2.6.1. Recommendation - - An authoritative server can detect this situation. A trailing dot - missing from an NS record's RDATA always results by definition in a - name server name that exists somewhere under the apex of the zone the - NS record appears in. Note that further levels of delegation are - possible, so a missing trailing dot could inadvertently create a name - server name that actually exists in a subzone. - - An authoritative name server SHOULD issue a warning when one of a - zone's NS records references a name server below the zone's apex when - a corresponding address record does not exist in the zone AND there - are no delegated subzones where the address record could exist. - -2.7. Name server records with zero TTL - - Sometimes a popular com/net subdomain's zone is configured with a TTL - of zero on the zone's NS records, which prohibits these records from - being cached and will result in a higher query volume to the zone's - authoritative servers. The zone's administrator should understand - the consequences of such a configuration and provision resources - accordingly. A zero TTL on the zone's NS RRset, however, carries - additional consequences beyond the zone itself: if an iterative - resolver cannot cache a zone's NS records because of a zero TTL, it - will be forced to query that zone's parent's name servers each time - it resolves a name in the zone. The com/net authoritative servers do - see an increased query load when a popular com/net subdomain's zone - is configured with a TTL of zero on the zone's NS records. - - A zero TTL on an RRset expected to change frequently is extreme but - permissible. A zone's NS RRset is a special case, however, because - changes to it must be coordinated with the zone's parent. In most - - - -Larson & Barber Expires August 14, 2006 [Page 12] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - - zone parent/child relationships we are aware of, there is typically - some delay involved in effecting changes. Further, changes to the - set of a zone's authoritative name servers (and therefore to the - zone's NS RRset) are typically relatively rare: providing reliable - authoritative service requires a reasonably stable set of servers. - Therefore an extremely low or zero TTL on a zone's NS RRset rarely - makes sense, except in anticipation of an upcoming change. In this - case, when the zone's administrator has planned a change and does not - want iterative resolvers throughout the Internet to cache the NS - RRset for a long period of time, a low TTL is reasonable. - -2.7.1. Recommendation - - Because of the additional load placed on a zone's parent's - authoritative servers resulting from a zero TTL on a zone's NS RRset, - under such circumstances authoritative name servers SHOULD issue a - warning when loading a zone. - -2.8. Unnecessary dynamic update messages - - The UPDATE message specified in RFC 2136 [6] allows an authorized - agent to update a zone's data on an authoritative name server using a - DNS message sent over the network. Consider the case of an agent - desiring to add a particular resource record. Because of zone cuts, - the agent does not necessarily know the proper zone to which the - record should be added. The dynamic update process requires that the - agent determine the appropriate zone so the UPDATE message can be - sent to one of the zone's authoritative servers (typically the - primary master as specified in the zone's SOA MNAME field). - - The appropriate zone to update is the closest enclosing zone, which - cannot be determined only by inspecting the domain name of the record - to be updated, since zone cuts can occur anywhere. One way to - determine the closest enclosing zone entails walking up the name - space tree by sending repeated UPDATE messages until success. For - example, consider an agent attempting to add an address record with - the name "foo.bar.example.com". The agent could first attempt to - update the "foo.bar.example.com" zone. If the attempt failed, the - update could be directed to the "bar.example.com" zone, then the - "example.com" zone, then the "com" zone, and finally the root zone. - - A popular dynamic agent follows this algorithm. The result is many - UPDATE messages received by the root name servers, the com/net - authoritative servers, and presumably other TLD authoritative - servers. A valid question is why the algorithm proceeds to send - updates all the way to TLD and root name servers. This behavior is - not entirely unreasonable: in enterprise DNS architectures with an - "internal root" design, there could conceivably be private, non- - - - -Larson & Barber Expires August 14, 2006 [Page 13] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - - public TLD or root zones that would be the appropriate targets for a - dynamic update. - - A significant deficiency with this algorithm is that knowledge of a - given UPDATE message's failure is not helpful in directing future - UPDATE messages to the appropriate servers. A better algorithm would - be to find the closest enclosing zone by walking up the name space - with queries for SOA or NS rather than "probing" with UPDATE - messages. Once the appropriate zone is found, an UPDATE message can - be sent. In addition, the results of these queries can be cached to - aid in determining closest enclosing zones for future updates. Once - the closest enclosing zone is determined with this method, the update - will either succeed or fail and there is no need to send further - updates to higher-level zones. The important point is that walking - up the tree with queries yields cacheable information, whereas - walking up the tree by sending UPDATE messages does not. - -2.8.1. Recommendation - - Dynamic update agents SHOULD send SOA or NS queries to progressively - higher-level names to find the closest enclosing zone for a given - name to update. Only after the appropriate zone is found should the - client send an UPDATE message to one of the zone's authoritative - servers. Update clients SHOULD NOT "probe" using UPDATE messages by - walking up the tree to progressively higher-level zones. - -2.9. Queries for domain names resembling IPv4 addresses - - The root name servers receive a significant number of A record - queries where the QNAME looks like an IPv4 address. The source of - these queries is unknown. It could be attributed to situations where - a user believes an application will accept either a domain name or an - IP address in a given configuration option. The user enters an IP - address, but the application assumes any input is a domain name and - attempts to resolve it, resulting in an A record lookup. There could - also be applications that produce such queries in a misguided attempt - to reverse map IP addresses. - - These queries result in Name Error (RCODE=3) responses. An iterative - resolver can negatively cache such responses, but each response - requires a separate cache entry, i.e., a negative cache entry for the - domain name "192.0.2.1" does not prevent a subsequent query for the - domain name "192.0.2.2". - -2.9.1. Recommendation - - It would be desirable for the root name servers not to have to answer - these queries: they unnecessarily consume CPU resources and network - - - -Larson & Barber Expires August 14, 2006 [Page 14] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - - bandwidth. A possible solution is to delegate these numeric TLDs - from the root zone to a separate set of servers to absorb the - traffic. The "black hole servers" used by the AS 112 Project [8], - which are currently delegated the in-addr.arpa zones corresponding to - RFC 1918 [7] private use address space, would be a possible choice to - receive these delegations. Of course, the proper and usual root zone - change procedures would have to be followed to make such a change to - the root zone. - -2.10. Misdirected recursive queries - - The root name servers receive a significant number of recursive - queries (i.e., queries with the RD bit set in the header). Since - none of the root servers offers recursion, the servers' response in - such a situation ignores the request for recursion and the response - probably does not contain the data the querier anticipated. Some of - these queries result from users configuring stub resolvers to query a - root server. (This situation is not hypothetical: we have received - complaints from users when this configuration does not work as - hoped.) Of course, users should not direct stub resolvers to use - name servers that do not offer recursion, but we are not aware of any - stub resolver implementation that offers any feedback to the user - when so configured, aside from simply "not working". - -2.10.1. Recommendation - - When the IP address of a name server that supposedly offers recursion - is configured in a stub resolver using an interactive user interface, - the resolver could send a test query to verify that the server indeed - supports recursion (i.e., verify that the response has the RA bit set - in the header). The user could be immediately notified if the server - is non-recursive. - - The stub resolver could also report an error, either through a user - interface or in a log file, if the queried server does not support - recursion. Error reporting SHOULD be throttled to avoid a - notification or log message for every response from a non-recursive - server. - -2.11. Suboptimal name server selection algorithm - - An entire document could be devoted to the topic of problems with - different implementations of the recursive resolution algorithm. The - entire process of recursion is woefully under specified, requiring - each implementor to design an algorithm. Sometimes implementors make - poor design choices that could be avoided if a suggested algorithm - and best practices were documented, but that is a topic for another - document. - - - -Larson & Barber Expires August 14, 2006 [Page 15] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - - Some deficiencies cause significant operational impact and are - therefore worth mentioning here. One of these is name server - selection by an iterative resolver. When an iterative resolver wants - to contact one of a zone's authoritative name servers, how does it - choose from the NS records listed in the zone's NS RRset? If the - selection mechanism is suboptimal, queries are not spread evenly - among a zone's authoritative servers. The details of the selection - mechanism are up to the implementor, but we offer some suggestions. - -2.11.1. Recommendation - - This list is not conclusive, but reflects the changes that would - produce the most impact in terms of reducing disproportionate query - load among a zone's authoritative servers. I.e., these changes would - help spread the query load evenly. - - o Do not make assumptions based on NS RRset order: all NS RRs SHOULD - be treated equally. (In the case of the "com" zone, for example, - most of the root servers return the NS record for "a.gtld- - servers.net" first in the authority section of referrals. - Apparently as a result, this server receives disproportionately - more traffic than the other 12 authoritative servers for "com".) - - o Use all NS records in an RRset. (For example, we are aware of - implementations that hard-coded information for a subset of the - root servers.) - - o Maintain state and favor the best-performing of a zone's - authoritative servers. A good definition of performance is - response time. Non-responsive servers can be penalized with an - extremely high response time. - - o Do not lock onto the best-performing of a zone's name servers. An - iterative resolver SHOULD periodically check the performance of - all of a zone's name servers to adjust its determination of the - best-performing one. - - - - - - - - - - - - - - - -Larson & Barber Expires August 14, 2006 [Page 16] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - -3. Acknowledgments - - The authors would like to thank the following people for their - comments that improved this document: Andras Salamon, Dave Meyer, - Doug Barton, Jaap Akkerhuis, Jinmei Tatuya, John Brady, Kevin Darcy, - Olafur Gudmundsson, Pekka Savola, Peter Koch and Rob Austein. We - apologize if we have omitted anyone; any oversight was unintentional. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Larson & Barber Expires August 14, 2006 [Page 17] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - -4. IANA considerations - - There are no new IANA considerations introduced by this memo. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Larson & Barber Expires August 14, 2006 [Page 18] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - -5. Security considerations - - The iterative resolver misbehavior discussed in this document exposes - the root and TLD name servers to increased risk of both intentional - and unintentional denial of service attacks. - - We believe that implementation of the recommendations offered in this - document will reduce the amount of unnecessary traffic seen at root - and TLD name servers, thus reducing the opportunity for an attacker - to use such queries to his or her advantage. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Larson & Barber Expires August 14, 2006 [Page 19] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - -6. Internationalization considerations - - There are no new internationalization considerations introduced by - this memo. - -7. Informative References - - [1] Bradner, S., "Key words for use in RFCs to Indicate Requirement - Levels", BCP 14, RFC 2119, March 1997. - - [2] Mockapetris, P., "Domain names - concepts and facilities", - STD 13, RFC 1034, November 1987. - - [3] Elz, R. and R. Bush, "Clarifications to the DNS Specification", - RFC 2181, July 1997. - - [4] Andrews, M., "Negative Caching of DNS Queries (DNS NCACHE)", - RFC 2308, March 1998. - - [5] Morishita, Y. and T. Jinmei, "Common Misbehavior Against DNS - Queries for IPv6 Addresses", RFC 4074, May 2005. - - [6] Vixie, P., Thomson, S., Rekhter, Y., and J. Bound, "Dynamic - Updates in the Domain Name System (DNS UPDATE)", RFC 2136, - April 1997. - - [7] Rekhter, Y., Moskowitz, R., Karrenberg, D., Groot, G., and E. - Lear, "Address Allocation for Private Internets", BCP 5, - RFC 1918, February 1996. - - [8] - - - - - - - - - - - - - - - - - - - - -Larson & Barber Expires August 14, 2006 [Page 20] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - -Authors' Addresses - - Matt Larson - VeriSign, Inc. - 21345 Ridgetop Circle - Dulles, VA 20166-6503 - USA - - Email: mlarson@verisign.com - - - Piet Barber - VeriSign, Inc. - 21345 Ridgetop Circle - Dulles, VA 20166-6503 - USA - - Email: pbarber@verisign.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Larson & Barber Expires August 14, 2006 [Page 21] - -Internet-Draft Observed DNS Resolution Misbehavior February 2006 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2006). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Larson & Barber Expires August 14, 2006 [Page 22] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsop-dnssec-operational-practices-08.txt b/contrib/bind9/doc/draft/draft-ietf-dnsop-dnssec-operational-practices-08.txt deleted file mode 100644 index 8ca68a8..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsop-dnssec-operational-practices-08.txt +++ /dev/null @@ -1,2016 +0,0 @@ - - - -DNSOP O. Kolkman -Internet-Draft R. Gieben -Obsoletes: 2541 (if approved) NLnet Labs -Expires: September 7, 2006 March 6, 2006 - - - DNSSEC Operational Practices - draft-ietf-dnsop-dnssec-operational-practices-08.txt - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on September 7, 2006. - -Copyright Notice - - Copyright (C) The Internet Society (2006). - -Abstract - - This document describes a set of practices for operating the DNS with - security extensions (DNSSEC). The target audience is zone - administrators deploying DNSSEC. - - The document discusses operational aspects of using keys and - signatures in the DNS. It discusses issues as key generation, key - storage, signature generation, key rollover and related policies. - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 1] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - This document obsoletes RFC 2541, as it covers more operational - ground and gives more up to date requirements with respect to key - sizes and the new DNSSEC specification. - - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4 - 1.1. The Use of the Term 'key' . . . . . . . . . . . . . . . . 4 - 1.2. Time Definitions . . . . . . . . . . . . . . . . . . . . . 5 - 2. Keeping the Chain of Trust Intact . . . . . . . . . . . . . . 5 - 3. Keys Generation and Storage . . . . . . . . . . . . . . . . . 6 - 3.1. Zone and Key Signing Keys . . . . . . . . . . . . . . . . 6 - 3.1.1. Motivations for the KSK and ZSK Separation . . . . . . 7 - 3.1.2. KSKs for High Level Zones . . . . . . . . . . . . . . 8 - 3.2. Key Generation . . . . . . . . . . . . . . . . . . . . . . 8 - 3.3. Key Effectivity Period . . . . . . . . . . . . . . . . . . 9 - 3.4. Key Algorithm . . . . . . . . . . . . . . . . . . . . . . 9 - 3.5. Key Sizes . . . . . . . . . . . . . . . . . . . . . . . . 10 - 3.6. Private Key Storage . . . . . . . . . . . . . . . . . . . 12 - 4. Signature generation, Key Rollover and Related Policies . . . 12 - 4.1. Time in DNSSEC . . . . . . . . . . . . . . . . . . . . . . 12 - 4.1.1. Time Considerations . . . . . . . . . . . . . . . . . 13 - 4.2. Key Rollovers . . . . . . . . . . . . . . . . . . . . . . 14 - 4.2.1. Zone Signing Key Rollovers . . . . . . . . . . . . . . 15 - 4.2.2. Key Signing Key Rollovers . . . . . . . . . . . . . . 19 - 4.2.3. Difference Between ZSK and KSK Rollovers . . . . . . . 20 - 4.2.4. Automated Key Rollovers . . . . . . . . . . . . . . . 21 - 4.3. Planning for Emergency Key Rollover . . . . . . . . . . . 22 - 4.3.1. KSK Compromise . . . . . . . . . . . . . . . . . . . . 22 - 4.3.2. ZSK Compromise . . . . . . . . . . . . . . . . . . . . 24 - 4.3.3. Compromises of Keys Anchored in Resolvers . . . . . . 24 - 4.4. Parental Policies . . . . . . . . . . . . . . . . . . . . 24 - 4.4.1. Initial Key Exchanges and Parental Policies - Considerations . . . . . . . . . . . . . . . . . . . . 24 - 4.4.2. Storing Keys or Hashes? . . . . . . . . . . . . . . . 25 - 4.4.3. Security Lameness . . . . . . . . . . . . . . . . . . 25 - 4.4.4. DS Signature Validity Period . . . . . . . . . . . . . 26 - 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 26 - 6. Security Considerations . . . . . . . . . . . . . . . . . . . 27 - 7. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 27 - 8. References . . . . . . . . . . . . . . . . . . . . . . . . . . 27 - 8.1. Normative References . . . . . . . . . . . . . . . . . . . 27 - 8.2. Informative References . . . . . . . . . . . . . . . . . . 28 - Appendix A. Terminology . . . . . . . . . . . . . . . . . . . . . 29 - Appendix B. Zone Signing Key Rollover Howto . . . . . . . . . . . 30 - Appendix C. Typographic Conventions . . . . . . . . . . . . . . . 31 - Appendix D. Document Details and Changes . . . . . . . . . . . . 33 - - - -Kolkman & Gieben Expires September 7, 2006 [Page 2] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - D.1. draft-ietf-dnsop-dnssec-operational-practices-00 . . . . . 33 - D.2. draft-ietf-dnsop-dnssec-operational-practices-01 . . . . . 33 - D.3. draft-ietf-dnsop-dnssec-operational-practices-02 . . . . . 33 - D.4. draft-ietf-dnsop-dnssec-operational-practices-03 . . . . . 33 - D.5. draft-ietf-dnsop-dnssec-operational-practices-04 . . . . . 34 - D.6. draft-ietf-dnsop-dnssec-operational-practices-05 . . . . . 34 - D.7. draft-ietf-dnsop-dnssec-operational-practices-06 . . . . . 34 - D.8. draft-ietf-dnsop-dnssec-operational-practices-07 . . . . . 34 - D.9. draft-ietf-dnsop-dnssec-operational-practices-08 . . . . . 34 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 35 - Intellectual Property and Copyright Statements . . . . . . . . . . 36 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 3] - -Internet-Draft DNSSEC Operational Practices March 2006 - - -1. Introduction - - This document describes how to run a DNSSEC (DNS SECure) enabled - environment. It is intended for operators who have knowledge of the - DNS (see RFC 1034 [1] and RFC 1035 [2]) and want deploy DNSSEC. See - RFC 4033 [4] for an introduction into DNSSEC and RFC 4034 [5] for the - newly introduced Resource Records and finally RFC 4035 [6] for the - protocol changes. - - During workshops and early operational deployment tests, operators - and system administrators have gained experience about operating the - DNS with security extensions (DNSSEC). This document translates - these experiences into a set of practices for zone administrators. - At the time of writing, there exists very little experience with - DNSSEC in production environments; this document should therefore - explicitly not be seen as representing 'Best Current Practices'. - - The procedures herein are focused on the maintenance of signed zones - (i.e. signing and publishing zones on authoritative servers). It is - intended that maintenance of zones such as re-signing or key - rollovers be transparent to any verifying clients on the Internet. - - The structure of this document is as follows. In Section 2 we - discuss the importance of keeping the "chain of trust" intact. - Aspects of key generation and storage of private keys are discussed - in Section 3; the focus in this section is mainly on the private part - of the key(s). Section 4 describes considerations concerning the - public part of the keys. Since these public keys appear in the DNS - one has to take into account all kinds of timing issues, which are - discussed in Section 4.1. Section 4.2 and Section 4.3 deal with the - rollover, or supercession, of keys. Finally Section 4.4 discusses - considerations on how parents deal with their children's public keys - in order to maintain chains of trust. - - The typographic conventions used in this document are explained in - Appendix C. - - Since this is a document with operational suggestions and there are - no protocol specifications, the RFC 2119 [9] language does not apply. - - This document obsoletes RFC 2541 [12]. - -1.1. The Use of the Term 'key' - - It is assumed that the reader is familiar with the concept of - asymmetric keys on which DNSSEC is based (Public Key Cryptography - [18]). Therefore, this document will use the term 'key' rather - loosely. Where it is written that 'a key is used to sign data' it is - - - -Kolkman & Gieben Expires September 7, 2006 [Page 4] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - assumed that the reader understands that it is the private part of - the key pair that is used for signing. It is also assumed that the - reader understands that the public part of the key pair is published - in the DNSKEY resource record and that it is the public part that is - used in key exchanges. - -1.2. Time Definitions - - In this document we will be using a number of time related terms. - The following definitions apply: - o "Signature validity period" - The period that a signature is valid. It starts at the time - specified in the signature inception field of the RRSIG RR and - ends at the time specified in the expiration field of the RRSIG - RR. - o "Signature publication period" - Time after which a signature (made with a specific key) is - replaced with a new signature (made with the same key). This - replacement takes place by publishing the relevant RRSIG in the - master zone file. - After one stops publishing an RRSIG in a zone it may take a - while before the RRSIG has expired from caches and has actually - been removed from the DNS. - o "Key effectivity period" - The period during which a key pair is expected to be effective. - This period is defined as the time between the first inception - time stamp and the last expiration date of any signature made - with this key, regardless of any discontinuity in the use of - the key. - The key effectivity period can span multiple signature validity - periods. - o "Maximum/Minimum Zone Time to Live (TTL)" - The maximum or minimum value of the TTLs from the complete set - of RRs in a zone. Note that the minimum TTL is not the same as - the MINIMUM field in the SOA RR. See [11] for more - information. - - -2. Keeping the Chain of Trust Intact - - Maintaining a valid chain of trust is important because broken chains - of trust will result in data being marked as Bogus (as defined in [4] - section 5), which may cause entire (sub)domains to become invisible - to verifying clients. The administrators of secured zones have to - realize that their zone is, to verifying clients, part of a chain of - trust. - - As mentioned in the introduction, the procedures herein are intended - - - -Kolkman & Gieben Expires September 7, 2006 [Page 5] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - to ensure that maintenance of zones, such as re-signing or key - rollovers, will be transparent to the verifying clients on the - Internet. - - Administrators of secured zones will have to keep in mind that data - published on an authoritative primary server will not be immediately - seen by verifying clients; it may take some time for the data to be - transferred to other secondary authoritative nameservers and clients - may be fetching data from caching non-authoritative servers. In this - light it is good to note that the time for a zone transfer from - master to slave is negligible when using NOTIFY [8] and IXFR [7], - increasing by reliance on AXFR, and more if you rely on the SOA - timing parameters for zone refresh. - - For the verifying clients it is important that data from secured - zones can be used to build chains of trust regardless of whether the - data came directly from an authoritative server, a caching nameserver - or some middle box. Only by carefully using the available timing - parameters can a zone administrator assure that the data necessary - for verification can be obtained. - - The responsibility for maintaining the chain of trust is shared by - administrators of secured zones in the chain of trust. This is most - obvious in the case of a 'key compromise' when a trade off between - maintaining a valid chain of trust and replacing the compromised keys - as soon as possible must be made. Then zone administrators will have - to make a trade off, between keeping the chain of trust intact - - thereby allowing for attacks with the compromised key - or to - deliberately break the chain of trust and making secured sub domains - invisible to security aware resolvers. Also see Section 4.3. - - -3. Keys Generation and Storage - - This section describes a number of considerations with respect to the - security of keys. It deals with the generation, effectivity period, - size and storage of private keys. - -3.1. Zone and Key Signing Keys - - The DNSSEC validation protocol does not distinguish between different - types of DNSKEYs. All DNSKEYs can be used during the validation. In - practice operators use Key Signing and Zone Signing Keys and use the - so-called (Secure Entry Point) SEP [3] flag to distinguish between - them during operations. The dynamics and considerations are - discussed below. - - To make zone re-signing and key rollover procedures easier to - - - -Kolkman & Gieben Expires September 7, 2006 [Page 6] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - implement, it is possible to use one or more keys as Key Signing Keys - (KSK). These keys will only sign the apex DNSKEY RRSet in a zone. - Other keys can be used to sign all the RRSets in a zone and are - referred to as Zone Signing Keys (ZSK). In this document we assume - that KSKs are the subset of keys that are used for key exchanges with - the parent and potentially for configuration as trusted anchors - the - SEP keys. In this document we assume a one-to-one mapping between - KSK and SEP keys and we assume the SEP flag to be set on all KSKs. - -3.1.1. Motivations for the KSK and ZSK Separation - - Differentiating between the KSK and ZSK functions has several - advantages: - - o No parent/child interaction is required when ZSKs are updated. - o The KSK can be made stronger (i.e. using more bits in the key - material). This has little operational impact since it is only - used to sign a small fraction of the zone data. Also the KSK is - only used to verify the zone's key set, not for other RRSets in - the zone. - o As the KSK is only used to sign a key set, which is most probably - updated less frequently than other data in the zone, it can be - stored separately from and in a safer location than the ZSK. - o A KSK can have a longer key effectivity period. - - For almost any method of key management and zone signing the KSK is - used less frequently than the ZSK. Once a key set is signed with the - KSK all the keys in the key set can be used as ZSK. If a ZSK is - compromised, it can be simply dropped from the key set. The new key - set is then re-signed with the KSK. - - Given the assumption that for KSKs the SEP flag is set, the KSK can - be distinguished from a ZSK by examining the flag field in the DNSKEY - RR. If the flag field is an odd number it is a KSK. If it is an - even number it is a ZSK. - - The zone signing key can be used to sign all the data in a zone on a - regular basis. When a zone signing key is to be rolled, no - interaction with the parent is needed. This allows for "Signature - Validity Periods" on the order of days. - - The key signing key is only to be used to sign the DNSKEY RRs in a - zone. If a key signing key is to be rolled over, there will be - interactions with parties other than the zone administrator. These - can include the registry of the parent zone or administrators of - verifying resolvers that have the particular key configured as secure - entry points. Hence, the key effectivity period of these keys can - and should be made much longer. Although, given a long enough key, - - - -Kolkman & Gieben Expires September 7, 2006 [Page 7] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - the Key Effectivity Period can be on the order of years we suggest - planning for a key effectivity of the order of a few months so that a - key rollover remains an operational routine. - -3.1.2. KSKs for High Level Zones - - Higher level zones are generally more sensitive than lower level - zones. Anyone controlling or breaking the security of a zone thereby - obtains authority over all of its sub domains (except in the case of - resolvers that have locally configured the public key of a sub - domain, in which case this, and only this, sub domain wouldn't be - affected by the compromise of the parent zone). Therefore, extra - care should be taken with high level zones and strong keys should - used. - - The root zone is the most critical of all zones. Someone controlling - or compromising the security of the root zone would control the - entire DNS name space of all resolvers using that root zone (except - in the case of resolvers that have locally configured the public key - of a sub domain). Therefore, the utmost care must be taken in the - securing of the root zone. The strongest and most carefully handled - keys should be used. The root zone private key should always be kept - off line. - - Many resolvers will start at a root server for their access to and - authentication of DNS data. Securely updating the trust anchors in - an enormous population of resolvers around the world will be - extremely difficult. - -3.2. Key Generation - - Careful generation of all keys is a sometimes overlooked but - absolutely essential element in any cryptographically secure system. - The strongest algorithms used with the longest keys are still of no - use if an adversary can guess enough to lower the size of the likely - key space so that it can be exhaustively searched. Technical - suggestions for the generation of random keys will be found in RFC - 4086 [15]. One should carefully assess if the random number - generator used during key generation adheres to these suggestions. - - Keys with a long effectivity period are particularly sensitive as - they will represent a more valuable target and be subject to attack - for a longer time than short period keys. It is strongly recommended - that long term key generation occur off-line in a manner isolated - from the network via an air gap or, at a minimum, high level secure - hardware. - - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 8] - -Internet-Draft DNSSEC Operational Practices March 2006 - - -3.3. Key Effectivity Period - - For various reasons keys in DNSSEC need to be changed once in a - while. The longer a key is in use, the greater the probability that - it will have been compromised through carelessness, accident, - espionage, or cryptanalysis. Furthermore when key rollovers are too - rare an event, they will not become part of the operational habit and - there is risk that nobody on-site will remember the procedure for - rollover when the need is there. - - From a purely operational perspective a reasonable key effectivity - period for Key Signing Keys is 13 months, with the intent to replace - them after 12 months. An intended key effectivity period of a month - is reasonable for Zone Signing Keys. - - For key sizes that matches these effectivity periods see Section 3.5. - - As argued in Section 3.1.2 securely updating trust anchors will be - extremely difficult. On the other hand the "operational habit" - argument does also apply to trust anchor reconfiguration. If a short - key-effectivity period is used and the trust anchor configuration has - to be revisited on a regular basis the odds that the configuration - tends to be forgotten is smaller. The trade-off is against a system - that is so dynamic that administrators of the validating clients will - not be able to follow the modifications. - - Key effectivity periods can be made very short, as in the order of a - few minutes. But when replacing keys one has to take the - considerations from Section 4.1 and Section 4.2 into account. - -3.4. Key Algorithm - - There are currently three different types of algorithms that can be - used in DNSSEC: RSA, DSA and elliptic curve cryptography. The latter - is fairly new and has yet to be standardized for usage in DNSSEC. - - RSA has been developed in an open and transparent manner. As the - patent on RSA expired in 2000, its use is now also free. - - DSA has been developed by NIST. The creation of signatures takes - roughly the same time as with RSA, but is 10 to 40 times as slow for - verification [18]. - - We suggest the use of RSA/SHA-1 as the preferred algorithm for the - key. The current known attacks on RSA can be defeated by making your - key longer. As the MD5 hashing algorithm is showing (theoretical) - cracks, we recommend the usage of SHA-1. - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 9] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - At the time of publication it is known that the SHA-1 hash has - cryptanalysis issues. There is work in progress on addressing these - issues. We recommend the use of public key algorithms based on - hashes stronger than SHA-1, e.g. SHA-256, as soon as these - algorithms are available in protocol specifications (See [20] and - [21] ) and implementations. - -3.5. Key Sizes - - When choosing key sizes, zone administrators will need to take into - account how long a key will be used, how much data will be signed - during the key publication period (See Section 8.10 of [18]) and, - optionally, how large the key size of the parent is. As the chain of - trust really is "a chain", there is not much sense in making one of - the keys in the chain several times larger then the others. As - always, it's the weakest link that defines the strength of the entire - chain. Also see Section 3.1.1 for a discussion of how keys serving - different roles (ZSK v. KSK) may need different key sizes. - - Generating a key of the correct size is a difficult problem, RFC 3766 - [14] tries to deal with that problem. The first part of the - selection procedure in Section 1 of the RFC states: - - 1. Determine the attack resistance necessary to satisfy the - security requirements of the application. Do this by - estimating the minimum number of computer operations that - the attacker will be forced to do in order to compromise - the security of the system and then take the logarithm base - two of that number. Call that logarithm value "n". - - A 1996 report recommended 90 bits as a good all-around choice - for system security. The 90 bit number should be increased - by about 2/3 bit/year, or about 96 bits in 2005. - - [14] goes on to explain how this number "n" can be used to calculate - the key sizes in public key cryptography. This culminated in the - table given below (slightly modified for our purpose): - - - - - - - - - - - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 10] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - +-------------+-----------+--------------+ - | System | | | - | requirement | Symmetric | RSA or DSA | - | for attack | key size | modulus size | - | resistance | (bits) | (bits) | - | (bits) | | | - +-------------+-----------+--------------+ - | 70 | 70 | 947 | - | 80 | 80 | 1228 | - | 90 | 90 | 1553 | - | 100 | 100 | 1926 | - | 150 | 150 | 4575 | - | 200 | 200 | 8719 | - | 250 | 250 | 14596 | - +-------------+-----------+--------------+ - - The key sizes given are rather large. This is because these keys are - resilient against a trillionaire attacker. Assuming this rich - attacker will not attack your key and that the key is rolled over - once a year, we come to the following recommendations about KSK - sizes; 1024 bits low value domains, 1300 for medium value and 2048 - for the high value domains. - - Whether a domain is of low, medium, high value depends solely on the - views of the zone owner. One could for instance view leaf nodes in - the DNS as of low value and TLDs or the root zone of high value. The - suggested key sizes should be safe for the next 5 years. - - As ZSKs can be rolled over more easily (and thus more often) the key - sizes can be made smaller. But as said in the introduction of this - paragraph, making the ZSKs' key sizes too small (in relation to the - KSKs' sizes) doesn't make much sense. Try to limit the difference in - size to about 100 bits. - - Note that nobody can see into the future, and that these key sizes - are only provided here as a guide. Further information can be found - in [17] and Section 7.5 of [18]. It should be noted though that [17] - is already considered overly optimistic about what key sizes are - considered safe. - - One final note concerning key sizes. Larger keys will increase the - sizes of the RRSIG and DNSKEY records and will therefore increase the - chance of DNS UDP packet overflow. Also the time it takes to - validate and create RRSIGs increases with larger keys, so don't - needlessly double your key sizes. - - - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 11] - -Internet-Draft DNSSEC Operational Practices March 2006 - - -3.6. Private Key Storage - - It is recommended that, where possible, zone private keys and the - zone file master copy that is to be signed, be kept and used in off- - line, non-network connected, physically secure machines only. - Periodically an application can be run to add authentication to a - zone by adding RRSIG and NSEC RRs. Then the augmented file can be - transferred. - - When relying on dynamic update to manage a signed zone [10], be aware - that at least one private key of the zone will have to reside on the - master server. This key is only as secure as the amount of exposure - the server receives to unknown clients and the security of the host. - Although not mandatory one could administer the DNS in the following - way. The master that processes the dynamic updates is unavailable - from generic hosts on the Internet, it is not listed in the NS RR - set, although its name appears in the SOA RRs MNAME field. The - nameservers in the NS RR set are able to receive zone updates through - NOTIFY, IXFR, AXFR or an out-of-band distribution mechanism. This - approach is known as the "hidden master" setup. - - The ideal situation is to have a one way information flow to the - network to avoid the possibility of tampering from the network. - Keeping the zone master file on-line on the network and simply - cycling it through an off-line signer does not do this. The on-line - version could still be tampered with if the host it resides on is - compromised. For maximum security, the master copy of the zone file - should be off net and should not be updated based on an unsecured - network mediated communication. - - In general keeping a zone-file off-line will not be practical and the - machines on which zone files are maintained will be connected to a - network. Operators are advised to take security measures to shield - unauthorized access to the master copy. - - For dynamically updated secured zones [10] both the master copy and - the private key that is used to update signatures on updated RRs will - need to be on-line. - - -4. Signature generation, Key Rollover and Related Policies - -4.1. Time in DNSSEC - - Without DNSSEC all times in DNS are relative. The SOA fields - REFRESH, RETRY and EXPIRATION are timers used to determine the time - elapsed after a slave server synchronized with a master server. The - Time to Live (TTL) value and the SOA RR minimum TTL parameter [11] - - - -Kolkman & Gieben Expires September 7, 2006 [Page 12] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - are used to determine how long a forwarder should cache data after it - has been fetched from an authoritative server. By using a signature - validity period, DNSSEC introduces the notion of an absolute time in - the DNS. Signatures in DNSSEC have an expiration date after which - the signature is marked as invalid and the signed data is to be - considered Bogus. - -4.1.1. Time Considerations - - Because of the expiration of signatures, one should consider the - following: - o We suggest the Maximum Zone TTL of your zone data to be a fraction - of your signature validity period. - If the TTL would be of similar order as the signature validity - period, then all RRSets fetched during the validity period - would be cached until the signature expiration time. Section - 7.1 of [4] suggests that "the resolver may use the time - remaining before expiration of the signature validity period of - a signed RRSet as an upper bound for the TTL". As a result - query load on authoritative servers would peak at signature - expiration time, as this is also the time at which records - simultaneously expire from caches. - To avoid query load peaks we suggest the TTL on all the RRs in - your zone to be at least a few times smaller than your - signature validity period. - o We suggest the Signature Publication Period to end at least one - Maximum Zone TTL duration before the end of the Signature Validity - Period. - Re-signing a zone shortly before the end of the signature - validity period may cause simultaneous expiration of data from - caches. This in turn may lead to peaks in the load on - authoritative servers. - o We suggest the minimum zone TTL to be long enough to both fetch - and verify all the RRs in the trust chain. In workshop - environments it has been demonstrated [19] that a low TTL (under 5 - to 10 minutes) caused disruptions because of the following two - problems: - 1. During validation, some data may expire before the - validation is complete. The validator should be able to keep - all data, until is completed. This applies to all RRs needed - to complete the chain of trust: DSs, DNSKEYs, RRSIGs, and the - final answers i.e. the RRSet that is returned for the initial - query. - 2. Frequent verification causes load on recursive nameservers. - Data at delegation points, DSs, DNSKEYs and RRSIGs benefit from - caching. The TTL on those should be relatively long. - - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 13] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - o Slave servers will need to be able to fetch newly signed zones - well before the RRSIGs in the zone served by the slave server pass - their signature expiration time. - When a slave server is out of sync with its master and data in - a zone is signed by expired signatures it may be better for the - slave server not to give out any answer. - Normally a slave server that is not able to contact a master - server for an extended period will expire a zone. When that - happens the server will respond differently to queries for that - zone. Some servers issue SERVFAIL while others turn off the - 'AA' bit in the answers. The time of expiration is set in the - SOA record and is relative to the last successful refresh - between the master and the slave server. There exists no - coupling between the signature expiration of RRSIGs in the zone - and the expire parameter in the SOA. - If the server serves a DNSSEC zone then it may well happen that - the signatures expire well before the SOA expiration timer - counts down to zero. It is not possible to completely prevent - this from happening by tweaking the SOA parameters. - However, the effects can be minimized where the SOA expiration - time is equal or shorter than the signature validity period. - The consequence of an authoritative server not being able to - update a zone, whilst that zone includes expired signatures, is - that non-secure resolvers will continue to be able to resolve - data served by the particular slave servers while security - aware resolvers will experience problems because of answers - being marked as Bogus. - We suggest the SOA expiration timer being approximately one - third or one fourth of the signature validity period. It will - allow problems with transfers from the master server to be - noticed before the actual signature times out. - We also suggest that operators of nameservers that supply - secondary services develop 'watch dogs' to spot upcoming - signature expirations in zones they slave, and take appropriate - action. - When determining the value for the expiration parameter one has - to take the following into account: What are the chances that - all my secondaries expire the zone; How quickly can I reach an - administrator of secondary servers to load a valid zone? All - these arguments are not DNSSEC specific but may influence the - choice of your signature validity intervals. - -4.2. Key Rollovers - - A DNSSEC key cannot be used forever (see Section 3.3). So key - rollovers -- or supercessions, as they are sometimes called -- are a - fact of life when using DNSSEC. Zone administrators who are in the - process of rolling their keys have to take into account that data - - - -Kolkman & Gieben Expires September 7, 2006 [Page 14] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - published in previous versions of their zone still lives in caches. - When deploying DNSSEC, this becomes an important consideration; - ignoring data that may be in caches may lead to loss of service for - clients. - - The most pressing example of this occurs when zone material signed - with an old key is being validated by a resolver which does not have - the old zone key cached. If the old key is no longer present in the - current zone, this validation fails, marking the data Bogus. - Alternatively, an attempt could be made to validate data which is - signed with a new key against an old key that lives in a local cache, - also resulting in data being marked Bogus. - -4.2.1. Zone Signing Key Rollovers - - For zone signing key rollovers there are two ways to make sure that - during the rollover data still cached can be verified with the new - key sets or newly generated signatures can be verified with the keys - still in caches. One schema, described in Section 4.2.1.2, uses - double signatures; the other uses key pre-publication - (Section 4.2.1.1). The pros, cons and recommendations are described - in Section 4.2.1.3. - -4.2.1.1. Pre-publish Key Rollover - - This section shows how to perform a ZSK rollover without the need to - sign all the data in a zone twice - the so-called "pre-publish - rollover".This method has advantages in the case of a key compromise. - If the old key is compromised, the new key has already been - distributed in the DNS. The zone administrator is then able to - quickly switch to the new key and remove the compromised key from the - zone. Another major advantage is that the zone size does not double, - as is the case with the double signature ZSK rollover. A small - "HOWTO" for this kind of rollover can be found in Appendix B. - - Pre-publish Key Rollover involves four stages as follows: - - initial new DNSKEY new RRSIGs DNSKEY removal - - SOA0 SOA1 SOA2 SOA3 - RRSIG10(SOA0) RRSIG10(SOA1) RRSIG11(SOA2) RRSIG11(SOA3) - - DNSKEY1 DNSKEY1 DNSKEY1 DNSKEY1 - DNSKEY10 DNSKEY10 DNSKEY10 DNSKEY11 - DNSKEY11 DNSKEY11 - RRSIG1 (DNSKEY) RRSIG1 (DNSKEY) RRSIG1(DNSKEY) RRSIG1 (DNSKEY) - RRSIG10(DNSKEY) RRSIG10(DNSKEY) RRSIG11(DNSKEY) RRSIG11(DNSKEY) - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 15] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - initial: Initial version of the zone: DNSKEY 1 is the key signing - key. DNSKEY 10 is used to sign all the data of the zone, the zone - signing key. - new DNSKEY: DNSKEY 11 is introduced into the key set. Note that no - signatures are generated with this key yet, but this does not - secure against brute force attacks on the public key. The minimum - duration of this pre-roll phase is the time it takes for the data - to propagate to the authoritative servers plus TTL value of the - key set. - new RRSIGs: At the "new RRSIGs" stage (SOA serial 2) DNSKEY 11 is - used to sign the data in the zone exclusively (i.e. all the - signatures from DNSKEY 10 are removed from the zone). DNSKEY 10 - remains published in the key set. This way data that was loaded - into caches from version 1 of the zone can still be verified with - key sets fetched from version 2 of the zone. - The minimum time that the key set including DNSKEY 10 is to be - published is the time that it takes for zone data from the - previous version of the zone to expire from old caches i.e. the - time it takes for this zone to propagate to all authoritative - servers plus the Maximum Zone TTL value of any of the data in the - previous version of the zone. - DNSKEY removal: DNSKEY 10 is removed from the zone. The key set, now - only containing DNSKEY 1 and DNSKEY 11 is re-signed with the - DNSKEY 1. - - The above scheme can be simplified by always publishing the "future" - key immediately after the rollover. The scheme would look as follows - (we show two rollovers); the future key is introduced in "new DNSKEY" - as DNSKEY 12 and again a newer one, numbered 13, in "new DNSKEY - (II)": - - - - - - - - - - - - - - - - - - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 16] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - initial new RRSIGs new DNSKEY - - SOA0 SOA1 SOA2 - RRSIG10(SOA0) RRSIG11(SOA1) RRSIG11(SOA2) - - DNSKEY1 DNSKEY1 DNSKEY1 - DNSKEY10 DNSKEY10 DNSKEY11 - DNSKEY11 DNSKEY11 DNSKEY12 - RRSIG1(DNSKEY) RRSIG1 (DNSKEY) RRSIG1(DNSKEY) - RRSIG10(DNSKEY) RRSIG11(DNSKEY) RRSIG11(DNSKEY) - - - new RRSIGs (II) new DNSKEY (II) - - SOA3 SOA4 - RRSIG12(SOA3) RRSIG12(SOA4) - - DNSKEY1 DNSKEY1 - DNSKEY11 DNSKEY12 - DNSKEY12 DNSKEY13 - RRSIG1(DNSKEY) RRSIG1(DNSKEY) - RRSIG12(DNSKEY) RRSIG12(DNSKEY) - - - Pre-Publish Key Rollover, showing two rollovers. - - Note that the key introduced in the "new DNSKEY" phase is not used - for production yet; the private key can thus be stored in a - physically secure manner and does not need to be 'fetched' every time - a zone needs to be signed. - -4.2.1.2. Double Signature Zone Signing Key Rollover - - This section shows how to perform a ZSK key rollover using the double - zone data signature scheme, aptly named "double sig rollover". - - During the "new DNSKEY" stage the new version of the zone file will - need to propagate to all authoritative servers and the data that - exists in (distant) caches will need to expire, requiring at least - the maximum Zone TTL. - - - - - - - - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 17] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - Double Signature Zone Signing Key Rollover involves three stages as - follows: - - initial new DNSKEY DNSKEY removal - - SOA0 SOA1 SOA2 - RRSIG10(SOA0) RRSIG10(SOA1) RRSIG11(SOA2) - RRSIG11(SOA1) - - DNSKEY1 DNSKEY1 DNSKEY1 - DNSKEY10 DNSKEY10 DNSKEY11 - DNSKEY11 - RRSIG1(DNSKEY) RRSIG1(DNSKEY) RRSIG1(DNSKEY) - RRSIG10(DNSKEY) RRSIG10(DNSKEY) RRSIG11(DNSKEY) - RRSIG11(DNSKEY) - - initial: Initial Version of the zone: DNSKEY 1 is the key signing - key. DNSKEY 10 is used to sign all the data of the zone, the zone - signing key. - new DNSKEY: At the "New DNSKEY" stage (SOA serial 1) DNSKEY 11 is - introduced into the key set and all the data in the zone is signed - with DNSKEY 10 and DNSKEY 11. The rollover period will need to - continue until all data from version 0 of the zone has expired - from remote caches. This will take at least the maximum Zone TTL - of version 0 of the zone. - DNSKEY removal: DNSKEY 10 is removed from the zone. All the - signatures from DNSKEY 10 are removed from the zone. The key set, - now only containing DNSKEY 11, is re-signed with DNSKEY 1. - - At every instance, RRSIGs from the previous version of the zone can - be verified with the DNSKEY RRSet from the current version and the - other way around. The data from the current version can be verified - with the data from the previous version of the zone. The duration of - the "new DNSKEY" phase and the period between rollovers should be at - least the Maximum Zone TTL. - - Making sure that the "new DNSKEY" phase lasts until the signature - expiration time of the data in initial version of the zone is - recommended. This way all caches are cleared of the old signatures. - However, this duration could be considerably longer than the Maximum - Zone TTL, making the rollover a lengthy procedure. - - Note that in this example we assumed that the zone was not modified - during the rollover. New data can be introduced in the zone as long - as it is signed with both keys. - - - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 18] - -Internet-Draft DNSSEC Operational Practices March 2006 - - -4.2.1.3. Pros and Cons of the Schemes - - Pre-publish Key Rollover: This rollover does not involve signing the - zone data twice. Instead, before the actual rollover, the new key - is published in the key set and thus available for cryptanalysis - attacks. A small disadvantage is that this process requires four - steps. Also the pre-publish scheme involves more parental work - when used for KSK rollovers as explained in Section 4.2.3. - Double Signature Zone-signing Key Rollover: The drawback of this - signing scheme is that during the rollover the number of - signatures in your zone doubles, this may be prohibitive if you - have very big zones. An advantage is that it only requires three - steps. - -4.2.2. Key Signing Key Rollovers - - For the rollover of a key signing key the same considerations as for - the rollover of a zone signing key apply. However we can use a - double signature scheme to guarantee that old data (only the apex key - set) in caches can be verified with a new key set and vice versa. - Since only the key set is signed with a KSK, zone size considerations - do not apply. - - - initial new DNSKEY DS change DNSKEY removal - Parent: - SOA0 --------> SOA1 --------> - RRSIGpar(SOA0) --------> RRSIGpar(SOA1) --------> - DS1 --------> DS2 --------> - RRSIGpar(DS) --------> RRSIGpar(DS) --------> - - - Child: - SOA0 SOA1 --------> SOA2 - RRSIG10(SOA0) RRSIG10(SOA1) --------> RRSIG10(SOA2) - --------> - DNSKEY1 DNSKEY1 --------> DNSKEY2 - DNSKEY2 --------> - DNSKEY10 DNSKEY10 --------> DNSKEY10 - RRSIG1 (DNSKEY) RRSIG1 (DNSKEY) --------> RRSIG2 (DNSKEY) - RRSIG2 (DNSKEY) --------> - RRSIG10(DNSKEY) RRSIG10(DNSKEY) --------> RRSIG10(DNSKEY) - - Stages of Deployment for Key Signing Key Rollover. - - - - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 19] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - initial: Initial version of the zone. The parental DS points to - DNSKEY1. Before the rollover starts the child will have to verify - what the TTL is of the DS RR that points to DNSKEY1 - it is needed - during the rollover and we refer to the value as TTL_DS. - new DNSKEY: During the "new DNSKEY" phase the zone administrator - generates a second KSK, DNSKEY2. The key is provided to the - parent and the child will have to wait until a new DS RR has been - generated that points to DNSKEY2. After that DS RR has been - published on all servers authoritative for the parent's zone, the - zone administrator has to wait at least TTL_DS to make sure that - the old DS RR has expired from caches. - DS change: The parent replaces DS1 with DS2. - DNSKEY removal: DNSKEY1 has been removed. - - The scenario above puts the responsibility for maintaining a valid - chain of trust with the child. It also is based on the premises that - the parent only has one DS RR (per algorithm) per zone. An - alternative mechanism has been considered. Using an established - trust relation, the interaction can be performed in-band, and the - removal of the keys by the child can possibly be signaled by the - parent. In this mechanism there are periods where there are two DS - RRs at the parent. Since at the moment of writing the protocol for - this interaction has not been developed, further discussion is out of - scope for this document. - -4.2.3. Difference Between ZSK and KSK Rollovers - - Note that KSK rollovers and ZSK rollovers are different in the sense - that a KSK rollover requires interaction with the parent (and - possibly replacing of trust anchors) and the ensuing delay while - waiting for it. - - A zone key rollover can be handled in two different ways: pre-publish - (Section Section 4.2.1.1) and double signature (Section - Section 4.2.1.2). - - As the KSK is used to validate the key set and because the KSK is not - changed during a ZSK rollover, a cache is able to validate the new - key set of the zone. The pre-publish method would also work for a - KSK rollover. The records that are to be pre-published are the - parental DS RRs. The pre-publish method has some drawbacks for KSKs. - We first describe the rollover scheme and then indicate these - drawbacks. - - - - - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 20] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - initial new DS new DNSKEY DS/DNSKEY removal - Parent: - SOA0 SOA1 --------> SOA2 - RRSIGpar(SOA0) RRSIGpar(SOA1) --------> RRSIGpar(SOA2) - DS1 DS1 --------> DS2 - DS2 --------> - RRSIGpar(DS) RRSIGpar(DS) --------> RRSIGpar(DS) - - - - Child: - SOA0 --------> SOA1 SOA1 - RRSIG10(SOA0) --------> RRSIG10(SOA1) RRSIG10(SOA1) - --------> - DNSKEY1 --------> DNSKEY2 DNSKEY2 - --------> - DNSKEY10 --------> DNSKEY10 DNSKEY10 - RRSIG1 (DNSKEY) --------> RRSIG2(DNSKEY) RRSIG2 (DNSKEY) - RRSIG10(DNSKEY) --------> RRSIG10(DNSKEY) RRSIG10(DNSKEY) - - Stages of Deployment for a Pre-publish Key Signing Key rollover. - - When the child zone wants to roll it notifies the parent during the - "new DS" phase and submits the new key (or the corresponding DS) to - the parent. The parent publishes DS1 and DS2, pointing to DNSKEY1 - and DNSKEY2 respectively. During the rollover ("new DNSKEY" phase), - which can take place as soon as the new DS set propagated through the - DNS, the child replaces DNSKEY1 with DNSKEY2. Immediately after that - ("DS/DNSKEY removal" phase) it can notify the parent that the old DS - record can be deleted. - - The drawbacks of this scheme are that during the "new DS" phase the - parent cannot verify the match between the DS2 RR and DNSKEY2 using - the DNS -- as DNSKEY2 is not yet published. Besides, we introduce a - "security lame" key (See Section 4.4.3). Finally the child-parent - interaction consists of two steps. The "double signature" method - only needs one interaction. - -4.2.4. Automated Key Rollovers - - As keys must be renewed periodically, there is some motivation to - automate the rollover process. Consider that: - - o ZSK rollovers are easy to automate as only the child zone is - involved. - o A KSK rollover needs interaction between parent and child. Data - exchange is needed to provide the new keys to the parent, - consequently, this data must be authenticated and integrity must - - - -Kolkman & Gieben Expires September 7, 2006 [Page 21] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - be guaranteed in order to avoid attacks on the rollover. - -4.3. Planning for Emergency Key Rollover - - This section deals with preparation for a possible key compromise. - Our advice is to have a documented procedure ready for when a key - compromise is suspected or confirmed. - - When the private material of one of your keys is compromised it can - be used for as long as a valid trust chain exists. A trust chain - remains intact for: - o as long as a signature over the compromised key in the trust chain - is valid, - o as long as a parental DS RR (and signature) points to the - compromised key, - o as long as the key is anchored in a resolver and is used as a - starting point for validation (this is generally the hardest to - update). - - While a trust chain to your compromised key exists, your name-space - is vulnerable to abuse by anyone who has obtained illegitimate - possession of the key. Zone operators have to make a trade off if - the abuse of the compromised key is worse than having data in caches - that cannot be validated. If the zone operator chooses to break the - trust chain to the compromised key, data in caches signed with this - key cannot be validated. However, if the zone administrator chooses - to take the path of a regular roll-over, the malicious key holder can - spoof data so that it appears to be valid. - -4.3.1. KSK Compromise - - A zone containing a DNSKEY RRSet with a compromised KSK is vulnerable - as long as the compromised KSK is configured as trust anchor or a - parental DS points to it. - - A compromised KSK can be used to sign the key set of an attacker's - zone. That zone could be used to poison the DNS. - - Therefore when the KSK has been compromised, the trust anchor or the - parental DS, should be replaced as soon as possible. It is local - policy whether to break the trust chain during the emergency - rollover. The trust chain would be broken when the compromised KSK - is removed from the child's zone while the parent still has a DS - pointing to the compromised KSK (the assumption is that there is only - one DS at the parent. If there are multiple DSs this does not apply - -- however the chain of trust of this particular key is broken). - - Note that an attacker's zone still uses the compromised KSK and the - - - -Kolkman & Gieben Expires September 7, 2006 [Page 22] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - presence of a parental DS would cause the data in this zone to appear - as valid. Removing the compromised key would cause the attacker's - zone to appear as valid and the child's zone as Bogus. Therefore we - advise not to remove the KSK before the parent has a DS to a new KSK - in place. - -4.3.1.1. Keeping the Chain of Trust Intact - - If we follow this advice the timing of the replacement of the KSK is - somewhat critical. The goal is to remove the compromised KSK as soon - as the new DS RR is available at the parent. And also make sure that - the signature made with a new KSK over the key set with the - compromised KSK in it expires just after the new DS appears at the - parent. Thus removing the old cruft in one swoop. - - The procedure is as follows: - 1. Introduce a new KSK into the key set, keep the compromised KSK in - the key set. - 2. Sign the key set, with a short validity period. The validity - period should expire shortly after the DS is expected to appear - in the parent and the old DSs have expired from caches. - 3. Upload the DS for this new key to the parent. - 4. Follow the procedure of the regular KSK rollover: Wait for the DS - to appear in the authoritative servers and then wait as long as - the TTL of the old DS RRs. If necessary re-sign the DNSKEY RRSet - and modify/extend the expiration time. - 5. Remove the compromised DNSKEY RR from the zone and re-sign the - key set using your "normal" validity interval. - - An additional danger of a key compromise is that the compromised key - could be used to facilitate a legitimate DNSKEY/DS rollover and/or - nameserver changes at the parent. When that happens the domain may - be in dispute. An authenticated out-of-band and secure notify - mechanism to contact a parent is needed in this case. - - Note that this is only a problem when the DNSKEY and or DS records - are used for authentication at the parent. - -4.3.1.2. Breaking the Chain of Trust - - There are two methods to break the chain of trust. The first method - causes the child zone to appear as 'Bogus' to validating resolvers. - The other causes the the child zone to appear as 'insecure'. These - are described below. - - In the method that causes the child zone to appear as 'Bogus' to - validating resolvers, the child zone replaces the current KSK with a - new one and resigns the key set. Next it sends the DS of the new key - - - -Kolkman & Gieben Expires September 7, 2006 [Page 23] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - to the parent. Only after the parent has placed the new DS in the - zone, the child's chain of trust is repaired. - - An alternative method of breaking the chain of trust is by removing - the DS RRs from the parent zone altogether. As a result the child - zone would become insecure. - -4.3.2. ZSK Compromise - - Primarily because there is no parental interaction required when a - ZSK is compromised, the situation is less severe than with a KSK - compromise. The zone must still be re-signed with a new ZSK as soon - as possible. As this is a local operation and requires no - communication between the parent and child this can be achieved - fairly quickly. However, one has to take into account that just as - with a normal rollover the immediate disappearance of the old - compromised key may lead to verification problems. Also note that as - long as the RRSIG over the compromised ZSK is not expired the zone - may be still at risk. - -4.3.3. Compromises of Keys Anchored in Resolvers - - A key can also be pre-configured in resolvers. For instance, if - DNSSEC is successfully deployed the root key may be pre-configured in - most security aware resolvers. - - If trust-anchor keys are compromised, the resolvers using these keys - should be notified of this fact. Zone administrators may consider - setting up a mailing list to communicate the fact that a SEP key is - about to be rolled over. This communication will of course need to - be authenticated e.g. by using digital signatures. - - End-users faced with the task of updating an anchored key should - always validate the new key. New keys should be authenticated out- - of-band, for example, looking them up on an SSL secured announcement - website. - -4.4. Parental Policies - -4.4.1. Initial Key Exchanges and Parental Policies Considerations - - The initial key exchange is always subject to the policies set by the - parent. When designing a key exchange policy one should take into - account that the authentication and authorization mechanisms used - during a key exchange should be as strong as the authentication and - authorization mechanisms used for the exchange of delegation - information between parent and child. I.e. there is no implicit need - in DNSSEC to make the authentication process stronger than it was in - - - -Kolkman & Gieben Expires September 7, 2006 [Page 24] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - DNS. - - Using the DNS itself as the source for the actual DNSKEY material, - with an out-of-band check on the validity of the DNSKEY, has the - benefit that it reduces the chances of user error. A DNSKEY query - tool can make use of the SEP bit [3] to select the proper key from a - DNSSEC key set; thereby reducing the chance that the wrong DNSKEY is - sent. It can validate the self-signature over a key; thereby - verifying the ownership of the private key material. Fetching the - DNSKEY from the DNS ensures that the chain of trust remains intact - once the parent publishes the DS RR indicating the child is secure. - - Note: the out-of-band verification is still needed when the key- - material is fetched via the DNS. The parent can never be sure - whether the DNSKEY RRs have been spoofed or not. - -4.4.2. Storing Keys or Hashes? - - When designing a registry system one should consider which of the - DNSKEYs and/or the corresponding DSs to store. Since a child zone - might wish to have a DS published using a message digest algorithm - not yet understood by the registry, the registry can't count on being - able to generate the DS record from a raw DNSKEY. Thus, we recommend - that registry systems at least support storing DS records. - - It may also be useful to store DNSKEYs, since having them may help - during troubleshooting and, as long as the child's chosen message - digest is supported, the overhead of generating DS records from them - is minimal. Having an out-of-band mechanism, such as a registry - directory (e.g. Whois), to find out which keys are used to generate - DS Resource Records for specific owners and/or zones may also help - with troubleshooting. - - The storage considerations also relate to the design of the customer - interface and the method by which data is transferred between - registrant and registry; Will the child zone administrator be able to - upload DS RRs with unknown hash algorithms or does the interface only - allow DNSKEYs? In the registry-registrar model one can use the - DNSSEC EPP protocol extension [16] which allows transfer of DS RRs - and optionally DNSKEY RRs. - -4.4.3. Security Lameness - - Security Lameness is defined as what happens when a parent has a DS - RR pointing to a non-existing DNSKEY RR. When this happens the - child's zone may be marked as "Bogus" by verifying DNS clients. - - As part of a comprehensive delegation check the parent could, at key - - - -Kolkman & Gieben Expires September 7, 2006 [Page 25] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - exchange time, verify that the child's key is actually configured in - the DNS. However if a parent does not understand the hashing - algorithm used by child the parental checks are limited to only - comparing the key id. - - Child zones should be very careful removing DNSKEY material, - specifically SEP keys, for which a DS RR exists. - - Once a zone is "security lame", a fix (e.g. removing a DS RR) will - take time to propagate through the DNS. - -4.4.4. DS Signature Validity Period - - Since the DS can be replayed as long as it has a valid signature, a - short signature validity period over the DS minimizes the time a - child is vulnerable in the case of a compromise of the child's - KSK(s). A signature validity period that is too short introduces the - possibility that a zone is marked Bogus in case of a configuration - error in the signer. There may not be enough time to fix the - problems before signatures expire. Something as mundane as operator - unavailability during weekends shows the need for DS signature - validity periods longer than 2 days. We recommend an absolute - minimum for a DS signature validity period of a few days. - - The maximum signature validity period of the DS record depends on how - long child zones are willing to be vulnerable after a key compromise. - On the other hand shortening the DS signature validity interval - increases the operational risk for the parent. Therefore the parent - may have policy to use a signature validity interval that is - considerably longer than the child would hope for. - - A compromise between the operational constraints of the parent and - minimizing damage for the child may result in a DS signature validity - period somewhere between the order of a week to order of months. - - In addition to the signature validity period, which sets a lower - bound on the number of times the zone owner will need to sign the - zone data and which sets an upper bound to the time a child is - vulnerable after key compromise, there is the TTL value on the DS - RRs. Shortening the TTL means that the authoritative servers will - see more queries. But on the other hand, a short TTL lowers the - persistence of DS RRSets in caches thereby increases the speed with - which updated DS RRSets propagate through the DNS. - - -5. IANA Considerations - - This overview document introduces no new IANA considerations. - - - -Kolkman & Gieben Expires September 7, 2006 [Page 26] - -Internet-Draft DNSSEC Operational Practices March 2006 - - -6. Security Considerations - - DNSSEC adds data integrity to the DNS. This document tries to assess - the operational considerations to maintain a stable and secure DNSSEC - service. Not taking into account the 'data propagation' properties - in the DNS will cause validation failures and may make secured zones - unavailable to security aware resolvers. - - -7. Acknowledgments - - Most of the ideas in this draft were the result of collective efforts - during workshops, discussions and try outs. - - At the risk of forgetting individuals who were the original - contributors of the ideas we would like to acknowledge people who - were actively involved in the compilation of this document. In - random order: Rip Loomis, Olafur Gudmundsson, Wesley Griffin, Michael - Richardson, Scott Rose, Rick van Rein, Tim McGinnis, Gilles Guette - Olivier Courtay, Sam Weiler, Jelte Jansen, Niall O'Reilly, Holger - Zuleger, Ed Lewis, Hilarie Orman, Marcos Sanz and Peter Koch. - - Some material in this document has been copied from RFC 2541 [12]. - - Mike StJohns designed the key exchange between parent and child - mentioned in the last paragraph of Section 4.2.2 - - Section 4.2.4 was supplied by G. Guette and O. Courtay. - - Emma Bretherick, Adrian Bedford and Lindy Foster corrected many of - the spelling and style issues. - - Kolkman and Gieben take the blame for introducing all miscakes(SIC). - - Kolkman was employed by the RIPE NCC while working on this document. - - -8. References - -8.1. Normative References - - [1] Mockapetris, P., "Domain names - concepts and facilities", - STD 13, RFC 1034, November 1987. - - [2] Mockapetris, P., "Domain names - implementation and - specification", STD 13, RFC 1035, November 1987. - - [3] Kolkman, O., Schlyter, J., and E. Lewis, "Domain Name System KEY - - - -Kolkman & Gieben Expires September 7, 2006 [Page 27] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - (DNSKEY) Resource Record (RR) Secure Entry Point (SEP) Flag", - RFC 3757, May 2004. - - [4] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "DNS Security Introduction and Requirements", RFC 4033, - March 2005. - - [5] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "Resource Records for the DNS Security Extensions", RFC 4034, - March 2005. - - [6] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, - "Protocol Modifications for the DNS Security Extensions", - RFC 4035, March 2005. - -8.2. Informative References - - [7] Ohta, M., "Incremental Zone Transfer in DNS", RFC 1995, - August 1996. - - [8] Vixie, P., "A Mechanism for Prompt Notification of Zone Changes - (DNS NOTIFY)", RFC 1996, August 1996. - - [9] Bradner, S., "Key words for use in RFCs to Indicate Requirement - Levels", BCP 14, RFC 2119, March 1997. - - [10] Eastlake, D., "Secure Domain Name System Dynamic Update", - RFC 2137, April 1997. - - [11] Andrews, M., "Negative Caching of DNS Queries (DNS NCACHE)", - RFC 2308, March 1998. - - [12] Eastlake, D., "DNS Security Operational Considerations", - RFC 2541, March 1999. - - [13] Gudmundsson, O., "Delegation Signer (DS) Resource Record (RR)", - RFC 3658, December 2003. - - [14] Orman, H. and P. Hoffman, "Determining Strengths For Public - Keys Used For Exchanging Symmetric Keys", BCP 86, RFC 3766, - April 2004. - - [15] Eastlake, D., Schiller, J., and S. Crocker, "Randomness - Requirements for Security", BCP 106, RFC 4086, June 2005. - - [16] Hollenbeck, S., "Domain Name System (DNS) Security Extensions - Mapping for the Extensible Provisioning Protocol (EPP)", - RFC 4310, December 2005. - - - -Kolkman & Gieben Expires September 7, 2006 [Page 28] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - [17] Lenstra, A. and E. Verheul, "Selecting Cryptographic Key - Sizes", The Journal of Cryptology 14 (255-293), 2001. - - [18] Schneier, B., "Applied Cryptography: Protocols, Algorithms, and - Source Code in C", ISBN (hardcover) 0-471-12845-7, ISBN - (paperback) 0-471-59756-2, Published by John Wiley & Sons Inc., - 1996. - - [19] Rose, S., "NIST DNSSEC workshop notes", June 2001. - - [20] Jansen, J., "Use of RSA/SHA-256 DNSKEY and RRSIG Resource - Records in DNSSEC", draft-ietf-dnsext-dnssec-rsasha256-00.txt - (work in progress), January 2006. - - [21] Hardaker, W., "Use of SHA-256 in DNSSEC Delegation Signer (DS) - Resource Records (RRs)", draft-ietf-dnsext-ds-sha256-04.txt - (work in progress), January 2006. - - -Appendix A. Terminology - - In this document there is some jargon used that is defined in other - documents. In most cases we have not copied the text from the - documents defining the terms but given a more elaborate explanation - of the meaning. Note that these explanations should not be seen as - authoritative. - - Anchored Key: A DNSKEY configured in resolvers around the globe. - This key is hard to update, hence the term anchored. - Bogus: Also see Section 5 of [4]. An RRSet in DNSSEC is marked - "Bogus" when a signature of a RRSet does not validate against a - DNSKEY. - Key Signing Key or KSK: A Key Signing Key (KSK) is a key that is used - exclusively for signing the apex key set. The fact that a key is - a KSK is only relevant to the signing tool. - Key size: The term 'key size' can be substituted by 'modulus size' - throughout the document. It is mathematically more correct to use - modulus size, but as this is a document directed at operators we - feel more at ease with the term key size. - Private and Public Keys: DNSSEC secures the DNS through the use of - public key cryptography. Public key cryptography is based on the - existence of two (mathematically related) keys, a public key and a - private key. The public keys are published in the DNS by use of - the DNSKEY Resource Record (DNSKEY RR). Private keys should - remain private. - - - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 29] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - Key Rollover: A key rollover (also called key supercession in some - environments) is the act of replacing one key pair by another at - the end of a key effectivity period. - Secure Entry Point key or SEP Key: A KSK that has a parental DS - record pointing to it or is configured as a trust anchor. - Although not required by the protocol we recommend that the SEP - flag [3] is set on these keys. - Self-signature: This is only applies to signatures over DNSKEYs; a - signature made with DNSKEY x, over DNSKEY x is called a self- - signature. Note: without further information self-signatures - convey no trust, they are useful to check the authenticity of the - DNSKEY, i.e. they can be used as a hash. - Singing the Zone File: The term used for the event where an - administrator joyfully signs its zone file while producing melodic - sound patterns. - Signer: The system that has access to the private key material and - signs the Resource Record sets in a zone. A signer may be - configured to sign only parts of the zone e.g. only those RRSets - for which existing signatures are about to expire. - Zone Signing Key or ZSK: A Zone Signing Key (ZSK) is a key that is - used for signing all data in a zone. The fact that a key is a ZSK - is only relevant to the signing tool. - Zone Administrator: The 'role' that is responsible for signing a zone - and publishing it on the primary authoritative server. - - -Appendix B. Zone Signing Key Rollover Howto - - Using the pre-published signature scheme and the most conservative - method to assure oneself that data does not live in caches, here - follows the "HOWTO". - Step 0: The preparation: Create two keys and publish both in your key - set. Mark one of the keys as "active" and the other as - "published". Use the "active" key for signing your zone data. - Store the private part of the "published" key, preferably off- - line. - The protocol does not provide for attributes to mark a key as - active or published. This is something you have to do on your - own, through the use of a notebook or key management tool. - Step 1: Determine expiration: At the beginning of the rollover make a - note of the highest expiration time of signatures in your zone - file created with the current key marked as "active". - Wait until the expiration time marked in Step 1 has passed - Step 2: Then start using the key that was marked as "published" to - sign your data i.e. mark it as "active". Stop using the key that - was marked as "active", mark it as "rolled". - - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 30] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - Step 3: It is safe to engage in a new rollover (Step 1) after at - least one "signature validity period". - - -Appendix C. Typographic Conventions - - The following typographic conventions are used in this document: - Key notation: A key is denoted by DNSKEYx, where x is a number or an - identifier, x could be thought of as the key id. - RRSet notations: RRs are only denoted by the type. All other - information - owner, class, rdata and TTL - is left out. Thus: - "example.com 3600 IN A 192.0.2.1" is reduced to "A". RRSets are a - list of RRs. A example of this would be: "A1, A2", specifying the - RRSet containing two "A" records. This could again be abbreviated - to just "A". - Signature notation: Signatures are denoted as RRSIGx(RRSet), which - means that RRSet is signed with DNSKEYx. - Zone representation: Using the above notation we have simplified the - representation of a signed zone by leaving out all unnecessary - details such as the names and by representing all data by "SOAx" - SOA representation: SOAs are represented as SOAx, where x is the - serial number. - Using this notation the following signed zone: - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 31] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - example.net. 86400 IN SOA ns.example.net. bert.example.net. ( - 2006022100 ; serial - 86400 ; refresh ( 24 hours) - 7200 ; retry ( 2 hours) - 3600000 ; expire (1000 hours) - 28800 ) ; minimum ( 8 hours) - 86400 RRSIG SOA 5 2 86400 20130522213204 ( - 20130422213204 14 example.net. - cmL62SI6iAX46xGNQAdQ... ) - 86400 NS a.iana-servers.net. - 86400 NS b.iana-servers.net. - 86400 RRSIG NS 5 2 86400 20130507213204 ( - 20130407213204 14 example.net. - SO5epiJei19AjXoUpFnQ ... ) - 86400 DNSKEY 256 3 5 ( - EtRB9MP5/AvOuVO0I8XDxy0... ) ; id = 14 - 86400 DNSKEY 257 3 5 ( - gsPW/Yy19GzYIY+Gnr8HABU... ) ; id = 15 - 86400 RRSIG DNSKEY 5 2 86400 20130522213204 ( - 20130422213204 14 example.net. - J4zCe8QX4tXVGjV4e1r9... ) - 86400 RRSIG DNSKEY 5 2 86400 20130522213204 ( - 20130422213204 15 example.net. - keVDCOpsSeDReyV6O... ) - 86400 RRSIG NSEC 5 2 86400 20130507213204 ( - 20130407213204 14 example.net. - obj3HEp1GjnmhRjX... ) - a.example.net. 86400 IN TXT "A label" - 86400 RRSIG TXT 5 3 86400 20130507213204 ( - 20130407213204 14 example.net. - IkDMlRdYLmXH7QJnuF3v... ) - 86400 NSEC b.example.com. TXT RRSIG NSEC - 86400 RRSIG NSEC 5 3 86400 20130507213204 ( - 20130407213204 14 example.net. - bZMjoZ3bHjnEz0nIsPMM... ) - ... - - is reduced to the following representation: - - SOA2006022100 - RRSIG14(SOA2006022100) - DNSKEY14 - DNSKEY15 - - RRSIG14(KEY) - RRSIG15(KEY) - - The rest of the zone data has the same signature as the SOA record, - - - -Kolkman & Gieben Expires September 7, 2006 [Page 32] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - i.e a RRSIG created with DNSKEY 14. - - -Appendix D. Document Details and Changes - - This section is to be removed by the RFC editor if and when the - document is published. - - $Id: draft-ietf-dnsop-dnssec-operational-practices.xml,v 1.31.2.14 - 2005/03/21 15:51:41 dnssec Exp $ - -D.1. draft-ietf-dnsop-dnssec-operational-practices-00 - - Submission as working group document. This document is a modified - and updated version of draft-kolkman-dnssec-operational-practices-00. - -D.2. draft-ietf-dnsop-dnssec-operational-practices-01 - - changed the definition of "Bogus" to reflect the one in the protocol - draft. - - Bad to Bogus - - Style and spelling corrections - - KSK - SEP mapping made explicit. - - Updates from Sam Weiler added - -D.3. draft-ietf-dnsop-dnssec-operational-practices-02 - - Style and errors corrected. - - Added Automatic rollover requirements from I-D.ietf-dnsop-key- - rollover-requirements. - -D.4. draft-ietf-dnsop-dnssec-operational-practices-03 - - Added the definition of Key effectivity period and used that term - instead of Key validity period. - - Modified the order of the sections, based on a suggestion by Rip - Loomis. - - Included parts from RFC 2541 [12]. Most of its ground was already - covered. This document obsoletes RFC 2541 [12]. Section 3.1.2 - deserves some review as it in contrast to RFC 2541 does _not_ give - recomendations about root-zone keys. - - - -Kolkman & Gieben Expires September 7, 2006 [Page 33] - -Internet-Draft DNSSEC Operational Practices March 2006 - - - added a paragraph to Section 4.4.4 - -D.5. draft-ietf-dnsop-dnssec-operational-practices-04 - - Somewhat more details added about the pre-publish KSK rollover. Also - moved that subsection down a bit. - - Editorial and content nits that came in during wg last call were - fixed. - -D.6. draft-ietf-dnsop-dnssec-operational-practices-05 - - Applied some another set of comments that came in _after_ the the - WGLC. - - Applied comments from Hilarie Orman and made a referece to RFC 3766. - Deleted of a lot of key length discussion and took over the - recommendations from RFC 3766. - - Reworked all the heading of the rollover figures - -D.7. draft-ietf-dnsop-dnssec-operational-practices-06 - - One comment from Scott Rose applied. - - Marcos Sanz gave a lots of editorial nits. Almost all are - incorporated. - -D.8. draft-ietf-dnsop-dnssec-operational-practices-07 - - Peter Koch's comments applied. - - SHA-1/SHA-256 remarks added - -D.9. draft-ietf-dnsop-dnssec-operational-practices-08 - - IESG comments applied. Added headers and some captions to the tables - and applied all the nits. - - IESG DISCUSS comments applied - - - - - - - - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 34] - -Internet-Draft DNSSEC Operational Practices March 2006 - - -Authors' Addresses - - Olaf M. Kolkman - NLnet Labs - Kruislaan 419 - Amsterdam 1098 VA - The Netherlands - - Email: olaf@nlnetlabs.nl - URI: http://www.nlnetlabs.nl - - - Miek Gieben - NLnet Labs - Kruislaan 419 - Amsterdam 1098 VA - The Netherlands - - Email: miek@nlnetlabs.nl - URI: http://www.nlnetlabs.nl - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 35] - -Internet-Draft DNSSEC Operational Practices March 2006 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2006). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Kolkman & Gieben Expires September 7, 2006 [Page 36] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsop-inaddr-required-07.txt b/contrib/bind9/doc/draft/draft-ietf-dnsop-inaddr-required-07.txt deleted file mode 100644 index bcd0d14..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsop-inaddr-required-07.txt +++ /dev/null @@ -1,396 +0,0 @@ - - - - - - -INTERNET-DRAFT D. Senie -Category: BCP Amaranth Networks Inc. -Expires in six months July 2005 - - Encouraging the use of DNS IN-ADDR Mapping - draft-ietf-dnsop-inaddr-required-07.txt - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html - -Abstract - - Mapping of addresses to names has been a feature of DNS. Many sites, - implement it, many others don't. Some applications attempt to use it - as a part of a security strategy. The goal of this document is to - encourage proper deployment of address to name mappings, and provide - guidance for their use. - -Copyright Notice - - Copyright (C) The Internet Society. (2005) - -1. Introduction - - The Domain Name Service has provision for providing mapping of IP - addresses to host names. It is common practice to ensure both name to - address, and address to name mappings are provided for networks. This - practice, while documented, has never been required, though it is - generally encouraged. This document both encourages the presence of - - - -Senie [Page 1] - -Internet-Draft Encouraging the use of DNS IN-ADDR Mapping July 2005 - - - these mappings and discourages reliance on such mappings for security - checks. - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in RFC 2119 [RFC2119]. - -2. Discussion - - - From the early days of the Domain Name Service [RFC883] a special - domain has been set aside for resolving mappings of IP addresses to - domain names. This was refined in [RFC1035], describing the .IN- - ADDR.ARPA in use today. For the in the IPv6 address space, .IP6.ARPA - was added [RFC3152]. This document uses IPv4 CIDR block sizes and - allocation strategy where there are differences and uses IPv4 - terminology. Aside from these differences, this document can and - should be applied to both address spaces. - - The assignment of blocks of IP address space was delegated to three - regional registries. Guidelines for the registries are specified in - [RFC2050], which requires regional registries to maintain IN-ADDR - records on the large blocks of space issued to ISPs and others. - - ARIN's policy requires ISPs to maintain IN-ADDR for /16 or larger - allocations. For smaller allocations, ARIN can provide IN-ADDR for - /24 and shorter prefixes. [ARIN]. APNIC provides methods for ISPs to - update IN-ADDR, however the present version of its policy document - for IPv4 [APNIC] dropped the IN-ADDR requirements that were in draft - copies of this document. As of this writing, it appears APNIC has no - actual policy on IN-ADDR. RIPE appears to have the strongest policy - in this area [RIPE302] indicating Local Internet Registries should - provide IN-ADDR services, and delegate those as appropriate when - address blocks are delegated. - - As we can see, the regional registries have their own policies for - recommendations and/or requirements for IN-ADDR maintenance. It - should be noted, however, that many address blocks were allocated - before the creation of the regional registries, and thus it is - unclear whether any of the policies of the registries are binding on - those who hold blocks from that era. - - Registries allocate address blocks on CIDR [RFC1519] boundaries. - Unfortunately the IN-ADDR zones are based on classful allocations. - Guidelines [RFC2317] for delegating on non-octet-aligned boundaries - exist, but are not always implemented. - -3. Examples of impact of missing IN-ADDR - - - -Senie [Page 2] - -Internet-Draft Encouraging the use of DNS IN-ADDR Mapping July 2005 - - - These are some examples of problems that may be introduced by - reliance on IN-ADDR. - - Some applications use DNS lookups for security checks. To ensure - validity of claimed names, some applications will look up IN-ADDR - records to get names, and then look up the resultant name to see if - it maps back to the address originally known. Failure to resolve - matching names is seen as a potential security concern. - - Some FTP sites will flat-out reject users, even for anonymous FTP, if - the IN-ADDR lookup fails or if the result of the IN-ADDR lookup when - itself resolved, does not match. Some Telnet servers also implement - this check. - - Web sites are in some cases using IN-ADDR checks to verify whether - the client is located within a certain geopolitical entity. This - approach has been employed for downloads of crypto software, for - example, where export of that software is prohibited to some locales. - Credit card anti-fraud systems also use these methods for geographic - placement purposes. - - The popular TCP Wrappers program found on most Unix and Linux systems - has options to enforce IN-ADDR checks and to reject any client that - does not resolve. This program also has a way to check to see that - the name given by a PTR record then resolves back to the same IP - address. This method provdes more comfort but no appreciable - additional security. - - Some anti-spam (anti junk email) systems use IN-ADDR to verify the - presence of a PTR record, or validate the PTR value points back to - the same address. - - Many web servers look up the IN-ADDR of visitors to be used in log - analysis. This adds to the server load, but in the case of IN-ADDR - unavailability, it can lead to delayed responses for users. - - Traceroutes with descriptive IN-ADDR naming proves useful when - debugging problems spanning large areas. When this information is - missing, the traceroutes take longer, and it takes additional steps - to determine that network is the cause of problems. - - Wider-scale implementation of IN-ADDR on dialup, wireless access and - other such client-oriented portions of the Internet would result in - lower latency for queries (due to lack of negative caching), and - lower name server load and DNS traffic. - -4. Recommendations - - - - -Senie [Page 3] - -Internet-Draft Encouraging the use of DNS IN-ADDR Mapping July 2005 - - - 4.1 Delegation Recommendations - - - Regional Registries and any Local Registries to whom they delegate - should establish and convey a policy to those to whom they delegate - blocks that IN-ADDR mappings are recommended. Policies should - recommend those receiving delegations to provide IN-ADDR service - and/or delegate to downstream customers. - - Network operators should define and implement policies and procedures - which delegate IN-ADDR to their clients who wish to run their own IN- - ADDR DNS services, and provide IN-ADDR services for those who do not - have the resources to do it themselves. Delegation mechanisms should - permit the downstream customer to implement and comply with IETF - recommendations application of IN-ADDR to CIDR [RFC2317]. - - All IP address space assigned and in use should be resolved by IN- - ADDR records. All PTR records must use canonical names. - - All IP addresses in use within a block should have an IN-ADDR - mapping. Those addresses not in use, and those that are not valid for - use (zeros or ones broadcast addresses within a CIDR block) need not - have mappings. - - It should be noted that due to CIDR, many addresses that appear to be - otherwise valid host addresses may actually be zeroes or ones - broadcast addresses. As such, attempting to audit a site's degree of - compliance may only be done with knowledge of the internal subnet - architecture of the site. It can be assumed, however, any host that - originates an IP packet necessarily will have a valid host address, - and must therefore have an IN-ADDR mapping. - -4.2 Application Recommendations - - - Applications SHOULD NOT rely on IN-ADDR for proper operation. The use - of IN-ADDR, sometimes in conjunction with a lookup of the name - resulting from the PTR record provides no real security, can lead to - erroneous results and generally just increases load on DNS servers. - Further, in cases where address block holders fail to properly - configure IN-ADDR, users of those blocks are penalized. - -5. Security Considerations - - This document has no negative impact on security. While it could be - argued that lack of PTR record capabilities provides a degree of - anonymity, this is really not valid. Trace routes, whois lookups and - other sources will still provide methods for discovering identity. - - - -Senie [Page 4] - -Internet-Draft Encouraging the use of DNS IN-ADDR Mapping July 2005 - - - By recommending applications avoid using IN-ADDR as a security - mechanism this document points out that this practice, despite its - use by many applications, is an ineffective form of security. - Applications should use better mechanisms of authentication. - -6. IANA Considerations - - There are no IANA considerations for this document. - -7. References - -7.1 Normative References - - [RFC883] P.V. Mockapetris, "Domain names: Implementation - specification," RFC883, November 1983. - - [RFC1035] P.V. Mockapetris, "Domain Names: Implementation - Specification," RFC 1035, November 1987. - - [RFC1519] V. Fuller, et. al., "Classless Inter-Domain Routing (CIDR): - an Address Assignment and Aggregation Strategy," RFC 1519, September - 1993. - - [RFC2026] S. Bradner, "The Internet Standards Process -- Revision 3", - RFC 2026, BCP 9, October 1996. - - [RFC2119] S. Bradner, "Key words for use in RFCs to Indicate - Requirement Levels", RFC 2119, BCP 14, March 1997. - - [RFC2050] K. Hubbard, et. al., "Internet Registry IP Allocation - Guidelines", RFC2050, BCP 12, Novebmer 1996. - - [RFC2317] H. Eidnes, et. al., "Classless IN-ADDR.ARPA delegation," - RFC 2317, March 1998. - - [RFC3152] R. Bush, "Delegation of IP6.ARPA," RFC 3152, BCP 49, August - 2001. - -7.2 Informative References - - [ARIN] "ISP Guidelines for Requesting Initial IP Address Space," date - unknown, http://www.arin.net/regserv/initial-isp.html - - [APNIC] "Policies For IPv4 Address Space Management in the Asia - Pacific Region," APNIC-086, 13 January 2003. - - [RIPE302] "Policy for Reverse Address Delegation of IPv4 and IPv6 - Address Space in the RIPE NCC Service Region", RIPE-302, April 26, - - - -Senie [Page 5] - -Internet-Draft Encouraging the use of DNS IN-ADDR Mapping July 2005 - - - 2004. http://www.ripe.net//ripe/docs/rev-del.html - - - -8. Acknowledgements - - Thanks to Peter Koch and Gary Miller for their input, and to many - people who encouraged me to write this document. - -9. Author's Address - - Daniel Senie - Amaranth Networks Inc. - 324 Still River Road - Bolton, MA 01740 - - Phone: (978) 779-5100 - - EMail: dts@senie.com - -10. Full Copyright Statement - - Copyright (C) The Internet Society (2005). - - This document is subject to the rights, licenses and restrictions - contained in BCP 78, and except as set forth therein, the authors - retain all their rights. - - This document and the information contained herein are provided - on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE - REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND - THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT - THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR - ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A - PARTICULAR PURPOSE. - -Intellectual Property - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed - to pertain to the implementation or use of the technology - described in this document or the extent to which any license - under such rights might or might not be available; nor does it - represent that it has made any independent effort to identify any - such rights. Information on the procedures with respect to - rights in RFC documents can be found in BCP 78 and BCP 79. - - - - -Senie [Page 6] - -Internet-Draft Encouraging the use of DNS IN-ADDR Mapping July 2005 - - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use - of such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository - at http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention - any copyrights, patents or patent applications, or other - proprietary rights that may cover technology that may be required - to implement this standard. Please address the information to the - IETF at ietf-ipr@ietf.org. - - Internet-Drafts are working documents of the - Internet Engineering Task Force (IETF), its areas, and its - working groups. Note that other groups may also distribute - working documents as Internet-Drafts. - - Internet-Drafts are draft documents valid for a maximum of - six months and may be updated, replaced, or obsoleted by - other documents at any time. It is inappropriate to use - Internet-Drafts as reference material or to cite them other - than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/1id-abstracts.html - - The list of Internet-Draft Shadow Directories can be - accessed at http://www.ietf.org/shadow.html - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - - - - - - - - - - - - - -Senie [Page 7] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsop-ipv6-dns-configuration-06.txt b/contrib/bind9/doc/draft/draft-ietf-dnsop-ipv6-dns-configuration-06.txt deleted file mode 100644 index bf2afcd..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsop-ipv6-dns-configuration-06.txt +++ /dev/null @@ -1,1848 +0,0 @@ - - - -DNS Operations WG J. Jeong, Ed. -Internet-Draft ETRI/University of Minnesota -Expires: November 6, 2005 May 5, 2005 - - - IPv6 Host Configuration of DNS Server Information Approaches - draft-ietf-dnsop-ipv6-dns-configuration-06.txt - -Status of this Memo - - This document is an Internet-Draft and is subject to all provisions - of Section 3 of RFC 3667. By submitting this Internet-Draft, each - author represents that any applicable patent or other IPR claims of - which he or she is aware have been or will be disclosed, and any of - which he or she become aware will be disclosed, in accordance with - RFC 3668. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on November 6, 2005. - -Copyright Notice - - Copyright (C) The Internet Society (2005). - -Abstract - - This document describes three approaches for IPv6 recursive DNS - server address configuration. It details the operational attributes - of three solutions: RA option, DHCPv6 option, and Well-known anycast - addresses for recursive DNS servers. Additionally, it suggests the - deployment scenarios in four kinds of networks, such as ISP, - Enterprise, 3GPP, and Unmanaged networks, considering multi-solution - resolution. Therefore, this document will give the audience a - - - -Jeong Expires November 6, 2005 [Page 1] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - - guideline for IPv6 host DNS configuration. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Jeong Expires November 6, 2005 [Page 2] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 5 - 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 6 - 3. IPv6 DNS Configuration Approaches . . . . . . . . . . . . . . 7 - 3.1 RA Option . . . . . . . . . . . . . . . . . . . . . . . . 7 - 3.1.1 Advantages . . . . . . . . . . . . . . . . . . . . . . 8 - 3.1.2 Disadvantages . . . . . . . . . . . . . . . . . . . . 8 - 3.1.3 Observations . . . . . . . . . . . . . . . . . . . . . 9 - 3.2 DHCPv6 Option . . . . . . . . . . . . . . . . . . . . . . 9 - 3.2.1 Advantages . . . . . . . . . . . . . . . . . . . . . . 11 - 3.2.2 Disadvantages . . . . . . . . . . . . . . . . . . . . 12 - 3.2.3 Observations . . . . . . . . . . . . . . . . . . . . . 12 - 3.3 Well-known Anycast Addresses . . . . . . . . . . . . . . . 12 - 3.3.1 Advantages . . . . . . . . . . . . . . . . . . . . . . 13 - 3.3.2 Disadvantages . . . . . . . . . . . . . . . . . . . . 14 - 3.3.3 Observations . . . . . . . . . . . . . . . . . . . . . 14 - 4. Interworking among IPv6 DNS Configuration Approaches . . . . . 15 - 5. Deployment Scenarios . . . . . . . . . . . . . . . . . . . . . 16 - 5.1 ISP Network . . . . . . . . . . . . . . . . . . . . . . . 16 - 5.1.1 RA Option Approach . . . . . . . . . . . . . . . . . . 16 - 5.1.2 DHCPv6 Option Approach . . . . . . . . . . . . . . . . 17 - 5.1.3 Well-known Anycast Addresses Approach . . . . . . . . 17 - 5.2 Enterprise Network . . . . . . . . . . . . . . . . . . . . 17 - 5.3 3GPP Network . . . . . . . . . . . . . . . . . . . . . . . 18 - 5.3.1 Currently Available Mechanisms and Recommendations . . 19 - 5.3.2 RA Extension . . . . . . . . . . . . . . . . . . . . . 19 - 5.3.3 Stateless DHCPv6 . . . . . . . . . . . . . . . . . . . 20 - 5.3.4 Well-known Addresses . . . . . . . . . . . . . . . . . 21 - 5.3.5 Recommendations . . . . . . . . . . . . . . . . . . . 21 - 5.4 Unmanaged Network . . . . . . . . . . . . . . . . . . . . 22 - 5.4.1 Case A: Gateway does not provide IPv6 at all . . . . . 22 - 5.4.2 Case B: A dual-stack gateway connected to a - dual-stack ISP . . . . . . . . . . . . . . . . . . . . 22 - 5.4.3 Case C: A dual-stack gateway connected to an - IPv4-only ISP . . . . . . . . . . . . . . . . . . . . 22 - 5.4.4 Case D: A gateway connected to an IPv6-only ISP . . . 23 - 6. Security Considerations . . . . . . . . . . . . . . . . . . . 24 - 6.1 RA Option . . . . . . . . . . . . . . . . . . . . . . . . 25 - 6.2 DHCPv6 Option . . . . . . . . . . . . . . . . . . . . . . 25 - 6.3 Well-known Anycast Addresses . . . . . . . . . . . . . . . 25 - 7. Contributors . . . . . . . . . . . . . . . . . . . . . . . . . 26 - 8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 28 - 9. References . . . . . . . . . . . . . . . . . . . . . . . . . . 29 - 9.1 Normative References . . . . . . . . . . . . . . . . . . . 29 - 9.2 Informative References . . . . . . . . . . . . . . . . . . 29 - Author's Address . . . . . . . . . . . . . . . . . . . . . . . 31 - A. Link-layer Multicast Acknowledgements for RA Option . . . . . 32 - - - -Jeong Expires November 6, 2005 [Page 3] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - - Intellectual Property and Copyright Statements . . . . . . . . 33 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Jeong Expires November 6, 2005 [Page 4] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - -1. Introduction - - Neighbor Discovery (ND) for IP Version 6 and IPv6 Stateless Address - Autoconfiguration provide the ways to configure either fixed or - mobile nodes with one or more IPv6 addresses, default routes and some - other parameters [3][4]. To support the access to additional - services in the Internet that are identified by a DNS name, such as a - web server, the configuration of at least one recursive DNS server is - also needed for DNS name resolution. - - This document describes three approaches of recursive DNS server - address configuration for IPv6 host: (a) RA option [8], (b) DHCPv6 - option [5]-[7], and (c) Well-known anycast addresses for recursive - DNS servers [9]. Also, it suggests the applicable scenarios for four - kinds of networks: (a) ISP network, (b) Enterprise network, (c) 3GPP - network, and (d) Unmanaged network. - - This document is just an analysis of each possible approach, and does - not make any recommendation on a particular one or on a combination - of particular ones. Some approaches may even not be adopted at all - as a result of further discussion. - - Therefore, the objective of this document is to help the audience - select the approaches suitable for IPv6 host configuration of - recursive DNS servers. - - - - - - - - - - - - - - - - - - - - - - - - - - -Jeong Expires November 6, 2005 [Page 5] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - -2. Terminology - - This document uses the terminology described in [3]-[9]. In - addition, a new term is defined below: - - o Recursive DNS Server (RDNSS): A Recursive DNS Server is a name - server that offers the recursive service of DNS name resolution. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Jeong Expires November 6, 2005 [Page 6] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - -3. IPv6 DNS Configuration Approaches - - In this section, the operational attributes of the three solutions - are described in detail. - -3.1 RA Option - - The RA approach is to define a new ND option called the RDNSS option - that contains a recursive DNS server address. Existing ND transport - mechanisms (i.e., advertisements and solicitations) are used. This - works in the same way that nodes learn about routers and prefixes. - An IPv6 host can configure the IPv6 addresses of one or more RDNSSes - via RA message periodically sent by a router or solicited by a Router - Solicitation (RS) [8]. - - This approach needs RDNSS information to be configured in the routers - doing the advertisements. The configuration of RDNSS addresses can - be performed manually by an operator or other ways, such as automatic - configuration through a DHCPv6 client running on the router. When - advertising more than one RDNSS option, an RA message includes as - many RDNSS options as RDNSSes. - - Through the ND protocol and RDNSS option along with a prefix - information option, an IPv6 host can perform its network - configuration of its IPv6 address and RDNSS simultaneously [3][4]. - The RA option for RDNSS can be used on any network that supports the - use of ND. - - However, it is worth noting that some link layers, such as Wireless - LANs (e.g., IEEE 802.11 a/b/g), do not support reliable multicast, - which means that they cannot guarantee the timely delivery of RA - messages [25]-[28]. This is discussed in Appendix A. - - The RA approach is useful in some mobile environments where the - addresses of the RDNSSes are changing because the RA option includes - a lifetime field that allows client to use RDNSSes nearer to the - client. This can be configured to a value that will require the - client to time out the entry and switch over to another RDNSS address - [8]. However, from the viewpoint of implementation, the lifetime - field would seem to make matters a bit more complex. Instead of just - writing to a DNS configuration file, such as resolv.conf for the list - of RDNSS addresses, we have to have a daemon around (or a program - that is called at the defined intervals) that keeps monitoring the - lifetime of RDNSSes all the time. - - The preference value of RDNSS, included in the RDNSS option, allows - IPv6 hosts to select primary RDNSS among several RDNSSes; this can be - used for the load balancing of RDNSSes [8]. - - - -Jeong Expires November 6, 2005 [Page 7] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - -3.1.1 Advantages - - The RA option for RDNSS has a number of advantages. These include: - - 1. The RA option is an extension of existing ND/Autoconfig - mechanisms [3][4], and does not require a change in the base ND - protocol. - - 2. This approach, like ND, works well on a variety of link types - including point-to-point links, point-to-multipoint, and - multipoint-to-multipoint (i.e., Ethernet LANs), etc. RFC 2461 - [3] states, however, that there may be some link types on which - ND is not feasible; on such links, some other mechanisms will be - needed for DNS configuration. - - 3. All of the information a host needs to run the basic Internet - applications such as the email, web, ftp, etc., can be obtained - with the addition of this option to ND and address - autoconfiguration. The use of a single mechanism is more - reliable and easier to provide than when the RDNSS information is - learned via another protocol mechanism. Debugging problems when - multiple protocol mechanisms are being used is harder and much - more complex. - - 4. This mechanism works over a broad range of scenarios and - leverages IPv6 ND. This works well on links that support - broadcast reliably (e.g., Ethernet LANs) but not necessarily on - other links (e.g., Wireless LANs): Refer to Appendix A. Also, - this works well on links that are high performance (e.g., - Ethernet LANs) and low performance (e.g., Cellular networks). In - the latter case, by combining the RDNSS information with the - other information in the RA, the host can learn all of the - information needed to use most Internet applications, such as the - web in a single packet. This not only saves bandwidth where this - is an issue, but also minimizes the delay needed to learn the - RDNSS information. - - 5. The RA approach could be used as a model for other similar types - of configuration information. New RA options for other server - addresses, such as NTP server address, that are common to all - clients on a subnet would be easy to define. - - -3.1.2 Disadvantages - - 1. ND is mostly implemented in the kernel of operating system. - Therefore, if ND supports the configuration of some additional - services, such as DNS servers, ND should be extended in the - - - -Jeong Expires November 6, 2005 [Page 8] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - - kernel, and complemented by a user-land process. DHCPv6, - however, has more flexibility for the extension of service - discovery because it is an application layer protocol. - - 2. The current ND framework should be modified to facilitate the - synchronization between another ND cache for RDNSSes in the - kernel space and the DNS configuration file in the user space. - Because it is unacceptable to write and rewrite to the DNS - configuration file (e.g., resolv.conf) from the kernel, another - approach is needed. One simple approach to solve this is to have - a daemon listening to what the kernel conveys, and to have the - daemon do these steps, but such a daemon is not needed with the - current ND framework. - - 3. It is necessary to configure RDNSS addresses at least at one - router on every link where this information needs to be - configured via the RA option. - - -3.1.3 Observations - - The proposed RDNSS RA option along with the IPv6 ND and - Autoconfiguration allows a host to obtain all of the information it - needs to access the basic Internet services like the web, email, ftp, - etc. This is preferable in the environments where hosts use RAs to - autoconfigure their addresses and all the hosts on the subnet share - the same router and server addresses. If the configuration - information can be obtained from a single mechanism, it is preferable - because it does not add additional delay, and it uses a minimum of - bandwidth. The environments like this include the homes, public - cellular networks, and enterprise environments where no per host - configuration is needed, but exclude public WLAN hot spots. - - DHCPv6 is preferable where it is being used for address configuration - and if there is a need for host specific configuration [5]-[7]. The - environments like this are most likely to be the enterprise - environments where the local administration chooses to have per host - configuration control. - -Note - - The observation section is based on what the proponents of each - approach think makes a good overall solution. - -3.2 DHCPv6 Option - - DHCPv6 [5] includes the "DNS Recursive Name Server" option, through - which a host can obtain a list of IP addresses of recursive DNS - - - -Jeong Expires November 6, 2005 [Page 9] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - - servers [7]. The DNS Recursive Name Server option carries a list of - IPv6 addresses of RDNSSes to which the host may send DNS queries. - The DNS servers are listed in the order of preference for use by the - DNS resolver on the host. - - The DNS Recursive Name Server option can be carried in any DHCPv6 - Reply message, in response to either a Request or an Information - request message. Thus, the DNS Recursive Name Server option can be - used either when DHCPv6 is used for address assignment, or when - DHCPv6 is used only for other configuration information as stateless - DHCPv6 [6]. - - Stateless DHCPv6 can be deployed either using DHCPv6 servers running - on general-purpose computers, or on router hardware. Several router - vendors currently implement stateless DHCPv6 servers. Deploying - stateless DHCPv6 in routers has the advantage that no special - hardware is required, and should work well for networks where DHCPv6 - is needed for very straightforward configuration of network devices. - - However, routers can also act as DHCPv6 relay agents. In this case, - the DHCPv6 server need not be on the router - it can be on a general - purpose computer. This has the potential to give the operator of the - DHCPv6 server more flexibility in how the DHCPv6 server responds to - individual clients - clients can easily be given different - configuration information based on their identity, or for any other - reason. Nothing precludes adding this flexibility to a router, but - generally in current practice, DHCP servers running on general- - purpose hosts tend to have more configuration options than those that - are embedded in routers. - - DHCPv6 currently provides a mechanism for reconfiguring DHCPv6 - clients that use a stateful configuration assignment. To do this, - the DHCPv6 server sends a Reconfigure message to the client. The - client validates the Reconfigure message, and then contacts the - DHCPv6 server to obtain updated configuration information. Using - this mechanism, it is currently possible to propagate new - configuration information to DHCPv6 clients as this information - changes. - - The DHC Working Group is currently studying an additional mechanism - through which configuration information, including the list of - RDNSSes, can be updated. The lifetime option for DHCPv6 [10] assigns - a lifetime to configuration information obtained through DHCPv6. At - the expiration of the lifetime, the host contacts the DHCPv6 server - to obtain updated configuration information, including the list of - RDNSSes. This lifetime gives the network administrator another - mechanism to configure hosts with new RDNSSes by controlling the time - at which the host refreshes the list. - - - -Jeong Expires November 6, 2005 [Page 10] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - - The DHC Working Group has also discussed the possibility of defining - an extension to DHCPv6 that would allow the use of multicast to - provide configuration information to multiple hosts with a single - DHCPv6 message. Because of the lack of deployment experience, the WG - has deferred consideration of multicast DHCPv6 configuration at this - time. Experience with DHCPv4 has not identified a requirement for - multicast message delivery, even in large service provider networks - with tens of thousands of hosts that may initiate a DHCPv4 message - exchange simultaneously. - -3.2.1 Advantages - - The DHCPv6 option for RDNSS has a number of advantages. These - include: - - 1. DHCPv6 currently provides a general mechanism for conveying - network configuration information to clients. So configuring - DHCPv6 servers allows the network administrator to configure - RDNSSes along with the addresses of other network services, as - well as location-specific information like time zones. - - 2. As a consequence, when the network administrator goes to - configure DHCPv6, all the configuration information can be - managed through a single service, typically with a single user - interface and a single configuration database. - - 3. DHCPv6 allows for the configuration of a host with information - specific to that host, so that hosts on the same link can be - configured with different RDNSSes as well as with other - configuration information. This capability is important in some - network deployments such as service provider networks or WiFi hot - spots. - - 4. A mechanism exists for extending DHCPv6 to support the - transmission of additional configuration that has not yet been - anticipated. - - 5. Hosts that require other configuration information such as the - addresses of SIP servers and NTP servers are likely to need - DHCPv6 for other configuration information. - - 6. The specification for configuration of RDNSSes through DHCPv6 is - available as an RFC. No new protocol extensions such as new - options are necessary. - - 7. Interoperability among independent implementations has been - demonstrated. - - - - -Jeong Expires November 6, 2005 [Page 11] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - -3.2.2 Disadvantages - - The DHCPv6 option for RDNSS has a few disadvantages. These include: - - 1. Update currently requires message from server (however, see - [10]). - - 2. Because DNS information is not contained in RA messages, the host - must receive two messages from the router, and must transmit at - least one message to the router. On networks where bandwidth is - at a premium, this is a disadvantage, although on most networks - it is not a practical concern. - - 3. Increased latency for initial configuration - in addition to - waiting for an RA message, the client must now exchange packets - with a DHCPv6 server; even if it is locally installed on a - router, this will slightly extend the time required to configure - the client. For clients that are moving rapidly from one network - to another, this will be a disadvantage. - - -3.2.3 Observations - - In the general case, on general-purpose networks, stateless DHCPv6 - provides significant advantages and no significant disadvantages. - Even in the case where bandwidth is at a premium and low latency is - desired, if hosts require other configuration information in addition - to a list of RDNSSes or if hosts must be configured selectively, - those hosts will use DHCPv6 and the use of the DHCPv6 DNS recursive - name server option will be advantageous. - - However, we are aware of some applications where it would be - preferable to put the RDNSS information into an RA packet; for - example, on a cell phone network, where bandwidth is at a premium and - extremely low latency is desired. The final DNS configuration draft - should be written so as to allow these special applications to be - handled using DNS information in the RA packet. - -3.3 Well-known Anycast Addresses - - Anycast uses the same routing system as unicast [11]. However, - administrative entities are local ones. The local entities may - accept unicast routes (including default routes) to anycast servers - from adjacent entities. The administrative entities should not - advertise their peers routes to their internal anycast servers, if - they want to prohibit external access from some peers to the servers. - If some advertisement is inevitable (such as the case with default - routes), the packets to the servers should be blocked at the boundary - - - -Jeong Expires November 6, 2005 [Page 12] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - - of the entities. Thus, for this anycast, not only unicast routing - but also unicast ND protocols can be used as is. - - First of all, the well-known anycast addresses approach is much - different from that discussed at IPv6 Working Group in the past [9]. - It should be noted that "anycast" in this memo is simpler than that - of RFC 1546 [11] and RFC 3513 [12] where it is assumed to be - prohibited to have multiple servers on a single link sharing an - anycast address. That is, on a link, an anycast address is assumed - to be unique. DNS clients today already have redundancy by having - multiple well-known anycast addresses configured as RDNSS addresses. - There is no point in having multiple RDNSSes sharing an anycast - address on a single link. - - The approach with well-known anycast addresses is to set multiple - well-known anycast addresses in clients' resolver configuration files - from the beginning, say, as factory default. Thus, there is no - transport mechanism and no packet format [9]. - - An anycast address is an address shared by multiple servers (in this - case, the servers are RDNSSes). A request from a client to the - anycast address is routed to a server selected by the routing system. - However, it is a bad idea to mandate "site" boundary on anycast - addresses, because most users just do not have their own servers and - want to access their ISPs' across their site boundaries. Larger - sites may also depend on their ISPs or may have their own RDNSSes - within "site" boundaries. - -3.3.1 Advantages - - The basic advantage of the well-known addresses approach is that it - uses no transport mechanism. Thus, - - 1. There is no delay to get the response and no further delay by - packet losses. - - 2. The approach can be combined with any other configuration - mechanisms, such as the RA-based approach and DHCP based - approach, as well as the factory default configuration. - - 3. The approach works over any environment where DNS works. - - Another advantage is that the approach needs to configure DNS servers - as a router, but nothing else. Considering that DNS servers do need - configuration, the amount of overall configuration effort is - proportional to the number of the DNS servers and scales linearly. - It should be noted that, in the simplest case where a subscriber to - an ISP does not have any DNS server, the subscriber naturally - - - -Jeong Expires November 6, 2005 [Page 13] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - - accesses DNS servers of the ISP even though the subscriber and the - ISP do nothing and there is no protocol to exchange DNS server - information between the subscriber and the ISP. - -3.3.2 Disadvantages - - Well-known anycast addresses approach requires that DNS servers (or - routers near it as a proxy) act as routers to advertise their anycast - addresses to the routing system, which requires some configuration - (see the last paragraph of the previous section on the scalability of - the effort). - -3.3.3 Observations - - If other approaches are used in addition, the well-known anycast - addresses should also be set in RA or DHCP configuration files to - reduce the configuration effort of users. - - The redundancy by multiple RDNSSes is better provided by multiple - servers having different anycast addresses than multiple servers - sharing the same anycast address because the former approach allows - stale servers to still generate routes to their anycast addresses. - Thus, in a routing domain (or domains sharing DNS servers), there - will be only one server having an anycast address unless the domain - is so large that load distribution is necessary. - - Small ISPs will operate one RDNSS at each anycast address which is - shared by all the subscribers. Large ISPs may operate multiple - RDNSSes at each anycast address to distribute and reduce load, where - the boundary between RDNSSes may be fixed (redundancy is still - provided by multiple addresses) or change dynamically. DNS packets - with the well-known anycast addresses are not expected (though not - prohibited) to cross ISP boundaries, as ISPs are expected to be able - to take care of themselves. - - Because "anycast" in this memo is simpler than that of RFC 1546 [11] - and RFC 3513 [12] where it is assumed to be administratively - prohibited to have multiple servers on a single link sharing an - anycast address, anycast in this memo should be implemented as - UNICAST of RFC 2461 [3] and RFC 3513 [12]. As a result, ND-related - instability disappears. Thus, anycast in well-known anycast - addresses approach can and should use the anycast address as a source - unicast (according to RFC 3513 [12]) address of packets of UDP and - TCP responses. With TCP, if a route flips and packets to an anycast - address are routed to a new server, it is expected that the flip is - detected by ICMP or sequence number inconsistency and the TCP - connection is reset and retried. - - - - -Jeong Expires November 6, 2005 [Page 14] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - -4. Interworking among IPv6 DNS Configuration Approaches - - Three approaches can work together for IPv6 host configuration of - RDNSS. This section shows a consideration on how these approaches - can interwork each other. - - For ordering between RA and DHCP approaches, the O (Other stateful - configuration) flag in RA message can be used [8][32]. If no RDNSS - option is included, an IPv6 host may perform DNS configuration - through DHCPv6 [5]-[7] regardless of whether the O flag is set or - not. - - The well-known anycast addresses approach fully interworks with the - other approaches. That is, the other approaches can remove the - configuration effort on servers by using the well-known addresses as - the default configuration. Moreover, the clients preconfigured with - the well-known anycast addresses can be further configured to use - other approaches to override the well-known addresses, if the - configuration information from other approaches is available. - Otherwise, all the clients need to have the well-known anycast - addresses preconfigured. In order to use the anycast approach along - with two other approaches, there are three choices as follows: - - 1. The first choice is that well-known addresses are used as last - resort, when an IPv6 host cannot get RDNSS information through RA - and DHCP. The well-known anycast addresses have to be - preconfigured in all of IPv6 hosts' resolver configuration files. - - 2. The second is that an IPv6 host can configure well-known - addresses as the most preferable in its configuration file even - though either an RA option or DHCP option is available. - - 3. The last is that the well-known anycast addresses can be set in - RA or DHCP configuration to reduce the configuration effort of - users. According to either the RA or DHCP mechanism, the well- - known addresses can be obtained by an IPv6 host. Because this - approach is the most convenient for users, the last option is - recommended. - - -Note - - This section does not necessarily mean this document suggests - adopting all these three approaches and making them interwork in the - way described here. In fact, some approaches may even not be adopted - at all as a result of further discussion. - - - - - -Jeong Expires November 6, 2005 [Page 15] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - -5. Deployment Scenarios - - Regarding the DNS configuration on the IPv6 host, several mechanisms - are being considered at the DNSOP Working Group such as RA option, - DHCPv6 option and well-known preconfigured anycast addresses as of - today, and this document is a final result from the long thread. In - this section, we suggest four applicable scenarios of three - approaches for IPv6 DNS configuration. - -Note - - In the applicable scenarios, authors do not implicitly push any - specific approaches into the restricted environments. No enforcement - is in each scenario and all mentioned scenarios are probable. The - main objective of this work is to provide a useful guideline for IPv6 - DNS configuration. - -5.1 ISP Network - - A characteristic of ISP network is that multiple Customer Premises - Equipment (CPE) devices are connected to IPv6 PE (Provider Edge) - routers and each PE connects multiple CPE devices to the backbone - network infrastructure [13]. The CPEs may be hosts or routers. - - In the case where the CPE is a router, there is a customer network - that is connected to the ISP backbone through the CPE. Typically, - each customer network gets a different IPv6 prefix from an IPv6 PE - router, but the same RDNSS configuration will be distributed. - - This section discusses how the different approaches to distributing - DNS information are compared in an ISP network. - -5.1.1 RA Option Approach - - When the CPE is a host, the RA option for RDNSS can be used to allow - the CPE to get RDNSS information as well as /64 prefix information - for stateless address autoconfiguration at the same time when the - host is attached to a new subnet [8]. Because an IPv6 host must - receive at least one RA message for stateless address - autoconfiguration and router configuration, the host could receive - RDNSS configuration information in that RA without the overhead of an - additional message exchange. - - When the CPE is a router, the CPE may accept the RDNSS information - from the RA on the interface connected to the ISP, and copy that - information into the RAs advertised in the customer network. - - This approach is more valuable in the mobile host scenario, in which - - - -Jeong Expires November 6, 2005 [Page 16] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - - the host must receive at least an RA message for detecting a new - network, than in other scenarios generally although administrator - should configure RDNSS information on the routers. Secure ND [14] - can provide extended security when using RA messages. - -5.1.2 DHCPv6 Option Approach - - DHCPv6 can be used for RDNSS configuration through the use of the DNS - option, and can provide other configuration information in the same - message with RDNSS configuration [5]-[7]. The DHCPv6 DNS option is - already in place for DHCPv6 as RFC 3646 [7] and DHCPv6-lite or - stateless DHCP [6] is nowhere as complex as a full DHCPv6 - implementation. DHCP is a client-server model protocol, so ISPs can - handle user identification on its network intentionally, and also - authenticated DHCP [15] can be used for secure message exchange. - - The expected model for deployment of IPv6 service by ISPs is to - assign a prefix to each customer, which will be used by the customer - gateway to assign a /64 prefix to each network in the customer's - network. Prefix delegation with DHCP (DHCPv6 PD) has already been - adopted by ISPs for automating the assignment of the customer prefix - to the customer gateway [17]. DNS configuration can be carried in - the same DHCPv6 message exchange used for DHCPv6 to efficiently - provide that information, along with any other configuration - information needed by the customer gateway or customer network. This - service model can be useful to Home or SOHO subscribers. The Home or - SOHO gateway, which is a customer gateway for ISP, can then pass that - RDNSS configuration information to the hosts in the customer network - through DHCP. - -5.1.3 Well-known Anycast Addresses Approach - - The well-known anycast addresses approach is also a feasible and - simple mechanism for ISP [9]. The use of well-known anycast - addresses avoids some of the security risks in rogue messages sent - through an external protocol like RA or DHCPv6. The configuration of - hosts for the use of well-known anycast addresses requires no - protocol or manual configuration, but the configuration of routing - for the anycast addresses requires intervention on the part of the - network administrator. Also, the number of special addresses would - be equal to the number of RDNSSes that could be made available to - subscribers. - -5.2 Enterprise Network - - Enterprise network is defined as a network that has multiple internal - links, one or more router connections, to one or more Providers and - is actively managed by a network operations entity [16]. An - - - -Jeong Expires November 6, 2005 [Page 17] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - - enterprise network can get network prefixes from an ISP by either - manual configuration or prefix delegation [17]. In most cases, - because an enterprise network manages its own DNS domains, it - operates its own DNS servers for the domains. These DNS servers - within enterprise network process recursive DNS name resolution - requests from IPv6 hosts as RDNSSes. The RDNSS configuration in the - enterprise network can be performed like in Section 4, in which three - approaches can be used together as follows: - - 1. An IPv6 host can decide which approach is or may be used in its - subnet with the O flag in RA message [8][32]. As the first - choice in Section 4, well-known anycast addresses can be used as - a last resort when RDNSS information cannot be obtained through - either an RA option or DHCP option. This case needs IPv6 hosts - to preconfigure the well-known anycast addresses in their DNS - configuration files. - - 2. When the enterprise prefers the well-known anycast approach to - others, IPv6 hosts should preconfigure the well-known anycast - addresses like in the first choice. - - 3. The last choice, a more convenient and transparent way, does not - need IPv6 hosts to preconfigure the well-known anycast addresses - because the addresses are delivered to IPv6 hosts via either the - RA option or DHCPv6 option as if they were unicast addresses. - This way is most recommended for the sake of user's convenience. - - -5.3 3GPP Network - - The IPv6 DNS configuration is a missing part of IPv6 - autoconfiguration and an important part of the basic IPv6 - functionality in the 3GPP User Equipment (UE). The higher level - description of the 3GPP architecture can be found in [18], and - transition to IPv6 in 3GPP networks is analyzed in [19] and [20]. - - In the 3GPP architecture, there is a dedicated link between the UE - and the GGSN called the Packet Data Protocol (PDP) Context. This - link is created through the PDP Context activation procedure [21]. - There is a separate PDP context type for IPv4 and IPv6 traffic. If a - 3GPP UE user is communicating using IPv6 (having an active IPv6 PDP - context), it cannot be assumed that (s)he has simultaneously an - active IPv4 PDP context, and DNS queries could be done using IPv4. A - 3GPP UE can thus be an IPv6 node, and it needs to somehow discover - the address of the RDNSS. Before IP-based services (e.g., web - browsing or e-mail) can be used, the IPv6 (and IPv4) RDNSS addresses - need to be discovered in the 3GPP UE. - - - - -Jeong Expires November 6, 2005 [Page 18] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - - Section 5.3.1 briefly summarizes currently available mechanisms in - 3GPP networks and recommendations. 5.3.2 analyzes the Router - Advertisement based solution, 5.3.3 analyzes the Stateless DHCPv6 - mechanism, and 5.3.4 analyzes the Well-known addresses approach. - Section 5.3.5 finally summarizes the recommendations. - -5.3.1 Currently Available Mechanisms and Recommendations - - 3GPP has defined a mechanism, in which RDNSS addresses can be - received in the PDP context activation (a control plane mechanism). - That is called the Protocol Configuration Options Information Element - (PCO-IE) mechanism [22]. The RDNSS addresses can also be received - over the air (using text messages), or typed in manually in the UE. - Note that the two last mechanisms are not very well scalable. The UE - user most probably does not want to type IPv6 RDNSS addresses - manually in his/her UE. The use of well-known addresses is briefly - discussed in section 5.3.4. - - It is seen that the mechanisms above most probably are not sufficient - for the 3GPP environment. IPv6 is intended to operate in a zero- - configuration manner, no matter what the underlying network - infrastructure is. Typically, the RDNSS address is needed to make an - IPv6 node operational - and the DNS configuration should be as simple - as the address autoconfiguration mechanism. It must also be noted - that there will be additional IP interfaces in some near future 3GPP - UEs, e.g., WLAN, and 3GPP-specific DNS configuration mechanisms (such - as PCO-IE [22]) do not work for those IP interfaces. In other words, - a good IPv6 DNS configuration mechanism should also work in a multi- - access network environment. - - From a 3GPP point of view, the best IPv6 DNS configuration solution - is feasible for a very large number of IPv6-capable UEs (can be even - hundreds of millions in one operator's network), is automatic and - thus requires no user action. It is suggested to standardize a - lightweight, stateless mechanism that works in all network - environments. The solution could then be used for 3GPP, 3GPP2, WLAN - and other access network technologies. A light, stateless IPv6 DNS - configuration mechanism is thus not only needed in 3GPP networks, but - also 3GPP networks and UEs would certainly benefit from the new - mechanism. - -5.3.2 RA Extension - - Router Advertisement extension [8] is a lightweight IPv6 DNS - configuration mechanism that requires minor changes in the 3GPP UE - IPv6 stack and Gateway GPRS Support Node (GGSN, the default router in - the 3GPP architecture) IPv6 stack. This solution can be specified in - the IETF (no action needed in the 3GPP) and taken in use in 3GPP UEs - - - -Jeong Expires November 6, 2005 [Page 19] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - - and GGSNs - - In this solution, an IPv6-capable UE configures DNS information via - RA message sent by its default router (GGSN), i.e., RDNSS option for - recursive DNS server is included in the RA message. This solution is - easily scalable for a very large number of UEs. The operator can - configure the RDNSS addresses in the GGSN as a part of normal GGSN - configuration. The IPv6 RDNSS address is received in the Router - Advertisement, and an extra Round Trip Time (RTT) for asking RDNSS - addresses can be avoided. - - If thinking about the cons, this mechanism still requires - standardization effort in the IETF, and the end nodes and routers - need to support this mechanism. The equipment software update - should, however, be pretty straightforward, and new IPv6 equipment - could support RA extension already from the beginning. - -5.3.3 Stateless DHCPv6 - - DHCPv6-based solution needs the implementation of Stateless DHCP [6] - and DHCPv6 DNS options [7] in the UE, and a DHCPv6 server in the - operator's network. A possible configuration is such that the GGSN - works as a DHCP relay. - - Pros for Stateless DHCPv6-based solution are - - 1. Stateless DHCPv6 is a standardized mechanism. - - 2. DHCPv6 can be used for receiving other configuration information - than RDNSS addresses, e.g., SIP server addresses. - - 3. DHCPv6 works in different network environments. - - 4. When DHCPv6 service is deployed through a single, centralized - server, the RDNSS configuration information can be updated by the - network administrator at a single source. - - Some issues with DHCPv6 in 3GPP networks are listed below: - - 1. DHCPv6 requires an additional server in the network unless the - (Stateless) DHCPv6 functionality is integrated into a router - already existing, and that means one box more to be maintained. - - 2. DHCPv6 is not necessarily needed for 3GPP UE IPv6 addressing - (3GPP Stateless Address Autoconfiguration is typically used), and - not automatically implemented in 3GPP IPv6 UEs. - - - - - -Jeong Expires November 6, 2005 [Page 20] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - - 3. Scalability and reliability of DHCPv6 in very large 3GPP networks - (with tens or hundreds of millions of UEs) may be an issue, at - least the redundancy needs to be taken care of. However, if the - DHCPv6 service is integrated into the network elements, such as a - router operating system, scalability and reliability is - comparable with other DNS configuration approaches. - - 4. It is sub-optimal to utilize the radio resources in 3GPP networks - for DHCPv6 messages if there is a simpler alternative available. - - * The use of Stateless DHCPv6 adds one round trip delay to the - case in which the UE can start transmitting data right after - the Router Advertisement. - - 5. If the DNS information (suddenly) changes, Stateless DHCPv6 can - not automatically update the UE, see [23]. - - -5.3.4 Well-known Addresses - - Using well-known addresses is also a feasible and a light mechanism - for 3GPP UEs. Those well-known addresses can be preconfigured in the - UE software and the operator makes the corresponding configuration on - the network side. So this is a very easy mechanism for the UE, but - requires some configuration work in the network. When using well- - known addresses, UE forwards queries to any of the preconfigured - addresses. In the current proposal [9], IPv6 anycast addresses are - suggested. - -Note - - The IPv6 DNS configuration proposal based on the use of well-known - site-local addresses developed at the IPv6 Working Group was seen as - a feasible mechanism for 3GPP UEs, but opposition by some people in - the IETF and finally deprecating IPv6 site-local addresses made it - impossible to standardize it. Note that this mechanism is - implemented in some existing operating systems today (also in some - 3GPP UEs) as a last resort of IPv6 DNS configuration. - -5.3.5 Recommendations - - It is suggested that a lightweight, stateless DNS configuration - mechanism is specified as soon as possible. From a 3GPP UE and - network point of view, the Router Advertisement based mechanism looks - most promising. The sooner a light, stateless mechanism is - specified, the sooner we can get rid of using well-known site-local - addresses for IPv6 DNS configuration. - - - - -Jeong Expires November 6, 2005 [Page 21] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - -5.4 Unmanaged Network - - There are 4 deployment scenarios of interest in unmanaged networks - [24]: - - 1. A gateway which does not provide IPv6 at all; - - 2. A dual-stack gateway connected to a dual-stack ISP; - - 3. A dual-stack gateway connected to an IPv4-only ISP; and - - 4. A gateway connected to an IPv6-only ISP. - - -5.4.1 Case A: Gateway does not provide IPv6 at all - - In this case, the gateway does not provide IPv6; the ISP may or may - not provide IPv6. Automatic or Configured tunnels are the - recommended transition mechanisms for this scenario. - - The case where dual-stack hosts behind an NAT, that need access to an - IPv6 RDNSS, cannot be entirely ruled out. The DNS configuration - mechanism has to work over the tunnel, and the underlying tunneling - mechanism could be implementing NAT traversal. The tunnel server - assumes the role of a relay (both for DHCP and Well-known anycast - addresses approaches). - - RA-based mechanism is relatively straightforward in its operation, - assuming the tunnel server is also the IPv6 router emitting RAs. - Well-known anycast addresses approach seems also simple in operation - across the tunnel, but the deployment model using Well-known anycast - addresses in a tunneled environment is unclear or not well - understood. - -5.4.2 Case B: A dual-stack gateway connected to a dual-stack ISP - - This is similar to a typical IPv4 home user scenario, where DNS - configuration parameters are obtained using DHCP. Except that - Stateless DHCPv6 is used, as opposed to the IPv4 scenario where the - DHCP server is stateful (maintains the state for clients). - -5.4.3 Case C: A dual-stack gateway connected to an IPv4-only ISP - - This is similar to Case B. If a gateway provides IPv6 connectivity by - managing tunnels, then it is also supposed to provide access to an - RDNSS. Like this, the tunnel for IPv6 connectivity originates from - the dual-stack gateway instead of the host. - - - - -Jeong Expires November 6, 2005 [Page 22] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - -5.4.4 Case D: A gateway connected to an IPv6-only ISP - - This is similar to Case B. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Jeong Expires November 6, 2005 [Page 23] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - -6. Security Considerations - - As security requirements depend solely on applications and are - different application by application, there can be no generic - requirement defined at IP or application layer for DNS. - - However, it should be noted that cryptographic security requires - configured secret information that full autoconfiguration and - cryptographic security are mutually exclusive. People insisting on - secure full autoconfiguration will get false security, false - autoconfiguration or both. - - In some deployment scenarios [19], where cryptographic security is - required for applications, the secret information for the - cryptographic security is preconfigured through which application - specific configuration data, including those for DNS, can be securely - configured. It should be noted that if applications requiring - cryptographic security depend on DNS, the applications also require - cryptographic security to DNS. Therefore, the full autoconfiguration - of DNS is not acceptable. - - However, with full autoconfiguration, weaker but still reasonable - security is being widely accepted and will continue to be acceptable. - That is, with full autoconfiguration, which means there is no - cryptographic security for the autoconfiguration, it is already - assumed that the local environment is secure enough that the - information from the local autoconfiguration server has acceptable - security even without cryptographic security. Thus, the - communication between the local DNS client and local DNS server has - acceptable security. - - In autoconfiguring recursive servers, DNSSEC may be overkill, because - DNSSEC [29] needs the configuration and reconfiguration of clients at - root key roll-over [30][31]. Even if additional keys for secure key - roll-over are added at the initial configuration, they are as - vulnerable as the original keys to some forms of attacks, such as - social hacking. Another problem of using DNSSEC and - autoconfiguration together is that DNSSEC requires secure time, which - means secure communication with autoconfigured time servers, which - requires configured secret information. Therefore, in order that the - autoconfiguration may be secure, it requires configured secret - information. - - If DNSSEC [29] is used and the signatures are verified on the client - host, the misconfiguration of a DNS server may be simply denial of - service. Also, if local routing environment is not reliable, clients - may be directed to a false resolver with the same IP address as the - true one. - - - -Jeong Expires November 6, 2005 [Page 24] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - -6.1 RA Option - - The security of RA option for RDNSS is the same as the ND protocol - security [3][8]. The RA option does not add any new vulnerability. - - It should be noted that the vulnerability of ND is not worse and is a - subset of the attacks that any node attached to a LAN can do - independently of ND. A malicious node on a LAN can promiscuously - receive packets for any router's MAC address and send packets with - the router's MAC address as the source MAC address in the L2 header. - As a result, the L2 switches send packets addressed to the router to - the malicious node. Also, this attack can send redirects that tell - the hosts to send their traffic somewhere else. The malicious node - can send unsolicited RA or NA replies, answer RS or NS requests, etc. - All of this can be done independently of implementing ND. Therefore, - the RA option for RDNSS does not add to the vulnerability. - - Security issues regarding the ND protocol were discussed at IETF SEND - (Securing Neighbor Discovery) Working Group and RFC 3971 for the ND - security has been published [14]. - -6.2 DHCPv6 Option - - The DNS Recursive Name Server option may be used by an intruder DHCP - server to cause DHCP clients to send DNS queries to an intruder DNS - recursive name server [7]. The results of these misdirected DNS - queries may be used to spoof DNS names. - - To avoid attacks through the DNS Recursive Name Server option, the - DHCP client SHOULD require DHCP authentication (see section - "Authentication of DHCP messages" in RFC 3315 [5]) before installing - a list of DNS recursive name servers obtained through authenticated - DHCP. - -6.3 Well-known Anycast Addresses - - Well-known anycast addresses does not require configuration security - since there is no protocol [9]. - - The DNS server with the preconfigured addresses are still reasonably - reliable, if local environment is reasonably secure, that is, there - is no active attackers receiving queries to the anycast addresses of - the servers and reply to them. - - - - - - - - -Jeong Expires November 6, 2005 [Page 25] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - -7. Contributors - - Ralph Droms - Cisco Systems, Inc. - 1414 Massachusetts Ave. - Boxboro, MA 01719 - US - - Phone: +1 978 936 1674 - Email: rdroms@cisco.com - - - Robert M. Hinden - Nokia - 313 Fairchild Drive - Mountain View, CA 94043 - US - - Phone: +1 650 625 2004 - Email: bob.hinden@nokia.com - - - Ted Lemon - Nominum, Inc. - 950 Charter Street - Redwood City, CA 94043 - US - - Email: Ted.Lemon@nominum.com - - - Masataka Ohta - Tokyo Institute of Technology - 2-12-1, O-okayama, Meguro-ku - Tokyo 152-8552 - Japan - - Phone: +81 3 5734 3299 - Fax: +81 3 5734 3299 - Email: mohta@necom830.hpcl.titech.ac.jp - - - Soohong Daniel Park - Mobile Platform Laboratory, SAMSUNG Electronics - 416 Maetan-3dong, Yeongtong-Gu - Suwon, Gyeonggi-Do 443-742 - Korea - - - - -Jeong Expires November 6, 2005 [Page 26] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - - Phone: +82 31 200 4508 - Email: soohong.park@samsung.com - - - Suresh Satapati - Cisco Systems, Inc. - San Jose, CA 95134 - US - - Email: satapati@cisco.com - - - Juha Wiljakka - Nokia - Visiokatu 3 - FIN-33720, TAMPERE - Finland - - Phone: +358 7180 48372 - Email: juha.wiljakka@nokia.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Jeong Expires November 6, 2005 [Page 27] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - -8. Acknowledgements - - This draft has greatly benefited from inputs by David Meyer, Rob - Austein, Tatuya Jinmei, Pekka Savola, Tim Chown, Luc Beloeil, - Christian Huitema, Thomas Narten, Pascal Thubert, and Greg Daley. - Also, Tony Bonanno proofread this draft. The authors appreciate - their contribution. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Jeong Expires November 6, 2005 [Page 28] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - -9. References - -9.1 Normative References - - [1] Bradner, S., "IETF Rights in Contributions", RFC 3667, - February 2004. - - [2] Bradner, S., "Intellectual Property Rights in IETF Technology", - RFC 3668, February 2004. - - [3] Narten, T., Nordmark, E., and W. Simpson, "Neighbor Discovery - for IP Version 6 (IPv6)", RFC 2461, December 1998. - - [4] Thomson, S. and T. Narten, "IPv6 Stateless Address - Autoconfiguration", RFC 2462, December 1998. - - [5] Droms, R., Ed., "Dynamic Host Configuration Protocol for IPv6 - (DHCPv6)", RFC 3315, July 2003. - - [6] Droms, R., "Stateless Dynamic Host Configuration Protocol (DHCP) - Service for IPv6", RFC 3736, April 2004. - - [7] Droms, R., Ed., "DNS Configuration options for Dynamic Host - Configuration Protocol for IPv6 (DHCPv6)", RFC 3646, - December 2003. - -9.2 Informative References - - [8] Jeong, J., Park, S., Beloeil, L., and S. Madanapalli, "IPv6 DNS - Discovery based on Router Advertisement", - draft-jeong-dnsop-ipv6-dns-discovery-04.txt (Work in Progress), - February 2005. - - [9] Ohta, M., "Preconfigured DNS Server Addresses", - draft-ohta-preconfigured-dns-01.txt (Work in Progress), - February 2004. - - [10] Venaas, S., Chown, T., and B. Volz, "Information Refresh Time - Option for DHCPv6", draft-ietf-dhc-lifetime-03.txt (Work in - Progress), January 2005. - - [11] Partridge, C., Mendez, T., and W. Milliken, "Host Anycasting - Service", RFC 1546, November 1993. - - [12] Hinden, R. and S. Deering, "Internet Protocol Version 6 (IPv6) - Addressing Architecture", RFC 3513, April 2003. - - [13] Lind, M., Ed., "Scenarios and Analysis for Introduction IPv6 - - - -Jeong Expires November 6, 2005 [Page 29] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - - into ISP Networks", RFC 4029, March 2005. - - [14] Arkko, J., Ed., "SEcure Neighbor Discovery (SEND)", RFC 3971, - March 2005. - - [15] Droms, R. and W. Arbaugh, "Authentication for DHCP Messages", - RFC 3118, June 2001. - - [16] Bound, J., Ed., "IPv6 Enterprise Network Scenarios", - draft-ietf-v6ops-ent-scenarios-05.txt (Work in Progress), - July 2004. - - [17] Troan, O. and R. Droms, "IPv6 Prefix Options for Dynamic Host - Configuration Protocol (DHCP) version 6", RFC 3633, - December 2003. - - [18] Wasserman, M., Ed., "Recommendations for IPv6 in 3GPP - Standards", RFC 3314, September 2002. - - [19] Soininen, J., Ed., "Transition Scenarios for 3GPP Networks", - RFC 3574, August 2003. - - [20] Wiljakka, J., Ed., "Analysis on IPv6 Transition in 3GPP - Networks", draft-ietf-v6ops-3gpp-analysis-11.txt (Work in - Progress), October 2004. - - [21] 3GPP TS 23.060 V5.4.0, "General Packet Radio Service (GPRS); - Service description; Stage 2 (Release 5)", December 2002. - - [22] 3GPP TS 24.008 V5.8.0, "Mobile radio interface Layer 3 - specification; Core network protocols; Stage 3 (Release 5)", - June 2003. - - [23] Chown, T., Venaas, S., and A. Vijayabhaskar, "Renumbering - Requirements for Stateless DHCPv6", - draft-ietf-dhc-stateless-dhcpv6-renumbering-02.txt (Work in - Progress), October 2004. - - [24] Huitema, C., Ed., "Unmanaged Networks IPv6 Transition - Scenarios", RFC 3750, April 2004. - - [25] ANSI/IEEE Std 802.11, "Part 11: Wireless LAN Medium Access - Control (MAC) and Physical Layer (PHY) Specifications", - March 1999. - - [26] IEEE Std 802.11a, "Part 11: Wireless LAN Medium Access Control - (MAC) and Physical Layer (PHY) specifications: High-speed - Physical Layer in the 5 GHZ Band", September 1999. - - - -Jeong Expires November 6, 2005 [Page 30] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - - [27] IEEE Std 802.11b, "Part 11: Wireless LAN Medium Access Control - (MAC) and Physical Layer (PHY) specifications: Higher-Speed - Physical Layer Extension in the 2.4 GHz Band", September 1999. - - [28] IEEE P802.11g/D8.2, "Part 11: Wireless LAN Medium Access - Control (MAC) and Physical Layer (PHY) specifications: Further - Higher Data Rate Extension in the 2.4 GHz Band", April 2003. - - [29] Eastlake, D., "Domain Name System Security Extensions", - RFC 2535, March 1999. - - [30] Kolkman, O. and R. Gieben, "DNSSEC Operational Practices", - draft-ietf-dnsop-dnssec-operational-practices-03.txt (Work in - Progress), December 2004. - - [31] Guette, G. and O. Courtay, "Requirements for Automated Key - Rollover in DNSSEC", - draft-ietf-dnsop-key-rollover-requirements-02.txt (Work in - Progress), January 2005. - - [32] Park, S., Madanapalli, S., and T. Jinmei, "Considerations on M - and O Flags of IPv6 Router Advertisement", - draft-ietf-ipv6-ra-mo-flags-01.txt (Work in Progress), - March 2005. - - -Author's Address - - Jaehoon Paul Jeong (editor) - ETRI/Department of Computer Science and Engineering - University of Minnesota - 117 Pleasant Street SE - Minneapolis, MN 55455 - US - - Phone: +1 651 587 7774 - Fax: +1 612 625 2002 - Email: jjeong@cs.umn.edu - URI: http://www.cs.umn.edu/~jjeong/ - - - - - - - - - - - - -Jeong Expires November 6, 2005 [Page 31] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - -Appendix A. Link-layer Multicast Acknowledgements for RA Option - - One benefit of an RA option [8] is to be able to multicast the - advertisements, reducing the need for duplicated unicast - communications. - - However, some link-layers may not support this as well as others. - Consider, for example, WLAN networks where multicast is unreliable. - The unreliability problem is caused by lack of ACK for multicast, - especially on the path from the Access Point (AP) to the Station - (STA), which is specific to CSMA/CA of WLAN, such as IEEE 802.11 - a/b/g [25]-[28]. That is, a multicast packet is unacknowledged on - the path from the AP to the STA, but acknowledged in the reverse - direction from the STA to the AP [25]. For example, when a router is - placed at wired network connected to an AP, a host may sometimes not - receive RA message advertised through the AP. Therefore, the RA - option solution might not work well on a congested medium that uses - unreliable multicast for RA. - - The fact that this problem has not been addressed in Neighbor - Discovery [3] indicates that the extra link-layer acknowledgements - have not been considered a serious problem till now. - - A possible mitigation technique could be to map all-nodes link- local - multicast address to the link-layer broadcast address, and to rely on - the ND retransmissions for message delivery in order to achieve more - reliability. - - - - - - - - - - - - - - - - - - - - - - - - -Jeong Expires November 6, 2005 [Page 32] - -Internet-Draft IPv6 Host Configuration of DNS Server May 2005 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2005). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Jeong Expires November 6, 2005 [Page 33] - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsop-ipv6-dns-issues-11.txt b/contrib/bind9/doc/draft/draft-ietf-dnsop-ipv6-dns-issues-11.txt deleted file mode 100644 index 1276f9f..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsop-ipv6-dns-issues-11.txt +++ /dev/null @@ -1,1682 +0,0 @@ - - - - -DNS Operations WG A. Durand -Internet-Draft SUN Microsystems, Inc. -Expires: January 17, 2006 J. Ihren - Autonomica - P. Savola - CSC/FUNET - July 16, 2005 - - - Operational Considerations and Issues with IPv6 DNS - draft-ietf-dnsop-ipv6-dns-issues-11.txt - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on January 17, 2006. - -Copyright Notice - - Copyright (C) The Internet Society (2005). - -Abstract - - This memo presents operational considerations and issues with IPv6 - Domain Name System (DNS), including a summary of special IPv6 - addresses, documentation of known DNS implementation misbehaviour, - recommendations and considerations on how to perform DNS naming for - service provisioning and for DNS resolver IPv6 support, - - - -Durand, et al. Expires January 17, 2006 [Page 1] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - considerations for DNS updates for both the forward and reverse - trees, and miscellaneous issues. This memo is aimed to include a - summary of information about IPv6 DNS considerations for those who - have experience with IPv4 DNS. - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4 - 1.1 Representing IPv6 Addresses in DNS Records . . . . . . . . 4 - 1.2 Independence of DNS Transport and DNS Records . . . . . . 4 - 1.3 Avoiding IPv4/IPv6 Name Space Fragmentation . . . . . . . 5 - 1.4 Query Type '*' and A/AAAA Records . . . . . . . . . . . . 5 - 2. DNS Considerations about Special IPv6 Addresses . . . . . . . 5 - 2.1 Limited-scope Addresses . . . . . . . . . . . . . . . . . 6 - 2.2 Temporary Addresses . . . . . . . . . . . . . . . . . . . 6 - 2.3 6to4 Addresses . . . . . . . . . . . . . . . . . . . . . . 6 - 2.4 Other Transition Mechanisms . . . . . . . . . . . . . . . 6 - 3. Observed DNS Implementation Misbehaviour . . . . . . . . . . . 7 - 3.1 Misbehaviour of DNS Servers and Load-balancers . . . . . . 7 - 3.2 Misbehaviour of DNS Resolvers . . . . . . . . . . . . . . 7 - 4. Recommendations for Service Provisioning using DNS . . . . . . 7 - 4.1 Use of Service Names instead of Node Names . . . . . . . . 8 - 4.2 Separate vs the Same Service Names for IPv4 and IPv6 . . . 8 - 4.3 Adding the Records Only when Fully IPv6-enabled . . . . . 9 - 4.4 The Use of TTL for IPv4 and IPv6 RRs . . . . . . . . . . . 10 - 4.4.1 TTL With Courtesy Additional Data . . . . . . . . . . 10 - 4.4.2 TTL With Critical Additional Data . . . . . . . . . . 10 - 4.5 IPv6 Transport Guidelines for DNS Servers . . . . . . . . 11 - 5. Recommendations for DNS Resolver IPv6 Support . . . . . . . . 11 - 5.1 DNS Lookups May Query IPv6 Records Prematurely . . . . . . 11 - 5.2 Obtaining a List of DNS Recursive Resolvers . . . . . . . 13 - 5.3 IPv6 Transport Guidelines for Resolvers . . . . . . . . . 13 - 6. Considerations about Forward DNS Updating . . . . . . . . . . 13 - 6.1 Manual or Custom DNS Updates . . . . . . . . . . . . . . . 14 - 6.2 Dynamic DNS . . . . . . . . . . . . . . . . . . . . . . . 14 - 7. Considerations about Reverse DNS Updating . . . . . . . . . . 15 - 7.1 Applicability of Reverse DNS . . . . . . . . . . . . . . . 15 - 7.2 Manual or Custom DNS Updates . . . . . . . . . . . . . . . 16 - 7.3 DDNS with Stateless Address Autoconfiguration . . . . . . 16 - 7.4 DDNS with DHCP . . . . . . . . . . . . . . . . . . . . . . 18 - 7.5 DDNS with Dynamic Prefix Delegation . . . . . . . . . . . 18 - 8. Miscellaneous DNS Considerations . . . . . . . . . . . . . . . 19 - 8.1 NAT-PT with DNS-ALG . . . . . . . . . . . . . . . . . . . 19 - 8.2 Renumbering Procedures and Applications' Use of DNS . . . 19 - 9. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 20 - 10. Security Considerations . . . . . . . . . . . . . . . . . . 20 - 11. References . . . . . . . . . . . . . . . . . . . . . . . . . 20 - 11.1 Normative References . . . . . . . . . . . . . . . . . . . 20 - - - -Durand, et al. Expires January 17, 2006 [Page 2] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - 11.2 Informative References . . . . . . . . . . . . . . . . . . 22 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 24 - A. Unique Local Addressing Considerations for DNS . . . . . . . . 25 - B. Behaviour of Additional Data in IPv4/IPv6 Environments . . . . 25 - B.1 Description of Additional Data Scenarios . . . . . . . . . 26 - B.2 Which Additional Data to Keep, If Any? . . . . . . . . . . 27 - B.3 Discussion of the Potential Problems . . . . . . . . . . . 28 - Intellectual Property and Copyright Statements . . . . . . . . 30 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Durand, et al. Expires January 17, 2006 [Page 3] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - -1. Introduction - - This memo presents operational considerations and issues with IPv6 - DNS; it is meant to be an extensive summary and a list of pointers - for more information about IPv6 DNS considerations for those with - experience with IPv4 DNS. - - The purpose of this document is to give information about various - issues and considerations related to DNS operations with IPv6; it is - not meant to be a normative specification or standard for IPv6 DNS. - - The first section gives a brief overview of how IPv6 addresses and - names are represented in the DNS, how transport protocols and - resource records (don't) relate, and what IPv4/IPv6 name space - fragmentation means and how to avoid it; all of these are described - at more length in other documents. - - The second section summarizes the special IPv6 address types and how - they relate to DNS. The third section describes observed DNS - implementation misbehaviours which have a varying effect on the use - of IPv6 records with DNS. The fourth section lists recommendations - and considerations for provisioning services with DNS. The fifth - section in turn looks at recommendations and considerations about - providing IPv6 support in the resolvers. The sixth and seventh - sections describe considerations with forward and reverse DNS - updates, respectively. The eighth section introduces several - miscellaneous IPv6 issues relating to DNS for which no better place - has been found in this memo. Appendix A looks briefly at the - requirements for unique local addressing. - -1.1 Representing IPv6 Addresses in DNS Records - - In the forward zones, IPv6 addresses are represented using AAAA - records. In the reverse zones, IPv6 address are represented using - PTR records in the nibble format under the ip6.arpa. tree. See - [RFC3596] for more about IPv6 DNS usage, and [RFC3363] or [RFC3152] - for background information. - - In particular one should note that the use of A6 records in the - forward tree or Bitlabels in the reverse tree is not recommended - [RFC3363]. Using DNAME records is not recommended in the reverse - tree in conjunction with A6 records; the document did not mean to - take a stance on any other use of DNAME records [RFC3364]. - -1.2 Independence of DNS Transport and DNS Records - - DNS has been designed to present a single, globally unique name space - [RFC2826]. This property should be maintained, as described here and - - - -Durand, et al. Expires January 17, 2006 [Page 4] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - in Section 1.3. - - The IP version used to transport the DNS queries and responses is - independent of the records being queried: AAAA records can be queried - over IPv4, and A records over IPv6. The DNS servers must not make - any assumptions about what data to return for Answer and Authority - sections based on the underlying transport used in a query. - - However, there is some debate whether the addresses in Additional - section could be selected or filtered using hints obtained from which - transport was being used; this has some obvious problems because in - many cases the transport protocol does not correlate with the - requests, and because a "bad" answer is in a way worse than no answer - at all (consider the case where the client is led to believe that a - name received in the additional record does not have any AAAA records - at all). - - As stated in [RFC3596]: - - The IP protocol version used for querying resource records is - independent of the protocol version of the resource records; e.g., - IPv4 transport can be used to query IPv6 records and vice versa. - - -1.3 Avoiding IPv4/IPv6 Name Space Fragmentation - - To avoid the DNS name space from fragmenting into parts where some - parts of DNS are only visible using IPv4 (or IPv6) transport, the - recommendation is to always keep at least one authoritative server - IPv4-enabled, and to ensure that recursive DNS servers support IPv4. - See DNS IPv6 transport guidelines [RFC3901] for more information. - -1.4 Query Type '*' and A/AAAA Records - - QTYPE=* is typically only used for debugging or management purposes; - it is worth keeping in mind that QTYPE=* ("ANY" queries) only return - any available RRsets, not *all* the RRsets, because the caches do not - necessarily have all the RRsets and have no way of guaranteeing that - they have all the RRsets. Therefore, to get both A and AAAA records - reliably, two separate queries must be made. - -2. DNS Considerations about Special IPv6 Addresses - - There are a couple of IPv6 address types which are somewhat special; - these are considered here. - - - - - - -Durand, et al. Expires January 17, 2006 [Page 5] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - -2.1 Limited-scope Addresses - - The IPv6 addressing architecture [RFC3513] includes two kinds of - local-use addresses: link-local (fe80::/10) and site-local - (fec0::/10). The site-local addresses have been deprecated [RFC3879] - but are discussed with unique local addresses in Appendix A. - - Link-local addresses should never be published in DNS (whether in - forward or reverse tree), because they have only local (to the - connected link) significance [I-D.durand-dnsop-dont-publish]. - -2.2 Temporary Addresses - - Temporary addresses defined in RFC3041 [RFC3041] (sometimes called - "privacy addresses") use a random number as the interface identifier. - Having DNS AAAA records that are updated to always contain the - current value of a node's temporary address would defeat the purpose - of the mechanism and is not recommended. However, it would still be - possible to return a non-identifiable name (e.g., the IPv6 address in - hexadecimal format), as described in [RFC3041]. - -2.3 6to4 Addresses - - 6to4 [RFC3056] specifies an automatic tunneling mechanism which maps - a public IPv4 address V4ADDR to an IPv6 prefix 2002:V4ADDR::/48. - - If the reverse DNS population would be desirable (see Section 7.1 for - applicability), there are a number of possible ways to do so. - - The main proposal [I-D.huston-6to4-reverse-dns] aims to design an - autonomous reverse-delegation system that anyone being capable of - communicating using a specific 6to4 address would be able to set up a - reverse delegation to the corresponding 6to4 prefix. This could be - deployed by e.g., Regional Internet Registries (RIRs). This is a - practical solution, but may have some scalability concerns. - -2.4 Other Transition Mechanisms - - 6to4 is mentioned as a case of an IPv6 transition mechanism requiring - special considerations. In general, mechanisms which include a - special prefix may need a custom solution; otherwise, for example - when IPv4 address is embedded as the suffix or not embedded at all, - special solutions are likely not needed. - - Note that it does not seem feasible to provide reverse DNS with - another automatic tunneling mechanism, Teredo [I-D.huitema-v6ops- - teredo]; this is because the IPv6 address is based on the IPv4 - address and UDP port of the current NAT mapping which is likely to be - - - -Durand, et al. Expires January 17, 2006 [Page 6] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - relatively short-lived. - -3. Observed DNS Implementation Misbehaviour - - Several classes of misbehaviour in DNS servers, load-balancers and - resolvers have been observed. Most of these are rather generic, not - only applicable to IPv6 -- but in some cases, the consequences of - this misbehaviour are extremely severe in IPv6 environments and - deserve to be mentioned. - -3.1 Misbehaviour of DNS Servers and Load-balancers - - There are several classes of misbehaviour in certain DNS servers and - load-balancers which have been noticed and documented [RFC4074]: some - implementations silently drop queries for unimplemented DNS records - types, or provide wrong answers to such queries (instead of a proper - negative reply). While typically these issues are not limited to - AAAA records, the problems are aggravated by the fact that AAAA - records are being queried instead of (mainly) A records. - - The problems are serious because when looking up a DNS name, typical - getaddrinfo() implementations, with AF_UNSPEC hint given, first try - to query the AAAA records of the name, and after receiving a - response, query the A records. This is done in a serial fashion -- - if the first query is never responded to (instead of properly - returning a negative answer), significant timeouts will occur. - - In consequence, this is an enormous problem for IPv6 deployments, and - in some cases, IPv6 support in the software has even been disabled - due to these problems. - - The solution is to fix or retire those misbehaving implementations, - but that is likely not going to be effective. There are some - possible ways to mitigate the problem, e.g., by performing the - lookups somewhat in parallel and reducing the timeout as long as at - least one answer has been received; but such methods remain to be - investigated; slightly more on this is included in Section 5. - -3.2 Misbehaviour of DNS Resolvers - - Several classes of misbehaviour have also been noticed in DNS - resolvers [I-D.ietf-dnsop-bad-dns-res]. However, these do not seem - to directly impair IPv6 use, and are only referred to for - completeness. - -4. Recommendations for Service Provisioning using DNS - - When names are added in the DNS to facilitate a service, there are - - - -Durand, et al. Expires January 17, 2006 [Page 7] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - several general guidelines to consider to be able to do it as - smoothly as possible. - -4.1 Use of Service Names instead of Node Names - - It makes sense to keep information about separate services logically - separate in the DNS by using a different DNS hostname for each - service. There are several reasons for doing this, for example: - - o It allows more flexibility and ease for migration of (only a part - of) services from one node to another, - - o It allows configuring different properties (e.g., TTL) for each - service, and - - o It allows deciding separately for each service whether to publish - the IPv6 addresses or not (in cases where some services are more - IPv6-ready than others). - - Using SRV records [RFC2782] would avoid these problems. - Unfortunately, those are not sufficiently widely used to be - applicable in most cases. Hence an operation technique is to use - service names instead of node names (or, "hostnames"). This - operational technique is not specific to IPv6, but required to - understand the considerations described in Section 4.2 and - Section 4.3. - - For example, assume a node named "pobox.example.com" provides both - SMTP and IMAP service. Instead of configuring the MX records to - point at "pobox.example.com", and configuring the mail clients to - look up the mail via IMAP from "pobox.example.com", one could use - e.g., "smtp.example.com" for SMTP (for both message submission and - mail relaying between SMTP servers) and "imap.example.com" for IMAP. - Note that in the specific case of SMTP relaying, the server itself - must typically also be configured to know all its names to ensure - loops do not occur. DNS can provide a layer of indirection between - service names and where the service actually is, and using which - addresses. (Obviously, when wanting to reach a specific node, one - should use the hostname rather than a service name.) - -4.2 Separate vs the Same Service Names for IPv4 and IPv6 - - The service naming can be achieved in basically two ways: when a - service is named "service.example.com" for IPv4, the IPv6-enabled - service could either be added to "service.example.com", or added - separately under a different name, e.g., in a sub-domain, like, - "service.ipv6.example.com". - - - - -Durand, et al. Expires January 17, 2006 [Page 8] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - These two methods have different characteristics. Using a different - name allows for easier service piloting, minimizing the disturbance - to the "regular" users of IPv4 service; however, the service would - not be used transparently, without the user/application explicitly - finding it and asking for it -- which would be a disadvantage in most - cases. When the different name is under a sub-domain, if the - services are deployed within a restricted network (e.g., inside an - enterprise), it's possible to prefer them transparently, at least to - a degree, by modifying the DNS search path; however, this is a - suboptimal solution. Using the same service name is the "long-term" - solution, but may degrade performance for those clients whose IPv6 - performance is lower than IPv4, or does not work as well (see - Section 4.3 for more). - - In most cases, it makes sense to pilot or test a service using - separate service names, and move to the use of the same name when - confident enough that the service level will not degrade for the - users unaware of IPv6. - -4.3 Adding the Records Only when Fully IPv6-enabled - - The recommendation is that AAAA records for a service should not be - added to the DNS until all of following are true: - - 1. The address is assigned to the interface on the node. - - 2. The address is configured on the interface. - - 3. The interface is on a link which is connected to the IPv6 - infrastructure. - - In addition, if the AAAA record is added for the node, instead of - service as recommended, all the services of the node should be IPv6- - enabled prior to adding the resource record. - - For example, if an IPv6 node is isolated from an IPv6 perspective - (e.g., it is not connected to IPv6 Internet) constraint #3 would mean - that it should not have an address in the DNS. - - Consider the case of two dual-stack nodes, which both have IPv6 - enabled, but the server does not have (global) IPv6 connectivity. As - the client looks up the server's name, only A records are returned - (if the recommendations above are followed), and no IPv6 - communication, which would have been unsuccessful, is even attempted. - - The issues are not always so black-and-white. Usually it's important - that the service offered using both protocols is of roughly equal - quality, using the appropriate metrics for the service (e.g., - - - -Durand, et al. Expires January 17, 2006 [Page 9] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - latency, throughput, low packet loss, general reliability, etc.) -- - this is typically very important especially for interactive or real- - time services. In many cases, the quality of IPv6 connectivity may - not yet be equal to that of IPv4, at least globally -- this has to be - taken into consideration when enabling services. - -4.4 The Use of TTL for IPv4 and IPv6 RRs - - The behaviour of DNS caching when different TTL values are used for - different RRsets of the same name calls for explicit discussion. For - example, let's consider two unrelated zone fragments: - - example.com. 300 IN MX foo.example.com. - foo.example.com. 300 IN A 192.0.2.1 - foo.example.com. 100 IN AAAA 2001:db8::1 - - ... - - child.example.com. 300 IN NS ns.child.example.com. - ns.child.example.com. 300 IN A 192.0.2.1 - ns.child.example.com. 100 IN AAAA 2001:db8::1 - - In the former case, we have "courtesy" additional data; in the - latter, we have "critical" additional data. See more extensive - background discussion of additional data handling in Appendix B. - -4.4.1 TTL With Courtesy Additional Data - - When a caching resolver asks for the MX record of example.com, it - gets back "foo.example.com". It may also get back either one or both - of the A and AAAA records in the additional section. The resolver - must explicitly query for both A and AAAA records [RFC2821]. - - After 100 seconds, the AAAA record is removed from the cache(s) - because its TTL expired. It could be argued to be useful for the - caching resolvers to discard the A record when the shorter TTL (in - this case, for the AAAA record) expires; this would avoid the - situation where there would be a window of 200 seconds when - incomplete information is returned from the cache. Further argument - for discarding is that in the normal operation, the TTL values are so - high that very likely the incurred additional queries would not be - noticeable, compared to the obtained performance optimization. The - behaviour in this scenario is unspecified. - -4.4.2 TTL With Critical Additional Data - - The difference to courtesy additional data is that the A/AAAA records - served by the parent zone cannot be queried explicitly. Therefore - - - -Durand, et al. Expires January 17, 2006 [Page 10] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - after 100 seconds the AAAA record is removed from the cache(s), but - the A record remains. Queries for the remaining 200 seconds - (provided that there are no further queries from the parent which - could refresh the caches) only return the A record, leading to a - potential opererational situation with unreachable servers. - - Similar cache flushing strategies apply in this scenario; the record. - -4.5 IPv6 Transport Guidelines for DNS Servers - - As described in Section 1.3 and [RFC3901], there should continue to - be at least one authoritative IPv4 DNS server for every zone, even if - the zone has only IPv6 records. (Note that obviously, having more - servers with robust connectivity would be preferable, but this is the - minimum recommendation; also see [RFC2182].) - -5. Recommendations for DNS Resolver IPv6 Support - - When IPv6 is enabled on a node, there are several things to consider - to ensure that the process is as smooth as possible. - -5.1 DNS Lookups May Query IPv6 Records Prematurely - - The system library that implements the getaddrinfo() function for - looking up names is a critical piece when considering the robustness - of enabling IPv6; it may come in basically three flavours: - - 1. The system library does not know whether IPv6 has been enabled in - the kernel of the operating system: it may start looking up AAAA - records with getaddrinfo() and AF_UNSPEC hint when the system is - upgraded to a system library version which supports IPv6. - - 2. The system library might start to perform IPv6 queries with - getaddrinfo() only when IPv6 has been enabled in the kernel. - However, this does not guarantee that there exists any useful - IPv6 connectivity (e.g., the node could be isolated from the - other IPv6 networks, only having link-local addresses). - - 3. The system library might implement a toggle which would apply - some heuristics to the "IPv6-readiness" of the node before - starting to perform queries; for example, it could check whether - only link-local IPv6 address(es) exists, or if at least one - global IPv6 address exists. - - First, let us consider generic implications of unnecessary queries - for AAAA records: when looking up all the records in the DNS, AAAA - records are typically tried first, and then A records. These are - done in serial, and the A query is not performed until a response is - - - -Durand, et al. Expires January 17, 2006 [Page 11] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - received to the AAAA query. Considering the misbehaviour of DNS - servers and load-balancers, as described in Section 3.1, the look-up - delay for AAAA may incur additional unnecessary latency, and - introduce a component of unreliability. - - One option here could be to do the queries partially in parallel; for - example, if the final response to the AAAA query is not received in - 0.5 seconds, start performing the A query while waiting for the - result (immediate parallelism might be unoptimal, at least without - information sharing between the look-up threads, as that would - probably lead to duplicate non-cached delegation chain lookups). - - An additional concern is the address selection, which may, in some - circumstances, prefer AAAA records over A records even when the node - does not have any IPv6 connectivity [I-D.ietf-v6ops-v6onbydefault]. - In some cases, the implementation may attempt to connect or send a - datagram on a physical link [I-D.ietf-v6ops-onlinkassumption], - incurring very long protocol timeouts, instead of quickly failing - back to IPv4. - - Now, we can consider the issues specific to each of the three - possibilities: - - In the first case, the node performs a number of completely useless - DNS lookups as it will not be able to use the returned AAAA records - anyway. (The only exception is where the application desires to know - what's in the DNS, but not use the result for communication.) One - should be able to disable these unnecessary queries, for both latency - and reliability reasons. However, as IPv6 has not been enabled, the - connections to IPv6 addresses fail immediately, and if the - application is programmed properly, the application can fall - gracefully back to IPv4 [RFC4038]. - - The second case is similar to the first, except it happens to a - smaller set of nodes when IPv6 has been enabled but connectivity has - not been provided yet; similar considerations apply, with the - exception that IPv6 records, when returned, will be actually tried - first which may typically lead to long timeouts. - - The third case is a bit more complex: optimizing away the DNS lookups - with only link-locals is probably safe (but may be desirable with - different lookup services which getaddrinfo() may support), as the - link-locals are typically automatically generated when IPv6 is - enabled, and do not indicate any form of IPv6 connectivity. That is, - performing DNS lookups only when a non-link-local address has been - configured on any interface could be beneficial -- this would be an - indication that either the address has been configured either from a - router advertisement, DHCPv6 [RFC3315], or manually. Each would - - - -Durand, et al. Expires January 17, 2006 [Page 12] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - indicate at least some form of IPv6 connectivity, even though there - would not be guarantees of it. - - These issues should be analyzed at more depth, and the fixes found - consensus on, perhaps in a separate document. - -5.2 Obtaining a List of DNS Recursive Resolvers - - In scenarios where DHCPv6 is available, a host can discover a list of - DNS recursive resolvers through DHCPv6 "DNS Recursive Name Server" - option [RFC3646]. This option can be passed to a host through a - subset of DHCPv6 [RFC3736]. - - The IETF is considering the development of alternative mechanisms for - obtaining the list of DNS recursive name servers when DHCPv6 is - unavailable or inappropriate. No decision about taking on this - development work has been reached as of this writing (Aug 2004) - [I-D.ietf-dnsop-ipv6-dns-configuration]. - - In scenarios where DHCPv6 is unavailable or inappropriate, mechanisms - under consideration for development include the use of well-known - addresses [I-D.ohta-preconfigured-dns] and the use of Router - Advertisements to convey the information [I-D.jeong-dnsop-ipv6-dns- - discovery]. - - Note that even though IPv6 DNS resolver discovery is a recommended - procedure, it is not required for dual-stack nodes in dual-stack - networks as IPv6 DNS records can be queried over IPv4 as well as - IPv6. Obviously, nodes which are meant to function without manual - configuration in IPv6-only networks must implement the DNS resolver - discovery function. - -5.3 IPv6 Transport Guidelines for Resolvers - - As described in Section 1.3 and [RFC3901], the recursive resolvers - should be IPv4-only or dual-stack to be able to reach any IPv4-only - DNS server. Note that this requirement is also fulfilled by an IPv6- - only stub resolver pointing to a dual-stack recursive DNS resolver. - -6. Considerations about Forward DNS Updating - - While the topic of how to enable updating the forward DNS, i.e., the - mapping from names to the correct new addresses, is not specific to - IPv6, it should be considered especially due to the advent of - Stateless Address Autoconfiguration [RFC2462]. - - Typically forward DNS updates are more manageable than doing them in - the reverse DNS, because the updater can often be assumed to "own" a - - - -Durand, et al. Expires January 17, 2006 [Page 13] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - certain DNS name -- and we can create a form of security relationship - with the DNS name and the node which is allowed to update it to point - to a new address. - - A more complex form of DNS updates -- adding a whole new name into a - DNS zone, instead of updating an existing name -- is considered out - of scope for this memo as it could require zone-wide authentication. - Adding a new name in the forward zone is a problem which is still - being explored with IPv4, and IPv6 does not seem to add much new in - that area. - -6.1 Manual or Custom DNS Updates - - The DNS mappings can also be maintained by hand, in a semi-automatic - fashion or by running non-standardized protocols. These are not - considered at more length in this memo. - -6.2 Dynamic DNS - - Dynamic DNS updates (DDNS) [RFC2136] [RFC3007] is a standardized - mechanism for dynamically updating the DNS. It works equally well - with stateless address autoconfiguration (SLAAC), DHCPv6 or manual - address configuration. It is important to consider how each of these - behave if IP address-based authentication, instead of stronger - mechanisms [RFC3007], was used in the updates. - - 1. manual addresses are static and can be configured - - 2. DHCPv6 addresses could be reasonably static or dynamic, depending - on the deployment, and could or could not be configured on the - DNS server for the long term - - 3. SLAAC addresses are typically stable for a long time, but could - require work to be configured and maintained. - - As relying on IP addresses for Dynamic DNS is rather insecure at - best, stronger authentication should always be used; however, this - requires that the authorization keying will be explicitly configured - using unspecified operational methods. - - Note that with DHCP it is also possible that the DHCP server updates - the DNS, not the host. The host might only indicate in the DHCP - exchange which hostname it would prefer, and the DHCP server would - make the appropriate updates. Nonetheless, while this makes setting - up a secure channel between the updater and the DNS server easier, it - does not help much with "content" security, i.e., whether the - hostname was acceptable -- if the DNS server does not include - policies, they must be included in the DHCP server (e.g., a regular - - - -Durand, et al. Expires January 17, 2006 [Page 14] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - host should not be able to state that its name is "www.example.com"). - DHCP-initiated DDNS updates have been extensively described in - [I-D.ietf-dhc-ddns-resolution], [I-D.ietf-dhc-fqdn-option] and - [I-D.ietf-dnsext-dhcid-rr]. - - The nodes must somehow be configured with the information about the - servers where they will attempt to update their addresses, sufficient - security material for authenticating themselves to the server, and - the hostname they will be updating. Unless otherwise configured, the - first could be obtained by looking up the authoritative name servers - for the hostname; the second must be configured explicitly unless one - chooses to trust the IP address-based authentication (not a good - idea); and lastly, the nodename is typically pre-configured somehow - on the node, e.g., at install time. - - Care should be observed when updating the addresses not to use longer - TTLs for addresses than are preferred lifetimes for the addresses, so - that if the node is renumbered in a managed fashion, the amount of - stale DNS information is kept to the minimum. That is, if the - preferred lifetime of an address expires, the TTL of the record needs - be modified unless it was already done before the expiration. For - better flexibility, the DNS TTL should be much shorter (e.g., a half - or a third) than the lifetime of an address; that way, the node can - start lowering the DNS TTL if it seems like the address has not been - renewed/refreshed in a while. Some discussion on how an - administrator could manage the DNS TTL is included in [I-D.ietf- - v6ops-renumbering-procedure]; this could be applied to (smart) hosts - as well. - -7. Considerations about Reverse DNS Updating - - Updating the reverse DNS zone may be difficult because of the split - authority over an address. However, first we have to consider the - applicability of reverse DNS in the first place. - -7.1 Applicability of Reverse DNS - - Today, some applications use reverse DNS to either look up some hints - about the topological information associated with an address (e.g. - resolving web server access logs), or as a weak form of a security - check, to get a feel whether the user's network administrator has - "authorized" the use of the address (on the premises that adding a - reverse record for an address would signal some form of - authorization). - - One additional, maybe slightly more useful usage is ensuring that the - reverse and forward DNS contents match (by looking up the pointer to - the name by the IP address from the reverse tree, and ensuring that a - - - -Durand, et al. Expires January 17, 2006 [Page 15] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - record under the name in the forward tree points to the IP address) - and correspond to a configured name or domain. As a security check, - it is typically accompanied by other mechanisms, such as a user/ - password login; the main purpose of the reverse+forward DNS check is - to weed out the majority of unauthorized users, and if someone - managed to bypass the checks, he would still need to authenticate - "properly". - - It may also be desirable to store IPsec keying material corresponding - to an IP address in the reverse DNS, as justified and described in - [RFC4025]. - - It is not clear whether it makes sense to require or recommend that - reverse DNS records be updated. In many cases, it would just make - more sense to use proper mechanisms for security (or topological - information lookup) in the first place. At minimum, the applications - which use it as a generic authorization (in the sense that a record - exists at all) should be modified as soon as possible to avoid such - lookups completely. - - The applicability is discussed at more length in [I-D.ietf-dnsop- - inaddr-required]. - -7.2 Manual or Custom DNS Updates - - Reverse DNS can of course be updated using manual or custom methods. - These are not further described here, except for one special case. - - One way to deploy reverse DNS would be to use wildcard records, for - example, by configuring one name for a subnet (/64) or a site (/48). - As a concrete example, a site (or the site's ISP) could configure the - reverses of the prefix 2001:db8:f00::/48 to point to one name using a - wildcard record like "*.0.0.f.0.8.b.d.0.1.0.0.2.ip6.arpa. IN PTR - site.example.com." Naturally, such a name could not be verified from - the forward DNS, but would at least provide some form of "topological - information" or "weak authorization" if that is really considered to - be useful. Note that this is not actually updating the DNS as such, - as the whole point is to avoid DNS updates completely by manually - configuring a generic name. - -7.3 DDNS with Stateless Address Autoconfiguration - - Dynamic reverse DNS with SLAAC is simpler than forward DNS updates in - some regard, while being more difficult in another, as described - below. - - The address space administrator decides whether the hosts are trusted - to update their reverse DNS records or not. If they are trusted and - - - -Durand, et al. Expires January 17, 2006 [Page 16] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - deployed at the same site (e.g., not across the Internet), a simple - address-based authorization is typically sufficient (i.e., check that - the DNS update is done from the same IP address as the record being - updated); stronger security can also be used [RFC3007]. If they - aren't allowed to update the reverses, no update can occur. However, - such address-based update authorization operationally requires that - ingress filtering [RFC3704] has been set up at the border of the site - where the updates occur, and as close to the updater as possible. - - Address-based authorization is simpler with reverse DNS (as there is - a connection between the record and the address) than with forward - DNS. However, when a stronger form of security is used, forward DNS - updates are simpler to manage because the host can be assumed to have - an association with the domain. Note that the user may roam to - different networks, and does not necessarily have any association - with the owner of that address space -- so, assuming stronger form of - authorization for reverse DNS updates than an address association is - generally infeasible. - - Moreover, the reverse zones must be cleaned up by an unspecified - janitorial process: the node does not typically know a priori that it - will be disconnected, and cannot send a DNS update using the correct - source address to remove a record. - - A problem with defining the clean-up process is that it is difficult - to ensure that a specific IP address and the corresponding record are - no longer being used. Considering the huge address space, and the - unlikelihood of collision within 64 bits of the interface - identifiers, a process which would remove the record after no traffic - has been seen from a node in a long period of time (e.g., a month or - year) might be one possible approach. - - To insert or update the record, the node must discover the DNS server - to send the update to somehow, similar to as discussed in - Section 6.2. One way to automate this is looking up the DNS server - authoritative (e.g., through SOA record) for the IP address being - updated, but the security material (unless the IP address-based - authorization is trusted) must also be established by some other - means. - - One should note that Cryptographically Generated Addresses [RFC3972] - (CGAs) may require a slightly different kind of treatment. CGAs are - addresses where the interface identifier is calculated from a public - key, a modifier (used as a nonce), the subnet prefix, and other data. - Depending on the usage profile, CGAs might or might not be changed - periodically due to e.g., privacy reasons. As the CGA address is not - predicatable, a reverse record can only reasonably be inserted in the - DNS by the node which generates the address. - - - -Durand, et al. Expires January 17, 2006 [Page 17] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - -7.4 DDNS with DHCP - - With DHCPv4, the reverse DNS name is typically already inserted to - the DNS that reflects to the name (e.g., "dhcp-67.example.com"). One - can assume similar practice may become commonplace with DHCPv6 as - well; all such mappings would be pre-configured, and would require no - updating. - - If a more explicit control is required, similar considerations as - with SLAAC apply, except for the fact that typically one must update - a reverse DNS record instead of inserting one (if an address - assignment policy that reassigns disused addresses is adopted) and - updating a record seems like a slightly more difficult thing to - secure. However, it is yet uncertain how DHCPv6 is going to be used - for address assignment. - - Note that when using DHCP, either the host or the DHCP server could - perform the DNS updates; see the implications in Section 6.2. - - If disused addresses were to be reassigned, host-based DDNS reverse - updates would need policy considerations for DNS record modification, - as noted above. On the other hand, if disused address were not to be - assigned, host-based DNS reverse updates would have similar - considerations as SLAAC in Section 7.3. Server-based updates have - similar properties except that the janitorial process could be - integrated with DHCP address assignment. - -7.5 DDNS with Dynamic Prefix Delegation - - In cases where a prefix, instead of an address, is being used and - updated, one should consider what is the location of the server where - DDNS updates are made. That is, where the DNS server is located: - - 1. At the same organization as the prefix delegator. - - 2. At the site where the prefixes are delegated to. In this case, - the authority of the DNS reverse zone corresponding to the - delegated prefix is also delegated to the site. - - 3. Elsewhere; this implies a relationship between the site and where - DNS server is located, and such a relationship should be rather - straightforward to secure as well. Like in the previous case, - the authority of the DNS reverse zone is also delegated. - - In the first case, managing the reverse DNS (delegation) is simpler - as the DNS server and the prefix delegator are in the same - administrative domain (as there is no need to delegate anything at - all); alternatively, the prefix delegator might forgo DDNS reverse - - - -Durand, et al. Expires January 17, 2006 [Page 18] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - capability altogether, and use e.g., wildcard records (as described - in Section 7.2). In the other cases, it can be slighly more - difficult, particularly as the site will have to configure the DNS - server to be authoritative for the delegated reverse zone, implying - automatic configuration of the DNS server -- as the prefix may be - dynamic. - - Managing the DDNS reverse updates is typically simple in the second - case, as the updated server is located at the local site, and - arguably IP address-based authentication could be sufficient (or if - not, setting up security relationships would be simpler). As there - is an explicit (security) relationship between the parties in the - third case, setting up the security relationships to allow reverse - DDNS updates should be rather straightforward as well (but IP - address-based authentication might not be acceptable). In the first - case, however, setting up and managing such relationships might be a - lot more difficult. - -8. Miscellaneous DNS Considerations - - This section describes miscellaneous considerations about DNS which - seem related to IPv6, for which no better place has been found in - this document. - -8.1 NAT-PT with DNS-ALG - - The DNS-ALG component of NAT-PT mangles A records to look like AAAA - records to the IPv6-only nodes. Numerous problems have been - identified with DNS-ALG [I-D.ietf-v6ops-natpt-to-exprmntl]. This is - a strong reason not to use NAT-PT in the first place. - -8.2 Renumbering Procedures and Applications' Use of DNS - - One of the most difficult problems of systematic IP address - renumbering procedures [I-D.ietf-v6ops-renumbering-procedure] is that - an application which looks up a DNS name disregards information such - as TTL, and uses the result obtained from DNS as long as it happens - to be stored in the memory of the application. For applications - which run for a long time, this could be days, weeks or even months; - some applications may be clever enough to organize the data - structures and functions in such a manner that look-ups get refreshed - now and then. - - While the issue appears to have a clear solution, "fix the - applications", practically this is not reasonable immediate advice; - the TTL information is not typically available in the APIs and - libraries (so, the advice becomes "fix the applications, APIs and - libraries"), and a lot more analysis is needed on how to practically - - - -Durand, et al. Expires January 17, 2006 [Page 19] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - go about to achieve the ultimate goal of avoiding using the names - longer than expected. - -9. Acknowledgements - - Some recommendations (Section 4.3, Section 5.1) about IPv6 service - provisioning were moved here from [I-D.ietf-v6ops-mech-v2] by Erik - Nordmark and Bob Gilligan. Havard Eidnes and Michael Patton provided - useful feedback and improvements. Scott Rose, Rob Austein, Masataka - Ohta, and Mark Andrews helped in clarifying the issues regarding - additional data and the use of TTL. Jefsey Morfin, Ralph Droms, - Peter Koch, Jinmei Tatuya, Iljitsch van Beijnum, Edward Lewis, and - Rob Austein provided useful feedback during the WG last call. Thomas - Narten provided extensive feedback during the IESG evaluation. - -10. Security Considerations - - This document reviews the operational procedures for IPv6 DNS - operations and does not have security considerations in itself. - - However, it is worth noting that in particular with Dynamic DNS - Updates, security models based on the source address validation are - very weak and cannot be recommended -- they could only be considered - in the environments where ingress filtering [RFC3704] has been - deployed. On the other hand, it should be noted that setting up an - authorization mechanism (e.g., a shared secret, or public-private - keys) between a node and the DNS server has to be done manually, and - may require quite a bit of time and expertise. - - To re-emphasize what was already stated, the reverse+forward DNS - check provides very weak security at best, and the only - (questionable) security-related use for them may be in conjunction - with other mechanisms when authenticating a user. - -11. References - -11.1 Normative References - - [I-D.ietf-dnsop-ipv6-dns-configuration] - Jeong, J., "IPv6 Host Configuration of DNS Server - Information Approaches", - draft-ietf-dnsop-ipv6-dns-configuration-06 (work in - progress), May 2005. - - [I-D.ietf-ipv6-unique-local-addr] - Hinden, R. and B. Haberman, "Unique Local IPv6 Unicast - Addresses", draft-ietf-ipv6-unique-local-addr-09 (work in - progress), January 2005. - - - -Durand, et al. Expires January 17, 2006 [Page 20] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - [I-D.ietf-v6ops-renumbering-procedure] - Baker, F., "Procedures for Renumbering an IPv6 Network - without a Flag Day", - draft-ietf-v6ops-renumbering-procedure-05 (work in - progress), March 2005. - - [RFC1034] Mockapetris, P., "Domain names - concepts and facilities", - STD 13, RFC 1034, November 1987. - - [RFC2136] Vixie, P., Thomson, S., Rekhter, Y., and J. Bound, - "Dynamic Updates in the Domain Name System (DNS UPDATE)", - RFC 2136, April 1997. - - [RFC2181] Elz, R. and R. Bush, "Clarifications to the DNS - Specification", RFC 2181, July 1997. - - [RFC2182] Elz, R., Bush, R., Bradner, S., and M. Patton, "Selection - and Operation of Secondary DNS Servers", BCP 16, RFC 2182, - July 1997. - - [RFC2462] Thomson, S. and T. Narten, "IPv6 Stateless Address - Autoconfiguration", RFC 2462, December 1998. - - [RFC2671] Vixie, P., "Extension Mechanisms for DNS (EDNS0)", - RFC 2671, August 1999. - - [RFC2821] Klensin, J., "Simple Mail Transfer Protocol", RFC 2821, - April 2001. - - [RFC3007] Wellington, B., "Secure Domain Name System (DNS) Dynamic - Update", RFC 3007, November 2000. - - [RFC3041] Narten, T. and R. Draves, "Privacy Extensions for - Stateless Address Autoconfiguration in IPv6", RFC 3041, - January 2001. - - [RFC3056] Carpenter, B. and K. Moore, "Connection of IPv6 Domains - via IPv4 Clouds", RFC 3056, February 2001. - - [RFC3152] Bush, R., "Delegation of IP6.ARPA", BCP 49, RFC 3152, - August 2001. - - [RFC3315] Droms, R., Bound, J., Volz, B., Lemon, T., Perkins, C., - and M. Carney, "Dynamic Host Configuration Protocol for - IPv6 (DHCPv6)", RFC 3315, July 2003. - - [RFC3363] Bush, R., Durand, A., Fink, B., Gudmundsson, O., and T. - Hain, "Representing Internet Protocol version 6 (IPv6) - - - -Durand, et al. Expires January 17, 2006 [Page 21] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - Addresses in the Domain Name System (DNS)", RFC 3363, - August 2002. - - [RFC3364] Austein, R., "Tradeoffs in Domain Name System (DNS) - Support for Internet Protocol version 6 (IPv6)", RFC 3364, - August 2002. - - [RFC3513] Hinden, R. and S. Deering, "Internet Protocol Version 6 - (IPv6) Addressing Architecture", RFC 3513, April 2003. - - [RFC3596] Thomson, S., Huitema, C., Ksinant, V., and M. Souissi, - "DNS Extensions to Support IP Version 6", RFC 3596, - October 2003. - - [RFC3646] Droms, R., "DNS Configuration options for Dynamic Host - Configuration Protocol for IPv6 (DHCPv6)", RFC 3646, - December 2003. - - [RFC3736] Droms, R., "Stateless Dynamic Host Configuration Protocol - (DHCP) Service for IPv6", RFC 3736, April 2004. - - [RFC3879] Huitema, C. and B. Carpenter, "Deprecating Site Local - Addresses", RFC 3879, September 2004. - - [RFC3901] Durand, A. and J. Ihren, "DNS IPv6 Transport Operational - Guidelines", BCP 91, RFC 3901, September 2004. - - [RFC4038] Shin, M-K., Hong, Y-G., Hagino, J., Savola, P., and E. - Castro, "Application Aspects of IPv6 Transition", - RFC 4038, March 2005. - - [RFC4074] Morishita, Y. and T. Jinmei, "Common Misbehavior Against - DNS Queries for IPv6 Addresses", RFC 4074, May 2005. - -11.2 Informative References - - [I-D.durand-dnsop-dont-publish] - Durand, A. and T. Chown, "To publish, or not to publish, - that is the question.", draft-durand-dnsop-dont-publish-00 - (work in progress), February 2005. - - [I-D.huitema-v6ops-teredo] - Huitema, C., "Teredo: Tunneling IPv6 over UDP through - NATs", draft-huitema-v6ops-teredo-05 (work in progress), - April 2005. - - [I-D.huston-6to4-reverse-dns] - Huston, G., "6to4 Reverse DNS Delegation", - - - -Durand, et al. Expires January 17, 2006 [Page 22] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - draft-huston-6to4-reverse-dns-03 (work in progress), - October 2004. - - [I-D.ietf-dhc-ddns-resolution] - Stapp, M. and B. Volz, "Resolution of FQDN Conflicts among - DHCP Clients", draft-ietf-dhc-ddns-resolution-09 (work in - progress), June 2005. - - [I-D.ietf-dhc-fqdn-option] - Stapp, M. and Y. Rekhter, "The DHCP Client FQDN Option", - draft-ietf-dhc-fqdn-option-10 (work in progress), - February 2005. - - [I-D.ietf-dnsext-dhcid-rr] - Stapp, M., Lemon, T., and A. Gustafsson, "A DNS RR for - encoding DHCP information (DHCID RR)", - draft-ietf-dnsext-dhcid-rr-09 (work in progress), - February 2005. - - [I-D.ietf-dnsop-bad-dns-res] - Larson, M. and P. Barber, "Observed DNS Resolution - Misbehavior", draft-ietf-dnsop-bad-dns-res-03 (work in - progress), October 2004. - - [I-D.ietf-dnsop-inaddr-required] - Senie, D., "Encouraging the use of DNS IN-ADDR Mapping", - draft-ietf-dnsop-inaddr-required-06 (work in progress), - February 2005. - - [I-D.ietf-v6ops-3gpp-analysis] - Wiljakka, J., "Analysis on IPv6 Transition in 3GPP - Networks", draft-ietf-v6ops-3gpp-analysis-11 (work in - progress), October 2004. - - [I-D.ietf-v6ops-mech-v2] - Nordmark, E. and R. Gilligan, "Basic Transition Mechanisms - for IPv6 Hosts and Routers", draft-ietf-v6ops-mech-v2-07 - (work in progress), March 2005. - - [I-D.ietf-v6ops-natpt-to-exprmntl] - Aoun, C. and E. Davies, "Reasons to Move NAT-PT to - Experimental", draft-ietf-v6ops-natpt-to-exprmntl-01 (work - in progress), July 2005. - - [I-D.ietf-v6ops-onlinkassumption] - Roy, S., "IPv6 Neighbor Discovery On-Link Assumption - Considered Harmful", draft-ietf-v6ops-onlinkassumption-03 - (work in progress), May 2005. - - - -Durand, et al. Expires January 17, 2006 [Page 23] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - [I-D.ietf-v6ops-v6onbydefault] - Roy, S., Durand, A., and J. Paugh, "Issues with Dual Stack - IPv6 on by Default", draft-ietf-v6ops-v6onbydefault-03 - (work in progress), July 2004. - - [I-D.jeong-dnsop-ipv6-dns-discovery] - Jeong, J., "IPv6 DNS Configuration based on Router - Advertisement", draft-jeong-dnsop-ipv6-dns-discovery-04 - (work in progress), February 2005. - - [I-D.ohta-preconfigured-dns] - Ohta, M., "Preconfigured DNS Server Addresses", - draft-ohta-preconfigured-dns-01 (work in progress), - February 2004. - - [RFC2766] Tsirtsis, G. and P. Srisuresh, "Network Address - Translation - Protocol Translation (NAT-PT)", RFC 2766, - February 2000. - - [RFC2782] Gulbrandsen, A., Vixie, P., and L. Esibov, "A DNS RR for - specifying the location of services (DNS SRV)", RFC 2782, - February 2000. - - [RFC2826] Internet Architecture Board, "IAB Technical Comment on the - Unique DNS Root", RFC 2826, May 2000. - - [RFC3704] Baker, F. and P. Savola, "Ingress Filtering for Multihomed - Networks", BCP 84, RFC 3704, March 2004. - - [RFC3972] Aura, T., "Cryptographically Generated Addresses (CGA)", - RFC 3972, March 2005. - - [RFC4025] Richardson, M., "A Method for Storing IPsec Keying - Material in DNS", RFC 4025, March 2005. - - -Authors' Addresses - - Alain Durand - SUN Microsystems, Inc. - 17 Network circle UMPL17-202 - Menlo Park, CA 94025 - USA - - Email: Alain.Durand@sun.com - - - - - - -Durand, et al. Expires January 17, 2006 [Page 24] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - Johan Ihren - Autonomica - Bellmansgatan 30 - SE-118 47 Stockholm - Sweden - - Email: johani@autonomica.se - - - Pekka Savola - CSC/FUNET - Espoo - Finland - - Email: psavola@funet.fi - -Appendix A. Unique Local Addressing Considerations for DNS - - Unique local addresses [I-D.ietf-ipv6-unique-local-addr] have - replaced the now-deprecated site-local addresses [RFC3879]. From the - perspective of the DNS, the locally generated unique local addresses - (LUL) and site-local addresses have similar properties. - - The interactions with DNS come in two flavors: forward and reverse - DNS. - - To actually use local addresses within a site, this implies the - deployment of a "split-faced" or a fragmented DNS name space, for the - zones internal to the site, and the outsiders' view to it. The - procedures to achieve this are not elaborated here. The implication - is that local addresses must not be published in the public DNS. - - To faciliate reverse DNS (if desired) with local addresses, the stub - resolvers must look for DNS information from the local DNS servers, - not e.g. starting from the root servers, so that the local - information may be provided locally. Note that the experience of - private addresses in IPv4 has shown that the root servers get loaded - for requests for private address lookups in any case. This - requirement is discussed in [I-D.ietf-ipv6-unique-local-addr]. - -Appendix B. Behaviour of Additional Data in IPv4/IPv6 Environments - - DNS responses do not always fit in a single UDP packet. We'll - examine the cases which happen when this is due to too much data in - the Additional Section. - - - - - - -Durand, et al. Expires January 17, 2006 [Page 25] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - -B.1 Description of Additional Data Scenarios - - There are two kinds of additional data: - - 1. "critical" additional data; this must be included in all - scenarios, with all the RRsets, and - - 2. "courtesy" additional data; this could be sent in full, with only - a few RRsets, or with no RRsets, and can be fetched separately as - well, but at the cost of additional queries. - - The responding server can algorithmically determine which type the - additional data is by checking whether it's at or below a zone cut. - - Only those additional data records (even if sometimes carelessly - termed "glue") are considered "critical" or real "glue" if and only - if they meet the abovementioned condition, as specified in Section - 4.2.1 of [RFC1034]. - - Remember that resource record sets (RRsets) are never "broken up", so - if a name has 4 A records and 5 AAAA records, you can either return - all 9, all 4 A records, all 5 AAAA records or nothing. In - particular, notice that for the "critical" additional data getting - all the RRsets can be critical. - - In particular, [RFC2181] specifies (in Section 9) that: - - a. if all the "critical" RRsets do not fit, the sender should set - the TC bit, and the recipient should discard the whole response - and retry using mechanism allowing larger responses such as TCP. - - b. "courtesy" additional data should not cause the setting of TC - bit, but instead all the non-fitting additional data RRsets - should be removed. - - An example of the "courtesy" additional data is A/AAAA records in - conjunction with MX records as shown in Section 4.4; an example of - the "critical" additional data is shown below (where getting both the - A and AAAA RRsets is critical w.r.t. to the NS RR): - - child.example.com. IN NS ns.child.example.com. - ns.child.example.com. IN A 192.0.2.1 - ns.child.example.com. IN AAAA 2001:db8::1 - - When there is too much "courtesy" additional data, at least the non- - fitting RRsets should be removed [RFC2181]; however, as the - additional data is not critical, even all of it could be safely - removed. - - - -Durand, et al. Expires January 17, 2006 [Page 26] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - When there is too much "critical" additional data, TC bit will have - to be set, and the recipient should ignore the response and retry - using TCP; if some data were to be left in the UDP response, the - issue is which data could be retained. - - Failing to discard the response with TC bit or omitting critical - information but not setting TC bit lead to an unrecoverable problem. - Omitting only some of the RRsets if all would not fit (but not - setting TC bit) leads to a performance problem. These are discussed - in the next two subsections. - -B.2 Which Additional Data to Keep, If Any? - - If the implementation decides to keep as much data (whether - "critical" or "courtesy") as possible in the UDP responses, it might - be tempting to use the transport of the DNS query as a hint in either - of these cases: return the AAAA records if the query was done over - IPv6, or return the A records if the query was done over IPv4. - However, this breaks the model of independence of DNS transport and - resource records, as noted in Section 1.2. - - With courtesy additional data, as long as enough RRsets will be - removed so that TC will not be set, it is allowed to send as many - complete RRsets as the implementations prefers. However, the - implementations are also free to omit all such RRsets, even if - complete. Omitting all the RRsets (when removing only some would - suffice) may create a performance penalty, whereby the client may - need to issue one or more additional queries to obtain necessary - and/or consistent information. - - With critical additional data, the alternatives are either returning - nothing (and absolutely requiring a retry with TCP) or returning - something (working also in the case if the recipient does not discard - the response and retry using TCP) in addition to setting the TC bit. - If the process for selecting "something" from the critical data would - otherwise be practically "flipping the coin" between A and AAAA - records, it could be argued that if one looked at the transport of - the query, it would have a larger possibility of being right than - just 50/50. In other words, if the returned critical additional data - would have to be selected somehow, using something more sophisticated - than a random process would seem justifiable. - - That is, leaving in some intelligently selected critical additional - data is a tradeoff between creating an optimization for those - resolvers which ignore the "should discard" recommendation, and - causing a protocol problem by propagating inconsistent information - about "critical" records in the caches. - - - - -Durand, et al. Expires January 17, 2006 [Page 27] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - Similarly, leaving in the complete courtesy additional data RRsets - instead of removing all the RRsets is a performance tradeoff as - described in the next section. - -B.3 Discussion of the Potential Problems - - As noted above, the temptation for omitting only some of the - additional data could be problematic. This is discussed more below. - - For courtesy additional data, this causes a potential performance - problem as this requires that the clients issue re-queries for the - potentially omitted RRsets. For critical additional data, this - causes a potential unrecoverable problem if the response is not - discarded and the query not re-tried with TCP, as the nameservers - might be reachable only through the omitted RRsets. - - If an implementation would look at the transport used for the query, - it is worth remembering that often the host using the records is - different from the node requesting them from the authoritative DNS - server (or even a caching resolver). So, whichever version the - requestor (e.g., a recursive server in the middle) uses makes no - difference to the ultimate user of the records, whose transport - capabilities might differ from those of the requestor. This might - result in e.g., inappropriately returning A records to an IPv6-only - node, going through a translation, or opening up another IP-level - session (e.g., a PDP context [I-D.ietf-v6ops-3gpp-analysis]). - Therefore, at least in many scenarios, it would be very useful if the - information returned would be consistent and complete -- or if that - is not feasible, return no misleading information but rather leave it - to the client to query again. - - The problem of too much additional data seems to be an operational - one: the zone administrator entering too many records which will be - returned either truncated (or missing some RRsets, depending on - implementations) to the users. A protocol fix for this is using - EDNS0 [RFC2671] to signal the capacity for larger UDP packet sizes, - pushing up the relevant threshold. Further, DNS server - implementations should rather omit courtesy additional data - completely rather than including only some RRsets [RFC2181]. An - operational fix for this is having the DNS server implementations - return a warning when the administrators create zones which would - result in too much additional data being returned. Further, DNS - server implementations should warn of or disallow such zone - configurations which are recursive or otherwise difficult to manage - by the protocol. - - Additionally, to avoid the case where an application would not get an - address at all due to some of courtesy additional data being omitted, - - - -Durand, et al. Expires January 17, 2006 [Page 28] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - - the resolvers should be able to query the specific records of the - desired protocol, not just rely on getting all the required RRsets in - the additional section. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Durand, et al. Expires January 17, 2006 [Page 29] - -Internet-Draft Considerations with IPv6 DNS July 2005 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2005). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Durand, et al. Expires January 17, 2006 [Page 30] - - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsop-ipv6-transport-guidelines-01.txt b/contrib/bind9/doc/draft/draft-ietf-dnsop-ipv6-transport-guidelines-01.txt deleted file mode 100644 index b2e2341..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsop-ipv6-transport-guidelines-01.txt +++ /dev/null @@ -1,300 +0,0 @@ -Internet Engineering Task Force A.Durand -INTERNET-DRAFT SUN Microsystems,inc. -November, 24, 2003 J. Ihren -Expires May 25, 2004 Autonomica - - - DNS IPv6 transport operational guidelines - - - - -Status of this Memo - - This memo provides information to the Internet community. It does not - specify an Internet standard of any kind. This memo is in full - conformance with all provisions of Section 10 of RFC2026 - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet- Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/1id-abstracts.html - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html - - -Copyright Notice - - Copyright (C) The Internet Society (2003). All Rights Reserved. - - -Abstract - - This memo provides guidelines and Best Current Practice to operate - DNS in a world where queries and responses are carried in a mixed - environment of IPv4 and IPv6 networks. - - -Acknowledgment - - This document is the result of many conversations that happened in - the DNS community at IETF and elsewhere since 2001. During that - period of time, a number of Internet drafts have been published to - clarify various aspects of the issues at stake. This document focuses - on the conclusion of those discussions. - - The authors would like to acknowledge the role of Pekka Savola in his - thorough review of the document. - - -1. Terminology - - The phrase "IPv4 name server" indicates a name server available over - IPv4 transport. It does not imply anything about what DNS data is - served. Likewise, "IPv6 name server" indicates a name server - available over IPv6 transport. The phrase "dual-stack DNS server" - indicates a DNS server that is actually configured to run both - protocols, IPv4 and IPv6, and not merely a server running on a system - capable of running both but actually configured to run only one. - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in [2119]. - - -2. Introduction to the Problem of Name Space Fragmentation: - following the referral chain - - The caching resolver that tries to look up a name starts out at the - root, and follows referrals until it is referred to a nameserver that - is authoritative for the name. If somewhere down the chain of - referrals it is referred to a nameserver that is only accessible over - an unavailable type of transport, a traditional nameserver is unable - to finish the task. - - When the Internet moves from IPv4 to a mixture of IPv4 and IPv6 it is - only a matter of time until this starts to happen. The complete DNS - hierarchy then starts to fragment into a graph where authoritative - nameservers for certain nodes are only accessible over a certain - transport. What is feared is that a node using only a particular - version of IP, querying information about another node using the same - version of IP can not do it because, somewhere in the chain of - servers accessed during the resolution process, one or more of them - will only be accessible with the other version of IP. - - With all DNS data only available over IPv4 transport everything is - simple. IPv4 resolvers can use the intended mechanism of following - referrals from the root and down while IPv6 resolvers have to work - through a "translator", i.e. they have to use a second name server on - a so-called "dual stack" host as a "forwarder" since they cannot - access the DNS data directly. - - With all DNS data only available over IPv6 transport everything would - be equally simple, with the exception of old legacy IPv4 name servers - having to switch to a forwarding configuration. - - However, the second situation will not arise in a foreseeable time. - Instead, it is expected that the transition will be from IPv4 only to - a mixture of IPv4 and IPv6, with DNS data of theoretically three - categories depending on whether it is available only over IPv4 - transport, only over IPv6 or both. - - Having DNS data available on both transports is the best situation. - The major question is how to ensure that it as quickly as possible - becomes the norm. However, while it is obvious that some DNS data - will only be available over v4 transport for a long time it is also - obvious that it is important to avoid fragmenting the name space - available to IPv4 only hosts. I.e. during transition it is not - acceptable to break the name space that we presently have available - for IPv4-only hosts. - - -3. Policy Based Avoidance of Name Space Fragmentation - - Today there are only a few DNS "zones" on the public Internet that - are available over IPv6 transport, and most of them can be regarded - as "experimental". However, as soon as the root and top level domains - are available over IPv6 transport, it is reasonable to expect that it - will become more common to have zones served by IPv6 servers. - - Having those zones served only by IPv6-only name server would not be - a good development, since this will fragment the previously - unfragmented IPv4 name space and there are strong reasons to find a - mechanism to avoid it. - - The RECOMMENDED approach to maintain name space continuity is to use - administrative policies, as described in the next section. - - -4. DNS IPv6 Transport RECOMMENDED Guidelines - - In order to preserve name space continuity, the following administrative - policies are RECOMMENDED: - - every recursive DNS server SHOULD be either IPv4-only or dual - stack, - - every single DNS zone SHOULD be served by at least one IPv4 - reachable DNS server. - - This rules out IPv6-only DNS servers performing full recursion and - DNS zones served only by IPv6-only DNS servers. However, one could - very well design a configuration where a chain of IPv6 only DNS - servers forward queries to a set of dual stack DNS servers actually - performing those recursive queries. This approach could be revisited - if/when translation techniques between IPv4 and IPv6 were to be - widely deployed. - - In order to help enforcing the second point, the optional operational - zone validation processes SHOULD ensure that there is at least one - IPv4 address record available for the name servers of any child - delegations within the zone. - - -5. Security Considerations - - Being a critical piece of the Internet infrastructure, the DNS is a - potential value target and thus should be protected. Great care - should be taken not to weaken the security of DNS while introducing - IPv6 operation. - - Keeping the DNS name space from fragmenting is a critical thing for - the availability and the operation of the Internet; this memo - addresses this issue by clear and simple operational guidelines. - - The RECOMMENDED guidelines are compatible with the operation of - DNSSEC and do not introduce any new security issues. - - -6. Author Addresses - - Alain Durand - SUN Microsystems, Inc - 17 Network circle UMPK17-202 - Menlo Park, CA, 94025 - USA - Mail: Alain.Durand@sun.com - - Johan Ihren - Autonomica - Bellmansgatan 30 - SE-118 47 Stockholm, Sweden - Mail: johani@autonomica.se - - -7. Normative References - - [2119] Bradner, S., "Key Words for Use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - - -8. Full Copyright Statement - - "Copyright (C) The Internet Society (2003). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsop-key-rollover-requirements-02.txt b/contrib/bind9/doc/draft/draft-ietf-dnsop-key-rollover-requirements-02.txt deleted file mode 100644 index 6bece56..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsop-key-rollover-requirements-02.txt +++ /dev/null @@ -1,389 +0,0 @@ - -DNSOP G. Guette -Internet-Draft IRISA / INRIA -Expires: July 19, 2005 O. Courtay - Thomson R&D - January 18, 2005 - - Requirements for Automated Key Rollover in DNSSEC - draft-ietf-dnsop-key-rollover-requirements-02.txt - -Status of this Memo - - By submitting this Internet-Draft, I certify that any applicable - patent or other IPR claims of which I am aware have been disclosed, - and any of which I become aware will be disclosed, in accordance with - RFC 3668. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as - Internet-Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on July 19, 2005. - -Copyright Notice - - Copyright (C) The Internet Society (2005). All Rights Reserved. - -Abstract - - This document describes problems that appear during an automated - rollover and gives the requirements for the design of communication - between parent zone and child zone during an automated rollover - process. This document is essentially about in-band key rollover. - - - - -Guette & Courtay Expires July 19, 2005 [Page 1] -Internet-Draft Automated Rollover Requirements January 2005 - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 2. The Key Rollover Process . . . . . . . . . . . . . . . . . . . 3 - 3. Basic Requirements . . . . . . . . . . . . . . . . . . . . . . 4 - 4. Messages authentication and information exchanged . . . . . . 5 - 5. Emergency Rollover . . . . . . . . . . . . . . . . . . . . . . 5 - 6. Security consideration . . . . . . . . . . . . . . . . . . . . 6 - 7. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 6 - 8. Normative References . . . . . . . . . . . . . . . . . . . . . 6 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 7 - A. Documents details and changes . . . . . . . . . . . . . . . . 7 - Intellectual Property and Copyright Statements . . . . . . . . 8 - - - - - - - - - - - - - - - - - - - -Guette & Courtay Expires July 19, 2005 [Page 2] -Internet-Draft Automated Rollover Requirements January 2005 - -1. Introduction - - The DNS security extensions (DNSSEC) [4][6][5][7] uses public-key - cryptography and digital signatures. It stores the public part of - keys in DNSKEY Resource Records (RRs). Because old keys and - frequently used keys are vulnerable, they must be renewed - periodically. In DNSSEC, this is the case for Zone Signing Keys - (ZSKs) and Key Signing Keys (KSKs) [1][2]. Automation of key - exchanges between parents and children is necessary for large zones - because there are too many changes to handle. - - Let us consider for example a zone with 100000 secure delegations. - If the child zones change their keys once a year on average, that - implies 300 changes per day for the parent zone. This amount of - changes is hard to manage manually. - - Automated rollover is optional and resulting from an agreement - between the administrator of the parent zone and the administrator of - the child zone. Of course, key rollover can also be done manually by - administrators. - - This document describes the requirements for a protocol to perform - the automated key rollover process and focusses on interaction - between parent and child zone. - -2. The Key Rollover Process - - Key rollover consists of renewing the DNSSEC keys used to sign - resource records in a given DNS zone file. There are two types of - rollover, ZSK rollovers and KSK rollovers. - - During a ZSK rollover, all changes are local to the zone that renews - its key: there is no need to contact other zones administrators to - propagate the performed changes because a ZSK has no associated DS - record in the parent zone. - - During a KSK rollover, new DS RR(s) must be created and stored in the - parent zone. In consequence, data must be exchanged between child - and parent zones. - - The key rollover is built from two parts of different nature: - o An algorithm that generates new keys and signs the zone file. It - can be local to the zone, - o the interaction between parent and child zones. - - One example of manual key rollover [3] is: - o The child zone creates a new KSK, - - -Guette & Courtay Expires July 19, 2005 [Page 3] -Internet-Draft Automated Rollover Requirements January 2005 - - o the child zone waits for the creation of the DS RR in its parent - zone, - o the child zone deletes the old key, - o the parent zone deletes the old DS RR. - - This document concentrates on defining interactions between entities - present in key rollover process. - -3. Basic Requirements - - This section provides the requirements for automated key rollover in - case of normal use. Exceptional case like emergency rollover is - specifically described later in this document. - - The main condition during a key rollover is that the chain of trust - must be preserved to every validating DNS client. No matter if this - client retrieves some of the RRs from recursive caching name server - or from the authoritative servers for the zone involved in the - rollover. - - Automated key rollover solution may be interrupted by a manual - intervention. This manual intervention should not compromise the - security state of the chain of trust. If the chain is safe before - the manual intervention, the chain of trust must remain safe during - and after the manual intervention - - Two entities act during a KSK rollover: the child zone and its parent - zone. These zones are generally managed by different administrators. - These administrators should agree on some parameters like - availability of automated rollover, the maximum delay between - notification of changes in the child zone and the resigning of the - parent zone. The child zone needs to know this delay to schedule its - changes and/or to verify that the changes had been taken into account - in the parent zone. Hence, the child zone can also avoid some - critical cases where all child key are changed prior to the DS RR - creation. - - By keeping some resource records during a given time, the recursive - cache servers can act on the automated rollover. The existence of - recursive cache servers must be taken into account by automated - rollover solution. - - Indeed, during an automated key rollover a name server could have to - retrieve some DNSSEC data. An automated key rollover solution must - ensure that these data are not old DNSSEC material retrieved from a - recursive name server. - - - -Guette & Courtay Expires July 19, 2005 [Page 4] -Internet-Draft Automated Rollover Requirements January 2005 - -4. Messages authentication and information exchanged - - This section addresses in-band rollover, security of out-of-band - mechanisms is out of scope of this document. - - The security provided by DNSSEC must not be compromised by the key - rollover, thus every exchanged message must be authenticated to avoid - fake rollover messages from malicious parties. - - Once the changes related to a KSK are made in a child zone, there are - two ways for the parent zone to take this changes into account: - o the child zone notify directly or not directly its parent zone in - order to create the new DS RR and store this DS RR in parent zone - file, - o or the parent zone poll the child zone. - - In both cases, the parent zone must receive all the child keys that - need the creation of associated DS RRs in the parent zone. - - Because errors could occur during the transmission of keys between - child and parent, the key exchange protocol must be fault tolerant. - Should an error occured during the automated key rollover, an - automated key rollover solution must be able to keep the zone files - in a consistent state. - -5. Emergency Rollover - - Emergency key rollover is a special case of rollover decided by the - zone administrator generally for security reasons. In consequence, - emergency key rollover can break some of the requirement described - above. - - A zone key might be compromised and an attacker can use the - compromised key to create and sign fake records. To avoid this, the - zone administrator may change the compromised key or all its keys as - soon as possible, without waiting for the creation of new DS RRs in - its parent zone. - - Fast changes may break the chain of trust. The part of DNS tree - having this zone as apex can become unverifiable, but the break of - the chain of trust is necessary if the administrator wants to prevent - the compromised key from being used (to spoof DNS data). - - Parent and child zones sharing an automated rollover mechanism, - should have an out-of-band way to re-establish a consistent state at - the delegation point (DS and DNSKEY RRs). This allows to avoid that - a malicious party uses the compromised key to roll the zone keys. - - -Guette & Courtay Expires July 19, 2005 [Page 5] -Internet-Draft Automated Rollover Requirements January 2005 - -6. Security consideration - - The automated key rollover process in DNSSEC allows automated renewal - of any kind of DNS key (ZSK or KSK). It is essential that parent - side and child side can do mutual authentication. Moreover, - integrity of the material exchanged between the parent and child zone - must be provided to ensure the right DS are created. - - As in any application using public key cryptography, in DNSSEC a key - may be compromised. What to do in such a case can be describe in the - zone local policy and can violate some requirements described in this - draft. The emergency rollover can break the chain of trust in order - to protect the zone against the use of the compromised key. - -7. Acknowledgments - - The authors want to thank members of IDsA project for their - contribution to this document. - -8 Normative References - - [1] Gudmundsson, O., "Delegation Signer (DS) Resource Record (RR)", - RFC 3658, December 2003. - - [2] Kolkman, O., Schlyter, J. and E. Lewis, "Domain Name System KEY - (DNSKEY) Resource Record (RR) Secure Entry Point (SEP) Flag", - RFC 3757, May 2004. - - [3] Kolkman, O., "DNSSEC Operational Practices", - draft-ietf-dnsop-dnssec-operational-practice-01 (work in - progress), May 2004. - - [4] Eastlake, D., "Domain Name System Security Extensions", RFC - 2535, March 1999. - - [5] Arends, R., Austein, R., Larson, M., Massey, D. and S. Rose, - "Resource Records for the DNS Security Extensions", - draft-ietf-dnsext-dnssec-records-11 (work in progress), October - 2004. - - [6] Arends, R., Austein, R., Larson, M., Massey, D. and S. Rose, - "DNS Security Introduction and Requirements", - draft-ietf-dnsext-dnssec-intro-13 (work in progress), October - 2004. - - [7] Arends, R., Austein, R., Larson, M., Massey, D. and S. Rose, - "Protocol Modifications for the DNS Security Extensions", - draft-ietf-dnsext-dnssec-protocol-09 (work in progress), October - - -Guette & Courtay Expires July 19, 2005 [Page 6] -Internet-Draft Automated Rollover Requirements January 2005 - - 2004. - -Authors' Addresses - - Gilles Guette - IRISA / INRIA - Campus de Beaulieu - 35042 Rennes CEDEX - FR - - EMail: gilles.guette@irisa.fr - URI: http://www.irisa.fr - - Olivier Courtay - Thomson R&D - 1, avenue Belle Fontaine - 35510 Cesson S?vign? CEDEX - FR - - EMail: olivier.courtay@thomson.net - -Appendix A. Documents details and changes - - This section is to be removed by the RFC editor if and when the - document is published. - - Section about NS RR rollover has been removed - - Remarks from Samuel Weiler and Rip Loomis added - - Clarification about in-band rollover and in emergency section - - Section 3, details about recursive cache servers added - - - - - - - - -Guette & Courtay Expires July 19, 2005 [Page 7] -Internet-Draft Automated Rollover Requirements January 2005 - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - intellectual property or other rights that might be claimed to - pertain to the implementation or use of the technology described - in this document or the extent to which any license under such - rights might or might not be available; neither does it represent - that it has made any effort to identify any such rights. - Information on the IETF's procedures with respect to rights in - IETF Documents can be found in BCP 78 and 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use - of such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository - at http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention - any copyrights, patents or patent applications, or other - proprietary rights which may cover technology that may be required - to implement this standard. Please address the information to the - IETF at ietf-ipr.org. - - - Full Copyright Statement - - Copyright (C) The Internet Society (2005). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - -Guette & Courtay Expires July 19, 2005 [Page 8] diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsop-respsize-02.txt b/contrib/bind9/doc/draft/draft-ietf-dnsop-respsize-02.txt deleted file mode 100644 index 63fe2de..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsop-respsize-02.txt +++ /dev/null @@ -1,480 +0,0 @@ - - - - - - - DNSOP Working Group Paul Vixie, ISC - INTERNET-DRAFT Akira Kato, WIDE - July 2005 - - DNS Response Size Issues - - Status of this Memo - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - Copyright Notice - - Copyright (C) The Internet Society (2005). All Rights Reserved. - - - - - Abstract - - With a mandated default minimum maximum message size of 512 octets, - the DNS protocol presents some special problems for zones wishing to - expose a moderate or high number of authority servers (NS RRs). This - document explains the operational issues caused by, or related to - this response size limit. - - - - - - - Expires December 2005 [Page 1] - - INTERNET-DRAFT July 2005 RESPSIZE - - - 1 - Introduction and Overview - - 1.1. The DNS standard (see [RFC1035 4.2.1]) limits message size to 512 - octets. Even though this limitation was due to the required minimum UDP - reassembly limit for IPv4, it is a hard DNS protocol limit and is not - implicitly relaxed by changes in transport, for example to IPv6. - - 1.2. The EDNS0 standard (see [RFC2671 2.3, 4.5]) permits larger - responses by mutual agreement of the requestor and responder. However, - deployment of EDNS0 cannot be expected to reach every Internet resolver - in the short or medium term. The 512 octet message size limit remains - in practical effect at this time. - - 1.3. Since DNS responses include a copy of the request, the space - available for response data is somewhat less than the full 512 octets. - For negative responses, there is rarely a space constraint. For - positive and delegation responses, though, every octet must be carefully - and sparingly allocated. This document specifically addresses - delegation response sizes. - - 2 - Delegation Details - - 2.1. A delegation response will include the following elements: - - Header Section: fixed length (12 octets) - Question Section: original query (name, class, type) - Answer Section: (empty) - Authority Section: NS RRset (nameserver names) - Additional Section: A and AAAA RRsets (nameserver addresses) - - 2.2. If the total response size would exceed 512 octets, and if the data - that would not fit belonged in the question, answer, or authority - section, then the TC bit will be set (indicating truncation) which may - cause the requestor to retry using TCP, depending on what information - was desired and what information was omitted. If a retry using TCP is - needed, the total cost of the transaction is much higher. (See [RFC1123 - 6.1.3.2] for details on the protocol requirement that UDP be attempted - before falling back to TCP.) - - 2.3. RRsets are never sent partially unless truncation occurs, in which - case the final apparent RRset in the final nonempty section must be - considered "possibly damaged". With or without truncation, the glue - present in the additional data section should be considered "possibly - incomplete", and requestors should be prepared to re-query for any - damaged or missing RRsets. For multi-transport name or mail services, - - - - Expires December 2005 [Page 2] - - INTERNET-DRAFT July 2005 RESPSIZE - - - this can mean querying for an IPv6 (AAAA) RRset even when an IPv4 (A) - RRset is present. - - 2.4. DNS label compression allows a domain name to be instantiated only - once per DNS message, and then referenced with a two-octet "pointer" - from other locations in that same DNS message. If all nameserver names - in a message are similar (for example, all ending in ".ROOT- - SERVERS.NET"), then more space will be available for uncompressable data - (such as nameserver addresses). - - 2.5. The query name can be as long as 255 characters of presentation - data, which can be up to 256 octets of network data. In this worst case - scenario, the question section will be 260 octets in size, which would - leave only 240 octets for the authority and additional sections (after - deducting 12 octets for the fixed length header.) - - 2.6. Average and maximum question section sizes can be predicted by the - zone owner, since they will know what names actually exist, and can - measure which ones are queried for most often. For cost and performance - reasons, the majority of requests should be satisfied without truncation - or TCP retry. - - 2.7. Requestors who deliberately send large queries to force truncation - are only increasing their own costs, and cannot effectively attack the - resources of an authority server since the requestor would have to retry - using TCP to complete the attack. An attack that always used TCP would - have a lower cost. - - 2.8. The minimum useful number of address records is two, since with - only one address, the probability that it would refer to an unreachable - server is too high. Truncation which occurs after two address records - have been added to the additional data section is therefore less - operationally significant than truncation which occurs earlier. - - 2.9. The best case is no truncation. This is because many requestors - will retry using TCP by reflex, or will automatically re-query for - RRsets that are "possibly truncated", without considering whether the - omitted data was actually necessary. - - 2.10. Each added NS RR for a zone will add a minimum of between 16 and - 44 octets to every untruncated referral or negative response from the - zone's authority servers (16 octets for an NS RR, 16 octets for an A RR, - and 28 octets for an AAAA RR), in addition to whatever space is taken by - the nameserver name (NS NSDNAME and A/AAAA owner name). - - - - - Expires December 2005 [Page 3] - - INTERNET-DRAFT July 2005 RESPSIZE - - - 3 - Analysis - - 3.1. An instrumented protocol trace of a best case delegation response - follows. Note that 13 servers are named, and 13 addresses are given. - This query was artificially designed to exactly reach the 512 octet - limit. - - ;; flags: qr rd; QUERY: 1, ANS: 0, AUTH: 13, ADDIT: 13 - ;; QUERY SECTION: - ;; [23456789.123456789.123456789.\ - 123456789.123456789.123456789.com A IN] ;; @80 - - ;; AUTHORITY SECTION: - com. 86400 NS E.GTLD-SERVERS.NET. ;; @112 - com. 86400 NS F.GTLD-SERVERS.NET. ;; @128 - com. 86400 NS G.GTLD-SERVERS.NET. ;; @144 - com. 86400 NS H.GTLD-SERVERS.NET. ;; @160 - com. 86400 NS I.GTLD-SERVERS.NET. ;; @176 - com. 86400 NS J.GTLD-SERVERS.NET. ;; @192 - com. 86400 NS K.GTLD-SERVERS.NET. ;; @208 - com. 86400 NS L.GTLD-SERVERS.NET. ;; @224 - com. 86400 NS M.GTLD-SERVERS.NET. ;; @240 - com. 86400 NS A.GTLD-SERVERS.NET. ;; @256 - com. 86400 NS B.GTLD-SERVERS.NET. ;; @272 - com. 86400 NS C.GTLD-SERVERS.NET. ;; @288 - com. 86400 NS D.GTLD-SERVERS.NET. ;; @304 - - ;; ADDITIONAL SECTION: - A.GTLD-SERVERS.NET. 86400 A 192.5.6.30 ;; @320 - B.GTLD-SERVERS.NET. 86400 A 192.33.14.30 ;; @336 - C.GTLD-SERVERS.NET. 86400 A 192.26.92.30 ;; @352 - D.GTLD-SERVERS.NET. 86400 A 192.31.80.30 ;; @368 - E.GTLD-SERVERS.NET. 86400 A 192.12.94.30 ;; @384 - F.GTLD-SERVERS.NET. 86400 A 192.35.51.30 ;; @400 - G.GTLD-SERVERS.NET. 86400 A 192.42.93.30 ;; @416 - H.GTLD-SERVERS.NET. 86400 A 192.54.112.30 ;; @432 - I.GTLD-SERVERS.NET. 86400 A 192.43.172.30 ;; @448 - J.GTLD-SERVERS.NET. 86400 A 192.48.79.30 ;; @464 - K.GTLD-SERVERS.NET. 86400 A 192.52.178.30 ;; @480 - L.GTLD-SERVERS.NET. 86400 A 192.41.162.30 ;; @496 - M.GTLD-SERVERS.NET. 86400 A 192.55.83.30 ;; @512 - - ;; MSG SIZE sent: 80 rcvd: 512 - - - - - - Expires December 2005 [Page 4] - - INTERNET-DRAFT July 2005 RESPSIZE - - - 3.2. For longer query names, the number of address records supplied will - be lower. Furthermore, it is only by using a common parent name (which - is GTLD-SERVERS.NET in this example) that all 13 addresses are able to - fit. The following output from a response simulator demonstrates these - properties: - - % perl respsize.pl a.dns.br b.dns.br c.dns.br d.dns.br - a.dns.br requires 10 bytes - b.dns.br requires 4 bytes - c.dns.br requires 4 bytes - d.dns.br requires 4 bytes - # of NS: 4 - For maximum size query (255 byte): - if only A is considered: # of A is 4 (green) - if A and AAAA are condered: # of A+AAAA is 3 (yellow) - if prefer_glue A is assumed: # of A is 4, # of AAAA is 3 (yellow) - For average size query (64 byte): - if only A is considered: # of A is 4 (green) - if A and AAAA are condered: # of A+AAAA is 4 (green) - if prefer_glue A is assumed: # of A is 4, # of AAAA is 4 (green) - - % perl respsize.pl ns-ext.isc.org ns.psg.com ns.ripe.net ns.eu.int - ns-ext.isc.org requires 16 bytes - ns.psg.com requires 12 bytes - ns.ripe.net requires 13 bytes - ns.eu.int requires 11 bytes - # of NS: 4 - For maximum size query (255 byte): - if only A is considered: # of A is 4 (green) - if A and AAAA are condered: # of A+AAAA is 3 (yellow) - if prefer_glue A is assumed: # of A is 4, # of AAAA is 2 (yellow) - For average size query (64 byte): - if only A is considered: # of A is 4 (green) - if A and AAAA are condered: # of A+AAAA is 4 (green) - if prefer_glue A is assumed: # of A is 4, # of AAAA is 4 (green) - - (Note: The response simulator program is shown in Section 5.) - - Here we use the term "green" if all address records could fit, or - "orange" if two or more could fit, or "red" if fewer than two could fit. - It's clear that without a common parent for nameserver names, much space - would be lost. For these examples we use an average/common name size of - 15 octets, befitting our assumption of GTLD-SERVERS.NET as our common - parent name. - - - - - Expires December 2005 [Page 5] - - INTERNET-DRAFT July 2005 RESPSIZE - - - We're assuming an average query name size of 64 since that is the - typical average maximum size seen in trace data at the time of this - writing. If Internationalized Domain Name (IDN) or any other technology - which results in larger query names be deployed significantly in advance - of EDNS, then new measurements and new estimates will have to be made. - - 4 - Conclusions - - 4.1. The current practice of giving all nameserver names a common parent - (such as GTLD-SERVERS.NET or ROOT-SERVERS.NET) saves space in DNS - responses and allows for more nameservers to be enumerated than would - otherwise be possible. (Note that in this case it is wise to serve the - common parent domain's zone from the same servers that are named within - it, in order to limit external dependencies when all your eggs are in a - single basket.) - - 4.2. Thirteen (13) seems to be the effective maximum number of - nameserver names usable traditional (non-extended) DNS, assuming a - common parent domain name, and given that response truncation is - undesirable as an average case, and assuming mostly IPv4-only - reachability (only A RRs exist, not AAAA RRs). - - 4.3. Adding two to five IPv6 nameserver address records (AAAA RRs) to a - prototypical delegation that currently contains thirteen (13) IPv4 - nameserver addresses (A RRs) for thirteen (13) nameserver names under a - common parent, would not have a significant negative operational impact - on the domain name system. - - 5 - Source Code - - #!/usr/bin/perl - # - # SYNOPSIS - # repsize.pl [ -z zone ] fqdn_ns1 fqdn_ns2 ... - # if all queries are assumed to have zone suffux, such as "jp" in - # JP TLD servers, specify it in -z option - # - use strict; - use Getopt::Std; - my ($sz_msg) = (512); - my ($sz_header, $sz_ptr, $sz_rr_a, $sz_rr_aaaa) = (12, 2, 16, 28); - my ($sz_type, $sz_class, $sz_ttl, $sz_rdlen) = (2, 2, 4, 2); - my (%namedb, $name, $nssect, %opts, $optz); - my $n_ns = 0; - - - - - Expires December 2005 [Page 6] - - INTERNET-DRAFT July 2005 RESPSIZE - - - getopt('z', opts); - if (defined($opts{'z'})) { - server_name_len($opts{'z'}); # just register it - } - - foreach $name (@ARGV) { - my $len; - $n_ns++; - $len = server_name_len($name); - print "$name requires $len bytes\n"; - $nssect += $sz_ptr + $sz_type + $sz_class + $sz_ttl + $sz_rdlen + $len; - } - print "# of NS: $n_ns\n"; - arsect(255, $nssect, $n_ns, "maximum"); - arsect(64, $nssect, $n_ns, "average"); - - sub server_name_len { - my ($name) = @_; - my (@labels, $len, $n, $suffix); - - $name =~ tr/A-Z/a-z/; - @labels = split(/./, $name); - $len = length(join('.', @labels)) + 2; - for ($n = 0; $#labels >= 0; $n++, shift @labels) { - $suffix = join('.', @labels); - return length($name) - length($suffix) + $sz_ptr - if (defined($namedb{$suffix})); - $namedb{$suffix} = 1; - } - return $len; - } - - sub arsect { - my ($sz_query, $nssect, $n_ns, $cond) = @_; - my ($space, $n_a, $n_a_aaaa, $n_p_aaaa, $ansect); - $ansect = $sz_query + 1 + $sz_type + $sz_class; - $space = $sz_msg - $sz_header - $ansect - $nssect; - $n_a = atmost(int($space / $sz_rr_a), $n_ns); - $n_a_aaaa = atmost(int($space / ($sz_rr_a + $sz_rr_aaaa)), $n_ns); - $n_p_aaaa = atmost(int(($space - $sz_rr_a * $n_ns) / $sz_rr_aaaa), $n_ns); - printf "For %s size query (%d byte):\n", $cond, $sz_query; - printf "if only A is considered: "; - printf "# of A is %d (%s)\n", $n_a, &judge($n_a, $n_ns); - printf "if A and AAAA are condered: "; - printf "# of A+AAAA is %d (%s)\n", $n_a_aaaa, &judge($n_a_aaaa, $n_ns); - - - - Expires December 2005 [Page 7] - - INTERNET-DRAFT July 2005 RESPSIZE - - - printf "if prefer_glue A is assumed: "; - printf "# of A is %d, # of AAAA is %d (%s)\n", - $n_a, $n_p_aaaa, &judge($n_p_aaaa, $n_ns); - } - - sub judge { - my ($n, $n_ns) = @_; - return "green" if ($n >= $n_ns); - return "yellow" if ($n >= 2); - return "orange" if ($n == 1); - return "red"; - } - - sub atmost { - my ($a, $b) = @_; - return 0 if ($a < 0); - return $b if ($a > $b); - return $a; - } - - Security Considerations - - The recommendations contained in this document have no known security - implications. - - IANA Considerations - - This document does not call for changes or additions to any IANA - registry. - - IPR Statement - - Copyright (C) The Internet Society (2005). This document is subject to - the rights, licenses and restrictions contained in BCP 78, and except as - set forth therein, the authors retain all their rights. - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR - IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - - - Expires December 2005 [Page 8] - - INTERNET-DRAFT July 2005 RESPSIZE - - - Authors' Addresses - - Paul Vixie - 950 Charter Street - Redwood City, CA 94063 - +1 650 423 1301 - vixie@isc.org - - Akira Kato - University of Tokyo, Information Technology Center - 2-11-16 Yayoi Bunkyo - Tokyo 113-8658, JAPAN - +81 3 5841 2750 - kato@wide.ad.jp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Expires December 2005 [Page 9] - \ No newline at end of file diff --git a/contrib/bind9/doc/draft/draft-ietf-dnsop-serverid-06.txt b/contrib/bind9/doc/draft/draft-ietf-dnsop-serverid-06.txt deleted file mode 100644 index c6ec7e4..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-dnsop-serverid-06.txt +++ /dev/null @@ -1,618 +0,0 @@ - - - - -Network Working Group S. Woolf -Internet-Draft Internet Systems Consortium, Inc. -Expires: September 6, 2006 D. Conrad - Nominum, Inc. - March 5, 2006 - - - Requirements for a Mechanism Identifying a Name Server Instance - draft-ietf-dnsop-serverid-06 - -Status of this Memo - - By submitting this Internet-Draft, each author represents that any - applicable patent or other IPR claims of which he or she is aware - have been or will be disclosed, and any of which he or she becomes - aware will be disclosed, in accordance with Section 6 of BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on September 6, 2006. - -Copyright Notice - - Copyright (C) The Internet Society (2006). - -Abstract - - With the increased use of DNS anycast, load balancing, and other - mechanisms allowing more than one DNS name server to share a single - IP address, it is sometimes difficult to tell which of a pool of name - servers has answered a particular query. A standardized mechanism to - determine the identity of a name server responding to a particular - query would be useful, particularly as a diagnostic aid for - administrators. Existing ad hoc mechanisms for addressing this need - - - -Woolf & Conrad Expires September 6, 2006 [Page 1] - -Internet-Draft Serverid March 2006 - - - have some shortcomings, not the least of which is the lack of prior - analysis of exactly how such a mechanism should be designed and - deployed. This document describes the existing convention used in - some widely deployed implementations of the DNS protocol, including - advantages and disadvantages, and discusses some attributes of an - improved mechanism. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Woolf & Conrad Expires September 6, 2006 [Page 2] - -Internet-Draft Serverid March 2006 - - -1. Introduction and Rationale - - Identifying which name server is responding to queries is often - useful, particularly in attempting to diagnose name server - difficulties. This is most obviously useful for authoritative - nameservers in the attempt to diagnose the source or prevalence of - inaccurate data, but can also conceivably be useful for caching - resolvers in similar and other situations. Furthermore, the ability - to identify which server is responding to a query has become more - useful as DNS has become more critical to more Internet users, and as - network and server deployment topologies have become more complex. - - The traditional means for determining which of several possible - servers is answering a query has traditionally been based on the use - of the server's IP address as a unique identifier. However, the - modern Internet has seen the deployment of various load balancing, - fault-tolerance, or attack-resistance schemes such as shared use of - unicast IP addresses as documented in [RFC3258]. An unfortunate side - effect of these schemes has been to make the use of IP addresses as - identifiers somewhat problematic. Specifically, a dedicated DNS - query may not go to the same server as answered a previous query, - even though sent to the same IP address. Non-DNS methods such as - ICMP ping, TCP connections, or non-DNS UDP packets (such as those - generated by tools like "traceroute"), etc., may well be even less - certain to reach the same server as the one which receives the DNS - queries. - - There is a well-known and frequently-used technique for determining - an identity for a nameserver more specific than the possibly-non- - unique "server that answered the query I sent to IP address XXX". - The widespread use of the existing convention suggests a need for a - documented, interoperable means of querying the identity of a - nameserver that may be part of an anycast or load-balancing cluster. - At the same time, however, it also has some drawbacks that argue - against standardizing it as it's been practiced so far. - - - - - - - - - - - - - - - - -Woolf & Conrad Expires September 6, 2006 [Page 3] - -Internet-Draft Serverid March 2006 - - -2. Existing Conventions - - For some time, the commonly deployed Berkeley Internet Name Domain - implementation of the DNS protocol suite from the Internet Systems - Consortium [BIND] has supported a way of identifying a particular - server via the use of a standards-compliant, if somewhat unusual, DNS - query. Specifically, a query to a recent BIND server for a TXT - resource record in class 3 (CHAOS) for the domain name - "HOSTNAME.BIND." will return a string that can be configured by the - name server administrator to provide a unique identifier for the - responding server. (The value defaults to the result of a - gethostname() call). This mechanism, which is an extension of the - BIND convention of using CHAOS class TXT RR queries to sub-domains of - the "BIND." domain for version information, has been copied by - several name server vendors. - - A refinement to the BIND-based mechanism, which dropped the - implementation-specific string, replaces ".BIND" with ".SERVER". - Thus the query string to learn the unique name of a server may be - queried as "ID.SERVER". - - (For reference, the other well-known name used by recent versions of - BIND within the CHAOS class "BIND." domain is "VERSION.BIND." A - query for a CHAOS TXT RR for this name will return an - administratively defined string which defaults to the version of the - server responding. This is, however, not generally implemented by - other vendors.) - -2.1. Advantages - - There are several valuable attributes to this mechanism, which - account for its usefulness. - - 1. The "HOSTNAME.BIND" or "ID.SERVER" query response mechanism is - within the DNS protocol itself. An identification mechanism that - relies on the DNS protocol is more likely to be successful - (although not guaranteed) in going to the same system as a - "normal" DNS query. - - 2. Since the identity information is requested and returned within - the DNS protocol, it doesn't require allowing any other query - mechanism to the server, such as holes in firewalls for - otherwise-unallowed ICMP Echo requests. Thus it is likely to - reach the same server over a path subject to the same routing, - resource, and security policy as the query, without any special - exceptions to site security policy. - - - - - -Woolf & Conrad Expires September 6, 2006 [Page 4] - -Internet-Draft Serverid March 2006 - - - 3. It is simple to configure. An administrator can easily turn on - this feature and control the results of the relevant query. - - 4. It allows the administrator complete control of what information - is given out in the response, minimizing passive leakage of - implementation or configuration details. Such details are often - considered sensitive by infrastructure operators. - - 5. Hypothetically, since it's an ordinary DNS record and the - relevant DNSSEC RRs are class independent, the id.server response - RR could be signed, which has the advantages described in - [RFC4033]. - -2.2. Disadvantages - - At the same time, there are some serious drawbacks to the CHAOS/TXT - query mechanism that argue against standardizing it as it currently - operates. - - 1. It requires an additional query to correlate between the answer - to a DNS query under normal conditions and the supposed identity - of the server receiving the query. There are a number of - situations in which this simply isn't reliable. - - 2. It reserves an entire class in the DNS (CHAOS) for what amounts - to one zone. While CHAOS class is defined in [RFC1034] and - [RFC1035], it's not clear that supporting it solely for this - purpose is a good use of the namespace or of implementation - effort. - - 3. The initial and still common form, using .BIND, is implementation - specific. BIND is one DNS implementation. At the time of this - writing, it is probably the most prevalent for authoritative - servers. This does not justify standardizing on its ad hoc - solution to a problem shared across many operators and - implementors. Meanwhile, the proposed refinement changes the - string but preserves the ad hoc CHAOS/TXT mechanism. - - 4. There is no convention or shared understanding of what - information an answer to such a query for a server identity could - or should include, including a possible encoding or - authentication mechanism. - - The first of the listed disadvantages may be technically the most - serious. It argues for an attempt to design a good answer to the - problem that "I need to know what nameserver is answering my - queries", not simply a convenient one. - - - - -Woolf & Conrad Expires September 6, 2006 [Page 5] - -Internet-Draft Serverid March 2006 - - -2.3. Characteristics of an Implementation Neutral Convention - - The discussion above of advantages and disadvantages to the - HOSTNAME.BIND mechanism suggest some requirements for a better - solution to the server identification problem. These are summarized - here as guidelines for any effort to provide appropriate protocol - extensions: - - 1. The mechanism adopted must be in-band for the DNS protocol. That - is, it needs to allow the query for the server's identifying - information to be part of a normal, operational query. It should - also permit a separate, dedicated query for the server's - identifying information. But it should preserve the ability of - the CHAOS/TXT query-based mechanism to work through firewalls and - in other situations where only DNS can be relied upon to reach - the server of interest. - - 2. The new mechanism should not require dedicated namespaces or - other reserved values outside of the existing protocol mechanisms - for these, i.e. the OPT pseudo-RR. In particular, it should not - propagate the existing drawback of requiring support for a CLASS - and top level domain in the authoritative server (or the querying - tool) to be useful. - - 3. Support for the identification functionality should be easy to - implement and easy to enable. It must be easy to disable and - should lend itself to access controls on who can query for it. - - 4. It should be possible to return a unique identifier for a server - without requiring the exposure of information that may be non- - public and considered sensitive by the operator, such as a - hostname or unicast IP address maintained for administrative - purposes. - - 5. It should be possible to authenticate the received data by some - mechanism analogous to those provided by DNSSEC. In this - context, the need could be met by including encryption options in - the specification of a new mechanism. - - 6. The identification mechanism should not be implementation- - specific. - - - - - - - - - - -Woolf & Conrad Expires September 6, 2006 [Page 6] - -Internet-Draft Serverid March 2006 - - -3. IANA Considerations - - This document proposes no specific IANA action. Protocol extensions, - if any, to meet the requirements described are out of scope for this - document. A proposed extension, specified and adopted by normal IETF - process, is described in [NSID], including relevant IANA action. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Woolf & Conrad Expires September 6, 2006 [Page 7] - -Internet-Draft Serverid March 2006 - - -4. Security Considerations - - Providing identifying information as to which server is responding to - a particular query from a particular location in the Internet can be - seen as information leakage and thus a security risk. This motivates - the suggestion above that a new mechanism for server identification - allow the administrator to disable the functionality altogether or - partially restrict availability of the data. It also suggests that - the serverid data should not be readily correlated with a hostname or - unicast IP address that may be considered private to the nameserver - operator's management infrastructure. - - Propagation of protocol or service meta-data can sometimes expose the - application to denial of service or other attack. As DNS is a - critically important infrastructure service for the production - Internet, extra care needs to be taken against this risk for - designers, implementors, and operators of a new mechanism for server - identification. - - Both authentication and confidentiality of serverid data are - potentially of interest to administrators-- that is, operators may - wish to make serverid data available and reliable to themselves and - their chosen associates only. This would imply both an ability to - authenticate it to themselves and keep it private from arbitrary - other parties. This led to Characteristics 4 and 5 of an improved - solution. - - - - - - - - - - - - - - - - - - - - - - - - - -Woolf & Conrad Expires September 6, 2006 [Page 8] - -Internet-Draft Serverid March 2006 - - -5. Acknowledgements - - The technique for host identification documented here was initially - implemented by Paul Vixie of the Internet Software Consortium in the - Berkeley Internet Name Daemon package. Comments and questions on - earlier drafts were provided by Bob Halley, Brian Wellington, Andreas - Gustafsson, Ted Hardie, Chris Yarnell, Randy Bush, and members of the - ICANN Root Server System Advisory Committee. The newest version - takes a significantly different direction from previous versions, - owing to discussion among contributors to the DNSOP working group and - others, particularly Olafur Gudmundsson, Ed Lewis, Bill Manning, Sam - Weiler, and Rob Austein. - -6. References - - [1] Mockapetris, P., "Domain Names - Concepts and Facilities", - RFC 1034, STD 0013, November 1987. - - [2] Mockapetris, P., "Domain Names - Implementation and - Specification", RFC 1035, STD 0013, November 1987. - - [3] Hardie, T., "Distributing Authoritative Name Servers via Shared - Unicast Addresses", RFC 3258, April 2002. - - [4] ISC, "BIND 9 Configuration Reference". - - [5] Austein, S., "DNS Name Server Identifier Option (NSID)", - Internet Drafts http://www.ietf.org/internet-drafts/ - draft-ietf-dnsext-nsid-01.txt, January 2006. - - [6] Arends, R., Austein, S., Larson, M., Massey, D., and S. Rose, - "DNS Security Introduction and Requirements", RFC 4033, - March 2005. - - - - - - - - - - - - - - - - - - -Woolf & Conrad Expires September 6, 2006 [Page 9] - -Internet-Draft Serverid March 2006 - - -Authors' Addresses - - Suzanne Woolf - Internet Systems Consortium, Inc. - 950 Charter Street - Redwood City, CA 94063 - US - - Phone: +1 650 423-1333 - Email: woolf@isc.org - URI: http://www.isc.org/ - - - David Conrad - Nominum, Inc. - 2385 Bay Road - Redwood City, CA 94063 - US - - Phone: +1 1 650 381 6003 - Email: david.conrad@nominum.com - URI: http://www.nominum.com/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Woolf & Conrad Expires September 6, 2006 [Page 10] - -Internet-Draft Serverid March 2006 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - Intellectual Property Rights or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; nor does it represent that it has - made any independent effort to identify any such rights. Information - on the procedures with respect to rights in RFC documents can be - found in BCP 78 and BCP 79. - - Copies of IPR disclosures made to the IETF Secretariat and any - assurances of licenses to be made available, or the result of an - attempt made to obtain a general license or permission for the use of - such proprietary rights by implementers or users of this - specification can be obtained from the IETF on-line IPR repository at - http://www.ietf.org/ipr. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights that may cover technology that may be required to implement - this standard. Please address the information to the IETF at - ietf-ipr@ietf.org. - - -Disclaimer of Validity - - This document and the information contained herein are provided on an - "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS - OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET - ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE - INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Copyright Statement - - Copyright (C) The Internet Society (2006). This document is subject - to the rights, licenses and restrictions contained in BCP 78, and - except as set forth therein, the authors retain all their rights. - - -Acknowledgment - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - -Woolf & Conrad Expires September 6, 2006 [Page 11] - - diff --git a/contrib/bind9/doc/draft/draft-ietf-enum-e164-gstn-np-05.txt b/contrib/bind9/doc/draft/draft-ietf-enum-e164-gstn-np-05.txt deleted file mode 100644 index 3353b3b..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-enum-e164-gstn-np-05.txt +++ /dev/null @@ -1,1588 +0,0 @@ - - Mark Foster -Internet Draft Tom McGarry -Document: James Yu - NeuStar, Inc. -Category: Informational June 24, 2002 - - - Number Portability in the GSTN: An Overview - - -Status of this Memo - - This document is an Internet-Draft and is in full conformance with - all provisions of Section 10 of RFC2026 [RFC]. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. Internet-Drafts are draft documents valid for a maximum of - six months and may be updated, replaced, or obsoleted by other - documents at any time. It is inappropriate to use Internet- Drafts - as reference material or to cite them other than as "work in - progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - - Copyright Notice - - Copyright (C) The Internet Society (2002). All rights reserved. - - - Abstract - - This document provides an overview of E.164 telephone number - portability (NP) in the Global Switched Telephone Network (GSTN). - NP is a regulatory imperative seeking to liberalize local telephony - service competition, by enabling end-users to retain telephone - numbers while changing service providers. NP changes the - fundamental nature of a dialed E.164 number from a hierarchical - physical routing address to a virtual address, thereby requiring the - transparent translation of the later to the former. In addition, - there are various regulatory constraints that establish relevant - parameters for NP implementation, most of which are not network - technology specific. Consequently, the implementation of NP - behavior consistent with applicable regulatory constraints, as well - as the need for interoperation with the existing GSTN NP - implementations, are relevant topics for numerous areas of IP - telephony work-in-progress at IETF. - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 1] - -Number Portability in the GSTN: An Overview June 24, 2002 - - - Table of Contents - - 1. Introduction ............................................... 2 - 2. Abbreviations and Acronyms ................................. 4 - 3. Types of Number Portability ................................ 5 - 4. Service Provider Number Portability Schemes ................ 7 - 4.1 All Call Query (ACQ) .................................. 7 - 4.2 Query on Release (QoR) ................................ 8 - 4.3 Call Dropback ......................................... 9 - 4.4 Onward Routing (OR) ................................... 9 - 4.5 Comparisons of the Four Schemes ....................... 10 - 5. Database Queries in the NP Environment ..................... 11 - 5.1 U.S. and Canada ....................................... 12 - 5.2 Europe ................................................ 13 - 6. Call Routing in the NP Environment ......................... 14 - 6.1 U.S. and Canada ....................................... 14 - 6.2 Europe ................................................ 15 - 7. NP Implementations for Geographic E.164 Numbers ............ 17 - 8. Number Conservation Method Enabled By NP ................... 20 - 8.1 Block Pooling ......................................... 20 - 8.2 ITN Pooling ........................................... 21 - 9. Potential Implications ..................................... 21 - 10. Security Considerations .................................... 24 - 11. IANA Considerations ........................................ 24 - 12. Normative References ....................................... 24 - 13. Informative References ..................................... 25 - 14. Acknowledgement ............................................ 25 - 15. AuthorsË Addresses ......................................... 25 - - - -1. Introduction - - This document provides an overview of E.164 telephone number - portability in the Global Switched Telephone Network (GSTN). There - are considered to be three types of number portability (NP): service - provider portability (SPNP), location portability (not to be - confused with terminal mobility), and service portability. - - Service provider portability (SPNP), the focus of the present draft, - is a regulatory imperative in many countries seeking to liberalize - telephony service competition, especially local service. - Historically, local telephony service (as compared to long distance - or international service) has been regulated as a utility-like form - of service. While a number of countries had begun liberalization - (e.g. privatization, de-regulation, or re-regulation) some years - ago, the advent of NP is relatively recent (since ~1995). - - E.164 numbers can be non-geographic and geographic numbers. Non- - geographic numbers do not reveal the locations information of those - numbers. Geographic E.164 numbers were intentionally designed as - hierarchical routing addresses which could systematically be digit- - analyzed to ascertain the country, serving network provider, serving - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 2] - -Number Portability in the GSTN: An Overview June 24, 2002 - - end-office switch, and specific line of the called party. As such, - without NP a subscriber wishing to change service providers would - incur a number change as a consequence of being served off of a - different end-office switch operated by the new service provider. - The cost and convenience impact to the subscriber of changing - numbers is seen as barrier to competition. Hence NP has become - associated with GSTN infrastructure enhancements associated with a - competitive environment driven by regulatory directives. - - Forms of SPNP have been deployed or are being deployed widely in the - GSTN in various parts of the world, including the U.S., Canada, - Western Europe, Australia, and the Pacific Rim (e.g. Hong Kong). - Other regions, such as South America (e.g. Brazil) are actively - considering it. - - Implementation of NP within a national telephony infrastructure - entails potentially significant changes to numbering administration, - network element signaling, call routing and processing, billing, - service management, and other functions. - - NP changes the fundamental nature of a dialed E.164 number from a - hierarchical physical routing address to a virtual address. NP - implementations attempt to encapsulate the impacts to the GSTN and - make NP transparent to subscribers by incorporating a translation - function to map a dialed, potentially ported E.164 address, into a - network routing address (either a number prefix or another E.164 - address) which can be hierarchically routed. - - This is roughly analogous to the use of network address translation - on IP addresses to enable IP address portability by containing the - impact of the address change to the edge of the network and retain - the use of CIDR blocks in the core which can be route aggregated by - the network service provider to the rest of the internet. - - NP bifurcates the historical role of a subscriberËs E.164 address - into two or more data elements (a dialed or virtual address, and a - network routing address) that must be made available to network - elements through an NP translations database, carried by forward - call signaling, and recorded on call detail records. Not only is - call processing and routing affected, but also so is SS7/C7 - messaging. A number of TCAP-based SS7 messaging sets utilize an - E.164 address as an application-level network element address in the - global title address (GTA) field of the SCCP message header. - Consequently, SS7/C7 signaling transfer points (STPs) and gateways - need to be able to perform n-digit global title translation (GTT) to - translate a dialed E.164 address into its network address - counterpart via the NP database. - - In addition, there are various national regulatory constraints that - establish relevant parameters for NP implementation, most of which - are not network technology specific. Consequently, implementations - of NP behavior in IP telephony consistent with applicable regulatory - constraints, as well as the need for interoperation with the - - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 3] - -Number Portability in the GSTN: An Overview June 24, 2002 - - existing GSTN NP implementations, are relevant topics for numerous - areas of IP telephony work-in-progress at IETF. - - This document describes three types of number portability and the - four schemes that have been standardized to support SPNP for - geographic E.164 numbersspecifically. Following that, specific - information regarding the call routing and database query - implementations are described for several regions (North American - and Europe) and industries (wireless vs. wireline). The Number - Portability Database (NPDB) interfaces and the call routing schemes - that are used in the North America and Europe are described to show - the variety of standards that may be implemented worldwide. A - glance of the NP implementations worldwide is provided. Number - pooling is briefly discussed to show how NP is being enhanced in the - U.S. to conserve North American area codes. The conclusion briefly - touches the potential impacts of NP on IP & Telecommunications - Interoperability. Appendix A provides some specific technical and - regulatory information on NP in North America. Appendix B describes - the number portability administration process that manages the - number portability database in North America. - - -2. Abbreviations and Acronyms - - ACQ All Call Query - AIN Advanced Intelligent Network - AMPS Advanced Mobile Phone System - ANSI American National Standards Institute - CDMA Code Division Multiple Access - CdPA Called Party Address - CdPN Called Party Number - CH Code Holder - CMIP Common Management Information Protocol - CS1 Capability Set 1 - CS2 Capability Set 2 - DN Directory Number - DNS Domain Name System - ETSI European Technical Standards Institute - FCI Forward Call Indicator - GAP Generic Address Parameter - GMSC Gateway Mobile Services Switching Center or Gateway Mobile - Switching Center - GSM Global System for Mobile Communications - GSTN Global Switched Telephone Network - GW Gateways - HLR Home Location Register - IAM Initial Address Message - IETF Internet Engineering Task Force - ILNP Interim LNP - IN Intelligent Network - INAP Intelligent Network Application Part - INP Interim NP - IP Internet Protocol - IS-41 Interim Standards Number 41 - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 4] - -Number Portability in the GSTN: An Overview June 24, 2002 - - ISDN Integrated Services Digital Network - ISUP ISDN User Part - ITN Individual Telephony Number - ITU International Telecommunication Union - ITU-TS ITU-Telecommunication Sector - LDAP Lightweight Directory Access Protocol - LEC Local Exchange Carrier - LERG Local Exchange Routing Guide - LNP Local Number Portability - LRN Location Routing Number - MAP Mobile Application Part - MNP Mobile Number Portability - MSRN Mobile Station Roaming Number - MTP Message Transfer Part - NANP North American Numbering Plan - NP Number Portability - NPDB Number Portability Database - NRN Network Routing Number - OR Onward Routing - OSS Operation Support System - PCS Personal Communication Services - PNTI Ported Number Translation Indicator - PODP Public Office Dialing Plan - PUC Public Utility Commission - QoR Query on Release - RN Routing Number - RTP Return to Pivot - SCCP Signaling Connection Control Part - SCP Service Control Point - SIP Session Initiation Protocol - SMR Special Mobile Radio - SMS Service Management System - SPNP Service Provider Number Portability - SRF Signaling Relaying Function - SRI Send Routing Information - SS7 Signaling System Number 7 - STP Signaling Transfer Point - TCAP Transaction Capabilities Application Part - TDMA Time Division Multiple Access - TN Telephone Number - TRIP Telephony Routing Information Protocol - URL Universal Resource Locator - U.S. United States - - -3. Types of Number Portability - - As there are several types of E.164 numbers (telephone numbers, or - just TN) in the GSTN, there are correspondingly several types of - E.164 NP in the GSTN. First there are so-call non-geographic E.164 - numbers, commonly used for service-specific applications such as - freephone (800 or 0800). Portability of these numbers is called - non-geographic number portability (NGNP). NGNP, for example, was - deployed in the U.S. in 1986-92. - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 5] - -Number Portability in the GSTN: An Overview June 24, 2002 - - - Geographic number portability, which includes traditional fixed or - wireline numbers as well as mobile numbers which are allocated out - of geographic number range prefixes, is called NP or GNP or in the - U.S. local number portability (LNP). - - Number portability allows the telephony subscribers in the Global - Switched Telephone Network (GSTN) to keep their phone numbers when - they change their service providers or subscribed services, or when - they move to a new location. - - The ability to change the service provider while keeping the same - phone number is called service provider portability (SPNP) also - known as "operator portability." - - The ability to change the subscriberËs fixed service location while - keeping the same phone number is called location portability. - - The ability to change the subscribed services (e.g., from the plain - old telephone service to Integrated Services Digital Network (ISDN) - services) while keeping the same phone number is called service - portability. Another aspect of service portability is to allow the - subscribers to enjoy the subscribed services in the same way when - they roam outside their home networks as is supported by the - cellular/wireless networks. - - In addition, mobile number portability (MNP) refers to specific NP - implementation in mobile networks either as part of a broader NP - implementation in the GSTN or on a stand-alone basis. Where - interoperation of LNP and MNP is supported, service portability - between fixed and mobile service types is possible. - - At present, SPNP has been the primary form of NP deployed due to its - relevance in enabling local service competition. - - Also in use in the GSTN are the terms interim NP (INP) or Interim - LNP (ILNP) and true NP. Interim NP usually refers to the use of - remote call forwarding-like measures to forward calls to ported - numbers through the donor network to the new service network. These - are considered interim relative to true NP, which seeks to remove - the donor network or old service provider from the call or signaling - path altogether. Often the distinction between interim and true NP - is a national regulatory matter relative to the - technical/operational requirements imposed on NP in that country. - - Implementations of true NP in certain countries (e.g. U.S., Canada, - Spain, Belgium, Denmark) may pose specific requirements for IP - telephony implementations as a result of regulatory and industry - requirements for providing call routing and signaling independent of - the donor network or last previous serving network. - - - - - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 6] - -Number Portability in the GSTN: An Overview June 24, 2002 - - -4. Service Provider Number Portability Schemes - - Four schemes can be used to support service provider portability and - are briefly described below. But first, some further terms are - introduced. - - The donor network is the network that first assigned a telephone - number (e.g., TN +1-202-533-1234) to a subscriber, out of a number - range administratively (e.g., +1 202-533) assigned to it. The - current service provider (new SP) or new serving network is the - network that currently serves the ported number. The old serving - network (or old SP) is the network that previously served the ported - number before the number was ported to the new serving network. - Since a TN can port a number of times, the old SP is not necessarily - the same as the donor network, except for the first time the TN - ports away, or if the TN ports back into the donor network and away - again. While the new SP and old SP roles are transitory as a TN - ports around, the donor network is always the same for any - particular TN based on the service provider to whom the subtending - number range was administratively assigned. See the discussion - below on number pooling, as this enhancement to NP further - bifurcates the role of donor network into two (the number range or - code holder network, and the block holder network). - - To simplify the illustration, all the transit networks are ignored, - the originating or donor network is the one that performs the - database queries or call redirection, and the dialed directory - number (TN) has been ported out of the donor network before. - - It is assumed that the old serving network, the new serving network - and the donor network are different networks so as to show which - networks are involved in call handling and routing and database - queries in each of four schemes. Please note that the port of the - number (process of moving it from one network to another) happened - prior to the call setup and is not included in the call steps. - Information carried in the signaling messages to support each of the - four schemes is not discussed to simplify the explanation. - - -4.1 All Call Query (ACQ) - - Figure 1 shows the call steps for the ACQ scheme. Those call steps - are as follows: - - (1) The Originating Network receives a call from the caller and - sends a query to a centrally administered Number Portability - Database (NPDB), a copy of which is usually resident on a - network element within its network or through a third party - provider. - (2) The NPDB returns the routing number associated with the dialed - directory number. The routing number is discussed later in - Section 6. - - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 7] - -Number Portability in the GSTN: An Overview June 24, 2002 - - (3) The Originating Network uses the routing number to route the - call to the new serving network. - - - +-------------+ +-----------+ Number +-----------+ - | Centralized | | New Serv. | ported | Old Serv. | - | NPDB | +-------->| Network |<------------| Network | - +-------------+ | +-----------+ +-----------+ - ^ | | - | | | - 1| | 3.| - | | 2. | - | | | - | v | - +----------+ | +----------+ +----------+ - | Orig. |------+ | Donor | | Internal | - | Network | | Network | | NPDB | - +----------+ +----------+ +----------+ - - - Figure 1 - All Call Query (ACQ) Scheme. - - -4.2 Query on Release (QoR) - - Figure 2 shows the call steps for the QoR scheme. Those call steps - are as follows: - - - +-------------+ +-----------+ Number +-----------+ - | Centralized | | New Serv. | ported | Old Serv. | - | NPDB | | Network |<------------| Network | - +-------------+ +-----------+ +-----------+ - ^ | ^ - | | 4. | - 3.| | 5. | - | | +----------------------+ - | | | - | v | - +----------+ 2. +----------+ +----------+ - | Orig. |<---------------| Donor | | Internal | - | Network |--------------->| Network | | NPDB | - +----------+ 1. +----------+ +----------+ - - - Figure 2 - Query on Release (QoR) Scheme. - - (1) The Originating Network receives a call from the caller and - routes the call to the donor network. - (2) The donor network releases the call and indicates that the - dialed directory number has been ported out of that switch. - (3) The Originating Network sends a query to its copy of the - centrally administered NPDB. - - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 8] - -Number Portability in the GSTN: An Overview June 24, 2002 - - (4) The NPDB returns the routing number associated with the dialed - directory number. - (5) The Originating Network uses the routing number to route the - call to the new serving network. - - -4.3 Call Dropback - - Figure 3 shows the call steps for the Dropback scheme. This scheme - is also known as "Return to Pivot (RTP)." Those call steps are as - follows: - - (1) The Originating Network receives a call from the caller and - routes the call to the donor network. - (2) The donor network detects that the dialed directory number has - been ported out of the donor switch and checks with an internal - network-specific NPDB. - (3) The internal NPDB returns the routing number associated with the - dialed directory number. - (4) The donor network releases the call by providing the routing - number. - (5) The Originating Network uses the routing number to route the - call to the new serving network. - - +-------------+ +-----------+ Number +-----------+ - | Centralized | | New Serv. | porting | Old Serv. | - | NPDB | | Network |<------------| Network | - +-------------+ +-----------+ +-----------+ - /\ - | - 5. | - +------------------------+ - | - | - +----------+ 4. +----------+ 3. +----------+ - | Orig. |<---------------| Donor |<----------| Internal | - | Network |--------------->| Network |---------->| NPDB | - +----------+ 1. +----------+ 2. +----------+ - - - Figure 3 - Dropback Scheme. - - -4.4 Onward Routing (OR) - - Figure 4 shows the call steps for the OR scheme. Those call steps - are as follows: - - (1) The Originating Network receives a call from the caller and - routes the call to the donor network. - (2) The donor network detects that the dialed directory number has - been ported out of the donor switch and checks with an internal - network-specific NPDB. - - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 9] - -Number Portability in the GSTN: An Overview June 24, 2002 - - (3) The internal NPDB returns the routing number associated with the - dialed directory number. - (4) The donor network uses the routing number to route the call to - the new serving network. - - - +-------------+ +-----------+ Number +-----------+ - | Centralized | | New Serv. | porting | Old Serv. | - | NPDB | | Network |<------------| Network | - +-------------+ +-----------+ +-----------+ - /\ - | - 4.| - | - +----------+ +----------+ 3. +----------+ - | Orig. | | Donor |<----------| Internal | - | Network |--------------->| Network |---------->| NPDB | - +----------+ 1. +----------+ 2. +----------+ - - - Figure 4 - Onward Routing (OR) Scheme. - -4.5 Comparisons of the Four Schemes - - Only the ACQ scheme does not involve the donor network when routing - the call to the new serving network of the dialed ported number. - The other three schemes involve call setup to or signaling with the - donor network. - - Only the OR scheme requires the setup of two physical call segments, - one from the Originating Network to the donor network and the other - from the donor network to the new serving network. The OR scheme is - the least efficient in terms of using the network transmission - facilities. The QoR and Dropback schemes set up calls to the donor - network first but release the call back to the Originating Network - that then initiates a new call to the Current Serving Network. For - the QoR and Dropback schemes, circuits are still reserved one by one - between the Originating Network and the donor network when the - Originating Network sets up the call towards the donor network. - Those circuits are released one by one when the call is released - from the donor network back to the Originating Network. The ACQ - scheme is the most efficient in terms of using the switching and - transmission facilities for the call. - - Both the ACQ and QoR schemes involve Centralized NPDBs for the - Originating Network to retrieve the routing information. - Centralized NPDB means that the NPDB contains ported number - information from multiple networks. This is in contrast to the - internal network-specific NPDB that is used for the Dropback and OR - schemes. The internal NPDB only contains information about the - numbers that were ported out of the donor network. The internal - NPDB can be a stand-alone database that contains information about - all or some ported-out numbers from the donor network. It can also - reside on the donor switch and only contains information about those - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 10] - -Number Portability in the GSTN: An Overview June 24, 2002 - - numbers ported out of the donor switch. In that case, no query to a - stand-alone internal NPDB is required. The donor switch for a - particular phone number is the switch to which the number range is - assigned from which that phone number was originally assigned. - - For example, number ranges in the North American Numbering Plan - (NANP) are usually assigned in the form of central office codes (CO - codes) comprising a six-digit prefix formatted as a NPA+NXX. Thus a - switch serving +1-202-533 would typically serve +1-202-533-0000 - through +1-202-533-9999. In major cities, switches usually host - several CO codes. NPA stands for Numbering Plan Area that is also - known as the area code. It is three-digit long and has the format - of NXX where N is any digit from 2 to 9 and X is any digit from 0 to - 9. NXX in the NPA+NXX format is known as the office code that has - the same format as the NPA. When a NPA+NXX code is set as - Ÿportable÷ in the Local Exchange Routing Guide (LERG), it becomes a - "portable NPA+NXX" code. - - Similarly, in other national E.164 numbering plans, number ranges - cover a contiguous range of numbers within that range. Once a - number within that range has ported away from the donor network, all - numbers in that range are considered potentially ported and should - be queried in the NPDB. - - The ACQ scheme has two versions. One version is for the Originating - Network to always query the NPDB when a call is received from the - caller regardless whether the dialed directory number belongs to any - number range that is portable or has at least one number ported out. - The other version is to check whether the dialed directory number - belongs to any number range that is portable or has at least one - number ported out. If yes, an NPDB query is sent. If not, no NPDB - query is sent. The former performs better when there are many - portable number ranges. The latter performs better when there are - not too many portable number ranges at the expense of checking every - call to see whether NPDB query is needed. The latter ACQ scheme is - similar to the QoR scheme except that the QoR scheme uses call setup - and relies on the donor network to indicate "number ported out" - before launching the NPDB query. - - -5. Database Queries in the NP Environment - - As indicated earlier, the ACQ and QoR schemes require that a switch - query the NPDB for routing information. Various standards have been - defined for the switch-to-NPDB interface. Those interfaces with - their protocol stacks are briefly described below. The term "NPDB" - is used for a stand-alone database that may support just one or some - or all of the interfaces mentioned below. The NPDB query contains - the dialed directory number and the NPDB response contains the - routing number. There are certainly other information that is sent - in the query and response. The primary interest is to get the - routing number from the NPDB to the switch for call routing. - - - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 11] - -Number Portability in the GSTN: An Overview June 24, 2002 - -5.1 U.S. and Canada - - One of the following five NPDB interfaces can be used to query an - NPDB: - - (a) Advanced Intelligent Network (AIN) using the American National - Standards Institute (ANSI) version of the Intelligent Network - Application Part (INAP) [ANSI SS] [ANSI DB]. The INAP is - carried on top of the protocol stack that includes the (ANSI) - Message Transfer Part (MTP) Levels 1 through 3, ANSI Signaling - Connection Control Part (SCCP), and ANSI Transaction - Capabilities Application Part (TCAP). This interface can be - used by the wireline or wireless switches, is specific to the NP - implementation in North America, and is modeled on the Public - Office Dialing Plan (PODP) trigger defined in the Advanced - Intelligent Network (AIN) 0.1 call model. - - (b) Intelligent Network (IN), which is similar to the one used for - querying the 800 databases. The IN protocol is carried on top - of the protocol stack that includes the ANSI MTP Levels 1 - through 3, ANSI SCCP, and ANSI TCAP. This interface can be used - by the wireline or wireless switches. - - (c) ANSI IS-41 [IS41] [ISNP], which is carried on top of the - protocol stack that includes the ANSI MTP Levels 1 through 3, - ANSI SCCP, and ANSI TCAP. This interface can be used by the IS- - 41 based cellular/Personal Communication Services (PCS) wireless - switches (e.g., AMPS, TDMA and CDMA). Cellular systems use - spectrum at 800 MHz range and PCS systems use spectrum at 1900 - MHz range. - - (d) Global System for Mobile Communication Mobile Application Part - (GSM MAP) [GSM], which is carried on top of the protocol stack - that includes the ANSI MTP Levels 1 through 3, ANSI SCCP, and - International Telecommunication Union - Telecommunication Sector - (ITU-TS) TCAP. It can be used by the PCS1900 wireless switches - that are based on the GSM technologies. GSM is a series of - wireless standards defined by the European Telecommunications - Standards Institute (ETSI). - - (e) ISUP triggerless translation. NP translations are performed - transparently to the switching network by the signaling network - (e.g. Signaling Transfer Points (STPs) or signaling gateways). - ISUP IAM messages are examined to determine if the CdPN field - has already been translated, and if not, an NPDB query is - performed, and the appropriate parameters in the IAM message - modified to reflect the results of the translation. The - modified IAM message is forwarded by the signaling node on to - the designated DPC in a transparent manner to continue call - setup. The NPDB can be integrated with the signaling node or be - accessed via an API locally or by a query to a remote NPDB using - a proprietary protocol or the schemes described above. - - - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 12] - -Number Portability in the GSTN: An Overview June 24, 2002 - - Wireline switches have the choice of using either (a), (b), or (e). - IS-41 based wireless switches have the choice of using (a), (b), - (c), or (e). PCS1900 wireless switches have the choice of using - (a), (b), (d), or (e). In the United States, service provider - portability will be supported by both the wireline and wireless - systems, not only within the wireline or wireless domain but also - across the wireline/wireless boundary. However, this is not true in - Europe where service provider portability is usually supported only - within the wireline or wireless domain, not across the - wireline/wireless boundary due to explicit use of service-specific - number range prefixes. The reason is to avoid caller confusion - about the call charge. GSM systems in Europe are assigned - distinctive destination network codes, and the caller pays a higher - charge when calling a GSM directory number. - - -5.2 Europe - - One of the following two interfaces can be used to query an NPDB: - - (a) Capability Set 1 (CS1) of the ITU-TS INAP [CS1], which is - carried on top of the protocol stack that includes the ITU-TS - MTP Levels 1 through 3, ITU-TS SCCP, and ITU-TS TCAP. - - (b) Capability Set 2 (CS2) of the ITU-TS INAP [CS2], which is - carried on top of the protocol stack that includes the ITU-TS - MTP Levels 1 through ITU-TS MTP Levels 1 through 3, ITU-TS SCCP, - and ITU-TS TCAP. - - Wireline switches have the choice of using either (a) or (b); - however, all the implementations in Europe so far are based on CS1. - As indicated earlier that number portability in Europe does not go - across the wireline/wireless boundary. The wireless switches can - also use (a) or (b) to query the NPDBs if those NPDBs contains - ported wireless directory numbers. The term "Mobile Number - Portability (MNP)" is used for the support of service provider - portability by the GSM networks in Europe. - - In most, if not all, cases in Europe, the calls to the wireless - directory numbers are routed to the wireless donor network first. - Over there, an internal NPDB is queried to determine whether the - dialed wireless directory number has been ported out or not. In - this case, the interface to the internal NPDB is not subject to - standardization. - - MNP in Europe can also be supported via MNP Signaling Relay Function - (MNP-SRF). Again, an internal NPDB or a database integrated at the - MNP-SRF is used to modify the SCCP Called Party Address parameter in - the GSM MAP messages so that they can be re-directed to the wireless - serving network. Call routing involving MNP will be explained in - Section 6.2. - - - - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 13] - -Number Portability in the GSTN: An Overview June 24, 2002 - -6. Call Routing in the NP Environment - - This section discusses the call routing after the routing - information has been retrieved either through an NPDB query or an - internal database lookup at the donor switch, or from the Integrated - Services Digital Network User Part (ISUP) signaling message (e.g., - for the Dropback scheme). For the ACQ, QoR and Dropback schemes, it - is the Originating Network that has the routing information and is - ready to route the call. For the OR scheme, it is the donor network - that has the routing information and is ready to route the call. - - A number of triggering schemes may be employed that determine where - in the call path the NPDB query is performed. In the U.S. an ŸN-1÷ - policy is used, which essentially says that for domestic calls, the - originating local carriers performs the query, otherwise, the long - distance carrier is expected to. To ensure independence of the - actual trigger policy employed in any one carrier, forward call - signaling is used to flag that an NPDB query has already been - performed and to therefore suppress any subsequent NP triggers that - may be encountered in downstream switches, in downstream networks. - This allows the earliest able network in the call path to perform - the query without introducing additional costs and call setup delays - were redundant queries performed downstream. - - -6.1 U.S. and Canada - - In the U.S. and Canada, a ten-digit North American Numbering Plan - (NANP) number called Location Routing Number (LRN) is assigned to - every switch involved in NP. In the NANP, a switch is not reachable - unless it has a unique number range (CO code) assigned to it. - Consequently, the LRN for a switch is always assigned out of a CO - code that is assigned to that switch. - - The LRN assigned to a switch currently serving a particular ported - telephone number is returned as the network routing address in the - NPDB response. The service portability scheme that was adopted in - the North America is very often referred to as the LRN scheme or - method. - - LRN serves as a network address for terminating calls served off - that switch using ported numbers. The LRN is assigned by the switch - operator using any of the unique CO codes (NPA+NXX) assigned to that - switch. The LRN is considered a non-dialable address, as the same - 10-digit number value may be assigned to a line on that switch. A - switch may have more than one LRN. - - During call routing/processing, a switch performs an NPDB query to - obtain the LRN associated with the dialed directory number. NPDB - queries are performed for all the dialed directory numbers whose - NPA+NXX codes are marked as portable NPA+NXX at that switch. When - formulating the ISUP Initial Address Message (IAM) to be sent to the - next switch, the switch puts the ten-digit LRN in the ISUP Called - Party Number (CdPN) parameter and the originally dialed directory - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 14] - -Number Portability in the GSTN: An Overview June 24, 2002 - - number in the ISUP Generic Address parameter (GAP). A new code in - the GAP was defined to indicate that the address information in the - GAP is the dialed directory number. A new bit in the ISUP Forward - Call Indicator (FCI) parameter, the Ported Number Translation - Indicator (PNTI) bit, is set to imply that NPDB query has already - been performed. All the switches in the downstream will not perform - the NPDB query if the PNTI bit is set. - - When the terminating switch receives the IAM and sees the PNTI bit - in the FCI parameter set and its own LRN in the CdPN parameter, it - retrieves the originally dialed directory number from the GAP and - uses the dialed directory number to terminate the call. - - A dialed directory number with a portable NPA+NXX does not imply - that directory number has been ported. The NPDBs currently do not - store records for non-ported directory numbers. In that case, the - NPDB will return the same dialed directory number instead of the - LRN. The switch will then set the PNTI bit but keep the dialed - directory number in the CdPN parameter. - - In the real world environment, the Originating Network is not always - the one that performs the NPDB query. For example, it is usually - the long distance carriers that query the NPDBs for long distance - calls. In that case, the Originating Network operated by the local - exchange carrier (LEC) simply routes the call to the long distance - carrier that is to handle that call. A wireless network acting as - the Originating Network can also route the call to the - interconnected local exchange carrier network if it does not want to - support the NPDB interface at its mobile switches. - - -6.2 Europe - - In some European countries, a routing number is prefixed to the - dialed directory number. The ISUP CdPN parameter in the IAM will - contain the routing prefix and the dialed directory number. For - example, United Kingdom uses routing prefixes with the format of - 5XXXXX and Italy uses C600XXXXX as the routing prefix. The networks - use the information in the ISUP CdPN parameter to route the call to - the New/Current Serving Network. - - The routing prefix can identify the Current Serving Network or the - Current Serving Switch of a ported number. For the former case, - another query to the "internal" NPDB at the Current Serving Network - is required to identify the Current Serving Switch before routing - the call to that switch. This shields the Current Serving Switch - information for a ported number from the other networks at the - expense of an additional NPDB query. Another routing number, may be - meaningful within the Current Serving Network, will replace the - previously prefixed routing number in the ISUP CdPN parameter. For - the latter case, the call is routed to the Current Serving Switch - without an additional NPDB query. - - - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 15] - -Number Portability in the GSTN: An Overview June 24, 2002 - - When the terminating switch receives the IAM and sees its own - routing prefix in the CdPN parameter, it retrieves the originally - dialed directory number after the routing prefix, and uses the - dialed directory number to terminate the call. - - The call routing example described above shows one of the three - methods that can be used to transport the Directory Number (DN) and - the Routing Number (RN) in the ISUP IAM message. In addition, some - other information may be added/modified as is listed in the ETSI 302 - 097 document [ETSIISUP], which is based on the ITU-T Recommendation - Q.769.1 [ITUISUP]. The three methods and the enhancements in the - ISUP to support number portability are briefly described below - - (a) Two separate parameters with the CdPN parameter containing the - RN and a new Called Directory Number (CdDN) parameter containing - the DN. A new value for the Nature of Address (NOA) indicator in - the CdPN parameter is defined to indicate that the RN is in the - CdPN parameter. The switches use the CdPN parameter to route the - call as is done today. - - (b) Two separate parameters with the CdPN parameter containing the - DN and a new Network Routing Number (NRN) parameter containing - the RN. This method requires that the switches use the NRN - parameter to route the call. - - (c) Concatenated parameter with the CdPN parameter containing the RN - plus the DN. A new Nature of Address (NOA) indicator in the CdPN - parameter is defined to indicate that the RN is concatenated with - the DN in the CdPN parameter. Some countries may not use new NOA - value because the routing prefix does not overlap with the dialed - directory numbers. But if the routing prefix overlaps with the - dialed directory numbers, a new NOA value must be assigned. For - example, Spain uses "XXXXXX" as the routing prefix to identify - the new serving network and uses a new NOA value of 126. - - There is also a network option to add a new ISUP parameter called - Number Portability Forwarding Information parameter. This parameter - has a four-bit Number Portability Status Indicator field that can - provide an indication whether number portability query is done for - the called directory number and whether the called directory number - is ported or not if the number portability query is done. - - Please note that all those NP enhancements for a ported number can - only be used in the country that defined them. This is because - number portability is supported within a nation. Within each - nation, the telecommunications industry or the regulatory bodies can - decide which method or methods to use. Number portability related - parameters and coding are usually not passed across the national - boundaries unless the interconnection agreements allow that. For - example, a UK routing prefix can only be used in UK, and would cause - routing problem if it appears outside UK. - - - - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 16] - -Number Portability in the GSTN: An Overview June 24, 2002 - - As indicated earlier, an originating wireless network can query the - NPDB and concatenate the RN with DN in the CdPN parameter and route - the call directly to the Current Serving Network. - - If NPDBs do not contain information about the wireless directory - numbers, the call, originated from either a wireline or a wireless - network, will be routed to the Wireless donor network. Over there, - an internal NPDB is queried to retrieve the RN that then is - concatenated with the DN in the CdPN parameter. - - There are several ways of realizing MNP. When MNP-SRF is supported, - the Gateway Mobile Services Switching Center (GMSC) at the wireless - donor network, when receiving a call from the wireline network, can - send the GSM MAP Send Routing Information (SRI) message to the MNP- - SRF. The MNP-SRF interrogates an internal or integrated NPDB for - the RN of the MNP-SRF of the wireless Current Serving Network and - prefixes the RN to the dialed wireless directory number in the - global title address information in the SCCP Called Party Address - (CdPA) parameter. This SRI message will be routed to the MNP-SRF of - the wireless Current Serving Network, which then responds with an - acknowledgement by providing the RN plus the dialed wireless - directory number as the Mobile Station Roaming Number (MSRN). The - GMSC of the wireless donor network formulates the ISUP IAM with the - RN plus the dialed wireless directory number in the CdPN parameter - and routes the call to the wireless Current Serving Network. A GMSC - of the wireless Current Serving Network receives the call and sends - an SRI message to the associated MNP-SRF where the global title - address information of the SCCP CdPA parameter contains only the - dialed wireless directory number. The MNP-SRF then replaces the - global title address information in the SCCP CdPA parameter with the - address information associated with a Home Location Register (HLR) - that hosts the dialed wireless directory number and forwards the - message to that HLR after verifying that the dialed wireless - directory number is a ported-in number. The HLR then returns an - acknowledgement by providing an MSRN for the GMSC to route the call - to the MSC that currently serves the mobile station that is - associated with the dialed wireless directory number. Please see - [MNP] for details and additional scenarios. - - -7. NP Implementations for Geographic E.164 Numbers - - This section shows the known SPNP implementations worldwide. - - +-------------+----------------------------------------------------+ - + Country + SPNP Implementation + - +-------------+----------------------------------------------------+ - + Argentina + Analyzing operative viability now. Will determine + - + + whether portability should be made obligatory + - + + after a technical solution has been determined. + - +-------------+----------------------------------------------------+ - + Australia + NP supported by wireline operators since 11/30/99. + - + + NP among wireless operators in March/April 2000, + - - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 17] - -Number Portability in the GSTN: An Overview June 24, 2002 - - + + but may be delayed to 1Q01. The access provider + - + + or long distance provider has the obligation to + - + + route the call to the correct destination. The + - + + donor network is obligated to maintain and make + - + + available a register of numbers ported away from + - + + its network. Telstra uses onward routing via an + - + + on-switch solution. + - +-------------+----------------------------------------------------+ - + Austria + Uses onward routing at the donor network. Routing + - + + prefix is "86xx" where "xx" identifies the + - + + recipient network. + - +-------------+----------------------------------------------------+ - + Belgium + ACQ selected by the industry. Routing prefix is + - + + "Cxxxx" where "xxxx" identifies the recipient + - + + switch. Another routing prefix is "C00xx" with "xx"+ - + + identifying the recipient network. Plan to use NOA+ - + + to identify concatenated numbers and abandon the + - + + hexadecimal routing prefix. + - +-------------+----------------------------------------------------+ - + Brazil + Considering NP for wireless users. + - +-------------+----------------------------------------------------+ - + Chile + There has been discussions lately on NP. + - +-------------+----------------------------------------------------+ - + Colombia + There was an Article 3.1 on NP to support NP prior + - + + to December 31, 1999 when NP became technically + - + + possible. Regulator has not yet issued regulations + - + + concerning this matter. + - +-------------+----------------------------------------------------+ - + Denmark + Uses ACQ. Routing number not passed between + - + + operators; however, NOA is set to "112" to + - + + indicate "ported number." QoR can be used based + - + + on bilateral agreements. + - +-------------+----------------------------------------------------+ - + Finland + Uses ACQ. Routing prefix is "1Dxxy" where "xxy" + - + + identifies the recipient network and service type. + - +-------------+----------------------------------------------------+ - + France + Uses onward routing. Routing prefix is "Z0xxx" + - + + where "xxx" identifies the recipient switch. + - +-------------+----------------------------------------------------+ - + Germany + The originating network needs to do necessary + - + + rerouting. Operators decide their own solution(s).+ - + + Deutsche Telekom uses ACQ. Routing prefix is + - + + "Dxxx" where "xxx" identifies the recipient + - + + network. + - +-------------+----------------------------------------------------+ - + Hong Kong + Recipient network informs other networks about + - + + ported-in numbers. Routing prefix is "14x" where + - + + "14x" identifies the recipient network, or a + - + + routing number of "4x" plus 7 or 8 digits is used + - + + where "4x" identifies the recipient network and + - + + the rest of digits identify the called party. + - +-------------+----------------------------------------------------+ - + Ireland + Operators choose their own solution but use onward + - + + routing now. Routing prefix is "1750" as the intra-+ - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 18] - -Number Portability in the GSTN: An Overview June 24, 2002 - - + + network routing code (network-specific) and + - + + "1752xxx" to "1759xxx" for GNP where "xxx" + - + + identifies the recipient switch. + - +-------------+----------------------------------------------------+ - + Italy + Uses onward routing. Routing prefix is "C600xxxxx" + - + + where "xxxxx" identifies the recipient switch. + - + + Telecom Italia uses IN solution and other operators+ - + + use on-switch solution. + - +-------------+----------------------------------------------------+ - + Japan + Uses onward routing. Donor switch uses IN to get + - + + routing number. + - +-------------+----------------------------------------------------+ - + Mexico + NP is considered in the Telecom law; however, the + - + + regulator (Cofetel) or the new local entrants have + - + + started no initiatives on this process. + - +-------------+----------------------------------------------------+ - + Netherlands + Operators decide NP scheme to use. Operators have + - + + chosen ACQ or QoR. KPN implemented IN solution + - + + similar to U.S. solution. Routing prefix is not + - + + passed between operators. + - +-------------+----------------------------------------------------+ - + Norway + OR for short-term and ACQ for long-term. QoR is + - + + optional. Routing prefix can be "xxx" with NOA=8, + - + + or "142xx" with NOA=3 where "xxx" or "xx" + - + + identifies the recipient network. + - +------------ +----------------------------------------------------+ - + Peru + Wireline NP may be supported in 2001. + - +-------------+----------------------------------------------------+ - + Portugal + No NP today. + - +-------------+----------------------------------------------------+ - + Spain + Uses ACQ. Telefonica uses QoR within its network. + - + + Routing prefix is "xxyyzz" where "xxyyzz" + - + + identifies the recipient network. NOA is set to + - + + 126. + - +-------------+----------------------------------------------------+ - + Sweden + Standardized the ACQ but OR for operators without + - + + IN. Routing prefix is "xxx" with NOA=8 or "394xxx" + - + + with NOA=3 where "xxx" identifies the recipient + - + + network. But operators decide NP scheme to use. + - + + Telia uses onward routing between operators. + - +-------------+----------------------------------------------------+ - + Switzerland + Uses OR now and QoR in 2001. Routing prefix is + - + + "980xxx" where "xxx" identifies the recipient + - + + network. + - +-------------+----------------------------------------------------+ - + UK + Uses onward routing. Routing prefix is "5xxxxx" + - + + where "xxxxx" identifies the recipient switch. NOA + - + + is 126. BT uses the dropback scheme in some parts + - + + of its network. + - +-------------+----------------------------------------------------+ - + US + Uses ACQ. "Location Routing Number (LRN)" is used + - + + in the Called Party Number parameter. Called party+ - + + number is carried in the Generic Address Parameter + - + + Use a PNTI indicator in the Forward Call Indicator + - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 19] - -Number Portability in the GSTN: An Overview June 24, 2002 - - + + parameter to indicate that NPDB dip has been + - + + performed. + - +-------------+----------------------------------------------------+ - - -8. Number Conservation Methods Enabled by NP - - In addition to porting numbers NP provides the ability for number - administrators to assign numbering resources to operators in smaller - increments. Today it is common for numbering resources to be - assigned to telephone operators in a large block of consecutive - telephone numbers (TNs). For example, in North America each of - these blocks contains 10,000 TNs and is of the format NXX+0000 to - NXX+9999. Operators are assigned a specific NXX, or block. That - operator is referred to as the block holder. In that block there - are 10,000 TNs with line numbers ranging from 0000 to 9999. - - Instead of assigning an entire block to the operator NP allows the - administrator to assign a sub-block or even an individual telephone - number. This is referred to as block pooling and individual - telephone number (ITN) pooling, respectively. - - -8.1 Block Pooling - - Block Pooling refers to the process whereby the number administrator - assigns a range of numbers defined by a logical sub-block of the - existing block. Using North America as an example, block pooling - would allow the administrator to assign sub-blocks of 1,000 TNs to - multiple operators. That is, NXX+0000 to NXX+0999 can be assigned - to operator A, NXX+1000 to NXX+1999 can be assigned to operator B, - NXX-2000 to 2999 can be assigned to operator C, etc. In this - example block pooling divides one block of 10,000 TNs into ten - blocks of 1,000 TNs. - - Porting the sub-blocks from the block holder enables block pooling. - Using the example above operator A is the block holder, as well as, - the holder of the first sub-block, NXX+0000 to NXX+0999. The second - sub-block, NXX+1000 to NXX+1999, is ported from operator A to - operator B. The third sub-block, NXX+2000 to NXX+2999, is ported - from operator A to operator C, and so on. NP administrative - processes and call processing will enable proper and efficient - routing. - - From a number administration and NP administration perspective block - pooling introduces a new concept, that of the sub-block holder. - Block pooling requires coordination between the number - administrator, the NP administrator, the block holder, and the sub- - block holder. Block pooling must be implemented in a manner that - allows for NP within the sub-blocks. Each TN can have a different - serving operator, sub-block holder, and block holder. - - - - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 20] - -Number Portability in the GSTN: An Overview June 24, 2002 - -8.2 ITN Pooling - - ITN pooling refers to the process whereby the number administrator - assigns individual telephone numbers to operators. Using the North - American example, one block of 10,000 TNs can be divided into 10,000 - ITNs. ITN is more commonly deployed in freephone services. - - In ITN the block is not assigned to an operator but to a central - administrator. The administrator then assigns ITNs to operators. - NP administrative processes and call processing will enable proper - and efficient routing. - - -9. Potential Implications - - There are three general areas of impact to IP telephony work-in- - progress at IETF: - - - Interoperation between NP in GSTN and IP telephony - - NP implementation or emulation in IP telephony - - Interconnection to NP administrative environment - - A good understanding of how number portability is supported in the - GSTN is important when addressing the interworking issues between - IP-based networks and the GSTN. This is especially important when - the IP-based network needs to route the calls to the GSTN. As shown - in Section 5, there are a variety of standards with various protocol - stacks for the switch-to-NPDB interface. Not only that, the - national variations of the protocol standards make it very - complicated to deal with in a global environment. If an entity in - the IP-based network needs to query those existing NPDBs for routing - number information to terminate the calls to the destination GSTN, - it would be impractical, if not an impossible, job for that entity - to support all those interface standards to access the NPDBs in many - countries. - - Several alternatives may address this particular problem. One - alternative is to use certain entities in the IP-based networks for - dealing with NP query, similar to the International Switches that - are used in the GSTN to interwork different national ISUP - variations. This will force signaling information associated with - the calls to certain NP-capable networks in the terminating GSTN to - be routed to those IP entities that support the NP functions. Those - IP entities then query the NPDBs in the terminating country. This - will limit the number of NPDB interfaces that certain IP entities - need to support. Another alternative can be to define a "common" - interface to be supported by all the NPDBs so that all the IP - entities use that standardized protocol to query them. The - existing NPDBs can support this additional interface, or new NPDBs - can be deployed that contain the same information but support the - common IP interface. The candidates for such a common interface - include Lightweight Directory Access Protocol (LDAP) and SIP - [SIP](e.g., using the SIP redirection capability). Certainly - - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 21] - -Number Portability in the GSTN: An Overview June 24, 2002 - - another possibility is to use interworking function to convert from - one protocol to another. - - IP-based networks can handle the domestic calls between two GSTNs. - If the originating GSTN has performed NPDB query, SIP will need to - transport and make use of some of the ISUP signaling information - even if ISUP signaling may be encapsulated in SIP. Also, IP-based - networks may perform the NPDB queries, as the N-1 carrier. In that - case, SIP also needs to transport the NP related information while - the call is being routed to the destination GSTN. There are three - pieces of NP related information that SIP needs to transport. They - are 1) the called directory number, 2) a routing number, and 3) a - NPDB dip indicator. The NPDB dip indicator is needed so that the - terminating GSTN will not perform another NPDB dip. The routing - number is needed so that it is used to route the call to the - destination network or switch in the destination GSTN. The called - directory number is needed so that the terminating GSTN switch can - terminate the call. When the routing number is present, the NPDB - dip indicator may not be present because there are cases where - routing number is added for routing the call even if NP is not - involved. One issue is how to transport the NP related information - via SIP. The SIP Universal Resource Locator (URL) is one mechanism. - Another better choice may be to add an extension to the "tel" URL - [TEL] that is also supported by SIP. Please see [TELNP] for the - proposed extensions to the "tel" URL to support NP and freephone - service. Those extensions to the "tel" URL will be automatically - supported by SIP because they can be carried as the optional - parameters in the user portion of the "sip" URL. - - For a called directory number that belongs to a country that - supports NP, and if the IP-based network is to perform the NPDB - query, the logical step is to perform the NPDB dip first to retrieve - the routing number and use that routing number to select the correct - IP telephony gateways that can reach the serving switch that serves - the called directory number. Therefore, if the "rn" parameter is - present in the "tel" URL or sip URL in the SIP INVITE message, it - instead of the called directory number should be used for making - routing decisions assuming that no other higher priority routing- - related parameters such as the Ÿcic÷ are present. If "rn" is not - present, then the dialed directory number can be used as the routing - number for making routing decisions. - - Telephony Routing Information Protocol (TRIP) [TRIP] is a policy - driven inter-administrative domain protocol for advertising the - reachability of telephony destinations between location servers, and - for advertising attributes of the routes to those destinations. - With the NP in mind, it is very important to know that it is the - routing number, if present, not the called directory number that - should be used to check against the TRIP tables for making the - routing decisions. - - Overlap signaling exists in the GSTN today. For a call routing from - the originating GSTN to the IP-based network that involves overlap - signaling, NP will impact the call processing within the IP-based - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 22] - -Number Portability in the GSTN: An Overview June 24, 2002 - - networks if they must deal with the overlap signaling. The entities - in the IP-based networks that are to retrieve the NP information - (e.g., the routing number) must collect a complete called directory - number information before retrieving the NP information for a ported - number. Otherwise, the information retrieval won't be successful. - This is an issue for the IP-based networks if the originating GSTN - does not handle the overlap signaling by collecting the complete - called directory number. - - The IETF enum working group is defining the use of Domain Name - System (DNS) for identifying available services associated with a - particular E.164 number [ENUM]. [ENUMPO] outlines the principles - for the operation of a telephone number service that resolves - telephone numbers into Internet domain name addresses and service- - specific directory discovery. [ENUMPO] implements a three-level - approach where the first level is the mapping of the telephone - number delegation tree to the authority to which the number has been - delegated, the second level is the provision of the requested DNS - resource records from a service registrar, and the third level is - the provision of service specific data from the service provider - itself. NP certainly must be considered at the first level because - the telephony service providers do not "own" or control the - telephone numbers under the NP environment; therefore, they may not - be the proper entities to have the authority for a given E.164 - number. Not only that, there is a regulatory requirement on NP in - some countries that the donor network should not be relied on to - reach the delegated authority during the DNS process . The - delegated authority for a given E.164 number is likely to be an - entity designated by the end user that owns/controls a specific - telephone number or one that is designated by the service registrar. - - Since the telephony service providers may have the need to use ENUM - for their network-related services (e.g., map an E.164 number to a - HLR Identifier in the wireless networks), their ENUM records must be - collocated with those of the telephony subscribers. If that is the - case, NP will impact ENUM when a telephony subscriber who has ENUM - service changes the telephony service provider. This is because - that the ENUM records from the new telephony service provider must - replace those from the old telephony service provider. To avoid the - NP impact on ENUM, it is recommended that the telephony service - providers use a different domain tree for their network-related - service. For example, if e164.arpa is chosen for Ÿend user÷ ENUM, a - domain tree different from e164.arpa should be used for Ÿcarrier÷ - ENUM. - - The IP-based networks also may need to support some forms of number - portability in the future if E.164 numbers [E164] are assigned to - the IP-based end users. One method is to assign a GSTN routing - number for each IP-based network domain or entity in a NP-capable - country. This may increase the number of digits in the routing - number to incorporate the IP entities and impact the existing - routing in the GSTN. Another method is to associate each IP entity - with a particular GSTN gateway. At that particular GSTN gateway, - the called directory number then is used to locate the IP-entity - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 23] - -Number Portability in the GSTN: An Overview June 24, 2002 - - that serves that dialed directory number. Yet, another method can - be to assign a special routing number so that the call to an end - user currently served by an IP entity is routed to the nearest GSTN - gateway. The called directory number then is used to locate the IP- - entity that serves that dialed directory number. A mechanism can be - developed or used for the IP-based network to locate the IP entity - that serves a particular dialed directory number. Many other types - of networks use E.164 numbers to identify the end users or terminals - in those networks. Number portability among GSTN, IP-based network - and those various types of networks may also need to be supported in - the future. - - -10. Security Considerations - - This document does not raise any security issues. - - -11. IANA Considerations - - This document introduces no new values for IANA registration. - - -12. Normative References - - [ANSI OSS] ANSI Technical Requirements No. 1, "Number Portability - - Operator Services Switching Systems," April 1999. - - [ANSI SS] ANSI Technical Requirements No. 2, "Number Portability - - Switching Systems," April 1999. - - [ANSI DB] ANSI Technical Requirements No. 3, "Number Portability - Database and Global Title Translation," April 1999. - - [CS1] ITU-T Q-series Recommendations - Supplement 4, "Number - portability Capability set 1 requirements for service provider - portability (All call query and onward routing)," May 1998. - - [CS2] ITU-T Q-series Recommendations - Supplement 5, "Number - portability -Capability set 2 requirements for service provider - portability (Query on release and Dropback)," March 1999. - - [E164] ITU-T Recommendation E.164, "The International Public - Telecommunications Numbering Plan," 1997. - - [ENUM] P. Falstrom, "E.164 number and DNS," RFC 2916. - - [ETSIISUP] ETSI EN 302 097 V.1.2.2, ŸIntegrated Services Digital - Network (ISDN); Signalling System No.7 (SS7); ISDN User Part - (ISUP); Enhancement for support of Number Portability (NP) - [ITU-T Recommendation Q.769.1 (2000), modified] - - [GSM] GSM 09.02: "Digital cellular telecommunications system (Phase - 2+); Mobile Application Part (MAP) specification". - -Foster,McGarry,Yu Expired on December 23, 2002 [Page 24] - -Number Portability in the GSTN: An Overview March 1, 2002 - - - - [IS41] TIA/EIA IS-756 Rev. A, "TIA/EIA-41-D Enhancements for - Wireless Number Portability Phase II (December 1998)"Number - Portability Network Support," April 1998. - - [ITUISUP] ITU-T Recommendation Q.769.1, "Signaling System No. 7 - - ISDN User Part Enhancements for the Support of Number - Portability," December 1999. - - [MNP] ETSI EN 301 716 (2000-10) European Standard - (Telecommunications series) Digital cellular telecommunications - system (Phase 2+); Support of Mobile Number Portability (MNP); - Technical Realisation; Stage 2; (GSM 03.66 Version 7.2.0 - Release 1998). - - [RFC] Scott Bradner, RFC2026, "The Internet Standards Process -- - Revision 3," October 1996. - - -13. Informative References - - [ENUMPO] A. Brown and G. Vaudreuil, "ENUM Service Specific - Provisioning: Principles of Operations," draft-ietf-enum- - operation-02.txt, February 23, 2001. - - [SIP] J. Rosenberg, et al., draft-ietf-sip-rfc2543bis-09.txt, "SIP: - Session Initiation Protocol," February 27, 2002. - - [TEL] H. Schulzrinne and A. Vaha-Sipila, draft-antti-rfc2806bis- - 04.txt, "URIs for Telephone Calls," May 24, 2002. - - [TELNP] J. Yu, draft-yu-tel-url-05.txt, "Extensions to the "tel" URL - to support Number Portability and Freephone Service," June 14, - 2002. - - [TRIP] J. Rosenberg, H. Salama and M. Squire, RFC 3219, "Telephony - Routing Information Protocol (TRIP)," January 2002. - - -14. Acknowledgment - - The authors would like to thank Monika Muench for providing - information on ISUP and MNP. - - -15. Authors' Addresses - - Mark D. Foster - NeuStar, Inc. - 1120 Vermont Avenue, NW, - Suite 400 - Washington, D.C. 20005 - United States - -Foster,McGarry,Yu Expired on August 31, 2002 [Page 25] - -Number Portability in the GSTN: An Overview March 1, 2002 - - - - Phone: +1-202-533-2800 - Fax: +1-202-533-2987 - Email: mark.foster@neustar.biz - - Tom McGarry - NeuStar, Inc. - 1120 Vermont Avenue, NW, - Suite 400 - Washington, D.C. 20005 - United States - - Phone: +1-202-533-2810 - Fax: +1-202-533-2987 - Email: tom.mcgarry@neustar.biz - - James Yu - NeuStar, Inc. - 1120 Vermont Avenue, NW, - Suite 400 - Washington, D.C. 20005 - United States - - Phone: +1-202-533-2814 - Fax: +1-202-533-2987 - Email: james.yu@neustar.biz - - - -Full Copyright Statement - - "Copyright (C) The Internet Society (2002). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph - are included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - - -Foster,McGarry,Yu Expired on August 31, 2002 [Page 26] - -Number Portability in the GSTN: An Overview March 1, 2002 - - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Foster,McGarry,Yu Expired on August 31, 2002 [Page 27] - \ No newline at end of file diff --git a/contrib/bind9/doc/draft/draft-ietf-ipv6-node-requirements-08.txt b/contrib/bind9/doc/draft/draft-ietf-ipv6-node-requirements-08.txt deleted file mode 100644 index 2d5c87e..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-ipv6-node-requirements-08.txt +++ /dev/null @@ -1,1200 +0,0 @@ - - - - - - -IPv6 Working Group John Loughney (ed) -Internet-Draft Nokia - January 14, 2004 - -Expires: July 14, 2004 - - - - IPv6 Node Requirements - draft-ietf-ipv6-node-requirements-08.txt - - - - -Status of this Memo - - This document is an Internet-Draft and is in full conformance with - all provisions of Section 10 of RFC2026. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as Internet- - Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - -Copyright Notice - - Copyright (C) The Internet Society (2003). All Rights Reserved. - -Abstract - - This document defines requirements for IPv6 nodes. It is expected - that IPv6 will be deployed in a wide range of devices and situations. - Specifying the requirements for IPv6 nodes allows IPv6 to function - well and interoperate in a large number of situations and - deployments. - - - - - -Loughney (editor) February 16, 2004 [Page 1] - - - - - -Internet-Draft - - -Table of Contents - - 1. Introduction - 1.1 Requirement Language - 1.2 Scope of this Document - 1.3 Description of IPv6 Nodes - 2. Abbreviations Used in This Document - 3. Sub-IP Layer - 3.1 Transmission of IPv6 Packets over Ethernet Networks - RFC2464 - 3.2 IP version 6 over PPP - RFC2472 - 3.3 IPv6 over ATM Networks - RFC2492 - 4. IP Layer - 4.1 Internet Protocol Version 6 - RFC2460 - 4.2 Neighbor Discovery for IPv6 - RFC2461 - 4.3 Path MTU Discovery & Packet Size - 4.4 ICMP for the Internet Protocol Version 6 (IPv6) - RFC2463 - 4.5 Addressing - 4.6 Multicast Listener Discovery (MLD) for IPv6 - RFC2710 - 5. Transport and DNS - 5.1 Transport Layer - 5.2 DNS - 5.3 Dynamic Host Configuration Protocol for IPv6 (DHCPv6) - 6. IPv4 Support and Transition - 6.1 Transition Mechanisms - 7. Mobility - 8. Security - 8.1 Basic Architecture - 8.2 Security Protocols - 8.3 Transforms and Algorithms - 8.4 Key Management Methods - 9. Router Functionality - 9.1 General - 10. Network Management - 10.1 MIBs - 11. Security Considerations - 12. References - 12.1 Normative - 12.2 Non-Normative - 13. Authors and Acknowledgements - 14. Editor's Address - Notices - - - - - - - - - - -Loughney (editor) February 16, 2004 [Page 2] - - - - - -Internet-Draft - - -1. Introduction - - The goal of this document is to define the common functionality - required from both IPv6 hosts and routers. Many IPv6 nodes will - implement optional or additional features, but all IPv6 nodes can be - expected to implement the mandatory requirements listed in this - document. - - This document tries to avoid discussion of protocol details, and - references RFCs for this purpose. In case of any conflicting text, - this document takes less precedence than the normative RFCs, unless - additional clarifying text is included in this document. - - Although the document points to different specifications, it should - be noted that in most cases, the granularity of requirements are - smaller than a single specification, as many specifications define - multiple, independent pieces, some of which may not be mandatory. - - As it is not always possible for an implementer to know the exact - usage of IPv6 in a node, an overriding requirement for IPv6 nodes is - that they should adhere to Jon Postel's Robustness Principle: - - Be conservative in what you do, be liberal in what you accept from - others [RFC-793]. - -1.1 Requirement Language - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in RFC 2119 [RFC-2119]. - -1.2 Scope of this Document - - IPv6 covers many specifications. It is intended that IPv6 will be - deployed in many different situations and environments. Therefore, - it is important to develop the requirements for IPv6 nodes, in order - to ensure interoperability. - - This document assumes that all IPv6 nodes meet the minimum - requirements specified here. - -1.3 Description of IPv6 Nodes - - From Internet Protocol, Version 6 (IPv6) Specification [RFC-2460] we - have the following definitions: - - Description of an IPv6 Node - - - - -Loughney (editor) February 16, 2004 [Page 3] - - - - - -Internet-Draft - - - - a device that implements IPv6 - - Description of an IPv6 router - - - a node that forwards IPv6 packets not explicitly addressed to - itself. - - Description of an IPv6 Host - - - any node that is not a router. - -2. Abbreviations Used in This Document - - ATM Asynchronous Transfer Mode - - AH Authentication Header - - DAD Duplicate Address Detection - - ESP Encapsulating Security Payload - - ICMP Internet Control Message Protocol - - IKE Internet Key Exchange - - MIB Management Information Base - - MLD Multicast Listener Discovery - - MTU Maximum Transfer Unit - - NA Neighbor Advertisement - - NBMA Non-Broadcast Multiple Access - - ND Neighbor Discovery - - NS Neighbor Solicitation - - NUD Neighbor Unreachability Detection - - PPP Point-to-Point Protocol - - PVC Permanent Virtual Circuit - - SVC Switched Virtual Circuit - -3. Sub-IP Layer - - - -Loughney (editor) February 16, 2004 [Page 4] - - - - - -Internet-Draft - - - An IPv6 node must include support for one or more IPv6 link-layer - specifications. Which link-layer specifications are included will - depend upon what link-layers are supported by the hardware available - on the system. It is possible for a conformant IPv6 node to support - IPv6 on some of its interfaces and not on others. - - As IPv6 is run over new layer 2 technologies, it is expected that new - specifications will be issued. This section highlights some major - layer 2 technologies and is not intended to be complete. - -3.1 Transmission of IPv6 Packets over Ethernet Networks - RFC2464 - - Nodes supporting IPv6 over Ethernet interfaces MUST implement - Transmission of IPv6 Packets over Ethernet Networks [RFC-2464]. - -3.2 IP version 6 over PPP - RFC2472 - - Nodes supporting IPv6 over PPP MUST implement IPv6 over PPP [RFC- - 2472]. - -3.3 IPv6 over ATM Networks - RFC2492 - - Nodes supporting IPv6 over ATM Networks MUST implement IPv6 over ATM - Networks [RFC-2492]. Additionally, RFC 2492 states: - - A minimally conforming IPv6/ATM driver SHALL support the PVC mode - of operation. An IPv6/ATM driver that supports the full SVC mode - SHALL also support PVC mode of operation. - -4. IP Layer - -4.1 Internet Protocol Version 6 - RFC2460 - - The Internet Protocol Version 6 is specified in [RFC-2460]. This - specification MUST be supported. - - Unrecognized options in Hop-by-Hop Options or Destination Options - extensions MUST be processed as described in RFC 2460. - - The node MUST follow the packet transmission rules in RFC 2460. - - Nodes MUST always be able to send, receive and process fragment - headers. All conformant IPv6 implementations MUST be capable of - sending and receving IPv6 packets; forwarding functionality MAY be - supported - - RFC 2460 specifies extension headers and the processing for these - headers. - - - -Loughney (editor) February 16, 2004 [Page 5] - - - - - -Internet-Draft - - - A full implementation of IPv6 includes implementation of the - following extension headers: Hop-by-Hop Options, Routing (Type 0), - Fragment, Destination Options, Authentication and Encapsulating - Security Payload. [RFC-2460] - - An IPv6 node MUST be able to process these headers. It should be - noted that there is some discussion about the use of Routing Headers - and possible security threats [IPv6-RH] caused by them. - -4.2 Neighbor Discovery for IPv6 - RFC2461 - - Neighbor Discovery SHOULD be supported. RFC 2461 states: - - "Unless specified otherwise (in a document that covers operating - IP over a particular link type) this document applies to all link - types. However, because ND uses link-layer multicast for some of - its services, it is possible that on some link types (e.g., NBMA - links) alternative protocols or mechanisms to implement those - services will be specified (in the appropriate document covering - the operation of IP over a particular link type). The services - described in this document that are not directly dependent on - multicast, such as Redirects, Next-hop determination, Neighbor - Unreachability Detection, etc., are expected to be provided as - specified in this document. The details of how one uses ND on - NBMA links is an area for further study." - - Some detailed analysis of Neighbor Discovery follows: - - Router Discovery is how hosts locate routers that reside on an - attached link. Router Discovery MUST be supported for - implementations. - - Prefix Discovery is how hosts discover the set of address prefixes - that define which destinations are on-link for an attached link. - Prefix discovery MUST be supported for implementations. Neighbor - Unreachability Detection (NUD) MUST be supported for all paths - between hosts and neighboring nodes. It is not required for paths - between routers. However, when a node receives a unicast Neighbor - Solicitation (NS) message (that may be a NUD's NS), the node MUST - respond to it (i.e. send a unicast Neighbor Advertisement). - - Duplicate Address Detection MUST be supported on all links supporting - link-layer multicast (RFC2462 section 5.4 specifies DAD MUST take - place on all unicast addresses). - - A host implementation MUST support sending Router Solicitations. - - Receiving and processing Router Advertisements MUST be supported for - - - -Loughney (editor) February 16, 2004 [Page 6] - - - - - -Internet-Draft - - - host implementations. The ability to understand specific Router - Advertisement options is dependent on supporting the specification - where the RA is specified. - - Sending and Receiving Neighbor Solicitation (NS) and Neighbor - Advertisement (NA) MUST be supported. NS and NA messages are required - for Duplicate Address Detection (DAD). - - Redirect functionality SHOULD be supported. If the node is a router, - Redirect functionality MUST be supported. - -4.3 Path MTU Discovery & Packet Size - -4.3.1 Path MTU Discovery - RFC1981 - - Path MTU Discovery [RFC-1981] SHOULD be supported, though minimal - implementations MAY choose to not support it and avoid large packets. - The rules in RFC 2460 MUST be followed for packet fragmentation and - reassembly. - -4.3.2 IPv6 Jumbograms - RFC2675 - - IPv6 Jumbograms [RFC-2675] MAY be supported. - -4.4 ICMP for the Internet Protocol Version 6 (IPv6) - RFC2463 - - ICMPv6 [RFC-2463] MUST be supported. - -4.5 Addressing - -4.5.1 IP Version 6 Addressing Architecture - RFC3513 - - The IPv6 Addressing Architecture [RFC-3513] MUST be supported. - -4.5.2 IPv6 Stateless Address Autoconfiguration - RFC2462 - - IPv6 Stateless Address Autoconfiguration is defined in [RFC-2462]. - This specification MUST be supported for nodes that are hosts. - - Nodes that are routers MUST be able to generate link local addresses - as described in RFC 2462 [RFC-2462]. - - From 2462: - - The autoconfiguration process specified in this document applies - only to hosts and not routers. Since host autoconfiguration uses - information advertised by routers, routers will need to be - configured by some other means. However, it is expected that - - - -Loughney (editor) February 16, 2004 [Page 7] - - - - - -Internet-Draft - - - routers will generate link-local addresses using the mechanism - described in this document. In addition, routers are expected to - successfully pass the Duplicate Address Detection procedure - described in this document on all addresses prior to assigning - them to an interface. - - Duplicate Address Detection (DAD) MUST be supported. - -4.5.3 Privacy Extensions for Address Configuration in IPv6 - RFC3041 - - Privacy Extensions for Stateless Address Autoconfiguration [RFC-3041] - SHOULD be supported. It is recommended that this behavior be - configurable on a connection basis within each application when - available. It is noted that a number of applications do not work - with addresses generated with this method, while other applications - work quite well with them. - -4.5.4 Default Address Selection for IPv6 - RFC3484 - - The rules specified in the Default Address Selection for IPv6 [RFC- - 3484] document MUST be implemented. It is expected that IPv6 nodes - will need to deal with multiple addresses. - -4.5.5 Stateful Address Autoconfiguration - - Stateful Address Autoconfiguration MAY be supported. DHCPv6 [RFC- - 3315] is the standard stateful address configuration protocol; see - section 5.3 for DHCPv6 support. - - Nodes which do not support Stateful Address Autoconfiguration may be - unable to obtain any IPv6 addresses aside from link-local addresses - when it receives a router advertisement with the 'M' flag (Managed - address configuration) set and which contains no prefixes advertised - for Stateless Address Autoconfiguration (see section 4.5.2). - Additionally, such nodes will be unable to obtain other configuration - information such as the addresses of DNS servers when it is connected - to a link over which the node receives a router advertisement in - which the 'O' flag ("Other stateful configuration") is set. - -4.6 Multicast Listener Discovery (MLD) for IPv6 - RFC2710 - - Nodes that need to join multicast groups SHOULD implement MLDv2 - [MLDv2]. However, if the node has applications, which only need - support for Any- Source Multicast [RFC3569], the node MAY implement - MLDv1 [MLDv1] instead. If the node has applications, which need - support for Source- Specific Multicast [RFC3569, SSMARCH], the node - MUST support MLDv2 [MLDv2]. - - - - -Loughney (editor) February 16, 2004 [Page 8] - - - - - -Internet-Draft - - - When MLD is used, the rules in "Source Address Selection for the - Multicast Listener Discovery (MLD) Protocol" [RFC-3590] MUST be - followed. - -5. Transport Layer and DNS - -5.1 Transport Layer - -5.1.1 TCP and UDP over IPv6 Jumbograms - RFC2147 - - This specification MUST be supported if jumbograms are implemented - [RFC- 2675]. - -5.2 DNS - - DNS, as described in [RFC-1034], [RFC-1035], [RFC-3152], [RFC-3363] - and [RFC-3596] MAY be supported. Not all nodes will need to resolve - names. All nodes that need to resolve names SHOULD implement stub- - resolver [RFC-1034] functionality, in RFC 1034 section 5.3.1 with - support for: - - - AAAA type Resource Records [RFC-3596]; - - reverse addressing in ip6.arpa using PTR records [RFC-3152]; - - EDNS0 [RFC-2671] to allow for DNS packet sizes larger than 512 - octets. - - Those nodes are RECOMMENDED to support DNS security extentions - [DNSSEC- INTRO], [DNSSEC-REC] and [DNSSEC-PROT]. - - Those nodes are NOT RECOMMENDED to support the experimental A6 and - DNAME Resource Records [RFC-3363]. - -5.2.2 Format for Literal IPv6 Addresses in URL's - RFC2732 - - RFC 2732 MUST be supported if applications on the node use URL's. - -5.3 Dynamic Host Configuration Protocol for IPv6 (DHCPv6) - RFC3315 - -5.3.1 Managed Address Configuration - - Those IPv6 Nodes that use DHCP for address assignment initiate DHCP - to obtain IPv6 addresses and other configuration information upon - receipt of a Router Advertisement with the 'M' flag set, as described - in section 5.5.3 of RFC 2462. In addition, in the absence of a - router, those IPv6 Nodes that use DHCP for address assignment MUST - initiate DHCP to obtain IPv6 addresses and other configuration - information, as described in section 5.5.2 of RFC 2462. Those IPv6 - nodes that do not use DHCP for address assignment can ignore the 'M' - - - -Loughney (editor) February 16, 2004 [Page 9] - - - - - -Internet-Draft - - - flag in Router Advertisements. - -5.3.2 Other Configuration Information - - Those IPv6 Nodes that use DHCP to obtain other configuration - information initiate DHCP for other configuration information upon - receipt of a Router Advertisement with the 'O' flag set, as described - in section 5.5.3 of RFC 2462. Those IPv6 nodes that do not use DHCP - for other configuration information can ignore the 'O' flag in Router - Advertisements. - - An IPv6 Node can use the subset of DHCP described in [DHCPv6-SL] to - obtain other configuration information. - -6. IPv4 Support and Transition - - IPv6 nodes MAY support IPv4. - -6.1 Transition Mechanisms - -6.1.1 Transition Mechanisms for IPv6 Hosts and Routers - RFC2893 - - If an IPv6 node implements dual stack and tunneling, then RFC2893 - MUST be supported. - - RFC 2893 is currently being updated. - -7. Mobile IP - - The Mobile IPv6 [MIPv6] specification defines requirements for the - following types of nodes: - - - mobile nodes - - correspondent nodes with support for route optimization - - home agents - - all IPv6 routers - - Hosts MAY support mobile node functionality described in Section 8.5 - of [MIPv6], including support of generic packet tunneling [RFC-2473] - and secure home agent communications [MIPv6-HASEC]. - - Hosts SHOULD support route optimization requirements for - correspondent nodes described in Section 8.2 of [MIPv6]. - - Routers SHOULD support the generic mobility-related requirements for - all IPv6 routers described in Section 8.3 of [MIPv6]. Routers MAY - support the home agent functionality described in Section 8.4 of - [MIPv6], including support of [RFC-2473] and [MIPv6-HASEC]. - - - -Loughney (editor) February 16, 2004 [Page 10] - - - - - -Internet-Draft - - -8. Security - - This section describes the specification of IPsec for the IPv6 node. - -8.1 Basic Architecture - - Security Architecture for the Internet Protocol [RFC-2401] MUST be - supported. RFC-2401 is being updated by the IPsec Working Group. - -8.2 Security Protocols - - ESP [RFC-2406] MUST be supported. AH [RFC-2402] MUST be supported. - RFC- 2406 and RFC 2402 are being updated by the IPsec Working Group. - - -8.3 Transforms and Algorithms - - Current IPsec RFCs specify the support of certain transforms and - algorithms, NULL encryption, DES-CBC, HMAC-SHA-1-96, and HMAC-MD5-96. - The requirements for these are discussed first, and then additional - algorithms 3DES-CBC, AES-128-CBC and HMAC-SHA-256-96 are discussed. - - NULL encryption algorithm [RFC-2410] MUST be supported for providing - integrity service and also for debugging use. - - The "ESP DES-CBC Cipher Algorithm With Explicit IV" [RFC-2405] SHOULD - NOT be supported. Security issues related to the use of DES are - discussed in [DESDIFF], [DESINT], [DESCRACK]. It is still listed as - required by the existing IPsec RFCs, but as it is currently viewed as - an inherently weak algorithm, and no longer fulfills its intended - role. - - The NULL authentication algorithm [RFC-2406] MUST be supported within - ESP. The use of HMAC-SHA-1-96 within AH and ESP, described in [RFC- - 2404] MUST be supported. The use of HMAC-MD5-96 within AH and ESP, - described in [RFC-2403] MUST be supported. An implementer MUST refer - to Keyed- Hashing for Message Authentication [RFC-2104]. - - 3DES-CBC does not suffer from the issues related to DES-CBC. 3DES-CBC - and ESP CBC-Mode Cipher Algorithms [RFC-2451] MAY be supported. AES- - CBC Cipher Algorithm [RFC-3602] MUST be supported, as it is expected - to be a widely available, secure algorithm that is required for - interoperability. It is not required by the current IPsec RFCs, but - is expected to become required in the future. - - In addition to the above requirements, "Cryptographic Algorithm - Implementation Requirements For ESP And AH" [CRYPTREQ] contains the - current set of mandatory to implement algorithms for ESP and AH as - - - -Loughney (editor) February 16, 2004 [Page 11] - - - - - -Internet-Draft - - - well as specifying algorithms that should be implemented because they - may be promoted to mandatory at some future time. It is RECOMMENDED - that IPv6 nodes conform to the requirements in this document. - -8.4 Key Management Methods - - Manual keying MUST be supported. - - IKE [RFC-2407] [RFC-2408] [RFC-2409] MAY be supported for unicast - traffic. Where key refresh, anti-replay features of AH and ESP, or - on- demand creation of Security Associations (SAs) is required, - automated keying MUST be supported. Note that the IPsec WG is working - on the successor to IKE [IKE2]. Key management methods for multicast - traffic are also being worked on by the MSEC WG. - - "Cryptographic Algorithms for use in the Internet Key Exchange - Version 2" [IKEv2ALGO] defines the current set of mandatory to - implement algorithms for use of IKEv2 as well as specifying - algorithms that should be implemented because they made be promoted - to mandatory at some future time. It is RECOMMENDED that IPv6 nodes - implementing IKEv2 conform to the requirements in this - document. - -9. Router-Specific Functionality - - This section defines general host considerations for IPv6 nodes that - act as routers. Currently, this section does not discuss routing- - specific requirements. - -9.1 General - -9.1.1 IPv6 Router Alert Option - RFC2711 - - - The IPv6 Router Alert Option [RFC-2711] is an optional IPv6 Hop-by- - Hop Header that is used in conjunction with some protocols (e.g., - RSVP [RFC- 2205], or MLD [RFC-2710]). The Router Alert option will - need to be implemented whenever protocols that mandate its usage are - implemented. See Section 4.6. - -9.1.2 Neighbor Discovery for IPv6 - RFC2461 - - Sending Router Advertisements and processing Router Solicitation MUST - be supported. - -10. Network Management - - Network Management MAY be supported by IPv6 nodes. However, for IPv6 - - - -Loughney (editor) February 16, 2004 [Page 12] - - - - - -Internet-Draft - - - nodes that are embedded devices, network management may be the only - possibility to control these nodes. - -10.1 Management Information Base Modules (MIBs) - - The following two MIBs SHOULD be supported by nodes that support an - SNMP agent. - -10.1.1 IP Forwarding Table MIB - - IP Forwarding Table MIB [RFC-2096BIS] SHOULD be supported by nodes - that support an SNMP agent. - -10.1.2 Management Information Base for the Internet Protocol (IP) - - IP MIB [RFC-2011BIS] SHOULD be supported by nodes that support an - SNMP agent. - -11. Security Considerations - - This draft does not affect the security of the Internet, but - implementations of IPv6 are expected to support a minimum set of - security features to ensure security on the Internet. "IP Security - Document Roadmap" [RFC-2411] is important for everyone to read. - - The security considerations in RFC2460 describe the following: - - The security features of IPv6 are described in the Security - Architecture for the Internet Protocol [RFC-2401]. - -12. References - -12.1 Normative - - [CRYPTREQ] D. Eastlake 3rd, "Cryptographic Algorithm Implementa- - tion Requirements For ESP And AH", draft-ietf-ipsec- - esp-ah-algorithms-01.txt, January 2004. - - [IKEv2ALGO] J. Schiller, "Cryptographic Algorithms for use in the - Internet Key Exchange Version 2", draft-ietf-ipsec- - ikev2-algorithms-04.txt, Work in Progress. - - [DHCPv6-SL] R. Droms, "A Guide to Implementing Stateless DHCPv6 - Service", draft- ietf-dhc-dhcpv6-stateless-00.txt, - Work in Progress. - - [MIPv6] J. Arkko, D. Johnson and C. Perkins, "Mobility Support - in IPv6", draft- ietf-mobileip-ipv6-24.txt, Work in - - - -Loughney (editor) February 16, 2004 [Page 13] - - - - - -Internet-Draft - - - progress. - - [MIPv6-HASEC] J. Arkko, V. Devarapalli and F. Dupont, "Using IPsec - to Protect Mobile IPv6 Signaling between Mobile Nodes - and Home Agents", draft-ietf- mobileip-mipv6-ha- - ipsec-06.txt, Work in Progress. - - [MLDv2] Vida, R. et al., "Multicast Listener Discovery Version - 2 (MLDv2) for IPv6", draft-vida-mld-v2-07.txt, Work in - Progress. - - [RFC-1035] Mockapetris, P., "Domain names - implementation and - specification", STD 13, RFC 1035, November 1987. - - [RFC-1981] McCann, J., Mogul, J. and Deering, S., "Path MTU - Discovery for IP version 6", RFC 1981, August 1996. - - [RFC-2096BIS] Haberman, B. and Wasserman, M., "IP Forwarding Table - MIB", draft-ietf- ipv6-rfc2096-update-07.txt, Work in - Progress. - - [RFC-2011BIS] Routhier, S (ed), "Management Information Base for the - Internet Protocol (IP)", draft-ietf-ipv6-rfc2011- - update-07.txt, Work in progress. - - [RFC-2104] Krawczyk, K., Bellare, M., and Canetti, R., "HMAC: - Keyed-Hashing for Message Authentication", RFC 2104, - February 1997. - - [RFC-2119] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - - [RFC-2401] Kent, S. and Atkinson, R., "Security Architecture for - the Internet Protocol", RFC 2401, November 1998. - - [RFC-2402] Kent, S. and Atkinson, R., "IP Authentication - Header", RFC 2402, November 1998. - - [RFC-2403] Madson, C., and Glenn, R., "The Use of HMAC-MD5 within - ESP and AH", RFC 2403, November 1998. - - [RFC-2404] Madson, C., and Glenn, R., "The Use of HMAC-SHA-1 - within ESP and AH", RFC 2404, November 1998. - - [RFC-2405] Madson, C. and Doraswamy, N., "The ESP DES-CBC Cipher - Algorithm With Explicit IV", RFC 2405, November 1998. - - [RFC-2406] Kent, S. and Atkinson, R., "IP Encapsulating Security - - - -Loughney (editor) February 16, 2004 [Page 14] - - - - - -Internet-Draft - - - Protocol (ESP)", RFC 2406, November 1998. - - [RFC-2407] Piper, D., "The Internet IP Security Domain of - Interpretation for ISAKMP", RFC 2407, November 1998. - - [RFC-2408] Maughan, D., Schertler, M., Schneider, M., and Turner, - J., "Internet Security Association and Key Management - Protocol (ISAKMP)", RFC 2408, November 1998. - - [RFC-2409] Harkins, D., and Carrel, D., "The Internet Key - Exchange (IKE)", RFC 2409, November 1998. - - [RFC-2410] Glenn, R. and Kent, S., "The NULL Encryption Algorithm - and Its Use With IPsec", RFC 2410, November 1998. - - [RFC-2451] Pereira, R. and Adams, R., "The ESP CBC-Mode Cipher - Algorithms", RFC 2451, November 1998. - - [RFC-2460] Deering, S. and Hinden, R., "Internet Protocol, Ver- - sion 6 (IPv6) Specification", RFC 2460, December 1998. - - [RFC-2461] Narten, T., Nordmark, E. and Simpson, W., "Neighbor - Discovery for IP Version 6 (IPv6)", RFC 2461, December - 1998. - - [RFC-2462] Thomson, S. and Narten, T., "IPv6 Stateless Address - Autoconfiguration", RFC 2462. - - [RFC-2463] Conta, A. and Deering, S., "ICMP for the Internet Pro- - tocol Version 6 (IPv6)", RFC 2463, December 1998. - - [RFC-2472] Haskin, D. and Allen, E., "IP version 6 over PPP", RFC - 2472, December 1998. - - [RFC-2473] Conta, A. and Deering, S., "Generic Packet Tunneling - in IPv6 Specification", RFC 2473, December 1998. Xxx - add - - [RFC-2671] Vixie, P., "Extension Mechanisms for DNS (EDNS0)", RFC - 2671, August 1999. - - [RFC-2710] Deering, S., Fenner, W. and Haberman, B., "Multicast - Listener Discovery (MLD) for IPv6", RFC 2710, October - 1999. - - [RFC-2711] Partridge, C. and Jackson, A., "IPv6 Router Alert - Option", RFC 2711, October 1999. - - - - -Loughney (editor) February 16, 2004 [Page 15] - - - - - -Internet-Draft - - - [RFC-3041] Narten, T. and Draves, R., "Privacy Extensions for - Stateless Address Autoconfiguration in IPv6", RFC - 3041, January 2001. - - [RFC-3152] Bush, R., "Delegation of IP6.ARPA", RFC 3152, August - 2001. - - [RFC-3315] Bound, J. et al., "Dynamic Host Configuration Protocol - for IPv6 (DHCPv6)", RFC 3315, July 2003. - - [RFC-3363] Bush, R., et al., "Representing Internet Protocol ver- - sion 6 (IPv6) Addresses in the Domain Name System - (DNS)", RFC 3363, August 2002. - - [RFC-3484] Draves, R., "Default Address Selection for IPv6", RFC - 3484, February 2003. - - [RFC-3513] Hinden, R. and Deering, S. "IP Version 6 Addressing - Architecture", RFC 3513, April 2003. - - [RFC-3590] Haberman, B., "Source Address Selection for the Multi- - cast Listener Discovery (MLD) Protocol", RFC 3590, - September 2003. - - [RFC-3596] Thomson, S., et al., "DNS Extensions to support IP - version 6", RFC 3596, October 2003. - - [RFC-3602] S. Frankel, "The AES-CBC Cipher Algorithm and Its Use - with IPsec", RFC 3602, September 2003. - -12.2 Non-Normative - - [ANYCAST] Hagino, J and Ettikan K., "An Analysis of IPv6 Anycast", - draft-ietf- ipngwg-ipv6-anycast-analysis-02.txt, Work in - Progress. - - [DESDIFF] Biham, E., Shamir, A., "Differential Cryptanalysis of - DES-like cryptosystems", Journal of Cryptology Vol 4, Jan - 1991. - - [DESCRACK] Cracking DES, O'Reilly & Associates, Sebastapol, CA 2000. - - [DESINT] Bellovin, S., "An Issue With DES-CBC When Used Without - Strong Integrity", Proceedings of the 32nd IETF, Danvers, - MA, April 1995. - - [DHCPv6-SL] Droms, R., "A Guide to Implementing Stateless DHCPv6 Ser- - vice", draft- ietf-dhc-dhcpv6-stateless-02.txt, Work in - - - -Loughney (editor) February 16, 2004 [Page 16] - - - - - -Internet-Draft - - - Progress. - - [DNSSEC-INTRO] Arends, R., Austein, R., Larson, M., Massey, D. and Rose, - S., "DNS Security Introduction and Requirements" draft- - ietf-dnsext-dnssec-intro- 06.txt, Work in Progress. - - [DNSSEC-REC] Arends, R., Austein, R., Larson, M., Massey, D. and Rose, - S., "Resource Records for the DNS Security Extensions", - draft-ietf-dnsext-dnssec- records-04.txt, Work in Pro- - gress. - - [DNSSEC-PROT] Arends, R., Austein, R., Larson, M., Massey, D. and Rose, - S., "Protocol Modifications for the DNS Security Exten- - sions", draft-ietf-dnsext- dnssec-protocol-02.txt, Work - in Progress. - - [IKE2] Kaufman, C. (ed), "Internet Key Exchange (IKEv2) Proto- - col", draft-ietf- ipsec-ikev2-10.txt, Work in Progress. - - [IPv6-RH] P. Savola, "Security of IPv6 Routing Header and Home - Address Options", draft-savola-ipv6-rh-ha-security- - 03.txt, Work in Progress, March 2002. - - [MC-THREAT] Ballardie A. and Crowcroft, J.; Multicast-Specific Secu- - rity Threats and Counter-Measures; In Proceedings "Sympo- - sium on Network and Distributed System Security", Febru- - ary 1995, pp.2-16. - - [RFC-793] Postel, J., "Transmission Control Protocol", RFC 793, - August 1980. - - [RFC-1034] Mockapetris, P., "Domain names - concepts and facili- - ties", RFC 1034, November 1987. - - [RFC-2147] Borman, D., "TCP and UDP over IPv6 Jumbograms", RFC 2147, - May 1997. - - [RFC-2205] Braden, B. (ed.), Zhang, L., Berson, S., Herzog, S. and - S. Jamin, "Resource ReSerVation Protocol (RSVP)", RFC - 2205, September 1997. - - [RFC-2464] Crawford, M., "Transmission of IPv6 Packets over Ethernet - Networks", RFC 2462, December 1998. - - [RFC-2492] G. Armitage, M. Jork, P. Schulter, G. Harter, IPv6 over - ATM Networks", RFC 2492, January 1999. - - [RFC-2675] Borman, D., Deering, S. and Hinden, B., "IPv6 - - - -Loughney (editor) February 16, 2004 [Page 17] - - - - - -Internet-Draft - - - Jumbograms", RFC 2675, August 1999. - - [RFC-2732] R. Hinden, B. Carpenter, L. Masinter, "Format for Literal - IPv6 Addresses in URL's", RFC 2732, December 1999. - - [RFC-2851] M. Daniele, B. Haberman, S. Routhier, J. Schoenwaelder, - "Textual Conventions for Internet Network Addresses", RFC - 2851, June 2000. - - [RFC-2893] Gilligan, R. and Nordmark, E., "Transition Mechanisms for - IPv6 Hosts and Routers", RFC 2893, August 2000. - - [RFC-3569] S. Bhattacharyya, Ed., "An Overview of Source-Specific - Multicast (SSM)", RFC 3569, July 2003. - - [SSM-ARCH] H. Holbrook, B. Cain, "Source-Specific Multicast for IP", - draft-ietf- ssm-arch-03.txt, Work in Progress. - -13. Authors and Acknowledgements - - This document was written by the IPv6 Node Requirements design team: - - Jari Arkko - [jari.arkko@ericsson.com] - - Marc Blanchet - [marc.blanchet@viagenie.qc.ca] - - Samita Chakrabarti - [samita.chakrabarti@eng.sun.com] - - Alain Durand - [alain.durand@sun.com] - - Gerard Gastaud - [gerard.gastaud@alcatel.fr] - - Jun-ichiro itojun Hagino - [itojun@iijlab.net] - - Atsushi Inoue - [inoue@isl.rdc.toshiba.co.jp] - - Masahiro Ishiyama - [masahiro@isl.rdc.toshiba.co.jp] - - John Loughney - [john.loughney@nokia.com] - - - -Loughney (editor) February 16, 2004 [Page 18] - - - - - -Internet-Draft - - - Rajiv Raghunarayan - [raraghun@cisco.com] - - Shoichi Sakane - [shouichi.sakane@jp.yokogawa.com] - - Dave Thaler - [dthaler@windows.microsoft.com] - - Juha Wiljakka - [juha.wiljakka@Nokia.com] - - The authors would like to thank Ran Atkinson, Jim Bound, Brian Car- - penter, Ralph Droms, Christian Huitema, Adam Machalek, Thomas Narten, - Juha Ollila and Pekka Savola for their comments. - -14. Editor's Contact Information - - Comments or questions regarding this document should be sent to the - IPv6 Working Group mailing list (ipv6@ietf.org) or to: - - John Loughney - Nokia Research Center - Itamerenkatu 11-13 - 00180 Helsinki - Finland - - Phone: +358 50 483 6242 - Email: John.Loughney@Nokia.com - -Notices - - The IETF takes no position regarding the validity or scope of any - intellectual property or other rights that might be claimed to per- - tain to the implementation or use of the technology described in this - document or the extent to which any license under such rights might - or might not be available; neither does it represent that it has made - any effort to identify any such rights. Information on the IETF's - procedures with respect to rights in standards-track and standards- - related documentation can be found in BCP-11. Copies of claims of - rights made available for publication and any assurances of licenses - to be made available, or the result of an attempt made to obtain a - general license or permission for the use of such proprietary rights - by implementors or users of this specification can be obtained from - the IETF Secretariat. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - - - -Loughney (editor) February 16, 2004 [Page 19] - - - - - -Internet-Draft - - - rights, which may cover technology that may be required to practice - this standard. Please address the information to the IETF Executive - Director. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Loughney (editor) February 16, 2004 [Page 20] - - diff --git a/contrib/bind9/doc/draft/draft-ietf-secsh-dns-05.txt b/contrib/bind9/doc/draft/draft-ietf-secsh-dns-05.txt deleted file mode 100644 index a272d81..0000000 --- a/contrib/bind9/doc/draft/draft-ietf-secsh-dns-05.txt +++ /dev/null @@ -1,614 +0,0 @@ -Secure Shell Working Group J. Schlyter -Internet-Draft OpenSSH -Expires: March 5, 2004 W. Griffin - SPARTA - September 5, 2003 - - - Using DNS to Securely Publish SSH Key Fingerprints - draft-ietf-secsh-dns-05.txt - -Status of this Memo - - This document is an Internet-Draft and is in full conformance with - all provisions of Section 10 of RFC2026. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that other - groups may also distribute working documents as Internet-Drafts. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - The list of current Internet-Drafts can be accessed at http:// - www.ietf.org/ietf/1id-abstracts.txt. - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - This Internet-Draft will expire on March 5, 2004. - -Copyright Notice - - Copyright (C) The Internet Society (2003). All Rights Reserved. - -Abstract - - This document describes a method to verify SSH host keys using - DNSSEC. The document defines a new DNS resource record that contains - a standard SSH key fingerprint. - - - - - - - - - - - -Schlyter & Griffin Expires March 5, 2004 [Page 1] - -Internet-Draft DNS and SSH Fingerprints September 2003 - - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 - 2. SSH Host Key Verification . . . . . . . . . . . . . . . . . 3 - 2.1 Method . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 - 2.2 Implementation Notes . . . . . . . . . . . . . . . . . . . . 3 - 2.3 Fingerprint Matching . . . . . . . . . . . . . . . . . . . . 4 - 2.4 Authentication . . . . . . . . . . . . . . . . . . . . . . . 4 - 3. The SSHFP Resource Record . . . . . . . . . . . . . . . . . 4 - 3.1 The SSHFP RDATA Format . . . . . . . . . . . . . . . . . . . 5 - 3.1.1 Algorithm Number Specification . . . . . . . . . . . . . . . 5 - 3.1.2 Fingerprint Type Specification . . . . . . . . . . . . . . . 5 - 3.1.3 Fingerprint . . . . . . . . . . . . . . . . . . . . . . . . 5 - 3.2 Presentation Format of the SSHFP RR . . . . . . . . . . . . 6 - 4. Security Considerations . . . . . . . . . . . . . . . . . . 6 - 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . 7 - Normative References . . . . . . . . . . . . . . . . . . . . 8 - Informational References . . . . . . . . . . . . . . . . . . 8 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 9 - A. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 9 - Intellectual Property and Copyright Statements . . . . . . . 10 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Schlyter & Griffin Expires March 5, 2004 [Page 2] - -Internet-Draft DNS and SSH Fingerprints September 2003 - - -1. Introduction - - The SSH [6] protocol provides secure remote login and other secure - network services over an insecure network. The security of the - connection relies on the server authenticating itself to the client - as well as the user authenticating itself to the server. - - If a connection is established to a server whose public key is not - already known to the client, a fingerprint of the key is presented to - the user for verification. If the user decides that the fingerprint - is correct and accepts the key, the key is saved locally and used for - verification for all following connections. While some - security-conscious users verify the fingerprint out-of-band before - accepting the key, many users blindly accept the presented key. - - The method described here can provide out-of-band verification by - looking up a fingerprint of the server public key in the DNS [1][2] - and using DNSSEC [5] to verify the lookup. - - In order to distribute the fingerprint using DNS, this document - defines a new DNS resource record, "SSHFP", to carry the fingerprint. - - Basic understanding of the DNS system [1][2] and the DNS security - extensions [5] is assumed by this document. - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this - document are to be interpreted as described in RFC 2119 [3]. - -2. SSH Host Key Verification - -2.1 Method - - Upon connection to a SSH server, the SSH client MAY look up the SSHFP - resource record(s) for the host it is connecting to. If the - algorithm and fingerprint of the key received from the SSH server - match the algorithm and fingerprint of one of the SSHFP resource - record(s) returned from DNS, the client MAY accept the identity of - the server. - -2.2 Implementation Notes - - Client implementors SHOULD provide a configurable policy used to - select the order of methods used to verify a host key. This document - defines one method: Fingerprint storage in DNS. Another method - defined in the SSH Architecture [6] uses local files to store keys - for comparison. Other methods that could be defined in the future - might include storing fingerprints in LDAP or other databases. A - - - -Schlyter & Griffin Expires March 5, 2004 [Page 3] - -Internet-Draft DNS and SSH Fingerprints September 2003 - - - configurable policy will allow administrators to determine which - methods they want to use and in what order the methods should be - prioritized. This will allow administrators to determine how much - trust they want to place in the different methods. - - One specific scenario for having a configurable policy is where - clients do not use fully qualified host names to connect to servers. - In this scenario, the implementation SHOULD verify the host key - against a local database before verifying the key via the fingerprint - returned from DNS. This would help prevent an attacker from injecting - a DNS search path into the local resolver and forcing the client to - connect to a different host. - -2.3 Fingerprint Matching - - The public key and the SSHFP resource record are matched together by - comparing algorithm number and fingerprint. - - The public key algorithm and the SSHFP algorithm number MUST - match. - - A message digest of the public key, using the message digest - algorithm specified in the SSHFP fingerprint type, MUST match the - SSHFP fingerprint. - - -2.4 Authentication - - A public key verified using this method MUST NOT be trusted if the - SSHFP resource record (RR) used for verification was not - authenticated by a trusted SIG RR. - - Clients that do validate the DNSSEC signatures themselves SHOULD use - standard DNSSEC validation procedures. - - Clients that do not validate the DNSSEC signatures themselves MUST - use a secure transport, e.g. TSIG [9], SIG(0) [10] or IPsec [8], - between themselves and the entity performing the signature - validation. - -3. The SSHFP Resource Record - - The SSHFP resource record (RR) is used to store a fingerprint of a - SSH public host key that is associated with a Domain Name System - (DNS) name. - - The RR type code for the SSHFP RR is TBA. - - - - -Schlyter & Griffin Expires March 5, 2004 [Page 4] - -Internet-Draft DNS and SSH Fingerprints September 2003 - - -3.1 The SSHFP RDATA Format - - The RDATA for a SSHFP RR consists of an algorithm number, fingerprint - type and the fingerprint of the public host key. - - 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | algorithm | fp type | / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / - / / - / fingerprint / - / / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - -3.1.1 Algorithm Number Specification - - This algorithm number octet describes the algorithm of the public - key. The following values are assigned: - - Value Algorithm name - ----- -------------- - 0 reserved - 1 RSA - 2 DSS - - Reserving other types requires IETF consensus [4]. - -3.1.2 Fingerprint Type Specification - - The fingerprint type octet describes the message-digest algorithm - used to calculate the fingerprint of the public key. The following - values are assigned: - - Value Fingerprint type - ----- ---------------- - 0 reserved - 1 SHA-1 - - Reserving other types requires IETF consensus [4]. - - For interoperability reasons, as few fingerprint types as possible - should be reserved. The only reason to reserve additional types is - to increase security. - -3.1.3 Fingerprint - - - - -Schlyter & Griffin Expires March 5, 2004 [Page 5] - -Internet-Draft DNS and SSH Fingerprints September 2003 - - - The fingerprint is calculated over the public key blob as described - in [7]. - - The message-digest algorithm is presumed to produce an opaque octet - string output which is placed as-is in the RDATA fingerprint field. - -3.2 Presentation Format of the SSHFP RR - - The RDATA of the presentation format of the SSHFP resource record - consists of two numbers (algorithm and fingerprint type) followed by - the fingerprint itself presented in hex, e.g: - - host.example. SSHFP 2 1 123456789abcdef67890123456789abcdef67890 - - The use of mnemonics instead of numbers is not allowed. - -4. Security Considerations - - Currently, the amount of trust a user can realistically place in a - server key is proportional to the amount of attention paid to - verifying that the public key presented actually corresponds to the - private key of the server. If a user accepts a key without verifying - the fingerprint with something learned through a secured channel, the - connection is vulnerable to a man-in-the-middle attack. - - The overall security of using SSHFP for SSH host key verification is - dependent on the security policies of the SSH host administrator and - DNS zone administrator (in transferring the fingerprint), detailed - aspects of how verification is done in the SSH implementation, and in - the client's diligence in accessing the DNS in a secure manner. - - One such aspect is in which order fingerprints are looked up (e.g. - first checking local file and then SSHFP). We note that in addition - to protecting the first-time transfer of host keys, SSHFP can - optionally be used for stronger host key protection. - - If SSHFP is checked first, new SSH host keys may be distributed by - replacing the corresponding SSHFP in DNS. - - If SSH host key verification can be configured to require SSHFP, - SSH host key revocation can be implemented by removing the - corresponding SSHFP from DNS. - - As stated in Section 2.2, we recommend that SSH implementors provide - a policy mechanism to control the order of methods used for host key - verification. One specific scenario for having a configurable policy - is where clients use unqualified host names to connect to servers. In - this case, we recommend that SSH implementations check the host key - - - -Schlyter & Griffin Expires March 5, 2004 [Page 6] - -Internet-Draft DNS and SSH Fingerprints September 2003 - - - against a local database before verifying the key via the fingerprint - returned from DNS. This would help prevent an attacker from injecting - a DNS search path into the local resolver and forcing the client to - connect to a different host. - - A different approach to solve the DNS search path issue would be for - clients to use a trusted DNS search path, i.e., one not acquired - through DHCP or other autoconfiguration mechanisms. Since there is no - way with current DNS lookup APIs to tell whether a search path is - from a trusted source, the entire client system would need to be - configured with this trusted DNS search path. - - Another dependency is on the implementation of DNSSEC itself. As - stated in Section 2.4, we mandate the use of secure methods for - lookup and that SSHFP RRs are authenticated by trusted SIG RRs. This - is especially important if SSHFP is to be used as a basis for host - key rollover and/or revocation, as described above. - - Since DNSSEC only protects the integrity of the host key fingerprint - after it is signed by the DNS zone administrator, the fingerprint - must be transferred securely from the SSH host administrator to the - DNS zone administrator. This could be done manually between the - administrators or automatically using secure DNS dynamic update [11] - between the SSH server and the nameserver. We note that this is no - different from other key enrollment situations, e.g. a client sending - a certificate request to a certificate authority for signing. - -5. IANA Considerations - - IANA needs to allocate a RR type code for SSHFP from the standard RR - type space (type 44 requested). - - IANA needs to open a new registry for the SSHFP RR type for public - key algorithms. Defined types are: - - 0 is reserved - 1 is RSA - 2 is DSA - - Adding new reservations requires IETF consensus [4]. - - IANA needs to open a new registry for the SSHFP RR type for - fingerprint types. Defined types are: - - 0 is reserved - 1 is SHA-1 - - Adding new reservations requires IETF consensus [4]. - - - -Schlyter & Griffin Expires March 5, 2004 [Page 7] - -Internet-Draft DNS and SSH Fingerprints September 2003 - - -Normative References - - [1] Mockapetris, P., "Domain names - concepts and facilities", STD - 13, RFC 1034, November 1987. - - [2] Mockapetris, P., "Domain names - implementation and - specification", STD 13, RFC 1035, November 1987. - - [3] Bradner, S., "Key words for use in RFCs to Indicate Requirement - Levels", BCP 14, RFC 2119, March 1997. - - [4] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA - Considerations Section in RFCs", BCP 26, RFC 2434, October 1998. - - [5] Eastlake, D., "Domain Name System Security Extensions", RFC - 2535, March 1999. - - [6] Ylonen, T., Kivinen, T., Saarinen, M., Rinne, T. and S. - Lehtinen, "SSH Protocol Architecture", - draft-ietf-secsh-architecture-14 (work in progress), July 2003. - - [7] Ylonen, T., Kivinen, T., Saarinen, M., Rinne, T. and S. - Lehtinen, "SSH Transport Layer Protocol", - draft-ietf-secsh-transport-16 (work in progress), July 2003. - -Informational References - - [8] Thayer, R., Doraswamy, N. and R. Glenn, "IP Security Document - Roadmap", RFC 2411, November 1998. - - [9] Vixie, P., Gudmundsson, O., Eastlake, D. and B. Wellington, - "Secret Key Transaction Authentication for DNS (TSIG)", RFC - 2845, May 2000. - - [10] Eastlake, D., "DNS Request and Transaction Signatures ( - SIG(0)s)", RFC 2931, September 2000. - - [11] Wellington, B., "Secure Domain Name System (DNS) Dynamic - Update", RFC 3007, November 2000. - - - - - - - - - - - - -Schlyter & Griffin Expires March 5, 2004 [Page 8] - -Internet-Draft DNS and SSH Fingerprints September 2003 - - -Authors' Addresses - - Jakob Schlyter - OpenSSH - 812 23rd Avenue SE - Calgary, Alberta T2G 1N8 - Canada - - EMail: jakob@openssh.com - URI: http://www.openssh.com/ - - - Wesley Griffin - SPARTA - 7075 Samuel Morse Drive - Columbia, MD 21046 - USA - - EMail: wgriffin@sparta.com - URI: http://www.sparta.com/ - -Appendix A. Acknowledgements - - The authors gratefully acknowledge, in no particular order, the - contributions of the following persons: - - Martin Fredriksson - - Olafur Gudmundsson - - Edward Lewis - - Bill Sommerfeld - - - - - - - - - - - - - - - - - - -Schlyter & Griffin Expires March 5, 2004 [Page 9] - -Internet-Draft DNS and SSH Fingerprints September 2003 - - -Intellectual Property Statement - - The IETF takes no position regarding the validity or scope of any - intellectual property or other rights that might be claimed to - pertain to the implementation or use of the technology described in - this document or the extent to which any license under such rights - might or might not be available; neither does it represent that it - has made any effort to identify any such rights. Information on the - IETF's procedures with respect to rights in standards-track and - standards-related documentation can be found in BCP-11. Copies of - claims of rights made available for publication and any assurances of - licenses to be made available, or the result of an attempt made to - obtain a general license or permission for the use of such - proprietary rights by implementors or users of this specification can - be obtained from the IETF Secretariat. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights which may cover technology that may be required to practice - this standard. Please address the information to the IETF Executive - Director. - - -Full Copyright Statement - - Copyright (C) The Internet Society (2003). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assignees. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - - - -Schlyter & Griffin Expires March 5, 2004 [Page 10] - -Internet-Draft DNS and SSH Fingerprints September 2003 - - - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - -Acknowledgement - - Funding for the RFC Editor function is currently provided by the - Internet Society. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Schlyter & Griffin Expires March 5, 2004 [Page 11] - diff --git a/contrib/bind9/doc/draft/draft-ihren-dnsext-threshold-validation-00.txt b/contrib/bind9/doc/draft/draft-ihren-dnsext-threshold-validation-00.txt deleted file mode 100644 index 3578d2a..0000000 --- a/contrib/bind9/doc/draft/draft-ihren-dnsext-threshold-validation-00.txt +++ /dev/null @@ -1,519 +0,0 @@ - -Internet Draft Johan Ihren -draft-ihren-dnsext-threshold-validation-00.txt Autonomica -February 2003 -Expires in six months - - - Threshold Validation: - - A Mechanism for Improved Trust and Redundancy for DNSSEC Keys - - -Status of this Memo - - This document is an Internet-Draft and is in full conformance with - all provisions of Section 10 of RFC2026. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as - Internet-Drafts. - - Internet-Drafts are draft documents valid for a maximum of six - months and may be updated, replaced, or obsoleted by other - documents at any time. It is inappropriate to use Internet-Drafts - as reference material or to cite them other than as "work in - progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - -Abstract - - This memo documents a proposal for a different method of validation - for DNSSEC aware resolvers. The key change is that by changing from - a model of one Key Signing Key, KSK, at a time to multiple KSKs it - will be possible to increase the aggregated trust in the signed - keys by leveraging from the trust associated with the different - signees. - - By having multiple keys to chose from validating resolvers get the - opportunity to use local policy to reflect actual trust in - different keys. For instance, it is possible to trust a single, - particular key ultimately, while requiring multiple valid - signatures by less trusted keys for validation to succeed. - Furthermore, with multiple KSKs there are additional redundancy - benefits available since it is possible to roll over different KSKs - at different times which may make rollover scenarios easier to - manage. - -Contents - - 1. Terminology - 2. Introduction and Background - - 3. Trust in DNSSEC Keys - 3.1. Key Management, Split Keys and Trust Models - 3.2. Trust Expansion: Authentication versus Authorization - - 4. Proposed Semantics for Signing the KEY Resource Record - Set - 4.1. Packet Size Considerations - - 5. Proposed Use of Multiple "Trusted Keys" in a Validating - Resolver - 5.1. Not All Possible KSKs Need to Be Trusted - 5.2. Possible to do Threshold Validation - 5.3. Not All Trusted Keys Will Be Available - - 6. Additional Benefits from Having Multiple KSKs - 6.1. More Robust Key Rollovers - 6.2. Evaluation of Multiple Key Distribution Mechanisms - - 7. Security Considerations - 8. IANA Considerations. - 9. References - 9.1. Normative. - 9.2. Informative. - 10. Acknowledgments. - 11. Authors' Address - - -1. Terminology - - The key words "MUST", "SHALL", "REQUIRED", "SHOULD", "RECOMMENDED", - and "MAY" in this document are to be interpreted as described in - RFC 2119. - - The term "zone" refers to the unit of administrative control in the - Domain Name System. "Name server" denotes a DNS name server that is - authoritative (i.e. knows all there is to know) for a DNS zone, - typically the root zone. A "resolver", is a DNS "client", i.e. an - entity that sends DNS queries to authoritative nameservers and - interpret the results. A "validating resolver" is a resolver that - attempts to perform DNSSEC validation on data it retrieves by doing - DNS lookups. - - -2. Introduction and Background - - From a protocol perspective there is no real difference between - different keys in DNSSEC. They are all just keys. However, in - actual use there is lots of difference. First and foremost, most - DNSSEC keys have in-band verification. I.e. the keys are signed by - some other key, and this other key is in its turn also signed by - yet another key. This way a "chain of trust" is created. Such - chains have to end in what is referred to as a "trusted key" for - validation of DNS lookups to be possible. - - A "trusted key" is a the public part of a key that the resolver - acquired by some other means than by looking it up in DNS. The - trusted key has to be explicitly configured. - - A node in the DNS hierarchy that issues such out-of-band "trusted - keys" is called a "security apex" and the trusted key for that apex - is the ultimate source of trust for all DNS lookups within that - entire subtree. - - DNSSEC is designed to be able to work with more than on security - apex. These apexes will all share the problem of how to distribute - their "trusted keys" in a way that provides validating resolvers - confidence in the distributed keys. - - Maximizing that confidence is crucial to the usefulness of DNSSEC - and this document tries to address this issue. - - -3. Trust in DNSSEC Keys - - In the end the trust that a validating resolver will be able to put - in a key that it cannot validate within DNSSEC will have to be a - function of - - * trust in the key issuer, aka the KSK holder - - * trust in the distribution method - - * trust in extra, out-of-band verification - - The KSK holder needs to be trusted not to accidentally lose private - keys in public places. Furthermore it needs to be trusted to - perform correct identification of the ZSK holders in case they are - separate from the KSK holder itself. - - The distribution mechanism can be more or less tamper-proof. If the - key holder publishes the public key, or perhaps just a secure - fingerprint of the key in a major newspaper it may be rather - difficult to tamper with. A key acquired that way may be easier to - trust than if it had just been downloaded from a web page. - - Out-of-band verification can for instance be the key being signed - by a certificate issued by a known Certificate Authority that the - resolver has reason to trust. - -3.1. Simplicity vs Trust - - The fewer keys that are in use the simpler the key management - becomes. Therefore increasing the number of keys should only be - considered when the complexity is not the major concern. A perfect - example of this is the distinction between so called Key Signing - Keys, KSK, and Zone Signing Keys, ZSK. This distinction adds - overall complexity but simplifies real life operations and was an - overall gain since operational simplification was considered to be - a more crucial issue than the added complexity. - - In the case of a security apex there are additional issues to - consider, among them - - * maximizing trust in the KSK received out-of-band - - * authenticating the legitimacy of the ZSKs used - - In some cases this will be easy, since the same entity will manage - both ZSKs and KSKs (i.e. it will authenticate itself, somewhat - similar to a self-signed certificate). In some environments it will - be possible to get the trusted key installed in the resolver end by - decree (this would seem to be a likely method within corporate and - government environments). - - In other cases, however, this will possibly not be sufficient. In - the case of the root zone this is obvious, but there may well be - other cases. - -3.2. Expanding the "Trust Base" - - For a security apex where the ZSKs and KSK are not held by the same - entity the KSK will effectively authenticate the identity of - whoever does real operational zone signing. The amount of trust - that the data signed by a ZSK will get is directly dependent on - whether the end resolver trusts the KSK or not, since the resolver - has no OOB access to the public part of the ZSKs (for practical - reasons). - - Since the KSK holder is distinct from the ZSK holder the obvious - question is whether it would then be possible to further improve - the situation by using multiple KSK holders and thereby expanding - the trust base to the union of that available to each individual - KSK holder. "Trust base" is an invented term intended to signify - the aggregate of Internet resolvers that will eventually choose to - trust a key issued by a particular KSK holder. - - A crucial issue when considering trust expansion through addition - of multiple KSK holders is that the KSK holders are only used to - authenticate the ZSKs used for signing the zone. I.e. the function - performed by the KSK is basically: - - "This is indeed the official ZSK holder for this zone, - I've verified this fact to the best of my abilitites." - - Which can be thought of as similar to the service of a public - notary. I.e. the point with adding more KSK holders is to improve - the public trust in data signed by the ZSK holders by improving the - strength of available authentication. - - Therefore adding more KSK holders, each with their own trust base, - is by definition a good thing. More authentication is not - controversial. On the contrary, when it comes to authentication, - the more the merrier. - - -4. Proposed Semantics for Signing the KEY Resource Record Set - - In DNSSEC according to RFC2535 all KEY Resource Records are used to - sign all authoritative data in the zone, including the KEY RRset - itself, since RFC2535 makes no distinction between Key Signing - Keys, KSK, and Zone Signing Keys, ZSK. With Delegation Signer [DS] - it is possible to change this to the KEY RRset being signed with - all KSKs and ZSKs but the rest of the zone only being signed by the - ZSKs. - - This proposal changes this one step further, by recommending that - the KEY RRset is only signed by the Key Signing Keys, KSK, and - explicitly not by the Zone Signing Keys, ZSK. The reason for this - is to maximize the amount of space in the DNS response packet that - is available for additional KSKs and signatures thereof. The rest - of the authoritative zone contents are as previously signed by only - the ZSKs. - -4.1. Packet Size Considerations - - The reason for the change is to keep down the size of the aggregate - of KEY RRset plus SIG(KEY) that resolvers will need to acquire to - perform validation of data below a security apex. For DNSSEC data - to be returned the DNSSEC OK bit in the EDNS0 OPT Record has to be - set, and therefore the allowed packet size can be assumed to be at - least the EDNS0 minimum of 4000 bytes. - - When querying for KEY + SIG(KEY) for "." (the case that is assumed - to be most crucial) the size of the response packet after the - change to only sign the KEY RR with the KSKs break down into a - rather large space of possibilities. Here are a few examples for - the possible alternatives for different numbers of KSKs and ZSKs - for some different key lengths (all RSA keys, with a public - exponent that is < 254). This is all based upon the size of the - response for the particular example of querying for - - ". KEY IN" - - with a response of entire KEY + SIG(KEY) with the authority and - additional sections empty: - - ZSK/768 and KSK/1024 (real small) - Max 12 KSK + 3 ZSK at 3975 - 10 KSK + 8 ZSK at 3934 - 8 KSK + 13 ZSK at 3893 - - ZSK/768 + KSK/1280 - MAX 10 KSK + 2 ZSK at 3913 - 8 KSK + 9 ZSK at 3970 - 6 KSK + 15 ZSK at 3914 - - ZSK/768 + KSK/1536 - MAX 8 KSK + 4 ZSK at 3917 - 7 KSK + 8 ZSK at 3938 - 6 KSK + 12 ZSK at 3959 - - ZSK/768 + KSK/2048 - MAX 6 KSK + 5 ZSK at 3936 - 5 KSK + 10 ZSK at 3942 - - ZSK/1024 + KSK/1024 - MAX 12 KSK + 2 ZSK at 3943 - 11 KSK + 4 ZSK at 3930 - 10 KSK + 6 ZSK at 3917 - 8 KSK + 10 ZSK at 3891 - - ZSK/1024 + KSK/1536 - MAX 8 KSK + 3 ZSK at 3900 - 7 KSK + 6 ZSK at 3904 - 6 KSK + 9 ZSK at 3908 - - ZSK/1024 + KSK/2048 - MAX 6 KSK + 4 ZSK at 3951 - 5 KSK + 8 ZSK at 3972 - 4 KSK + 12 ZSK at 3993 - - Note that these are just examples and this document is not making - any recommendations on suitable choices of either key lengths nor - number of different keys employed at a security apex. - - This document does however, based upon the above figures, make the - recommendation that at a security apex that expects to distribute - "trusted keys" the KEY RRset should only be signed with the KSKs - and not with the ZSKs to keep the size of the response packets - down. - - -5. Proposed Use of Multiple "Trusted Keys" in a Validating Resolver - - In DNSSEC according to RFC2535[RFC2535] validation is the process - of tracing a chain of signatures (and keys) upwards through the DNS - hierarchy until a "trusted key" is reached. If there is a known - trusted key present at a security apex above the starting point - validation becomes an exercise with a binary outcome: either the - validation succeeds or it fails. No intermediate states are - possible. - - With multiple "trusted keys" (i.e. the KEY RRset for the security - apex signed by multiple KSKs) this changes into a more complicated - space of alternatives. From the perspective of complexity that may - be regarded as a change for the worse. However, from a perspective - of maximizing available trust the multiple KSKs add value to the - system. - -5.1. Possible to do Threshold Validation - - With multiple KSKs a new option that opens for the security - concious resolver is to not trust a key individually. Instead the - resolver may decide to require the validated signatures to exceed a - threshold. For instance, given M trusted keys it is possible for - the resolver to require N-of-M signatures to treat the data as - validated. - - I.e. with the following pseudo-configuration in a validating - resolver - - security-apex "." IN { - keys { ksk-1 .... ; - ksk-2 .... ; - ksk-3 .... ; - ksk-4 .... ; - ksk-5 .... ; - }; - validation { - # Note that ksk-4 is not present below - keys { ksk-1; ksk-2; ksk-3; ksk-5; }; - # 3 signatures needed with 4 possible keys, aka 75% - needed-signatures 3; - }; - }; - - we configure five trusted keys for the root zone, but require two - valid signatures for the top-most KEY for validation to - succeed. I.e. threshold validation does not force multiple - signatures on the entire signature chain, only on the top-most - signature, closest to the security apex for which the resolver has - trusted keys. - -5.2. Not All Trusted Keys Will Be Available - - With multiple KSKs held and managed by separate entities the end - resolvers will not always manage to get access to all possible - trusted keys. In the case of just a single KSK this would be fatal - to validation and necessary to avoid at whatever cost. But with - several fully trusted keys available the resolver can decide to - trust several of them individually. An example based upon more - pseudo-configuration: - - security-apex "." IN { - keys { ksk-1 .... ; - ksk-2 .... ; - ksk-3 .... ; - ksk-4 .... ; - ksk-5 .... ; - }; - validation { - # Only these two keys are trusted independently - keys { ksk-1; ksk-4; }; - # With these keys a single signature is sufficient - needed-signatures 1; - }; - }; - - Here we have the same five keys and instruct the validating - resolver to fully trust data that ends up with just one signature - from by a fully trusted key. - - The typical case where this will be useful is for the case where - there is a risk of the resolver not catching a rollover event by - one of the KSKs. By doing rollovers of different KSKs with - different schedules it is possible for a resolver to "survive" - missing a rollover without validation breaking. This improves - overall robustness from a management point of view. - -5.3. Not All Possible KSKs Need to Be Trusted - - With just one key available it simply has to be trusted, since that - is the only option available. With multiple KSKs the validating - resolver immediately get the option of implementing a local policy - of only trusting some of the possible keys. - - This local policy can be implemented either by simply not - configuring keys that are not trusted or, possibly, configure them - but specify to the resolver that certain keys are not to be - ultimately trusted alone. - - -6. Additional Benefits from Having Multiple KSKs - -6.1. More Robust Key Rollovers - - With only one KSK the rollover operation will be a delicate - operation since the new trusted key needs to reach every validating - resolver before the old key is retired. For this reason it is - expected that long periods of overlap will be needed. - - With multiple KSKs this changes into a system where different - "series" of KSKs can have different rollover schedules, thereby - changing from one "big" rollover to several "smaller" rollovers. - - If the resolver trusts several of the available keys individually - then even a failure to track a certain rollover operation within - the overlap period will not be fatal to validation since the other - available trusted keys will be sufficient. - -6.2. Evaluation of Multiple Key Distribution Mechanisms - - Distribution of the trusted keys for the DNS root zone is - recognized to be a difficult problem that ... - - With only one trusted key, from one single "source" to distribute - it will be difficult to evaluate what distribution mechanism works - best. With multiple KSKs, held by separate entitites it will be - possible to measure how large fraction of the resolver population - that is trusting what subsets of KSKs. - - -7. Security Considerations - - From a systems perspective the simplest design is arguably the - best, i.e. one single holder of both KSK and ZSKs. However, if that - is not possible in all cases a more complex scheme is needed where - additional trust is injected by using multiple KSK holders, each - contributing trust, then there are only two alternatives - available. The first is so called "split keys", where a single key - is split up among KSK holders, each contributing trust. The second - is the multiple KSK design outlined in this proposal. - - Both these alternatives provide for threshold mechanisms. However - split keys makes the threshold integral to the key generating - mechanism (i.e. it will be a property of the keys how many - signatures are needed). In the case of multiple KSKs the threshold - validation is not a property of the keys but rather local policy in - the validating resolver. A benefit from this is that it is possible - for different resolvers to use different trust policies. Some may - configure threshold validation requiring multiple signatures and - specific keys (optimizing for security) while others may choose to - accept a single signature from a larger set of keys (optimizing for - redundancy). Since the security requirements are different it would - seem to be a good idea to make this choice local policy rather than - global policy. - - Furthermore, a clear issue for validating resolvers will be how to - ensure that they track all rollover events for keys they - trust. Even with operlap during the rollover (which is clearly - needed) there is still a need to be exceedingly careful not to miss - any rollovers (or fail to acquire a new key) since without this - single key validation will fail. With multiple KSKs this operation - becomes more robust, since different KSKs may roll at different - times according to different rollover schedules and losing one key, - for whatever reason, will not be crucial unless the resolver - intentionally chooses to be completely dependent on that exact key. - -8. IANA Considerations. - - NONE. - - -9. References - -9.1. Normative. - - [RFC2535] Domain Name System Security Extensions. D. Eastlake. - March 1999. - - [RFC3090] DNS Security Extension Clarification on Zone Status. - E. Lewis. March 2001. - - -9.2. Informative. - - [RFC3110] RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System - (DNS). D. Eastlake 3rd. May 2001. - - [RFC3225] Indicating Resolver Support of DNSSEC. D. Conrad. - December 2001. - - [DS] Delegation Signer Resource Record. - O. Gudmundsson. October 2002. Work In Progress. - -10. Acknowledgments. - - Bill Manning came up with the original idea of moving complexity - from the signing side down to the resolver in the form of threshold - validation. I've also had much appreciated help from (in no - particular order) Jakob Schlyter, Paul Vixie, Olafur Gudmundson and - Olaf Kolkman. - - -11. Authors' Address -Johan Ihren -Autonomica AB -Bellmansgatan 30 -SE-118 47 Stockholm, Sweden -johani@autonomica.se diff --git a/contrib/bind9/doc/draft/draft-kato-dnsop-local-zones-00.txt b/contrib/bind9/doc/draft/draft-kato-dnsop-local-zones-00.txt deleted file mode 100644 index d857cd9..0000000 --- a/contrib/bind9/doc/draft/draft-kato-dnsop-local-zones-00.txt +++ /dev/null @@ -1,295 +0,0 @@ - - - -Internet Engineering Task Force Akira Kato, WIDE -INTERNET-DRAFT Paul Vixie, ISC -Expires: August 24, 2003 February 24, 2003 - - - Operational Guidelines for "local" zones in the DNS - draft-kato-dnsop-local-zones-00.txt - -Status of this Memo - - -This document is an Internet-Draft and is in full conformance with all -provisions of Section 10 of RFC2026. - -Internet-Drafts are working documents of the Internet Engineering Task -Force (IETF), its areas, and its working groups. Note that other groups -may also distribute working documents as Internet-Drafts. - -Internet-Drafts are draft documents valid for a maximum of six months -and may be updated, replaced, or obsoleted by other documents at any -time. It is inappropriate to use Internet-Drafts as reference material -or to cite them other than as ``work in progress.'' - -To view the list Internet-Draft Shadow Directories, see -http://www.ietf.org/shadow.html. - -Distribution of this memo is unlimited. - -The internet-draft will expire in 6 months. The date of expiration will -be August 24, 2003. - - -Abstract - -A large number of DNS queries regarding to the "local" zones are sent -over the Internet in every second. This memo describes operational -guidelines to reduce the unnecessary DNS traffic as well as the load of -the Root DNS Servers. - -1. Introduction - -While it has yet been described in a RFC, .local is used to provide a -local subspace of the DNS tree. Formal delegation process has not been -completed for this TLD. In spite of this informal status, .local has -been used in many installations regardless of the awareness of the -users. Usually, the local DNS servers are not authoritative to the -.local domain, they end up to send queries to the Root DNS Servers. - -There are several other DNS zones which describe the "local" -information. .localhost has been used to describe the localhost for -more than a couple of decades and virtually all of the DNS servers are -configured authoritative for .localhost and its reverse zone .127.in- - - -KATO Expires: August 24, 2003 [Page 1] - - -DRAFT DNS local zones February 2003 - -addr.arpa. However, there are other "local" zones currently used in the -Internet or Intranets connected to the Internet through NATs or similar -devices. - -At a DNS server of an university in Japan, half of the DNS queries sent -to one of the 13 Root DNS Servers were regarding to the .local. At -another DNS Server running in one of the Major ISPs in Japan, the 1/4 -were .local. If those "local" queries are able to direct other DNS -servers than Root, or they can be resolved locally, it contributes the -reduction of the Root DNS Servers. - -2. Rationale - -Any DNS queries regarding to "local" names should not be sent to the DNS -servers on the Internet. - -3. Operational Guidelines - -Those queries should be processed at the DNS servers internal to each -site so that the severs respond with NXDOMAIN rather than sending -queries to the DNS servers outside. - -The "local" names have common DNS suffixes which are listed below: - -3.1. Local host related zones: - -Following two zones are described in [Barr, 1996] and .localhost is also -defined in [Eastlake, 1999] . - - o .localhost - o .127.in-addr.arpa - - -Following two zones are for the loopback address in IPv6 [Hinden, 1998] -. While the TLD for IPv6 reverse lookup is .arpa as defined in [Bush, -2001] , the old TLD .int has been used for this purpose for years -[Thomson, 1995] and many implementations still use .int. So it is -suggested that both zones should be provided for each IPv6 reverse -lookup zone for a while. - - o 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.int - o 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa - - -3.2. Locally created name space - -While the use of .local has been proposed in several Internet-Drafts, it -has not been described in any Internet documents with formal status. -However, the amount of the queries for .local is much larger than -others, it is suggested to resolve the following zone locally: - - - - -KATO Expires: August 24, 2003 [Page 2] - - -DRAFT DNS local zones February 2003 - - o .local - - - -3.3. Private or site-local addresses - -The following IPv4 "private" addresses [Rekhter, 1996] and IPv6 site- -local addresses [Hinden, 1998] should be resolved locally: - - o 10.in-addr.arpa - o 16.172.in-addr.arpa - o 17.172.in-addr.arpa - o 18.172.in-addr.arpa - o 19.172.in-addr.arpa - o 20.172.in-addr.arpa - o 21.172.in-addr.arpa - o 22.172.in-addr.arpa - o 23.172.in-addr.arpa - o 24.172.in-addr.arpa - o 25.172.in-addr.arpa - o 26.172.in-addr.arpa - o 27.172.in-addr.arpa - o 28.172.in-addr.arpa - o 29.172.in-addr.arpa - o 30.172.in-addr.arpa - o 31.172.in-addr.arpa - o 168.192.in-addr.arpa - o c.e.f.ip6.int - o d.e.f.ip6.int - o e.e.f.ip6.int - o f.e.f.ip6.int - o c.e.f.ip6.arpa - o d.e.f.ip6.arpa - o e.e.f.ip6.arpa - o f.e.f.ip6.arpa - - -3.4. Link-local addresses - -The link-local address blocks for IPv4 [IANA, 2002] and IPv6 [Hinden, -1998] should be resolved locally: - - o 254.169.in-addr.arpa - o 8.e.f.ip6.int - o 9.e.f.ip6.int - o a.e.f.ip6.int - o b.e.f.ip6.int - o 8.e.f.ip6.arpa - o 9.e.f.ip6.arpa - o a.e.f.ip6.arpa - o b.e.f.ip6.arpa - - - -KATO Expires: August 24, 2003 [Page 3] - - -DRAFT DNS local zones February 2003 - -4. Suggestions to developers - -4.1. Suggestions to DNS software implementors - -In order to avoid unnecessary traffic, it is suggested that DNS software -implementors provide configuration templates or default configurations -so that the names described in the previous section are resolved locally -rather than sent to other DNS servers in the Internet. - -4.2. Suggestions to developers of NATs or similar devices - -There are many NAT or similar devices available in the market. -Regardless of the availability of DNS Servers in those devices, it is -suggested that those devices are able to filter the DNS traffic or -respond to the DNS traffic related to "local" zones by configuration -regardless of its ability of DNS service. It is suggested that this -functionality is activated by default. - -5. IANA Consideration - -While .local TLD has yet defined officially, there are substantial -queries to the Root DNS Servers as of writing. About 1/4 to 1/2% of the -traffic sent to the Root DNS Servers are related to the .local zone. -Therefore, while it is not formally defined, it is suggested that IANA -delegates .local TLD to an organization. - -The AS112 Project [Vixie, ] serves authoritative DNS service for RFC1918 -address and the link-local address. It has several DNS server instances -around the world by using BGP Anycast [Hardie, 2002] . So the AS112 -Project is one of the candidates to host the .local TLD. - -Authors' addresses - - Akira Kato - The University of Tokyo, Information Technology Center - 2-11-16 Yayoi Bunkyo - Tokyo 113-8658, JAPAN - Tel: +81 3-5841-2750 - Email: kato@wide.ad.jp - - - Paul Vixie - Internet Software Consortium - 950 Charter Street - Redwood City, CA 94063, USA - Tel: +1 650-779-7001 - Email: vixie@isc.org - - - - - - - -KATO Expires: August 24, 2003 [Page 4] - - -DRAFT DNS local zones February 2003 - -References - -To be filled - -References - -Barr, 1996. -D. Barr, "Common DNS Operational and Configuration Errors" in RFC1912 -(February 1996). - -Eastlake, 1999. -D. Eastlake, "Reserved Top Level DNS Names" in RFC2606 (June 1999). - -Hinden, 1998. -R. Hinden and S. Deering, "IP Version 6 Addressing Architecture" in -RFC2373 (July 1998). - -Bush, 2001. -R. Bush, "Delegation of IP6.ARPA" in RFC3152 (August 2001). - -Thomson, 1995. -S. Thomson and C. Huitema, "DNS Extensions to support IP version 6" in -RFC1886 (December 1995). - -Rekhter, 1996. -Y. Rekhter, B. Moskowitz, D. Karrenberg, G. J. de Groot, and E. Lear, -"Address Allocation for Private Internets" in RFC1918 (February 1996). - -IANA, 2002. -IANA, "Special-Use IPv4 Addresses" in RFC3330 (September 2002). - -Vixie, . -P. Vixie, "AS112 Project" in AS112. http://www.as112.net/. - -Hardie, 2002. -T. Hardie, "Distributing Authoritative Name Servers via Shared Unicast -Addresses" in RFC3258 (April 2002). - - - - - - - - - - - - - - - - - -KATO Expires: August 24, 2003 [Page 5] - diff --git a/contrib/bind9/doc/draft/draft-park-ipv6-extensions-dns-pnp-00.txt b/contrib/bind9/doc/draft/draft-park-ipv6-extensions-dns-pnp-00.txt deleted file mode 100644 index f9eaf26..0000000 --- a/contrib/bind9/doc/draft/draft-park-ipv6-extensions-dns-pnp-00.txt +++ /dev/null @@ -1,1830 +0,0 @@ - - - - INTERNET-DRAFT S. Daniel Park - Expires: October 2003 Syam Madanapalli - File: SAMSUNG Electronics - draft-park-ipv6-extensions-dns-pnp-00.txt April 2003 - - - - - IPv6 Extensions for DNS Plug and Play - - - - Status of This Memo - - This document is an Internet-Draft and is in full conformance with - all provisions of Section 10 of RFC2026. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF), its areas, and its working groups. Note that - other groups may also distribute working documents as - Internet-Drafts. - - Internet-Drafts are draft documents valid for a maximum of six - months and may be updated, replaced, or obsoleted by other - documents at any time. It is inappropriate to use Internet-Drafts - as reference material or to cite them other than as "work in - progress." - - The list of current Internet-Drafts can be accessed at - http://www.ietf.org/ietf/1id-abstracts.txt - - The list of Internet-Draft Shadow Directories can be accessed at - http://www.ietf.org/shadow.html. - - - - Abstract - - This document proposes automatic configuration of domain name (FQDN) - for IPv6 nodes using Domain Name Auto-Configuration (called 6DNAC) as - a part of IPv6 plug and play feature. 6DNAC allows the automatic - registration of domain name and corresponding IPv6 Addresses with - the DNS server. In order to provide 6DNAC function, Neighbor Discovery - Protocol [2461] will be used. Moreover, 6DNAC does not require any - changes to the existing DNS system. - - - Table of Contents - - 1. Introduction ............................................. 3 - 2. Terminology .............................................. 3 - 3. 6DNAC Design Principles .................................. 4 - 4. 6DNAC Overview ........................................... 4 - 5. 6DNAC Requirements ....................................... 5 - 5.1. 6DANR Client Requirements ................................ 5 - 5.2. 6DNAC Server Requirements ................................ 6 - -Park & Madanapalli Expires October 2003 [Page 1] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - 6. 6DNAC Messages and Option Formats ........................ 6 - 6.1. Router Advertisement (RA) Message Format ................. 6 - 6.2. Neighbor Solicitation (NS) Message Format ................ 7 - 6.3. Neighbor Advertisement (NA) Message Format ............... 8 - 6.4. Option Formats ........................................... 8 - 6.4.1. DNS Zone Suffix Information Option Format ................ 8 - 6.4.2. Domain Name (FQDN) Option Format ......................... 9 - 6.4.3. Router Alert Option for 6DNAC ............................ 10 - 7. 6DNAC Operation .......................................... 10 - 7.1. 6DNAC Network Topology ................................... 11 - 7.2. 6DNAC Operational Scenarios .............................. 12 - 7.2.1. Domain Name Registration-Success Case .................... 12 - 7.2.2. Domain Name Registration-with DupAddrDetectTransmits=2.... 14 - 7.2.3. Domain Name Registration-Defend Case ..................... 16 - 7.2.4. Domain Name Registration in Retry Mode ................... 19 - 7.2.5. Domain Name Registration when DAD Fails .................. 20 - 7.3. DNS Zone Suffix Discovery and FQDN Construction .......... 22 - 7.3.1. Sending Router Advertisement Messages .................... 22 - 7.3.2. Processing Router Advertisement Messages ................. 22 - 7.3.3. FQDN Lifetime expiry ..................................... 23 - 7.3.4. Host Naming Algorithm .................................... 23 - 7.4. Duplicate Domain Name Detection .......................... 23 - 7.4.1. DAD with All Nodes Multicast Address ..................... 24 - 7.4.1.1. Sending Neighbor Solicitation Messages ................... 24 - 7.4.1.2. Processing Neighbor Solicitation Messages ................ 24 - 7.4.1.3. Sending Neighbor Advertisement Messages .................. 25 - 7.4.1.4. Processing Neighbor Advertisement Messages ............... 25 - 7.4.1.5. Pros and Cons ............................................ 25 - 7.4.2. DAD with Router Alert Option for 6DNAC ................... 25 - 7.4.2.1. Sending Neighbor Solicitation Messages ................... 25 - 7.4.2.2. Processing Neighbor Solicitation Messages ................ 26 - 7.4.2.3. Sending Neighbor Advertisement Messages .................. 26 - 7.4.2.4. Processing Neighbor Advertisement Messages ............... 26 - 7.4.2.5. Pros and Cons ............................................ 26 - 7.4.3. Explicit Detection of Duplicate Domain Name .............. 26 - 7.4.3.1. Sending Neighbor Solicitation Messages ................... 26 - 7.4.3.2. Processing Neighbor Solicitation Messages ................ 26 - 7.4.3.3. Sending Neighbor Advertisement Messages .................. 27 - 7.4.3.4. Processing Neighbor Advertisement Messages ............... 27 - 7.4.3.5. Pros and Cons ............................................ 27 - 7.4.4. Retry Mode for Re-registering Domain Name ................ 27 - 7.5. Domain Name Registration ................................. 27 - 8. Security Consideration ................................... 27 - 9. IANA Consideration ....................................... 28 - 10. Acknowledgement .......................................... 28 - 11. Intellectual Property .................................... 28 - 12. Copyright ................................................ 28 - 13. References ............................................... 29 - 14. Author's Addresses ....................................... 30 - - - - - - - - -Park & Madanapalli Expires October 2003 [Page 2] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - 1. Introduction - - Today, most networks use DNS[1034][1035] for convenience. In case of - IPv6, DNS is more important element because of IPv6 long addresses - which are difficult to remember. In addition, small networks like home - networks using IPv6, should be able to make network easily without - manual configuration. Also, these small networks may not have DHCP - Server, DNS Server etc. that are used to configure the network. This - document discusses IPv6 Domain Name Auto-Configuration(6DNAC) procedure - for generating and registering the Domain Name and IPv6 addresses with - the DNS Server automatically. In order to use 6DNAC, IPv6 nodes are - required to implement lightweight functions specified in this document. - 6DNAC can be applied to all defined IPv6 unicast addresses except Link - local IPv6 addresses, viz: Site-local and Global addresses. - - 6DNAC uses Neighbor Discovery Protocol [2461] with new additions - (defined in section 6) and DAD procedures for generating and - registering the Domain Name with the DNS server automatically. - - - 2. Terminology - - 6DNAC - IPv6 Domain Name Auto Configuration. It can provide - IPv6 hosts with Domain Name Generation and - Registration automatically. - - 6DNAC Client - An IPv6 node that can generate its own unique Domain - Name. Section 3 identifies the new requirements that - 6DNAC places on an IPv6 node to be a 6DNAC node. - - 6DNAC Server - An IPv6 node that can collect and registrate Domain - Name and IPv6 addresses automatically. 6DNAC server - uses the information from the DAD operation messages - with newly defined options for the registration of the - Domain Name and IPv6 Addresses. Section 3 identifies - the new requirements that 6DNAC places on an IPv6 - node to be a 6DNAC server. Also 6DNAC server can have - various other functions depending on network - environment and the network operator. For instance - 6DNAC Server can acts as a Gateway as well Home Server - in Home Networks. - - DAD - Duplicate Address Detection (is defined [2461]) - - DFQDND - Duplicate Domain Name Detection - - FQDN - Fully Qualified Domain Name - FQDN and Domain Name are - used interchangeably in this document. - - NA - Neighbor Advertisement message (is defined [2461]) - - NS - Neighbor Solicitation message (is defined [2461]) - - RA - Router Advertisement message (is defined [2461]) - - SLAAC - Stateless Address Autoconfiguration [2462]. - -Park & Madanapalli Expires October 2003 [Page 3] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - 3. 6DNAC Design Principles - - This section discusses the design principles of 6DNAC mechanism. - - 1. The new procedures for plug and play DNS should not cause changes - to existing DNS system. 6DNAC requires lightweight functions to be - implemented only at the client side of the DNS system, and uses the - existing DDNS UPDATE [2136] to communicate with DNS Servers. - - 2. Introducing a new protocol will always introduce new problems. - 6DNAC uses the existing protocols NDP [2461] with minor extensions - for generating and registering the domain name automatically - without defining a new protocol - - 3. Reusing proven and well understood design principles/patterns - will always yield a robust system. 6DNAC is based on IPv6 Address - Auotoconfiguration principle, where routers advertise the prefix - and host adds the interface ID to the prefix and forms the IPv6 - address. Domain Name (FQDN) also contains two parts: host name - and DNS zone suffix. Routers can advertise the DNS zone suffix - on a particular link in Router Advertisements (RA Messages) and - hosts can prefix their preferred host name to the DNS zone suffix - and form the fully qualified domain name. Also the detection of - duplicate domain name is similar to Duplicate Address Detection - (DAD) and can be part of DAD operation itself. - - - 4. 6DNAC Overview - - 6DNAC proposes minor extensions to NDP [2461] for automatic generation - and registration of domain name with the DNS server. It introduces two - new options: DNS Zone Suffix and Fully Qualified Domain Name. DNS Zone - Suffix option is carried in Router Advertisement (RA) messages for - notifying IPv6 nodes about the valid DNS Zone Suffix on the link and - FQDN option in Neighbor Solicitation (NS) and Neighbor Advertisement - (NA) messages to detect duplicate domain name. 6DNAC consists of two - components: 6DNAC Client and 6DNAC Server. 6DNAC Clients generate the - domain name based on DNS Zone Suffix using Host Naming Algorithm (see - section 7.3.1) and 6DNAC Server collects and registers the DNS - information with the DNS Server on behalf of 6DNAC Clients. - - The automatic configuration of domain name using 6DNAC consists of - three parts. - - - DNS Zone Suffix Discovery and FQDN Construction: - - IPv6 Nodes collect DNS Zone Suffix information from Router - Advertisements and constructs FQDN by prefixing host name to the - DNS Zone Suffix. The IPv6 Nodes are required to implement Host - Naming Algorithm for generating host part of the FQDN in the - absence of administrator. - - Generation of node's FQDN within the node itself has advantages. Nodes - can provide forward and reverse name lookups independent of the DNS - System by sending queries directly to IPv6 nodes [NIQ]. Moreover Domain - Name is some thing that is owned by the node. - -Park & Madanapalli Expires October 2003 [Page 4] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - - Duplicate Domain Name Detection - - All nodes are expected to go for DAD for all new IPv6 unicast - addresses, regardless of whether they are obtained through - stateful, stateless or manual configuration. 6DNAC uses the DAD - messages with new option for carrying the Domain Name along with - the new IPv6 Address. 6DNAC Server captures this information and - updates DNS Server provided that the IPv6 Address and its domain - name are not duplicate. If the domain name is already in use, - the 6DNAC server replies to the sender with FQDN Option in NA - message indicating that the domain name is duplicate. Then the - node is expected to generate another domain name using host - naming algorithm and go for DAD. This time the DAD is only for - duplicate domain name detection (DFQDND). In order to avoid - confusion with the normal NDP processing, the target address - field of the NS message must carry the unspecified address - in retry mode. This can be repeated depending on number of - retries defined by the administrator in the host naming algorithm. - - - - Domain Name Registration - - 6DNAC Server detects the DNS information (IPv6 Address and - corresponding FQDN) from DAD/DFQDND messages and updates DNS - Server using existing protocol DDNS UPDATE [2136] provided that - the IPv6 Address and its domain name are not duplicate. - - If an IPv6 Address is duplicate, the IPv6 node cannot perform - stateless address autoconfiguration repeatedly. Unlike IPv6 stateless - address autoconfiguration, 6DNAC allows the automatic configuration of - domain name repeatedly if the domain name is duplicate depending on - number of retries defined by the administrator in the host naming - algorithm. - - - 5. 6DNAC Requirements - - Depending on the 6DNAC functionality, the IPv6 nodes implement, they - are called either 6DNAC Clients or 6DNAC Servers. The following - sections lists the requirements that the 6DNAC Client and 6DNAC server - must support. - - - 5.1. 6DANC Client Requirements - - - 6DNAC Client must recognize and process the following NDP - extensions - - - DNS Zone Suffix option in RA messages for generating its - domain name (FQDN). - - - Domain Name option in NS and NA messages for detecting - the duplicate domain name - - - - -Park & Madanapalli Expires October 2003 [Page 5] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - - It must generate its domain name (FQDN) based on the DNS - suffix that it got from the router advertisement. And it must - have a host naming algorithm for generating the host part of - the FQDN. - - - If NA message is received with unspecified target address and - FQDN option, then the node must treat that the domain is - duplicate. - - - 5.2. 6DNAC Server Requirements - - - 6DNAC Server must recognize and process the following NDP - extensions - - - If the 6DNAC Server is a router on the link, then it - must advertise DNS Zone Suffix option in RA messages - for hosts to generate their domain name (FQDN). - - - FQDN option in NS messages for detecting new DNS - information for of nodes on the link for which it - must update the AAAA RR and PTR RR in DNS Server. - - - FQDN option in NA messages for notifying duplicate - domain name with unspecified target address. - - - 6DNAC server must update the DNS Server (both AAAA RR and - PTR RR) dynamically using DDNS UPDATE [2136]. - - - 6DNAC server must cache this (newly detected) FQDN, Link - Layer Address, and IPv6 Address information, so that it can - decide whether it really needs to update DNS Server or not, - to avoid redundant updates. This information will also be - used for notifying the duplicate domain name. - - - 6. 6DNAC Messages and Option Formats - - In order to achieve the plug and play DNS, 6DNAC proposes new - extensions to the NDP [2461]. This section specifies the new - additions to NDP messages and formats of new options. - - - 6.1. Router Advertisement (RA) Message Format - - Routers send out Router Advertisement (RA) message periodically, or - in response to a Router Solicitation. 6DNAC does not modify the format - of the RA message, but proposes new option (DNS Zone Suffix Information) - to be carried in RA messages. - - - - - - - - -Park & Madanapalli Expires October 2003 [Page 6] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Type | Code | Checksum | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Cur Hop Limit |M|O| Reserved | Router Lifetime | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Reachable Time | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Retrans Timer | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Options ... | - / / - | DNS Zone Suffix Information | - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - - - - - - 6.2. Neighbor Solicitation (NS) Message Format - - 6DNAC does not modify the format of the Neighbor Solicitation (NS) - message, but proposes new option (FQDN Option) to be carried in NS - messages. When a node is going for DAD, the node must include FQDN - option in NS message to participate in plug and play DNS. If the - node is going for Explicit Detection of Duplicate Domain Name, the - node must use FQDN option in NS message and unspecified address in - the target address field. - - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Type | Code | Checksum | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Reserved | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - + + - | | - + Target Address + - | | - + + - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Options ... | - / / - | Domain Name | - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - - - -Park & Madanapalli Expires October 2003 [Page 7] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - 6.3. Neighbor Advertisement (NA) Message Format - - 6DNAC does not modify the format of the Neighbor Advertisement (NA) - message, but proposes new option (FQDN Option) to be carried in NA - messages. 6DNAC Server sends NA message with FQDN option to 6DNAC - Client that is performing duplicate domain name detection in case - the domain name found to be duplicate. - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Type | Code | Checksum | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |R|S|O| Reserved | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - + + - | | - + Target Address + - | | - + + - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Options ... | - / / - | FQDN Option | - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - - - - - 6.4 Option Formats - - 6.4.1. DNS Zone Suffix Information Option Format - - IPv6 nodes require DNS Zone Suffix for constructing their FQDN. - 6DNAC introduces new option for routers to advertise the DNS Zone - Suffix Information for IPv6 nodes on the link. The suffix information - should be configured into routers manually. - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Type | Length | Reserved | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Valid Lifetime | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - / DNS Zone Suffix / - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - - - -Park & Madanapalli Expires October 2003 [Page 8] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - Type [TBD] - - Length 8-bit unsigned integer. The length of the option - (including the type and length fields) in units of - 8 octets. - - Reserved This field is unused. It must be initialized to zero - by the sender and must be ignored by the receiver. - - Valid Life Time 32-bit signed integer. The maximum time, in - seconds, over which this suffix is valid. Nodes - should treat this as the life time for their domain - name. Nodes should contact the source of this - information before expiry of this time interval. - A value of all one bits (0xFFFFFFFF) represents - infinity. - - DNS Zone Suffix The suffix part of the FQDN. The data in the DNS - Zone Suffix field should be encoded according to - DNS encoding rules specified in [1035]. - - - - 6.4.2. Domain Name (FQDN) Option Format - - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Type | Length | Reserved | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Valid Lifetime | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - + + - | | - + FQDN Target Address + - | | - + + - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - / Domain Name / - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - - - - Type [TBD] - - Length 8-bit unsigned integer. The length of the option - (including the type and length fields) in units - of 8 octets. It must be greater than 3. - - - -Park & Madanapalli Expires October 2003 [Page 9] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - Reserved This field is unused. It must be initialized to - zero by the sender and must be ignored by the - receiver. - - Valid Life Time 32-bit signed integer. The maximum time, in - seconds, over which this domain name is valid - 6DNAC should deregister this domain name at - the expiry of this interval. 6DNAC clients - should send updates by the expiry of this - interval. A value of all one bits (0xFFFFFFFF) - represents infinity. - - FQDN Target Address The Address for which the FQDN maps to. It - should be same as Target Address field of the - NS message in case of DAD & duplicate FQDN are - running in parallel. - - Domain Name The domain name (FQDN) of the node. The data in - the domain name should be encoded according to - DNS encoding rules specified in [1035]. - - - 6.4.3. Router Alert Option for 6DNAC - - Router Alert Option for 6DNAC is new option within the IPv6 Hop-by-Hop - Header for using in NDP messages. The presence of this option in NS - message informs the router that this NS message is carrying Domain - Name information and must be processed by the 6DNAC Server on the router. - 6DNAC Clients can use this option for sending DAD packets instead - of addressing the DAD packets to the all-nodes multicast address - when 6DNAC Server is implemented on router. - - The Router Alert option has the following format: - - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |0 0 0|0 0 1 0 1|0 0 0 0 0 0 1 0| Value (2 octets) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - Length = 2 - - Values are registered and maintained by the IANA. For 6DNAC, the - value has to be assigned by IANA. - - Further information about this option can be obtained from - IPv6 Router Alert Option [2711]. - - - 7. 6DNAC Operation - - 6DNAC provides mechanisms for automatic generation of domain name - and registering it with the DNS Server for IPv6 nodes. 6DNAC consists - of two components: 6DNAC Client and 6DNAC Server. All nodes that want - to participate in plug and play DNS are required to implement 6DNAC - Client functionality, and one of the IPv6 nodes is required to - implement 6DNAC Server functionality. The IPv6 node that implements - the 6DNAC Server functionality must know the location of the DNS - Server and must be a trusted node to send DDNS UPDATE [2136] messages. - -Park & Madanapalli Expires October 2003 [Page 10] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - 7.1. 6DNAC Network Topology - - This section identifies the possible locations for the 6DNAC Server. - Note that, all nodes are required to implement 6DNAC Client - functionality for constructing the domain name from the DNS Zone - Suffix Information advertised by the router. Figure 6 illustrates - IPv6 host (H4) implementing 6DNAC Server functionality. In this case - H4 can serve only one link (that it belongs to) for automatic - registration of domain name. H4 must observe the DAD packets on the - link to detect the DNS information, this requires all nodes on the - link must belong to same solicited node multicast address. In general, - this may not be the case. So the node that is going for DAD must use - all nodes multicast address for DAD packets, so that the 6DNAC Server - (H4) can observe the DAD packets, detects IPv6 address and - corresponding domain name, checks if this domain name is duplicate - and finally registers the domain name with the DNS Server. - - - 6DNAC Server - +---+ +---+ +----------+ - | H1| | H4|<--- DDNS UPDATE --->|DNS Server| - +-+-+ +-+-+ +----+-----+ - | | +----+ +---/ - | | | | / - ---+-----+-----------+-----+-----------+ R1 +-----+ - | | | | - | | +----+ - +-+-+ +-+-+ - | H2| | H3| - +---+ +---+ - - - H1, H2, H3 - 6DNAC Clients - H4 - 6DNAC Server - R1 - Router - - - - - - Figure 7 shows the 6DNAC Server implemented on a router R1. In this - case a single 6DNAC server can serve multiple links for automatic - configuration of the domain name. This topology also has flexibility - of using DAD packets with Router Alert option instead of sending DAD - packets to all nodes multicast address. The routers are required to - process all the packets with Router Alert option as per [2711]. - - In case of Home Networks, R1 is will acts as a Home Gateway (CPE) - connected to ISP. R1 delegates the prefix from the ISP edge router. - After delegating the prefix the CPE can advertise the DNS Zone suffix - along with the prefix information to the nodes on the links to which - the router is connected to. Note that the R1 must be configured with - the DNS Zone suffix Information manually. - - - - -Park & Madanapalli Expires October 2003 [Page 11] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - +---+ +---+ - | H3+ | H4| - +-+-+ +-+-+ - | | - | LINK2 | - +---+ ---+--------+--+-- +----------+ - | H1| | |DNS Server| - +-+-+ | +----+-----+ - | +--+-+ -------/ - | LINK 1 | | / - ---+-----+------------------+ R1 +---------+ - | | | DDNS UPDATE - | +----+ - +-+-+ 6DNAC Server - | H2| - +---+ - - - H1, H2 - 6DNAC Clients on Link1 - H3, H4 - 6DNAC Clients on Link2 - R1 - Router with 6DNAC Server, serving both Link1 and Link2 - - - - - - 7.2. 6DNAC Operational Scenarios - - This section provides message sequence charts for various 6DNAC - operational scenarios assuming that the 6DNAC Server is implemented - on a router. All the scenarios assume that the normal boot up time - stateless address autoconfiguration of Link Local address derived - from the Interface Identifier has been completed successfully. And - it is also assumed that the router is already configured with the - DNS Zone Suffix Information. - - - Legend: - - 6DNAC-A, B, C : 6DNAC Clients - 6DNAC-S : 6DNAC Server/Router - DAD : Duplicate Address Detection - DFQDND : Duplicate Domain Name Detection - DNS-S : DNS Server - - - 7.2.1. Domain Name Registration-Successful Case - - This scenario starts when a 6DNAC Client receives RA message with - DNS Zone Suffix and other parameters including address prefix as - specified in NDP [2461] and wants configure its IPv6 address (Global - or Site Local) and domain name. It is Assumed that the - DupAddrDetectTransmits is set to 1. - - - - -Park & Madanapalli Expires October 2003 [Page 12] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - +---------+ +---------+ +---------+ - | 6DNAC-C | | 6DNAC-S | | DNS-S | - +----+----+ +----+----+ +----+----+ - | | | - | RA with | | - | DNS Suffix Opt | | - |<---------------| | - | #1 | | - |---+ | | - Construct |#2 | | - FQDN | | | - |<--+ | | -DAD/DFQDND Starts | | - | | | - | | | - | NS With | | - | FQDN Opt | | - |--------------->| | - | #3 | | - | | | - | |------+ | - | Create FQDN | #4 | - | | | - | |<-----+ | - | | | - | | Register FQDN | - | |--------------->| - | | #5 | - | #6 | | - |--------+ | | - No Response | | | - DFQDND-Success | | | - |<-------+ | | - | | | - | | | - v V v - - - - - - #1. 6DNAC Server (Router) sends out router advertisement with DNS - Suffix information along with other parameters as specified in - NDP [2461]. - - #2. 6DNAC Client processes the router advertisement and constructs - the FQDN by prefixing hostname to the DNS Zone Suffix. It also - constructs IPv6 address from the autoconfiguration prefix - information option. - - #3. 6DNAC Client starts duplicate address & FQDN detection for the - IPv6 address & FQDN constructed and sends out a Neighbor - Solicitation message with FQDN option. - - Note that the DAD packets must be addressed to all nodes multicast - address if Router Alert option is not used. - -Park & Madanapalli Expires October 2003 [Page 13] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - #4. 6DNAC Server processes the Neighbor Solicitation message sent by - 6DNAC Client as part of duplicate FQDN detection procedure and - creates a FQDN entry in its FQDN Cache (assuming that there is no - entry ), where C is Link Layer Address of the 6DNAC Client. - - #5. 6DNAC Server then registers FQDN and corresponding IPv6 address - through the existing protocol DDNS UPDATE. - - #6. 6DNAC Client times out and observes that there is no response to - defend its duplicate FQDN detection procedure and the node is - successful in configuring its domain name. - - Note that, Stateless Address Autoconfiguration DAD procedure is not - depicted in the following message sequence chart, which simultaneously - happens along with duplicate FQDN detection. - - - 7.2.2. Domain Name Registration-with DupAddrDetectTransmits=2 - - This scenario starts when a 6DNAC Client receives RA message with - DNS Zone Suffix and other parameters including address prefix as - specified in NDP [2461] and wants configure its IPv6 address (Global - or Site Local) and domain name. The node is configured with - DupAddrDetectTransmits = 2 for reliability in delivering DAD messages. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Park & Madanapalli Expires October 2003 [Page 14] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - +---------+ +---------+ +---------+ - | 6DNAC-C | | 6DNAC-S | | DNS-S | - +----+----+ +----+----+ +----+----+ - | | | - | RA with | | - | DNS Suffix Opt | | - |<---------------| | - | #1 | | - |---+ | | - Construct |#2 | | - FQDN | | | - |<--+ | | -DAD/DFQDND Starts | | - | | | - | | | - | NS With | | - | FQDN Opt | | - |--------------->| | - | #3 | | - | | | - | |------+ | - | Create FQDN | #4 | - | | | - | |<-----+ | - | | | - | | Register FQDN | - | |--------------->| - | | #5 | - | NS With | | - | FQDN Opt | | - |--------------->| | - | #6 | | - | | | - | Lookup FQDN | - | Entry exists | - | |------+ | - | Ignore | #7 | - | |<-----+ | - | #8 | | - |--------+ | | - No Response | | | - DFQDND-Success | | | - |<-------+ | | - | | | - | | | - v V v - - - - - - - Steps from #1 to #5 are same as that of scenario.7.2.1. - - #6. 6DNAC Client sends out second Neighbor Solicitation message with - FQDN option as part of duplicate FQDN detection. - -Park & Madanapalli Expires October 2003 [Page 15] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - #7. 6DNAC Server receives and observes that the FQDN Cache exactly - matches with that of the NS information and ignores the NS message. - - #8. 6DNAC Client times out and observes that there is no response to - defend its duplicate FQDN detection procedure and the node is - successful in configuring its domain name.. - - - 7.2.3. Domain Name Registration-Defend Case - - This scenario starts when two 6DNAC Client receive RA message with - DNS Zone Suffix and other parameters including address prefix as - specified in NDP [2461] and both the nodes want configure their IPv6 - address (Global or Site Local) and domain name. In this scenario both - the nodes want to have same domain name. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Park & Madanapalli Expires October 2003 [Page 16] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - - - +---------+ +---------+ +---------+ +---------+ - | 6DNAC-A | | 6DNAC-S | | 6DNAC-B | | DNS-S | - +----+----+ +----+----+ +----+----+ +----+----+ - | | | | - | RA with | RA with | | - | DNS Suffix Opt | DNS Suffix Opt | | - |<---------------|--------------->| | - | #1 | #1 | | - |---+ | |---+ | - Construct | #2 | Construct | #2 | - FQDN | | FQDN | | - |<--+ | |<--+ | - DAD/DFQDND Starts | DAD/DFQDND Starts | - | | | - | | | | - | NS with | | | - | FQDN Opt | | | - |--------------->| | | - | #3 | | | - | No Entry | | - | |------+ | | - | Create FQDN | #4 | | - | | | | - | |<-----+ | | - | | | | - | | Register FQDN #5 | - | |-------------------------------->| - | | | | - | | NS with | | - | | FQDN Opt | | - | |<---------------| | - | | #6 | | - | |------+ | | - | FQDN is in use| | | - | Defend DFQDND| #7 | | - | |<-----+ | | - | | | | - | | NA with | | - | | D-flag Set | | - | |--------------->| | - | | #8 | | - |------+ | |---+ | - No Response | #9 | Enter | #10 | - DFQDND Success| | Retry Mode| | - |<-----+ | |<--+ | - | | | | - v v v v - - - - - - - - -Park & Madanapalli Expires October 2003 [Page 17] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - #1. 6DNAC Server (Router) sends out router advertisement with DNS - Suffix information. - - #2. 6DNAC Clients A&B process the router advertisement and construct - their FQDN by prefixing hostname to the DNS Zone Suffix. They - also construct IPv6 address from the autoconfiguration prefix - information option. - - When each host is trying to go for DAD, all hosts must have - random delay to avoid the traffic congestion according to [2461]. - So here it is assumed that 6DNAC Client-A starts DAD first and - 6DNAC Client-B starts DAD later. - - #3. 6DNAC Client-A starts duplicate address & FQDN detection for the - IPv6 address & FQDN constructed and sends out a Neighbor - Solicitation message with FQDN option. - - #4. 6DNAC Server processes the Neighbor Solicitation message sent by - 6DNAC Client-A as part of duplicate FQDN detection procedure and - creates a FQDN entry in its FQDN Cache (assuming that there is no - entry ), where A is Link Layer Address of the 6DNAC Client-A. - - #5. 6DNAC Server then registers FQDN and corresponding IPv6 address - through the existing protocol DDNS UPDATE. - - #6. 6DNAC Client-B starts duplicate address & FQDN detection for the - IPv6 address & FQDN constructed and sends out a Neighbor Solicitation - message with FQDN option. - - #7. 6DNAC Server processes the Neighbor Solicitation message sent by - 6DNAC Client-B as part of duplicate FQDN detection procedure and - finds that the domain name is already in use by the 6DNAC Client-A. - Hence, concludes to defend the duplicate FQDN detection of 6DNAC - Client-B. - - #8. 6DNAC Server sends out Neighbor Advertisement message with FQDN - option to 6DNAC Client-B to defend its duplicate FQDN detection. - - #9. 6DNAC Client-A times out and observes that there is no response to - defend its duplicate FQDN detection procedure and the node is - successful in configuring its domain name. - - #10. 6DNAC Client-B observes that there is a NA with FQDN option - indicating that the domain name is duplicate and enters Retry - Mode. In retry mode, 6DNAC Client constructs another FQDN based - on Host Naming Algorithm. The number of retries is defined by the - administrator and must be a configurable value. - - - - - - - - - - -Park & Madanapalli Expires October 2003 [Page 18] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - 7.2.4. Domain Name Registration in Retry Mode - - Pre-Conditions: - - 1. Duplicate Address Detection has succeeded - 2. Duplicate FQDN Detection FAILED - 3. FQDN is the first FQDN one constructed and FAILED - 4. FQDN2 is the second FQDN to be constructed - 5. The Neighbor Solicitation in the 'Retry Mode' - carries unspecified address in its target field (NS*). - - +---------+ +---------+ +---------+ - | 6DNAC-C | | 6DNAC-S | | DNS-S | - +----+----+ +----+----+ +----+----+ - | | | - |--------+ | | - Construct | #1 | | - new FQDN2 | | | - |<-------+ | | - | | | - DFQDND Restarts | | - | | | - | | | - | NS* With | | - | FQDN Opt | | - |--------------->| | - | #2 | | - | | | - | No Entry | - | |------+ | - | Create FQDN | #3 | - | | | - | |<-----+ | - | | | - | | Register FQDN2 | - | |--------------->| - | | #4 | - | | | - |--------+ | | - No Response | #5 | | - DFQDND-Success | | | - |<-------+ | | - | | | - v V v - - - - - - - - - - - - - -Park & Madanapalli Expires October 2003 [Page 19] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - #1. 6DNAC Client constructs the FQDN again as per Host Naming Algorithm, - the DNS Zone Suffix, and it is FQDN2. - #2. It then starts Duplicate Detection only for Domain Name. 6DNAC - Client sends out NS with FQDN option and unspecified target - address. - - #3. 6DNAC Server processes the Retry Mode NS message and finds that - the FQDN2 is not in use and creates Cache entry as . - - #4. It then starts registration procedures with the DNS Server. - - #5. Meanwhile, 6DNAC Client timesout and observes that there is no - defending NA for its DFQDND NS sent out and successfully - configures its domain name. - - - 7.2.5. Domain Name Registration when DAD Fails - - Duplicate domain name detection and subsequent registration starts - if and only if the DAD for IPv6 address succeeds. If the DAD for - IPv6 address fails then no actions are taken for domain name. When - DAD fails for stateless address autoconfiguration, then the domain - configuration starts only when the address has been configured using - Stateful Address Configuration methods and the node is going on DAD - for this address. - - This scenario starts when a 6DNAC Client receives RA message with - DNS Zone Suffix and other parameters including address prefix as - specified in NDP [2461] and wants configure its IPv6 address (Global - or Site Local) and domain name. - - - - - - - - - - - - - - - - - - - - - - - - - - - -Park & Madanapalli Expires October 2003 [Page 20] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - +---------+ +---------+ +---------+ +---------+ - | 6DNAC-A | | 6DNAC-S | | 6DNAC-B | | DNS-S | - +----+----+ +----+----+ +----+----+ +----+----+ - | | | | - | | | | - | RA with | | | - | DNS Suffix Opt | | | - |<---------------| | | - | #1 | | | - |-----+ | | | - Construct | | | | - FQDN& | #2 | | | - IPv6 Addr | | | | - |<----+ | | | - DAD/DFQDND Starts | | | - | | | | - | | | | - | NS with | | | - | FQDN Opt | | | - |--------------->+--------------->| | - | #3 | #3 | | - | No Entry | | - | |------+ | | - | Create FQDN | | | - | | #4 | | - | |<-----+ | | - | | | | - | | |------+ | - | | My IPv6 Addr| #5 | - | | |<-----+ | - | | Defend DAD | | - | | with NA | | - |<---------------+<---------------| | - | #6 | #6 | | - | Entry | | - | |------+ | | - | Delete FQDN | #7 | | - | |<-----+ | | - | | | | - |----+ | | | - DAD Failed | #8 | | | - Stop DFQDND | | | | - |<---+ | | | - | | | | - v v v v - - - - #1. 6DNAC Server sends out Router Advertisement to 6DNAC Client-A. - - #2. 6DNAC Client-A constructs IPv6 Address based on the prefix and - FQDN as per Host Naming Algorithm. - - #3. It then starts Duplicate address & FQDN Detection, for the newly - constructed IPv6 address and FQDN, and sends out DAD/DFQDND NS - with FQDN option. - -Park & Madanapalli Expires October 2003 [Page 21] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - #4. 6DNAC Server processes the DAD/DFQDND NS message and finds - that there is no entry for the FQDN in its cache. And, - creates Cache entry as and starts a Registration - timer with RegistrationWaitTime seconds. - - #5. 6DNAC Client-B finds that the DAD/DFQDND-NS target address is - in its unicast address list. - - #6. It then starts defending DAD by sending NA to all-nodes multicast. - - #7. 6DNAC Server finds that the DAD has failed for 6DNAC Client-A. - And, deletes its FQDN Cache entry . - - #8. 6DNAC Client gets defending DAD-NA and desists from DAD. - And also, stops Duplicate FQDN Detection as well. - At this point the address must be configured using stateful - methods and the domain name registration starts with the DAD - for the newly constructed IPv6 address. - - 7.3. DNS Zone Suffix Discovery and FQDN Construction - - 7.3.1. Sending Router Advertisement Messages - - Routers send out Router Advertisement message periodically, - or in response to a Router Solicitation. Router should include - the DNS Zone Suffix Option in their advertisements. If the DNS - Zone Suffix changes (similar to Site Renumbering), then it should - advertise the Old Zone Suffix with zero Valid Lifetime and New - Zone Suffix with proper non-zero Valid Lifetime. In any other - case, a router should not send this option twice in a single - router advertisement. - - 7.3.2. Processing Router Advertisement Messages - - For each DNS Zone Suffix Option in Router Advertisement, - - a. 6DNAC node stores the Zone Suffix information in its local - database. Also, constructs FQDN as per Host Naming Algorithm. - - b. If the node has not configured FQDN yet, - - 1. If the node is going to perform DAD for either Site local or - Global Address, then it should include FQDN option to perform - Duplicate FQDN Detection in parallel with DAD. - - 2. If the node has already got either Site local or Global - address, then it should send out NS with FQDN option and - unspecified target address to perform Duplicate FQDN - Detection. - - c. If the node has already configured FQDN, and if the - advertisement carries two DNS Zone Suffix Options, - First DNS Zone Suffix should match with the configured FQDN - Suffix and its Valid Lifetime must be zero. Second DNS Zone - - - -Park & Madanapalli Expires October 2003 [Page 22] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - - Suffix should have non-zero Valid Lifetime. In this case, the - node constructs new FQDN based on the new DNS Zone Suffix (from - second DNS Zone Suffix option), and perform Duplicate FQDN - Detection with unspecified target address. Also, it should - overwrite the old FQDN with the newly constructed FQDN. - - - 7.3.3. FQDN Lifetime expiry - - 6DNAC Server: - It should delete the FQDN cache entry and should de-register from - the DNS Server. - - 6DNAC Client: - It should send update to 6DNAC Server by restarting the Duplicate - FQDN Detection. - - 7.3.4. Host Naming Algorithm - - A node constructs FQDN by combining DNS Zone Suffix and the hostname - as depicted in the following diagram. - - +------------------+----------------------------------+ - | Host Name | Advertised Suffix | - +------------------+----------------------------------+ - -
- - A node can choose Host Name using any of the following methods: - - a. String form of random number generated from the Interface - Identifier. - - b. List of configured Host Names provided by the administrator. - - - The number of retries must be specified in this algorithm in - case of domain name duplication. - - - 7.4. Duplicate Domain Name Detection - - The procedure for detecting duplicated FQDNs uses Neighbor - Solicitation and Advertisement messages as described below. - - If a duplicate FQDN is detected during the procedure, the - FQDN cannot be assigned to the node. - - An FQDN on which the DFQDND Procedure is applied is said - to be tentative until the procedure has completed successfully. - A tentative FQDN is not considered "assigned to the node" in the - traditional sense. That is, the node must accept Neighbor - Advertisement message containing the tentative FQDN in the FQDN - Option. - - -Park & Madanapalli Expires October 2003 [Page 23] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - - It should also be noted that DFQDN must be performed prior to - registering with DNS Server to prevent multiple nodes from using - the same FQDN simultaneously. All the Duplicate Address Detection - Neighbor Solicitation messages must carry Source Link Layer Address - Option as specified in NDP [2461]. - - The detection of duplicate FQDN can be achieved through one of the - following three types of procedures. - - 1. DAD with All Nodes Multicast Address - 2. DAD with Router Alert Option for 6DNAC. - 3. Explicit Detection of Duplicate Domain Name - - Even though three solutions are listed, authors prefer only one - procedure to be followed in future based on further analysis and - comments received from others. - - 7.4.1. DAD with All Nodes Multicast Address - - 7.4.1.1. Sending Neighbor Solicitation Messages - - 6DNAC Client sends Neighbor Solicitation Messages as part - of Duplicate Address Detection SLAAC [2462] with the following - extra information and modifications: - - a. Include FQDN Option in the DAD Neighbor Solicitation Message - b. Destination Address is set to All Nodes Multicast Address - - There may be a case where DAD has succeeded but DFQDND is in Retry - Mode. In such case, the Neighbor Solicitation must carry unspecified - address in the ICMP target address field and new domain name in FQDN - option to re-try the registration of the domain name. - - 7.4.1.2. Processing Neighbor Solicitation Messages - - 6DNAC Clients must ignore the FQDN option found in any of the - neighbor solicitation messages. - - 6DNAC Server processes FQDN Option found in the Duplicate Address - Detection Neighbor Solicitation Messages as described below: - - Lookup FQDN Cache for the domain name in FQDN Option. - - If the entry exists and - i. Link Layer Address matches with SLLA option, this is the case, - where node has changed its IPv6 address or updating the valid - life time. 6DNAC Server updates its cache and also updates DNS - Server using DDNS-UPDATE. If there is no change in IPv6 address - or life time then no updates are sent to the DNS server. - - ii. Link Layer Address differs with SLLA option, defend the duplicate - FQDN Detection by sending Neighbor Advertisement Message as - described in $7.4.1.3$. - - - -Park & Madanapalli Expires October 2003 [Page 24] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - - else, - Lookup FQDN Cache for the Link Layer Address in SLLA Option. - - If the entry exists, update the FQDN Cache and update DNS Server - using DDNS-UPDATE. This is the case, where node has changed its - domain name (similar to Site Re-numbering). - - If then entry does not exists, then it means that this is the new - registration. It must create a cache entry and start Registration - - timer with RegistrationWaitTime. At the expiry of the Registration - timer, it should update DNS Server with DDNS-UPDATE. - - 7.4.1.3. Sending Neighbor Advertisement Messages - - 6DNAC Server sends Neighbor Advertisement Messages as part - of Duplicate Address Detection SLAAC [2462] with the FQDN Option - in Neighbor Advertisement message to defend duplicate FQDN - detection. - - There may be the case where defending of duplicate address detection - is not required but defending of FQDN is required. In such instance, - the defending Neighbor Advertisement must carry FQDN and unspecified - address in the ICMP target address field. - - 7.4.1.4. Processing Neighbor Advertisement Messages - - 6DNAC Server must ignore the any FQDN option found any of - the neighbor advertisement messages. If the Neighbor Advertisement - is a DAD defending, then it must delete its FQDN Cache entry created - on the reception of DAD Neighbor Solicitation message. - - When 6DNAC Clients gets the duplicate address detection neighbor - advertisement messages with FQDN option set it means that its - duplicate FQDN detection failed and enters Retry Mode. - - 7.4.1.5. Pros and Cons - - The advantage of this procedure is that it does not need any - extension header options to be included. The disadvantage of this - procedure is that, it needs change in the existing DAD procedure. - The change is only that the DAD neighbor solicitations are to be - addressed to all nodes multicast address instead of solicited - node multicast address. The another disadvantage is that, it needs - the existence of Duplicate Address Detection Procedure to - perform duplicate FQDN detection. - - 7.4.2. DAD with Router Alert Option for 6DNAC - - 7.4.2.1. Sending Neighbor Solicitation Messages - - 6DNAC Client sends Neighbor Solicitation Messages as part - of Duplicate Address Detection SLAAC [2462] with the following - extra information: - - -Park & Madanapalli Expires October 2003 [Page 25] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - - a. Include Hop-by-Hop extension Header with Router Alert Option - for 6DNAC as described in IPv6 Router Alert Option[2711]. - - b. Include FQDN Option in the DAD Neighbor Solicitation Message - - 7.4.2.2. Processing Neighbor Solicitation Messages - - This is same as described in $7.4.1.2$. - - 7.4.2.3. Sending Neighbor Advertisement Messages - - This is same as described in $7.4.1.3$. - - 7.4.2.4. Processing Neighbor Advertisement Messages - - This is same as described in $7.4.1.4$. - - 7.4.2.5. Pros and Cons - - The advantage of this procedure is that it does not disturb - the existing implementation and their way of processing the - packets. The disadvantage is that, it needs the existence - of Duplicate Address Detection Procedure to perform duplicate - FQDN detection. Another disadvantage is that this procedure - requires 6DNAC Server functionality to be implemented on Router. - However, in this case 6DNAC Server can serve multiple links. - - 7.4.3. Explicit Detection of Duplicate Domain Name - - In this procedure Duplicate FQDN Detection starts after completion - of successful Site local or Global Address configuration. - - 7.4.3.1. Sending Neighbor Solicitation Messages - - 6DNAC Client sends Neighbor Solicitation Messages as part - of Duplicate FQDN Detection with the following information: - - a. Include FQDN Option in the Neighbor Solicitation Message - - b. Destination Address is set to All Nodes Multicast Address - or uses Router Alert Option for 6DNAC, when 6DNAC Server is - implemented on router. - - c. Target Address is set to Unspecified Address - - d. Other fields are set as per DAD SLAAC [2462]. - - 7.4.3.2. Processing Neighbor Solicitation Messages - - This is same as described in $7.4.1.2$. - - - - - - -Park & Madanapalli Expires October 2003 [Page 26] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - - 7.4.3.3. Sending Neighbor Advertisement Messages - - This is same as described in $7.4.1.3$. - - 7.4.3.4. Processing Neighbor Advertisement Messages - - This is same as described in $7.4.1.4$. - - 7.4.3.5. Pros and Cons - - The advantage of this procedure is that it does not need the - existing duplicate address detection procedure. This is introduced - as the DAD procedure is found to be redundant in when IPv6 addresses - are constructed from the interface ID [DIID]. - - Note that, if 6DNAC Clients know the address of 6DNAC Server then - they can directly send DFQDND-NS to 6DNAC Server. - - 7.4.4. Retry Mode for Re-registering Domain Name - - In retry mode, nodes construct new FQDN as per Host Naming Algorithm. - Then they restart Duplicate FQDN Detection as described in $7.4.3$. - - - 7.5. Domain Name Registration - - 6DNAC Server must be an authenticated to update the DNS Server. - 6DNAC Server must also be configured with the DNS Server - information. - - 6DNAC Server detects the DNS information (IPv6 Address and - corresponding FQDN) from DAD/DFQDND messages and caches the - information. It also have an associated Registration Timer with - RegistrationWaitTime to wait for the successful completion of - DFQDND and update DNS Server using existing protocol DDNS UPDATE - [2136]. - - - 8. Security Consideration - - If someone wants to hijack correct Domain Name registration, they - could send a NS message with incorrect or same Domain Name to the - 6DNAC server repeatedly and server would start the Domain Name - registration through above mechanism, which is a security hole. - As described in [2461], a host can check validity of NDP messages. - If the NDP message include an IP Authentication Header, the message - authenticates correctly. For DNS UPDATE processing, secure DNS - Dynamic Update is described in [3007]. - - - - - - - - -Park & Madanapalli Expires October 2003 [Page 27] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - - 9. IANA Consideration - - Values in the Router Alert Option are registered and maintained by - IANA. For 6DNAC, the value has to be assigned by IANA. Also IANA is - required to assign the Type values for DNS Zone Suffix Information - option and FADN option. - - - 10. Acknowledgement - - Special thanks are due to Badrinarayana N.S. and Christian Huitema for - many helpful suggestions and revisions. - - - 11. Intellectual Property - - The following notice is copied from RFC 2026 [Bradner, 1996], - Section 10.4, and describes the position of the IETF concerning - intellectual property claims made against this document. - - The IETF takes no position regarding the validity or scope of any - intellectual property or other rights that might be claimed to - pertain to the implementation or use other technology described in - - this document or the extent to which any license under such rights - might or might not be available; neither does it represent that it - - has made any effort to identify any such rights. Information on the - IETF's procedures with respect to rights in standards-track and - standards-related documentation can be found in BCP-11. Copies of - claims of rights made available for publication and any assurances - of licenses to be made available, or the result of an attempt made - to obtain a general license or permission for the use of such - proprietary rights by implementers or users of this specification - can be obtained from the IETF Secretariat. - - The IETF invites any interested party to bring to its attention any - copyrights, patents or patent applications, or other proprietary - rights which may cover technology that may be required to practice - this standard. Please address the information to the IETF Executive - Director. - - - 12. Copyright - - The following copyright notice is copied from RFC 2026 [Bradner, - 1996], Section 10.4, and describes the applicable copyright for this - document. - - Copyright (C) The Internet Society July 12, 2001. All Rights - Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - -Park & Madanapalli Expires October 2003 [Page 28] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph - are included on all such copies and derivative works. However, this - - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assignees. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - 13. References - - [2373] Hinden, R. and S. Deering, "IP Version 6 Addressing - Architecture", RFC 2373, July 1998. - - [2460] Deering, S. abd R. Hinden, "Internet Protocol, - Version 6 (IPv6) Specification", RFC 2460, - December 1998. - - [2461] Narten, T., Nordmark, E. and W. Simpson, "Neighbor - Discovery for IP version 6(IPv6)", RFC 2461, December - 1998. - - [2462] S. Thomson and Narten T, "IPv6 Stateless Address Auto- - Configuration", RFC 2462, December 1998. - - [2711] C. Patridge and A.Jackson, "IPv6 Router Alert Option", - RFC 2711, October 1999. - - [1034] P. Mockapetris, "DOMAIN NAMES - CONCEPTS AND - FACILITIES", RFC 1034, November 1987. - - [1035] P. Mockapetris, "Domain Names - Implementation and - Specification" RFC 1035, November 1987. - - [2136] P. Vixie et al., "Dynamic Updates in the Domain Name - System (DNS UPDATE)", RFC2136, April 1997. - - [3007] B. Wellington, "Secure Domain Name System (DNS) Dynamic - Update", RFC 3007, November 2000. - - - -Park & Madanapalli Expires October 2003 [Page 29] - -INTERNET-DRAFT IPv6 Extensions for DNS Plug and Play April 2003 - - - [DIID] yokohama-dad-vs-diid.pdf - at http://playground.sun.com/ipng/presentations/July2002/ - - [DNSISSUES] Durand, A., "IPv6 DNS transition issues", draft-ietf- - dnsop-ipv6-dns-issues-00.txt, work in progress. - - [PREFIX] S. Miyakawa, R. Droms, "Requirements for IPv6 prefix - delegation", draft-ietf-ipv6-prefix-delegation- - requirement-01.txt, work in progress. - - [Autoreg] H. Kitamura, "Domain Name Auto-Registration for - Plugged-in IPv6 Nodes", draft-ietf-dnsext-ipv6-name- - auto-reg-00.txt, work in progress. - - [NIQ] Matt Crawford, "IPv6 Node Information Queries", , work in progress. - - - 14. Author's Addresses - - Soohong Daniel Park - Mobile Platform Laboratory, SAMSUNG Electronics, KOREA - Phone: +82-31-200-3728 - Email:soohong.park@samsung.com - - Syam Madanapalli - Network Systems Division, SAMSUNG India Software Operations, INDIA - Phone: +91-80-5550555 - Email:syam@samsung.com - - - - - - - - - - - - - - - - - - - - - - - - - - - -Park & Madanapalli Expires October 2003 [Page 30] diff --git a/contrib/bind9/doc/draft/update b/contrib/bind9/doc/draft/update deleted file mode 100644 index 6ac2090..0000000 --- a/contrib/bind9/doc/draft/update +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -commit= -for i -do - z=`expr "$i" : 'http://www.ietf.org/internet-drafts/\(.*\)'` - if test -n "$z" - then - i="$z" - fi - if test -f "$i" - then - continue - fi - pat=`echo "$i" | sed 's/...txt/??.txt/'` - old=`echo $pat 2> /dev/null` - if test "X$old" != "X$pat" - then - newer=0 - for j in $old - do - if test $j ">" $i - then - newer=1 - fi - done - if test $newer = 1 - then - continue; - fi - fi - if fetch "http://www.ietf.org/internet-drafts/$i" - then - cvs add "$i" - if test "X$old" != "X$pat" - then - rm $old - cvs delete $old - commit="$commit $old" - fi - commit="$commit $i" - fi -done -if test -n "$commit" -then - cvs commit -m "new draft" $commit -fi diff --git a/contrib/bind9/doc/misc/Makefile.in b/contrib/bind9/doc/misc/Makefile.in deleted file mode 100644 index 40a62fe..0000000 --- a/contrib/bind9/doc/misc/Makefile.in +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 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. - -# $Id: Makefile.in,v 1.3.18.3 2007/08/28 07:20:03 tbox Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -@BIND9_MAKE_RULES@ - -PERL = @PERL@ - -MANOBJS = options - -doc man:: ${MANOBJS} - -docclean manclean maintainer-clean:: - rm -f options - -# Do not make options depend on ../../bin/tests/cfg_test, doing so -# will cause excessively clever versions of make to attempt to build -# that program right here, right now, if it is missing, which will -# cause make doc to bomb. - -CFG_TEST = ../../bin/tests/cfg_test - -options: FORCE - if test -x ${CFG_TEST} && \ - ${CFG_TEST} --named --grammar | \ - ${PERL} ${srcdir}/format-options.pl >$@.new ; then \ - mv -f $@.new $@ ; \ - else \ - rm -f $@.new ; \ - fi diff --git a/contrib/bind9/doc/misc/dnssec b/contrib/bind9/doc/misc/dnssec deleted file mode 100644 index 4451e6c..0000000 --- a/contrib/bind9/doc/misc/dnssec +++ /dev/null @@ -1,84 +0,0 @@ -Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -Copyright (C) 2000-2002 Internet Software Consortium. -See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. - -DNSSEC Release Notes - -This document summarizes the state of the DNSSEC implementation in -this release of BIND9. - - -OpenSSL Library Required - -To support DNSSEC, BIND 9 must be linked with version 0.9.6e or newer of -the OpenSSL library. As of BIND 9.2, the library is no longer -included in the distribution - it must be provided by the operating -system or installed separately. - -To build BIND 9 with OpenSSL, use "configure --with-openssl". If -the OpenSSL library is installed in a nonstandard location, you can -specify a path as in "configure --with-openssl=/var". - - -Key Generation and Signing - -The tools for generating DNSSEC keys and signatures are now in the -bin/dnssec directory. Documentation for these programs can be found -in doc/arm/Bv9ARM.4.html and the man pages. - -The random data used in generating DNSSEC keys and signatures comes -from either /dev/random (if the OS supports it) or keyboard input. -Alternatively, a device or file containing entropy/random data can be -specified. - - -Serving Secure Zones - -When acting as an authoritative name server, BIND9 includes KEY, SIG -and NXT records in responses as specified in RFC2535 when the request -has the DO flag set in the query. - - -Secure Resolution - -Basic support for validation of DNSSEC signatures in responses has -been implemented but should still be considered experimental. - -When acting as a caching name server, BIND9 is capable of performing -basic DNSSEC validation of positive as well as nonexistence responses. -This functionality is enabled by including a "trusted-keys" clause -in the configuration file, containing the top-level zone key of the -the DNSSEC tree. - -Validation of wildcard responses is not currently supported. In -particular, a "name does not exist" response will validate -successfully even if it does not contain the NXT records to prove the -nonexistence of a matching wildcard. - -Proof of insecure status for insecure zones delegated from secure -zones works when the zones are completely insecure. Privately -secured zones delegated from secure zones will not work in all cases, -such as when the privately secured zone is served by the same server -as an ancestor (but not parent) zone. - -Handling of the CD bit in queries is now fully implemented. Validation -is not attempted for recursive queries if CD is set. - - -Secure Dynamic Update - -Dynamic update of secure zones has been implemented, but may not be -complete. Affected NXT and SIG records are updated by the server when -an update occurs. Advanced access control is possible using the -"update-policy" statement in the zone definition. - - -Secure Zone Transfers - -BIND 9 does not implement the zone transfer security mechanisms of -RFC2535 section 5.6, and we have no plans to implement them in the -future as we consider them inferior to the use of TSIG or SIG(0) to -ensure the integrity of zone transfers. - - -$Id: dnssec,v 1.19 2004/03/05 05:04:53 marka Exp $ diff --git a/contrib/bind9/doc/misc/format-options.pl b/contrib/bind9/doc/misc/format-options.pl deleted file mode 100644 index 70b334e..0000000 --- a/contrib/bind9/doc/misc/format-options.pl +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/perl -# -# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 2001 Internet Software Consortium. -# -# Permission to use, copy, modify, and 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: format-options.pl,v 1.2 2004/03/05 05:04:53 marka Exp $ - -print <) { - s/\t/ /g; - if (length >= 79) { - m!^( *)!; - my $indent = $1; - s!^(.{0,75}) (.*)$!\1\n$indent \2!; - } - print; -} diff --git a/contrib/bind9/doc/misc/ipv6 b/contrib/bind9/doc/misc/ipv6 deleted file mode 100644 index aeba275..0000000 --- a/contrib/bind9/doc/misc/ipv6 +++ /dev/null @@ -1,113 +0,0 @@ -Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -Copyright (C) 2000, 2001 Internet Software Consortium. -See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. - -Currently, there are multiple interesting problems with ipv6 -implementations on various platforms. These problems range from not -being able to use ipv6 with bind9 (or in particular the ISC socket -library, contained in libisc) to listen-on lists not being respected, -to strange warnings but seemingly correct behavior of named. - -COMPILE-TIME ISSUES -------------------- - -The socket library requires a certain level of support from the -operating system. In particular, it must follow the advanced ipv6 -socket API to be usable. The systems which do not follow this will -currently not get any warnings or errors, but ipv6 will simply not -function on them. - -These systems currently include, but are not limited to: - - AIX 3.4 (with ipv6 patches) - - -RUN-TIME ISSUES ---------------- - -In the original drafts of the ipv6 RFC documents, binding an ipv6 -socket to the ipv6 wildcard address would also cause the socket to -accept ipv4 connections and datagrams. When an ipv4 packet is -received on these systems, it is mapped into an ipv6 address. For -example, 1.2.3.4 would be mapped into ::ffff:1.2.3.4. The intent of -this mapping was to make transition from an ipv4-only application into -ipv6 easier, by only requiring one socket to be open on a given port. - -Later, it was discovered that this was generally a bad idea. For one, -many firewalls will block connection to 1.2.3.4, but will let through -::ffff:1.2.3.4. This, of course, is bad. Also, access control lists -written to accept only ipv4 addresses were suddenly ignored unless -they were rewritten to handle the ipv6 mapped addresses as well. - -Partly because of these problems, the latest IPv6 API introduces an -explicit knob (the "IPV6_V6ONLY" socket option ) to turn off the ipv6 -mapped address usage. - -In bind9, we first check if both the advanced API and the IPV6_V6ONLY -socket option are available. If both of them are available, bind9 -named will bind to the ipv6 wildcard port for both TCP and UDP. -Otherwise named will make a warning and try to bind to all available -ipv6 addresses separately. - -In any case, bind9 named binds to specific addresses for ipv4 sockets. - -The followings are historical notes when we always bound to the ipv6 -wildcard port regardless of the availability of the API support. -These problems should not happen with the closer checks above. - - -IPV6 Sockets Accept IPV4, Specific IPV4 Addresses Bindings Fail ---------------------------------------------------------------- - -The only OS which seems to do this is (some kernel versions of) linux. -If an ipv6 socket is bound to the ipv6 wildcard socket, and a specific -ipv4 socket is later bound (say, to 1.2.3.4 port 53) the ipv4 binding -will fail. - -What this means to bind9 is that the application will log warnings -about being unable to bind to a socket because the address is already -in use. Since the ipv6 socket will accept ipv4 packets and map them, -however, the ipv4 addresses continue to function. - -The effect is that the config file listen-on directive will not be -respected on these systems. - - -IPV6 Sockets Accept IPV4, Specific IPV4 Address Bindings Succeed ----------------------------------------------------------------- - -In this case, the system allows opening an ipv6 wildcard address -socket and then binding to a more specific ipv4 address later. An -example of this type of system is Digital Unix with ipv6 patches -applied. - -What this means to bind9 is that the application will respect -listen-on in regards to ipv4 sockets, but it will use mapped ipv6 -addresses for any that do not match the listen-on list. This, in -effect, makes listen-on useless for these machines as well. - - -IPV6 Sockets Do Not Accept IPV4 -------------------------------- - -On these systems, opening an IPV6 socket does not implicitly open any -ipv4 sockets. An example of these systems are NetBSD-current with the -latest KAME patch, and other systems which use the latest KAME patches -as their ipv6 implementation. - -On these systems, listen-on is fully functional, as the ipv6 socket -only accepts ipv6 packets, and the ipv4 sockets will handle the ipv4 -packets. - - -RELEVANT RFCs -------------- - -3513: Internet Protocol Version 6 (IPv6) Addressing Architecture - -3493: Basic Socket Interface Extensions for IPv6 - -3542: Advanced Sockets Application Program Interface (API) for IPv6 - - -$Id: ipv6,v 1.6.18.3 2004/08/10 04:28:41 jinmei Exp $ diff --git a/contrib/bind9/doc/misc/migration b/contrib/bind9/doc/misc/migration deleted file mode 100644 index b48371b..0000000 --- a/contrib/bind9/doc/misc/migration +++ /dev/null @@ -1,257 +0,0 @@ -Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") -Copyright (C) 2000, 2001, 2003 Internet Software Consortium. -See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. - - BIND 8 to BIND 9 Migration Notes - -BIND 9 is designed to be mostly upwards compatible with BIND 8, but -there is still a number of caveats you should be aware of when -upgrading an existing BIND 8 installation to use BIND 9. - - -1. Configuration File Compatibility - -1.1. Unimplemented Options and Changed Defaults - -BIND 9 supports most, but not all of the named.conf options of BIND 8. -For a complete list of implemented options, see doc/misc/options. - -If your named.conf file uses an unimplemented option, named will log a -warning message. A message is also logged about each option whose -default has changed unless the option is set explicitly in named.conf. - -The default of the "transfer-format" option has changed from -"one-answer" to "many-answers". If you have slave servers that do not -understand the many-answers zone transfer format (e.g., BIND 4.9.5 or -older) you need to explicitly specify "transfer-format one-answer;" in -either the options block or a server statement. - -1.2. Handling of Configuration File Errors - -In BIND 9, named refuses to start if it detects an error in -named.conf. Earlier versions would start despite errors, causing the -server to run with a partial configuration. Errors detected during -subsequent reloads do not cause the server to exit. - -Errors in master files do not cause the server to exit, but they -do cause the zone not to load. - -1.3. Logging - -The set of logging categories in BIND 9 is different from that -in BIND 8. If you have customised your logging on a per-category -basis, you need to modify your logging statement to use the -new categories. - -Another difference is that the "logging" statement only takes effect -after the entire named.conf file has been read. This means that when -the server starts up, any messages about errors in the configuration -file are always logged to the default destination (syslog) when the -server first starts up, regardless of the contents of the "logging" -statement. In BIND 8, the new logging configuration took effect -immediately after the "logging" statement was read. - -1.4. Notify messages and Refresh queries - -The source address and port for these is now controlled by -"notify-source" and "transfer-source", respectively, rather that -query-source as in BIND 8. - -1.5. Multiple Classes. - -Multiple classes have to be put into explicit views for each class. - - -2. Zone File Compatibility - -2.1. Strict RFC1035 Interpretation of TTLs in Zone Files - -BIND 9 strictly complies with the RFC1035 and RFC2308 rules regarding -omitted TTLs in zone files. Omitted TTLs are replaced by the value -specified with the $TTL directive, or by the previous explicit TTL if -there is no $TTL directive. - -If there is no $TTL directive and the first RR in the file does not -have an explicit TTL field, the zone file is illegal according to -RFC1035 since the TTL of the first RR is undefined. Unfortunately, -BIND 4 and many versions of BIND 8 accept such files without warning -and use the value of the SOA MINTTL field as a default for missing TTL -values. - -BIND 9.0 and 9.1 completely refused to load such files. BIND 9.2 -emulates the nonstandard BIND 4/8 SOA MINTTL behaviour and loads the -files anyway (provided the SOA is the first record in the file), but -will issue the warning message "no TTL specified; using SOA MINTTL -instead". - -To avoid problems, we recommend that you use a $TTL directive in each -zone file. - -2.2. Periods in SOA Serial Numbers Deprecated - -Some versions of BIND allow SOA serial numbers with an embedded -period, like "3.002", and convert them into integers in a rather -unintuitive way. This feature is not supported by BIND 9; serial -numbers must be integers. - -2.3. Handling of Unbalanced Quotes - -TXT records with unbalanced quotes, like 'host TXT "foo', were not -treated as errors in some versions of BIND. If your zone files -contain such records, you will get potentially confusing error -messages like "unexpected end of file" because BIND 9 will interpret -everything up to the next quote character as a literal string. - -2.4. Handling of Line Breaks - -Some versions of BIND accept RRs containing line breaks that are not -properly quoted with parentheses, like the following SOA: - - @ IN SOA ns.example. hostmaster.example. - ( 1 3600 1800 1814400 3600 ) - -This is not legal master file syntax and will be treated as an error -by BIND 9. The fix is to move the opening parenthesis to the first -line. - -2.5. Unimplemented BIND 8 Extensions - -$GENERATE: The "$$" construct for getting a literal $ into a domain -name is deprecated. Use \$ instead. - -2.6. TXT records are no longer automatically split. - -Some versions of BIND accepted strings in TXT RDATA consisting of more -than 255 characters and silently split them to be able to encode the -strings in a protocol conformant way. You may now see errors like this - dns_rdata_fromtext: local.db:119: ran out of space -if you have TXT RRs with too longs strings. Make sure to split the -string in the zone data file at or before a single one reaches 255 -characters. - -3. Interoperability Impact of New Protocol Features - -3.1. EDNS0 - -BIND 9 uses EDNS0 (RFC2671) to advertise its receive buffer size. It -also sets DO EDNS flag bit in queries to indicate that it wishes to -receive DNSSEC responses. - -Most older servers that do not support EDNS0, including prior versions -of BIND, will send a FORMERR or NOTIMP response to these queries. -When this happens, BIND 9 will automatically retry the query without -EDNS0. - -Unfortunately, there exists at least one non-BIND name server -implementation that silently ignores these queries instead of sending -an error response. Resolving names in zones where all or most -authoritative servers use this server will be very slow or fail -completely. We have contacted the manufacturer of the name server in -case, and they are working on a solution. - -When BIND 9 communicates with a server that does support EDNS0, such as -another BIND 9 server, responses of up to 4096 bytes may be -transmitted as a single UDP datagram which is subject to fragmentation -at the IP level. If a firewall incorrectly drops IP fragments, it can -cause resolution to slow down dramatically or fail. - -3.2. Zone Transfers - -Outgoing zone transfers now use the "many-answers" format by default. -This format is not understood by certain old versions of BIND 4. -You can work around this problem using the option "transfer-format -one-answer;", but since these old versions all have known security -problems, the correct fix is to upgrade the slave servers. - -Zone transfers to Windows 2000 DNS servers sometimes fail due to a -bug in the Windows 2000 DNS server where DNS messages larger than -16K are not handled properly. Obtain the latest service pack for -Windows 2000 from Microsoft to address this issue. In the meantime, -the problem can be worked around by setting "transfer-format one-answer;". -http://support.microsoft.com/default.aspx?scid=kb;en-us;297936 - -4. Unrestricted Character Set - - BIND 9.2 only - -BIND 9 does not restrict the character set of domain names - it is -fully 8-bit clean in accordance with RFC2181 section 11. - -It is strongly recommended that hostnames published in the DNS follow -the RFC952 rules, but BIND 9 will not enforce this restriction. - -Historically, some applications have suffered from security flaws -where data originating from the network, such as names returned by -gethostbyaddr(), are used with insufficient checking and may cause a -breach of security when containing unexpected characters; see - -for details. Some earlier versions of BIND attempt to protect these -flawed applications from attack by discarding data containing -characters deemed inappropriate in host names or mail addresses, under -the control of the "check-names" option in named.conf and/or "options -no-check-names" in resolv.conf. BIND 9 provides no such protection; -if applications with these flaws are still being used, they should -be upgraded. - - BIND 9.3 onwards implements check-names. - -5. Server Administration Tools - -5.1 Ndc Replaced by Rndc - -The "ndc" program has been replaced by "rndc", which is capable of -remote operation. Unlike ndc, rndc requires a configuration file. -The easiest way to generate a configuration file is to run -"rndc-confgen -a"; see the man pages for rndc(8), rndc-confgen(8), -and rndc.conf(5) for details. - -5.2. Nsupdate Differences - -The BIND 8 implementation of nsupdate had an undocumented feature -where an update request would be broken down into multiple requests -based upon the discovered zones that contained the records. This -behaviour has not been implemented in BIND 9. Each update request -must pertain to a single zone, but it is still possible to do multiple -updates in a single invocation of nsupdate by terminating each update -with an empty line or a "send" command. - - -6. No Information Leakage between Zones - -BIND 9 stores the authoritative data for each zone in a separate data -structure, as recommended in RFC1035 and as required by DNSSEC and -IXFR. When a BIND 9 server is authoritative for both a child zone and -its parent, it will have two distinct sets of NS records at the -delegation point: the authoritative NS records at the child's apex, -and a set of glue NS records in the parent. - -BIND 8 was unable to properly distinguish between these two sets of NS -records and would "leak" the child's NS records into the parent, -effectively causing the parent zone to be silently modified: responses -and zone transfers from the parent contained the child's NS records -rather than the glue configured into the parent (if any). In the case -of children of type "stub", this behaviour was documented as a feature, -allowing the glue NS records to be omitted from the parent -configuration. - -Sites that were relying on this BIND 8 behaviour need to add any -omitted glue NS records, and any necessary glue A records, to the -parent zone. - -Although stub zones can no longer be used as a mechanism for injecting -NS records into their parent zones, they are still useful as a way of -directing queries for a given domain to a particular set of name -servers. - - -7. Umask not Modified - -The BIND 8 named unconditionally sets the umask to 022. BIND 9 does -not; the umask inherited from the parent process remains in effect. -This may cause files created by named, such as journal files, to be -created with different file permissions than they did in BIND 8. If -necessary, the umask should be set explicitly in the script used to -start the named process. - - -$Id: migration,v 1.45.18.2 2007/09/07 06:34:21 marka Exp $ diff --git a/contrib/bind9/doc/misc/migration-4to9 b/contrib/bind9/doc/misc/migration-4to9 deleted file mode 100644 index 008cbed..0000000 --- a/contrib/bind9/doc/misc/migration-4to9 +++ /dev/null @@ -1,57 +0,0 @@ -Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -Copyright (C) 2001 Internet Software Consortium. -See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. - -$Id: migration-4to9,v 1.4 2004/03/05 05:04:53 marka Exp $ - - BIND 4 to BIND 9 Migration Notes - -To transition from BIND 4 to BIND 9 you first need to convert your -configuration file to the new format. There is a conversion tool in -contrib/named-bootconf that allows you to do this. - - named-bootconf.sh < /etc/named.boot > /etc/named.conf - -BIND 9 uses a system assigned port for the UDP queries it makes rather -than port 53 that BIND 4 uses. This may conflict with some firewalls. -The following directives in /etc/named.conf allows you to specify -a port to use. - - query-source address * port 53; - transfer-source * port 53; - notify-source * port 53; - -BIND 9 no longer uses the minimum field to specify the TTL of records -without a explicit TTL. Use the $TTL directive to specify a default TTL -before the first record without a explicit TTL. - - $TTL 3600 - @ IN SOA ns1.example.com. hostmaster.example.com. ( - 2001021100 - 7200 - 1200 - 3600000 - 7200 ) - -BIND 9 does not support multiple CNAMEs with the same owner name. - - Illegal: - www.example.com. CNAME host1.example.com. - www.example.com. CNAME host2.example.com. - -BIND 9 does not support "CNAMEs with other data" with the same owner name, -ignoring the DNSSEC records (SIG, NXT, KEY) that BIND 4 did not support. - - Illegal: - www.example.com. CNAME host1.example.com. - www.example.com. MX 10 host2.example.com. - -BIND 9 is less tolerant of errors in master files, so check your logs and -fix any errors reported. The named-checkzone program can also be to check -master files. - -Outgoing zone transfers now use the "many-answers" format by default. -This format is not understood by certain old versions of BIND 4. -You can work around this problem using the option "transfer-format -one-answer;", but since these old versions all have known security -problems, the correct fix is to upgrade the slave servers. diff --git a/contrib/bind9/doc/misc/options b/contrib/bind9/doc/misc/options deleted file mode 100644 index a17c522..0000000 --- a/contrib/bind9/doc/misc/options +++ /dev/null @@ -1,481 +0,0 @@ - -This is a summary of the named.conf options supported by -this version of BIND 9. - -options { - avoid-v4-udp-ports { ; ... }; - avoid-v6-udp-ports { ; ... }; - blackhole { ; ... }; - coresize ; - datasize ; - deallocate-on-exit ; // obsolete - directory ; - dump-file ; - fake-iquery ; // obsolete - files ; - has-old-clients ; // obsolete - heartbeat-interval ; - host-statistics ; // not implemented - host-statistics-max ; // not implemented - hostname ( | none ); - interface-interval ; - listen-on [ port ] { ; ... }; - listen-on-v6 [ port ] { ; ... }; - match-mapped-addresses ; - memstatistics-file ; - multiple-cnames ; // obsolete - named-xfer ; // obsolete - pid-file ( | none ); - port ; - querylog ; - recursing-file ; - random-device ; - recursive-clients ; - serial-queries ; // obsolete - serial-query-rate ; - server-id ( | none |; - stacksize ; - statistics-file ; - statistics-interval ; // not yet implemented - tcp-clients ; - tcp-listen-queue ; - tkey-dhkey ; - tkey-gssapi-credential ; - tkey-domain ; - transfers-per-ns ; - transfers-in ; - transfers-out ; - treat-cr-as-space ; // obsolete - use-id-pool ; // obsolete - use-ixfr ; - version ( | none ); - flush-zones-on-shutdown ; - allow-query-cache { ; ... }; - allow-recursion { ; ... }; - allow-v6-synthesis { ; ... }; // obsolete - sortlist { ; ... }; - topology { ; ... }; // not implemented - auth-nxdomain ; // default changed - minimal-responses ; - recursion ; - rrset-order { [ class ] [ type ] [ name - ] ; ... }; - provide-ixfr ; - request-ixfr ; - fetch-glue ; // obsolete - rfc2308-type1 ; // not yet implemented - additional-from-auth ; - additional-from-cache ; - query-source ; - query-source-v6 ; - cleaning-interval ; - min-roots ; // not implemented - lame-ttl ; - max-ncache-ttl ; - max-cache-ttl ; - transfer-format ( many-answers | one-answer ); - max-cache-size ; - check-names ( master | slave | response ) ( fail | warn | ignore ); - cache-file ; - suppress-initial-notify ; // not yet implemented - preferred-glue ; - dual-stack-servers [ port ] { ( [port - ] | [port ] | [port ] ); ... }; - edns-udp-size ; - max-udp-size ; - root-delegation-only [ exclude { ; ... } ]; - disable-algorithms { ; ... }; - dnssec-enable ; - dnssec-validation ; - dnssec-lookaside trust-anchor ; - dnssec-must-be-secure ; - dnssec-accept-expired ; - ixfr-from-differences ; - acache-enable ; - acache-cleaning-interval ; - max-acache-size ; - clients-per-query ; - max-clients-per-query ; - empty-server ; - empty-contact ; - empty-zones-enable ; - disable-empty-zone ; - zero-no-soa-ttl-cache ; - allow-query { ; ... }; - allow-transfer { ; ... }; - allow-update { ; ... }; - allow-update-forwarding { ; ... }; - allow-notify { ; ... }; - masterfile-format ( text | raw ); - notify ; - notify-source ( | * ) [ port ( | * ) ]; - notify-source-v6 ( | * ) [ port ( | * ) ]; - also-notify [ port ] { ( | - ) [ port ]; ... }; - notify-delay ; - dialup ; - forward ( first | only ); - forwarders [ port ] { ( | ) - [ port ]; ... }; - maintain-ixfr-base ; // obsolete - max-ixfr-log-size ; // obsolete - max-journal-size ; - max-transfer-time-in ; - max-transfer-time-out ; - max-transfer-idle-in ; - max-transfer-idle-out ; - max-retry-time ; - min-retry-time ; - max-refresh-time ; - min-refresh-time ; - multi-master ; - sig-validity-interval ; - transfer-source ( | * ) [ port ( | * ) ]; - transfer-source-v6 ( | * ) [ port ( | * ) ]; - alt-transfer-source ( | * ) [ port ( | * ) - ]; - alt-transfer-source-v6 ( | * ) [ port ( | - * ) ]; - use-alt-transfer-source ; - zone-statistics ; - key-directory ; - check-wildcard ; - check-integrity ; - check-mx ( fail | warn | ignore ); - check-mx-cname ( fail | warn | ignore ); - check-srv-cname ( fail | warn | ignore ); - check-sibling ; - zero-no-soa-ttl ; - update-check-ksk ; -}; - -controls { - inet ( | | * ) [ port ( | * - ) ] allow { ; ... } [ keys { ; ... } ]; - unix perm owner group - [ keys { ; ... } ]; -}; - -acl { ; ... }; - -masters [ port ] { ( | [port - ] | [port ] ) [ key ]; ... }; - -logging { - channel { - file ; - syslog ; - null; - stderr; - severity ; - print-time ; - print-severity ; - print-category ; - }; - category { ; ... }; -}; - -view { - match-clients { ; ... }; - match-destinations { ; ... }; - match-recursive-only ; - key { - algorithm ; - secret ; - }; - zone { - type ( master | slave | stub | hint | forward | - delegation-only ); - file ; - journal ; - ixfr-base ; // obsolete - ixfr-tmp-file ; // obsolete - masters [ port ] { ( | - [port ] | [port ] ) [ key ]; ... }; - pubkey ; // - obsolete - update-policy { ( grant | deny ) ( name | - subdomain | wildcard | self | selfsub | selfwild ) ; ... }; - database ; - delegation-only ; - check-names ( fail | warn | ignore ); - ixfr-from-differences ; - allow-query { ; ... }; - allow-transfer { ; ... }; - allow-update { ; ... }; - allow-update-forwarding { ; ... }; - allow-notify { ; ... }; - masterfile-format ( text | raw ); - notify ; - notify-source ( | * ) [ port ( | * - ) ]; - notify-source-v6 ( | * ) [ port ( - | * ) ]; - also-notify [ port ] { ( | - ) [ port ]; ... }; - notify-delay ; - dialup ; - forward ( first | only ); - forwarders [ port ] { ( | - ) [ port ]; ... }; - maintain-ixfr-base ; // obsolete - max-ixfr-log-size ; // obsolete - max-journal-size ; - max-transfer-time-in ; - max-transfer-time-out ; - max-transfer-idle-in ; - max-transfer-idle-out ; - max-retry-time ; - min-retry-time ; - max-refresh-time ; - min-refresh-time ; - multi-master ; - sig-validity-interval ; - transfer-source ( | * ) [ port ( | - * ) ]; - transfer-source-v6 ( | * ) [ port ( - | * ) ]; - alt-transfer-source ( | * ) [ port ( - | * ) ]; - alt-transfer-source-v6 ( | * ) [ port ( - | * ) ]; - use-alt-transfer-source ; - zone-statistics ; - key-directory ; - check-wildcard ; - check-integrity ; - check-mx ( fail | warn | ignore ); - check-mx-cname ( fail | warn | ignore ); - check-srv-cname ( fail | warn | ignore ); - check-sibling ; - zero-no-soa-ttl ; - update-check-ksk ; - }; - dlz { - database ; - }; - server { - bogus ; - provide-ixfr ; - request-ixfr ; - support-ixfr ; // obsolete - transfers ; - transfer-format ( many-answers | one-answer ); - keys ; - edns ; - edns-udp-size ; - max-udp-size ; - notify-source ( | * ) [ port ( | * - ) ]; - notify-source-v6 ( | * ) [ port ( - | * ) ]; - query-source ; - query-source-v6 ; - transfer-source ( | * ) [ port ( | - * ) ]; - transfer-source-v6 ( | * ) [ port ( - | * ) ]; - }; - trusted-keys { - ; ... }; - allow-query-cache { ; ... }; - allow-recursion { ; ... }; - allow-v6-synthesis { ; ... }; // obsolete - sortlist { ; ... }; - topology { ; ... }; // not implemented - auth-nxdomain ; // default changed - minimal-responses ; - recursion ; - rrset-order { [ class ] [ type ] [ name - ] ; ... }; - provide-ixfr ; - request-ixfr ; - fetch-glue ; // obsolete - rfc2308-type1 ; // not yet implemented - additional-from-auth ; - additional-from-cache ; - query-source ; - query-source-v6 ; - cleaning-interval ; - min-roots ; // not implemented - lame-ttl ; - max-ncache-ttl ; - max-cache-ttl ; - transfer-format ( many-answers | one-answer ); - max-cache-size ; - check-names ( master | slave | response ) ( fail | warn | ignore ); - cache-file ; - suppress-initial-notify ; // not yet implemented - preferred-glue ; - dual-stack-servers [ port ] { ( [port - ] | [port ] | [port ] ); ... }; - edns-udp-size ; - max-udp-size ; - root-delegation-only [ exclude { ; ... } ]; - disable-algorithms { ; ... }; - dnssec-enable ; - dnssec-validation ; - dnssec-lookaside trust-anchor ; - dnssec-must-be-secure ; - dnssec-accept-expired ; - ixfr-from-differences ; - acache-enable ; - acache-cleaning-interval ; - max-acache-size ; - clients-per-query ; - max-clients-per-query ; - empty-server ; - empty-contact ; - empty-zones-enable ; - disable-empty-zone ; - zero-no-soa-ttl-cache ; - allow-query { ; ... }; - allow-transfer { ; ... }; - allow-update { ; ... }; - allow-update-forwarding { ; ... }; - allow-notify { ; ... }; - masterfile-format ( text | raw ); - notify ; - notify-source ( | * ) [ port ( | * ) ]; - notify-source-v6 ( | * ) [ port ( | * ) ]; - also-notify [ port ] { ( | - ) [ port ]; ... }; - notify-delay ; - dialup ; - forward ( first | only ); - forwarders [ port ] { ( | ) - [ port ]; ... }; - maintain-ixfr-base ; // obsolete - max-ixfr-log-size ; // obsolete - max-journal-size ; - max-transfer-time-in ; - max-transfer-time-out ; - max-transfer-idle-in ; - max-transfer-idle-out ; - max-retry-time ; - min-retry-time ; - max-refresh-time ; - min-refresh-time ; - multi-master ; - sig-validity-interval ; - transfer-source ( | * ) [ port ( | * ) ]; - transfer-source-v6 ( | * ) [ port ( | * ) ]; - alt-transfer-source ( | * ) [ port ( | * ) - ]; - alt-transfer-source-v6 ( | * ) [ port ( | - * ) ]; - use-alt-transfer-source ; - zone-statistics ; - key-directory ; - check-wildcard ; - check-integrity ; - check-mx ( fail | warn | ignore ); - check-mx-cname ( fail | warn | ignore ); - check-srv-cname ( fail | warn | ignore ); - check-sibling ; - zero-no-soa-ttl ; - update-check-ksk ; - database ; -}; - -lwres { - listen-on [ port ] { ( | ) - [ port ]; ... }; - view ; - search { ; ... }; - ndots ; -}; - -key { - algorithm ; - secret ; -}; - -zone { - type ( master | slave | stub | hint | forward | delegation-only ); - file ; - journal ; - ixfr-base ; // obsolete - ixfr-tmp-file ; // obsolete - masters [ port ] { ( | [port - ] | [port ] ) [ key ]; ... }; - pubkey ; // obsolete - update-policy { ( grant | deny ) ( name | subdomain | - wildcard | self | selfsub | selfwild ) ; ... }; - database ; - delegation-only ; - check-names ( fail | warn | ignore ); - ixfr-from-differences ; - allow-query { ; ... }; - allow-transfer { ; ... }; - allow-update { ; ... }; - allow-update-forwarding { ; ... }; - allow-notify { ; ... }; - masterfile-format ( text | raw ); - notify ; - notify-source ( | * ) [ port ( | * ) ]; - notify-source-v6 ( | * ) [ port ( | * ) ]; - also-notify [ port ] { ( | - ) [ port ]; ... }; - notify-delay ; - dialup ; - forward ( first | only ); - forwarders [ port ] { ( | ) - [ port ]; ... }; - maintain-ixfr-base ; // obsolete - max-ixfr-log-size ; // obsolete - max-journal-size ; - max-transfer-time-in ; - max-transfer-time-out ; - max-transfer-idle-in ; - max-transfer-idle-out ; - max-retry-time ; - min-retry-time ; - max-refresh-time ; - min-refresh-time ; - multi-master ; - sig-validity-interval ; - transfer-source ( | * ) [ port ( | * ) ]; - transfer-source-v6 ( | * ) [ port ( | * ) ]; - alt-transfer-source ( | * ) [ port ( | * ) - ]; - alt-transfer-source-v6 ( | * ) [ port ( | - * ) ]; - use-alt-transfer-source ; - zone-statistics ; - key-directory ; - check-wildcard ; - check-integrity ; - check-mx ( fail | warn | ignore ); - check-mx-cname ( fail | warn | ignore ); - check-srv-cname ( fail | warn | ignore ); - check-sibling ; - zero-no-soa-ttl ; - update-check-ksk ; -}; - -dlz { - database ; -}; - -server { - bogus ; - provide-ixfr ; - request-ixfr ; - support-ixfr ; // obsolete - transfers ; - transfer-format ( many-answers | one-answer ); - keys ; - edns ; - edns-udp-size ; - max-udp-size ; - notify-source ( | * ) [ port ( | * ) ]; - notify-source-v6 ( | * ) [ port ( | * ) ]; - query-source ; - query-source-v6 ; - transfer-source ( | * ) [ port ( | * ) ]; - transfer-source-v6 ( | * ) [ port ( | * ) ]; -}; - -trusted-keys { ; ... }; - diff --git a/contrib/bind9/doc/misc/rfc-compliance b/contrib/bind9/doc/misc/rfc-compliance deleted file mode 100644 index 4c87c66..0000000 --- a/contrib/bind9/doc/misc/rfc-compliance +++ /dev/null @@ -1,62 +0,0 @@ -Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -Copyright (C) 2001 Internet Software Consortium. -See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. - -$Id: rfc-compliance,v 1.4 2004/03/05 05:04:53 marka Exp $ - -BIND 9 is striving for strict compliance with IETF standards. We -believe this release of BIND 9 complies with the following RFCs, with -the caveats and exceptions listed in the numbered notes below. Note -that a number of these RFCs do not have the status of Internet -standards but are proposed or draft standards, experimental RFCs, -or Best Current Practice (BCP) documents. - - RFC1034 - RFC1035 [1] [2] - RFC1123 - RFC1183 - RFC1535 - RFC1536 - RFC1706 - RFC1712 - RFC1750 - RFC1876 - RFC1982 - RFC1995 - RFC1996 - RFC2136 - RFC2163 - RFC2181 - RFC2230 - RFC2308 - RFC2535 [3] [4] - RFC2536 - RFC2537 - RFC2538 - RFC2539 - RFC2671 - RFC2672 - RFC2673 - RFC2782 - RFC2915 - RFC2930 - RFC2931 [5] - RFC3007 - - -[1] Queries to zones that have failed to load return SERVFAIL rather -than a non-authoritative response. This is considered a feature. - -[2] CLASS ANY queries are not supported. This is considered a feature. - -[3] Wildcard records are not supported in DNSSEC secure zones. - -[4] Servers authoritative for secure zones being resolved by BIND 9 -must support EDNS0 (RFC2671), and must return all relevant SIGs and -NXTs in responses rather than relying on the resolving server to -perform separate queries for missing SIGs and NXTs. - -[5] When receiving a query signed with a SIG(0), the server will only -be able to verify the signature if it has the key in its local -authoritative data; it will not do recursion or validation to -retrieve unknown keys. diff --git a/contrib/bind9/doc/misc/roadmap b/contrib/bind9/doc/misc/roadmap deleted file mode 100644 index f63a469..0000000 --- a/contrib/bind9/doc/misc/roadmap +++ /dev/null @@ -1,47 +0,0 @@ -Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -Copyright (C) 2000, 2001 Internet Software Consortium. -See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. - -$Id: roadmap,v 1.2 2004/03/05 05:04:54 marka Exp $ - -Road Map to the BIND 9 Source Tree - -bin/named The name server. This relies heavily on the - libraries in lib/isc and lib/dns. - client.c Handling of incoming client requests - query.c Query processing -bin/rndc The remote name daemon control program -bin/dig The "dig" program -bin/dnssec The DNSSEC signer and other DNSSEC tools -bin/nsupdate The "nsupdate" program -bin/tests Test suites and miscellaneous test programs -bin/tests/system System tests; see bin/tests/system/README -lib/dns The DNS library - resolver.c The "full resolver" (performs recursive lookups) - validator.c The DNSSEC validator - db.c The database interface - sdb.c The simple database interface - rbtdb.c The red-black tree database -lib/dns/rdata Routines for handling the various RR types -lib/dns/sec Cryptographic libraries for DNSSEC -lib/isc The ISC library - task.c Task library - unix/socket.c Unix implementation of socket library -lib/isccfg Routines for reading and writing ISC-style - configuration files like named.conf and rndc.conf -lib/isccc The command channel library, used by rndc. -lib/tests Support code for the test suites. -lib/lwres The lightweight resolver library. -doc/draft Current internet-drafts pertaining to the DNS -doc/rfc RFCs pertaining to the DNS -doc/misc Miscellaneous documentation -doc/arm The BIND 9 Administrator Reference Manual -doc/man Man pages -contrib Contributed and other auxiliary code -contrib/idn/mdnkit The multilingual domain name evaluation kit -contrib/sdb Sample drivers for the simple database interface -make Makefile fragments, used by configure - -The library interfaces are mainly documented in the form of comments -in the header files. For example, the task subsystem is documented in -lib/isc/include/isc/task.h diff --git a/contrib/bind9/doc/misc/sdb b/contrib/bind9/doc/misc/sdb deleted file mode 100644 index 552028a..0000000 --- a/contrib/bind9/doc/misc/sdb +++ /dev/null @@ -1,169 +0,0 @@ -Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -Copyright (C) 2000, 2001 Internet Software Consortium. -See COPYRIGHT in the source root or http://isc.org/copyright.html for terms. - -Using the BIND 9 Simplified Database Interface - -This document describes the care and feeding of the BIND 9 Simplified -Database Interface, which allows you to extend BIND 9 with new ways -of obtaining the data that is published as DNS zones. - - -The Original BIND 9 Database Interface - -BIND 9 has a well-defined "back-end database interface" that makes it -possible to replace the component of the name server responsible for -the storage and retrieval of zone data, called the "database", on a -per-zone basis. The default database is an in-memory, red-black-tree -data structure commonly referred to as "rbtdb", but it is possible to -write drivers to support any number of alternative database -technologies such as in-memory hash tables, application specific -persistent on-disk databases, object databases, or relational -databases. - -The original BIND 9 database interface defined in is -designed to efficiently support the full set of database functionality -needed by a name server that implements the complete DNS protocols, -including features such as zone transfers, dynamic update, and DNSSEC. -Each of these aspects of name server operations places its own set of -demands on the data store, with the result that the database API is -quite complex and contains operations that are highly specific to the -DNS. For example, data are stored in a binary format, the name space -is tree structured, and sets of data records are conceptually -associated with DNSSEC signature sets. For these reasons, writing a -driver using this interface is a highly nontrivial undertaking. - - -The Simplified Database Interface - -Many BIND users wish to provide access to various data sources through -the DNS, but are not necessarily interested in completely replacing -the in-memory "rbt" database or in supporting features like dynamic -update, DNSSEC, or even zone transfers. - -Often, all you want is limited, read-only DNS access to an existing -system. For example, you may have an existing relational database -containing hostname/address mappings and wish to provide forvard and -reverse DNS lookups based on this information. Or perhaps you want to -set up a simple DNS-based load balancing system where the name server -answers queries about a single DNS name with a dynamically changing -set of A records. - -BIND 9.1 introduced a new, simplified database interface, or "sdb", -which greatly simplifies the writing of drivers for these kinds of -applications. - - -The sdb Driver - -An sdb driver is an object module, typically written in C, which is -linked into the name server and registers itself with the sdb -subsystem. It provides a set of callback functions, which also serve -to advertise its capabilities. When the name server receives DNS -queries, invokes the callback functions to obtain the data to respond -with. - -Unlike the full database interface, the sdb interface represents all -domain names and resource records as ASCII text. - - -Writing an sdb Driver - -When a driver is registered, it specifies its name, a list of callback -functions, and flags. - -The flags specify whether the driver wants to use relative domain -names where possible. - -The callback functions are as follows. The only one that must be -defined is lookup(). - - - create(zone, argc, argv, driverdata, dbdata) - Create a database object for "zone". - - - destroy(zone, driverdata, dbdata) - Destroy the database object for "zone". - - - lookup(zone, name, dbdata, lookup) - Return all the records at the domain name "name". - - - authority(zone, dbdata, lookup) - Return the SOA and NS records at the zone apex. - - - allnodes(zone, dbdata, allnodes) - Return all data in the zone, for zone transfers. - -For more detail about these functions and their parameters, see -bind9/lib/dns/include/dns/sdb.h. For example drivers, see -bind9/contrib/sdb. - - -Rebuilding the Server - -The driver module and header file must be copied to (or linked into) -the bind9/bin/named and bind9/bin/named/include directories -respectively, and must be added to the DBDRIVER_OBJS and DBDRIVER_SRCS -lines in bin/named/Makefile.in (e.g. for the timedb sample sdb driver, -add timedb.c to DBDRIVER_SRCS and timedb.@O@ to DBDRIVER_OBJS). If -the driver needs additional header files or libraries in nonstandard -places, the DBDRIVER_INCLUDES and DBDRIVER_LIBS lines should also be -updated. - -Calls to dns_sdb_register() and dns_sdb_unregister() (or wrappers, -e.g. timedb_init() and timedb_clear() for the timedb sample sdb -driver) must be inserted into the server, in bind9/bin/named/main.c. -Registration should be in setup(), before the call to -ns_server_create(). Unregistration should be in cleanup(), -after the call to ns_server_destroy(). A #include should be added -corresponding to the driver header file. - -You should try doing this with one or more of the sample drivers -before attempting to write a driver of your own. - - -Configuring the Server - -To make a zone use a new database driver, specify a "database" option -in its "zone" statement in named.conf. For example, if the driver -registers itself under the name "acmedb", you might say - - zone "foo.com" { - database "acmedb"; - }; - -You can pass arbitrary arguments to the create() function of the -driver by adding any number of whitespace-separated words after the -driver name: - - zone "foo.com" { - database "acmedb -mode sql -connect 10.0.0.1"; - }; - - -Hints for Driver Writers - - - If a driver is generating data on the fly, it probably should - not implement the allnodes() function, since a zone transfer - will not be meaningful. The allnodes() function is more relevant - with data from a database. - - - The authority() function is necessary if and only if the lookup() - function will not add SOA and NS records at the zone apex. If - SOA and NS records are provided by the lookup() function, - the authority() function should be NULL. - - - When a driver is registered, an opaque object can be provided. This - object is passed into the database create() and destroy() functions. - - - When a database is created, an opaque object can be created that - is associated with that database. This object is passed into the - lookup(), authority(), and allnodes() functions, and is - destroyed by the destroy() function. - - -Future Directions - -A future release may support dynamic loading of sdb drivers. - - -$Id: sdb,v 1.6 2004/03/05 05:04:54 marka Exp $ diff --git a/contrib/bind9/doc/rfc/index b/contrib/bind9/doc/rfc/index deleted file mode 100644 index 990d4a9..0000000 --- a/contrib/bind9/doc/rfc/index +++ /dev/null @@ -1,114 +0,0 @@ - 952: DOD INTERNET HOST TABLE SPECIFICATION -1032: DOMAIN ADMINISTRATORS GUIDE -1033: DOMAIN ADMINISTRATORS OPERATIONS GUIDE -1034: DOMAIN NAMES - CONCEPTS AND FACILITIES -1035: DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION -1101: DNS Encoding of Network Names and Other Types -1122: Requirements for Internet Hosts -- Communication Layers -1123: Requirements for Internet Hosts -- Application and Support -1183: New DNS RR Definitions (AFSDB, RP, X25, ISDN and RT) -1348: DNS NSAP RRs -1535: A Security Problem and Proposed Correction - With Widely Deployed DNS Software -1536: Common DNS Implementation Errors and Suggested Fixes -1537: Common DNS Data File Configuration Errors -1591: Domain Name System Structure and Delegation -1611: DNS Server MIB Extensions -1612: DNS Resolver MIB Extensions -1706: DNS NSAP Resource Records -1712: DNS Encoding of Geographical Location -1750: Randomness Recommendations for Security -1876: A Means for Expressing Location Information in the Domain Name System -1886: DNS Extensions to support IP version 6 -1982: Serial Number Arithmetic -1995: Incremental Zone Transfer in DNS -1996: A Mechanism for Prompt Notification of Zone Changes (DNS NOTIFY) -2052: A DNS RR for specifying the location of services (DNS SRV) -2104: HMAC: Keyed-Hashing for Message Authentication -2119: Key words for use in RFCs to Indicate Requirement Levels -2133: Basic Socket Interface Extensions for IPv6 -2136: Dynamic Updates in the Domain Name System (DNS UPDATE) -2137: Secure Domain Name System Dynamic Update -2163: Using the Internet DNS to Distribute MIXER - Conformant Global Address Mapping (MCGAM) -2168: Resolution of Uniform Resource Identifiers using the Domain Name System -2181: Clarifications to the DNS Specification -2230: Key Exchange Delegation Record for the DNS -2308: Negative Caching of DNS Queries (DNS NCACHE) -2317: Classless IN-ADDR.ARPA delegation -2373: IP Version 6 Addressing Architecture -2374: An IPv6 Aggregatable Global Unicast Address Format -2375: IPv6 Multicast Address Assignments -2418: IETF Working Group Guidelines and Procedures -2535: Domain Name System Security Extensions -2536: DSA KEYs and SIGs in the Domain Name System (DNS) -2537: RSA/MD5 KEYs and SIGs in the Domain Name System (DNS) -2538: Storing Certificates in the Domain Name System (DNS) -2539: Storage of Diffie-Hellman Keys in the Domain Name System (DNS) -2540: Detached Domain Name System (DNS) Information -2541: DNS Security Operational Considerations -2553: Basic Socket Interface Extensions for IPv6 -2671: Extension Mechanisms for DNS (EDNS0) -2672: Non-Terminal DNS Name Redirection -2673: Binary Labels in the Domain Name System -2782: A DNS RR for specifying the location of services (DNS SRV) -2825: A Tangled Web: Issues of I18N, Domain Names, and the - Other Internet protocols -2826: IAB Technical Comment on the Unique DNS Root -2845: Secret Key Transaction Authentication for DNS (TSIG) -2874: DNS Extensions to Support IPv6 Address Aggregation and Renumbering -2915: The Naming Authority Pointer (NAPTR) DNS Resource Record -2929: Domain Name System (DNS) IANA Considerations -2930: Secret Key Establishment for DNS (TKEY RR) -2931: DNS Request and Transaction Signatures ( SIG(0)s ) -3007: Secure Domain Name System (DNS) Dynamic Update -3008: Domain Name System Security (DNSSEC) Signing Authority -3071: Reflections on the DNS, RFC 1591, and Categories of Domains -3090: DNS Security Extension Clarification on Zone Status -3110: RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS) -3123: A DNS RR Type for Lists of Address Prefixes (APL RR) -3152: Delegation of IP6.ARPA -3197: Applicability Statement for DNS MIB Extensions -3225: Indicating Resolver Support of DNSSEC -3226: DNSSEC and IPv6 A6 aware server/resolver message size requirements -3258: Distributing Authoritative Name Servers via Shared Unicast Addresses -3363: Representing Internet Protocol version 6 (IPv6) - Addresses in the Domain Name System (DNS) -3364: Tradeoffs in Domain Name System (DNS) Support - for Internet Protocol version 6 (IPv6) -3425: Obsoleting IQUERY -3445: Limiting the Scope of the KEY Resource Record (RR) -3490: Internationalizing Domain Names In Applications (IDNA) -3491: Nameprep: A Stringprep Profile for Internationalized Domain Names (IDN) -3492: Punycode:A Bootstring encoding of Unicode for - Internationalized Domain Names in Applications (IDNA) -3493: Basic Socket Interface Extensions for IPv6 -3513: Internet Protocol Version 6 (IPv6) Addressing Architecture -3596: DNS Extensions to Support IP Version 6 -3597: Handling of Unknown DNS Resource Record (RR) Types -3645: Generic Security Service Algorithm for - Secret Key Transaction Authentication for DNS (GSS-TSIG) -3655: Redefinition of DNS Authenticated Data (AD) bit -3658: Delegation Signer (DS) Resource Record (RR) -3757: Domain Name System KEY (DNSKEY) Resource Record (RR) - Secure Entry Point (SEP) Flag -3833: Threat Analysis of the Domain Name System (DNS) -3845: DNS Security (DNSSEC) NextSECure (NSEC) RDATA Format -3901: DNS IPv6 Transport Operational Guidelines -4025: A Method for Storing IPsec Keying Material in DNS -4033: DNS Security Introduction and Requirements -4034: Resource Records for the DNS Security Extensions -4035: Protocol Modifications for the DNS Security Extensions -4074: Common Misbehavior Against DNS Queries for IPv6 Addresses -4159: Deprecation of "ip6.int" -4193: Unique Local IPv6 Unicast Addresses -4255: Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints -4343: Domain Name System (DNS) Case Insensitivity Clarification -4367: What's in a Name: False Assumptions about DNS Names -4398: Storing Certificates in the Domain Name System (DNS) -4431: The DNSSEC Lookaside Validation (DLV) DNS Resource Record -4408: Sender Policy Framework (SPF) for Authorizing Use of Domains - in E-Mail, Version 1 -4470: Minimally Covering NSEC Records and DNSSEC On-line Signing -4634: US Secure Hash Algorithms (SHA and HMAC-SHA) -4641: DNSSEC Operational Practices diff --git a/contrib/bind9/doc/rfc/rfc1032.txt b/contrib/bind9/doc/rfc/rfc1032.txt deleted file mode 100644 index 0e82721..0000000 --- a/contrib/bind9/doc/rfc/rfc1032.txt +++ /dev/null @@ -1,781 +0,0 @@ -Network Working Group M. Stahl -Request for Comments: 1032 SRI International - November 1987 - - - DOMAIN ADMINISTRATORS GUIDE - - -STATUS OF THIS MEMO - - This memo describes procedures for registering a domain with the - Network Information Center (NIC) of Defense Data Network (DDN), and - offers guidelines on the establishment and administration of a domain - in accordance with the requirements specified in RFC-920. It is - intended for use by domain administrators. This memo should be used - in conjunction with RFC-920, which is an official policy statement of - the Internet Activities Board (IAB) and the Defense Advanced Research - Projects Agency (DARPA). Distribution of this memo is unlimited. - -BACKGROUND - - Domains are administrative entities that provide decentralized - management of host naming and addressing. The domain-naming system - is distributed and hierarchical. - - The NIC is designated by the Defense Communications Agency (DCA) to - provide registry services for the domain-naming system on the DDN and - DARPA portions of the Internet. - - As registrar of top-level and second-level domains, as well as - administrator of the root domain name servers on behalf of DARPA and - DDN, the NIC is responsible for maintaining the root server zone - files and their binary equivalents. In addition, the NIC is - responsible for administering the top-level domains of "ARPA," "COM," - "EDU," "ORG," "GOV," and "MIL" on behalf of DCA and DARPA until it - becomes feasible for other appropriate organizations to assume those - responsibilities. - - It is recommended that the guidelines described in this document be - used by domain administrators in the establishment and control of - second-level domains. - -THE DOMAIN ADMINISTRATOR - - The role of the domain administrator (DA) is that of coordinator, - manager, and technician. If his domain is established at the second - level or lower in the tree, the DA must register by interacting with - the management of the domain directly above his, making certain that - - - -Stahl [Page 1] - -RFC 1032 DOMAIN ADMINISTRATORS GUIDE November 1987 - - - his domain satisfies all the requirements of the administration under - which his domain would be situated. To find out who has authority - over the name space he wishes to join, the DA can ask the NIC - Hostmaster. Information on contacts for the top-level and second- - level domains can also be found on line in the file NETINFO:DOMAIN- - CONTACTS.TXT, which is available from the NIC via anonymous FTP. - - The DA should be technically competent; he should understand the - concepts and procedures for operating a domain server, as described - in RFC-1034, and make sure that the service provided is reliable and - uninterrupted. It is his responsibility or that of his delegate to - ensure that the data will be current at all times. As a manager, the - DA must be able to handle complaints about service provided by his - domain name server. He must be aware of the behavior of the hosts in - his domain, and take prompt action on reports of problems, such as - protocol violations or other serious misbehavior. The administrator - of a domain must be a responsible person who has the authority to - either enforce these actions himself or delegate them to someone - else. - - Name assignments within a domain are controlled by the DA, who should - verify that names are unique within his domain and that they conform - to standard naming conventions. He furnishes access to names and - name-related information to users both inside and outside his domain. - He should work closely with the personnel he has designated as the - "technical and zone" contacts for his domain, for many administrative - decisions will be made on the basis of input from these people. - -THE DOMAIN TECHNICAL AND ZONE CONTACT - - A zone consists of those contiguous parts of the domain tree for - which a domain server has complete information and over which it has - authority. A domain server may be authoritative for more than one - zone. The domain technical/zone contact is the person who tends to - the technical aspects of maintaining the domain's name server and - resolver software, and database files. He keeps the name server - running, and interacts with technical people in other domains and - zones to solve problems that affect his zone. - -POLICIES - - Domain or host name choices and the allocation of domain name space - are considered to be local matters. In the event of conflicts, it is - the policy of the NIC not to get involved in local disputes or in the - local decision-making process. The NIC will not act as referee in - disputes over such matters as who has the "right" to register a - particular top-level or second-level domain for an organization. The - NIC considers this a private local matter that must be settled among - - - -Stahl [Page 2] - -RFC 1032 DOMAIN ADMINISTRATORS GUIDE November 1987 - - - the parties involved prior to their commencing the registration - process with the NIC. Therefore, it is assumed that the responsible - person for a domain will have resolved any local conflicts among the - members of his domain before registering that domain with the NIC. - The NIC will give guidance, if requested, by answering specific - technical questions, but will not provide arbitration in disputes at - the local level. This policy is also in keeping with the distributed - hierarchical nature of the domain-naming system in that it helps to - distribute the tasks of solving problems and handling questions. - - Naming conventions for hosts should follow the rules specified in - RFC-952. From a technical standpoint, domain names can be very long. - Each segment of a domain name may contain up to 64 characters, but - the NIC strongly advises DAs to choose names that are 12 characters - or fewer, because behind every domain system there is a human being - who must keep track of the names, addresses, contacts, and other data - in a database. The longer the name, the more likely the data - maintainer is to make a mistake. Users also will appreciate shorter - names. Most people agree that short names are easier to remember and - type; most domain names registered so far are 12 characters or fewer. - - Domain name assignments are made on a first-come-first-served basis. - The NIC has chosen not to register individual hosts directly under - the top-level domains it administers. One advantage of the domain - naming system is that administration and data maintenance can be - delegated down a hierarchical tree. Registration of hosts at the - same level in the tree as a second-level domain would dilute the - usefulness of this feature. In addition, the administrator of a - domain is responsible for the actions of hosts within his domain. We - would not want to find ourselves in the awkward position of policing - the actions of individual hosts. Rather, the subdomains registered - under these top-level domains retain the responsibility for this - function. - - Countries that wish to be registered as top-level domains are - required to name themselves after the two-letter country code listed - in the international standard ISO-3166. In some cases, however, the - two-letter ISO country code is identical to a state code used by the - U.S. Postal Service. Requests made by countries to use the three- - letter form of country code specified in the ISO-3166 standard will - be considered in such cases so as to prevent possible conflicts and - confusion. - - - - - - - - - -Stahl [Page 3] - -RFC 1032 DOMAIN ADMINISTRATORS GUIDE November 1987 - - -HOW TO REGISTER - - Obtain a domain questionnaire from the NIC hostmaster, or FTP the - file NETINFO:DOMAIN-TEMPLATE.TXT from host SRI-NIC.ARPA. - - Fill out the questionnaire completely. Return it via electronic mail - to HOSTMASTER@SRI-NIC.ARPA. - - The APPENDIX to this memo contains the application form for - registering a top-level or second-level domain with the NIC. It - supersedes the version of the questionnaire found in RFC-920. The - application should be submitted by the person administratively - responsible for the domain, and must be filled out completely before - the NIC will authorize establishment of a top-level or second-level - domain. The DA is responsible for keeping his domain's data current - with the NIC or with the registration agent with which his domain is - registered. For example, the CSNET and UUCP managements act as - domain filters, processing domain applications for their own - organizations. They pass pertinent information along periodically to - the NIC for incorporation into the domain database and root server - files. The online file NETINFO:ALTERNATE-DOMAIN-PROCEDURE.TXT - outlines this procedure. It is highly recommended that the DA review - this information periodically and provide any corrections or - additions. Corrections should be submitted via electronic mail. - -WHICH DOMAIN NAME? - - The designers of the domain-naming system initiated several general - categories of names as top-level domain names, so that each could - accommodate a variety of organizations. The current top-level - domains registered with the DDN Network Information Center are ARPA, - COM, EDU, GOV, MIL, NET, and ORG, plus a number of top-level country - domains. To join one of these, a DA needs to be aware of the purpose - for which it was intended. - - "ARPA" is a temporary domain. It is by default appended to the - names of hosts that have not yet joined a domain. When the system - was begun in 1984, the names of all hosts in the Official DoD - Internet Host Table maintained by the NIC were changed by adding - of the label ".ARPA" in order to accelerate a transition to the - domain-naming system. Another reason for the blanket name changes - was to force hosts to become accustomed to using the new style - names and to modify their network software, if necessary. This - was done on a network-wide basis and was directed by DCA in DDN - Management Bulletin No. 22. Hosts that fall into this domain will - eventually move to other branches of the domain tree. - - - - - -Stahl [Page 4] - -RFC 1032 DOMAIN ADMINISTRATORS GUIDE November 1987 - - - "COM" is meant to incorporate subdomains of companies and - businesses. - - "EDU" was initiated to accommodate subdomains set up by - universities and other educational institutions. - - "GOV" exists to act as parent domain for subdomains set up by - government agencies. - - "MIL" was initiated to act as parent to subdomains that are - developed by military organizations. - - "NET" was introduced as a parent domain for various network-type - organizations. Organizations that belong within this top-level - domain are generic or network-specific, such as network service - centers and consortia. "NET" also encompasses network - management-related organizations, such as information centers and - operations centers. - - "ORG" exists as a parent to subdomains that do not clearly fall - within the other top-level domains. This may include technical- - support groups, professional societies, or similar organizations. - - One of the guidelines in effect in the domain-naming system is that a - host should have only one name regardless of what networks it is - connected to. This implies, that, in general, domain names should - not include routing information or addresses. For example, a host - that has one network connection to the Internet and another to BITNET - should use the same name when talking to either network. For a - description of the syntax of domain names, please refer to Section 3 - of RFC-1034. - -VERIFICATION OF DATA - - The verification process can be accomplished in several ways. One of - these is through the NIC WHOIS server. If he has access to WHOIS, - the DA can type the command "whois domain ". - The reply from WHOIS will supply the following: the name and address - of the organization "owning" the domain; the name of the domain; its - administrative, technical, and zone contacts; the host names and - network addresses of sites providing name service for the domain. - - - - - - - - - - -Stahl [Page 5] - -RFC 1032 DOMAIN ADMINISTRATORS GUIDE November 1987 - - - Example: - - @whois domain rice.edu - - Rice University (RICE-DOM) - Advanced Studies and Research - Houston, TX 77001 - - Domain Name: RICE.EDU - - Administrative Contact: - Kennedy, Ken (KK28) Kennedy@LLL-CRG.ARPA (713) 527-4834 - Technical Contact, Zone Contact: - Riffle, Vicky R. (VRR) rif@RICE.EDU - (713) 527-8101 ext 3844 - - Domain servers: - - RICE.EDU 128.42.5.1 - PENDRAGON.CS.PURDUE.EDU 128.10.2.5 - - - Alternatively, the DA can send an electronic mail message to - SERVICE@SRI-NIC.ARPA. In the subject line of the message header, the - DA should type "whois domain ". The requested - information will be returned via electronic mail. This method is - convenient for sites that do not have access to the NIC WHOIS - service. - - The initial application for domain authorization should be submitted - via electronic mail, if possible, to HOSTMASTER@SRI-NIC.ARPA. The - questionnaire described in the appendix may be used or a separate - application can be FTPed from host SRI-NIC.ARPA. The information - provided by the administrator will be reviewed by hostmaster - personnel for completeness. There will most likely be a few - exchanges of correspondence via electronic mail, the preferred method - of communication, prior to authorization of the domain. - -HOW TO GET MORE INFORMATION - - An informational table of the top-level domains and their root - servers is contained in the file NETINFO:DOMAINS.TXT online at SRI- - NIC.ARPA. This table can be obtained by FTPing the file. - Alternatively, the information can be acquired by opening a TCP or - UDP connection to the NIC Host Name Server, port 101 on SRI-NIC.ARPA, - and invoking the command "ALL-DOM". - - - - - -Stahl [Page 6] - -RFC 1032 DOMAIN ADMINISTRATORS GUIDE November 1987 - - - The following online files, all available by FTP from SRI-NIC.ARPA, - contain pertinent domain information: - - - NETINFO:DOMAINS.TXT, a table of all top-level domains and the - network addresses of the machines providing domain name - service for them. It is updated each time a new top-level - domain is approved. - - - NETINFO:DOMAIN-INFO.TXT contains a concise list of all - top-level and second-level domain names registered with the - NIC and is updated monthly. - - - NETINFO:DOMAIN-CONTACTS.TXT also contains a list of all the - top level and second-level domains, but includes the - administrative, technical and zone contacts for each as well. - - - NETINFO:DOMAIN-TEMPLATE.TXT contains the questionnaire to be - completed before registering a top-level or second-level - domain. - - For either general or specific information on the domain system, do - one or more of the following: - - 1. Send electronic mail to HOSTMASTER@SRI-NIC.ARPA - - 2. Call the toll-free NIC hotline at (800) 235-3155 - - 3. Use FTP to get background RFCs and other files maintained - online at the NIC. Some pertinent RFCs are listed below in - the REFERENCES section of this memo. - - - - - - - - - - - - - - - - - - - - - -Stahl [Page 7] - -RFC 1032 DOMAIN ADMINISTRATORS GUIDE November 1987 - - -REFERENCES - - The references listed here provide important background information - on the domain-naming system. Path names of the online files - available via anonymous FTP from the SRI-NIC.ARPA host are noted in - brackets. - - 1. Defense Communications Agency DDN Defense Communications - System, DDN Management Bulletin No. 22, Domain Names - Transition, March 1984. - [ DDN-NEWS:DDN-MGT-BULLETIN-22.TXT ] - - 2. Defense Communications Agency DDN Defense Communications - System, DDN Management Bulletin No. 32, Phase I of the Domain - Name Implementation, January 1987. - [ DDN-NEWS:DDN-MGT-BULLETIN-32.TXT ] - - 3. Harrenstien, K., M. Stahl, and E. Feinler, "Hostname - Server", RFC-953, DDN Network Information Center, SRI - International, October 1985. [ RFC:RFC953.TXT ] - - 4. Harrenstien, K., M. Stahl, and E. Feinler, "Official DoD - Internet Host Table Specification", RFC-952, DDN Network - Information Center, SRI International, October 1985. - [ RFC:RFC952.TXT ] - - 5. ISO, "Codes for the Representation of Names of Countries", - ISO-3166, International Standards Organization, May 1981. - [ Not online ] - - 6. Lazear, W.D., "MILNET Name Domain Transition", RFC-1031, - Mitre Corporation, October 1987. [ RFC:RFC1031.TXT ] - - 7. Lottor, M.K., "Domain Administrators Operations Guide", - RFC-1033, DDN Network Information Center, SRI International, - July 1987. [ RFC:RFC1033.TXT ] - - 8. Mockapetris, P., "Domain Names - Concepts and Facilities", - RFC-1034, USC Information Sciences Institute, October 1987. - [ RFC:RFC1034.TXT ] - - 9. Mockapetris, P., "Domain Names - Implementation and - Specification", RFC-1035, USC Information Sciences Institute, - October 1987. [ RFC:RFC1035.TXT ] - - 10. Mockapetris, P., "The Domain Name System", Proceedings of the - IFIP 6.5 Working Conference on Computer Message Services, - Nottingham, England, May 1984. Also as ISI/RS-84-133, June - - - -Stahl [Page 8] - -RFC 1032 DOMAIN ADMINISTRATORS GUIDE November 1987 - - - 1984. [ Not online ] - - 11. Mockapetris, P., J. Postel, and P. Kirton, "Name Server - Design for Distributed Systems", Proceedings of the Seventh - International Conference on Computer Communication, October - 30 to November 3 1984, Sidney, Australia. Also as - ISI/RS-84-132, June 1984. [ Not online ] - - 12. Partridge, C., "Mail Routing and the Domain System", RFC-974, - CSNET-CIC, BBN Laboratories, January 1986. - [ RFC:RFC974.TXT ] - - 13. Postel, J., "The Domain Names Plan and Schedule", RFC-881, - USC Information Sciences Institute, November 1983. - [ RFC:RFC881.TXT ] - - 14. Reynolds, J., and Postel, J., "Assigned Numbers", RFC-1010 - USC Information Sciences Institute, May 1986. - [ RFC:RFC1010.TXT ] - - 15. Romano, S., and Stahl, M., "Internet Numbers", RFC-1020, - SRI, November 1987. - [ RFC:RFC1020.TXT ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Stahl [Page 9] - -RFC 1032 DOMAIN ADMINISTRATORS GUIDE November 1987 - - -APPENDIX - - The following questionnaire may be FTPed from SRI-NIC.ARPA as - NETINFO:DOMAIN-TEMPLATE.TXT. - - --------------------------------------------------------------------- - - To establish a domain, the following information must be sent to the - NIC Domain Registrar (HOSTMASTER@SRI-NIC.ARPA): - - NOTE: The key people must have electronic mailboxes and NIC - "handles," unique NIC database identifiers. If you have access to - "WHOIS", please check to see if you are registered and if so, make - sure the information is current. Include only your handle and any - changes (if any) that need to be made in your entry. If you do not - have access to "WHOIS", please provide all the information indicated - and a NIC handle will be assigned. - - (1) The name of the top-level domain to join. - - For example: COM - - (2) The NIC handle of the administrative head of the organization. - Alternately, the person's name, title, mailing address, phone number, - organization, and network mailbox. This is the contact point for - administrative and policy questions about the domain. In the case of - a research project, this should be the principal investigator. - - For example: - - Administrator - - Organization The NetWorthy Corporation - Name Penelope Q. Sassafrass - Title President - Mail Address The NetWorthy Corporation - 4676 Andrews Way, Suite 100 - Santa Clara, CA 94302-1212 - Phone Number (415) 123-4567 - Net Mailbox Sassafrass@ECHO.TNC.COM - NIC Handle PQS - - (3) The NIC handle of the technical contact for the domain. - Alternately, the person's name, title, mailing address, phone number, - organization, and network mailbox. This is the contact point for - problems concerning the domain or zone, as well as for updating - information about the domain or zone. - - - - -Stahl [Page 10] - -RFC 1032 DOMAIN ADMINISTRATORS GUIDE November 1987 - - - For example: - - Technical and Zone Contact - - Organization The NetWorthy Corporation - Name Ansel A. Aardvark - Title Executive Director - Mail Address The NetWorthy Corporation - 4676 Andrews Way, Suite 100 - Santa Clara, CA. 94302-1212 - Phone Number (415) 123-6789 - Net Mailbox Aardvark@ECHO.TNC.COM - NIC Handle AAA2 - - (4) The name of the domain (up to 12 characters). This is the name - that will be used in tables and lists associating the domain with the - domain server addresses. [While, from a technical standpoint, domain - names can be quite long (programmers beware), shorter names are - easier for people to cope with.] - - For example: TNC - - (5) A description of the servers that provide the domain service for - translating names to addresses for hosts in this domain, and the date - they will be operational. - - A good way to answer this question is to say "Our server is - supplied by person or company X and does whatever their standard - issue server does." - - For example: Our server is a copy of the one operated by - the NIC; it will be installed and made operational on - 1 November 1987. - - (6) Domains must provide at least two independent servers for the - domain. Establishing the servers in physically separate locations - and on different PSNs is strongly recommended. A description of the - server machine and its backup, including - - - - - - - - - - - - - -Stahl [Page 11] - -RFC 1032 DOMAIN ADMINISTRATORS GUIDE November 1987 - - - (a) Hardware and software (using keywords from the Assigned - Numbers RFC). - - (b) Host domain name and network addresses (which host on which - network for each connected network). - - (c) Any domain-style nicknames (please limit your domain-style - nickname request to one) - - For example: - - - Hardware and software - - VAX-11/750 and UNIX, or - IBM-PC and MS-DOS, or - DEC-1090 and TOPS-20 - - - Host domain names and network addresses - - BAR.FOO.COM 10.9.0.193 on ARPANET - - - Domain-style nickname - - BR.FOO.COM (same as BAR.FOO.COM 10.9.0.13 on ARPANET) - - (7) Planned mapping of names of any other network hosts, other than - the server machines, into the new domain's naming space. - - For example: - - BAR-FOO2.ARPA (10.8.0.193) -> FOO2.BAR.COM - BAR-FOO3.ARPA (10.7.0.193) -> FOO3.BAR.COM - BAR-FOO4.ARPA (10.6.0.193) -> FOO4.BAR.COM - - - (8) An estimate of the number of hosts that will be in the domain. - - (a) Initially - (b) Within one year - (c) Two years - (d) Five years. - - For example: - - (a) Initially = 50 - (b) One year = 100 - (c) Two years = 200 - (d) Five years = 500 - - - -Stahl [Page 12] - -RFC 1032 DOMAIN ADMINISTRATORS GUIDE November 1987 - - - (9) The date you expect the fully qualified domain name to become - the official host name in HOSTS.TXT. - - Please note: If changing to a fully qualified domain name (e.g., - FOO.BAR.COM) causes a change in the official host name of an - ARPANET or MILNET host, DCA approval must be obtained beforehand. - Allow 10 working days for your requested changes to be processed. - - ARPANET sites should contact ARPANETMGR@DDN1.ARPA. MILNET sites - should contact HOSTMASTER@SRI-NIC.ARPA, 800-235-3155, for - further instructions. - - (10) Please describe your organization briefly. - - For example: The NetWorthy Corporation is a consulting - organization of people working with UNIX and the C language in an - electronic networking environment. It sponsors two technical - conferences annually and distributes a bimonthly newsletter. - - --------------------------------------------------------------------- - - This example of a completed application corresponds to the examples - found in the companion document RFC-1033, "Domain Administrators - Operations Guide." - - (1) The name of the top-level domain to join. - - COM - - (2) The NIC handle of the administrative contact person. - - NIC Handle JAKE - - (3) The NIC handle of the domain's technical and zone - contact person. - - NIC Handle DLE6 - - (4) The name of the domain. - - SRI - - (5) A description of the servers. - - Our server is the TOPS20 server JEEVES supplied by ISI; it - will be installed and made operational on 1 July 1987. - - - - - -Stahl [Page 13] - -RFC 1032 DOMAIN ADMINISTRATORS GUIDE November 1987 - - - (6) A description of the server machine and its backup: - - (a) Hardware and software - - DEC-1090T and TOPS20 - DEC-2065 and TOPS20 - - (b) Host domain name and network address - - KL.SRI.COM 10.1.0.2 on ARPANET, 128.18.10.6 on SRINET - STRIPE.SRI.COM 10.4.0.2 on ARPANET, 128.18.10.4 on SRINET - - (c) Domain-style nickname - - None - - (7) Planned mapping of names of any other network hosts, other than - the server machines, into the new domain's naming space. - - SRI-Blackjack.ARPA (128.18.2.1) -> Blackjack.SRI.COM - SRI-CSL.ARPA (192.12.33.2) -> CSL.SRI.COM - - (8) An estimate of the number of hosts that will be directly within - this domain. - - (a) Initially = 50 - (b) One year = 100 - (c) Two years = 200 - (d) Five years = 500 - - (9) A date when you expect the fully qualified domain name to become - the official host name in HOSTS.TXT. - - 31 September 1987 - - (10) Brief description of organization. - - SRI International is an independent, nonprofit, scientific - research organization. It performs basic and applied research - for government and commercial clients, and contributes to - worldwide economic, scientific, industrial, and social progress - through research and related services. - - - - - - - - - -Stahl [Page 14] - diff --git a/contrib/bind9/doc/rfc/rfc1033.txt b/contrib/bind9/doc/rfc/rfc1033.txt deleted file mode 100644 index 37029fd..0000000 --- a/contrib/bind9/doc/rfc/rfc1033.txt +++ /dev/null @@ -1,1229 +0,0 @@ -Network Working Group M. Lottor -Request For Comments: 1033 SRI International - November 1987 - - - DOMAIN ADMINISTRATORS OPERATIONS GUIDE - - - -STATUS OF THIS MEMO - - This RFC provides guidelines for domain administrators in operating a - domain server and maintaining their portion of the hierarchical - database. Familiarity with the domain system is assumed. - Distribution of this memo is unlimited. - -ACKNOWLEDGMENTS - - This memo is a formatted collection of notes and excerpts from the - references listed at the end of this document. Of particular mention - are Paul Mockapetris and Kevin Dunlap. - -INTRODUCTION - - A domain server requires a few files to get started. It will - normally have some number of boot/startup files (also known as the - "safety belt" files). One section will contain a list of possible - root servers that the server will use to find the up-to-date list of - root servers. Another section will list the zone files to be loaded - into the server for your local domain information. A zone file - typically contains all the data for a particular domain. This guide - describes the data formats that can be used in zone files and - suggested parameters to use for certain fields. If you are - attempting to do anything advanced or tricky, consult the appropriate - domain RFC's for more details. - - Note: Each implementation of domain software may require different - files. Zone files are standardized but some servers may require - other startup files. See the appropriate documentation that comes - with your software. See the appendix for some specific examples. - -ZONES - - A zone defines the contents of a contiguous section of the domain - space, usually bounded by administrative boundaries. There will - typically be a separate data file for each zone. The data contained - in a zone file is composed of entries called Resource Records (RRs). - - - - -Lottor [Page 1] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - - You may only put data in your domain server that you are - authoritative for. You must not add entries for domains other than - your own (except for the special case of "glue records"). - - A domain server will probably read a file on start-up that lists the - zones it should load into its database. The format of this file is - not standardized and is different for most domain server - implementations. For each zone it will normally contain the domain - name of the zone and the file name that contains the data to load for - the zone. - -ROOT SERVERS - - A resolver will need to find the root servers when it first starts. - When the resolver boots, it will typically read a list of possible - root servers from a file. - - The resolver will cycle through the list trying to contact each one. - When it finds a root server, it will ask it for the current list of - root servers. It will then discard the list of root servers it read - from the data file and replace it with the current list it received. - - Root servers will not change very often. You can get the names of - current root servers from the NIC. - - FTP the file NETINFO:ROOT-SERVERS.TXT or send a mail request to - NIC@SRI-NIC.ARPA. - - As of this date (June 1987) they are: - - SRI-NIC.ARPA 10.0.0.51 26.0.0.73 - C.ISI.EDU 10.0.0.52 - BRL-AOS.ARPA 192.5.25.82 192.5.22.82 128.20.1.2 - A.ISI.EDU 26.3.0.103 - -RESOURCE RECORDS - - Records in the zone data files are called resource records (RRs). - They are specified in RFC-883 and RFC-973. An RR has a standard - format as shown: - - [] [] - - The record is divided into fields which are separated by white space. - - - - The name field defines what domain name applies to the given - - - -Lottor [Page 2] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - - RR. In some cases the name field can be left blank and it will - default to the name field of the previous RR. - - - - TTL stands for Time To Live. It specifies how long a domain - resolver should cache the RR before it throws it out and asks a - domain server again. See the section on TTL's. If you leave - the TTL field blank it will default to the minimum time - specified in the SOA record (described later). - - - - The class field specifies the protocol group. If left blank it - will default to the last class specified. - - - - The type field specifies what type of data is in the RR. See - the section on types. - - - - The data field is defined differently for each type and class - of data. Popular RR data formats are described later. - - The domain system does not guarantee to preserve the order of - resource records. Listing RRs (such as multiple address records) in - a certain order does not guarantee they will be used in that order. - - Case is preserved in names and data fields when loaded into the name - server. All comparisons and lookups in the name server are case - insensitive. - - Parenthesis ("(",")") are used to group data that crosses a line - boundary. - - A semicolon (";") starts a comment; the remainder of the line is - ignored. - - The asterisk ("*") is used for wildcarding. - - The at-sign ("@") denotes the current default domain name. - - - - - - - - -Lottor [Page 3] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - -NAMES - - A domain name is a sequence of labels separated by dots. - - Domain names in the zone files can be one of two types, either - absolute or relative. An absolute name is the fully qualified domain - name and is terminated with a period. A relative name does not - terminate with a period, and the current default domain is appended - to it. The default domain is usually the name of the domain that was - specified in the boot file that loads each zone. - - The domain system allows a label to contain any 8-bit character. - Although the domain system has no restrictions, other protocols such - as SMTP do have name restrictions. Because of other protocol - restrictions, only the following characters are recommended for use - in a host name (besides the dot separator): - - "A-Z", "a-z", "0-9", dash and underscore - -TTL's (Time To Live) - - It is important that TTLs are set to appropriate values. The TTL is - the time (in seconds) that a resolver will use the data it got from - your server before it asks your server again. If you set the value - too low, your server will get loaded down with lots of repeat - requests. If you set it too high, then information you change will - not get distributed in a reasonable amount of time. If you leave the - TTL field blank, it will default to what is specified in the SOA - record for the zone. - - Most host information does not change much over long time periods. A - good way to set up your TTLs would be to set them at a high value, - and then lower the value if you know a change will be coming soon. - You might set most TTLs to anywhere between a day (86400) and a week - (604800). Then, if you know some data will be changing in the near - future, set the TTL for that RR down to a lower value (an hour to a - day) until the change takes place, and then put it back up to its - previous value. - - Also, all RRs with the same name, class, and type should have the - same TTL value. - -CLASSES - - The domain system was designed to be protocol independent. The class - field is used to identify the protocol group that each RR is in. - - The class of interest to people using TCP/IP software is the class - - - -Lottor [Page 4] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - - "Internet". Its standard designation is "IN". - - A zone file should only contain RRs of the same class. - -TYPES - - There are many defined RR types. For a complete list, see the domain - specification RFCs. Here is a list of current commonly used types. - The data for each type is described in the data section. - - Designation Description - ========================================== - SOA Start Of Authority - NS Name Server - - A Internet Address - CNAME Canonical Name (nickname pointer) - HINFO Host Information - WKS Well Known Services - - MX Mail Exchanger - - PTR Pointer - -SOA (Start Of Authority) - - [] [] SOA ( - - - - - ) - - The Start Of Authority record designates the start of a zone. The - zone ends at the next SOA record. - - is the name of the zone. - - is the name of the host on which the master zone file - resides. - - is a mailbox for the person responsible for the zone. It is - formatted like a mailing address but the at-sign that normally - separates the user from the host name is replaced with a dot. - - is the version number of the zone file. It should be - incremented anytime a change is made to data in the zone. - - - - -Lottor [Page 5] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - - is how long, in seconds, a secondary name server is to - check with the primary name server to see if an update is needed. A - good value here would be one hour (3600). - - is how long, in seconds, a secondary name server is to retry - after a failure to check for a refresh. A good value here would be - 10 minutes (600). - - is the upper limit, in seconds, that a secondary name server - is to use the data before it expires for lack of getting a refresh. - You want this to be rather large, and a nice value is 3600000, about - 42 days. - - is the minimum number of seconds to be used for TTL values - in RRs. A minimum of at least a day is a good value here (86400). - - There should only be one SOA record per zone. A sample SOA record - would look something like: - - @ IN SOA SRI-NIC.ARPA. HOSTMASTER.SRI-NIC.ARPA. ( - 45 ;serial - 3600 ;refresh - 600 ;retry - 3600000 ;expire - 86400 ) ;minimum - - -NS (Name Server) - - [] [] NS - - The NS record lists the name of a machine that provides domain - service for a particular domain. The name associated with the RR is - the domain name and the data portion is the name of a host that - provides the service. If machines SRI-NIC.ARPA and C.ISI.EDU provide - name lookup service for the domain COM then the following entries - would be used: - - COM. NS SRI-NIC.ARPA. - NS C.ISI.EDU. - - Note that the machines providing name service do not have to live in - the named domain. There should be one NS record for each server for - a domain. Also note that the name "COM" defaults for the second NS - record. - - NS records for a domain exist in both the zone that delegates the - domain, and in the domain itself. - - - -Lottor [Page 6] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - -GLUE RECORDS - - If the name server host for a particular domain is itself inside the - domain, then a 'glue' record will be needed. A glue record is an A - (address) RR that specifies the address of the server. Glue records - are only needed in the server delegating the domain, not in the - domain itself. If for example the name server for domain SRI.COM was - KL.SRI.COM, then the NS record would look like this, but you will - also need to have the following A record. - - SRI.COM. NS KL.SRI.COM. - KL.SRI.COM. A 10.1.0.2 - - -A (Address) - - [] [] A
- - The data for an A record is an internet address in dotted decimal - form. A sample A record might look like: - - SRI-NIC.ARPA. A 10.0.0.51 - - There should be one A record for each address of a host. - -CNAME ( Canonical Name) - - [] [] CNAME - - The CNAME record is used for nicknames. The name associated with the - RR is the nickname. The data portion is the official name. For - example, a machine named SRI-NIC.ARPA may want to have the nickname - NIC.ARPA. In that case, the following RR would be used: - - NIC.ARPA. CNAME SRI-NIC.ARPA. - - There must not be any other RRs associated with a nickname of the - same class. - - Nicknames are also useful when a host changes it's name. In that - case, it is usually a good idea to have a CNAME pointer so that - people still using the old name will get to the right place. - - - - - - - - - -Lottor [Page 7] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - -HINFO (Host Info) - - [] [] HINFO - - The HINFO record gives information about a particular host. The data - is two strings separated by whitespace. The first string is a - hardware description and the second is software. The hardware is - usually a manufacturer name followed by a dash and model designation. - The software string is usually the name of the operating system. - - Official HINFO types can be found in the latest Assigned Numbers RFC, - the latest of which is RFC-1010. The Hardware type is called the - Machine name and the Software type is called the System name. - - Some sample HINFO records: - - SRI-NIC.ARPA. HINFO DEC-2060 TOPS20 - UCBARPA.Berkeley.EDU. HINFO VAX-11/780 UNIX - - -WKS (Well Known Services) - - [] [] WKS
- - The WKS record is used to list Well Known Services a host provides. - WKS's are defined to be services on port numbers below 256. The WKS - record lists what services are available at a certain address using a - certain protocol. The common protocols are TCP or UDP. A sample WKS - record for a host offering the same services on all address would - look like: - - Official protocol names can be found in the latest Assigned Numbers - RFC, the latest of which is RFC-1010. - - SRI-NIC.ARPA. WKS 10.0.0.51 TCP TELNET FTP SMTP - WKS 10.0.0.51 UDP TIME - WKS 26.0.0.73 TCP TELNET FTP SMTP - WKS 26.0.0.73 UDP TIME - -MX (Mail Exchanger) (See RFC-974 for more details.) - - [] [] MX - - MX records specify where mail for a domain name should be delivered. - There may be multiple MX records for a particular name. The - preference value specifies the order a mailer should try multiple MX - records when delivering mail. Zero is the highest preference. - Multiple records for the same name may have the same preference. - - - -Lottor [Page 8] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - - A host BAR.FOO.COM may want its mail to be delivered to the host - PO.FOO.COM and would then use the MX record: - - BAR.FOO.COM. MX 10 PO.FOO.COM. - - A host BAZ.FOO.COM may want its mail to be delivered to one of three - different machines, in the following order: - - BAZ.FOO.COM. MX 10 PO1.FOO.COM. - MX 20 PO2.FOO.COM. - MX 30 PO3.FOO.COM. - - An entire domain of hosts not connected to the Internet may want - their mail to go through a mail gateway that knows how to deliver - mail to them. If they would like mail addressed to any host in the - domain FOO.COM to go through the mail gateway they might use: - - FOO.COM. MX 10 RELAY.CS.NET. - *.FOO.COM. MX 20 RELAY.CS.NET. - - Note that you can specify a wildcard in the MX record to match on - anything in FOO.COM, but that it won't match a plain FOO.COM. - -IN-ADDR.ARPA - - The structure of names in the domain system is set up in a - hierarchical way such that the address of a name can be found by - tracing down the domain tree contacting a server for each label of - the name. Because of this 'indexing' based on name, there is no easy - way to translate a host address back into its host name. - - In order to do the reverse translation easily, a domain was created - that uses hosts' addresses as part of a name that then points to the - data for that host. In this way, there is now an 'index' to hosts' - RRs based on their address. This address mapping domain is called - IN-ADDR.ARPA. Within that domain are subdomains for each network, - based on network number. Also, for consistency and natural - groupings, the 4 octets of a host number are reversed. - - For example, the ARPANET is net 10. That means there is a domain - called 10.IN-ADDR.ARPA. Within this domain there is a PTR RR at - 51.0.0.10.IN-ADDR that points to the RRs for the host SRI-NIC.ARPA - (who's address is 10.0.0.51). Since the NIC is also on the MILNET - (Net 26, address 26.0.0.73), there is also a PTR RR at 73.0.0.26.IN- - ADDR.ARPA that points to the same RR's for SRI-NIC.ARPA. The format - of these special pointers is defined below along with the examples - for the NIC. - - - - -Lottor [Page 9] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - -PTR - - [] [] PTR - - The PTR record is used to let special names point to some other - location in the domain tree. They are mainly used in the IN- - ADDR.ARPA records for translation of addresses to names. PTR's - should use official names and not aliases. - - For example, host SRI-NIC.ARPA with addresses 10.0.0.51 and 26.0.0.73 - would have the following records in the respective zone files for net - 10 and net 26: - - 51.0.0.10.IN-ADDR.ARPA. PTR SRI-NIC.ARPA. - 73.0.0.26.IN-ADDR.ARPA. PTR SRI-NIC.ARPA. - -GATEWAY PTR's - - The IN-ADDR tree is also used to locate gateways on a particular - network. Gateways have the same kind of PTR RRs as hosts (as above) - but in addition they have other PTRs used to locate them by network - number alone. These records have only 1, 2, or 3 octets as part of - the name depending on whether they are class A, B, or C networks, - respectively. - - Lets take the SRI-CSL gateway for example. It connects 3 different - networks, one class A, one class B and one class C. It will have the - standard RR's for a host in the CSL.SRI.COM zone: - - GW.CSL.SRI.COM. A 10.2.0.2 - A 128.18.1.1 - A 192.12.33.2 - - Also, in 3 different zones (one for each network), it will have one - of the following number to name translation pointers: - - 2.0.2.10.IN-ADDR.ARPA. PTR GW.CSL.SRI.COM. - 1.1.18.128.IN-ADDR.ARPA. PTR GW.CSL.SRI.COM. - 1.33.12.192.IN-ADDR.ARPA. PTR GW.CSL.SRI.COM. - - In addition, in each of the same 3 zones will be one of the following - gateway location pointers: - - 10.IN-ADDR.ARPA. PTR GW.CSL.SRI.COM. - 18.128.IN-ADDR.ARPA. PTR GW.CSL.SRI.COM. - 33.12.192.IN-ADDR.ARPA. PTR GW.CSL.SRI.COM. - - - - - -Lottor [Page 10] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - -INSTRUCTIONS - - Adding a subdomain. - - To add a new subdomain to your domain: - - Setup the other domain server and/or the new zone file. - - Add an NS record for each server of the new domain to the zone - file of the parent domain. - - Add any necessary glue RRs. - - Adding a host. - - To add a new host to your zone files: - - Edit the appropriate zone file for the domain the host is in. - - Add an entry for each address of the host. - - Optionally add CNAME, HINFO, WKS, and MX records. - - Add the reverse IN-ADDR entry for each host address in the - appropriate zone files for each network the host in on. - - Deleting a host. - - To delete a host from the zone files: - - Remove all the hosts' resource records from the zone file of - the domain the host is in. - - Remove all the hosts' PTR records from the IN-ADDR zone files - for each network the host was on. - - Adding gateways. - - Follow instructions for adding a host. - - Add the gateway location PTR records for each network the - gateway is on. - - Deleting gateways. - - Follow instructions for deleting a host. - - Also delete the gateway location PTR records for each network - - - -Lottor [Page 11] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - - the gateway was on. - -COMPLAINTS - - These are the suggested steps you should take if you are having - problems that you believe are caused by someone else's name server: - - - 1. Complain privately to the responsible person for the domain. You - can find their mailing address in the SOA record for the domain. - - 2. Complain publicly to the responsible person for the domain. - - 3. Ask the NIC for the administrative person responsible for the - domain. Complain. You can also find domain contacts on the NIC in - the file NETINFO:DOMAIN-CONTACTS.TXT - - 4. Complain to the parent domain authorities. - - 5. Ask the parent authorities to excommunicate the domain. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Lottor [Page 12] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - -EXAMPLE DOMAIN SERVER DATABASE FILES - - The following examples show how zone files are set up for a typical - organization. SRI will be used as the example organization. SRI has - decided to divided their domain SRI.COM into a few subdomains, one - for each group that wants one. The subdomains are CSL and ISTC. - - Note the following interesting items: - - There are both hosts and domains under SRI.COM. - - CSL.SRI.COM is both a domain name and a host name. - - All the domains are serviced by the same pair of domain servers. - - All hosts at SRI are on net 128.18 except hosts in the CSL domain - which are on net 192.12.33. Note that a domain does not have to - correspond to a physical network. - - The examples do not necessarily correspond to actual data in use - by the SRI domain. - - SRI Domain Organization - - +-------+ - | COM | - +-------+ - | - +-------+ - | SRI | - +-------+ - | - +----------++-----------+ - | | | - +-------+ +------+ +-------+ - | CSL | | ISTC | | Hosts | - +-------+ +------+ +-------+ - | | - +-------+ +-------+ - | Hosts | | Hosts | - +-------+ +-------+ - - - - - - - - - - -Lottor [Page 13] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - - [File "CONFIG.CMD". Since bootstrap files are not standardized, this - file is presented using a pseudo configuration file syntax.] - - load root server list from file ROOT.SERVERS - load zone SRI.COM. from file SRI.ZONE - load zone CSL.SRI.COM. from file CSL.ZONE - load zone ISTC.SRI.COM. from file ISTC.ZONE - load zone 18.128.IN-ADDR.ARPA. from file SRINET.ZONE - load zone 33.12.192.IN-ADDR.ARPA. from file SRI-CSL-NET.ZONE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Lottor [Page 14] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - - [File "ROOT.SERVERS". Again, the format of this file is not - standardized.] - - ;list of possible root servers - SRI-NIC.ARPA 10.0.0.51 26.0.0.73 - C.ISI.EDU 10.0.0.52 - BRL-AOS.ARPA 192.5.25.82 192.5.22.82 128.20.1.2 - A.ISI.EDU 26.3.0.103 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Lottor [Page 15] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - - [File "SRI.ZONE"] - - SRI.COM. IN SOA KL.SRI.COM. DLE.STRIPE.SRI.COM. ( - 870407 ;serial - 1800 ;refresh every 30 minutes - 600 ;retry every 10 minutes - 604800 ;expire after a week - 86400 ;default of an hour - ) - - SRI.COM. NS KL.SRI.COM. - NS STRIPE.SRI.COM. - MX 10 KL.SRI.COM. - - ;SRI.COM hosts - - KL A 10.1.0.2 - A 128.18.10.6 - MX 10 KL.SRI.COM. - - STRIPE A 10.4.0.2 - STRIPE A 128.18.10.4 - MX 10 STRIPE.SRI.COM. - - NIC CNAME SRI-NIC.ARPA. - - Blackjack A 128.18.2.1 - HINFO VAX-11/780 UNIX - WKS 128.18.2.1 TCP TELNET FTP - - CSL A 192.12.33.2 - HINFO FOONLY-F4 TOPS20 - WKS 192.12.33.2 TCP TELNET FTP SMTP FINGER - MX 10 CSL.SRI.COM. - - - - - - - - - - - - - - - - - -Lottor [Page 16] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - - [File "CSL.ZONE"] - - CSL.SRI.COM. IN SOA KL.SRI.COM. DLE.STRIPE.SRI.COM. ( - 870330 ;serial - 1800 ;refresh every 30 minutes - 600 ;retry every 10 minutes - 604800 ;expire after a week - 86400 ;default of a day - ) - - CSL.SRI.COM. NS KL.SRI.COM. - NS STRIPE.SRI.COM. - A 192.12.33.2 - - ;CSL.SRI.COM hosts - - A CNAME CSL.SRI.COM. - B A 192.12.33.3 - HINFO FOONLY-F4 TOPS20 - WKS 192.12.33.3 TCP TELNET FTP SMTP - GW A 10.2.0.2 - A 192.12.33.1 - A 128.18.1.1 - HINFO PDP-11/23 MOS - SMELLY A 192.12.33.4 - HINFO IMAGEN IMAGEN - SQUIRREL A 192.12.33.5 - HINFO XEROX-1100 INTERLISP - VENUS A 192.12.33.7 - HINFO SYMBOLICS-3600 LISPM - HELIUM A 192.12.33.30 - HINFO SUN-3/160 UNIX - ARGON A 192.12.33.31 - HINFO SUN-3/75 UNIX - RADON A 192.12.33.32 - HINFO SUN-3/75 UNIX - - - - - - - - - - - - - - - -Lottor [Page 17] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - - [File "ISTC.ZONE"] - - ISTC.SRI.COM. IN SOA KL.SRI.COM. roemers.JOYCE.ISTC.SRI.COM. ( - 870406 ;serial - 1800 ;refresh every 30 minutes - 600 ;retry every 10 minutes - 604800 ;expire after a week - 86400 ;default of a day - ) - - ISTC.SRI.COM. NS KL.SRI.COM. - NS STRIPE.SRI.COM. - MX 10 SPAM.ISTC.SRI.COM. - - ; ISTC hosts - - joyce A 128.18.4.2 - HINFO VAX-11/750 UNIX - bozo A 128.18.0.6 - HINFO SUN UNIX - sundae A 128.18.0.11 - HINFO SUN UNIX - tsca A 128.18.0.201 - A 10.3.0.2 - HINFO VAX-11/750 UNIX - MX 10 TSCA.ISTC.SRI.COM. - tsc CNAME tsca - prmh A 128.18.0.203 - A 10.2.0.51 - HINFO PDP-11/44 UNIX - spam A 128.18.4.3 - A 10.2.0.107 - HINFO VAX-11/780 UNIX - MX 10 SPAM.ISTC.SRI.COM. - - - - - - - - - - - - - - - - - -Lottor [Page 18] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - - [File "SRINET.ZONE"] - - 18.128.IN-ADDR.ARPA. IN SOA KL.SRI.COM DLE.STRIPE.SRI.COM. ( - 870406 ;serial - 1800 ;refresh every 30 minutes - 600 ;retry every 10 minutes - 604800 ;expire after a week - 86400 ;default of a day - ) - - 18.128.IN-ADDR.ARPA. NS KL.SRI.COM. - NS STRIPE.SRI.COM. - PTR GW.CSL.SRI.COM. - - ; SRINET [128.18.0.0] Address Translations - - ; SRI.COM Hosts - 1.2.18.128.IN-ADDR.ARPA. PTR Blackjack.SRI.COM. - - ; ISTC.SRI.COM Hosts - 2.4.18.128.IN-ADDR.ARPA. PTR joyce.ISTC.SRI.COM. - 6.0.18.128.IN-ADDR.ARPA. PTR bozo.ISTC.SRI.COM. - 11.0.18.128.IN-ADDR.ARPA. PTR sundae.ISTC.SRI.COM. - 201.0.18.128.IN-ADDR.ARPA. PTR tsca.ISTC.SRI.COM. - 203.0.18.128.IN-ADDR.ARPA. PTR prmh.ISTC.SRI.COM. - 3.4.18.128.IN-ADDR.ARPA. PTR spam.ISTC.SRI.COM. - - ; CSL.SRI.COM Hosts - 1.1.18.128.IN-ADDR.ARPA. PTR GW.CSL.SRI.COM. - - - - - - - - - - - - - - - - - - - - - - -Lottor [Page 19] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - - [File "SRI-CSL-NET.ZONE"] - - 33.12.192.IN-ADDR.ARPA. IN SOA KL.SRI.COM DLE.STRIPE.SRI.COM. ( - 870404 ;serial - 1800 ;refresh every 30 minutes - 600 ;retry every 10 minutes - 604800 ;expire after a week - 86400 ;default of a day - ) - - 33.12.192.IN-ADDR.ARPA. NS KL.SRI.COM. - NS STRIPE.SRI.COM. - PTR GW.CSL.SRI.COM. - - ; SRI-CSL-NET [192.12.33.0] Address Translations - - ; SRI.COM Hosts - 2.33.12.192.IN-ADDR.ARPA. PTR CSL.SRI.COM. - - ; CSL.SRI.COM Hosts - 1.33.12.192.IN-ADDR.ARPA. PTR GW.CSL.SRI.COM. - 3.33.12.192.IN-ADDR.ARPA. PTR B.CSL.SRI.COM. - 4.33.12.192.IN-ADDR.ARPA. PTR SMELLY.CSL.SRI.COM. - 5.33.12.192.IN-ADDR.ARPA. PTR SQUIRREL.CSL.SRI.COM. - 7.33.12.192.IN-ADDR.ARPA. PTR VENUS.CSL.SRI.COM. - 30.33.12.192.IN-ADDR.ARPA. PTR HELIUM.CSL.SRI.COM. - 31.33.12.192.IN-ADDR.ARPA. PTR ARGON.CSL.SRI.COM. - 32.33.12.192.IN-ADDR.ARPA. PTR RADON.CSL.SRI.COM. - - - - - - - - - - - - - - - - - - - - - - - -Lottor [Page 20] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - -APPENDIX - - BIND (Berkeley Internet Name Domain server) distributed with 4.3 BSD - UNIX - - This section describes two BIND implementation specific files; the - boot file and the cache file. BIND has other options, files, and - specifications that are not described here. See the Name Server - Operations Guide for BIND for details. - - The boot file for BIND is usually called "named.boot". This - corresponds to file "CONFIG.CMD" in the example section. - - -------------------------------------------------------- - cache . named.ca - primary SRI.COM SRI.ZONE - primary CSL.SRI.COM CSL.ZONE - primary ISTC.SRI.COM ISTC.ZONE - primary 18.128.IN-ADDR.ARPA SRINET.ZONE - primary 33.12.192.IN-ADDR.ARPA SRI-CSL-NET.ZONE - -------------------------------------------------------- - - The cache file for BIND is usually called "named.ca". This - corresponds to file "ROOT.SERVERS" in the example section. - - ------------------------------------------------- - ;list of possible root servers - . 1 IN NS SRI-NIC.ARPA. - NS C.ISI.EDU. - NS BRL-AOS.ARPA. - NS C.ISI.EDU. - ;and their addresses - SRI-NIC.ARPA. A 10.0.0.51 - A 26.0.0.73 - C.ISI.EDU. A 10.0.0.52 - BRL-AOS.ARPA. A 192.5.25.82 - A 192.5.22.82 - A 128.20.1.2 - A.ISI.EDU. A 26.3.0.103 - ------------------------------------------------- - - - - - - - - - - - -Lottor [Page 21] - -RFC 1033 DOMAIN OPERATIONS GUIDE November 1987 - - -REFERENCES - - [1] Dunlap, K., "Name Server Operations Guide for BIND", CSRG, - Department of Electrical Engineering and Computer Sciences, - University of California, Berkeley, California. - - [2] Partridge, C., "Mail Routing and the Domain System", RFC-974, - CSNET CIC BBN Laboratories, January 1986. - - [3] Mockapetris, P., "Domains Names - Concepts and Facilities", - RFC-1034, USC/Information Sciences Institute, November 1987. - - [4] Mockapetris, P., "Domain Names - Implementations Specification", - RFC-1035, USC/Information Sciences Institute, November 1987. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Lottor [Page 22] - diff --git a/contrib/bind9/doc/rfc/rfc1034.txt b/contrib/bind9/doc/rfc/rfc1034.txt deleted file mode 100644 index 55cdb21..0000000 --- a/contrib/bind9/doc/rfc/rfc1034.txt +++ /dev/null @@ -1,3077 +0,0 @@ -Network Working Group P. Mockapetris -Request for Comments: 1034 ISI -Obsoletes: RFCs 882, 883, 973 November 1987 - - - DOMAIN NAMES - CONCEPTS AND FACILITIES - - - -1. STATUS OF THIS MEMO - -This RFC is an introduction to the Domain Name System (DNS), and omits -many details which can be found in a companion RFC, "Domain Names - -Implementation and Specification" [RFC-1035]. That RFC assumes that the -reader is familiar with the concepts discussed in this memo. - -A subset of DNS functions and data types constitute an official -protocol. The official protocol includes standard queries and their -responses and most of the Internet class data formats (e.g., host -addresses). - -However, the domain system is intentionally extensible. Researchers are -continuously proposing, implementing and experimenting with new data -types, query types, classes, functions, etc. Thus while the components -of the official protocol are expected to stay essentially unchanged and -operate as a production service, experimental behavior should always be -expected in extensions beyond the official protocol. Experimental or -obsolete features are clearly marked in these RFCs, and such information -should be used with caution. - -The reader is especially cautioned not to depend on the values which -appear in examples to be current or complete, since their purpose is -primarily pedagogical. Distribution of this memo is unlimited. - -2. INTRODUCTION - -This RFC introduces domain style names, their use for Internet mail and -host address support, and the protocols and servers used to implement -domain name facilities. - -2.1. The history of domain names - -The impetus for the development of the domain system was growth in the -Internet: - - - Host name to address mappings were maintained by the Network - Information Center (NIC) in a single file (HOSTS.TXT) which - was FTPed by all hosts [RFC-952, RFC-953]. The total network - - - -Mockapetris [Page 1] - -RFC 1034 Domain Concepts and Facilities November 1987 - - - bandwidth consumed in distributing a new version by this - scheme is proportional to the square of the number of hosts in - the network, and even when multiple levels of FTP are used, - the outgoing FTP load on the NIC host is considerable. - Explosive growth in the number of hosts didn't bode well for - the future. - - - The network population was also changing in character. The - timeshared hosts that made up the original ARPANET were being - replaced with local networks of workstations. Local - organizations were administering their own names and - addresses, but had to wait for the NIC to change HOSTS.TXT to - make changes visible to the Internet at large. Organizations - also wanted some local structure on the name space. - - - The applications on the Internet were getting more - sophisticated and creating a need for general purpose name - service. - - -The result was several ideas about name spaces and their management -[IEN-116, RFC-799, RFC-819, RFC-830]. The proposals varied, but a -common thread was the idea of a hierarchical name space, with the -hierarchy roughly corresponding to organizational structure, and names -using "." as the character to mark the boundary between hierarchy -levels. A design using a distributed database and generalized resources -was described in [RFC-882, RFC-883]. Based on experience with several -implementations, the system evolved into the scheme described in this -memo. - -The terms "domain" or "domain name" are used in many contexts beyond the -DNS described here. Very often, the term domain name is used to refer -to a name with structure indicated by dots, but no relation to the DNS. -This is particularly true in mail addressing [Quarterman 86]. - -2.2. DNS design goals - -The design goals of the DNS influence its structure. They are: - - - The primary goal is a consistent name space which will be used - for referring to resources. In order to avoid the problems - caused by ad hoc encodings, names should not be required to - contain network identifiers, addresses, routes, or similar - information as part of the name. - - - The sheer size of the database and frequency of updates - suggest that it must be maintained in a distributed manner, - with local caching to improve performance. Approaches that - - - -Mockapetris [Page 2] - -RFC 1034 Domain Concepts and Facilities November 1987 - - - attempt to collect a consistent copy of the entire database - will become more and more expensive and difficult, and hence - should be avoided. The same principle holds for the structure - of the name space, and in particular mechanisms for creating - and deleting names; these should also be distributed. - - - Where there tradeoffs between the cost of acquiring data, the - speed of updates, and the accuracy of caches, the source of - the data should control the tradeoff. - - - The costs of implementing such a facility dictate that it be - generally useful, and not restricted to a single application. - We should be able to use names to retrieve host addresses, - mailbox data, and other as yet undetermined information. All - data associated with a name is tagged with a type, and queries - can be limited to a single type. - - - Because we want the name space to be useful in dissimilar - networks and applications, we provide the ability to use the - same name space with different protocol families or - management. For example, host address formats differ between - protocols, though all protocols have the notion of address. - The DNS tags all data with a class as well as the type, so - that we can allow parallel use of different formats for data - of type address. - - - We want name server transactions to be independent of the - communications system that carries them. Some systems may - wish to use datagrams for queries and responses, and only - establish virtual circuits for transactions that need the - reliability (e.g., database updates, long transactions); other - systems will use virtual circuits exclusively. - - - The system should be useful across a wide spectrum of host - capabilities. Both personal computers and large timeshared - hosts should be able to use the system, though perhaps in - different ways. - -2.3. Assumptions about usage - -The organization of the domain system derives from some assumptions -about the needs and usage patterns of its user community and is designed -to avoid many of the the complicated problems found in general purpose -database systems. - -The assumptions are: - - - The size of the total database will initially be proportional - - - -Mockapetris [Page 3] - -RFC 1034 Domain Concepts and Facilities November 1987 - - - to the number of hosts using the system, but will eventually - grow to be proportional to the number of users on those hosts - as mailboxes and other information are added to the domain - system. - - - Most of the data in the system will change very slowly (e.g., - mailbox bindings, host addresses), but that the system should - be able to deal with subsets that change more rapidly (on the - order of seconds or minutes). - - - The administrative boundaries used to distribute - responsibility for the database will usually correspond to - organizations that have one or more hosts. Each organization - that has responsibility for a particular set of domains will - provide redundant name servers, either on the organization's - own hosts or other hosts that the organization arranges to - use. - - - Clients of the domain system should be able to identify - trusted name servers they prefer to use before accepting - referrals to name servers outside of this "trusted" set. - - - Access to information is more critical than instantaneous - updates or guarantees of consistency. Hence the update - process allows updates to percolate out through the users of - the domain system rather than guaranteeing that all copies are - simultaneously updated. When updates are unavailable due to - network or host failure, the usual course is to believe old - information while continuing efforts to update it. The - general model is that copies are distributed with timeouts for - refreshing. The distributor sets the timeout value and the - recipient of the distribution is responsible for performing - the refresh. In special situations, very short intervals can - be specified, or the owner can prohibit copies. - - - In any system that has a distributed database, a particular - name server may be presented with a query that can only be - answered by some other server. The two general approaches to - dealing with this problem are "recursive", in which the first - server pursues the query for the client at another server, and - "iterative", in which the server refers the client to another - server and lets the client pursue the query. Both approaches - have advantages and disadvantages, but the iterative approach - is preferred for the datagram style of access. The domain - system requires implementation of the iterative approach, but - allows the recursive approach as an option. - - - - - -Mockapetris [Page 4] - -RFC 1034 Domain Concepts and Facilities November 1987 - - -The domain system assumes that all data originates in master files -scattered through the hosts that use the domain system. These master -files are updated by local system administrators. Master files are text -files that are read by a local name server, and hence become available -through the name servers to users of the domain system. The user -programs access name servers through standard programs called resolvers. - -The standard format of master files allows them to be exchanged between -hosts (via FTP, mail, or some other mechanism); this facility is useful -when an organization wants a domain, but doesn't want to support a name -server. The organization can maintain the master files locally using a -text editor, transfer them to a foreign host which runs a name server, -and then arrange with the system administrator of the name server to get -the files loaded. - -Each host's name servers and resolvers are configured by a local system -administrator [RFC-1033]. For a name server, this configuration data -includes the identity of local master files and instructions on which -non-local master files are to be loaded from foreign servers. The name -server uses the master files or copies to load its zones. For -resolvers, the configuration data identifies the name servers which -should be the primary sources of information. - -The domain system defines procedures for accessing the data and for -referrals to other name servers. The domain system also defines -procedures for caching retrieved data and for periodic refreshing of -data defined by the system administrator. - -The system administrators provide: - - - The definition of zone boundaries. - - - Master files of data. - - - Updates to master files. - - - Statements of the refresh policies desired. - -The domain system provides: - - - Standard formats for resource data. - - - Standard methods for querying the database. - - - Standard methods for name servers to refresh local data from - foreign name servers. - - - - - -Mockapetris [Page 5] - -RFC 1034 Domain Concepts and Facilities November 1987 - - -2.4. Elements of the DNS - -The DNS has three major components: - - - The DOMAIN NAME SPACE and RESOURCE RECORDS, which are - specifications for a tree structured name space and data - associated with the names. Conceptually, each node and leaf - of the domain name space tree names a set of information, and - query operations are attempts to extract specific types of - information from a particular set. A query names the domain - name of interest and describes the type of resource - information that is desired. For example, the Internet - uses some of its domain names to identify hosts; queries for - address resources return Internet host addresses. - - - NAME SERVERS are server programs which hold information about - the domain tree's structure and set information. A name - server may cache structure or set information about any part - of the domain tree, but in general a particular name server - has complete information about a subset of the domain space, - and pointers to other name servers that can be used to lead to - information from any part of the domain tree. Name servers - know the parts of the domain tree for which they have complete - information; a name server is said to be an AUTHORITY for - these parts of the name space. Authoritative information is - organized into units called ZONEs, and these zones can be - automatically distributed to the name servers which provide - redundant service for the data in a zone. - - - RESOLVERS are programs that extract information from name - servers in response to client requests. Resolvers must be - able to access at least one name server and use that name - server's information to answer a query directly, or pursue the - query using referrals to other name servers. A resolver will - typically be a system routine that is directly accessible to - user programs; hence no protocol is necessary between the - resolver and the user program. - -These three components roughly correspond to the three layers or views -of the domain system: - - - From the user's point of view, the domain system is accessed - through a simple procedure or OS call to a local resolver. - The domain space consists of a single tree and the user can - request information from any section of the tree. - - - From the resolver's point of view, the domain system is - composed of an unknown number of name servers. Each name - - - -Mockapetris [Page 6] - -RFC 1034 Domain Concepts and Facilities November 1987 - - - server has one or more pieces of the whole domain tree's data, - but the resolver views each of these databases as essentially - static. - - - From a name server's point of view, the domain system consists - of separate sets of local information called zones. The name - server has local copies of some of the zones. The name server - must periodically refresh its zones from master copies in - local files or foreign name servers. The name server must - concurrently process queries that arrive from resolvers. - -In the interests of performance, implementations may couple these -functions. For example, a resolver on the same machine as a name server -might share a database consisting of the the zones managed by the name -server and the cache managed by the resolver. - -3. DOMAIN NAME SPACE and RESOURCE RECORDS - -3.1. Name space specifications and terminology - -The domain name space is a tree structure. Each node and leaf on the -tree corresponds to a resource set (which may be empty). The domain -system makes no distinctions between the uses of the interior nodes and -leaves, and this memo uses the term "node" to refer to both. - -Each node has a label, which is zero to 63 octets in length. Brother -nodes may not have the same label, although the same label can be used -for nodes which are not brothers. One label is reserved, and that is -the null (i.e., zero length) label used for the root. - -The domain name of a node is the list of the labels on the path from the -node to the root of the tree. By convention, the labels that compose a -domain name are printed or read left to right, from the most specific -(lowest, farthest from the root) to the least specific (highest, closest -to the root). - -Internally, programs that manipulate domain names should represent them -as sequences of labels, where each label is a length octet followed by -an octet string. Because all domain names end at the root, which has a -null string for a label, these internal representations can use a length -byte of zero to terminate a domain name. - -By convention, domain names can be stored with arbitrary case, but -domain name comparisons for all present domain functions are done in a -case-insensitive manner, assuming an ASCII character set, and a high -order zero bit. This means that you are free to create a node with -label "A" or a node with label "a", but not both as brothers; you could -refer to either using "a" or "A". When you receive a domain name or - - - -Mockapetris [Page 7] - -RFC 1034 Domain Concepts and Facilities November 1987 - - -label, you should preserve its case. The rationale for this choice is -that we may someday need to add full binary domain names for new -services; existing services would not be changed. - -When a user needs to type a domain name, the length of each label is -omitted and the labels are separated by dots ("."). Since a complete -domain name ends with the root label, this leads to a printed form which -ends in a dot. We use this property to distinguish between: - - - a character string which represents a complete domain name - (often called "absolute"). For example, "poneria.ISI.EDU." - - - a character string that represents the starting labels of a - domain name which is incomplete, and should be completed by - local software using knowledge of the local domain (often - called "relative"). For example, "poneria" used in the - ISI.EDU domain. - -Relative names are either taken relative to a well known origin, or to a -list of domains used as a search list. Relative names appear mostly at -the user interface, where their interpretation varies from -implementation to implementation, and in master files, where they are -relative to a single origin domain name. The most common interpretation -uses the root "." as either the single origin or as one of the members -of the search list, so a multi-label relative name is often one where -the trailing dot has been omitted to save typing. - -To simplify implementations, the total number of octets that represent a -domain name (i.e., the sum of all label octets and label lengths) is -limited to 255. - -A domain is identified by a domain name, and consists of that part of -the domain name space that is at or below the domain name which -specifies the domain. A domain is a subdomain of another domain if it -is contained within that domain. This relationship can be tested by -seeing if the subdomain's name ends with the containing domain's name. -For example, A.B.C.D is a subdomain of B.C.D, C.D, D, and " ". - -3.2. Administrative guidelines on use - -As a matter of policy, the DNS technical specifications do not mandate a -particular tree structure or rules for selecting labels; its goal is to -be as general as possible, so that it can be used to build arbitrary -applications. In particular, the system was designed so that the name -space did not have to be organized along the lines of network -boundaries, name servers, etc. The rationale for this is not that the -name space should have no implied semantics, but rather that the choice -of implied semantics should be left open to be used for the problem at - - - -Mockapetris [Page 8] - -RFC 1034 Domain Concepts and Facilities November 1987 - - -hand, and that different parts of the tree can have different implied -semantics. For example, the IN-ADDR.ARPA domain is organized and -distributed by network and host address because its role is to translate -from network or host numbers to names; NetBIOS domains [RFC-1001, RFC- -1002] are flat because that is appropriate for that application. - -However, there are some guidelines that apply to the "normal" parts of -the name space used for hosts, mailboxes, etc., that will make the name -space more uniform, provide for growth, and minimize problems as -software is converted from the older host table. The political -decisions about the top levels of the tree originated in RFC-920. -Current policy for the top levels is discussed in [RFC-1032]. MILNET -conversion issues are covered in [RFC-1031]. - -Lower domains which will eventually be broken into multiple zones should -provide branching at the top of the domain so that the eventual -decomposition can be done without renaming. Node labels which use -special characters, leading digits, etc., are likely to break older -software which depends on more restrictive choices. - -3.3. Technical guidelines on use - -Before the DNS can be used to hold naming information for some kind of -object, two needs must be met: - - - A convention for mapping between object names and domain - names. This describes how information about an object is - accessed. - - - RR types and data formats for describing the object. - -These rules can be quite simple or fairly complex. Very often, the -designer must take into account existing formats and plan for upward -compatibility for existing usage. Multiple mappings or levels of -mapping may be required. - -For hosts, the mapping depends on the existing syntax for host names -which is a subset of the usual text representation for domain names, -together with RR formats for describing host addresses, etc. Because we -need a reliable inverse mapping from address to host name, a special -mapping for addresses into the IN-ADDR.ARPA domain is also defined. - -For mailboxes, the mapping is slightly more complex. The usual mail -address @ is mapped into a domain name by -converting into a single label (regardles of dots it -contains), converting into a domain name using the usual -text format for domain names (dots denote label breaks), and -concatenating the two to form a single domain name. Thus the mailbox - - - -Mockapetris [Page 9] - -RFC 1034 Domain Concepts and Facilities November 1987 - - -HOSTMASTER@SRI-NIC.ARPA is represented as a domain name by -HOSTMASTER.SRI-NIC.ARPA. An appreciation for the reasons behind this -design also must take into account the scheme for mail exchanges [RFC- -974]. - -The typical user is not concerned with defining these rules, but should -understand that they usually are the result of numerous compromises -between desires for upward compatibility with old usage, interactions -between different object definitions, and the inevitable urge to add new -features when defining the rules. The way the DNS is used to support -some object is often more crucial than the restrictions inherent in the -DNS. - -3.4. Example name space - -The following figure shows a part of the current domain name space, and -is used in many examples in this RFC. Note that the tree is a very -small subset of the actual name space. - - | - | - +---------------------+------------------+ - | | | - MIL EDU ARPA - | | | - | | | - +-----+-----+ | +------+-----+-----+ - | | | | | | | - BRL NOSC DARPA | IN-ADDR SRI-NIC ACC - | - +--------+------------------+---------------+--------+ - | | | | | - UCI MIT | UDEL YALE - | ISI - | | - +---+---+ | - | | | - LCS ACHILLES +--+-----+-----+--------+ - | | | | | | - XX A C VAXA VENERA Mockapetris - -In this example, the root domain has three immediate subdomains: MIL, -EDU, and ARPA. The LCS.MIT.EDU domain has one immediate subdomain named -XX.LCS.MIT.EDU. All of the leaves are also domains. - -3.5. Preferred name syntax - -The DNS specifications attempt to be as general as possible in the rules - - - -Mockapetris [Page 10] - -RFC 1034 Domain Concepts and Facilities November 1987 - - -for constructing domain names. The idea is that the name of any -existing object can be expressed as a domain name with minimal changes. -However, when assigning a domain name for an object, the prudent user -will select a name which satisfies both the rules of the domain system -and any existing rules for the object, whether these rules are published -or implied by existing programs. - -For example, when naming a mail domain, the user should satisfy both the -rules of this memo and those in RFC-822. When creating a new host name, -the old rules for HOSTS.TXT should be followed. This avoids problems -when old software is converted to use domain names. - -The following syntax will result in fewer problems with many -applications that use domain names (e.g., mail, TELNET). - - ::= | " " - - ::=