From 15eb2ac32214256015b9a5d05fbd8c857318f179 Mon Sep 17 00:00:00 2001 From: Jeroen Ruigrok/asmodai Date: Mon, 20 Sep 2004 06:33:19 +0000 Subject: [PATCH 01/13] Add BIND 9.2.4rc7. Notable changes: 1643. [bug] dns_db_closeversion() could leak memory / node references. [RT #11163] 1650. [bug] dig, nslookup: flush standard out after each command. 1654. [bug] isc_result_totext() contained array bounds read error. 1681. [bug] Only set SO_REUSEADDR when a port is specified in isc_socket_bind(). [RT #11742] 1686. [bug] Named sent a extraneous NOTIFY when it received a redundant UPDATE request. [RT #11943] 1687. [bug] Race condition in dispatch. [RT #10272] 1690. [bug] Delay detaching view from the client until UPDATE processing completes when shutting down. [RT #11714] --- contrib/bind-9.2.4rc7/CHANGES | 4679 +++++++++++++++ contrib/bind-9.2.4rc7/COPYRIGHT | 30 + contrib/bind-9.2.4rc7/FAQ | 449 ++ contrib/bind-9.2.4rc7/Makefile.in | 59 + contrib/bind-9.2.4rc7/README | 351 ++ contrib/bind-9.2.4rc7/README.DELETED | 48 + contrib/bind-9.2.4rc7/README.DRAGONFLY | 53 + contrib/bind-9.2.4rc7/acconfig.h | 132 + contrib/bind-9.2.4rc7/bin/check/check-tool.c | 52 + contrib/bind-9.2.4rc7/bin/check/check-tool.h | 34 + contrib/bind-9.2.4rc7/bin/check/named-checkconf.8 | 52 + contrib/bind-9.2.4rc7/bin/check/named-checkconf.c | 138 + .../bind-9.2.4rc7/bin/check/named-checkconf.html | 196 + contrib/bind-9.2.4rc7/bin/check/named-checkzone.8 | 65 + contrib/bind-9.2.4rc7/bin/check/named-checkzone.c | 178 + .../bind-9.2.4rc7/bin/check/named-checkzone.html | 237 + contrib/bind-9.2.4rc7/bin/dig/dig.1 | 370 ++ contrib/bind-9.2.4rc7/bin/dig/dig.c | 1409 +++++ contrib/bind-9.2.4rc7/bin/dig/dig.html | 1158 ++++ contrib/bind-9.2.4rc7/bin/dig/dighost.c | 2723 +++++++++ contrib/bind-9.2.4rc7/bin/dig/host.1 | 130 + contrib/bind-9.2.4rc7/bin/dig/host.c | 728 +++ contrib/bind-9.2.4rc7/bin/dig/host.html | 443 ++ contrib/bind-9.2.4rc7/bin/dig/include/dig/dig.h | 280 + contrib/bind-9.2.4rc7/bin/dig/nslookup.c | 882 +++ contrib/bind-9.2.4rc7/bin/dnssec/dnssec-keygen.8 | 168 + contrib/bind-9.2.4rc7/bin/dnssec/dnssec-keygen.c | 402 ++ .../bind-9.2.4rc7/bin/dnssec/dnssec-keygen.html | 575 ++ .../bind-9.2.4rc7/bin/dnssec/dnssec-makekeyset.8 | 113 + .../bind-9.2.4rc7/bin/dnssec/dnssec-makekeyset.c | 466 ++ .../bin/dnssec/dnssec-makekeyset.html | 407 ++ contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signkey.8 | 108 + contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signkey.c | 471 ++ .../bind-9.2.4rc7/bin/dnssec/dnssec-signkey.html | 407 ++ contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signzone.8 | 155 + contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signzone.c | 1880 ++++++ .../bind-9.2.4rc7/bin/dnssec/dnssec-signzone.html | 556 ++ contrib/bind-9.2.4rc7/bin/dnssec/dnssectool.c | 260 + contrib/bind-9.2.4rc7/bin/dnssec/dnssectool.h | 73 + contrib/bind-9.2.4rc7/bin/named/aclconf.c | 231 + contrib/bind-9.2.4rc7/bin/named/client.c | 2215 +++++++ contrib/bind-9.2.4rc7/bin/named/config.c | 455 ++ contrib/bind-9.2.4rc7/bin/named/control.c | 126 + contrib/bind-9.2.4rc7/bin/named/controlconf.c | 1329 +++++ .../bin/named/include/named/aclconf.h | 72 + .../bind-9.2.4rc7/bin/named/include/named/client.h | 311 + .../bind-9.2.4rc7/bin/named/include/named/config.h | 68 + .../bin/named/include/named/control.h | 82 + .../bin/named/include/named/globals.h | 113 + .../bin/named/include/named/interfacemgr.h | 153 + .../bin/named/include/named/listenlist.h | 104 + .../bind-9.2.4rc7/bin/named/include/named/log.h | 95 + .../bin/named/include/named/logconf.h | 32 + .../bind-9.2.4rc7/bin/named/include/named/lwaddr.h | 34 + .../bin/named/include/named/lwdclient.h | 230 + .../bind-9.2.4rc7/bin/named/include/named/lwresd.h | 111 + .../bin/named/include/named/lwsearch.h | 110 + .../bind-9.2.4rc7/bin/named/include/named/main.h | 29 + .../bind-9.2.4rc7/bin/named/include/named/notify.h | 54 + .../bind-9.2.4rc7/bin/named/include/named/query.h | 87 + .../bind-9.2.4rc7/bin/named/include/named/server.h | 182 + .../bin/named/include/named/sortlist.h | 84 + .../bin/named/include/named/tkeyconf.h | 51 + .../bin/named/include/named/tsigconf.h | 47 + .../bind-9.2.4rc7/bin/named/include/named/types.h | 41 + .../bind-9.2.4rc7/bin/named/include/named/update.h | 49 + .../bind-9.2.4rc7/bin/named/include/named/xfrout.h | 38 + .../bin/named/include/named/zoneconf.h | 61 + contrib/bind-9.2.4rc7/bin/named/interfacemgr.c | 738 +++ contrib/bind-9.2.4rc7/bin/named/listenlist.c | 136 + contrib/bind-9.2.4rc7/bin/named/log.c | 203 + contrib/bind-9.2.4rc7/bin/named/logconf.c | 295 + contrib/bind-9.2.4rc7/bin/named/lwaddr.c | 92 + contrib/bind-9.2.4rc7/bin/named/lwdclient.c | 450 ++ contrib/bind-9.2.4rc7/bin/named/lwderror.c | 78 + contrib/bind-9.2.4rc7/bin/named/lwdgabn.c | 655 +++ contrib/bind-9.2.4rc7/bin/named/lwdgnba.c | 274 + contrib/bind-9.2.4rc7/bin/named/lwdgrbn.c | 513 ++ contrib/bind-9.2.4rc7/bin/named/lwdnoop.c | 86 + contrib/bind-9.2.4rc7/bin/named/lwresd.8 | 140 + contrib/bind-9.2.4rc7/bin/named/lwresd.c | 855 +++ contrib/bind-9.2.4rc7/bin/named/lwresd.html | 541 ++ contrib/bind-9.2.4rc7/bin/named/lwsearch.c | 199 + contrib/bind-9.2.4rc7/bin/named/main.c | 656 +++ contrib/bind-9.2.4rc7/bin/named/named.8 | 167 + contrib/bind-9.2.4rc7/bin/named/named.html | 633 ++ contrib/bind-9.2.4rc7/bin/named/notify.c | 151 + contrib/bind-9.2.4rc7/bin/named/query.c | 3899 +++++++++++++ contrib/bind-9.2.4rc7/bin/named/server.c | 3132 ++++++++++ contrib/bind-9.2.4rc7/bin/named/sortlist.c | 144 + contrib/bind-9.2.4rc7/bin/named/tkeyconf.c | 117 + contrib/bind-9.2.4rc7/bin/named/tsigconf.c | 170 + .../bin/named/unix/include/named/os.h | 58 + contrib/bind-9.2.4rc7/bin/named/unix/os.c | 569 ++ contrib/bind-9.2.4rc7/bin/named/update.c | 2634 +++++++++ contrib/bind-9.2.4rc7/bin/named/xfrout.c | 1709 ++++++ contrib/bind-9.2.4rc7/bin/named/zoneconf.c | 613 ++ contrib/bind-9.2.4rc7/bin/nsupdate/nsupdate.8 | 347 ++ contrib/bind-9.2.4rc7/bin/nsupdate/nsupdate.c | 1974 +++++++ contrib/bind-9.2.4rc7/bin/nsupdate/nsupdate.html | 984 ++++ contrib/bind-9.2.4rc7/bin/rndc/include/rndc/os.h | 44 + contrib/bind-9.2.4rc7/bin/rndc/rndc-confgen.8 | 130 + contrib/bind-9.2.4rc7/bin/rndc/rndc-confgen.c | 322 + contrib/bind-9.2.4rc7/bin/rndc/rndc-confgen.html | 548 ++ contrib/bind-9.2.4rc7/bin/rndc/rndc.8 | 118 + contrib/bind-9.2.4rc7/bin/rndc/rndc.c | 715 +++ contrib/bind-9.2.4rc7/bin/rndc/rndc.conf | 36 + contrib/bind-9.2.4rc7/bin/rndc/rndc.conf.5 | 142 + contrib/bind-9.2.4rc7/bin/rndc/rndc.conf.html | 381 ++ contrib/bind-9.2.4rc7/bin/rndc/rndc.html | 424 ++ contrib/bind-9.2.4rc7/bin/rndc/unix/os.c | 68 + contrib/bind-9.2.4rc7/bin/rndc/util.c | 55 + contrib/bind-9.2.4rc7/bin/rndc/util.h | 49 + contrib/bind-9.2.4rc7/lib/bind/README | 4 + contrib/bind-9.2.4rc7/lib/bind/api | 3 + contrib/bind-9.2.4rc7/lib/bind/bsd/daemon.c | 79 + contrib/bind-9.2.4rc7/lib/bind/bsd/ftruncate.c | 63 + contrib/bind-9.2.4rc7/lib/bind/bsd/gettimeofday.c | 62 + contrib/bind-9.2.4rc7/lib/bind/bsd/mktemp.c | 154 + contrib/bind-9.2.4rc7/lib/bind/bsd/putenv.c | 25 + contrib/bind-9.2.4rc7/lib/bind/bsd/readv.c | 38 + contrib/bind-9.2.4rc7/lib/bind/bsd/setenv.c | 149 + contrib/bind-9.2.4rc7/lib/bind/bsd/setitimer.c | 27 + contrib/bind-9.2.4rc7/lib/bind/bsd/strcasecmp.c | 122 + contrib/bind-9.2.4rc7/lib/bind/bsd/strdup.c | 18 + contrib/bind-9.2.4rc7/lib/bind/bsd/strerror.c | 90 + contrib/bind-9.2.4rc7/lib/bind/bsd/strpbrk.c | 68 + contrib/bind-9.2.4rc7/lib/bind/bsd/strsep.c | 86 + contrib/bind-9.2.4rc7/lib/bind/bsd/strtoul.c | 117 + contrib/bind-9.2.4rc7/lib/bind/bsd/utimes.c | 39 + contrib/bind-9.2.4rc7/lib/bind/bsd/writev.c | 87 + contrib/bind-9.2.4rc7/lib/bind/config.h.in | 45 + contrib/bind-9.2.4rc7/lib/bind/dst/dst_api.c | 1048 ++++ contrib/bind-9.2.4rc7/lib/bind/dst/dst_internal.h | 154 + contrib/bind-9.2.4rc7/lib/bind/dst/hmac_link.c | 468 ++ contrib/bind-9.2.4rc7/lib/bind/dst/md5.h | 101 + contrib/bind-9.2.4rc7/lib/bind/dst/md5_dgst.c | 370 ++ contrib/bind-9.2.4rc7/lib/bind/dst/md5_locl.h | 190 + contrib/bind-9.2.4rc7/lib/bind/dst/support.c | 350 ++ contrib/bind-9.2.4rc7/lib/bind/include/arpa/inet.h | 124 + .../bind-9.2.4rc7/lib/bind/include/arpa/nameser.h | 576 ++ .../lib/bind/include/arpa/nameser_compat.h | 232 + .../bind-9.2.4rc7/lib/bind/include/fd_setsize.h | 9 + contrib/bind-9.2.4rc7/lib/bind/include/hesiod.h | 38 + contrib/bind-9.2.4rc7/lib/bind/include/irp.h | 103 + contrib/bind-9.2.4rc7/lib/bind/include/irs.h | 345 ++ .../lib/bind/include/isc/assertions.h | 122 + contrib/bind-9.2.4rc7/lib/bind/include/isc/ctl.h | 109 + contrib/bind-9.2.4rc7/lib/bind/include/isc/dst.h | 180 + .../bind-9.2.4rc7/lib/bind/include/isc/eventlib.h | 200 + contrib/bind-9.2.4rc7/lib/bind/include/isc/heap.h | 47 + .../lib/bind/include/isc/irpmarshall.h | 115 + contrib/bind-9.2.4rc7/lib/bind/include/isc/list.h | 112 + .../bind-9.2.4rc7/lib/bind/include/isc/logging.h | 112 + .../lib/bind/include/isc/memcluster.h | 49 + contrib/bind-9.2.4rc7/lib/bind/include/isc/misc.h | 39 + contrib/bind-9.2.4rc7/lib/bind/include/isc/tree.h | 58 + contrib/bind-9.2.4rc7/lib/bind/include/netdb.h | 549 ++ contrib/bind-9.2.4rc7/lib/bind/include/netgroup.h | 24 + .../bind-9.2.4rc7/lib/bind/include/res_update.h | 65 + contrib/bind-9.2.4rc7/lib/bind/include/resolv.h | 501 ++ contrib/bind-9.2.4rc7/lib/bind/inet/inet_addr.c | 206 + .../bind-9.2.4rc7/lib/bind/inet/inet_cidr_ntop.c | 259 + .../bind-9.2.4rc7/lib/bind/inet/inet_cidr_pton.c | 275 + contrib/bind-9.2.4rc7/lib/bind/inet/inet_data.c | 44 + contrib/bind-9.2.4rc7/lib/bind/inet/inet_lnaof.c | 63 + .../bind-9.2.4rc7/lib/bind/inet/inet_makeaddr.c | 66 + .../bind-9.2.4rc7/lib/bind/inet/inet_net_ntop.c | 277 + .../bind-9.2.4rc7/lib/bind/inet/inet_net_pton.c | 405 ++ contrib/bind-9.2.4rc7/lib/bind/inet/inet_neta.c | 87 + contrib/bind-9.2.4rc7/lib/bind/inet/inet_netof.c | 62 + contrib/bind-9.2.4rc7/lib/bind/inet/inet_network.c | 104 + contrib/bind-9.2.4rc7/lib/bind/inet/inet_ntoa.c | 62 + contrib/bind-9.2.4rc7/lib/bind/inet/inet_ntop.c | 203 + contrib/bind-9.2.4rc7/lib/bind/inet/inet_pton.c | 222 + contrib/bind-9.2.4rc7/lib/bind/inet/nsap_addr.c | 108 + contrib/bind-9.2.4rc7/lib/bind/irs/dns.c | 153 + contrib/bind-9.2.4rc7/lib/bind/irs/dns_gr.c | 293 + contrib/bind-9.2.4rc7/lib/bind/irs/dns_ho.c | 1150 ++++ contrib/bind-9.2.4rc7/lib/bind/irs/dns_nw.c | 589 ++ contrib/bind-9.2.4rc7/lib/bind/irs/dns_p.h | 50 + contrib/bind-9.2.4rc7/lib/bind/irs/dns_pr.c | 266 + contrib/bind-9.2.4rc7/lib/bind/irs/dns_pw.c | 231 + contrib/bind-9.2.4rc7/lib/bind/irs/dns_sv.c | 298 + contrib/bind-9.2.4rc7/lib/bind/irs/gai_strerror.c | 86 + contrib/bind-9.2.4rc7/lib/bind/irs/gen.c | 430 ++ contrib/bind-9.2.4rc7/lib/bind/irs/gen_gr.c | 492 ++ contrib/bind-9.2.4rc7/lib/bind/irs/gen_ho.c | 391 ++ contrib/bind-9.2.4rc7/lib/bind/irs/gen_ng.c | 172 + contrib/bind-9.2.4rc7/lib/bind/irs/gen_nw.c | 262 + contrib/bind-9.2.4rc7/lib/bind/irs/gen_p.h | 113 + contrib/bind-9.2.4rc7/lib/bind/irs/gen_pr.c | 226 + contrib/bind-9.2.4rc7/lib/bind/irs/gen_pw.c | 233 + contrib/bind-9.2.4rc7/lib/bind/irs/gen_sv.c | 227 + contrib/bind-9.2.4rc7/lib/bind/irs/getaddrinfo.c | 1226 ++++ contrib/bind-9.2.4rc7/lib/bind/irs/getgrent.c | 223 + contrib/bind-9.2.4rc7/lib/bind/irs/getgrent_r.c | 229 + contrib/bind-9.2.4rc7/lib/bind/irs/gethostent.c | 1069 ++++ contrib/bind-9.2.4rc7/lib/bind/irs/gethostent_r.c | 262 + contrib/bind-9.2.4rc7/lib/bind/irs/getnameinfo.c | 322 + contrib/bind-9.2.4rc7/lib/bind/irs/getnetent.c | 343 ++ contrib/bind-9.2.4rc7/lib/bind/irs/getnetent_r.c | 227 + contrib/bind-9.2.4rc7/lib/bind/irs/getnetgrent.c | 156 + contrib/bind-9.2.4rc7/lib/bind/irs/getnetgrent_r.c | 167 + contrib/bind-9.2.4rc7/lib/bind/irs/getprotoent.c | 174 + contrib/bind-9.2.4rc7/lib/bind/irs/getprotoent_r.c | 216 + contrib/bind-9.2.4rc7/lib/bind/irs/getpwent.c | 200 + contrib/bind-9.2.4rc7/lib/bind/irs/getpwent_r.c | 275 + contrib/bind-9.2.4rc7/lib/bind/irs/getservent.c | 177 + contrib/bind-9.2.4rc7/lib/bind/irs/getservent_r.c | 237 + contrib/bind-9.2.4rc7/lib/bind/irs/hesiod.c | 507 ++ contrib/bind-9.2.4rc7/lib/bind/irs/hesiod_p.h | 48 + contrib/bind-9.2.4rc7/lib/bind/irs/irp.c | 592 ++ contrib/bind-9.2.4rc7/lib/bind/irs/irp_gr.c | 408 ++ contrib/bind-9.2.4rc7/lib/bind/irs/irp_ho.c | 429 ++ contrib/bind-9.2.4rc7/lib/bind/irs/irp_ng.c | 272 + contrib/bind-9.2.4rc7/lib/bind/irs/irp_nw.c | 375 ++ contrib/bind-9.2.4rc7/lib/bind/irs/irp_p.h | 59 + contrib/bind-9.2.4rc7/lib/bind/irs/irp_pr.c | 353 ++ contrib/bind-9.2.4rc7/lib/bind/irs/irp_pw.c | 358 ++ contrib/bind-9.2.4rc7/lib/bind/irs/irp_sv.c | 369 ++ contrib/bind-9.2.4rc7/lib/bind/irs/irpmarshall.c | 2344 ++++++++ contrib/bind-9.2.4rc7/lib/bind/irs/irs_data.c | 230 + contrib/bind-9.2.4rc7/lib/bind/irs/irs_data.h | 62 + contrib/bind-9.2.4rc7/lib/bind/irs/irs_p.h | 49 + contrib/bind-9.2.4rc7/lib/bind/irs/lcl.c | 140 + contrib/bind-9.2.4rc7/lib/bind/irs/lcl_gr.c | 354 ++ contrib/bind-9.2.4rc7/lib/bind/irs/lcl_ho.c | 576 ++ contrib/bind-9.2.4rc7/lib/bind/irs/lcl_ng.c | 444 ++ contrib/bind-9.2.4rc7/lib/bind/irs/lcl_nw.c | 371 ++ contrib/bind-9.2.4rc7/lib/bind/irs/lcl_p.h | 50 + contrib/bind-9.2.4rc7/lib/bind/irs/lcl_pr.c | 284 + contrib/bind-9.2.4rc7/lib/bind/irs/lcl_pw.c | 308 + contrib/bind-9.2.4rc7/lib/bind/irs/lcl_sv.c | 431 ++ contrib/bind-9.2.4rc7/lib/bind/irs/nis.c | 154 + contrib/bind-9.2.4rc7/lib/bind/irs/nis_gr.c | 353 ++ contrib/bind-9.2.4rc7/lib/bind/irs/nis_ho.c | 533 ++ contrib/bind-9.2.4rc7/lib/bind/irs/nis_ng.c | 302 + contrib/bind-9.2.4rc7/lib/bind/irs/nis_nw.c | 383 ++ contrib/bind-9.2.4rc7/lib/bind/irs/nis_p.h | 46 + contrib/bind-9.2.4rc7/lib/bind/irs/nis_pr.c | 300 + contrib/bind-9.2.4rc7/lib/bind/irs/nis_pw.c | 287 + contrib/bind-9.2.4rc7/lib/bind/irs/nis_sv.c | 308 + contrib/bind-9.2.4rc7/lib/bind/irs/nul_ng.c | 126 + contrib/bind-9.2.4rc7/lib/bind/irs/pathnames.h | 50 + contrib/bind-9.2.4rc7/lib/bind/irs/util.c | 107 + contrib/bind-9.2.4rc7/lib/bind/isc/assertions.c | 91 + contrib/bind-9.2.4rc7/lib/bind/isc/assertions.mdoc | 138 + contrib/bind-9.2.4rc7/lib/bind/isc/base64.c | 320 + contrib/bind-9.2.4rc7/lib/bind/isc/bitncmp.c | 66 + contrib/bind-9.2.4rc7/lib/bind/isc/bitncmp.mdoc | 82 + contrib/bind-9.2.4rc7/lib/bind/isc/ctl_clnt.c | 602 ++ contrib/bind-9.2.4rc7/lib/bind/isc/ctl_p.c | 186 + contrib/bind-9.2.4rc7/lib/bind/isc/ctl_p.h | 26 + contrib/bind-9.2.4rc7/lib/bind/isc/ctl_srvr.c | 780 +++ contrib/bind-9.2.4rc7/lib/bind/isc/ev_connects.c | 367 ++ contrib/bind-9.2.4rc7/lib/bind/isc/ev_files.c | 283 + contrib/bind-9.2.4rc7/lib/bind/isc/ev_streams.c | 306 + contrib/bind-9.2.4rc7/lib/bind/isc/ev_timers.c | 497 ++ contrib/bind-9.2.4rc7/lib/bind/isc/ev_waits.c | 245 + contrib/bind-9.2.4rc7/lib/bind/isc/eventlib.c | 728 +++ contrib/bind-9.2.4rc7/lib/bind/isc/eventlib.mdoc | 918 +++ contrib/bind-9.2.4rc7/lib/bind/isc/eventlib_p.h | 219 + contrib/bind-9.2.4rc7/lib/bind/isc/heap.c | 230 + contrib/bind-9.2.4rc7/lib/bind/isc/heap.mdoc | 378 ++ contrib/bind-9.2.4rc7/lib/bind/isc/hex.c | 116 + contrib/bind-9.2.4rc7/lib/bind/isc/logging.c | 720 +++ contrib/bind-9.2.4rc7/lib/bind/isc/logging.mdoc | 1056 ++++ contrib/bind-9.2.4rc7/lib/bind/isc/logging_p.h | 60 + contrib/bind-9.2.4rc7/lib/bind/isc/memcluster.c | 545 ++ contrib/bind-9.2.4rc7/lib/bind/isc/memcluster.mdoc | 376 ++ contrib/bind-9.2.4rc7/lib/bind/isc/movefile.c | 35 + contrib/bind-9.2.4rc7/lib/bind/isc/tree.c | 532 ++ contrib/bind-9.2.4rc7/lib/bind/isc/tree.mdoc | 154 + contrib/bind-9.2.4rc7/lib/bind/ltmain.sh | 4950 ++++++++++++++++ contrib/bind-9.2.4rc7/lib/bind/make/includes.in | 44 + contrib/bind-9.2.4rc7/lib/bind/make/mkdep.in | 147 + contrib/bind-9.2.4rc7/lib/bind/make/rules.in | 177 + contrib/bind-9.2.4rc7/lib/bind/mkinstalldirs | 40 + contrib/bind-9.2.4rc7/lib/bind/nameser/ns_date.c | 128 + contrib/bind-9.2.4rc7/lib/bind/nameser/ns_name.c | 963 +++ contrib/bind-9.2.4rc7/lib/bind/nameser/ns_netint.c | 56 + contrib/bind-9.2.4rc7/lib/bind/nameser/ns_parse.c | 203 + contrib/bind-9.2.4rc7/lib/bind/nameser/ns_print.c | 898 +++ .../bind-9.2.4rc7/lib/bind/nameser/ns_samedomain.c | 206 + contrib/bind-9.2.4rc7/lib/bind/nameser/ns_sign.c | 380 ++ contrib/bind-9.2.4rc7/lib/bind/nameser/ns_ttl.c | 159 + contrib/bind-9.2.4rc7/lib/bind/nameser/ns_verify.c | 480 ++ .../lib/bind/port/freebsd/include/sys/bitypes.h | 37 + contrib/bind-9.2.4rc7/lib/bind/port_after.h.in | 395 ++ contrib/bind-9.2.4rc7/lib/bind/port_before.h.in | 138 + contrib/bind-9.2.4rc7/lib/bind/resolv/herror.c | 127 + contrib/bind-9.2.4rc7/lib/bind/resolv/res_comp.c | 251 + contrib/bind-9.2.4rc7/lib/bind/resolv/res_data.c | 291 + contrib/bind-9.2.4rc7/lib/bind/resolv/res_debug.c | 1163 ++++ contrib/bind-9.2.4rc7/lib/bind/resolv/res_debug.h | 34 + .../lib/bind/resolv/res_findzonecut.c | 722 +++ contrib/bind-9.2.4rc7/lib/bind/resolv/res_init.c | 740 +++ .../bind-9.2.4rc7/lib/bind/resolv/res_mkquery.c | 256 + .../bind-9.2.4rc7/lib/bind/resolv/res_mkupdate.c | 1159 ++++ .../bind-9.2.4rc7/lib/bind/resolv/res_mkupdate.h | 24 + .../bind-9.2.4rc7/lib/bind/resolv/res_private.h | 20 + contrib/bind-9.2.4rc7/lib/bind/resolv/res_query.c | 432 ++ contrib/bind-9.2.4rc7/lib/bind/resolv/res_send.c | 1052 ++++ .../bind-9.2.4rc7/lib/bind/resolv/res_sendsigned.c | 159 + contrib/bind-9.2.4rc7/lib/bind/resolv/res_update.c | 212 + contrib/bind-9.2.4rc7/lib/dns/a6.c | 237 + contrib/bind-9.2.4rc7/lib/dns/acl.c | 422 ++ contrib/bind-9.2.4rc7/lib/dns/adb.c | 4124 +++++++++++++ contrib/bind-9.2.4rc7/lib/dns/api | 3 + contrib/bind-9.2.4rc7/lib/dns/byaddr.c | 325 + contrib/bind-9.2.4rc7/lib/dns/cache.c | 963 +++ contrib/bind-9.2.4rc7/lib/dns/callbacks.c | 111 + contrib/bind-9.2.4rc7/lib/dns/compress.c | 316 + contrib/bind-9.2.4rc7/lib/dns/db.c | 793 +++ contrib/bind-9.2.4rc7/lib/dns/dbiterator.c | 141 + contrib/bind-9.2.4rc7/lib/dns/dbtable.c | 291 + contrib/bind-9.2.4rc7/lib/dns/diff.c | 528 ++ contrib/bind-9.2.4rc7/lib/dns/dispatch.c | 2105 +++++++ contrib/bind-9.2.4rc7/lib/dns/dnssec.c | 817 +++ contrib/bind-9.2.4rc7/lib/dns/forward.c | 195 + contrib/bind-9.2.4rc7/lib/dns/gen-unix.h | 92 + contrib/bind-9.2.4rc7/lib/dns/gen-win32.h | 290 + contrib/bind-9.2.4rc7/lib/dns/gen.c | 864 +++ contrib/bind-9.2.4rc7/lib/dns/include/dns/a6.h | 82 + contrib/bind-9.2.4rc7/lib/dns/include/dns/acl.h | 204 + contrib/bind-9.2.4rc7/lib/dns/include/dns/adb.h | 574 ++ contrib/bind-9.2.4rc7/lib/dns/include/dns/bit.h | 37 + contrib/bind-9.2.4rc7/lib/dns/include/dns/byaddr.h | 165 + contrib/bind-9.2.4rc7/lib/dns/include/dns/cache.h | 240 + .../bind-9.2.4rc7/lib/dns/include/dns/callbacks.h | 83 + contrib/bind-9.2.4rc7/lib/dns/include/dns/cert.h | 67 + .../bind-9.2.4rc7/lib/dns/include/dns/compress.h | 248 + contrib/bind-9.2.4rc7/lib/dns/include/dns/db.h | 1244 ++++ .../bind-9.2.4rc7/lib/dns/include/dns/dbiterator.h | 298 + .../bind-9.2.4rc7/lib/dns/include/dns/dbtable.h | 164 + contrib/bind-9.2.4rc7/lib/dns/include/dns/diff.h | 274 + .../bind-9.2.4rc7/lib/dns/include/dns/dispatch.h | 420 ++ contrib/bind-9.2.4rc7/lib/dns/include/dns/dnssec.h | 164 + contrib/bind-9.2.4rc7/lib/dns/include/dns/events.h | 69 + .../bind-9.2.4rc7/lib/dns/include/dns/fixedname.h | 83 + .../bind-9.2.4rc7/lib/dns/include/dns/forward.h | 98 + .../bind-9.2.4rc7/lib/dns/include/dns/journal.h | 263 + .../bind-9.2.4rc7/lib/dns/include/dns/keyflags.h | 52 + .../bind-9.2.4rc7/lib/dns/include/dns/keytable.h | 255 + .../bind-9.2.4rc7/lib/dns/include/dns/keyvalues.h | 92 + contrib/bind-9.2.4rc7/lib/dns/include/dns/lib.h | 39 + contrib/bind-9.2.4rc7/lib/dns/include/dns/log.h | 103 + contrib/bind-9.2.4rc7/lib/dns/include/dns/lookup.h | 138 + contrib/bind-9.2.4rc7/lib/dns/include/dns/master.h | 186 + .../bind-9.2.4rc7/lib/dns/include/dns/masterdump.h | 181 + .../bind-9.2.4rc7/lib/dns/include/dns/message.h | 1263 ++++ contrib/bind-9.2.4rc7/lib/dns/include/dns/name.h | 1361 +++++ contrib/bind-9.2.4rc7/lib/dns/include/dns/ncache.h | 122 + contrib/bind-9.2.4rc7/lib/dns/include/dns/nxt.h | 68 + contrib/bind-9.2.4rc7/lib/dns/include/dns/peer.h | 170 + contrib/bind-9.2.4rc7/lib/dns/include/dns/rbt.h | 823 +++ contrib/bind-9.2.4rc7/lib/dns/include/dns/rcode.h | 96 + contrib/bind-9.2.4rc7/lib/dns/include/dns/rdata.h | 652 +++ .../bind-9.2.4rc7/lib/dns/include/dns/rdataclass.h | 79 + .../bind-9.2.4rc7/lib/dns/include/dns/rdatalist.h | 104 + .../bind-9.2.4rc7/lib/dns/include/dns/rdataset.h | 418 ++ .../lib/dns/include/dns/rdatasetiter.h | 171 + .../bind-9.2.4rc7/lib/dns/include/dns/rdataslab.h | 151 + .../bind-9.2.4rc7/lib/dns/include/dns/rdatatype.h | 81 + .../bind-9.2.4rc7/lib/dns/include/dns/request.h | 336 ++ .../bind-9.2.4rc7/lib/dns/include/dns/resolver.h | 354 ++ contrib/bind-9.2.4rc7/lib/dns/include/dns/result.h | 171 + contrib/bind-9.2.4rc7/lib/dns/include/dns/rootns.h | 35 + contrib/bind-9.2.4rc7/lib/dns/include/dns/sdb.h | 192 + contrib/bind-9.2.4rc7/lib/dns/include/dns/secalg.h | 69 + .../bind-9.2.4rc7/lib/dns/include/dns/secproto.h | 69 + contrib/bind-9.2.4rc7/lib/dns/include/dns/soa.h | 80 + contrib/bind-9.2.4rc7/lib/dns/include/dns/ssu.h | 157 + contrib/bind-9.2.4rc7/lib/dns/include/dns/stats.h | 57 + contrib/bind-9.2.4rc7/lib/dns/include/dns/tcpmsg.h | 145 + contrib/bind-9.2.4rc7/lib/dns/include/dns/time.h | 70 + contrib/bind-9.2.4rc7/lib/dns/include/dns/timer.h | 50 + contrib/bind-9.2.4rc7/lib/dns/include/dns/tkey.h | 196 + contrib/bind-9.2.4rc7/lib/dns/include/dns/tsig.h | 242 + contrib/bind-9.2.4rc7/lib/dns/include/dns/ttl.h | 76 + contrib/bind-9.2.4rc7/lib/dns/include/dns/types.h | 304 + .../bind-9.2.4rc7/lib/dns/include/dns/validator.h | 186 + contrib/bind-9.2.4rc7/lib/dns/include/dns/view.h | 769 +++ contrib/bind-9.2.4rc7/lib/dns/include/dns/xfrin.h | 99 + contrib/bind-9.2.4rc7/lib/dns/include/dns/zone.h | 1327 +++++ .../bind-9.2.4rc7/lib/dns/include/dns/zonekey.h | 40 + contrib/bind-9.2.4rc7/lib/dns/include/dns/zt.h | 167 + contrib/bind-9.2.4rc7/lib/dns/journal.c | 1908 ++++++ contrib/bind-9.2.4rc7/lib/dns/keytable.c | 396 ++ contrib/bind-9.2.4rc7/lib/dns/lib.c | 62 + contrib/bind-9.2.4rc7/lib/dns/log.c | 93 + contrib/bind-9.2.4rc7/lib/dns/lookup.c | 492 ++ contrib/bind-9.2.4rc7/lib/dns/master.c | 2105 +++++++ contrib/bind-9.2.4rc7/lib/dns/masterdump.c | 1129 ++++ contrib/bind-9.2.4rc7/lib/dns/message.c | 3093 ++++++++++ contrib/bind-9.2.4rc7/lib/dns/name.c | 3342 +++++++++++ contrib/bind-9.2.4rc7/lib/dns/ncache.c | 379 ++ contrib/bind-9.2.4rc7/lib/dns/nxt.c | 186 + contrib/bind-9.2.4rc7/lib/dns/peer.c | 502 ++ contrib/bind-9.2.4rc7/lib/dns/rbt.c | 2682 +++++++++ contrib/bind-9.2.4rc7/lib/dns/rbtdb.c | 5385 +++++++++++++++++ contrib/bind-9.2.4rc7/lib/dns/rbtdb.h | 43 + contrib/bind-9.2.4rc7/lib/dns/rbtdb64.c | 21 + contrib/bind-9.2.4rc7/lib/dns/rbtdb64.h | 44 + contrib/bind-9.2.4rc7/lib/dns/rdata.c | 2087 +++++++ .../bind-9.2.4rc7/lib/dns/rdata/any_255/tsig_250.c | 566 ++ .../bind-9.2.4rc7/lib/dns/rdata/any_255/tsig_250.h | 39 + .../bind-9.2.4rc7/lib/dns/rdata/generic/afsdb_18.c | 267 + .../bind-9.2.4rc7/lib/dns/rdata/generic/afsdb_18.h | 33 + .../bind-9.2.4rc7/lib/dns/rdata/generic/cert_37.c | 254 + .../bind-9.2.4rc7/lib/dns/rdata/generic/cert_37.h | 34 + .../bind-9.2.4rc7/lib/dns/rdata/generic/cname_5.c | 207 + .../bind-9.2.4rc7/lib/dns/rdata/generic/cname_5.h | 29 + .../bind-9.2.4rc7/lib/dns/rdata/generic/dname_39.c | 208 + .../bind-9.2.4rc7/lib/dns/rdata/generic/dname_39.h | 31 + .../bind-9.2.4rc7/lib/dns/rdata/generic/gpos_27.c | 227 + .../bind-9.2.4rc7/lib/dns/rdata/generic/gpos_27.h | 36 + .../bind-9.2.4rc7/lib/dns/rdata/generic/hinfo_13.c | 199 + .../bind-9.2.4rc7/lib/dns/rdata/generic/hinfo_13.h | 32 + .../bind-9.2.4rc7/lib/dns/rdata/generic/isdn_20.c | 209 + .../bind-9.2.4rc7/lib/dns/rdata/generic/isdn_20.h | 34 + .../bind-9.2.4rc7/lib/dns/rdata/generic/key_25.c | 287 + .../bind-9.2.4rc7/lib/dns/rdata/generic/key_25.h | 36 + .../bind-9.2.4rc7/lib/dns/rdata/generic/loc_29.c | 740 +++ .../bind-9.2.4rc7/lib/dns/rdata/generic/loc_29.h | 42 + contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mb_7.c | 210 + contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mb_7.h | 29 + contrib/bind-9.2.4rc7/lib/dns/rdata/generic/md_3.c | 211 + contrib/bind-9.2.4rc7/lib/dns/rdata/generic/md_3.h | 30 + contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mf_4.c | 210 + contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mf_4.h | 29 + contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mg_8.c | 206 + contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mg_8.h | 29 + .../bind-9.2.4rc7/lib/dns/rdata/generic/minfo_14.c | 276 + .../bind-9.2.4rc7/lib/dns/rdata/generic/minfo_14.h | 30 + contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mr_9.c | 206 + contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mr_9.h | 29 + .../bind-9.2.4rc7/lib/dns/rdata/generic/mx_15.c | 248 + .../bind-9.2.4rc7/lib/dns/rdata/generic/mx_15.h | 30 + contrib/bind-9.2.4rc7/lib/dns/rdata/generic/ns_2.c | 210 + contrib/bind-9.2.4rc7/lib/dns/rdata/generic/ns_2.h | 30 + .../bind-9.2.4rc7/lib/dns/rdata/generic/null_10.c | 167 + .../bind-9.2.4rc7/lib/dns/rdata/generic/null_10.h | 31 + .../bind-9.2.4rc7/lib/dns/rdata/generic/nxt_30.c | 304 + .../bind-9.2.4rc7/lib/dns/rdata/generic/nxt_30.h | 33 + .../bind-9.2.4rc7/lib/dns/rdata/generic/opt_41.c | 256 + .../bind-9.2.4rc7/lib/dns/rdata/generic/opt_41.h | 54 + .../bind-9.2.4rc7/lib/dns/rdata/generic/proforma.c | 146 + .../bind-9.2.4rc7/lib/dns/rdata/generic/proforma.h | 29 + .../bind-9.2.4rc7/lib/dns/rdata/generic/ptr_12.c | 207 + .../bind-9.2.4rc7/lib/dns/rdata/generic/ptr_12.h | 29 + .../bind-9.2.4rc7/lib/dns/rdata/generic/rp_17.c | 273 + .../bind-9.2.4rc7/lib/dns/rdata/generic/rp_17.h | 33 + .../bind-9.2.4rc7/lib/dns/rdata/generic/rt_21.c | 269 + .../bind-9.2.4rc7/lib/dns/rdata/generic/rt_21.h | 32 + .../bind-9.2.4rc7/lib/dns/rdata/generic/sig_24.c | 553 ++ .../bind-9.2.4rc7/lib/dns/rdata/generic/sig_24.h | 41 + .../bind-9.2.4rc7/lib/dns/rdata/generic/soa_6.c | 387 ++ .../bind-9.2.4rc7/lib/dns/rdata/generic/soa_6.h | 36 + .../bind-9.2.4rc7/lib/dns/rdata/generic/tkey_249.c | 530 ++ .../bind-9.2.4rc7/lib/dns/rdata/generic/tkey_249.h | 40 + .../bind-9.2.4rc7/lib/dns/rdata/generic/txt_16.c | 213 + .../bind-9.2.4rc7/lib/dns/rdata/generic/txt_16.h | 51 + .../lib/dns/rdata/generic/unspec_103.c | 164 + .../lib/dns/rdata/generic/unspec_103.h | 30 + .../bind-9.2.4rc7/lib/dns/rdata/generic/x25_19.c | 194 + .../bind-9.2.4rc7/lib/dns/rdata/generic/x25_19.h | 32 + contrib/bind-9.2.4rc7/lib/dns/rdata/hs_4/a_1.c | 205 + contrib/bind-9.2.4rc7/lib/dns/rdata/hs_4/a_1.h | 28 + contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/a6_38.c | 415 ++ contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/a6_38.h | 33 + contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/a_1.c | 211 + contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/a_1.h | 28 + contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/aaaa_28.c | 208 + contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/aaaa_28.h | 30 + contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/kx_36.c | 261 + contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/kx_36.h | 32 + .../bind-9.2.4rc7/lib/dns/rdata/in_1/naptr_35.c | 551 ++ .../bind-9.2.4rc7/lib/dns/rdata/in_1/naptr_35.h | 39 + .../bind-9.2.4rc7/lib/dns/rdata/in_1/nsap-ptr_23.c | 218 + .../bind-9.2.4rc7/lib/dns/rdata/in_1/nsap-ptr_23.h | 31 + contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/nsap_22.c | 228 + contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/nsap_22.h | 32 + contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/px_26.c | 347 ++ contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/px_26.h | 33 + contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/srv_33.c | 329 ++ contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/srv_33.h | 36 + contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/wks_11.c | 324 + contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/wks_11.h | 32 + .../bind-9.2.4rc7/lib/dns/rdata/rdatastructpre.h | 42 + .../bind-9.2.4rc7/lib/dns/rdata/rdatastructsuf.h | 22 + contrib/bind-9.2.4rc7/lib/dns/rdatalist.c | 152 + contrib/bind-9.2.4rc7/lib/dns/rdatalist_p.h | 48 + contrib/bind-9.2.4rc7/lib/dns/rdataset.c | 555 ++ contrib/bind-9.2.4rc7/lib/dns/rdatasetiter.c | 78 + contrib/bind-9.2.4rc7/lib/dns/rdataslab.c | 597 ++ contrib/bind-9.2.4rc7/lib/dns/request.c | 1353 +++++ contrib/bind-9.2.4rc7/lib/dns/resolver.c | 5384 +++++++++++++++++ contrib/bind-9.2.4rc7/lib/dns/result.c | 265 + contrib/bind-9.2.4rc7/lib/dns/rootns.c | 246 + contrib/bind-9.2.4rc7/lib/dns/sdb.c | 1471 +++++ contrib/bind-9.2.4rc7/lib/dns/sec/dst/dst_api.c | 1119 ++++ .../bind-9.2.4rc7/lib/dns/sec/dst/dst_internal.h | 142 + contrib/bind-9.2.4rc7/lib/dns/sec/dst/dst_lib.c | 65 + contrib/bind-9.2.4rc7/lib/dns/sec/dst/dst_parse.c | 432 ++ contrib/bind-9.2.4rc7/lib/dns/sec/dst/dst_parse.h | 95 + contrib/bind-9.2.4rc7/lib/dns/sec/dst/dst_result.c | 85 + .../bind-9.2.4rc7/lib/dns/sec/dst/gssapi_link.c | 229 + contrib/bind-9.2.4rc7/lib/dns/sec/dst/gssapictx.c | 262 + contrib/bind-9.2.4rc7/lib/dns/sec/dst/hmac_link.c | 290 + .../lib/dns/sec/dst/include/dst/dst.h | 545 ++ .../lib/dns/sec/dst/include/dst/gssapi.h | 56 + .../lib/dns/sec/dst/include/dst/lib.h | 39 + .../lib/dns/sec/dst/include/dst/result.h | 67 + contrib/bind-9.2.4rc7/lib/dns/sec/dst/key.c | 126 + .../bind-9.2.4rc7/lib/dns/sec/dst/openssl_link.c | 167 + .../bind-9.2.4rc7/lib/dns/sec/dst/openssldh_link.c | 572 ++ .../lib/dns/sec/dst/openssldsa_link.c | 444 ++ .../lib/dns/sec/dst/opensslrsa_link.c | 519 ++ contrib/bind-9.2.4rc7/lib/dns/soa.c | 109 + contrib/bind-9.2.4rc7/lib/dns/ssu.c | 357 ++ contrib/bind-9.2.4rc7/lib/dns/stats.c | 53 + contrib/bind-9.2.4rc7/lib/dns/tcpmsg.c | 240 + contrib/bind-9.2.4rc7/lib/dns/time.c | 171 + contrib/bind-9.2.4rc7/lib/dns/timer.c | 58 + contrib/bind-9.2.4rc7/lib/dns/tkey.c | 1244 ++++ contrib/bind-9.2.4rc7/lib/dns/tsig.c | 1216 ++++ contrib/bind-9.2.4rc7/lib/dns/ttl.c | 205 + contrib/bind-9.2.4rc7/lib/dns/validator.c | 1695 ++++++ contrib/bind-9.2.4rc7/lib/dns/version.c | 24 + contrib/bind-9.2.4rc7/lib/dns/view.c | 1303 +++++ contrib/bind-9.2.4rc7/lib/dns/xfrin.c | 1385 +++++ contrib/bind-9.2.4rc7/lib/dns/zone.c | 6159 ++++++++++++++++++++ contrib/bind-9.2.4rc7/lib/dns/zonekey.c | 53 + contrib/bind-9.2.4rc7/lib/dns/zt.c | 316 + contrib/bind-9.2.4rc7/lib/isc/api | 3 + contrib/bind-9.2.4rc7/lib/isc/assertions.c | 93 + contrib/bind-9.2.4rc7/lib/isc/base64.c | 246 + contrib/bind-9.2.4rc7/lib/isc/bitstring.c | 125 + contrib/bind-9.2.4rc7/lib/isc/buffer.c | 411 ++ contrib/bind-9.2.4rc7/lib/isc/bufferlist.c | 62 + contrib/bind-9.2.4rc7/lib/isc/commandline.c | 222 + contrib/bind-9.2.4rc7/lib/isc/entropy.c | 1250 ++++ contrib/bind-9.2.4rc7/lib/isc/error.c | 101 + contrib/bind-9.2.4rc7/lib/isc/event.c | 87 + contrib/bind-9.2.4rc7/lib/isc/fsaccess.c | 101 + contrib/bind-9.2.4rc7/lib/isc/hash.c | 387 ++ contrib/bind-9.2.4rc7/lib/isc/heap.c | 252 + contrib/bind-9.2.4rc7/lib/isc/hex.c | 199 + contrib/bind-9.2.4rc7/lib/isc/hmacmd5.c | 113 + contrib/bind-9.2.4rc7/lib/isc/include/isc/app.h | 212 + .../bind-9.2.4rc7/lib/isc/include/isc/assertions.h | 120 + contrib/bind-9.2.4rc7/lib/isc/include/isc/base64.h | 97 + .../bind-9.2.4rc7/lib/isc/include/isc/bitstring.h | 152 + .../bind-9.2.4rc7/lib/isc/include/isc/boolean.h | 29 + contrib/bind-9.2.4rc7/lib/isc/include/isc/buffer.h | 800 +++ .../bind-9.2.4rc7/lib/isc/include/isc/bufferlist.h | 86 + .../lib/isc/include/isc/commandline.h | 47 + .../bind-9.2.4rc7/lib/isc/include/isc/entropy.h | 288 + contrib/bind-9.2.4rc7/lib/isc/include/isc/error.h | 55 + contrib/bind-9.2.4rc7/lib/isc/include/isc/event.h | 115 + .../bind-9.2.4rc7/lib/isc/include/isc/eventclass.h | 53 + contrib/bind-9.2.4rc7/lib/isc/include/isc/file.h | 246 + .../lib/isc/include/isc/formatcheck.h | 34 + .../bind-9.2.4rc7/lib/isc/include/isc/fsaccess.h | 177 + contrib/bind-9.2.4rc7/lib/isc/include/isc/hash.h | 175 + contrib/bind-9.2.4rc7/lib/isc/include/isc/heap.h | 51 + contrib/bind-9.2.4rc7/lib/isc/include/isc/hex.h | 96 + .../bind-9.2.4rc7/lib/isc/include/isc/hmacmd5.h | 60 + .../lib/isc/include/isc/interfaceiter.h | 134 + contrib/bind-9.2.4rc7/lib/isc/include/isc/ipv6.h | 140 + contrib/bind-9.2.4rc7/lib/isc/include/isc/lang.h | 31 + contrib/bind-9.2.4rc7/lib/isc/include/isc/lex.h | 395 ++ contrib/bind-9.2.4rc7/lib/isc/include/isc/lfsr.h | 133 + contrib/bind-9.2.4rc7/lib/isc/include/isc/lib.h | 39 + contrib/bind-9.2.4rc7/lib/isc/include/isc/list.h | 180 + contrib/bind-9.2.4rc7/lib/isc/include/isc/log.h | 880 +++ contrib/bind-9.2.4rc7/lib/isc/include/isc/magic.h | 40 + contrib/bind-9.2.4rc7/lib/isc/include/isc/md5.h | 72 + contrib/bind-9.2.4rc7/lib/isc/include/isc/mem.h | 437 ++ contrib/bind-9.2.4rc7/lib/isc/include/isc/msgcat.h | 132 + contrib/bind-9.2.4rc7/lib/isc/include/isc/msgs.h | 180 + .../bind-9.2.4rc7/lib/isc/include/isc/mutexblock.h | 69 + .../bind-9.2.4rc7/lib/isc/include/isc/netaddr.h | 130 + .../bind-9.2.4rc7/lib/isc/include/isc/ondestroy.h | 108 + contrib/bind-9.2.4rc7/lib/isc/include/isc/os.h | 36 + .../lib/isc/include/isc/platform.h.in | 197 + contrib/bind-9.2.4rc7/lib/isc/include/isc/print.h | 69 + contrib/bind-9.2.4rc7/lib/isc/include/isc/quota.h | 106 + contrib/bind-9.2.4rc7/lib/isc/include/isc/random.h | 60 + .../lib/isc/include/isc/ratelimiter.h | 120 + .../bind-9.2.4rc7/lib/isc/include/isc/refcount.h | 164 + contrib/bind-9.2.4rc7/lib/isc/include/isc/region.h | 80 + .../bind-9.2.4rc7/lib/isc/include/isc/resource.h | 85 + contrib/bind-9.2.4rc7/lib/isc/include/isc/result.h | 105 + .../lib/isc/include/isc/resultclass.h | 54 + contrib/bind-9.2.4rc7/lib/isc/include/isc/rwlock.h | 95 + contrib/bind-9.2.4rc7/lib/isc/include/isc/serial.h | 76 + contrib/bind-9.2.4rc7/lib/isc/include/isc/sha1.h | 58 + .../bind-9.2.4rc7/lib/isc/include/isc/sockaddr.h | 187 + contrib/bind-9.2.4rc7/lib/isc/include/isc/socket.h | 687 +++ contrib/bind-9.2.4rc7/lib/isc/include/isc/stdio.h | 67 + contrib/bind-9.2.4rc7/lib/isc/include/isc/string.h | 56 + contrib/bind-9.2.4rc7/lib/isc/include/isc/symtab.h | 127 + contrib/bind-9.2.4rc7/lib/isc/include/isc/task.h | 601 ++ .../bind-9.2.4rc7/lib/isc/include/isc/taskpool.h | 107 + contrib/bind-9.2.4rc7/lib/isc/include/isc/timer.h | 327 ++ contrib/bind-9.2.4rc7/lib/isc/include/isc/types.h | 103 + contrib/bind-9.2.4rc7/lib/isc/include/isc/util.h | 211 + contrib/bind-9.2.4rc7/lib/isc/inet_aton.c | 195 + contrib/bind-9.2.4rc7/lib/isc/inet_ntop.c | 194 + contrib/bind-9.2.4rc7/lib/isc/inet_pton.c | 211 + contrib/bind-9.2.4rc7/lib/isc/lex.c | 904 +++ contrib/bind-9.2.4rc7/lib/isc/lfsr.c | 161 + contrib/bind-9.2.4rc7/lib/isc/lib.c | 77 + contrib/bind-9.2.4rc7/lib/isc/log.c | 1773 ++++++ contrib/bind-9.2.4rc7/lib/isc/md5.c | 249 + contrib/bind-9.2.4rc7/lib/isc/mem.c | 1726 ++++++ contrib/bind-9.2.4rc7/lib/isc/mutexblock.c | 57 + contrib/bind-9.2.4rc7/lib/isc/netaddr.c | 285 + contrib/bind-9.2.4rc7/lib/isc/nls/msgcat.c | 129 + .../bind-9.2.4rc7/lib/isc/nothreads/condition.c | 32 + .../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 + contrib/bind-9.2.4rc7/lib/isc/nothreads/mutex.c | 28 + contrib/bind-9.2.4rc7/lib/isc/nothreads/thread.c | 28 + contrib/bind-9.2.4rc7/lib/isc/ondestroy.c | 83 + contrib/bind-9.2.4rc7/lib/isc/print.c | 546 ++ contrib/bind-9.2.4rc7/lib/isc/pthreads/condition.c | 72 + .../lib/isc/pthreads/include/isc/condition.h | 63 + .../lib/isc/pthreads/include/isc/mutex.h | 131 + .../lib/isc/pthreads/include/isc/once.h | 48 + .../lib/isc/pthreads/include/isc/thread.h | 52 + contrib/bind-9.2.4rc7/lib/isc/pthreads/mutex.c | 222 + contrib/bind-9.2.4rc7/lib/isc/pthreads/thread.c | 68 + contrib/bind-9.2.4rc7/lib/isc/quota.c | 82 + contrib/bind-9.2.4rc7/lib/isc/random.c | 102 + contrib/bind-9.2.4rc7/lib/isc/ratelimiter.c | 276 + contrib/bind-9.2.4rc7/lib/isc/result.c | 208 + contrib/bind-9.2.4rc7/lib/isc/rwlock.c | 417 ++ contrib/bind-9.2.4rc7/lib/isc/serial.c | 56 + contrib/bind-9.2.4rc7/lib/isc/sha1.c | 309 + contrib/bind-9.2.4rc7/lib/isc/sockaddr.c | 429 ++ contrib/bind-9.2.4rc7/lib/isc/string.c | 111 + contrib/bind-9.2.4rc7/lib/isc/symtab.c | 250 + contrib/bind-9.2.4rc7/lib/isc/task.c | 1289 ++++ contrib/bind-9.2.4rc7/lib/isc/task_p.h | 29 + contrib/bind-9.2.4rc7/lib/isc/taskpool.c | 89 + contrib/bind-9.2.4rc7/lib/isc/timer.c | 864 +++ contrib/bind-9.2.4rc7/lib/isc/timer_p.h | 29 + contrib/bind-9.2.4rc7/lib/isc/unix/app.c | 664 +++ contrib/bind-9.2.4rc7/lib/isc/unix/dir.c | 253 + contrib/bind-9.2.4rc7/lib/isc/unix/entropy.c | 349 ++ contrib/bind-9.2.4rc7/lib/isc/unix/errno2result.c | 121 + contrib/bind-9.2.4rc7/lib/isc/unix/errno2result.h | 37 + contrib/bind-9.2.4rc7/lib/isc/unix/file.c | 315 + contrib/bind-9.2.4rc7/lib/isc/unix/fsaccess.c | 90 + contrib/bind-9.2.4rc7/lib/isc/unix/ifiter_ioctl.c | 404 ++ contrib/bind-9.2.4rc7/lib/isc/unix/ifiter_sysctl.c | 290 + .../bind-9.2.4rc7/lib/isc/unix/include/isc/dir.h | 100 + .../bind-9.2.4rc7/lib/isc/unix/include/isc/int.h | 53 + .../lib/isc/unix/include/isc/keyboard.h | 50 + .../bind-9.2.4rc7/lib/isc/unix/include/isc/net.h | 275 + .../bind-9.2.4rc7/lib/isc/unix/include/isc/netdb.h | 56 + .../lib/isc/unix/include/isc/offset.h | 44 + .../bind-9.2.4rc7/lib/isc/unix/include/isc/stat.h | 53 + .../lib/isc/unix/include/isc/stdtime.h | 47 + .../lib/isc/unix/include/isc/strerror.h | 43 + .../lib/isc/unix/include/isc/syslog.h | 45 + .../bind-9.2.4rc7/lib/isc/unix/include/isc/time.h | 298 + contrib/bind-9.2.4rc7/lib/isc/unix/interfaceiter.c | 152 + contrib/bind-9.2.4rc7/lib/isc/unix/ipv6.c | 23 + contrib/bind-9.2.4rc7/lib/isc/unix/keyboard.c | 126 + contrib/bind-9.2.4rc7/lib/isc/unix/net.c | 153 + contrib/bind-9.2.4rc7/lib/isc/unix/os.c | 92 + contrib/bind-9.2.4rc7/lib/isc/unix/resource.c | 204 + contrib/bind-9.2.4rc7/lib/isc/unix/socket.c | 3453 +++++++++++ contrib/bind-9.2.4rc7/lib/isc/unix/socket_p.h | 33 + contrib/bind-9.2.4rc7/lib/isc/unix/stdio.c | 117 + contrib/bind-9.2.4rc7/lib/isc/unix/stdtime.c | 83 + contrib/bind-9.2.4rc7/lib/isc/unix/strerror.c | 74 + contrib/bind-9.2.4rc7/lib/isc/unix/syslog.c | 82 + contrib/bind-9.2.4rc7/lib/isc/unix/time.c | 409 ++ contrib/bind-9.2.4rc7/lib/isc/version.c | 24 + contrib/bind-9.2.4rc7/lib/isccc/alist.c | 297 + contrib/bind-9.2.4rc7/lib/isccc/api | 3 + contrib/bind-9.2.4rc7/lib/isccc/base64.c | 63 + contrib/bind-9.2.4rc7/lib/isccc/cc.c | 805 +++ contrib/bind-9.2.4rc7/lib/isccc/ccmsg.c | 220 + .../bind-9.2.4rc7/lib/isccc/include/isccc/alist.h | 72 + .../bind-9.2.4rc7/lib/isccc/include/isccc/base64.h | 70 + contrib/bind-9.2.4rc7/lib/isccc/include/isccc/cc.h | 88 + .../bind-9.2.4rc7/lib/isccc/include/isccc/ccmsg.h | 132 + .../bind-9.2.4rc7/lib/isccc/include/isccc/events.h | 35 + .../bind-9.2.4rc7/lib/isccc/include/isccc/lib.h | 40 + .../bind-9.2.4rc7/lib/isccc/include/isccc/result.h | 52 + .../bind-9.2.4rc7/lib/isccc/include/isccc/sexpr.h | 107 + .../bind-9.2.4rc7/lib/isccc/include/isccc/symtab.h | 123 + .../lib/isccc/include/isccc/symtype.h | 29 + .../bind-9.2.4rc7/lib/isccc/include/isccc/types.h | 38 + .../bind-9.2.4rc7/lib/isccc/include/isccc/util.h | 211 + contrib/bind-9.2.4rc7/lib/isccc/lib.c | 63 + contrib/bind-9.2.4rc7/lib/isccc/result.c | 70 + contrib/bind-9.2.4rc7/lib/isccc/sexpr.c | 310 + contrib/bind-9.2.4rc7/lib/isccc/symtab.c | 278 + contrib/bind-9.2.4rc7/lib/isccc/version.c | 24 + contrib/bind-9.2.4rc7/lib/isccfg/api | 3 + contrib/bind-9.2.4rc7/lib/isccfg/check.c | 737 +++ .../bind-9.2.4rc7/lib/isccfg/include/isccfg/cfg.h | 418 ++ .../lib/isccfg/include/isccfg/check.h | 54 + .../bind-9.2.4rc7/lib/isccfg/include/isccfg/log.h | 53 + contrib/bind-9.2.4rc7/lib/isccfg/log.c | 50 + contrib/bind-9.2.4rc7/lib/isccfg/parser.c | 3971 +++++++++++++ contrib/bind-9.2.4rc7/lib/isccfg/version.c | 24 + contrib/bind-9.2.4rc7/lib/lwres/api | 3 + contrib/bind-9.2.4rc7/lib/lwres/assert_p.h | 33 + contrib/bind-9.2.4rc7/lib/lwres/context.c | 380 ++ contrib/bind-9.2.4rc7/lib/lwres/context_p.h | 59 + contrib/bind-9.2.4rc7/lib/lwres/gai_strerror.c | 52 + contrib/bind-9.2.4rc7/lib/lwres/getaddrinfo.c | 691 +++ contrib/bind-9.2.4rc7/lib/lwres/gethost.c | 219 + contrib/bind-9.2.4rc7/lib/lwres/getipnode.c | 848 +++ contrib/bind-9.2.4rc7/lib/lwres/getnameinfo.c | 285 + contrib/bind-9.2.4rc7/lib/lwres/getrrset.c | 211 + contrib/bind-9.2.4rc7/lib/lwres/herror.c | 101 + .../lib/lwres/include/lwres/context.h | 133 + .../bind-9.2.4rc7/lib/lwres/include/lwres/int.h | 32 + .../bind-9.2.4rc7/lib/lwres/include/lwres/ipv6.h | 118 + .../bind-9.2.4rc7/lib/lwres/include/lwres/lang.h | 31 + .../bind-9.2.4rc7/lib/lwres/include/lwres/list.h | 119 + .../lib/lwres/include/lwres/lwbuffer.h | 402 ++ .../lib/lwres/include/lwres/lwpacket.h | 124 + .../bind-9.2.4rc7/lib/lwres/include/lwres/lwres.h | 578 ++ .../lib/lwres/include/lwres/netdb.h.in | 518 ++ .../lib/lwres/include/lwres/platform.h.in | 91 + .../bind-9.2.4rc7/lib/lwres/include/lwres/result.h | 40 + contrib/bind-9.2.4rc7/lib/lwres/lwbuffer.c | 287 + contrib/bind-9.2.4rc7/lib/lwres/lwconfig.c | 703 +++ contrib/bind-9.2.4rc7/lib/lwres/lwinetaton.c | 203 + contrib/bind-9.2.4rc7/lib/lwres/lwinetntop.c | 191 + contrib/bind-9.2.4rc7/lib/lwres/lwinetpton.c | 206 + contrib/bind-9.2.4rc7/lib/lwres/lwpacket.c | 85 + contrib/bind-9.2.4rc7/lib/lwres/lwres_gabn.c | 415 ++ contrib/bind-9.2.4rc7/lib/lwres/lwres_gnba.c | 328 ++ contrib/bind-9.2.4rc7/lib/lwres/lwres_grbn.c | 416 ++ contrib/bind-9.2.4rc7/lib/lwres/lwres_noop.c | 255 + contrib/bind-9.2.4rc7/lib/lwres/lwresutil.c | 491 ++ contrib/bind-9.2.4rc7/lib/lwres/man/lwres.3 | 159 + contrib/bind-9.2.4rc7/lib/lwres/man/lwres.html | 447 ++ contrib/bind-9.2.4rc7/lib/lwres/man/lwres_buffer.3 | 279 + .../bind-9.2.4rc7/lib/lwres/man/lwres_buffer.html | 632 ++ contrib/bind-9.2.4rc7/lib/lwres/man/lwres_config.3 | 107 + .../bind-9.2.4rc7/lib/lwres/man/lwres_config.html | 298 + .../bind-9.2.4rc7/lib/lwres/man/lwres_context.3 | 196 + .../bind-9.2.4rc7/lib/lwres/man/lwres_context.html | 522 ++ contrib/bind-9.2.4rc7/lib/lwres/man/lwres_gabn.3 | 195 + .../bind-9.2.4rc7/lib/lwres/man/lwres_gabn.html | 445 ++ .../lib/lwres/man/lwres_gai_strerror.3 | 88 + .../lib/lwres/man/lwres_gai_strerror.html | 297 + .../lib/lwres/man/lwres_getaddrinfo.3 | 249 + .../lib/lwres/man/lwres_getaddrinfo.html | 725 +++ .../bind-9.2.4rc7/lib/lwres/man/lwres_gethostent.3 | 272 + .../lib/lwres/man/lwres_gethostent.html | 830 +++ .../bind-9.2.4rc7/lib/lwres/man/lwres_getipnode.3 | 189 + .../lib/lwres/man/lwres_getipnode.html | 532 ++ .../lib/lwres/man/lwres_getnameinfo.3 | 86 + .../lib/lwres/man/lwres_getnameinfo.html | 306 + .../lib/lwres/man/lwres_getrrsetbyname.3 | 144 + .../lib/lwres/man/lwres_getrrsetbyname.html | 374 ++ contrib/bind-9.2.4rc7/lib/lwres/man/lwres_gnba.3 | 188 + .../bind-9.2.4rc7/lib/lwres/man/lwres_gnba.html | 411 ++ .../bind-9.2.4rc7/lib/lwres/man/lwres_hstrerror.3 | 69 + .../lib/lwres/man/lwres_hstrerror.html | 245 + .../bind-9.2.4rc7/lib/lwres/man/lwres_inetntop.3 | 54 + .../lib/lwres/man/lwres_inetntop.html | 189 + contrib/bind-9.2.4rc7/lib/lwres/man/lwres_noop.3 | 162 + .../bind-9.2.4rc7/lib/lwres/man/lwres_noop.html | 412 ++ contrib/bind-9.2.4rc7/lib/lwres/man/lwres_packet.3 | 151 + .../bind-9.2.4rc7/lib/lwres/man/lwres_packet.html | 376 ++ .../bind-9.2.4rc7/lib/lwres/man/lwres_resutil.3 | 153 + .../bind-9.2.4rc7/lib/lwres/man/lwres_resutil.html | 415 ++ .../lib/lwres/unix/include/lwres/net.h | 127 + contrib/bind-9.2.4rc7/lib/lwres/version.c | 24 + contrib/bind-9.2.4rc7/version | 10 + 787 files changed, 271512 insertions(+), 0 deletions(-) create mode 100644 contrib/bind-9.2.4rc7/CHANGES create mode 100644 contrib/bind-9.2.4rc7/COPYRIGHT create mode 100644 contrib/bind-9.2.4rc7/FAQ create mode 100644 contrib/bind-9.2.4rc7/Makefile.in create mode 100644 contrib/bind-9.2.4rc7/README create mode 100644 contrib/bind-9.2.4rc7/README.DELETED create mode 100644 contrib/bind-9.2.4rc7/README.DRAGONFLY create mode 100644 contrib/bind-9.2.4rc7/acconfig.h create mode 100644 contrib/bind-9.2.4rc7/bin/check/check-tool.c create mode 100644 contrib/bind-9.2.4rc7/bin/check/check-tool.h create mode 100644 contrib/bind-9.2.4rc7/bin/check/named-checkconf.8 create mode 100644 contrib/bind-9.2.4rc7/bin/check/named-checkconf.c create mode 100644 contrib/bind-9.2.4rc7/bin/check/named-checkconf.html create mode 100644 contrib/bind-9.2.4rc7/bin/check/named-checkzone.8 create mode 100644 contrib/bind-9.2.4rc7/bin/check/named-checkzone.c create mode 100644 contrib/bind-9.2.4rc7/bin/check/named-checkzone.html create mode 100644 contrib/bind-9.2.4rc7/bin/dig/dig.1 create mode 100644 contrib/bind-9.2.4rc7/bin/dig/dig.c create mode 100644 contrib/bind-9.2.4rc7/bin/dig/dig.html create mode 100644 contrib/bind-9.2.4rc7/bin/dig/dighost.c create mode 100644 contrib/bind-9.2.4rc7/bin/dig/host.1 create mode 100644 contrib/bind-9.2.4rc7/bin/dig/host.c create mode 100644 contrib/bind-9.2.4rc7/bin/dig/host.html create mode 100644 contrib/bind-9.2.4rc7/bin/dig/include/dig/dig.h create mode 100644 contrib/bind-9.2.4rc7/bin/dig/nslookup.c create mode 100644 contrib/bind-9.2.4rc7/bin/dnssec/dnssec-keygen.8 create mode 100644 contrib/bind-9.2.4rc7/bin/dnssec/dnssec-keygen.c create mode 100644 contrib/bind-9.2.4rc7/bin/dnssec/dnssec-keygen.html create mode 100644 contrib/bind-9.2.4rc7/bin/dnssec/dnssec-makekeyset.8 create mode 100644 contrib/bind-9.2.4rc7/bin/dnssec/dnssec-makekeyset.c create mode 100644 contrib/bind-9.2.4rc7/bin/dnssec/dnssec-makekeyset.html create mode 100644 contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signkey.8 create mode 100644 contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signkey.c create mode 100644 contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signkey.html create mode 100644 contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signzone.8 create mode 100644 contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signzone.c create mode 100644 contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signzone.html create mode 100644 contrib/bind-9.2.4rc7/bin/dnssec/dnssectool.c create mode 100644 contrib/bind-9.2.4rc7/bin/dnssec/dnssectool.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/aclconf.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/client.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/config.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/control.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/controlconf.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/aclconf.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/client.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/config.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/control.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/globals.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/interfacemgr.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/listenlist.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/log.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/logconf.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/lwaddr.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/lwdclient.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/lwresd.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/lwsearch.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/main.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/notify.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/query.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/server.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/sortlist.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/tkeyconf.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/tsigconf.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/types.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/update.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/xfrout.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/include/named/zoneconf.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/interfacemgr.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/listenlist.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/log.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/logconf.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/lwaddr.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/lwdclient.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/lwderror.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/lwdgabn.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/lwdgnba.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/lwdgrbn.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/lwdnoop.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/lwresd.8 create mode 100644 contrib/bind-9.2.4rc7/bin/named/lwresd.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/lwresd.html create mode 100644 contrib/bind-9.2.4rc7/bin/named/lwsearch.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/main.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/named.8 create mode 100644 contrib/bind-9.2.4rc7/bin/named/named.html create mode 100644 contrib/bind-9.2.4rc7/bin/named/notify.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/query.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/server.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/sortlist.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/tkeyconf.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/tsigconf.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/unix/include/named/os.h create mode 100644 contrib/bind-9.2.4rc7/bin/named/unix/os.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/update.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/xfrout.c create mode 100644 contrib/bind-9.2.4rc7/bin/named/zoneconf.c create mode 100644 contrib/bind-9.2.4rc7/bin/nsupdate/nsupdate.8 create mode 100644 contrib/bind-9.2.4rc7/bin/nsupdate/nsupdate.c create mode 100644 contrib/bind-9.2.4rc7/bin/nsupdate/nsupdate.html create mode 100644 contrib/bind-9.2.4rc7/bin/rndc/include/rndc/os.h create mode 100644 contrib/bind-9.2.4rc7/bin/rndc/rndc-confgen.8 create mode 100644 contrib/bind-9.2.4rc7/bin/rndc/rndc-confgen.c create mode 100644 contrib/bind-9.2.4rc7/bin/rndc/rndc-confgen.html create mode 100644 contrib/bind-9.2.4rc7/bin/rndc/rndc.8 create mode 100644 contrib/bind-9.2.4rc7/bin/rndc/rndc.c create mode 100644 contrib/bind-9.2.4rc7/bin/rndc/rndc.conf create mode 100644 contrib/bind-9.2.4rc7/bin/rndc/rndc.conf.5 create mode 100644 contrib/bind-9.2.4rc7/bin/rndc/rndc.conf.html create mode 100644 contrib/bind-9.2.4rc7/bin/rndc/rndc.html create mode 100644 contrib/bind-9.2.4rc7/bin/rndc/unix/os.c create mode 100644 contrib/bind-9.2.4rc7/bin/rndc/util.c create mode 100644 contrib/bind-9.2.4rc7/bin/rndc/util.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/README create mode 100644 contrib/bind-9.2.4rc7/lib/bind/api create mode 100644 contrib/bind-9.2.4rc7/lib/bind/bsd/daemon.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/bsd/ftruncate.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/bsd/gettimeofday.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/bsd/mktemp.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/bsd/putenv.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/bsd/readv.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/bsd/setenv.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/bsd/setitimer.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/bsd/strcasecmp.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/bsd/strdup.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/bsd/strerror.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/bsd/strpbrk.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/bsd/strsep.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/bsd/strtoul.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/bsd/utimes.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/bsd/writev.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/config.h.in create mode 100644 contrib/bind-9.2.4rc7/lib/bind/dst/dst_api.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/dst/dst_internal.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/dst/hmac_link.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/dst/md5.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/dst/md5_dgst.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/dst/md5_locl.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/dst/support.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/arpa/inet.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/arpa/nameser.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/arpa/nameser_compat.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/fd_setsize.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/hesiod.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/irp.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/irs.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/isc/assertions.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/isc/ctl.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/isc/dst.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/isc/eventlib.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/isc/heap.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/isc/irpmarshall.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/isc/list.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/isc/logging.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/isc/memcluster.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/isc/misc.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/isc/tree.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/netdb.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/netgroup.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/res_update.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/include/resolv.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/inet/inet_addr.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/inet/inet_cidr_ntop.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/inet/inet_cidr_pton.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/inet/inet_data.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/inet/inet_lnaof.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/inet/inet_makeaddr.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/inet/inet_net_ntop.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/inet/inet_net_pton.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/inet/inet_neta.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/inet/inet_netof.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/inet/inet_network.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/inet/inet_ntoa.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/inet/inet_ntop.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/inet/inet_pton.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/inet/nsap_addr.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/dns.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/dns_gr.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/dns_ho.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/dns_nw.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/dns_p.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/dns_pr.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/dns_pw.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/dns_sv.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/gai_strerror.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/gen.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/gen_gr.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/gen_ho.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/gen_ng.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/gen_nw.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/gen_p.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/gen_pr.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/gen_pw.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/gen_sv.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/getaddrinfo.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/getgrent.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/getgrent_r.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/gethostent.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/gethostent_r.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/getnameinfo.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/getnetent.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/getnetent_r.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/getnetgrent.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/getnetgrent_r.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/getprotoent.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/getprotoent_r.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/getpwent.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/getpwent_r.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/getservent.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/getservent_r.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/hesiod.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/hesiod_p.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/irp.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/irp_gr.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/irp_ho.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/irp_ng.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/irp_nw.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/irp_p.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/irp_pr.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/irp_pw.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/irp_sv.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/irpmarshall.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/irs_data.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/irs_data.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/irs_p.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/lcl.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/lcl_gr.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/lcl_ho.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/lcl_ng.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/lcl_nw.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/lcl_p.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/lcl_pr.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/lcl_pw.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/lcl_sv.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/nis.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/nis_gr.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/nis_ho.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/nis_ng.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/nis_nw.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/nis_p.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/nis_pr.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/nis_pw.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/nis_sv.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/nul_ng.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/pathnames.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/irs/util.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/assertions.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/assertions.mdoc create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/base64.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/bitncmp.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/bitncmp.mdoc create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/ctl_clnt.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/ctl_p.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/ctl_p.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/ctl_srvr.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/ev_connects.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/ev_files.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/ev_streams.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/ev_timers.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/ev_waits.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/eventlib.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/eventlib.mdoc create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/eventlib_p.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/heap.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/heap.mdoc create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/hex.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/logging.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/logging.mdoc create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/logging_p.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/memcluster.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/memcluster.mdoc create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/movefile.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/tree.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/isc/tree.mdoc create mode 100644 contrib/bind-9.2.4rc7/lib/bind/ltmain.sh create mode 100644 contrib/bind-9.2.4rc7/lib/bind/make/includes.in create mode 100644 contrib/bind-9.2.4rc7/lib/bind/make/mkdep.in create mode 100644 contrib/bind-9.2.4rc7/lib/bind/make/rules.in create mode 100644 contrib/bind-9.2.4rc7/lib/bind/mkinstalldirs create mode 100644 contrib/bind-9.2.4rc7/lib/bind/nameser/ns_date.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/nameser/ns_name.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/nameser/ns_netint.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/nameser/ns_parse.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/nameser/ns_print.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/nameser/ns_samedomain.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/nameser/ns_sign.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/nameser/ns_ttl.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/nameser/ns_verify.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/port/freebsd/include/sys/bitypes.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/port_after.h.in create mode 100644 contrib/bind-9.2.4rc7/lib/bind/port_before.h.in create mode 100644 contrib/bind-9.2.4rc7/lib/bind/resolv/herror.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/resolv/res_comp.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/resolv/res_data.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/resolv/res_debug.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/resolv/res_debug.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/resolv/res_findzonecut.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/resolv/res_init.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/resolv/res_mkquery.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/resolv/res_mkupdate.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/resolv/res_mkupdate.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/resolv/res_private.h create mode 100644 contrib/bind-9.2.4rc7/lib/bind/resolv/res_query.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/resolv/res_send.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/resolv/res_sendsigned.c create mode 100644 contrib/bind-9.2.4rc7/lib/bind/resolv/res_update.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/a6.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/acl.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/adb.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/api create mode 100644 contrib/bind-9.2.4rc7/lib/dns/byaddr.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/cache.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/callbacks.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/compress.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/db.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/dbiterator.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/dbtable.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/diff.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/dispatch.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/dnssec.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/forward.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/gen-unix.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/gen-win32.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/gen.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/a6.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/acl.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/adb.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/bit.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/byaddr.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/cache.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/callbacks.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/cert.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/compress.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/db.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/dbiterator.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/dbtable.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/diff.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/dispatch.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/dnssec.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/events.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/fixedname.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/forward.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/journal.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/keyflags.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/keytable.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/keyvalues.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/lib.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/log.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/lookup.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/master.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/masterdump.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/message.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/name.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/ncache.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/nxt.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/peer.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/rbt.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/rcode.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/rdata.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/rdataclass.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/rdatalist.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/rdataset.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/rdatasetiter.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/rdataslab.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/rdatatype.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/request.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/resolver.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/result.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/rootns.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/sdb.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/secalg.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/secproto.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/soa.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/ssu.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/stats.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/tcpmsg.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/time.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/timer.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/tkey.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/tsig.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/ttl.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/types.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/validator.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/view.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/xfrin.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/zone.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/zonekey.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/include/dns/zt.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/journal.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/keytable.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/lib.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/log.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/lookup.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/master.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/masterdump.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/message.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/name.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/ncache.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/nxt.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/peer.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rbt.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rbtdb.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rbtdb.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rbtdb64.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rbtdb64.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/any_255/tsig_250.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/any_255/tsig_250.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/afsdb_18.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/afsdb_18.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/cert_37.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/cert_37.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/cname_5.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/cname_5.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/dname_39.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/dname_39.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/gpos_27.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/gpos_27.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/hinfo_13.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/hinfo_13.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/isdn_20.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/isdn_20.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/key_25.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/key_25.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/loc_29.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/loc_29.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mb_7.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mb_7.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/md_3.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/md_3.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mf_4.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mf_4.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mg_8.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mg_8.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/minfo_14.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/minfo_14.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mr_9.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mr_9.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mx_15.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/mx_15.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/ns_2.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/ns_2.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/null_10.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/null_10.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/nxt_30.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/nxt_30.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/opt_41.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/opt_41.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/proforma.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/proforma.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/ptr_12.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/ptr_12.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/rp_17.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/rp_17.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/rt_21.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/rt_21.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/sig_24.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/sig_24.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/soa_6.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/soa_6.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/tkey_249.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/tkey_249.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/txt_16.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/txt_16.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/unspec_103.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/unspec_103.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/x25_19.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/generic/x25_19.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/hs_4/a_1.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/hs_4/a_1.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/a6_38.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/a6_38.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/a_1.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/a_1.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/aaaa_28.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/aaaa_28.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/kx_36.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/kx_36.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/naptr_35.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/naptr_35.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/nsap-ptr_23.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/nsap-ptr_23.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/nsap_22.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/nsap_22.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/px_26.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/px_26.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/srv_33.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/srv_33.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/wks_11.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/in_1/wks_11.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/rdatastructpre.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdata/rdatastructsuf.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdatalist.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdatalist_p.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdataset.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdatasetiter.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rdataslab.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/request.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/resolver.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/result.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/rootns.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sdb.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/dst_api.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/dst_internal.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/dst_lib.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/dst_parse.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/dst_parse.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/dst_result.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/gssapi_link.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/gssapictx.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/hmac_link.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/include/dst/dst.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/include/dst/gssapi.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/include/dst/lib.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/include/dst/result.h create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/key.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/openssl_link.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/openssldh_link.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/openssldsa_link.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/sec/dst/opensslrsa_link.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/soa.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/ssu.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/stats.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/tcpmsg.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/time.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/timer.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/tkey.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/tsig.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/ttl.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/validator.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/version.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/view.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/xfrin.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/zone.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/zonekey.c create mode 100644 contrib/bind-9.2.4rc7/lib/dns/zt.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/api create mode 100644 contrib/bind-9.2.4rc7/lib/isc/assertions.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/base64.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/bitstring.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/buffer.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/bufferlist.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/commandline.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/entropy.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/error.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/event.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/fsaccess.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/hash.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/heap.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/hex.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/hmacmd5.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/app.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/assertions.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/base64.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/bitstring.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/boolean.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/buffer.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/bufferlist.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/commandline.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/entropy.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/error.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/event.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/eventclass.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/file.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/formatcheck.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/fsaccess.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/hash.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/heap.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/hex.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/hmacmd5.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/interfaceiter.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/ipv6.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/lang.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/lex.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/lfsr.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/lib.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/list.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/log.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/magic.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/md5.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/mem.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/msgcat.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/msgs.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/mutexblock.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/netaddr.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/ondestroy.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/os.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/platform.h.in create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/print.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/quota.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/random.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/ratelimiter.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/refcount.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/region.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/resource.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/result.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/resultclass.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/rwlock.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/serial.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/sha1.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/sockaddr.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/socket.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/stdio.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/string.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/symtab.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/task.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/taskpool.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/timer.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/types.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/include/isc/util.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/inet_aton.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/inet_ntop.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/inet_pton.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/lex.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/lfsr.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/lib.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/log.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/md5.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/mem.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/mutexblock.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/netaddr.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/nls/msgcat.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/nothreads/condition.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/nothreads/include/isc/condition.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/nothreads/include/isc/mutex.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/nothreads/include/isc/once.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/nothreads/include/isc/thread.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/nothreads/mutex.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/nothreads/thread.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/ondestroy.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/print.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/pthreads/condition.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/pthreads/include/isc/condition.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/pthreads/include/isc/mutex.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/pthreads/include/isc/once.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/pthreads/include/isc/thread.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/pthreads/mutex.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/pthreads/thread.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/quota.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/random.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/ratelimiter.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/result.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/rwlock.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/serial.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/sha1.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/sockaddr.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/string.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/symtab.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/task.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/task_p.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/taskpool.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/timer.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/timer_p.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/app.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/dir.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/entropy.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/errno2result.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/errno2result.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/file.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/fsaccess.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/ifiter_ioctl.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/ifiter_sysctl.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/include/isc/dir.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/include/isc/int.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/include/isc/keyboard.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/include/isc/net.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/include/isc/netdb.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/include/isc/offset.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/include/isc/stat.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/include/isc/stdtime.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/include/isc/strerror.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/include/isc/syslog.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/include/isc/time.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/interfaceiter.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/ipv6.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/keyboard.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/net.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/os.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/resource.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/socket.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/socket_p.h create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/stdio.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/stdtime.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/strerror.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/syslog.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/unix/time.c create mode 100644 contrib/bind-9.2.4rc7/lib/isc/version.c create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/alist.c create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/api create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/base64.c create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/cc.c create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/ccmsg.c create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/include/isccc/alist.h create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/include/isccc/base64.h create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/include/isccc/cc.h create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/include/isccc/ccmsg.h create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/include/isccc/events.h create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/include/isccc/lib.h create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/include/isccc/result.h create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/include/isccc/sexpr.h create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/include/isccc/symtab.h create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/include/isccc/symtype.h create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/include/isccc/types.h create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/include/isccc/util.h create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/lib.c create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/result.c create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/sexpr.c create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/symtab.c create mode 100644 contrib/bind-9.2.4rc7/lib/isccc/version.c create mode 100644 contrib/bind-9.2.4rc7/lib/isccfg/api create mode 100644 contrib/bind-9.2.4rc7/lib/isccfg/check.c create mode 100644 contrib/bind-9.2.4rc7/lib/isccfg/include/isccfg/cfg.h create mode 100644 contrib/bind-9.2.4rc7/lib/isccfg/include/isccfg/check.h create mode 100644 contrib/bind-9.2.4rc7/lib/isccfg/include/isccfg/log.h create mode 100644 contrib/bind-9.2.4rc7/lib/isccfg/log.c create mode 100644 contrib/bind-9.2.4rc7/lib/isccfg/parser.c create mode 100644 contrib/bind-9.2.4rc7/lib/isccfg/version.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/api create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/assert_p.h create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/context.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/context_p.h create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/gai_strerror.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/getaddrinfo.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/gethost.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/getipnode.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/getnameinfo.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/getrrset.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/herror.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/include/lwres/context.h create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/include/lwres/int.h create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/include/lwres/ipv6.h create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/include/lwres/lang.h create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/include/lwres/list.h create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/include/lwres/lwbuffer.h create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/include/lwres/lwpacket.h create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/include/lwres/lwres.h create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/include/lwres/netdb.h.in create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/include/lwres/platform.h.in create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/include/lwres/result.h create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/lwbuffer.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/lwconfig.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/lwinetaton.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/lwinetntop.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/lwinetpton.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/lwpacket.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/lwres_gabn.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/lwres_gnba.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/lwres_grbn.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/lwres_noop.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/lwresutil.c create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres.3 create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres.html create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_buffer.3 create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_buffer.html create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_config.3 create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_config.html create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_context.3 create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_context.html create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_gabn.3 create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_gabn.html create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_gai_strerror.3 create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_gai_strerror.html create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_getaddrinfo.3 create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_getaddrinfo.html create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_gethostent.3 create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_gethostent.html create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_getipnode.3 create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_getipnode.html create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_getnameinfo.3 create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_getnameinfo.html create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_getrrsetbyname.3 create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_getrrsetbyname.html create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_gnba.3 create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_gnba.html create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_hstrerror.3 create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_hstrerror.html create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_inetntop.3 create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_inetntop.html create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_noop.3 create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_noop.html create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_packet.3 create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_packet.html create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_resutil.3 create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/man/lwres_resutil.html create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/unix/include/lwres/net.h create mode 100644 contrib/bind-9.2.4rc7/lib/lwres/version.c create mode 100644 contrib/bind-9.2.4rc7/version diff --git a/contrib/bind-9.2.4rc7/CHANGES b/contrib/bind-9.2.4rc7/CHANGES new file mode 100644 index 0000000..6155ca9 --- /dev/null +++ b/contrib/bind-9.2.4rc7/CHANGES @@ -0,0 +1,4679 @@ + + --- 9.2.4rc7 released --- + +1694. [bug] Report if the builtin views of "_default" / "_bind" + are defined in named.conf. [RT #12023] + +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() macros contained a 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] + + --- 9.2.4rc6 released --- + +1685. [bug] Change #1679 loop tests weren't quite right. + +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] + +1679. [bug] When there was a single nameserver with multiple + addresses for a zone not all addresses were tried. + [RT #11706] + +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. + +1669. [bug] Restore "update forwarding denied" log messages + accidentally suppressed by change #1633. [RT# 11657] + +1660. [bug] win32: connection_reset_fix() was being called + unconditionally. [RT #11595] + + --- 9.2.4rc5 released --- + +1655. [bug] Logging multiple versions w/o a size was broken. + [RT #11446] + +1654. [bug] isc_result_totext() contained array bounds read + error. + +1650. [bug] dig, nslookup: flush standard out after each command. + +1649. [bug] Silence "unexpected non-minimal diff" message. + [RT #11206] + +1646. [bug] win32: logging file versions didn't work with + non-UNC filenames. [RT#11486] + +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] + + --- 9.2.4rc4 released --- + +1640. [bug] win32: isc_socket_cancel(ISC_SOCKCANCEL_ACCEPT) was + incorrectly closing the socket. [RT #11291] + +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] + +1627. [bug] win32: sockets were not being closed when the + last external reference was removed. [RT# 11179] + + --- 9.2.4rc3 released --- + +1623. [bug] A serial number of zero was being displayed in the + "sending notifies" log message when also-notify was + used. [RT #11177] + +1621. [bug] match-destinations did not work for IPv6 TCP queries. + [RT# 11156] + +1619. [bug] Missing ISC_LIST_UNLINK in end_reserved_dispatches(). + [RT# 11118] + +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] + +1610. [bug] On dual stack machines "dig -b" failed to set the + address type to be looked up with "@server". + [RT #11069] + +1600. [bug] Duplicate zone pre-load checks were not case + insensitive. + +1599. [bug] Fix memory leak on error path when checking named.conf. + + --- 9.2.4rc2 released --- + +1607. [bug] dig, host and nslookup were still using random() + to generate query ids. [RT# 11013] + +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] + +1455. [bug] missing from server grammar in + doc/misc/options. [RT #5616] + +1593. [bug] rndc should return "unknown command" to unknown + commands. [RT# 10642] + + --- 9.2.4rc1 released --- + +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. + +1588. [bug] win32: TCP sockets could become blocked. [RT #10115] + +1587. [bug] dns_message_settsigkey() failed to clear existing key. + [RT #10590] + +1585. [bug] allow-v6-synthesis was not performing lookups under + IP6.INT. allow-v6-synthesis now performs a nibble + lookups under IP6.ARPA rather than a bitstring lookups. + [RT #10497] + + NOTE: allow-v6-synthesis has been deprecated. + +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] + +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] + +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] + +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] + +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] + +1559. [port] named should ignore SIGFSZ. + +1556. [bug] nsupdate now treats all names as fully qualified. + [RT #6427] + +1553. [bug] The windows socket code could stop accepting + connections. + +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(). + +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. [bug] Reversed timestamp sanity test on SIG. [RT #10095] + +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] + +1536. [bug] Windows socket code failed to log a error description + when returning ISC_R_UNEXPECTED. [RT #9998] + +1535. [bug] dig -x of a partial IPv4 address broken. [RT# 9949] + +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] + +1025. [bug] Don't use multicast addresses to resolve iterative + queries. [RT #101] + + --- 9.2.3 released --- + +1525. [bug] dns_cache_create() could trigger a REQUIRE + failure in isc_mem_put() during error cleanup. + +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] + +1518. [bug] dns_nxt_buildrdata(), and hence dns_nxt_build(), + contained a off-by-one error when working out the + number of octets in the bitmap. + +1514. [bug] named: isc_hash_destroy() was being called too early. + [RT #9160] + +1513. [doc] Add "US" to root-delegation-only exclude list. + + --- 9.2.3rc4 released --- + +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. + + --- 9.2.3rc3 released --- + +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(). + + --- 9.2.3rc2 released --- + +1505. [bug] Uninitialized rdataset in sdb. [RT #8750] + +1504. [func] New zone type "delegation-only". + +1503. [port] win32: install libeay32.dll outside of system32. + + --- 9.2.3rc1 released --- + +1499. [bug] isc_random need to be seeded better if arc4random() + is not used. + +1498. [port] bsdos: 5.x support. + +1497. [protocol] dig, nslookup and host now perform nibble lookups + under IP6.ARPA, use -i for IP6.INT (dig and host). + lwres now uses IP6.ARPA. + +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. [doc] A6 and "bitstring" labels are now experimental. + +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. [port] win32: port unreachables were blocking further i/o + on sockets (Windows 2000 SP2 and later). + +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] + +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. [bug] win32: we were leaking a bits in the exception + fd_set resulting in "Socket operation on non-socket" + errors from select(). [RT #2966] + +1456. [contrib] gen-data-queryperf.py from Stephane Bortzmeyer. + +1453. [doc] ARM: $GENERATE example wasn't accurate. [RT #5298] + +1452. [bug] Bad #ifdef, ISC_RFC2335 -> ISC_RFC2535. + +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. + +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. + +1439. [bug] Named could return NOERROR with certain NOTIFY + failures. Return NOTAUTH if the NOTIFY zone is + not being served. + +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. + +1437. [bug] Leave space for stdio to work in. [RT #5033] + +1434. [bug] "rndc reconfig" failed to initiate the initial + zone transfer of new slave zones. + +1431. [bug] isc_print_snprintf() "%s" with precision could walk off + end of argument. [RT #5191] + +1429. [bug] Prevent the cache getting locked to old servers. + +1424. [bug] EDNS version not being correctly printed. + +1423. [contrib] queryperf: added A6 and SRV. + +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. + +1416. [bug] Empty node should return NOERROR NODATA, not NXDOMAIN. + [RT #4715] + +1411. [bug] empty nodes should stop wildcard matches. [RT #4802] + +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. + +1401. [bug] adb wasn't clearing state when the timer expired. + +1399. [bug] Use serial number arithmetic when testing SIG + timestamps. [RT #4268] + +1397. [bug] J.ROOT-SERVERS.NET is now 192.58.128.30. + +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] + +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] + +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] + +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. + +1366. [contrib] queryperf usage was incomplete. Add '-h' for help. + +1348. [port] win32: Rewrote code to use I/O Completion Ports + in socket.c and eliminating a host of socket + errors. Performance is enhanced. + +1333. [contrib] queryperf now reports a summary of returned + rcodes (-c), rcodes are printed in mnemonic form (-v). + +1299. [bug] Set AI_ADDRCONFIG when looking up addresses + via getaddrinfo() (affects dig, host, nslookup, rndc + and nsupdate). + +1199. [doc] ARM reference to RFC 2157 should have been RFC 1918. + [RT #2436] + +1122. [tuning] Resolution timeout reduced from 90 to 30 seconds. + [RT #2046] + + 992. [doc] dig: ~/.digrc is now documented. + + --- 9.2.2 released --- + +1428. [port] hpux: temporary work around of hpux 11.11 interface + scanning. + +1427. [bug] Race condition in adb with threaded build. + +1426. [cleanup] Disable RFC2535 style DNSSEC. This is incompatible + with the forthcoming DS style DNSSEC. + +1425. [port] linux/libbind: define __USE_MISC when testing *_r() + function prototypes in netdb.h. [RT #4921] + +1395. [port] OpenSSL 0.9.7 defines CRYPTO_LOCK_ENGINE but doesn't + have a working implementation. [RT #4079] + +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. + + --- 9.2.2rc1 released --- + +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. + +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 + +1346. [bug] Win32: select timeout in socket.c was too small + as value given was meant to be milliseconds and + timeval structure requires microseconds. This + caused high CPU loads with a compute bound loop. + [RT #3358] + +1345. [port] Use a explicit -Wformat with gcc. Not all versions + include it in -Wall. + +1340. [bug] Delay and spread out the startup refresh load. + +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. + +1330. [bug] When processing events (non-threaded) only allow + the task one chance to use to use its quantum. + +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] + +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]. + +1311. [bug] lwres_getrrsetbyname leaked memory. [RT #3159] + +1310. [bug] 'rndc stop' failed to cause zones to be flushed + sometimes. [RT #3157] + +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. + +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. + +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. + +1284. [bug] The RTT estimate on unused servers was not aged. + [RT #2569] + +1282. [port] libbind: hpux 11.11 interface scanning. + +1280. [bug] libbind: escape '(' and ')' when converting to + presentation form. + +1279. [port] Darwin uses (unsigned long) for size_t. [RT #2590] + +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 . + +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. + +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. + +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. + +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] + +1248. [bug] DESTDIR was not being propagated between makes. + +1245. [bug] Treat ENOBUFS, ENOMEM and ENFILE as soft errors for + accept(). + +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] + +1209. [bug] Dig, host, nslookup were not checking the message ids + on the responses. [RT #2454] + +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. + +1089. [func] libbind: inet_{cidr,net}_{pton,ntop}() now have IPv6 + support. + + --- 9.2.1 released --- + +1251. [port] win32: a make file contained absolute version specific + references. + +1249. [bug] Missing masters clause was not handled gracefully. + [RT #2703] + +1244. [bug] Receiving a TCP message from a blackhole address would + prevent further messages being received over that + interface. + +1178. [bug] Follow and cache (if appropriate) A6 and other + data chains to completion in the additional section. + + --- 9.2.1rc2 released --- + +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] + +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] + +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] + +1218. [bug] Named incorrectly returned SERVFAIL rather than + NOTAUTH when there was a TSIG BADTIME error. [RT #2519] + +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. + +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] + +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] + + --- 9.2.1rc1 released --- + +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. + +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] + +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] Best effort parsing didn't handle packet truncation. + +1191. [bug] A dynamic update removing the last non-apex name in + a secure zone would fail. [RT #2399] + +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. + +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. + +1176. [doc] Document that allow-v6-synthesis is only performed + for clients that are supplied recursive service. + [RT #2260] + +1175. [bug] named-checkzone 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. + +1170. [bug] Don't attempt to print the token when a I/O error + occurs when parsing named.conf. [RT #2275] + +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] + +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] + +1156. [port] The configure test for strsep() incorrectly + succeeded on certain patched versions of + AIX 4.3.3. [RT #2190] + +1154. [bug] Don't attempt to obtain the netmask of a interface + if there is no address configured. [RT #2176] + +1152. [bug] libbind: read buffer overflows. + +1144. [bug] rndc-confgen would crash if both the -a and -t + options were specified. [RT #2159] + +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] + +1136. [bug] CNAME records synthesized from DNAMEs did not + have a TTL of zero as required by RFC2672. + [RT #2129] + +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] + +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] + +1081. [bug] Multicast queries were incorrectly identified + based on the source address, not the destination + address. + +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. + +1014. [bug] Some queries would cause statistics counters to + increment more than once or not at all. [RT #1321] + +1012. [bug] The -p option to named did not behave as documented. + + 988. [bug] 'additional-from-auth no;' did not work reliably + in the case of queries answered from the cache. + [RT #1436] + + 995. [bug] dig, host, nslookup: using a raw IPv6 address as a + target address should be fatal on a IPv4 only system. + + --- 9.2.0 released --- + +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] + + --- 9.2.0rc10 released --- + +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] + +1126. [bug] The server could access a freed event if shut + down while a client start event was pending + delivery. [RT #2061] + +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] + +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] + +1114. [port] Ignore more accept() errors. [RT #2021] + +1113. [bug] The allow-update-forwarding option was ignored + when specified in a view. [RT #2014] + +1111. [bug] Multi-threaded servers could deadlock processing + recursive queries due to a locking hierarchy + violation in adb.c. [RT #2017] + + --- 9.2.0rc9 released --- + +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] + +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. + +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. + +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] + +1078. [bug] We failed to correct bad tv_usec values in one case. + [RT #1966] + +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] + + --- 9.2.0rc8 released --- + +1068. [bug] errno could be overwritten by catgets(). [RT #1921] + +1066. [bug] Provide a thread safe wrapper for strerror(). + [RT #1689] + +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] + +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] + + --- 9.2.0rc7 released --- + +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] + +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] + +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. + + --- 9.2.0rc6 released --- + +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. [port] Recognize OpenUNIX 8 in config.guess. [RT #1830] + +1022. [bug] Don't report empty root hints as "extra data". + [RT #1802] + + --- 9.2.0rc5 released --- + +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] + + --- 9.2.0rc4 released --- + + +1013. [bug] It was possible to cancel a query twice when marking + a server as bogus or by having a blackhole acl. + [RT #1776] + +1010. [bug] The server could attempt to execute a command channel + command after initiating server shutdown, causing + an assertion failure. [RT #1766] + +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] + +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] + + --- 9.2.0rc3 released --- + + 990. [bug] The rndc-confgen man page was not installed. + + 989. [bug] Report filename if $INCLUDE fails for file related + errors. [RT #1736] + + 987. [bug] "dig -help" didn't show "+[no]stats". + + 986. [bug] "dig +noall" failed to clear stats and command + printing. + + 984. [bug] Multi-threading should be enabled by default on + Solaris 2.7 and newer, but it wasn't. + + --- 9.2.0rc2 released --- + + 980. [bug] Incoming zone transfers restarting after an error + could trigger an assertion failure. [RT #1692] + + 978. [bug] dns_db_attachversion() had an invalid REQUIRE() + condition. + + 977. [bug] Improve "not at top of zone" error message. + + 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] + + 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] + + 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] + + 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] + + 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. + + 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(). + + 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} + + 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. [func] Add support for .digrc config file, in the + user's current directory. + + 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 seperate 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 stuctures 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/bind-9.2.4rc7/COPYRIGHT b/contrib/bind-9.2.4rc7/COPYRIGHT new file mode 100644 index 0000000..cf55a00 --- /dev/null +++ b/contrib/bind-9.2.4rc7/COPYRIGHT @@ -0,0 +1,30 @@ +Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") +Copyright (C) 1996-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: COPYRIGHT,v 1.6.2.4 2004/03/15 04:44:37 marka 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/bind-9.2.4rc7/FAQ b/contrib/bind-9.2.4rc7/FAQ new file mode 100644 index 0000000..2bb2a38 --- /dev/null +++ b/contrib/bind-9.2.4rc7/FAQ @@ -0,0 +1,449 @@ + + + +Frequently Asked Questions about BIND 9 + + +Q: Why doesn't -u work on Linux 2.2.x when I build with --enable-threads? + +A: Linux threads do not fully implement the Posix threads (pthreads) standard. +In particular, setuid() operates only on the current thread, not the full +process. Because of this limitation, BIND 9 cannot use setuid() on Linux as it +can on all other supported platforms. setuid() cannot be called before +creating threads, since the server does not start listening on reserved ports +until after threads have started. + + In the 2.2.18 or 2.3.99-pre3 and newer kernels, the ability to preserve +capabilities across a setuid() call is present. This allows BIND 9 to call +setuid() early, while retaining the ability to bind reserved ports. This is +a Linux-specific hack. + + On a 2.2 kernel, BIND 9 does drop many root privileges, so it should be less +of a security risk than a root process that has not dropped privileges. + + If Linux threads ever work correctly, this restriction will go away. + + Configuring BIND9 with the --disable-threads option (the default) causes a +non-threaded version to be built, which will allow -u to be used. + + +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 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. + + +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: 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 produce a usable core file from a multithreaded named on Linux? + +A: If the Linux kernel is 2.4.7 or newer, multithreaded core dumps +are usable (that is, the correct thread is dumped). Otherwise, if using +a 2.2 kernel, apply the kernel patch found in contrib/linux/coredump-patch +and rebuild the kernel. This patch will cause multithreaded programs to dump +the correct thread. + + +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 installed BIND 9 and restarted named, but it's still BIND 8. Why? + +A: BIND 9 is installed under /usr/local by default. BIND 8 is often +installed under /usr. Check that the correct named is running. + + +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 synchronized (e.g., using ntp). + + +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: I have a BIND 9 master and a BIND 8.2.3 slave, and the master is +logging error messages like "notify to 10.0.0.1#53 failed: unexpected +end of input". What's wrong? + +A: This error message is caused by a known bug in BIND 8.2.3 and is fixed +in BIND 8.2.4. It can be safely ignored - the notify has been acted on by +the slave despite the error message. + + +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 +for information about how to turn them off. + + +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: 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: 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: 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: 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. + + e.g. + 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.0.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.0.1 { keys external; }; + recursion no; + ... + }; + + +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. + +e.g. + /etc/rc.conf + rand_irqs="3 14 15" + +See also http://people.freebsd.org/~dougb/randomness.html + + +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 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. + + e.g. + dig axfr example.com @master-server > tmp + named-checkzone example.com tmp + + +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 termination +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: 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 + +A: You could be generating queries faster than the slave can cope with. Lower +the serial query rate. + + serial-query-rate 5; // default 20 + +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 { !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 { 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. Forgeting 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 timzone +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 the error message "named: capset failed: Operation not permitted" +when starting named. + +A: The capset module has not been loaded into the kernel. See insmod(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 terminal can help at this + point. + + Secondly ensure that named is configured to use rndc either by + "rndc-confgen -a", rndc-confgen or manually. The Administators + 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 arguements. diff --git a/contrib/bind-9.2.4rc7/Makefile.in b/contrib/bind-9.2.4rc7/Makefile.in new file mode 100644 index 0000000..b2a8dda --- /dev/null +++ b/contrib/bind-9.2.4rc7/Makefile.in @@ -0,0 +1,59 @@ +# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 1998-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: Makefile.in,v 1.41.2.3 2004/03/09 06:09:07 marka 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} + +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) diff --git a/contrib/bind-9.2.4rc7/README b/contrib/bind-9.2.4rc7/README new file mode 100644 index 0000000..2d5d7d8 --- /dev/null +++ b/contrib/bind-9.2.4rc7/README @@ -0,0 +1,351 @@ +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 + organisations: + + 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.2.4 + + BIND 9.2.4 is a maintenance release, containing fixes for + a number of bugs in 9.2.3. + + libbind: corresponds to that from BIND 8.4.5. + +BIND 9.2.3 + + BIND 9.2.3 is a maintenance release, containing fixes for + a number of bugs in 9.2.2. + + A new zone type delegation-only is now supported. + A new view option root-delegation-only is now supported. + + libbind: corresponds to that from BIND 8.4.0. + +BIND 9.2.2 + + BIND 9.2.2 is a maintenance release, containing fixes for + a number of bugs in 9.2.1 but no new features. RFC 2535 + style DNSSEC is disabled as it is incompatible with the + forthcoming DS style DNSSEC. + + libbind: from BIND 8.3.3. [CERT CA-2002-19] + Minimum OpenSSL version now 0.9.6e. [CERT CA-2002-23] + +BIND 9.2.1 + + BIND 9.2.1 is a maintenance release, containing fixes for + a number of bugs in 9.2.0 but no new features. + + NOTE: dig, nslookup name. now report "Not Implemented" as + NOTIMP rather than NOTIMPL. This will have impact on scripts + that are looking for NOTIMPL. + +BIND 9.2.0 + + BIND 9.2.0 introduces 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 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) 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. + + 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: + + AIX 4.3 + COMPAQ Tru64 UNIX 4.0D + COMPAQ Tru64 UNIX 5 (with IPv6 EAK) + FreeBSD 3.4-STABLE, 3.5, 4.0, 4.1 + HP-UX 11.x, x < 11 + IRIX64 6.5 + NetBSD 1.5 + Red Hat Linux 6.0, 6.1, 6.2, 7.0 + Solaris 2.6, 7, 8 + Windows NT/W2K + + 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 + OpenBSD 2.6, 2.8, 2.9 + UnixWare 7.1.1 + HP-UX 10.20 + BSD/OS 4.2 + OpenUNIX 8 + Mac OS X 10.1 + + 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: + -DISC_RFC2535 + Enable support RFC 2535 style DNSSEC. This + is incompatable with the upcoming DS support + and SHOULD NOT be set unless you are currently + making use of it. + + LDFLAGS + Linker flags. Defaults to empty string. + + 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). + + * gcc-3.2.1 and gcc-3.1.1 is known to cause problems with solaris-x86 + if the optimiser is enabled. Use -O0 to disable the optimiser. + * gcc ultrasparc generates incorrect code at -02. + + 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 + + Configuration questions should be sent to the BIND 9 Users + mailing list. Compilation questions should be sent to the + BIND 9 Users mailing list. + + 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/ml-archives/ + + If you're planning on making changes to the BIND 9 source + code, you might want to join the BIND Workers mailing list. + Send mail to + + bind-workers-request@isc.org + + diff --git a/contrib/bind-9.2.4rc7/README.DELETED b/contrib/bind-9.2.4rc7/README.DELETED new file mode 100644 index 0000000..70b6c90 --- /dev/null +++ b/contrib/bind-9.2.4rc7/README.DELETED @@ -0,0 +1,48 @@ +bin/tests +bin/*/win32 +bin/win32 +lib/*/win32 +lib/win32 +lib/tests +lib/bind/configure* +lib/bind/port/aix32 +lib/bind/port/aix4 +lib/bind/port/bsdos* +lib/bind/port/cygwin +lib/bind/port/darwin +lib/bind/port/decunix +lib/bind/port/hpux* +lib/bind/port/irix +lib/bind/port/linux +lib/bind/port/lynxos +lib/bind/port/mpe +lib/bind/port/netbsd +lib/bind/port/next +lib/bind/port/openbsd +lib/bind/port/qnx +lib/bind/port/rhapsody +lib/bind/port/sco* +lib/bind/port/solaris +lib/bind/port/sunos +lib/bind/port/ultrix +lib/bind/port/unixware* +win32utils +make +contrib +doc +docutil +*.m4 +*/*/*.m4 +config* +install-sh +isc-config.sh.in +ltmain.sh +mkinstalldirs +*/Makefile* +*/*/Makefile* +*/*/*/Makefile* +*/*/*/*/Makefile* +*/*/*/*/*/Makefile* +*/*/*/*/*/*/Makefile* +*/*/*.docbook +*/*/*/*.docbook diff --git a/contrib/bind-9.2.4rc7/README.DRAGONFLY b/contrib/bind-9.2.4rc7/README.DRAGONFLY new file mode 100644 index 0000000..f689f60 --- /dev/null +++ b/contrib/bind-9.2.4rc7/README.DRAGONFLY @@ -0,0 +1,53 @@ + + BIND-9.2.4RC7 AS USED BY DRAGONFLY + + This directory contains a selected set of files from the ISC + bind-9.2.4rc7.tar.gz distribution. No files have been moved + or modified from their extracted position. + + This distribution was downloaded from the following site: + + http://www.isc.org/index.pl?/sw/bind/ + + DO NOT CREATE OR EDIT ANY FILES IN THIS DIRECTORY HIERARCHY! THIS + HIERARCHY REPRESENTS AN EXACT COPY, MINUS UNNEEDED FILES, OF THE + ORIGINAL ARCHIVE. All modifications are made in the + DragonFly build wrapper, in: + + /usr/src/usr.sbin/named + /usr/src/usr.sbin/(various) + /usr/src/usr.bin/(various) + /usr/src/lib/libbind + /usr/src/lib/libisc + + The only additional files added to this directory are README.DRAGONFLY + and README.DELETED. + + UPGRADE PROCDURE: + + * download a new bind distribution + + * extract the archive into /usr/src/contrib, using the subdirectory + that the archive extracts as. + + * redirect the build directory to the new directory: + + /usr/src/usr.sbin/named/Makefile.inc + /usr/src/lib/libbind/Makefile + /usr/src/lib/libisc/Makefile + + * remove files that are not used (or run a build and figure out + what files are not used and remove them). + + * Add the remainder to CVS. + + * Once the new archive is in place, the old one can be physically + removed from the DragonFly CVS repository. The CVS meister would + have to do the physical removal. + + DO NOT MAKE ANY EDITS TO THE DISTRIBUTION IN THIS CONTRIB + DIRECTORY, OTHER THEN TO ADD OR DELETE FILES ASSOCIATED WITH THE + DISTRIBUTION. + + The file README.DELETED contains a list of deleted files. + diff --git a/contrib/bind-9.2.4rc7/acconfig.h b/contrib/bind-9.2.4rc7/acconfig.h new file mode 100644 index 0000000..9c57898 --- /dev/null +++ b/contrib/bind-9.2.4rc7/acconfig.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-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: acconfig.h,v 1.35.2.8 2004/03/09 06:09:07 marka Exp $ */ + +/*** + *** 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 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 diff --git a/contrib/bind-9.2.4rc7/bin/check/check-tool.c b/contrib/bind-9.2.4rc7/bin/check/check-tool.c new file mode 100644 index 0000000..fda04f4 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/check/check-tool.c @@ -0,0 +1,52 @@ +/* + * 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: check-tool.c,v 1.4.2.1 2004/03/09 06:09:08 marka Exp $ */ + +#include + +#include + +#include "check-tool.h" +#include + +#include +#include + +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_setcontext(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); +} diff --git a/contrib/bind-9.2.4rc7/bin/check/check-tool.h b/contrib/bind-9.2.4rc7/bin/check/check-tool.h new file mode 100644 index 0000000..3e0dfd5 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/check/check-tool.h @@ -0,0 +1,34 @@ +/* + * 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: check-tool.h,v 1.2.2.1 2004/03/09 06:09:09 marka Exp $ */ + +#ifndef CHECK_TOOL_H +#define CHECK_TOOL_H + +#include + +#include + +ISC_LANG_BEGINDECLS + +isc_result_t +setup_logging(isc_mem_t *mctx, isc_log_t **logp); + +ISC_LANG_ENDDECLS + +#endif diff --git a/contrib/bind-9.2.4rc7/bin/check/named-checkconf.8 b/contrib/bind-9.2.4rc7/bin/check/named-checkconf.8 new file mode 100644 index 0000000..508a149 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/check/named-checkconf.8 @@ -0,0 +1,52 @@ +.\" 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: named-checkconf.8,v 1.11.2.2 2004/06/03 05:21:07 marka Exp $ +.\" +.TH "NAMED-CHECKCONF" "8" "June 14, 2000" "BIND9" "" +.SH NAME +named-checkconf \- named configuration file syntax checking tool +.SH SYNOPSIS +.sp +\fBnamed-checkconf\fR [ \fB-v\fR ] [ \fB-t \fIdirectory\fB\fR ] \fBfilename\fR +.SH "DESCRIPTION" +.PP +\fBnamed-checkconf\fR checks the syntax, but not +the semantics, of a named configuration file. +.SH "OPTIONS" +.TP +\fB-t \fIdirectory\fB\fR +chroot to \fIdirectory\fR so that include +directives in the configuration file are processed as if +run by a similarly chrooted named. +.TP +\fB-v\fR +Print the version of the \fBnamed-checkconf\fR +program and exit. +.TP +\fBfilename\fR +The name of the configuration file to be checked. If not +specified, it defaults to \fI/etc/named.conf\fR. +.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), +\fIBIND 9 Administrator Reference Manual\fR. +.SH "AUTHOR" +.PP +Internet Systems Consortium diff --git a/contrib/bind-9.2.4rc7/bin/check/named-checkconf.c b/contrib/bind-9.2.4rc7/bin/check/named-checkconf.c new file mode 100644 index 0000000..83d3cd9 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/check/named-checkconf.c @@ -0,0 +1,138 @@ +/* + * 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: named-checkconf.c,v 1.12.2.1 2004/03/09 06:09:09 marka Exp $ */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "check-tool.h" + +isc_log_t *logc = NULL; + +static void +usage(void) { + fprintf(stderr, "usage: named-checkconf [-v] [-t directory] [named.conf]\n"); + exit(1); +} + +static isc_result_t +directory_callback(const char *clausename, cfg_obj_t *obj, void *arg) { + isc_result_t result; + 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", + directory, isc_result_totext(result)); + return (result); + } + + return (ISC_R_SUCCESS); +} + +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; + + while ((c = isc_commandline_parse(argc, argv, "t:v")) != EOF) { + switch (c) { + 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); + + 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(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 = cfg_check_namedconf(config, logc, mctx); + if (result != ISC_R_SUCCESS) + exit_status = 1; + + cfg_obj_destroy(parser, &config); + + cfg_parser_destroy(&parser); + + isc_log_destroy(&logc); + + isc_mem_destroy(&mctx); + + return (exit_status); +} diff --git a/contrib/bind-9.2.4rc7/bin/check/named-checkconf.html b/contrib/bind-9.2.4rc7/bin/check/named-checkconf.html new file mode 100644 index 0000000..fbdc5c0 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/check/named-checkconf.html @@ -0,0 +1,196 @@ + + + + +named-checkconf

named-checkconf

Name

named-checkconf -- named configuration file syntax checking tool

Synopsis

named-checkconf [-v] [-t directory] {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. +

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), + BIND 9 Administrator Reference Manual. +

AUTHOR

Internet Systems Consortium +

diff --git a/contrib/bind-9.2.4rc7/bin/check/named-checkzone.8 b/contrib/bind-9.2.4rc7/bin/check/named-checkzone.8 new file mode 100644 index 0000000..a2c114b --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/check/named-checkzone.8 @@ -0,0 +1,65 @@ +.\" 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: named-checkzone.8,v 1.11.2.3 2004/06/03 05:21:08 marka Exp $ +.\" +.TH "NAMED-CHECKZONE" "8" "June 13, 2000" "BIND9" "" +.SH NAME +named-checkzone \- zone file validity checking tool +.SH SYNOPSIS +.sp +\fBnamed-checkzone\fR [ \fB-d\fR ] [ \fB-j\fR ] [ \fB-q\fR ] [ \fB-v\fR ] [ \fB-c \fIclass\fB\fR ] \fBzonename\fR \fBfilename\fR +.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. +.SH "OPTIONS" +.TP +\fB-d\fR +Enable debugging. +.TP +\fB-q\fR +Quiet mode - exit code only. +.TP +\fB-v\fR +Print the version of the \fBnamed-checkzone\fR +program and exit. +.TP +\fB-j\fR +When loading the zone file read the journal if it exists. +.TP +\fB-c \fIclass\fB\fR +Specify the class of the zone. If not specified "IN" is assumed. +.TP +\fBzonename\fR +The domain name of the zone being checked. +.TP +\fBfilename\fR +The name of the zone file. +.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), +\fIRFC 1035\fR, +\fIBIND 9 Administrator Reference Manual\fR. +.SH "AUTHOR" +.PP +Internet Systems Consortium diff --git a/contrib/bind-9.2.4rc7/bin/check/named-checkzone.c b/contrib/bind-9.2.4rc7/bin/check/named-checkzone.c new file mode 100644 index 0000000..d92b86a --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/check/named-checkzone.c @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2004 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-checkzone.c,v 1.13.2.4 2004/03/09 06:09:09 marka Exp $ */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "check-tool.h" + +static int debug = 0; +isc_boolean_t nomerge = ISC_TRUE; +static int quiet = 0; +static isc_mem_t *mctx = NULL; +dns_zone_t *zone = NULL; +dns_zonetype_t zonetype = dns_zone_master; +static const char *dbtype[] = { "rbt" }; + +#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: named-checkzone [-djqv] [-c class] zonename filename \n"); + exit(1); +} + +static isc_result_t +setup(char *zonename, char *filename, char *classname) { + isc_result_t result; + dns_rdataclass_t rdclass; + isc_textregion_t region; + isc_buffer_t buffer; + dns_fixedname_t fixorigin; + dns_name_t *origin; + + if (debug) + fprintf(stderr, "loading \"%s\" from \"%s\" class \"%s\"\n", + zonename, filename, classname); + result = dns_zone_create(&zone, mctx); + ERRRET(result, "dns_zone_new"); + + dns_zone_settype(zone, zonetype); + + isc_buffer_init(&buffer, zonename, strlen(zonename)); + isc_buffer_add(&buffer, strlen(zonename)); + dns_fixedname_init(&fixorigin); + result = dns_name_fromtext(dns_fixedname_name(&fixorigin), + &buffer, dns_rootname, ISC_FALSE, NULL); + ERRRET(result, "dns_name_fromtext"); + origin = dns_fixedname_name(&fixorigin); + + result = dns_zone_setorigin(zone, origin); + ERRRET(result, "dns_zone_setorigin"); + + result = dns_zone_setdbtype(zone, 1, (const char * const *) dbtype); + ERRRET(result, "dns_zone_setdatabase"); + + result = dns_zone_setfile(zone, filename); + ERRRET(result, "dns_zone_setdatabase"); + + region.base = classname; + region.length = strlen(classname); + result = dns_rdataclass_fromtext(&rdclass, ®ion); + ERRRET(result, "dns_rdataclass_fromtext"); + + dns_zone_setclass(zone, rdclass); + dns_zone_setoption(zone, DNS_ZONEOPT_MANYERRORS, ISC_TRUE); + dns_zone_setoption(zone, DNS_ZONEOPT_NOMERGE, nomerge); + + result = dns_zone_load(zone); + + return (result); +} + +static void +destroy(void) { + if (zone != NULL) + dns_zone_detach(&zone); +} + +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; + + while ((c = isc_commandline_parse(argc, argv, "c:djqsv")) != EOF) { + switch (c) { + case 'c': + classname = isc_commandline_argument; + break; + case 'd': + debug++; + break; + + case 'j': + nomerge = ISC_FALSE; + break; + case 'q': + quiet++; + break; + case 'v': + printf(VERSION "\n"); + exit(0); + default: + usage(); + } + } + + 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); + dns_log_init(lctx); + dns_log_setcontext(lctx); + } + + dns_result_register(); + + origin = argv[isc_commandline_index++]; + filename = argv[isc_commandline_index++]; + result = setup(origin, filename, classname); + if (!quiet && result == ISC_R_SUCCESS) + fprintf(stdout, "OK\n"); + destroy(); + if (lctx != NULL) + isc_log_destroy(&lctx); + isc_mem_destroy(&mctx); + return ((result == ISC_R_SUCCESS) ? 0 : 1); +} diff --git a/contrib/bind-9.2.4rc7/bin/check/named-checkzone.html b/contrib/bind-9.2.4rc7/bin/check/named-checkzone.html new file mode 100644 index 0000000..de0eeb4 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/check/named-checkzone.html @@ -0,0 +1,237 @@ + + + + +named-checkzone

named-checkzone

Name

named-checkzone -- zone file validity checking tool

Synopsis

named-checkzone [-d] [-j] [-q] [-v] [-c class] {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. +

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

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), + RFC 1035, + BIND 9 Administrator Reference Manual. +

AUTHOR

Internet Systems Consortium +

diff --git a/contrib/bind-9.2.4rc7/bin/dig/dig.1 b/contrib/bind-9.2.4rc7/bin/dig/dig.1 new file mode 100644 index 0000000..1e919dc --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dig/dig.1 @@ -0,0 +1,370 @@ +.\" 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: dig.1,v 1.14.2.5 2004/03/15 04:44:38 marka Exp $ +.\" +.TH "DIG" "1" "Jun 30, 2000" "BIND9" "" +.SH NAME +dig \- DNS lookup utility +.SH SYNOPSIS +.sp +\fBdig\fR [ \fB@server\fR ] [ \fB-b \fIaddress\fB\fR ] [ \fB-c \fIclass\fB\fR ] [ \fB-f \fIfilename\fB\fR ] [ \fB-k \fIfilename\fB\fR ] [ \fB-p \fIport#\fB\fR ] [ \fB-t \fItype\fB\fR ] [ \fB-x \fIaddr\fB\fR ] [ \fB-y \fIname:key\fB\fR ] [ \fBname\fR ] [ \fBtype\fR ] [ \fBclass\fR ] [ \fBqueryopt\fR\fI...\fR ] +.sp +\fBdig\fR [ \fB-h\fR ] +.sp +\fBdig\fR [ \fBglobal-queryopt\fR\fI...\fR ] [ \fBquery\fR\fI...\fR ] +.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 BIND9 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 arguements. +.SH "SIMPLE USAGE" +.PP +A typical invocation of \fBdig\fR looks like: +.sp +.nf + dig @server name type +.sp +.fi +where: +.TP +\fBserver\fR +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. +.TP +\fBname\fR +is the name of the resource record that is to be looked up. +.TP +\fBtype\fR +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. +.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. +.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 organised 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-t\fR option sets the query type to +\fItype\fR. It can be any valid query type which is +supported in BIND9. The default query type "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 +Reverse lookups - mapping addresses to names - 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 the IP6.ARPA domain and binary labels as defined in +RFC2874. To use the older RFC1886 method using the IP6.INT domain and +"nibble" labels, specify the \fB-n\fR (nibble) option. +.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; +\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: +.TP +\fB+[no]tcp\fR +Use [do not use] TCP when querying name servers. The default +behaviour is to use UDP unless an AXFR or IXFR query is requested, in +which case a TCP connection is used. +.TP +\fB+[no]vc\fR +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". +.TP +\fB+[no]ignore\fR +Ignore truncation in UDP responses instead of retrying with TCP. By +default, TCP retries are performed. +.TP +\fB+domain=somename\fR +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. +.TP +\fB+[no]search\fR +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. +.TP +\fB+[no]defname\fR +Deprecated, treated as a synonym for \fI+[no]search\fR +.TP +\fB+[no]aaonly\fR +This option does nothing. It is provided for compatibility with old +versions of \fBdig\fR where it set an unimplemented +resolver flag. +.TP +\fB+[no]adflag\fR +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. +.TP +\fB+[no]cdflag\fR +Set [do not set] the CD (checking disabled) bit in the query. This +requests the server to not perform DNSSEC validation of responses. +.TP +\fB+[no]recurse\fR +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. +.TP +\fB+[no]nssearch\fR +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. +.TP +\fB+[no]trace\fR +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. +.TP +\fB+[no]cmd\fR +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. +.TP +\fB+[no]short\fR +Provide a terse answer. The default is to print the answer in a +verbose form. +.TP +\fB+[no]identify\fR +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. +.TP +\fB+[no]comments\fR +Toggle the display of comment lines in the output. The default is to +print comments. +.TP +\fB+[no]stats\fR +This query option toggles the printing of statistics: when the query +was made, the size of the reply and so on. The default behaviour is +to print the query statistics. +.TP +\fB+[no]qr\fR +Print [do not print] the query as it is sent. +By default, the query is not printed. +.TP +\fB+[no]question\fR +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. +.TP +\fB+[no]answer\fR +Display [do not display] the answer section of a reply. The default +is to display it. +.TP +\fB+[no]authority\fR +Display [do not display] the authority section of a reply. The +default is to display it. +.TP +\fB+[no]additional\fR +Display [do not display] the additional section of a reply. +The default is to display it. +.TP +\fB+[no]all\fR +Set or clear all display flags. +.TP +\fB+time=T\fR +Sets the timeout for a query to +\fIT\fR seconds. The default time out is 5 seconds. +An attempt to set \fIT\fR to less than 1 will result +in a query timeout of 1 second being applied. +.TP +\fB+tries=T\fR +Sets the number of times to retry 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 +retries is silently rounded up to 1. +.TP +\fB+ndots=D\fR +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. +.TP +\fB+bufsize=B\fR +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. +.TP +\fB+[no]multiline\fR +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. +.TP +\fB+[no]fail\fR +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 +behaviour. +.TP +\fB+[no]besteffort\fR +Attempt to display the contents of messages which are malformed. +The default is to not display malformed answers. +.TP +\fB+[no]dnssec\fR +Requests DNSSEC records be sent by setting the DNSSEC OK bit (DO) +in the OPT record in the additional section of the query. +.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 +.nf +dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr +.sp +.fi +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 "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), +\fIRFC1035\fR. +.SH "BUGS" +.PP +There are probably too many query options. diff --git a/contrib/bind-9.2.4rc7/bin/dig/dig.c b/contrib/bind-9.2.4rc7/bin/dig/dig.c new file mode 100644 index 0000000..b401dc7 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dig/dig.c @@ -0,0 +1,1409 @@ +/* + * Copyright (C) 2004 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.c,v 1.157.2.16 2004/06/07 03:59:08 marka Exp $ */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +extern ISC_LIST(dig_lookup_t) lookup_list; +extern dig_serverlist_t server_list; +extern ISC_LIST(dig_searchlist_t) search_list; + +#define ADD_STRING(b, s) { \ + if (strlen(s) >= isc_buffer_availablelength(b)) \ + return (ISC_R_NOSPACE); \ + else \ + isc_buffer_putstr(b, s); \ +} + + +extern isc_boolean_t have_ipv4, have_ipv6, specified_source, + usesearch, 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 tries; +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_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; +dig_lookup_t *default_lookup = NULL; + +extern isc_boolean_t debugging, memdebugging; +static char *batchname = NULL; +static FILE *batchfp = NULL; +static char *argv0; + +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; + +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" +}; + +extern char *progname; + +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); +} + +static void +help(void) { + print_usage(stdout); + fputs( +"Where: domain are 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 (bind to source address)\n" +" -p port (specify port number)\n" +" -t type (specify query type)\n" +" -c class (specify query class)\n" +" -k keyfile (specify tsig key file)\n" +" -y name:key (specify named base64 tsig key)\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" +" +domain=### (Set default domainname)\n" +" +bufsize=### (Set EDNS0 Max UDP packet size)\n" +" +ndots=### (Set NDOTS value)\n" +" +[no]search (Set whether to use searchlist)\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)\n" +" +[no]adflag (Set AD flag in query)\n" +" +[no]cdflag (Set CD flag in query)\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]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" +" +[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", + 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; + isc_result_t result; + time_t tnow; + char fromtext[ISC_SOCKADDR_FORMATSIZE]; + + isc_sockaddr_format(from, fromtext, sizeof(fromtext)); + + result = isc_time_now(&now); + check_result(result, "isc_time_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: %d records\n", + query->rr_count); + } else { + printf(";; MSG SIZE rcvd: %d\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 %u bytes from %s(%s) in %d ms\n\n", + 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) { + result = isc_time_now(&now); + if (result != ISC_R_SUCCESS) + return (result); + 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); +} + +/* + * 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; + const dns_master_style_t *style; + + if (multiline) + style = &dns_master_style_default; + else + style = &dns_master_style_debug; + + 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]); + } + } + +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 + return (result); + } + 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); + 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) { + 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); + } + } +} + +/* + * Reorder an argument list so that server names all come at the end. + * This is a bit of a hack, to allow batch-mode processing to properly + * handle the server options. + */ +static void +reorder_args(int argc, char *argv[]) { + int i, j; + char *ptr; + int end; + + debug("reorder_args()"); + end = argc - 1; + while (argv[end][0] == '@') { + end--; + if (end == 0) + return; + } + debug("arg[end]=%s", argv[end]); + for (i = 1; i < end - 1; i++) { + if (argv[i][0] == '@') { + debug("arg[%d]=%s", i, argv[i]); + ptr = argv[i]; + for (j = i + 1; j < end; j++) { + debug("Moving %s to %d", argv[j], j - 1); + argv[j - 1] = argv[j]; + } + debug("moving %s to end, %d", ptr, end - 1); + argv[end - 1] = ptr; + end--; + if (end < 1) + return; + } + } +} + +static isc_uint32_t +parse_uint(char *arg, const char *desc, isc_uint32_t max) { + char *endp; + isc_uint32_t tmp; + + tmp = strtoul(arg, &endp, 10); + if (*endp != '\0') + fatal("%s '%s' must be numeric", desc, arg); + if (tmp > max) + fatal("%s '%s' out of range", desc, arg); + 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; + + 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; + } + switch (cmd[0]) { + case 'a': + switch (cmd[1]) { + case 'a': /* aaflag */ + lookup->aaonly = state; + break; + case 'd': + switch (cmd[2]) { + case 'd': /* additional */ + lookup->section_additional = state; + break; + case 'f': /* adflag */ + lookup->adflag = state; + break; + default: + goto invalid_option; + } + break; + case 'l': /* 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 */ + lookup->section_answer = state; + break; + case 'u': /* authority */ + lookup->section_authority = state; + break; + default: + goto invalid_option; + } + break; + case 'b': + switch (cmd[1]) { + case 'e':/* besteffort */ + lookup->besteffort = state; + break; + case 'u':/* 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 */ + lookup->cdflag = state; + break; + case 'm': /* cmd */ + printcmd = state; + break; + case 'o': /* comments */ + lookup->comments = state; + if (lookup == default_lookup) + pluscomm = state; + break; + default: + goto invalid_option; + } + break; + case 'd': + switch (cmd[1]) { + case 'e': /* defname */ + usesearch = state; + break; + case 'n': /* dnssec */ + lookup->dnssec = state; + break; + case 'o': /* 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 'f': /* fail */ + lookup->servfail_stops = state; + break; + case 'i': + switch (cmd[1]) { + case 'd': /* identify */ + lookup->identify = state; + break; + case 'g': /* ignore */ + default: /* Inherets default for compatibility */ + lookup->ignore = ISC_TRUE; + } + break; + case 'm': /* multiline */ + multiline = state; + break; + case 'n': + switch (cmd[1]) { + case 'd': /* ndots */ + if (value == NULL) + goto need_value; + if (!state) + goto invalid_option; + ndots = parse_uint(value, "ndots", MAXNDOTS); + break; + case 's': /* nssearch */ + lookup->ns_search_only = state; + if (state) { + lookup->trace_root = ISC_TRUE; + lookup->recurse = ISC_FALSE; + 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 */ + qr = state; + break; + case 'u': /* question */ + lookup->section_question = state; + if (lookup == default_lookup) + plusquest = state; + break; + default: + goto invalid_option; + } + break; + case 'r': /* recurse */ + lookup->recurse = state; + break; + case 's': + switch (cmd[1]) { + case 'e': /* search */ + usesearch = state; + break; + case 'h': /* 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 't': /* stats */ + lookup->stats = state; + break; + default: + goto invalid_option; + } + break; + case 't': + switch (cmd[1]) { + case 'c': /* tcp */ + if (!is_batchfile) + lookup->tcp_mode = state; + break; + case 'i': /* timeout */ + if (value == NULL) + goto need_value; + if (!state) + goto invalid_option; + timeout = parse_uint(value, "timeout", MAXTIMEOUT); + if (timeout == 0) + timeout = 1; + break; + case 'r': + switch (cmd[2]) { + case 'a': /* 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 */ + if (value == NULL) + goto need_value; + if (!state) + goto invalid_option; + lookup->retries = parse_uint(value, "retries", + MAXTRIES); + if (lookup->retries == 0) + lookup->retries = 1; + break; + default: + goto invalid_option; + } + break; + default: + goto invalid_option; + } + break; + case 'v': + 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 isc_boolean_t +dash_option(char *option, char *next, dig_lookup_t **lookup, + isc_boolean_t *open_type_class, + isc_boolean_t *firstarg, + int argc, char **argv) +{ + char cmd, *value, *ptr; + 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; + + cmd = option[0]; + if (strlen(option) > 1U) { + value_from_next = ISC_FALSE; + value = &option[1]; + } else { + value_from_next = ISC_TRUE; + value = next; + } + switch (cmd) { + case 'd': + debugging = ISC_TRUE; + return (ISC_FALSE); + case 'h': + help(); + exit(0); + break; + case 'i': + ip6_int = ISC_TRUE; + return (ISC_FALSE); + case 'm': /* memdebug */ + /* memdebug is handled in preparse_args() */ + return (ISC_FALSE); + case 'n': + /* deprecated */ + return (ISC_FALSE); + } + if (value == NULL) + goto invalid_option; + switch (cmd) { + case 'b': + if (have_ipv6 && inet_pton(AF_INET6, value, &in6) == 1) + isc_sockaddr_fromin6(&bind_address, &in6, 0); + else if (have_ipv4 && inet_pton(AF_INET, value, &in4) == 1) + isc_sockaddr_fromin(&bind_address, &in4, 0); + else + fatal("invalid address %s", value); + 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 '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,":"); + if (ptr == NULL) { + usage(); + } + strncpy(keynametext, ptr, sizeof(keynametext)); + keynametext[sizeof(keynametext)-1]=0; + ptr = next_token(&value, ""); + if (ptr == NULL) + usage(); + strncpy(keysecret, ptr, sizeof(keysecret)); + keysecret[sizeof(keysecret)-1]=0; + return (value_from_next); + case 'x': + *lookup = clone_lookup(default_lookup, ISC_TRUE); + if (get_reverse(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 (*lookup && *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; + + rc = argc; + rv = argv; + for (rc--, rv++; rc > 0; rc--, rv++) { + if (strcmp(rv[0], "-m") == 0) { + memdebugging = ISC_TRUE; + isc_mem_debugging = ISC_MEM_DEBUGTRACE | + ISC_MEM_DEBUGRECORD; + return; + } + } +} + + +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_server_t *srv = NULL; + 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; + + /* + * 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 .digrc as a special batchfile + */ + homedir = getenv("HOME"); + if (homedir != NULL) + snprintf(rcfile, sizeof(rcfile), "%s/.digrc", homedir); + else + strcpy(rcfile, ".digrc"); + 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]; + + reorder_args(bargc, (char **)bargv); + parse_args(ISC_TRUE, ISC_TRUE, bargc, + (char **)bargv); + } + fclose(batchfp); + } +#endif + } + + 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) { + srv = make_server(&rv[0][1]); + ISC_LIST_APPEND(lookup->my_server_list, + srv, link); + } 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, + &firstarg, argc, argv)) { + rc--; + rv++; + } + } else { + if (dash_option(&rv[0][1], rv[1], + &lookup, &open_type_class, + &firstarg, argc, argv)) { + rc--; + rv++; + } + } + } else { + /* + * Anything which isn't an option + */ + if (open_type_class) { + if (strncmp(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) { + lookup = clone_lookup(default_lookup, + ISC_TRUE); + if (firstarg) { + printgreeting(argc, argv, lookup); + firstarg = ISC_FALSE; + } + 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; + 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]; + + reorder_args(bargc, (char **)bargv); + parse_args(ISC_TRUE, ISC_FALSE, bargc, (char **)bargv); + } + } + /* + * If no lookup specified, search for root + */ + if ((lookup_list.head == NULL) && !config_only) { + lookup = clone_lookup(default_lookup, 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); + } +} + +/* + * Callback from dighost.c to allow program-specific shutdown code. Here, + * 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; + + + 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; + + reorder_args(bargc, (char **)bargv); + parse_args(ISC_TRUE, ISC_FALSE, bargc, (char **)bargv); + start_lookup(); + } else { + batchname = NULL; + if (batchfp != stdin) + fclose(batchfp); + isc_app_shutdown(); + return; + } +} + +int +main(int argc, char **argv) { + isc_result_t result; + dig_server_t *s, *s2; + + 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(); + s = ISC_LIST_HEAD(default_lookup->my_server_list); + while (s != NULL) { + debug("freeing server %p belonging to %p", + s, default_lookup); + s2 = s; + s = ISC_LIST_NEXT(s, link); + ISC_LIST_DEQUEUE(default_lookup->my_server_list, s2, link); + isc_mem_free(mctx, s2); + } + isc_mem_free(mctx, default_lookup); + if (batchname != NULL) { + if (batchfp != stdin) + fclose(batchfp); + batchname = NULL; + } + cancel_all(); + destroy_libs(); + isc_app_finish(); + return (exitcode); +} diff --git a/contrib/bind-9.2.4rc7/bin/dig/dig.html b/contrib/bind-9.2.4rc7/bin/dig/dig.html new file mode 100644 index 0000000..c8110db --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dig/dig.html @@ -0,0 +1,1158 @@ + + + + +dig

dig

Name

dig -- DNS lookup utility

Synopsis

dig [@server] [-b address] [-c class] [-f filename] [-k filename] [-p port#] [-t type] [-x addr] [-y name:key] [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 BIND9 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 arguements.

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.

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 organised 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 -t option sets the query type to +type. It can be any valid query type which is +supported in BIND9. The default query type "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.

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 the IP6.ARPA domain and binary labels as defined in +RFC2874. To use the older RFC1886 method using the IP6.INT domain and +"nibble" labels, specify the -n (nibble) option.

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; +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 +behaviour 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]defname

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

+[no]aaonly

This option does nothing. It is provided for compatibility with old +versions of dig where it set an unimplemented +resolver flag.

+[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]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 behaviour 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 time out 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 retry UDP queries to server to +T instead of the default, 3. If +T is less than or equal to zero, the number of +retries is silently rounded up to 1.

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

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

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

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.

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/bind-9.2.4rc7/bin/dig/dighost.c b/contrib/bind-9.2.4rc7/bin/dig/dighost.c new file mode 100644 index 0000000..301a464 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dig/dighost.c @@ -0,0 +1,2723 @@ +/* + * Copyright (C) 2004 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: dighost.c,v 1.221.2.22 2004/04/15 06:53:18 marka Exp $ */ + +/* + * 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 + +#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 + +ISC_LIST(dig_lookup_t) lookup_list; +dig_serverlist_t server_list; +ISC_LIST(dig_searchlist_t) search_list; + +isc_boolean_t + have_ipv4 = ISC_FALSE, + have_ipv6 = ISC_FALSE, + specified_source = ISC_FALSE, + free_now = ISC_FALSE, + cancel_now = ISC_FALSE, + usesearch = ISC_FALSE, + qr = ISC_FALSE, + is_dst_up = ISC_FALSE; +in_port_t port = 53; +unsigned int timeout = 0; +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 = 2; +int lookup_counter = 0; + +/* + * Exit Codes: + * 0 Everything went well, including things like NXDOMAIN + * 1 Usage error + * 7 Got too many RR's or Names + * 8 Couldn't open batch file + * 9 No reply from server + * 10 Internal error + */ +int exitcode = 0; +int fatalexit = 0; +char keynametext[MXNAME]; +char keyfile[MXNAME] = ""; +char keysecret[MXNAME] = ""; +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; + +/* + * 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 +connect_timeout(isc_task_t *task, isc_event_t *event); + +static void +launch_next_query(dig_query_t *query, isc_boolean_t include_question); + +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, 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 = DNS_BYADDROPT_IPV6NIBBLE; + + 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, MXNAME); + 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 + MXNAME; + 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) { + 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); + srv->servername[MXNAME-1] = 0; + ISC_LINK_INIT(srv, link); + return (srv); +} + +/* + * 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); + 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; + looknew->udpsize = 0; + 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; + 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); + 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; + looknew->udpsize = lookold->udpsize; + 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; + + 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, dns_tsig_hmacmd5_name, + 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)); + + 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, + mctx, &dstkey); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "Couldn't read key from %s: %s\n", + keyfile, isc_result_totext(result)); + goto failure; + } + + result = dns_tsigkey_createfromkey(dst_key_name(dstkey), + dns_tsig_hmacmd5_name, + 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); +} + +/* + * Setup the system as a whole, reading key information and resolv.conf + * settings. + */ +void +setup_system(void) { + char rcinput[MXNAME]; + FILE *fp; + char *ptr; + dig_server_t *srv; + dig_searchlist_t *search, *domain = NULL; + isc_boolean_t get_servers; + char *input; + + debug("setup_system()"); + + free_now = ISC_FALSE; + get_servers = ISC_TF(server_list.head == NULL); + fp = fopen(RESOLV_CONF, "r"); + /* XXX Use lwres resolv.conf reader */ + if (fp == NULL) + goto no_file; + + while (fgets(rcinput, MXNAME, fp) != 0) { + input = rcinput; + ptr = next_token(&input, " \t\r\n"); + if (ptr != NULL) { + if (get_servers && + strcasecmp(ptr, "nameserver") == 0) { + debug("got a nameserver line"); + ptr = next_token(&input, " \t\r\n"); + if (ptr != NULL) { + srv = make_server(ptr); + ISC_LIST_APPEND(server_list, srv, link); + } + } else if (strcasecmp(ptr, "options") == 0) { + ptr = next_token(&input, " \t\r\n"); + if (ptr != NULL) { + if (strncasecmp(ptr, "ndots:", 6) == 0 + && ndots == -1) + { + ndots = atoi(&ptr[6]); + debug("ndots is %d.", ndots); + } + } + } else if (strcasecmp(ptr, "search") == 0){ + while ((ptr = next_token(&input, " \t\r\n")) + != NULL) { + debug("adding search %s", ptr); + search = make_searchlist_entry(ptr); + ISC_LIST_INITANDAPPEND(search_list, + search, link); + } + } else if (strcasecmp(ptr, "domain") == 0) { + while ((ptr = next_token(&input, " \t\r\n")) + != NULL) { + if (domain != NULL) + isc_mem_free(mctx, domain); + domain = make_searchlist_entry(ptr); + } + } + } + } + fclose(fp); + no_file: + + if (ISC_LIST_EMPTY(search_list) && domain != NULL) { + ISC_LIST_INITANDAPPEND(search_list, domain, link); + domain = NULL; + } + if (domain != NULL) + isc_mem_free(mctx, domain); + + if (ndots == -1) + ndots = 1; + + if (server_list.head == NULL) { + srv = make_server("127.0.0.1"); + ISC_LIST_APPEND(server_list, srv, link); + } + + if (keyfile[0] != 0) + setup_file_key(); + else if (keysecret[0] != 0) + setup_text_key(); +} + +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_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 = 0; + 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); + 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_server_t *s; + dig_query_t *q; + void *ptr; + + 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. + */ + debug("cleared"); + 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); + return (ISC_TRUE); +} + + +/* + * 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); + 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; + + 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); + + rdataset = NULL; + result = dns_message_findtype(name, dns_rdatatype_ns, 0, + &rdataset); + if (result != ISC_R_SUCCESS) + continue; + + debug("found NS set"); + + 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; + } + srv = make_server(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)); + + 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; + + 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) + /* + * Then we just did rootorg; there's nothing left. + */ + return (ISC_FALSE); + lookup = requeue_lookup(query->lookup, ISC_TRUE); + lookup->origin = ISC_LIST_NEXT(query->lookup->origin, link); + 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]; + + 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)); + + /* + * 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. + */ + /* XXX New search here? */ + if ((count_dots(lookup->textname) >= ndots) || !usesearch) + lookup->origin = NULL; /* Force abs lookup */ + else if (lookup->origin == NULL && lookup->new_search && usesearch) { + lookup->origin = ISC_LIST_HEAD(search_list); + } + 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 { + debug("using root origin"); + 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, + dns_rootname, + ISC_FALSE, + &lookup->namebuf); + } + 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->sendbuf, lookup->sendspace, COMMSIZE); + result = dns_message_renderbegin(lookup->sendmsg, &cctx, + &lookup->sendbuf); + check_result(result, "dns_message_renderbegin"); + if (lookup->udpsize > 0 || lookup->dnssec) { + if (lookup->udpsize == 0) + lookup->udpsize = 2048; + add_opt(lookup->sendmsg, lookup->udpsize, 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->sendbuf) > 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->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->rr_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); + + ISC_LINK_INIT(query, link); + ISC_LIST_ENQUEUE(lookup->q, query, link); + } + /* XXX qrflag, print_query, etc... */ + if (!ISC_LIST_EMPTY(lookup->q) && qr) { + 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) { + REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE); + + UNUSED(_task); + + LOCK_LOOKUP; + + isc_event_free(&event); + + debug("send_done()"); + sendcount--; + debug("sendcount=%d", sendcount); + INSIST(sendcount >= 0); + 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; + dig_query_t *next; + 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_LINK_INIT(&l->sendbuf, link); + ISC_LIST_ENQUEUE(query->sendlist, &l->sendbuf, + link); + debug("sending a request"); + result = isc_time_now(&query->time_sent); + check_result(result, "isc_time_now"); + INSIST(query->sock != NULL); + result = isc_socket_sendtov(query->sock, &query->sendlist, + global_task, send_done, query, + &query->sockaddr, NULL); + check_result(result, "isc_socket_sendtov"); + sendcount++; + /* + * 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_udp(next); + } +} + +/* + * 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, *n; + 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--; + n = 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); + + 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; + } + b = ISC_LIST_HEAD(sevent->bufferlist); + ISC_LIST_DEQUEUE(sevent->bufferlist, &query->lengthbuf, link); + 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->lookup->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_LINK_INIT(&query->lookup->sendbuf, link); + ISC_LIST_ENQUEUE(query->sendlist, &query->lookup->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"); + result = isc_time_now(&query->time_sent); + check_result(result, "isc_time_now"); + 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. + */ + + 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; + 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; + + 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; + + 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; + } + + b = ISC_LIST_HEAD(sevent->bufferlist); + ISC_LIST_DEQUEUE(sevent->bufferlist, &query->recvbuf, link); + + if (!l->tcp_mode && + !isc_sockaddr_equal(&sevent->address, &query->sockaddr)) { + 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 (!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; + 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) { + 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)) { + printf(";; Got SERVFAIL reply from %s, " + "trying next server\n", + 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"); + } + + 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) { + if (!next_origin(msg, query)) { + printmessage(query, msg, ISC_TRUE); + received(b->used, &sevent->address, query); + } + } else if (!l->trace && !l->ns_search_only) { + 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 + printmessage(query, msg, ISC_TRUE); + } + } + + 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) + 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) + { + dns_message_destroy(&msg); + cancel_lookup(l); + } + clear_query(query); + check_next_lookup(l); + } + if (msg != NULL) + 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) { + struct in_addr in4; + struct in6_addr in6; +#ifdef USE_GETADDRINFO + struct addrinfo *res = NULL, hints; + int result; +#else + struct hostent *he; +#endif + + debug("get_address()"); + + if (inet_pton(AF_INET6, host, &in6) == 1) { + if (!have_ipv6) + fatal("Protocol family INET6 not supported '%s'", host); + isc_sockaddr_fromin6(sockaddr, &in6, port); + } else if (inet_pton(AF_INET, host, &in4) == 1) { + if (have_ipv4) + isc_sockaddr_fromin(sockaddr, &in4, port); + else + isc_sockaddr_v6fromin(sockaddr, &in4, port); + } else { +#ifdef USE_GETADDRINFO + memset(&hints, 0, sizeof(hints)); + if (specified_source) + hints.ai_family = isc_sockaddr_pf(&bind_address); + else if (!have_ipv6) + hints.ai_family = PF_INET; + else if (!have_ipv4) + hints.ai_family = PF_INET6; + else { + hints.ai_family = PF_UNSPEC; +#ifdef AI_ADDRCONFIG + hints.ai_flags = AI_ADDRCONFIG; +#endif + } + debug ("before getaddrinfo()"); + isc_app_block(); +#ifdef AI_ADDRCONFIG + again: +#endif + result = getaddrinfo(host, NULL, &hints, &res); +#ifdef AI_ADDRCONFIG + if (result == EAI_BADFLAGS && + (hints.ai_flags & AI_ADDRCONFIG) != 0) { + hints.ai_flags &= ~AI_ADDRCONFIG; + goto again; + } +#endif + isc_app_unblock(); + if (result != 0) { + fatal("Couldn't find server '%s': %s", + host, gai_strerror(result)); + } + memcpy(&sockaddr->type.sa, res->ai_addr, res->ai_addrlen); + sockaddr->length = res->ai_addrlen; + isc_sockaddr_setport(sockaddr, port); + freeaddrinfo(res); +#else + debug ("before gethostbyname()"); + isc_app_block(); + he = gethostbyname(host); + isc_app_unblock(); + if (he == NULL) + fatal("Couldn't find server '%s' (h_errno=%d)", + host, h_errno); + INSIST(he->h_addrtype == AF_INET); + isc_sockaddr_fromin(sockaddr, + (struct in_addr *)(he->h_addr_list[0]), + port); +#endif + } +} + +/* + * 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) { + void *ptr; + dig_server_t *s; + + 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; + + s = ISC_LIST_HEAD(server_list); + while (s != NULL) { + debug("freeing global server %p", s); + ptr = s; + s = ISC_LIST_NEXT(s, link); + isc_mem_free(mctx, ptr); + } + clear_searchlist(); + 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); + if (memdebugging != 0) + isc_mem_stats(mctx, stderr); + if (mctx != NULL) + isc_mem_destroy(&mctx); +} diff --git a/contrib/bind-9.2.4rc7/bin/dig/host.1 b/contrib/bind-9.2.4rc7/bin/dig/host.1 new file mode 100644 index 0000000..7201e9d --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dig/host.1 @@ -0,0 +1,130 @@ +.\" Copyright (C) 2004 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: host.1,v 1.11.2.2 2004/03/15 04:44:38 marka Exp $ +.\" +.TH "HOST" "1" "Jun 30, 2000" "BIND9" "" +.SH NAME +host \- DNS lookup utility +.SH SYNOPSIS +.sp +\fBhost\fR [ \fB-aCdlnrTwv\fR ] [ \fB-c \fIclass\fB\fR ] [ \fB-N \fIndots\fB\fR ] [ \fB-R \fInumber\fB\fR ] [ \fB-t \fItype\fB\fR ] [ \fB-W \fIwait\fB\fR ] \fBname\fR [ \fBserver\fR ] +.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. The argument is provided for +compatibility with older implementations. This option is equivalent +to making a query of type AXFR. +.PP +The \fB-n\fR +option specifies that reverse lookups of IPv6 addresses should +use the IP6.INT domain and "nibble" labels as defined in RFC1886. +The default is to use IP6.ARPA and binary labels as defined in RFC2874. +.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 behaviour 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-t\fR option is used to select the query type. +\fItype\fR can be any recognised 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. +.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. +.SH "FILES" +.PP +\fI/etc/resolv.conf\fR +.SH "SEE ALSO" +.PP +\fBdig\fR(1), +\fBnamed\fR(8). diff --git a/contrib/bind-9.2.4rc7/bin/dig/host.c b/contrib/bind-9.2.4rc7/bin/dig/host.c new file mode 100644 index 0000000..403481d --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dig/host.c @@ -0,0 +1,728 @@ +/* + * Copyright (C) 2004 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: host.c,v 1.76.2.6 2004/03/09 06:09:13 marka Exp $ */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +extern ISC_LIST(dig_lookup_t) lookup_list; +extern ISC_LIST(dig_server_t) server_list; +extern ISC_LIST(dig_searchlist_t) search_list; + +extern isc_boolean_t usesearch; +extern isc_boolean_t debugging; +extern unsigned int timeout; +extern isc_mem_t *mctx; +extern int ndots; +extern int tries; +extern char *progname; +extern isc_task_t *global_task; +extern int fatalexit; + +static isc_boolean_t short_form = ISC_TRUE, listed_server = ISC_FALSE; +static isc_boolean_t list_addresses = ISC_TRUE; +static dns_rdatatype_t list_type = dns_rdatatype_a; + +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" +}; + +static const char *rtypetext[] = { + "zero", /* 0 */ + "has address", /* 1 */ + "name server", /* 2 */ + "MD", /* 3 */ + "MF", /* 4 */ + "is an alias for", /* 5 */ + "SOA", /* 6 */ + "MB", /* 7 */ + "MG", /* 8 */ + "MR", /* 9 */ + "NULL", /* 10 */ + "has well known services", /* 11 */ + "domain name pointer", /* 12 */ + "host information", /* 13 */ + "MINFO", /* 14 */ + "mail is handled by", /* 15 */ + "text", /* 16 */ + "RP", /* 17 */ + "AFSDB", /* 18 */ + "x25 address", /* 19 */ + "isdn address", /* 20 */ + "RT", /* 21 */ + "NSAP", /* 22 */ + "NSAP_PTR", /* 23 */ + "has signature", /* 24 */ + "has key", /* 25 */ + "PX", /* 26 */ + "GPOS", /* 27 */ + "has AAAA address", /* 28 */ + "LOC", /* 29 */ + "has next record", /* 30 */ + "EID", /* 31 */ + "NIMLOC", /* 32 */ + "SRV", /* 33 */ + "ATMA", /* 34 */ + "NAPTR", /* 35 */ + "KX", /* 36 */ + "CERT", /* 37 */ + "has v6 address", /* 38 */ + "DNAME", /* 39 */ + "has optional information", /* 41 */ + "has 42 record", /* 42 */ + "has 43 record", /* 43 */ + "has 44 record", /* 44 */ + "has 45 record", /* 45 */ + "has 46 record", /* 46 */ + "has 47 record", /* 47 */ + "has 48 record", /* 48 */ + "has 49 record", /* 49 */ + "has 50 record", /* 50 */ + "has 51 record", /* 51 */ + "has 52 record", /* 52 */ + "has 53 record", /* 53 */ + "has 54 record", /* 54 */ + "has 55 record", /* 55 */ + "has 56 record", /* 56 */ + "has 57 record", /* 57 */ + "has 58 record", /* 58 */ + "has 59 record", /* 59 */ + "has 60 record", /* 60 */ + "has 61 record", /* 61 */ + "has 62 record", /* 62 */ + "has 63 record", /* 63 */ + "has 64 record", /* 64 */ + "has 65 record", /* 65 */ + "has 66 record", /* 66 */ + "has 67 record", /* 67 */ + "has 68 record", /* 68 */ + "has 69 record", /* 69 */ + "has 70 record", /* 70 */ + "has 71 record", /* 71 */ + "has 72 record", /* 72 */ + "has 73 record", /* 73 */ + "has 74 record", /* 74 */ + "has 75 record", /* 75 */ + "has 76 record", /* 76 */ + "has 77 record", /* 77 */ + "has 78 record", /* 78 */ + "has 79 record", /* 79 */ + "has 80 record", /* 80 */ + "has 81 record", /* 81 */ + "has 82 record", /* 82 */ + "has 83 record", /* 83 */ + "has 84 record", /* 84 */ + "has 85 record", /* 85 */ + "has 86 record", /* 86 */ + "has 87 record", /* 87 */ + "has 88 record", /* 88 */ + "has 89 record", /* 89 */ + "has 90 record", /* 90 */ + "has 91 record", /* 91 */ + "has 92 record", /* 92 */ + "has 93 record", /* 93 */ + "has 94 record", /* 94 */ + "has 95 record", /* 95 */ + "has 96 record", /* 96 */ + "has 97 record", /* 97 */ + "has 98 record", /* 98 */ + "has 99 record", /* 99 */ + "UINFO", /* 100 */ + "UID", /* 101 */ + "GID", /* 102 */ + "UNSPEC"}; /* 103 */ + + +static void +show_usage(void) { + fputs( +"Usage: host [-aCdlrTwv] [-c class] [-n] [-N ndots] [-t type] [-W time]\n" +" [-R number] hostname [server]\n" +" -a is equivalent to -v -t *\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 Use the old IN6.INT form of IPv6 reverse lookup\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" +" -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", 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; + isc_result_t result; + int diff; + + if (!short_form) { + char fromtext[ISC_SOCKADDR_FORMATSIZE]; + isc_sockaddr_format(from, fromtext, sizeof(fromtext)); + result = isc_time_now(&now); + check_result(result, "isc_time_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); +} + + +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; + const char *rtt; + + 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) { + dns_rdataset_current(rdataset, &rdata); + if (rdata.type <= 103) + rtt = rtypetext[rdata.type]; + else if (rdata.type == 249) + rtt = "key"; + else if (rdata.type == 250) + rtt = "signature"; + else + rtt = "unknown"; + 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); +} + +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; + + UNUSED(headers); + + if (listed_server) { + char sockstr[ISC_SOCKADDR_FORMATSIZE]; + + printf("Using domain server:\n"); + printf("Name: %s\n", query->servname); + isc_sockaddr_format(&query->sockaddr, sockstr, + sizeof(sockstr)); + printf("Address: %s\n", sockstr); + printf("Aliases: \n\n"); + } + + 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", namestr, + msg->rcode, rcodetext[msg->rcode]); + return (ISC_R_SUCCESS); + } + 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"); + + return (result); +} + +static void +parse_args(isc_boolean_t is_batchfile, int argc, char **argv) { + char hostname[MXNAME]; + dig_server_t *srv; + 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; + + UNUSED(is_batchfile); + + lookup = make_empty_lookup(); + + while ((c = isc_commandline_parse(argc, argv, "ilvwrdt:c:aTCN:R:W:Dn")) + != EOF) { + 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': + 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; + if (rdtype == dns_rdatatype_axfr) { + /* -l -t any -v */ + list_type = dns_rdatatype_any; + short_form = ISC_FALSE; + lookup->tcp_mode = ISC_TRUE; + } else + list_type = rdtype; + list_addresses = 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; + } + 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; + break; + case 'i': + lookup->ip6_int = ISC_TRUE; + break; + case 'n': + 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); + if (tries < 1) + tries = 1; + 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; + break; + case 'N': + debug("setting NDOTS to %s", + isc_commandline_argument); + ndots = atoi(isc_commandline_argument); + break; + case 'D': + debugging = ISC_TRUE; + break; + } + } + 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) { + srv = make_server(argv[isc_commandline_index+1]); + debug("server is %s", srv->servername); + ISC_LIST_APPEND(server_list, srv, link); + listed_server = ISC_TRUE; + } + + lookup->pending = ISC_FALSE; + if (get_reverse(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; + } 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; + + ISC_LIST_INIT(lookup_list); + ISC_LIST_INIT(server_list); + ISC_LIST_INIT(search_list); + + fatalexit = 1; + + debug("main()"); + progname = argv[0]; + 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 (0); +} + diff --git a/contrib/bind-9.2.4rc7/bin/dig/host.html b/contrib/bind-9.2.4rc7/bin/dig/host.html new file mode 100644 index 0000000..c912fb3 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dig/host.html @@ -0,0 +1,443 @@ + + + + +host

host

Name

host -- DNS lookup utility

Synopsis

host [-aCdlnrTwv] [-c class] [-N ndots] [-R number] [-t type] [-W wait] {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. The argument is provided for +compatibility with older implementations. This option is equivalent +to making a query of type AXFR.

The -n +option specifies that reverse lookups of IPv6 addresses should +use the IP6.INT domain and "nibble" labels as defined in RFC1886. +The default is to use IP6.ARPA and binary labels as defined in RFC2874.

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 behaviour 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 -t option is used to select the query type. +type can be any recognised 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.

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.

FILES

/etc/resolv.conf

SEE ALSO

dig(1), +named(8).

diff --git a/contrib/bind-9.2.4rc7/bin/dig/include/dig/dig.h b/contrib/bind-9.2.4rc7/bin/dig/include/dig/dig.h new file mode 100644 index 0000000..3b2d9e6 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dig/include/dig/dig.h @@ -0,0 +1,280 @@ +/* + * 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: dig.h,v 1.71.2.7 2004/03/09 06:09:14 marka Exp $ */ + +#ifndef DIG_H +#define DIG_H + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MXSERV 6 +#define MXNAME (DNS_NAME_MAXTEXT+1) +#define MXRD 32 +#define BUFSIZE 512 +#define COMMSIZE 0xffff +#ifndef RESOLV_CONF +#define RESOLV_CONF "/etc/resolv.conf" +#endif +#define OUTPUTBUF 32767 +#define MAXRRLIMIT 0xffffffff +#define MAXTIMEOUT 0xffff +#define MAXTRIES 0xffffffff +#define MAXNDOTS 0xffff +#define MAXPORT 0xffff +#define MAXSERIAL 0xffffffff + +/* + * Default timeout values + */ +#define TCP_TIMEOUT 10 +#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. + */ + +#define ROOTNS 1 +/* + * Set the number of root servers to ask for information when running in + * trace mode. + * XXXMWS -- trace mode is currently semi-broken, and this number *MUST* + * be 1. + */ + +ISC_LANG_BEGINDECLS + +typedef struct dig_lookup dig_lookup_t; +typedef struct dig_query dig_query_t; +typedef struct dig_server dig_server_t; +typedef ISC_LIST(dig_server_t) dig_serverlist_t; +typedef struct dig_searchlist dig_searchlist_t; + +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, + besteffort, + dnssec; + char textname[MXNAME]; /* Name we're going to be looking up */ + char cmdline[MXNAME]; + dns_rdatatype_t rdtype; + dns_rdatatype_t qrdtype; + 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 sendbuf; + 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_uint32_t ixfr_serial; + isc_buffer_t rdatabuf; + char rdatastore[MXNAME]; + dst_context_t *tsigctx; + isc_buffer_t *querysig; + isc_uint32_t msgcounter; +}; + +struct dig_query { + dig_lookup_t *lookup; + isc_boolean_t waiting_connect, + 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 rr_count; + char *servname; + 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; +}; + +struct dig_server { + char servername[MXNAME]; + ISC_LINK(dig_server_t) link; +}; + +struct dig_searchlist { + char origin[MXNAME]; + ISC_LINK(dig_searchlist_t) link; +}; + +/* + * Routines in dighost.c. + */ +void +get_address(char *host, in_port_t port, isc_sockaddr_t *sockaddr); + +isc_result_t +get_reverse(char *reverse, char *value, isc_boolean_t ip6int, + 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 +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); + +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); + +/* + * Routines to be defined in dig.c, host.c, and nslookup.c. + */ + +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); + +ISC_LANG_ENDDECLS + +#endif diff --git a/contrib/bind-9.2.4rc7/bin/dig/nslookup.c b/contrib/bind-9.2.4rc7/bin/dig/nslookup.c new file mode 100644 index 0000000..28244b6 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dig/nslookup.c @@ -0,0 +1,882 @@ +/* + * Copyright (C) 2004 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: nslookup.c,v 1.90.2.7 2004/06/07 03:59:08 marka Exp $ */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +extern ISC_LIST(dig_lookup_t) lookup_list; +extern ISC_LIST(dig_server_t) server_list; +extern ISC_LIST(dig_searchlist_t) search_list; + +extern isc_boolean_t have_ipv6, usesearch, qr, debugging; +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 tries; +extern int lookup_counter; +extern int exitcode; +extern isc_taskmgr_t *taskmgr; +extern isc_task_t *global_task; +extern char *progname; + +static isc_boolean_t short_form = ISC_TRUE, + tcpmode = ISC_FALSE, deprecation_msg = ISC_TRUE, + 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; +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)); +} + +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->servname); + 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", nametext, + 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->servername, 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 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) { + port = atoi(&opt[5]); + } else if (strncasecmp(opt, "po=", 3) == 0) { + port = atoi(&opt[3]); + } else if (strncasecmp(opt, "timeout=", 8) == 0) { + timeout = atoi(&opt[8]); + } else if (strncasecmp(opt, "t=", 2) == 0) { + timeout = atoi(&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) { + tries = atoi(&opt[6]); + } else if (strncasecmp(opt, "ret=", 4) == 0) { + tries = atoi(&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; + } else if (strncasecmp(opt, "nodeb", 5) == 0) { + short_form = ISC_TRUE; + } 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 { + 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, 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; + 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 +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); + } +} + +/* + * This works on the global server list, instead of on a per-lookup + * server list, since the change is persistent. + */ +static void +setsrv(char *opt) { + dig_server_t *srv; + + if (opt == NULL) + return; + + flush_server_list(); + srv = isc_mem_allocate(mctx, sizeof(struct dig_server)); + if (srv == NULL) + fatal("memory allocation failure"); + safecpy(srv->servername, opt, sizeof(srv->servername)); + ISC_LIST_INITANDAPPEND(server_list, srv, link); +} + +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); + 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)) { + setsrv(arg); + 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 + setsrv(argv[0]); + } + } +} + +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); + + result = isc_app_start(); + check_result(result, "isc_app_start"); + + setup_libs(); + progname = argv[0]; + + parse_args(argc, argv); + + if (deprecation_msg) { + fputs( +"Note: nslookup is deprecated and may be removed from future releases.\n" +"Consider using the `dig' or `host' programs instead. Run nslookup with\n" +"the `-sil[ent]' option to prevent this message from appearing.\n", stderr); + } + 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/bind-9.2.4rc7/bin/dnssec/dnssec-keygen.8 b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-keygen.8 new file mode 100644 index 0000000..297c872 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-keygen.8 @@ -0,0 +1,168 @@ +.\" 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: dnssec-keygen.8,v 1.19.2.2 2004/06/03 05:21:09 marka Exp $ +.\" +.TH "DNSSEC-KEYGEN" "8" "June 30, 2000" "BIND9" "" +.SH NAME +dnssec-keygen \- DNSSEC key generation tool +.SH SYNOPSIS +.sp +\fBdnssec-keygen\fR \fB-a \fIalgorithm\fB\fR \fB-b \fIkeysize\fB\fR \fB-n \fInametype\fB\fR [ \fB-c \fIclass\fB\fR ] [ \fB-e\fR ] [ \fB-g \fIgenerator\fB\fR ] [ \fB-h\fR ] [ \fB-p \fIprotocol\fB\fR ] [ \fB-r \fIrandomdev\fB\fR ] [ \fB-s \fIstrength\fB\fR ] [ \fB-t \fItype\fB\fR ] [ \fB-v \fIlevel\fB\fR ] \fBname\fR +.SH "DESCRIPTION" +.PP +\fBdnssec-keygen\fR generates keys for DNSSEC +(Secure DNS), as defined in RFC 2535. It can also generate +keys for use with TSIG (Transaction Signatures), as +defined in RFC 2845. +.SH "OPTIONS" +.TP +\fB-a \fIalgorithm\fB\fR +Selects the cryptographic algorithm. The value of +\fBalgorithm\fR must be one of RSAMD5 or RSA, +DSA, DH (Diffie Hellman), or HMAC-MD5. These values +are case insensitive. + +Note that for DNSSEC, DSA is a mandatory to implement algorithm, +and RSA is recommended. For TSIG, HMAC-MD5 is mandatory. +.TP +\fB-b \fIkeysize\fB\fR +Specifies the number of bits in the key. The choice of key +size depends on the algorithm used. RSA 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. +.TP +\fB-n \fInametype\fB\fR +Specifies the owner type of the key. The value of +\fBnametype\fR must either be ZONE (for a DNSSEC +zone key), HOST or ENTITY (for a key associated with a host), +or USER (for a key associated with a user). These values are +case insensitive. +.TP +\fB-c \fIclass\fB\fR +Indicates that the DNS record containing the key should have +the specified class. If not specified, class IN is used. +.TP +\fB-e\fR +If generating an RSA key, use a large exponent. +.TP +\fB-g \fIgenerator\fB\fR +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. +.TP +\fB-h\fR +Prints a short summary of the options and arguments to +\fBdnssec-keygen\fR. +.TP +\fB-p \fIprotocol\fB\fR +Sets the protocol value for the generated key. The protocol +is a number between 0 and 255. The default is 2 (email) for +keys of type USER and 3 (DNSSEC) for all other key types. +Other possible values for this argument are listed in +RFC 2535 and its successors. +.TP +\fB-r \fIrandomdev\fB\fR +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. +.TP +\fB-s \fIstrength\fB\fR +Specifies the strength value of the key. The strength is +a number between 0 and 15, and currently has no defined +purpose in DNSSEC. +.TP +\fB-t \fItype\fB\fR +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. +.TP +\fB-v \fIlevel\fB\fR +Sets the debugging level. +.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. These strings can be used as arguments +to \fBdnssec-makekeyset\fR. +.TP 0.2i +\(bu +\fInnnn\fR is the key name. +.TP 0.2i +\(bu +\fIaaa\fR is the numeric representation of the +algorithm. +.TP 0.2i +\(bu +\fIiiiii\fR is the key identifier (or footprint). +.PP +\fBdnssec-keygen\fR creates two file, 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 +.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 +.PP +The \fI.private\fR file contains algorithm specific +fields. For obvious security reasons, this file does not have +general read permission. +.PP +.PP +Both \fI.key\fR and \fI.private\fR +files are generated for symmetric encryption algorithm such as +HMAC-MD5, even though the public and private key are equivalent. +.PP +.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-makekeyset\fR(8), +\fBdnssec-signkey\fR(8), +\fBdnssec-signzone\fR(8), +\fIBIND 9 Administrator Reference Manual\fR, +\fIRFC 2535\fR, +\fIRFC 2845\fR, +\fIRFC 2539\fR. +.SH "AUTHOR" +.PP +Internet Systems Consortium diff --git a/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-keygen.c b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-keygen.c new file mode 100644 index 0000000..103cc12 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-keygen.c @@ -0,0 +1,402 @@ +/* + * Portions Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2000, 2001 Internet Software Consortium. + * Portions Copyright (C) 1995-2000 by Network Associates, 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 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.48.2.2 2004/03/09 06:09:14 marka Exp $ */ + +#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 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, "Required options:\n"); + fprintf(stderr, " -a algorithm: RSA | RSAMD5 | DH | DSA | HMAC-MD5" + "\n"); + fprintf(stderr, " -b key size, in bits:\n"); + fprintf(stderr, " RSA:\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, " -n nametype: ZONE | HOST | ENTITY | USER\n"); + fprintf(stderr, " name: owner of the key\n"); + fprintf(stderr, "Other options:\n"); + fprintf(stderr, " -c class (default: IN)\n"); + fprintf(stderr, " -e use large exponent (RSA only)\n"); + fprintf(stderr, " -g use specified generator (DH only)\n"); + fprintf(stderr, " -t type: AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF " + "(default: AUTHCONF)\n"); + fprintf(stderr, " -p protocol value " + "(default: 2 [email] for USER, 3 [dnssec] otherwise)\n"); + fprintf(stderr, " -s strength value this key signs DNS records " + "with (default: 0)\n"); + fprintf(stderr, " -r randomdev (a file containing random data)\n"); + fprintf(stderr, " -v verbose level\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 *randomfile = NULL; + char *prog, *endp; + dst_key_t *key = NULL, *oldkey; + dns_fixedname_t fname; + dns_name_t *name; + isc_uint16_t flags = 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; + + RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); + + if ((prog = strrchr(argv[0],'/')) == NULL) + prog = isc_mem_strdup(mctx, argv[0]); + else + prog = isc_mem_strdup(mctx, ++prog); + if (prog == NULL) + fatal("out of memory"); + + if (argc == 1) + usage(); + + dns_result_register(); + + while ((ch = isc_commandline_parse(argc, argv, + "a:b:c:eg:n:t:p:s:hr:v:")) != -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 'e': + rsa_exp = 1; + break; + case 'g': + generator = strtol(isc_commandline_argument, + &endp, 10); + if (*endp != '\0' || generator <= 0) + fatal("-g requires a positive number"); + break; + case 'n': + nametype = isc_commandline_argument; + if (nametype == NULL) + fatal("out of memory"); + break; + case 't': + type = isc_commandline_argument; + if (type == NULL) + fatal("out of memory"); + 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': + randomfile = isc_commandline_argument; + 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(); + } + } + + setup_entropy(mctx, randomfile, &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) + alg = DNS_KEYALG_RSA; + else if (strcasecmp(algname, "HMAC-MD5") == 0) + alg = DST_ALG_HMACMD5; + 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 (type != NULL) { + 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_RSA: + 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); + break; + } + + if (alg != DNS_KEYALG_RSA && rsa_exp != 0) + fatal("specified RSA exponent without RSA"); + + if (alg != DNS_KEYALG_DH && generator != 0) + fatal("specified DH generator without DH"); + + if (nametype == NULL) + fatal("no nametype specified"); + if (strcasecmp(nametype, "zone") == 0) + flags |= DNS_KEYOWNER_ZONE; + else 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 nametype %s", nametype); + + if (classname != NULL) { + r.base = classname; + r.length = strlen(classname); + ret = dns_rdataclass_fromtext(&rdclass, &r); + if (ret != ISC_R_SUCCESS) + fatal("unknown class %s",classname); + } else + rdclass = dns_rdataclass_in; + + flags |= signatory; + + if (protocol == -1) { + if ((flags & DNS_KEYFLAG_OWNERMASK) == DNS_KEYOWNER_USER) + protocol = DNS_KEYPROTO_EMAIL; + else + protocol = DNS_KEYPROTO_DNSSEC; + } + + 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"); + } + + 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_RSA: + param = rsa_exp; + break; + case DNS_KEYALG_DH: + param = generator; + break; + case DNS_KEYALG_DSA: + case DST_ALG_HMACMD5: + 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); + } + + /* + * 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, DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, 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); + isc_mem_free(mctx, prog); + dst_key_free(&key); + + cleanup_logging(&log); + cleanup_entropy(&ectx); + dst_lib_destroy(); + if (verbose > 10) + isc_mem_stats(mctx, stdout); + isc_mem_destroy(&mctx); + + return (0); +} diff --git a/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-keygen.html b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-keygen.html new file mode 100644 index 0000000..18d8cdf --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-keygen.html @@ -0,0 +1,575 @@ + + + + +dnssec-keygen

dnssec-keygen

Name

dnssec-keygen -- DNSSEC key generation tool

Synopsis

dnssec-keygen {-a algorithm} {-b keysize} {-n nametype} [-c class] [-e] [-g generator] [-h] [-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. 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 or RSA, + DSA, DH (Diffie Hellman), or HMAC-MD5. These values + are case insensitive. +

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

-b keysize

Specifies the number of bits in the key. The choice of key + size depends on the algorithm used. RSA 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), HOST or ENTITY (for a key associated with a host), + or USER (for a key associated with a user). 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 RSA key, use a large exponent. +

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

-p protocol

Sets the protocol value for the generated key. The protocol + is a number between 0 and 255. The default is 2 (email) for + keys of type USER and 3 (DNSSEC) for all other key types. + 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. These strings can be used as arguments + to dnssec-makekeyset. +

  • nnnn is the key name. +

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

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

dnssec-keygen creates two file, 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 algorithm 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-makekeyset(8), + dnssec-signkey(8), + dnssec-signzone(8), + BIND 9 Administrator Reference Manual, + RFC 2535, + RFC 2845, + RFC 2539. +

AUTHOR

Internet Systems Consortium +

diff --git a/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-makekeyset.8 b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-makekeyset.8 new file mode 100644 index 0000000..63526ad --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-makekeyset.8 @@ -0,0 +1,113 @@ +.\" 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: dnssec-makekeyset.8,v 1.16.2.4 2004/06/03 05:21:10 marka Exp $ +.\" +.TH "DNSSEC-MAKEKEYSET" "8" "June 30, 2000" "BIND9" "" +.SH NAME +dnssec-makekeyset \- DNSSEC zone signing tool +.SH SYNOPSIS +.sp +\fBdnssec-makekeyset\fR [ \fB-a\fR ] [ \fB-s \fIstart-time\fB\fR ] [ \fB-e \fIend-time\fB\fR ] [ \fB-h\fR ] [ \fB-p\fR ] [ \fB-r \fIrandomdev\fB\fR ] [ \fB-t\fIttl\fB\fR ] [ \fB-v \fIlevel\fB\fR ] \fBkey\fR\fI...\fR +.SH "DESCRIPTION" +.PP +\fBdnssec-makekeyset\fR generates a key set from one +or more keys created by \fBdnssec-keygen\fR. It creates +a file containing a KEY record for each key, and self-signs the key +set with each zone key. The output file is of the form +\fIkeyset-nnnn.\fR, where \fInnnn\fR +is the zone name. +.SH "OPTIONS" +.TP +\fB-a\fR +Verify all generated signatures. +.TP +\fB-s \fIstart-time\fB\fR +Specify the date and time when the generated SIG 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 is used. +.TP +\fB-e \fIend-time\fB\fR +Specify the date and time when the generated SIG 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. +.TP +\fB-h\fR +Prints a short summary of the options and arguments to +\fBdnssec-makekeyset\fR. +.TP +\fB-p\fR +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. +.TP +\fB-r \fIrandomdev\fB\fR +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. +.TP +\fB-t \fIttl\fB\fR +Specify the TTL (time to live) of the KEY and SIG records. +The default is 3600 seconds. +.TP +\fB-v \fIlevel\fB\fR +Sets the debugging level. +.TP +\fBkey\fR +The list of keys to be included in the keyset file. These keys +are expressed in the form \fIKnnnn.+aaa+iiiii\fR +as generated by \fBdnssec-keygen\fR. +.SH "EXAMPLE" +.PP +The following command generates a keyset containing the DSA key for +\fBexample.com\fR generated in the +\fBdnssec-keygen\fR man page. +.PP +\fBdnssec-makekeyset -t 86400 -s 20000701120000 -e +2592000 Kexample.com.+003+26160\fR +.PP +In this example, \fBdnssec-makekeyset\fR creates +the file \fIkeyset-example.com.\fR. This file +contains the specified key and a self-generated signature. +.PP +The DNS administrator for \fBexample.com\fR could +send \fIkeyset-example.com.\fR to the DNS +administrator for \fB.com\fR for signing, if the +\&.com zone is DNSSEC-aware and the administrators of the two zones +have some mechanism for authenticating each other and exchanging +the keys and signatures securely. +.SH "SEE ALSO" +.PP +\fBdnssec-keygen\fR(8), +\fBdnssec-signkey\fR(8), +\fIBIND 9 Administrator Reference Manual\fR, +\fIRFC 2535\fR. +.SH "AUTHOR" +.PP +Internet Systems Consortium diff --git a/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-makekeyset.c b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-makekeyset.c new file mode 100644 index 0000000..ab7932d --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-makekeyset.c @@ -0,0 +1,466 @@ +/* + * Portions Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2000, 2001 Internet Software Consortium. + * Portions Copyright (C) 1995-2000 by Network Associates, 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 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-makekeyset.c,v 1.52.2.2 2004/03/09 06:09:15 marka Exp $ */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dnssectool.h" + +#define BUFSIZE 2048 + +const char *program = "dnssec-makekeyset"; +int verbose; + +typedef struct keynode keynode_t; +struct keynode { + dst_key_t *key; + ISC_LINK(keynode_t) link; +}; +typedef ISC_LIST(keynode_t) keylist_t; + +static isc_stdtime_t starttime = 0, endtime = 0, now; +static int ttl = -1; + +static isc_mem_t *mctx = NULL; +static isc_entropy_t *ectx = NULL; + +static keylist_t keylist; + +static void +usage(void) { + fprintf(stderr, "Usage:\n"); + fprintf(stderr, "\t%s [options] keys\n", program); + + fprintf(stderr, "\n"); + + fprintf(stderr, "Options: (default value in parenthesis) \n"); + fprintf(stderr, "\t-a\n"); + fprintf(stderr, "\t\tverify generated signatures\n"); + fprintf(stderr, "\t-s YYYYMMDDHHMMSS|+offset:\n"); + fprintf(stderr, "\t\tSIG start time - absolute|offset (now)\n"); + fprintf(stderr, "\t-e YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n"); + fprintf(stderr, "\t\tSIG end time - " + "absolute|from start|from now (now + 30 days)\n"); + fprintf(stderr, "\t-t ttl\n"); + fprintf(stderr, "\t-p\n"); + fprintf(stderr, "\t\tuse pseudorandom data (faster but less secure)\n"); + fprintf(stderr, "\t-r randomdev:\n"); + fprintf(stderr, "\t\ta file containing random data\n"); + fprintf(stderr, "\t-v level:\n"); + fprintf(stderr, "\t\tverbose level (0)\n"); + + fprintf(stderr, "\n"); + + fprintf(stderr, "keys:\n"); + fprintf(stderr, "\tkeyfile (Kname+alg+tag)\n"); + + fprintf(stderr, "\n"); + + fprintf(stderr, "Output:\n"); + fprintf(stderr, "\tkeyset (keyset-)\n"); + exit(0); +} + +static isc_boolean_t +zonekey_on_list(dst_key_t *key) { + keynode_t *keynode; + for (keynode = ISC_LIST_HEAD(keylist); + keynode != NULL; + keynode = ISC_LIST_NEXT(keynode, link)) + { + if (dst_key_compare(keynode->key, key)) + return (ISC_TRUE); + } + return (ISC_FALSE); +} + +static isc_boolean_t +rdata_on_list(dns_rdata_t *rdata, dns_rdatalist_t *list) { + dns_rdata_t *trdata; + for (trdata = ISC_LIST_HEAD(list->rdata); + trdata != NULL; + trdata = ISC_LIST_NEXT(trdata, link)) + { + if (dns_rdata_compare(trdata, rdata) == 0) + return (ISC_TRUE); + } + return (ISC_FALSE); +} + +int +main(int argc, char *argv[]) { + int i, ch; + char *startstr = NULL, *endstr = NULL; + char *randomfile = NULL; + dns_fixedname_t fdomain; + dns_name_t *domain = NULL; + char *output = NULL; + char *endp; + unsigned char *data; + dns_db_t *db; + dns_dbnode_t *node; + dns_dbversion_t *version; + dst_key_t *key = NULL; + dns_rdata_t *rdata; + dns_rdatalist_t rdatalist, sigrdatalist; + dns_rdataset_t rdataset, sigrdataset; + isc_result_t result; + isc_buffer_t b; + isc_region_t r; + isc_log_t *log = NULL; + keynode_t *keynode; + dns_name_t *savedname = NULL; + unsigned int eflags; + isc_boolean_t pseudorandom = ISC_FALSE; + isc_boolean_t tryverify = ISC_FALSE; + + result = isc_mem_create(0, 0, &mctx); + if (result != ISC_R_SUCCESS) + fatal("failed to create memory context: %s", + isc_result_totext(result)); + + dns_result_register(); + + while ((ch = isc_commandline_parse(argc, argv, "as:e:t:r:v:ph")) != -1) + { + switch (ch) { + case 'a': + tryverify = ISC_TRUE; + break; + case 's': + startstr = isc_commandline_argument; + break; + + case 'e': + endstr = isc_commandline_argument; + break; + + case 't': + endp = NULL; + ttl = strtol(isc_commandline_argument, &endp, 0); + if (*endp != '\0') + fatal("TTL must be numeric"); + break; + + case 'r': + randomfile = isc_commandline_argument; + break; + + case 'v': + endp = NULL; + verbose = strtol(isc_commandline_argument, &endp, 0); + if (*endp != '\0') + fatal("verbose level must be numeric"); + break; + + case 'p': + pseudorandom = ISC_TRUE; + break; + + case 'h': + default: + usage(); + + } + } + + argc -= isc_commandline_index; + argv += isc_commandline_index; + + if (argc < 1) + usage(); + + setup_entropy(mctx, randomfile, &ectx); + eflags = ISC_ENTROPY_BLOCKING; + if (!pseudorandom) + eflags |= ISC_ENTROPY_GOODONLY; + result = dst_lib_init(mctx, ectx, eflags); + if (result != ISC_R_SUCCESS) + fatal("could not initialize dst: %s", + isc_result_totext(result)); + + isc_stdtime_get(&now); + + if (startstr != NULL) + starttime = strtotime(startstr, now, now); + else + starttime = now; + + if (endstr != NULL) + endtime = strtotime(endstr, now, starttime); + else + endtime = starttime + (30 * 24 * 60 * 60); + + if (ttl == -1) { + ttl = 3600; + fprintf(stderr, "%s: TTL not specified, assuming 3600\n", + program); + } + + setup_logging(verbose, mctx, &log); + + dns_rdatalist_init(&rdatalist); + rdatalist.rdclass = 0; + rdatalist.type = dns_rdatatype_key; + rdatalist.covers = 0; + rdatalist.ttl = ttl; + + ISC_LIST_INIT(keylist); + + for (i = 0; i < argc; i++) { + char namestr[DNS_NAME_FORMATSIZE]; + isc_buffer_t namebuf; + + key = NULL; + result = dst_key_fromnamedfile(argv[i], DST_TYPE_PUBLIC, + mctx, &key); + if (result != ISC_R_SUCCESS) + fatal("error loading key from %s: %s", argv[i], + isc_result_totext(result)); + if (rdatalist.rdclass == 0) + rdatalist.rdclass = dst_key_class(key); + + isc_buffer_init(&namebuf, namestr, sizeof namestr); + result = dns_name_tofilenametext(dst_key_name(key), + ISC_FALSE, + &namebuf); + check_result(result, "dns_name_tofilenametext"); + isc_buffer_putuint8(&namebuf, 0); + + if (savedname == NULL) { + savedname = isc_mem_get(mctx, sizeof(dns_name_t)); + if (savedname == NULL) + fatal("out of memory"); + dns_name_init(savedname, NULL); + result = dns_name_dup(dst_key_name(key), mctx, + savedname); + if (result != ISC_R_SUCCESS) + fatal("out of memory"); + } else { + char savednamestr[DNS_NAME_FORMATSIZE]; + dns_name_format(savedname, savednamestr, + sizeof savednamestr); + if (!dns_name_equal(savedname, dst_key_name(key)) != 0) + fatal("all keys must have the same owner - %s " + "and %s do not match", + savednamestr, namestr); + } + if (output == NULL) { + output = isc_mem_allocate(mctx, + strlen("keyset-") + + strlen(namestr) + 1); + if (output == NULL) + fatal("out of memory"); + strcpy(output, "keyset-"); + strcat(output, namestr); + } + if (domain == NULL) { + dns_fixedname_init(&fdomain); + domain = dns_fixedname_name(&fdomain); + dns_name_copy(dst_key_name(key), domain, NULL); + } + if (dst_key_iszonekey(key)) { + dst_key_t *zonekey = NULL; + result = dst_key_fromnamedfile(argv[i], + DST_TYPE_PUBLIC | + DST_TYPE_PRIVATE, + mctx, &zonekey); + if (result != ISC_R_SUCCESS) + fatal("failed to read private key %s: %s", + argv[i], isc_result_totext(result)); + if (!zonekey_on_list(zonekey)) { + keynode = isc_mem_get(mctx, + sizeof (keynode_t)); + if (keynode == NULL) + fatal("out of memory"); + keynode->key = zonekey; + ISC_LIST_INITANDAPPEND(keylist, keynode, link); + } else + dst_key_free(&zonekey); + } + rdata = isc_mem_get(mctx, sizeof(dns_rdata_t)); + if (rdata == NULL) + fatal("out of memory"); + dns_rdata_init(rdata); + data = isc_mem_get(mctx, BUFSIZE); + if (data == NULL) + fatal("out of memory"); + isc_buffer_init(&b, data, BUFSIZE); + result = dst_key_todns(key, &b); + if (result != ISC_R_SUCCESS) + fatal("failed to convert key %s to a DNS KEY: %s", + argv[i], isc_result_totext(result)); + isc_buffer_usedregion(&b, &r); + dns_rdata_fromregion(rdata, rdatalist.rdclass, + dns_rdatatype_key, &r); + if (!rdata_on_list(rdata, &rdatalist)) + ISC_LIST_APPEND(rdatalist.rdata, rdata, link); + else { + isc_mem_put(mctx, data, BUFSIZE); + isc_mem_put(mctx, rdata, sizeof *rdata); + } + dst_key_free(&key); + } + + dns_rdataset_init(&rdataset); + result = dns_rdatalist_tordataset(&rdatalist, &rdataset); + check_result(result, "dns_rdatalist_tordataset()"); + + dns_rdatalist_init(&sigrdatalist); + sigrdatalist.rdclass = rdatalist.rdclass; + sigrdatalist.type = dns_rdatatype_sig; + sigrdatalist.covers = dns_rdatatype_key; + sigrdatalist.ttl = ttl; + + if (ISC_LIST_EMPTY(keylist)) + fprintf(stderr, + "%s: no private zone key found; not self-signing\n", + program); + for (keynode = ISC_LIST_HEAD(keylist); + keynode != NULL; + keynode = ISC_LIST_NEXT(keynode, link)) + { + rdata = isc_mem_get(mctx, sizeof(dns_rdata_t)); + if (rdata == NULL) + fatal("out of memory"); + dns_rdata_init(rdata); + data = isc_mem_get(mctx, BUFSIZE); + if (data == NULL) + fatal("out of memory"); + isc_buffer_init(&b, data, BUFSIZE); + result = dns_dnssec_sign(domain, &rdataset, keynode->key, + &starttime, &endtime, mctx, &b, + rdata); + isc_entropy_stopcallbacksources(ectx); + if (result != ISC_R_SUCCESS) { + char keystr[KEY_FORMATSIZE]; + key_format(keynode->key, keystr, sizeof keystr); + fatal("failed to sign keyset with key %s: %s", + keystr, isc_result_totext(result)); + } + if (tryverify) { + result = dns_dnssec_verify(domain, &rdataset, + keynode->key, ISC_TRUE, + mctx, rdata); + if (result != ISC_R_SUCCESS) { + char keystr[KEY_FORMATSIZE]; + key_format(keynode->key, keystr, sizeof keystr); + fatal("signature from key '%s' failed to " + "verify: %s", + keystr, isc_result_totext(result)); + } + } + ISC_LIST_APPEND(sigrdatalist.rdata, rdata, link); + dns_rdataset_init(&sigrdataset); + result = dns_rdatalist_tordataset(&sigrdatalist, &sigrdataset); + check_result(result, "dns_rdatalist_tordataset()"); + } + + db = NULL; + result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, + rdataset.rdclass, 0, NULL, &db); + if (result != ISC_R_SUCCESS) { + char domainstr[DNS_NAME_FORMATSIZE]; + dns_name_format(domain, domainstr, sizeof domainstr); + fatal("failed to create a database for %s", domainstr); + } + + version = NULL; + dns_db_newversion(db, &version); + + node = NULL; + result = dns_db_findnode(db, domain, ISC_TRUE, &node); + check_result(result, "dns_db_findnode()"); + + dns_db_addrdataset(db, node, version, 0, &rdataset, 0, NULL); + if (!ISC_LIST_EMPTY(keylist)) + dns_db_addrdataset(db, node, version, 0, &sigrdataset, 0, + NULL); + + dns_db_detachnode(db, &node); + dns_db_closeversion(db, &version, ISC_TRUE); + result = dns_db_dump(db, version, output); + if (result != ISC_R_SUCCESS) { + char domainstr[DNS_NAME_FORMATSIZE]; + dns_name_format(domain, domainstr, sizeof domainstr); + fatal("failed to write database for %s to %s", + domainstr, output); + } + + printf("%s\n", output); + + dns_db_detach(&db); + + dns_rdataset_disassociate(&rdataset); + while (!ISC_LIST_EMPTY(rdatalist.rdata)) { + rdata = ISC_LIST_HEAD(rdatalist.rdata); + ISC_LIST_UNLINK(rdatalist.rdata, rdata, link); + isc_mem_put(mctx, rdata->data, BUFSIZE); + isc_mem_put(mctx, rdata, sizeof *rdata); + } + while (!ISC_LIST_EMPTY(sigrdatalist.rdata)) { + rdata = ISC_LIST_HEAD(sigrdatalist.rdata); + ISC_LIST_UNLINK(sigrdatalist.rdata, rdata, link); + isc_mem_put(mctx, rdata->data, BUFSIZE); + isc_mem_put(mctx, rdata, sizeof *rdata); + } + + while (!ISC_LIST_EMPTY(keylist)) { + keynode = ISC_LIST_HEAD(keylist); + ISC_LIST_UNLINK(keylist, keynode, link); + dst_key_free(&keynode->key); + isc_mem_put(mctx, keynode, sizeof(keynode_t)); + } + + if (savedname != NULL) { + dns_name_free(savedname, mctx); + isc_mem_put(mctx, savedname, sizeof(dns_name_t)); + } + + cleanup_logging(&log); + cleanup_entropy(&ectx); + + isc_mem_free(mctx, output); + dst_lib_destroy(); + if (verbose > 10) + isc_mem_stats(mctx, stdout); + isc_mem_destroy(&mctx); + return (0); +} diff --git a/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-makekeyset.html b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-makekeyset.html new file mode 100644 index 0000000..64c4c20 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-makekeyset.html @@ -0,0 +1,407 @@ + + + + +dnssec-makekeyset

dnssec-makekeyset

Name

dnssec-makekeyset -- DNSSEC zone signing tool

Synopsis

dnssec-makekeyset [-a] [-s start-time] [-e end-time] [-h] [-p] [-r randomdev] [-tttl] [-v level] {key...}

DESCRIPTION

dnssec-makekeyset generates a key set from one + or more keys created by dnssec-keygen. It creates + a file containing a KEY record for each key, and self-signs the key + set with each zone key. The output file is of the form + keyset-nnnn., where nnnn + is the zone name. +

OPTIONS

-a

Verify all generated signatures. +

-s start-time

Specify the date and time when the generated SIG 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 is used. +

-e end-time

Specify the date and time when the generated SIG 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. +

-h

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

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

Specify the TTL (time to live) of the KEY and SIG records. + The default is 3600 seconds. +

-v level

Sets the debugging level. +

key

The list of keys to be included in the keyset file. These keys + are expressed in the form Knnnn.+aaa+iiiii + as generated by dnssec-keygen. +

EXAMPLE

The following command generates a keyset containing the DSA key for + example.com generated in the + dnssec-keygen man page. +

dnssec-makekeyset -t 86400 -s 20000701120000 -e +2592000 Kexample.com.+003+26160 +

In this example, dnssec-makekeyset creates + the file keyset-example.com.. This file + contains the specified key and a self-generated signature. +

The DNS administrator for example.com could + send keyset-example.com. to the DNS + administrator for .com for signing, if the + .com zone is DNSSEC-aware and the administrators of the two zones + have some mechanism for authenticating each other and exchanging + the keys and signatures securely. +

SEE ALSO

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

AUTHOR

Internet Systems Consortium +

diff --git a/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signkey.8 b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signkey.8 new file mode 100644 index 0000000..34b7df0 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signkey.8 @@ -0,0 +1,108 @@ +.\" 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: dnssec-signkey.8,v 1.18.2.3 2004/06/03 05:21:11 marka Exp $ +.\" +.TH "DNSSEC-SIGNKEY" "8" "June 30, 2000" "BIND9" "" +.SH NAME +dnssec-signkey \- DNSSEC key set signing tool +.SH SYNOPSIS +.sp +\fBdnssec-signkey\fR [ \fB-a\fR ] [ \fB-c \fIclass\fB\fR ] [ \fB-s \fIstart-time\fB\fR ] [ \fB-e \fIend-time\fB\fR ] [ \fB-h\fR ] [ \fB-p\fR ] [ \fB-r \fIrandomdev\fB\fR ] [ \fB-v \fIlevel\fB\fR ] \fBkeyset\fR \fBkey\fR\fI...\fR +.SH "DESCRIPTION" +.PP +\fBdnssec-signkey\fR signs a keyset. Typically +the keyset will be for a child zone, and will have been generated +by \fBdnssec-makekeyset\fR. The child zone's keyset +is signed with the zone keys for its parent zone. The output file +is of the form \fIsignedkey-nnnn.\fR, where +\fInnnn\fR is the zone name. +.SH "OPTIONS" +.TP +\fB-a\fR +Verify all generated signatures. +.TP +\fB-c \fIclass\fB\fR +Specifies the DNS class of the key sets. +.TP +\fB-s \fIstart-time\fB\fR +Specify the date and time when the generated SIG 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 is used. +.TP +\fB-e \fIend-time\fB\fR +Specify the date and time when the generated SIG 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. +.TP +\fB-h\fR +Prints a short summary of the options and arguments to +\fBdnssec-signkey\fR. +.TP +\fB-p\fR +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. +.TP +\fB-r \fIrandomdev\fB\fR +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. +.TP +\fB-v \fIlevel\fB\fR +Sets the debugging level. +.TP +\fBkeyset\fR +The file containing the child's keyset. +.TP +\fBkey\fR +The keys used to sign the child's keyset. +.SH "EXAMPLE" +.PP +The DNS administrator for a DNSSEC-aware \fB.com\fR +zone would use the following command to sign the +\fIkeyset\fR file for \fBexample.com\fR +created by \fBdnssec-makekeyset\fR with a key generated +by \fBdnssec-keygen\fR: +.PP +\fBdnssec-signkey keyset-example.com. Kcom.+003+51944\fR +.PP +In this example, \fBdnssec-signkey\fR creates +the file \fIsignedkey-example.com.\fR, which +contains the \fBexample.com\fR keys and the +signatures by the \fB.com\fR keys. +.SH "SEE ALSO" +.PP +\fBdnssec-keygen\fR(8), +\fBdnssec-makekeyset\fR(8), +\fBdnssec-signzone\fR(8). +.SH "AUTHOR" +.PP +Internet Systems Consortium diff --git a/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signkey.c b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signkey.c new file mode 100644 index 0000000..e687e31 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signkey.c @@ -0,0 +1,471 @@ +/* + * Portions Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2000, 2001, 2003 Internet Software Consortium. + * Portions Copyright (C) 1995-2000 by Network Associates, 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 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-signkey.c,v 1.50.2.4 2004/03/09 06:09:15 marka Exp $ */ + +#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-signkey"; +int verbose; + +#define BUFSIZE 2048 + +typedef struct keynode keynode_t; +struct keynode { + dst_key_t *key; + isc_boolean_t verified; + ISC_LINK(keynode_t) link; +}; +typedef ISC_LIST(keynode_t) keylist_t; + +static isc_stdtime_t starttime = 0, endtime = 0, now; + +static isc_mem_t *mctx = NULL; +static isc_entropy_t *ectx = NULL; +static keylist_t keylist; + +static void +usage(void) { + fprintf(stderr, "Usage:\n"); + fprintf(stderr, "\t%s [options] keyset keys\n", program); + + fprintf(stderr, "\n"); + + fprintf(stderr, "Options: (default value in parenthesis) \n"); + fprintf(stderr, "\t-a\n"); + fprintf(stderr, "\t\tverify generated signatures\n"); + fprintf(stderr, "\t-c class (IN)\n"); + fprintf(stderr, "\t-s YYYYMMDDHHMMSS|+offset:\n"); + fprintf(stderr, "\t\tSIG start time - absolute|offset (from keyset)\n"); + fprintf(stderr, "\t-e YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n"); + fprintf(stderr, "\t\tSIG end time - absolute|from start|from now " + "(from keyset)\n"); + fprintf(stderr, "\t-v level:\n"); + fprintf(stderr, "\t\tverbose level (0)\n"); + fprintf(stderr, "\t-p\n"); + fprintf(stderr, "\t\tuse pseudorandom data (faster but less secure)\n"); + fprintf(stderr, "\t-r randomdev:\n"); + fprintf(stderr, "\t\ta file containing random data\n"); + + fprintf(stderr, "\n"); + + fprintf(stderr, "keyset:\n"); + fprintf(stderr, "\tfile with keyset to be signed (keyset-)\n"); + fprintf(stderr, "keys:\n"); + fprintf(stderr, "\tkeyfile (Kname+alg+tag)\n"); + + fprintf(stderr, "\n"); + fprintf(stderr, "Output:\n"); + fprintf(stderr, "\tsigned keyset (signedkey-)\n"); + exit(0); +} + +static void +loadkeys(dns_name_t *name, dns_rdataset_t *rdataset) { + dst_key_t *key; + dns_rdata_t rdata = DNS_RDATA_INIT; + keynode_t *keynode; + isc_result_t result; + + ISC_LIST_INIT(keylist); + result = dns_rdataset_first(rdataset); + check_result(result, "dns_rdataset_first"); + for (; result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { + dns_rdata_reset(&rdata); + dns_rdataset_current(rdataset, &rdata); + key = NULL; + result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &key); + if (result != ISC_R_SUCCESS) + continue; + if (!dst_key_iszonekey(key)) + continue; + keynode = isc_mem_get(mctx, sizeof (keynode_t)); + if (keynode == NULL) + fatal("out of memory"); + keynode->key = key; + keynode->verified = ISC_FALSE; + ISC_LIST_INITANDAPPEND(keylist, keynode, link); + } + if (result != ISC_R_NOMORE) + fatal("failure traversing key list"); +} + +static dst_key_t * +findkey(dns_rdata_sig_t *sig) { + keynode_t *keynode; + for (keynode = ISC_LIST_HEAD(keylist); + keynode != NULL; + keynode = ISC_LIST_NEXT(keynode, link)) + { + if (dst_key_id(keynode->key) == sig->keyid && + dst_key_alg(keynode->key) == sig->algorithm) { + keynode->verified = ISC_TRUE; + return (keynode->key); + } + } + fatal("signature generated by non-zone or missing key"); + return (NULL); +} + +int +main(int argc, char *argv[]) { + int i, ch; + char *startstr = NULL, *endstr = NULL, *classname = NULL; + char tdomain[1025]; + dns_fixedname_t fdomain; + dns_name_t *domain; + char *output = NULL; + char *endp; + unsigned char *data; + char *randomfile = NULL; + dns_db_t *db; + dns_dbnode_t *node; + dns_dbversion_t *version; + dns_dbiterator_t *dbiter; + dns_rdatasetiter_t *rdsiter; + dst_key_t *key = NULL; + dns_rdata_t *rdata; + dns_rdata_t sigrdata = DNS_RDATA_INIT; + dns_rdatalist_t sigrdatalist; + dns_rdataset_t rdataset, sigrdataset, newsigrdataset; + dns_rdata_sig_t sig; + isc_result_t result; + isc_buffer_t b; + isc_textregion_t tr; + isc_log_t *log = NULL; + keynode_t *keynode; + isc_boolean_t pseudorandom = ISC_FALSE; + unsigned int eflags; + dns_rdataclass_t rdclass; + static isc_boolean_t tryverify = ISC_FALSE; + + result = isc_mem_create(0, 0, &mctx); + check_result(result, "isc_mem_create()"); + + dns_result_register(); + + while ((ch = isc_commandline_parse(argc, argv, "ac:s:e:pr:v:h")) != -1) + { + switch (ch) { + case 'a': + tryverify = ISC_TRUE; + break; + case 'c': + classname = isc_commandline_argument; + break; + + case 's': + startstr = isc_commandline_argument; + break; + + case 'e': + endstr = isc_commandline_argument; + break; + + case 'p': + pseudorandom = ISC_TRUE; + break; + + case 'r': + randomfile = isc_commandline_argument; + break; + + case 'v': + endp = NULL; + verbose = strtol(isc_commandline_argument, &endp, 0); + if (*endp != '\0') + fatal("verbose level must be numeric"); + break; + + case 'h': + default: + usage(); + + } + } + + argc -= isc_commandline_index; + argv += isc_commandline_index; + + if (argc < 2) + usage(); + + if (classname != NULL) { + tr.base = classname; + tr.length = strlen(classname); + result = dns_rdataclass_fromtext(&rdclass, &tr); + if (result != ISC_R_SUCCESS) + fatal("unknown class %s",classname); + } else + rdclass = dns_rdataclass_in; + + setup_entropy(mctx, randomfile, &ectx); + eflags = ISC_ENTROPY_BLOCKING; + if (!pseudorandom) + eflags |= ISC_ENTROPY_GOODONLY; + result = dst_lib_init(mctx, ectx, eflags); + if (result != ISC_R_SUCCESS) + fatal("could not initialize dst: %s", + isc_result_totext(result)); + + isc_stdtime_get(&now); + + if ((startstr == NULL || endstr == NULL) && + !(startstr == NULL && endstr == NULL)) + fatal("if -s or -e is specified, both must be"); + + setup_logging(verbose, mctx, &log); + + if (strlen(argv[0]) < 8U || strncmp(argv[0], "keyset-", 7) != 0) + fatal("keyset file '%s' must start with keyset-", argv[0]); + + db = NULL; + result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, + rdclass, 0, NULL, &db); + check_result(result, "dns_db_create()"); + + result = dns_db_load(db, argv[0]); + if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) + fatal("failed to load database from '%s': %s", argv[0], + isc_result_totext(result)); + + dns_fixedname_init(&fdomain); + domain = dns_fixedname_name(&fdomain); + + dbiter = NULL; + result = dns_db_createiterator(db, ISC_FALSE, &dbiter); + check_result(result, "dns_db_createiterator()"); + + result = dns_dbiterator_first(dbiter); + check_result(result, "dns_dbiterator_first()"); + while (result == ISC_R_SUCCESS) { + node = NULL; + dns_dbiterator_current(dbiter, &node, domain); + rdsiter = NULL; + result = dns_db_allrdatasets(db, node, NULL, 0, &rdsiter); + check_result(result, "dns_db_allrdatasets()"); + result = dns_rdatasetiter_first(rdsiter); + dns_rdatasetiter_destroy(&rdsiter); + if (result == ISC_R_SUCCESS) + break; + dns_db_detachnode(db, &node); + result = dns_dbiterator_next(dbiter); + } + dns_dbiterator_destroy(&dbiter); + if (result != ISC_R_SUCCESS) + fatal("failed to find data in keyset file"); + + isc_buffer_init(&b, tdomain, sizeof(tdomain) - 1); + result = dns_name_tofilenametext(domain, ISC_FALSE, &b); + check_result(result, "dns_name_tofilenametext()"); + isc_buffer_putuint8(&b, 0); + + output = isc_mem_allocate(mctx, + strlen("signedkey-") + strlen(tdomain) + 1); + if (output == NULL) + fatal("out of memory"); + strcpy(output, "signedkey-"); + strcat(output, tdomain); + + version = NULL; + dns_db_newversion(db, &version); + + dns_rdataset_init(&rdataset); + dns_rdataset_init(&sigrdataset); + result = dns_db_findrdataset(db, node, version, dns_rdatatype_key, 0, + 0, &rdataset, &sigrdataset); + if (result != ISC_R_SUCCESS) { + char domainstr[DNS_NAME_FORMATSIZE]; + dns_name_format(domain, domainstr, sizeof domainstr); + fatal("failed to find rdataset '%s KEY': %s", + domainstr, isc_result_totext(result)); + } + + loadkeys(domain, &rdataset); + + if (!dns_rdataset_isassociated(&sigrdataset)) + fatal("no SIG KEY set present"); + + result = dns_rdataset_first(&sigrdataset); + check_result(result, "dns_rdataset_first()"); + do { + dns_rdataset_current(&sigrdataset, &sigrdata); + result = dns_rdata_tostruct(&sigrdata, &sig, mctx); + check_result(result, "dns_rdata_tostruct()"); + key = findkey(&sig); + result = dns_dnssec_verify(domain, &rdataset, key, + ISC_TRUE, mctx, &sigrdata); + if (result != ISC_R_SUCCESS) { + char keystr[KEY_FORMATSIZE]; + key_format(key, keystr, sizeof keystr); + fatal("signature by key '%s' did not verify: %s", + keystr, isc_result_totext(result)); + } + dns_rdata_reset(&sigrdata); + dns_rdata_freestruct(&sig); + result = dns_rdataset_next(&sigrdataset); + } while (result == ISC_R_SUCCESS); + + if (startstr != NULL) { + starttime = strtotime(startstr, now, now); + endtime = strtotime(endstr, now, starttime); + } else { + starttime = sig.timesigned; + endtime = sig.timeexpire; + } + + + for (keynode = ISC_LIST_HEAD(keylist); + keynode != NULL; + keynode = ISC_LIST_NEXT(keynode, link)) + if (!keynode->verified) + fatal("Not all zone keys self signed the key set"); + + result = dns_rdataset_first(&sigrdataset); + check_result(result, "dns_rdataset_first()"); + dns_rdataset_current(&sigrdataset, &sigrdata); + result = dns_rdata_tostruct(&sigrdata, &sig, mctx); + check_result(result, "dns_rdata_tostruct()"); + + dns_rdataset_disassociate(&sigrdataset); + + argc -= 1; + argv += 1; + + dns_rdatalist_init(&sigrdatalist); + sigrdatalist.rdclass = rdataset.rdclass; + sigrdatalist.type = dns_rdatatype_sig; + sigrdatalist.covers = dns_rdatatype_key; + sigrdatalist.ttl = rdataset.ttl; + + for (i = 0; i < argc; i++) { + key = NULL; + result = dst_key_fromnamedfile(argv[i], + DST_TYPE_PUBLIC | + DST_TYPE_PRIVATE, + mctx, &key); + if (result != ISC_R_SUCCESS) + fatal("failed to read key %s from disk: %s", + argv[i], isc_result_totext(result)); + + rdata = isc_mem_get(mctx, sizeof(dns_rdata_t)); + if (rdata == NULL) + fatal("out of memory"); + dns_rdata_init(rdata); + data = isc_mem_get(mctx, BUFSIZE); + if (data == NULL) + fatal("out of memory"); + isc_buffer_init(&b, data, BUFSIZE); + result = dns_dnssec_sign(domain, &rdataset, key, + &starttime, &endtime, + mctx, &b, rdata); + isc_entropy_stopcallbacksources(ectx); + if (result != ISC_R_SUCCESS) { + char keystr[KEY_FORMATSIZE]; + key_format(key, keystr, sizeof keystr); + fatal("key '%s' failed to sign data: %s", + keystr, isc_result_totext(result)); + } + if (tryverify) { + result = dns_dnssec_verify(domain, &rdataset, key, + ISC_TRUE, mctx, rdata); + if (result != ISC_R_SUCCESS) { + char keystr[KEY_FORMATSIZE]; + key_format(key, keystr, sizeof keystr); + fatal("signature from key '%s' failed to " + "verify: %s", + keystr, isc_result_totext(result)); + } + } + ISC_LIST_APPEND(sigrdatalist.rdata, rdata, link); + dst_key_free(&key); + } + + dns_rdataset_init(&newsigrdataset); + result = dns_rdatalist_tordataset(&sigrdatalist, &newsigrdataset); + check_result (result, "dns_rdatalist_tordataset()"); + + dns_db_addrdataset(db, node, version, 0, &newsigrdataset, 0, NULL); + check_result (result, "dns_db_addrdataset()"); + + dns_db_detachnode(db, &node); + dns_db_closeversion(db, &version, ISC_TRUE); + result = dns_db_dump(db, version, output); + if (result != ISC_R_SUCCESS) + fatal("failed to write database to '%s': %s", + output, isc_result_totext(result)); + + printf("%s\n", output); + + dns_rdataset_disassociate(&rdataset); + dns_rdataset_disassociate(&newsigrdataset); + + dns_rdata_freestruct(&sig); + + while (!ISC_LIST_EMPTY(sigrdatalist.rdata)) { + rdata = ISC_LIST_HEAD(sigrdatalist.rdata); + ISC_LIST_UNLINK(sigrdatalist.rdata, rdata, link); + isc_mem_put(mctx, rdata->data, BUFSIZE); + isc_mem_put(mctx, rdata, sizeof *rdata); + } + + dns_db_detach(&db); + + while (!ISC_LIST_EMPTY(keylist)) { + keynode = ISC_LIST_HEAD(keylist); + ISC_LIST_UNLINK(keylist, keynode, link); + dst_key_free(&keynode->key); + isc_mem_put(mctx, keynode, sizeof(keynode_t)); + } + + cleanup_logging(&log); + + isc_mem_free(mctx, output); + cleanup_entropy(&ectx); + dst_lib_destroy(); + if (verbose > 10) + isc_mem_stats(mctx, stdout); + isc_mem_destroy(&mctx); + return (0); +} diff --git a/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signkey.html b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signkey.html new file mode 100644 index 0000000..78d3a39 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signkey.html @@ -0,0 +1,407 @@ + + + + +dnssec-signkey

dnssec-signkey

Name

dnssec-signkey -- DNSSEC key set signing tool

Synopsis

dnssec-signkey [-a] [-c class] [-s start-time] [-e end-time] [-h] [-p] [-r randomdev] [-v level] {keyset} {key...}

DESCRIPTION

dnssec-signkey signs a keyset. Typically + the keyset will be for a child zone, and will have been generated + by dnssec-makekeyset. The child zone's keyset + is signed with the zone keys for its parent zone. The output file + is of the form signedkey-nnnn., where + nnnn is the zone name. +

OPTIONS

-a

Verify all generated signatures. +

-c class

Specifies the DNS class of the key sets. +

-s start-time

Specify the date and time when the generated SIG 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 is used. +

-e end-time

Specify the date and time when the generated SIG 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. +

-h

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

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

-v level

Sets the debugging level. +

keyset

The file containing the child's keyset. +

key

The keys used to sign the child's keyset. +

EXAMPLE

The DNS administrator for a DNSSEC-aware .com + zone would use the following command to sign the + keyset file for example.com + created by dnssec-makekeyset with a key generated + by dnssec-keygen: +

dnssec-signkey keyset-example.com. Kcom.+003+51944 +

In this example, dnssec-signkey creates + the file signedkey-example.com., which + contains the example.com keys and the + signatures by the .com keys. +

SEE ALSO

dnssec-keygen(8), + dnssec-makekeyset(8), + dnssec-signzone(8). +

AUTHOR

Internet Systems Consortium +

diff --git a/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signzone.8 b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signzone.8 new file mode 100644 index 0000000..72d766b --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signzone.8 @@ -0,0 +1,155 @@ +.\" 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: dnssec-signzone.8,v 1.23.2.4 2004/06/03 05:21:12 marka Exp $ +.\" +.TH "DNSSEC-SIGNZONE" "8" "June 30, 2000" "BIND9" "" +.SH NAME +dnssec-signzone \- DNSSEC zone signing tool +.SH SYNOPSIS +.sp +\fBdnssec-signzone\fR [ \fB-a\fR ] [ \fB-c \fIclass\fB\fR ] [ \fB-d \fIdirectory\fB\fR ] [ \fB-s \fIstart-time\fB\fR ] [ \fB-e \fIend-time\fB\fR ] [ \fB-f \fIoutput-file\fB\fR ] [ \fB-h\fR ] [ \fB-i \fIinterval\fB\fR ] [ \fB-n \fInthreads\fB\fR ] [ \fB-o \fIorigin\fB\fR ] [ \fB-p\fR ] [ \fB-r \fIrandomdev\fB\fR ] [ \fB-t\fR ] [ \fB-v \fIlevel\fB\fR ] \fBzonefile\fR [ \fBkey\fR\fI...\fR ] +.SH "DESCRIPTION" +.PP +\fBdnssec-signzone\fR signs a zone. It generates NXT +and SIG records and produces a signed version of the zone. If there +is a \fIsignedkey\fR file from the zone's parent, +the parent's signatures will be incorporated into the generated +signed zone file. 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 +\fIsignedkey\fR file for each child zone. +.SH "OPTIONS" +.TP +\fB-a\fR +Verify all generated signatures. +.TP +\fB-c \fIclass\fB\fR +Specifies the DNS class of the zone. +.TP +\fB-d \fIdirectory\fB\fR +Look for \fIsignedkey\fR files in +\fBdirectory\fR as the directory +.TP +\fB-s \fIstart-time\fB\fR +Specify the date and time when the generated SIG 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 is used. +.TP +\fB-e \fIend-time\fB\fR +Specify the date and time when the generated SIG 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. +.TP +\fB-f \fIoutput-file\fB\fR +The name of the output file containing the signed zone. The +default is to append \fI.signed\fR to the +input file. +.TP +\fB-h\fR +Prints a short summary of the options and arguments to +\fBdnssec-signzone\fR. +.TP +\fB-i \fIinterval\fB\fR +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 SIG 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 +\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 SIG records +are due to expire in less than 7.5 days, they would be +replaced. +.TP +\fB-n \fIncpus\fB\fR +Specifies the number of threads to use. By default, one +thread is started for each detected CPU. +.TP +\fB-o \fIorigin\fB\fR +The zone origin. If not specified, the name of the zone file +is assumed to be the origin. +.TP +\fB-p\fR +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. +.TP +\fB-r \fIrandomdev\fB\fR +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. +.TP +\fB-t\fR +Print statistics at completion. +.TP +\fB-v \fIlevel\fB\fR +Sets the debugging level. +.TP +\fBzonefile\fR +The file containing the zone to be signed. +Sets the debugging level. +.TP +\fBkey\fR +The keys used to sign the zone. If no keys are specified, the +default all zone keys that have private key files in the +current directory. +.SH "EXAMPLE" +.PP +The following command signs the \fBexample.com\fR +zone with the DSA key generated in the \fBdnssec-keygen\fR +man page. The zone's keys must be in the zone. If there are +\fIsignedkey\fR files associated with this zone +or any child zones, they must be in the current directory. +\fBexample.com\fR, the following command would be +issued: +.PP +\fBdnssec-signzone -o example.com db.example.com Kexample.com.+003+26160\fR +.PP +The command would print a string of the form: +.PP +In this 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. +.SH "SEE ALSO" +.PP +\fBdnssec-keygen\fR(8), +\fBdnssec-signkey\fR(8), +\fIBIND 9 Administrator Reference Manual\fR, +\fIRFC 2535\fR. +.SH "AUTHOR" +.PP +Internet Systems Consortium diff --git a/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signzone.c b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signzone.c new file mode 100644 index 0000000..ca7b981 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signzone.c @@ -0,0 +1,1880 @@ +/* + * Portions Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 1999-2001, 2003 Internet Software Consortium. + * Portions Copyright (C) 1995-2000 by Network Associates, 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 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.139.2.5 2004/04/15 02:16:24 marka 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 +#include +#include +#include +#include +#include + +#include +#include + +#include "dnssectool.h" + +const char *program = "dnssec-signzone"; +int verbose; + +#define BUFSIZE 2048 + +typedef struct signer_key_struct signer_key_t; + +struct signer_key_struct { + dst_key_t *key; + isc_boolean_t isdefault; + 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) + +typedef struct signer_event sevent_t; +struct signer_event { + ISC_EVENT_COMMON(sevent_t); + dns_fixedname_t *fname; + dns_fixedname_t *fnextname; + 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 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 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_name_t *gorigin; /* The database origin */ +static dns_dbnode_t *gnode = NULL; /* The "current" database node */ +static dns_name_t *lastzonecut; +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; + +#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 signer_key_t * +newkeystruct(dst_key_t *dstkey, isc_boolean_t isdefault) { + signer_key_t *key; + + key = isc_mem_get(mctx, sizeof(signer_key_t)); + if (key == NULL) + fatal("out of memory"); + key->key = dstkey; + key->isdefault = isdefault; + 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; + + result = dns_dnssec_sign(name, rdataset, key, &starttime, &endtime, + mctx, b, rdata); + isc_entropy_stopcallbacksources(ectx); + if (result != ISC_R_SUCCESS) { + char keystr[KEY_FORMATSIZE]; + key_format(key, keystr, sizeof keystr); + fatal("key '%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->isdefault); +} + +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 SIG, 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_sig_t *sig) { + isc_result_t result; + dst_key_t *pubkey = NULL, *privkey = NULL; + signer_key_t *key; + + key = ISC_LIST_HEAD(keylist); + while (key != NULL) { + if (sig->keyid == dst_key_id(key->key) && + sig->algorithm == dst_key_alg(key->key) && + dns_name_equal(&sig->signer, dst_key_name(key->key))) + return key; + key = ISC_LIST_NEXT(key, link); + } + + result = dst_key_fromfile(&sig->signer, sig->keyid, sig->algorithm, + DST_TYPE_PUBLIC, NULL, mctx, &pubkey); + if (result != ISC_R_SUCCESS) + return (NULL); + + result = dst_key_fromfile(&sig->signer, sig->keyid, sig->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 SIG + * and can't find the signing key that we expect to find, we drop the sig. + * 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_key, 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 KEY' 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 *sig) +{ + isc_result_t result; + result = dns_dnssec_verify(name, set, key->key, ISC_FALSE, mctx, sig); + 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 SIG should + * be dropped or retained, and then determines if any new SIGs need to + * be generated. + */ +static void +signset(dns_diff_t *diff, 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_sig_t sig; + 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_sig, + 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 SIG %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, &sig, NULL); + check_result(result, "dns_rdata_tostruct"); + + expired = ISC_TF(now + cycle > sig.timeexpire); + future = ISC_TF(now < sig.timesigned); + + key = keythatsigned(&sig); + sig_format(&sig, sigstr, sizeof sigstr); + + if (sig.timesigned > sig.timeexpire) { + /* sig is dropped and not replaced */ + vbprintf(2, "\tsig by %s dropped - " + "invalid validity period\n", + sigstr); + } else if (key == NULL && !future && + expecttofindkey(&sig.signer)) + { + /* sig is dropped and not replaced */ + vbprintf(2, "\tsig by %s dropped - " + "private key not found\n", + sigstr); + } else if (key == NULL || future) { + vbprintf(2, "\tsig by %s %s - key 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, "\tsig by %s retained\n", sigstr); + keep = ISC_TRUE; + wassignedby[key->position] = ISC_TRUE; + nowsignedby[key->position] = ISC_TRUE; + } else { + vbprintf(2, "\tsig 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, "\tsig by %s retained\n", sigstr); + keep = ISC_TRUE; + wassignedby[key->position] = ISC_TRUE; + nowsignedby[key->position] = ISC_TRUE; + } else { + vbprintf(2, "\tsig by %s dropped - %s\n", + sigstr, + expired ? "expired" : + "failed to verify"); + wassignedby[key->position] = ISC_TRUE; + } + } else if (!expired) { + vbprintf(2, "\tsig by %s retained\n", sigstr); + keep = ISC_TRUE; + } else { + vbprintf(2, "\tsig by %s expired\n", sigstr); + } + + if (keep) { + nowsignedby[key->position] = ISC_TRUE; + INCSTAT(nretained); + } 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(diff, &tuple); + INCSTAT(ndropped); + } + + if (resign) { + isc_buffer_t b; + dns_rdata_t trdata = DNS_RDATA_INIT; + unsigned char array[BUFSIZE]; + char keystr[KEY_FORMATSIZE]; + + key_format(key->key, keystr, sizeof keystr); + vbprintf(1, "\tresigning with key %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(diff, &tuple); + } + + dns_rdata_reset(&sigrdata); + dns_rdata_freestruct(&sig); + 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); + + key = ISC_LIST_HEAD(keylist); + while (key != NULL) { + if (key->isdefault && !nowsignedby[key->position]) { + isc_buffer_t b; + dns_rdata_t trdata = DNS_RDATA_INIT; + unsigned char array[BUFSIZE]; + char keystr[KEY_FORMATSIZE]; + + key_format(key->key, keystr, sizeof keystr); + vbprintf(1, "\tsigning with key %s\n", keystr); + 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(diff, &tuple); + } + key = ISC_LIST_NEXT(key, link); + } + + isc_mem_put(mctx, wassignedby, arraysize * sizeof(isc_boolean_t)); + isc_mem_put(mctx, nowsignedby, arraysize * sizeof(isc_boolean_t)); +} + +/* Determine if a KEY set contains a null key */ +static isc_boolean_t +hasnullkey(dns_rdataset_t *rdataset) { + isc_result_t result; + dns_rdata_t rdata = DNS_RDATA_INIT; + isc_boolean_t found = ISC_FALSE; + + result = dns_rdataset_first(rdataset); + while (result == ISC_R_SUCCESS) { + dst_key_t *key = NULL; + + dns_rdata_reset(&rdata); + dns_rdataset_current(rdataset, &rdata); + result = dns_dnssec_keyfromrdata(dns_rootname, + &rdata, mctx, &key); + if (result != ISC_R_SUCCESS) + fatal("could not convert KEY into internal format: %s", + isc_result_totext(result)); + if (dst_key_isnullkey(key)) + found = ISC_TRUE; + dst_key_free(&key); + if (found == ISC_TRUE) + return (ISC_TRUE); + result = dns_rdataset_next(rdataset); + } + if (result != ISC_R_NOMORE) + fatal("failure looking for null keys"); + return (ISC_FALSE); +} + +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); +} + +/* + * Looks for signatures of the zone keys by the parent, and imports them + * if found. + */ +static void +importparentsig(dns_diff_t *diff, dns_name_t *name, dns_rdataset_t *set) { + dns_db_t *newdb = NULL; + dns_dbnode_t *newnode = NULL; + dns_rdataset_t newset, sigset; + dns_rdata_t rdata = DNS_RDATA_INIT, newrdata = DNS_RDATA_INIT; + isc_result_t result; + + dns_rdataset_init(&newset); + dns_rdataset_init(&sigset); + + opendb("signedkey-", name, dns_db_class(gdb), &newdb); + if (newdb == NULL) + return; + + result = dns_db_findnode(newdb, name, ISC_FALSE, &newnode); + if (result != ISC_R_SUCCESS) + goto failure; + result = dns_db_findrdataset(newdb, newnode, NULL, dns_rdatatype_key, + 0, 0, &newset, &sigset); + if (result != ISC_R_SUCCESS) + goto failure; + + if (!dns_rdataset_isassociated(&newset) || + !dns_rdataset_isassociated(&sigset)) + goto failure; + + if (dns_rdataset_count(set) != dns_rdataset_count(&newset)) { + result = DNS_R_BADDB; + goto failure; + } + + result = dns_rdataset_first(set); + check_result(result, "dns_rdataset_first()"); + for (; result == ISC_R_SUCCESS; result = dns_rdataset_next(set)) { + dns_rdataset_current(set, &rdata); + result = dns_rdataset_first(&newset); + check_result(result, "dns_rdataset_first()"); + for (; + result == ISC_R_SUCCESS; + result = dns_rdataset_next(&newset)) + { + dns_rdataset_current(&newset, &newrdata); + if (dns_rdata_compare(&rdata, &newrdata) == 0) + break; + dns_rdata_reset(&newrdata); + } + dns_rdata_reset(&newrdata); + dns_rdata_reset(&rdata); + if (result != ISC_R_SUCCESS) + break; + } + if (result != ISC_R_NOMORE) + goto failure; + + vbprintf(2, "found the parent's signature of our zone key\n"); + + result = dns_rdataset_first(&sigset); + while (result == ISC_R_SUCCESS) { + dns_difftuple_t *tuple = NULL; + + dns_rdataset_current(&sigset, &rdata); + result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, + sigset.ttl, &rdata, &tuple); + check_result(result, "dns_difftuple_create"); + dns_diff_append(diff, &tuple); + result = dns_rdataset_next(&sigset); + dns_rdata_reset(&rdata); + } + if (result == ISC_R_NOMORE) + result = ISC_R_SUCCESS; + + failure: + if (dns_rdataset_isassociated(&newset)) + dns_rdataset_disassociate(&newset); + if (dns_rdataset_isassociated(&sigset)) + dns_rdataset_disassociate(&sigset); + if (newnode != NULL) + dns_db_detachnode(newdb, &newnode); + if (newdb != NULL) + dns_db_detach(&newdb); + if (result != ISC_R_SUCCESS) + fatal("zone signedkey file is invalid or does not match zone"); +} + +/* + * Looks for our signatures of child keys. If present, inform the caller. + */ +static isc_boolean_t +haschildkey(dns_name_t *name) { + dns_db_t *newdb = NULL; + dns_dbnode_t *newnode = NULL; + dns_rdataset_t set, sigset; + dns_rdata_t sigrdata = DNS_RDATA_INIT; + isc_result_t result; + isc_boolean_t found = ISC_FALSE; + dns_rdata_sig_t sig; + signer_key_t *key; + + dns_rdataset_init(&set); + dns_rdataset_init(&sigset); + + opendb("signedkey-", name, dns_db_class(gdb), &newdb); + if (newdb == NULL) + return (ISC_FALSE); + + result = dns_db_findnode(newdb, name, ISC_FALSE, &newnode); + if (result != ISC_R_SUCCESS) + goto failure; + result = dns_db_findrdataset(newdb, newnode, NULL, dns_rdatatype_key, + 0, 0, &set, &sigset); + if (result != ISC_R_SUCCESS) + goto failure; + + if (!dns_rdataset_isassociated(&set) || + !dns_rdataset_isassociated(&sigset)) + goto failure; + + result = dns_rdataset_first(&sigset); + check_result(result, "dns_rdataset_first()"); + dns_rdata_init(&sigrdata); + for (; result == ISC_R_SUCCESS; result = dns_rdataset_next(&sigset)) { + dns_rdataset_current(&sigset, &sigrdata); + result = dns_rdata_tostruct(&sigrdata, &sig, NULL); + if (result != ISC_R_SUCCESS) + goto failure; + key = keythatsigned(&sig); + dns_rdata_freestruct(&sig); + if (key == NULL) { + char namestr[DNS_NAME_FORMATSIZE]; + dns_name_format(name, namestr, sizeof namestr); + fprintf(stderr, + "creating KEY from signedkey file for %s: " + "%s\n", + namestr, isc_result_totext(result)); + goto failure; + } + result = dns_dnssec_verify(name, &set, key->key, + ISC_FALSE, mctx, &sigrdata); + if (result == ISC_R_SUCCESS) { + found = ISC_TRUE; + break; + } else { + char namestr[DNS_NAME_FORMATSIZE]; + dns_name_format(name, namestr, sizeof namestr); + fprintf(stderr, + "verifying SIG in signedkey file for %s: %s\n", + namestr, isc_result_totext(result)); + } + dns_rdata_reset(&sigrdata); + } + + failure: + if (dns_rdataset_isassociated(&set)) + dns_rdataset_disassociate(&set); + if (dns_rdataset_isassociated(&sigset)) + dns_rdataset_disassociate(&sigset); + if (newnode != NULL) + dns_db_detachnode(newdb, &newnode); + if (newdb != NULL) + dns_db_detach(&newdb); + + return (found); +} + +/* + * There probably should be a dns_nxt_setbit, but it can get complicated if + * the length of the bit set needs to be increased. In this case, since the + * NXT bit is set and both SIG and KEY are less than NXT, the easy way works. + */ +static void +nxt_setbit(dns_rdataset_t *rdataset, dns_rdatatype_t type) { + isc_result_t result; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdata_nxt_t nxt; + + result = dns_rdataset_first(rdataset); + check_result(result, "dns_rdataset_first()"); + dns_rdataset_current(rdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &nxt, NULL); + check_result(result, "dns_rdata_tostruct"); + set_bit(nxt.typebits, type, 1); + dns_rdata_freestruct(&nxt); +} + +static void +createnullkey(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, + dns_ttl_t ttl) +{ + unsigned char keydata[4]; + dns_rdata_t keyrdata = DNS_RDATA_INIT; + dns_rdata_key_t key; + dns_diff_t diff; + dns_difftuple_t *tuple = NULL; + isc_buffer_t b; + isc_result_t result; + char namestr[DNS_NAME_FORMATSIZE]; + + dns_name_format(name, namestr, sizeof namestr); + vbprintf(2, "adding null key at %s\n", namestr); + + key.common.rdclass = dns_db_class(db); + key.common.rdtype = dns_rdatatype_key; + ISC_LINK_INIT(&key.common, link); + key.mctx = NULL; + key.flags = DNS_KEYTYPE_NOKEY | DNS_KEYOWNER_ZONE; + key.protocol = DNS_KEYPROTO_DNSSEC; + key.algorithm = DNS_KEYALG_DSA; + key.datalen = 0; + key.data = NULL; + isc_buffer_init(&b, keydata, sizeof keydata); + result = dns_rdata_fromstruct(&keyrdata, dns_db_class(db), + dns_rdatatype_key, &key, &b); + if (result != ISC_R_SUCCESS) + fatal("failed to build null key"); + + dns_diff_init(mctx, &diff); + + result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, ttl, + &keyrdata, &tuple); + check_result(result, "dns_difftuple_create"); + + dns_diff_append(&diff, &tuple); + + result = dns_diff_apply(&diff, db, version); + check_result(result, "dns_diff_apply"); + + dns_diff_clear(&diff); +} + +/* + * Signs all records at a name. This mostly just signs each set individually, + * but also adds the SIG bit to any NXTs 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 childkey = ISC_FALSE; + static int warnwild = 0; + isc_boolean_t atorigin; + isc_boolean_t neednullkey = ISC_FALSE; + dns_diff_t diff; + + if (dns_name_iswildcard(name)) { + char namestr[DNS_NAME_FORMATSIZE]; + dns_name_format(name, namestr, sizeof namestr); + if (warnwild++ == 0) { + fprintf(stderr, "%s: warning: BIND 9 doesn't properly " + "handle wildcards in secure zones:\n", + program); + fprintf(stderr, "\t- wildcard nonexistence proof is " + "not generated by the server\n"); + fprintf(stderr, "\t- wildcard nonexistence proof is " + "not required by the resolver\n"); + } + fprintf(stderr, "%s: warning: wildcard name seen: %s\n", + program, namestr); + } + + atorigin = dns_name_equal(name, gorigin); + + /* + * If this is not the origin, determine if it's a delegation point. + */ + if (!atorigin) { + dns_rdataset_t nsset; + + dns_rdataset_init(&nsset); + result = dns_db_findrdataset(gdb, node, gversion, + dns_rdatatype_ns, 0, 0, &nsset, + NULL); + /* Is this a delegation point? */ + if (result == ISC_R_SUCCESS) { + isdelegation = ISC_TRUE; + dns_rdataset_disassociate(&nsset); + } + } + + /* + * If this is a delegation point, determine if we need to generate + * a null key. + */ + if (isdelegation) { + dns_rdataset_t keyset; + dns_ttl_t nullkeyttl; + + childkey = haschildkey(name); + neednullkey = ISC_TRUE; + nullkeyttl = zonettl; + + dns_rdataset_init(&keyset); + result = dns_db_findrdataset(gdb, node, gversion, + dns_rdatatype_key, 0, 0, &keyset, + NULL); + if (result == ISC_R_SUCCESS && childkey) { + char namestr[DNS_NAME_FORMATSIZE]; + dns_name_format(name, namestr, sizeof namestr); + if (hasnullkey(&keyset)) { + fatal("%s has both a signedkey file and " + "null keys in the zone. Aborting.", + namestr); + } + vbprintf(2, "child key for %s found\n", namestr); + neednullkey = ISC_FALSE; + dns_rdataset_disassociate(&keyset); + } + else if (result == ISC_R_SUCCESS) { + if (hasnullkey(&keyset)) + neednullkey = ISC_FALSE; + nullkeyttl = keyset.ttl; + dns_rdataset_disassociate(&keyset); + } else if (childkey) { + char namestr[DNS_NAME_FORMATSIZE]; + dns_name_format(name, namestr, sizeof namestr); + vbprintf(2, "child key for %s found\n", namestr); + neednullkey = ISC_FALSE; + } + + if (neednullkey) + createnullkey(gdb, gversion, name, nullkeyttl); + } + + /* + * Now iterate through the rdatasets. + */ + dns_diff_init(mctx, &diff); + dns_rdataset_init(&rdataset); + 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 SIG set, skip it. */ + if (rdataset.type == dns_rdatatype_sig) + goto skip; + + /* + * If this is a KEY set at the apex, look for a signedkey file. + */ + if (atorigin && rdataset.type == dns_rdatatype_key) { + importparentsig(&diff, name, &rdataset); + goto skip; + } + + /* + * If this name is a delegation point, skip all records + * except an NXT set a KEY set containing a null key. + */ + if (isdelegation) { + if (!(rdataset.type == dns_rdatatype_nxt || + (rdataset.type == dns_rdatatype_key && + hasnullkey(&rdataset)))) + goto skip; + } + + if (rdataset.type == dns_rdatatype_nxt) { + if (!nokeys) + nxt_setbit(&rdataset, dns_rdatatype_sig); + if (neednullkey) + nxt_setbit(&rdataset, dns_rdatatype_key); + } + + signset(&diff, node, name, &rdataset); + + skip: + dns_rdataset_disassociate(&rdataset); + result = dns_rdatasetiter_next(rdsiter); + } + if (result != ISC_R_NOMORE) { + char namestr[DNS_NAME_FORMATSIZE]; + dns_name_format(name, namestr, sizeof namestr); + fatal("rdataset iteration for name '%s' failed: %s", + namestr, isc_result_totext(result)); + } + dns_rdatasetiter_destroy(&rdsiter); + + result = dns_diff_apply(&diff, gdb, gversion); + if (result != ISC_R_SUCCESS) { + char namestr[DNS_NAME_FORMATSIZE]; + dns_name_format(name, namestr, sizeof namestr); + fatal("failed to add SIGs at node '%s': %s", + namestr, isc_result_totext(result)); + } + dns_diff_clear(&diff); +} + +static inline isc_boolean_t +active_node(dns_dbnode_t *node) { + dns_rdatasetiter_t *rdsiter; + isc_boolean_t active = ISC_FALSE; + isc_result_t result; + dns_rdataset_t rdataset; + + dns_rdataset_init(&rdataset); + 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 (rdataset.type != dns_rdatatype_nxt) + 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)); + dns_rdatasetiter_destroy(&rdsiter); + + if (!active) { + /* + * Make sure there is no NXT record for this node. + */ + result = dns_db_deleterdataset(gdb, node, gversion, + dns_rdatatype_nxt, 0); + if (result == DNS_R_UNCHANGED) + result = ISC_R_SUCCESS; + check_result(result, "dns_db_deleterdataset"); + } + + return (active); +} + +static inline isc_result_t +next_active(dns_name_t *name, dns_dbnode_t **nodep) { + isc_result_t result; + isc_boolean_t active; + + do { + active = ISC_FALSE; + result = dns_dbiterator_current(gdbiter, nodep, name); + if (result == ISC_R_SUCCESS) { + active = active_node(*nodep); + if (!active) { + dns_db_detachnode(gdb, nodep); + result = dns_dbiterator_next(gdbiter); + } + } + } while (result == ISC_R_SUCCESS && !active); + + return (result); +} + +static inline isc_result_t +next_nonglue(dns_name_t *name, dns_dbnode_t **nodep, dns_name_t *origin, + dns_name_t *lastcut) +{ + isc_result_t result; + + do { + result = next_active(name, nodep); + if (result == ISC_R_SUCCESS) { + if (dns_name_issubdomain(name, origin) && + (lastcut == NULL || + !dns_name_issubdomain(name, lastcut))) + return (ISC_R_SUCCESS); + result = dns_master_dumpnodetostream(mctx, gdb, + gversion, + *nodep, name, + masterstyle, fp); + check_result(result, "dns_master_dumpnodetostream"); + dns_db_detachnode(gdb, nodep); + result = dns_dbiterator_next(gdbiter); + } + } while (result == ISC_R_SUCCESS); + return (result); +} + +/* + * 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_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) { + char namestr[DNS_NAME_FORMATSIZE]; + dns_name_format(name, namestr, sizeof namestr); + fatal("failed to find '%s SOA' in the zone: %s", + namestr, isc_result_totext(result)); + } + ttl = soaset.ttl; + dns_rdataset_disassociate(&soaset); + return (ttl); +} + +/* + * Delete any SIG 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; + + 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_sig) { + 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_sig, + 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()"); + + lastzonecut = NULL; + + zonettl = soattl(); + +} + +/* + * Clean up the iterator and global state after the tasks complete. + */ +static void +postsign(void) { + if (lastzonecut != NULL) { + dns_name_free(lastzonecut, mctx); + isc_mem_put(mctx, lastzonecut, sizeof(dns_name_t)); + } + dns_dbiterator_destroy(&gdbiter); +} + +/* + * Find the next name to nxtify & sign + */ +static isc_result_t +getnextname(dns_name_t *name, dns_name_t *nextname, dns_dbnode_t **nodep) { + isc_result_t result; + dns_dbnode_t *nextnode, *curnode; + + LOCK(&namelock); + + if (shuttingdown || finished) { + result = ISC_R_NOMORE; + if (gnode != NULL) + dns_db_detachnode(gdb, &gnode); + goto out; + } + + if (gnode == NULL) { + dns_fixedname_t ftname; + dns_name_t *tname; + + dns_fixedname_init(&ftname); + tname = dns_fixedname_name(&ftname); + + result = next_nonglue(tname, &gnode, gorigin, lastzonecut); + if (result != ISC_R_SUCCESS) + fatal("failed to iterate through the zone"); + } + + nextnode = NULL; + curnode = NULL; + dns_dbiterator_current(gdbiter, &curnode, name); + if (!dns_name_equal(name, gorigin)) { + dns_rdatasetiter_t *rdsiter = NULL; + dns_rdataset_t set; + + dns_rdataset_init(&set); + result = dns_db_allrdatasets(gdb, curnode, gversion, 0, + &rdsiter); + check_result(result, "dns_db_allrdatasets"); + result = dns_rdatasetiter_first(rdsiter); + while (result == ISC_R_SUCCESS) { + dns_rdatasetiter_current(rdsiter, &set); + if (set.type == dns_rdatatype_ns) { + dns_rdataset_disassociate(&set); + break; + } + dns_rdataset_disassociate(&set); + result = dns_rdatasetiter_next(rdsiter); + } + if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) + fatal("rdataset iteration failed: %s", + isc_result_totext(result)); + if (result == ISC_R_SUCCESS) { + if (lastzonecut != NULL) + dns_name_free(lastzonecut, mctx); + else { + lastzonecut = isc_mem_get(mctx, + sizeof(dns_name_t)); + if (lastzonecut == NULL) + fatal("out of memory"); + } + dns_name_init(lastzonecut, NULL); + result = dns_name_dup(name, mctx, lastzonecut); + check_result(result, "dns_name_dup()"); + } + dns_rdatasetiter_destroy(&rdsiter); + } + result = dns_dbiterator_next(gdbiter); + if (result == ISC_R_SUCCESS) + result = next_nonglue(nextname, &nextnode, gorigin, + lastzonecut); + if (result == ISC_R_NOMORE) { + dns_name_clone(gorigin, nextname); + finished = ISC_TRUE; + result = ISC_R_SUCCESS; + } else if (result != ISC_R_SUCCESS) + fatal("iterating through the database failed: %s", + isc_result_totext(result)); + dns_db_detachnode(gdb, &curnode); + + *nodep = gnode; + gnode = nextnode; + + out: + UNLOCK(&namelock); + return (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, *fnextname; + dns_dbnode_t *node; + sevent_t *sevent; + isc_result_t result; + + fname = isc_mem_get(mctx, sizeof(dns_fixedname_t)); + fnextname = isc_mem_get(mctx, sizeof(dns_fixedname_t)); + if (fname == NULL || fnextname == NULL) + fatal("out of memory"); + dns_fixedname_init(fname); + dns_fixedname_init(fnextname); + node = NULL; + result = getnextname(dns_fixedname_name(fname), + dns_fixedname_name(fnextname), &node); + if (result == ISC_R_NOMORE) { + isc_mem_put(mctx, fname, sizeof(dns_fixedname_t)); + isc_mem_put(mctx, fnextname, sizeof(dns_fixedname_t)); + if (assigned == completed) { + isc_task_detach(&task); + isc_app_shutdown(); + } + 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; + sevent->fnextname = fnextname; + 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_result_t result; + isc_task_t *worker; + sevent_t *sevent = (sevent_t *)event; + + completed++; + worker = (isc_task_t *)event->ev_sender; + result = dns_master_dumpnodetostream(mctx, gdb, gversion, + sevent->node, + dns_fixedname_name(sevent->fname), + masterstyle, fp); + check_result(result, "dns_master_dumpnodetostream"); + 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 and nxtify a database node. + */ +static void +sign(isc_task_t *task, isc_event_t *event) { + dns_fixedname_t *fname, *fnextname; + dns_dbnode_t *node; + sevent_t *sevent, *wevent; + isc_result_t result; + + sevent = (sevent_t *)event; + node = sevent->node; + fname = sevent->fname; + fnextname = sevent->fnextname; + isc_event_free(&event); + + result = dns_nxt_build(gdb, gversion, node, + dns_fixedname_name(fnextname), zonettl); + check_result(result, "dns_nxt_build()"); + isc_mem_put(mctx, fnextname, sizeof(dns_fixedname_t)); + 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)); +} + +/* + * 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_load(*db, file); + 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], ISC_FALSE); + 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_key, 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 +print_time(FILE *fp) { + time_t currenttime; + + currenttime = time(NULL); + fprintf(fp, "; File written on %s", ctime(¤ttime)); +} + +static void +print_version(FILE *fp) { + 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, "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 signedkey files (.)\n"); + fprintf(stderr, "\t-s YYYYMMDDHHMMSS|+offset:\n"); + fprintf(stderr, "\t\tSIG start time - absolute|offset (now)\n"); + fprintf(stderr, "\t-e YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n"); + fprintf(stderr, "\t\tSIG 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-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-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, "\n"); + + fprintf(stderr, "Signing Keys: "); + fprintf(stderr, "(default: all zone keys that have private keys)\n"); + fprintf(stderr, "\tkeyfile (Kname+alg+tag)\n"); +#ifndef ISC_RFC2535 + fprintf(stderr, +"WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\n" +"WARNING WARNING\n" +"WARNING This version of dnssec-signzone produces zones that are WARNING\n" +"WARNING incompatible with the forthcoming DS based DNSSEC WARNING\n" +"WARNING standard. WARNING\n" +"WARNING WARNING\n" +"WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\n"); +#endif + exit(0); +} + +static void +removetempfile(void) { + if (removefile) + isc_file_remove(tempfile); +} + +int +main(int argc, char *argv[]) { + int i, ch; + char *startstr = NULL, *endstr = NULL, *classname = NULL; + char *origin = NULL, *file = NULL, *output = NULL; + char *randomfile = NULL; + 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_textregion_t r; + isc_task_t **tasks = NULL; + 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, + "c:s:e:i:v:o:f:ahpr:td:n:")) + != -1) { + switch (ch) { + case 'c': + classname = isc_commandline_argument; + break; + + case 's': + startstr = isc_commandline_argument; + break; + + case 'e': + endstr = isc_commandline_argument; + 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 'p': + pseudorandom = ISC_TRUE; + break; + + case 'r': + randomfile = isc_commandline_argument; + break; + + case 'v': + endp = NULL; + verbose = strtol(isc_commandline_argument, &endp, 0); + if (*endp != '\0') + fatal("verbose level must be numeric"); + break; + + case 'o': + origin = isc_commandline_argument; + break; + + case 'f': + output = isc_commandline_argument; + break; + + case 'a': + tryverify = ISC_TRUE; + break; + + case 't': + printstats = ISC_TRUE; + break; + + case 'd': + directory = 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 'h': + default: + usage(); + + } + } + +#ifndef ISC_RFC2535 + fprintf(stderr, +"WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\n" +"WARNING WARNING\n" +"WARNING This version of dnssec-signzone produces zones that are WARNING\n" +"WARNING incompatible with the forth coming DS based DNSSEC WARNING\n" +"WARNING standard. WARNING\n" +"WARNING WARNING\n" +"WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\n"); +#endif + + setup_entropy(mctx, randomfile, &ectx); + eflags = ISC_ENTROPY_BLOCKING; + if (!pseudorandom) + eflags |= ISC_ENTROPY_GOODONLY; + 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; + + 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); + + + if (classname != NULL) { + r.base = classname; + r.length = strlen(classname); + result = dns_rdataclass_fromtext(&rdclass, &r); + if (result != ISC_R_SUCCESS) + fatal("unknown class %s",classname); + } else + rdclass = dns_rdataclass_in; + + 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 (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 (origin == NULL) + origin = file; + + gdb = NULL; + isc_time_now(&timer_start); + loadzone(file, origin, rdclass, &gdb); + gorigin = dns_db_origin(gdb); + + ISC_LIST_INIT(keylist); + + if (argc == 0) { + signer_key_t *key; + + loadzonekeys(gdb); + + key = ISC_LIST_HEAD(keylist); + while (key != NULL) { + key->isdefault = ISC_TRUE; + key = ISC_LIST_NEXT(key, link); + } + } 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 key %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))) + { + key->isdefault = ISC_TRUE; + if (!dst_key_isprivate(dkey)) + fatal("cannot sign zone with " + "non-private key %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); + } + + if (ISC_LIST_EMPTY(keylist)) { + fprintf(stderr, "%s: warning: No keys specified or found\n", + program); + nokeys = ISC_TRUE; + } + + gversion = NULL; + result = dns_db_newversion(gdb, &gversion); + check_result(result, "dns_db_newversion()"); + + 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)); + result = isc_app_onrun(mctx, master, startworker, tasks[i]); + if (result != ISC_R_SUCCESS) + fatal("failed to start 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(); + (void)isc_app_run(); + if (!finished) + fatal("process aborted by user"); + 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(); + + 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); + + cleanup_logging(&log); + dst_lib_destroy(); + cleanup_entropy(&ectx); + if (verbose > 10) + isc_mem_stats(mctx, stdout); + isc_mem_destroy(&mctx); + + (void) isc_app_finish(); + + if (printstats) { + isc_uint64_t runtime_us; /* Runtime in microseconds */ + isc_uint64_t runtime_ms; /* Runtime in milliseconds */ + isc_uint64_t sig_ms; /* Signatures per millisecond */ + + isc_time_now(&timer_finish); + + 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); + } + } + + return (0); +} diff --git a/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signzone.html b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signzone.html new file mode 100644 index 0000000..a4f5024 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dnssec/dnssec-signzone.html @@ -0,0 +1,556 @@ + + + + +dnssec-signzone

dnssec-signzone

Name

dnssec-signzone -- DNSSEC zone signing tool

Synopsis

dnssec-signzone [-a] [-c class] [-d directory] [-s start-time] [-e end-time] [-f output-file] [-h] [-i interval] [-n nthreads] [-o origin] [-p] [-r randomdev] [-t] [-v level] {zonefile} [key...]

DESCRIPTION

dnssec-signzone signs a zone. It generates NXT + and SIG records and produces a signed version of the zone. If there + is a signedkey file from the zone's parent, + the parent's signatures will be incorporated into the generated + signed zone file. 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 + signedkey file for each child zone. +

OPTIONS

-a

Verify all generated signatures. +

-c class

Specifies the DNS class of the zone. +

-d directory

Look for signedkey files in + directory as the directory +

-s start-time

Specify the date and time when the generated SIG 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 is used. +

-e end-time

Specify the date and time when the generated SIG 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 file. +

-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 SIG 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 SIG records + are due to expire in less than 7.5 days, they would be + replaced. +

-n ncpus

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

-o origin

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

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

zonefile

The file containing the zone to be signed. + Sets the debugging level. +

key

The keys used to sign the zone. If no keys are specified, the + default all zone keys that have private key files in the + current directory. +

EXAMPLE

The following command signs the example.com + zone with the DSA key generated in the dnssec-keygen + man page. The zone's keys must be in the zone. If there are + signedkey files associated with this zone + or any child zones, they must be in the current directory. + example.com, the following command would be + issued: +

dnssec-signzone -o example.com db.example.com Kexample.com.+003+26160 +

The command would print a string of the form: +

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

SEE ALSO

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

AUTHOR

Internet Systems Consortium +

diff --git a/contrib/bind-9.2.4rc7/bin/dnssec/dnssectool.c b/contrib/bind-9.2.4rc7/bin/dnssec/dnssectool.c new file mode 100644 index 0000000..4142bd7 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dnssec/dnssectool.c @@ -0,0 +1,260 @@ +/* + * 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.c,v 1.31.2.5 2004/03/09 06:09:16 marka Exp $ */ + +#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; + +static isc_entropysource_t *source = NULL; +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_sig_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; + + 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; + 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"); + } + + 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)); +} + +void +cleanup_entropy(isc_entropy_t **ectx) { + if (source != NULL) + isc_entropy_destroysource(&source); + isc_entropy_detach(ectx); +} + +isc_stdtime_t +strtotime(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); +} diff --git a/contrib/bind-9.2.4rc7/bin/dnssec/dnssectool.h b/contrib/bind-9.2.4rc7/bin/dnssec/dnssectool.h new file mode 100644 index 0000000..1d760d4 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/dnssec/dnssectool.h @@ -0,0 +1,73 @@ +/* + * 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: dnssectool.h,v 1.15.2.1 2004/03/09 06:09:16 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_sig_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(char *str, isc_int64_t now, isc_int64_t base); + +#endif /* DNSSEC_DNSSECTOOL_H */ diff --git a/contrib/bind-9.2.4rc7/bin/named/aclconf.c b/contrib/bind-9.2.4rc7/bin/named/aclconf.c new file mode 100644 index 0000000..d9f17f1 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/aclconf.c @@ -0,0 +1,231 @@ +/* + * 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: aclconf.c,v 1.27.2.1 2004/03/09 06:09:17 marka Exp $ */ + +#include + +#include +#include /* Required for HP/UX (and others?) */ +#include + +#include +#include +#include + +#include + +void +ns_aclconfctx_init(ns_aclconfctx_t *ctx) { + ISC_LIST_INIT(ctx->named_acl_cache); +} + +void +ns_aclconfctx_destroy(ns_aclconfctx_t *ctx) { + dns_acl_t *dacl, *next; + for (dacl = ISC_LIST_HEAD(ctx->named_acl_cache); + dacl != NULL; + dacl = next) + { + next = ISC_LIST_NEXT(dacl, nextincache); + dns_acl_detach(&dacl); + } +} + +/* + * Find the definition of the named acl whose name is "name". + */ +static isc_result_t +get_acl_def(cfg_obj_t *cctx, char *name, cfg_obj_t **ret) { + isc_result_t result; + cfg_obj_t *acls = NULL; + cfg_listelt_t *elt; + + result = cfg_map_get(cctx, "acl", &acls); + if (result != ISC_R_SUCCESS) + return (result); + for (elt = cfg_list_first(acls); + elt != NULL; + elt = cfg_list_next(elt)) { + cfg_obj_t *acl = cfg_listelt_value(elt); + const char *aclname = cfg_obj_asstring(cfg_tuple_get(acl, "name")); + if (strcasecmp(aclname, name) == 0) { + *ret = cfg_tuple_get(acl, "value"); + return (ISC_R_SUCCESS); + } + } + return (ISC_R_NOTFOUND); +} + +static isc_result_t +convert_named_acl(cfg_obj_t *nameobj, cfg_obj_t *cctx, + ns_aclconfctx_t *ctx, isc_mem_t *mctx, + dns_acl_t **target) +{ + isc_result_t result; + cfg_obj_t *cacl = NULL; + dns_acl_t *dacl; + char *aclname = cfg_obj_asstring(nameobj); + + /* Look for an already-converted version. */ + for (dacl = ISC_LIST_HEAD(ctx->named_acl_cache); + dacl != NULL; + dacl = ISC_LIST_NEXT(dacl, nextincache)) + { + if (strcasecmp(aclname, dacl->name) == 0) { + dns_acl_attach(dacl, target); + return (ISC_R_SUCCESS); + } + } + /* Not yet converted. Convert now. */ + result = get_acl_def(cctx, aclname, &cacl); + if (result != ISC_R_SUCCESS) { + cfg_obj_log(nameobj, dns_lctx, ISC_LOG_WARNING, + "undefined ACL '%s'", aclname); + return (result); + } + result = ns_acl_fromconfig(cacl, cctx, ctx, mctx, &dacl); + if (result != ISC_R_SUCCESS) + return (result); + dacl->name = isc_mem_strdup(dacl->mctx, aclname); + if (dacl->name == NULL) + return (ISC_R_NOMEMORY); + ISC_LIST_APPEND(ctx->named_acl_cache, dacl, nextincache); + dns_acl_attach(dacl, target); + return (ISC_R_SUCCESS); +} + +static isc_result_t +convert_keyname(cfg_obj_t *keyobj, isc_mem_t *mctx, dns_name_t *dnsname) { + isc_result_t result; + isc_buffer_t buf; + dns_fixedname_t fixname; + unsigned int keylen; + const char *txtname = cfg_obj_asstring(keyobj); + + keylen = strlen(txtname); + isc_buffer_init(&buf, txtname, keylen); + isc_buffer_add(&buf, keylen); + dns_fixedname_init(&fixname); + result = dns_name_fromtext(dns_fixedname_name(&fixname), &buf, + dns_rootname, ISC_FALSE, NULL); + if (result != ISC_R_SUCCESS) { + cfg_obj_log(keyobj, dns_lctx, ISC_LOG_WARNING, + "key name '%s' is not a valid domain name", + txtname); + return (result); + } + return (dns_name_dup(dns_fixedname_name(&fixname), mctx, dnsname)); +} + +isc_result_t +ns_acl_fromconfig(cfg_obj_t *caml, + cfg_obj_t *cctx, + ns_aclconfctx_t *ctx, + isc_mem_t *mctx, + dns_acl_t **target) +{ + isc_result_t result; + unsigned int count; + dns_acl_t *dacl = NULL; + dns_aclelement_t *de; + cfg_listelt_t *elt; + + REQUIRE(target != NULL && *target == NULL); + + count = 0; + for (elt = cfg_list_first(caml); + elt != NULL; + elt = cfg_list_next(elt)) + count++; + + result = dns_acl_create(mctx, count, &dacl); + if (result != ISC_R_SUCCESS) + return (result); + + de = dacl->elements; + for (elt = cfg_list_first(caml); + elt != NULL; + elt = cfg_list_next(elt)) + { + cfg_obj_t *ce = cfg_listelt_value(elt); + if (cfg_obj_istuple(ce)) { + /* This must be a negated element. */ + ce = cfg_tuple_get(ce, "value"); + de->negative = ISC_TRUE; + } else { + de->negative = ISC_FALSE; + } + + if (cfg_obj_isnetprefix(ce)) { + /* Network prefix */ + de->type = dns_aclelementtype_ipprefix; + + cfg_obj_asnetprefix(ce, + &de->u.ip_prefix.address, + &de->u.ip_prefix.prefixlen); + } else if (cfg_obj_istype(ce, &cfg_type_keyref)) { + /* Key name */ + de->type = dns_aclelementtype_keyname; + dns_name_init(&de->u.keyname, NULL); + result = convert_keyname(ce, mctx, &de->u.keyname); + if (result != ISC_R_SUCCESS) + goto cleanup; + } else if (cfg_obj_islist(ce)) { + /* Nested ACL */ + de->type = dns_aclelementtype_nestedacl; + result = ns_acl_fromconfig(ce, cctx, ctx, mctx, + &de->u.nestedacl); + if (result != ISC_R_SUCCESS) + goto cleanup; + } else if (cfg_obj_isstring(ce)) { + /* ACL name */ + char *name = cfg_obj_asstring(ce); + if (strcasecmp(name, "localhost") == 0) { + de->type = dns_aclelementtype_localhost; + } else if (strcasecmp(name, "localnets") == 0) { + de->type = dns_aclelementtype_localnets; + } else if (strcasecmp(name, "any") == 0) { + de->type = dns_aclelementtype_any; + } else if (strcasecmp(name, "none") == 0) { + de->type = dns_aclelementtype_any; + de->negative = ISC_TF(! de->negative); + } else { + de->type = dns_aclelementtype_nestedacl; + result = convert_named_acl(ce, cctx, ctx, mctx, + &de->u.nestedacl); + if (result != ISC_R_SUCCESS) + goto cleanup; + } + } else { + cfg_obj_log(ce, dns_lctx, ISC_LOG_WARNING, + "address match list contains " + "unsupported element type"); + result = ISC_R_FAILURE; + goto cleanup; + } + de++; + dacl->length++; + } + + *target = dacl; + return (ISC_R_SUCCESS); + + cleanup: + dns_acl_detach(&dacl); + return (result); +} diff --git a/contrib/bind-9.2.4rc7/bin/named/client.c b/contrib/bind-9.2.4rc7/bin/named/client.c new file mode 100644 index 0000000..4074fbd --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/client.c @@ -0,0 +1,2215 @@ +/* + * Copyright (C) 2004 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.c,v 1.176.2.16 2004/07/23 02:56:59 marka 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 + +/*** + *** Client + ***/ + +/* + * 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 + +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 inactive; /* To be recycled */ +}; + +#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. + */ + + +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_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. + */ + 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)) + 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_put(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; + 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) + 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]; + + REQUIRE(NS_CLIENT_VALID(client)); + + CTRACE("send"); + + if ((client->attributes & NS_CLIENTATTR_RA) != 0) + client->message->flags |= DNS_MESSAGEFLAG_RA; + + /* + * 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); + 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); + 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, 0); + 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); +} + +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); + + /* + * 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; + + 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. + */ + rdatalist->rdclass = RECV_BUFFER_SIZE; + + /* + * Set EXTENDED-RCODE, VERSION, and Z to 0. + */ +#ifdef ISC_RFC2535 + rdatalist->ttl = (client->extflags & DNS_MESSAGEEXTFLAG_REPLYPRESERVE); +#else + rdatalist->ttl = 0; +#endif + + /* + * No ENDS 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); + dns_rdatalist_tordataset(rdatalist, rdataset); + + client->opt = rdataset; + + return (ISC_R_SUCCESS); +} + +static inline isc_boolean_t +allowed(isc_netaddr_t *addr, dns_acl_t *acl) { + int match; + isc_result_t result; + + if (acl == NULL) + return (ISC_TRUE); + result = dns_acl_match(addr, NULL, acl, &ns_g_server->aclenv, + &match, NULL); + if (result == ISC_R_SUCCESS && match > 0) + return (ISC_TRUE); + return (ISC_FALSE); +} + +/* + * 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_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); + + UNUSED(task); + + INSIST(client->recursionquota == NULL); + + INSIST(client->state == + TCP_CLIENT(client) ? + NS_CLIENTSTATE_READING : + NS_CLIENTSTATE_READY); + + 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_stdtime_get(&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); + + 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; + } + } + + if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) { + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), + "multicast request"); +#if 0 + ns_client_error(client, DNS_R_REFUSED); +#endif + } + + 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; + } + } + + /* + * 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; + + /* + * Deal with EDNS. + */ + opt = dns_message_getopt(client->message); + if (opt != NULL) { + unsigned int version; + + /* + * 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); + + /* + * Create an OPT for our reply. + */ + result = client_addopt(client); + if (result != ISC_R_SUCCESS) { + ns_client_error(client, result); + goto cleanup; + } + + /* + * Do we understand this version of ENDS? + * + * XXXRTH need library support for this! + */ + version = (opt->ttl & 0x00FF0000) >> 16; + if (version != 0) { + ns_client_error(client, DNS_R_BADVERS); + 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. For TCP/IPv6, we get this from + * the receiving socket. For UDP/IPv6, we get it from the pktinfo + * structure (if supported). For IPv4, we have to do with + * the address of the interface where the request was received. + */ + if (client->interface->addr.type.sa.sa_family == AF_INET6) { + 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->attributes & NS_CLIENTATTR_PKTINFO) != 0) { + isc_netaddr_fromin6(&destaddr, &client->pktinfo.ipi6_addr); + result = ISC_R_SUCCESS; + } + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "failed to get request's " + "destination: %s", + isc_result_totext(result)); + goto cleanup; + } + } else { + isc_netaddr_fromsockaddr(&destaddr, &client->interface->addr); + } + + /* + * 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) + { + if (allowed(&netaddr, view->matchclients) && + allowed(&destaddr, view->matchdestinations) && + !((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; + 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. + */ + sigresult = dns_message_checksig(client->message, client->view); + 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 { + /* There is a signature, but it is bad. */ + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_CLIENT, ISC_LOG_ERROR, + "request has invalid signature: %s", + isc_result_totext(result)); + /* + * 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. + */ + ra = ISC_FALSE; + if (client->view->resolver != NULL && + client->view->recursion == ISC_TRUE && + /* XXX this will log too much too early */ + ns_client_checkacl(client, "recursion available:", + client->view->recursionacl, + ISC_TRUE, ISC_LOG_DEBUG(1)) == ISC_R_SUCCESS) + ra = ISC_TRUE; + + if (ra == ISC_TRUE) + client->attributes |= NS_CLIENTATTR_RA; + + /* + * 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 +client_create(ns_clientmgr_t *manager, ns_client_t **clientp) +{ + ns_client_t *client; + isc_result_t result; + + /* + * 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); + + client = isc_mem_get(manager->mctx, sizeof *client); + if (client == NULL) + return (ISC_R_NOMEMORY); + + 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(manager->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(manager->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(manager->mctx, RECV_BUFFER_SIZE); + if (client->recvbuf == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup_sendevent; + } + + client->recvevent = (isc_socketevent_t *) + isc_event_allocate(manager->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->mctx = manager->mctx; + 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->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(manager->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_put(manager->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_recv() failed: %s", + isc_result_totext(result)); + /* + * This cannot happen in the current implementation, since + * isc_socket_recv2() cannot fail if flags == 0A + * + * 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) { + REQUIRE(ISC_LIST_EMPTY(manager->active)); + REQUIRE(ISC_LIST_EMPTY(manager->inactive)); + + MTRACE("clientmgr_destroy"); + + 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; + + 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); + 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->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)) + 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); +} + +static 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); + +static 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]; + + vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); + ns_client_name(client, peerbuf, sizeof peerbuf); + + isc_log_write(ns_g_lctx, category, module, level, + "client %s: %s", peerbuf, 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_rdataclass_t rdclass, + char *buf, size_t len) +{ + char namebuf[DNS_NAME_FORMATSIZE]; + char classbuf[DNS_RDATACLASS_FORMATSIZE]; + + dns_name_format(name, namebuf, sizeof(namebuf)); + dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf)); + (void)snprintf(buf, len, "%s '%s/%s'", msg, namebuf, 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); +} diff --git a/contrib/bind-9.2.4rc7/bin/named/config.c b/contrib/bind-9.2.4rc7/bin/named/config.c new file mode 100644 index 0000000..fc650ec --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/config.c @@ -0,0 +1,455 @@ +/* + * Copyright (C) 2004 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.c,v 1.11.2.6 2004/04/19 23:15:38 marka Exp $ */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +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\ +" +#ifdef PATH_RANDOMDEV +"\ + random-device \"" PATH_RANDOMDEV "\";\n\ +" +#endif +"\ + recursive-clients 1000;\n\ + rrset-order {order cyclic;};\n\ + serial-queries 20;\n\ + serial-query-rate 20;\n\ + statistics-file \"named.stats\";\n\ + statistics-interval 60;\n\ + tcp-clients 100;\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\ + version \""VERSION"\";\n\ +\n\ + /* view */\n\ + allow-notify {none;};\n\ + allow-update-forwarding {none;};\n\ + allow-recursion {any;};\n\ + allow-v6-synthesis {none;};\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 ignore;\n\ + check-names slave ignore;\n\ + check-names response ignore;\n\ +\n\ + /* zone */\n\ + allow-query {any;};\n\ + allow-transfer {any;};\n\ + notify yes;\n\ +# also-notify \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\ + 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\ + sig-validity-interval 30; /* days */\n\ + zone-statistics false;\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(cfg_obj_t **maps, const char* name, 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); + } +} + +int +ns_config_listcount(cfg_obj_t *list) { + 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(cfg_obj_t *classobj, dns_rdataclass_t defclass, + dns_rdataclass_t *classp) { + char *str; + isc_textregion_t r; + isc_result_t result; + + if (!cfg_obj_isstring(classobj)) { + *classp = defclass; + return (ISC_R_SUCCESS); + } + str = cfg_obj_asstring(classobj); + r.base = str; + r.length = strlen(str); + result = dns_rdataclass_fromtext(classp, &r); + if (result != ISC_R_SUCCESS) + cfg_obj_log(classobj, ns_g_lctx, ISC_LOG_ERROR, + "unknown class '%s'", str); + return (result); +} + +dns_zonetype_t +ns_config_getzonetype(cfg_obj_t *zonetypeobj) { + dns_zonetype_t ztype = dns_zone_none; + 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(cfg_obj_t *config, cfg_obj_t *list, + in_port_t defport, isc_mem_t *mctx, + isc_sockaddr_t **addrsp, isc_uint32_t *countp) +{ + int count, i = 0; + cfg_obj_t *addrlist; + cfg_obj_t *portobj; + cfg_listelt_t *element; + isc_sockaddr_t *addrs; + in_port_t port; + isc_result_t result; + + INSIST(addrsp != NULL && *addrsp == 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; +} + +isc_result_t +ns_config_getipandkeylist(cfg_obj_t *config, cfg_obj_t *list, isc_mem_t *mctx, + isc_sockaddr_t **addrsp, dns_name_t ***keysp, + isc_uint32_t *countp) +{ + isc_uint32_t count, i = 0; + isc_result_t result; + cfg_listelt_t *element; + cfg_obj_t *addrlist; + cfg_obj_t *portobj; + in_port_t port; + dns_fixedname_t fname; + isc_sockaddr_t *addrs = NULL; + dns_name_t **keys = NULL; + + INSIST(addrsp != NULL && *addrsp == 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 { + result = ns_config_getport(config, &port); + if (result != ISC_R_SUCCESS) + return (result); + } + + result = ISC_R_NOMEMORY; + + addrs = isc_mem_get(mctx, count * sizeof(isc_sockaddr_t)); + if (addrs == NULL) + goto cleanup; + + keys = isc_mem_get(mctx, count * sizeof(dns_name_t *)); + if (keys == NULL) + goto cleanup; + + for (element = cfg_list_first(addrlist); + element != NULL; + element = cfg_list_next(element), i++) + { + cfg_obj_t *addr; + cfg_obj_t *key; + char *keystr; + isc_buffer_t b; + + INSIST(i < count); + + addr = cfg_tuple_get(cfg_listelt_value(element), "sockaddr"); + key = cfg_tuple_get(cfg_listelt_value(element), "key"); + + 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)) + 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; + } + INSIST(i == count); + + *addrsp = addrs; + *keysp = keys; + *countp = count; + + return (ISC_R_SUCCESS); + + cleanup: + if (addrs != NULL) + isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t)); + if (keys != NULL) { + unsigned int j; + 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, count * sizeof(dns_name_t *)); + } + 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(cfg_obj_t *config, in_port_t *portp) { + cfg_obj_t *maps[3]; + cfg_obj_t *options = NULL; + cfg_obj_t *portobj = NULL; + isc_result_t result; + int i; + + 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); +} + +isc_result_t +ns_config_getkeyalgorithm(const char *str, dns_name_t **name) +{ + if (strcasecmp(str, "hmac-md5") == 0 || + strcasecmp(str, "hmac-md5.sig-alg.reg.int") == 0 || + strcasecmp(str, "hmac-md5.sig-alg.reg.int.") == 0) + { + if (name != NULL) + *name = dns_tsig_hmacmd5_name; + return (ISC_R_SUCCESS); + } + return (ISC_R_NOTFOUND); +} diff --git a/contrib/bind-9.2.4rc7/bin/named/control.c b/contrib/bind-9.2.4rc7/bin/named/control.c new file mode 100644 index 0000000..a50aa92 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/control.c @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2004 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.c,v 1.7.2.4 2004/04/06 01:38:47 marka Exp $ */ + +#include + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +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; + + 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); + } 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); + } else if (command_compare(command, NS_COMMAND_HALT)) { + ns_server_flushonshutdown(ns_g_server, ISC_FALSE); + isc_app_shutdown(); + result = ISC_R_SUCCESS; + } else if (command_compare(command, NS_COMMAND_STOP)) { + ns_server_flushonshutdown(ns_g_server, ISC_TRUE); + 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); + 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_STATUS)) { + result = ns_server_status(ns_g_server, text); + } else if (command_compare(command, NS_COMMAND_NULL)) { + result = ISC_R_SUCCESS; + } 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/bind-9.2.4rc7/bin/named/controlconf.c b/contrib/bind-9.2.4rc7/bin/named/controlconf.c new file mode 100644 index 0000000..04f344a --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/controlconf.c @@ -0,0 +1,1329 @@ +/* + * Copyright (C) 2004 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.28.2.10 2004/03/09 06:09:18 marka 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 + +#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_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); + 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); + 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); + isc_mem_put(listener->mctx, secret.rstart, + REGION_SIZE(secret)); + } 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 (!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(cfg_obj_t *keylist, const char *keyname, cfg_obj_t **objp) { + cfg_listelt_t *element; + const char *str; + 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(cfg_obj_t *keylist, isc_mem_t *mctx, + controlkeylist_t *keyids) +{ + cfg_listelt_t *element; + char *newstr = NULL; + const char *str; + cfg_obj_t *obj; + controlkey_t *key = NULL; + + 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); + key = NULL; + newstr = NULL; + } + return (ISC_R_SUCCESS); + + cleanup: + if (newstr != NULL) + isc_mem_free(mctx, newstr); + if (key != NULL) + isc_mem_put(mctx, key, sizeof(*key)); + free_controlkeylist(keyids, mctx); + return (ISC_R_NOMEMORY); +} + +static void +register_keys(cfg_obj_t *control, cfg_obj_t *keylist, + controlkeylist_t *keyids, isc_mem_t *mctx, const char *socktext) +{ + controlkey_t *keyid, *next; + 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 { + cfg_obj_t *algobj = NULL; + cfg_obj_t *secretobj = NULL; + char *algstr = NULL; + 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) != + 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; + cfg_obj_t *key = NULL; + cfg_obj_t *algobj = NULL; + cfg_obj_t *secretobj = NULL; + char *algstr = NULL; + 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(cfg_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) != 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(cfg_obj_t *config, cfg_obj_t *control, + cfg_obj_t **global_keylistp, cfg_obj_t **control_keylistp) +{ + isc_result_t result; + cfg_obj_t *control_keylist = NULL; + 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, cfg_obj_t *control, + cfg_obj_t *config, isc_sockaddr_t *addr, + ns_aclconfctx_t *aclconfctx, const char *socktext) +{ + controllistener_t *listener; + cfg_obj_t *allow; + cfg_obj_t *global_keylist = NULL; + 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. + */ + 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)); + + + /* + * Now, keep the old access list unless a new one can be made. + */ + if (control != NULL) { + allow = cfg_tuple_get(control, "allow"); + result = ns_acl_fromconfig(allow, config, 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); + } else + /* XXXDCL say the old acl is still used? */ + 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)); + + *listenerp = listener; +} + +static void +add_listener(ns_controls_t *cp, controllistener_t **listenerp, + cfg_obj_t *control, cfg_obj_t *config, isc_sockaddr_t *addr, + ns_aclconfctx_t *aclconfctx, const char *socktext) +{ + isc_mem_t *mctx = cp->server->mctx; + controllistener_t *listener; + cfg_obj_t *allow; + cfg_obj_t *global_keylist = NULL; + 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; + ISC_LINK_INIT(listener, link); + ISC_LIST_INIT(listener->keys); + ISC_LIST_INIT(listener->connections); + + /* + * Make the acl. + */ + if (control != NULL) { + allow = cfg_tuple_get(control, "allow"); + result = ns_acl_fromconfig(allow, config, 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) || + (pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS)) + result = ISC_R_FAMILYNOSUPPORT; + } + + if (result == ISC_R_SUCCESS) + result = isc_socket_create(ns_g_socketmgr, + isc_sockaddr_pf(&listener->address), + isc_sockettype_tcp, + &listener->sock); + + if (result == ISC_R_SUCCESS) + result = isc_socket_bind(listener->sock, + &listener->address); + + 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, cfg_obj_t *config, + ns_aclconfctx_t *aclconfctx) +{ + controllistener_t *listener; + controllistenerlist_t new_listeners; + cfg_obj_t *controlslist = NULL; + 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)) { + cfg_obj_t *controls; + 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)) { + cfg_obj_t *control; + 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. + * + * "unix" phrases have been reported as + * unsupported by the parser. + */ + 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); + + 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); + + 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); + + 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); + + 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/bind-9.2.4rc7/bin/named/include/named/aclconf.h b/contrib/bind-9.2.4rc7/bin/named/include/named/aclconf.h new file mode 100644 index 0000000..639ce56 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/aclconf.h @@ -0,0 +1,72 @@ +/* + * 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: aclconf.h,v 1.12.2.1 2004/03/09 06:09:21 marka Exp $ */ + +#ifndef NS_ACLCONF_H +#define NS_ACLCONF_H 1 + +#include + +#include + +#include + +typedef struct ns_aclconfctx { + ISC_LIST(dns_acl_t) named_acl_cache; +} ns_aclconfctx_t; + +/*** + *** Functions + ***/ + +ISC_LANG_BEGINDECLS + +void +ns_aclconfctx_init(ns_aclconfctx_t *ctx); +/* + * Initialize an ACL configuration context. + */ + +void +ns_aclconfctx_destroy(ns_aclconfctx_t *ctx); +/* + * Destroy an ACL configuration context. + */ + +isc_result_t +ns_acl_fromconfig(cfg_obj_t *caml, + cfg_obj_t *cctx, + ns_aclconfctx_t *ctx, + isc_mem_t *mctx, + dns_acl_t **target); +/* + * Construct a new dns_acl_t from configuration data in 'caml' and + * 'cctx'. Memory is allocated through 'mctx'. + * + * Any named ACLs referred to within 'caml' will be be converted + * inte nested dns_acl_t objects. Multiple references to the same + * named ACLs will be converted into shared references to a single + * nested dns_acl_t object when the referring objects were created + * passing the same ACL configuration context 'ctx'. + * + * On success, attach '*target' to the new dns_acl_t object. + */ + +ISC_LANG_ENDDECLS + +#endif /* NS_ACLCONF_H */ diff --git a/contrib/bind-9.2.4rc7/bin/named/include/named/client.h b/contrib/bind-9.2.4rc7/bin/named/include/named/client.h new file mode 100644 index 0000000..3589c5b --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/client.h @@ -0,0 +1,311 @@ +/* + * 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: client.h,v 1.60.2.4 2004/07/23 02:57:01 marka Exp $ */ + +#ifndef NAMED_CLIENT_H +#define NAMED_CLIENT_H 1 + +/***** + ***** Module Info + *****/ + +/* + * Client + * + * 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: + * + * 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) + * + * 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 + +/*** + *** Types + ***/ + +typedef ISC_LIST(ns_client_t) client_list_t; + +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; + 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 */ + +/*** + *** 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. + */ + +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: + * 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: + * 'client' points to a valid client. + * 'acl' points to a valid ACL, or is NULL. + * + * Returns: + * ISC_R_SUCCESS if the request should be allowed + * ISC_R_REFUSED if the request should be denied + * 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: + * Those of ns_client_checkaclsilent(), and: + * + * '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_aclmsg(const char *msg, dns_name_t *name, dns_rdataclass_t rdclass, + char *buf, size_t len); + +#endif /* NAMED_CLIENT_H */ diff --git a/contrib/bind-9.2.4rc7/bin/named/include/named/config.h b/contrib/bind-9.2.4rc7/bin/named/include/named/config.h new file mode 100644 index 0000000..3d97be6 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/config.h @@ -0,0 +1,68 @@ +/* + * 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: config.h,v 1.4.2.1 2004/03/09 06:09:21 marka Exp $ */ + +#ifndef NAMED_CONFIG_H +#define NAMED_CONFIG_H 1 + +#include + +#include +#include + +isc_result_t +ns_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf); + +isc_result_t +ns_config_get(cfg_obj_t **maps, const char* name, cfg_obj_t **obj); + +int +ns_config_listcount(cfg_obj_t *list); + +isc_result_t +ns_config_getclass(cfg_obj_t *classobj, dns_rdataclass_t defclass, + dns_rdataclass_t *classp); + +dns_zonetype_t +ns_config_getzonetype(cfg_obj_t *zonetypeobj); + +isc_result_t +ns_config_getiplist(cfg_obj_t *config, 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(cfg_obj_t *config, 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(cfg_obj_t *config, in_port_t *portp); + +isc_result_t +ns_config_getkeyalgorithm(const char *str, dns_name_t **name); + +#endif /* NAMED_CONFIG_H */ diff --git a/contrib/bind-9.2.4rc7/bin/named/include/named/control.h b/contrib/bind-9.2.4rc7/bin/named/include/named/control.h new file mode 100644 index 0000000..a805c00 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/control.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2004 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.6.2.3 2004/03/09 06:09:21 marka Exp $ */ + +#ifndef NAMED_CONTROL_H +#define NAMED_CONTROL_H 1 + +/* + * 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_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_STATUS "status" +#define NS_COMMAND_NULL "null" + +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, cfg_obj_t *config, + ns_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/bind-9.2.4rc7/bin/named/include/named/globals.h b/contrib/bind-9.2.4rc7/bin/named/include/named/globals.h new file mode 100644 index 0000000..d2a2250 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/globals.h @@ -0,0 +1,113 @@ +/* + * 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: globals.h,v 1.59.2.1 2004/03/09 06:09:21 marka Exp $ */ + +#ifndef NAMED_GLOBALS_H +#define NAMED_GLOBALS_H 1 + +#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); +/* + * 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 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); + +/* + * 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); + +#undef EXTERN +#undef INIT + +#endif /* NAMED_GLOBALS_H */ diff --git a/contrib/bind-9.2.4rc7/bin/named/include/named/interfacemgr.h b/contrib/bind-9.2.4rc7/bin/named/include/named/interfacemgr.h new file mode 100644 index 0000000..f0e3399 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/interfacemgr.h @@ -0,0 +1,153 @@ +/* + * 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: interfacemgr.h,v 1.23.2.1 2004/03/09 06:09:21 marka Exp $ */ + +#ifndef NAMED_INTERFACEMGR_H +#define NAMED_INTERFACEMGR_H 1 + +/***** + ***** Module Info + *****/ + +/* + * Interface manager + * + * The interface manager monitors the operating system's list + * of network interfaces, creating and destroying listeners + * as needed. + * + * Reliability: + * No impact expected. + * + * Resources: + * + * Security: + * The server will only be able to bind to the DNS port on + * newly discovered interfaces if it is running as root. + * + * Standards: + * 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) + +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. */ + 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_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. + */ + +#endif /* NAMED_INTERFACEMGR_H */ diff --git a/contrib/bind-9.2.4rc7/bin/named/include/named/listenlist.h b/contrib/bind-9.2.4rc7/bin/named/include/named/listenlist.h new file mode 100644 index 0000000..af30de0 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/listenlist.h @@ -0,0 +1,104 @@ +/* + * 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: listenlist.h,v 1.10.2.1 2004/03/09 06:09:21 marka Exp $ */ + +#ifndef NAMED_LISTENLIST_H +#define NAMED_LISTENLIST_H 1 + +/***** + ***** Module Info + *****/ + +/* + * "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/bind-9.2.4rc7/bin/named/include/named/log.h b/contrib/bind-9.2.4rc7/bin/named/include/named/log.h new file mode 100644 index 0000000..f9b250a --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/log.h @@ -0,0 +1,95 @@ +/* + * 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: log.h,v 1.19.2.1 2004/03/09 06:09:22 marka Exp $ */ + +#ifndef NAMED_LOG_H +#define NAMED_LOG_H 1 + +#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]) + +/* + * 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/bind-9.2.4rc7/bin/named/include/named/logconf.h b/contrib/bind-9.2.4rc7/bin/named/include/named/logconf.h new file mode 100644 index 0000000..9e0dbf1 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/logconf.h @@ -0,0 +1,32 @@ +/* + * 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: logconf.h,v 1.10.2.1 2004/03/09 06:09:22 marka Exp $ */ + +#ifndef NAMED_LOGCONF_H +#define NAMED_LOGCONF_H 1 + +#include + +isc_result_t +ns_log_configure(isc_logconfig_t *logconf, 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/bind-9.2.4rc7/bin/named/include/named/lwaddr.h b/contrib/bind-9.2.4rc7/bin/named/include/named/lwaddr.h new file mode 100644 index 0000000..ea7161e --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/lwaddr.h @@ -0,0 +1,34 @@ +/* + * 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: lwaddr.h,v 1.3.2.1 2004/03/09 06:09:22 marka Exp $ */ + +#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/bind-9.2.4rc7/bin/named/include/named/lwdclient.h b/contrib/bind-9.2.4rc7/bin/named/include/named/lwdclient.h new file mode 100644 index 0000000..047f98a --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/lwdclient.h @@ -0,0 +1,230 @@ +/* + * 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: lwdclient.h,v 1.13.2.1 2004/03/09 06:09:22 marka Exp $ */ + +#ifndef NAMED_LWDCLIENT_H +#define NAMED_LWDCLIENT_H 1 + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#define LWRD_EVENTCLASS ISC_EVENTCLASS(4242) + +#define LWRD_SHUTDOWN (LWRD_EVENTCLASS + 0x0001) + +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) + +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/bind-9.2.4rc7/bin/named/include/named/lwresd.h b/contrib/bind-9.2.4rc7/bin/named/include/named/lwresd.h new file mode 100644 index 0000000..37af4d6 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/lwresd.h @@ -0,0 +1,111 @@ +/* + * 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: lwresd.h,v 1.12.2.1 2004/03/09 06:09:22 marka Exp $ */ + +#ifndef NAMED_LWRESD_H +#define NAMED_LWRESD_H 1 + +#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, 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 + */ +isc_result_t +ns_lwdmanager_create(isc_mem_t *mctx, cfg_obj_t *lwres, ns_lwresd_t **lwresdp); + +void +ns_lwdmanager_attach(ns_lwresd_t *source, ns_lwresd_t **targetp); + +void +ns_lwdmanager_detach(ns_lwresd_t **lwresdp); + +/* + * Listener functions + */ +void +ns_lwreslistener_attach(ns_lwreslistener_t *source, + ns_lwreslistener_t **targetp); + +void +ns_lwreslistener_detach(ns_lwreslistener_t **listenerp); + +void +ns_lwreslistener_unlinkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm); + +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/bind-9.2.4rc7/bin/named/include/named/lwsearch.h b/contrib/bind-9.2.4rc7/bin/named/include/named/lwsearch.h new file mode 100644 index 0000000..9a7bb26 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/lwsearch.h @@ -0,0 +1,110 @@ +/* + * 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: lwsearch.h,v 1.4.2.1 2004/03/09 06:09:22 marka Exp $ */ + +#ifndef NAMED_LWSEARCH_H +#define NAMED_LWSEARCH_H 1 + +#include +#include +#include + +#include + +#include + +/* + * 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. + */ + +struct ns_lwsearchlist { + unsigned int magic; + + isc_mutex_t lock; + isc_mem_t *mctx; + unsigned int refs; + dns_namelist_t names; +}; + +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/bind-9.2.4rc7/bin/named/include/named/main.h b/contrib/bind-9.2.4rc7/bin/named/include/named/main.h new file mode 100644 index 0000000..7c8d6ca --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/main.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2004 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.8.2.3 2004/03/09 06:09:22 marka Exp $ */ + +#ifndef NAMED_MAIN_H +#define NAMED_MAIN_H 1 + +void +ns_main_earlyfatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); + +void +ns_main_earlywarning(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); + +#endif /* NAMED_MAIN_H */ diff --git a/contrib/bind-9.2.4rc7/bin/named/include/named/notify.h b/contrib/bind-9.2.4rc7/bin/named/include/named/notify.h new file mode 100644 index 0000000..69a1ac4 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/notify.h @@ -0,0 +1,54 @@ +/* + * 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: notify.h,v 1.9.2.1 2004/03/09 06:09:23 marka Exp $ */ + +#ifndef NAMED_NOTIFY_H +#define NAMED_NOTIFY_H 1 + +#include +#include + +/*** + *** Module Info + ***/ + +/* + * RFC 1996 + * 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 + * client to be valid. + */ + +#endif /* NAMED_NOTIFY_H */ + diff --git a/contrib/bind-9.2.4rc7/bin/named/include/named/query.h b/contrib/bind-9.2.4rc7/bin/named/include/named/query.h new file mode 100644 index 0000000..4de0af3 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/query.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2004 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.28.2.4 2004/03/09 06:09:23 marka Exp $ */ + +#ifndef NAMED_QUERY_H +#define NAMED_QUERY_H 1 + +#include +#include +#include + +#include +#include + +#include + +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; + +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; + dns_fetch_t * fetch; + dns_a6context_t a6ctx; + isc_bufferlist_t namebufs; + ISC_LIST(ns_dbversion_t) activeversions; + ISC_LIST(ns_dbversion_t) freeversions; + /* + * Additional state used during IPv6 response synthesis only. + */ + struct { + isc_netaddr_t na; + } synth; +}; + +#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_WANTDNSSEC 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); + +#endif /* NAMED_QUERY_H */ diff --git a/contrib/bind-9.2.4rc7/bin/named/include/named/server.h b/contrib/bind-9.2.4rc7/bin/named/include/named/server.h new file mode 100644 index 0000000..fc112d5 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/server.h @@ -0,0 +1,182 @@ +/* + * 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: server.h,v 1.58.2.3 2004/03/09 06:09:23 marka Exp $ */ + +#ifndef NAMED_SERVER_H +#define NAMED_SERVER_H 1 + +#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; + + /* + * 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_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 */ + + char * statsfile; /* Statistics file name */ + isc_uint64_t * querystats; /* Query statistics counters */ + + char * dumpfile; /* Dump file name */ + + ns_controls_t * controls; /* Control channels */ + unsigned int dispatchgen; + ns_dispatchlist_t dispatches; + +}; + +#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); +/* + * 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_refreshcommand(ns_server_t *server, char *args); +/* + * Act on a "refresh" 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); + +/* + * 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); + +/* + * Report the server's status. + */ +isc_result_t +ns_server_status(ns_server_t *server, isc_buffer_t *text); + +/* + * Maintain a list of dispatches that require reserved ports. + */ +void +ns_add_reserved_dispatch(ns_server_t *server, isc_sockaddr_t *addr); + +#endif /* NAMED_SERVER_H */ diff --git a/contrib/bind-9.2.4rc7/bin/named/include/named/sortlist.h b/contrib/bind-9.2.4rc7/bin/named/include/named/sortlist.h new file mode 100644 index 0000000..7b520b7 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/sortlist.h @@ -0,0 +1,84 @@ +/* + * 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: sortlist.h,v 1.4.2.1 2004/03/09 06:09:23 marka Exp $ */ + +#ifndef NAMED_SORTLIST_H +#define NAMED_SORTLIST_H 1 + +#include + +#include + +/* + * Type for callback functions that rank addresses. + */ +typedef int +(*dns_addressorderfunc_t)(isc_netaddr_t *address, 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, 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(isc_netaddr_t *addr, 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(isc_netaddr_t *addr, 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, + 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/bind-9.2.4rc7/bin/named/include/named/tkeyconf.h b/contrib/bind-9.2.4rc7/bin/named/include/named/tkeyconf.h new file mode 100644 index 0000000..87ba18f --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/tkeyconf.h @@ -0,0 +1,51 @@ +/* + * 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: tkeyconf.h,v 1.9.2.1 2004/03/09 06:09:23 marka Exp $ */ + +#ifndef NS_TKEYCONF_H +#define NS_TKEYCONF_H 1 + +#include +#include + +#include + +ISC_LANG_BEGINDECLS + +isc_result_t +ns_tkeyctx_fromconfig(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: + * 'cfg' is a valid configuration options object. + * 'mctx' is not NULL + * 'ectx' is not NULL + * 'tctx' is not NULL + * '*tctx' is NULL + * + * Returns: + * ISC_R_SUCCESS + * ISC_R_NOMEMORY + */ + +ISC_LANG_ENDDECLS + +#endif /* NS_TKEYCONF_H */ diff --git a/contrib/bind-9.2.4rc7/bin/named/include/named/tsigconf.h b/contrib/bind-9.2.4rc7/bin/named/include/named/tsigconf.h new file mode 100644 index 0000000..05f1a9e --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/tsigconf.h @@ -0,0 +1,47 @@ +/* + * 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: tsigconf.h,v 1.9.2.1 2004/03/09 06:09:23 marka Exp $ */ + +#ifndef NS_TSIGCONF_H +#define NS_TSIGCONF_H 1 + +#include +#include + +ISC_LANG_BEGINDECLS + +isc_result_t +ns_tsigkeyring_fromconfig(cfg_obj_t *config, 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: + * 'config' is not NULL. + * 'mctx' is not NULL + * 'ring' is not NULL, and '*ring' is NULL + * + * Returns: + * ISC_R_SUCCESS + * ISC_R_NOMEMORY + */ + +ISC_LANG_ENDDECLS + +#endif /* NS_TSIGCONF_H */ diff --git a/contrib/bind-9.2.4rc7/bin/named/include/named/types.h b/contrib/bind-9.2.4rc7/bin/named/include/named/types.h new file mode 100644 index 0000000..f35c4c1 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/types.h @@ -0,0 +1,41 @@ +/* + * 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: types.h,v 1.19.2.2 2004/03/09 06:09:23 marka Exp $ */ + +#ifndef NAMED_TYPES_H +#define NAMED_TYPES_H 1 + +#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/bind-9.2.4rc7/bin/named/include/named/update.h b/contrib/bind-9.2.4rc7/bin/named/include/named/update.h new file mode 100644 index 0000000..e340d3c --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/update.h @@ -0,0 +1,49 @@ +/* + * 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: update.h,v 1.8.2.1 2004/03/09 06:09:23 marka Exp $ */ + +#ifndef NAMED_UPDATE_H +#define NAMED_UPDATE_H 1 + +/***** + ***** Module Info + *****/ + +/* + * 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/bind-9.2.4rc7/bin/named/include/named/xfrout.h b/contrib/bind-9.2.4rc7/bin/named/include/named/xfrout.h new file mode 100644 index 0000000..08638d4 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/xfrout.h @@ -0,0 +1,38 @@ +/* + * 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: xfrout.h,v 1.7.2.1 2004/03/09 06:09:23 marka Exp $ */ + +#ifndef NAMED_XFROUT_H +#define NAMED_XFROUT_H 1 + +/***** + ***** Module Info + *****/ + +/* + * 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/bind-9.2.4rc7/bin/named/include/named/zoneconf.h b/contrib/bind-9.2.4rc7/bin/named/include/named/zoneconf.h new file mode 100644 index 0000000..a343785 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/include/named/zoneconf.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2004 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.16.2.3 2004/03/09 06:09:23 marka Exp $ */ + +#ifndef NS_ZONECONF_H +#define NS_ZONECONF_H 1 + +#include +#include + +#include + +#include + +ISC_LANG_BEGINDECLS + +isc_result_t +ns_zone_configure(cfg_obj_t *config, cfg_obj_t *vconfig, cfg_obj_t *zconfig, + ns_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: + * 'lctx' to be initialized or NULL. + * 'cctx' to be initialized or NULL. + * 'ac' to point to an initialized ns_aclconfctx_t. + * 'czone' to be initialized. + * 'zone' to be initialized. + */ + +isc_boolean_t +ns_zone_reusable(dns_zone_t *zone, 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/bind-9.2.4rc7/bin/named/interfacemgr.c b/contrib/bind-9.2.4rc7/bin/named/interfacemgr.c new file mode 100644 index 0000000..96b7c74 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/interfacemgr.c @@ -0,0 +1,738 @@ +/* + * Copyright (C) 2004 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.59.2.7 2004/08/10 04:58:00 jinmei Exp $ */ + +#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 + +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. */ +}; + +static void +purge_old_interfaces(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); + + /* + * 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); + 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; + 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; + } + 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, 3); + 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; + } + + 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_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; + + 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_result_t +do_ipv4(ns_interfacemgr_t *mgr) { + isc_interfaceiter_t *iter = NULL; + isc_result_t result; + + result = isc_interfaceiter_create(mgr->mctx, &iter); + if (result != ISC_R_SUCCESS) + return (result); + + 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; + + for (result = isc_interfaceiter_first(iter); + result == ISC_R_SUCCESS; + result = isc_interfaceiter_next(iter)) + { + ns_interface_t *ifp; + isc_interface_t interface; + ns_listenelt_t *le; + dns_aclelement_t elt; + unsigned int prefixlen; + + result = isc_interfaceiter_current(iter, &interface); + if (result != ISC_R_SUCCESS) + break; + + if (interface.address.family != AF_INET) + continue; + + if ((interface.flags & INTERFACE_F_UP) == 0) + continue; + + elt.type = dns_aclelementtype_ipprefix; + elt.negative = ISC_FALSE; + elt.u.ip_prefix.address = interface.address; + elt.u.ip_prefix.prefixlen = 32; + result = dns_acl_appendelement(mgr->aclenv.localhost, &elt); + if (result != ISC_R_SUCCESS) + goto ignore_interface; + + result = isc_netaddr_masktoprefixlen(&interface.netmask, + &prefixlen); + 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; + /* XXX suppress duplicates */ + result = dns_acl_appendelement(mgr->aclenv.localnets, + &elt); + if (result != ISC_R_SUCCESS) + goto ignore_interface; + } + + for (le = ISC_LIST_HEAD(mgr->listenon4->elts); + le != NULL; + le = ISC_LIST_NEXT(le, link)) + { + int match; + isc_netaddr_t listen_netaddr; + isc_sockaddr_t listen_sockaddr; + + /* + * Construct a socket address for this IP/port + * combination. + */ + isc_netaddr_fromin(&listen_netaddr, + &interface.address.type.in); + isc_sockaddr_fromnetaddr(&listen_sockaddr, + &listen_netaddr, + le->port); + + /* + * See if the address matches the listen-on statement; + * if not, ignore the interface. + */ + result = dns_acl_match(&listen_netaddr, NULL, + le->acl, &mgr->aclenv, + &match, NULL); + if (match <= 0) + continue; + + ifp = find_matching_interface(mgr, &listen_sockaddr); + if (ifp != NULL) { + ifp->generation = mgr->generation; + } else { + char sabuf[ISC_SOCKADDR_FORMATSIZE]; + isc_sockaddr_format(&listen_sockaddr, + sabuf, sizeof(sabuf)); + isc_log_write(IFMGR_COMMON_LOGARGS, + ISC_LOG_INFO, + "listening on IPv4 interface " + "%s, %s", interface.name, sabuf); + + result = ns_interface_setup(mgr, + &listen_sockaddr, + interface.name, + &ifp); + if (result != ISC_R_SUCCESS) { + isc_log_write(IFMGR_COMMON_LOGARGS, + ISC_LOG_ERROR, + "creating IPv4 interface %s " + "failed; interface ignored", + interface.name); + } + /* Continue. */ + } + + } + continue; + + ignore_interface: + isc_log_write(IFMGR_COMMON_LOGARGS, + ISC_LOG_ERROR, + "ignoring IPv4 interface %s: %s", + interface.name, isc_result_totext(result)); + continue; + } + if (result != ISC_R_NOMORE) + UNEXPECTED_ERROR(__FILE__, __LINE__, + "IPv4: interface iteration failed: %s", + isc_result_totext(result)); + else + result = ISC_R_SUCCESS; + cleanup_iter: + isc_interfaceiter_destroy(&iter); + return (result); +} + +static isc_boolean_t +listenon_is_ip6_none(ns_listenelt_t *elt) { + if (elt->acl->length == 0) + return (ISC_TRUE); /* listen-on-v6 { } */ + if (elt->acl->length > 1) + return (ISC_FALSE); /* listen-on-v6 { ...; ...; } */ + if (elt->acl->elements[0].negative == ISC_TRUE && + elt->acl->elements[0].type == dns_aclelementtype_any) + return (ISC_TRUE); /* listen-on-v6 { none; } */ + return (ISC_FALSE); /* All others */ +} + +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 +do_ipv6(ns_interfacemgr_t *mgr) { + isc_result_t result; + ns_interface_t *ifp; + isc_sockaddr_t listen_addr; + struct in6_addr in6a; + ns_listenelt_t *le; + + for (le = ISC_LIST_HEAD(mgr->listenon6->elts); + le != NULL; + le = ISC_LIST_NEXT(le, link)) + { + if (listenon_is_ip6_none(le)) + continue; + if (! listenon_is_ip6_any(le)) { + isc_log_write(IFMGR_COMMON_LOGARGS, + ISC_LOG_ERROR, + "bad IPv6 listen-on list: " + "must be 'any' or 'none'"); + return (ISC_R_FAILURE); + } + + 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); + if (result != ISC_R_SUCCESS) { + isc_log_write(IFMGR_COMMON_LOGARGS, + ISC_LOG_ERROR, + "listening on IPv6 interfaces " + "failed"); + /* Continue. */ + } + } + } + return (ISC_R_SUCCESS); +} + +void +ns_interfacemgr_scan(ns_interfacemgr_t *mgr, isc_boolean_t verbose) { + isc_boolean_t purge = ISC_TRUE; + + REQUIRE(NS_INTERFACEMGR_VALID(mgr)); + + mgr->generation++; /* Increment the generation count. */ + + if (isc_net_probeipv6() == ISC_R_SUCCESS) { + if (do_ipv6(mgr) != ISC_R_SUCCESS) + purge = ISC_FALSE; + } +#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) { + if (do_ipv4(mgr) != ISC_R_SUCCESS) + purge = ISC_FALSE; + } else + isc_log_write(IFMGR_COMMON_LOGARGS, + verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1), + "no IPv4 interfaces found"); + + /* + * 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 (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_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); +} + diff --git a/contrib/bind-9.2.4rc7/bin/named/listenlist.c b/contrib/bind-9.2.4rc7/bin/named/listenlist.c new file mode 100644 index 0000000..dbc24cb --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/listenlist.c @@ -0,0 +1,136 @@ +/* + * 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: listenlist.c,v 1.9.2.1 2004/03/09 06:09:18 marka Exp $ */ + +#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/bind-9.2.4rc7/bin/named/log.c b/contrib/bind-9.2.4rc7/bin/named/log.c new file mode 100644 index 0000000..6cd92b9 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/log.c @@ -0,0 +1,203 @@ +/* + * 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: log.c,v 1.33.2.2 2004/03/09 06:09:18 marka Exp $ */ + +#include + +#include + +#include + +#include + +/* + * When adding a new category, be sure to add the appropriate + * #define to . + */ +static isc_logcategory_t categories[] = { + { "", 0 }, + { "client", 0 }, + { "network", 0 }, + { "update", 0 }, + { "queries", 0 }, + { "unmatched", 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); + + 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; + } + + /* + * 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 (! 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); + } + + 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/bind-9.2.4rc7/bin/named/logconf.c b/contrib/bind-9.2.4rc7/bin/named/logconf.c new file mode 100644 index 0000000..6e87d5c --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/logconf.c @@ -0,0 +1,295 @@ +/* + * 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: logconf.c,v 1.30.2.5 2004/03/09 06:09:18 marka Exp $ */ + +#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(cfg_obj_t *ccat, isc_logconfig_t *lctx) { + isc_result_t result; + const char *catname; + isc_logcategory_t *category; + isc_logmodule_t *module; + cfg_obj_t *destinations = NULL; + 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)) + { + cfg_obj_t *channel = cfg_listelt_value(element); + 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(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; + cfg_obj_t *fileobj = NULL; + cfg_obj_t *syslogobj = NULL; + cfg_obj_t *nullobj = NULL; + cfg_obj_t *stderrobj = NULL; + 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) { + cfg_obj_t *pathobj = cfg_tuple_get(fileobj, "file"); + cfg_obj_t *sizeobj = cfg_tuple_get(fileobj, "size"); + 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)) { + 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. + */ + { + cfg_obj_t *printcat = NULL; + cfg_obj_t *printsev = NULL; + 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)) { + 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, cfg_obj_t *logstmt) { + isc_result_t result; + cfg_obj_t *channels = NULL; + cfg_obj_t *categories = NULL; + cfg_listelt_t *element; + isc_boolean_t default_set = ISC_FALSE; + isc_boolean_t unmatched_set = ISC_FALSE; + + 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)) + { + 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)) + { + cfg_obj_t *category = cfg_listelt_value(element); + CHECK(category_fromconf(category, logconf)); + if (!default_set) { + cfg_obj_t *catname = cfg_tuple_get(category, "name"); + if (strcmp(cfg_obj_asstring(catname), "default") == 0) + default_set = ISC_TRUE; + } + if (!unmatched_set) { + cfg_obj_t *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/bind-9.2.4rc7/bin/named/lwaddr.c b/contrib/bind-9.2.4rc7/bin/named/lwaddr.c new file mode 100644 index 0000000..5441549 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/lwaddr.c @@ -0,0 +1,92 @@ +/* + * 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: lwaddr.c,v 1.3.2.1 2004/03/09 06:09:18 marka Exp $ */ + +#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/bind-9.2.4rc7/bin/named/lwdclient.c b/contrib/bind-9.2.4rc7/bin/named/lwdclient.c new file mode 100644 index 0000000..67c3a88 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/lwdclient.c @@ -0,0 +1,450 @@ +/* + * 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: lwdclient.c,v 1.13.2.1 2004/03/09 06:09:18 marka Exp $ */ + +#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) { + 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; + + ns_lwdclient_startrecv(cm); + + 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; + + 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); + + ns_lwdclient_startrecv(cm); +} + +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/bind-9.2.4rc7/bin/named/lwderror.c b/contrib/bind-9.2.4rc7/bin/named/lwderror.c new file mode 100644 index 0000000..6a4c15b --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/lwderror.c @@ -0,0 +1,78 @@ +/* + * 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: lwderror.c,v 1.7.2.1 2004/03/09 06:09:18 marka Exp $ */ + +#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/bind-9.2.4rc7/bin/named/lwdgabn.c b/contrib/bind-9.2.4rc7/bin/named/lwdgabn.c new file mode 100644 index 0000000..d53a5df --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/lwdgabn.c @@ -0,0 +1,655 @@ +/* + * 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: lwdgabn.c,v 1.13.2.1 2004/03/09 06:09:18 marka Exp $ */ + +#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; + 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, 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/bind-9.2.4rc7/bin/named/lwdgnba.c b/contrib/bind-9.2.4rc7/bin/named/lwdgnba.c new file mode 100644 index 0000000..4d3fe96 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/lwdgnba.c @@ -0,0 +1,274 @@ +/* + * 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: lwdgnba.c,v 1.13.2.3 2004/03/09 06:09:18 marka Exp $ */ + +#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_IPV6NIBBLE) == 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 nibble then IP6.ARPA bitstring. + */ + if ((client->options & DNS_BYADDROPT_IPV6INT) == 0) + client->options |= DNS_BYADDROPT_IPV6INT; + else + client->options &= ~DNS_BYADDROPT_IPV6NIBBLE; + + 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; + + /* + * Start with IP6.ARPA NIBBLE lookups. + */ + client->options = DNS_BYADDROPT_IPV6NIBBLE; + 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); + + /* + * 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/bind-9.2.4rc7/bin/named/lwdgrbn.c b/contrib/bind-9.2.4rc7/bin/named/lwdgrbn.c new file mode 100644 index 0000000..a6365ff --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/lwdgrbn.c @@ -0,0 +1,513 @@ +/* + * 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: lwdgrbn.c,v 1.11.2.1 2004/03/09 06:09:18 marka Exp $ */ + +#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_sig) { + 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)); + if (newlens != NULL) + isc_mem_put(mctx, newlens, used * sizeof(*oldlens)); + 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 out; + + 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)); + + 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/bind-9.2.4rc7/bin/named/lwdnoop.c b/contrib/bind-9.2.4rc7/bin/named/lwdnoop.c new file mode 100644 index 0000000..cfaea20 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/lwdnoop.c @@ -0,0 +1,86 @@ +/* + * 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: lwdnoop.c,v 1.6.2.1 2004/03/09 06:09:18 marka Exp $ */ + +#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/bind-9.2.4rc7/bin/named/lwresd.8 b/contrib/bind-9.2.4rc7/bin/named/lwresd.8 new file mode 100644 index 0000000..db76a07 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/lwresd.8 @@ -0,0 +1,140 @@ +.\" 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: lwresd.8,v 1.13.2.2 2004/06/03 05:21:13 marka Exp $ +.\" +.TH "LWRESD" "8" "June 30, 2000" "BIND9" "" +.SH NAME +lwresd \- lightweight resolver daemon +.SH SYNOPSIS +.sp +\fBlwresd\fR [ \fB-C \fIconfig-file\fB\fR ] [ \fB-d \fIdebug-level\fB\fR ] [ \fB-f\fR ] [ \fB-g\fR ] [ \fB-i \fIpid-file\fB\fR ] [ \fB-n \fI#cpus\fB\fR ] [ \fB-P \fIport\fB\fR ] [ \fB-p \fIport\fB\fR ] [ \fB-s\fR ] [ \fB-t \fIdirectory\fB\fR ] [ \fB-u \fIuser\fB\fR ] [ \fB-v\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" +.TP +\fB-C \fIconfig-file\fB\fR +Use \fIconfig-file\fR as the +configuration file instead of the default, +\fI/etc/resolv.conf\fR. +.TP +\fB-d \fIdebug-level\fB\fR +Set the daemon's debug level to \fIdebug-level\fR. +Debugging traces from \fBlwresd\fR become +more verbose as the debug level increases. +.TP +\fB-f\fR +Run the server in the foreground (i.e. do not daemonize). +.TP +\fB-g\fR +Run the server in the foreground and force all logging +to \fIstderr\fR. +.TP +\fB-n \fI#cpus\fB\fR +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. +.TP +\fB-P \fIport\fB\fR +Listen for lightweight resolver queries on port +\fIport\fR. If +not specified, the default is port 921. +.TP +\fB-p \fIport\fB\fR +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. +.TP +\fB-s\fR +Write memory usage statistics to \fIstdout\fR +on exit. +.sp +.RS +.B "Note:" +This option is mainly of interest to BIND 9 developers +and may be removed or changed in a future release. +.RE +.sp +.TP +\fB-t \fIdirectory\fB\fR +\fBchroot()\fR to \fIdirectory\fR after +processing the command line arguments, but before +reading the configuration file. +.sp +.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()\fR is +defined allows a process with root privileges to +escape a chroot jail. +.RE +.sp +.TP +\fB-u \fIuser\fB\fR +\fBsetuid()\fR to \fIuser\fR after completing +privileged operations, such as creating sockets that +listen on privileged ports. +.TP +\fB-v\fR +Report the version number and exit. +.SH "FILES" +.TP +\fB\fI/etc/resolv.conf\fB\fR +The default configuration file. +.TP +\fB\fI/var/run/lwresd.pid\fB\fR +The default process-id file. +.SH "SEE ALSO" +.PP +\fBnamed\fR(8), +\fBlwres\fR(3), +\fBresolver\fR(5). +.SH "AUTHOR" +.PP +Internet Systems Consortium diff --git a/contrib/bind-9.2.4rc7/bin/named/lwresd.c b/contrib/bind-9.2.4rc7/bin/named/lwresd.c new file mode 100644 index 0000000..eb5687f --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/lwresd.c @@ -0,0 +1,855 @@ +/* + * 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: lwresd.c,v 1.37.2.3 2004/03/09 06:09:19 marka Exp $ */ + +/* + * 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, cfg_obj_t *lwres, + ns_lwresd_t **lwresdp) +{ + ns_lwresd_t *lwresd; + const char *vname; + dns_rdataclass_t vclass; + cfg_obj_t *obj, *viewobj, *searchobj; + 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; + 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)) + { + cfg_obj_t *search; + 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); + 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; + + REQUIRE(listenerp != NULL && *listenerp == NULL); + + listener = isc_mem_get(mctx, sizeof(ns_lwreslistener_t)); + if (listener == NULL) + return (ISC_R_NOMEMORY); + RUNTIME_CHECK(isc_mutex_init(&listener->lock) == ISC_R_SUCCESS); + + 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) { + ns_lwdclient_startrecv(cm); + 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, cfg_obj_t *config) { + cfg_obj_t *lwreslist = NULL; + cfg_obj_t *lwres = NULL; + cfg_obj_t *listenerslist = NULL; + 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; + 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/bind-9.2.4rc7/bin/named/lwresd.html b/contrib/bind-9.2.4rc7/bin/named/lwresd.html new file mode 100644 index 0000000..8ac46ac --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/lwresd.html @@ -0,0 +1,541 @@ + + + + +lwresd

lwresd

Name

lwresd -- lightweight resolver daemon

Synopsis

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

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

-C config-file

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

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

-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() 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/bind-9.2.4rc7/bin/named/lwsearch.c b/contrib/bind-9.2.4rc7/bin/named/lwsearch.c new file mode 100644 index 0000000..433f40e --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/lwsearch.c @@ -0,0 +1,199 @@ +/* + * 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: lwsearch.c,v 1.7.2.1 2004/03/09 06:09:19 marka Exp $ */ + +#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; + + REQUIRE(mctx != NULL); + REQUIRE(listp != NULL && *listp == NULL); + + list = isc_mem_get(mctx, sizeof(ns_lwsearchlist_t)); + if (list == NULL) + return (ISC_R_NOMEMORY); + + RUNTIME_CHECK(isc_mutex_init(&list->lock) == ISC_R_SUCCESS); + 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/bind-9.2.4rc7/bin/named/main.c b/contrib/bind-9.2.4rc7/bin/named/main.c new file mode 100644 index 0000000..9c772c8 --- /dev/null +++ b/contrib/bind-9.2.4rc7/bin/named/main.c @@ -0,0 +1,656 @@ +/* + * Copyright (C) 2004 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.119.2.10 2004/04/20 13:54:17 marka Exp $ */ + +#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 /* Explicit, though named/log.h includes it. */ +#include +#include +#include +#include +#include +#include + +/* + * Include header files for database drivers here. + */ +/* #include "xxdb.h" */ + +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_